コード例 #1
0
def test_recv_udp():
    sock = Mock()
    sock.recvfrom.return_value = "11111", "127.0.0.1"
    method = get_method('nat')
    result = method.recv_udp(sock, 1024)
    assert sock.mock_calls == [call.recvfrom(1024)]
    assert result == ("127.0.0.1", None, "11111")
コード例 #2
0
def test_get_tcp_dstip():
    sock = Mock()
    sock.family = AF_INET
    sock.getsockopt.return_value = struct.pack(
        '!HHBBBB', socket.ntohs(AF_INET), 1024, 127, 0, 0, 1)
    method = get_method('nat')
    assert method.get_tcp_dstip(sock) == ('127.0.0.1', 1024)
    assert sock.mock_calls == [call.getsockopt(0, 80, 16)]

    sock = Mock()
    sock.family = AF_INET6
    sock.getsockopt.return_value = struct.pack(
        '!HH4xBBBBBBBBBBBBBBBB', socket.ntohs(AF_INET6),
        1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    method = get_method('nft')
    assert method.get_tcp_dstip(sock) == ('::1', 1024)
    assert sock.mock_calls == [call.getsockopt(41, 80, 64)]
コード例 #3
0
def test_recv_udp(mock_recv_udp):
    mock_recv_udp.return_value = ("127.0.0.1", "127.0.0.2", "11111")

    sock = Mock()
    method = get_method('tproxy')
    result = method.recv_udp(sock, 1024)
    assert sock.mock_calls == []
    assert mock_recv_udp.mock_calls == [call(sock, 1024)]
    assert result == ("127.0.0.1", "127.0.0.2", "11111")
コード例 #4
0
def test_setup_udp_listener():
    listener = Mock()
    method = get_method('tproxy')
    method.setup_udp_listener(listener)
    assert listener.mock_calls == [
        call.setsockopt(0, 19, 1),
        call.v4.setsockopt(0, 20, 1),
        call.v6.setsockopt(41, 74, 1)
    ]
コード例 #5
0
ファイル: client.py プロジェクト: transferwise/tshuttle
    def __init__(self, method_name, sudo_pythonpath):
        self.auto_nets = []
        python_path = os.path.dirname(os.path.dirname(__file__))
        argvbase = ([sys.executable, sys.argv[0]] + ['-v'] *
                    (helpers.verbose or 0) + ['--method', method_name] +
                    ['--firewall'])
        if ssyslog._p:
            argvbase += ['--syslog']

        # Determine how to prefix the command in order to elevate privileges.
        if platform.platform().startswith('OpenBSD'):
            elev_prefix = ['doas']  # OpenBSD uses built in `doas`
        else:
            elev_prefix = ['sudo', '-p', '[local sudo] Password: '******'/usr/bin/env', 'PYTHONPATH=%s' % python_path]
        argv_tries = [elev_prefix + argvbase, argvbase]

        # we can't use stdin/stdout=subprocess.PIPE here, as we normally would,
        # because stupid Linux 'su' requires that stdin be attached to a tty.
        # Instead, attach a *bidirectional* socket to its stdout, and use
        # that for talking in both directions.
        (s1, s2) = socket.socketpair()

        def setup():
            # run in the child process
            s2.close()

        if os.getuid() == 0:
            argv_tries = argv_tries[-1:]  # last entry only
        for argv in argv_tries:
            try:
                if argv[0] == 'su':
                    sys.stderr.write('[local su] ')
                self.p = ssubprocess.Popen(argv, stdout=s1, preexec_fn=setup)
                # No env: Talking to `FirewallClient.start`, which has no i18n.
                break
            except OSError as e:
                log('Spawning firewall manager: %r' % argv)
                raise Fatal(e)
        self.argv = argv
        s1.close()
        self.pfile = s2.makefile('rwb')
        line = self.pfile.readline()
        self.check()
        if line[0:5] != b'READY':
            raise Fatal('%r expected READY, got %r' % (self.argv, line))
        method_name = line[6:-1]
        self.method = get_method(method_name.decode("ASCII"))
        self.method.set_firewall(self)
コード例 #6
0
def test_assert_features():
    method = get_method('nat')
    features = method.get_supported_features()
    method.assert_features(features)

    features.udp = True
    with pytest.raises(Fatal):
        method.assert_features(features)

    features.ipv6 = True
    with pytest.raises(Fatal):
        method.assert_features(features)
コード例 #7
0
def test_send_udp(mock_socket):
    sock = Mock()
    method = get_method('tproxy')
    method.send_udp(sock, "127.0.0.2", "127.0.0.1", "2222222")
    assert sock.mock_calls == []
    assert mock_socket.mock_calls == [
        call(sock.family, 2),
        call().setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1),
        call().setsockopt(0, 19, 1),
        call().bind('127.0.0.2'),
        call().sendto("2222222", '127.0.0.1'),
        call().close()
    ]
