Exemplo n.º 1
0
def check_ok_settings(namespace):

    # If -req is set, check that all of its arguments are correct
    if namespace.req is not None:
        try:
            priv_port = int(namespace.req[0])
            if not 1 <= priv_port <= 65535:
                raise ValueError
        except ValueError:
            sys.exit(
                "The private port must be an integer between 1 and 65535.")

        try:
            pub_port = int(namespace.req[1])
            if not 0 <= pub_port <= 65535:
                raise ValueError
        except ValueError:
            sys.exit("The public port must be an integer between 0 and 65535.")

        if namespace.req[2].upper() not in ['TCP', 'UDP']:
            sys.exit("The protocol for the mapping must be either TCP or UDP")

    if namespace.sec and namespace.v0:
        sys.exit("NAT-PMP v0 does not support secure requests.")

    if namespace.ips and namespace.v0:
        print(
            "Warning: specifying public IPs when sending a v0 request will have no effect."
        )

    # If -l is set, check that it's a positive integer
    if namespace.l < 0:
        sys.exit("The lifetime must be a positive amount.")

    if namespace.v1 and namespace.req and not namespace.ips:
        sys.exit(
            "Must specify IPv4 addresses to map ports into when issuing a v1 request."
        )

    # If -ips is set, check that all of them are valid
    if namespace.ips is not None:
        for ip in namespace.ips:
            if not is_valid_ip_string(ip):
                sys.exit("IP address %s from -l is not a valid address." % ip)

    # If -g is set, check that it's a valid address
    if namespace.g is not None:
        if not is_valid_ip_string(namespace.g):
            sys.exit("IP address %s from -g is not a valid address." %
                     namespace.g)
    else:
        namespace.g = get_default_router_address()
Exemplo n.º 2
0
def check_mapping_params(proto=None, public_ip=None, private_ip=None):

    if proto:
        if proto not in ["tcp", "udp"]:
            raise ValueError("Proto '%s' is not valid" % proto)

    if public_ip:
        if not is_valid_ip_string(public_ip):
            raise ValueError("Public IP address '%s' is not valid" % public_ip)

        if not get_interface_name(public_ip):
            raise ValueError("No interface found for public address " +
                             public_ip)

    if private_ip:
        if not is_valid_ip_string(private_ip):
            raise ValueError("Private IP address '%s' is not valid" %
                             private_ip)
Exemplo n.º 3
0
def check_params_ok(namespace):
    if not 0 <= namespace.v <= 1:
        sys.exit("Only version 0 and 1 are currently supported.")

    if namespace.n < 1:
        sys.exit("Please, provide a request count greater than zero.")

    if namespace.t < 1:
        sys.exit(
            "Please, provide a timeout amount greater than zero milliseconds.")

    if not namespace.g or not is_valid_ip_string(namespace.g):
        sys.exit("Please, provide a valid gateway address using the -g flag.")

    if not namespace.op or namespace.op not in ["info", "req"]:
        sys.exit(
            "Please, provide a valid operation using the -op flag (info/req)")

    if namespace.v == 1 and namespace.op == "req":
        if not namespace.ips or any(not is_valid_ip_string(x)
                                    for x in namespace.ips):
            sys.exit(
                "At least one argument provided by the -ips flag is not a valid IP address."
            )
Exemplo n.º 4
0
def get_errors(version, opcode, priv_port, pub_port, lifetime, ips, gateway,
               usetls, cert_path, key_path):
    errors = []

    ok_data = {'version': version, 'opcode': opcode}

    if opcode != 0:
        # It's a request, check the parameters
        try:
            priv_port_int = int(priv_port)
            if not 0 <= priv_port_int <= 65535:
                raise ValueError
            ok_data['private_port'] = priv_port_int
        except ValueError:
            errors.append(
                "The private port must be an integer between 0 and 65535.")

        try:
            pub_port_int = int(pub_port)
            if not 0 <= pub_port_int <= 65535:
                raise ValueError
            ok_data['public_port'] = pub_port_int
        except ValueError:
            errors.append(
                "The public port must be an integer between 0 and 65535.")

        try:
            lifetime_int = int(lifetime)
            if not 0 <= lifetime_int:
                raise ValueError
            ok_data['lifetime'] = lifetime_int
        except ValueError:
            errors.append(
                "The lifetime must be an integer equal to or greater than zero."
            )

        if version == 1:
            if not ips:
                errors.append(
                    "You must provide at least one public IPv4 address for the request."
                )
            else:
                ok_data['ips'] = []
                for ip in ips.split(","):
                    if not is_valid_ip_string(ip):
                        errors.append(
                            "IPv4 address '%s' from public IPs is not a valid address."
                            % ip)
                    else:
                        ok_data['ips'].append(ip)

    if gateway == "" or gateway == "default":
        try:
            gateway = get_default_router_address()
        except IOError:
            errors.append(
                "Could not determine the default gateway, please provide it manually."
            )
    elif not is_valid_ip_string(gateway):
        errors.append("The gateway '%s' is not a valid IPv4 address." %
                      gateway)

    ok_data['gateway'] = gateway
    ok_data['usetls'] = usetls

    if usetls:
        try:
            ok_data['tls_cert'] = open(cert_path, "rb")
        except IOError:
            errors.append("Cannot read the certificate file.")

        try:
            ok_data['tls_key'] = open(key_path, "rb")
        except IOError:
            errors.append("Cannot read the key file.")

    return errors, ok_data
