[tor-commits] [pluggable-transports/snowflake] 02/03: Forward bridge fingerprint

gitolite role git at cupani.torproject.org
Mon Mar 21 19:37:17 UTC 2022


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

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

commit b563141c6abba128386bc1ad18122d5e13e09789
Author: Arlo Breault <arlolra at gmail.com>
AuthorDate: Tue Mar 8 16:27:52 2022 -0500

    Forward bridge fingerprint
    
    gitlab 28651
---
 broker/broker.go          |  7 ++++---
 broker/ipc.go             |  5 +++--
 client/lib/rendezvous.go  |  7 +++++--
 client/lib/snowflake.go   |  3 +++
 client/snowflake.go       |  3 +++
 client/torrc              |  2 +-
 common/messages/client.go | 25 ++++++++++++++++++++++---
 7 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/broker/broker.go b/broker/broker.go
index 7a29265..6e85fbd 100644
--- a/broker/broker.go
+++ b/broker/broker.go
@@ -139,10 +139,11 @@ func (ctx *BrokerContext) AddSnowflake(id string, proxyType string, natType stri
 	return snowflake
 }
 
-// Client offer contains an SDP and the NAT type of the client
+// Client offer contains an SDP, bridge fingerprint and the NAT type of the client
 type ClientOffer struct {
-	natType string
-	sdp     []byte
+	natType     string
+	sdp         []byte
+	fingerprint string
 }
 
 func main() {
diff --git a/broker/ipc.go b/broker/ipc.go
index 5cc595b..2ef4ccd 100644
--- a/broker/ipc.go
+++ b/broker/ipc.go
@@ -130,8 +130,9 @@ func (i *IPC) ClientOffers(arg messages.Arg, response *[]byte) error {
 	}
 
 	offer := &ClientOffer{
-		natType: req.NAT,
-		sdp:     []byte(req.Offer),
+		natType:     req.NAT,
+		sdp:         []byte(req.Offer),
+		fingerprint: req.Fingerprint,
 	}
 
 	// Only hand out known restricted snowflakes to unrestricted clients
diff --git a/client/lib/rendezvous.go b/client/lib/rendezvous.go
index d908b77..38e4620 100644
--- a/client/lib/rendezvous.go
+++ b/client/lib/rendezvous.go
@@ -43,6 +43,7 @@ type BrokerChannel struct {
 	keepLocalAddresses bool
 	natType            string
 	lock               sync.Mutex
+	BridgeFingerprint  string
 }
 
 // We make a copy of DefaultTransport because we want the default Dial
@@ -92,6 +93,7 @@ func newBrokerChannelFromConfig(config ClientConfig) (*BrokerChannel, error) {
 		Rendezvous:         rendezvous,
 		keepLocalAddresses: config.KeepLocalAddresses,
 		natType:            nat.NATUnknown,
+		BridgeFingerprint:  config.BridgeFingerprint,
 	}, nil
 }
 
