From df187e8a5fcacb0ef171947d106bdfdeb788aa03 Mon Sep 17 00:00:00 2001 From: Tchoupinax Date: Wed, 25 May 2022 19:00:09 +0200 Subject: [PATCH 1/4] feat: allow password to be taken from pipe --- util/client.go | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/util/client.go b/util/client.go index 1ba4946..2cf142d 100644 --- a/util/client.go +++ b/util/client.go @@ -1,19 +1,47 @@ package util import ( + "bufio" "context" "encoding/json" "errors" "fmt" "net/http" + "os" + "strings" "syscall" "github.com/passbolt/go-passbolt/api" "github.com/passbolt/go-passbolt/helper" "github.com/spf13/viper" + "golang.org/x/crypto/ssh/terminal" "golang.org/x/term" ) +func readPassword() (string, error) { + var fd int + var pass []byte + if terminal.IsTerminal(syscall.Stdin) { + fmt.Print("Enter Password:") + + fd = syscall.Stdin + inputPass, err := terminal.ReadPassword(fd) + if err != nil { + return "", err + } + pass = inputPass + } else { + reader := bufio.NewReader(os.Stdin) + s, err := reader.ReadString('\n') + if err != nil { + return "", err + } + pass = []byte(s) + } + + return strings.Replace(string(pass), "\n", "", 1), nil +} + // GetClient gets a Logged in Passbolt Client func GetClient(ctx context.Context) (*api.Client, error) { serverAddress := viper.GetString("serverAddress") @@ -28,13 +56,13 @@ func GetClient(ctx context.Context) (*api.Client, error) { userPassword := viper.GetString("userPassword") if userPassword == "" { - fmt.Print("Enter Password:") - bytepw, err := term.ReadPassword(int(syscall.Stdin)) + cliPassword, err := readPassword() if err != nil { fmt.Println() return nil, fmt.Errorf("Reading Password: %w", err) } - userPassword = string(bytepw) + + userPassword = cliPassword fmt.Println() } From a8b14c959f9ea9ac95c38eaaa3b548a36c12be0e Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Mon, 30 May 2022 17:51:10 +0200 Subject: [PATCH 2/4] use golang.org/x/term instead of depricated golang.org/x/crypto/ssh/terminal --- util/client.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/util/client.go b/util/client.go index 2cf142d..15422e6 100644 --- a/util/client.go +++ b/util/client.go @@ -14,18 +14,17 @@ import ( "github.com/passbolt/go-passbolt/api" "github.com/passbolt/go-passbolt/helper" "github.com/spf13/viper" - "golang.org/x/crypto/ssh/terminal" "golang.org/x/term" ) func readPassword() (string, error) { var fd int var pass []byte - if terminal.IsTerminal(syscall.Stdin) { + if term.IsTerminal(syscall.Stdin) { fmt.Print("Enter Password:") fd = syscall.Stdin - inputPass, err := terminal.ReadPassword(fd) + inputPass, err := term.ReadPassword(fd) if err != nil { return "", err } From bfbc15bd0d28e766d204e18f86990858ec3f3398 Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Mon, 30 May 2022 17:51:54 +0200 Subject: [PATCH 3/4] Make util ReadPassword Public --- util/client.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/util/client.go b/util/client.go index 15422e6..54acf12 100644 --- a/util/client.go +++ b/util/client.go @@ -17,7 +17,8 @@ import ( "golang.org/x/term" ) -func readPassword() (string, error) { +// ReadPassword reads a Password interactively or via Pipe +func ReadPassword() (string, error) { var fd int var pass []byte if term.IsTerminal(syscall.Stdin) { @@ -55,7 +56,7 @@ func GetClient(ctx context.Context) (*api.Client, error) { userPassword := viper.GetString("userPassword") if userPassword == "" { - cliPassword, err := readPassword() + cliPassword, err := ReadPassword() if err != nil { fmt.Println() return nil, fmt.Errorf("Reading Password: %w", err) From 440f41a2af5bd9dab353811dd1c3b5cb797c620a Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Mon, 30 May 2022 17:52:17 +0200 Subject: [PATCH 4/4] Replace usages of term.ReadPassword with util.ReadPassword --- cmd/verify.go | 6 ++---- keepass/export.go | 6 ++---- util/client.go | 3 +-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/cmd/verify.go b/cmd/verify.go index 0570367..7fa94ae 100644 --- a/cmd/verify.go +++ b/cmd/verify.go @@ -2,13 +2,11 @@ package cmd import ( "fmt" - "syscall" "github.com/passbolt/go-passbolt-cli/util" "github.com/passbolt/go-passbolt/api" "github.com/spf13/cobra" "github.com/spf13/viper" - "golang.org/x/term" ) // verifyCMD represents the verify command @@ -35,12 +33,12 @@ var verifyCMD = &cobra.Command{ userPassword := viper.GetString("userPassword") if userPassword == "" { fmt.Print("Enter Password:") - bytepw, err := term.ReadPassword(int(syscall.Stdin)) + pw, err := util.ReadPassword() if err != nil { fmt.Println() return fmt.Errorf("Reading Password: %w", err) } - userPassword = string(bytepw) + userPassword = pw fmt.Println() } diff --git a/keepass/export.go b/keepass/export.go index c4b62d0..a4c34fb 100644 --- a/keepass/export.go +++ b/keepass/export.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "os" - "syscall" "github.com/passbolt/go-passbolt-cli/util" "github.com/passbolt/go-passbolt/api" @@ -13,7 +12,6 @@ import ( "github.com/spf13/cobra" "github.com/tobischo/gokeepasslib/v3" w "github.com/tobischo/gokeepasslib/v3/wrappers" - "golang.org/x/term" ) // KeepassExportCmd Exports a Passbolt Keepass @@ -56,12 +54,12 @@ func KeepassExport(cmd *cobra.Command, args []string) error { if keepassPassword == "" { fmt.Print("Enter Keepass Password:") - bytepw, err := term.ReadPassword(int(syscall.Stdin)) + pw, err := util.ReadPassword() if err != nil { fmt.Println() return fmt.Errorf("Reading Keepass Password: %w", err) } - keepassPassword = string(bytepw) + keepassPassword = pw fmt.Println() } diff --git a/util/client.go b/util/client.go index 54acf12..f8abb09 100644 --- a/util/client.go +++ b/util/client.go @@ -97,12 +97,11 @@ func GetClient(ctx context.Context) (*api.Client, error) { for i := 0; i < 3; i++ { var code string fmt.Print("Enter TOTP:") - bytepw, err := term.ReadPassword(int(syscall.Stdin)) + code, err := ReadPassword() if err != nil { fmt.Printf("\n") return http.Cookie{}, fmt.Errorf("Reading TOTP: %w", err) } - code = string(bytepw) fmt.Printf("\n") req := api.MFAChallangeResponse{ TOTP: code,