Пример #1
0
def link_location_exclude_post(link_id, location_id):
    if not settings.local.sub_plan or \
            'enterprise' not in settings.local.sub_plan:
        return flask.abort(404)

    if settings.app.demo_mode:
        return utils.demo_blocked()

    lnk = link.get_by_id(link_id)
    if not lnk:
        return flask.abort(404)

    loc = lnk.get_location(location_id)
    if not loc:
        return flask.abort(404)

    exclude_id = utils.ObjectId(flask.request.json.get('exclude_id'))
    loc.add_exclude(exclude_id)

    lnk.commit('excludes')

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify({
        'location_id': exclude_id,
    })
Пример #2
0
def link_location_host_delete(link_id, location_id, host_id):
    if not settings.local.sub_plan or \
            'enterprise' not in settings.local.sub_plan:
        return flask.abort(404)

    if settings.app.demo_mode:
        return utils.demo_blocked()

    lnk = link.get_by_id(link_id)
    if not lnk:
        return flask.abort(404)

    loc = lnk.get_location(location_id)
    if not loc:
        return flask.abort(404)

    hst = loc.get_host(host_id)
    if not hst:
        return flask.abort(404)

    hst.remove()

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify({})
Пример #3
0
def server_link_put(server_id, link_server_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    use_local_address = flask.request.json.get('use_local_address', False)

    try:
        server.link_servers(server_id, link_server_id, use_local_address)
    except ServerLinkOnlineError:
        return utils.jsonify({
            'error': SERVER_NOT_OFFLINE,
            'error_msg': SERVER_NOT_OFFLINE_LINK_SERVER_MSG,
        }, 400)
    except ServerLinkCommonHostError:
        return utils.jsonify({
            'error': SERVER_LINK_COMMON_HOST,
            'error_msg': SERVER_LINK_COMMON_HOST_MSG,
        }, 400)
    except ServerLinkCommonRouteError:
        return utils.jsonify({
            'error': SERVER_LINK_COMMON_ROUTE,
            'error_msg': SERVER_LINK_COMMON_ROUTE_MSG,
        }, 400)
    except ServerLinkReplicaError:
        return utils.jsonify({
            'error': SERVER_LINKS_AND_REPLICA,
            'error_msg': SERVER_LINKS_AND_REPLICA_MSG,
        }, 400)

    event.Event(type=SERVER_LINKS_UPDATED, resource_id=server_id)
    event.Event(type=SERVER_LINKS_UPDATED, resource_id=link_server_id)
    event.Event(type=SERVER_ROUTES_UPDATED, resource_id=server_id)
    event.Event(type=SERVER_ROUTES_UPDATED, resource_id=link_server_id)

    return utils.jsonify({})
Пример #4
0
def link_location_route_post(link_id, location_id):
    if not settings.local.sub_plan or \
            'enterprise' not in settings.local.sub_plan:
        return flask.abort(404)

    if settings.app.demo_mode:
        return utils.demo_blocked()

    lnk = link.get_by_id(link_id)
    if not lnk:
        return flask.abort(404)

    loc = lnk.get_location(location_id)
    if not loc:
        return flask.abort(404)

    try:
        network = loc.add_route(flask.request.json.get('network'))
    except NetworkInvalid:
        return utils.jsonify({
            'error': LINK_NETWORK_INVALID,
            'error_msg': LINK_NETWORK_INVALID_MSG,
        }, 400)

    loc.commit('routes')

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify({
        'id': network,
    })
Пример #5
0
def server_operation_put(server_id, operation):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    svr = server.get_by_id(server_id, fields=server.operation_fields)

    try:
        if operation == START:
            svr.start()
            logger.LogEntry(message='Started server "%s".' % svr.name)
        if operation == STOP:
            svr.stop()
            logger.LogEntry(message='Stopped server "%s".' % svr.name)
        elif operation == RESTART:
            svr.restart()
            logger.LogEntry(message='Restarted server "%s".' % svr.name)
    except:
        event.Event(type=SERVERS_UPDATED)
        raise

    event.Event(type=SERVERS_UPDATED)
    event.Event(type=SERVER_HOSTS_UPDATED, resource_id=svr.id)
    for org in svr.iter_orgs():
        event.Event(type=USERS_UPDATED, resource_id=org.id)
    svr.send_link_events()

    return utils.jsonify(svr.dict())
Пример #6
0
def link_location_host_put(link_id, location_id, host_id):
    if not settings.local.sub_plan or \
            'enterprise' not in settings.local.sub_plan:
        return flask.abort(404)

    if settings.app.demo_mode:
        return utils.demo_blocked()

    lnk = link.get_by_id(link_id)
    if not lnk:
        return flask.abort(404)

    loc = lnk.get_location(location_id)
    if not loc:
        return flask.abort(404)

    hst = loc.get_host(host_id)
    if not hst:
        return flask.abort(404)

    hst.name = utils.filter_str(flask.request.json.get('name')) or 'undefined'
    hst.timeout = abs(int(flask.request.json.get('timeout') or 0)) or None
    hst.priority = abs(int(flask.request.json.get('priority') or 1)) or 1

    hst.commit(('name', 'timeout', 'priority'))

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify(hst.dict())
Пример #7
0
def server_route_delete(server_id, route_network):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    svr = server.get_by_id(server_id, fields=('_id', 'network', 'links',
        'network_start', 'network_end', 'routes', 'organizations', 'status',
        'ipv6'))
    route_network = route_network.decode('hex')

    try:
        route = svr.remove_route(route_network)
    except ServerOnlineError:
        return utils.jsonify({
            'error': SERVER_ROUTE_ONLINE,
            'error_msg': SERVER_ROUTE_ONLINE_MSG,
        }, 400)

    svr.commit('routes')

    event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr.id)
    for svr_link in svr.links:
        event.Event(type=SERVER_ROUTES_UPDATED,
            resource_id=svr_link['server_id'])

    return utils.jsonify(route)
