Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Agent confirmation tests #202

Merged
merged 5 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
}
Loading