The attached patch, instead of refusing to connect to clients on
unusual ports (which is apparently not that unusual these days), meets
the firewall requirements for allowed outgoing connects by limiting
connects to be from a specified range of source ports.  This means no
client is ignore due to the port it is on, but still makes a
restrictive firewall possible, by allowing the firewall designer to
specify the allowed source ports.  In shorewall I use:

# Allow 50000-55600 as source port out, for use by BitTorrent
ACCEPT           $FW           inet      tcp     -      55000:55600

and --min_outgoing_port 55000 --max_outgoing_port 55600

when calling bittorrent.



-- 
And that's my crabbing done for the day.  Got it out of the way early, 
now I have the rest of the afternoon to sniff fragrant tea-roses or 
strangle cute bunnies or something.   -- Michael Devore
GnuPG Key Fingerprint 86 F5 81 A5 D4 2E 1F 1C      http://gnupg.org
No more sea shells:  Daniel's Weblog    http://cshore.wordpress.com
diff -Naur bittorrent_3.4.2-11/BitTorrent/download.py bittorrent-3.4.2/BitTorrent/download.py
--- bittorrent_3.4.2-11/BitTorrent/download.py	2004-04-02 23:10:45.000000000 -0500
+++ bittorrent-3.4.2/BitTorrent/download.py	2008-05-31 17:59:09.000000000 -0400
@@ -92,6 +92,10 @@
         "the number of uploads to fill out to with extra optimistic unchokes"),
     ('report_hash_failures', 0,
         "whether to inform the user that hash failures occur. They're non-fatal."),
+    ('min_outgoing_port', 1024,
+        "lowest port from which we are allowed to connect"),
+    ('max_outgoing_port', 65535,
+        "highest port from which we are allowed to connect"),
     ]
 
 def download(params, filefunc, statusfunc, finfunc, errorfunc, doneflag, cols, pathFunc = None, paramfunc = None, spewflag = Event()):
@@ -197,7 +201,7 @@
         doneflag.set()
         if reason is not None:
             errorfunc(reason)
-    rawserver = RawServer(doneflag, config['timeout_check_interval'], config['timeout'], errorfunc = errorfunc, maxconnects = config['max_allow_in'])
+    rawserver = RawServer(doneflag, config['timeout_check_interval'], config['timeout'], errorfunc = errorfunc, maxconnects = config['max_allow_in'], min_outgoing_port = config['min_outgoing_port'], max_outgoing_port = config['max_outgoing_port'] )
     try:
         try:
             storage = Storage(files, open, path.exists, path.getsize)
@@ -242,6 +246,13 @@
         errorfunc("Couldn't listen - " + str(e))
         return
 
+    if config['min_outgoing_port'] < 1024 or config['max_outgoing_port'] > 65535:
+        errorfunc("We can only connect to peers using ports between 1024 and 65535")
+        return
+    if config['min_outgoing_port'] > config['max_outgoing_port']:
+        errorfunc("max_outgoing_port less than min_outgoing_port; can't connect")
+        return
+
     choker = Choker(config['max_uploads'], rawserver.add_task, finflag.isSet, 
         config['min_uploads'])
     upmeasure = Measure(config['max_rate_period'], 
diff -Naur bittorrent_3.4.2-11/BitTorrent/RawServer.py bittorrent-3.4.2/BitTorrent/RawServer.py
--- bittorrent_3.4.2-11/BitTorrent/RawServer.py	2008-05-22 21:58:42.000000000 -0400
+++ bittorrent-3.4.2/BitTorrent/RawServer.py	2008-05-31 18:15:27.000000000 -0400
@@ -80,7 +80,7 @@
 
 class RawServer:
     def __init__(self, doneflag, timeout_check_interval, timeout, noisy = True,
-            errorfunc = default_error_handler, maxconnects = 55):
+            errorfunc = default_error_handler, maxconnects = 55, min_outgoing_port = 1024, max_outgoing_port = 65535):
         self.timeout_check_interval = timeout_check_interval
         self.timeout = timeout
         self.poll = poll()
@@ -92,6 +92,8 @@
         self.errorfunc = errorfunc
         self.maxconnects = maxconnects
         self.funcs = []
+        self.min_outgoing_port = min_outgoing_port
+        self.max_outgoing_port = max_outgoing_port
         self.unscheduled_tasks = []
         self.add_task(self.scan_for_timeouts, timeout_check_interval)
 
@@ -133,7 +135,14 @@
             sock.setsockopt(socket.IPPROTO_IP, socket.IP_TOS, 32)
         except:
             pass
-        sock.bind((self.bindaddr, 0))
+        for out_port in xrange(max_outgoing_port, min_outgoing_port - 1, -1):
+            was_bound = True
+            try:
+                sock.bind((self.bindaddr, out_port))
+            except:
+                was_bound = False
+            if was_bound:
+                break
         try:
             sock.connect_ex(dns)
         except socket.error:
diff -Naur bittorrent_3.4.2-11/debian/changelog bittorrent-3.4.2/debian/changelog
--- bittorrent_3.4.2-11/debian/changelog	2008-05-22 21:58:42.000000000 -0400
+++ bittorrent-3.4.2/debian/changelog	2008-05-31 18:20:43.000000000 -0400
@@ -1,3 +1,10 @@
+bittorrent (3.4.2-11.1~dfd9) unstable; urgency=low
+
+  * Add outgoing port range limiting in order to play well with strict 
+    firewalls.  Closes: #481276
+
+ -- Daniel Dickinson <[EMAIL PROTECTED]>  Sat, 31 May 2008 18:20:38 -0500
+
 bittorrent (3.4.2-11) unstable; urgency=low
 
   * Add LSB logging functionality. (thanks David!) Closes: #384724

Attachment: signature.asc
Description: PGP signature

Reply via email to