Ejemplo n.º 1
0
def test_get_tcp_dstip():
    sock = Mock()
    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)]
Ejemplo n.º 2
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)
    ]
Ejemplo n.º 3
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"

    with pytest.raises(Exception) as excinfo:
        method.setup_firewall(
            1024,
            1026,
            [(10, u"2404:6800:4004:80c::33")],
            10,
            [(10, 64, False, u"2404:6800:4004:80c::"), (10, 128, True, u"2404:6800:4004:80c::101f")],
            True,
        )
    assert str(excinfo.value) == 'Address family "AF_INET6" unsupported by pf method_name'
    assert mock_pf_get_dev.mock_calls == []
    assert mock_ioctl.mock_calls == []
    assert mock_pfctl.mock_calls == []

    with pytest.raises(Exception) as excinfo:
        method.setup_firewall(
            1025, 1027, [(2, u"1.2.3.33")], 2, [(2, 24, False, u"1.2.3.0"), (2, 32, True, u"1.2.3.66")], True
        )
    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, [(2, u"1.2.3.33")], 2, [(2, 24, False, u"1.2.3.0"), (2, 32, True, u"1.2.3.66")], False
    )
    assert mock_ioctl.mock_calls == [call(mock_pf_get_dev(), 0xCD48441A, ANY), call(mock_pf_get_dev(), 0xCD48441A, ANY)]
    assert mock_pfctl.mock_calls == [
        call("-f /dev/stdin", b"match on lo\n"),
        call("-s all"),
        call(
            "-a sshuttle -f /dev/stdin",
            b"table <forward_subnets> {!1.2.3.66/32,1.2.3.0/24}\n"
            b"table <dns_servers> {1.2.3.33}\n"
            b"pass in on lo0 inet proto tcp divert-to 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 "
            b"<forward_subnets> route-to lo0 keep state\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, 2, False)
    assert mock_ioctl.mock_calls == []
    assert mock_pfctl.mock_calls == [call("-a sshuttle -F all"), call("-d")]
    mock_pf_get_dev.reset_mock()
    mock_pfctl.reset_mock()
    mock_ioctl.reset_mock()
Ejemplo n.º 4
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")
Ejemplo n.º 5
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)
    ]
Ejemplo n.º 6
0
def test_setup_firewall(mock_pf_get_dev, mock_ioctl, mock_pfctl):
    method = get_method('pf')
    assert method.name == 'pf'

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

    with pytest.raises(Exception) as excinfo:
        method.setup_firewall(
            1025, 1027,
            [(2, u'1.2.3.33')],
            2,
            [(2, 24, False, u'1.2.3.0'), (2, 32, True, u'1.2.3.66')],
            True)
    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,
        [(2, u'1.2.3.33')],
        2,
        [(2, 24, False, u'1.2.3.0'), (2, 32, True, u'1.2.3.66')],
        False)
    assert mock_ioctl.mock_calls == [
        call(mock_pf_get_dev(), 3295691827, ANY),
        call(mock_pf_get_dev(), 3424666650, ANY),
        call(mock_pf_get_dev(), 3424666650, ANY),
        call(mock_pf_get_dev(), 3295691827, ANY),
        call(mock_pf_get_dev(), 3424666650, ANY),
        call(mock_pf_get_dev(), 3424666650, ANY),
    ]
    # FIXME - needs more work
    # print(mock_pfctl.mock_calls)
    # assert mock_pfctl.mock_calls == []
    mock_pf_get_dev.reset_mock()
    mock_ioctl.reset_mock()
    mock_pfctl.reset_mock()

    method.setup_firewall(1025, 0, [], 2, [], False)
    assert mock_ioctl.mock_calls == []
    assert mock_pfctl.mock_calls == [call('-a sshuttle -F all')]
    mock_pf_get_dev.reset_mock()
    mock_pfctl.reset_mock()
    mock_ioctl.reset_mock()
Ejemplo n.º 7
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")
Ejemplo n.º 8
0
    def __init__(self, method_name):
        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']
        argv_tries = [
            ['sudo', '-p', '[local sudo] Password: '******'PYTHONPATH=%s' % python_path), '--'] + 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()
        e = None
        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)
                e = None
                break
            except OSError as e:
                pass
        self.argv = argv
        s1.close()
        if sys.version_info < (3, 0):
            # python 2.7
            self.pfile = s2.makefile('wb+')
        else:
            # python 3.5
            self.pfile = s2.makefile('rwb')
        if e:
            log('Spawning firewall manager: %r\n' % self.argv)
            raise Fatal(e)
        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)
Ejemplo n.º 9
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)
Ejemplo n.º 10
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(1, 2, 1),
        call().setsockopt(0, 19, 1),
        call().bind('127.0.0.2'),
        call().sendto("2222222", '127.0.0.1'),
        call().close()
    ]
Ejemplo n.º 11
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" % (
        socket.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(),
    ]
Ejemplo n.º 12
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 = socket.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(),
    ]
Ejemplo n.º 13
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(), 0xcd58441a, ANY),
        call(mock_pf_get_dev(), 0xcd58441a, 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 sshuttle6-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(), 0xcd58441a, ANY),
        call(mock_pf_get_dev(), 0xcd58441a, 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 sshuttle-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 sshuttle-1025 -F all'),
        call('-a sshuttle6-1024 -F all'),
        call('-d'),
    ]
    mock_pf_get_dev.reset_mock()
    mock_pfctl.reset_mock()
    mock_ioctl.reset_mock()
Ejemplo n.º 14
0
def test_setup_tcp_listener():
    listener = Mock()
    method = get_method('pf')
    method.setup_tcp_listener(listener)
    assert listener.mock_calls == []
