Ejemplo n.º 1
0
def net4to6x96(prefix, net):
    prefix = str(ipaddress.IPv6Network(prefix)).split('/')[0]
    net = net.split('/')[0]
    nets = net.split('.')

    if prefix.count(':') == 5:
        prefix = prefix[:-1]

    net_num = int(nets[0]) * 256**3 + int(nets[1]) * 256**2 + \
        int(nets[2]) * 256**1 + int(nets[3]) * 256**0
    net_hex = hex(net_num)

    net6 = prefix + net_hex[2:6] + ':' + net_hex[6:10] + ':0:0/96'

    return str(ipaddress.IPv6Network(net6))
Ejemplo n.º 2
0
def host_put(hst=None):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    hst = host.get_by_id(hst)

    if 'name' in flask.request.json:
        hst.name = utils.filter_str(
            flask.request.json['name']) or utils.random_name()

    if 'public_address' in flask.request.json:
        hst.public_address = utils.filter_str(
            flask.request.json['public_address'])

    if 'public_address6' in flask.request.json:
        hst.public_address6 = utils.filter_str(
            flask.request.json['public_address6'])

    if 'routed_subnet6' in flask.request.json:
        routed_subnet6 = flask.request.json['routed_subnet6']
        if routed_subnet6:
            try:
                routed_subnet6 = ipaddress.IPv6Network(
                    flask.request.json['routed_subnet6'])
            except (ipaddress.AddressValueError, ValueError):
                return utils.jsonify({
                    'error': IPV6_SUBNET_INVALID,
                    'error_msg': IPV6_SUBNET_INVALID_MSG,
                }, 400)

            if routed_subnet6.prefixlen > 64:
                return utils.jsonify({
                    'error': IPV6_SUBNET_SIZE_INVALID,
                    'error_msg': IPV6_SUBNET_SIZE_INVALID_MSG,
                }, 400)

            routed_subnet6 = str(routed_subnet6)
        else:
            routed_subnet6 = None

        if hst.routed_subnet6 != routed_subnet6:
            if server.get_online_ipv6_count():
                return utils.jsonify({
                    'error': IPV6_SUBNET_ONLINE,
                    'error_msg': IPV6_SUBNET_ONLINE_MSG,
                }, 400)
            hst.routed_subnet6 = routed_subnet6

    if 'link_address' in flask.request.json:
        hst.link_address = utils.filter_str(
            flask.request.json['link_address'])

    hst.commit(hst.changed)
    event.Event(type=HOSTS_UPDATED)
    messenger.publish('hosts', 'updated')

    return utils.jsonify(hst.dict())
Ejemplo n.º 3
0
def ip4to6x96(prefix, net, addr):
    prefix = str(ipaddress.IPv6Network(prefix)).split('/')[0]
    addrs = addr.split('/')[0].split('.')
    net = net.split('/')[0]
    nets = net.split('.')

    if prefix.count(':') == 5:
        prefix = prefix[:-1]

    net_num = int(nets[0]) * 256**3 + int(nets[1]) * 256**2 + \
        int(nets[2]) * 256**1 + int(nets[3]) * 256**0
    net_hex = hex(net_num)

    addr_num = int(addrs[0]) * 256**3 + int(addrs[1]) * 256**2 + \
        int(addrs[2]) * 256**1 + int(addrs[3]) * 256**0
    addr_hex = hex(addr_num)

    addr6 = prefix + net_hex[2:6] + ':' + net_hex[6:10] + ':' + \
        addr_hex[2:6] + ':' + addr_hex[6:10]

    return str(ipaddress.IPv6Address(addr6))
Ejemplo n.º 4
0
    def generate_iptables_rules(self):
        server_addr = utils.get_network_gateway(self.server.network)
        server_addr6 = utils.get_network_gateway(self.server.network6)
        ipv6_firewall = self.server.ipv6_firewall and \
            settings.local.host.routed_subnet6

        self.iptables.id = self.server.id
        self.iptables.ipv6 = self.server.ipv6
        self.iptables.server_addr = server_addr
        self.iptables.server_addr6 = server_addr6
        self.iptables.virt_interface = self.interface
        self.iptables.virt_network = self.server.network
        self.iptables.virt_network6 = self.server.network6
        self.iptables.ipv6_firewall = ipv6_firewall
        self.iptables.inter_client = self.server.inter_client
        self.iptables.restrict_routes = self.server.restrict_routes

        try:
            routes_output = utils.check_output_logged(['route', '-n'])
        except subprocess.CalledProcessError:
            logger.exception(
                'Failed to get IP routes',
                'server',
                server_id=self.server.id,
            )
            raise

        routes = []
        default_interface = None
        for line in routes_output.splitlines():
            line_split = line.split()
            if len(line_split) < 8 or not re.match(IP_REGEX, line_split[0]):
                continue
            if line_split[0] not in routes:
                if line_split[0] == '0.0.0.0':
                    if default_interface:
                        continue
                    default_interface = line_split[7]

                routes.append((ipaddress.IPNetwork(
                    '%s/%s' %
                    (line_split[0], utils.subnet_to_cidr(line_split[2]))),
                               line_split[7]))
        routes.reverse()

        if not default_interface:
            raise IptablesError('Failed to find default network interface')

        routes6 = []
        default_interface6 = None
        if self.server.ipv6:
            try:
                routes_output = utils.check_output_logged(
                    ['route', '-n', '-A', 'inet6'])
            except subprocess.CalledProcessError:
                logger.exception(
                    'Failed to get IPv6 routes',
                    'server',
                    server_id=self.server.id,
                )
                raise

            for line in routes_output.splitlines():
                line_split = line.split()

                if len(line_split) < 7:
                    continue

                try:
                    route_network = ipaddress.IPv6Network(line_split[0])
                except (ipaddress.AddressValueError, ValueError):
                    continue

                if line_split[0] == '::/0':
                    if default_interface6:
                        continue
                    default_interface6 = line_split[6]

                routes6.append((
                    route_network,
                    line_split[6],
                ))

            if not default_interface6:
                raise IptablesError(
                    'Failed to find default IPv6 network interface')

            if default_interface6 == 'lo':
                logger.error(
                    'Failed to find default IPv6 interface',
                    'server',
                    server_id=self.server.id,
                )
        routes6.reverse()

        interfaces = set()
        interfaces6 = set()

        for route in self.server.get_routes(
                include_hidden=True,
                include_server_links=True,
                include_default=True,
        ):
            if route['virtual_network'] or route['link_virtual_network']:
                self.iptables.add_nat_network(route['network'])

            if route['virtual_network'] or route['net_gateway']:
                continue

            network = route['network']
            is6 = ':' in network
            network_obj = ipaddress.IPNetwork(network)

            interface = route['nat_interface']
            if is6:
                if not interface:
                    for route_net, route_intf in routes6:
                        if network_obj in route_net:
                            interface = route_intf
                            break

                    if not interface:
                        logger.info(
                            'Failed to find interface for local ' + \
                                'IPv6 network route, using default route',
                                'server',
                            server_id=self.server.id,
                            network=network,
                        )
                        interface = default_interface6
                interfaces6.add(interface)
            else:
                if not interface:
                    for route_net, route_intf in routes:
                        if network_obj in route_net:
                            interface = route_intf
                            break

                    if not interface:
                        logger.info(
                            'Failed to find interface for local ' + \
                                'network route, using default route',
                                'server',
                            server_id=self.server.id,
                            network=network,
                        )
                        interface = default_interface
                interfaces.add(interface)

            self.iptables.add_route(
                network,
                nat=route['nat'],
                nat_interface=interface,
            )

        if self.vxlan:
            self.iptables.add_route(self.vxlan.vxlan_net)

        self.iptables.generate()
