コード例 #1
0
ファイル: tproxy.py プロジェクト: 64BitChris/sshuttle
 def recv_udp(listener, bufsize):
     debug3('Accept UDP using socket_ext recvmsg.\n')
     srcip, data, adata, flags = listener.recvmsg(
         (bufsize,), socket.CMSG_SPACE(24))
     dstip = None
     family = None
     for a in adata:
         if a.cmsg_level == socket.SOL_IP and a.cmsg_type == IP_ORIGDSTADDR:
             family, port = struct.unpack('=HH', a.cmsg_data[0:4])
             port = socket.htons(port)
             if family == socket.AF_INET:
                 start = 4
                 length = 4
             else:
                 raise Fatal("Unsupported socket type '%s'" % family)
             ip = socket.inet_ntop(
                 family, a.cmsg_data[start:start + length])
             dstip = (ip, port)
             break
         elif a.cmsg_level == SOL_IPV6 and a.cmsg_type == IPV6_ORIGDSTADDR:
             family, port = struct.unpack('=HH', a.cmsg_data[0:4])
             port = socket.htons(port)
             if family == socket.AF_INET6:
                 start = 8
                 length = 16
             else:
                 raise Fatal("Unsupported socket type '%s'" % family)
             ip = socket.inet_ntop(
                 family, a.cmsg_data[start:start + length])
             dstip = (ip, port)
             break
     return (srcip, dstip, data[0])
コード例 #2
0
ファイル: hostwatch.py プロジェクト: dlenski/sshuttle
def _check_nmb(hostname, is_workgroup, is_master):
    return
    global _nmb_ok
    if not _nmb_ok:
        return
    argv = ['nmblookup'] + ['-M'] * is_master + ['--', hostname]
    debug2(' > n%d%d: %s\n' % (is_workgroup, is_master, hostname))
    try:
        p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, stderr=null)
        lines = p.stdout.readlines()
        rv = p.wait()
    except OSError:
        _, e = sys.exc_info()[:2]
        log('%r failed: %r\n' % (argv, e))
        _nmb_ok = False
        return
    if rv:
        log('%r returned %d\n' % (argv, rv))
        return
    for line in lines:
        m = re.match(r'(\d+\.\d+\.\d+\.\d+) (\w+)<\w\w>\n', line)
        if m:
            g = m.groups()
            (ip, name) = (g[0], g[1].lower())
            debug3('<    %s -> %s\n' % (name, ip))
            if is_workgroup:
                _enqueue(_check_smb, ip)
            else:
                found_host(name, ip)
                check_host(name)
コード例 #3
0
ファイル: hostwatch.py プロジェクト: dlenski/sshuttle
def _check_revdns(ip):
    debug2(' > rev: %s\n' % ip)
    try:
        r = socket.gethostbyaddr(ip)
        debug3('<    %s\n' % r[0])
        check_host(r[0])
        found_host(r[0], ip)
    except socket.herror:
        pass
コード例 #4
0
ファイル: ssnet.py プロジェクト: 64BitChris/sshuttle
def _nb_clean(func, *args):
    try:
        return func(*args)
    except OSError as e:
        if e.errno not in (errno.EWOULDBLOCK, errno.EAGAIN):
            raise
        else:
            debug3('%s: err was: %s\n' % (func.__name__, e))
            return None
コード例 #5
0
ファイル: hostwatch.py プロジェクト: dlenski/sshuttle
def _check_dns(hostname):
    debug2(' > dns: %s\n' % hostname)
    try:
        ip = socket.gethostbyname(hostname)
        debug3('<    %s\n' % ip)
        check_host(ip)
        found_host(hostname, ip)
    except socket.gaierror:
        pass
コード例 #6
0
ファイル: hostwatch.py プロジェクト: dlenski/sshuttle
def _check_smb(hostname):
    return
    global _smb_ok
    if not _smb_ok:
        return
    argv = ['smbclient', '-U', '%', '-L', hostname]
    debug2(' > smb: %s\n' % hostname)
    try:
        p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, stderr=null)
        lines = p.stdout.readlines()
        p.wait()
    except OSError:
        _, e = sys.exc_info()[:2]
        log('%r failed: %r\n' % (argv, e))
        _smb_ok = False
        return

    lines.reverse()

    # junk at top
    while lines:
        line = lines.pop().strip()
        if re.match(r'Server\s+', line):
            break

    # server list section:
    #    Server   Comment
    #    ------   -------
    while lines:
        line = lines.pop().strip()
        if not line or re.match(r'-+\s+-+', line):
            continue
        if re.match(r'Workgroup\s+Master', line):
            break
        words = line.split()
        hostname = words[0].lower()
        debug3('<    %s\n' % hostname)
        check_host(hostname)

    # workgroup list section:
    #   Workgroup  Master
    #   ---------  ------
    while lines:
        line = lines.pop().strip()
        if re.match(r'-+\s+', line):
            continue
        if not line:
            break
        words = line.split()
        (workgroup, hostname) = (words[0].lower(), words[1].lower())
        debug3('<    group(%s) -> %s\n' % (workgroup, hostname))
        check_host(hostname)
        check_workgroup(workgroup)

    if lines:
        assert(0)
コード例 #7
0
ファイル: hostwatch.py プロジェクト: tberton/sshuttle
def _check_smb(hostname):
    return
    global _smb_ok
    if not _smb_ok:
        return
    argv = ["smbclient", "-U", "%", "-L", hostname]
    debug2(" > smb: %s\n" % hostname)
    try:
        p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, stderr=null)
        lines = p.stdout.readlines()
        p.wait()
    except OSError as e:
        log("%r failed: %r\n" % (argv, e))
        _smb_ok = False
        return

    lines.reverse()

    # junk at top
    while lines:
        line = lines.pop().strip()
        if re.match(r"Server\s+", line):
            break

    # server list section:
    #    Server   Comment
    #    ------   -------
    while lines:
        line = lines.pop().strip()
        if not line or re.match(r"-+\s+-+", line):
            continue
        if re.match(r"Workgroup\s+Master", line):
            break
        words = line.split()
        hostname = words[0].lower()
        debug3("<    %s\n" % hostname)
        check_host(hostname)

    # workgroup list section:
    #   Workgroup  Master
    #   ---------  ------
    while lines:
        line = lines.pop().strip()
        if re.match(r"-+\s+", line):
            continue
        if not line:
            break
        words = line.split()
        (workgroup, hostname) = (words[0].lower(), words[1].lower())
        debug3("<    group(%s) -> %s\n" % (workgroup, hostname))
        check_host(hostname)
        check_workgroup(workgroup)

    if lines:
        assert 0
