github.com/devops-filetransfer/sshego@v7.0.4+incompatible/server_test.go (about)

     1  package sshego
     2  
     3  import (
     4  	"context"
     5  	cryrand "crypto/rand"
     6  	"fmt"
     7  	"io"
     8  	"io/ioutil"
     9  	"net"
    10  	"strings"
    11  	"testing"
    12  
    13  	cv "github.com/glycerine/goconvey/convey"
    14  	"github.com/glycerine/sshego/xendor/github.com/glycerine/xcryptossh"
    15  	"github.com/glycerine/sshego/xendor/github.com/glycerine/xcryptossh/testdata"
    16  )
    17  
    18  func Test101StartupAndShutdown(t *testing.T) {
    19  
    20  	cv.Convey("The -esshd embedded SSHd goroutine should start and stop when requested.", t, func() {
    21  		cfg, r1 := GenTestConfig()
    22  		r1() // release the held-open ports.
    23  		defer TempDirCleanup(cfg.Origdir, cfg.Tempdir)
    24  		cfg.NewEsshd()
    25  		ctx := context.Background()
    26  
    27  		cfg.Esshd.Start(ctx)
    28  		cfg.Esshd.Stop()
    29  		<-cfg.Esshd.Halt.DoneChan()
    30  		cv.So(true, cv.ShouldEqual, true) // we should get here.
    31  	})
    32  }
    33  
    34  func Test102SSHdRequiresTripleAuth(t *testing.T) {
    35  
    36  	cv.Convey("The -esshd should require triple auth: RSA key, password, and one-time-passowrd, not any (proper) subset of only two", t, func() {
    37  
    38  		srvCfg, r1 := GenTestConfig()
    39  		cliCfg, r2 := GenTestConfig()
    40  
    41  		// now that we have all different ports, we
    42  		// must release them for use below.
    43  		r1()
    44  		r2()
    45  		defer TempDirCleanup(srvCfg.Origdir, srvCfg.Tempdir)
    46  		srvCfg.NewEsshd()
    47  		ctx := context.Background()
    48  		halt := ssh.NewHalter()
    49  
    50  		srvCfg.Esshd.Start(ctx)
    51  		// create a new acct
    52  		mylogin := "bob"
    53  		myemail := "bob@example.com"
    54  		fullname := "Bob Fakey McFakester"
    55  		pw := fmt.Sprintf("%x", string(CryptoRandBytes(30)))
    56  
    57  		p("srvCfg.HostDb = %#v", srvCfg.HostDb)
    58  		toptPath, qrPath, rsaPath, err := srvCfg.HostDb.AddUser(
    59  			mylogin, myemail, pw, "gosshtun", fullname, "")
    60  
    61  		cv.So(err, cv.ShouldBeNil)
    62  
    63  		cv.So(strings.HasPrefix(toptPath, srvCfg.Tempdir), cv.ShouldBeTrue)
    64  		cv.So(strings.HasPrefix(qrPath, srvCfg.Tempdir), cv.ShouldBeTrue)
    65  		cv.So(strings.HasPrefix(rsaPath, srvCfg.Tempdir), cv.ShouldBeTrue)
    66  
    67  		pp("toptPath = %v", toptPath)
    68  		pp("qrPath = %v", qrPath)
    69  		pp("rsaPath = %v", rsaPath)
    70  
    71  		// try to login to esshd
    72  
    73  		// need an ssh client
    74  
    75  		// allow server to be discovered
    76  		cliCfg.AddIfNotKnown = true
    77  		cliCfg.TestAllowOneshotConnect = true
    78  
    79  		totpUrl, err := ioutil.ReadFile(toptPath)
    80  		panicOn(err)
    81  		totp := string(totpUrl)
    82  
    83  		// tell the client not to run an esshd
    84  		cliCfg.EmbeddedSSHd.Addr = ""
    85  		//cliCfg.LocalToRemote.Listen.Addr = ""
    86  		rev := cliCfg.RemoteToLocal.Listen.Addr
    87  		cliCfg.RemoteToLocal.Listen.Addr = ""
    88  
    89  		_, _, err = cliCfg.SSHConnect(ctx, cliCfg.KnownHosts, mylogin, rsaPath,
    90  			srvCfg.EmbeddedSSHd.Host, srvCfg.EmbeddedSSHd.Port, pw, totp, halt)
    91  		// we should be able to login, but then the sshd should
    92  		// reject the port forwarding request.
    93  		//
    94  		// Anyway, forward request denies does indicate we
    95  		// logged in when all three (RSA, TOTP, passphrase)
    96  		// were given.
    97  		pp("err is %#v", err)
    98  		// should have succeeded in logging in
    99  		cv.So(err, cv.ShouldBeNil)
   100  
   101  		// try with only 2 of the 3:
   102  		fmt.Printf("\n test with only 2 of the required 3 auth...\n")
   103  		cliCfg.AddIfNotKnown = false
   104  		_, _, err = cliCfg.SSHConnect(ctx, cliCfg.KnownHosts, mylogin, rsaPath,
   105  			srvCfg.EmbeddedSSHd.Host, srvCfg.EmbeddedSSHd.Port, pw, "", halt)
   106  		cv.So(err.Error(), cv.ShouldContainSubstring, "ssh: unable to authenticate")
   107  
   108  		_, _, err = cliCfg.SSHConnect(ctx, cliCfg.KnownHosts, mylogin, rsaPath,
   109  			srvCfg.EmbeddedSSHd.Host, srvCfg.EmbeddedSSHd.Port, "", totp, halt)
   110  		cv.So(err.Error(), cv.ShouldContainSubstring, "ssh: unable to authenticate")
   111  
   112  		_, _, err = cliCfg.SSHConnect(ctx, cliCfg.KnownHosts, mylogin, "",
   113  			srvCfg.EmbeddedSSHd.Host, srvCfg.EmbeddedSSHd.Port, pw, totp, halt)
   114  		cv.So(err.Error(), cv.ShouldContainSubstring, "ssh: unable to authenticate")
   115  
   116  		fmt.Printf("\n and test with only one auth method...\n")
   117  		_, _, err = cliCfg.SSHConnect(ctx, cliCfg.KnownHosts, mylogin, rsaPath,
   118  			srvCfg.EmbeddedSSHd.Host, srvCfg.EmbeddedSSHd.Port, "", "", halt)
   119  		cv.So(err.Error(), cv.ShouldContainSubstring, "ssh: unable to authenticate")
   120  
   121  		_, _, err = cliCfg.SSHConnect(ctx, cliCfg.KnownHosts, mylogin, "",
   122  			srvCfg.EmbeddedSSHd.Host, srvCfg.EmbeddedSSHd.Port, "", totp, halt)
   123  		cv.So(err.Error(), cv.ShouldContainSubstring, "ssh: unable to authenticate")
   124  
   125  		_, _, err = cliCfg.SSHConnect(ctx, cliCfg.KnownHosts, mylogin, "",
   126  			srvCfg.EmbeddedSSHd.Host, srvCfg.EmbeddedSSHd.Port, pw, "", halt)
   127  		cv.So(err.Error(), cv.ShouldContainSubstring, "ssh: unable to authenticate")
   128  
   129  		fmt.Printf("\n and test with zero auth methods...\n")
   130  		_, _, err = cliCfg.SSHConnect(ctx, cliCfg.KnownHosts, mylogin, "",
   131  			srvCfg.EmbeddedSSHd.Host, srvCfg.EmbeddedSSHd.Port, "", "", halt)
   132  		cv.So(err.Error(), cv.ShouldContainSubstring, "ssh: unable to authenticate")
   133  
   134  		fmt.Printf("\n test that reverse forwarding is denied by our sshd... even if all 3 proper auth is given\n")
   135  		cliCfg.RemoteToLocal.Listen.Addr = rev
   136  		_, _, err = cliCfg.SSHConnect(ctx, cliCfg.KnownHosts, mylogin, rsaPath,
   137  			srvCfg.EmbeddedSSHd.Host, srvCfg.EmbeddedSSHd.Port, pw, totp, halt)
   138  		cv.So(err.Error(), cv.ShouldEqual, "StartupReverseListener failed: ssh: tcpip-forward request denied by peer")
   139  		fmt.Printf("\n excellent: as expected, err was '%s'\n", err)
   140  
   141  		// done with testing, cleanup
   142  		halt.RequestStop()
   143  		halt.MarkDone()
   144  		srvCfg.Esshd.Stop()
   145  		<-srvCfg.Esshd.Halt.DoneChan()
   146  		cv.So(true, cv.ShouldEqual, true) // we should get here.
   147  	})
   148  }
   149  
   150  // from ~/go/src/github.com/glycerine/xcryptossh/testdata_test.go : init() function.
   151  
   152  // Copyright 2014 The Go Authors. All rights reserved.
   153  // Use of this source code is governed by a BSD-style
   154  // license that can be found in the LICENSE file.
   155  
   156  type server struct {
   157  	*ssh.ServerConn
   158  	chans <-chan ssh.NewChannel
   159  }
   160  
   161  func newServer(ctx context.Context, c net.Conn, conf *ssh.ServerConfig) (*server, error) {
   162  	sconn, chans, reqs, err := ssh.NewServerConn(ctx, c, conf)
   163  	if err != nil {
   164  		return nil, err
   165  	}
   166  	go ssh.DiscardRequests(ctx, reqs, nil)
   167  	return &server{sconn, chans}, nil
   168  }
   169  
   170  // CertTimeInfinity can be used for
   171  // OpenSSHCertV01.ValidBefore to indicate that
   172  // a certificate does not expire.
   173  const CertTimeInfinity = 1<<64 - 1
   174  
   175  func (a *AuthState) InitTestData() error {
   176  	var err error
   177  
   178  	n := len(testdata.PEMBytes)
   179  	a.PrivateKeys = make(map[string]interface{}, n)
   180  	a.Signers = make(map[string]ssh.Signer, n)
   181  	a.PublicKeys = make(map[string]ssh.PublicKey, n)
   182  	for t, k := range testdata.PEMBytes {
   183  		a.PrivateKeys[t], err = ssh.ParseRawPrivateKey(k)
   184  		if err != nil {
   185  			panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err))
   186  		}
   187  		a.Signers[t], err = ssh.NewSignerFromKey(a.PrivateKeys[t])
   188  		if err != nil {
   189  			panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err))
   190  		}
   191  		a.PublicKeys[t] = a.Signers[t].PublicKey()
   192  	}
   193  
   194  	nonce := make([]byte, 32)
   195  	if _, err := io.ReadFull(cryrand.Reader, nonce); err != nil {
   196  		return err
   197  	}
   198  
   199  	// Create a cert and sign it for use in tests.
   200  	a.Cert = &ssh.Certificate{
   201  		Nonce:           nonce,
   202  		ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage
   203  		ValidAfter:      0,                              // unix epoch
   204  		ValidBefore:     ssh.CertTimeInfinity,           // The end of currently representable time.
   205  		Reserved:        []byte{},                       // To pass reflect.DeepEqual after marshal & parse, this must be non-nil
   206  		Key:             a.PublicKeys["ecdsa"],
   207  		SignatureKey:    a.PublicKeys["rsa"],
   208  		Permissions: ssh.Permissions{
   209  			CriticalOptions: map[string]string{},
   210  			Extensions:      map[string]string{},
   211  		},
   212  	}
   213  	a.Cert.SignCert(cryrand.Reader, a.Signers["rsa"])
   214  	a.PrivateKeys["cert"] = a.PrivateKeys["ecdsa"]
   215  	a.Signers["cert"], err = ssh.NewCertSigner(a.Cert, a.Signers["ecdsa"])
   216  	if err != nil {
   217  		panic(fmt.Sprintf("Unable to create certificate signer: %v", err))
   218  	}
   219  	return nil
   220  }