Ejemplo n.º 5
0
def settings_put():
    if settings.app.demo_mode:
        return utils.demo_blocked()

    org_event = False
    admin_event = False
    admin = flask.g.administrator
    changes = set()

    settings_commit = False
    update_server = False
    update_acme = False
    update_cert = False

    if 'username' in flask.request.json and flask.request.json['username']:
        username = utils.filter_str(flask.request.json['username']).lower()
        if username != admin.username:
            changes.add('username')
        admin.username = username

    if 'password' in flask.request.json and flask.request.json['password']:
        password = flask.request.json['password']
        changes.add('password')
        admin.password = password

    if 'server_cert' in flask.request.json:
        settings_commit = True
        server_cert = flask.request.json['server_cert']
        if server_cert:
            server_cert = server_cert.strip()
        else:
            server_cert = None

        if server_cert != settings.app.server_cert:
            update_server = True

        settings.app.server_cert = server_cert

    if 'server_key' in flask.request.json:
        settings_commit = True
        server_key = flask.request.json['server_key']
        if server_key:
            server_key = server_key.strip()
        else:
            server_key = None

        if server_key != settings.app.server_key:
            update_server = True

        settings.app.server_key = server_key

    if 'server_port' in flask.request.json:
        settings_commit = True

        server_port = flask.request.json['server_port']
        if not server_port:
            server_port = 443

        try:
            server_port = int(server_port)
            if server_port < 1 or server_port > 65535:
                raise ValueError('Port invalid')
        except ValueError:
            return utils.jsonify(
                {
                    'error': PORT_INVALID,
                    'error_msg': PORT_INVALID_MSG,
                }, 400)

        if settings.app.redirect_server and server_port == 80:
            return utils.jsonify(
                {
                    'error': PORT_RESERVED,
                    'error_msg': PORT_RESERVED_MSG,
                }, 400)

        if server_port != settings.app.server_port:
            update_server = True

        settings.app.server_port = server_port

    if 'acme_domain' in flask.request.json:
        settings_commit = True

        acme_domain = utils.filter_str(flask.request.json['acme_domain']
                                       or None)
        if acme_domain:
            acme_domain = acme_domain.replace('https://', '')
            acme_domain = acme_domain.replace('http://', '')
            acme_domain = acme_domain.replace('/', '')

        if acme_domain != settings.app.acme_domain:
            if not acme_domain:
                settings.app.acme_key = None
                settings.app.acme_timestamp = None
                settings.app.server_key = None
                settings.app.server_cert = None
                update_server = True
                update_cert = True
            else:
                update_acme = True
        settings.app.acme_domain = acme_domain

    if 'auditing' in flask.request.json:
        settings_commit = True
        auditing = flask.request.json['auditing'] or None

        if settings.app.auditing != auditing:
            if not flask.g.administrator.super_user:
                return utils.jsonify(
                    {
                        'error': REQUIRES_SUPER_USER,
                        'error_msg': REQUIRES_SUPER_USER_MSG,
                    }, 400)
            admin_event = True
            org_event = True

        settings.app.auditing = auditing

    if 'monitoring' in flask.request.json:
        settings_commit = True
        monitoring = flask.request.json['monitoring'] or None
        settings.app.monitoring = monitoring

    if 'influxdb_uri' in flask.request.json:
        settings_commit = True
        influxdb_uri = flask.request.json['influxdb_uri'] or None
        settings.app.influxdb_uri = influxdb_uri

    if 'email_from' in flask.request.json:
        settings_commit = True
        email_from = flask.request.json['email_from'] or None
        if email_from != settings.app.email_from:
            changes.add('smtp')
        settings.app.email_from = email_from

    if 'email_server' in flask.request.json:
        settings_commit = True
        email_server = flask.request.json['email_server'] or None
        if email_server != settings.app.email_server:
            changes.add('smtp')
        settings.app.email_server = email_server

    if 'email_username' in flask.request.json:
        settings_commit = True
        email_username = flask.request.json['email_username'] or None
        if email_username != settings.app.email_username:
            changes.add('smtp')
        settings.app.email_username = email_username

    if 'email_password' in flask.request.json:
        settings_commit = True
        email_password = flask.request.json['email_password'] or None
        if email_password != settings.app.email_password:
            changes.add('smtp')
        settings.app.email_password = email_password

    if 'pin_mode' in flask.request.json:
        settings_commit = True
        pin_mode = flask.request.json['pin_mode'] or None
        if pin_mode != settings.user.pin_mode:
            changes.add('pin_mode')
        settings.user.pin_mode = pin_mode

    if 'sso' in flask.request.json:
        org_event = True
        settings_commit = True
        sso = flask.request.json['sso'] or None
        if sso != settings.app.sso:
            changes.add('sso')
        settings.app.sso = sso

    if 'sso_match' in flask.request.json:
        settings_commit = True
        sso_match = flask.request.json['sso_match'] or None

        if sso_match != settings.app.sso_match:
            changes.add('sso')

        if isinstance(sso_match, list):
            settings.app.sso_match = sso_match
        else:
            settings.app.sso_match = None

    if 'sso_duo_token' in flask.request.json:
        settings_commit = True
        sso_duo_token = flask.request.json['sso_duo_token'] or None
        if sso_duo_token != settings.app.sso_duo_token:
            changes.add('sso')
        settings.app.sso_duo_token = sso_duo_token

    if 'sso_duo_secret' in flask.request.json:
        settings_commit = True
        sso_duo_secret = flask.request.json['sso_duo_secret'] or None
        if sso_duo_secret != settings.app.sso_duo_secret:
            changes.add('sso')
        settings.app.sso_duo_secret = sso_duo_secret

    if 'sso_duo_host' in flask.request.json:
        settings_commit = True
        sso_duo_host = flask.request.json['sso_duo_host'] or None
        if sso_duo_host != settings.app.sso_duo_host:
            changes.add('sso')
        settings.app.sso_duo_host = sso_duo_host

    if 'sso_duo_mode' in flask.request.json:
        settings_commit = True
        sso_duo_mode = flask.request.json['sso_duo_mode'] or None
        if sso_duo_mode != settings.app.sso_duo_mode:
            changes.add('sso')
        settings.app.sso_duo_mode = sso_duo_mode

    if 'sso_radius_secret' in flask.request.json:
        settings_commit = True
        sso_radius_secret = flask.request.json['sso_radius_secret'] or None
        if sso_radius_secret != settings.app.sso_radius_secret:
            changes.add('sso')
        settings.app.sso_radius_secret = sso_radius_secret

    if 'sso_radius_host' in flask.request.json:
        settings_commit = True
        sso_radius_host = flask.request.json['sso_radius_host'] or None
        if sso_radius_host != settings.app.sso_radius_host:
            changes.add('sso')
        settings.app.sso_radius_host = sso_radius_host

    if 'sso_org' in flask.request.json:
        settings_commit = True
        sso_org = flask.request.json['sso_org'] or None

        if sso_org:
            sso_org = utils.ObjectId(sso_org)
        else:
            sso_org = None

        if sso_org != settings.app.sso_org:
            changes.add('sso')

        if settings.app.sso and not sso_org:
            return utils.jsonify(
                {
                    'error': SSO_ORG_NULL,
                    'error_msg': SSO_ORG_NULL_MSG,
                }, 400)

        settings.app.sso_org = sso_org

    if 'sso_saml_url' in flask.request.json:
        settings_commit = True
        sso_saml_url = flask.request.json['sso_saml_url'] or None
        if sso_saml_url != settings.app.sso_saml_url:
            changes.add('sso')
        settings.app.sso_saml_url = sso_saml_url

    if 'sso_saml_issuer_url' in flask.request.json:
        settings_commit = True
        sso_saml_issuer_url = flask.request.json['sso_saml_issuer_url'] or None
        if sso_saml_issuer_url != settings.app.sso_saml_issuer_url:
            changes.add('sso')
        settings.app.sso_saml_issuer_url = sso_saml_issuer_url

    if 'sso_saml_cert' in flask.request.json:
        settings_commit = True
        sso_saml_cert = flask.request.json['sso_saml_cert'] or None
        if sso_saml_cert != settings.app.sso_saml_cert:
            changes.add('sso')
        settings.app.sso_saml_cert = sso_saml_cert

    if 'sso_okta_token' in flask.request.json:
        settings_commit = True
        sso_okta_token = flask.request.json['sso_okta_token'] or None
        if sso_okta_token != settings.app.sso_okta_token:
            changes.add('sso')
        settings.app.sso_okta_token = sso_okta_token

    if 'sso_onelogin_id' in flask.request.json:
        settings_commit = True
        sso_onelogin_id = flask.request.json['sso_onelogin_id'] or None
        if sso_onelogin_id != settings.app.sso_onelogin_id:
            changes.add('sso')
        settings.app.sso_onelogin_id = sso_onelogin_id

    if 'sso_onelogin_secret' in flask.request.json:
        settings_commit = True
        sso_onelogin_secret = \
            flask.request.json['sso_onelogin_secret'] or None
        if sso_onelogin_secret != settings.app.sso_onelogin_secret:
            changes.add('sso')
        settings.app.sso_onelogin_secret = sso_onelogin_secret

    if 'sso_client_cache' in flask.request.json:
        settings_commit = True
        sso_client_cache = True if \
            flask.request.json['sso_client_cache'] else False
        if sso_client_cache != settings.app.sso_client_cache:
            changes.add('sso')
        settings.app.sso_client_cache = sso_client_cache

    if 'sso_yubico_client' in flask.request.json:
        settings_commit = True
        sso_yubico_client = \
            flask.request.json['sso_yubico_client'] or None
        if sso_yubico_client != settings.app.sso_yubico_client:
            changes.add('sso')
        settings.app.sso_yubico_client = sso_yubico_client

    if 'sso_yubico_secret' in flask.request.json:
        settings_commit = True
        sso_yubico_secret = \
            flask.request.json['sso_yubico_secret'] or None
        if sso_yubico_secret != settings.app.sso_yubico_secret:
            changes.add('sso')
        settings.app.sso_yubico_secret = sso_yubico_secret

    if flask.request.json.get('theme'):
        settings_commit = True
        theme = 'light' if flask.request.json['theme'] == 'light' else 'dark'

        if theme != settings.app.theme:
            if theme == 'dark':
                event.Event(type=THEME_DARK)
            else:
                event.Event(type=THEME_LIGHT)

        settings.app.theme = theme

    if 'public_address' in flask.request.json:
        public_address = flask.request.json['public_address'] or None

        if public_address != settings.local.host.public_addr:
            settings.local.host.public_address = public_address
            settings.local.host.commit('public_address')

    if 'public_address6' in flask.request.json:
        public_address6 = flask.request.json['public_address6'] or None

        if public_address6 != settings.local.host.public_addr6:
            settings.local.host.public_address6 = public_address6
            settings.local.host.commit('public_address6')

    if 'routed_subnet6' in flask.request.json:
        routed_subnet6 = flask.request.json['routed_subnet6']
        if routed_subnet6:
            try:
                routed_subnet6 = ipaddress.IPv6Network(
                    flask.request.json['routed_subnet6'])
            except (ipaddress.AddressValueError, ValueError):
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_INVALID,
                        'error_msg': IPV6_SUBNET_INVALID_MSG,
                    }, 400)

            if routed_subnet6.prefixlen > 64:
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_SIZE_INVALID,
                        'error_msg': IPV6_SUBNET_SIZE_INVALID_MSG,
                    }, 400)

            routed_subnet6 = str(routed_subnet6)
        else:
            routed_subnet6 = None

        if settings.local.host.routed_subnet6 != routed_subnet6:
            if server.get_online_ipv6_count():
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_ONLINE,
                        'error_msg': IPV6_SUBNET_ONLINE_MSG,
                    }, 400)
            settings.local.host.routed_subnet6 = routed_subnet6
            settings.local.host.commit('routed_subnet6')

    if 'reverse_proxy' in flask.request.json:
        settings_commit = True
        reverse_proxy = flask.request.json['reverse_proxy']
        settings.app.reverse_proxy = True if reverse_proxy else False

    if 'cloud_provider' in flask.request.json:
        settings_commit = True
        cloud_provider = flask.request.json['cloud_provider'] or None
        settings.app.cloud_provider = cloud_provider

    if 'route53_region' in flask.request.json:
        settings_commit = True
        settings.app.route53_region = utils.filter_str(
            flask.request.json['route53_region']) or None

    if 'route53_zone' in flask.request.json:
        settings_commit = True
        settings.app.route53_zone = utils.filter_str(
            flask.request.json['route53_zone']) or None

    for aws_key in (
            'us_east_1_access_key',
            'us_east_1_secret_key',
            'us_east_2_access_key',
            'us_east_2_secret_key',
            'us_west_1_access_key',
            'us_west_1_secret_key',
            'us_west_2_access_key',
            'us_west_2_secret_key',
            'eu_west_1_access_key',
            'eu_west_1_secret_key',
            'eu_central_1_access_key',
            'eu_central_1_secret_key',
            'ap_northeast_1_access_key',
            'ap_northeast_1_secret_key',
            'ap_northeast_2_access_key',
            'ap_northeast_2_secret_key',
            'ap_southeast_1_access_key',
            'ap_southeast_1_secret_key',
            'ap_southeast_2_access_key',
            'ap_southeast_2_secret_key',
            'ap_south_1_access_key',
            'ap_south_1_secret_key',
            'sa_east_1_access_key',
            'sa_east_1_secret_key',
    ):
        if aws_key in flask.request.json:
            settings_commit = True
            aws_value = flask.request.json[aws_key]

            if aws_value:
                setattr(settings.app, aws_key, utils.filter_str(aws_value))
            else:
                setattr(settings.app, aws_key, None)

    if not settings.app.sso:
        settings.app.sso_host = None
        settings.app.sso_token = None
        settings.app.sso_secret = None
        settings.app.sso_match = None
        settings.app.sso_duo_token = None
        settings.app.sso_duo_secret = None
        settings.app.sso_duo_host = None
        settings.app.sso_yubico_client = None
        settings.app.sso_yubico_secret = None
        settings.app.sso_org = None
        settings.app.sso_saml_url = None
        settings.app.sso_saml_issuer_url = None
        settings.app.sso_saml_cert = None
        settings.app.sso_okta_token = None
        settings.app.sso_onelogin_key = None
        settings.app.sso_onelogin_id = None
        settings.app.sso_onelogin_secret = None
        settings.app.sso_radius_secret = None
        settings.app.sso_radius_host = None
    else:
        if RADIUS_AUTH in settings.app.sso and \
                settings.app.sso_duo_mode == 'passcode':
            return utils.jsonify(
                {
                    'error': RADIUS_DUO_PASSCODE,
                    'error_msg': RADIUS_DUO_PASSCODE_MSG,
                }, 400)

        if settings.app.sso == DUO_AUTH and \
                settings.app.sso_duo_mode == 'passcode':
            return utils.jsonify(
                {
                    'error': DUO_PASSCODE,
                    'error_msg': DUO_PASSCODE_MSG,
                }, 400)

    for change in changes:
        flask.g.administrator.audit_event(
            'admin_settings',
            _changes_audit_text[change],
            remote_addr=utils.get_remote_addr(),
        )

    if settings_commit:
        settings.commit()

    admin.commit(admin.changed)

    if admin_event:
        event.Event(type=ADMINS_UPDATED)

    if org_event:
        for org in organization.iter_orgs(fields=('_id')):
            event.Event(type=USERS_UPDATED, resource_id=org.id)

    event.Event(type=SETTINGS_UPDATED)

    if update_acme:
        try:
            acme.update_acme_cert()
            app.update_server(0.5)
        except:
            logger.exception(
                'Failed to get LetsEncrypt cert',
                'handler',
                acme_domain=settings.app.acme_domain,
            )
            settings.app.acme_domain = None
            settings.app.acme_key = None
            settings.app.acme_timestamp = None
            settings.commit()
            return utils.jsonify(
                {
                    'error': ACME_ERROR,
                    'error_msg': ACME_ERROR_MSG,
                }, 400)
    elif update_cert:
        logger.info('Regenerating server certificate...', 'handler')
        utils.create_server_cert()
        app.update_server(0.5)
    elif update_server:
        app.update_server(0.5)

    response = flask.g.administrator.dict()
    response.update(_dict())
    return utils.jsonify(response)