コード例 #8
0
 def __init__(self, rsock, wsock, connect_to=None, peername=None):
     global _swcount
     _swcount += 1
     debug3('creating new SockWrapper (%d now exist)\n' % _swcount)
     self.exc = None
     self.rsock = rsock
     self.wsock = wsock
     self.shut_read = self.shut_write = False
     self.buf = []
     self.connect_to = connect_to
     self.peername = peername or _try_peername(self.rsock)
     self.try_connect()
コード例 #9
0
ファイル: ipfw.py プロジェクト: xiongyw/sshuttle
 def recv_udp(listener, bufsize):
     debug3('Accept UDP using socket_ext recvmsg.\n')
     srcip, data, adata, _ = listener.recvmsg((bufsize,),
                                              socket.CMSG_SPACE(4))
     dstip = None
     for a in adata:
         if a.cmsg_level == socket.SOL_IP and a.cmsg_type == IP_RECVDSTADDR:
             port = 53
             ip = socket.inet_ntop(socket.AF_INET, a.cmsg_data[0:4])
             dstip = (ip, port)
             break
     return (srcip, dstip, data[0])
コード例 #10
0
ファイル: ipfw.py プロジェクト: xiongyw/sshuttle
 def recv_udp(listener, bufsize):
     debug3('Accept UDP python using recvmsg.\n')
     data, ancdata, _, srcip = listener.recvmsg(4096,
                                                socket.CMSG_SPACE(4))
     dstip = None
     for cmsg_level, cmsg_type, cmsg_data in ancdata:
         if cmsg_level == socket.SOL_IP and cmsg_type == IP_RECVDSTADDR:
             port = 53
             ip = socket.inet_ntop(socket.AF_INET, cmsg_data[0:4])
             dstip = (ip, port)
             break
     return (srcip, dstip, data)
コード例 #11
0
ファイル: ssnet.py プロジェクト: TooKennySupreme/sshuttle
 def __init__(self, rsock, wsock, connect_to=None, peername=None):
     global _swcount
     _swcount += 1
     debug3('creating new SockWrapper (%d now exist)\n' % _swcount)
     self.exc = None
     self.rsock = rsock
     self.wsock = wsock
     self.shut_read = self.shut_write = False
     self.buf = []
     self.connect_to = connect_to
     self.peername = peername or _try_peername(self.rsock)
     self.try_connect()
コード例 #12
0
def get_auto_method():
    debug3("Selecting a method automatically...")
    # Try these methods, in order:
    methods_to_try = ["nat", "nft", "pf", "ipfw"]
    for m in methods_to_try:
        method = get_method(m)
        if method.is_supported():
            debug3("Method '%s' was automatically selected." % m)
            return method

    raise Fatal("Unable to automatically find a supported method. Check that "
                "the appropriate programs are in your PATH. We tried "
                "methods: %s" % str(methods_to_try))
コード例 #13
0
    def __del__(self):
        self.nowrite()

        if self.buf_total > 0:
            # If the wrapper is destroyed (e.g., by iperf3), might still have data in the buffer
            # Do not need to make sure buffer is flushed but do need to reduce the size of the global var
            global _global_mux_wrapper_buffer_size
            _global_mux_wrapper_buffer_size -= self.buf_total
            debug3(
                'MuxWrapper on channel %d dead. Remove %d from global mux wrap buf size, which is now %d\n'
                % (self.channel, self.buf_total,
                   _global_mux_wrapper_buffer_size))

        SockWrapper.__del__(self)
コード例 #14
0
ファイル: hostwatch.py プロジェクト: tberton/sshuttle
def _check_etc_hosts():
    debug2(' > hosts\n')
    for line in open('/etc/hosts'):
        line = re.sub(r'#.*', '', line)
        words = line.strip().split()
        if not words:
            continue
        ip = words[0]
        names = words[1:]
        if _is_ip(ip):
            debug3('<    %s %r\n' % (ip, names))
            for n in names:
                check_host(n)
                found_host(n, ip)
コード例 #15
0
ファイル: hostwatch.py プロジェクト: tberton/sshuttle
def _check_etc_hosts():
    debug2(" > hosts\n")
    for line in open("/etc/hosts"):
        line = re.sub(r"#.*", "", line)
        words = line.strip().split()
        if not words:
            continue
        ip = words[0]
        names = words[1:]
        if _is_ip(ip):
            debug3("<    %s %r\n" % (ip, names))
            for n in names:
                check_host(n)
                found_host(n, ip)
コード例 #16
0
ファイル: hostwatch.py プロジェクト: dlenski/sshuttle
def _check_etc_hosts():
    debug2(' > hosts\n')
    for line in open('/etc/hosts'):
        line = re.sub(r'#.*', '', line)
        words = line.strip().split()
        if not words:
            continue
        ip = words[0]
        names = words[1:]
        if _is_ip(ip):
            debug3('<    %s %r\n' % (ip, names))
            for n in names:
                check_host(n)
                found_host(n, ip)
コード例 #17
0
ファイル: hostwatch.py プロジェクト: 64BitChris/sshuttle
def _check_netstat():
    debug2(' > netstat\n')
    argv = ['netstat', '-n']
    try:
        p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, stderr=null)
        content = p.stdout.read().decode("ASCII")
        p.wait()
    except OSError as e:
        log('%r failed: %r\n' % (argv, e))
        return

    for ip in re.findall(r'\d+\.\d+\.\d+\.\d+', content):
        debug3('<    %s\n' % ip)
        check_host(ip)