コード例 #8
0
def test_firewall_command_darwin(mock_pf_get_dev, mock_ioctl, mock_stdout):
    method = get_method('pf')
    assert not method.firewall_command("somthing")

    command = "QUERY_PF_NAT %d,%d,%s,%d,%s,%d\n" % (
        AF_INET, socket.IPPROTO_TCP, "127.0.0.1", 1025, "127.0.0.2", 1024)
    assert method.firewall_command(command)

    assert mock_pf_get_dev.mock_calls == [call()]
    assert mock_ioctl.mock_calls == [
        call(mock_pf_get_dev(), 0xc0544417, ANY),
    ]
    assert mock_stdout.mock_calls == [
        call.write('QUERY_PF_NAT_SUCCESS 0.0.0.0,0\n'),
        call.flush(),
    ]
コード例 #9
0
def test_get_tcp_dstip():
    sock = Mock()
    sock.getpeername.return_value = ("127.0.0.1", 1024)
    sock.getsockname.return_value = ("127.0.0.2", 1025)
    sock.family = AF_INET

    firewall = Mock()
    firewall.pfile.readline.return_value = \
        b"QUERY_PF_NAT_SUCCESS 127.0.0.3,1026\n"

    method = get_method('pf')
    method.set_firewall(firewall)
    assert method.get_tcp_dstip(sock) == ('127.0.0.3', 1026)

    assert sock.mock_calls == [
        call.getpeername(),
        call.getsockname(),
    ]
    assert firewall.mock_calls == [
        call.pfile.write(b'QUERY_PF_NAT 2,6,127.0.0.1,1024,127.0.0.2,1025\n'),
        call.pfile.flush(),
        call.pfile.readline()
    ]
コード例 #10
0
ファイル: firewall.py プロジェクト: transferwise/tshuttle
def main(method_name, syslog):
    helpers.logprefix = 'fw: '
    stdin, stdout = setup_daemon()
    hostmap = {}
    debug1('Starting firewall with Python version %s' %
           platform.python_version())

    if method_name == "auto":
        method = get_auto_method()
    else:
        method = get_method(method_name)

    if syslog:
        ssyslog.start_syslog()
        ssyslog.stderr_to_syslog()

    if not method.is_supported():
        raise Fatal("The %s method is not supported on this machine. "
                    "Check that the appropriate programs are in your "
                    "PATH." % method_name)

    debug1('ready method name %s.' % method.name)
    stdout.write('READY %s\n' % method.name)
    stdout.flush()

    # we wait until we get some input before creating the rules.  That way,
    # tshuttle can launch us as early as possible (and get sudo password
    # authentication as early in the startup process as possible).
    line = stdin.readline(128)
    if not line:
        return  # parent died; nothing to do

    subnets = []
    if line != 'ROUTES\n':
        raise Fatal('expected ROUTES but got %r' % line)
    while 1:
        line = stdin.readline(128)
        if not line:
            raise Fatal('expected route but got %r' % line)
        elif line.startswith("NSLIST\n"):
            break
        try:
            (family, width, exclude, ip, fport, lport) = \
                    line.strip().split(',', 5)
        except BaseException:
            raise Fatal('expected route or NSLIST but got %r' % line)
        subnets.append((int(family), int(width), bool(int(exclude)), ip,
                        int(fport), int(lport)))
    debug2('Got subnets: %r' % subnets)

    nslist = []
    if line != 'NSLIST\n':
        raise Fatal('expected NSLIST but got %r' % line)
    while 1:
        line = stdin.readline(128)
        if not line:
            raise Fatal('expected nslist but got %r' % line)
        elif line.startswith("PORTS "):
            break
        try:
            (family, ip) = line.strip().split(',', 1)
        except BaseException:
            raise Fatal('expected nslist or PORTS but got %r' % line)
        nslist.append((int(family), ip))
        debug2('Got partial nslist: %r' % nslist)
    debug2('Got nslist: %r' % nslist)

    if not line.startswith('PORTS '):
        raise Fatal('expected PORTS but got %r' % line)
    _, _, ports = line.partition(" ")
    ports = ports.split(",")
    if len(ports) != 4:
        raise Fatal('expected 4 ports but got %d' % len(ports))
    port_v6 = int(ports[0])
    port_v4 = int(ports[1])
    dnsport_v6 = int(ports[2])
    dnsport_v4 = int(ports[3])

    assert (port_v6 >= 0)
    assert (port_v6 <= 65535)
    assert (port_v4 >= 0)
    assert (port_v4 <= 65535)
    assert (dnsport_v6 >= 0)
    assert (dnsport_v6 <= 65535)
    assert (dnsport_v4 >= 0)
    assert (dnsport_v4 <= 65535)

    debug2('Got ports: %d,%d,%d,%d' %
           (port_v6, port_v4, dnsport_v6, dnsport_v4))

    line = stdin.readline(128)
    if not line:
        raise Fatal('expected GO but got %r' % line)
    elif not line.startswith("GO "):
        raise Fatal('expected GO but got %r' % line)

    _, _, args = line.partition(" ")
    udp, user = args.strip().split(" ", 1)
    udp = bool(int(udp))
    if user == '-':
        user = None
    debug2('Got udp: %r, user: %r' % (udp, user))

    subnets_v6 = [i for i in subnets if i[0] == socket.AF_INET6]
    nslist_v6 = [i for i in nslist if i[0] == socket.AF_INET6]
    subnets_v4 = [i for i in subnets if i[0] == socket.AF_INET]
    nslist_v4 = [i for i in nslist if i[0] == socket.AF_INET]

    try:
        debug1('setting up.')

        if subnets_v6 or nslist_v6:
            debug2('setting up IPv6.')
            method.setup_firewall(port_v6, dnsport_v6, nslist_v6,
                                  socket.AF_INET6, subnets_v6, udp, user)

        if subnets_v4 or nslist_v4:
            debug2('setting up IPv4.')
            method.setup_firewall(port_v4, dnsport_v4, nslist_v4,
                                  socket.AF_INET, subnets_v4, udp, user)

        stdout.write('STARTED\n')

        try:
            stdout.flush()
        except IOError:
            # the parent process died for some reason; he's surely been loud
            # enough, so no reason to report another error
            return

        # Now we wait until EOF or any other kind of exception.  We need
        # to stay running so that we don't need a *second* password
        # authentication at shutdown time - that cleanup is important!
        while 1:
            line = stdin.readline(128)
            if line.startswith('HOST '):
                (name, ip) = line[5:].strip().split(',', 1)
                hostmap[name] = ip
                debug2('setting up /etc/hosts.')
                rewrite_etc_hosts(hostmap, port_v6 or port_v4)
            elif line:
                if not method.firewall_command(line):
                    raise Fatal('expected command, got %r' % line)
            else:
                break
    finally:
        try:
            debug1('undoing changes.')
        except BaseException:
            debug2('An error occurred, ignoring it.')

        try:
            if subnets_v6 or nslist_v6:
                debug2('undoing IPv6 changes.')
                method.restore_firewall(port_v6, socket.AF_INET6, udp, user)
        except BaseException:
            try:
                debug1("Error trying to undo IPv6 firewall.")
                debug1(traceback.format_exc())
            except BaseException:
                debug2('An error occurred, ignoring it.')

        try:
            if subnets_v4 or nslist_v4:
                debug2('undoing IPv4 changes.')
                method.restore_firewall(port_v4, socket.AF_INET, udp, user)
        except BaseException:
            try:
                debug1("Error trying to undo IPv4 firewall.")
                debug1(traceback.format_exc())
            except BaseException:
                debug2('An error occurred, ignoring it.')

        try:
            # debug2() message printed in restore_etc_hosts() function.
            restore_etc_hosts(hostmap, port_v6 or port_v4)
        except BaseException:
            try:
                debug1("Error trying to undo /etc/hosts changes.")
                debug1(traceback.format_exc())
            except BaseException:
                debug2('An error occurred, ignoring it.')