Ejemplo n.º 6
0
    def generate_iptables_rules(self):
        rules = []
        rules6 = []

        try:
            routes_output = utils.check_output_logged(['route', '-n'])
        except subprocess.CalledProcessError:
            logger.exception('Failed to get IP routes', 'server',
                server_id=self.server.id,
            )
            raise

        routes = []
        default_interface = None
        for line in routes_output.splitlines():
            line_split = line.split()
            if len(line_split) < 8 or not re.match(IP_REGEX, line_split[0]):
                continue
            if line_split[0] not in routes:
                if line_split[0] == '0.0.0.0':
                    default_interface = line_split[7]

                routes.append((
                    ipaddress.IPNetwork('%s/%s' % (line_split[0],
                        utils.subnet_to_cidr(line_split[2]))),
                    line_split[7]
                ))
        routes.reverse()

        if not default_interface:
            raise IptablesError('Failed to find default network interface')

        routes6 = []
        default_interface6 = None
        if self.server.ipv6:
            try:
                routes_output = utils.check_output_logged(
                    ['route', '-n', '-A', 'inet6'])
            except subprocess.CalledProcessError:
                logger.exception('Failed to get IPv6 routes', 'server',
                    server_id=self.server.id,
                )
                raise

            for line in routes_output.splitlines():
                line_split = line.split()

                if len(line_split) < 7:
                    continue

                try:
                    route_network = ipaddress.IPv6Network(line_split[0])
                except (ipaddress.AddressValueError, ValueError):
                    continue

                if not default_interface6 and line_split[0] == '::/0':
                    default_interface6 = line_split[6]

                routes6.append((
                    route_network,
                    line_split[6]
                ))

            if not default_interface6:
                raise IptablesError(
                    'Failed to find default IPv6 network interface')

            if default_interface6 == 'lo':
                logger.error('Failed to find default IPv6 interface',
                    'server',
                    server_id=self.server.id,
                )
        routes6.reverse()

        route_all = self.server.is_route_all()
        if route_all:
            rules.append([
                'INPUT',
                '-i', self.interface,
                '-j', 'ACCEPT',
            ])
            rules.append([
                'OUTPUT',
                '-o', self.interface,
                '-j', 'ACCEPT',
            ])
            rules.append([
                'FORWARD',
                '-i', self.interface,
                '-j', 'ACCEPT',
            ])
            if self.server.ipv6:
                if self.server.ipv6_firewall and \
                        settings.local.host.routed_subnet6:
                    rules6.append([
                        'INPUT',
                        '-d', self.server.network6,
                         '-m', 'conntrack',
                         '--ctstate','RELATED,ESTABLISHED',
                         '-j', 'ACCEPT',
                    ])
                    rules6.append([
                        'INPUT',
                        '-d', self.server.network6,
                        '-p', 'icmpv6',
                         '-m', 'conntrack',
                        '--ctstate', 'NEW',
                        '-j', 'ACCEPT',
                    ])

                    rules6.append([
                        'INPUT',
                        '-d', self.server.network6,
                        '-j', 'DROP',
                    ])

                    rules6.append([
                        'FORWARD',
                        '-d', self.server.network6,
                        '-m', 'conntrack',
                         '--ctstate', 'RELATED,ESTABLISHED',
                        '-j', 'ACCEPT',
                    ])
                    rules6.append([
                        'FORWARD',
                        '-d', self.server.network6,
                        '-p', 'icmpv6',
                         '-m', 'conntrack',
                        '--ctstate', 'NEW',
                        '-j', 'ACCEPT',
                    ])

                    rules6.append([
                        'FORWARD',
                        '-d', self.server.network6,
                        '-j', 'DROP',
                    ])
                else:
                    rules6.append([
                        'INPUT',
                        '-d', self.server.network6,
                        '-j', 'ACCEPT',
                    ])
                    rules6.append([
                        'FORWARD',
                        '-d', self.server.network6,
                        '-j', 'ACCEPT',
                    ])
        elif self.server.restrict_routes:
            if self.server.inter_client:
                rules.append([
                    'INPUT', '-i', self.interface,
                    '-d', self.server.network,
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'INPUT', '-i', self.interface,
                    '-d', self.server.network6,
                    '-j', 'ACCEPT',
                ])
                rules.append([
                    'OUTPUT', '-o', self.interface,
                    '-s', self.server.network,
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'OUTPUT', '-o', self.interface,
                    '-s', self.server.network6,
                    '-j', 'ACCEPT',
                ])
                rules.append([
                    'FORWARD', '-i', self.interface,
                    '-d', self.server.network,
                    '-j', 'ACCEPT',
                ])
                rules.append([
                    'FORWARD', '-o', self.interface,
                    '-s', self.server.network,
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'FORWARD', '-i', self.interface,
                    '-d', self.server.network6,
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'FORWARD', '-o', self.interface,
                    '-s', self.server.network6,
                    '-j', 'ACCEPT',
                ])
            else:
                server_addr = utils.get_network_gateway(self.server.network)
                server_addr6 = utils.get_network_gateway(self.server.network6)
                rules.append([
                    'INPUT', '-i', self.interface,
                    '-d', server_addr,
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'INPUT', '-i', self.interface,
                    '-d', server_addr6,
                    '-j', 'ACCEPT',
                ])
                rules.append([
                    'OUTPUT', '-o', self.interface,
                    '-s', server_addr,
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'OUTPUT', '-o', self.interface,
                    '-s', server_addr6,
                    '-j', 'ACCEPT',
                ])

            for route in self.server.get_routes(
                        include_hidden=True,
                        include_server_links=True,
                        include_default=False,
                    ):
                network_address = route['network']
                is6 = ':' in network_address
                is_nat = route['nat']

                if route['virtual_network']:
                    continue

                if self.server.restrict_routes:
                    if is6:
                        rules6.append([
                            'INPUT',
                            '-i', self.interface,
                            '-d', network_address,
                            '-j', 'ACCEPT',
                        ])
                        rules6.append([
                            'OUTPUT',
                            '-o', self.interface,
                            '-s', network_address,
                            '-j', 'ACCEPT',
                        ])
                        rules6.append([
                            'FORWARD',
                            '-i', self.interface,
                            '-d', network_address,
                            '-j', 'ACCEPT',
                        ])

                        if is_nat:
                            rules6.append([
                                'FORWARD',
                                '-o', self.interface,
                                '-m', 'conntrack',
                                '--ctstate', 'RELATED,ESTABLISHED',
                                '-s', network_address,
                                '-j', 'ACCEPT',
                            ])
                        else:
                            rules6.append([
                                'FORWARD',
                                '-o', self.interface,
                                '-s', network_address,
                                '-j', 'ACCEPT',
                            ])
                    else:
                        rules.append([
                            'INPUT',
                            '-i', self.interface,
                            '-d', network_address,
                            '-j', 'ACCEPT',
                        ])
                        rules.append([
                            'OUTPUT',
                            '-o', self.interface,
                            '-s', network_address,
                            '-j', 'ACCEPT',
                        ])
                        rules.append([
                            'FORWARD',
                            '-i', self.interface,
                            '-d', network_address,
                            '-j', 'ACCEPT',
                        ])

                        if is_nat:
                            rules.append([
                                'FORWARD',
                                '-o', self.interface,
                                '-m', 'conntrack',
                                '--ctstate', 'RELATED,ESTABLISHED',
                                '-s', network_address,
                                '-j', 'ACCEPT',
                            ])
                        else:
                            rules.append([
                                'FORWARD',
                                '-o', self.interface,
                                '-s', network_address,
                                '-j', 'ACCEPT',
                            ])

        interfaces = set()
        interfaces6 = set()

        link_svr_networks = []
        for link_svr in self.server.iter_links(fields=('_id', 'network',
                'network_start', 'network_end', 'organizations', 'routes',
                'links')):
            link_svr_networks.append(link_svr.network)

        for route in self.server.get_routes(include_hidden=True):
            if route['virtual_network'] or not route['nat']:
                continue

            network_address = route['network']

            args_base = ['POSTROUTING', '-t', 'nat']
            is6 = ':' in network_address
            if is6:
                network = network_address
            else:
                network = utils.parse_network(network_address)[0]
            network_obj = ipaddress.IPNetwork(network_address)

            if is6:
                interface = None
                for route_net, route_intf in routes6:
                    if network_obj in route_net:
                        interface = route_intf
                        break

                if not interface:
                    logger.info(
                        'Failed to find interface for local ' + \
                            'IPv6 network route, using default route',
                            'server',
                        server_id=self.server.id,
                        network=network,
                    )
                    interface = default_interface6
                interfaces6.add(interface)
            else:
                interface = None
                for route_net, route_intf in routes:
                    if network_obj in route_net:
                        interface = route_intf
                        break

                if not interface:
                    logger.info(
                        'Failed to find interface for local ' + \
                            'network route, using default route',
                            'server',
                        server_id=self.server.id,
                        network=network,
                    )
                    interface = default_interface
                interfaces.add(interface)

            if network != '0.0.0.0' and network != '::/0':
                args_base += ['-d', network_address]

            args_base += [
                '-o', interface,
                '-j', 'MASQUERADE',
            ]

            if is6:
                rules6.append(args_base + ['-s', self.server.network6])
            else:
                rules.append(args_base + ['-s', self.server.network])

            for link_svr_net in link_svr_networks:
                if ':' in link_svr_net:
                    rules6.append(args_base + ['-s', link_svr_net])
                else:
                    rules.append(args_base + ['-s', link_svr_net])

        if route_all:
            for interface in interfaces:
                rules.append([
                    'FORWARD',
                    '-i', interface,
                    '-o', self.interface,
                    '-m', 'state',
                    '--state', 'ESTABLISHED,RELATED',
                    '-j', 'ACCEPT',
                ])
                rules.append([
                    'FORWARD',
                    '-i', self.interface,
                    '-o', interface,
                    '-m', 'state',
                    '--state', 'ESTABLISHED,RELATED',
                    '-j', 'ACCEPT',
                ])

            for interface in interfaces6:
                if self.server.ipv6 and self.server.ipv6_firewall and \
                        settings.local.host.routed_subnet6 and \
                        interface == default_interface6:
                    continue

                rules6.append([
                    'FORWARD',
                    '-i', interface,
                    '-o', self.interface,
                    '-m', 'state',
                    '--state', 'ESTABLISHED,RELATED',
                    '-j', 'ACCEPT',
                ])
                rules6.append([
                    'FORWARD',
                    '-i', self.interface,
                    '-o', interface,
                    '-m', 'state',
                    '--state', 'ESTABLISHED,RELATED',
                    '-j', 'ACCEPT',
                ])

        extra_args = [
            '-m', 'comment',
            '--comment', 'pritunl_%s' % self.server.id,
        ]

        if settings.local.iptables_wait:
            extra_args.append('--wait')

        rules = [x + extra_args for x in rules]
        rules6 = [x + extra_args for x in rules6]

        return rules, rules6