Ejemplo n.º 15
0
def main(method_name, syslog):
    stdin, stdout = setup_daemon()
    hostmap = {}

    debug1('firewall manager: Starting firewall with Python version %s\n'
           % 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()

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

    # we wait until we get some input before creating the rules.  That way,
    # sshuttle 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('firewall: expected ROUTES but got %r' % line)
    while 1:
        line = stdin.readline(128)
        if not line:
            raise Fatal('firewall: expected route but got %r' % line)
        elif line.startswith("NSLIST\n"):
            break
        try:
            (family, width, exclude, ip) = line.strip().split(',', 3)
        except:
            raise Fatal('firewall: expected route or NSLIST but got %r' % line)
        subnets.append((int(family), int(width), bool(int(exclude)), ip))
    debug2('firewall manager: Got subnets: %r\n' % subnets)

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

    if not line.startswith('PORTS '):
        raise Fatal('firewall: expected PORTS but got %r' % line)
    _, _, ports = line.partition(" ")
    ports = ports.split(",")
    if len(ports) != 4:
        raise Fatal('firewall: expected 4 ports but got %n' % 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('firewall manager: Got ports: %d,%d,%d,%d\n'
           % (port_v6, port_v4, dnsport_v6, dnsport_v4))

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

    _, _, udp = line.partition(" ")
    udp = bool(int(udp))
    debug2('firewall manager: Got udp: %r\n' % udp)

    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('firewall manager: setting up.\n')

        if len(subnets_v6) > 0 or len(nslist_v6) > 0:
            debug2('firewall manager: setting up IPv6.\n')
            method.setup_firewall(
                port_v6, dnsport_v6, nslist_v6,
                socket.AF_INET6, subnets_v6, udp)

        if len(subnets_v4) > 0 or len(nslist_v4) > 0:
            debug2('firewall manager: setting up IPv4.\n')
            method.setup_firewall(
                port_v4, dnsport_v4, nslist_v4,
                socket.AF_INET, subnets_v4, udp)

        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('firewall manager: setting up /etc/hosts.\n')
                rewrite_etc_hosts(hostmap, port_v6 or port_v4)
            elif line:
                if not method.firewall_command(line):
                    raise Fatal('firewall: expected command, got %r' % line)
            else:
                break
    finally:
        try:
            debug1('firewall manager: undoing changes.\n')
        except:
            pass

        try:
            if len(subnets_v6) > 0 or len(nslist_v6) > 0:
                debug2('firewall manager: undoing IPv6 changes.\n')
                method.restore_firewall(port_v6, socket.AF_INET6, udp)
        except:
            try:
                debug1("firewall manager: "
                       "Error trying to undo IPv6 firewall.\n")
                for line in traceback.format_exc().splitlines():
                    debug1("---> %s\n" % line)
            except:
                pass

        try:
            if len(subnets_v4) > 0 or len(nslist_v4) > 0:
                debug2('firewall manager: undoing IPv4 changes.\n')
                method.restore_firewall(port_v4, socket.AF_INET, udp)
        except:
            try:
                debug1("firewall manager: "
                       "Error trying to undo IPv4 firewall.\n")
                for line in traceback.format_exc().splitlines():
                    debug1("firewall manager: ---> %s\n" % line)
            except:
                pass

        try:
            debug2('firewall manager: undoing /etc/hosts changes.\n')
            restore_etc_hosts(port_v6 or port_v4)
        except:
            try:
                debug1("firewall manager: "
                       "Error trying to undo /etc/hosts changes.\n")
                for line in traceback.format_exc().splitlines():
                    debug1("firewall manager: ---> %s\n" % line)
            except:
                pass
Ejemplo n.º 16
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', 'sshuttle-m-1024'),
        call(AF_INET6, 'mangle', 'sshuttle-t-1024'),
        call(AF_INET6, 'mangle', 'sshuttle-d-1024')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(AF_INET6, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1024'),
        call(AF_INET6, 'mangle', '-F', 'sshuttle-m-1024'),
        call(AF_INET6, 'mangle', '-X', 'sshuttle-m-1024'),
        call(AF_INET6, 'mangle', '-D', 'PREROUTING', '-j', 'sshuttle-t-1024'),
        call(AF_INET6, 'mangle', '-F', 'sshuttle-t-1024'),
        call(AF_INET6, 'mangle', '-X', 'sshuttle-t-1024'),
        call(AF_INET6, 'mangle', '-F', 'sshuttle-d-1024'),
        call(AF_INET6, 'mangle', '-X', 'sshuttle-d-1024'),
        call(AF_INET6, 'mangle', '-N', 'sshuttle-m-1024'),
        call(AF_INET6, 'mangle', '-F', 'sshuttle-m-1024'),
        call(AF_INET6, 'mangle', '-N', 'sshuttle-d-1024'),
        call(AF_INET6, 'mangle', '-F', 'sshuttle-d-1024'),
        call(AF_INET6, 'mangle', '-N', 'sshuttle-t-1024'),
        call(AF_INET6, 'mangle', '-F', 'sshuttle-t-1024'),
        call(AF_INET6, 'mangle', '-I', 'OUTPUT', '1', '-j', 'sshuttle-m-1024'),
        call(AF_INET6, 'mangle', '-I', 'PREROUTING', '1', '-j',
             'sshuttle-t-1024'),
        call(AF_INET6, 'mangle', '-A', 'sshuttle-d-1024', '-j', 'MARK',
             '--set-mark', '1'),
        call(AF_INET6, 'mangle', '-A', 'sshuttle-d-1024', '-j', 'ACCEPT'),
        call(AF_INET6, 'mangle', '-A', 'sshuttle-t-1024', '-m', 'socket', '-j',
             'sshuttle-d-1024', '-m', 'tcp', '-p', 'tcp'),
        call(AF_INET6, 'mangle', '-A', 'sshuttle-t-1024', '-m', 'socket', '-j',
             'sshuttle-d-1024', '-m', 'udp', '-p', 'udp'),
        call(AF_INET6, 'mangle', '-A', 'sshuttle-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', 'sshuttle-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', 'sshuttle-m-1024', '-j', 'RETURN',
             '--dest', u'2404:6800:4004:80c::101f/128', '-m', 'tcp', '-p',
             'tcp', '--dport', '8080:8080'),
        call(AF_INET6, 'mangle', '-A', 'sshuttle-t-1024', '-j', 'RETURN',
             '--dest', u'2404:6800:4004:80c::101f/128', '-m', 'tcp', '-p',
             'tcp', '--dport', '8080:8080'),
        call(AF_INET6, 'mangle', '-A', 'sshuttle-m-1024', '-j', 'RETURN',
             '--dest', u'2404:6800:4004:80c::101f/128', '-m', 'udp', '-p',
             'udp', '--dport', '8080:8080'),
        call(AF_INET6, 'mangle', '-A', 'sshuttle-t-1024', '-j', 'RETURN',
             '--dest', u'2404:6800:4004:80c::101f/128', '-m', 'udp', '-p',
             'udp', '--dport', '8080:8080'),
        call(AF_INET6, 'mangle', '-A', 'sshuttle-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', 'sshuttle-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', 'sshuttle-m-1024', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'2404:6800:4004:80c::/64', '-m',
             'udp', '-p', 'udp'),
        call(AF_INET6, 'mangle', '-A', 'sshuttle-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', 'sshuttle-m-1025'),
        call(AF_INET6, 'mangle', 'sshuttle-t-1025'),
        call(AF_INET6, 'mangle', 'sshuttle-d-1025')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(AF_INET6, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1025'),
        call(AF_INET6, 'mangle', '-F', 'sshuttle-m-1025'),
        call(AF_INET6, 'mangle', '-X', 'sshuttle-m-1025'),
        call(AF_INET6, 'mangle', '-D', 'PREROUTING', '-j', 'sshuttle-t-1025'),
        call(AF_INET6, 'mangle', '-F', 'sshuttle-t-1025'),
        call(AF_INET6, 'mangle', '-X', 'sshuttle-t-1025'),
        call(AF_INET6, 'mangle', '-F', 'sshuttle-d-1025'),
        call(AF_INET6, 'mangle', '-X', 'sshuttle-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', 'sshuttle-m-1025'),
        call(AF_INET, 'mangle', 'sshuttle-t-1025'),
        call(AF_INET, 'mangle', 'sshuttle-d-1025')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(AF_INET, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1025'),
        call(AF_INET, 'mangle', '-F', 'sshuttle-m-1025'),
        call(AF_INET, 'mangle', '-X', 'sshuttle-m-1025'),
        call(AF_INET, 'mangle', '-D', 'PREROUTING', '-j', 'sshuttle-t-1025'),
        call(AF_INET, 'mangle', '-F', 'sshuttle-t-1025'),
        call(AF_INET, 'mangle', '-X', 'sshuttle-t-1025'),
        call(AF_INET, 'mangle', '-F', 'sshuttle-d-1025'),
        call(AF_INET, 'mangle', '-X', 'sshuttle-d-1025'),
        call(AF_INET, 'mangle', '-N', 'sshuttle-m-1025'),
        call(AF_INET, 'mangle', '-F', 'sshuttle-m-1025'),
        call(AF_INET, 'mangle', '-N', 'sshuttle-d-1025'),
        call(AF_INET, 'mangle', '-F', 'sshuttle-d-1025'),
        call(AF_INET, 'mangle', '-N', 'sshuttle-t-1025'),
        call(AF_INET, 'mangle', '-F', 'sshuttle-t-1025'),
        call(AF_INET, 'mangle', '-I', 'OUTPUT', '1', '-j', 'sshuttle-m-1025'),
        call(AF_INET, 'mangle', '-I', 'PREROUTING', '1', '-j',
             'sshuttle-t-1025'),
        call(AF_INET, 'mangle', '-A', 'sshuttle-d-1025', '-j', 'MARK',
             '--set-mark', '1'),
        call(AF_INET, 'mangle', '-A', 'sshuttle-d-1025', '-j', 'ACCEPT'),
        call(AF_INET, 'mangle', '-A', 'sshuttle-t-1025', '-m', 'socket', '-j',
             'sshuttle-d-1025', '-m', 'tcp', '-p', 'tcp'),
        call(AF_INET, 'mangle', '-A', 'sshuttle-t-1025', '-m', 'socket', '-j',
             'sshuttle-d-1025', '-m', 'udp', '-p', 'udp'),
        call(AF_INET, 'mangle', '-A', 'sshuttle-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', 'sshuttle-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', 'sshuttle-m-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-m', 'tcp', '-p', 'tcp', '--dport',
             '80:80'),
        call(AF_INET, 'mangle', '-A', 'sshuttle-t-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-m', 'tcp', '-p', 'tcp', '--dport',
             '80:80'),
        call(AF_INET, 'mangle', '-A', 'sshuttle-m-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-m', 'udp', '-p', 'udp', '--dport',
             '80:80'),
        call(AF_INET, 'mangle', '-A', 'sshuttle-t-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-m', 'udp', '-p', 'udp', '--dport',
             '80:80'),
        call(AF_INET, 'mangle', '-A', 'sshuttle-m-1025', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'1.2.3.0/24', '-m', 'tcp', '-p',
             'tcp'),
        call(AF_INET, 'mangle', '-A', 'sshuttle-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', 'sshuttle-m-1025', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'1.2.3.0/24', '-m', 'udp', '-p',
             'udp'),
        call(AF_INET, 'mangle', '-A', 'sshuttle-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', 'sshuttle-m-1025'),
        call(AF_INET, 'mangle', 'sshuttle-t-1025'),
        call(AF_INET, 'mangle', 'sshuttle-d-1025')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(AF_INET, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1025'),
        call(AF_INET, 'mangle', '-F', 'sshuttle-m-1025'),
        call(AF_INET, 'mangle', '-X', 'sshuttle-m-1025'),
        call(AF_INET, 'mangle', '-D', 'PREROUTING', '-j', 'sshuttle-t-1025'),
        call(AF_INET, 'mangle', '-F', 'sshuttle-t-1025'),
        call(AF_INET, 'mangle', '-X', 'sshuttle-t-1025'),
        call(AF_INET, 'mangle', '-F', 'sshuttle-d-1025'),
        call(AF_INET, 'mangle', '-X', 'sshuttle-d-1025')
    ]
    mock_ipt_chain_exists.reset_mock()
    mock_ipt_ttl.reset_mock()
    mock_ipt.reset_mock()
Ejemplo n.º 17
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)]
Ejemplo n.º 18
0
def test_firewall_command():
    method = get_method('tproxy')
    assert not method.firewall_command("somthing")
Ejemplo n.º 19
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,
        [(10, u'2404:6800:4004:80c::33')],
        10,
        [(10, 64, False, u'2404:6800:4004:80c::'),
            (10, 128, True, u'2404:6800:4004:80c::101f')],
        True)
    assert mock_ipt_chain_exists.mock_calls == [
        call(10, 'mangle', 'sshuttle-m-1024'),
        call(10, 'mangle', 'sshuttle-t-1024'),
        call(10, 'mangle', 'sshuttle-d-1024')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(10, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1024'),
        call(10, 'mangle', '-F', 'sshuttle-m-1024'),
        call(10, 'mangle', '-X', 'sshuttle-m-1024'),
        call(10, 'mangle', '-D', 'PREROUTING', '-j', 'sshuttle-t-1024'),
        call(10, 'mangle', '-F', 'sshuttle-t-1024'),
        call(10, 'mangle', '-X', 'sshuttle-t-1024'),
        call(10, 'mangle', '-F', 'sshuttle-d-1024'),
        call(10, 'mangle', '-X', 'sshuttle-d-1024'),
        call(10, 'mangle', '-N', 'sshuttle-m-1024'),
        call(10, 'mangle', '-F', 'sshuttle-m-1024'),
        call(10, 'mangle', '-N', 'sshuttle-d-1024'),
        call(10, 'mangle', '-F', 'sshuttle-d-1024'),
        call(10, 'mangle', '-N', 'sshuttle-t-1024'),
        call(10, 'mangle', '-F', 'sshuttle-t-1024'),
        call(10, 'mangle', '-I', 'OUTPUT', '1', '-j', 'sshuttle-m-1024'),
        call(10, 'mangle', '-I', 'PREROUTING', '1', '-j', 'sshuttle-t-1024'),
        call(10, 'mangle', '-A', 'sshuttle-d-1024', '-j', 'MARK',
             '--set-mark', '1'),
        call(10, 'mangle', '-A', 'sshuttle-d-1024', '-j', 'ACCEPT'),
        call(10, 'mangle', '-A', 'sshuttle-t-1024', '-m', 'socket',
             '-j', 'sshuttle-d-1024', '-m', 'tcp', '-p', 'tcp'),
        call(10, 'mangle', '-A', 'sshuttle-t-1024', '-m', 'socket',
             '-j', 'sshuttle-d-1024', '-m', 'udp', '-p', 'udp'),
        call(10, 'mangle', '-A', 'sshuttle-m-1024', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'2404:6800:4004:80c::33/32',
             '-m', 'udp', '-p', 'udp', '--dport', '53'),
        call(10, 'mangle', '-A', 'sshuttle-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(10, 'mangle', '-A', 'sshuttle-m-1024', '-j', 'RETURN',
             '--dest', u'2404:6800:4004:80c::101f/128',
             '-m', 'tcp', '-p', 'tcp'),
        call(10, 'mangle', '-A', 'sshuttle-t-1024', '-j', 'RETURN',
             '--dest', u'2404:6800:4004:80c::101f/128',
             '-m', 'tcp', '-p', 'tcp'),
        call(10, 'mangle', '-A', 'sshuttle-m-1024', '-j', 'RETURN',
             '--dest', u'2404:6800:4004:80c::101f/128',
             '-m', 'udp', '-p', 'udp'),
        call(10, 'mangle', '-A', 'sshuttle-t-1024', '-j', 'RETURN',
             '--dest', u'2404:6800:4004:80c::101f/128',
             '-m', 'udp', '-p', 'udp'),
        call(10, 'mangle', '-A', 'sshuttle-m-1024', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'2404:6800:4004:80c::/64',
             '-m', 'tcp', '-p', 'tcp'),
        call(10, 'mangle', '-A', 'sshuttle-t-1024', '-j', 'TPROXY',
             '--tproxy-mark', '0x1/0x1', '--dest', u'2404:6800:4004:80c::/64',
             '-m', 'tcp', '-p', 'tcp', '--on-port', '1024'),
        call(10, 'mangle', '-A', 'sshuttle-m-1024', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'2404:6800:4004:80c::/64',
             '-m', 'udp', '-p', 'udp'),
        call(10, 'mangle', '-A', 'sshuttle-t-1024', '-j', 'TPROXY',
             '--tproxy-mark', '0x1/0x1', '--dest', u'2404:6800:4004:80c::/64',
             '-m', 'udp', '-p', 'udp', '--on-port', '1024')
    ]
    mock_ipt_chain_exists.reset_mock()
    mock_ipt_ttl.reset_mock()
    mock_ipt.reset_mock()

    method.setup_firewall(1025, 0, [], 10, [], True)
    assert mock_ipt_chain_exists.mock_calls == [
        call(10, 'mangle', 'sshuttle-m-1025'),
        call(10, 'mangle', 'sshuttle-t-1025'),
        call(10, 'mangle', 'sshuttle-d-1025')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(10, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1025'),
        call(10, 'mangle', '-F', 'sshuttle-m-1025'),
        call(10, 'mangle', '-X', 'sshuttle-m-1025'),
        call(10, 'mangle', '-D', 'PREROUTING', '-j', 'sshuttle-t-1025'),
        call(10, 'mangle', '-F', 'sshuttle-t-1025'),
        call(10, 'mangle', '-X', 'sshuttle-t-1025'),
        call(10, 'mangle', '-F', 'sshuttle-d-1025'),
        call(10, 'mangle', '-X', 'sshuttle-d-1025')
    ]
    mock_ipt_chain_exists.reset_mock()
    mock_ipt_ttl.reset_mock()
    mock_ipt.reset_mock()

    # IPV4

    method.setup_firewall(
        1025, 1027,
        [(2, u'1.2.3.33')],
        2,
        [(2, 24, False, u'1.2.3.0'), (2, 32, True, u'1.2.3.66')],
        True)
    assert mock_ipt_chain_exists.mock_calls == [
        call(2, 'mangle', 'sshuttle-m-1025'),
        call(2, 'mangle', 'sshuttle-t-1025'),
        call(2, 'mangle', 'sshuttle-d-1025')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(2, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1025'),
        call(2, 'mangle', '-F', 'sshuttle-m-1025'),
        call(2, 'mangle', '-X', 'sshuttle-m-1025'),
        call(2, 'mangle', '-D', 'PREROUTING', '-j', 'sshuttle-t-1025'),
        call(2, 'mangle', '-F', 'sshuttle-t-1025'),
        call(2, 'mangle', '-X', 'sshuttle-t-1025'),
        call(2, 'mangle', '-F', 'sshuttle-d-1025'),
        call(2, 'mangle', '-X', 'sshuttle-d-1025'),
        call(2, 'mangle', '-N', 'sshuttle-m-1025'),
        call(2, 'mangle', '-F', 'sshuttle-m-1025'),
        call(2, 'mangle', '-N', 'sshuttle-d-1025'),
        call(2, 'mangle', '-F', 'sshuttle-d-1025'),
        call(2, 'mangle', '-N', 'sshuttle-t-1025'),
        call(2, 'mangle', '-F', 'sshuttle-t-1025'),
        call(2, 'mangle', '-I', 'OUTPUT', '1', '-j', 'sshuttle-m-1025'),
        call(2, 'mangle', '-I', 'PREROUTING', '1', '-j', 'sshuttle-t-1025'),
        call(2, 'mangle', '-A', 'sshuttle-d-1025',
             '-j', 'MARK', '--set-mark', '1'),
        call(2, 'mangle', '-A', 'sshuttle-d-1025', '-j', 'ACCEPT'),
        call(2, 'mangle', '-A', 'sshuttle-t-1025', '-m', 'socket',
             '-j', 'sshuttle-d-1025', '-m', 'tcp', '-p', 'tcp'),
        call(2, 'mangle', '-A', 'sshuttle-t-1025', '-m', 'socket',
             '-j', 'sshuttle-d-1025', '-m', 'udp', '-p', 'udp'),
        call(2, 'mangle', '-A', 'sshuttle-m-1025', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'1.2.3.33/32',
             '-m', 'udp', '-p', 'udp', '--dport', '53'),
        call(2, 'mangle', '-A', 'sshuttle-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(2, 'mangle', '-A', 'sshuttle-m-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-m', 'tcp', '-p', 'tcp'),
        call(2, 'mangle', '-A', 'sshuttle-t-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-m', 'tcp', '-p', 'tcp'),
        call(2, 'mangle', '-A', 'sshuttle-m-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-m', 'udp', '-p', 'udp'),
        call(2, 'mangle', '-A', 'sshuttle-t-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-m', 'udp', '-p', 'udp'),
        call(2, 'mangle', '-A', 'sshuttle-m-1025', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'1.2.3.0/24',
             '-m', 'tcp', '-p', 'tcp'),
        call(2, 'mangle', '-A', 'sshuttle-t-1025', '-j', 'TPROXY',
             '--tproxy-mark', '0x1/0x1', '--dest', u'1.2.3.0/24',
             '-m', 'tcp', '-p', 'tcp', '--on-port', '1025'),
        call(2, 'mangle', '-A', 'sshuttle-m-1025', '-j', 'MARK',
             '--set-mark', '1', '--dest', u'1.2.3.0/24',
             '-m', 'udp', '-p', 'udp'),
        call(2, 'mangle', '-A', 'sshuttle-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.setup_firewall(1025, 0, [], 2, [], True)
    assert mock_ipt_chain_exists.mock_calls == [
        call(2, 'mangle', 'sshuttle-m-1025'),
        call(2, 'mangle', 'sshuttle-t-1025'),
        call(2, 'mangle', 'sshuttle-d-1025')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(2, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1025'),
        call(2, 'mangle', '-F', 'sshuttle-m-1025'),
        call(2, 'mangle', '-X', 'sshuttle-m-1025'),
        call(2, 'mangle', '-D', 'PREROUTING', '-j', 'sshuttle-t-1025'),
        call(2, 'mangle', '-F', 'sshuttle-t-1025'),
        call(2, 'mangle', '-X', 'sshuttle-t-1025'),
        call(2, 'mangle', '-F', 'sshuttle-d-1025'),
        call(2, 'mangle', '-X', 'sshuttle-d-1025')
    ]
    mock_ipt_chain_exists.reset_mock()
    mock_ipt_ttl.reset_mock()
    mock_ipt.reset_mock()
Ejemplo n.º 20
0
def test_setup_firewall_notdarwin(mock_pf_get_dev, mock_ioctl, mock_pfctl):
    mock_pfctl.side_effect = pfctl

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

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

    with pytest.raises(Exception) as excinfo:
        method.setup_firewall(
            1025, 1027,
            [(2, u'1.2.3.33')],
            2,
            [(2, 24, False, u'1.2.3.0'), (2, 32, True, u'1.2.3.66')],
            True)
    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,
        [(2, u'1.2.3.33')],
        2,
        [(2, 24, False, u'1.2.3.0'), (2, 32, True, u'1.2.3.66')],
        False)
    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 sshuttle -f /dev/stdin',
             b'table <forward_subnets> {!1.2.3.66/32,1.2.3.0/24}\n'
             b'table <dns_servers> {1.2.3.33}\n'
             b'rdr pass on lo0 proto tcp '
             b'to <forward_subnets> -> 127.0.0.1 port 1025\n'
             b'rdr pass on lo0 proto udp '
             b'to <dns_servers> port 53 -> 127.0.0.1 port 1027\n'
             b'pass out route-to lo0 inet proto tcp '
             b'to <forward_subnets> keep state\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, 2, False)
    assert mock_ioctl.mock_calls == []
    assert mock_pfctl.mock_calls == [
        call('-a sshuttle -F all'),
        call("-d"),
    ]
    mock_pf_get_dev.reset_mock()
    mock_pfctl.reset_mock()
    mock_ioctl.reset_mock()
Ejemplo n.º 21
0
def test_check_settings():
    method = get_method('tproxy')
    method.check_settings(True, True)
    method.check_settings(False, True)
Ejemplo n.º 22
0
def test_firewall_command():
    method = get_method('tproxy')
    assert not method.firewall_command("somthing")
Ejemplo n.º 23
0
def main(method_name, syslog):
    stdin, stdout = setup_daemon()

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

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

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

    # we wait until we get some input before creating the rules.  That way,
    # sshuttle 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('firewall: expected ROUTES but got %r' % line)
    while 1:
        line = stdin.readline(128)
        if not line:
            raise Fatal('firewall: expected route but got %r' % line)
        elif line.startswith("NSLIST\n"):
            break
        try:
            (family, width, exclude, ip) = line.strip().split(',', 3)
        except:
            raise Fatal('firewall: expected route or NSLIST but got %r' % line)
        subnets.append((int(family), int(width), bool(int(exclude)), ip))
    debug2('Got subnets: %r\n' % subnets)

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

    if not line.startswith('PORTS '):
        raise Fatal('firewall: expected PORTS but got %r' % line)
    _, _, ports = line.partition(" ")
    ports = ports.split(",")
    if len(ports) != 4:
        raise Fatal('firewall: expected 4 ports but got %n' % 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\n' %
           (port_v6, port_v4, dnsport_v6, dnsport_v4))

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

    _, _, udp = line.partition(" ")
    udp = bool(int(udp))
    debug2('Got udp: %r\n' % udp)

    try:
        do_wait = None
        debug1('firewall manager: starting transproxy.\n')

        nslist_v6 = [i for i in nslist if i[0] == socket.AF_INET6]
        subnets_v6 = [i for i in subnets if i[0] == socket.AF_INET6]
        if port_v6 > 0:
            do_wait = method.setup_firewall(port_v6, dnsport_v6, nslist_v6,
                                            socket.AF_INET6, subnets_v6, udp)
        elif len(subnets_v6) > 0:
            debug1("IPv6 subnets defined but IPv6 disabled\n")

        nslist_v4 = [i for i in nslist if i[0] == socket.AF_INET]
        subnets_v4 = [i for i in subnets if i[0] == socket.AF_INET]
        if port_v4 > 0:
            do_wait = method.setup_firewall(port_v4, dnsport_v4, nslist_v4,
                                            socket.AF_INET, subnets_v4, udp)
        elif len(subnets_v4) > 0:
            debug1('IPv4 subnets defined but IPv4 disabled\n')

        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:
            if do_wait is not None:
                do_wait()
            line = stdin.readline(128)
            if line.startswith('HOST '):
                (name, ip) = line[5:].strip().split(',', 1)
                hostmap[name] = ip
                rewrite_etc_hosts(port_v6 or port_v4)
            elif line:
                if not method.firewall_command(line):
                    raise Fatal('expected EOF, got %r' % line)
            else:
                break
    finally:
        try:
            debug1('firewall manager: undoing changes.\n')
        except:
            pass
        if port_v6:
            method.setup_firewall(port_v6, 0, [], socket.AF_INET6, [], udp)
        if port_v4:
            method.setup_firewall(port_v4, 0, [], socket.AF_INET, [], udp)
        restore_etc_hosts(port_v6 or port_v4)
Ejemplo n.º 24
0
def test_get_supported_features():
    method = get_method('tproxy')
    features = method.get_supported_features()
    assert features.ipv6
    assert features.udp
Ejemplo n.º 25
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 sshuttle6-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']) 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 sshuttle-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 sshuttle-1025 -F all'),
        call('-a sshuttle6-1024 -F all'),
        call("-d"),
    ]
    mock_pf_get_dev.reset_mock()
    mock_pfctl.reset_mock()
    mock_ioctl.reset_mock()
Ejemplo n.º 26
0
    def __init__(self, method_name):

        # Default to sudo unless on OpenBSD in which case use built in `doas`
        elevbin = 'sudo'
        if platform.platform().startswith('OpenBSD'):
            elevbin = 'doas'

        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']
        elev_prefix = [
            part % {
                'eb': elevbin,
                'pp': python_path
            } for part in [
                '%(eb)s', '-p', '[local %(eb)s] Password: '******'/usr/bin/env',
                'PYTHONPATH=%(pp)s'
            ]
        ]
        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()

        e = None
        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)
                e = None
                break
            except OSError as e:
                pass
        self.argv = argv
        s1.close()
        if sys.version_info < (3, 0):
            # python 2.7
            self.pfile = s2.makefile('wb+')
        else:
            # python 3.5
            self.pfile = s2.makefile('rwb')
        if e:
            log('Spawning firewall manager: %r\n' % self.argv)
            raise Fatal(e)
        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)
Ejemplo n.º 27
0
def test_get_tcp_dstip():
    sock = Mock()
    sock.getsockopt.return_value = struct.pack("!HHBBBB", socket.ntohs(socket.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)]
Ejemplo n.º 28
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()]
Ejemplo n.º 29
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")]
Ejemplo n.º 30
0
def test_assert_features():
    method = get_method('tproxy')
    features = method.get_supported_features()
    method.assert_features(features)
Ejemplo n.º 31
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', 'sshuttle-1025')
    ]
    assert mock_ipt_ttl.mock_calls == [
        call(AF_INET, 'nat', '-A', 'sshuttle-1025', '-j', 'REDIRECT',
             '--dest', u'1.2.3.0/24', '-p', 'tcp', '--dport', '8000:9000',
             '--to-ports', '1025'),
        call(AF_INET, 'nat', '-A', 'sshuttle-1025', '-j', 'REDIRECT',
             '--dest', u'1.2.3.33/32', '-p', 'udp',
             '--dport', '53', '--to-ports', '1027')
    ]
    assert mock_ipt.mock_calls == [
        call(AF_INET, 'nat', '-D', 'OUTPUT', '-j', 'sshuttle-1025'),
        call(AF_INET, 'nat', '-D', 'PREROUTING', '-j', 'sshuttle-1025'),
        call(AF_INET, 'nat', '-F', 'sshuttle-1025'),
        call(AF_INET, 'nat', '-X', 'sshuttle-1025'),
        call(AF_INET, 'nat', '-N', 'sshuttle-1025'),
        call(AF_INET, 'nat', '-F', 'sshuttle-1025'),
        call(AF_INET, 'nat', '-I', 'OUTPUT', '1', '-j', 'sshuttle-1025'),
        call(AF_INET, 'nat', '-I', 'PREROUTING', '1', '-j', 'sshuttle-1025'),
        call(AF_INET, 'nat', '-A', 'sshuttle-1025', '-j', 'RETURN',
             '--dest', u'1.2.3.66/32', '-p', 'tcp', '--dport', '8080:8080')
    ]
    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', 'sshuttle-1025')
    ]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(AF_INET, 'nat', '-D', 'OUTPUT', '-j', 'sshuttle-1025'),
        call(AF_INET, 'nat', '-D', 'PREROUTING', '-j', 'sshuttle-1025'),
        call(AF_INET, 'nat', '-F', 'sshuttle-1025'),
        call(AF_INET, 'nat', '-X', 'sshuttle-1025')
    ]
    mock_ipt_chain_exists.reset_mock()
    mock_ipt_ttl.reset_mock()
    mock_ipt.reset_mock()