Пример #8
0
def server_host_put(server_id, host_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    svr = server.get_by_id(server_id, fields=('_id', 'hosts', 'links'))
    hst = host.get_by_id(host_id, fields=('_id', 'name',
        'public_address', 'auto_public_address'))

    try:
        svr.add_host(hst.id)
    except ServerLinkCommonHostError:
        return utils.jsonify({
            'error': SERVER_LINK_COMMON_HOST,
            'error_msg': SERVER_LINK_COMMON_HOST_MSG,
        }, 400)

    svr.commit('hosts')
    event.Event(type=SERVER_HOSTS_UPDATED, resource_id=svr.id)

    return utils.jsonify({
        'id': hst.id,
        'server': svr.id,
        'status': OFFLINE,
        'name': hst.name,
        'address': hst.public_addr,
    })
Пример #9
0
def user_post(org_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    remote_addr = utils.get_remote_addr()

    if isinstance(flask.request.json, list):
        users_data = flask.request.json
    else:
        users_data = [flask.request.json]

    if len(users_data) > 10:
        if _users_background:
            return utils.jsonify({
                'error': USERS_BACKGROUND_BUSY,
                'error_msg': USERS_BACKGROUND_BUSY_MSG,
            }, 429)

        thread = threading.Thread(
            target=_create_users,
            args=(org_id, users_data, remote_addr, True),
        )
        thread.daemon = True
        thread.start()

        return utils.jsonify({
            'status': USERS_BACKGROUND,
            'status_msg': USERS_BACKGROUND_MSG,
        }, 202)

    return _create_users(org_id, users_data, remote_addr, False)
Пример #10
0
def link_put(link_id):
    if not settings.local.sub_plan or \
            'enterprise' not in settings.local.sub_plan:
        return flask.abort(404)

    if settings.app.demo_mode:
        return utils.demo_blocked()

    lnk = link.get_by_id(link_id)
    if not lnk:
        return flask.abort(404)

    lnk.name = utils.filter_str(flask.request.json.get('name')) or 'undefined'

    status = flask.request.json.get('status')
    if status in (ONLINE, OFFLINE):
        if status == ONLINE and lnk.status != ONLINE:
            lnk.generate_key()

        lnk.status = status

    lnk.commit(('name', 'status', 'key'))

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify(lnk.dict())
Пример #11
0
def server_org_delete(server_id, org_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    svr = server.get_by_id(server_id,
        fields=('_id', 'status', 'network', 'network_start',
            'network_end', 'primary_organization',
            'primary_user', 'organizations', 'routes', 'ipv6'))
    org = organization.get_by_id(org_id, fields=('_id'))

    if svr.status == ONLINE:
        return utils.jsonify({
            'error': SERVER_NOT_OFFLINE,
            'error_msg': SERVER_NOT_OFFLINE_DETACH_ORG_MSG,
        }, 400)

    svr.remove_org(org)
    svr.commit(svr.changed)

    event.Event(type=SERVERS_UPDATED)
    event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr.id)
    event.Event(type=SERVER_ORGS_UPDATED, resource_id=svr.id)
    event.Event(type=USERS_UPDATED, resource_id=org.id)

    return utils.jsonify({})
Пример #12
0
def admin_delete(admin_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    if not flask.g.administrator.super_user:
        return utils.jsonify({
            'error': REQUIRES_SUPER_USER,
            'error_msg': REQUIRES_SUPER_USER_MSG,
        }, 400)

    admin = auth.get_by_id(admin_id)
    remote_addr = utils.get_remote_addr()

    if admin.super_user and auth.super_user_count() < 2:
        return utils.jsonify({
            'error': NO_ADMINS,
            'error_msg': NO_ADMINS_MSG,
        }, 400)

    journal.entry(
        journal.ADMIN_DELETE,
        admin.journal_data,
        event_long='Administrator deleted',
        remote_addr=remote_addr,
    )

    admin.remove()
    event.Event(type=ADMINS_UPDATED)

    return utils.jsonify({})
Пример #13
0
def server_route_delete(server_id, route_network):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    svr = server.get_by_id(server_id)
    route_network = route_network.decode('hex')

    try:
        route = svr.remove_route(route_network)
    except ServerOnlineError:
        return utils.jsonify({
            'error': SERVER_ROUTE_ONLINE,
            'error_msg': SERVER_ROUTE_ONLINE_MSG,
        }, 400)

    err, err_msg = svr.validate_conf()
    if err:
        return utils.jsonify({
            'error': err,
            'error_msg': err_msg,
        }, 400)

    svr.commit('routes')

    event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr.id)
    for svr_link in svr.links:
        event.Event(type=SERVER_ROUTES_UPDATED,
            resource_id=svr_link['server_id'])

    return utils.jsonify(route)
Пример #14
0
def admin_post():
    if settings.app.demo_mode:
        return utils.demo_blocked()

    if not flask.g.administrator.super_user:
        return utils.jsonify({"error": REQUIRES_SUPER_USER, "error_msg": REQUIRES_SUPER_USER_MSG}, 400)

    username = utils.filter_str(flask.request.json["username"])
    password = flask.request.json["password"]
    otp_auth = flask.request.json.get("otp_auth", False)
    auth_api = flask.request.json.get("auth_api", False)
    disabled = flask.request.json.get("disabled", False)
    super_user = flask.request.json.get("super_user", False)

    try:
        admin = auth.new_admin(
            username=username,
            password=password,
            default=True,
            otp_auth=otp_auth,
            auth_api=auth_api,
            disabled=disabled,
            super_user=super_user,
        )
    except pymongo.errors.DuplicateKeyError:
        return utils.jsonify({"error": ADMIN_USERNAME_EXISTS, "error_msg": ADMIN_USERNAME_EXISTS_MSG}, 400)

    admin.audit_event("admin_created", "Administrator created", remote_addr=utils.get_remote_addr())

    event.Event(type=ADMINS_UPDATED)

    return utils.jsonify(admin.dict())
Пример #15
0
def org_put(org_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    org = organization.get_by_id(org_id)

    org.name = utils.filter_str(flask.request.json['name'])

    auth_api = flask.request.json.get('auth_api', False)
    if auth_api:
        org.auth_api = True
        if not org.auth_token:
            org.generate_auth_token()
        if not org.auth_secret:
            org.generate_auth_secret()
    else:
        org.auth_api = False
        org.auth_token = None
        org.auth_secret = None

    if flask.request.json.get('auth_token') == True:
        org.generate_auth_token()

    if flask.request.json.get('auth_secret') == True:
        org.generate_auth_secret()

    org.commit()
    event.Event(type=ORGS_UPDATED)
    return utils.jsonify(org.dict())
Пример #16
0
def subscription_post():
    if settings.app.demo_mode:
        return utils.demo_blocked()

    license = flask.request.json['license']
    license = license.lower().replace('begin license', '').replace(
        'end license', '')
    license = re.sub(r'[\W_]+', '', license)

    try:
        response = requests.get(
            'https://app.pritunl.com/subscription',
            json={
                'license': license,
                'version': settings.local.version_int,
            },
        )
    except httplib.HTTPException:
        return utils.jsonify({
            'error': SUBSCRIPTION_SERVER_ERROR,
            'error_msg': SUBSCRIPTION_SERVER_ERROR_MSG,
        }, 500)
    data = response.json()

    if response.status_code != 200:
        return utils.jsonify(data, response.status_code)

    try:
        subscription.update_license(license)
    except LicenseInvalid:
        return utils.jsonify({
            'error': LICENSE_INVALID,
            'error_msg': LICENSE_INVALID_MSG,
        }, 500)
    return utils.jsonify(subscription.dict())
Пример #17
0
def user_key_pin_put(key_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    doc = _find_doc({"key_id": key_id})
    if not doc:
        return flask.abort(404)

    if settings.app.demo_mode:
        return utils.demo_blocked()

    if settings.user.pin_mode == PIN_DISABLED:
        return utils.jsonify({"error": PIN_IS_DISABLED, "error_msg": PIN_IS_DISABLED_MSG}, 400)

    org = organization.get_by_id(doc["org_id"])
    usr = org.get_user(doc["user_id"])
    if usr.disabled:
        return flask.abort(403)

    if RADIUS_AUTH in usr.auth_type:
        return utils.jsonify({"error": PIN_RADIUS, "error_msg": PIN_RADIUS_MSG}, 400)

    current_pin = utils.filter_str(flask.request.json.get("current_pin")) or None
    pin = utils.filter_str(flask.request.json.get("pin")) or None

    if pin:
        if not pin.isdigit():
            return utils.jsonify({"error": PIN_NOT_DIGITS, "error_msg": PIN_NOT_DIGITS_MSG}, 400)

        if len(pin) < settings.user.pin_min_length:
            return utils.jsonify({"error": PIN_TOO_SHORT, "error_msg": PIN_TOO_SHORT_MSG}, 400)

    if usr.pin and not usr.check_pin(current_pin):
        return utils.jsonify({"error": PIN_INVALID, "error_msg": PIN_INVALID_MSG}, 400)

    if usr.set_pin(pin):
        usr.audit_event(
            "user_updated", "User pin changed with temporary profile link", remote_addr=utils.get_remote_addr()
        )

    usr.commit()

    event.Event(type=USERS_UPDATED, resource_id=org.id)

    return utils.jsonify({})
Пример #18
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())
Пример #19
0
def server_route_put(server_id, route_network):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    svr = server.get_by_id(server_id)
    route_network = route_network.decode('hex')
    comment = flask.request.json.get('comment') or None
    nat_route = True if flask.request.json.get('nat') else False
    nat_interface = flask.request.json.get('nat_interface') or None
    vpc_region = utils.filter_str(flask.request.json.get('vpc_region')) or None
    vpc_id = utils.filter_str(flask.request.json.get('vpc_id')) or None
    net_gateway = True if flask.request.json.get('net_gateway') else False

    try:
        route = svr.upsert_route(route_network, nat_route, nat_interface,
            vpc_region, vpc_id, net_gateway, comment)
    except ServerOnlineError:
        return utils.jsonify({
            'error': SERVER_ROUTE_ONLINE,
            'error_msg': SERVER_ROUTE_ONLINE_MSG,
        }, 400)
    except NetworkInvalid:
        return utils.jsonify({
            'error': SERVER_ROUTE_INVALID,
            'error_msg': SERVER_ROUTE_INVALID_MSG,
        }, 400)
    except ServerRouteNatVirtual:
        return utils.jsonify({
            'error': SERVER_ROUTE_VIRTUAL_NAT,
            'error_msg': SERVER_ROUTE_VIRTUAL_NAT_MSG,
        }, 400)
    except ServerRouteNatServerLink:
        return utils.jsonify({
            'error': SERVER_ROUTE_SERVER_LINK_NAT,
            'error_msg': SERVER_ROUTE_SERVER_LINK_NAT_MSG,
        }, 400)
    except ServerRouteNatNetworkLink:
        return utils.jsonify({
            'error': SERVER_ROUTE_NETWORK_LINK_NAT,
            'error_msg': SERVER_ROUTE_NETWORK_LINK_NAT_MSG,
        }, 400)

    err, err_msg = svr.validate_conf()
    if err:
        return utils.jsonify({
            'error': err,
            'error_msg': err_msg,
        }, 400)

    svr.commit('routes')

    event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr.id)
    for svr_link in svr.links:
        event.Event(type=SERVER_ROUTES_UPDATED,
            resource_id=svr_link['server_id'])

    return utils.jsonify(route)
Пример #20
0
def user_key_pin_put(key_id):
    doc = _find_doc({
        'key_id': key_id,
    })
    if not doc:
        return flask.abort(404)

    if settings.app.demo_mode:
        return utils.demo_blocked()

    org = organization.get_by_id(doc['org_id'])
    usr = org.get_user(doc['user_id'])
    if usr.disabled:
        return flask.abort(403)

    if RADIUS_AUTH in usr.auth_type:
        return utils.jsonify({
            'error': PIN_RADIUS,
            'error_msg': PIN_RADIUS_MSG,
        }, 400)

    current_pin = utils.filter_str(
        flask.request.json.get('current_pin')) or None
    pin = utils.filter_str(flask.request.json.get('pin')) or None

    if pin:
        if not pin.isdigit():
            return utils.jsonify({
                'error': PIN_NOT_DIGITS,
                'error_msg': PIN_NOT_DIGITS_MSG,
            }, 400)

        if len(pin) < settings.user.pin_min_length:
            return utils.jsonify({
                'error': PIN_TOO_SHORT,
                'error_msg': PIN_TOO_SHORT_MSG,
            }, 400)

    if usr.pin and not usr.check_pin(current_pin):
        return utils.jsonify({
            'error': PIN_INVALID,
            'error_msg': PIN_INVALID_MSG,
        }, 400)

    if usr.set_pin(pin):
        usr.audit_event('user_updated',
            'User pin changed with temporary profile link',
            remote_addr=utils.get_remote_addr(),
        )

    usr.commit()

    event.Event(type=USERS_UPDATED, resource_id=org.id)

    return utils.jsonify({})
Пример #21
0
def user_post(org_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    org = organization.get_by_id(org_id)
    users = []

    if isinstance(flask.request.json, list):
        users_data = flask.request.json
    else:
        users_data = [flask.request.json]

    try:
        for user_data in users_data:
            name = utils.filter_str(user_data['name'])
            email = utils.filter_str(user_data.get('email'))
            disabled = user_data.get('disabled')
            network_links = user_data.get('network_links')
            bypass_secondary = user_data.get('bypass_secondary')
            dns_servers = user_data.get('dns_servers') or None
            dns_suffix = utils.filter_str(user_data.get('dns_suffix')) or None

            user = org.new_user(type=CERT_CLIENT, name=name, email=email,
                disabled=disabled, bypass_secondary=bypass_secondary,
                dns_servers=dns_servers, dns_suffix=dns_suffix)
            user.audit_event('user_created',
                'User created from web console',
                remote_addr=utils.get_remote_addr(),
            )

            if network_links:
                for network_link in network_links:
                    try:
                        user.add_network_link(network_link)
                    except (ipaddress.AddressValueError, ValueError):
                        return _network_link_invalid()
                    except ServerOnlineError:
                        return utils.jsonify({
                            'error': NETWORK_LINK_NOT_OFFLINE,
                            'error_msg': NETWORK_LINK_NOT_OFFLINE_MSG,
                        }, 400)

            users.append(user.dict())
    finally:
        event.Event(type=ORGS_UPDATED)
        event.Event(type=USERS_UPDATED, resource_id=org.id)
        event.Event(type=SERVERS_UPDATED)

    if isinstance(flask.request.json, list):
        logger.LogEntry(message='Created %s new users.' % len(
            flask.request.json))
        return utils.jsonify(users)
    else:
        logger.LogEntry(message='Created new user "%s".' % users[0]['name'])
        return utils.jsonify(users[0])
Пример #22
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 "local_address" in flask.request.json:
        hst.local_address = utils.filter_str(flask.request.json["local_address"])

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

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

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

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

    return utils.jsonify(hst.dict())
Пример #23
0
def link_state_delete():
    if settings.app.demo_mode:
        return utils.demo_blocked()

    auth_token = flask.request.headers.get('Auth-Token', None)
    auth_timestamp = flask.request.headers.get('Auth-Timestamp', None)
    auth_nonce = flask.request.headers.get('Auth-Nonce', None)
    auth_signature = flask.request.headers.get('Auth-Signature', None)
    if not auth_token or not auth_timestamp or not auth_nonce or \
        not auth_signature:
        return flask.abort(401)
    auth_nonce = auth_nonce[:32]

    try:
        if abs(int(auth_timestamp) - int(utils.time_now())) > \
            settings.app.auth_time_window:
            return flask.abort(401)
    except ValueError:
        return flask.abort(401)

    host = link.get_host(utils.ObjectId(auth_token))
    if not host:
        return flask.abort(401)

    auth_string = '&'.join([
        auth_token,
        auth_timestamp,
        auth_nonce,
        flask.request.method,
        flask.request.path,
    ])

    if len(auth_string) > AUTH_SIG_STRING_MAX_LEN:
        return flask.abort(401)

    auth_test_signature = base64.b64encode(hmac.new(
        host.secret.encode(), auth_string,
        hashlib.sha512).digest())
    if not utils.const_compare(auth_signature, auth_test_signature):
        return flask.abort(401)

    nonces_collection = mongo.get_collection('auth_nonces')
    try:
        nonces_collection.insert({
            'token': auth_token,
            'nonce': auth_nonce,
            'timestamp': utils.now(),
        })
    except pymongo.errors.DuplicateKeyError:
        return flask.abort(401)

    host.set_inactive()

    return utils.jsonify({})
Пример #24
0
def server_delete(server_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    svr = server.get_by_id(server_id, fields=('_id', 'name', 'organizations'))
    svr.remove()
    logger.LogEntry(message='Deleted server "%s".' % svr.name)
    event.Event(type=SERVERS_UPDATED)
    for org in svr.iter_orgs():
        event.Event(type=USERS_UPDATED, resource_id=org.id)
    return utils.jsonify({})
Пример #25
0
def host_delete(hst):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    hst = host.get_by_id(hst)
    hst.remove()

    logger.LogEntry(message='Deleted host "%s".' % hst.name)
    event.Event(type=HOSTS_UPDATED)

    return utils.jsonify({})
Пример #26
0
def admin_post():
    if settings.app.demo_mode:
        return utils.demo_blocked()

    if not flask.g.administrator.super_user:
        return utils.jsonify({
            'error': REQUIRES_SUPER_USER,
            'error_msg': REQUIRES_SUPER_USER_MSG,
        }, 400)

    username = utils.filter_str(flask.request.json['username']).lower()
    password = flask.request.json['password']
    yubikey_id = flask.request.json.get('yubikey_id') or None
    yubikey_id = yubikey_id[:12] if yubikey_id else None
    otp_auth = flask.request.json.get('otp_auth', False)
    auth_api = flask.request.json.get('auth_api', False)
    disabled = flask.request.json.get('disabled', False)
    super_user = flask.request.json.get('super_user', False)
    remote_addr = utils.get_remote_addr()

    try:
        admin = auth.new_admin(
            username=username,
            password=password,
            yubikey_id=yubikey_id,
            default=True,
            otp_auth=otp_auth,
            auth_api=auth_api,
            disabled=disabled,
            super_user=super_user,
        )
    except pymongo.errors.DuplicateKeyError:
        return utils.jsonify({
            'error': ADMIN_USERNAME_EXISTS,
            'error_msg': ADMIN_USERNAME_EXISTS_MSG,
        }, 400)

    admin.audit_event('admin_created',
        'Administrator created',
        remote_addr=remote_addr,
    )

    journal.entry(
        journal.ADMIN_CREATE,
        admin.journal_data,
        event_long='Administrator created',
        remote_addr=remote_addr,
    )

    event.Event(type=ADMINS_UPDATED)

    return utils.jsonify(admin.dict())
Пример #27
0
def server_route_post(server_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    svr = server.get_by_id(server_id, fields=('_id', 'network', 'links',
        'network_start', 'network_end', 'routes', 'organizations', 'status',
        'ipv6'))
    route_network = flask.request.json['network']
    nat_route = True if flask.request.json.get('nat') else False
    nat_interface = flask.request.json.get('nat_interface') or None
    vpc_region = utils.filter_str(flask.request.json.get('vpc_region')) or None
    vpc_id = utils.filter_str(flask.request.json.get('vpc_id')) or None

    try:
        route = svr.upsert_route(route_network, nat_route, nat_interface,
            vpc_region, vpc_id)
    except ServerOnlineError:
        return utils.jsonify({
            'error': SERVER_ROUTE_ONLINE,
            'error_msg': SERVER_ROUTE_ONLINE_MSG,
        }, 400)
    except NetworkInvalid:
        return utils.jsonify({
            'error': SERVER_ROUTE_INVALID,
            'error_msg': SERVER_ROUTE_INVALID_MSG,
        }, 400)
    except ServerRouteNatVirtual:
        return utils.jsonify({
            'error': SERVER_ROUTE_VIRTUAL_NAT,
            'error_msg': SERVER_ROUTE_VIRTUAL_NAT_MSG,
        }, 400)
    except ServerRouteNatServerLink:
        return utils.jsonify({
            'error': SERVER_ROUTE_SERVER_LINK_NAT,
            'error_msg': SERVER_ROUTE_SERVER_LINK_NAT_MSG,
        }, 400)
    except ServerRouteNatNetworkLink:
        return utils.jsonify({
            'error': SERVER_ROUTE_NETWORK_LINK_NAT,
            'error_msg': SERVER_ROUTE_NETWORK_LINK_NAT_MSG,
        }, 400)

    svr.commit('routes')

    event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr.id)
    for svr_link in svr.links:
        event.Event(type=SERVER_ROUTES_UPDATED,
            resource_id=svr_link['server_id'])

    return utils.jsonify(route)
Пример #28
0
def server_host_delete(server_id, host_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    svr = server.get_by_id(server_id, fields=('_id', 'hosts', 'replica_count'))
    hst = host.get_by_id(host_id, fields=('_id', 'name'))

    svr.remove_host(hst.id)
    svr.commit('hosts')

    event.Event(type=SERVERS_UPDATED)
    event.Event(type=SERVER_HOSTS_UPDATED, resource_id=svr.id)

    return utils.jsonify({})
Пример #29
0
def server_link_delete(server_id, link_server_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    try:
        server.unlink_servers(server_id, link_server_id)
    except ServerLinkOnlineError:
        return utils.jsonify({
            'error': SERVER_NOT_OFFLINE,
            'error_msg': SERVER_NOT_OFFLINE_UNLINK_SERVER_MSG,
        }, 400)

    event.Event(type=SERVER_LINKS_UPDATED, resource_id=server_id)
    event.Event(type=SERVER_LINKS_UPDATED, resource_id=link_server_id)

    return utils.jsonify({})
Пример #30
0
def user_otp_secret_put(org_id, user_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    org = organization.get_by_id(org_id)
    user = org.get_user(user_id)

    user.audit_event('user_updated',
        'User two step secret reset',
        remote_addr=utils.get_remote_addr(),
    )

    user.generate_otp_secret()
    user.commit()
    event.Event(type=USERS_UPDATED, resource_id=org.id)
    return utils.jsonify(user.dict())
Пример #31
0
def link_state_put():
    if settings.app.demo_mode:
        return utils.demo_blocked()

    auth_token = flask.request.headers.get('Auth-Token', None)
    auth_timestamp = flask.request.headers.get('Auth-Timestamp', None)
    auth_nonce = flask.request.headers.get('Auth-Nonce', None)
    auth_signature = flask.request.headers.get('Auth-Signature', None)
    if not auth_token or not auth_timestamp or not auth_nonce or \
            not auth_signature:
        return flask.abort(401)
    auth_nonce = auth_nonce[:32]

    try:
        if abs(int(auth_timestamp) - int(utils.time_now())) > \
                settings.app.auth_time_window:
            return flask.abort(401)
    except ValueError:
        return flask.abort(401)

    host = link.get_host(utils.ObjectId(auth_token))
    if not host:
        return flask.abort(401)

    auth_string = '&'.join([
        auth_token,
        auth_timestamp,
        auth_nonce,
        flask.request.method,
        flask.request.path,
    ])

    if len(auth_string) > AUTH_SIG_STRING_MAX_LEN:
        return flask.abort(401)

    auth_test_signature = base64.b64encode(
        hmac.new(host.secret.encode(), auth_string, hashlib.sha512).digest())
    if not utils.const_compare(auth_signature, auth_test_signature):
        return flask.abort(401)

    nonces_collection = mongo.get_collection('auth_nonces')
    try:
        nonces_collection.insert({
            'token': auth_token,
            'nonce': auth_nonce,
            'timestamp': utils.now(),
        })
    except pymongo.errors.DuplicateKeyError:
        return flask.abort(401)

    host.load_link()

    host.version = flask.request.json.get('version')
    host.public_address = flask.request.json.get('public_address')

    data = json.dumps(host.get_state(), default=lambda x: str(x))
    data += (16 - len(data) % 16) * '\x00'

    iv = Crypto.Random.new().read(16)
    key = hashlib.sha256(host.secret).digest()
    cipher = Crypto.Cipher.AES.new(
        key,
        Crypto.Cipher.AES.MODE_CBC,
        iv,
    )

    enc_data = base64.b64encode(cipher.encrypt(data))
    enc_signature = base64.b64encode(
        hmac.new(host.secret.encode(), enc_data, hashlib.sha512).digest())

    resp = flask.Response(response=enc_data, mimetype='application/base64')
    resp.headers.add('Cache-Control', 'no-cache, no-store, must-revalidate')
    resp.headers.add('Pragma', 'no-cache')
    resp.headers.add('Expires', 0)
    resp.headers.add('Cipher-IV', base64.b64encode(iv))
    resp.headers.add('Cipher-Signature', enc_signature)

    return resp
Пример #32
0
def user_put(org_id, user_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    org = organization.get_by_id(org_id)
    user = org.get_user(user_id)
    reset_user = False

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

        if name != user.name:
            user.audit_event('user_updated',
                'User name changed',
                remote_addr=utils.get_remote_addr(),
            )

        user.name = name

    if 'email' in flask.request.json:
        email = utils.filter_str(flask.request.json['email']) or None

        if email != user.email:
            user.audit_event('user_updated',
                'User email changed',
                remote_addr=utils.get_remote_addr(),
            )

        user.email = email

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

        if pin != True:
            if pin:
                if not pin.isdigit():
                    return utils.jsonify({
                        'error': PIN_NOT_DIGITS,
                        'error_msg': PIN_NOT_DIGITS_MSG,
                    }, 400)

                if len(pin) < settings.user.pin_min_length:
                    return utils.jsonify({
                        'error': PIN_TOO_SHORT,
                        'error_msg': PIN_TOO_SHORT_MSG,
                    }, 400)

            user.audit_event('user_updated',
                'User pin changed',
                remote_addr=utils.get_remote_addr(),
            )

            user.set_pin(pin)

    if 'network_links' in flask.request.json:
        network_links_cur = set(user.get_network_links())
        network_links_new = set()

        for network_link in flask.request.json['network_links']:
            try:
                network_link = str(ipaddress.IPNetwork(network_link))
            except (ipaddress.AddressValueError, ValueError):
                return _network_link_invalid()
            network_links_new.add(network_link)

        network_links_add = network_links_new - network_links_cur
        network_links_rem = network_links_cur - network_links_new

        if len(network_links_add) or len(network_links_rem):
            reset_user = True
            user.audit_event('user_updated',
                'User network links updated',
                remote_addr=utils.get_remote_addr(),
            )

        try:
            for network_link in network_links_add:
                user.add_network_link(network_link)
        except ServerOnlineError:
            return utils.jsonify({
                'error': NETWORK_LINK_NOT_OFFLINE,
                'error_msg': NETWORK_LINK_NOT_OFFLINE_MSG,
            }, 400)

        for network_link in network_links_rem:
            user.remove_network_link(network_link)

    disabled = flask.request.json.get('disabled')
    if disabled is not None:
        if disabled != user.disabled:
            user.audit_event('user_updated',
                'User %s' % ('disabled' if disabled else 'enabled'),
                remote_addr=utils.get_remote_addr(),
            )

        user.disabled = disabled

    bypass_secondary = flask.request.json.get('bypass_secondary')
    if bypass_secondary is not None:
        user.bypass_secondary = bypass_secondary

    if 'dns_servers' in flask.request.json:
        dns_servers = flask.request.json['dns_servers'] or None
        if user.dns_servers != dns_servers:
            user.audit_event('user_updated',
                'User dns servers changed',
                remote_addr=utils.get_remote_addr(),
            )
            reset_user = True
        user.dns_servers = dns_servers

    if 'dns_suffix' in flask.request.json:
        dns_suffix = utils.filter_str(
            flask.request.json['dns_suffix']) or None
        if user.dns_suffix != dns_suffix:
            user.audit_event('user_updated',
                'User dns suffix changed',
                remote_addr=utils.get_remote_addr(),
            )
            reset_user = True
        user.dns_suffix = dns_suffix

    user.commit()
    event.Event(type=USERS_UPDATED, resource_id=user.org.id)

    if reset_user or disabled:
        user.disconnect()

    if disabled:
        if user.type == CERT_CLIENT:
            logger.LogEntry(message='Disabled user "%s".' % user.name)
    elif disabled == False and user.type == CERT_CLIENT:
        logger.LogEntry(message='Enabled user "%s".' % user.name)

    send_key_email = flask.request.json.get('send_key_email')
    if send_key_email and user.email:
        user.audit_event('user_emailed',
            'User key email sent to "%s"' % user.email,
            remote_addr=utils.get_remote_addr(),
        )

        try:
            user.send_key_email(flask.request.url_root[:-1])
        except EmailNotConfiguredError:
            return utils.jsonify({
                'error': EMAIL_NOT_CONFIGURED,
                'error_msg': EMAIL_NOT_CONFIGURED_MSG,
            }, 400)
        except EmailFromInvalid:
            return utils.jsonify({
                'error': EMAIL_FROM_INVALID,
                'error_msg': EMAIL_FROM_INVALID_MSG,
            }, 400)
        except EmailAuthInvalid:
            return utils.jsonify({
                'error': EMAIL_AUTH_INVALID,
                'error_msg': EMAIL_AUTH_INVALID_MSG,
            }, 400)

    return utils.jsonify(user.dict())
Пример #33
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 'local_address' in flask.request.json:
        hst.local_address = utils.filter_str(
            flask.request.json['local_address'])

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

    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())
Пример #34
0
def link_post():
    if not settings.local.sub_plan or \
            'enterprise' not in settings.local.sub_plan:
        return flask.abort(404)

    if settings.app.demo_mode:
        return utils.demo_blocked()

    name = utils.filter_str(flask.request.json.get('name')) or 'undefined'
    type = DIRECT if flask.request.json.get('type') == DIRECT \
        else SITE_TO_SITE
    ipv6 = True if flask.request.json.get('ipv6') else False
    host_check = True if flask.request.json.get('host_check') else False
    action = RESTART if flask.request.json.get('action') == RESTART else HOLD
    preferred_ike = utils.filter_str2(
        flask.request.json.get('preferred_ike')) or None
    preferred_esp = utils.filter_str2(
        flask.request.json.get('preferred_esp')) or None
    force_preferred = True if flask.request.json.get(
        'force_preferred') else False

    lnk = link.Link(
        name=name,
        type=type,
        status=ONLINE,
        ipv6=ipv6,
        host_check=host_check,
        action=action,
        preferred_ike=preferred_ike,
        preferred_esp=preferred_esp,
        force_preferred=force_preferred,
    )

    lnk.generate_key()

    lnk.commit()

    if lnk.type == DIRECT:
        try:
            loc = link.Location(
                link=lnk,
                name='server',
                type=DIRECT_SERVER,
                link_id=lnk.id,
            )
            loc.commit()

            loc = link.Location(
                link=lnk,
                name='client',
                type=DIRECT_CLIENT,
                link_id=lnk.id,
            )
            loc.commit()
        except:
            lnk.remove()
            raise

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify(lnk.dict())
Пример #35
0
def subscription_delete():
    if settings.app.demo_mode:
        return utils.demo_blocked()

    subscription.update_license(None)
    return utils.jsonify({})
Пример #36
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 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 == ALL and auditing != ALL:
            return utils.jsonify(
                {
                    'error': CANNOT_DISABLE_AUTIDING,
                    'error_msg': CANNOT_DISABLE_AUTIDING_MSG,
                }, 400)

        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_url' in flask.request.json:
        settings_commit = True
        influxdb_url = flask.request.json['influxdb_url'] or None
        settings.app.influxdb_url = influxdb_url

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

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

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

    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_azure_directory_id' in flask.request.json:
        settings_commit = True
        sso_azure_directory_id = flask.request.json[
            'sso_azure_directory_id'] or None
        if sso_azure_directory_id != settings.app.sso_azure_directory_id:
            changes.add('sso')
        settings.app.sso_azure_directory_id = sso_azure_directory_id

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

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

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

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

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

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

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

    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_app_id' in flask.request.json:
        settings_commit = True
        sso_okta_app_id = flask.request.json['sso_okta_app_id'] or None
        if sso_okta_app_id != settings.app.sso_okta_app_id:
            changes.add('sso')
        settings.app.sso_okta_app_id = sso_okta_app_id

    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_okta_mode' in flask.request.json:
        sso_mode = settings.app.sso
        if sso_mode and sso_mode == SAML_OKTA_AUTH:
            settings_commit = True
            sso_okta_mode = flask.request.json['sso_okta_mode']
            settings.app.sso_okta_mode = sso_okta_mode

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

    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_onelogin_mode' in flask.request.json:
        sso_mode = settings.app.sso
        if sso_mode and sso_mode == SAML_ONELOGIN_AUTH:
            settings_commit = True
            sso_onelogin_mode = flask.request.json['sso_onelogin_mode']
            settings.app.sso_onelogin_mode = sso_onelogin_mode

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

    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 'restrict_import' in flask.request.json:
        settings_commit = True
        restrict_import = True if \
            flask.request.json['restrict_import'] else False
        if restrict_import != settings.user.restrict_import:
            changes.add('restrict_import')
        settings.user.restrict_import = restrict_import

    if 'client_reconnect' in flask.request.json:
        settings_commit = True
        client_reconnect = True if \
            flask.request.json['client_reconnect'] else False
        settings.user.reconnect = client_reconnect

    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 'routed_subnet6_wg' in flask.request.json:
        routed_subnet6_wg = flask.request.json['routed_subnet6_wg']
        if routed_subnet6_wg:
            try:
                routed_subnet6_wg = ipaddress.IPv6Network(
                    flask.request.json['routed_subnet6_wg'])
            except (ipaddress.AddressValueError, ValueError):
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_WG_INVALID,
                        'error_msg': IPV6_SUBNET_WG_INVALID_MSG,
                    }, 400)

            if routed_subnet6_wg.prefixlen > 64:
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_WG_SIZE_INVALID,
                        'error_msg': IPV6_SUBNET_WG_SIZE_INVALID_MSG,
                    }, 400)

            routed_subnet6_wg = str(routed_subnet6_wg)
        else:
            routed_subnet6_wg = None

        if settings.local.host.routed_subnet6_wg != routed_subnet6_wg:
            if server.get_online_ipv6_count():
                return utils.jsonify(
                    {
                        'error': IPV6_SUBNET_WG_ONLINE,
                        'error_msg': IPV6_SUBNET_WG_ONLINE_MSG,
                    }, 400)
            settings.local.host.routed_subnet6_wg = routed_subnet6_wg
            settings.local.host.commit('routed_subnet6_wg')

    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

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

    if 'oracle_public_key' in flask.request.json:
        if flask.request.json['oracle_public_key'] == 'reset':
            settings_commit = True
            private_key, public_key = utils.generate_rsa_key()
            settings.app.oracle_private_key = private_key
            settings.app.oracle_public_key = public_key

    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',
            'us_gov_east_1_access_key',
            'us_gov_east_1_secret_key',
            'us_gov_west_1_access_key',
            'us_gov_west_1_secret_key',
            'eu_north_1_access_key',
            'eu_north_1_secret_key',
            'eu_west_1_access_key',
            'eu_west_1_secret_key',
            'eu_west_2_access_key',
            'eu_west_2_secret_key',
            'eu_west_3_access_key',
            'eu_west_3_secret_key',
            'eu_central_1_access_key',
            'eu_central_1_secret_key',
            'ca_central_1_access_key',
            'ca_central_1_secret_key',
            'cn_north_1_access_key',
            'cn_north_1_secret_key',
            'cn_northwest_1_access_key',
            'cn_northwest_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_east_1_access_key',
            'ap_east_1_secret_key',
            'ap_south_1_access_key',
            'ap_south_1_secret_key',
            'sa_east_1_access_key',
            'sa_east_1_secret_key',
    ):
        if settings.app.cloud_provider != 'aws':
            settings_commit = True
            setattr(settings.app, aws_key, None)
        elif 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_match = None
        settings.app.sso_azure_directory_id = None
        settings.app.sso_azure_app_id = None
        settings.app.sso_azure_app_secret = None
        settings.app.sso_authzero_directory_id = None
        settings.app.sso_authzero_app_id = None
        settings.app.sso_authzero_app_secret = None
        settings.app.sso_google_key = None
        settings.app.sso_google_email = None
        settings.app.sso_duo_token = None
        settings.app.sso_duo_secret = None
        settings.app.sso_duo_host = 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_app_id = None
        settings.app.sso_okta_token = None
        settings.app.sso_onelogin_key = None
        settings.app.sso_onelogin_app_id = 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:
        remote_addr = utils.get_remote_addr()
        flask.g.administrator.audit_event(
            'admin_settings',
            _changes_audit_text[change],
            remote_addr=remote_addr,
        )
        journal.entry(
            journal.SETTINGS_UPDATE,
            remote_address=remote_addr,
            event_long='Settings updated',
            changed=_changes_audit_text[change],
        )

    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)
Пример #37
0
def settings_put():
    if settings.app.demo_mode:
        return utils.demo_blocked()

    org_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 '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')

    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)
            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_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_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 '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']
        if cloud_provider:
            settings.app.cloud_provider = cloud_provider
        else:
            settings.app.cloud_provider = None

    for aws_key in (
                'us_east_1_access_key',
                'us_east_1_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',
                '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_match = None
        settings.app.sso_token = None
        settings.app.sso_secret = None
        settings.app.sso_host = 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:
        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 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.commit()
            return utils.jsonify({
                'error': ACME_ERROR,
                'error_msg': ACME_ERROR_MSG,
            }, 400)
    elif update_cert:
        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)