Ejemplo n.º 7
0
    def generate_iptables_rules(self):
        rules = []
        rules6 = []

        try:
            routes_output = utils.check_output_logged(['route', '-n'])
        except subprocess.CalledProcessError:
            logger.exception('Failed to get IP routes', 'server',
                server_id=self.server.id,
            )
            raise

        routes = {}
        for line in routes_output.splitlines():
            line_split = line.split()
            if len(line_split) < 8 or not re.match(IP_REGEX, line_split[0]):
                continue
            if line_split[0] not in routes:
                routes[line_split[0]] = line_split[7]

        if '0.0.0.0' not in routes:
            raise IptablesError('Failed to find default network interface')
        default_interface = routes['0.0.0.0']

        routes6 = {}
        default_interface6 = None
        if self.server.ipv6:
            try:
                routes_output = utils.check_output_logged(
                    ['route', '-n', '-A', 'inet6'])
            except subprocess.CalledProcessError:
                logger.exception('Failed to get IPv6 routes', 'server',
                    server_id=self.server.id,
                )
                raise

            for line in routes_output.splitlines():
                line_split = line.split()

                if len(line_split) < 7:
                    continue

                try:
                    ipaddress.IPv6Network(line_split[0])
                except (ipaddress.AddressValueError, ValueError):
                    continue

                if line_split[0] not in routes6:
                    routes6[line_split[0]] = line_split[6]

            if '::/0' not in routes6:
                raise IptablesError(
                    'Failed to find default IPv6 network interface')
            default_interface6 = routes6['::/0']

            if default_interface6 == 'lo':
                logger.error('Failed to find default IPv6 interface',
                    'server',
                    server_id=self.server.id,
                )

        rules.append(['INPUT', '-i', self.interface, '-j', 'ACCEPT'])
        rules.append(['FORWARD', '-i', self.interface, '-j', 'ACCEPT'])
        if self.server.ipv6:
            if self.server.ipv6_firewall and \
                    settings.local.host.routed_subnet6:
                rules6.append(
                    ['INPUT', '-d', self.server.network6, '-j', 'DROP'])
                rules6.append(
                    ['INPUT', '-d', self.server.network6, '-m', 'conntrack',
                     '--ctstate','RELATED,ESTABLISHED', '-j', 'ACCEPT'])
                rules6.append(
                    ['INPUT', '-d', self.server.network6, '-p', 'icmpv6',
                     '-m', 'conntrack', '--ctstate', 'NEW', '-j', 'ACCEPT'])
                rules6.append(
                    ['FORWARD', '-d', self.server.network6, '-j', 'DROP'])
                rules6.append(
                    ['FORWARD', '-d', self.server.network6, '-m', 'conntrack',
                     '--ctstate', 'RELATED,ESTABLISHED', '-j', 'ACCEPT'])
                rules6.append(
                    ['FORWARD', '-d', self.server.network6, '-p', 'icmpv6',
                     '-m', 'conntrack', '--ctstate', 'NEW', '-j', 'ACCEPT'])
            else:
                rules6.append(
                    ['INPUT', '-d', self.server.network6, '-j', 'ACCEPT'])
                rules6.append(
                    ['FORWARD', '-d', self.server.network6, '-j', 'ACCEPT'])

        interfaces = set()
        interfaces6 = set()
        other_networks = []
        if self.server.mode == ALL_TRAFFIC and \
                self.server.network_mode != BRIDGE:
            other_networks = ['0.0.0.0/0']
            if self.server.ipv6 and not settings.local.host.routed_subnet6:
                other_networks.append('::/0')

        link_svr_networks = []
        for link_svr in self.server.iter_links(fields=(
                '_id', 'network', 'network_start', 'network_end')):
            link_svr_networks.append(link_svr.network)

        if settings.vpn.nat_routes:
            for network_address in self.server.local_networks or \
                    other_networks:
                args_base = ['POSTROUTING', '-t', 'nat']
                is6 = ':' in network_address
                if is6:
                    network = network_address
                else:
                    network = utils.parse_network(network_address)[0]

                if is6:
                    if network not in routes6:
                        logger.info(
                            'Failed to find interface for local ' + \
                            'IPv6 network route, using default route',
                            'server',
                            server_id=self.server.id,
                            network=network,
                        )
                        interface = default_interface6
                    else:
                        interface = routes6[network]
                    interfaces6.add(interface)
                else:
                    if network not in routes:
                        logger.info(
                            'Failed to find interface for local ' + \
                            'network route, using default route',
                            'server',
                            server_id=self.server.id,
                            network=network,
                        )
                        interface = default_interface
                    else:
                        interface = routes[network]
                    interfaces.add(interface)

                if network != '0.0.0.0' and network != '::/0':
                    args_base += ['-d', network_address]

                args_base += [
                    '-o', interface,
                    '-j', 'MASQUERADE',
                ]

                if is6:
                    rules6.append(args_base + ['-s', self.server.network6])
                else:
                    rules.append(args_base + ['-s', self.server.network])

                for link_svr_net in link_svr_networks:
                    if ':' in link_svr_net:
                        rules6.append(args_base + ['-s', link_svr_net])
                    else:
                        rules.append(args_base + ['-s', link_svr_net])

        for interface in interfaces:
            rules.append([
                'FORWARD',
                '-i', interface,
                '-o', self.interface,
                '-m', 'state',
                '--state', 'ESTABLISHED,RELATED',
                '-j', 'ACCEPT',
            ])
            rules.append([
                'FORWARD',
                '-i', self.interface,
                '-o', interface,
                '-m', 'state',
                '--state', 'ESTABLISHED,RELATED',
                '-j', 'ACCEPT',
            ])

        for interface in interfaces6:
            if self.server.ipv6 and self.server.ipv6_firewall and \
                    settings.local.host.routed_subnet6 and \
                    interface == default_interface6:
                continue

            rules6.append([
                'FORWARD',
                '-i', interface,
                '-o', self.interface,
                '-m', 'state',
                '--state', 'ESTABLISHED,RELATED',
                '-j', 'ACCEPT',
            ])
            rules6.append([
                'FORWARD',
                '-i', self.interface,
                '-o', interface,
                '-m', 'state',
                '--state', 'ESTABLISHED,RELATED',
                '-j', 'ACCEPT',
            ])

        extra_args = [
            '-m', 'comment',
            '--comment', 'pritunl_%s' % self.server.id,
        ]

        if settings.local.iptables_wait:
            extra_args.append('--wait')

        rules = [x + extra_args for x in rules]
        rules6 = [x + extra_args for x in rules6]

        return rules, rules6
