[tor-commits] [pluggable-transports/snowflake] 23/31: Represent Bridge Fingerprint As String

gitolite role git at cupani.torproject.org
Thu Jun 16 17:04:10 UTC 2022


This is an automated email from the git hooks/post-receive script.

shelikhoo pushed a commit to branch main
in repository pluggable-transports/snowflake.

commit f789dce6d2b5e6e7d02eef6b168c31ed2ddd149e
Author: Shelikhoo <xiaokangwang at outlook.com>
AuthorDate: Tue May 17 15:53:15 2022 +0100

    Represent Bridge Fingerprint As String
---
 broker/bridge-list.go                   | 22 +++++++++++-----------
 broker/bridge-list_test.go              |  9 +++++++--
 broker/broker.go                        |  5 +++--
 broker/ipc.go                           | 17 ++++++++++++++---
 broker/snowflake-broker_test.go         |  2 +-
 common/bridgefingerprint/fingerprint.go | 30 ++++++++++++++++++++++++++++++
 common/messages/client.go               |  5 +++--
 7 files changed, 69 insertions(+), 21 deletions(-)

diff --git a/broker/bridge-list.go b/broker/bridge-list.go
index e77db65..ca2c041 100644
--- a/broker/bridge-list.go
+++ b/broker/bridge-list.go
@@ -2,27 +2,26 @@ package main
 
 import (
 	"bufio"
-	"encoding/hex"
 	"encoding/json"
 	"errors"
+	"git.torproject.org/pluggable-transports/snowflake.git/v2/common/bridgefingerprint"
 	"io"
 	"sync"
 )
 
 var ErrBridgeNotFound = errors.New("bridge not found")