Пример #38
0
def admin_put(admin_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    if not flask.g.administrator.super_user:
        return utils.jsonify({
            'error': REQUIRES_SUPER_USER,
            'error_msg': REQUIRES_SUPER_USER_MSG,
        }, 400)

    admin = auth.get_by_id(admin_id)

    if 'username' in flask.request.json:
        username = utils.filter_str(flask.request.json['username']) or None

        if username != admin.username:
            admin.audit_event('admin_updated',
                'Administrator username changed',
                remote_addr=utils.get_remote_addr(),
            )

        admin.username = username

    if 'password' in flask.request.json and flask.request.json['password']:
        password = flask.request.json['password']

        if password != admin.password:
            admin.audit_event('admin_updated',
                'Administrator password changed',
                remote_addr=utils.get_remote_addr(),
            )

        admin.password = password

    super_user = flask.request.json.get('super_user')
    if super_user is not None:
        if super_user != admin.super_user:
            if not super_user and auth.super_user_count() < 2:
                return utils.jsonify({
                    'error': NO_SUPER_USERS,
                    'error_msg': NO_SUPER_USERS_MSG,
                }, 400)

            admin.audit_event('admin_updated',
                'Administrator super user %s' % (
                    'disabled' if super_user else 'enabled'),
                remote_addr=utils.get_remote_addr(),
            )

        admin.super_user = super_user

    auth_api = flask.request.json.get('auth_api')
    if auth_api is not None:
        if auth_api != admin.auth_api:
            if not auth_api:
                admin.token = None
                admin.secret = None
            elif not admin.token or not admin.secret:
                admin.generate_token()
                admin.generate_secret()

            admin.audit_event('admin_updated',
                'Administrator token authentication %s' % (
                    'disabled' if auth_api else 'enabled'),
                remote_addr=utils.get_remote_addr(),
            )

        admin.auth_api = auth_api

    if 'token' in flask.request.json and flask.request.json['token']:
        admin.generate_token()
        admin.audit_event('admin_updated',
            'Administrator api token changed',
            remote_addr=utils.get_remote_addr(),
        )

    if 'secret' in flask.request.json and flask.request.json['secret']:
        admin.generate_secret()
        admin.audit_event('admin_updated',
            'Administrator api secret changed',
            remote_addr=utils.get_remote_addr(),
        )

    disabled = flask.request.json.get('disabled')
    if disabled is not None:
        if disabled != admin.disabled:
            if disabled and admin.super_user and auth.super_user_count() < 2:
                return utils.jsonify({
                    'error': NO_ADMINS_ENABLED,
                    'error_msg': NO_ADMINS_ENABLED_MSG,
                }, 400)

            admin.audit_event('admin_updated',
                'Administrator %s' % ('disabled' if disabled else 'enabled'),
                remote_addr=utils.get_remote_addr(),
            )

        admin.disabled = disabled

    otp_auth = flask.request.json.get('otp_auth')
    if otp_auth is not None:
        if otp_auth != admin.otp_auth:
            if not otp_auth:
                admin.otp_secret = None
            elif not admin.otp_secret:
                admin.generate_otp_secret()

            admin.audit_event('admin_updated',
                'Administrator two-step authentication %s' % (
                    'disabled' if otp_auth else 'enabled'),
                remote_addr=utils.get_remote_addr(),
            )

        admin.otp_auth = otp_auth

    otp_secret = flask.request.json.get('otp_secret')
    if otp_secret == True:
        admin.audit_event('admin_updated',
            'Administrator two-factor authentication secret reset',
            remote_addr=utils.get_remote_addr(),
        )
        admin.generate_otp_secret()

    try:
        admin.commit()
    except pymongo.errors.DuplicateKeyError:
        return utils.jsonify({
            'error': ADMIN_USERNAME_EXISTS,
            'error_msg': ADMIN_USERNAME_EXISTS_MSG,
        }, 400)

    event.Event(type=ADMINS_UPDATED)

    return utils.jsonify(admin.dict())
Пример #39
0
def user_key_pin_put(key_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    key_id = key_id[:128]
    remote_addr = utils.get_remote_addr()

    doc = _find_doc({
        'key_id': key_id,
    })
    if not doc:
        journal.entry(
            journal.USER_PROFILE_FAILURE,
            remote_address=remote_addr,
            event_long='Key ID not found',
        )
        return flask.abort(404)

    if settings.user.pin_mode == PIN_DISABLED:
        return utils.jsonify(
            {
                'error': PIN_IS_DISABLED,
                'error_msg': PIN_IS_DISABLED_MSG,
            }, 400)

    org = organization.get_by_id(doc['org_id'])
    usr = org.get_user(doc['user_id'])
    if usr.disabled:
        return flask.abort(403)

    if RADIUS_AUTH in usr.auth_type:
        return utils.jsonify(
            {
                'error': PIN_RADIUS,
                'error_msg': PIN_RADIUS_MSG,
            }, 400)

    current_pin = utils.filter_str(
        flask.request.json.get('current_pin')) or None
    pin = utils.filter_str(flask.request.json.get('pin')) or None

    if pin:
        if settings.user.pin_digits_only and not pin.isdigit():
            return utils.jsonify(
                {
                    'error': PIN_NOT_DIGITS,
                    'error_msg': PIN_NOT_DIGITS_MSG,
                }, 400)

        if len(pin) < settings.user.pin_min_length:
            return utils.jsonify(
                {
                    'error': PIN_TOO_SHORT,
                    'error_msg': PIN_TOO_SHORT_MSG,
                }, 400)

    if usr.pin:
        if not limiter.auth_check(usr.id):
            return utils.jsonify(
                {
                    'error': AUTH_TOO_MANY,
                    'error_msg': AUTH_TOO_MANY_MSG,
                }, 400)

        if not usr.check_pin(current_pin):
            return utils.jsonify(
                {
                    'error': PIN_INVALID,
                    'error_msg': PIN_INVALID_MSG,
                }, 400)

    if usr.set_pin(pin):
        journal.entry(
            journal.USER_PIN_UPDATE,
            usr.journal_data,
            remote_address=remote_addr,
            event_long='User pin changed with temporary profile link',
        )

        usr.audit_event(
            'user_updated',
            'User pin changed with temporary profile link',
            remote_addr=remote_addr,
        )

    usr.commit()

    event.Event(type=USERS_UPDATED, resource_id=org.id)

    return utils.jsonify({})
Пример #40
0
def server_output_delete(server_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    server.output_clear(server_id)
    return utils.jsonify({})
Пример #41
0
def server_route_put(server_id, route_network):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    svr = server.get_by_id(server_id)
    route_network = route_network.decode('hex')
    comment = flask.request.json.get('comment') or None
    metric = flask.request.json.get('metric') or None
    nat_route = True if flask.request.json.get('nat') else False
    nat_interface = flask.request.json.get('nat_interface') or None
    vpc_region = utils.filter_str(flask.request.json.get('vpc_region')) or None
    vpc_id = utils.filter_str(flask.request.json.get('vpc_id')) or None
    net_gateway = True if flask.request.json.get('net_gateway') else False

    try:
        route = svr.upsert_route(route_network, nat_route, nat_interface,
                                 vpc_region, vpc_id, net_gateway, comment,
                                 metric)
    except ServerOnlineError:
        return utils.jsonify(
            {
                'error': SERVER_ROUTE_ONLINE,
                'error_msg': SERVER_ROUTE_ONLINE_MSG,
            }, 400)
    except NetworkInvalid:
        return utils.jsonify(
            {
                'error': SERVER_ROUTE_INVALID,
                'error_msg': SERVER_ROUTE_INVALID_MSG,
            }, 400)
    except ServerRouteNatVirtual:
        return utils.jsonify(
            {
                'error': SERVER_ROUTE_VIRTUAL_NAT,
                'error_msg': SERVER_ROUTE_VIRTUAL_NAT_MSG,
            }, 400)
    except ServerRouteNatServerLink:
        return utils.jsonify(
            {
                'error': SERVER_ROUTE_SERVER_LINK_NAT,
                'error_msg': SERVER_ROUTE_SERVER_LINK_NAT_MSG,
            }, 400)
    except ServerRouteGatewayNetworkLink:
        return utils.jsonify(
            {
                'error': SERVER_ROUTE_NETWORK_LINK_GATEWAY,
                'error_msg': SERVER_ROUTE_NETWORK_LINK_GATEWAY_MSG,
            }, 400)
    except ServerRouteNatNetGateway:
        return utils.jsonify(
            {
                'error': SERVER_ROUTE_NET_GATEWAY_NAT,
                'error_msg': SERVER_ROUTE_NET_GATEWAY_NAT_MSG,
            }, 400)

    err, err_msg = svr.validate_conf()
    if err:
        return utils.jsonify({
            'error': err,
            'error_msg': err_msg,
        }, 400)

    svr.commit('routes')

    event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr.id)
    for svr_link in svr.links:
        event.Event(type=SERVER_ROUTES_UPDATED,
                    resource_id=svr_link['server_id'])

    return utils.jsonify(route)
Пример #42
0
def server_put_post(server_id=None):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    used_resources = server.get_used_resources(server_id)
    network_used = used_resources['networks']
    port_used = used_resources['ports']

    name = None
    name_def = False
    if 'name' in flask.request.json:
        name_def = True
        name = utils.filter_str(flask.request.json['name'])

    network = None
    network_def = False
    if 'network' in flask.request.json and \
            flask.request.json['network'] != '':
        network_def = True
        network = flask.request.json['network']

        try:
            if not _check_network_private(network):
                return _network_invalid()
        except (ipaddress.AddressValueError, ValueError):
            return _network_invalid()

    network_mode = None
    network_mode_def = False
    if 'network_mode' in flask.request.json:
        network_mode_def = True
        network_mode = flask.request.json['network_mode']

    network_start = None
    network_start_def = False
    if 'network_start' in flask.request.json:
        network_start_def = True
        network_start = flask.request.json['network_start']

    network_end = None
    network_end_def = False
    if 'network_end' in flask.request.json:
        network_end_def = True
        network_end = flask.request.json['network_end']

    restrict_routes = None
    restrict_routes_def = False
    if 'restrict_routes' in flask.request.json:
        restrict_routes_def = True
        restrict_routes = True if flask.request.json['restrict_routes'] \
            else False

    ipv6 = None
    ipv6_def = False
    if 'ipv6' in flask.request.json:
        ipv6_def = True
        ipv6 = True if flask.request.json['ipv6'] else False

    ipv6_firewall = None
    ipv6_firewall_def = False
    if 'ipv6_firewall' in flask.request.json:
        ipv6_firewall_def = True
        ipv6_firewall = True if flask.request.json['ipv6_firewall'] else False

    bind_address = None
    bind_address_def = False
    if 'bind_address' in flask.request.json:
        bind_address_def = True
        bind_address = utils.filter_str(flask.request.json['bind_address'])

    protocol = 'udp'
    protocol_def = False
    if 'protocol' in flask.request.json:
        protocol_def = True
        protocol = flask.request.json['protocol'].lower()

        if protocol not in ('udp', 'tcp'):
            return utils.jsonify(
                {
                    'error': PROTOCOL_INVALID,
                    'error_msg': PROTOCOL_INVALID_MSG,
                }, 400)

    port = None
    port_def = False
    if 'port' in flask.request.json and flask.request.json['port'] != 0:
        port_def = True
        port = flask.request.json['port']

        try:
            port = int(port)
        except ValueError:
            return _port_invalid()

        if port < 1 or port > 65535:
            return _port_invalid()

    dh_param_bits = None
    dh_param_bits_def = False
    if flask.request.json.get('dh_param_bits'):
        dh_param_bits_def = True
        dh_param_bits = flask.request.json['dh_param_bits']

        try:
            dh_param_bits = int(dh_param_bits)
        except ValueError:
            return _dh_param_bits_invalid()

        if dh_param_bits not in VALID_DH_PARAM_BITS:
            return _dh_param_bits_invalid()

    groups = None
    groups_def = False
    if 'groups' in flask.request.json:
        groups_def = True
        groups = flask.request.json['groups'] or []
        for i, group in enumerate(groups):
            groups[i] = utils.filter_str(group)
        groups = list(set(groups))

    multi_device = False
    multi_device_def = False
    if 'multi_device' in flask.request.json:
        multi_device_def = True
        multi_device = True if flask.request.json['multi_device'] else False

    dns_servers = None
    dns_servers_def = False
    if 'dns_servers' in flask.request.json:
        dns_servers_def = True
        dns_servers = flask.request.json['dns_servers'] or []

        for dns_server in dns_servers:
            try:
                ipaddress.IPAddress(dns_server)
            except (ipaddress.AddressValueError, ValueError):
                return _dns_server_invalid()

    search_domain = None
    search_domain_def = False
    if 'search_domain' in flask.request.json:
        search_domain_def = True
        search_domain = flask.request.json['search_domain']
        if search_domain:
            search_domain = ', '.join([
                utils.filter_str(x.strip()) for x in search_domain.split(',')
            ])
        else:
            search_domain = None

    inter_client = True
    inter_client_def = False
    if 'inter_client' in flask.request.json:
        inter_client_def = True
        inter_client = True if flask.request.json['inter_client'] else False

    ping_interval = None
    ping_interval_def = False
    if 'ping_interval' in flask.request.json:
        ping_interval_def = True
        ping_interval = int(flask.request.json['ping_interval'] or 10)

    ping_timeout = None
    ping_timeout_def = False
    if 'ping_timeout' in flask.request.json:
        ping_timeout_def = True
        ping_timeout = int(flask.request.json['ping_timeout'] or 60)

    link_ping_interval = None
    link_ping_interval_def = False
    if 'link_ping_interval' in flask.request.json:
        link_ping_interval_def = True
        link_ping_interval = int(flask.request.json['link_ping_interval'] or 1)

    link_ping_timeout = None
    link_ping_timeout_def = False
    if 'link_ping_timeout' in flask.request.json:
        link_ping_timeout_def = True
        link_ping_timeout = int(flask.request.json['link_ping_timeout'] or 5)

    inactive_timeout = None
    inactive_timeout_def = False
    if 'inactive_timeout' in flask.request.json:
        inactive_timeout_def = True
        inactive_timeout = int(flask.request.json['inactive_timeout']
                               or 0) or None

    allowed_devices = None
    allowed_devices_def = False
    if 'allowed_devices' in flask.request.json:
        allowed_devices_def = True
        allowed_devices = flask.request.json['allowed_devices'] or None

    max_clients = None
    max_clients_def = False
    if 'max_clients' in flask.request.json:
        max_clients_def = True
        max_clients = flask.request.json['max_clients']
        if max_clients:
            max_clients = int(max_clients)
        else:
            max_clients = 2000

    max_devices = None
    max_devices_def = False
    if 'max_devices' in flask.request.json:
        max_devices_def = True
        max_devices = flask.request.json['max_devices']
        if max_devices:
            max_devices = int(max_devices)
        else:
            max_devices = 0

    replica_count = None
    replica_count_def = False
    if 'replica_count' in flask.request.json:
        replica_count_def = True
        replica_count = flask.request.json['replica_count']
        if replica_count:
            replica_count = int(replica_count)
        if not replica_count:
            replica_count = 1

    vxlan = True
    vxlan_def = False
    if 'vxlan' in flask.request.json:
        vxlan_def = True
        vxlan = True if flask.request.json['vxlan'] else False

    dns_mapping = False
    dns_mapping_def = False
    if 'dns_mapping' in flask.request.json:
        dns_mapping_def = True
        dns_mapping = True if flask.request.json['dns_mapping'] else False

    debug = False
    debug_def = False
    if 'debug' in flask.request.json:
        debug_def = True
        debug = True if flask.request.json['debug'] else False

    pre_connect_msg = None
    pre_connect_msg_def = False
    if 'pre_connect_msg' in flask.request.json:
        pre_connect_msg_def = True
        if flask.request.json['pre_connect_msg']:
            pre_connect_msg = flask.request.json['pre_connect_msg'].strip()

    otp_auth = False
    otp_auth_def = False
    if 'otp_auth' in flask.request.json:
        otp_auth_def = True
        otp_auth = True if flask.request.json['otp_auth'] else False

    mss_fix = None
    mss_fix_def = False
    if 'mss_fix' in flask.request.json:
        mss_fix_def = True
        mss_fix = flask.request.json['mss_fix'] or None
        if mss_fix:
            mss_fix = int(mss_fix) or None

    lzo_compression = False
    lzo_compression_def = False
    if 'lzo_compression' in flask.request.json:
        lzo_compression_def = True
        lzo_compression = True if flask.request.json[
            'lzo_compression'] else False

    cipher = None
    cipher_def = False
    if 'cipher' in flask.request.json:
        cipher_def = True
        cipher = flask.request.json['cipher']

        if cipher not in CIPHERS:
            return utils.jsonify(
                {
                    'error': CIPHER_INVALID,
                    'error_msg': CIPHER_INVALID_MSG,
                }, 400)

    hash = None
    hash_def = False
    if 'hash' in flask.request.json:
        hash_def = True
        hash = flask.request.json['hash']

        if hash not in HASHES:
            return utils.jsonify(
                {
                    'error': HASH_INVALID,
                    'error_msg': HASH_INVALID_MSG,
                }, 400)

    block_outside_dns = False
    block_outside_dns_def = False
    if 'block_outside_dns' in flask.request.json:
        block_outside_dns_def = True
        block_outside_dns = True if flask.request.json[
            'block_outside_dns'] else False

    jumbo_frames = False
    jumbo_frames_def = False
    if 'jumbo_frames' in flask.request.json:
        jumbo_frames_def = True
        jumbo_frames = True if flask.request.json['jumbo_frames'] else False

    if not server_id:
        if not name_def:
            return utils.jsonify(
                {
                    'error': MISSING_PARAMS,
                    'error_msg': MISSING_PARAMS_MSG,
                }, 400)

        if not network_def:
            network_def = True
            rand_range = range(215, 250)
            rand_range_low = range(15, 215)
            random.shuffle(rand_range)
            random.shuffle(rand_range_low)
            rand_range += rand_range_low
            for i in rand_range:
                rand_network = '192.168.%s.0/24' % i
                if not _check_network_overlap(rand_network, network_used):
                    network = rand_network
                    break
            if not network:
                return utils.jsonify(
                    {
                        'error': NETWORK_IN_USE,
                        'error_msg': NETWORK_IN_USE_MSG,
                    }, 400)

        if not port_def:
            port_def = True
            rand_ports = range(10000, 19999)
            random.shuffle(rand_ports)
            for rand_port in rand_ports:
                if '%s%s' % (rand_port, protocol) not in port_used:
                    port = rand_port
                    break
            if not port:
                return utils.jsonify(
                    {
                        'error': PORT_PROTOCOL_IN_USE,
                        'error_msg': PORT_PROTOCOL_IN_USE_MSG,
                    }, 400)

        if not dh_param_bits_def:
            dh_param_bits_def = True
            dh_param_bits = settings.vpn.default_dh_param_bits

    changed = None

    if not server_id:
        svr = server.new_server(
            name=name,
            network=network,
            groups=groups,
            network_mode=network_mode,
            network_start=network_start,
            network_end=network_end,
            restrict_routes=restrict_routes,
            ipv6=ipv6,
            ipv6_firewall=ipv6_firewall,
            bind_address=bind_address,
            port=port,
            protocol=protocol,
            dh_param_bits=dh_param_bits,
            multi_device=multi_device,
            dns_servers=dns_servers,
            search_domain=search_domain,
            otp_auth=otp_auth,
            cipher=cipher,
            hash=hash,
            block_outside_dns=block_outside_dns,
            jumbo_frames=jumbo_frames,
            lzo_compression=lzo_compression,
            inter_client=inter_client,
            ping_interval=ping_interval,
            ping_timeout=ping_timeout,
            link_ping_interval=link_ping_interval,
            link_ping_timeout=link_ping_timeout,
            inactive_timeout=inactive_timeout,
            allowed_devices=allowed_devices,
            max_clients=max_clients,
            max_devices=max_devices,
            replica_count=replica_count,
            vxlan=vxlan,
            dns_mapping=dns_mapping,
            debug=debug,
            pre_connect_msg=pre_connect_msg,
            mss_fix=mss_fix,
        )
        svr.add_host(settings.local.host_id)
    else:
        svr = server.get_by_id(server_id)

        if name_def:
            svr.name = name
        if network_def:
            svr.network = network
        if groups_def:
            svr.groups = groups
        if network_start_def:
            svr.network_start = network_start
        if network_end_def:
            svr.network_end = network_end
        if restrict_routes_def:
            svr.restrict_routes = restrict_routes
        if ipv6_def:
            svr.ipv6 = ipv6
        if ipv6_firewall_def:
            svr.ipv6_firewall = ipv6_firewall
        if network_mode_def:
            svr.network_mode = network_mode
        if bind_address_def:
            svr.bind_address = bind_address
        if port_def:
            svr.port = port
        if protocol_def:
            svr.protocol = protocol
        if dh_param_bits_def and svr.dh_param_bits != dh_param_bits:
            svr.dh_param_bits = dh_param_bits
            svr.generate_dh_param()
        if multi_device_def:
            svr.multi_device = multi_device
        if dns_servers_def:
            svr.dns_servers = dns_servers
        if search_domain_def:
            svr.search_domain = search_domain
        if otp_auth_def:
            svr.otp_auth = otp_auth
        if cipher_def:
            svr.cipher = cipher
        if hash_def:
            svr.hash = hash
        if block_outside_dns_def:
            svr.block_outside_dns = block_outside_dns
        if jumbo_frames_def:
            svr.jumbo_frames = jumbo_frames
        if lzo_compression_def:
            svr.lzo_compression = lzo_compression
        if inter_client_def:
            svr.inter_client = inter_client
        if ping_interval_def:
            svr.ping_interval = ping_interval
        if ping_timeout_def:
            svr.ping_timeout = ping_timeout
        if link_ping_interval_def:
            svr.link_ping_interval = link_ping_interval
        if link_ping_timeout_def:
            svr.link_ping_timeout = link_ping_timeout
        if inactive_timeout_def:
            svr.inactive_timeout = inactive_timeout
        if allowed_devices_def:
            svr.allowed_devices = allowed_devices
        if max_clients_def:
            svr.max_clients = max_clients
        if max_devices_def:
            svr.max_devices = max_devices
        if replica_count_def:
            svr.replica_count = replica_count
        if vxlan_def:
            svr.vxlan = vxlan
        if dns_mapping_def:
            svr.dns_mapping = dns_mapping
        if debug_def:
            svr.debug = debug
        if pre_connect_msg_def:
            svr.pre_connect_msg = pre_connect_msg
        if mss_fix_def:
            svr.mss_fix = mss_fix

        changed = svr.changed

    err, err_msg = svr.validate_conf()
    if err:
        return utils.jsonify({
            'error': err,
            'error_msg': err_msg,
        }, 400)

    svr.commit(changed)

    logger.LogEntry(message='Created server "%s".' % svr.name)
    event.Event(type=SERVERS_UPDATED)
    event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr.id)
    for org in svr.iter_orgs():
        event.Event(type=USERS_UPDATED, resource_id=org.id)
    return utils.jsonify(svr.dict())
Пример #43
0
def link_state_put():
    if settings.app.demo_mode:
        return utils.demo_blocked()

    auth_token = flask.request.headers.get('Auth-Token', None)
    auth_timestamp = flask.request.headers.get('Auth-Timestamp', None)
    auth_nonce = flask.request.headers.get('Auth-Nonce', None)
    auth_signature = flask.request.headers.get('Auth-Signature', None)
    if not auth_token or not auth_timestamp or not auth_nonce or \
            not auth_signature:
        return flask.abort(406)
    auth_token = auth_token[:256]
    auth_timestamp = auth_timestamp[:64]
    auth_nonce = auth_nonce[:32]
    auth_signature = auth_signature[:512]

    try:
        if abs(int(auth_timestamp) - int(utils.time_now())) > \
                settings.app.auth_time_window:
            return flask.abort(408)
    except ValueError:
        return flask.abort(405)

    host = link.get_host(database.ObjectId(auth_token))
    if not host:
        return flask.abort(404)

    auth_string = '&'.join([
        auth_token,
        auth_timestamp,
        auth_nonce,
        flask.request.method,
        flask.request.path,
    ])

    if len(auth_string) > AUTH_SIG_STRING_MAX_LEN:
        return flask.abort(413)

    auth_test_signature = base64.b64encode(
        hmac.new(host.secret.encode(), auth_string.encode(),
                 hashlib.sha512).digest()).decode()
    if not utils.const_compare(auth_signature, auth_test_signature):
        return flask.abort(401)

    nonces_collection = mongo.get_collection('auth_nonces')
    try:
        nonces_collection.insert({
            'token': auth_token,
            'nonce': auth_nonce,
            'timestamp': utils.now(),
        })
    except pymongo.errors.DuplicateKeyError:
        return flask.abort(409)

    host.load_link()

    host.version = flask.request.json.get('version')
    host.public_address = flask.request.json.get('public_address')
    host.local_address = flask.request.json.get('local_address')
    host.address6 = flask.request.json.get('address6')
    if flask.request.json.get('hosts'):
        host.hosts = flask.request.json.get('hosts')
        if host.hosts_hist:
            host.hosts_hist.insert(0, flask.request.json.get('hosts'))
            host.hosts_hist = host.hosts_hist[:6]
        else:
            host.hosts_hist = [flask.request.json.get('hosts')]
    else:
        host.hosts = None
        host.hosts_hist = None

    state, active = host.get_state()
    if active:
        host.location.status = flask.request.json.get('status') or None
        host.location.commit('status')

    data = json.dumps(state, default=lambda x: str(x))
    data += (16 - len(data) % 16) * '\x00'

    iv = os.urandom(16)
    key = hashlib.sha256(host.secret.encode()).digest()
    cipher = Cipher(algorithms.AES(key),
                    modes.CBC(iv),
                    backend=default_backend()).encryptor()
    enc_data = base64.b64encode(
        cipher.update(data.encode()) + cipher.finalize())

    enc_signature = base64.b64encode(
        hmac.new(host.secret.encode(), enc_data,
                 hashlib.sha512).digest()).decode()

    resp = flask.Response(response=enc_data, mimetype='application/base64')
    resp.headers.add('Cache-Control', 'no-cache, no-store, must-revalidate')
    resp.headers.add('Pragma', 'no-cache')
    resp.headers.add('Expires', 0)
    resp.headers.add('Cipher-IV', base64.b64encode(iv))
    resp.headers.add('Cipher-Signature', enc_signature)

    return resp
Пример #44
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:
            if not flask.g.administrator.super_user:
                return utils.jsonify({
                    'error': REQUIRES_SUPER_USER,
                    'error_msg': REQUIRES_SUPER_USER_MSG,
                }, 400)
            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:
        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 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)
