github.com/devops-filetransfer/sshego@v7.0.4+incompatible/direct.go (about) 1 package sshego 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "net" 8 9 ssh "github.com/glycerine/sshego/xendor/github.com/glycerine/xcryptossh" 10 ) 11 12 // see also dev.justinjudd.org/justin/easyssh for examples 13 // of multiplexing ssh channels. 14 15 // channelOpenDirectMsg is the structure for RFC 4254 7.2. It can be 16 // used for "forwarded-tcpip" and "direct-tcpip" 17 type channelOpenDirectMsg struct { 18 Rhost string 19 Rport uint32 20 Lhost string 21 Lport uint32 22 } 23 24 const minus2_uint32 uint32 = 0xFFFFFFFE 25 const minus10_uint32 uint32 = 0xFFFFFFF6 26 27 // server side: handle channel type "direct-tcpip" - RFC 4254 7.2 28 // ca can be nil. 29 func handleDirectTcp(ctx context.Context, parentHalt *ssh.Halter, newChannel ssh.NewChannel, ca *ConnectionAlert) { 30 pp("handleDirectTcp called!") 31 32 p := &channelOpenDirectMsg{} 33 ssh.Unmarshal(newChannel.ExtraData(), p) 34 targetAddr := fmt.Sprintf("%s:%d", p.Rhost, p.Rport) 35 log.Printf("direct-tcpip got channelOpenDirectMsg request to destination %s", 36 targetAddr) 37 38 channel, req, err := newChannel.Accept() // (Channel, <-chan *Request, error) 39 panicOn(err) 40 go ssh.DiscardRequests(ctx, req, parentHalt) 41 42 go func(ch ssh.Channel, host string, port uint32) { 43 44 var targetConn net.Conn 45 var err error 46 addr := fmt.Sprintf("%s:%d", p.Rhost, p.Rport) 47 switch port { 48 case minus2_uint32: 49 // unix domain request 50 //pp("direct.go has unix domain forwarding request") 51 targetConn, err = net.Dial("unix", host) 52 case 1: 53 //pp("direct.go has port 1 forwarding request. ca = %#v", ca) 54 if ca != nil && ca.PortOne != nil { 55 //pp("handleDirectTcp sees a port one request with a live ca.PortOne") 56 select { 57 case ca.PortOne <- ch: 58 case <-ca.ShutDown: 59 } 60 return 61 } 62 panic("wat?") 63 fallthrough 64 default: 65 targetConn, err = net.Dial("tcp", targetAddr) 66 } 67 if err != nil { 68 log.Printf("sshd direct.go could not forward connection to addr: '%s'", addr) 69 return 70 } 71 log.Printf("sshd direct.go forwarding direct connection to addr: '%s'", addr) 72 73 sp := newShovelPair(false) 74 parentHalt.AddDownstream(sp.Halt) 75 sp.Start(targetConn, ch, "targetBehindSshd<-fromDirectClient", "fromDirectClient<-targetBehindSshd") 76 }(channel, p.Rhost, p.Rport) 77 } 78 79 // client side 80 func dialDirect(ctx context.Context, c *ssh.Client, laddr string, lport int, raddr string, rport int, parentHalt *ssh.Halter) (ssh.Channel, error) { 81 msg := channelOpenDirectMsg{ 82 Rhost: raddr, 83 Rport: uint32(rport), 84 Lhost: laddr, 85 Lport: uint32(lport), 86 } 87 ch, in, err := c.OpenChannel(ctx, "direct-tcpip", ssh.Marshal(&msg), parentHalt) 88 if err != nil { 89 return nil, err 90 } 91 go ssh.DiscardRequests(ctx, in, nil) 92 return ch, err 93 }