Exemplo n.º 5
0
    if len(args) < 2:
        sys.exit(
            "Not enough arguments, use create-cert.py --help to get help.")

    client_ip = args[0]
    lifetime = args[1]

    if len(args) >= 3 and args[2] != "-der":
        keylen = args[2]
        if keylen not in ['1024', '2048', '4096']:
            sys.exit("The key length is not a valid size.")
        keylen = int(keylen)
    else:
        keylen = 2048

    # Check that the IP is OK
    if not is_valid_ip_string(client_ip):
        sys.exit("The client IP address is not a valid IP.")

    # Check that the lifetime is OK
    try:
        lifetime_int = int(lifetime)
        if lifetime_int <= 0:
            raise ValueError
    except ValueError:
        sys.exit("The lifetime must be a positive integer.")

    # Everything is fine, create the cert
    create_cert(client_ip, lifetime_int, '-der' in args, keylen)
Exemplo n.º 6
0
def _check_all_ips_correct(ip_list, name):
    for ip in ip_list:
        if not is_valid_ip_string(ip):
            printerr("Warning: IP address '%s' from %s is not a valid IPv4 address." % (ip, name))
Exemplo n.º 7
0
    def create_mapping_handler():
        # Ensure that the user has introduced the correct pasword
        if settings.WEB_INTERFACE_PASSWORD and not session.get("allowed", False):
            return redirect("/")

        # Auxiliary function
        def mapping_view(message, form):
            return render_template("create-mapping.html", public_ips=settings.PUBLIC_INTERFACES, message=message, form=form)

        if request.method == "GET":
            return mapping_view(None, {'public_ip': '', 'public_port': 1, 'private_ip': '', 'private_port': 1, 'proto': '', 'lifetime': 3600})
        else:
            # Check that all params are there
            if not all(k in request.form for k in ['public_ip', 'public_port', 'private_ip', 'private_port', 'proto', 'lifetime']):
                return mapping_view("At least one mandatory field wasn't provided.", request.form)

            # Check that they are all OK
            public_ip = request.form['public_ip']
            if not is_valid_ip_string(public_ip) or public_ip not in settings.PUBLIC_INTERFACES:
                return mapping_view("The public interface is not valid.", request.form)

            public_port = request.form['public_port']
            try:
                public_port = int(public_port)
                if not 1 <= public_port <= 65535:
                    raise ValueError
            except ValueError:
                return mapping_view("The public port must be between 1 and 65535.", request.form)

            if public_port in settings.EXCLUDED_PORTS or not settings.MIN_ALLOWED_MAPPABLE_PORT <= public_port <= settings.MAX_ALLOWED_MAPPABLE_PORT:
                return mapping_view("That public port is excluded per configuration settings, please select another one.", request.form)

            private_ip = request.form['private_ip']
            if not is_valid_ip_string(private_ip):
                return mapping_view("The client address is not valid.", request.form)

            private_port = request.form['private_port']
            try:
                private_port = int(private_port)
                if not 1 <= private_port <= 65535:
                    raise ValueError
            except ValueError:
                return mapping_view("The private port must be between 1 and 65535.", request.form)

            proto = request.form['proto']
            if proto not in ["TCP", "UDP"]:
                return mapping_view("The protocol is not recognized", request.form)

            lifetime = request.form['lifetime']
            try:
                lifetime = int(lifetime)
                if not 1 <= lifetime <= 65535:
                    raise ValueError
            except ValueError:
                return mapping_view("The lifetime must be between 1 and 65535.", request.form)

            from natpmp_operation import natpmp_logic_common
            lifetime = natpmp_logic_common.get_acceptable_lifetime(lifetime)

            # Parameters are correct, check that the mapping can actually be made

            # Check that the client doesn't have another mapping for that public IP and private port
            cur_mappings = natpmp_logic_common.get_mappings_client([public_ip], [private_port], [proto], private_ip)
            if cur_mappings and cur_mappings[0]['public_port'] != public_port:
                return mapping_view("That client already has another mapping for the desired private port, public IP and protocol.", request.form)
            elif cur_mappings and cur_mappings[0]['public_port'] == public_port:
                # The client already has this mapping, refresh it
                natpmp_logic_common.create_mapping(public_ip, public_port, proto, private_ip, private_port, lifetime)
                flash("Mapping successfully created.", "success")
                return redirect("/dashboard")

            # Check that the mapping can be made and do it if so
            if natpmp_logic_common.is_new_mapping_available(public_ip, public_port, proto, private_ip):
                natpmp_logic_common.create_mapping(public_ip, public_port, proto, private_ip, private_port, lifetime)
                flash("Mapping successfully created.", "success")
                return redirect("/dashboard")
            else:
                return mapping_view("That mapping cannot be created because it's already asigned to another client.", request.form)