Пример #45
0
def user_key_pin_put(key_id):
    doc = _find_doc({
        'key_id': key_id,
    })
    if not doc:
        return flask.abort(404)

    if settings.app.demo_mode:
        return utils.demo_blocked()

    if settings.user.pin_mode == PIN_DISABLED:
        return utils.jsonify(
            {
                'error': PIN_IS_DISABLED,
                'error_msg': PIN_IS_DISABLED_MSG,
            }, 400)

    org = organization.get_by_id(doc['org_id'])
    usr = org.get_user(doc['user_id'])
    if usr.disabled:
        return flask.abort(403)

    if RADIUS_AUTH in usr.auth_type:
        return utils.jsonify(
            {
                'error': PIN_RADIUS,
                'error_msg': PIN_RADIUS_MSG,
            }, 400)

    current_pin = utils.filter_str(
        flask.request.json.get('current_pin')) or None
    pin = utils.filter_str(flask.request.json.get('pin')) or None

    if pin:
        if not pin.isdigit():
            return utils.jsonify(
                {
                    'error': PIN_NOT_DIGITS,
                    'error_msg': PIN_NOT_DIGITS_MSG,
                }, 400)

        if len(pin) < settings.user.pin_min_length:
            return utils.jsonify(
                {
                    'error': PIN_TOO_SHORT,
                    'error_msg': PIN_TOO_SHORT_MSG,
                }, 400)

    if usr.pin and not usr.check_pin(current_pin):
        return utils.jsonify(
            {
                'error': PIN_INVALID,
                'error_msg': PIN_INVALID_MSG,
            }, 400)

    if usr.set_pin(pin):
        usr.audit_event(
            'user_updated',
            'User pin changed with temporary profile link',
            remote_addr=utils.get_remote_addr(),
        )

    usr.commit()

    event.Event(type=USERS_UPDATED, resource_id=org.id)

    return utils.jsonify({})