コード例 #18
0
ファイル: hostwatch.py プロジェクト: tberton/sshuttle
def _check_netstat():
    debug2(" > netstat\n")
    argv = ["netstat", "-n"]
    try:
        p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, stderr=null)
        content = p.stdout.read()
        p.wait()
    except OSError as e:
        log("%r failed: %r\n" % (argv, e))
        return

    for ip in re.findall(r"\d+\.\d+\.\d+\.\d+", content):
        debug3("<    %s\n" % ip)
        check_host(ip)
コード例 #19
0
ファイル: hostwatch.py プロジェクト: tberton/sshuttle
def _check_netstat():
    debug2(' > netstat\n')
    argv = ['netstat', '-n']
    try:
        p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, stderr=null)
        content = p.stdout.read()
        p.wait()
    except OSError as e:
        log('%r failed: %r\n' % (argv, e))
        return

    for ip in re.findall(r'\d+\.\d+\.\d+\.\d+', content):
        debug3('<    %s\n' % ip)
        check_host(ip)
コード例 #20
0
ファイル: client.py プロジェクト: taoweng/sshuttle
    def reload_acl_sources_file(self):
        global _allowed_sources

        if self.acl is not None:
            try:
                _new_allowed_sources = json.loads(self.acl, "utf-8")
                _allowed_sources = _new_allowed_sources
            except BaseException as e:
                debug3(
                    "An exception has occurred while loading the sources data: {}\n\n"
                    .format(e))
        else:
            _allowed_sources = None

        debug3("Network Connection Sources ACL \n\n%s" % _allowed_sources)
コード例 #21
0
ファイル: client.py プロジェクト: johnstonpythian/sshuttle
    def reload_acl_always_connected(self):
        global _acl_always_connected

        if self.acl is not None:
            try:
                _new_acl_always_connected = json.loads(self.acl, "utf-8")
                _acl_always_connected = _new_acl_always_connected
            except BaseException as e:
                debug3(
                    "An exception occurred while loading the aclAlwaysConnected data: {}\n\n"
                    .format(e))
        else:
            _acl_always_connected = None

        debug3("Always Connected ACL: \n\n%s" % _acl_always_connected)
コード例 #22
0
    def handlePubSubEvent(self, item):
        acl_type = None
        if (item['channel'] == sshuttleAclEventsChannel
                and item['type'] == "message"):
            if (item['data'] == sshuttleAcl):
                acl_type = ALLOWED_ACL_TYPE
            elif (item['data'] == sshuttleAclSources):
                acl_type = ACL_SOURCES_TYPE
            elif (item['data'] == sshuttleAclExcluded):
                acl_type = ACL_EXCLUDED_SOURCES_TYPE
            else:
                debug3("Unsupported ACL type. Channel: %s, Data: %s\n" %
                       (item['channel'], item['data']))

        if acl_type is not None:
            AclHandler(self.redisClient, acl_type).reload_acl_file()
コード例 #23
0
    def maybe_resume(self, wrote):
        self.buf_total = self.buf_total - wrote

        global _global_mux_wrapper_buffer_size
        _global_mux_wrapper_buffer_size -= wrote

        debug3(
            'Global mux wrap buf size: %d. Individual buf size: %d. On channel %s\n'
            % (_global_mux_wrapper_buffer_size, self.buf_total, self.channel))

        if self.isPaused and self.buf_total < INDIVIDUAL_BUFFER_RESUME_SIZE:
            self.mux.send(self.channel, CMD_RESUME, b(''))
            self.isPaused = False
            log('Global mux wrap buf size: %d. Individual buf size: %d (below threshold). Sent CMD_RESUME on channel %s\n'
                % (_global_mux_wrapper_buffer_size, self.buf_total,
                   self.channel))
コード例 #24
0
def connection_is_allowed(dstip, dstport, srcip):

    ctime = time.time()
    if _excluded_sources and srcip in _excluded_sources and (
            _excluded_sources[srcip] / 1000.0) >= ctime:
        debug1("Connection from a source excluded from the ACL\n")
        return True
    if not _allowed_sources or (srcip not in _allowed_sources) or (
            srcip in _allowed_sources and
        (_allowed_sources[srcip] / 1000.0) < ctime):
        debug3("Connection not allowed - allowed sources exception\n")
        return False
    if matches_acl(dstip, dstport, _disallowed_targets):
        debug3("Connection not allowed - firewall ACL exception\n")
        return False
    elif matches_acl(dstip, dstport, _allowed_targets):
        return True
コード例 #25
0
def _check_netstat():
    debug2(' > netstat')
    argv = ['netstat', '-n']
    try:
        p = ssubprocess.Popen(argv,
                              stdout=ssubprocess.PIPE,
                              stderr=null,
                              env=get_env())
        content = p.stdout.read().decode("ASCII")
        p.wait()
    except OSError:
        _, e = sys.exc_info()[:2]
        log('%r failed: %r' % (argv, e))
        return

    for ip in re.findall(r'\d+\.\d+\.\d+\.\d+', content):
        debug3('<    %s' % ip)
        check_host(ip)
コード例 #26
0
    def reload_acl_targets_file(self):

        global _allowed_targets

        if self.acl is not None:
            try:
                _new_targets = json.loads(self.acl, "utf-8")
                _allowed_targets = _new_targets
            except BaseException as e:
                debug3(
                    "An exception has occurred while loading the allowed targets (sshuttleAcl) data: {}\n\n"
                    .format(e))
        else:
            _allowed_targets = None

        if (not _allowed_targets):
            log("Allowed ACL list is empty. Restricting all access\n")
        else:
            log("Network Connection Allowed ACL \n\n%s" % _allowed_targets)
コード例 #27
0
ファイル: client.py プロジェクト: taoweng/sshuttle
    def handlePubSubEvent(self, item):
        acl_type = None
        channel = item['channel'].decode('utf-8')
        if (channel == sshuttleAclEventsChannel and item['type'] == "message"):
            data = item['data'].decode('utf-8')
            if (data == sshuttleAclTcp):
                acl_type = ALLOWED_TCP_ACL_TYPE
            elif (data == sshuttleAclUdp):
                acl_type = ALLOWED_UDP_ACL_TYPE
            elif (data == sshuttleAclSources):
                acl_type = ACL_SOURCES_TYPE
            elif (data == sshuttleAclExcluded):
                acl_type = ACL_EXCLUDED_SOURCES_TYPE
            else:
                debug3("Unsupported ACL type. Channel: %s, Data: %s\n" %
                       (channel, data))

        if acl_type is not None:
            AclHandler(self.redisClient, acl_type).reload_acl_file()
