@@ -444,6 +444,19 @@ def starttls (self):
444
444
access afterwards. The variables that are required at
445
445
this point are service and, already obliged when making
446
446
a new instance, cryptfd.
447
+
448
+ Quoting the library documentation on file handles and
449
+ who should close them:
450
+
451
+ The cryptfd handle supplies the TLS connection that is
452
+ assumed to have been setup. When the function ends,
453
+ either in success or failure, this handle will no longer
454
+ be available to the caller; the responsibility of closing
455
+ it is passed on to the function and/or the TLS Pool.
456
+
457
+ And on plainfd: The file handle returned [in privdata],
458
+ if it is >= 0, should be closed by the caller, both in
459
+ case of success and failure.
447
460
"""
448
461
assert (self .cryptsk is not None )
449
462
assert (self .cryptfd >= 0 )
@@ -463,12 +476,18 @@ def starttls (self):
463
476
socktp = socket .SOCK_STREAM
464
477
plainsockptr = socket_data ()
465
478
plainsockptr .unix_socket = self .plainfd
479
+ # Clone cryptfd so _starttls() and Python can each close it
480
+ unix_cryptfd = os .dup (self .cryptfd )
481
+ if unix_cryptfd < 0 :
482
+ _tlspool .raise_errno ()
483
+ # We close cryptsk now and it will not repeat during garbage collection
484
+ self .cryptsk .close ()
485
+ self .cryptsk = None
486
+ self .cryptfd = - 1
466
487
# Provide None for the callback function, SWIG won't support it
467
488
# We might at some point desire a library of C routine options?
468
- rv = _starttls (self . cryptfd , self .tlsdata , plainsockptr , None )
489
+ rv = _starttls (unix_cryptfd , self .tlsdata , plainsockptr , None )
469
490
self .plainfd = - 1
470
- self .cryptfd = - 1
471
- self .cryptsk = None
472
491
if rv < 0 :
473
492
_tlspool .raise_errno ()
474
493
if self .plainsk is None :
@@ -612,17 +631,24 @@ def starttls (self):
612
631
socktp = socket .SOCK_STREAM
613
632
plainsockptr = socket_data ()
614
633
plainsockptr .unix_socket = - 1
615
- rv = _starttls (sox .fileno (), self .tlsdata , plainsockptr , None )
634
+ unix_sox = os .dup (sox .fileno ())
635
+ if unix_sox < 0 :
636
+ _tlspool .raise_errno ()
637
+ sox .close ()
638
+ rv = _starttls (unix_sox , self .tlsdata , plainsockptr , None )
616
639
if rv < 0 :
617
640
_tlspool .raise_errno ()
618
641
assert (plainsockptr .unix_socket >= 0 )
619
642
sox2 = socket .fromfd (plainsockptr .unix_socket , af , socktp )
643
+ # Now, since socket.fromfd() used os.dup(), we close the original
644
+ os .close (plainsockptr .unix_socket )
645
+ plainsockptr .unix_socket = - 1
620
646
if type (self .request ) == tuple :
647
+ #TODO# This is not permitted, editing a tuple
621
648
self .request [1 ] = sox2
622
649
else :
623
650
self .request = sox2
624
651
self .handle_secure ()
625
- sox2 .close ()
626
652
627
653
def startssh (self ):
628
654
raise NotImplementedError ("Python wrapper does not implement STARTSSH" )
@@ -694,6 +720,7 @@ def handle_secure (self):
694
720
PIOF_LIDENTRY_SKIP_NOTROOT = _tlspool .PIOF_LIDENTRY_SKIP_NOTROOT
695
721
PIOF_LIDENTRY_SKIP_USER = _tlspool .PIOF_LIDENTRY_SKIP_USER
696
722
PIOF_LIDENTRY_WANT_DBENTRY = _tlspool .PIOF_LIDENTRY_WANT_DBENTRY
723
+ PIOF_STARTTLS_BOTHROLES_PEER = _tlspool .PIOF_STARTTLS_BOTHROLES_PEER
697
724
PIOF_STARTTLS_DETACH = _tlspool .PIOF_STARTTLS_DETACH
698
725
PIOF_STARTTLS_DOMAIN_REPRESENTS_USER = _tlspool .PIOF_STARTTLS_DOMAIN_REPRESENTS_USER
699
726
PIOF_STARTTLS_DTLS = _tlspool .PIOF_STARTTLS_DTLS
@@ -712,6 +739,7 @@ def handle_secure (self):
712
739
PIOF_STARTTLS_REQUEST_REMOTEID = _tlspool .PIOF_STARTTLS_REQUEST_REMOTEID
713
740
PIOF_STARTTLS_WITHOUT_SNI = _tlspool .PIOF_STARTTLS_WITHOUT_SNI
714
741
TLSPOOL_CTLKEYLEN = _tlspool .TLSPOOL_CTLKEYLEN
742
+ TLSPOOL_DEFAULT_CONFIG_PATH = _tlspool .TLSPOOL_DEFAULT_CONFIG_PATH
715
743
TLSPOOL_DEFAULT_PIDFILE_PATH = _tlspool .TLSPOOL_DEFAULT_PIDFILE_PATH
716
744
TLSPOOL_DEFAULT_SOCKET_PATH = _tlspool .TLSPOOL_DEFAULT_SOCKET_PATH
717
745
TLSPOOL_IDENTITY_V2 = _tlspool .TLSPOOL_IDENTITY_V2
0 commit comments