From ed688790ebfc465699cb58d86518bd84a835f565 Mon Sep 17 00:00:00 2001 From: "Michael L. Young" Date: Thu, 5 Dec 2024 11:37:55 -0500 Subject: [PATCH] Add support for encrypted private key This PR adds support for prompting the user for their SSH key password if they are using an encrypted private key. Testing was performed locally. Signed-off-by: Michael L. Young resolves rocky-linux/srpmproc#28 --- cmd/srpmproc/main.go | 3 +++ go.mod | 3 ++- go.sum | 4 ++++ pkg/srpmproc/process.go | 17 ++++++++++++++++- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/cmd/srpmproc/main.go b/cmd/srpmproc/main.go index f72151b..46eb3bd 100644 --- a/cmd/srpmproc/main.go +++ b/cmd/srpmproc/main.go @@ -35,6 +35,7 @@ var ( sourceRpmGitName string sshKeyLocation string sshUser string + sshAskKeyPassword bool upstreamPrefix string version int storageAddr string @@ -80,6 +81,7 @@ func mn(_ *cobra.Command, _ []string) { RpmPrefix: rpmPrefix, SshKeyLocation: sshKeyLocation, SshUser: sshUser, + SshKeyPassword: sshAskKeyPassword, ManualCommits: manualCommits, UpstreamPrefix: upstreamPrefix, GitCommitterName: gitCommitterName, @@ -130,6 +132,7 @@ func main() { root.Flags().StringVar(&sourceRpmGitName, "source-rpm-git-name", "", "Actual git repo name of package if name is different from source-rpm value") root.Flags().StringVar(&sshKeyLocation, "ssh-key-location", "", "Location of the SSH key to use to authenticate against upstream") root.Flags().StringVar(&sshUser, "ssh-user", "git", "SSH User") + root.Flags().BoolVar(&sshAskKeyPassword, "ssh-key-password", false, "If enabled, prompt for ssh key password") root.Flags().StringVar(&gitCommitterName, "git-committer-name", "rockyautomation", "Name of committer") root.Flags().StringVar(&gitCommitterEmail, "git-committer-email", "rockyautomation@rockylinux.org", "Email of committer") root.Flags().StringVar(&modulePrefix, "module-prefix", "https://git.centos.org/modules", "Where to retrieve modules if exists. Only used when source-rpm is a git repo") diff --git a/go.mod b/go.mod index 6a90bae..3ca2575 100644 --- a/go.mod +++ b/go.mod @@ -72,7 +72,8 @@ require ( golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/term v0.26.0 golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.23.0 // indirect diff --git a/go.sum b/go.sum index 7595878..c851a7c 100644 --- a/go.sum +++ b/go.sum @@ -511,6 +511,8 @@ golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -519,6 +521,8 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= +golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= diff --git a/pkg/srpmproc/process.go b/pkg/srpmproc/process.go index e4b4e20..27a2b61 100644 --- a/pkg/srpmproc/process.go +++ b/pkg/srpmproc/process.go @@ -31,6 +31,7 @@ import ( "os/user" "path/filepath" "strings" + "syscall" "time" "github.com/go-git/go-billy/v5" @@ -55,6 +56,7 @@ import ( "github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/storage/memory" "github.com/rocky-linux/srpmproc/pkg/data" + "golang.org/x/term" ) const ( @@ -79,6 +81,7 @@ type ProcessDataRequest struct { RpmPrefix string SshKeyLocation string SshUser string + SshKeyPassword bool HttpUsername string HttpPassword string ManualCommits string @@ -267,8 +270,20 @@ func NewProcessData(req *ProcessDataRequest) (*data.ProcessData, error) { Password: req.HttpPassword, } } else { + var sshPassword string = "" + if req.SshKeyPassword { + + fmt.Print("Enter SSH key password: ") + sshBytePassword, err := term.ReadPassword(int(syscall.Stdin)) + if err != nil { + return nil, fmt.Errorf("could not read password for ssh key: %v", err) + } + + sshPassword = string(sshBytePassword) + } + // create ssh key authenticator - authenticator, err = ssh.NewPublicKeysFromFile(req.SshUser, lastKeyLocation, "") + authenticator, err = ssh.NewPublicKeysFromFile(req.SshUser, lastKeyLocation, sshPassword) } if err != nil { return nil, fmt.Errorf("could not get git authenticator: %v", err)