-var ErrBridgeFingerprintInvalid = errors.New("bridge fingerprint invalid")
 
 func NewBridgeListHolder() BridgeListHolderFileBased {
 	return &bridgeListHolder{}
 }
 
 type bridgeListHolder struct {
-	bridgeInfo       map[[20]byte]BridgeInfo
+	bridgeInfo       map[bridgefingerprint.Fingerprint]BridgeInfo
 	accessBridgeInfo sync.RWMutex
 }
 
 type BridgeListHolder interface {
-	GetBridgeInfo(fingerprint [20]byte) (BridgeInfo, error)
+	GetBridgeInfo(bridgefingerprint.Fingerprint) (BridgeInfo, error)
 }
 
 type BridgeListHolderFileBased interface {
@@ -36,7 +35,7 @@ type BridgeInfo struct {
 	Fingerprint      string `json:"fingerprint"`
 }
 
-func (h *bridgeListHolder) GetBridgeInfo(fingerprint [20]byte) (BridgeInfo, error) {
+func (h *bridgeListHolder) GetBridgeInfo(fingerprint bridgefingerprint.Fingerprint) (BridgeInfo, error) {
 	h.accessBridgeInfo.RLock()
 	defer h.accessBridgeInfo.RUnlock()
 	if bridgeInfo, ok := h.bridgeInfo[fingerprint]; ok {
@@ -46,7 +45,7 @@ func (h *bridgeListHolder) GetBridgeInfo(fingerprint [20]byte) (BridgeInfo, erro
 }
 
 func (h *bridgeListHolder) LoadBridgeInfo(reader io.Reader) error {
-	bridgeInfoMap := map[[20]byte]BridgeInfo{}
+	bridgeInfoMap := map[bridgefingerprint.Fingerprint]BridgeInfo{}
 	inputScanner := bufio.NewScanner(reader)
 	for inputScanner.Scan() {
 		inputLine := inputScanner.Bytes()
@@ -54,13 +53,14 @@ func (h *bridgeListHolder) LoadBridgeInfo(reader io.Reader) error {
 		if err := json.Unmarshal(inputLine, &bridgeInfo); err != nil {
 			return err
 		}
-		var bridgeHash [20]byte
-		if n, err := hex.Decode(bridgeHash[:], []byte(bridgeInfo.Fingerprint)); err != nil {
+
+		var bridgeFingerprint bridgefingerprint.Fingerprint
+		var err error
+		if bridgeFingerprint, err = bridgefingerprint.FingerprintFromHexString(bridgeInfo.Fingerprint); err != nil {
 			return err
-		} else if n != 20 {
-			return ErrBridgeFingerprintInvalid
 		}
-		bridgeInfoMap[bridgeHash] = bridgeInfo
+
+		bridgeInfoMap[bridgeFingerprint] = bridgeInfo
 	}
 	h.accessBridgeInfo.Lock()
 	defer h.accessBridgeInfo.Unlock()
diff --git a/broker/bridge-list_test.go b/broker/bridge-list_test.go
index 73da43c..4b53821 100644
--- a/broker/bridge-list_test.go
+++ b/broker/bridge-list_test.go
@@ -3,6 +3,7 @@ package main
 import (
 	"bytes"
 	"encoding/hex"
+	"git.torproject.org/pluggable-transports/snowflake.git/v2/common/bridgefingerprint"
 	. "github.com/smartystreets/goconvey/convey"
 	"testing"
 )
@@ -34,7 +35,9 @@ func TestBridgeLoad(t *testing.T) {
 				So(n, ShouldEqual, 20)
 				So(err, ShouldBeNil)
 			}
-			bridgeInfo, err := bridgeList.GetBridgeInfo(bridgeFingerprint)
+			Fingerprint, err := bridgefingerprint.FingerprintFromBytes(bridgeFingerprint[:])
+			So(err, ShouldBeNil)
+			bridgeInfo, err := bridgeList.GetBridgeInfo(Fingerprint)
 			So(err, ShouldBeNil)
 			So(bridgeInfo.DisplayName, ShouldEqual, "default")
 			So(bridgeInfo.WebSocketAddress, ShouldEqual, "wss://snowflake.torproject.org")
@@ -50,7 +53,9 @@ func TestBridgeLoad(t *testing.T) {
 				So(n, ShouldEqual, 20)
 				So(err, ShouldBeNil)
 			}
-			bridgeInfo, err := bridgeList.GetBridgeInfo(bridgeFingerprint)
+			Fingerprint, err := bridgefingerprint.FingerprintFromBytes(bridgeFingerprint[:])
+			So(err, ShouldBeNil)
+			bridgeInfo, err := bridgeList.GetBridgeInfo(Fingerprint)
 			So(err, ShouldBeNil)
 			So(bridgeInfo.DisplayName, ShouldEqual, "imaginary-8")
 			So(bridgeInfo.WebSocketAddress, ShouldEqual, "wss://imaginary-8-snowflake.torproject.org")
diff --git a/broker/broker.go b/broker/broker.go
index 8ca0120..9162370 100644
--- a/broker/broker.go
+++ b/broker/broker.go
@@ -10,6 +10,7 @@ import (
 	"container/heap"
 	"crypto/tls"
 	"flag"
+	"git.torproject.org/pluggable-transports/snowflake.git/v2/common/bridgefingerprint"
 	"io"
 	"log"
 	"net/http"
@@ -44,7 +45,7 @@ type BrokerContext struct {
 	presumedPatternForLegacyClient string
 }
 
-func (ctx *BrokerContext) GetBridgeInfo(fingerprint [20]byte) (BridgeInfo, error) {
+func (ctx *BrokerContext) GetBridgeInfo(fingerprint bridgefingerprint.Fingerprint) (BridgeInfo, error) {
 	return ctx.bridgeList.GetBridgeInfo(fingerprint)
 }
 
@@ -178,7 +179,7 @@ func (ctx *BrokerContext) CheckProxyRelayPattern(pattern string, nonSupported bo
 type ClientOffer struct {
 	natType     string
 	sdp         []byte
-	fingerprint [20]byte
+	fingerprint []byte
 }
 
 func main() {
diff --git a/broker/ipc.go b/broker/ipc.go
index c86d1a7..f5d4747 100644
--- a/broker/ipc.go
+++ b/broker/ipc.go
@@ -4,6 +4,7 @@ import (
 	"container/heap"
 	"encoding/hex"
 	"fmt"
+	"git.torproject.org/pluggable-transports/snowflake.git/v2/common/bridgefingerprint"
 	"log"
 	"net"
 	"time"
@@ -130,7 +131,11 @@ func (i *IPC) ProxyPolls(arg messages.Arg, response *[]byte) error {
 
 	i.ctx.metrics.promMetrics.ProxyPollTotal.With(prometheus.Labels{"nat": natType, "status": "matched"}).Inc()
 	var relayURL string
-	if info, err := i.ctx.bridgeList.GetBridgeInfo(offer.fingerprint); err != nil {
+	bridgeFingerprint, err := bridgefingerprint.FingerprintFromBytes(offer.fingerprint)
+	if err != nil {
+		return messages.ErrBadRequest
+	}
+	if info, err := i.ctx.bridgeList.GetBridgeInfo(bridgeFingerprint); err != nil {
 		return err
 	} else {
 		relayURL = info.WebSocketAddress
@@ -172,12 +177,18 @@ func (i *IPC) ClientOffers(arg messages.Arg, response *[]byte) error {
 	if err != nil {
 		return sendClientResponse(&messages.ClientPollResponse{Error: err.Error()}, response)
 	}
-	copy(offer.fingerprint[:], fingerprint)
 
-	if _, err := i.ctx.GetBridgeInfo(offer.fingerprint); err != nil {
+	BridgeFingerprint, err := bridgefingerprint.FingerprintFromBytes(fingerprint)
+	if err != nil {
+		return sendClientResponse(&messages.ClientPollResponse{Error: err.Error()}, response)
+	}
+
+	if _, err := i.ctx.GetBridgeInfo(BridgeFingerprint); err != nil {
 		return err
 	}
 
+	offer.fingerprint = BridgeFingerprint.ToBytes()
+
 	// Only hand out known restricted snowflakes to unrestricted clients
 	var snowflakeHeap *SnowflakeHeap
 	if offer.natType == NATUnrestricted {
diff --git a/broker/snowflake-broker_test.go b/broker/snowflake-broker_test.go
index aee8578..a72f3ac 100644
--- a/broker/snowflake-broker_test.go
+++ b/broker/snowflake-broker_test.go
@@ -258,7 +258,7 @@ func TestBroker(t *testing.T) {
 				// Pass a fake client offer to this proxy
 				p := <-ctx.proxyPolls
 				So(p.id, ShouldEqual, "ymbcCMto7KHNGYlp")
-				p.offerChannel <- &ClientOffer{sdp: []byte("fake offer"), fingerprint: defaultBridge}
+				p.offerChannel <- &ClientOffer{sdp: []byte("fake offer"), fingerprint: defaultBridge[:]}
 				<-done
 				So(w.Code, ShouldEqual, http.StatusOK)
 				So(w.Body.String(), ShouldEqual, `{"Status":"client match","Offer":"fake offer","NAT":"","RelayURL":"wss://snowflake.torproject.net/"}`)
diff --git a/common/bridgefingerprint/fingerprint.go b/common/bridgefingerprint/fingerprint.go
new file mode 100644
index 0000000..1a89773
--- /dev/null
+++ b/common/bridgefingerprint/fingerprint.go
@@ -0,0 +1,30 @@
+package bridgefingerprint
+
+import (
+	"encoding/hex"
+	"errors"
+)
+
+type Fingerprint string
+
+var ErrBridgeFingerprintInvalid = errors.New("bridge fingerprint invalid")
+
+func FingerprintFromBytes(bytes []byte) (Fingerprint, error) {
+	n := len(bytes)
+	if n != 20 && n != 32 {
+		return Fingerprint(""), ErrBridgeFingerprintInvalid
+	}
+	return Fingerprint(bytes), nil
+}
+
+func FingerprintFromHexString(hexString string) (Fingerprint, error) {
+	decoded, err := hex.DecodeString(hexString)
+	if err != nil {
+		return "", err
+	}
+	return FingerprintFromBytes(decoded)
+}
+
+func (f Fingerprint) ToBytes() []byte {
+	return []byte(f)
+}
diff --git a/common/messages/client.go b/common/messages/client.go
index 96f8ed8..af63e08 100644
--- a/common/messages/client.go
+++ b/common/messages/client.go
@@ -5,9 +5,9 @@ package messages
 
 import (
 	"bytes"
-	"encoding/hex"
 	"encoding/json"
 	"fmt"
+	"git.torproject.org/pluggable-transports/snowflake.git/v2/common/bridgefingerprint"
 
 	"git.torproject.org/pluggable-transports/snowflake.git/v2/common/nat"
 )
@@ -106,7 +106,8 @@ func DecodeClientPollRequest(data []byte) (*ClientPollRequest, error) {
 	if message.Fingerprint == "" {
 		message.Fingerprint = defaultBridgeFingerprint
 	}
-	if hex.DecodedLen(len(message.Fingerprint)) != 20 {
+
+	if _, err := bridgefingerprint.FingerprintFromHexString(message.Fingerprint); err != nil {
 		return nil, fmt.Errorf("cannot decode fingerprint")
 	}
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tor-commits mailing list