Skip to content

Commit 3ac3886

Browse files
committed
Use x5cInsecure token for /ssh/check-host endpoint
1 parent ab126d6 commit 3ac3886

File tree

6 files changed

+32
-8
lines changed

6 files changed

+32
-8
lines changed

api/ssh.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type SSHAuthority interface {
2525
GetSSHRoots() (*authority.SSHKeys, error)
2626
GetSSHFederation() (*authority.SSHKeys, error)
2727
GetSSHConfig(typ string, data map[string]string) ([]templates.Output, error)
28-
CheckSSHHost(principal string) (bool, error)
28+
CheckSSHHost(ctx context.Context, principal string, token string) (bool, error)
2929
GetSSHHosts(cert *x509.Certificate) ([]sshutil.Host, error)
3030
GetSSHBastion(user string, hostname string) (*authority.Bastion, error)
3131
}
@@ -199,6 +199,7 @@ type SSHConfigResponse struct {
199199
type SSHCheckPrincipalRequest struct {
200200
Type string `json:"type"`
201201
Principal string `json:"principal"`
202+
Token string `json:"token,omitempty"`
202203
}
203204

204205
// Validate checks the check principal request.
@@ -431,7 +432,7 @@ func (h *caHandler) SSHCheckHost(w http.ResponseWriter, r *http.Request) {
431432
return
432433
}
433434

434-
exists, err := h.Authority.CheckSSHHost(body.Principal)
435+
exists, err := h.Authority.CheckSSHHost(r.Context(), body.Principal, body.Token)
435436
if err != nil {
436437
WriteError(w, InternalServerError(err))
437438
return

authority/authority.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package authority
22

33
import (
4+
"context"
45
"crypto"
56
"crypto/sha256"
67
"crypto/x509"
@@ -40,9 +41,10 @@ type Authority struct {
4041
// Do not re-initialize
4142
initOnce bool
4243
// Custom functions
43-
sshBastionFunc func(user, hostname string) (*Bastion, error)
44-
sshGetHostsFunc func(cert *x509.Certificate) ([]sshutil.Host, error)
45-
getIdentityFunc provisioner.GetIdentityFunc
44+
sshBastionFunc func(user, hostname string) (*Bastion, error)
45+
sshCheckHostFunc func(ctx context.Context, principal string, tok string, roots []*x509.Certificate) (bool, error)
46+
sshGetHostsFunc func(cert *x509.Certificate) ([]sshutil.Host, error)
47+
getIdentityFunc provisioner.GetIdentityFunc
4648
}
4749

4850
// New creates and initiates a new Authority type.

authority/options.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package authority
22

33
import (
4+
"context"
45
"crypto/x509"
56

67
"github.com/smallstep/certificates/authority/provisioner"
@@ -42,3 +43,12 @@ func WithSSHGetHosts(fn func(cert *x509.Certificate) ([]sshutil.Host, error)) Op
4243
a.sshGetHostsFunc = fn
4344
}
4445
}
46+
47+
// WithSSHCheckHost sets a custom function to check whether a given host is
48+
// step ssh enabled. The token is used to validate the request, while the roots
49+
// are used to validate the token.
50+
func WithSSHCheckHost(fn func(ctx context.Context, principal string, tok string, roots []*x509.Certificate) (bool, error)) Option {
51+
return func(a *Authority) {
52+
a.sshCheckHostFunc = fn
53+
}
54+
}

authority/ssh.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,17 @@ func (a *Authority) SignSSHAddUser(key ssh.PublicKey, subject *ssh.Certificate)
656656
}
657657

658658
// CheckSSHHost checks the given principal has been registered before.
659-
func (a *Authority) CheckSSHHost(principal string) (bool, error) {
659+
func (a *Authority) CheckSSHHost(ctx context.Context, principal string, token string) (bool, error) {
660+
if a.sshCheckHostFunc != nil {
661+
exists, err := a.sshCheckHostFunc(ctx, principal, token, a.GetRootCertificates())
662+
if err != nil {
663+
return false, &apiError{
664+
err: errors.Wrap(err, "checkSSHHost: error from injected checkSSHHost func"),
665+
code: http.StatusInternalServerError,
666+
}
667+
}
668+
return exists, nil
669+
}
660670
exists, err := a.db.IsSSHHost(principal)
661671
if err != nil {
662672
if err == db.ErrNotImplemented {

ca/client.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,11 +952,12 @@ retry:
952952

953953
// SSHCheckHost performs the POST /ssh/check-host request to the CA with the
954954
// given principal.
955-
func (c *Client) SSHCheckHost(principal string) (*api.SSHCheckPrincipalResponse, error) {
955+
func (c *Client) SSHCheckHost(principal string, token string) (*api.SSHCheckPrincipalResponse, error) {
956956
var retried bool
957957
body, err := json.Marshal(&api.SSHCheckPrincipalRequest{
958958
Type: provisioner.SSHHostCert,
959959
Principal: principal,
960+
Token: token,
960961
})
961962
if err != nil {
962963
return nil, errors.Wrap(err, "error marshaling request")

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ require (
1818
gopkg.in/square/go-jose.v2 v2.4.0
1919
)
2020

21-
// replace github.com/smallstep/cli => ../cli
21+
//replace github.com/smallstep/cli => ../cli

0 commit comments

Comments
 (0)