Ejemplo n.º 8
0
def settings_put():
    if settings.app.demo_mode:
        return utils.demo_blocked()

    org_event = False
    admin = flask.g.administrator
    changes = set()

    if 'username' in flask.request.json and flask.request.json['username']:
        username = utils.filter_str(flask.request.json['username']).lower()
        if username != admin.username:
            changes.add('username')
        admin.username = username
    if 'password' in flask.request.json and flask.request.json['password']:
        password = flask.request.json['password']
        changes.add('password')
        admin.password = password
    if 'token' in flask.request.json and flask.request.json['token']:
        admin.generate_token()
        changes.add('token')
    if 'secret' in flask.request.json and flask.request.json['secret']:
        admin.generate_secret()
        changes.add('token')

    settings_commit = False
    if 'auditing' in flask.request.json:
        settings_commit = True
        auditing = flask.request.json['auditing'] or None

        if settings.app.auditing != auditing:
            org_event = True

        settings.app.auditing = auditing

    if 'monitoring' in flask.request.json:
        settings_commit = True
        monitoring = flask.request.json['monitoring'] or None
        settings.app.monitoring = monitoring

    if 'datadog_api_key' in flask.request.json:
        settings_commit = True
        datadog_api_key = flask.request.json['datadog_api_key'] or None
        settings.app.datadog_api_key = datadog_api_key

    if 'email_from' in flask.request.json:
        settings_commit = True
        email_from = flask.request.json['email_from'] or None
        if email_from != settings.app.email_from:
            changes.add('smtp')
        settings.app.email_from = email_from

    if 'email_server' in flask.request.json:
        settings_commit = True
        email_server = flask.request.json['email_server'] or None
        if email_server != settings.app.email_server:
            changes.add('smtp')
        settings.app.email_server = email_server

    if 'email_username' in flask.request.json:
        settings_commit = True
        email_username = flask.request.json['email_username'] or None
        if email_username != settings.app.email_username:
            changes.add('smtp')
        settings.app.email_username = email_username

    if 'email_password' in flask.request.json:
        settings_commit = True
        email_password = flask.request.json['email_password'] or None
        if email_password != settings.app.email_password:
            changes.add('smtp')
        settings.app.email_password = email_password

    if 'pin_mode' in flask.request.json:
        settings_commit = True
        pin_mode = flask.request.json['pin_mode'] or None
        if pin_mode != settings.user.pin_mode:
            changes.add('pin_mode')
        settings.user.pin_mode = pin_mode

    if 'sso' in flask.request.json:
        org_event = True
        settings_commit = True
        sso = flask.request.json['sso'] or None
        if sso != settings.app.sso:
            changes.add('sso')
        settings.app.sso = sso

    if 'sso_match' in flask.request.json:
        settings_commit = True
        sso_match = flask.request.json['sso_match'] or None

        if sso_match != settings.app.sso_match:
            changes.add('sso')

        if isinstance(sso_match, list):
            settings.app.sso_match = sso_match
        else:
            settings.app.sso_match = None

    if 'sso_token' in flask.request.json:
        settings_commit = True
        sso_token = flask.request.json['sso_token'] or None
        if sso_token != settings.app.sso_token:
            changes.add('sso')
        settings.app.sso_token = sso_token

    if 'sso_secret' in flask.request.json:
        settings_commit = True
        sso_secret = flask.request.json['sso_secret'] or None
        if sso_secret != settings.app.sso_secret:
            changes.add('sso')
        settings.app.sso_secret = sso_secret

    if 'sso_host' in flask.request.json:
        settings_commit = True
        sso_host = flask.request.json['sso_host'] or None
        if sso_host != settings.app.sso_host:
            changes.add('sso')
        settings.app.sso_host = sso_host

    if 'sso_admin' in flask.request.json:
        settings_commit = True
        sso_admin = flask.request.json['sso_admin'] or None
        if sso_admin != settings.app.sso_admin:
            changes.add('sso')
        settings.app.sso_admin = sso_admin

    if 'sso_org' in flask.request.json:
        settings_commit = True
        sso_org = flask.request.json['sso_org']

        if sso_org:
            sso_org = utils.ObjectId(sso_org)
        else:
            sso_org = None

        if sso_org != settings.app.sso_org:
            changes.add('sso')

        settings.app.sso_org = sso_org

    if 'sso_saml_url' in flask.request.json:
        settings_commit = True
        sso_saml_url = flask.request.json['sso_saml_url'] or None
        if sso_saml_url != settings.app.sso_saml_url:
            changes.add('sso')
        settings.app.sso_saml_url = sso_saml_url

    if 'sso_saml_issuer_url' in flask.request.json:
        settings_commit = True
        sso_saml_issuer_url = flask.request.json['sso_saml_issuer_url'] or None
        if sso_saml_issuer_url != settings.app.sso_saml_issuer_url:
            changes.add('sso')
        settings.app.sso_saml_issuer_url = sso_saml_issuer_url

    if 'sso_saml_cert' in flask.request.json:
        settings_commit = True
        sso_saml_cert = flask.request.json['sso_saml_cert'] or None
        if sso_saml_cert != settings.app.sso_saml_cert:
            changes.add('sso')
        settings.app.sso_saml_cert = sso_saml_cert

    if 'sso_okta_token' in flask.request.json:
        settings_commit = True
        sso_okta_token = flask.request.json['sso_okta_token'] or None
        if sso_okta_token != settings.app.sso_okta_token:
            changes.add('sso')
        settings.app.sso_okta_token = sso_okta_token

    if 'sso_onelogin_key' in flask.request.json:
        settings_commit = True
        sso_onelogin_key = flask.request.json['sso_onelogin_key'] or None
        if sso_onelogin_key != settings.app.sso_onelogin_key:
            changes.add('sso')
        settings.app.sso_onelogin_key = sso_onelogin_key

    if 'theme' in flask.request.json:
        settings_commit = True
        theme = 'dark' if flask.request.json['theme'] == 'dark' else 'light'

        if theme != settings.app.theme:
            if theme == 'dark':
                event.Event(type=THEME_DARK)
            else:
                event.Event(type=THEME_LIGHT)

        settings.app.theme = theme

    if 'public_address' in flask.request.json:
        public_address = flask.request.json['public_address']
        settings.local.host.public_address = public_address
        settings.local.host.commit('public_address')

    if 'public_address6' in flask.request.json:
        public_address6 = flask.request.json['public_address6']
        settings.local.host.public_address6 = public_address6
        settings.local.host.commit('public_address6')

    if 'routed_subnet6' in flask.request.json:
        routed_subnet6 = flask.request.json['routed_subnet6']
        if routed_subnet6:
            try:
                routed_subnet6 = ipaddress.IPv6Network(
                    flask.request.json['routed_subnet6'])
            except (ipaddress.AddressValueError, ValueError):
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_INVALID,
                        'error_msg': IPV6_SUBNET_INVALID_MSG,
                    }, 400)

            if routed_subnet6.prefixlen > 64:
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_SIZE_INVALID,
                        'error_msg': IPV6_SUBNET_SIZE_INVALID_MSG,
                    }, 400)

            routed_subnet6 = str(routed_subnet6)
        else:
            routed_subnet6 = None

        if settings.local.host.routed_subnet6 != routed_subnet6:
            if server.get_online_ipv6_count():
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_ONLINE,
                        'error_msg': IPV6_SUBNET_ONLINE_MSG,
                    }, 400)
            settings.local.host.routed_subnet6 = routed_subnet6
            settings.local.host.commit('routed_subnet6')

    if 'server_cert' in flask.request.json:
        settings_commit = True
        server_cert = flask.request.json['server_cert']
        if server_cert:
            settings.app.server_cert = server_cert.strip()
        else:
            settings.app.server_cert = None

    if 'server_key' in flask.request.json:
        settings_commit = True
        server_key = flask.request.json['server_key']
        if server_key:
            settings.app.server_key = server_key.strip()
        else:
            settings.app.server_key = None

    if not settings.app.sso:
        settings.app.sso_match = None
        settings.app.sso_token = None
        settings.app.sso_secret = None
        settings.app.sso_host = None
        settings.app.sso_admin = None
        settings.app.sso_org = None
        settings.app.sso_saml_url = None
        settings.app.sso_saml_issuer_url = None
        settings.app.sso_saml_cert = None
        settings.app.sso_okta_token = None
        settings.app.sso_onelogin_key = None

    for change in changes:
        auth.audit_event(
            'admin_settings',
            _changes_audit_text[change],
            remote_addr=utils.get_remote_addr(),
        )

    if settings_commit:
        settings.commit()

    admin.commit(admin.changed)

    if org_event:
        for org in organization.iter_orgs(fields=('_id')):
            event.Event(type=USERS_UPDATED, resource_id=org.id)

    event.Event(type=SETTINGS_UPDATED)

    response = flask.g.administrator.dict()
    response.update({
        'theme': settings.app.theme,
        'auditing': settings.app.auditing,
        'monitoring': settings.app.monitoring,
        'datadog_api_key': settings.app.datadog_api_key,
        'email_from': settings.app.email_from,
        'email_server': settings.app.email_server,
        'email_username': settings.app.email_username,
        'email_password': bool(settings.app.email_password),
        'pin_mode': settings.user.pin_mode,
        'sso': settings.app.sso,
        'sso_match': settings.app.sso_match,
        'sso_token': settings.app.sso_token,
        'sso_secret': settings.app.sso_secret,
        'sso_host': settings.app.sso_host,
        'sso_admin': settings.app.sso_admin,
        'sso_org': settings.app.sso_org,
        'sso_saml_url': settings.app.sso_saml_url,
        'sso_saml_issuer_url': settings.app.sso_saml_issuer_url,
        'sso_saml_cert': settings.app.sso_saml_cert,
        'sso_okta_token': settings.app.sso_okta_token,
        'sso_onelogin_key': settings.app.sso_onelogin_key,
        'public_address': settings.local.host.public_addr,
    })
    return utils.jsonify(response)
