fix remap user failed when banner enabled
This commit is contained in:
parent
feaf4b6ec0
commit
49170a50f8
7 changed files with 171 additions and 71 deletions
2
Gopkg.lock
generated
2
Gopkg.lock
generated
|
|
@ -25,7 +25,7 @@
|
|||
"ssh",
|
||||
"ssh/testdata"
|
||||
]
|
||||
revision = "d47aa888633435f7d7af47a9b39ab3788b387f0c"
|
||||
revision = "c832b236b4049eae471365acd18bc0b462a64a2b"
|
||||
source = "https://github.com/tg123/sshpiper.crypto"
|
||||
|
||||
[solve-meta]
|
||||
|
|
|
|||
7
vendor/golang.org/x/crypto/openpgp/keys.go
generated
vendored
7
vendor/golang.org/x/crypto/openpgp/keys.go
generated
vendored
|
|
@ -486,7 +486,7 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err
|
|||
}
|
||||
isPrimaryId := true
|
||||
e.Identities[uid.Id] = &Identity{
|
||||
Name: uid.Name,
|
||||
Name: uid.Id,
|
||||
UserId: uid,
|
||||
SelfSignature: &packet.Signature{
|
||||
CreationTime: currentTime,
|
||||
|
|
@ -507,6 +507,11 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err
|
|||
e.Identities[uid.Id].SelfSignature.PreferredHash = []uint8{hashToHashId(config.DefaultHash)}
|
||||
}
|
||||
|
||||
// Likewise for DefaultCipher.
|
||||
if config != nil && config.DefaultCipher != 0 {
|
||||
e.Identities[uid.Id].SelfSignature.PreferredSymmetric = []uint8{uint8(config.DefaultCipher)}
|
||||
}
|
||||
|
||||
e.Subkeys = make([]Subkey, 1)
|
||||
e.Subkeys[0] = Subkey{
|
||||
PublicKey: packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey),
|
||||
|
|
|
|||
50
vendor/golang.org/x/crypto/openpgp/keys_test.go
generated
vendored
50
vendor/golang.org/x/crypto/openpgp/keys_test.go
generated
vendored
|
|
@ -320,6 +320,56 @@ func TestNewEntityWithoutPreferredHash(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNewEntityCorrectName(t *testing.T) {
|
||||
entity, err := NewEntity("Golang Gopher", "Test Key", "no-reply@golang.com", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(entity.Identities) != 1 {
|
||||
t.Fatalf("len(entity.Identities) = %d, want 1", len(entity.Identities))
|
||||
}
|
||||
var got string
|
||||
for _, i := range entity.Identities {
|
||||
got = i.Name
|
||||
}
|
||||
want := "Golang Gopher (Test Key) <no-reply@golang.com>"
|
||||
if got != want {
|
||||
t.Fatalf("Identity.Name = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewEntityWithPreferredSymmetric(t *testing.T) {
|
||||
c := &packet.Config{
|
||||
DefaultCipher: packet.CipherAES256,
|
||||
}
|
||||
entity, err := NewEntity("Golang Gopher", "Test Key", "no-reply@golang.com", c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, identity := range entity.Identities {
|
||||
if len(identity.SelfSignature.PreferredSymmetric) == 0 {
|
||||
t.Fatal("didn't find a preferred cipher in self signature")
|
||||
}
|
||||
if identity.SelfSignature.PreferredSymmetric[0] != uint8(c.DefaultCipher) {
|
||||
t.Fatalf("Expected preferred cipher to be %d, got %d", uint8(c.DefaultCipher), identity.SelfSignature.PreferredSymmetric[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewEntityWithoutPreferredSymmetric(t *testing.T) {
|
||||
entity, err := NewEntity("Golang Gopher", "Test Key", "no-reply@golang.com", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, identity := range entity.Identities {
|
||||
if len(identity.SelfSignature.PreferredSymmetric) != 0 {
|
||||
t.Fatalf("Expected preferred cipher to be empty but got length %d", len(identity.SelfSignature.PreferredSymmetric))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const expiringKeyHex = "988d0451d1ec5d010400ba3385721f2dc3f4ab096b2ee867ab77213f0a27a8538441c35d2fa225b08798a1439a66a5150e6bdc3f40f5d28d588c712394c632b6299f77db8c0d48d37903fb72ebd794d61be6aa774688839e5fdecfe06b2684cc115d240c98c66cb1ef22ae84e3aa0c2b0c28665c1e7d4d044e7f270706193f5223c8d44e0d70b7b8da830011010001b40f4578706972792074657374206b657988be041301020028050251d1ec5d021b03050900278d00060b090807030206150802090a0b0416020301021e01021780000a091072589ad75e237d8c033503fd10506d72837834eb7f994117740723adc39227104b0d326a1161871c0b415d25b4aedef946ca77ea4c05af9c22b32cf98be86ab890111fced1ee3f75e87b7cc3c00dc63bbc85dfab91c0dc2ad9de2c4d13a34659333a85c6acc1a669c5e1d6cecb0cf1e56c10e72d855ae177ddc9e766f9b2dda57ccbb75f57156438bbdb4e42b88d0451d1ec5d0104009c64906559866c5cb61578f5846a94fcee142a489c9b41e67b12bb54cfe86eb9bc8566460f9a720cb00d6526fbccfd4f552071a8e3f7744b1882d01036d811ee5a3fb91a1c568055758f43ba5d2c6a9676b012f3a1a89e47bbf624f1ad571b208f3cc6224eb378f1645dd3d47584463f9eadeacfd1ce6f813064fbfdcc4b5a53001101000188a504180102000f021b0c050251d1f06b050900093e89000a091072589ad75e237d8c20e00400ab8310a41461425b37889c4da28129b5fae6084fafbc0a47dd1adc74a264c6e9c9cc125f40462ee1433072a58384daef88c961c390ed06426a81b464a53194c4e291ddd7e2e2ba3efced01537d713bd111f48437bde2363446200995e8e0d4e528dda377fd1e8f8ede9c8e2198b393bd86852ce7457a7e3daf74d510461a5b77b88d0451d1ece8010400b3a519f83ab0010307e83bca895170acce8964a044190a2b368892f7a244758d9fc193482648acb1fb9780d28cc22d171931f38bb40279389fc9bf2110876d4f3db4fcfb13f22f7083877fe56592b3b65251312c36f83ffcb6d313c6a17f197dd471f0712aad15a8537b435a92471ba2e5b0c72a6c72536c3b567c558d7b6051001101000188a504180102000f021b0c050251d1f07b050900279091000a091072589ad75e237d8ce69e03fe286026afacf7c97ee20673864d4459a2240b5655219950643c7dba0ac384b1d4359c67805b21d98211f7b09c2a0ccf6410c8c04d4ff4a51293725d8d6570d9d8bb0e10c07d22357caeb49626df99c180be02d77d1fe8ed25e7a54481237646083a9f89a11566cd20b9e995b1487c5f9e02aeb434f3a1897cd416dd0a87861838da3e9e"
|
||||
const subkeyUsageHex = "988d04533a52bc010400d26af43085558f65b9e7dbc90cb9238015259aed5e954637adcfa2181548b2d0b60c65f1f42ec5081cbf1bc0a8aa4900acfb77070837c58f26012fbce297d70afe96e759ad63531f0037538e70dbf8e384569b9720d99d8eb39d8d0a2947233ed242436cb6ac7dfe74123354b3d0119b5c235d3dd9c9d6c004f8ffaf67ad8583001101000188b7041f010200210502533b8552170c8001ce094aa433f7040bb2ddf0be3893cb843d0fe70c020700000a0910a42704b92866382aa98404009d63d916a27543da4221c60087c33f1c44bec9998c5438018ed370cca4962876c748e94b73eb39c58eb698063f3fd6346d58dd2a11c0247934c4a9d71f24754f7468f96fb24c3e791dd2392b62f626148ad724189498cbf993db2df7c0cdc2d677c35da0f16cb16c9ce7c33b4de65a4a91b1d21a130ae9cc26067718910ef8e2b417556d627261203c756d627261407379642e65642e61753e88b80413010200220502533a52bc021b03060b090807030206150802090a0b0416020301021e01021780000a0910a42704b92866382a47840400c0c2bd04f5fca586de408b395b3c280a278259c93eaaa8b79a53b97003f8ed502a8a00446dd9947fb462677e4fcac0dac2f0701847d15130aadb6cd9e0705ea0cf5f92f129136c7be21a718d46c8e641eb7f044f2adae573e11ae423a0a9ca51324f03a8a2f34b91fa40c3cc764bee4dccadedb54c768ba0469b683ea53f1c29b88d04533a52bc01040099c92a5d6f8b744224da27bc2369127c35269b58bec179de6bbc038f749344222f85a31933224f26b70243c4e4b2d242f0c4777eaef7b5502f9dad6d8bf3aaeb471210674b74de2d7078af497d55f5cdad97c7bedfbc1b41e8065a97c9c3d344b21fc81d27723af8e374bc595da26ea242dccb6ae497be26eea57e563ed517e90011010001889f0418010200090502533a52bc021b0c000a0910a42704b92866382afa1403ff70284c2de8a043ff51d8d29772602fa98009b7861c540535f874f2c230af8caf5638151a636b21f8255003997ccd29747fdd06777bb24f9593bd7d98a3e887689bf902f999915fcc94625ae487e5d13e6616f89090ebc4fdc7eb5cad8943e4056995bb61c6af37f8043016876a958ec7ebf39c43d20d53b7f546cfa83e8d2604b88d04533b8283010400c0b529316dbdf58b4c54461e7e669dc11c09eb7f73819f178ccd4177b9182b91d138605fcf1e463262fabefa73f94a52b5e15d1904635541c7ea540f07050ce0fb51b73e6f88644cec86e91107c957a114f69554548a85295d2b70bd0b203992f76eb5d493d86d9eabcaa7ef3fc7db7e458438db3fcdb0ca1cc97c638439a9170011010001889f0418010200090502533b8283021b0c000a0910a42704b92866382adc6d0400cfff6258485a21675adb7a811c3e19ebca18851533f75a7ba317950b9997fda8d1a4c8c76505c08c04b6c2cc31dc704d33da36a21273f2b388a1a706f7c3378b66d887197a525936ed9a69acb57fe7f718133da85ec742001c5d1864e9c6c8ea1b94f1c3759cebfd93b18606066c063a63be86085b7e37bdbc65f9a915bf084bb901a204533b85cd110400aed3d2c52af2b38b5b67904b0ef73d6dd7aef86adb770e2b153cd22489654dcc91730892087bb9856ae2d9f7ed1eb48f214243fe86bfe87b349ebd7c30e630e49c07b21fdabf78b7a95c8b7f969e97e3d33f2e074c63552ba64a2ded7badc05ce0ea2be6d53485f6900c7860c7aa76560376ce963d7271b9b54638a4028b573f00a0d8854bfcdb04986141568046202192263b9b67350400aaa1049dbc7943141ef590a70dcb028d730371d92ea4863de715f7f0f16d168bd3dc266c2450457d46dcbbf0b071547e5fbee7700a820c3750b236335d8d5848adb3c0da010e998908dfd93d961480084f3aea20b247034f8988eccb5546efaa35a92d0451df3aaf1aee5aa36a4c4d462c760ecd9cebcabfbe1412b1f21450f203fd126687cd486496e971a87fd9e1a8a765fe654baa219a6871ab97768596ab05c26c1aeea8f1a2c72395a58dbc12ef9640d2b95784e974a4d2d5a9b17c25fedacfe551bda52602de8f6d2e48443f5dd1a2a2a8e6a5e70ecdb88cd6e766ad9745c7ee91d78cc55c3d06536b49c3fee6c3d0b6ff0fb2bf13a314f57c953b8f4d93bf88e70418010200090502533b85cd021b0200520910a42704b92866382a47200419110200060502533b85cd000a091042ce2c64bc0ba99214b2009e26b26852c8b13b10c35768e40e78fbbb48bd084100a0c79d9ea0844fa5853dd3c85ff3ecae6f2c9dd6c557aa04008bbbc964cd65b9b8299d4ebf31f41cc7264b8cf33a00e82c5af022331fac79efc9563a822497ba012953cefe2629f1242fcdcb911dbb2315985bab060bfd58261ace3c654bdbbe2e8ed27a46e836490145c86dc7bae15c011f7e1ffc33730109b9338cd9f483e7cef3d2f396aab5bd80efb6646d7e778270ee99d934d187dd98"
|
||||
const revokedKeyHex = "988d045331ce82010400c4fdf7b40a5477f206e6ee278eaef888ca73bf9128a9eef9f2f1ddb8b7b71a4c07cfa241f028a04edb405e4d916c61d6beabc333813dc7b484d2b3c52ee233c6a79b1eea4e9cc51596ba9cd5ac5aeb9df62d86ea051055b79d03f8a4fa9f38386f5bd17529138f3325d46801514ea9047977e0829ed728e68636802796801be10011010001889f04200102000905025331d0e3021d03000a0910a401d9f09a34f7c042aa040086631196405b7e6af71026b88e98012eab44aa9849f6ef3fa930c7c9f23deaedba9db1538830f8652fb7648ec3fcade8dbcbf9eaf428e83c6cbcc272201bfe2fbb90d41963397a7c0637a1a9d9448ce695d9790db2dc95433ad7be19eb3de72dacf1d6db82c3644c13eae2a3d072b99bb341debba012c5ce4006a7d34a1f4b94b444526567205265766f6b657220283c52656727732022424d204261726973746122204b657920262530305c303e5c29203c72656740626d626172697374612e636f2e61753e88b704130102002205025331ce82021b03060b090807030206150802090a0b0416020301021e01021780000a0910a401d9f09a34f7c0019c03f75edfbeb6a73e7225ad3cc52724e2872e04260d7daf0d693c170d8c4b243b8767bc7785763533febc62ec2600c30603c433c095453ede59ff2fcabeb84ce32e0ed9d5cf15ffcbc816202b64370d4d77c1e9077d74e94a16fb4fa2e5bec23a56d7a73cf275f91691ae1801a976fcde09e981a2f6327ac27ea1fecf3185df0d56889c04100102000605025331cfb5000a0910fe9645554e8266b64b4303fc084075396674fb6f778d302ac07cef6bc0b5d07b66b2004c44aef711cbac79617ef06d836b4957522d8772dd94bf41a2f4ac8b1ee6d70c57503f837445a74765a076d07b829b8111fc2a918423ddb817ead7ca2a613ef0bfb9c6b3562aec6c3cf3c75ef3031d81d95f6563e4cdcc9960bcb386c5d757b104fcca5fe11fc709df884604101102000605025331cfe7000a09107b15a67f0b3ddc0317f6009e360beea58f29c1d963a22b962b80788c3fa6c84e009d148cfde6b351469b8eae91187eff07ad9d08fcaab88d045331ce820104009f25e20a42b904f3fa555530fe5c46737cf7bd076c35a2a0d22b11f7e0b61a69320b768f4a80fe13980ce380d1cfc4a0cd8fbe2d2e2ef85416668b77208baa65bf973fe8e500e78cc310d7c8705cdb34328bf80e24f0385fce5845c33bc7943cf6b11b02348a23da0bf6428e57c05135f2dc6bd7c1ce325d666d5a5fd2fd5e410011010001889f04180102000905025331ce82021b0c000a0910a401d9f09a34f7c0418003fe34feafcbeaef348a800a0d908a7a6809cc7304017d820f70f0474d5e23cb17e38b67dc6dca282c6ca00961f4ec9edf2738d0f087b1d81e4871ef08e1798010863afb4eac4c44a376cb343be929c5be66a78cfd4456ae9ec6a99d97f4e1c3ff3583351db2147a65c0acef5c003fb544ab3a2e2dc4d43646f58b811a6c3a369d1f"
|
||||
|
|
|
|||
4
vendor/golang.org/x/crypto/ssh/client_auth_test.go
generated
vendored
4
vendor/golang.org/x/crypto/ssh/client_auth_test.go
generated
vendored
|
|
@ -614,8 +614,8 @@ func TestClientAuthErrorList(t *testing.T) {
|
|||
for i, e := range authErrs.Errors {
|
||||
switch i {
|
||||
case 0:
|
||||
if e.Error() != "no auth passed yet" {
|
||||
t.Fatalf("errors: got %v, want no auth passed yet", e.Error())
|
||||
if _, ok := e.(*NoAuthError); !ok {
|
||||
t.Fatalf("errors: got error type %T, want NoAuthError", e)
|
||||
}
|
||||
case 1:
|
||||
if e != publicKeyErr {
|
||||
|
|
|
|||
10
vendor/golang.org/x/crypto/ssh/server.go
generated
vendored
10
vendor/golang.org/x/crypto/ssh/server.go
generated
vendored
|
|
@ -309,6 +309,14 @@ func (l ServerAuthError) Error() string {
|
|||
return "[" + strings.Join(errs, ", ") + "]"
|
||||
}
|
||||
|
||||
// NoAuthError is the unique error that is returned if no authentication method
|
||||
// has been passed yet
|
||||
type NoAuthError struct{}
|
||||
|
||||
func (e *NoAuthError) Error() string {
|
||||
return "no auth passed yet"
|
||||
}
|
||||
|
||||
func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) {
|
||||
sessionID := s.transport.getSessionID()
|
||||
var cache pubKeyCache
|
||||
|
|
@ -363,7 +371,7 @@ userAuthLoop:
|
|||
}
|
||||
|
||||
perms = nil
|
||||
authErr := errors.New("no auth passed yet")
|
||||
authErr := error(&NoAuthError{})
|
||||
|
||||
switch userAuthReq.Method {
|
||||
case "none":
|
||||
|
|
|
|||
162
vendor/golang.org/x/crypto/ssh/sshpiper.go
generated
vendored
162
vendor/golang.org/x/crypto/ssh/sshpiper.go
generated
vendored
|
|
@ -14,17 +14,38 @@ import (
|
|||
type AuthPipeType int
|
||||
|
||||
const (
|
||||
// Do nothing but pass auth message to upstream
|
||||
AuthPipeTypePassThrough AuthPipeType = iota
|
||||
|
||||
// Convert auth message to AuthMetod return by callback and pass it to upstream
|
||||
AuthPipeTypeMap
|
||||
|
||||
// Discard auth message, do not pass it to uptream
|
||||
AuthPipeTypeDiscard
|
||||
|
||||
// Convert auth message to NoneAuth and pass it to upstream
|
||||
AuthPipeTypeNone
|
||||
)
|
||||
|
||||
// SSHPiperAuthPipe:
|
||||
// Convert Auth
|
||||
// Any Auth to Password
|
||||
//
|
||||
// Any Auth to Public Key
|
||||
// SSHPiper will sign the auth packet message using the returned Signer.
|
||||
// This func might be called twice, one is for query message, the other
|
||||
// is real auth packet message.
|
||||
// If any error occurs during this period, a NoneAuth packet will be sent to
|
||||
// upstream ssh server instead.
|
||||
//
|
||||
// More info: https://github.com/tg123/sshpiper#publickey-sign-again
|
||||
type SSHPiperAuthPipe struct {
|
||||
// Username to upstream
|
||||
User string
|
||||
|
||||
PasswordCallback func(conn ConnMetadata, password []byte) (AuthPipeType, AuthMethod, error)
|
||||
|
||||
// PublicKeyCallback, if non-nil, is called when downstream requests a publickey auth.
|
||||
PublicKeyCallback func(conn ConnMetadata, key PublicKey) (AuthPipeType, AuthMethod, error)
|
||||
|
||||
// HostKeyCallback is called during the cryptographic
|
||||
|
|
@ -55,16 +76,12 @@ type SSHPiperConfig struct {
|
|||
// If any error occurs, the piped connection will be closed.
|
||||
FindUpstream func(conn ConnMetadata) (net.Conn, *SSHPiperAuthPipe, error)
|
||||
|
||||
// MapPublicKey, if non-nil, is called when downstream requests a publickey auth.
|
||||
// SSHPiper will sign the auth packet message using the returned Signer.
|
||||
// This func might be called twice, one is for query message, the other
|
||||
// is real auth packet message.
|
||||
// If any error occurs during this period, a NoneAuth packet will be sent to
|
||||
// upstream ssh server instead.
|
||||
//
|
||||
// More info: https://github.com/tg123/sshpiper#publickey-sign-again
|
||||
// MapPublicKey func(conn ConnMetadata, key PublicKey) (Signer, error)
|
||||
|
||||
// ServerVersion is the version identification string to announce in
|
||||
// the public handshake.
|
||||
// If empty, a reasonable default is used.
|
||||
// Note that RFC 4253 section 4.2 requires that this string start with
|
||||
// "SSH-2.0-".
|
||||
ServerVersion string
|
||||
}
|
||||
|
||||
type upstream struct{ *connection }
|
||||
|
|
@ -151,14 +168,10 @@ func NewSSHPiperConn(conn net.Conn, piper *SSHPiperConfig) (pipe *SSHPiperConn,
|
|||
return nil, errors.New("sshpiper: must specify FindUpstream")
|
||||
}
|
||||
|
||||
// TODO
|
||||
//if piper.UpstreamHostKeyCallback == nil {
|
||||
// return nil, errors.New("sshpiper: must specify UpstreamHostKeyCallback")
|
||||
//}
|
||||
|
||||
d, err := newDownstream(conn, &ServerConfig{
|
||||
Config: piper.Config,
|
||||
hostKeys: piper.hostKeys,
|
||||
Config: piper.Config,
|
||||
hostKeys: piper.hostKeys,
|
||||
ServerVersion: piper.ServerVersion,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -410,26 +423,26 @@ func (pipe *pipedConn) ack(key PublicKey) error {
|
|||
}
|
||||
|
||||
// not used after method to method map enable
|
||||
func (pipe *pipedConn) validAndAck(user string, upKey, downKey PublicKey) (*userAuthRequestMsg, error) {
|
||||
|
||||
ok, err := validateKey(upKey, user, pipe.upstream.transport)
|
||||
|
||||
if ok {
|
||||
|
||||
if err = pipe.ack(downKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return noneAuthMsg(user), nil
|
||||
}
|
||||
//func (pipe *pipedConn) validAndAck(user string, upKey, downKey PublicKey) (*userAuthRequestMsg, error) {
|
||||
//
|
||||
// ok, err := validateKey(upKey, user, pipe.upstream.transport)
|
||||
//
|
||||
// if ok {
|
||||
//
|
||||
// if err = pipe.ack(downKey); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// return nil, nil
|
||||
// }
|
||||
//
|
||||
// return noneAuthMsg(user), nil
|
||||
//}
|
||||
|
||||
func (pipe *pipedConn) checkPublicKey(msg *userAuthRequestMsg, pubkey PublicKey, sig *Signature) (bool, error) {
|
||||
|
||||
if !isAcceptableAlgo(sig.Format) {
|
||||
return false, nil
|
||||
return false, fmt.Errorf("ssh: algorithm %q not accepted", sig.Format)
|
||||
}
|
||||
signedData := buildDataSignedForAuth(pipe.downstream.transport.getSessionID(), *msg, []byte(pubkey.Type()), pubkey.Marshal())
|
||||
|
||||
|
|
@ -562,6 +575,41 @@ func (pipe *pipedConn) Close() {
|
|||
pipe.downstream.transport.Close()
|
||||
}
|
||||
|
||||
func (pipe *pipedConn) pipeAuthSkipBanner(packet []byte) (bool, error) {
|
||||
// pipe to auth succ if not a authreq
|
||||
// typically, authinfo see RFC 4256
|
||||
// TODO support hook this msg
|
||||
err := pipe.upstream.transport.writePacket(packet)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for {
|
||||
packet, err := pipe.upstream.transport.readPacket()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
msgType := packet[0]
|
||||
|
||||
if err = pipe.downstream.transport.writePacket(packet); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
switch msgType {
|
||||
case msgUserAuthSuccess:
|
||||
return true, nil
|
||||
case msgUserAuthBanner:
|
||||
// should read another packet from upstream
|
||||
continue
|
||||
case msgUserAuthFailure:
|
||||
default:
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (pipe *pipedConn) pipeAuth(initUserAuthMsg *userAuthRequestMsg) error {
|
||||
err := pipe.upstream.sendAuthReq()
|
||||
if err != nil {
|
||||
|
|
@ -580,61 +628,42 @@ func (pipe *pipedConn) pipeAuth(initUserAuthMsg *userAuthRequestMsg) error {
|
|||
|
||||
// nil for ignore
|
||||
if userAuthMsg != nil {
|
||||
err = pipe.upstream.transport.writePacket(Marshal(userAuthMsg))
|
||||
// send a mapped auth msg
|
||||
succ, err := pipe.pipeAuthSkipBanner(Marshal(userAuthMsg))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
packet, err := pipe.upstream.transport.readPacket()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
success := packet[0] == msgUserAuthSuccess || packet[0] == msgUserAuthBanner
|
||||
|
||||
if err = pipe.downstream.transport.writePacket(packet); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if success {
|
||||
if succ {
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var packet []byte
|
||||
|
||||
for {
|
||||
|
||||
// find next msg which need to be hooked
|
||||
if packet, err = pipe.downstream.transport.readPacket(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// we can only handle auth req at the moment
|
||||
if packet[0] == msgUserAuthRequest {
|
||||
// should hook, deal with it
|
||||
break
|
||||
}
|
||||
|
||||
// pipe to auth succ if not a authreq
|
||||
// typically, authinfo see RFC 4256
|
||||
// TODO support hook this msg
|
||||
err = pipe.upstream.transport.writePacket(packet)
|
||||
// pipe other auth msg
|
||||
succ, err := pipe.pipeAuthSkipBanner(packet)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO clean up dup code
|
||||
packet, err := pipe.upstream.transport.readPacket()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
success := packet[0] == msgUserAuthSuccess || packet[0] == msgUserAuthBanner
|
||||
|
||||
if err = pipe.downstream.transport.writePacket(packet); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if success {
|
||||
if succ {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
@ -646,7 +675,6 @@ func (pipe *pipedConn) pipeAuth(initUserAuthMsg *userAuthRequestMsg) error {
|
|||
}
|
||||
|
||||
userAuthMsg = &userAuthReq
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -756,7 +784,11 @@ func (s *connection) serverHandshakeNoAuth(config *ServerConfig) (*Permissions,
|
|||
}
|
||||
|
||||
var err error
|
||||
s.serverVersion = []byte("SSH-2.0-SSHPiper")
|
||||
if config.ServerVersion != "" {
|
||||
s.serverVersion = []byte(config.ServerVersion)
|
||||
} else {
|
||||
s.serverVersion = []byte("SSH-2.0-SSHPiper")
|
||||
}
|
||||
s.clientVersion, err = exchangeVersions(s.sshConn.conn, s.serverVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
7
vendor/golang.org/x/crypto/ssh/sshpiper_test.go
generated
vendored
7
vendor/golang.org/x/crypto/ssh/sshpiper_test.go
generated
vendored
|
|
@ -364,6 +364,7 @@ func TestPiperPasswordToMapPublicKey(t *testing.T) {
|
|||
func TestPiperServerWithBanner(t *testing.T) {
|
||||
|
||||
const username = "testuser"
|
||||
const mappedname = "mappedname"
|
||||
|
||||
var called bool
|
||||
|
||||
|
|
@ -375,15 +376,19 @@ func TestPiperServerWithBanner(t *testing.T) {
|
|||
|
||||
s, err := dialUpstream(simpleEchoHandler, &ServerConfig{
|
||||
PasswordCallback: func(conn ConnMetadata, password []byte) (*Permissions, error) {
|
||||
if mappedname != conn.User() {
|
||||
t.Errorf("username changed after banner")
|
||||
}
|
||||
called = true
|
||||
return nil, nil
|
||||
},
|
||||
BannerCallback: func(conn ConnMetadata) string {
|
||||
called = true
|
||||
return "banner"
|
||||
},
|
||||
}, t)
|
||||
|
||||
return s, &SSHPiperAuthPipe{
|
||||
User: mappedname,
|
||||
UpstreamHostKeyCallback: InsecureIgnoreHostKey(),
|
||||
}, err
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue