def attach(self, parent, sock, conf): self.parent = parent self.conf = conf self.filenum = sock.fileno() self.myname = utils_net.getsockname(sock) self.peername = utils_net.getpeername(sock) self.logname = str((self.myname, self.peername)) logging.debug("* Connection made %s", str(self.logname)) if conf["net.stream.secure"]: if not ssl: raise RuntimeError("SSL support not available") server_side = conf["net.stream.server_side"] certfile = conf["net.stream.certfile"] # wrap_socket distinguishes between None and '' if not certfile: certfile = None ssl_sock = ssl.wrap_socket(sock, do_handshake_on_connect=False, certfile=certfile, server_side=server_side) self.sock = SSLWrapper(ssl_sock) self.recv_ssl_needs_kickoff = not server_side else: self.sock = SocketWrapper(sock) self.connection_made()
def connection_made(self, sock, endpoint, rtt): ''' Invoked when the connection is made ''' stream = ServerStream(self.poller) nconf = self.conf.copy() # # Setup SSL if needed. # XXX The private key and public certificate file is # hardcoded and must be readable by the user that owns # this process for SSL to work. We can live with the # former issue but the latter belongs clearly to the # not-so-good dept. (Even if loading a copy of the # private key at startup and then keeping it in memory # is dangerous as well. Yes an attacker cannot read # the file but she can read the process memory and # find the private key without too much effort.) # Maybe radical privilege separation is the answer # here, but I'm not sure: I need to study more. # port = utils_net.getsockname(sock)[1] if port in self._ssl_ports: nconf["net.stream.certfile"] = "/etc/neubot/cert.pem" nconf["net.stream.secure"] = True nconf["net.stream.server_side"] = True stream.attach(self, sock, nconf) self.connection_ready(stream)
def __init__(self, poller, sock, connection_made, connection_lost, sslconfig, sslcert, opaque): Pollable.__init__(self) self.poller = poller self.filenum = sock.fileno() self.myname = utils_net.getsockname(sock) self.peername = utils_net.getpeername(sock) self.logname = '%s %s' % (utils_net.format_epnt(self.myname), utils_net.format_epnt(self.peername)) logging.debug('stream: __init__(): %s', self.logname) # Variables pointing to other objects self.atclose = Deferred() self.atconnect = Deferred() self.opaque = opaque self.recv_complete = None self.send_complete = None self.send_octets = EMPTY_STRING self.sock = None # Variables we don't need to clear self.bytes_in = 0 self.bytes_out = 0 self.conn_rst = False self.eof = False self.isclosed = False self.recv_bytes = 0 self.recv_blocked = False self.send_blocked = False self.atclose.add_callback(connection_lost) self.atconnect.add_callback(connection_made) self.atconnect.add_errback(self._connection_made_error) if not sslconfig: self.sock = _stream_wrapper(sock) self.atconnect.callback(self) return # # Lazy import: this fails on Python 2.5, because SSL is not part of # v2.5 standard library. We do not intercept the error here, because # accept() code already needs to setup a try..except to route any # error away from the listening socket. # from . import sslstream # # If there is SSL support, initialise() deals transparently with SSL # negotiation, and invokes connection_made() when done. Errors are # routed to the self.poller, which generates CLOSE events accordingly. # sslstream.initialise(self.poller, self, sock, sslcert)