OLD | NEW |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package ssh | 5 package ssh |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "crypto/rand" | 9 "crypto/rand" |
10 "encoding/binary" | 10 "encoding/binary" |
11 "errors" | 11 "errors" |
12 "fmt" | |
13 "io" | 12 "io" |
14 "net" | 13 "net" |
15 "sync" | 14 "sync" |
16 | 15 |
17 _ "crypto/sha1" | 16 _ "crypto/sha1" |
18 ) | 17 ) |
19 | 18 |
20 type ServerConfig struct { | 19 type ServerConfig struct { |
21 hostKeys []Signer | 20 hostKeys []Signer |
22 | 21 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 type cachedPubKey struct { | 89 type cachedPubKey struct { |
91 user, algo string | 90 user, algo string |
92 pubKey []byte | 91 pubKey []byte |
93 result bool | 92 result bool |
94 } | 93 } |
95 | 94 |
96 const maxCachedPubKeys = 16 | 95 const maxCachedPubKeys = 16 |
97 | 96 |
98 // A ServerConn represents an incoming connection. | 97 // A ServerConn represents an incoming connection. |
99 type ServerConn struct { | 98 type ServerConn struct { |
100 » transport *transport | 99 » transport *handshakeTransport |
101 config *ServerConfig | 100 config *ServerConfig |
| 101 sshConn |
102 | 102 |
103 channels map[uint32]*serverChan | 103 channels map[uint32]*serverChan |
104 nextChanId uint32 | 104 nextChanId uint32 |
105 | 105 |
106 // lock protects err and channels. | 106 // lock protects err and channels. |
107 lock sync.Mutex | 107 lock sync.Mutex |
108 err error | 108 err error |
109 | 109 |
110 // cachedPubKeys contains the cache results of tests for public keys. | 110 // cachedPubKeys contains the cache results of tests for public keys. |
111 // Since SSH clients will query whether a public key is acceptable | 111 // Since SSH clients will query whether a public key is acceptable |
(...skipping 11 matching lines...) Expand all Loading... |
123 ClientVersion []byte | 123 ClientVersion []byte |
124 | 124 |
125 // Our version. | 125 // Our version. |
126 serverVersion []byte | 126 serverVersion []byte |
127 } | 127 } |
128 | 128 |
129 // Server returns a new SSH server connection | 129 // Server returns a new SSH server connection |
130 // using c as the underlying transport. | 130 // using c as the underlying transport. |
131 func Server(c net.Conn, config *ServerConfig) *ServerConn { | 131 func Server(c net.Conn, config *ServerConfig) *ServerConn { |
132 return &ServerConn{ | 132 return &ServerConn{ |
133 » » transport: newTransport(c, config.rand(), false /* not client */
), | 133 » » sshConn: sshConn{c, c}, |
134 » » channels: make(map[uint32]*serverChan), | 134 » » channels: make(map[uint32]*serverChan), |
135 » » config: config, | 135 » » config: config, |
136 } | 136 } |
137 } | 137 } |
138 | 138 |
139 // signAndMarshal signs the data with the appropriate algorithm, | 139 // signAndMarshal signs the data with the appropriate algorithm, |
140 // and serializes the result in SSH wire format. | 140 // and serializes the result in SSH wire format. |
141 func signAndMarshal(k Signer, rand io.Reader, data []byte) ([]byte, error) { | 141 func signAndMarshal(k Signer, rand io.Reader, data []byte) ([]byte, error) { |
142 sig, err := k.Sign(rand, data) | 142 sig, err := k.Sign(rand, data) |
143 if err != nil { | 143 if err != nil { |
144 return nil, err | 144 return nil, err |
145 } | 145 } |
146 | 146 |
147 return serializeSignature(k.PublicKey().PrivateKeyAlgo(), sig), nil | 147 return serializeSignature(k.PublicKey().PrivateKeyAlgo(), sig), nil |
148 } | 148 } |
149 | 149 |
150 // Close closes the connection. | |
151 func (s *ServerConn) Close() error { return s.transport.Close() } | |
152 | |
153 // LocalAddr returns the local network address. | |
154 func (c *ServerConn) LocalAddr() net.Addr { return c.transport.LocalAddr() } | |
155 | |
156 // RemoteAddr returns the remote network address. | |
157 func (c *ServerConn) RemoteAddr() net.Addr { return c.transport.RemoteAddr() } | |
158 | |
159 // Handshake performs an SSH transport and client authentication on the given Se
rverConn. | 150 // Handshake performs an SSH transport and client authentication on the given Se
rverConn. |
160 func (s *ServerConn) Handshake() error { | 151 func (s *ServerConn) Handshake() error { |
161 var err error | 152 var err error |
162 s.serverVersion = []byte(packageVersion) | 153 s.serverVersion = []byte(packageVersion) |
163 » s.ClientVersion, err = exchangeVersions(s.transport.Conn, s.serverVersio
n) | 154 » s.ClientVersion, err = exchangeVersions(s.sshConn.conn, s.serverVersion) |
164 if err != nil { | 155 if err != nil { |
165 return err | 156 return err |
166 } | 157 } |
167 » if err := s.clientInitHandshake(nil, nil); err != nil { | 158 |
| 159 » tr := newTransport(s.sshConn.conn, s.config.rand(), false /* not client
*/) |
| 160 » s.transport = newServerTransport(tr, s.ClientVersion, s.serverVersion, s
.config) |
| 161 |
| 162 » if err := s.transport.requestKeyChange(); err != nil { |
168 return err | 163 return err |
169 } | 164 } |
170 | 165 |
| 166 if packet, err := s.transport.readPacket(); err != nil { |
| 167 return err |
| 168 } else if packet[0] != msgNewKeys { |
| 169 return UnexpectedMessageError{msgNewKeys, packet[0]} |
| 170 } |
| 171 |
171 var packet []byte | 172 var packet []byte |
172 if packet, err = s.transport.readPacket(); err != nil { | 173 if packet, err = s.transport.readPacket(); err != nil { |
173 return err | 174 return err |
174 } | 175 } |
| 176 |
175 var serviceRequest serviceRequestMsg | 177 var serviceRequest serviceRequestMsg |
176 » if err := unmarshal(&serviceRequest, packet, msgServiceRequest); err !=
nil { | 178 » if err = unmarshal(&serviceRequest, packet, msgServiceRequest); err != n
il { |
177 return err | 179 return err |
178 } | 180 } |
179 if serviceRequest.Service != serviceUserAuth { | 181 if serviceRequest.Service != serviceUserAuth { |
180 return errors.New("ssh: requested service '" + serviceRequest.Se
rvice + "' before authenticating") | 182 return errors.New("ssh: requested service '" + serviceRequest.Se
rvice + "' before authenticating") |
181 } | 183 } |
182 serviceAccept := serviceAcceptMsg{ | 184 serviceAccept := serviceAcceptMsg{ |
183 Service: serviceUserAuth, | 185 Service: serviceUserAuth, |
184 } | 186 } |
185 if err := s.transport.writePacket(marshal(msgServiceAccept, serviceAccep
t)); err != nil { | 187 if err := s.transport.writePacket(marshal(msgServiceAccept, serviceAccep
t)); err != nil { |
186 return err | 188 return err |
187 } | 189 } |
188 | 190 |
189 if err := s.authenticate(); err != nil { | 191 if err := s.authenticate(); err != nil { |
190 return err | 192 return err |
191 } | 193 } |
192 return err | 194 return err |
193 } | 195 } |
194 | 196 |
195 func (s *ServerConn) clientInitHandshake(clientKexInit *kexInitMsg, clientKexIni
tPacket []byte) (err error) { | |
196 serverKexInit := kexInitMsg{ | |
197 KexAlgos: s.config.Crypto.kexes(), | |
198 CiphersClientServer: s.config.Crypto.ciphers(), | |
199 CiphersServerClient: s.config.Crypto.ciphers(), | |
200 MACsClientServer: s.config.Crypto.macs(), | |
201 MACsServerClient: s.config.Crypto.macs(), | |
202 CompressionClientServer: supportedCompressions, | |
203 CompressionServerClient: supportedCompressions, | |
204 } | |
205 for _, k := range s.config.hostKeys { | |
206 serverKexInit.ServerHostKeyAlgos = append( | |
207 serverKexInit.ServerHostKeyAlgos, k.PublicKey().PublicKe
yAlgo()) | |
208 } | |
209 | |
210 serverKexInitPacket := marshal(msgKexInit, serverKexInit) | |
211 if err = s.transport.writePacket(serverKexInitPacket); err != nil { | |
212 return | |
213 } | |
214 | |
215 if clientKexInitPacket == nil { | |
216 clientKexInit = new(kexInitMsg) | |
217 if clientKexInitPacket, err = s.transport.readPacket(); err != n
il { | |
218 return | |
219 } | |
220 if err = unmarshal(clientKexInit, clientKexInitPacket, msgKexIni
t); err != nil { | |
221 return | |
222 } | |
223 } | |
224 | |
225 algs := findAgreedAlgorithms(clientKexInit, &serverKexInit) | |
226 if algs == nil { | |
227 return errors.New("ssh: no common algorithms") | |
228 } | |
229 | |
230 if clientKexInit.FirstKexFollows && algs.kex != clientKexInit.KexAlgos[0
] { | |
231 // The client sent a Kex message for the wrong algorithm, | |
232 // which we have to ignore. | |
233 if _, err = s.transport.readPacket(); err != nil { | |
234 return | |
235 } | |
236 } | |
237 | |
238 var hostKey Signer | |
239 for _, k := range s.config.hostKeys { | |
240 if algs.hostKey == k.PublicKey().PublicKeyAlgo() { | |
241 hostKey = k | |
242 } | |
243 } | |
244 | |
245 kex, ok := kexAlgoMap[algs.kex] | |
246 if !ok { | |
247 return fmt.Errorf("ssh: unexpected key exchange algorithm %v", a
lgs.kex) | |
248 } | |
249 | |
250 magics := handshakeMagics{ | |
251 serverVersion: s.serverVersion, | |
252 clientVersion: s.ClientVersion, | |
253 serverKexInit: marshal(msgKexInit, serverKexInit), | |
254 clientKexInit: clientKexInitPacket, | |
255 } | |
256 result, err := kex.Server(s.transport, s.config.rand(), &magics, hostKey
) | |
257 if err != nil { | |
258 return err | |
259 } | |
260 | |
261 if err = s.transport.prepareKeyChange(algs, result); err != nil { | |
262 return err | |
263 } | |
264 | |
265 if err = s.transport.writePacket([]byte{msgNewKeys}); err != nil { | |
266 return | |
267 } | |
268 if packet, err := s.transport.readPacket(); err != nil { | |
269 return err | |
270 } else if packet[0] != msgNewKeys { | |
271 return UnexpectedMessageError{msgNewKeys, packet[0]} | |
272 } | |
273 | |
274 return | |
275 } | |
276 | |
277 func isAcceptableAlgo(algo string) bool { | 197 func isAcceptableAlgo(algo string) bool { |
278 switch algo { | 198 switch algo { |
279 case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoEC
DSA521, | 199 case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoEC
DSA521, |
280 CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECD
SA384v01, CertAlgoECDSA521v01: | 200 CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECD
SA384v01, CertAlgoECDSA521v01: |
281 return true | 201 return true |
282 } | 202 } |
283 return false | 203 return false |
284 } | 204 } |
285 | 205 |
286 // testPubKey returns true if the given public key is acceptable for the user. | 206 // testPubKey returns true if the given public key is acceptable for the user. |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 return ParseError{msgUserAuthRequest} | 322 return ParseError{msgUserAuthRequest} |
403 } | 323 } |
404 // Ensure the public key algo and signature algo | 324 // Ensure the public key algo and signature algo |
405 // are supported. Compare the private key | 325 // are supported. Compare the private key |
406 // algorithm name that corresponds to algo with | 326 // algorithm name that corresponds to algo with |
407 // sig.Format. This is usually the same, but | 327 // sig.Format. This is usually the same, but |
408 // for certs, the names differ. | 328 // for certs, the names differ. |
409 if !isAcceptableAlgo(algo) || !isAcceptableAlgo(
sig.Format) || pubAlgoToPrivAlgo(algo) != sig.Format { | 329 if !isAcceptableAlgo(algo) || !isAcceptableAlgo(
sig.Format) || pubAlgoToPrivAlgo(algo) != sig.Format { |
410 break | 330 break |
411 } | 331 } |
412 » » » » signedData := buildDataSignedForAuth(s.transport
.sessionID, userAuthReq, algoBytes, pubKey) | 332 » » » » signedData := buildDataSignedForAuth(s.transport
.getSessionID(), userAuthReq, algoBytes, pubKey) |
413 key, _, ok := ParsePublicKey(pubKey) | 333 key, _, ok := ParsePublicKey(pubKey) |
414 if !ok { | 334 if !ok { |
415 return ParseError{msgUserAuthRequest} | 335 return ParseError{msgUserAuthRequest} |
416 } | 336 } |
417 | 337 |
418 if !key.Verify(signedData, sig.Blob) { | 338 if !key.Verify(signedData, sig.Blob) { |
| 339 // TODO(hanwen): fix this |
| 340 // message. It's not a parse |
| 341 // error |
419 return ParseError{msgUserAuthRequest} | 342 return ParseError{msgUserAuthRequest} |
420 } | 343 } |
421 // TODO(jmpittman): Implement full validation fo
r certificates. | 344 // TODO(jmpittman): Implement full validation fo
r certificates. |
422 s.User = userAuthReq.User | 345 s.User = userAuthReq.User |
423 if s.testPubKey(userAuthReq.User, algo, pubKey)
{ | 346 if s.testPubKey(userAuthReq.User, algo, pubKey)
{ |
424 break userAuthLoop | 347 break userAuthLoop |
425 } | 348 } |
426 } | 349 } |
427 } | 350 } |
428 | 351 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 // in order to demultiplex messages to any resulting Channels. | 438 // in order to demultiplex messages to any resulting Channels. |
516 func (s *ServerConn) Accept() (Channel, error) { | 439 func (s *ServerConn) Accept() (Channel, error) { |
517 // TODO(dfc) s.lock is not held here so visibility of s.err is not guara
nteed. | 440 // TODO(dfc) s.lock is not held here so visibility of s.err is not guara
nteed. |
518 if s.err != nil { | 441 if s.err != nil { |
519 return nil, s.err | 442 return nil, s.err |
520 } | 443 } |
521 | 444 |
522 for { | 445 for { |
523 packet, err := s.transport.readPacket() | 446 packet, err := s.transport.readPacket() |
524 if err != nil { | 447 if err != nil { |
525 | |
526 s.lock.Lock() | 448 s.lock.Lock() |
527 s.err = err | 449 s.err = err |
528 s.lock.Unlock() | 450 s.lock.Unlock() |
529 | 451 |
530 // TODO(dfc) s.lock protects s.channels but isn't being
held here. | 452 // TODO(dfc) s.lock protects s.channels but isn't being
held here. |
531 for _, c := range s.channels { | 453 for _, c := range s.channels { |
532 c.setDead() | 454 c.setDead() |
533 c.handleData(nil) | 455 c.handleData(nil) |
534 } | 456 } |
535 | 457 |
536 return nil, err | 458 return nil, err |
537 } | 459 } |
538 | 460 |
539 switch packet[0] { | 461 switch packet[0] { |
| 462 case msgNewKeys: |
| 463 // Lower level changed keys. Do nothing. |
| 464 |
540 case msgChannelData: | 465 case msgChannelData: |
541 if len(packet) < 9 { | 466 if len(packet) < 9 { |
542 // malformed data packet | 467 // malformed data packet |
543 return nil, ParseError{msgChannelData} | 468 return nil, ParseError{msgChannelData} |
544 } | 469 } |
545 remoteId := binary.BigEndian.Uint32(packet[1:5]) | 470 remoteId := binary.BigEndian.Uint32(packet[1:5]) |
546 s.lock.Lock() | 471 s.lock.Lock() |
547 c, ok := s.channels[remoteId] | 472 c, ok := s.channels[remoteId] |
548 if !ok { | 473 if !ok { |
549 s.lock.Unlock() | 474 s.lock.Unlock() |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 c.handlePacket(msg) | 551 c.handlePacket(msg) |
627 s.lock.Unlock() | 552 s.lock.Unlock() |
628 | 553 |
629 case *globalRequestMsg: | 554 case *globalRequestMsg: |
630 if msg.WantReply { | 555 if msg.WantReply { |
631 if err := s.transport.writePacket([]byte
{msgRequestFailure}); err != nil { | 556 if err := s.transport.writePacket([]byte
{msgRequestFailure}); err != nil { |
632 return nil, err | 557 return nil, err |
633 } | 558 } |
634 } | 559 } |
635 | 560 |
636 case *kexInitMsg: | |
637 s.lock.Lock() | |
638 if err := s.clientInitHandshake(msg, packet); er
r != nil { | |
639 s.lock.Unlock() | |
640 return nil, err | |
641 } | |
642 s.lock.Unlock() | |
643 case *disconnectMsg: | 561 case *disconnectMsg: |
644 return nil, io.EOF | 562 return nil, io.EOF |
645 default: | 563 default: |
646 // Unknown message. Ignore. | 564 // Unknown message. Ignore. |
647 } | 565 } |
648 } | 566 } |
649 } | 567 } |
650 | 568 |
651 panic("unreachable") | 569 panic("unreachable") |
652 } | 570 } |
(...skipping 30 matching lines...) Expand all Loading... |
683 func Listen(network, addr string, config *ServerConfig) (*Listener, error) { | 601 func Listen(network, addr string, config *ServerConfig) (*Listener, error) { |
684 l, err := net.Listen(network, addr) | 602 l, err := net.Listen(network, addr) |
685 if err != nil { | 603 if err != nil { |
686 return nil, err | 604 return nil, err |
687 } | 605 } |
688 return &Listener{ | 606 return &Listener{ |
689 l, | 607 l, |
690 config, | 608 config, |
691 }, nil | 609 }, nil |
692 } | 610 } |
OLD | NEW |