Ejemplo n.º 9
0
def settings_put():
    admin = flask.g.administrator

    if 'username' in flask.request.json and flask.request.json['username']:
        admin.username = utils.filter_str(
            flask.request.json['username']).lower()
    if 'password' in flask.request.json and flask.request.json['password']:
        admin.password = flask.request.json['password']
    if 'token' in flask.request.json and flask.request.json['token']:
        admin.generate_token()
    if 'secret' in flask.request.json and flask.request.json['secret']:
        admin.generate_secret()

    settings_commit = False
    if 'email_from' in flask.request.json:
        settings_commit = True
        email_from = flask.request.json['email_from']
        settings.app.email_from = email_from or None

    if 'email_server' in flask.request.json:
        settings_commit = True
        email_server = flask.request.json['email_server']
        settings.app.email_server = email_server or None

    if 'email_username' in flask.request.json:
        settings_commit = True
        email_username = flask.request.json['email_username']
        settings.app.email_username = email_username or None

    if 'email_password' in flask.request.json:
        settings_commit = True
        email_password = flask.request.json['email_password']
        settings.app.email_password = email_password or None

    if 'sso' in flask.request.json:
        settings_commit = True
        sso = flask.request.json['sso']
        settings.app.sso = sso or None

    if 'sso_match' in flask.request.json:
        sso_match = flask.request.json['sso_match']

        if isinstance(sso_match, list):
            settings_commit = True
            settings.app.sso_match = sso_match or None

    if 'sso_token' in flask.request.json:
        sso_token = flask.request.json['sso_token']
        settings_commit = True
        settings.app.sso_token = sso_token or None

    if 'sso_secret' in flask.request.json:
        sso_secret = flask.request.json['sso_secret']
        settings_commit = True
        settings.app.sso_secret = sso_secret or None

    if 'sso_host' in flask.request.json:
        sso_host = flask.request.json['sso_host']
        settings_commit = True
        settings.app.sso_host = sso_host or None

    if 'sso_admin' in flask.request.json:
        sso_admin = flask.request.json['sso_admin']
        settings_commit = True
        settings.app.sso_admin = sso_admin or None

    if 'sso_org' in flask.request.json:
        settings_commit = True
        sso_org = flask.request.json['sso_org']
        if sso_org:
            settings.app.sso_org = utils.ObjectId(sso_org)
        else:
            settings.app.sso_org = None

    if 'theme' in flask.request.json:
        settings_commit = True
        theme = 'dark' if flask.request.json['theme'] == 'dark' else 'light'

        if theme != settings.app.theme:
            if theme == 'dark':
                event.Event(type=THEME_DARK)
            else:
                event.Event(type=THEME_LIGHT)

        settings.app.theme = theme

    if 'public_address' in flask.request.json:
        public_address = flask.request.json['public_address']
        settings.local.host.public_address = public_address
        settings.local.host.commit('public_address')

    if 'public_address6' in flask.request.json:
        public_address6 = flask.request.json['public_address6']
        settings.local.host.public_address6 = public_address6
        settings.local.host.commit('public_address6')

    if 'routed_subnet6' in flask.request.json:
        routed_subnet6 = flask.request.json['routed_subnet6']
        if routed_subnet6:
            try:
                routed_subnet6 = ipaddress.IPv6Network(
                    flask.request.json['routed_subnet6'])
            except (ipaddress.AddressValueError, ValueError):
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_INVALID,
                        'error_msg': IPV6_SUBNET_INVALID_MSG,
                    }, 400)

            if routed_subnet6.prefixlen > 64:
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_SIZE_INVALID,
                        'error_msg': IPV6_SUBNET_SIZE_INVALID_MSG,
                    }, 400)

            routed_subnet6 = str(routed_subnet6)
        else:
            routed_subnet6 = None

        if settings.local.host.routed_subnet6 != routed_subnet6:
            if server.get_online_ipv6_count():
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_ONLINE,
                        'error_msg': IPV6_SUBNET_ONLINE_MSG,
                    }, 400)
            settings.local.host.routed_subnet6 = routed_subnet6
            settings.local.host.commit('routed_subnet6')

    if 'server_cert' in flask.request.json:
        settings_commit = True
        server_cert = flask.request.json['server_cert']
        if server_cert:
            settings.app.server_cert = server_cert.strip()
        else:
            settings.app.server_cert = None

    if 'server_key' in flask.request.json:
        settings_commit = True
        server_key = flask.request.json['server_key']
        if server_key:
            settings.app.server_key = server_key.strip()
        else:
            settings.app.server_key = None

    if not settings.app.sso:
        settings.app.sso_match = None
        settings.app.sso_token = None
        settings.app.sso_secret = None
        settings.app.sso_host = None
        settings.app.sso_admin = None
        settings.app.sso_org = None

    if settings_commit:
        settings.commit()

    admin.commit(admin.changed)

    response = flask.g.administrator.dict()
    response.update({
        'theme': settings.app.theme,
        'email_from': settings.app.email_from,
        'email_server': settings.app.email_server,
        'email_username': settings.app.email_username,
        'email_password': bool(settings.app.email_password),
        'sso': settings.app.sso,
        'sso_match': settings.app.sso_match,
        'sso_token': settings.app.sso_token,
        'sso_secret': settings.app.sso_secret,
        'sso_host': settings.app.sso_host,
        'sso_admin': settings.app.sso_admin,
        'sso_org': settings.app.sso_org,
        'public_address': settings.local.host.public_addr,
    })
    return utils.jsonify(response)
