diff --git a/authority/ssh.go b/authority/ssh.go index 0521ab58..bb69f9db 100644 --- a/authority/ssh.go +++ b/authority/ssh.go @@ -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") }