예제 #1
0
def accept_loop(sock: ssl.SSLSocket):
    while True:
        client_sock, addr = sock.accept()

        logging.debug('accepted from %s', addr)

        handler = ConnHandler(client_sock, addr)
        handler.start()
예제 #2
0
파일: ssl.py 프로젝트: ufwt/dizzy
class DizzySession(object):
    def __init__(self, section_proxy):
        self.dest = section_proxy.get('target_host')
        self.dport = section_proxy.getint('target_port')
        self.src = section_proxy.get('source_host', '')
        self.sport = section_proxy.getint('source_port')
        self.client_cert = section_proxy.get('certfile')
        self.client_key = section_proxy.get('keyfile')
        self.timeout = section_proxy.getfloat('timeout', 1)
        self.recv_buffer = section_proxy.getfloat('recv_buffer', 4096)
        self.auto_reopen = section_proxy.getboolean('auto_reopen', True)
        self.server_side = section_proxy.getboolean('server', False)
        self.read_first = self.server_side
        self.read_first = section_proxy.getboolean('read_first',
                                                   self.read_first)
        self.connect_retry = section_proxy.getint('retry', 3)
        self.is_open = False

        try:
            inet_aton(self.dest)
            self.af = AF_INET
        except Exception as e:
            try:
                inet_pton(AF_INET6, self.dest)
                self.af = AF_INET6
            except Exception as f:
                raise SessionParseException(
                    "unknown address family: %s: %s, %s" % (self.dest, e, f))
        if self.src != '':
            try:
                inet_aton(self.src)
            except Exception as e:
                try:
                    inet_pton(AF_INET6, self.src)
                except Exception as f:
                    raise SessionParseException(
                        "unknown address family: %s: %s, %s" %
                        (self.src, e, f))
                else:
                    if not self.af == AF_INET6:
                        raise SessionParseException(
                            "address family missmatch: %s - %s" %
                            (self.dest, self.src))
            else:
                if not self.af == AF_INET:
                    raise SessionParseException(
                        "address family missmatch: %s - %s" %
                        (self.dest, self.src))

        self.cs = None
        self.maxsize = 65534

    def open(self):
        try:
            self.s = socket(self.af, SOCK_STREAM)
            if self.dest == "255.255.255.255":
                self.s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
            self.s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
            self.s.settimeout(self.timeout)
            sendbuf = self.s.getsockopt(SOL_SOCKET, SO_SNDBUF)
            if sendbuf < self.maxsize:
                self.maxsize = sendbuf
            if not self.sport is None:
                if self.af == AF_INET:
                    self.s.bind((self.src, self.sport))
                elif self.af == AF_INET6:
                    try:
                        self.s.bind((self.src, self.port, 0, 0))
                    except:
                        if not self.interface is '':
                            (_, _, _, _, addri) = getaddrinfo(
                                "%s%%%s" % (self.src, self.interface),
                                self.sport,
                                family=AF_INET6,
                                proto=IPPROTO_UDP)[0]
                            self.s.bind(addri)
                        else:
                            raise SessionException(
                                "cant bind to ipv6 LL without interface!")
            self.s = SSLSocket(self.s,
                               self.client_key,
                               self.client_cert,
                               ssl_version=3)
            if self.server_side:
                self.s.listen(1)
                (self.cs, (rip, rport)) = self.s.accept()
                if self.dport:
                    while self.dport != rport or self.src != rip:
                        if self.dport != rport:
                            print_dizzy(
                                "session/ssl: remote port %i not destination port %i"
                                % (rport, self.dport), DEBUG)
                        if self.src != rip:
                            print_dizzy(
                                "session/ssl: remote ip %s not destination ip %i"
                                % (rip, self.dst), DEBUG)
                        (self.cs, (sip, rport)) = self.s.accept()
                self.cs.settimeout(self.timeout)
            else:
                connected = False
                attempt = 1
                try:
                    self.s.connect((self.dest, self.dport))
                    connected = True
                except (timeout, SSLError):
                    print_dizzy(
                        "session/ssl: Connection attempt %d timed out." %
                        attempt)
                    while not connected and attempt <= self.connect_retry:
                        try:
                            (r, w, x) = select([], [self.s], [], self.timeout)
                            if self.s in w:
                                connected = True
                        except:
                            pass
                        attempt += 1
                    if not connected:
                        raise SessionException("too much connection attempts")
        except Exception as e:
            raise SessionException("cant open session: %s" % str(e))
        else:
            self.is_open = True

    def close(self):
        self.s.close()
        self.s = None
        if self.cs:
            self.cs.close()
            self.cs = None
        self.is_open = False

    def send(self, data):
        try:
            if not self.maxsize is None and len(data) > self.maxsize:
                data = data[:self.maxsize - 1]
                print_dizzy("Truncated data to %d byte." % self.maxsize, DEBUG)
            if self.server_side:
                if not self.cs:
                    raise SessionException("no client connection, cant send")
                self.cs.send(data)
            else:
                self.s.send(data)
        except Exception as e:
            if self.auto_reopen:
                print_dizzy("session got closed '%s', autoreopening..." % e,
                            DEBUG)
                self.close()
                self.open()
            else:
                self.close()
                raise SessionException(
                    "error on sending '%s', connection closed." % e)

    def recv(self):
        if self.server_side:
            return self.cs.recv(self.recv_buffer)
        else:
            return self.s.recv(self.recv_buffer)