コード例 #11
0
def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
    mock_ipt_chain_exists.return_value = True
    method = get_method('tproxy')
    assert method.name == 'tproxy'

    # IPV6

    method.setup_firewall(
        1024, 1026, [(AF_INET6, u'2404:6800:4004:80c::33')], AF_INET6,
        [(AF_INET6, 64, False, u'2404:6800:4004:80c::', 8000, 9000),
         (AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 8080, 8080)], True,
        None)
    assert mock_ipt_chain_exists.mock_calls == [
        call(AF_INET6, 'mangle', 'tshuttle-m-1024'),
        call(AF_INET6, 'mangle', 'tshuttle-t-1024'),
        call(AF_INET6, 'mangle', 'tshuttle-d-1024')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(AF_INET6, 'mangle', '-D', 'OUTPUT', '-j', 'tshuttle-m-1024'),
        call(AF_INET6, 'mangle', '-F', 'tshuttle-m-1024'),
        call(AF_INET6, 'mangle', '-X', 'tshuttle-m-1024'),
        call(AF_INET6, 'mangle', '-D', 'PREROUTING', '-j', 'tshuttle-t-1024'),
        call(AF_INET6, 'mangle', '-F', 'tshuttle-t-1024'),
        call(AF_INET6, 'mangle', '-X', 'tshuttle-t-1024'),
        call(AF_INET6, 'mangle', '-F', 'tshuttle-d-1024'),
        call(AF_INET6, 'mangle', '-X', 'tshuttle-d-1024'),
        call(AF_INET6, 'mangle', '-N', 'tshuttle-m-1024'),
        call(AF_INET6, 'mangle', '-F', 'tshuttle-m-1024'),
        call(AF_INET6, 'mangle', '-N', 'tshuttle-d-1024'),
        call(AF_INET6, 'mangle', '-F', 'tshuttle-d-1024'),
        call(AF_INET6, 'mangle', '-N', 'tshuttle-t-1024'),
        call(AF_INET6, 'mangle', '-F', 'tshuttle-t-1024'),
        call(AF_INET6, 'mangle', '-I', 'OUTPUT', '1', '-j', 'tshuttle-m-1024'),
        call(AF_INET6, 'mangle', '-I', 'PREROUTING', '1', '-j',
             'tshuttle-t-1024'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-t-1024', '-j', 'RETURN', '-m',
             'addrtype', '--dst-type', 'LOCAL'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-m-1024', '-j', 'RETURN', '-m',
             'addrtype', '--dst-type', 'LOCAL'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-d-1024', '-j', 'MARK',
             '--set-mark', '1'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-d-1024', '-j', 'ACCEPT'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-t-1024', '-m', 'socket', '-j',
             'tshuttle-d-1024', '-m', 'tcp', '-p', 'tcp'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-t-1024', '-m', 'socket', '-j',
             'tshuttle-d-1024', '-m', 'udp', '-p', 'udp'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-m-1024', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'2404:6800:4004:80c::33/32', '-m',
             'udp', '-p', 'udp', '--dport', '53'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-t-1024', '-j', 'TPROXY',
             '--tproxy-mark', '0x1/0x1', '--dest',
             u'2404:6800:4004:80c::33/32', '-m', 'udp', '-p', 'udp', '--dport',
             '53', '--on-port', '1026'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-m-1024', '-j', 'RETURN',
             '--dest', u'2404:6800:4004:80c::101f/128', '-m', 'tcp', '-p',
             'tcp', '--dport', '8080:8080'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-t-1024', '-j', 'RETURN',
             '--dest', u'2404:6800:4004:80c::101f/128', '-m', 'tcp', '-p',
             'tcp', '--dport', '8080:8080'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-m-1024', '-j', 'RETURN',
             '--dest', u'2404:6800:4004:80c::101f/128', '-m', 'udp', '-p',
             'udp', '--dport', '8080:8080'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-t-1024', '-j', 'RETURN',
             '--dest', u'2404:6800:4004:80c::101f/128', '-m', 'udp', '-p',
             'udp', '--dport', '8080:8080'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-m-1024', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'2404:6800:4004:80c::/64', '-m',
             'tcp', '-p', 'tcp', '--dport', '8000:9000'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-t-1024', '-j', 'TPROXY',
             '--tproxy-mark', '0x1/0x1', '--dest', u'2404:6800:4004:80c::/64',
             '-m', 'tcp', '-p', 'tcp', '--dport', '8000:9000', '--on-port',
             '1024'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-m-1024', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'2404:6800:4004:80c::/64', '-m',
             'udp', '-p', 'udp', '--dport', '8000:9000'),
        call(AF_INET6, 'mangle', '-A', 'tshuttle-t-1024', '-j', 'TPROXY',
             '--tproxy-mark', '0x1/0x1', '--dest', u'2404:6800:4004:80c::/64',
             '-m', 'udp', '-p', 'udp', '--dport', '8000:9000', '--on-port',
             '1024')
    ]
    mock_ipt_chain_exists.reset_mock()
    mock_ipt_ttl.reset_mock()
    mock_ipt.reset_mock()

    method.restore_firewall(1025, AF_INET6, True, None)
    assert mock_ipt_chain_exists.mock_calls == [
        call(AF_INET6, 'mangle', 'tshuttle-m-1025'),
        call(AF_INET6, 'mangle', 'tshuttle-t-1025'),
        call(AF_INET6, 'mangle', 'tshuttle-d-1025')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(AF_INET6, 'mangle', '-D', 'OUTPUT', '-j', 'tshuttle-m-1025'),
        call(AF_INET6, 'mangle', '-F', 'tshuttle-m-1025'),
        call(AF_INET6, 'mangle', '-X', 'tshuttle-m-1025'),
        call(AF_INET6, 'mangle', '-D', 'PREROUTING', '-j', 'tshuttle-t-1025'),
        call(AF_INET6, 'mangle', '-F', 'tshuttle-t-1025'),
        call(AF_INET6, 'mangle', '-X', 'tshuttle-t-1025'),
        call(AF_INET6, 'mangle', '-F', 'tshuttle-d-1025'),
        call(AF_INET6, 'mangle', '-X', 'tshuttle-d-1025')
    ]
    mock_ipt_chain_exists.reset_mock()
    mock_ipt_ttl.reset_mock()
    mock_ipt.reset_mock()

    # IPV4

    method.setup_firewall(1025, 1027, [(AF_INET, u'1.2.3.33')], AF_INET,
                          [(AF_INET, 24, False, u'1.2.3.0', 0, 0),
                           (AF_INET, 32, True, u'1.2.3.66', 80, 80)], True,
                          None)
    assert mock_ipt_chain_exists.mock_calls == [
        call(AF_INET, 'mangle', 'tshuttle-m-1025'),
        call(AF_INET, 'mangle', 'tshuttle-t-1025'),
        call(AF_INET, 'mangle', 'tshuttle-d-1025')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(AF_INET, 'mangle', '-D', 'OUTPUT', '-j', 'tshuttle-m-1025'),
        call(AF_INET, 'mangle', '-F', 'tshuttle-m-1025'),
        call(AF_INET, 'mangle', '-X', 'tshuttle-m-1025'),
        call(AF_INET, 'mangle', '-D', 'PREROUTING', '-j', 'tshuttle-t-1025'),
        call(AF_INET, 'mangle', '-F', 'tshuttle-t-1025'),
        call(AF_INET, 'mangle', '-X', 'tshuttle-t-1025'),
        call(AF_INET, 'mangle', '-F', 'tshuttle-d-1025'),
        call(AF_INET, 'mangle', '-X', 'tshuttle-d-1025'),
        call(AF_INET, 'mangle', '-N', 'tshuttle-m-1025'),
        call(AF_INET, 'mangle', '-F', 'tshuttle-m-1025'),
        call(AF_INET, 'mangle', '-N', 'tshuttle-d-1025'),
        call(AF_INET, 'mangle', '-F', 'tshuttle-d-1025'),
        call(AF_INET, 'mangle', '-N', 'tshuttle-t-1025'),
        call(AF_INET, 'mangle', '-F', 'tshuttle-t-1025'),
        call(AF_INET, 'mangle', '-I', 'OUTPUT', '1', '-j', 'tshuttle-m-1025'),
        call(AF_INET, 'mangle', '-I', 'PREROUTING', '1', '-j',
             'tshuttle-t-1025'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-t-1025', '-j', 'RETURN', '-m',
             'addrtype', '--dst-type', 'LOCAL'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-m-1025', '-j', 'RETURN', '-m',
             'addrtype', '--dst-type', 'LOCAL'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-d-1025', '-j', 'MARK',
             '--set-mark', '1'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-d-1025', '-j', 'ACCEPT'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-t-1025', '-m', 'socket', '-j',
             'tshuttle-d-1025', '-m', 'tcp', '-p', 'tcp'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-t-1025', '-m', 'socket', '-j',
             'tshuttle-d-1025', '-m', 'udp', '-p', 'udp'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-m-1025', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'1.2.3.33/32', '-m', 'udp', '-p',
             'udp', '--dport', '53'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-t-1025', '-j', 'TPROXY',
             '--tproxy-mark', '0x1/0x1', '--dest', u'1.2.3.33/32', '-m', 'udp',
             '-p', 'udp', '--dport', '53', '--on-port', '1027'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-m-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-m', 'tcp', '-p', 'tcp', '--dport',
             '80:80'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-t-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-m', 'tcp', '-p', 'tcp', '--dport',
             '80:80'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-m-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-m', 'udp', '-p', 'udp', '--dport',
             '80:80'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-t-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-m', 'udp', '-p', 'udp', '--dport',
             '80:80'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-m-1025', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'1.2.3.0/24', '-m', 'tcp', '-p',
             'tcp'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-t-1025', '-j', 'TPROXY',
             '--tproxy-mark', '0x1/0x1', '--dest', u'1.2.3.0/24', '-m', 'tcp',
             '-p', 'tcp', '--on-port', '1025'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-m-1025', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'1.2.3.0/24', '-m', 'udp', '-p',
             'udp'),
        call(AF_INET, 'mangle', '-A', 'tshuttle-t-1025', '-j', 'TPROXY',
             '--tproxy-mark', '0x1/0x1', '--dest', u'1.2.3.0/24', '-m', 'udp',
             '-p', 'udp', '--on-port', '1025')
    ]
    mock_ipt_chain_exists.reset_mock()
    mock_ipt_ttl.reset_mock()
    mock_ipt.reset_mock()

    method.restore_firewall(1025, AF_INET, True, None)
    assert mock_ipt_chain_exists.mock_calls == [
        call(AF_INET, 'mangle', 'tshuttle-m-1025'),
        call(AF_INET, 'mangle', 'tshuttle-t-1025'),
        call(AF_INET, 'mangle', 'tshuttle-d-1025')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(AF_INET, 'mangle', '-D', 'OUTPUT', '-j', 'tshuttle-m-1025'),
        call(AF_INET, 'mangle', '-F', 'tshuttle-m-1025'),
        call(AF_INET, 'mangle', '-X', 'tshuttle-m-1025'),
        call(AF_INET, 'mangle', '-D', 'PREROUTING', '-j', 'tshuttle-t-1025'),
        call(AF_INET, 'mangle', '-F', 'tshuttle-t-1025'),
        call(AF_INET, 'mangle', '-X', 'tshuttle-t-1025'),
        call(AF_INET, 'mangle', '-F', 'tshuttle-d-1025'),
        call(AF_INET, 'mangle', '-X', 'tshuttle-d-1025')
    ]
    mock_ipt_chain_exists.reset_mock()
    mock_ipt_ttl.reset_mock()
    mock_ipt.reset_mock()
