[tor-commits] [snowflake-webext/master] Only extract remote address from peer SDP

cohosh at torproject.org cohosh at torproject.org
Mon Oct 5 19:55:52 UTC 2020


commit e0f00904102b76af0f8b3cdbb40d8ee45f1018f4
Author: Cecylia Bocovich <cohosh at torproject.org>
Date:   Wed Sep 30 15:08:54 2020 -0400

    Only extract remote address from peer SDP
    
    We need to extract the remote address of the client to pass along to the
    bridge. This adds an extra check to see whether the retrieved address is
    a remote address (as opposed to local, loopback, or unspecified). It
    also expands the SDP regexes to check for addresses in the ice
    candidates.
    
    This fixes issue #16
---
 spec/util.spec.js | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 util.js           |  43 +++++++++++++++++---
 2 files changed, 152 insertions(+), 5 deletions(-)

diff --git a/spec/util.spec.js b/spec/util.spec.js
index a15c201..687ae98 100644
--- a/spec/util.spec.js
+++ b/spec/util.spec.js
@@ -136,6 +136,15 @@ describe('Parse', function() {
         sdp: "v=0\no=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\ns=SDP Seminar\ni=A Seminar on the session description protocol\nu=http://www.example.com/seminars/sdp.pdf\ne=j.doe@example.com (Jane Doe)\nc=IN IP4 224.2.17.12/127\nt=2873397496 2873404696\na=recvonly\nm=audio 49170 RTP/AVP 0\nm=video 51372 RTP/AVP 99\na=rtpmap:99 h263-1998/90000",
         expected: '224.2.17.12'
       },
+      {
+        // local addresses only
+        sdp: "v=0\no=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\ns=SDP Seminar\ni=A Seminar on the session description protocol\nu=http://www.example.com/seminars/sdp.pdf\ne=j.doe@example.com (Jane Doe)\nc=IN IP4 10.47.16.5\nt=2873397496 2873404696\na=recvonly\nm=audio 49170 RTP/AVP 0\nm=video 51372 RTP/AVP 99\na=rtpmap:99 h263-1998/90000",
+        expected: void 0
+      },
+      {
+        sdp: "v=0\no=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\ns=SDP Seminar\ni=A Seminar on the session description protocol\nu=http://www.example.com/seminars/sdp.pdf\ne=j.doe@example.com (Jane Doe)\nc=IN IP4 10.47.16.5\na=candidate:3581707038 1 udp 2122260223 192.168.0.1 54653 typ host generation 0 network-id 1 network-cost 50\na=candidate:2617212910 1 tcp 1518280447 192.168.0.1 59673 typ host tcptype passive generation 0 network-id 1 network-cost 50\na=candidate:2082671819 1 udp 1686052607 1.2.3.4 54653 typ srflx raddr 192.168.0.1 rport 54653 generation 0 network-id 1 network-cost 50\nt=2873397496 2873404696\na=recvonly\nm=audio 49170 RTP/AVP 0\nm=video 51372 RTP/AVP 99\na=rtpmap:99 h263-1998/90000",
+        expected: '1.2.3.4'
+      },
       {
         // Missing c= line
         sdp: "v=0\no=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\ns=SDP Seminar\ni=A Seminar on the session description protocol\nu=http://www.example.com/seminars/sdp.pdf\ne=j.doe@example.com (Jane Doe)\nt=2873397496 2873404696\na=recvonly\nm=audio 49170 RTP/AVP 0\nm=video 51372 RTP/AVP 99\na=rtpmap:99 h263-1998/90000",
@@ -235,6 +244,111 @@ describe('Parse', function() {
       }
     });
   });
