|
|
|
@ -442,16 +442,37 @@ func (a *Authority) RekeySSH(ctx context.Context, oldCert *ssh.Certificate, pub
|
|
|
|
|
return cert, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// IsValidForAddUser checks if a user provisioner certificate can be issued to
|
|
|
|
|
// the given certificate.
|
|
|
|
|
func IsValidForAddUser(cert *ssh.Certificate) error {
|
|
|
|
|
if cert.CertType != ssh.UserCert {
|
|
|
|
|
return errors.New("certificate is not a user certificate")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch len(cert.ValidPrincipals) {
|
|
|
|
|
case 0:
|
|
|
|
|
return errors.New("certificate does not have any principals")
|
|
|
|
|
case 1:
|
|
|
|
|
return nil
|
|
|
|
|
case 2:
|
|
|
|
|
// OIDC provisioners adds a second principal with the email address.
|
|
|
|
|
// @ cannot be the first character.
|
|
|
|
|
if strings.Index(cert.ValidPrincipals[1], "@") > 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return errors.New("certificate does not have only one principal")
|
|
|
|
|
default:
|
|
|
|
|
return errors.New("certificate does not have only one principal")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SignSSHAddUser signs a certificate that provisions a new user in a server.
|
|
|
|
|
func (a *Authority) SignSSHAddUser(ctx context.Context, key ssh.PublicKey, subject *ssh.Certificate) (*ssh.Certificate, error) {
|
|
|
|
|
if a.sshCAUserCertSignKey == nil {
|
|
|
|
|
return nil, errs.NotImplemented("signSSHAddUser: user certificate signing is not enabled")
|
|
|
|
|
}
|
|
|
|
|
if subject.CertType != ssh.UserCert {
|
|
|
|
|
return nil, errs.Forbidden("signSSHAddUser: certificate is not a user certificate")
|
|
|
|
|
}
|
|
|
|
|
if len(subject.ValidPrincipals) != 1 {
|
|
|
|
|
return nil, errs.Forbidden("signSSHAddUser: certificate does not have only one principal")
|
|
|
|
|
if err := IsValidForAddUser(subject); err != nil {
|
|
|
|
|
return nil, errs.Wrap(http.StatusForbidden, err, "signSSHAddUser")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nonce, err := randutil.ASCII(32)
|
|
|
|
|