3
3
import re
4
4
import signal
5
5
import time
6
- import sshuttle . compat . ssubprocess as ssubprocess
7
- import helpers
6
+ import subprocess as ssubprocess
7
+ import sshuttle . helpers as helpers
8
8
import os
9
9
import sshuttle .ssnet as ssnet
10
10
import sshuttle .ssh as ssh
11
- import ssyslog
11
+ import sshuttle . ssyslog as ssyslog
12
12
import sys
13
13
from sshuttle .ssnet import SockWrapper , Handler , Proxy , Mux , MuxWrapper
14
14
from sshuttle .helpers import log , debug1 , debug2 , debug3 , Fatal , islocal , \
@@ -124,7 +124,7 @@ def check_daemon(pidfile):
124
124
_pidname = os .path .abspath (pidfile )
125
125
try :
126
126
oldpid = open (_pidname ).read (1024 )
127
- except IOError , e :
127
+ except IOError as e :
128
128
if e .errno == errno .ENOENT :
129
129
return # no pidfile, ok
130
130
else :
@@ -138,7 +138,7 @@ def check_daemon(pidfile):
138
138
return # invalid pidfile, ok
139
139
try :
140
140
os .kill (oldpid , 0 )
141
- except OSError , e :
141
+ except OSError as e :
142
142
if e .errno == errno .ESRCH :
143
143
os .unlink (_pidname )
144
144
return # outdated pidfile, ok
@@ -157,7 +157,7 @@ def daemonize():
157
157
if os .fork ():
158
158
os ._exit (0 )
159
159
160
- outfd = os .open (_pidname , os .O_WRONLY | os .O_CREAT | os .O_EXCL , 0666 )
160
+ outfd = os .open (_pidname , os .O_WRONLY | os .O_CREAT | os .O_EXCL , 0o666 )
161
161
try :
162
162
os .write (outfd , '%d\n ' % os .getpid ())
163
163
finally :
@@ -179,7 +179,7 @@ def daemonize():
179
179
def daemon_cleanup ():
180
180
try :
181
181
os .unlink (_pidname )
182
- except OSError , e :
182
+ except OSError as e :
183
183
if e .errno == errno .ENOENT :
184
184
pass
185
185
else :
@@ -215,7 +215,7 @@ def original_dst(sock):
215
215
assert (socket .htons (proto ) == socket .AF_INET )
216
216
ip = '%d.%d.%d.%d' % (a , b , c , d )
217
217
return (ip , port )
218
- except socket .error , e :
218
+ except socket .error as e :
219
219
if e .args [0 ] == errno .ENOPROTOOPT :
220
220
return sock .getsockname ()
221
221
raise
@@ -251,7 +251,7 @@ def listen(self, backlog):
251
251
if self .v4 :
252
252
try :
253
253
self .v4 .listen (backlog )
254
- except socket .error , e :
254
+ except socket .error as e :
255
255
# on some systems v4 bind will fail if the v6 suceeded,
256
256
# in this case the v6 socket will receive v4 too.
257
257
if e .errno == errno .EADDRINUSE and self .v6 :
@@ -321,17 +321,22 @@ def setup():
321
321
self .p = ssubprocess .Popen (argv , stdout = s1 , preexec_fn = setup )
322
322
e = None
323
323
break
324
- except OSError , e :
324
+ except OSError as e :
325
325
pass
326
326
self .argv = argv
327
327
s1 .close ()
328
- self .pfile = s2 .makefile ('wb+' )
328
+ if sys .version_info < (3 , 0 ):
329
+ # python 2.7
330
+ self .pfile = s2 .makefile ('wb+' )
331
+ else :
332
+ # python 3.5
333
+ self .pfile = s2 .makefile ('rwb' )
329
334
if e :
330
335
log ('Spawning firewall manager: %r\n ' % self .argv )
331
336
raise Fatal (e )
332
337
line = self .pfile .readline ()
333
338
self .check ()
334
- if line [0 :5 ] != 'READY' :
339
+ if line [0 :5 ] != b 'READY' :
335
340
raise Fatal ('%r expected READY, got %r' % (self .argv , line ))
336
341
self .method = line [6 :- 1 ]
337
342
@@ -341,22 +346,26 @@ def check(self):
341
346
raise Fatal ('%r returned %d' % (self .argv , rv ))
342
347
343
348
def start (self ):
344
- self .pfile .write ('ROUTES\n ' )
345
- for (family , ip , width ) in self .subnets_include + self .auto_nets :
346
- self .pfile .write ('%d,%d,0,%s\n ' % (family , width , ip ))
347
- for (family , ip , width ) in self .subnets_exclude :
348
- self .pfile .write ('%d,%d,1,%s\n ' % (family , width , ip ))
349
- self .pfile .write ('GO\n ' )
349
+ self .pfile .write (b'ROUTES\n ' )
350
+ try :
351
+ for (family , ip , width ) in self .subnets_include + self .auto_nets :
352
+ self .pfile .write (b'%d,%d,0,%s\n ' % (family , width , ip .encode ("ASCII" )))
353
+ for (family , ip , width ) in self .subnets_exclude :
354
+ self .pfile .write (b'%d,%d,1,%s\n ' % (family , width , ip .encode ("ASCII" )))
355
+ except Exception as e :
356
+ debug1 ("exception occured %r" % e )
357
+ raise
358
+ self .pfile .write (b'GO\n ' )
350
359
self .pfile .flush ()
351
360
line = self .pfile .readline ()
352
361
self .check ()
353
- if line != 'STARTED\n ' :
362
+ if line != b 'STARTED\n ' :
354
363
raise Fatal ('%r expected STARTED, got %r' % (self .argv , line ))
355
364
356
365
def sethostip (self , hostname , ip ):
357
366
assert (not re .search (r'[^-\w]' , hostname ))
358
367
assert (not re .search (r'[^0-9.]' , ip ))
359
- self .pfile .write ('HOST %s,%s\n ' % (hostname , ip ))
368
+ self .pfile .write (b 'HOST %s,%s\n ' % (hostname , ip ))
360
369
self .pfile .flush ()
361
370
362
371
def done (self ):
@@ -390,7 +399,7 @@ def onaccept_tcp(listener, method, mux, handlers):
390
399
global _extra_fd
391
400
try :
392
401
sock , srcip = listener .accept ()
393
- except socket .error , e :
402
+ except socket .error as e :
394
403
if e .args [0 ] in [errno .EMFILE , errno .ENFILE ]:
395
404
debug1 ('Rejected incoming connection: too many open files!\n ' )
396
405
# free up an fd so we can eat the connection
@@ -403,9 +412,9 @@ def onaccept_tcp(listener, method, mux, handlers):
403
412
return
404
413
else :
405
414
raise
406
- if method == "tproxy" :
415
+ if method == b "tproxy" :
407
416
dstip = sock .getsockname ()
408
- elif method == "pf" :
417
+ elif method == b "pf" :
409
418
dstip = pf_dst (sock )
410
419
else :
411
420
dstip = original_dst (sock )
@@ -420,8 +429,8 @@ def onaccept_tcp(listener, method, mux, handlers):
420
429
log ('warning: too many open channels. Discarded connection.\n ' )
421
430
sock .close ()
422
431
return
423
- mux .send (chan , ssnet .CMD_TCP_CONNECT , '%d,%s,%s ' %
424
- (sock .family , dstip [0 ], dstip [1 ]))
432
+ mux .send (chan , ssnet .CMD_TCP_CONNECT , b '%d,%s,%d ' %
433
+ (sock .family , dstip [0 ]. encode ( "ASCII" ) , dstip [1 ]))
425
434
outwrap = MuxWrapper (mux , chan )
426
435
handlers .append (Proxy (SockWrapper (sock , sock ), outwrap ))
427
436
expire_connections (time .time (), mux )
@@ -439,7 +448,7 @@ def udp_done(chan, data, method, family, dstip):
439
448
sender .bind (srcip )
440
449
sender .sendto (data , dstip )
441
450
sender .close ()
442
- except socket .error , e :
451
+ except socket .error as e :
443
452
debug1 ('-- ignored socket error sending UDP data: %r\n ' % e )
444
453
445
454
@@ -471,7 +480,7 @@ def dns_done(chan, data, method, sock, srcip, dstip, mux):
471
480
debug3 ('dns_done: channel=%d src=%r dst=%r\n ' % (chan , srcip , dstip ))
472
481
del mux .channels [chan ]
473
482
del dnsreqs [chan ]
474
- if method == "tproxy" :
483
+ if method == b "tproxy" :
475
484
debug3 ('doing send from %r to %r\n ' % (srcip , dstip ,))
476
485
sender = socket .socket (sock .family , socket .SOCK_DGRAM )
477
486
sender .setsockopt (socket .SOL_SOCKET , socket .SO_REUSEADDR , 1 )
@@ -487,7 +496,7 @@ def dns_done(chan, data, method, sock, srcip, dstip, mux):
487
496
def ondns (listener , method , mux , handlers ):
488
497
now = time .time ()
489
498
srcip , dstip , data = recv_udp (listener , 4096 )
490
- if method == "tproxy" and not dstip :
499
+ if method == b "tproxy" and not dstip :
491
500
debug1 (
492
501
"-- ignored UDP from %r: "
493
502
"couldn't determine destination IP address\n " % (srcip ,))
@@ -517,25 +526,25 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
517
526
ssh_cmd , remotename , python ,
518
527
stderr = ssyslog ._p and ssyslog ._p .stdin ,
519
528
options = dict (latency_control = latency_control , method = method ))
520
- except socket .error , e :
529
+ except socket .error as e :
521
530
if e .args [0 ] == errno .EPIPE :
522
531
raise Fatal ("failed to establish ssh session (1)" )
523
532
else :
524
533
raise
525
534
mux = Mux (serversock , serversock )
526
535
handlers .append (mux )
527
536
528
- expected = 'SSHUTTLE0001'
537
+ expected = b 'SSHUTTLE0001'
529
538
530
539
try :
531
540
v = 'x'
532
- while v and v != '\0 ' :
541
+ while v and v != b '\0 ' :
533
542
v = serversock .recv (1 )
534
543
v = 'x'
535
- while v and v != '\0 ' :
544
+ while v and v != b '\0 ' :
536
545
v = serversock .recv (1 )
537
546
initstring = serversock .recv (len (expected ))
538
- except socket .error , e :
547
+ except socket .error as e :
539
548
if e .args [0 ] == errno .ECONNRESET :
540
549
raise Fatal ("failed to establish ssh session (2)" )
541
550
else :
@@ -549,7 +558,7 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
549
558
raise Fatal ('expected server init string %r; got %r'
550
559
% (expected , initstring ))
551
560
debug1 ('connected.\n ' )
552
- print 'Connected.'
561
+ print ( 'Connected.' )
553
562
sys .stdout .flush ()
554
563
if daemon :
555
564
daemonize ()
@@ -616,15 +625,15 @@ def main(listenip_v6, listenip_v4,
616
625
if daemon :
617
626
try :
618
627
check_daemon (pidfile )
619
- except Fatal , e :
628
+ except Fatal as e :
620
629
log ("%s\n " % e )
621
630
return 5
622
631
debug1 ('Starting sshuttle proxy.\n ' )
623
632
624
633
if recvmsg is not None :
625
634
debug1 ("recvmsg %s support enabled.\n " % recvmsg )
626
635
627
- if method == "tproxy" :
636
+ if method == b "tproxy" :
628
637
if recvmsg is not None :
629
638
debug1 ("tproxy UDP support enabled.\n " )
630
639
udp = True
@@ -643,7 +652,7 @@ def main(listenip_v6, listenip_v4,
643
652
ports = [0 , ]
644
653
else :
645
654
# if at least one port missing, we have to search
646
- ports = xrange (12300 , 9000 , - 1 )
655
+ ports = range (12300 , 9000 , - 1 )
647
656
648
657
# search for free ports and try to bind
649
658
last_e = None
@@ -688,7 +697,7 @@ def main(listenip_v6, listenip_v4,
688
697
udp_listener .bind (lv6 , lv4 )
689
698
bound = True
690
699
break
691
- except socket .error , e :
700
+ except socket .error as e :
692
701
if e .errno == errno .EADDRINUSE :
693
702
last_e = e
694
703
else :
@@ -708,7 +717,7 @@ def main(listenip_v6, listenip_v4,
708
717
nslist += resolvconf_nameservers ()
709
718
# search for spare port for DNS
710
719
debug2 ('Binding DNS:' )
711
- ports = xrange (12300 , 9000 , - 1 )
720
+ ports = range (12300 , 9000 , - 1 )
712
721
for port in ports :
713
722
debug2 (' %d' % port )
714
723
dns_listener = MultiListener (socket .SOCK_DGRAM )
@@ -731,7 +740,7 @@ def main(listenip_v6, listenip_v4,
731
740
dns_listener .bind (lv6 , lv4 )
732
741
bound = True
733
742
break
734
- except socket .error , e :
743
+ except socket .error as e :
735
744
if e .errno == errno .EADDRINUSE :
736
745
last_e = e
737
746
else :
@@ -750,7 +759,7 @@ def main(listenip_v6, listenip_v4,
750
759
subnets_exclude , dnsport_v6 , dnsport_v4 , nslist ,
751
760
method , udp )
752
761
753
- if fw .method == "tproxy" :
762
+ if fw .method == b "tproxy" :
754
763
tcp_listener .setsockopt (socket .SOL_IP , IP_TRANSPARENT , 1 )
755
764
if udp_listener :
756
765
udp_listener .setsockopt (socket .SOL_IP , IP_TRANSPARENT , 1 )
@@ -767,7 +776,7 @@ def main(listenip_v6, listenip_v4,
767
776
if dns_listener .v6 is not None :
768
777
dns_listener .v6 .setsockopt (SOL_IPV6 , IPV6_RECVORIGDSTADDR , 1 )
769
778
770
- if fw .method == "pf" :
779
+ if fw .method == b "pf" :
771
780
global pf_command_file
772
781
pf_command_file = fw .pfile
773
782
0 commit comments