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 <myoung@ciq.com>

resolves rocky-linux/srpmproc#28
This commit is contained in:
Michael L. Young 2024-12-05 11:37:55 -05:00
parent cd9ebd17b9
commit ed688790eb
No known key found for this signature in database
GPG key ID: D84A6A5913926D2B
4 changed files with 25 additions and 2 deletions

View file

@ -35,6 +35,7 @@ var (
sourceRpmGitName string sourceRpmGitName string
sshKeyLocation string sshKeyLocation string
sshUser string sshUser string
sshAskKeyPassword bool
upstreamPrefix string upstreamPrefix string
version int version int
storageAddr string storageAddr string
@ -80,6 +81,7 @@ func mn(_ *cobra.Command, _ []string) {
RpmPrefix: rpmPrefix, RpmPrefix: rpmPrefix,
SshKeyLocation: sshKeyLocation, SshKeyLocation: sshKeyLocation,
SshUser: sshUser, SshUser: sshUser,
SshKeyPassword: sshAskKeyPassword,
ManualCommits: manualCommits, ManualCommits: manualCommits,
UpstreamPrefix: upstreamPrefix, UpstreamPrefix: upstreamPrefix,
GitCommitterName: gitCommitterName, 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(&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(&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().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(&gitCommitterName, "git-committer-name", "rockyautomation", "Name of committer")
root.Flags().StringVar(&gitCommitterEmail, "git-committer-email", "rockyautomation@rockylinux.org", "Email 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") 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")

3
go.mod
View file

@ -72,7 +72,8 @@ require (
golang.org/x/net v0.27.0 // indirect golang.org/x/net v0.27.0 // indirect
golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/sync v0.7.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/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.23.0 // indirect golang.org/x/tools v0.23.0 // indirect

4
go.sum
View file

@ -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.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 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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-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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= 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 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= 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.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.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.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=

View file

@ -31,6 +31,7 @@ import (
"os/user" "os/user"
"path/filepath" "path/filepath"
"strings" "strings"
"syscall"
"time" "time"
"github.com/go-git/go-billy/v5" "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/plumbing/object"
"github.com/go-git/go-git/v5/storage/memory" "github.com/go-git/go-git/v5/storage/memory"
"github.com/rocky-linux/srpmproc/pkg/data" "github.com/rocky-linux/srpmproc/pkg/data"
"golang.org/x/term"
) )
const ( const (
@ -79,6 +81,7 @@ type ProcessDataRequest struct {
RpmPrefix string RpmPrefix string
SshKeyLocation string SshKeyLocation string
SshUser string SshUser string
SshKeyPassword bool
HttpUsername string HttpUsername string
HttpPassword string HttpPassword string
ManualCommits string ManualCommits string
@ -267,8 +270,20 @@ func NewProcessData(req *ProcessDataRequest) (*data.ProcessData, error) {
Password: req.HttpPassword, Password: req.HttpPassword,
} }
} else { } 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 // create ssh key authenticator
authenticator, err = ssh.NewPublicKeysFromFile(req.SshUser, lastKeyLocation, "") authenticator, err = ssh.NewPublicKeysFromFile(req.SshUser, lastKeyLocation, sshPassword)
} }
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get git authenticator: %v", err) return nil, fmt.Errorf("could not get git authenticator: %v", err)