Support passphrase-protected SSH identity files on non-CLI clients

This commit is contained in:
2024-12-28 15:09:17 -05:00
parent 1b9237af0b
commit a4a39a3a99
8 changed files with 22 additions and 35 deletions
+8 -5
View File
@@ -4,16 +4,19 @@ import (
"os"
)
type ByteInputFetcher func(prompt string) []byte
var (
Home, _ = os.UserHomeDir()
PassphraseInputFunction ByteInputFetcher // Clients should set this to a function that fetches hidden input from the user
Home, _ = os.UserHomeDir()
)
const (
LibmuttonVersion = "0.2.F" // untagged releases feature a letter suffix corresponding to the eventual release version, e.g "0.2.A" -> "0.2.0", "0.2.B" -> "0.2.1"
LibmuttonVersion = "0.2.F" // Untagged releases feature a letter suffix corresponding to the eventual release version, e.g "0.2.A" -> "0.2.0", "0.2.B" -> "0.2.1"
FSSpace = "\u259d" // ▝ space/list separator
FSPath = "\u259e" // ▞ path separator
FSMisc = "\u259f" // ▟ misc. field separator (if \u259d is already used)
FSSpace = "\u259d" // ▝ Space/list separator
FSPath = "\u259e" // ▞ Path separator
FSMisc = "\u259f" // ▟ Misc. field separator (if \u259d is already used)
AnsiError = "\033[38;5;9m"
AnsiReset = "\033[0m"
+5 -5
View File
@@ -2,13 +2,13 @@
package core
var EntryRoot = Home + "/.local/share/libmutton" // path to libmutton entry directory
var ConfigDir = Home + "/.config/libmutton" // path to libmutton configuration directory
var ConfigPath = ConfigDir + "/libmutton.ini" // path to libmutton configuration file
var EntryRoot = Home + "/.local/share/libmutton" // Path to libmutton entry directory
var ConfigDir = Home + "/.config/libmutton" // Path to libmutton configuration directory
var ConfigPath = ConfigDir + "/libmutton.ini" // Path to libmutton configuration file
const (
PathSeparator = "/" // platform-specific path separator
IsWindows = false // platform indicator
PathSeparator = "/" // Platform-specific path separator
IsWindows = false // Platform indicator
)
// enableVirtualTerminalProcessing is a dummy function on UNIX-like systems (only needed on Windows).
+5 -5
View File
@@ -7,13 +7,13 @@ import (
"syscall"
)
var EntryRoot = Home + "\\AppData\\Local\\libmutton\\entries" // path to libmutton entry directory
var ConfigDir = Home + "\\AppData\\Local\\libmutton\\config" // path to libmutton configuration directory
var ConfigPath = ConfigDir + "\\libmutton.ini" // path to libmutton configuration file
var EntryRoot = Home + "\\AppData\\Local\\libmutton\\entries" // Path to libmutton entry directory
var ConfigDir = Home + "\\AppData\\Local\\libmutton\\config" // Path to libmutton configuration directory
var ConfigPath = ConfigDir + "\\libmutton.ini" // Path to libmutton configuration file
const (
PathSeparator = "\\" // platform-specific path separator
IsWindows = true // platform indicator
PathSeparator = "\\" // Platform-specific path separator
IsWindows = true // Platform indicator
)
// enableVirtualTerminalProcessing ensures ANSI escape sequences are interpreted properly on Windows.
-1
View File
@@ -7,7 +7,6 @@ require (
github.com/pkg/sftp v1.13.7
github.com/pquerna/otp v1.4.1-0.20231130234153-3357de7c0481
golang.org/x/crypto v0.31.0
golang.org/x/term v0.27.0
gopkg.in/ini.v1 v1.67.0
)
+1 -1
View File
@@ -71,7 +71,7 @@ func GetSSHClient(manualSync bool) (*ssh.Client, string, bool) {
if keyFileProtected != "true" {
parsedKey, err = ssh.ParsePrivateKey(key)
} else {
parsedKey, err = ssh.ParsePrivateKeyWithPassphrase(key, inputKeyFilePassphrase())
parsedKey, err = ssh.ParsePrivateKeyWithPassphrase(key, core.PassphraseInputFunction("Enter passphrase for your SSH keyfile:"))
}
if err != nil {
fmt.Println(core.AnsiError+"Sync failed - Unable to parse private key:", keyFile+core.AnsiReset)
-17
View File
@@ -1,17 +0,0 @@
package sync
import (
"fmt"
"os"
"golang.org/x/term"
)
// inputKeyFilePassphrase prompts the user for a passphrase for an SSH key file.
// TODO support non-CLI implementations
func inputKeyFilePassphrase() []byte {
fmt.Print("\nEnter passphrase for your SSH keyfile: ")
passphrase, _ := term.ReadPassword(int(os.Stdin.Fd()))
fmt.Println()
return passphrase
}
-1
View File
@@ -1,4 +1,3 @@
## Known Bugs - libmutton
- On Windows, GPG is sometimes (seems unpredictable) incredibly slow to start (often after a reboot), leading to many operations seemingly hanging
- **This will be addressed** in the migration off of GPG that will take place before v1.0.0
- Password-protected SSH identity files currently only prompt for password entry in the CLI, and thus they are not yet supported in GUI/TUI implementations
+3
View File
@@ -15,6 +15,9 @@ These are as follows:
- `wsl`: Allows creating a Linux binary that can interact with the Windows clipboard (for WSL)
- `termux`: Allows creating a Linux binary that can interact with the Termux clipboard (for Android)
## Required Global Variable Manipulation
libmutton provides a `PassphraseInputFunction` global variable that all clients must set to support passphrase-protected SSH identity files. This approach allows for different types of clients (CLI, GUI, TUI) to prompt for the passphrase in the most appropriate way.
## Required Arguments
Some arguments should be accepted by all/most libmutton-based password managers. These are as follows:
- `clipclear`: This argument is required for correct functionality of non-interactive CLI implementations (not needed for interactive GUI/TUI implementations). In order to clear the clipboard on a timer, libmutton-based password managers call another instance of their executable with the `clipclear` argument (e.g. `mutn clipclear`) with the intended clipboard contents provided via STDIN. If after 30 seconds the clipboard contents have not changed, they are cleared. Please accept a `clipclear` argument that calls `core.ClipClearArgument()`.