Exemplo n.º 8
0
    def edit_settings_handler():
        # Ensure that the user has introduced the correct pasword
        if settings.WEB_INTERFACE_PASSWORD and not session.get("allowed", False):
            return redirect("/")

        # Auxiliary function
        def settings_view(message, form):
            return render_template("edit-settings.html", message=message, form=form, pass_enabled=bool(settings.WEB_INTERFACE_PASSWORD))

        if request.method == "GET":
            return settings_view(None, {'allow_v0': settings.ALLOW_VERSION_0, 'allow_v1': settings.ALLOW_VERSION_1, 'allow_tls': settings.ALLOW_SECURITY_IN_V1,
                                        'force_tls': settings.FORCE_SECURITY_IN_V1, 'strict_tls': settings.STRICT_CERTIFICATE_CHECKING,
                                        'max_port': settings.MAX_ALLOWED_MAPPABLE_PORT, 'min_port': settings.MIN_ALLOWED_MAPPABLE_PORT, 'excluded_ports': str(settings.EXCLUDED_PORTS)[1:-1],
                                        'max_lifetime': settings.MAX_ALLOWED_LIFETIME, 'min_lifetime': settings.MIN_ALLOWED_LIFETIME, 'fixed_lifetime': settings.FIXED_LIFETIME,
                                        'blacklist_mode': settings.BLACKLIST_MODE, 'whitelist_mode': settings.WHITELIST_MODE, 'blacklisted_ips': str(settings.BLACKLISTED_IPS)[1:-1].replace("'", "").replace('"', ""),
                                        'whitelisted_ips': str(settings.WHITELISTED_IPS)[1:-1].replace("'", "").replace('"', ""), 'debug': settings.DEBUG})
        else:
            form = request.form
            # Check that the password is there if it's set
            if settings.WEB_INTERFACE_PASSWORD and ("password" not in form or form["password"] != settings.WEB_INTERFACE_PASSWORD):
                return settings_view("The password is not correct.", form)

            # Check that all of the required params are there
            if not all(param in form for param in ["max_port", "min_port", "excluded_ports", "max_lifetime", "min_lifetime", "fixed_lifetime", "blacklisted_ips", "whitelisted_ips"]):
                return settings_view("At least one mandatory field wasn't provided.", form)

            # Dump them into variables
            allow_v0 = "allow_v0" in form and form["allow_v0"]
            allow_v1 = "allow_v1" in form and form["allow_v1"]
            allow_tls = "allow_tls" in form and form["allow_tls"]
            force_tls = "force_tls" in form and form["force_tls"]
            strict_tls = "strict_tls" in form and form["strict_tls"]
            max_port = form["max_port"]
            min_port = form["min_port"]
            excluded_ports = form["excluded_ports"]
            max_lifetime = form["max_lifetime"]
            min_lifetime = form["min_lifetime"]
            fixed_lifetime = form["fixed_lifetime"]
            blacklist_mode = "blacklist_mode" in form and form["blacklist_mode"]
            whitelist_mode = "whitelist_mode" in form and form["whitelist_mode"]
            blacklisted_ips = form["blacklisted_ips"]
            whitelisted_ips = form["whitelisted_ips"]
            debug = "debug" in form and form["debug"]

            # Check that they are all OK
            if not allow_v0 and not allow_v1:
                return settings_view("At least either version must be enabled", form)

            if allow_tls and not allow_v1:
                return settings_view("TLS can only be enabled if v1 is enabled.", form)

            if (force_tls or strict_tls) and not allow_tls:
                return settings_view("TLS settings require that TLS is enabled.", form)

            try:
                max_port = int(max_port)
                if not 1 <= max_port <= 65535:
                    raise ValueError
            except ValueError:
                return settings_view("The maximum port must be between 1 and 65535.", form)

            try:
                min_port = int(min_port)
                if not 1 <= min_port <= 65535:
                    raise ValueError
            except ValueError:
                return settings_view("The minimum port must be between 1 and 65535.", form)

            if not excluded_ports:
                excluded_ports = []
            else:
                tmp = []
                for spl in excluded_ports.split(","):
                    spl = spl.strip()
                    try:
                        spl = int(spl)
                        if not 1 <= spl <= 65535:
                            raise ValueError
                        tmp.append(spl)
                    except ValueError:
                        return settings_view("Port %s from excluded ports is not a valid port." % spl, form)
                excluded_ports = tmp

            try:
                max_lifetime = int(max_lifetime)
                if not max_lifetime >= 1:
                    raise ValueError
            except ValueError:
                return settings_view("The maximum lifetime must be greater than 1.", form)

            try:
                min_lifetime = int(min_lifetime)
                if not min_lifetime >= 1:
                    raise ValueError
            except ValueError:
                return settings_view("The maximum lifetime must be greater than 1.", form)

            if fixed_lifetime:
                try:
                    fixed_lifetime = int(fixed_lifetime)
                    if not fixed_lifetime >= 1:
                        raise ValueError
                except ValueError:
                    return settings_view("The fixed lifetime must be greater than 1.", form)
            else:
                fixed_lifetime = None

            if blacklist_mode and whitelist_mode:
                return settings_view("Blacklist and whitelist mode cannot be both active at once.", form)

            if not blacklisted_ips:
                blacklisted_ips = []
            else:
                tmp = []
                for spl in blacklisted_ips.split(","):
                    spl = spl.strip()
                    if not is_valid_ip_string(spl):
                        return settings_view("IP %s from the blacklist is not a valid address." % spl, form)
                    tmp.append(spl)
                blacklisted_ips = tmp

            if not whitelisted_ips:
                whitelisted_ips = []
            else:
                tmp = []
                for spl in whitelisted_ips.split(","):
                    spl = spl.strip()
                    if not is_valid_ip_string(spl):
                        return settings_view("IP %s from the whitelist is not a valid address." % spl, form)
                    tmp.append(spl)
                    whitelisted_ips = tmp

            # All settings are valid by now, dump them into the settings module
            settings.ALLOW_VERSION_0 = allow_v0
            settings.ALLOW_VERSION_1 = allow_v1
            settings.ALLOW_SECURITY_IN_V1 = allow_tls
            settings.FORCE_SECURITY_IN_V1 = force_tls
            settings.STRICT_CERTIFICATE_CHECKING = strict_tls
            settings.MAX_ALLOWED_MAPPABLE_PORT = max_port
            settings.MIN_ALLOWED_MAPPABLE_PORT = min_port
            settings.EXCLUDED_PORTS = excluded_ports
            settings.MAX_ALLOWED_LIFETIME = max_lifetime
            settings.MIN_ALLOWED_LIFETIME = min_lifetime
            settings.FIXED_LIFETIME = fixed_lifetime
            settings.BLACKLIST_MODE = blacklist_mode
            settings.BLACKLISTED_IPS = blacklisted_ips
            settings.WHITELIST_MODE = whitelist_mode
            settings.WHITELISTED_IPS = whitelisted_ips
            settings.DEBUG = debug

            # Perform some additional changes if needed
            from natpmp_operation import natpmp_logic_common
            if allow_tls and natpmp_logic_common.NATPMP_OPCODE_SENDCERT not in natpmp_logic_common.SUPPORTED_OPCODES[1]:
                natpmp_logic_common.SUPPORTED_OPCODES[1].append(natpmp_logic_common.NATPMP_OPCODE_SENDCERT)
            elif not allow_tls and natpmp_logic_common.NATPMP_OPCODE_SENDCERT in natpmp_logic_common.SUPPORTED_OPCODES[1]:
                natpmp_logic_common.SUPPORTED_OPCODES[1].remove(natpmp_logic_common.NATPMP_OPCODE_SENDCERT)

            import logging
            log = logging.getLogger('werkzeug')

            if debug:
                log.setLevel(logging.DEBUG)
            else:
                log.setLevel(logging.ERROR)

            printlog("Settings changed via web interface.")
            flash("Settings updated.", "success")
            return redirect("/dashboard")