Ejemplo n.º 32
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
Ejemplo n.º 33
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,
            [(10, u"2404:6800:4004:80c::33")],
            10,
            [(10, 64, False, u"2404:6800:4004:80c::"), (10, 128, True, u"2404:6800:4004:80c::101f")],
            True,
        )
    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, [(2, u"1.2.3.33")], 2, [(2, 24, False, u"1.2.3.0"), (2, 32, True, u"1.2.3.66")], True
        )
    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, [(2, u"1.2.3.33")], 2, [(2, 24, False, u"1.2.3.0"), (2, 32, True, u"1.2.3.66")], False
    )
    assert mock_ipt_chain_exists.mock_calls == [call(2, "nat", "sshuttle-1025")]
    assert mock_ipt_ttl.mock_calls == [
        call(
            2,
            "nat",
            "-A",
            "sshuttle-1025",
            "-j",
            "REDIRECT",
            "--dest",
            u"1.2.3.0/24",
            "-p",
            "tcp",
            "--to-ports",
            "1025",
        ),
        call(
            2,
            "nat",
            "-A",
            "sshuttle-1025",
            "-j",
            "REDIRECT",
            "--dest",
            u"1.2.3.33/32",
            "-p",
            "udp",
            "--dport",
            "53",
            "--to-ports",
            "1027",
        ),
    ]
    assert mock_ipt.mock_calls == [
        call(2, "nat", "-D", "OUTPUT", "-j", "sshuttle-1025"),
        call(2, "nat", "-D", "PREROUTING", "-j", "sshuttle-1025"),
        call(2, "nat", "-F", "sshuttle-1025"),
        call(2, "nat", "-X", "sshuttle-1025"),
        call(2, "nat", "-N", "sshuttle-1025"),
        call(2, "nat", "-F", "sshuttle-1025"),
        call(2, "nat", "-I", "OUTPUT", "1", "-j", "sshuttle-1025"),
        call(2, "nat", "-I", "PREROUTING", "1", "-j", "sshuttle-1025"),
        call(2, "nat", "-A", "sshuttle-1025", "-j", "RETURN", "--dest", u"1.2.3.66/32", "-p", "tcp"),
    ]
    mock_ipt_chain_exists.reset_mock()
    mock_ipt_ttl.reset_mock()
    mock_ipt.reset_mock()

    method.restore_firewall(1025, 2, False)
    assert mock_ipt_chain_exists.mock_calls == [call(2, "nat", "sshuttle-1025")]
    assert mock_ipt_ttl.mock_calls == []
    assert mock_ipt.mock_calls == [
        call(2, "nat", "-D", "OUTPUT", "-j", "sshuttle-1025"),
        call(2, "nat", "-D", "PREROUTING", "-j", "sshuttle-1025"),
        call(2, "nat", "-F", "sshuttle-1025"),
        call(2, "nat", "-X", "sshuttle-1025"),
    ]
    mock_ipt_chain_exists.reset_mock()
    mock_ipt_ttl.reset_mock()
    mock_ipt.reset_mock()