コード例 #28
0
def _check_etc_hosts():
    """If possible, read /etc/hosts to find hosts."""
    filename = '/etc/hosts'
    debug2(' > Reading %s on remote host' % filename)
    try:
        for line in open(filename):
            line = re.sub(r'#.*', '', line)  # remove comments
            words = line.strip().split()
            if not words:
                continue
            ip = words[0]
            if _is_ip(ip):
                names = words[1:]
                debug3('<    %s %r' % (ip, names))
                for n in names:
                    check_host(n)
                    found_host(n, ip)
    except (OSError, IOError):
        debug1("Failed to read %s on remote host" % filename)
コード例 #29
0
ファイル: client.py プロジェクト: johnstonpythian/sshuttle
def tcp_connection_is_allowed_conditional(dstip, dstport, srcip, check_acl,
                                          check_sources):

    if check_sources:
        ctime = time.time()
        if _excluded_sources and srcip in _excluded_sources and (
                _excluded_sources[srcip] / 1000.0) >= ctime:
            debug3("Connection from a source excluded from the ACL\n")
            return True

        check_allowed_sources = True
        # the global roomFeature must be turned ON and the srcip must match a desktop that has Always Connected enabled
        if (_always_connected
                == ALWAYS_CONNECTED_ON) and (srcip in _acl_always_connected):
            debug3(
                "TCP source %r allowed because alwaysConnected mode is ON and srcip is in aclAlwaysConnected\n"
                % srcip)
            check_allowed_sources = False

        if check_allowed_sources:
            if not _allowed_sources:
                debug3(
                    "Connection not allowed - allowed sources exception - not _allowed_sources\n"
                )
                return False
            if (srcip not in _allowed_sources):
                debug3(
                    "Connection not allowed - allowed sources exception - (srcip not in _allowed_sources)\n"
                )
                return False
            if (srcip in _allowed_sources
                    and (_allowed_sources[srcip] / 1000.0) < ctime):
                debug3(
                    "Connection not allowed - allowed sources exception - (srcip in _allowed_sources and (_allowed_sources[srcip] / 1000.0) < ctime)\n"
                )
                return False

    if check_acl:
        if matches_acl(dstip, dstport, _allowed_tcp_targets):
            return True
    else:
        return True
コード例 #30
0
    def maybe_pause(self, data):
        self.buf_total = self.buf_total + len(data)

        global _global_mux_wrapper_buffer_size
        _global_mux_wrapper_buffer_size += len(data)
        self.metrics.save_max_mux_wrapper_buffer_size(
            _global_mux_wrapper_buffer_size)

        debug3(
            'Global mux wrap buf size: %d. Individual buf size: %d. On channel %s\n'
            % (_global_mux_wrapper_buffer_size, self.buf_total, self.channel))

        if not self.isPaused and _global_mux_wrapper_buffer_size > PAUSE_TRAFFIC_TO_EDGE_THRESHOLD and self.buf_total\
                > INDIVIDUAL_BUFFER_PAUSE_SIZE:
            self.mux.send(self.channel, CMD_PAUSE, b(''))
            self.isPaused = True
            self.metrics.incr_paused_to_the_edge_count()
            log('Global mux wrap buf size: %d (above threshold). Individual buf size: %d (above threshold). Sent CMD_PAUSE on channel %s\n'
                % (_global_mux_wrapper_buffer_size, self.buf_total,
                   self.channel))
コード例 #31
0
def _check_netstat():
    debug2(' > netstat\n')
    env = {
        'PATH': os.environ['PATH'],
        'LC_ALL': "C",
    }
    argv = ['netstat', '-n']
    try:
        p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, stderr=null,
                              env=env)
        content = p.stdout.read().decode("ASCII")
        p.wait()
    except OSError:
        _, e = sys.exc_info()[:2]
        log('%r failed: %r\n' % (argv, e))
        return

    for ip in re.findall(r'\d+\.\d+\.\d+\.\d+', content):
        debug3('<    %s\n' % ip)
        check_host(ip)
コード例 #32
0
 def __init__(self,
              rsock,
              wsock,
              connect_to=None,
              peername=None,
              connection_is_allowed_callback=None):
     global _swcount
     _swcount += 1
     debug3('creating new SockWrapper (%d now exist)\n' % _swcount)
     self.exc = None
     self.rsock = rsock
     self.wsock = wsock
     self.shut_read = self.shut_write = False
     self.buf = []
     self.connect_to = connect_to
     self.peername = peername or _try_peername(self.rsock)
     self.connection_is_allowed_callback = connection_is_allowed_callback
     self.try_connect()
     self.isWrite = False
     self.isPaused = False  # traffic to the edge is paused (always false in SockWrapper; may be true in MuxWrapper)
コード例 #33
0
def expire_connections(now, mux):
    for chan, timeout in dnsreqs.items():
        if timeout < now:
            debug3('expiring dnsreqs channel=%d\n' % chan)
            del mux.channels[chan]
            del dnsreqs[chan]
    debug3('Remaining DNS requests: %d\n' % len(dnsreqs))
    for peer, (chan, timeout) in udp_by_src.items():
        if timeout < now:
            debug3('expiring UDP channel channel=%d peer=%r\n' % (chan, peer))
            mux.send(chan, ssnet.CMD_UDP_CLOSE, '')
            del mux.channels[chan]
            del udp_by_src[peer]
    debug3('Remaining UDP channels: %d\n' % len(udp_by_src))
