Skip to content

Commit

Permalink
Agent confirmation tests (#202)
Browse files Browse the repository at this point in the history
* enable agent confirmation from config

* cleanup

* update versions

* fixing tests

* fixing typo
  • Loading branch information
cviecco authored Oct 4, 2023
1 parent 55ae648 commit 5f3ee7c
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ endif
BINARY=keymaster

# These are the values we want to pass for Version and BuildTime
VERSION=1.13.5
VERSION=1.14.0
#BUILD_TIME=`date +%FT%T%z`

# Setup the -ldflags option for go build here, interpolate the variable values
Expand Down
34 changes: 32 additions & 2 deletions cmd/keymaster/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import (
"strings"
"time"

"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"

"github.com/Cloud-Foundations/Dominator/lib/log/cmdlogger"
"github.com/Cloud-Foundations/Dominator/lib/net/rrdialer"
"github.com/Cloud-Foundations/golib/pkg/log"
Expand Down Expand Up @@ -271,9 +274,29 @@ func insertSSHCertIntoAgentORWriteToFilesystem(certText []byte,
filePrefix string,
userName string,
privateKeyPath string,
confirmBeforeUse bool,
logger log.DebugLogger) (err error) {

pubKey, _, _, _, err := ssh.ParseAuthorizedKey(certText)
if err != nil {
logger.Println(err)
return err
}
sshCert, ok := pubKey.(*ssh.Certificate)
if !ok {
return fmt.Errorf("It is not a certificate")
}
comment := filePrefix + "-" + userName
keyToAdd := agent.AddedKey{
PrivateKey: signer,
Certificate: sshCert,
Comment: comment,
LifetimeSecs: uint32((*twofa.Duration).Seconds()),
ConfirmBeforeUse: confirmBeforeUse,
}

//comment should be based on key type?
err = sshagent.UpsertCertIntoAgent(certText, signer, filePrefix+"-"+userName, uint32((*twofa.Duration).Seconds()), logger)
err = sshagent.WithAddedKeyUpsertCertIntoAgent(keyToAdd, logger)
if err == nil {
return nil
}
Expand All @@ -282,7 +305,10 @@ func insertSSHCertIntoAgentORWriteToFilesystem(certText []byte,
// barfs on timeouts missing, so we rety without a timeout in case
// we are on windows OR we have an agent running on windows thar is forwarded
// to us.
err = sshagent.UpsertCertIntoAgent(certText, signer, filePrefix+"-"+userName, 0, logger)
keyToAdd.LifetimeSecs = 0
// confirmation is also broken on windows, but since it is an opt-in security
// feature we never change the user preference
err = sshagent.WithAddedKeyUpsertCertIntoAgent(keyToAdd, logger)
if err == nil {
return nil
}
Expand Down Expand Up @@ -390,6 +416,7 @@ func setupCerts(
}
logger.Debugf(0, "certificates successfully generated")

confirmKeyUse := configContents.Base.AgentConfirmUse
// Time to write certs and keys
// old agents do not understand sha2 certs, so we inject Ed25519 first
// if present
Expand All @@ -399,6 +426,7 @@ func setupCerts(
FilePrefix+"-ed25519",
userName,
sshKeyPath+"-ed25519",
confirmKeyUse,
logger)
if err != nil {
return err
Expand All @@ -409,6 +437,7 @@ func setupCerts(
FilePrefix+"-rsa",
userName,
sshKeyPath+"-rsa",
confirmKeyUse,
logger)
if err != nil {
return err
Expand Down Expand Up @@ -502,6 +531,7 @@ func main() {
logger.Fatal(err)
}
config := loadConfigFile(client, logger)
logger.Debugf(3, "loaded Config=%+v", config)
// Adjust user name
if len(config.Base.Username) > 0 {
userName = config.Base.Username
Expand Down
1 change: 1 addition & 0 deletions cmd/keymaster/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ func TestInsertSSHCertIntoAgentORWriteToFilesystem(t *testing.T) {
"someprefix",
"username",
privateKeyPath,
false,
testlogger.New(t))
if err != nil {
t.Fatal(err)
Expand Down
2 changes: 1 addition & 1 deletion keymaster.spec
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Name: keymaster
Version: 1.13.5
Version: 1.14.0
Release: 1%{?dist}
Summary: Short term access certificate generator and client

Expand Down
11 changes: 6 additions & 5 deletions lib/client/config/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import (
)

type BaseConfig struct {
Gen_Cert_URLS string `yaml:"gen_cert_urls"`
Username string `yaml:"username"`
FilePrefix string `yaml:"file_prefix"`
AddGroups bool `yaml:"add_groups"`
WebauthBrowser string `yaml:"webauth_browser"`
Gen_Cert_URLS string `yaml:"gen_cert_urls"`
Username string `yaml:"username"`
FilePrefix string `yaml:"file_prefix"`
AddGroups bool `yaml:"add_groups"`
WebauthBrowser string `yaml:"webauth_browser"`
AgentConfirmUse bool `yaml:"agent_confirm_use"`
}

// AppConfigFile represents a keymaster client configuration file
Expand Down
30 changes: 20 additions & 10 deletions lib/client/sshagent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func upsertCertIntoAgent(
privateKey interface{},
comment string,
lifeTimeSecs uint32,
confirmBeforeUse bool,
logger log.Logger) error {
pubKey, _, _, _, err := ssh.ParseAuthorizedKey(certText)
if err != nil {
Expand All @@ -65,6 +66,20 @@ func upsertCertIntoAgent(
if !ok {
return fmt.Errorf("It is not a certificate")
}
keyToAdd := agent.AddedKey{
PrivateKey: privateKey,
Certificate: sshCert,
Comment: comment,
ConfirmBeforeUse: confirmBeforeUse,
}
return withAddedKeyUpsertCertIntoAgent(keyToAdd, logger)
}

func withAddedKeyUpsertCertIntoAgent(certToAdd agent.AddedKey, logger log.Logger) error {
if certToAdd.Certificate == nil {
return fmt.Errorf("Needs a certificate to be added")
}

conn, err := connectToDefaultSSHAgentLocation()
if err != nil {
return err
Expand All @@ -73,22 +88,17 @@ func upsertCertIntoAgent(
agentClient := agent.NewClient(conn)

//delete certs in agent with the same comment
_, err = deleteDuplicateEntries(comment, agentClient, logger)
_, err = deleteDuplicateEntries(certToAdd.Comment, agentClient, logger)
if err != nil {
logger.Printf("failed during deletion err=%s", err)
return err
}

keyToAdd := agent.AddedKey{
PrivateKey: privateKey,
Certificate: sshCert,
Comment: comment,
}
// NOTE: Current Windows ssh (OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5)
// barfs when encountering a lifetime so we only add it for non-windows
if runtime.GOOS != "windows" {
keyToAdd.LifetimeSecs = lifeTimeSecs
if runtime.GOOS == "windows" {
certToAdd.LifetimeSecs = 0
certToAdd.ConfirmBeforeUse = false
}

return agentClient.Add(keyToAdd)
return agentClient.Add(certToAdd)
}
8 changes: 7 additions & 1 deletion lib/client/sshagent/api.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package sshagent

import (
"golang.org/x/crypto/ssh/agent"

"github.com/Cloud-Foundations/golib/pkg/log"
)

Expand All @@ -10,5 +12,9 @@ func UpsertCertIntoAgent(
comment string,
lifeTimeSecs uint32,
logger log.Logger) error {
return upsertCertIntoAgent(certText, privateKey, comment, lifeTimeSecs, logger)
return upsertCertIntoAgent(certText, privateKey, comment, lifeTimeSecs, false, logger)
}

func WithAddedKeyUpsertCertIntoAgent(certToAdd agent.AddedKey, logger log.Logger) error {
return withAddedKeyUpsertCertIntoAgent(certToAdd, logger)
}

0 comments on commit 5f3ee7c

Please sign in to comment.