Пример #46
0
def user_post(org_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    org = organization.get_by_id(org_id)
    users = []

    if isinstance(flask.request.json, list):
        users_data = flask.request.json
    else:
        users_data = [flask.request.json]

    try:
        for user_data in users_data:
            name = utils.filter_str(user_data['name'])
            email = utils.filter_str(user_data.get('email'))
            pin = utils.filter_str(user_data.get('pin')) or None
            disabled = user_data.get('disabled')
            network_links = user_data.get('network_links')
            bypass_secondary = user_data.get('bypass_secondary')
            dns_servers = user_data.get('dns_servers') or None
            dns_suffix = utils.filter_str(user_data.get('dns_suffix')) or None
            port_forwarding_in = user_data.get('port_forwarding')
            port_forwarding = []

            if pin:
                if not pin.isdigit():
                    return utils.jsonify({
                        'error': PIN_NOT_DIGITS,
                        'error_msg': PIN_NOT_DIGITS_MSG,
                    }, 400)

                if len(pin) < settings.user.pin_min_length:
                    return utils.jsonify({
                        'error': PIN_TOO_SHORT,
                        'error_msg': PIN_TOO_SHORT_MSG,
                    }, 400)

                pin = auth.generate_hash_pin_v2(pin)

            if port_forwarding_in:
                for data in port_forwarding_in:
                    port_forwarding.append({
                        'protocol': utils.filter_str(data.get('protocol')),
                        'port': utils.filter_str(data.get('port')),
                        'dport': utils.filter_str(data.get('dport')),
                    })

            user = org.new_user(type=CERT_CLIENT, name=name, email=email,
                pin=pin, disabled=disabled, bypass_secondary=bypass_secondary,
                dns_servers=dns_servers, dns_suffix=dns_suffix,
                port_forwarding=port_forwarding)
            user.audit_event('user_created',
                'User created from web console',
                remote_addr=utils.get_remote_addr(),
            )

            if network_links:
                for network_link in network_links:
                    try:
                        user.add_network_link(network_link)
                    except (ipaddress.AddressValueError, ValueError):
                        return _network_link_invalid()
                    except ServerOnlineError:
                        return utils.jsonify({
                            'error': NETWORK_LINK_NOT_OFFLINE,
                            'error_msg': NETWORK_LINK_NOT_OFFLINE_MSG,
                        }, 400)

            users.append(user.dict())
    finally:
        event.Event(type=ORGS_UPDATED)
        event.Event(type=USERS_UPDATED, resource_id=org.id)
        event.Event(type=SERVERS_UPDATED)

    if isinstance(flask.request.json, list):
        logger.LogEntry(message='Created %s new users.' % len(
            flask.request.json))
        return utils.jsonify(users)
    else:
        logger.LogEntry(message='Created new user "%s".' % users[0]['name'])
        return utils.jsonify(users[0])
Пример #47
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())
Пример #48
0
def auth_user_post():
    if settings.app.demo_mode:
        return utils.demo_blocked()

    auth_token = flask.request.headers.get('Auth-Token', None)
    auth_timestamp = flask.request.headers.get('Auth-Timestamp', None)
    auth_nonce = flask.request.headers.get('Auth-Nonce', None)
    auth_signature = flask.request.headers.get('Auth-Signature', None)

    if not auth_token or not auth_timestamp or not auth_nonce or \
            not auth_signature:
        return utils.jsonify({
            'error': AUTH_INVALID,
            'error_msg': AUTH_INVALID_MSG,
        }, 401)
    auth_nonce = auth_nonce[:32]

    try:
        if abs(int(auth_timestamp) - int(utils.time_now())) > \
                settings.app.auth_time_window:
            return utils.jsonify({
                'error': AUTH_INVALID,
                'error_msg': AUTH_INVALID_MSG,
            }, 401)
    except ValueError:
        return utils.jsonify({
            'error': AUTH_INVALID,
            'error_msg': AUTH_INVALID_MSG,
        }, 401)

    org = organization.get_by_token(auth_token)
    if not org:
        return utils.jsonify({
            'error': AUTH_INVALID,
            'error_msg': AUTH_INVALID_MSG,
        }, 401)

    auth_string = '&'.join([
        auth_token,
        auth_timestamp,
        auth_nonce,
        flask.request.method,
        flask.request.path,
    ] + ([flask.request.data] if flask.request.data else []))

    if len(auth_string) > AUTH_SIG_STRING_MAX_LEN:
        return utils.jsonify({
            'error': AUTH_INVALID,
            'error_msg': AUTH_INVALID_MSG,
        }, 401)

    if not org.auth_secret or len(org.auth_secret) < 8:
        return utils.jsonify({
            'error': AUTH_INVALID,
            'error_msg': AUTH_INVALID_MSG,
        }, 401)

    auth_test_signature = base64.b64encode(hmac.new(
        org.auth_secret.encode(), auth_string,
        hashlib.sha256).digest())
    if auth_signature != auth_test_signature:
        return utils.jsonify({
            'error': AUTH_INVALID,
            'error_msg': AUTH_INVALID_MSG,
        }, 401)

    try:
        org.nonces_collection.insert({
            'token': auth_token,
            'nonce': auth_nonce,
            'timestamp': utils.now(),
        })
    except pymongo.errors.DuplicateKeyError:
        return utils.jsonify({
            'error': AUTH_INVALID,
            'error_msg': AUTH_INVALID_MSG,
        }, 401)

    username = flask.request.json['username']
    network_links = flask.request.json.get('network_links')

    usr = org.find_user(name=username)
    if usr:
        usr.remove()

    usr = org.new_user(name=username, type=CERT_CLIENT)
    usr.audit_event('user_created',
        'User created with authentication token',
        remote_addr=utils.get_remote_addr())

    if network_links:
        for network_link in network_links:
            try:
                usr.add_network_link(network_link, force=True)
            except (ipaddress.AddressValueError, ValueError):
                return _network_link_invalid()

    event.Event(type=ORGS_UPDATED)
    event.Event(type=USERS_UPDATED, resource_id=org.id)
    event.Event(type=SERVERS_UPDATED)

    keys = {}
    for svr in org.iter_servers():
        key = usr.build_key_conf(svr.id)
        keys[key['name']] = key['conf']

    return utils.jsonify(keys)