コード例 #34
0
ファイル: client.py プロジェクト: taoweng/sshuttle
def udp_connection_is_allowed(dstip, dstport, srcip):

    ctime = time.time()
    if _excluded_sources and srcip in _excluded_sources and (
            _excluded_sources[srcip] / 1000.0) >= ctime:
        debug1("Connection from a source excluded from the ACL\n")
        return True

    if not _allowed_sources:
        debug3(
            "Connection not allowed - allowed sources exception - not _allowed_sources\n"
        )
        return False
    if (srcip not in _allowed_sources):
        debug3(
            "Connection not allowed - allowed sources exception - (srcip not in _allowed_sources)\n"
        )
        return False
    if (srcip in _allowed_sources
            and (_allowed_sources[srcip] / 1000.0) < ctime):
        debug3(
            "Connection not allowed - allowed sources exception - (srcip in _allowed_sources and (_allowed_sources[srcip] / 1000.0) < ctime)\n"
        )
        return False

    if matches_acl(dstip, dstport, _allowed_udp_targets):
        return True
コード例 #35
0
def _check_netstat():
    debug2(' > netstat')
    argv = ['netstat', '-n']
    try:
        p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, stderr=null,
                              env=get_env())
        content = p.stdout.read().decode("ASCII")
        p.wait()
    except OSError:
        _, e = sys.exc_info()[:2]
        log('%r failed: %r' % (argv, e))
        return

    # The same IPs may appear multiple times. Consolidate them so the
    # debug message doesn't print the same IP repeatedly.
    ip_list = []
    for ip in re.findall(r'\d+\.\d+\.\d+\.\d+', content):
        if ip not in ip_list:
            ip_list.append(ip)

    for ip in sorted(ip_list):
        debug3('<    %s' % ip)
        check_host(ip)
コード例 #36
0
ファイル: hostwatch.py プロジェクト: xiongyw/sshuttle
def _check_nmb(hostname, is_workgroup, is_master):
    return
    global _nmb_ok
    if not _nmb_ok:
        return
    debug2(' > n%d%d: %s\n' % (is_workgroup, is_master, hostname))
    env = {
        'PATH': os.environ['PATH'],
        'LC_ALL': "C",
    }
    argv = ['nmblookup'] + ['-M'] * is_master + ['--', hostname]
    try:
        p = ssubprocess.Popen(argv,
                              stdout=ssubprocess.PIPE,
                              stderr=null,
                              env=env)
        lines = p.stdout.readlines()
        rv = p.wait()
    except OSError:
        _, e = sys.exc_info()[:2]
        log('%r failed: %r\n' % (argv, e))
        _nmb_ok = False
        return
    if rv:
        log('%r returned %d\n' % (argv, rv))
        return
    for line in lines:
        m = re.match(r'(\d+\.\d+\.\d+\.\d+) (\w+)<\w\w>\n', line)
        if m:
            g = m.groups()
            (ip, name) = (g[0], g[1].lower())
            debug3('<    %s -> %s\n' % (name, ip))
            if is_workgroup:
                _enqueue(_check_smb, ip)
            else:
                found_host(name, ip)
                check_host(name)
コード例 #37
0
def expire_connections(now, mux):
    remove = []
    for chan, timeout in dnsreqs.items():
        if timeout < now:
            debug3('expiring dnsreqs channel=%d\n' % chan)
            remove.append(chan)
            del mux.channels[chan]
    for chan in remove:
        del dnsreqs[chan]
    debug3('Remaining DNS requests: %d\n' % len(dnsreqs))

    remove = []
    for peer, (chan, timeout) in udp_by_src.items():
        if timeout < now:
            debug3('expiring UDP channel channel=%d peer=%r\n' % (chan, peer))
            mux.send(chan, ssnet.CMD_UDP_CLOSE, b'')
            remove.append(peer)
            del mux.channels[chan]
    for peer in remove:
        del udp_by_src[peer]
    debug3('Remaining UDP channels: %d\n' % len(udp_by_src))

    # we also want to close all TCP connections from sources that have expired their lease
    global tcp_conns
    new_tcp_conns = []
    for (srcip, dstip, s, sock) in tcp_conns:
        if connection_is_allowed(dstip[0], str(dstip[1]), srcip[0]) and s.ok:
            new_tcp_conns.append((srcip, dstip, s, sock))
        else:
            try:
                # remove from list of active tcp connections
                del active_tcp_conns[sock]

                # really make sure we kill everything while we can
                s.ok = False
                s.wrap1.noread()
                s.wrap1.nowrite()
                s.wrap2.noread()
                s.wrap2.nowrite()
                del mux.channels[s.wrap2.channel]
                sock.close()
                sock.shutdown(2)
            except:
                # we may hit an exception if the socket has already been closed...that is ok
                pass

    tcp_conns = new_tcp_conns
コード例 #38
0
ファイル: client.py プロジェクト: taoweng/sshuttle
def acl_port_match(port, acl_port_rule):
    for port_entry in acl_port_rule:
        if '-' in port_entry:
            if (port_in_range(port_entry, port)):
                debug3('port: %s is in acl port range: %s' %
                       (port, port_entry))
                return True

            debug3('port: %s is NOT in acl port range: %s' %
                   (port, port_entry))
        elif int(port_entry) == int(port):
            debug3('port: %s is in acl port rule: %s' % (port, acl_port_rule))
            return True

    return False
コード例 #39
0
ファイル: ssnet.py プロジェクト: mheiges/sshuttle-1
 def try_connect(self):
     if self.connect_to and self.shut_write:
         self.noread()
         self.connect_to = None
     if not self.connect_to:
         return  # already connected
     self.rsock.setblocking(False)
     debug3('%r: trying connect to %r\n' % (self, self.connect_to))
     try:
         self.rsock.connect(self.connect_to)
         # connected successfully (Linux)
         self.connect_to = None
     except socket.error:
         _, e = sys.exc_info()[:2]
         debug3('%r: connect result: %s\n' % (self, e))
         if e.args[0] == errno.EINVAL:
             # this is what happens when you call connect() on a socket
             # that is now connected but returned EINPROGRESS last time,
             # on BSD, on python pre-2.5.1.  We need to use getsockopt()
             # to get the "real" error.  Later pythons do this
             # automatically, so this code won't run.
             realerr = self.rsock.getsockopt(socket.SOL_SOCKET,
                                             socket.SO_ERROR)
             e = socket.error(realerr, os.strerror(realerr))
             debug3('%r: fixed connect result: %s\n' % (self, e))
         if e.args[0] in [errno.EINPROGRESS, errno.EALREADY]:
             pass  # not connected yet
         elif e.args[0] == 0:
             # connected successfully (weird Linux bug?)
             # Sometimes Linux seems to return EINVAL when it isn't
             # invalid.  This *may* be caused by a race condition
             # between connect() and getsockopt(SO_ERROR) (ie. it
             # finishes connecting in between the two, so there is no
             # longer an error).  However, I'm not sure of that.
             #
             # I did get at least one report that the problem went away
             # when we added this, however.
             self.connect_to = None
         elif e.args[0] == errno.EISCONN:
             # connected successfully (BSD)
             self.connect_to = None
         elif e.args[0] in NET_ERRS + [errno.EACCES, errno.EPERM]:
             # a "normal" kind of error
             self.connect_to = None
             self.seterr(e)
         else:
             raise  # error we've never heard of?!  barf completely.
