aboutsummaryrefslogtreecommitdiff
path: root/ssh/server.go
diff options
context:
space:
mode:
authorNicola Murino <nicola.murino@gmail.com>2024-12-15 20:02:38 +0100
committerNicola Murino <nicola.murino@gmail.com>2025-09-27 12:43:41 -0700
commit2beaa59a3c994e5d01b6d58dc348dcd6d814ef26 (patch)
treea6ca9948e1e9a7dd335bb182059a0a21c8518105 /ssh/server.go
parent66c3d8ce714c31eb5a8adb6c931b4e29f5bebcf5 (diff)
downloadgo-x-crypto-2beaa59a3c994e5d01b6d58dc348dcd6d814ef26.tar.xz
ssh: add VerifiedPublicKeyCallback
Fixes golang/go#70795 Change-Id: I9b7c91f35f89495d1e9b5f6ec0c036c02a61d774 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/636335 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Junyang Shao <shaojunyang@google.com> Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu> Reviewed-by: Filippo Valsorda <filippo@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Jorge Hernández <jorgehcrda39@gmail.com>
Diffstat (limited to 'ssh/server.go')
-rw-r--r--ssh/server.go27
1 files changed, 27 insertions, 0 deletions
diff --git a/ssh/server.go b/ssh/server.go
index f06c08c..064dcba 100644
--- a/ssh/server.go
+++ b/ssh/server.go
@@ -44,6 +44,9 @@ type Permissions struct {
// pass data from the authentication callbacks to the server
// application layer.
Extensions map[string]string
+
+ // ExtraData allows to store user defined data.
+ ExtraData map[any]any
}
type GSSAPIWithMICConfig struct {
@@ -127,6 +130,21 @@ type ServerConfig struct {
// Permissions.Extensions entry.
PublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)
+ // VerifiedPublicKeyCallback, if non-nil, is called after a client
+ // successfully confirms having control over a key that was previously
+ // approved by PublicKeyCallback. The permissions object passed to the
+ // callback is the one returned by PublicKeyCallback for the given public
+ // key and its ownership is transferred to the callback. The returned
+ // Permissions object can be the same object, optionally modified, or a
+ // completely new object. If VerifiedPublicKeyCallback is non-nil,
+ // PublicKeyCallback is not allowed to return a PartialSuccessError, which
+ // can instead be returned by VerifiedPublicKeyCallback.
+ //
+ // VerifiedPublicKeyCallback does not affect which authentication methods
+ // are included in the list of methods that can be attempted by the client.
+ VerifiedPublicKeyCallback func(conn ConnMetadata, key PublicKey, permissions *Permissions,
+ signatureAlgorithm string) (*Permissions, error)
+
// KeyboardInteractiveCallback, if non-nil, is called when
// keyboard-interactive authentication is selected (RFC
// 4256). The client object's Challenge function should be
@@ -653,6 +671,9 @@ userAuthLoop:
candidate.pubKeyData = pubKeyData
candidate.perms, candidate.result = authConfig.PublicKeyCallback(s, pubKey)
_, isPartialSuccessError := candidate.result.(*PartialSuccessError)
+ if isPartialSuccessError && config.VerifiedPublicKeyCallback != nil {
+ return nil, errors.New("ssh: invalid library usage: PublicKeyCallback must not return partial success when VerifiedPublicKeyCallback is defined")
+ }
if (candidate.result == nil || isPartialSuccessError) &&
candidate.perms != nil &&
@@ -723,6 +744,12 @@ userAuthLoop:
authErr = candidate.result
perms = candidate.perms
+ if authErr == nil && config.VerifiedPublicKeyCallback != nil {
+ // Only call VerifiedPublicKeyCallback after the key has been accepted
+ // and successfully verified. If authErr is non-nil, the key is not
+ // considered verified and the callback must not run.
+ perms, authErr = config.VerifiedPublicKeyCallback(s, pubKey, perms, algo)
+ }
}
case "gssapi-with-mic":
if authConfig.GSSAPIWithMICConfig == nil {