Пример #49
0
def user_put(org_id, user_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    org = organization.get_by_id(org_id)
    user = org.get_user(user_id)
    reset_user = False
    port_forwarding_event = False

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

        if name != user.name:
            user.audit_event(
                'user_updated',
                'User name changed',
                remote_addr=utils.get_remote_addr(),
            )

        user.name = name

    if 'email' in flask.request.json:
        email = utils.filter_str(flask.request.json['email']) or None

        if email != user.email:
            user.audit_event(
                'user_updated',
                'User email changed',
                remote_addr=utils.get_remote_addr(),
            )

        user.email = email

    if 'groups' in flask.request.json:
        groups = flask.request.json['groups'] or []
        for i, group in enumerate(groups):
            groups[i] = utils.filter_str(group)
        groups = set(groups)

        if groups != set(user.groups or []):
            user.audit_event(
                'user_updated',
                'User groups changed',
                remote_addr=utils.get_remote_addr(),
            )

        user.groups = list(groups)

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

        if pin is not True:
            if pin:
                if settings.user.pin_mode == PIN_DISABLED:
                    return utils.jsonify(
                        {
                            'error': PIN_IS_DISABLED,
                            'error_msg': PIN_IS_DISABLED_MSG,
                        }, 400)

                if RADIUS_AUTH in user.auth_type:
                    return utils.jsonify(
                        {
                            'error': PIN_RADIUS,
                            'error_msg': PIN_RADIUS_MSG,
                        }, 400)

                if not pin.isdigit():
                    return utils.jsonify(
                        {
                            'error': PIN_NOT_DIGITS,
                            'error_msg': PIN_NOT_DIGITS_MSG,
                        }, 400)

                if len(pin) < settings.user.pin_min_length:
                    return utils.jsonify(
                        {
                            'error': PIN_TOO_SHORT,
                            'error_msg': PIN_TOO_SHORT_MSG,
                        }, 400)

            if user.set_pin(pin):
                user.audit_event(
                    'user_updated',
                    'User pin changed',
                    remote_addr=utils.get_remote_addr(),
                )

    if 'network_links' in flask.request.json:
        network_links_cur = set(user.get_network_links())
        network_links_new = set()

        for network_link in flask.request.json['network_links'] or []:
            try:
                network_link = str(ipaddress.IPNetwork(network_link))
            except (ipaddress.AddressValueError, ValueError):
                return _network_link_invalid()
            network_links_new.add(network_link)

        network_links_add = network_links_new - network_links_cur
        network_links_rem = network_links_cur - network_links_new

        if len(network_links_add) or len(network_links_rem):
            reset_user = True
            user.audit_event(
                'user_updated',
                'User network links updated',
                remote_addr=utils.get_remote_addr(),
            )

        try:
            for network_link in network_links_add:
                user.add_network_link(network_link)
        except ServerOnlineError:
            return utils.jsonify(
                {
                    'error': NETWORK_LINK_NOT_OFFLINE,
                    'error_msg': NETWORK_LINK_NOT_OFFLINE_MSG,
                }, 400)

        for network_link in network_links_rem:
            user.remove_network_link(network_link)

    if 'port_forwarding' in flask.request.json:
        port_forwarding = []
        for data in flask.request.json['port_forwarding'] or []:
            port_forwarding.append({
                'protocol':
                utils.filter_str(data.get('protocol')),
                'port':
                utils.filter_str(data.get('port')),
                'dport':
                utils.filter_str(data.get('dport')),
            })

        if port_forwarding != user.port_forwarding:
            port_forwarding_event = True
            user.audit_event(
                'user_updated',
                'User port forwarding changed',
                remote_addr=utils.get_remote_addr(),
            )

        user.port_forwarding = port_forwarding

    disabled = True if flask.request.json.get('disabled') else False
    if disabled != user.disabled:
        user.audit_event(
            'user_updated',
            'User %s' % ('disabled' if disabled else 'enabled'),
            remote_addr=utils.get_remote_addr(),
        )
        if disabled:
            reset_user = True
    user.disabled = disabled

    user.bypass_secondary = True if flask.request.json.get(
        'bypass_secondary') else False

    user.client_to_client = True if flask.request.json.get(
        'client_to_client') else False

    if 'dns_servers' in flask.request.json:
        dns_servers = flask.request.json['dns_servers'] or None
        if user.dns_servers != dns_servers:
            user.audit_event(
                'user_updated',
                'User dns servers changed',
                remote_addr=utils.get_remote_addr(),
            )
            reset_user = True
        user.dns_servers = dns_servers

    if 'dns_suffix' in flask.request.json:
        dns_suffix = utils.filter_str(flask.request.json['dns_suffix']) or None
        if user.dns_suffix != dns_suffix:
            user.audit_event(
                'user_updated',
                'User dns suffix changed',
                remote_addr=utils.get_remote_addr(),
            )
            reset_user = True
        user.dns_suffix = dns_suffix

    user.commit()
    event.Event(type=USERS_UPDATED, resource_id=user.org.id)
    if port_forwarding_event:
        messenger.publish('port_forwarding', {
            'org_id': org.id,
            'user_id': user.id,
        })

    if reset_user:
        user.disconnect()

    send_key_email = flask.request.json.get('send_key_email')
    if send_key_email and user.email:
        user.audit_event(
            'user_emailed',
            'User key email sent to "%s"' % user.email,
            remote_addr=utils.get_remote_addr(),
        )

        try:
            user.send_key_email(utils.get_url_root())
        except EmailNotConfiguredError:
            return utils.jsonify(
                {
                    'error': EMAIL_NOT_CONFIGURED,
                    'error_msg': EMAIL_NOT_CONFIGURED_MSG,
                }, 400)
        except EmailFromInvalid:
            return utils.jsonify(
                {
                    'error': EMAIL_FROM_INVALID,
                    'error_msg': EMAIL_FROM_INVALID_MSG,
                }, 400)
        except EmailAuthInvalid:
            return utils.jsonify(
                {
                    'error': EMAIL_AUTH_INVALID,
                    'error_msg': EMAIL_AUTH_INVALID_MSG,
                }, 400)

    return utils.jsonify(user.dict())
Пример #50
0
def server_put_post(server_id=None):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    used_resources = server.get_used_resources(server_id)
    network_used = used_resources['networks']
    port_used = used_resources['ports']

    name = None
    name_def = False
    if 'name' in flask.request.json:
        name_def = True
        name = utils.filter_str(flask.request.json['name'])

    network = None
    network_def = False
    if 'network' in flask.request.json:
        network_def = True
        network = flask.request.json['network']

        try:
            if not _check_network_private(network):
                return _network_invalid()
        except (ipaddress.AddressValueError, ValueError):
            return _network_invalid()

    network_mode = None
    network_mode_def = False
    if 'network_mode' in flask.request.json:
        network_mode_def = True
        network_mode = flask.request.json['network_mode']

    network_start = None
    network_start_def = False
    if 'network_start' in flask.request.json:
        network_start_def = True
        network_start = flask.request.json['network_start']

    network_end = None
    network_end_def = False
    if 'network_end' in flask.request.json:
        network_end_def = True
        network_end = flask.request.json['network_end']

    restrict_routes = None
    restrict_routes_def = False
    if 'restrict_routes' in flask.request.json:
        restrict_routes_def = True
        restrict_routes = True if flask.request.json['restrict_routes'] \
            else False

    ipv6 = None
    ipv6_def = False
    if 'ipv6' in flask.request.json:
        ipv6_def = True
        ipv6 = True if flask.request.json['ipv6'] else False

    ipv6_firewall = None
    ipv6_firewall_def = False
    if 'ipv6_firewall' in flask.request.json:
        ipv6_firewall_def = True
        ipv6_firewall = True if flask.request.json['ipv6_firewall'] else False

    bind_address = None
    bind_address_def = False
    if 'bind_address' in flask.request.json:
        bind_address_def = True
        bind_address = utils.filter_str(flask.request.json['bind_address'])

    protocol = 'udp'
    protocol_def = False
    if 'protocol' in flask.request.json:
        protocol_def = True
        protocol = flask.request.json['protocol'].lower()

        if protocol not in ('udp', 'tcp'):
            return utils.jsonify({
                'error': PROTOCOL_INVALID,
                'error_msg': PROTOCOL_INVALID_MSG,
            }, 400)

    port = None
    port_def = False
    if 'port' in flask.request.json:
        port_def = True
        port = flask.request.json['port']

        try:
            port = int(port)
        except ValueError:
            return _port_invalid()

        if port < 1 or port > 65535:
            return _port_invalid()

    dh_param_bits = None
    dh_param_bits_def = False
    if flask.request.json.get('dh_param_bits'):
        dh_param_bits_def = True
        dh_param_bits = flask.request.json['dh_param_bits']

        try:
            dh_param_bits = int(dh_param_bits)
        except ValueError:
            return _dh_param_bits_invalid()

        if dh_param_bits not in VALID_DH_PARAM_BITS:
            return _dh_param_bits_invalid()

    multi_device = False
    multi_device_def = False
    if 'multi_device' in flask.request.json:
        multi_device_def = True
        multi_device = True if flask.request.json['multi_device'] else False

    dns_servers = None
    dns_servers_def = False
    if 'dns_servers' in flask.request.json:
        dns_servers_def = True
        dns_servers = flask.request.json['dns_servers'] or []

        for dns_server in dns_servers:
            try:
                ipaddress.IPAddress(dns_server)
            except (ipaddress.AddressValueError, ValueError):
                return _dns_server_invalid()

    search_domain = None
    search_domain_def = False
    if 'search_domain' in flask.request.json:
        search_domain_def = True
        search_domain = utils.filter_str(flask.request.json['search_domain'])

    inter_client = True
    inter_client_def = False
    if 'inter_client' in flask.request.json:
        inter_client_def = True
        inter_client = True if flask.request.json['inter_client'] else False

    ping_interval = None
    ping_interval_def = False
    if 'ping_interval' in flask.request.json:
        ping_interval_def = True
        ping_interval = flask.request.json['ping_interval']
        if ping_interval:
            ping_interval = int(ping_interval)
        if not ping_interval:
            ping_interval = 10

    ping_timeout = None
    ping_timeout_def = False
    if 'ping_timeout' in flask.request.json:
        ping_timeout_def = True
        ping_timeout = flask.request.json['ping_timeout']
        if ping_timeout:
            ping_timeout = int(ping_timeout)
        if not ping_timeout:
            ping_timeout = 60

    link_ping_interval = None
    link_ping_interval_def = False
    if 'link_ping_interval' in flask.request.json:
        link_ping_interval_def = True
        link_ping_interval = flask.request.json['link_ping_interval']
        if link_ping_interval:
            link_ping_interval = int(link_ping_interval)
        if not link_ping_interval:
            link_ping_interval = 1

    link_ping_timeout = None
    link_ping_timeout_def = False
    if 'link_ping_timeout' in flask.request.json:
        link_ping_timeout_def = True
        link_ping_timeout = flask.request.json['link_ping_timeout']
        if link_ping_timeout:
            link_ping_timeout = int(link_ping_timeout)
        if not link_ping_timeout:
            link_ping_timeout = 5

    max_clients = None
    max_clients_def = False
    if 'max_clients' in flask.request.json:
        max_clients_def = True
        max_clients = flask.request.json['max_clients']
        if max_clients:
            max_clients = int(max_clients)
        if not max_clients:
            max_clients = 4096

    replica_count = None
    replica_count_def = False
    if 'replica_count' in flask.request.json:
        replica_count_def = True
        replica_count = flask.request.json['replica_count']
        if replica_count:
            replica_count = int(replica_count)
        if not replica_count:
            replica_count = 1

    dns_mapping = False
    dns_mapping_def = False
    if 'dns_mapping' in flask.request.json:
        dns_mapping_def = True
        dns_mapping = True if flask.request.json['dns_mapping'] else False

    debug = False
    debug_def = False
    if 'debug' in flask.request.json:
        debug_def = True
        debug = True if flask.request.json['debug'] else False

    otp_auth = False
    otp_auth_def = False
    if 'otp_auth' in flask.request.json:
        otp_auth_def = True
        otp_auth = True if flask.request.json['otp_auth'] else False

    lzo_compression = False
    lzo_compression_def = False
    if 'lzo_compression' in flask.request.json:
        lzo_compression_def = True
        lzo_compression = True if flask.request.json[
            'lzo_compression'] else False

    cipher = None
    cipher_def = False
    if 'cipher' in flask.request.json:
        cipher_def = True
        cipher = flask.request.json['cipher']

        if cipher not in CIPHERS:
            return utils.jsonify({
                'error': CIPHER_INVALID,
                'error_msg': CIPHER_INVALID_MSG,
            }, 400)

    hash = None
    hash_def = False
    if 'hash' in flask.request.json:
        hash_def = True
        hash = flask.request.json['hash']

        if hash not in HASHES:
            return utils.jsonify({
                'error': HASH_INVALID,
                'error_msg': HASH_INVALID_MSG,
            }, 400)

    jumbo_frames = False
    jumbo_frames_def = False
    if 'jumbo_frames' in flask.request.json:
        jumbo_frames_def = True
        jumbo_frames = True if flask.request.json[
            'jumbo_frames'] else False

    if not server_id:
        if not name_def:
            return utils.jsonify({
                'error': MISSING_PARAMS,
                'error_msg': MISSING_PARAMS_MSG,
            }, 400)

        if network_def and network_mode == BRIDGE and \
                (not network_start or not network_end):
            return utils.jsonify({
                'error': MISSING_PARAMS,
                'error_msg': MISSING_PARAMS_MSG,
            }, 400)

        if not network_def:
            network_def = True
            rand_range = range(215, 250)
            rand_range_low = range(15, 215)
            random.shuffle(rand_range)
            random.shuffle(rand_range_low)
            rand_range += rand_range_low
            for i in rand_range:
                rand_network = '192.168.%s.0/24' % i
                if not _check_network_overlap(rand_network, network_used):
                    network = rand_network
                    break
            if not network:
                return utils.jsonify({
                    'error': NETWORK_IN_USE,
                    'error_msg': NETWORK_IN_USE_MSG,
                }, 400)

        if not port_def:
            port_def = True
            rand_ports = range(10000, 19999)
            random.shuffle(rand_ports)
            for rand_port in rand_ports:
                if '%s%s' % (rand_port, protocol) not in port_used:
                    port = rand_port
                    break
            if not port:
                return utils.jsonify({
                    'error': PORT_PROTOCOL_IN_USE,
                    'error_msg': PORT_PROTOCOL_IN_USE_MSG,
                }, 400)

        if not dh_param_bits_def:
            dh_param_bits_def = True
            dh_param_bits = settings.vpn.default_dh_param_bits

    if network_def:
        if _check_network_overlap(network, network_used):
            return utils.jsonify({
                'error': NETWORK_IN_USE,
                'error_msg': NETWORK_IN_USE_MSG,
            }, 400)

    if port_def:
        if '%s%s' % (port, protocol) in port_used:
            return utils.jsonify({
                'error': PORT_PROTOCOL_IN_USE,
                'error_msg': PORT_PROTOCOL_IN_USE_MSG,
            }, 400)

    if not server_id:
        if network_mode == BRIDGE:
            if not _check_network_range(network, network_start, network_end):
                return utils.jsonify({
                    'error': BRIDGE_NETWORK_INVALID,
                    'error_msg': BRIDGE_NETWORK_INVALID_MSG,
                }, 400)

            if ipv6:
                return utils.jsonify({
                    'error': IPV6_BRIDGED_INVALID,
                    'error_msg': IPV6_BRIDGED_INVALID_MSG,
                }, 400)

        svr = server.new_server(
            name=name,
            network=network,
            network_mode=network_mode,
            network_start=network_start,
            network_end=network_end,
            restrict_routes=restrict_routes,
            ipv6=ipv6,
            ipv6_firewall=ipv6_firewall,
            bind_address=bind_address,
            port=port,
            protocol=protocol,
            dh_param_bits=dh_param_bits,
            multi_device=multi_device,
            dns_servers=dns_servers,
            search_domain=search_domain,
            otp_auth=otp_auth,
            cipher=cipher,
            hash=hash,
            jumbo_frames=jumbo_frames,
            lzo_compression=lzo_compression,
            inter_client=inter_client,
            ping_interval=ping_interval,
            ping_timeout=ping_timeout,
            link_ping_interval=link_ping_interval,
            link_ping_timeout=link_ping_timeout,
            max_clients=max_clients,
            replica_count=replica_count,
            dns_mapping=dns_mapping,
            debug=debug,
        )
        svr.add_host(settings.local.host_id)
        svr.commit()
    else:
        svr = server.get_by_id(server_id)
        if svr.status == ONLINE:
            return utils.jsonify({
                'error': SERVER_NOT_OFFLINE,
                'error_msg': SERVER_NOT_OFFLINE_SETTINGS_MSG,
            }, 400)

        for link_svr in svr.iter_links(fields=('status',)):
            if link_svr.status == ONLINE:
                return utils.jsonify({
                    'error': SERVER_LINKS_NOT_OFFLINE,
                    'error_msg': SERVER_LINKS_NOT_OFFLINE_SETTINGS_MSG,
                }, 400)

        if name_def:
            svr.name = name
        if network_def:
            svr.network = network
        if network_start_def:
            svr.network_start = network_start
        if network_end_def:
            svr.network_end = network_end
        if restrict_routes_def:
            svr.restrict_routes = restrict_routes
        if ipv6_def:
            svr.ipv6 = ipv6
        if ipv6_firewall_def:
            svr.ipv6_firewall = ipv6_firewall
        if network_mode_def:
            if network_mode == BRIDGE and (
                    not network_start or not network_end):
                return utils.jsonify({
                    'error': MISSING_PARAMS,
                    'error_msg': MISSING_PARAMS_MSG,
                }, 400)
            svr.network_mode = network_mode
        if bind_address_def:
            svr.bind_address = bind_address
        if port_def:
            svr.port = port
        if protocol_def:
            svr.protocol = protocol
        if dh_param_bits_def and svr.dh_param_bits != dh_param_bits:
            svr.dh_param_bits = dh_param_bits
            svr.generate_dh_param()
        if multi_device_def:
            svr.multi_device = multi_device
        if dns_servers_def:
            svr.dns_servers = dns_servers
        if search_domain_def:
            svr.search_domain = search_domain
        if otp_auth_def:
            svr.otp_auth = otp_auth
        if cipher_def:
            svr.cipher = cipher
        if hash_def:
            svr.hash = hash
        if jumbo_frames_def:
            svr.jumbo_frames = jumbo_frames
        if lzo_compression_def:
            svr.lzo_compression = lzo_compression
        if inter_client_def:
            svr.inter_client = inter_client
        if ping_interval_def:
            svr.ping_interval = ping_interval
        if ping_timeout_def:
            svr.ping_timeout = ping_timeout
        if link_ping_interval_def:
            svr.link_ping_interval = link_ping_interval
        if link_ping_timeout_def:
            svr.link_ping_timeout = link_ping_timeout
        if max_clients_def:
            svr.max_clients = max_clients
        if replica_count_def:
            svr.replica_count = replica_count
        if dns_mapping_def:
            svr.dns_mapping = dns_mapping
        if debug_def:
            svr.debug = debug

        if svr.network_mode == BRIDGE:
            if not _check_network_range(svr.network, svr.network_start,
                    svr.network_end):
                return utils.jsonify({
                    'error': BRIDGE_NETWORK_INVALID,
                    'error_msg': BRIDGE_NETWORK_INVALID_MSG,
                }, 400)

            if svr.ipv6:
                return utils.jsonify({
                    'error': IPV6_BRIDGED_INVALID,
                    'error_msg': IPV6_BRIDGED_INVALID_MSG,
                }, 400)

        if svr.links and svr.replica_count > 1:
            return utils.jsonify({
                'error': SERVER_LINKS_AND_REPLICA,
                'error_msg': SERVER_LINKS_AND_REPLICA_MSG,
            }, 400)

        svr.commit(svr.changed)

    logger.LogEntry(message='Created server "%s".' % svr.name)
    event.Event(type=SERVERS_UPDATED)
    event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr.id)
    for org in svr.iter_orgs():
        event.Event(type=USERS_UPDATED, resource_id=org.id)
    return utils.jsonify(svr.dict())