コード例 #12
0
def test_firewall_command():
    method = get_method('nat')
    assert not method.firewall_command("somthing")
コード例 #13
0
def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
    mock_ipt_chain_exists.return_value = True
    method = get_method('nat')
    assert method.name == 'nat'

    with pytest.raises(Exception) as excinfo:
        method.setup_firewall(
            1024, 1026,
            [(AF_INET6, u'2404:6800:4004:80c::33')],
            AF_INET6,
            [(AF_INET6, 64, False, u'2404:6800:4004:80c::', 0, 0),
                (AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 80, 80)],
            True,
            None)
    assert str(excinfo.value) \
        == 'Address family "AF_INET6" unsupported by nat method_name'
    assert mock_ipt_chain_exists.mock_calls == []
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == []

    with pytest.raises(Exception) as excinfo:
        method.setup_firewall(
            1025, 1027,
            [(AF_INET, u'1.2.3.33')],
            AF_INET,
            [(AF_INET, 24, False, u'1.2.3.0', 8000, 9000),
                (AF_INET, 32, True, u'1.2.3.66', 8080, 8080)],
            True,
            None)
    assert str(excinfo.value) == 'UDP not supported by nat method_name'
    assert mock_ipt_chain_exists.mock_calls == []
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == []

    method.setup_firewall(
        1025, 1027,
        [(AF_INET, u'1.2.3.33')],
        AF_INET,
        [(AF_INET, 24, False, u'1.2.3.0', 8000, 9000),
            (AF_INET, 32, True, u'1.2.3.66', 8080, 8080)],
        False,
        None)
    assert mock_ipt_chain_exists.mock_calls == [
        call(AF_INET, 'nat', 'tshuttle-1025')
    ]
    assert mock_ipt_ttl.mock_calls == [
        call(AF_INET, 'nat', '-A', 'tshuttle-1025', '-j', 'RETURN',
             '-m', 'ttl', '--ttl', '63')
    ]
    assert mock_ipt.mock_calls == [
        call(AF_INET, 'nat', '-D', 'OUTPUT', '-j', 'tshuttle-1025'),
        call(AF_INET, 'nat', '-D', 'PREROUTING', '-j', 'tshuttle-1025'),
        call(AF_INET, 'nat', '-F', 'tshuttle-1025'),
        call(AF_INET, 'nat', '-X', 'tshuttle-1025'),
        call(AF_INET, 'nat', '-N', 'tshuttle-1025'),
        call(AF_INET, 'nat', '-F', 'tshuttle-1025'),
        call(AF_INET, 'nat', '-I', 'OUTPUT', '1', '-j', 'tshuttle-1025'),
        call(AF_INET, 'nat', '-I', 'PREROUTING', '1', '-j', 'tshuttle-1025'),
        call(AF_INET, 'nat', '-A', 'tshuttle-1025', '-j', 'REDIRECT',
             '--dest', u'1.2.3.33/32', '-p', 'udp',
             '--dport', '53', '--to-ports', '1027'),
        call(AF_INET, 'nat', '-A', 'tshuttle-1025', '-j', 'RETURN',
             '-m', 'addrtype', '--dst-type', 'LOCAL'),
        call(AF_INET, 'nat', '-A', 'tshuttle-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-p', 'tcp', '--dport', '8080:8080'),
        call(AF_INET, 'nat', '-A', 'tshuttle-1025', '-j', 'REDIRECT',
             '--dest', u'1.2.3.0/24', '-p', 'tcp', '--dport', '8000:9000',
             '--to-ports', '1025')
    ]
    mock_ipt_chain_exists.reset_mock()
    mock_ipt_ttl.reset_mock()
    mock_ipt.reset_mock()

    method.restore_firewall(1025, AF_INET, False, None)
    assert mock_ipt_chain_exists.mock_calls == [
        call(AF_INET, 'nat', 'tshuttle-1025')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(AF_INET, 'nat', '-D', 'OUTPUT', '-j', 'tshuttle-1025'),
        call(AF_INET, 'nat', '-D', 'PREROUTING', '-j', 'tshuttle-1025'),
        call(AF_INET, 'nat', '-F', 'tshuttle-1025'),
        call(AF_INET, 'nat', '-X', 'tshuttle-1025')
    ]
    mock_ipt_chain_exists.reset_mock()
    mock_ipt_ttl.reset_mock()
    mock_ipt.reset_mock()