Ejemplo n.º 10
0
def host_put(hst=None):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    hst = host.get_by_id(hst)

    if 'name' in flask.request.json:
        hst.name = utils.filter_str(
            flask.request.json['name']) or utils.random_name()

    if 'public_address' in flask.request.json:
        public_address = utils.filter_str(flask.request.json['public_address'])
        hst.public_address = public_address

    if 'public_address6' in flask.request.json:
        public_address6 = utils.filter_str(
            flask.request.json['public_address6'])
        hst.public_address6 = public_address6

    if 'routed_subnet6' in flask.request.json:
        routed_subnet6 = flask.request.json['routed_subnet6']
        if routed_subnet6:
            try:
                routed_subnet6 = ipaddress.IPv6Network(
                    flask.request.json['routed_subnet6'])
            except (ipaddress.AddressValueError, ValueError):
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_INVALID,
                        'error_msg': IPV6_SUBNET_INVALID_MSG,
                    }, 400)

            if routed_subnet6.prefixlen > 64:
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_SIZE_INVALID,
                        'error_msg': IPV6_SUBNET_SIZE_INVALID_MSG,
                    }, 400)

            routed_subnet6 = str(routed_subnet6)
        else:
            routed_subnet6 = None

        if hst.routed_subnet6 != routed_subnet6:
            if server.get_online_ipv6_count():
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_ONLINE,
                        'error_msg': IPV6_SUBNET_ONLINE_MSG,
                    }, 400)
            hst.routed_subnet6 = routed_subnet6

    if 'proxy_ndp' in flask.request.json:
        proxy_ndp = True if flask.request.json['proxy_ndp'] else False
        hst.proxy_ndp = proxy_ndp

    if 'local_address' in flask.request.json:
        local_address = utils.filter_str(flask.request.json['local_address'])
        hst.local_address = local_address

    if 'local_address6' in flask.request.json:
        local_address6 = utils.filter_str(flask.request.json['local_address6'])
        hst.local_address6 = local_address6

    if 'link_address' in flask.request.json:
        link_address = utils.filter_str(flask.request.json['link_address'])
        hst.link_address = link_address

    if 'sync_address' in flask.request.json:
        sync_address = utils.filter_str(flask.request.json['sync_address'])
        hst.sync_address = sync_address

    if 'availability_group' in flask.request.json:
        hst.availability_group = utils.filter_str(
            flask.request.json['availability_group']) or DEFAULT

    if 'instance_id' in flask.request.json:
        instance_id = utils.filter_str(flask.request.json['instance_id'])

        if instance_id != hst.aws_id:
            hst.instance_id = instance_id

    hst.commit(hst.changed)
    event.Event(type=HOSTS_UPDATED)
    messenger.publish('hosts', 'updated')

    return utils.jsonify(hst.dict())