diff --git a/core/1globals.go b/core/1globals.go index ab43825..89aa388 100644 --- a/core/1globals.go +++ b/core/1globals.go @@ -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" diff --git a/core/2globalsUNIX.go b/core/2globalsUNIX.go index 88c800d..0e8c1e9 100644 --- a/core/2globalsUNIX.go +++ b/core/2globalsUNIX.go @@ -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). diff --git a/core/2globalsWIN.go b/core/2globalsWIN.go index 92cd134..0454e61 100644 --- a/core/2globalsWIN.go +++ b/core/2globalsWIN.go @@ -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. diff --git a/go.mod b/go.mod index ec9f27e..4676974 100644 --- a/go.mod +++ b/go.mod @@ -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 ) diff --git a/sync/client.go b/sync/client.go index 8691e72..41445e9 100644 --- a/sync/client.go +++ b/sync/client.go @@ -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) diff --git a/sync/input.go b/sync/input.go deleted file mode 100644 index 0bf16f3..0000000 --- a/sync/input.go +++ /dev/null @@ -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 -} diff --git a/wiki/bugs.md b/wiki/bugs.md index 0013643..8849a4d 100644 --- a/wiki/bugs.md +++ b/wiki/bugs.md @@ -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 diff --git a/wiki/developers.md b/wiki/developers.md index 2617438..0e64ea2 100644 --- a/wiki/developers.md +++ b/wiki/developers.md @@ -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()`.