Ejemplo n.º 34
0
def test_setup_firewall_darwin(mock_pf_get_dev, mock_ioctl, mock_pfctl):
    mock_pfctl.side_effect = pfctl

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

    # 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)],
        False,
        None)
    assert mock_ioctl.mock_calls == [
        call(mock_pf_get_dev(), 0xC4704433, ANY),
        call(mock_pf_get_dev(), 0xCC20441A, ANY),
        call(mock_pf_get_dev(), 0xCC20441A, ANY),
        call(mock_pf_get_dev(), 0xC4704433, ANY),
        call(mock_pf_get_dev(), 0xCC20441A, ANY),
        call(mock_pf_get_dev(), 0xCC20441A, ANY),
    ]
    assert mock_pfctl.mock_calls == [
        call('-s Interfaces -i lo -v'),
        call('-f /dev/stdin', b'pass on lo\n'),
        call('-s all'),
        call('-a sshuttle6-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 quick inet6 proto tcp to '
             b'2404:6800:4004:80c::101f/128 port 8080:8080\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 route-to lo0 inet6 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()

    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(), 0xCC20441A, ANY),
        call(mock_pf_get_dev(), 0xCC20441A, ANY),
        call(mock_pf_get_dev(), 0xC4704433, ANY),
        call(mock_pf_get_dev(), 0xCC20441A, ANY),
        call(mock_pf_get_dev(), 0xCC20441A, ANY),
    ]
    assert mock_pfctl.mock_calls == [
        call('-s Interfaces -i lo -v'),
        call('-f /dev/stdin', b'pass on lo\n'),
        call('-s all'),
        call('-a sshuttle-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 to 1.2.3.0/24 '
             b'-> 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 quick inet proto tcp to 1.2.3.66/32 port 80:80\n'
             b'pass out route-to lo0 inet proto tcp to 1.2.3.0/24 keep state\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)
    assert mock_ioctl.mock_calls == []
    assert mock_pfctl.mock_calls == [
        call('-a sshuttle-1025 -F all'),
        call("-X abcdefg"),
    ]
    mock_pf_get_dev.reset_mock()
    mock_pfctl.reset_mock()
    mock_ioctl.reset_mock()
Ejemplo n.º 35
0
def test_get_supported_features():
    method = get_method('tproxy')
    features = method.get_supported_features()
    assert features.ipv6
    assert features.udp
Ejemplo n.º 36
0
def test_check_settings():
    method = get_method('nat')
    method.check_settings(True, True)
    method.check_settings(False, True)
Ejemplo n.º 37
0
def test_setup_udp_listener():
    listener = Mock()
    method = get_method('pf')
    method.setup_udp_listener(listener)
    assert listener.mock_calls == []
Ejemplo n.º 38
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,
        [(10, u'2404:6800:4004:80c::33')],
        10,
        [(10, 64, False, u'2404:6800:4004:80c::'),
            (10, 128, True, u'2404:6800:4004:80c::101f')],
        False)

    assert mock_ioctl.mock_calls == [
        call(mock_pf_get_dev(), 0xcd48441a, ANY),
        call(mock_pf_get_dev(), 0xcd48441a, 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 sshuttle6-1024 -f /dev/stdin',
             b'table <forward_subnets> {'
             b'!2404:6800:4004:80c::101f/128,2404:6800:4004:80c::/64'
             b'}\n'
             b'table <dns_servers> {2404:6800:4004:80c::33}\n'
             b'pass in on lo0 inet6 proto tcp to '
             b'<forward_subnets> 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 '
             b'<forward_subnets> route-to lo0 keep state\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,
            [(2, u'1.2.3.33')],
            2,
            [(2, 24, False, u'1.2.3.0'), (2, 32, True, u'1.2.3.66')],
            True)
    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,
        [(2, u'1.2.3.33')],
        2,
        [(2, 24, False, u'1.2.3.0'), (2, 32, True, u'1.2.3.66')],
        False)
    assert mock_ioctl.mock_calls == [
        call(mock_pf_get_dev(), 0xcd48441a, ANY),
        call(mock_pf_get_dev(), 0xcd48441a, 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 sshuttle-1025 -f /dev/stdin',
             b'table <forward_subnets> {!1.2.3.66/32,1.2.3.0/24}\n'
             b'table <dns_servers> {1.2.3.33}\n'
             b'pass in on lo0 inet proto tcp to <forward_subnets> divert-to 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 '
             b'<forward_subnets> route-to lo0 keep state\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, 2, False)
    assert mock_ioctl.mock_calls == []
    assert mock_pfctl.mock_calls == [
        call('-a sshuttle-1025 -F all'),
        call("-d"),
    ]
    mock_pf_get_dev.reset_mock()
    mock_pfctl.reset_mock()
    mock_ioctl.reset_mock()
Ejemplo n.º 39
0
def main(method_name, syslog):
    stdin, stdout = setup_daemon()
    hostmap = {}

    debug1('firewall manager: Starting firewall with Python version %s\n' %
           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()

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

    # we wait until we get some input before creating the rules.  That way,
    # sshuttle 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('firewall: expected ROUTES but got %r' % line)
    while 1:
        line = stdin.readline(128)
        if not line:
            raise Fatal('firewall: expected route but got %r' % line)
        elif line.startswith("NSLIST\n"):
            break
        try:
            (family, width, exclude, ip, fport, lport) = \
                    line.strip().split(',', 5)
        except:
            raise Fatal('firewall: expected route or NSLIST but got %r' % line)
        subnets.append((int(family), int(width), bool(int(exclude)), ip,
                        int(fport), int(lport)))
    debug2('firewall manager: Got subnets: %r\n' % subnets)

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

    if not line.startswith('PORTS '):
        raise Fatal('firewall: expected PORTS but got %r' % line)
    _, _, ports = line.partition(" ")
    ports = ports.split(",")
    if len(ports) != 4:
        raise Fatal('firewall: expected 4 ports but got %n' % 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('firewall manager: Got ports: %d,%d,%d,%d\n' %
           (port_v6, port_v4, dnsport_v6, dnsport_v4))

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

    _, _, udp = line.partition(" ")
    udp = bool(int(udp))
    debug2('firewall manager: Got udp: %r\n' % udp)

    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('firewall manager: setting up.\n')

        if len(subnets_v6) > 0 or len(nslist_v6) > 0:
            debug2('firewall manager: setting up IPv6.\n')
            method.setup_firewall(port_v6, dnsport_v6, nslist_v6,
                                  socket.AF_INET6, subnets_v6, udp)

        if len(subnets_v4) > 0 or len(nslist_v4) > 0:
            debug2('firewall manager: setting up IPv4.\n')
            method.setup_firewall(port_v4, dnsport_v4, nslist_v4,
                                  socket.AF_INET, subnets_v4, udp)

        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('firewall manager: setting up /etc/hosts.\n')
                rewrite_etc_hosts(hostmap, port_v6 or port_v4)
            elif line:
                if not method.firewall_command(line):
                    raise Fatal('firewall: expected command, got %r' % line)
            else:
                break
    finally:
        try:
            sdnotify.send(sdnotify.stop())
            debug1('firewall manager: undoing changes.\n')
        except:
            pass

        try:
            if len(subnets_v6) > 0 or len(nslist_v6) > 0:
                debug2('firewall manager: undoing IPv6 changes.\n')
                method.restore_firewall(port_v6, socket.AF_INET6, udp)
        except:
            try:
                debug1("firewall manager: "
                       "Error trying to undo IPv6 firewall.\n")
                for line in traceback.format_exc().splitlines():
                    debug1("---> %s\n" % line)
            except:
                pass

        try:
            if len(subnets_v4) > 0 or len(nslist_v4) > 0:
                debug2('firewall manager: undoing IPv4 changes.\n')
                method.restore_firewall(port_v4, socket.AF_INET, udp)
        except:
            try:
                debug1("firewall manager: "
                       "Error trying to undo IPv4 firewall.\n")
                for line in traceback.format_exc().splitlines():
                    debug1("firewall manager: ---> %s\n" % line)
            except:
                pass

        try:
            debug2('firewall manager: undoing /etc/hosts changes.\n')
            restore_etc_hosts(port_v6 or port_v4)
        except:
            try:
                debug1("firewall manager: "
                       "Error trying to undo /etc/hosts changes.\n")
                for line in traceback.format_exc().splitlines():
                    debug1("firewall manager: ---> %s\n" % line)
            except:
                pass
Ejemplo n.º 40
0
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,
    # sshuttle 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(" ")
    global sshuttle_pid
    udp, user, tmark, sshuttle_pid = args.strip().split(" ", 3)
    udp = bool(int(udp))
    sshuttle_pid = int(sshuttle_pid)
    if user == '-':
        user = None
    debug2('Got udp: %r, user: %r, tmark: %s, sshuttle_pid: %d' %
           (udp, user, tmark, sshuttle_pid))

    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, tmark)

        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, tmark)

        flush_systemd_dns_cache()
        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.')

        try:
            flush_systemd_dns_cache()
        except BaseException:
            try:
                debug1("Error trying to flush systemd dns cache.")
                debug1(traceback.format_exc())
            except BaseException:
                debug2("An error occurred, ignoring it.")
Ejemplo n.º 41
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()]
Ejemplo n.º 42
0
def test_get_supported_features():
    method = get_method('pf')
    features = method.get_supported_features()
    assert features.ipv6
    assert not features.udp
    assert features.dns
Ejemplo n.º 43
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, 63, '0x01')

    assert mock_pfctl.mock_calls == [
        call('-s all'),
        call(
            '-a sshuttle6-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, 63, '0x01')
    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, 63, '0x01')
    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 sshuttle-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 sshuttle-1025 -F all'),
        call('-a sshuttle6-1024 -F all'),
        call("-d"),
    ]
    mock_pf_get_dev.reset_mock()
    mock_pfctl.reset_mock()
    mock_ioctl.reset_mock()
Ejemplo n.º 44
0
def test_setup_udp_listener():
    listener = Mock()
    method = get_method("nat")
    method.setup_udp_listener(listener)
    assert listener.mock_calls == []
Ejemplo n.º 45
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, 63, '0x01')

    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 sshuttle6-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, 63, '0x01')
    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, 63, '0x01')
    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 sshuttle-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 sshuttle-1025 -F all'),
        call('-a sshuttle6-1024 -F all'),
        call('-d'),
    ]
    mock_pf_get_dev.reset_mock()
    mock_pfctl.reset_mock()
    mock_ioctl.reset_mock()
