Store provisioner with SignSSH

This change also allows to store the old certificate on renewal on
linkedca or if the db interface supports it.
This commit is contained in:
Mariano Cano 2022-05-18 18:33:53 -07:00
parent c8d7ad7ab9
commit 293586079a

View file

@ -161,8 +161,13 @@ func (a *Authority) SignSSH(ctx context.Context, key ssh.PublicKey, opts provisi
// Set backdate with the configured value
opts.Backdate = a.config.AuthorityConfig.Backdate.Duration
var prov provisioner.Interface
for _, op := range signOpts {
switch o := op.(type) {
// Capture current provisioner
case provisioner.Interface:
prov = o
// add options to NewCertificate
case provisioner.SSHCertificateOptions:
certOptions = append(certOptions, o.Options(opts)...)
@ -276,7 +281,7 @@ func (a *Authority) SignSSH(ctx context.Context, key ssh.PublicKey, opts provisi
}
}
if err = a.storeSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
if err = a.storeSSHCertificate(prov, cert); err != nil && err != db.ErrNotImplemented {
return nil, errs.Wrap(http.StatusInternalServerError, err, "authority.SignSSH: error storing certificate in db")
}
@ -340,7 +345,7 @@ func (a *Authority) RenewSSH(ctx context.Context, oldCert *ssh.Certificate) (*ss
return nil, errs.Wrap(http.StatusInternalServerError, err, "signSSH: error signing certificate")
}
if err = a.storeSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
if err = a.storeRenewedSSHCertificate(oldCert, cert); err != nil && err != db.ErrNotImplemented {
return nil, errs.Wrap(http.StatusInternalServerError, err, "renewSSH: error storing certificate in db")
}
@ -419,21 +424,59 @@ func (a *Authority) RekeySSH(ctx context.Context, oldCert *ssh.Certificate, pub
}
}
if err = a.storeSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
if err = a.storeRenewedSSHCertificate(oldCert, cert); err != nil && err != db.ErrNotImplemented {
return nil, errs.Wrap(http.StatusInternalServerError, err, "rekeySSH; error storing certificate in db")
}
return cert, nil
}
func (a *Authority) storeSSHCertificate(cert *ssh.Certificate) error {
func (a *Authority) storeSSHCertificate(prov provisioner.Interface, cert *ssh.Certificate) error {
type sshCertificateStorer interface {
StoreSSHCertificate(crt *ssh.Certificate) error
StoreSSHCertificate(provisioner.Interface, *ssh.Certificate) error
}
if s, ok := a.adminDB.(sshCertificateStorer); ok {
// Store certificate in admindb or linkedca
switch s := a.adminDB.(type) {
case sshCertificateStorer:
return s.StoreSSHCertificate(prov, cert)
case db.CertificateStorer:
return s.StoreSSHCertificate(cert)
}
return a.db.StoreSSHCertificate(cert)
// Store certificate in localdb
switch s := a.db.(type) {
case sshCertificateStorer:
return s.StoreSSHCertificate(prov, cert)
case db.CertificateStorer:
return s.StoreSSHCertificate(cert)
default:
return nil
}
}
func (a *Authority) storeRenewedSSHCertificate(parent, cert *ssh.Certificate) error {
type sshRenewerCertificateStorer interface {
StoreRenewedSSHCertificate(parent, cert *ssh.Certificate) error
}
// Store certificate in admindb or linkedca
switch s := a.adminDB.(type) {
case sshRenewerCertificateStorer:
return s.StoreRenewedSSHCertificate(parent, cert)
case db.CertificateStorer:
return s.StoreSSHCertificate(cert)
}
// Store certificate in localdb
switch s := a.db.(type) {
case sshRenewerCertificateStorer:
return s.StoreRenewedSSHCertificate(parent, cert)
case db.CertificateStorer:
return s.StoreSSHCertificate(cert)
default:
return nil
}
}
// IsValidForAddUser checks if a user provisioner certificate can be issued to
@ -511,7 +554,7 @@ func (a *Authority) SignSSHAddUser(ctx context.Context, key ssh.PublicKey, subje
}
cert.Signature = sig
if err = a.storeSSHCertificate(cert); err != nil && err != db.ErrNotImplemented {
if err = a.storeRenewedSSHCertificate(subject, cert); err != nil && err != db.ErrNotImplemented {
return nil, errs.Wrap(http.StatusInternalServerError, err, "signSSHAddUser: error storing certificate in db")
}