コード例 #14
0
def test_setup_udp_listener():
    listener = Mock()
    method = get_method('nat')
    method.setup_udp_listener(listener)
    assert listener.mock_calls == []
コード例 #15
0
def test_setup_firewall_openbsd(mock_pf_get_dev, mock_ioctl, mock_pfctl):
    mock_pfctl.side_effect = pfctl

    method = get_method('pf')
    assert method.name == 'pf'

    method.setup_firewall(
        1024, 1026, [(AF_INET6, u'2404:6800:4004:80c::33')], AF_INET6,
        [(AF_INET6, 64, False, u'2404:6800:4004:80c::', 8000, 9000),
         (AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 8080, 8080)],
        False, None)

    assert mock_ioctl.mock_calls == [
        call(mock_pf_get_dev(), 0xcd60441a, ANY),
        call(mock_pf_get_dev(), 0xcd60441a, ANY),
    ]
    assert mock_pfctl.mock_calls == [
        call('-s Interfaces -i lo -v'),
        call('-f /dev/stdin', b'match on lo\n'),
        call('-s all'),
        call(
            '-a tshuttle6-1024 -f /dev/stdin',
            b'table <dns_servers> {2404:6800:4004:80c::33}\n'
            b'pass in on lo0 inet6 proto tcp to 2404:6800:4004:80c::/64 '
            b'port 8000:9000 divert-to ::1 port 1024\n'
            b'pass in on lo0 inet6 proto udp '
            b'to <dns_servers> port 53 rdr-to ::1 port 1026\n'
            b'pass out inet6 proto tcp to 2404:6800:4004:80c::/64 '
            b'port 8000:9000 route-to lo0 keep state\n'
            b'pass out inet6 proto tcp to '
            b'2404:6800:4004:80c::101f/128 port 8080:8080\n'
            b'pass out inet6 proto udp to '
            b'<dns_servers> port 53 route-to lo0 keep state\n'),
        call('-e'),
    ]
    mock_pf_get_dev.reset_mock()
    mock_ioctl.reset_mock()
    mock_pfctl.reset_mock()

    with pytest.raises(Exception) as excinfo:
        method.setup_firewall(1025, 1027, [(AF_INET, u'1.2.3.33')], AF_INET,
                              [(AF_INET, 24, False, u'1.2.3.0', 0, 0),
                               (AF_INET, 32, True, u'1.2.3.66', 80, 80)], True,
                              None)
    assert str(excinfo.value) == 'UDP not supported by pf method_name'
    assert mock_pf_get_dev.mock_calls == []
    assert mock_ioctl.mock_calls == []
    assert mock_pfctl.mock_calls == []

    method.setup_firewall(1025, 1027, [(AF_INET, u'1.2.3.33')], AF_INET,
                          [(AF_INET, 24, False, u'1.2.3.0', 0, 0),
                           (AF_INET, 32, True, u'1.2.3.66', 80, 80)], False,
                          None)
    assert mock_ioctl.mock_calls == [
        call(mock_pf_get_dev(), 0xcd60441a, ANY),
        call(mock_pf_get_dev(), 0xcd60441a, ANY),
    ]
    assert mock_pfctl.mock_calls == [
        call('-s Interfaces -i lo -v'),
        call('-f /dev/stdin', b'match on lo\n'),
        call('-s all'),
        call(
            '-a tshuttle-1025 -f /dev/stdin',
            b'table <dns_servers> {1.2.3.33}\n'
            b'pass in on lo0 inet proto tcp to 1.2.3.0/24 divert-to '
            b'127.0.0.1 port 1025\n'
            b'pass in on lo0 inet proto udp to '
            b'<dns_servers> port 53 rdr-to 127.0.0.1 port 1027\n'
            b'pass out inet proto tcp to 1.2.3.0/24 route-to lo0 keep state\n'
            b'pass out inet proto tcp to 1.2.3.66/32 port 80:80\n'
            b'pass out inet proto udp to '
            b'<dns_servers> port 53 route-to lo0 keep state\n'),
        call('-e'),
    ]
    mock_pf_get_dev.reset_mock()
    mock_ioctl.reset_mock()
    mock_pfctl.reset_mock()

    method.restore_firewall(1025, AF_INET, False, None)
    method.restore_firewall(1024, AF_INET6, False, None)
    assert mock_ioctl.mock_calls == []
    assert mock_pfctl.mock_calls == [
        call('-a tshuttle-1025 -F all'),
        call('-a tshuttle6-1024 -F all'),
        call('-d'),
    ]
    mock_pf_get_dev.reset_mock()
    mock_pfctl.reset_mock()
    mock_ioctl.reset_mock()