Ejemplo n.º 46
0
def test_firewall_command():
    method = get_method("nat")
    assert not method.firewall_command("somthing")
Ejemplo n.º 47
0
def test_send_udp():
    sock = Mock()
    method = get_method('pf')
    method.send_udp(sock, None, "127.0.0.1", "22222")
    assert sock.mock_calls == [call.sendto("22222", "127.0.0.1")]
Ejemplo n.º 48
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
Ejemplo n.º 49
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'

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

    with pytest.raises(Exception) as excinfo:
        method.setup_firewall(1025, 1027, [(2, u'1.2.3.33')], 2,
                              [(2, 24, False, u'1.2.3.0'),
                               (2, 32, True, u'1.2.3.66')], True)
    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, [(2, u'1.2.3.33')], 2,
                          [(2, 24, False, u'1.2.3.0'),
                           (2, 32, True, u'1.2.3.66')], False)
    assert mock_ioctl.mock_calls == [
        call(mock_pf_get_dev(), 0xcd48441a, ANY),
        call(mock_pf_get_dev(), 0xcd48441a, ANY),
    ]
    assert mock_pfctl.mock_calls == [
        call('-f /dev/stdin', b'match on lo\n'),
        call('-s all'),
        call(
            '-a sshuttle -f /dev/stdin',
            b'table <forward_subnets> {!1.2.3.66/32,1.2.3.0/24}\n'
            b'table <dns_servers> {1.2.3.33}\n'
            b'pass in on lo0 inet proto tcp divert-to 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 '
            b'<forward_subnets> route-to lo0 keep state\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(false, 1025, 2, False)
    assert mock_ioctl.mock_calls == []
    assert mock_pfctl.mock_calls == [
        call('-a sshuttle -F all'),
        call("-d"),
    ]
    mock_pf_get_dev.reset_mock()
    mock_pfctl.reset_mock()
    mock_ioctl.reset_mock()