Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(567)

Delta Between Two Patch Sets: ssh/client.go

Issue 12837048: code review 12837048: crypto/ssh: ssh-agent forwarding support
Left Patch Set: diff -r 1e7a3e301825 https://code.google.com/p/go.crypto Created 10 years, 7 months ago
Right Patch Set: diff -r 1e7a3e301825 https://code.google.com/p/go.crypto Created 10 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | ssh/session.go » ('j') | ssh/session.go » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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 "crypto" 8 "crypto"
9 "crypto/rand" 9 "crypto/rand"
10 "encoding/binary" 10 "encoding/binary"
(...skipping 20 matching lines...) Expand all
31 dialAddress string 31 dialAddress string
32 32
33 serverVersion string 33 serverVersion string
34 } 34 }
35 35
36 type globalRequest struct { 36 type globalRequest struct {
37 sync.Mutex 37 sync.Mutex
38 response chan interface{} 38 response chan interface{}
39 } 39 }
40 40
41 // AgentConnector connects to the proper ssh-agent 41 // AgentDialer connects to the proper ssh-agent
jpsugar 2013/08/26 19:13:34 Un-wrap this comment now? Lines seem a little shor
42 // for key forwarding 42 // for key forwarding.
43 type AgentConnector interface { 43 type AgentDialer interface {
44 » Connect() (io.ReadWriteCloser, error) 44 » Dial() (io.ReadWriteCloser, error)
45 } 45 }
46 46
47 // Client returns a new SSH client connection using c as the underlying transpor t. 47 // Client returns a new SSH client connection using c as the underlying transpor t.
48 func Client(c net.Conn, config *ClientConfig) (*ClientConn, error) { 48 func Client(c net.Conn, config *ClientConfig) (*ClientConn, error) {
49 return clientWithAddress(c, "", config) 49 return clientWithAddress(c, "", config)
50 } 50 }
51 51
52 func clientWithAddress(c net.Conn, addr string, config *ClientConfig) (*ClientCo nn, error) { 52 func clientWithAddress(c net.Conn, addr string, config *ClientConfig) (*ClientCo nn, error) {
53 conn := &ClientConn{ 53 conn := &ClientConn{
54 transport: newTransport(c, config.rand()), 54 transport: newTransport(c, config.rand()),
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 marshalInt(K, kInt) 209 marshalInt(K, kInt)
210 h.Write(K) 210 h.Write(K)
211 211
212 H := h.Sum(nil) 212 H := h.Sum(nil)
213 213
214 return H, K, nil 214 return H, K, nil
215 } 215 }
216 216
217 // Run a very simple proxy back to the ssh-agent when 217 // Run a very simple proxy back to the ssh-agent when
218 // the server has requested an auth channel (and the client 218 // the server has requested an auth channel (and the client
219 // has enabled proxying 219 // has enabled proxying).
220 func (c *ClientConn) agentForward(agentSock io.ReadWriteCloser, ch *clientChan) { 220 func (c *ClientConn) agentForward(agentSock io.ReadWriteCloser, ch *clientChan) {
221 » // Server -> Agent 221 » // Server -> Agent.
222 » go io.Copy(agentSock, ch.stdout) 222 » go func() {
223 » // Agent -> Server 223 » » defer agentSock.Close()
224 » go io.Copy(ch.stdin, agentSock) 224 » » io.Copy(agentSock, ch.stdout)
225 » }()
226 » // Agent -> Server.
227 » go func() {
228 » » defer ch.stdin.Close()
229 » » io.Copy(ch.stdin, agentSock)
230 » }()
225 } 231 }
226 232
227 // mainLoop reads incoming messages and routes channel messages 233 // mainLoop reads incoming messages and routes channel messages
228 // to their respective ClientChans. 234 // to their respective ClientChans.
229 func (c *ClientConn) mainLoop() { 235 func (c *ClientConn) mainLoop() {
230 defer func() { 236 defer func() {
231 c.Close() 237 c.Close()
232 c.chanList.closeAll() 238 c.chanList.closeAll()
233 c.forwardList.closeAll() 239 c.forwardList.closeAll()
234 }() 240 }()
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 MyId: ch.localId, 414 MyId: ch.localId,
409 MyWindow: 1 << 14, 415 MyWindow: 1 << 14,
410 416
411 // As per RFC 4253 6.1, 32k is also the minimum. 417 // As per RFC 4253 6.1, 32k is also the minimum.
412 MaxPacketSize: 1 << 15, 418 MaxPacketSize: 1 << 15,
413 } 419 }
414 420
415 c.writePacket(marshal(msgChannelOpenConfirm, m)) 421 c.writePacket(marshal(msgChannelOpenConfirm, m))
416 l <- forward{ch, raddr} 422 l <- forward{ch, raddr}
417 case "auth-agent@openssh.com": 423 case "auth-agent@openssh.com":
418 » » if c.config.ForwardingAgentConnector != nil { 424 » » if c.config.ForwardingAgentDialer == nil {
419 » » » agentConn, err := c.config.ForwardingAgentConnector.Conn ect()
420 » » » if err != nil {
421 » » » » c.sendConnectionFailed(msg.PeersId)
422 » » » } else {
423 » » » » ch := c.newChan(c.transport)
424 » » » » ch.remoteId = msg.PeersId
425 » » » » ch.remoteWin.add(msg.PeersWindow)
jpsugar 2013/08/23 18:50:37 This needs to be moved down. If the window is open
jamwt 2013/08/23 19:17:46 I see what you're saying, but I copied the pattern
jpsugar 2013/08/23 19:53:54 No, because there cannot be any data sent on the f
426 » » » » ch.maxPacket = msg.MaxPacketSize
427 » » » » c.agentForward(agentConn, ch)
428
429 » » » » m := channelOpenConfirmMsg{
430 » » » » » PeersId: ch.remoteId,
431 » » » » » MyId: ch.localId,
432 » » » » » MyWindow: 1 << 14,
433
434 » » » » » // As per RFC 4253 6.1, 32k is also the minimum.
435 » » » » » MaxPacketSize: 1 << 15,
436 » » » » }
437
438 » » » » c.writePacket(marshal(msgChannelOpenConfirm, m))
439 » » » }
440 » » } else {
441 // Client did not ask for key forwarding! 425 // Client did not ask for key forwarding!
442 c.sendUnknownChannel(msg.PeersId) 426 c.sendUnknownChannel(msg.PeersId)
443 » » } 427 » » » return
428 » » }
429 » » agentConn, err := c.config.ForwardingAgentDialer.Dial()
430 » » if err != nil {
431 » » » c.sendConnectionFailed(msg.PeersId)
432 » » » return
433 » » }
434 » » ch := c.newChan(c.transport)
435 » » ch.remoteId = msg.PeersId
436 » » ch.remoteWin.add(msg.PeersWindow)
437 » » ch.maxPacket = msg.MaxPacketSize
438
439 » » m := channelOpenConfirmMsg{
440 » » » PeersId: ch.remoteId,
441 » » » MyId: ch.localId,
442 » » » MyWindow: 1 << 14,
443
444 » » » // As per RFC 4253 6.1, 32k is also the minimum.
445 » » » MaxPacketSize: 1 << 15,
446 » » }
447
448 » » c.writePacket(marshal(msgChannelOpenConfirm, m))
449 » » c.agentForward(agentConn, ch)
444 default: 450 default:
445 // unknown channel type 451 // unknown channel type
446 c.sendUnknownChannel(msg.PeersId) 452 c.sendUnknownChannel(msg.PeersId)
447 } 453 }
448 } 454 }
449 455
450 // sendGlobalRequest sends a global request message as specified 456 // sendGlobalRequest sends a global request message as specified
451 // in RFC4254 section 4. To correctly synchronise messages, a lock 457 // in RFC4254 section 4. To correctly synchronise messages, a lock
452 // is held internally until a response is returned. 458 // is held internally until a response is returned.
453 func (c *ClientConn) sendGlobalRequest(m interface{}) (*globalRequestSuccessMsg, error) { 459 func (c *ClientConn) sendGlobalRequest(m interface{}) (*globalRequestSuccessMsg, error) {
(...skipping 15 matching lines...) Expand all
469 m := channelOpenFailureMsg{ 475 m := channelOpenFailureMsg{
470 PeersId: remoteId, 476 PeersId: remoteId,
471 Reason: ConnectionFailed, 477 Reason: ConnectionFailed,
472 Message: "invalid request", 478 Message: "invalid request",
473 Language: "en_US.UTF-8", 479 Language: "en_US.UTF-8",
474 } 480 }
475 return c.writePacket(marshal(msgChannelOpenFailure, m)) 481 return c.writePacket(marshal(msgChannelOpenFailure, m))
476 } 482 }
477 483
478 // sendUnknownChannel rejects an incoming channel identified 484 // sendUnknownChannel rejects an incoming channel identified
479 // by remoteId on the basis of invalid or unrecognized type 485 // by remoteId on the basis of invalid or unrecognized type.
480 func (c *ClientConn) sendUnknownChannel(remoteId uint32) error { 486 func (c *ClientConn) sendUnknownChannel(remoteId uint32) error {
481 m := channelOpenFailureMsg{ 487 m := channelOpenFailureMsg{
482 PeersId: remoteId, 488 PeersId: remoteId,
483 Reason: UnknownChannelType, 489 Reason: UnknownChannelType,
484 Message: "unknown or invalid channel type", 490 Message: "unknown or invalid channel type",
485 Language: "en_US.UTF-8", 491 Language: "en_US.UTF-8",
486 } 492 }
487 return c.writePacket(marshal(msgChannelOpenFailure, m)) 493 return c.writePacket(marshal(msgChannelOpenFailure, m))
488 } 494 }
489 495
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 Auth []ClientAuth 538 Auth []ClientAuth
533 539
534 // HostKeyChecker, if not nil, is called during the cryptographic 540 // HostKeyChecker, if not nil, is called during the cryptographic
535 // handshake to validate the server's host key. A nil HostKeyChecker 541 // handshake to validate the server's host key. A nil HostKeyChecker
536 // implies that all host keys are accepted. 542 // implies that all host keys are accepted.
537 HostKeyChecker HostKeyChecker 543 HostKeyChecker HostKeyChecker
538 544
539 // Cryptographic-related configuration. 545 // Cryptographic-related configuration.
540 Crypto CryptoConfig 546 Crypto CryptoConfig
541 547
542 » // Connector to the local ssh-agent for key forwarding. 548 » // Dialer to the local ssh-agent for key forwarding.
543 » // If nil, no key forwarding will take place 549 » // If nil, no key forwarding will take place.
544 » // See `man ssh_config` on "ForwardAgent" for security implications 550 » // See `man ssh_config` on "ForwardAgent" for security implications.
545 » ForwardingAgentConnector AgentConnector 551 » ForwardingAgentDialer AgentDialer
546 } 552 }
547 553
548 func (c *ClientConfig) rand() io.Reader { 554 func (c *ClientConfig) rand() io.Reader {
549 if c.Rand == nil { 555 if c.Rand == nil {
550 return rand.Reader 556 return rand.Reader
551 } 557 }
552 return c.Rand 558 return c.Rand
553 } 559 }
554 560
555 // Thread safe channel list. 561 // Thread safe channel list.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 defer c.Unlock() 605 defer c.Unlock()
600 606
601 for _, ch := range c.chans { 607 for _, ch := range c.chans {
602 if ch == nil { 608 if ch == nil {
603 continue 609 continue
604 } 610 }
605 ch.Close() 611 ch.Close()
606 close(ch.msg) 612 close(ch.msg)
607 } 613 }
608 } 614 }
LEFTRIGHT
« no previous file | ssh/session.go » ('j') | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b