+  describe('isRemoteIP', function() {
+
+    var testCases = [
+      {
+        ip: "127.0.0.1",
+        expected: false
+      },
+      {
+        ip: "::1",
+        expected: false
+      },
+      {
+        ip: "0::1",
+        expected: false
+      },
+      {
+        ip: "192.168.1.1",
+        expected: false
+      },
+      {
+        ip: "10.0.0.0",
+        expected: false
+      },
+      {
+        ip: "172.16.1.1",
+        expected: false
+      },
+      {
+        ip: "172.15.1.1",
+        expected: true
+      },
+      {
+        ip: "100.63.1.1",
+        expected: true
+      },
+      {
+        ip: "100.64.1.1",
+        expected: false
+      },
+      {
+        ip: "100.127.255.255",
+        expected: false
+      },
+      {
+        ip: "100.128.0.0",
+        expected: true
+      },
+      {
+        ip: "169.254.0.0",
+        expected: false
+      },
+      {
+        ip: "169.244.0.1",
+        expected: true
+      },
+      {
+        ip: "fc00::",
+        expected: false
+      },
+      {
+        ip: "fdff::0",
+        expected: false
+      },
+      {
+        ip: "ff00::0",
+        expected: true
+      },
+      {
+        ip: "0.0.0.0",
+        expected: false
+      },
+      {
+        ip: "::",
+        expected: false
+      },
+      {
+        ip: "::0",
+        expected: false
+      },
+      {
+        ip: "0::0",
+        expected: false
+      },
+      {
+        ip: "0::",
+        expected: false
+      },
+      {
+        ip: "ff15::101",
+        expected: true
+      },
+      {
+        ip: "1.2.3.4",
+        expected: true
+      }
+    ];
+    it('finds local addresses', function() {
+      var i, len, ref, ref1, results, test;
+      results = [];
+      for (i = 0, len = testCases.length; i < len; i++) {
+        test = testCases[i];
+        expect(Parse.isRemoteIP(test.ip)).toEqual(test.expected);
+      }
+    });
+  });
 });
 
 describe('Params', function() {
diff --git a/util.js b/util.js
index 0199ae8..ee36478 100644
--- a/util.js
+++ b/util.js
@@ -133,17 +133,26 @@ class Parse {
     return count * multiplier;
   }
 
-  // Parse a connection-address out of the "c=" Connection Data field of a
-  // session description. Return undefined if none is found.
+  //Parse a remote connection-address out of the "c=" Connection Data field
+  // or the "a=" attribute fields of the session description.
+  // Return undefined if none is found.
   // https://tools.ietf.org/html/rfc4566#section-5.7
+  // https://tools.ietf.org/html/rfc5245#section-15
   static ipFromSDP(sdp) {
     var i, len, m, pattern, ref;
-    ref = [/^c=IN IP4 ([\d.]+)(?:(?:\/\d+)?\/\d+)?(:? |$)/m, /^c=IN IP6 ([0-9A-Fa-f:.]+)(?:\/\d+)?(:? |$)/m];
+    console.log(sdp);
+    ref = [
+      /^a=candidate:[a-zA-Z0-9+/]+ \d+ udp \d+ ([\d.]+) /mg,
+      /^a=candidate:[a-zA-Z0-9+/]+ \d+ udp \d+ ([0-9A-Fa-f:.]+) /mg,
+      /^c=IN IP4 ([\d.]+)(?:(?:\/\d+)?\/\d+)?(:? |$)/mg,
+      /^c=IN IP6 ([0-9A-Fa-f:.]+)(?:\/\d+)?(:? |$)/mg
+    ];
     for (i = 0, len = ref.length; i < len; i++) {
       pattern = ref[i];
       m = pattern.exec(sdp);
-      if (m != null) {
-        return m[1];
+      while (m != null) {
+        if(Parse.isRemoteIP(m[1])) return m[1];
+        m = pattern.exec(sdp);
       }
     }
   }
@@ -160,6 +169,30 @@ class Parse {
     return null;
   }
 
+  // Determine whether an IP address is a local, unspecified, or loopback address
+  static isRemoteIP(ip) {
+    if (ip.includes(":")) {
+      var ip6 = ip.split(':');
+      // Loopback address
+      var loopback = /^(?:0*:)*?:?0*1$/m;
+      // Unspecified address
+      var unspecified = /^(?:0*:)*?:?0*$/m;
+      // Local IPv6 addresses are defined in https://tools.ietf.org/html/rfc4193
+      return !((loopback.exec(ip) != null) || (unspecified.exec(ip) != null) ||
+        (parseInt(ip6[0],16)&0xfe00) == 0xfc00);
+    }
+
+    // Local IPv4 addresses are defined in https://tools.ietf.org/html/rfc1918
+    var ip4 = ip.split('.');
+    return !(ip4[0] == 10 || ip4[0] == 127 || ip == "0.0.0.0" ||
+      (ip4[0] == 172 && (ip4[1]&0xf0) == 16) ||
+      (ip4[0] == 192 && ip4[1] == 168) ||
+      // Carrier-Grade NAT as per https://tools.ietf.org/htm/rfc6598
+      (ip4[0] == 100 && (ip4[1]&0xc0) == 64) ||
+      // Dynamic Configuration as per https://tools.ietf.org/htm/rfc3927
+      (ip4[0] == 169 && ip4[1] == 254));
+  }
+
 }
 
 



More information about the tor-commits mailing list