コード例 #40
0
ファイル: ssnet.py プロジェクト: TooKennySupreme/sshuttle
 def try_connect(self):
     if self.connect_to and self.shut_write:
         self.noread()
         self.connect_to = None
     if not self.connect_to:
         return  # already connected
     self.rsock.setblocking(False)
     debug3('%r: trying connect to %r\n' % (self, self.connect_to))
     try:
         self.rsock.connect(self.connect_to)
         # connected successfully (Linux)
         self.connect_to = None
     except socket.error:
         _, e = sys.exc_info()[:2]
         debug3('%r: connect result: %s\n' % (self, e))
         if e.args[0] == errno.EINVAL:
             # this is what happens when you call connect() on a socket
             # that is now connected but returned EINPROGRESS last time,
             # on BSD, on python pre-2.5.1.  We need to use getsockopt()
             # to get the "real" error.  Later pythons do this
             # automatically, so this code won't run.
             realerr = self.rsock.getsockopt(socket.SOL_SOCKET,
                                             socket.SO_ERROR)
             e = socket.error(realerr, os.strerror(realerr))
             debug3('%r: fixed connect result: %s\n' % (self, e))
         if e.args[0] in [errno.EINPROGRESS, errno.EALREADY]:
             pass  # not connected yet
         elif e.args[0] == 0:
             # connected successfully (weird Linux bug?)
             # Sometimes Linux seems to return EINVAL when it isn't
             # invalid.  This *may* be caused by a race condition
             # between connect() and getsockopt(SO_ERROR) (ie. it
             # finishes connecting in between the two, so there is no
             # longer an error).  However, I'm not sure of that.
             #
             # I did get at least one report that the problem went away
             # when we added this, however.
             self.connect_to = None
         elif e.args[0] == errno.EISCONN:
             # connected successfully (BSD)
             self.connect_to = None
         elif e.args[0] in NET_ERRS + [errno.EACCES, errno.EPERM]:
             # a "normal" kind of error
             self.connect_to = None
             self.seterr(e)
         else:
             raise  # error we've never heard of?!  barf completely.
コード例 #41
0
ファイル: ipfw.py プロジェクト: tberton/sshuttle
def _handle_diversion(divertsock, dnsport):
    p, tag = divertsock.recvfrom(4096)
    src, dst = _udp_unpack(p)
    debug3('got diverted packet from %r to %r\n' % (src, dst))
    if dst[1] == 53:
        # outgoing DNS
        debug3('...packet is a DNS request.\n')
        _real_dns_server[0] = dst
        dst = ('127.0.0.1', dnsport)
    elif src[1] == dnsport:
        if islocal(src[0], divertsock.family):
            debug3('...packet is a DNS response.\n')
            src = _real_dns_server[0]
    else:
        log('weird?! unexpected divert from %r to %r\n' % (src, dst))
        assert (0)
    newp = _udp_repack(p, src, dst)
    divertsock.sendto(newp, tag)
コード例 #42
0
ファイル: ipfw.py プロジェクト: tberton/sshuttle
def _handle_diversion(divertsock, dnsport):
    p, tag = divertsock.recvfrom(4096)
    src, dst = _udp_unpack(p)
    debug3('got diverted packet from %r to %r\n' % (src, dst))
    if dst[1] == 53:
        # outgoing DNS
        debug3('...packet is a DNS request.\n')
        _real_dns_server[0] = dst
        dst = ('127.0.0.1', dnsport)
    elif src[1] == dnsport:
        if islocal(src[0], divertsock.family):
            debug3('...packet is a DNS response.\n')
            src = _real_dns_server[0]
    else:
        log('weird?! unexpected divert from %r to %r\n' % (src, dst))
        assert(0)
    newp = _udp_repack(p, src, dst)
    divertsock.sendto(newp, tag)
