656
656
def handle(self):
657
657
logger.info(u"TCP connection from: %s",
658
658
unicode(self.client_address))
659
session = (gnutls.connection
660
.ClientSession(self.request,
664
line = self.request.makefile().readline()
665
logger.debug(u"Protocol version: %r", line)
667
if int(line.strip().split()[0]) > 1:
669
except (ValueError, IndexError, RuntimeError), error:
670
logger.error(u"Unknown protocol version: %s", error)
673
# Note: gnutls.connection.X509Credentials is really a generic
674
# GnuTLS certificate credentials object so long as no X.509
675
# keys are added to it. Therefore, we can use it here despite
676
# using OpenPGP certificates.
678
#priority = ':'.join(("NONE", "+VERS-TLS1.1", "+AES-256-CBC",
679
# "+SHA1", "+COMP-NULL", "+CTYPE-OPENPGP",
681
# Use a fallback default, since this MUST be set.
682
priority = self.server.settings.get("priority", "NORMAL")
683
(gnutls.library.functions
684
.gnutls_priority_set_direct(session._c_object,
689
except gnutls.errors.GNUTLSError, error:
690
logger.warning(u"Handshake failed: %s", error)
691
# Do not run session.bye() here: the session is not
692
# established. Just abandon the request.
694
logger.debug(u"Handshake succeeded")
696
fpr = fingerprint(peer_certificate(session))
697
except (TypeError, gnutls.errors.GNUTLSError), error:
698
logger.warning(u"Bad certificate: %s", error)
701
logger.debug(u"Fingerprint: %s", fpr)
702
for c in self.server.clients:
703
if c.fingerprint == fpr:
707
logger.warning(u"Client not found for fingerprint: %s",
711
# Have to check if client.still_valid(), since it is possible
712
# that the client timed out while establishing the GnuTLS
714
if not client.still_valid():
715
logger.warning(u"Client %(name)s is invalid",
719
## This won't work here, since we're in a fork.
720
# client.checked_ok()
722
while sent_size < len(client.secret):
723
sent = session.send(client.secret[sent_size:])
724
logger.debug(u"Sent: %d, remaining: %d",
725
sent, len(client.secret)
726
- (sent_size + sent))
731
class IPv6_TCPServer(SocketServer.ForkingMixIn,
659
logger.debug(u"Pipe: %d", self.server.pipe[1])
660
# Open IPC pipe to parent process
661
with closing(os.fdopen(self.server.pipe[1], "w", 1)) as ipc:
662
session = (gnutls.connection
663
.ClientSession(self.request,
667
line = self.request.makefile().readline()
668
logger.debug(u"Protocol version: %r", line)
670
if int(line.strip().split()[0]) > 1:
672
except (ValueError, IndexError, RuntimeError), error:
673
logger.error(u"Unknown protocol version: %s", error)
676
# Note: gnutls.connection.X509Credentials is really a
677
# generic GnuTLS certificate credentials object so long as
678
# no X.509 keys are added to it. Therefore, we can use it
679
# here despite using OpenPGP certificates.
681
#priority = ':'.join(("NONE", "+VERS-TLS1.1",
682
# "+AES-256-CBC", "+SHA1",
683
# "+COMP-NULL", "+CTYPE-OPENPGP",
685
# Use a fallback default, since this MUST be set.
686
priority = self.server.settings.get("priority", "NORMAL")
687
(gnutls.library.functions
688
.gnutls_priority_set_direct(session._c_object,
693
except gnutls.errors.GNUTLSError, error:
694
logger.warning(u"Handshake failed: %s", error)
695
# Do not run session.bye() here: the session is not
696
# established. Just abandon the request.
698
logger.debug(u"Handshake succeeded")
700
fpr = fingerprint(peer_certificate(session))
701
except (TypeError, gnutls.errors.GNUTLSError), error:
702
logger.warning(u"Bad certificate: %s", error)
705
logger.debug(u"Fingerprint: %s", fpr)
706
for c in self.server.clients:
707
if c.fingerprint == fpr:
711
logger.warning(u"Client not found for fingerprint: %s",
713
ipc.write("NOTFOUND %s\n" % fpr)
716
# Have to check if client.still_valid(), since it is
717
# possible that the client timed out while establishing
718
# the GnuTLS session.
719
if not client.still_valid():
720
logger.warning(u"Client %(name)s is invalid",
722
ipc.write("INVALID %s\n" % client.name)
725
ipc.write("SENDING %s\n" % client.name)
726
## This won't work here, since we're in a fork.
727
# client.checked_ok()
729
while sent_size < len(client.secret):
730
sent = session.send(client.secret[sent_size:])
731
logger.debug(u"Sent: %d, remaining: %d",
732
sent, len(client.secret)
733
- (sent_size + sent))
738
class ForkingMixInWithPipe(SocketServer.ForkingMixIn, object):
739
"""Like SocketServer.ForkingMixIn, but also pass a pipe.
740
Assumes a gobject.MainLoop event loop.
742
def process_request(self, request, client_address):
743
"""This overrides and wraps the original process_request().
744
This function creates a new pipe in self.pipe
746
self.pipe = os.pipe()
747
super(ForkingMixInWithPipe,
748
self).process_request(request, client_address)
749
os.close(self.pipe[1]) # close write end
750
# Call "handle_ipc" for both data and EOF events
751
gobject.io_add_watch(self.pipe[0],
752
gobject.IO_IN | gobject.IO_HUP,
754
def handle_ipc(source, condition):
755
"""Dummy function; override as necessary"""
760
class IPv6_TCPServer(ForkingMixInWithPipe,
732
761
SocketServer.TCPServer, object):
733
762
"""IPv6 TCP server. Accepts 'None' as address and/or port.
786
815
return super(IPv6_TCPServer, self).server_activate()
787
816
def enable(self):
788
817
self.enabled = True
818
def handle_ipc(self, source, condition, file_objects={}):
819
logger.debug("Handling IPC: %r : %r", source, condition)
821
# Turn a file descriptor into a Python file object
822
if source not in file_objects:
823
file_objects[source] = os.fdopen(source, "r", 1)
825
# Read a line from the file object
826
cmdline = file_objects[source].readline()
827
if not cmdline: # Empty line means end of file
829
logger.debug("Closing: %r", source)
830
file_objects[source].close()
831
del file_objects[source]
833
# Stop calling this function
836
logger.debug("IPC command: %r\n" % cmdline)
838
# Parse and act on command
839
cmd, args = cmdline.split(None, 1)
840
if cmd == "NOTFOUND":
842
elif cmd == "INVALID":
844
elif cmd == "SENDING":
847
logger.error("Unknown IPC command: %r", cmdline)
849
# Keep calling this function
791
853
def string_to_delta(interval):