[tor-commits] [goptlib/master] Test for failure of SetDeadline in extOrPortSetup.

dcf at torproject.org dcf at torproject.org
Tue Mar 5 23:22:53 UTC 2019


commit c538911ed6f8fe50a268505a88561999e98d8566
Author: David Fifield <david at bamsoftware.com>
Date:   Tue Mar 5 16:05:24 2019 -0700

    Test for failure of SetDeadline in extOrPortSetup.
---
 pt_test.go      | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 test_authcookie |   2 +
 2 files changed, 141 insertions(+)

diff --git a/pt_test.go b/pt_test.go
index 15907ef..70f5533 100644
--- a/pt_test.go
+++ b/pt_test.go
@@ -11,8 +11,11 @@ import (
 	"path"
 	"sort"
 	"testing"
+	"time"
 )
 
+const testAuthCookiePath = "test_authcookie"
+
 func TestErrors(t *testing.T) {
 	Stdout = ioutil.Discard
 
@@ -763,6 +766,142 @@ func TestExtOrPortSetMetadata(t *testing.T) {
 	testExtOrPortSetMetadataIndividual(t, addr, methodName)
 }
 
+func simulateServerExtOrPortAuth(r io.Reader, w io.Writer, authCookie []byte) error {
+	// send auth types
+	_, err := w.Write([]byte{1, 0})
+	if err != nil {
+		return err
+	}
+	// read client auth type
+	buf := make([]byte, 1)
+	_, err = io.ReadFull(r, buf)
+	if err != nil {
+		return err
+	}
+	if buf[0] != 1 {
+		return fmt.Errorf("didn't get client auth type 1")
+	}
+	// read client nonce
+	clientNonce := make([]byte, 32)
+	_, err = io.ReadFull(r, clientNonce)
+	if err != nil {
+		return err
+	}
+	// send server hash and nonce
+	serverNonce := make([]byte, 32)
+	serverHash := computeServerHash(authCookie, clientNonce, serverNonce)
+	_, err = w.Write(serverHash)
+	if err != nil {
+		return err
+	}
+	_, err = w.Write(serverNonce)
+	if err != nil {
+		return err
+	}
+	// read client hash
+	clientHash := make([]byte, 32)
+	_, err = io.ReadFull(r, clientHash)
+	if err != nil {
+		return err
+	}
+	// send success status
+	_, err = w.Write([]byte{1})
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+type failSetDeadlineAfter struct {
+	n   int
+	err error
+}
+
+func (c *failSetDeadlineAfter) try() error {
+	if c.n > 0 {
+		c.n--
+		return nil
+	}
+	return c.err
+}
+
+func (c *failSetDeadlineAfter) SetDeadline(_ time.Time) error {
+	return c.try()
+}
+
+func (c *failSetDeadlineAfter) SetReadDeadline(_ time.Time) error {
+	return c.try()
+}
+
+func (c *failSetDeadlineAfter) SetWriteDeadline(_ time.Time) error {
+	return c.try()
+}
+
+// a fake Conn whose Set*Deadline functions fail after a certain number of
+// calls.
+type connFailSetDeadline struct {
+	io.Reader
+	io.Writer
+	failSetDeadlineAfter
+}
+
+func (c *connFailSetDeadline) Close() error {
+	return nil
+}
+
+func (c *connFailSetDeadline) LocalAddr() net.Addr {
+	return &net.IPAddr{net.IPv4(0, 0, 0, 0), ""}
+}
+
+func (c *connFailSetDeadline) RemoteAddr() net.Addr {
+	return &net.IPAddr{net.IPv4(0, 0, 0, 0), ""}
+}
+
+// Test that a failure of SetDeadline is reported.
+func TestExtOrPortSetupFailSetDeadline(t *testing.T) {
+	authCookie, err := readAuthCookieFile(testAuthCookiePath)
+	if err != nil {
+		panic(err)
+	}
+
+	// extOrPortSetup calls SetDeadline twice, so try failing the call after
+	// differing delays.
+	expectedErr := fmt.Errorf("distinguished error")
+	for _, delay := range []int{0, 1, 2} {
+		upstreamR, upstreamW := io.Pipe()
+		downstreamR, downstreamW := io.Pipe()
+
+		// mock ExtORPort to talk to
+		go func() {
+			// handle auth
+			err := simulateServerExtOrPortAuth(upstreamR, downstreamW, authCookie)
+			if err != nil {
+				return
+			}
+			// discard succeeding client data
+			go func() {
+				io.Copy(ioutil.Discard, upstreamR)
+			}()
+			// fake an OKAY response.
+			err = extOrPortSendCommand(downstreamW, extOrCmdOkay, []byte{})
+			if err != nil {
+				return
+			}
+		}()
+
+		// make a Conn that will fail SetDeadline after a certain number
+		// of calls.
+		s := &connFailSetDeadline{downstreamR, upstreamW, failSetDeadlineAfter{delay, expectedErr}}
+		serverInfo := &ServerInfo{AuthCookiePath: testAuthCookiePath}
+		err = extOrPortSetup(s, 1*time.Second, serverInfo, "", "")
+		if delay < 2 && err != expectedErr {
+			t.Fatalf("delay %v: expected error %v, got %v", delay, expectedErr, err)
+		} else if delay >= 2 && err != nil {
+			t.Fatalf("delay %v: got error %v", delay, err)
+		}
+	}
+}
+
 func TestMakeStateDir(t *testing.T) {
 	os.Clearenv()
 
diff --git a/test_authcookie b/test_authcookie
new file mode 100644
index 0000000..0df0cfb
--- /dev/null
+++ b/test_authcookie
@@ -0,0 +1,2 @@
+! Extended ORPort Auth Cookie !
+this file is used in test code.





More information about the tor-commits mailing list