コード例 #16
0
def test_get_tcp_dstip():
    sock = Mock()
    sock.getsockname.return_value = ('127.0.0.1', 1024)
    method = get_method('tproxy')
    assert method.get_tcp_dstip(sock) == ('127.0.0.1', 1024)
    assert sock.mock_calls == [call.getsockname()]
コード例 #17
0
def test_send_udp():
    sock = Mock()
    method = get_method('nat')
    method.send_udp(sock, None, "127.0.0.1", "22222")
    assert sock.mock_calls == [call.sendto("22222", "127.0.0.1")]
コード例 #18
0
def test_setup_tcp_listener():
    listener = Mock()
    method = get_method('tproxy')
    method.setup_tcp_listener(listener)
    assert listener.mock_calls == [call.setsockopt(0, 19, 1)]
コード例 #19
0
def test_get_supported_features():
    method = get_method('nat')
    features = method.get_supported_features()
    assert not features.ipv6
    assert not features.udp
    assert features.dns
コード例 #20
0
def test_setup_firewall_freebsd(mock_pf_get_dev, mock_ioctl, mock_pfctl,
                                mock_subprocess_call):
    mock_pfctl.side_effect = pfctl

    method = get_method('pf')
    assert method.name == 'pf'

    method.setup_firewall(
        1024, 1026, [(AF_INET6, u'2404:6800:4004:80c::33')], AF_INET6,
        [(AF_INET6, 64, False, u'2404:6800:4004:80c::', 8000, 9000),
         (AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 8080, 8080)],
        False, None)

    assert mock_pfctl.mock_calls == [
        call('-s all'),
        call(
            '-a tshuttle6-1024 -f /dev/stdin',
            b'table <dns_servers> {2404:6800:4004:80c::33}\n'
            b'rdr pass on lo0 inet6 proto tcp from ! ::1 to '
            b'2404:6800:4004:80c::/64 port 8000:9000 -> ::1 port 1024\n'
            b'rdr pass on lo0 inet6 proto udp '
            b'to <dns_servers> port 53 -> ::1 port 1026\n'
            b'pass out route-to lo0 inet6 proto tcp to '
            b'2404:6800:4004:80c::/64 port 8000:9000 keep state\n'
            b'pass out inet6 proto tcp to '
            b'2404:6800:4004:80c::101f/128 port 8080:8080\n'
            b'pass out route-to lo0 inet6 proto udp '
            b'to <dns_servers> port 53 keep state\n'),
        call('-e'),
    ]
    assert call(['kldload', 'pf'], env=get_env()) in \
        mock_subprocess_call.mock_calls
    mock_pf_get_dev.reset_mock()
    mock_ioctl.reset_mock()
    mock_pfctl.reset_mock()

    with pytest.raises(Exception) as excinfo:
        method.setup_firewall(1025, 1027, [(AF_INET, u'1.2.3.33')], AF_INET,
                              [(AF_INET, 24, False, u'1.2.3.0', 0, 0),
                               (AF_INET, 32, True, u'1.2.3.66', 80, 80)], True,
                              None)
    assert str(excinfo.value) == 'UDP not supported by pf method_name'
    assert mock_pf_get_dev.mock_calls == []
    assert mock_ioctl.mock_calls == []
    assert mock_pfctl.mock_calls == []

    method.setup_firewall(1025, 1027, [(AF_INET, u'1.2.3.33')], AF_INET,
                          [(AF_INET, 24, False, u'1.2.3.0', 0, 0),
                           (AF_INET, 32, True, u'1.2.3.66', 80, 80)], False,
                          None)
    assert mock_ioctl.mock_calls == [
        call(mock_pf_get_dev(), 0xC4704433, ANY),
        call(mock_pf_get_dev(), 0xCBE0441A, ANY),
        call(mock_pf_get_dev(), 0xCBE0441A, ANY),
        call(mock_pf_get_dev(), 0xC4704433, ANY),
        call(mock_pf_get_dev(), 0xCBE0441A, ANY),
        call(mock_pf_get_dev(), 0xCBE0441A, ANY),
    ]
    assert mock_pfctl.mock_calls == [
        call('-s all'),
        call(
            '-a tshuttle-1025 -f /dev/stdin',
            b'table <dns_servers> {1.2.3.33}\n'
            b'rdr pass on lo0 inet proto tcp from ! 127.0.0.1 '
            b'to 1.2.3.0/24 -> 127.0.0.1 port 1025\n'
            b'rdr pass on lo0 inet proto udp '
            b'to <dns_servers> port 53 -> 127.0.0.1 port 1027\n'
            b'pass out route-to lo0 inet proto tcp to 1.2.3.0/24 keep state\n'
            b'pass out inet proto tcp to 1.2.3.66/32 port 80:80\n'
            b'pass out route-to lo0 inet proto udp '
            b'to <dns_servers> port 53 keep state\n'),
        call('-e'),
    ]
    mock_pf_get_dev.reset_mock()
    mock_ioctl.reset_mock()
    mock_pfctl.reset_mock()

    method.restore_firewall(1025, AF_INET, False, None)
    method.restore_firewall(1024, AF_INET6, False, None)
    assert mock_ioctl.mock_calls == []
    assert mock_pfctl.mock_calls == [
        call('-a tshuttle-1025 -F all'),
        call('-a tshuttle6-1024 -F all'),
        call("-d"),
    ]
    mock_pf_get_dev.reset_mock()
    mock_pfctl.reset_mock()
    mock_ioctl.reset_mock()
コード例 #21
0
def test_get_supported_features_recvmsg(mock_recvmsg):
    method = get_method('tproxy')
    features = method.get_supported_features()
    assert features.ipv6
    assert features.udp
    assert features.dns
コード例 #22
0
def test_assert_features():
    method = get_method('tproxy')
    features = method.get_supported_features()
    method.assert_features(features)