@@ -116,8 +118,9 @@ func (bc *BrokerChannel) Negotiate(offer *webrtc.SessionDescription) (
 	// Encode the client poll request.
 	bc.lock.Lock()
 	req := &messages.ClientPollRequest{
-		Offer: offerSDP,
-		NAT:   bc.natType,
+		Offer:       offerSDP,
+		NAT:         bc.natType,
+		Fingerprint: bc.BridgeFingerprint,
 	}
 	encReq, err := req.EncodeClientPollRequest()
 	bc.lock.Unlock()
diff --git a/client/lib/snowflake.go b/client/lib/snowflake.go
index 1b236a6..dd78c12 100644
--- a/client/lib/snowflake.go
+++ b/client/lib/snowflake.go
@@ -103,6 +103,9 @@ type ClientConfig struct {
 	// UTLSRemoveSNI is the flag to control whether SNI should be removed from Client Hello
 	// when uTLS is used.
 	UTLSRemoveSNI bool
+	// BridgeFingerprint is the fingerprint of the bridge that the client will eventually
+	// connect to, as specified in the Bridge line of the torrc.
+	BridgeFingerprint string
 }
 
 // NewSnowflakeClient creates a new Snowflake transport client that can spawn multiple
diff --git a/client/snowflake.go b/client/snowflake.go
index 5856750..33834ad 100644
--- a/client/snowflake.go
+++ b/client/snowflake.go
@@ -95,6 +95,9 @@ func socksAcceptLoop(ln *pt.SocksListener, config sf.ClientConfig, shutdown chan
 			if arg, ok := conn.Req.Args.Get("utls-imitate"); ok {
 				config.UTLSClientID = arg
 			}
+			if arg, ok := conn.Req.Args.Get("fingerprint"); ok {
+				config.BridgeFingerprint = arg
+			}
 			transport, err := sf.NewSnowflakeClient(config)
 			if err != nil {
 				conn.Reject()
diff --git a/client/torrc b/client/torrc
index 039653f..aee4df1 100644
--- a/client/torrc
+++ b/client/torrc
@@ -3,6 +3,6 @@ DataDirectory datadir
 
 ClientTransportPlugin snowflake exec ./client -log snowflake.log
 
-Bridge snowflake 192.0.2.3:1 url=https://snowflake-broker.torproject.net.global.prod.fastly.net/ front=cdn.sstatic.net ice=stun:stun.voip.blackberry.com:3478,stun:stun.altar.com.pl:3478,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.com:3478,stun:stun.sonetel.net:3478,stun:stun.stunprotocol.org:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.voys.nl:3478
+Bridge snowflake 192.0.2.3:1 2B280B23E1107BB62ABFC40DDCC8824814F80A72 fingerprint=2B280B23E1107BB62ABFC40DDCC8824814F80A72 url=https://snowflake-broker.torproject.net.global.prod.fastly.net/ front=cdn.sstatic.net ice=stun:stun.voip.blackberry.com:3478,stun:stun.altar.com.pl:3478,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.com:3478,stun:stun.sonetel.net:3478,stun:stun.stunprotocol.org:3478,stun:stun.uls.co.za:3478 [...]
 
 SocksPort auto
diff --git a/common/messages/client.go b/common/messages/client.go
index b6155f7..4d435ab 100644
--- a/common/messages/client.go
+++ b/common/messages/client.go
@@ -29,10 +29,13 @@ each encoded in JSON format
 {
   offer: <sdp offer>
   [nat: (unknown|restricted|unrestricted)]
+  [fingerprint: <fingerprint string>]
 }
 
 The NAT field is optional, and if it is missing a
-value of "unknown" will be assumed.
+value of "unknown" will be assumed.  The fingerprint
+is also optional and, if absent, will be assigned the
+fingerprint of the default bridge.
 
 == ClientPollResponse ==
 <poll response> :=
@@ -49,13 +52,25 @@ for the error.
 
 */
 
+// The bridge fingerprint to assume, for client poll requests that do not
+// specify a fingerprint.  Before #28651, there was only one bridge with one
+// fingerprint, which all clients expected to be connected to implicitly.
+// If a client is old enough that it does not specify a fingerprint, this is
+// the fingerprint it expects.  Clients that do set a fingerprint in the
+// SOCKS params will also be assumed to want to connect to the default bridge.
+const defaultBridgeFingerprint = "2B280B23E1107BB62ABFC40DDCC8824814F80A72"
+
 type ClientPollRequest struct {
-	Offer string `json:"offer"`
-	NAT   string `json:"nat"`
+	Offer       string `json:"offer"`
+	NAT         string `json:"nat"`
+	Fingerprint string `json:"fingerprint"`
 }
 
 // Encodes a poll message from a snowflake client
 func (req *ClientPollRequest) EncodeClientPollRequest() ([]byte, error) {
+	if req.Fingerprint == "" {
+		req.Fingerprint = defaultBridgeFingerprint
+	}
 	body, err := json.Marshal(req)
 	if err != nil {
 		return nil, err
@@ -87,6 +102,10 @@ func DecodeClientPollRequest(data []byte) (*ClientPollRequest, error) {
 		return nil, fmt.Errorf("no supplied offer")
 	}
 
+	if message.Fingerprint == "" {
+		message.Fingerprint = defaultBridgeFingerprint
+	}
+
 	switch message.NAT {
 	case "":
 		message.NAT = nat.NATUnknown

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


More information about the tor-commits mailing list