Пример #51
0
def server_routes_post(server_id):
    if settings.app.demo_mode:
        return utils.demo_blocked()

    svr = server.get_by_id(server_id)

    for route_data in flask.request.json:
        route_network = route_data['network']
        comment = route_data.get('comment') or None
        metric = route_data.get('metric') or None
        nat_route = True if route_data.get('nat') else False
        nat_interface = route_data.get('nat_interface') or None
        nat_netmap = route_data.get('nat_netmap') or None
        advertise = True if route_data.get('advertise') else False
        net_gateway = True if route_data.get('net_gateway') else False

        try:
            route = svr.upsert_route(route_network, nat_route, nat_interface,
                nat_netmap, advertise, None, None, net_gateway, comment,
                metric)
        except ServerOnlineError:
            return utils.jsonify({
                'error': SERVER_ROUTE_ONLINE,
                'error_msg': SERVER_ROUTE_ONLINE_MSG,
            }, 400)
        except NetworkInvalid:
            return utils.jsonify({
                'error': SERVER_ROUTE_INVALID,
                'error_msg': SERVER_ROUTE_INVALID_MSG,
            }, 400)
        except ServerRouteNatVirtual:
            return utils.jsonify({
                'error': SERVER_ROUTE_VIRTUAL_NAT,
                'error_msg': SERVER_ROUTE_VIRTUAL_NAT_MSG,
            }, 400)
        except ServerRouteNatServerLink:
            return utils.jsonify({
                'error': SERVER_ROUTE_SERVER_LINK_NAT,
                'error_msg': SERVER_ROUTE_SERVER_LINK_NAT_MSG,
            }, 400)
        except ServerRouteGatewayNetworkLink:
            return utils.jsonify({
                'error': SERVER_ROUTE_NETWORK_LINK_GATEWAY,
                'error_msg': SERVER_ROUTE_NETWORK_LINK_GATEWAY_MSG,
            }, 400)
        except ServerRouteNatNetGateway:
            return utils.jsonify({
                'error': SERVER_ROUTE_NET_GATEWAY_NAT,
                'error_msg': SERVER_ROUTE_NET_GATEWAY_NAT_MSG,
            }, 400)
        except ServerRouteNonNatNetmap:
            return utils.jsonify({
                'error': SERVER_ROUTE_NON_NAT_NETMAP,
                'error_msg': SERVER_ROUTE_NON_NAT_NETMAP_MSG,
            }, 400)

    err, err_msg = svr.validate_conf()
    if err:
        return utils.jsonify({
            'error': err,
            'error_msg': err_msg,
        }, 400)

    svr.commit('routes')

    event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr.id)
    for svr_link in svr.links:
        event.Event(type=SERVER_ROUTES_UPDATED,
            resource_id=svr_link['server_id'])

    return utils.jsonify(route)