github.com/devops-filetransfer/sshego@v7.0.4+incompatible/cli_test.go (about) 1 package sshego 2 3 import ( 4 "context" 5 "fmt" 6 "net" 7 "strings" 8 "testing" 9 10 cv "github.com/glycerine/goconvey/convey" 11 ssh "github.com/glycerine/sshego/xendor/github.com/glycerine/xcryptossh" 12 ) 13 14 func Test201ClientDirectSSH(t *testing.T) { 15 16 cv.Convey("Used as a library, sshego should allow a client to establish a tcp forwarded TCP connection throught the SSHd without opening a listening port (that is exposed to other users' processes) on the local host", t, func() { 17 18 // what is the Go client interface to an TCP connection? 19 // the net.Conn that is returned by conn, err := net.Dial("tcp", "localhost:tcpSrvPort") 20 21 // start a simple TCP server that is the target of the forward through the sshd, 22 // so we can confirm the client has made the connection. 23 24 // generate a random payload for the client to send to the server. 25 payloadByteCount := 50 26 confirmationPayload := RandomString(payloadByteCount) 27 confirmationReply := RandomString(payloadByteCount) 28 29 serverDone := ssh.NewHalter() 30 31 tcpSrvLsn, tcpSrvPort := GetAvailPort() 32 33 StartBackgroundTestTcpServer( 34 serverDone, 35 payloadByteCount, 36 confirmationPayload, 37 confirmationReply, 38 tcpSrvLsn, nil) 39 40 s := MakeTestSshClientAndServer(true) 41 defer TempDirCleanup(s.SrvCfg.Origdir, s.SrvCfg.Tempdir) 42 43 dest := fmt.Sprintf("127.0.0.1:%v", tcpSrvPort) 44 45 // below over SSH should be equivalent of the following 46 // non-encrypted ping/pong. 47 48 if false { 49 UnencPingPong(dest, confirmationPayload, confirmationReply, payloadByteCount) 50 } 51 if true { 52 dc := DialConfig{ 53 ClientKnownHostsPath: s.CliCfg.ClientKnownHostsPath, 54 Mylogin: s.Mylogin, 55 RsaPath: s.RsaPath, 56 TotpUrl: s.Totp, 57 Pw: s.Pw, 58 Sshdhost: s.SrvCfg.EmbeddedSSHd.Host, 59 Sshdport: s.SrvCfg.EmbeddedSSHd.Port, 60 DownstreamHostPort: dest, 61 TofuAddIfNotKnown: true, 62 } 63 64 tries := 0 65 var channelToTcpServer net.Conn 66 var err error 67 ctx := context.Background() 68 69 for ; tries < 3; tries++ { 70 // first time we add the server key 71 channelToTcpServer, _, _, err = dc.Dial(ctx, nil, false) 72 fmt.Printf("after dc.Dial() in cli_test.go: err = '%v'", err) 73 errs := err.Error() 74 case1 := strings.Contains(errs, "Re-run without -new") 75 case2 := strings.Contains(errs, "getsockopt: connection refused") 76 ok := case1 || case2 77 cv.So(ok, cv.ShouldBeTrue) 78 if case1 { 79 break 80 } 81 } 82 if tries == 3 { 83 panic("could not get 'Re-run without -new' after 3 tries") 84 } 85 86 // second time we connect based on that server key 87 dc.TofuAddIfNotKnown = false 88 channelToTcpServer, _, _, err = dc.Dial(ctx, nil, false) 89 cv.So(err, cv.ShouldBeNil) 90 91 VerifyClientServerExchangeAcrossSshd(channelToTcpServer, confirmationPayload, confirmationReply, payloadByteCount) 92 channelToTcpServer.Close() 93 } 94 // tcp-server should have exited because it got the expected 95 // message and replied with the agreed upon reply and then exited. 96 serverDone.RequestStop() 97 <-serverDone.DoneChan() 98 99 // done with testing, cleanup 100 s.SrvCfg.Esshd.Stop() 101 <-s.SrvCfg.Esshd.Halt.DoneChan() 102 cv.So(true, cv.ShouldEqual, true) // we should get here. 103 }) 104 }