1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
21 type ServerConfig struct {
25 // Rand provides the source of entropy for key exchange. If Rand is
26 // nil, the cryptographic random reader in package crypto/rand will
30 // NoClientAuth is true if clients are allowed to connect without
34 // PasswordCallback, if non-nil, is called when a user attempts to
35 // authenticate using a password. It may be called concurrently from
36 // several goroutines.
37 PasswordCallback func(user, password string) bool
39 // PubKeyCallback, if non-nil, is called when a client attempts public
40 // key authentication. It must return true iff the given public key is
41 // valid for the given user.
42 PubKeyCallback func(user, algo string, pubkey []byte) bool
44 // Cryptographic-related configuration.
48 func (c *ServerConfig) rand() io.Reader {
55 // SetRSAPrivateKey sets the private key for a Server. A Server must have a
56 // private key configured in order to accept connections. The private key must
57 // be in the form of a PEM encoded, PKCS#1, RSA private key. The file "id_rsa"
58 // typically contains such a key.
59 func (s *ServerConfig) SetRSAPrivateKey(pemBytes []byte) error {
60 block, _ := pem.Decode(pemBytes)
62 return errors.New("ssh: no key found")
65 s.rsa, err = x509.ParsePKCS1PrivateKey(block.Bytes)
70 s.rsaSerialized = marshalRSA(s.rsa)
74 // marshalRSA serializes an RSA private key according to RFC 4256, section 6.6.
75 func marshalRSA(priv *rsa.PrivateKey) []byte {
76 e := new(big.Int).SetInt64(int64(priv.E))
77 length := stringLength([]byte(hostAlgoRSA))
78 length += intLength(e)
79 length += intLength(priv.N)
81 ret := make([]byte, length)
82 r := marshalString(ret, []byte(hostAlgoRSA))
84 r = marshalInt(r, priv.N)
89 // parseRSA parses an RSA key according to RFC 4256, section 6.6.
90 func parseRSA(in []byte) (pubKey *rsa.PublicKey, ok bool) {
91 algo, in, ok := parseString(in)
92 if !ok || string(algo) != hostAlgoRSA {
95 bigE, in, ok := parseInt(in)
96 if !ok || bigE.BitLen() > 24 {
100 if e < 3 || e&1 == 0 {
103 N, in, ok := parseInt(in)
104 if !ok || len(in) > 0 {
107 return &rsa.PublicKey{
113 func parseRSASig(in []byte) (sig []byte, ok bool) {
114 algo, in, ok := parseString(in)
115 if !ok || string(algo) != hostAlgoRSA {
118 sig, in, ok = parseString(in)
125 // cachedPubKey contains the results of querying whether a public key is
126 // acceptable for a user. The cache only applies to a single ServerConn.
127 type cachedPubKey struct {
133 const maxCachedPubKeys = 16
135 // A ServerConn represents an incomming connection.
136 type ServerConn struct {
140 channels map[uint32]*channel
143 // lock protects err and also allows Channels to serialise their writes
148 // cachedPubKeys contains the cache results of tests for public keys.
149 // Since SSH clients will query whether a public key is acceptable
150 // before attempting to authenticate with it, we end up with duplicate
151 // queries for public key validity.
152 cachedPubKeys []cachedPubKey
155 // Server returns a new SSH server connection
156 // using c as the underlying transport.
157 func Server(c net.Conn, config *ServerConfig) *ServerConn {
159 transport: newTransport(c, config.rand()),
160 channels: make(map[uint32]*channel),
166 // kexDH performs Diffie-Hellman key agreement on a ServerConnection. The
167 // returned values are given the same names as in RFC 4253, section 8.
168 func (s *ServerConn) kexDH(group *dhGroup, hashFunc crypto.Hash, magics *handshakeMagics, hostKeyAlgo string) (H, K []byte, err error) {
169 packet, err := s.readPacket()
173 var kexDHInit kexDHInitMsg
174 if err = unmarshal(&kexDHInit, packet, msgKexDHInit); err != nil {
178 if kexDHInit.X.Sign() == 0 || kexDHInit.X.Cmp(group.p) >= 0 {
179 return nil, nil, errors.New("client DH parameter out of bounds")
182 y, err := rand.Int(s.config.rand(), group.p)
187 Y := new(big.Int).Exp(group.g, y, group.p)
188 kInt := new(big.Int).Exp(kexDHInit.X, y, group.p)
190 var serializedHostKey []byte
193 serializedHostKey = s.config.rsaSerialized
195 return nil, nil, errors.New("internal error")
199 writeString(h, magics.clientVersion)
200 writeString(h, magics.serverVersion)
201 writeString(h, magics.clientKexInit)
202 writeString(h, magics.serverKexInit)
203 writeString(h, serializedHostKey)
204 writeInt(h, kexDHInit.X)
206 K = make([]byte, intLength(kInt))
219 sig, err = rsa.SignPKCS1v15(s.config.rand(), s.config.rsa, hashFunc, hh)
224 return nil, nil, errors.New("internal error")
227 serializedSig := serializeSignature(hostAlgoRSA, sig)
229 kexDHReply := kexDHReplyMsg{
230 HostKey: serializedHostKey,
232 Signature: serializedSig,
234 packet = marshal(msgKexDHReply, kexDHReply)
236 err = s.writePacket(packet)
240 // serverVersion is the fixed identification string that Server will use.
241 var serverVersion = []byte("SSH-2.0-Go\r\n")
243 // Handshake performs an SSH transport and client authentication on the given ServerConn.
244 func (s *ServerConn) Handshake() error {
245 var magics handshakeMagics
246 if _, err := s.Write(serverVersion); err != nil {
249 if err := s.Flush(); err != nil {
252 magics.serverVersion = serverVersion[:len(serverVersion)-2]
254 version, err := readVersion(s)
258 magics.clientVersion = version
260 serverKexInit := kexInitMsg{
261 KexAlgos: supportedKexAlgos,
262 ServerHostKeyAlgos: supportedHostKeyAlgos,
263 CiphersClientServer: s.config.Crypto.ciphers(),
264 CiphersServerClient: s.config.Crypto.ciphers(),
265 MACsClientServer: supportedMACs,
266 MACsServerClient: supportedMACs,
267 CompressionClientServer: supportedCompressions,
268 CompressionServerClient: supportedCompressions,
270 kexInitPacket := marshal(msgKexInit, serverKexInit)
271 magics.serverKexInit = kexInitPacket
273 if err := s.writePacket(kexInitPacket); err != nil {
277 packet, err := s.readPacket()
282 magics.clientKexInit = packet
284 var clientKexInit kexInitMsg
285 if err = unmarshal(&clientKexInit, packet, msgKexInit); err != nil {
289 kexAlgo, hostKeyAlgo, ok := findAgreedAlgorithms(s.transport, &clientKexInit, &serverKexInit)
291 return errors.New("ssh: no common algorithms")
294 if clientKexInit.FirstKexFollows && kexAlgo != clientKexInit.KexAlgos[0] {
295 // The client sent a Kex message for the wrong algorithm,
296 // which we have to ignore.
297 if _, err := s.readPacket(); err != nil {
303 var hashFunc crypto.Hash
305 case kexAlgoDH14SHA1:
306 hashFunc = crypto.SHA1
307 dhGroup14Once.Do(initDHGroup14)
308 H, K, err = s.kexDH(dhGroup14, hashFunc, &magics, hostKeyAlgo)
310 err = errors.New("ssh: unexpected key exchange algorithm " + kexAlgo)
316 if err = s.writePacket([]byte{msgNewKeys}); err != nil {
319 if err = s.transport.writer.setupKeys(serverKeys, K, H, H, hashFunc); err != nil {
322 if packet, err = s.readPacket(); err != nil {
326 if packet[0] != msgNewKeys {
327 return UnexpectedMessageError{msgNewKeys, packet[0]}
329 if err = s.transport.reader.setupKeys(clientKeys, K, H, H, hashFunc); err != nil {
332 if packet, err = s.readPacket(); err != nil {
336 var serviceRequest serviceRequestMsg
337 if err = unmarshal(&serviceRequest, packet, msgServiceRequest); err != nil {
340 if serviceRequest.Service != serviceUserAuth {
341 return errors.New("ssh: requested service '" + serviceRequest.Service + "' before authenticating")
343 serviceAccept := serviceAcceptMsg{
344 Service: serviceUserAuth,
346 if err = s.writePacket(marshal(msgServiceAccept, serviceAccept)); err != nil {
350 if err = s.authenticate(H); err != nil {
356 func isAcceptableAlgo(algo string) bool {
357 return algo == hostAlgoRSA
360 // testPubKey returns true if the given public key is acceptable for the user.
361 func (s *ServerConn) testPubKey(user, algo string, pubKey []byte) bool {
362 if s.config.PubKeyCallback == nil || !isAcceptableAlgo(algo) {
366 for _, c := range s.cachedPubKeys {
367 if c.user == user && c.algo == algo && bytes.Equal(c.pubKey, pubKey) {
372 result := s.config.PubKeyCallback(user, algo, pubKey)
373 if len(s.cachedPubKeys) < maxCachedPubKeys {
377 pubKey: make([]byte, len(pubKey)),
380 copy(c.pubKey, pubKey)
381 s.cachedPubKeys = append(s.cachedPubKeys, c)
387 func (s *ServerConn) authenticate(H []byte) error {
388 var userAuthReq userAuthRequestMsg
394 if packet, err = s.readPacket(); err != nil {
397 if err = unmarshal(&userAuthReq, packet, msgUserAuthRequest); err != nil {
401 if userAuthReq.Service != serviceSSH {
402 return errors.New("ssh: client attempted to negotiate for unknown service: " + userAuthReq.Service)
405 switch userAuthReq.Method {
407 if s.config.NoClientAuth {
411 if s.config.PasswordCallback == nil {
414 payload := userAuthReq.Payload
415 if len(payload) < 1 || payload[0] != 0 {
416 return ParseError{msgUserAuthRequest}
418 payload = payload[1:]
419 password, payload, ok := parseString(payload)
420 if !ok || len(payload) > 0 {
421 return ParseError{msgUserAuthRequest}
424 if s.config.PasswordCallback(userAuthReq.User, string(password)) {
428 if s.config.PubKeyCallback == nil {
431 payload := userAuthReq.Payload
432 if len(payload) < 1 {
433 return ParseError{msgUserAuthRequest}
435 isQuery := payload[0] == 0
436 payload = payload[1:]
437 algoBytes, payload, ok := parseString(payload)
439 return ParseError{msgUserAuthRequest}
441 algo := string(algoBytes)
443 pubKey, payload, ok := parseString(payload)
445 return ParseError{msgUserAuthRequest}
448 // The client can query if the given public key
450 if len(payload) > 0 {
451 return ParseError{msgUserAuthRequest}
453 if s.testPubKey(userAuthReq.User, algo, pubKey) {
454 okMsg := userAuthPubKeyOkMsg{
456 PubKey: string(pubKey),
458 if err = s.writePacket(marshal(msgUserAuthPubKeyOk, okMsg)); err != nil {
461 continue userAuthLoop
464 sig, payload, ok := parseString(payload)
465 if !ok || len(payload) > 0 {
466 return ParseError{msgUserAuthRequest}
468 if !isAcceptableAlgo(algo) {
471 rsaSig, ok := parseRSASig(sig)
473 return ParseError{msgUserAuthRequest}
475 signedData := buildDataSignedForAuth(H, userAuthReq, algoBytes, pubKey)
478 hashFunc := crypto.SHA1
482 rsaKey, ok := parseRSA(pubKey)
484 return ParseError{msgUserAuthRequest}
486 if rsa.VerifyPKCS1v15(rsaKey, hashFunc, digest, rsaSig) != nil {
487 return ParseError{msgUserAuthRequest}
490 return errors.New("ssh: isAcceptableAlgo incorrect")
492 if s.testPubKey(userAuthReq.User, algo, pubKey) {
498 var failureMsg userAuthFailureMsg
499 if s.config.PasswordCallback != nil {
500 failureMsg.Methods = append(failureMsg.Methods, "password")
502 if s.config.PubKeyCallback != nil {
503 failureMsg.Methods = append(failureMsg.Methods, "publickey")
506 if len(failureMsg.Methods) == 0 {
507 return errors.New("ssh: no authentication methods configured but NoClientAuth is also false")
510 if err = s.writePacket(marshal(msgUserAuthFailure, failureMsg)); err != nil {
515 packet = []byte{msgUserAuthSuccess}
516 if err = s.writePacket(packet); err != nil {
523 const defaultWindowSize = 32768
525 // Accept reads and processes messages on a ServerConn. It must be called
526 // in order to demultiplex messages to any resulting Channels.
527 func (s *ServerConn) Accept() (Channel, error) {
533 packet, err := s.readPacket()
540 for _, c := range s.channels {
551 // malformed data packet
552 return nil, ParseError{msgChannelData}
554 peersId := uint32(packet[1])<<24 | uint32(packet[2])<<16 | uint32(packet[3])<<8 | uint32(packet[4])
556 c, ok := s.channels[peersId]
561 if length := int(packet[5])<<24 | int(packet[6])<<16 | int(packet[7])<<8 | int(packet[8]); length > 0 {
563 c.handleData(packet[:length])
567 switch msg := decode(packet).(type) {
568 case *channelOpenMsg:
570 c.chanType = msg.ChanType
571 c.theirId = msg.PeersId
572 c.theirWindow = msg.PeersWindow
573 c.maxPacketSize = msg.MaxPacketSize
574 c.extraData = msg.TypeSpecificData
575 c.myWindow = defaultWindowSize
577 c.cond = sync.NewCond(&c.lock)
578 c.pendingData = make([]byte, c.myWindow)
581 c.myId = s.nextChanId
583 s.channels[c.myId] = c
587 case *channelRequestMsg:
589 c, ok := s.channels[msg.PeersId]
599 c, ok := s.channels[msg.PeersId]
607 case *channelCloseMsg:
609 c, ok := s.channels[msg.PeersId]
617 case *globalRequestMsg:
619 if err := s.writePacket([]byte{msgRequestFailure}); err != nil {
624 case UnexpectedMessageError:
629 // Unknown message. Ignore.
637 // A Listener implements a network listener (net.Listener) for SSH connections.
638 type Listener struct {
639 listener net.Listener
643 // Accept waits for and returns the next incoming SSH connection.
644 // The receiver should call Handshake() in another goroutine
645 // to avoid blocking the accepter.
646 func (l *Listener) Accept() (*ServerConn, error) {
647 c, err := l.listener.Accept()
651 conn := Server(c, l.config)
655 // Addr returns the listener's network address.
656 func (l *Listener) Addr() net.Addr {
657 return l.listener.Addr()
660 // Close closes the listener.
661 func (l *Listener) Close() error {
662 return l.listener.Close()
665 // Listen creates an SSH listener accepting connections on
666 // the given network address using net.Listen.
667 func Listen(network, addr string, config *ServerConfig) (*Listener, error) {
668 l, err := net.Listen(network, addr)