mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-11-04 00:55:11 +00:00 
			
		
		
		
	The upstream crypto package now supports sending banners at any time during authentication, so the Tailscale fork of crypto/ssh is no longer necessary. github.com/tailscale/golang-x-crypto is still needed for some custom ACME autocert functionality. tempfork/gliderlabs is still necessary because of a few other customizations, mostly related to TTY handling. Originally implemented in46fd4e58a2, which was reverted inb60f6b849ato keep the change out of v1.80. Updates #8593 Signed-off-by: Percy Wegmann <percy@tailscale.com>
		
			
				
	
	
		
			86 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
//go:build glidertests
 | 
						|
 | 
						|
package ssh
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"io"
 | 
						|
	"net"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	gossh "golang.org/x/crypto/ssh"
 | 
						|
)
 | 
						|
 | 
						|
var sampleServerResponse = []byte("Hello world")
 | 
						|
 | 
						|
func sampleSocketServer() net.Listener {
 | 
						|
	l := newLocalListener()
 | 
						|
 | 
						|
	go func() {
 | 
						|
		conn, err := l.Accept()
 | 
						|
		if err != nil {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		conn.Write(sampleServerResponse)
 | 
						|
		conn.Close()
 | 
						|
	}()
 | 
						|
 | 
						|
	return l
 | 
						|
}
 | 
						|
 | 
						|
func newTestSessionWithForwarding(t *testing.T, forwardingEnabled bool) (net.Listener, *gossh.Client, func()) {
 | 
						|
	l := sampleSocketServer()
 | 
						|
 | 
						|
	_, client, cleanup := newTestSession(t, &Server{
 | 
						|
		Handler: func(s Session) {},
 | 
						|
		LocalPortForwardingCallback: func(ctx Context, destinationHost string, destinationPort uint32) bool {
 | 
						|
			addr := net.JoinHostPort(destinationHost, strconv.FormatInt(int64(destinationPort), 10))
 | 
						|
			if addr != l.Addr().String() {
 | 
						|
				panic("unexpected destinationHost: " + addr)
 | 
						|
			}
 | 
						|
			return forwardingEnabled
 | 
						|
		},
 | 
						|
	}, nil)
 | 
						|
 | 
						|
	return l, client, func() {
 | 
						|
		cleanup()
 | 
						|
		l.Close()
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestLocalPortForwardingWorks(t *testing.T) {
 | 
						|
	t.Parallel()
 | 
						|
 | 
						|
	l, client, cleanup := newTestSessionWithForwarding(t, true)
 | 
						|
	defer cleanup()
 | 
						|
 | 
						|
	conn, err := client.Dial("tcp", l.Addr().String())
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Error connecting to %v: %v", l.Addr().String(), err)
 | 
						|
	}
 | 
						|
	result, err := io.ReadAll(conn)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	if !bytes.Equal(result, sampleServerResponse) {
 | 
						|
		t.Fatalf("result = %#v; want %#v", result, sampleServerResponse)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestLocalPortForwardingRespectsCallback(t *testing.T) {
 | 
						|
	t.Parallel()
 | 
						|
 | 
						|
	l, client, cleanup := newTestSessionWithForwarding(t, false)
 | 
						|
	defer cleanup()
 | 
						|
 | 
						|
	_, err := client.Dial("tcp", l.Addr().String())
 | 
						|
	if err == nil {
 | 
						|
		t.Fatalf("Expected error connecting to %v but it succeeded", l.Addr().String())
 | 
						|
	}
 | 
						|
	if !strings.Contains(err.Error(), "port forwarding is disabled") {
 | 
						|
		t.Fatalf("Expected permission error but got %#v", err)
 | 
						|
	}
 | 
						|
}
 |