コード例 #43
0
ファイル: server.py プロジェクト: Tobey123/sshuttle
def main(latency_control, auto_hosts):
    debug1('Starting server with Python version %s\n' %
           platform.python_version())

    if helpers.verbose >= 1:
        helpers.logprefix = ' s: '
    else:
        helpers.logprefix = 'server: '
    debug1('latency control setting = %r\n' % latency_control)

    routes = list(list_routes())
    debug1('available routes:\n')
    for r in routes:
        debug1('  %d/%s/%d\n' % r)

    # synchronization header
    sys.stdout.write('\0\0SSHUTTLE0001')
    sys.stdout.flush()

    handlers = []
    mux = Mux(
        socket.fromfd(sys.stdin.fileno(), socket.AF_INET, socket.SOCK_STREAM),
        socket.fromfd(sys.stdout.fileno(), socket.AF_INET, socket.SOCK_STREAM))
    handlers.append(mux)
    routepkt = ''
    for r in routes:
        routepkt += '%d,%s,%d\n' % r
    mux.send(0, ssnet.CMD_ROUTES, b(routepkt))

    hw = Hostwatch()
    hw.leftover = b('')

    def hostwatch_ready(sock):
        assert (hw.pid)
        content = hw.sock.recv(4096)
        if content:
            lines = (hw.leftover + content).split(b('\n'))
            if lines[-1]:
                # no terminating newline: entry isn't complete yet!
                hw.leftover = lines.pop()
                lines.append(b(''))
            else:
                hw.leftover = b('')
            mux.send(0, ssnet.CMD_HOST_LIST, b('\n').join(lines))
        else:
            raise Fatal('hostwatch process died')

    def got_host_req(data):
        if not hw.pid:
            (hw.pid, hw.sock) = start_hostwatch(data.strip().split(),
                                                auto_hosts)
            handlers.append(Handler(socks=[hw.sock], callback=hostwatch_ready))

    mux.got_host_req = got_host_req

    def new_channel(channel, data):
        (family, dstip, dstport) = data.decode("ASCII").split(',', 2)
        family = int(family)
        # AF_INET is the same constant on Linux and BSD but AF_INET6
        # is different. As the client and server can be running on
        # different platforms we can not just set the socket family
        # to what comes in the wire.
        if family != socket.AF_INET:
            family = socket.AF_INET6
        dstport = int(dstport)
        outwrap = ssnet.connect_dst(family, dstip, dstport)
        handlers.append(Proxy(MuxWrapper(mux, channel), outwrap))

    mux.new_channel = new_channel

    dnshandlers = {}

    def dns_req(channel, data):
        debug2('Incoming DNS request channel=%d.\n' % channel)
        h = DnsProxy(mux, channel, data)
        handlers.append(h)
        dnshandlers[channel] = h

    mux.got_dns_req = dns_req

    udphandlers = {}

    def udp_req(channel, cmd, data):
        debug2('Incoming UDP request channel=%d, cmd=%d\n' % (channel, cmd))
        if cmd == ssnet.CMD_UDP_DATA:
            (dstip, dstport, data) = data.split(b(','), 2)
            dstport = int(dstport)
            debug2('is incoming UDP data. %r %d.\n' % (dstip, dstport))
            h = udphandlers[channel]
            h.send((dstip, dstport), data)
        elif cmd == ssnet.CMD_UDP_CLOSE:
            debug2('is incoming UDP close\n')
            h = udphandlers[channel]
            h.ok = False
            del mux.channels[channel]

    def udp_open(channel, data):
        debug2('Incoming UDP open.\n')
        family = int(data)
        mux.channels[channel] = lambda cmd, data: udp_req(channel, cmd, data)
        if channel in udphandlers:
            raise Fatal('UDP connection channel %d already open' % channel)
        else:
            h = UdpProxy(mux, channel, family)
            handlers.append(h)
            udphandlers[channel] = h

    mux.got_udp_open = udp_open

    while mux.ok:
        if hw.pid:
            assert (hw.pid > 0)
            (rpid, rv) = os.waitpid(hw.pid, os.WNOHANG)
            if rpid:
                raise Fatal('hostwatch exited unexpectedly: code 0x%04x\n' %
                            rv)

        ssnet.runonce(handlers, mux)
        if latency_control:
            mux.check_fullness()

        if dnshandlers:
            now = time.time()
            remove = []
            for channel, h in dnshandlers.items():
                if h.timeout < now or not h.ok:
                    debug3('expiring dnsreqs channel=%d\n' % channel)
                    remove.append(channel)
                    h.ok = False
            for channel in remove:
                del dnshandlers[channel]
        if udphandlers:
            remove = []
            for channel, h in udphandlers.items():
                if not h.ok:
                    debug3('expiring UDP channel=%d\n' % channel)
                    remove.append(channel)
                    h.ok = False
            for channel in remove:
                del udphandlers[channel]
コード例 #44
0
ファイル: pf.py プロジェクト: maximilize/sshuttle
 def add_rules(self, anchor, rules):
     assert isinstance(rules, bytes)
     debug3("rules:\n" + rules.decode("ASCII"))
     pfctl('-a %s -f /dev/stdin' % anchor, rules)
コード例 #45
0
ファイル: pf.py プロジェクト: 64BitChris/sshuttle
 def add_rules(self, rules):
     assert isinstance(rules, bytes)
     debug3("rules:\n" + rules.decode("ASCII"))
     pfctl('-a sshuttle -f /dev/stdin', rules)
コード例 #46
0
ファイル: pf.py プロジェクト: luserx0/sshuttle
 def add_rules(anchor, rules):
     assert isinstance(rules, bytes)
     debug3("rules:\n" + rules.decode("ASCII"))
     pfctl('-a %s -f /dev/stdin' % anchor, rules)
コード例 #47
0
ファイル: pf.py プロジェクト: Kriechi/sshuttle
    def setup_firewall(self, port, dnsport, nslist, family, subnets, udp):
        tables = []
        translating_rules = []
        filtering_rules = []

        if family != socket.AF_INET:
            raise Exception(
                'Address family "%s" unsupported by pf method_name'
                % family_to_string(family))
        if udp:
            raise Exception("UDP not supported by pf method_name")

        if len(subnets) > 0:
            includes = []
            # If a given subnet is both included and excluded, list the
            # exclusion first; the table will ignore the second, opposite
            # definition
            for f, swidth, sexclude, snet in sorted(
                    subnets, key=lambda s: (s[1], s[2]), reverse=True):
                includes.append(b"%s%s/%d" %
                                (b"!" if sexclude else b"",
                                    snet.encode("ASCII"),
                                    swidth))

            tables.append(
                b'table <forward_subnets> {%s}' % b','.join(includes))
            translating_rules.append(
                b'rdr pass on lo0 proto tcp '
                b'to <forward_subnets> -> 127.0.0.1 port %r' % port)
            filtering_rules.append(
                b'pass out route-to lo0 inet proto tcp '
                b'to <forward_subnets> keep state')

        if len(nslist) > 0:
            tables.append(
                b'table <dns_servers> {%s}' %
                b','.join([ns[1].encode("ASCII") for ns in nslist]))
            translating_rules.append(
                b'rdr pass on lo0 proto udp to '
                b'<dns_servers> port 53 -> 127.0.0.1 port %r' % dnsport)
            filtering_rules.append(
                b'pass out route-to lo0 inet proto udp to '
                b'<dns_servers> port 53 keep state')

        rules = b'\n'.join(tables + translating_rules + filtering_rules) \
                + b'\n'
        assert isinstance(rules, bytes)
        debug3("rules:\n" + rules.decode("ASCII"))

        pf_status = pfctl('-s all')[0]
        if b'\nrdr-anchor "sshuttle" all\n' not in pf_status:
            pf_add_anchor_rule(osdefs.PF_RDR, b"sshuttle")
        if b'\nanchor "sshuttle" all\n' not in pf_status:
            pf_add_anchor_rule(osdefs.PF_PASS, b"sshuttle")

        pfctl('-a sshuttle -f /dev/stdin', rules)
        if osdefs.platform == "darwin":
            o = pfctl('-E')
            _pf_context['Xtoken'] = \
                re.search(b'Token : (.+)', o[1]).group(1)
        elif b'INFO:\nStatus: Disabled' in pf_status:
            pfctl('-e')
            _pf_context['started_by_sshuttle'] = True
