ソースを参照

go.crypto/ssh: add User to ServerConn and pass *ServerConn to callbacks.

R=golang-dev, dave, agl
CC=golang-dev
https://golang.org/cl/5577070
Daniel Theophanes 14 年 前
コミット
2b43ac23a9
3 ファイル変更14 行追加7 行削除
  1. 2 2
      ssh/client_auth_test.go
  2. 11 4
      ssh/server.go
  3. 1 1
      ssh/session_test.go

+ 2 - 2
ssh/client_auth_test.go

@@ -119,10 +119,10 @@ var (
 	clientKeychain = new(keychain)
 	clientKeychain = new(keychain)
 	clientPassword = password("tiger")
 	clientPassword = password("tiger")
 	serverConfig   = &ServerConfig{
 	serverConfig   = &ServerConfig{
-		PasswordCallback: func(user, pass string) bool {
+		PasswordCallback: func(conn *ServerConn, user, pass string) bool {
 			return user == "testuser" && pass == string(clientPassword)
 			return user == "testuser" && pass == string(clientPassword)
 		},
 		},
-		PublicKeyCallback: func(user, algo string, pubkey []byte) bool {
+		PublicKeyCallback: func(conn *ServerConn, user, algo string, pubkey []byte) bool {
 			key := clientKeychain.keys[0].(*rsa.PrivateKey).PublicKey
 			key := clientKeychain.keys[0].(*rsa.PrivateKey).PublicKey
 			expected := []byte(serializePublickey(key))
 			expected := []byte(serializePublickey(key))
 			algoname := algoName(key)
 			algoname := algoName(key)

+ 11 - 4
ssh/server.go

@@ -34,12 +34,12 @@ type ServerConfig struct {
 	// PasswordCallback, if non-nil, is called when a user attempts to
 	// PasswordCallback, if non-nil, is called when a user attempts to
 	// authenticate using a password. It may be called concurrently from
 	// authenticate using a password. It may be called concurrently from
 	// several goroutines.
 	// several goroutines.
-	PasswordCallback func(user, password string) bool
+	PasswordCallback func(conn *ServerConn, user, password string) bool
 
 
 	// PublicKeyCallback, if non-nil, is called when a client attempts public
 	// PublicKeyCallback, if non-nil, is called when a client attempts public
 	// key authentication. It must return true iff the given public key is
 	// key authentication. It must return true iff the given public key is
 	// valid for the given user.
 	// valid for the given user.
-	PublicKeyCallback func(user, algo string, pubkey []byte) bool
+	PublicKeyCallback func(conn *ServerConn, user, algo string, pubkey []byte) bool
 
 
 	// Cryptographic-related configuration.
 	// Cryptographic-related configuration.
 	Crypto CryptoConfig
 	Crypto CryptoConfig
@@ -150,6 +150,11 @@ type ServerConn struct {
 	// before attempting to authenticate with it, we end up with duplicate
 	// before attempting to authenticate with it, we end up with duplicate
 	// queries for public key validity.
 	// queries for public key validity.
 	cachedPubKeys []cachedPubKey
 	cachedPubKeys []cachedPubKey
+
+	// User holds the successfully authenticated user name.
+	// It is empty if no authentication is used.  It is populated before
+	// any authentication callback is called and not assigned to after that.
+	User string
 }
 }
 
 
 // Server returns a new SSH server connection
 // Server returns a new SSH server connection
@@ -369,7 +374,7 @@ func (s *ServerConn) testPubKey(user, algo string, pubKey []byte) bool {
 		}
 		}
 	}
 	}
 
 
-	result := s.config.PublicKeyCallback(user, algo, pubKey)
+	result := s.config.PublicKeyCallback(s, user, algo, pubKey)
 	if len(s.cachedPubKeys) < maxCachedPubKeys {
 	if len(s.cachedPubKeys) < maxCachedPubKeys {
 		c := cachedPubKey{
 		c := cachedPubKey{
 			user:   user,
 			user:   user,
@@ -421,7 +426,8 @@ userAuthLoop:
 				return ParseError{msgUserAuthRequest}
 				return ParseError{msgUserAuthRequest}
 			}
 			}
 
 
-			if s.config.PasswordCallback(userAuthReq.User, string(password)) {
+			s.User = userAuthReq.User
+			if s.config.PasswordCallback(s, userAuthReq.User, string(password)) {
 				break userAuthLoop
 				break userAuthLoop
 			}
 			}
 		case "publickey":
 		case "publickey":
@@ -489,6 +495,7 @@ userAuthLoop:
 				default:
 				default:
 					return errors.New("ssh: isAcceptableAlgo incorrect")
 					return errors.New("ssh: isAcceptableAlgo incorrect")
 				}
 				}
+				s.User = userAuthReq.User
 				if s.testPubKey(userAuthReq.User, algo, pubKey) {
 				if s.testPubKey(userAuthReq.User, algo, pubKey) {
 					break userAuthLoop
 					break userAuthLoop
 				}
 				}

+ 1 - 1
ssh/session_test.go

@@ -18,7 +18,7 @@ type serverType func(*channel)
 // dial constructs a new test server and returns a *ClientConn.
 // dial constructs a new test server and returns a *ClientConn.
 func dial(handler serverType, t *testing.T) *ClientConn {
 func dial(handler serverType, t *testing.T) *ClientConn {
 	pw := password("tiger")
 	pw := password("tiger")
-	serverConfig.PasswordCallback = func(user, pass string) bool {
+	serverConfig.PasswordCallback = func(conn *ServerConn, user, pass string) bool {
 		return user == "testuser" && pass == string(pw)
 		return user == "testuser" && pass == string(pw)
 	}
 	}
 	serverConfig.PublicKeyCallback = nil
 	serverConfig.PublicKeyCallback = nil