Example #1
0
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
Example #2
0
 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()
Example #3
0
 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()
Example #4
0
	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")
Example #5
0
 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()
Example #6
0
 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()
Example #7
0
 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
Example #8
0
 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
Example #9
0
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
Example #10
0
 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
Example #11
0
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
Example #12
0
 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
Example #13
0
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)
Example #14
0
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
Example #15
0
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()    
Example #16
0
 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)
Example #17
0
 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
Example #18
0
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