コード例 #48
0
ファイル: tproxy.py プロジェクト: 64BitChris/sshuttle
 def recv_udp(listener, bufsize):
     debug3('Accept UDP using recvfrom.\n')
     data, srcip = listener.recvfrom(bufsize)
     return (srcip, None, data)
コード例 #49
0
ファイル: client.py プロジェクト: dlenski/sshuttle
def udp_done(chan, data, method, sock, dstip):
    (src, srcport, data) = data.split(b",", 2)
    srcip = (src, int(srcport))
    debug3('doing send from %r to %r\n' % (srcip, dstip,))
    method.send_udp(sock, srcip, dstip, data)
コード例 #50
0
ファイル: client.py プロジェクト: dlenski/sshuttle
def dns_done(chan, data, method, sock, srcip, dstip, mux):
    debug3('dns_done: channel=%d src=%r dst=%r\n' % (chan, srcip, dstip))
    del mux.channels[chan]
    del dnsreqs[chan]
    method.send_udp(sock, srcip, dstip, data)
コード例 #51
0
ファイル: server.py プロジェクト: dlenski/sshuttle
def main(latency_control):
    debug1('Starting server with Python version %s\n'
           % platform.python_version())

    if helpers.verbose >= 1:
        helpers.logprefix = ' s: '
    else:
        helpers.logprefix = 'server: '
    debug1('latency control setting = %r\n' % latency_control)

    routes = list(list_routes())
    debug1('available routes:\n')
    for r in routes:
        debug1('  %d/%s/%d\n' % r)

    # synchronization header
    sys.stdout.write('\0\0SSHUTTLE0001')
    sys.stdout.flush()

    handlers = []
    mux = Mux(socket.fromfd(sys.stdin.fileno(),
                            socket.AF_INET, socket.SOCK_STREAM),
              socket.fromfd(sys.stdout.fileno(),
                            socket.AF_INET, socket.SOCK_STREAM))
    handlers.append(mux)
    routepkt = ''
    for r in routes:
        routepkt += '%d,%s,%d\n' % r
    mux.send(0, ssnet.CMD_ROUTES, b(routepkt))

    hw = Hostwatch()
    hw.leftover = b('')

    def hostwatch_ready(sock):
        assert(hw.pid)
        content = hw.sock.recv(4096)
        if content:
            lines = (hw.leftover + content).split(b('\n'))
            if lines[-1]:
                # no terminating newline: entry isn't complete yet!
                hw.leftover = lines.pop()
                lines.append(b(''))
            else:
                hw.leftover = b('')
            mux.send(0, ssnet.CMD_HOST_LIST, b('\n').join(lines))
        else:
            raise Fatal('hostwatch process died')

    def got_host_req(data):
        if not hw.pid:
            (hw.pid, hw.sock) = start_hostwatch(data.strip().split())
            handlers.append(Handler(socks=[hw.sock],
                                    callback=hostwatch_ready))
    mux.got_host_req = got_host_req

    def new_channel(channel, data):
        (family, dstip, dstport) = data.decode("ASCII").split(',', 2)
        family = int(family)
        dstport = int(dstport)
        outwrap = ssnet.connect_dst(family, dstip, dstport)
        handlers.append(Proxy(MuxWrapper(mux, channel), outwrap))
    mux.new_channel = new_channel

    dnshandlers = {}

    def dns_req(channel, data):
        debug2('Incoming DNS request channel=%d.\n' % channel)
        h = DnsProxy(mux, channel, data)
        handlers.append(h)
        dnshandlers[channel] = h
    mux.got_dns_req = dns_req

    udphandlers = {}

    def udp_req(channel, cmd, data):
        debug2('Incoming UDP request channel=%d, cmd=%d\n' % (channel, cmd))
        if cmd == ssnet.CMD_UDP_DATA:
            (dstip, dstport, data) = data.split(",", 2)
            dstport = int(dstport)
            debug2('is incoming UDP data. %r %d.\n' % (dstip, dstport))
            h = udphandlers[channel]
            h.send((dstip, dstport), data)
        elif cmd == ssnet.CMD_UDP_CLOSE:
            debug2('is incoming UDP close\n')
            h = udphandlers[channel]
            h.ok = False
            del mux.channels[channel]

    def udp_open(channel, data):
        debug2('Incoming UDP open.\n')
        family = int(data)
        mux.channels[channel] = lambda cmd, data: udp_req(channel, cmd, data)
        if channel in udphandlers:
            raise Fatal('UDP connection channel %d already open' % channel)
        else:
            h = UdpProxy(mux, channel, family)
            handlers.append(h)
            udphandlers[channel] = h
    mux.got_udp_open = udp_open

    while mux.ok:
        if hw.pid:
            assert(hw.pid > 0)
            (rpid, rv) = os.waitpid(hw.pid, os.WNOHANG)
            if rpid:
                raise Fatal(
                    'hostwatch exited unexpectedly: code 0x%04x\n' % rv)

        ssnet.runonce(handlers, mux)
        if latency_control:
            mux.check_fullness()

        if dnshandlers:
            now = time.time()
            remove = []
            for channel, h in dnshandlers.items():
                if h.timeout < now or not h.ok:
                    debug3('expiring dnsreqs channel=%d\n' % channel)
                    remove.append(channel)
                    h.ok = False
            for channel in remove:
                del dnshandlers[channel]
        if udphandlers:
            remove = []
            for channel, h in udphandlers.items():
                if not h.ok:
                    debug3('expiring UDP channel=%d\n' % channel)
                    remove.append(channel)
                    h.ok = False
            for channel in remove:
                del udphandlers[channel]