فهرست منبع

ssh: Support multiple source-addresses, don't require IPv4 in tests.

The ssh tests currently require 127.0.0.1 to work which isn't
necessarily available everywhere. To fix the source-address tests,
support comma-separated source-address values per the PROTOCOL.certkeys
file:

  Comma-separated list of source addresses
  from which this certificate is accepted
  for authentication. Addresses are
  specified in CIDR format (nn.nn.nn.nn/nn
  or hhhh::hhhh/nn).
  If this option is not present then
  certificates may be presented from any
  source address.

Change-Id: I87536ff81ffa005c073da103021ebc0dfb12b620
Reviewed-on: https://go-review.googlesource.com/36110
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Heschi Kreinick <heschi@google.com>
Heschi Kreinick 8 سال پیش
والد
کامیت
bed12803fa
3فایلهای تغییر یافته به همراه18 افزوده شده و 15 حذف شده
  1. 2 2
      ssh/client_auth_test.go
  2. 1 1
      ssh/handshake_test.go
  3. 15 12
      ssh/server.go

+ 2 - 2
ssh/client_auth_test.go

@@ -333,14 +333,14 @@ func TestClientLoginCert(t *testing.T) {
 	}
 	}
 
 
 	// allowed source address
 	// allowed source address
-	cert.CriticalOptions = map[string]string{"source-address": "127.0.0.42/24"}
+	cert.CriticalOptions = map[string]string{"source-address": "127.0.0.42/24,::42/120"}
 	cert.SignCert(rand.Reader, testSigners["ecdsa"])
 	cert.SignCert(rand.Reader, testSigners["ecdsa"])
 	if err := tryAuth(t, clientConfig); err != nil {
 	if err := tryAuth(t, clientConfig); err != nil {
 		t.Errorf("cert login with source-address failed: %v", err)
 		t.Errorf("cert login with source-address failed: %v", err)
 	}
 	}
 
 
 	// disallowed source address
 	// disallowed source address
-	cert.CriticalOptions = map[string]string{"source-address": "127.0.0.42"}
+	cert.CriticalOptions = map[string]string{"source-address": "127.0.0.42,::42"}
 	cert.SignCert(rand.Reader, testSigners["ecdsa"])
 	cert.SignCert(rand.Reader, testSigners["ecdsa"])
 	if err := tryAuth(t, clientConfig); err == nil {
 	if err := tryAuth(t, clientConfig); err == nil {
 		t.Errorf("cert login with source-address succeeded")
 		t.Errorf("cert login with source-address succeeded")

+ 1 - 1
ssh/handshake_test.go

@@ -40,7 +40,7 @@ func (t *testChecker) Check(dialAddr string, addr net.Addr, key PublicKey) error
 // therefore is buffered (net.Pipe deadlocks if both sides start with
 // therefore is buffered (net.Pipe deadlocks if both sides start with
 // a write.)
 // a write.)
 func netPipe() (net.Conn, net.Conn, error) {
 func netPipe() (net.Conn, net.Conn, error) {
-	listener, err := net.Listen("tcp", "127.0.0.1:0")
+	listener, err := net.Listen("tcp", ":0")
 	if err != nil {
 	if err != nil {
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}

+ 15 - 12
ssh/server.go

@@ -10,6 +10,7 @@ import (
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"net"
 	"net"
+	"strings"
 )
 )
 
 
 // The Permissions type holds fine-grained permissions that are
 // The Permissions type holds fine-grained permissions that are
@@ -231,7 +232,7 @@ func isAcceptableAlgo(algo string) bool {
 	return false
 	return false
 }
 }
 
 
-func checkSourceAddress(addr net.Addr, sourceAddr string) error {
+func checkSourceAddress(addr net.Addr, sourceAddrs string) error {
 	if addr == nil {
 	if addr == nil {
 		return errors.New("ssh: no address known for client, but source-address match required")
 		return errors.New("ssh: no address known for client, but source-address match required")
 	}
 	}
@@ -241,18 +242,20 @@ func checkSourceAddress(addr net.Addr, sourceAddr string) error {
 		return fmt.Errorf("ssh: remote address %v is not an TCP address when checking source-address match", addr)
 		return fmt.Errorf("ssh: remote address %v is not an TCP address when checking source-address match", addr)
 	}
 	}
 
 
-	if allowedIP := net.ParseIP(sourceAddr); allowedIP != nil {
-		if allowedIP.Equal(tcpAddr.IP) {
-			return nil
-		}
-	} else {
-		_, ipNet, err := net.ParseCIDR(sourceAddr)
-		if err != nil {
-			return fmt.Errorf("ssh: error parsing source-address restriction %q: %v", sourceAddr, err)
-		}
+	for _, sourceAddr := range strings.Split(sourceAddrs, ",") {
+		if allowedIP := net.ParseIP(sourceAddr); allowedIP != nil {
+			if allowedIP.Equal(tcpAddr.IP) {
+				return nil
+			}
+		} else {
+			_, ipNet, err := net.ParseCIDR(sourceAddr)
+			if err != nil {
+				return fmt.Errorf("ssh: error parsing source-address restriction %q: %v", sourceAddr, err)
+			}
 
 
-		if ipNet.Contains(tcpAddr.IP) {
-			return nil
+			if ipNet.Contains(tcpAddr.IP) {
+				return nil
+			}
 		}
 		}
 	}
 	}