def create_ssl_context(webserver=False, server_side=False, verify_mode=ssl.CERT_OPTIONAL, check_hostname=False, certfile=None, keyfile=None): c = ssl.create_default_context( ssl.Purpose.CLIENT_AUTH if server_side else ssl.Purpose.SERVER_AUTH) if verify_mode is not None: c.verify_mode = verify_mode if check_hostname is not None: c.check_hostname = check_hostname if not certfile: cfg_cert = config.web_cert.value if webserver else config.server_cert.value certfile = cfg_cert.get("certfile") keyfile = cfg_cert.get("keyfile") if certfile is None and webserver: cfg_cert = config.server_cert.value certfile = cfg_cert.get("certfile") keyfile = cfg_cert.get("keyfile") if certfile is None: certfile = os.path.join(constants.dir_certs, "happypandax.crt") keyfile = os.path.join(constants.dir_certs, "happypandax.key") pemfile = os.path.join(constants.dir_certs, "happypandax.pem") pfxfile = os.path.join(constants.dir_certs, "happypandax.pfx") if not os.path.exists(certfile): create_self_signed_cert(certfile, keyfile, pemfile, pfxfile) if not os.path.exists(pfxfile): export_cert_to_pfx(pfxfile, certfile, keyfile) if server_side and not webserver: log.i("Certs not provided, using self-signed certificate", stdout=True) else: if not os.path.exists(certfile) and not (os.path.exists(keyfile) if keyfile else False): raise exceptions.CoreError( this_function(), "Non-existent certificate or private key file") if not keyfile: keyfile = None try: if server_side: c.load_cert_chain(certfile=certfile, keyfile=keyfile) else: c.load_verify_locations(certfile) except OSError as e: if e.errno == errno.EINVAL: raise exceptions.CoreError( this_function(), "Invalid certificate or private key filepath") raise exceptions.CoreError( this_function(), "Invalid certificate or private key: {}".format(e)) return c
def __init__(self, context=None, **client_kwargs): super(MxSmtpRelay, self).__init__() self._mx_records = {} self._force_mx = {} self._relayers = {} self._client_kwargs = client_kwargs self._client_kwargs['context'] = context or \ ssl.create_default_context()
def start(self): if self.stopped: self.logger.info("Ignoring start() - already stopped (please create a new Client instead)") return if self.started: self.logger.info("Ignoring start() - already started") return self.started = True self.logger.info("Starting client for {self.nick} on {self.hostname}:{self.port}".format(self=self)) try: self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if self.ssl: context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) if self.ssl == 'insecure' else ssl.create_default_context() self._socket = context.wrap_socket(self._socket, server_hostname=self.hostname) self.stop_handlers.add(lambda self: self._socket.close()) self._socket.connect((self.hostname, self.port)) except Exception as ex: self.logger.exception("Error while connecting client") self.stop(ex) raise # registration is a delicate dance... with self._nick_lock, self._send_queue.limit_to(-1): # by limiting to 0, we block all messages except pongs and registration reg_done = gevent.event.Event() reg_handlers = set() @self.handler(command=replycodes.replies.WELCOME, sync=True) def reg_got_welcome(client, msg): reg_done.set() for handler in reg_handlers: handler.unregister(self) reg_handlers.add(reg_got_welcome) # Some anal servers require sending registration messages in a precise order # and/or can't handle PINGs being sent during registration. This makes the standard # nick-setting behaviour unsuitable. We're pretty sure we won't get a NICK # forced change from the server during registration, so we only need to special-case # handle a NICKNAMEINUSE message, and send the Nick() message manually. @self.handler(command=replycodes.errors.NICKNAMEINUSE, sync=True) def reg_nick_in_use(client, msg): self._nick = self.increment_nick(self._nick) message.Nick(self, self._nick).send(priority=-2) reg_handlers.add(reg_nick_in_use) if self.password: message.Message(self, 'PASS', self.password).send(priority=-2) message.Nick(self, self._nick).send(priority=-2) message.User(self, self.ident, self.real_name).send(priority=-2) self._start_greenlets() if not reg_done.wait(self.REGISTRATION_TIMEOUT): ex = Exception("Registration timeout") self.stop(ex) raise ex self.logger.debug("Registration complete")
def __init__(self, host, port=25, pool_size=None, client_class=None, context=None, **client_kwargs): super(StaticSmtpRelay, self).__init__(pool_size) self.host = host self.port = port self._client_class = client_class or self._default_class self._client_kwargs = client_kwargs self._client_kwargs['context'] = context or \ ssl.create_default_context()
def encrypt_socket_client(self, context=None): hostname = self.address[0] context = context or create_default_context() log.encrypt(self.socket, context) try: self.socket = context.wrap_socket(self.socket, server_hostname=hostname) return True except SSLError as exc: log.error(self.socket, exc, self.address) return False
def get_http2_tls_context() -> ssl.SSLContext: ctx = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH) ctx.options |= ( ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 ) ctx.options |= ssl.OP_NO_COMPRESSION ctx.set_ciphers('ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20') ctx.load_cert_chain(certfile='localhost.crt', keyfile='localhost.key') ctx.set_alpn_protocols(['h2']) try: ctx.set_npn_protocols(['h2']) except NotImplementedError: pass return ctx
def _start_edge(self, name, options=None): if name in self.edges: return self.edges[name] if not options: options = getattr(self.cfg.edge, name) new_edge = None queue_name = options.queue queue = self._start_queue(queue_name) ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) if options.type == 'smtp': from slimta.edge.smtp import SmtpEdge from .helpers import build_smtpedge_validators from .helpers import fill_hostname_template hostname = fill_hostname_template(options.get('hostname')) listener_defaults = {'interface': '127.0.0.1', 'port': 25} listener = self._get_listener(options.listener, listener_defaults) kwargs = {} kwargs['context'] = self._get_ssl_context(ctx, options.get('tls')) kwargs['tls_immediately'] = options.get('tls_immediately', False) kwargs['validator_class'] = build_smtpedge_validators(options) kwargs['auth'] = ['PLAIN', 'LOGIN'] kwargs['command_timeout'] = 20.0 kwargs['data_timeout'] = 30.0 kwargs['max_size'] = int(options.get('max_size', 10485760)) kwargs['hostname'] = hostname new_edge = SmtpEdge(listener, queue, **kwargs) new_edge.start() elif options.type == 'http': from slimta.edge.wsgi import WsgiEdge from .helpers import build_wsgiedge_validators from .helpers import fill_hostname_template hostname = fill_hostname_template(options.get('hostname')) uri_pattern = options.get('uri') validator_class = build_wsgiedge_validators(options) new_edge = WsgiEdge(queue, hostname, validator_class, uri_pattern) listener_defaults = {'interface': '127.0.0.1', 'port': 8025} listener = self._get_listener(options.listener, listener_defaults) server = new_edge.build_server(listener, tls=options.get('tls')) server.start() elif options.type == 'custom': new_edge = self._load_from_custom(options, queue) else: msg = 'edge type does not exist: '+options.type raise ConfigValidationError(msg) self.edges[name] = new_edge return new_edge
def get_http2_tls_context() -> ssl.SSLContext: ctx = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH) # RFC 7540 Section 9.2: Implementations of HTTP/2 MUST use TLS version 1.2 # or higher. Disable TLS 1.1 and lower. ctx.options |= (ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1) # RFC 7540 Section 9.2.1: A deployment of HTTP/2 over TLS 1.2 MUST disable # compression. ctx.options |= ssl.OP_NO_COMPRESSION ctx.set_ciphers('ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20') ctx.load_cert_chain(certfile='localhost.crt', keyfile='localhost.key') ctx.set_alpn_protocols(['h2']) try: ctx.set_npn_protocols(['h2']) except NotImplementedError: pass return ctx
def _get_ssl_context(self, purpose, tls_opts): key = (purpose, hash(tuple(tls_opts.items()))) if key in self.ssl_contexts: return self.ssl_contexts[key] ctx = ssl.create_default_context(purpose) certfile = tls_opts.certfile keyfile = tls_opts.keyfile cafile = tls_opts.ca_certs if certfile is not None: certfile = os.path.expandvars(certfile) certfile = os.path.expanduser(certfile) if keyfile is not None: keyfile = os.path.expandvars(keyfile) keyfile = os.path.expanduser(keyfile) if cafile is not None: cafile = os.path.expandvars(cafile) cafile = os.path.expanduser(cafile) if certfile or keyfile: ctx.load_cert_chain(certfile, keyfile) if cafile: ctx.load_verify_locations(cafile) self.ssl_contexts[key] = ctx return ctx
def handleTCP(socket, address): global ttl, httpData socket.settimeout(ttl) httpFlag = False ip, port = address buf = "" dport = 0 try: dport = int( os.popen( "grep \"src=%s\" /proc/net/nf_conntrack | grep tcp | grep \"sport=%d\"| tail -n 1" % ( ip, port, )).read().split("dport=", 1)[1].split(" ", 1)[0]) except: pass if dport == 0: try: dport = int( os.popen( "grep \"src=%s\" /proc/net/ip_conntrack | grep tcp | grep \"sport=%d\"| tail -n 1" % ( ip, port, )).read().split("dport=", 1)[1].split(" ", 1)[0]) except: pass log = "[+] TCP Connection on Port: %d from %s:%d Time: %s\n" % ( dport, ip, port, datetime.utcnow().isoformat()) print log, with open("logs.txt", "a") as f: f.write(log) f.close() try: if dport in [443] or 443 == dport % 1000: context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(certfile="ssl.crt", keyfile="ssl.key") context.options = ssl.OP_ALL try: sslsock = context.wrap_socket(socket, server_side=True) while True: buffer = sslsock.read() if not buffer: sslsock.send(httpData) break buf += buffer if checkHTTP(buf): httpFlag = True except Exception as e: print "[-] Error: %s" % (e, ) finally: try: sslsock.close() except: pass elif dport in [23]: socket.send("login: "******"\n": buf += buffer break else: buf += buffer if not socket.closed: socket.send("Password: "******"\n": buf += buffer socket.send("XM# ") break else: buf += buffer while not socket.closed: buffer = recv(socket) if not buffer: socket.close() break elif buffer == "\n": tosend = telnetparse(buf.split("\n")[-1]) if tosend <> None: socket.send(tosend) socket.send("\n") buf += buffer socket.send("XM# ") else: buf += buffer else: while not socket.closed: buffer = recv(socket) if not buffer: if httpFlag: socket.send(httpData) socket.close() break else: buf += buffer if checkHTTP(buf): httpFlag = True except Exception as e: print "[-] Error : %s " % (e, ) with open( "captures/tcp/%d_%s_%d_%s.txt" % ( dport, ip, port, datetime.utcnow().isoformat().replace(":", "-").replace(".", "-"), ), "wb") as file: file.write(buf) file.close() grabHTTP(buf, "tcp", ip, port, dport)
def _get_ssl_context_client(args): ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) ctx.load_cert_chain(keyfile=os.path.realpath(args.keyfile), certfile=os.path.realpath(args.certfile)) return ctx
def handleTCP(socket, address): global ttl, httpData socket.settimeout(ttl) httpFlag = False ip, port = address buf = "" dport = 0 try: dport = int(os.popen("grep \"src=%s\" /proc/net/nf_conntrack | grep tcp | grep \"sport=%d\"| tail -n 1" % (ip, port,)).read().split("dport=", 1)[1].split(" ", 1)[0]) except: pass if dport == 0: try: dport = int(os.popen("grep \"src=%s\" /proc/net/ip_conntrack | grep tcp | grep \"sport=%d\"| tail -n 1" % (ip, port,)).read().split("dport=", 1)[1].split(" ", 1)[0]) except: pass log = "[+] TCP Connection on Port: %d from %s:%d Time: %s\n" % (dport, ip, port, datetime.utcnow().isoformat()) print log, with open("logs.txt", "a") as f: f.write(log) f.close() try: if dport in [443] or 443 == dport%1000: context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(certfile="ssl.crt", keyfile="ssl.key") context.options = ssl.OP_ALL try: sslsock = context.wrap_socket(socket, server_side=True) while True: buffer = sslsock.read() if not buffer: sslsock.send(httpData) break buf+=buffer if checkHTTP(buf): httpFlag = True except Exception as e: print "[-] Error: %s" % (e,) finally: try: sslsock.close() except: pass elif dport in [23]: socket.send("login: "******"\n": buf+= buffer break else: buf+=buffer if not socket.closed: socket.send("Password: "******"\n": buf+= buffer socket.send("XM# ") break else: buf+=buffer while not socket.closed: buffer = recv(socket) if not buffer: socket.close() break elif buffer == "\n": tosend = telnetparse(buf.split("\n")[-1]) if tosend <> None: socket.send(tosend) socket.send("\n") buf+= buffer socket.send("XM# ") else: buf+= buffer else: while not socket.closed: buffer = recv(socket) if not buffer: if httpFlag: socket.send(httpData) socket.close() break else: buf+= buffer if checkHTTP(buf): httpFlag = True except Exception as e: print "[-] Error : %s " % (e,) with open("captures/tcp/%d_%s_%d_%s.txt" % (dport, ip, port, datetime.utcnow().isoformat().replace(":", "-").replace(".", "-"),) , "wb") as file: file.write(buf) file.close()
def _get_client_ssl_context(self, tls_opts): purpose = ssl.Purpose.SERVER_AUTH if not tls_opts: return ssl.create_default_context(purpose) else: return self._get_ssl_context(purpose, tls_opts)
def _start_relay(self, name, options=None): if name in self.relays: return self.relays[name] if not options: options = getattr(self.cfg.relay, name) new_relay = None ctx = ssl.create_default_context() if options.type == 'mx': from slimta.relay.smtp.mx import MxSmtpRelay from .helpers import fill_hostname_template kwargs = {} kwargs['connect_timeout'] = options.get('connect_timeout', 30) kwargs['command_timeout'] = options.get('command_timeout', 30) kwargs['data_timeout'] = options.get('data_timeout', 60) kwargs['idle_timeout'] = options.get('idle_timeout', 10) kwargs['pool_size'] = options.get('concurrent_connections', 5) kwargs['ehlo_as'] = fill_hostname_template(options.get('ehlo_as')) if 'tls' in options: kwargs['context'] = self._get_ssl_context(ctx, options.tls) if options.get('ipv4_only'): kwargs['socket_creator'] = build_ipv4_socket_creator([25]) new_relay = MxSmtpRelay(**kwargs) elif options.type == 'static': from slimta.relay.smtp.static import StaticSmtpRelay from .helpers import fill_hostname_template, get_relay_credentials kwargs = {} kwargs['host'] = options.host kwargs['port'] = options.get('port', 25) kwargs['connect_timeout'] = options.get('connect_timeout', 30) kwargs['command_timeout'] = options.get('command_timeout', 30) kwargs['data_timeout'] = options.get('data_timeout', 60) kwargs['idle_timeout'] = options.get('idle_timeout', 10) kwargs['pool_size'] = options.get('concurrent_connections', 5) kwargs['ehlo_as'] = fill_hostname_template(options.get('ehlo_as')) if 'tls' in options: kwargs['context'] = self._get_ssl_context(ctx, options.tls) if 'credentials' in options: credentials = get_relay_credentials(options.get('credentials')) kwargs['credentials'] = credentials if options.get('ipv4_only'): kwargs['socket_creator'] = \ build_ipv4_socket_creator([kwargs['port']]) new_relay = StaticSmtpRelay(**kwargs) elif options.type == 'lmtp': from slimta.relay.smtp.static import StaticLmtpRelay from .helpers import fill_hostname_template, get_relay_credentials kwargs = {} kwargs['host'] = options.get('host', 'localhost') kwargs['port'] = options.get('port', 24) kwargs['connect_timeout'] = options.get('connect_timeout', 30) kwargs['command_timeout'] = options.get('command_timeout', 30) kwargs['data_timeout'] = options.get('data_timeout', 60) kwargs['idle_timeout'] = options.get('idle_timeout', 10) kwargs['pool_size'] = options.get('concurrent_connections', 5) kwargs['ehlo_as'] = fill_hostname_template(options.get('ehlo_as')) if 'tls' in options: kwargs['context'] = self._get_ssl_context(ctx, options.tls) if 'credentials' in options: credentials = get_relay_credentials(options.get('credentials')) kwargs['credentials'] = credentials if options.get('ipv4_only'): kwargs['socket_creator'] = \ build_ipv4_socket_creator([kwargs['port']]) new_relay = StaticLmtpRelay(**kwargs) elif options.type == 'http': from slimta.relay.http import HttpRelay from .helpers import fill_hostname_template kwargs = {} kwargs['ehlo_as'] = fill_hostname_template(options.get('ehlo_as')) kwargs['timeout'] = options.get('timeout', 60) kwargs['idle_timeout'] = options.get('idle_timeout', 10) if 'tls' in options: kwargs['context'] = self._get_ssl_context(ctx, options.tls) new_relay = HttpRelay(options.url, **kwargs) elif options.type == 'blackhole': from slimta.relay.blackhole import BlackholeRelay new_relay = BlackholeRelay() elif options.type == 'maildrop': from slimta.relay.pipe import MaildropRelay path = options.get('path') new_relay = MaildropRelay(path) elif options.type == 'dovecot': from slimta.relay.pipe import DovecotLdaRelay path = options.get('path') new_relay = DovecotLdaRelay(path) elif options.type == 'custom': new_relay = self._load_from_custom(options) else: msg = 'relay type does not exist: '+options.type raise ConfigValidationError(msg) self.relays[name] = new_relay return new_relay