Set default SSH options if no user options are given.

pull/85/head
Mariano Cano 5 years ago
parent c17375a10a
commit a8f4ad1b8e

@ -448,13 +448,18 @@ func (p *AWS) authorizeSSHSign(claims *awsPayload) ([]SignOption, error) {
sshCertificateKeyIDModifier(claims.Subject),
}
signOptions = append(signOptions, &sshCertificateOptionsValidator{&SSHOptions{
// Default to host + known IPs/hostnames
defaults := SSHOptions{
CertType: SSHHostCert,
Principals: []string{
doc.PrivateIP,
fmt.Sprintf("ip-%s.%s.compute.internal", strings.Replace(doc.PrivateIP, ".", "-", -1), doc.Region),
},
}})
}
// Validate user options
signOptions = append(signOptions, sshCertificateOptionsValidator(defaults))
// Set defaults if not given as user options
signOptions = append(signOptions, sshCertificateDefaultsModifier(defaults))
return append(signOptions,
// set the default extensions

@ -308,10 +308,15 @@ func (p *Azure) authorizeSSHSign(claims azurePayload, name string) ([]SignOption
sshCertificateKeyIDModifier(name),
}
signOptions = append(signOptions, &sshCertificateOptionsValidator{&SSHOptions{
// Default to host + known hostnames
defaults := SSHOptions{
CertType: SSHHostCert,
Principals: []string{name},
}})
}
// Validate user options
signOptions = append(signOptions, sshCertificateOptionsValidator(defaults))
// Set defaults if not given as user options
signOptions = append(signOptions, sshCertificateDefaultsModifier(defaults))
return append(signOptions,
// set the default extensions

@ -360,13 +360,18 @@ func (p *GCP) authorizeSSHSign(claims *gcpPayload) ([]SignOption, error) {
sshCertificateKeyIDModifier(ce.InstanceName),
}
signOptions = append(signOptions, &sshCertificateOptionsValidator{&SSHOptions{
// Default to host + known hostnames
defaults := SSHOptions{
CertType: SSHHostCert,
Principals: []string{
fmt.Sprintf("%s.c.%s.internal", ce.InstanceName, ce.ProjectID),
fmt.Sprintf("%s.%s.c.%s.internal", ce.InstanceName, ce.Zone, ce.ProjectID),
},
}})
}
// Validate user options
signOptions = append(signOptions, sshCertificateOptionsValidator(defaults))
// Set defaults if not given as user options
signOptions = append(signOptions, sshCertificateDefaultsModifier(defaults))
return append(signOptions,
// set the default extensions

@ -178,7 +178,7 @@ func (p *JWK) authorizeSSHSign(claims *jwtPayload) ([]SignOption, error) {
opts := claims.Step.SSH
signOptions := []SignOption{
// validates user's SSHOptions with the ones in the token
&sshCertificateOptionsValidator{opts},
sshCertificateOptionsValidator(*opts),
// set the key id to the token subject
sshCertificateKeyIDModifier(claims.Subject),
}
@ -197,6 +197,9 @@ func (p *JWK) authorizeSSHSign(claims *jwtPayload) ([]SignOption, error) {
signOptions = append(signOptions, sshCertificateValidBeforeModifier(opts.ValidBefore.RelativeTime(t).Unix()))
}
// Default to a user certificate with no principals if not set
signOptions = append(signOptions, sshCertificateDefaultsModifier{CertType: SSHUserCert})
return append(signOptions,
// set the default extensions
&sshDefaultExtensionModifier{},

@ -303,20 +303,25 @@ func (o *OIDC) authorizeSSHSign(claims *openIDPayload) ([]SignOption, error) {
sshCertificateKeyIDModifier(claims.Email),
}
// Non-admins are only able to sign user certificates
if o.IsAdmin(claims.Email) {
signOptions = append(signOptions, &sshCertificateOptionsValidator{})
} else {
name := SanitizeSSHUserPrincipal(claims.Email)
if !sshUserRegex.MatchString(name) {
return nil, errors.Errorf("invalid principal '%s' from email address '%s'", name, claims.Email)
}
signOptions = append(signOptions, &sshCertificateOptionsValidator{&SSHOptions{
CertType: SSHUserCert,
Principals: []string{name},
}})
name := SanitizeSSHUserPrincipal(claims.Email)
if !sshUserRegex.MatchString(name) {
return nil, errors.Errorf("invalid principal '%s' from email address '%s'", name, claims.Email)
}
// Admin users will default to user + name but they can be changed by the
// user options. Non-admins are only able to sign user certificates.
defaults := SSHOptions{
CertType: SSHUserCert,
Principals: []string{name},
}
if !o.IsAdmin(claims.Email) {
signOptions = append(signOptions, sshCertificateOptionsValidator(defaults))
}
// Default to a user with name as principal if not set
signOptions = append(signOptions, sshCertificateDefaultsModifier(defaults))
return append(signOptions,
// set the default extensions
&sshDefaultExtensionModifier{},

@ -143,6 +143,27 @@ func (m sshCertificateValidBeforeModifier) Modify(cert *ssh.Certificate) error {
return nil
}
// sshCertificateDefaultModifier implements a SSHCertificateModifier that
// modifies the certificate with the given options if they are not set.
type sshCertificateDefaultsModifier SSHOptions
// Modify implements the SSHCertificateModifier interface.
func (m sshCertificateDefaultsModifier) Modify(cert *ssh.Certificate) error {
if cert.CertType == 0 {
cert.CertType = sshCertTypeUInt32(m.CertType)
}
if len(cert.ValidPrincipals) == 0 {
cert.ValidPrincipals = m.Principals
}
if cert.ValidAfter == 0 && !m.ValidAfter.IsZero() {
cert.ValidAfter = uint64(m.ValidAfter.Unix())
}
if cert.ValidBefore == 0 && !m.ValidBefore.IsZero() {
cert.ValidBefore = uint64(m.ValidBefore.Unix())
}
return nil
}
// sshDefaultExtensionModifier implements an SSHCertificateModifier that sets
// the default extensions in an SSH certificate.
type sshDefaultExtensionModifier struct{}
@ -212,17 +233,13 @@ func (m *sshCertificateValidityModifier) Modify(cert *ssh.Certificate) error {
// sshCertificateOptionsValidator validates the user SSHOptions with the ones
// usually present in the token.
type sshCertificateOptionsValidator struct {
Want *SSHOptions
}
type sshCertificateOptionsValidator SSHOptions
// Valid implements SSHCertificateOptionsValidator and returns nil if both
// SSHOptions match.
func (v *sshCertificateOptionsValidator) Valid(got SSHOptions) error {
if v.Want == nil {
return nil
}
return v.Want.match(got)
func (v sshCertificateOptionsValidator) Valid(got SSHOptions) error {
want := SSHOptions(v)
return want.match(got)
}
// sshCertificateDefaultValidator implements a simple validator for all the

Loading…
Cancel
Save