@ -254,7 +254,7 @@ func (c *conn) vlogf(format string, args ...any) {
// isAuthorized walks through the action chain and returns nil if the connection
// isAuthorized walks through the action chain and returns nil if the connection
// is authorized. If the connection is not authorized, it returns
// is authorized. If the connection is not authorized, it returns
// gossh.E rrDenied. If the action chain resolution fails, it returns the
// e rrDenied. If the action chain resolution fails, it returns the
// resolution error.
// resolution error.
func ( c * conn ) isAuthorized ( ctx ssh . Context ) error {
func ( c * conn ) isAuthorized ( ctx ssh . Context ) error {
action := c . currentAction
action := c . currentAction
@ -266,7 +266,7 @@ func (c *conn) isAuthorized(ctx ssh.Context) error {
return nil
return nil
}
}
if action . Reject || action . HoldAndDelegate == "" {
if action . Reject || action . HoldAndDelegate == "" {
return gossh. E rrDenied
return e rrDenied
}
}
var err error
var err error
action , err = c . resolveNextAction ( ctx )
action , err = c . resolveNextAction ( ctx )
@ -281,6 +281,10 @@ func (c *conn) isAuthorized(ctx ssh.Context) error {
}
}
}
}
// errDenied is returned by auth callbacks when a connection is denied by the
// policy.
var errDenied = errors . New ( "ssh: access denied" )
// errPubKeyRequired is returned by NoClientAuthCallback to make the client
// errPubKeyRequired is returned by NoClientAuthCallback to make the client
// resort to public-key auth; not user visible.
// resort to public-key auth; not user visible.
var errPubKeyRequired = errors . New ( "ssh publickey required" )
var errPubKeyRequired = errors . New ( "ssh publickey required" )
@ -293,7 +297,7 @@ var errPubKeyRequired = errors.New("ssh publickey required")
// starting it afresh). It returns an error if the policy evaluation fails, or
// starting it afresh). It returns an error if the policy evaluation fails, or
// if the decision is "reject"
// if the decision is "reject"
//
//
// It either returns nil (accept) or errPubKeyRequired or gossh.E rrDenied
// It either returns nil (accept) or errPubKeyRequired or e rrDenied
// (reject). The errors may be wrapped.
// (reject). The errors may be wrapped.
func ( c * conn ) NoClientAuthCallback ( ctx ssh . Context ) error {
func ( c * conn ) NoClientAuthCallback ( ctx ssh . Context ) error {
if c . insecureSkipTailscaleAuth {
if c . insecureSkipTailscaleAuth {
@ -360,18 +364,18 @@ func (c *conn) PublicKeyHandler(ctx ssh.Context, pubKey ssh.PublicKey) error {
// pubKey. It returns nil if the matching policy action is Accept or
// pubKey. It returns nil if the matching policy action is Accept or
// HoldAndDelegate. If pubKey is nil, there was no policy match but there is a
// HoldAndDelegate. If pubKey is nil, there was no policy match but there is a
// policy that might match a public key it returns errPubKeyRequired. Otherwise,
// policy that might match a public key it returns errPubKeyRequired. Otherwise,
// it returns gossh.E rrDenied.
// it returns e rrDenied.
func ( c * conn ) doPolicyAuth ( ctx ssh . Context , pubKey ssh . PublicKey ) error {
func ( c * conn ) doPolicyAuth ( ctx ssh . Context , pubKey ssh . PublicKey ) error {
if err := c . setInfo ( ctx ) ; err != nil {
if err := c . setInfo ( ctx ) ; err != nil {
c . logf ( "failed to get conninfo: %v" , err )
c . logf ( "failed to get conninfo: %v" , err )
return gossh. E rrDenied
return e rrDenied
}
}
a , localUser , err := c . evaluatePolicy ( pubKey )
a , localUser , err := c . evaluatePolicy ( pubKey )
if err != nil {
if err != nil {
if pubKey == nil && c . havePubKeyPolicy ( ) {
if pubKey == nil && c . havePubKeyPolicy ( ) {
return errPubKeyRequired
return errPubKeyRequired
}
}
return fmt . Errorf ( "%w: %v" , gossh. E rrDenied, err )
return fmt . Errorf ( "%w: %v" , e rrDenied, err )
}
}
c . action0 = a
c . action0 = a
c . currentAction = a
c . currentAction = a
@ -402,10 +406,10 @@ func (c *conn) doPolicyAuth(ctx ssh.Context, pubKey ssh.PublicKey) error {
}
}
if a . Reject {
if a . Reject {
c . finalAction = a
c . finalAction = a
return gossh. E rrDenied
return e rrDenied
}
}
// Shouldn't get here, but:
// Shouldn't get here, but:
return gossh. E rrDenied
return e rrDenied
}
}
// ServerConfig implements ssh.ServerConfigCallback.
// ServerConfig implements ssh.ServerConfigCallback.
@ -423,7 +427,7 @@ func (srv *server) newConn() (*conn, error) {
// Stop accepting new connections.
// Stop accepting new connections.
// Connections in the auth phase are handled in handleConnPostSSHAuth.
// Connections in the auth phase are handled in handleConnPostSSHAuth.
// Existing sessions are terminated by Shutdown.
// Existing sessions are terminated by Shutdown.
return nil , gossh. E rrDenied
return nil , e rrDenied
}
}
srv . mu . Unlock ( )
srv . mu . Unlock ( )
c := & conn { srv : srv }
c := & conn { srv : srv }