Beispiel #1
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')
    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)

    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)
Beispiel #2
0
def sso_duo_post():
    sso_mode = settings.app.sso
    token = utils.filter_str(flask.request.json.get("token")) or None
    passcode = utils.filter_str(flask.request.json.get("passcode")) or None

    if not token or not passcode:
        return utils.jsonify({"error": TOKEN_INVALID, "error_msg": TOKEN_INVALID_MSG}, 401)

    tokens_collection = mongo.get_collection("sso_tokens")
    doc = tokens_collection.find_one({"_id": token})
    if not doc or doc["_id"] != token:
        return utils.jsonify({"error": TOKEN_INVALID, "error_msg": TOKEN_INVALID_MSG}, 401)

    username = doc["username"]
    email = doc["email"]
    org_id = doc["org_id"]
    groups = doc["groups"]

    duo_auth = sso.Duo(
        username=username,
        factor=settings.app.sso_duo_mode,
        remote_ip=utils.get_remote_addr(),
        auth_type="Key",
        passcode=passcode,
    )
    valid = duo_auth.authenticate()
    if not valid:
        return utils.jsonify({"error": PASSCODE_INVALID, "error_msg": PASSCODE_INVALID_MSG}, 401)

    org = organization.get_by_id(org_id)
    if not org:
        return flask.abort(405)

    usr = org.find_user(name=username)
    if not usr:
        usr = org.new_user(
            name=username, email=email, type=CERT_CLIENT, auth_type=sso_mode, groups=list(groups) if groups else None
        )
        usr.audit_event("user_created", "User created with single sign-on", remote_addr=utils.get_remote_addr())

        event.Event(type=ORGS_UPDATED)
        event.Event(type=USERS_UPDATED, resource_id=org.id)
        event.Event(type=SERVERS_UPDATED)
    else:
        if usr.disabled:
            return flask.abort(403)

        if groups and groups - set(usr.groups or []):
            usr.groups = list(set(usr.groups or []) | groups)
            usr.commit("groups")

        if usr.auth_type != sso_mode:
            usr.auth_type = sso_mode
            usr.commit("auth_type")

    key_link = org.create_user_key_link(usr.id, one_time=True)

    usr.audit_event("user_profile", "User profile viewed from single sign-on", remote_addr=utils.get_remote_addr())

    return utils.jsonify({"redirect": utils.get_url_root() + key_link["view_url"]}, 200)
Beispiel #3
0
def user_post(org_id):
    org = organization.get_org(id=org_id)
    users = []

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

    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')
        user = org.new_user(type=CERT_CLIENT, name=name, email=email,
            disabled=disabled)
        users.append(user.dict())

    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])
Beispiel #4
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.static = bool(flask.request.json.get('static'))
    hst.public_address = utils.filter_str(
        flask.request.json.get('public_address'))
    hst.local_address = utils.filter_str(
        flask.request.json.get('local_address'))

    hst.commit(('name', 'timeout', 'priority', 'static', 'public_address',
                'local_address'))

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify(hst.dict())
Beispiel #5
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_str(
        flask.request.json.get('preferred_ike')) or None
    preferred_esp = utils.filter_str(
        flask.request.json.get('preferred_esp')) or None

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

    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())
Beispiel #6
0
def user_put(org_id, user_id):
    org = organization.get_by_id(org_id)
    user = org.get_user(user_id)

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

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

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

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

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

        for svr in org.iter_servers(fields=server.dict_fields + \
                ['hosts', 'links',  'replica_count', 'tls_auth_key',
                    'ca_certificate']):
            for instance in svr.instances:
                for client in instance['clients']:
                    if client['id'] == user_id:
                        svr.restart()
                        break
                if user_id in instance['clients']:
                    svr.restart()
    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:
        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())
Beispiel #7
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())
Beispiel #8
0
def user_put(org_id, user_id):
    org = Organization.get_org(id=org_id)
    user = org.get_user(user_id)

    name = flask.request.json.get('name')
    if name:
        name = utils.filter_str(name)

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

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

    if name:
        user.rename(name)
    else:
        user.commit()
        Event(type=USERS_UPDATED, resource_id=user.org.id)

    if disabled:
        if user.type == CERT_CLIENT:
            LogEntry(message='Disabled user "%s".' % user.name)

        for server in org.iter_servers():
            server_clients = server.clients
            if user_id in server_clients:
                server.restart()
    elif disabled == False and user.type == CERT_CLIENT:
        LogEntry(message='Enabled user "%s".' % user.name)

    send_key_email = flask.request.json.get('send_key_email')
    if send_key_email and user.email:
        try:
            user.send_key_email(send_key_email)
        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 EmailApiKeyInvalid:
            return utils.jsonify({
                'error': EMAIL_API_KEY_INVALID,
                'error_msg': EMAIL_API_KEY_INVALID_MSG,
            }, 400)

    return utils.jsonify(user.dict())
Beispiel #9
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)
Beispiel #10
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)
Beispiel #11
0
def sso_yubico_post():
    remote_addr = utils.get_remote_addr()
    sso_mode = settings.app.sso
    token = utils.filter_str(flask.request.json.get('token')) or None
    key = utils.filter_str(flask.request.json.get('key')) or None

    if sso_mode not in (GOOGLE_YUBICO_AUTH, SLACK_YUBICO_AUTH,
            SAML_YUBICO_AUTH, SAML_OKTA_YUBICO_AUTH,
            SAML_ONELOGIN_YUBICO_AUTH):
        return flask.abort(404)

    if not token or not key:
        return utils.jsonify({
            'error': TOKEN_INVALID,
            'error_msg': TOKEN_INVALID_MSG,
        }, 401)

    tokens_collection = mongo.get_collection('sso_tokens')
    doc = tokens_collection.find_and_modify(query={
        '_id': token,
    }, remove=True)
    if not doc or doc['_id'] != token or doc['type'] != YUBICO_AUTH:
        journal.entry(
            journal.SSO_AUTH_FAILURE,
            remote_address=remote_addr,
            reason=journal.SSO_AUTH_REASON_INVALID_TOKEN,
            reason_long='Invalid Yubikey authentication token',
        )

        return utils.jsonify({
            'error': TOKEN_INVALID,
            'error_msg': TOKEN_INVALID_MSG,
        }, 401)

    username = doc['username']
    email = doc['email']
    org_id = doc['org_id']
    groups = set(doc['groups'] or [])

    valid, yubico_id = sso.auth_yubico(key)
    if not valid or not yubico_id:
        journal.entry(
            journal.SSO_AUTH_FAILURE,
            username=username,
            remote_address=remote_addr,
            reason=journal.SSO_AUTH_REASON_YUBIKEY_FAILED,
            reason_long='Yubikey authentication failed',
        )

        return utils.jsonify({
            'error': YUBIKEY_INVALID,
            'error_msg': YUBIKEY_INVALID_MSG,
        }, 401)

    return _validate_user(username, email, sso_mode, org_id, groups,
        remote_addr, yubico_id=yubico_id)
Beispiel #12
0
def sso_yubico_post():
    remote_addr = utils.get_remote_addr()
    sso_mode = settings.app.sso
    token = utils.filter_str(flask.request.json.get('token')) or None
    key = utils.filter_str(flask.request.json.get('key')) or None

    if sso_mode not in (AZURE_YUBICO_AUTH, GOOGLE_YUBICO_AUTH,
            AUTHZERO_YUBICO_AUTH, SLACK_YUBICO_AUTH, SAML_YUBICO_AUTH,
            SAML_OKTA_YUBICO_AUTH, SAML_ONELOGIN_YUBICO_AUTH):
        return flask.abort(404)

    if not token or not key:
        return utils.jsonify({
            'error': TOKEN_INVALID,
            'error_msg': TOKEN_INVALID_MSG,
        }, 401)

    tokens_collection = mongo.get_collection('sso_tokens')
    doc = tokens_collection.find_and_modify(query={
        '_id': token,
    }, remove=True)
    if not doc or doc['_id'] != token or doc['type'] != YUBICO_AUTH:
        journal.entry(
            journal.SSO_AUTH_FAILURE,
            remote_address=remote_addr,
            reason=journal.SSO_AUTH_REASON_INVALID_TOKEN,
            reason_long='Invalid Yubikey authentication token',
        )

        return utils.jsonify({
            'error': TOKEN_INVALID,
            'error_msg': TOKEN_INVALID_MSG,
        }, 401)

    username = doc['username']
    email = doc['email']
    org_id = doc['org_id']
    groups = set(doc['groups'] or [])

    valid, yubico_id = sso.auth_yubico(key)
    if not valid or not yubico_id:
        journal.entry(
            journal.SSO_AUTH_FAILURE,
            username=username,
            remote_address=remote_addr,
            reason=journal.SSO_AUTH_REASON_YUBIKEY_FAILED,
            reason_long='Yubikey authentication failed',
        )

        return utils.jsonify({
            'error': YUBIKEY_INVALID,
            'error_msg': YUBIKEY_INVALID_MSG,
        }, 401)

    return _validate_user(username, email, sso_mode, org_id, groups,
        remote_addr, yubico_id=yubico_id)
Beispiel #13
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({})
Beispiel #14
0
def user_put(org_id, user_id):
    org = organization.get_by_id(org_id)
    user = org.get_user(user_id)

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

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

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

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

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

        for svr in org.iter_servers(fields=server.dict_fields + \
                ['hosts', 'links',  'replica_count', 'tls_auth_key',
                    'ca_certificate']):
            for instance in svr.instances:
                for client in instance['clients']:
                    if client['id'] == user_id:
                        svr.restart()
                        break
                if user_id in instance['clients']:
                    svr.restart()
    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:
        try:
            user.send_key_email(send_key_email)
        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())
Beispiel #15
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])
Beispiel #16
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)

    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)

    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({})
Beispiel #17
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)
Beispiel #18
0
def user_post(org_id):
    org = Organization.get_org(id=org_id)
    name = utils.filter_str(flask.request.json["name"])
    email = None
    if "email" in flask.request.json:
        email = utils.filter_str(flask.request.json["email"])
    user = org.new_user(type=CERT_CLIENT, name=name, email=email)

    disabled = flask.request.json.get("disabled")
    if disabled is not None:
        user.disabled = disabled
        user.commit()

    return utils.jsonify(user.dict())
Beispiel #19
0
def user_put(org_id, user_id):
    org = organization.get_org(id=org_id)
    user = org.get_user(user_id)

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

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

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

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

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

        for svr in org.iter_servers():
            server_clients = svr.clients
            if user_id in server_clients:
                svr.restart()
    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:
        try:
            user.send_key_email(send_key_email)
        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 EmailApiKeyInvalid:
            return utils.jsonify({
                'error': EMAIL_API_KEY_INVALID,
                'error_msg': EMAIL_API_KEY_INVALID_MSG,
            }, 400)

    return utils.jsonify(user.dict())
Beispiel #20
0
def user_put(org_id, user_id):
    org = organization.get_org(id=org_id)
    user = org.get_user(user_id)

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

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

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

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

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

        for svr in org.iter_servers(fields=('instances',)):
            for instance in svr.instances:
                if user_id in instance['clients']:
                    svr.restart()
    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:
        try:
            user.send_key_email(send_key_email)
        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 EmailApiKeyInvalid:
            return utils.jsonify({
                'error': EMAIL_API_KEY_INVALID,
                'error_msg': EMAIL_API_KEY_INVALID_MSG,
            }, 400)

    return utils.jsonify(user.dict())
Beispiel #21
0
def host_put(host_id=None):
    hst = host.get_host(id=host_id)

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

    hst.commit(hst.changed)
    event.Event(type=HOSTS_UPDATED)

    return utils.jsonify(host.dict())
Beispiel #22
0
def user_put(org_id, user_id):
    org = organization.get_by_id(org_id)
    user = org.get_user(user_id)

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

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

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

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

    if disabled:
        user.disconnect()
        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:
        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())
Beispiel #23
0
def sso_yubico_post():
    sso_mode = settings.app.sso
    token = utils.filter_str(flask.request.json.get('token')) or None
    key = utils.filter_str(flask.request.json.get('key')) or None

    if sso_mode not in (GOOGLE_YUBICO_AUTH, SLACK_YUBICO_AUTH,
                        SAML_YUBICO_AUTH, SAML_OKTA_YUBICO_AUTH,
                        SAML_ONELOGIN_YUBICO_AUTH):
        return flask.abort(404)

    if not token or not key:
        return utils.jsonify(
            {
                'error': TOKEN_INVALID,
                'error_msg': TOKEN_INVALID_MSG,
            }, 401)

    tokens_collection = mongo.get_collection('sso_tokens')
    doc = tokens_collection.find_and_modify(query={
        '_id': token,
    },
                                            remove=True)
    if not doc or doc['_id'] != token or doc['type'] != YUBICO_AUTH:
        return utils.jsonify(
            {
                'error': TOKEN_INVALID,
                'error_msg': TOKEN_INVALID_MSG,
            }, 401)

    username = doc['username']
    email = doc['email']
    org_id = doc['org_id']
    groups = set(doc['groups'] or [])

    valid, yubico_id = sso.auth_yubico(key)
    if not valid or not yubico_id:
        return utils.jsonify(
            {
                'error': YUBIKEY_INVALID,
                'error_msg': YUBIKEY_INVALID_MSG,
            }, 401)

    return _validate_user(username,
                          email,
                          sso_mode,
                          org_id,
                          groups,
                          yubico_id=yubico_id)
Beispiel #24
0
def auth_put():
    admin = flask.g.administrator

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

    settings_commit = False
    if 'email_from' in flask.request.json:
        settings_commit = True
        email_from = flask.request.json['email_from']
        settings.app.email_from_addr = email_from or None
    if 'email_api_key' in flask.request.json:
        settings_commit = True
        email_api_key = flask.request.json['email_api_key']
        settings.app.email_api_key = email_api_key or None
    if settings_commit:
        settings.commit()

    admin.commit(admin.changed)

    response = flask.g.administrator.dict()
    response.update({
        'email_from': settings.app.email_from_addr,
        'email_api_key': settings.app.email_api_key,
    })
    return utils.jsonify(response)
Beispiel #25
0
def check_auth(username, password, remote_addr=None):
    username = utils.filter_str(username).lower()

    if remote_addr:
        doc = Administrator.limiter_collection.find_and_modify({
            '_id': remote_addr,
        }, {
            '$inc': {'count': 1},
            '$setOnInsert': {'timestamp': utils.now()},
        }, new=True, upsert=True)

        if utils.now() > doc['timestamp'] + datetime.timedelta(minutes=1):
            doc = {
                'count': 1,
                'timestamp': utils.now(),
            }
            Administrator.limiter_collection.update({
                '_id': remote_addr,
            }, doc, upsert=True)

        if doc['count'] > settings.app.auth_limiter_count_max:
            raise flask.abort(403)

    administrator = find_user(username=username)
    if not administrator:
        return
    if not administrator.test_password(password):
        return
    return administrator
Beispiel #26
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())
Beispiel #27
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())
Beispiel #28
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())
Beispiel #29
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())
Beispiel #30
0
def auth_put():
    administrator = flask.request.administrator
    system_conf = SystemConf()

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

    if 'email_from' in flask.request.json:
        email_from = flask.request.json['email_from']
        system_conf.set('email', 'from_addr', email_from or None)
    if 'email_api_key' in flask.request.json:
        email_api_key = flask.request.json['email_api_key']
        system_conf.set('email', 'api_key', email_api_key or None)

    system_conf.commit()
    administrator.commit()

    response = flask.request.administrator.dict()
    response.update({
        'email_from': system_conf.get('email', 'from_addr'),
        'email_api_key': system_conf.get('email', 'api_key'),
    })
    return utils.jsonify(response)
Beispiel #31
0
def auth_put():
    username = utils.filter_str(flask.request.json.get('username'))
    password = flask.request.json['password']
    token = flask.request.json.get('token')

    utils.set_auth(username, password, token)
    return utils.jsonify(utils.get_auth())
Beispiel #32
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):
        lnk.status = status

    if flask.request.json.get('key'):
        lnk.generate_key()

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

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify(lnk.dict())
Beispiel #33
0
def link_location_host_post(link_id, location_id):
    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)

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

    hst = link.Host(
        link=lnk,
        location=loc,
        name=name,
        link_id=lnk.id,
        location_id=loc.id,
    )

    hst.generate_secret()

    hst.commit()

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify(hst.dict())
Beispiel #34
0
def org_put(org_id):
    org = organization.get_by_id(org_id)
    name = utils.filter_str(flask.request.json['name'])
    org.name = name
    org.commit(org.changed)
    event.Event(type=ORGS_UPDATED)
    return utils.jsonify(org.dict())
Beispiel #35
0
def auth_put():
    admin = flask.g.administrator

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

    settings_commit = False
    if 'email_from' in flask.request.json:
        settings_commit = True
        email_from = flask.request.json['email_from']
        settings.app.email_from_addr = email_from or None
    if 'email_api_key' in flask.request.json:
        settings_commit = True
        email_api_key = flask.request.json['email_api_key']
        settings.app.email_api_key = email_api_key or None
    if settings_commit:
        settings.commit()

    admin.commit(admin.changed)

    response = flask.g.administrator.dict()
    response.update({
        'email_from': settings.app.email_from_addr,
        'email_api_key': settings.app.email_api_key,
    })
    return utils.jsonify(response)
Beispiel #36
0
def user_put(org_id, user_id):
    org = Organization.get_org(id=org_id)
    user = org.get_user(user_id)
    name = utils.filter_str(flask.request.json['name'])
    user.rename(name)

    return utils.jsonify(user.dict())
Beispiel #37
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())
Beispiel #38
0
def user_post(org_id):
    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')

            user = org.new_user(type=CERT_CLIENT,
                                name=name,
                                email=email,
                                disabled=disabled)

            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])
Beispiel #39
0
def auth_put():
    username = utils.filter_str(flask.request.json.get('username'))
    password = flask.request.json['password']

    utils.set_auth(username, password)
    return utils.jsonify({
        'username': utils.get_auth(),
    })
Beispiel #40
0
def user_put(org_id, user_id):
    org = organization.get_by_id(org_id)
    user = org.get_user(user_id)

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

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

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

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

    if disabled:
        user.disconnect()
        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:
        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())
Beispiel #41
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({})
Beispiel #42
0
def link_location_host_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)

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

    hst = link.Host(
        link=lnk,
        location=loc,
        link_id=lnk.id,
        location_id=loc.id,
        name=name,
        timeout=timeout,
        priority=priority,
        static=static,
        public_address=public_address,
        local_address=local_address,
    )

    hst.generate_secret()

    hst.commit()

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify(hst.dict())
Beispiel #43
0
def user_post(org_id):
    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')

            user = org.new_user(type=CERT_CLIENT, name=name, email=email,
                disabled=disabled)

            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])
Beispiel #44
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())
Beispiel #45
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())
Beispiel #46
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):
        lnk.status = status

    if flask.request.json.get('key'):
        lnk.generate_key()

    lnk.ipv6 = True if flask.request.json.get('ipv6') else False

    lnk.host_check = True if flask.request.json.get('host_check') else False

    lnk.action = RESTART if flask.request.json.get(
        'action') == RESTART else HOLD

    lnk.preferred_ike = utils.filter_str(
        flask.request.json.get('preferred_ike')) or None
    lnk.preferred_esp = utils.filter_str(
        flask.request.json.get('preferred_esp')) or None

    lnk.commit(('name', 'status', 'key', 'ipv6', 'host_check', 'action',
                'preferred_ike', 'preferred_esp'))

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify(lnk.dict())
Beispiel #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:
        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())
Beispiel #48
0
def user_put(org_id, user_id):
    org = Organization.get_org(id=org_id)
    user = org.get_user(user_id)

    name = flask.request.json.get("name")
    if name:
        name = utils.filter_str(name)

    if "email" in flask.request.json:
        email = flask.request.json["email"]
        if email:
            user.email = utils.filter_str(email)
        else:
            user.email = None

    disabled = flask.request.json.get("disabled")
    if disabled is not None:
        user.disabled = disabled

    if name:
        user.rename(name)
    else:
        user.commit()
        Event(type=USERS_UPDATED, resource_id=user.org.id)

    if disabled:
        if user.type == CERT_CLIENT:
            LogEntry(message='Disabled user "%s".' % user.name)

        for server in org.iter_servers():
            server_clients = server.clients
            if user_id in server_clients:
                server.restart()
    elif disabled == False and user.type == CERT_CLIENT:
        LogEntry(message='Enabled user "%s".' % user.name)

    return utils.jsonify(user.dict())
Beispiel #49
0
def link_post():
    if settings.app.demo_mode:
        return utils.demo_blocked()

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

    lnk = link.Link(
        name=name,
        status=ONLINE,
    )
    lnk.commit()

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify(lnk.dict())
Beispiel #50
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

    lnk = link.Link(
        name=name,
        type=type,
        status=ONLINE,
    )

    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())
Beispiel #51
0
def org_post():
    if settings.app.demo_mode:
        return utils.demo_blocked()

    name = utils.filter_str(flask.request.json['name'])
    auth_api = flask.request.json.get('auth_api', False)

    org = organization.new_org(name=name, auth_api=None, type=ORG_DEFAULT)

    if auth_api:
        org.auth_api = True
        org.generate_auth_token()
        org.generate_auth_secret()
        org.commit()

    logger.LogEntry(message='Created new organization "%s".' % org.name)
    event.Event(type=ORGS_UPDATED)
    return utils.jsonify(org.dict())
Beispiel #52
0
def link_location_put(link_id, location_id):
    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)

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

    loc.commit('name')

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify(loc.dict())
Beispiel #53
0
def link_post():
    if settings.local.sub_plan != 'enterprise_plus':
        return flask.abort(404)

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

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

    lnk = link.Link(
        name=name,
        status=ONLINE,
    )

    lnk.generate_key()

    lnk.commit()

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify(lnk.dict())
Beispiel #54
0
def check_auth(username, password, remote_addr=None):
    username = utils.filter_str(username).lower()

    if remote_addr:
        doc = Administrator.limiter_collection.find_and_modify(
            {
                '_id': remote_addr,
            }, {
                '$inc': {
                    'count': 1
                },
                '$setOnInsert': {
                    'timestamp': utils.now()
                },
            },
            new=True,
            upsert=True)

        if utils.now() > doc['timestamp'] + datetime.timedelta(minutes=1):
            doc = {
                'count': 1,
                'timestamp': utils.now(),
            }
            Administrator.limiter_collection.update({
                '_id': remote_addr,
            },
                                                    doc,
                                                    upsert=True)

        if doc['count'] > settings.app.auth_limiter_count_max:
            raise flask.abort(403)

    administrator = find_user(username=username)
    if not administrator:
        return
    if not administrator.test_password(password):
        return
    return administrator
Beispiel #55
0
def link_location_post(link_id):
    if settings.local.sub_plan != 'enterprise_plus':
        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)

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

    loc = link.Location(
        link=lnk,
        name=name,
        link_id=lnk.id,
    )
    loc.commit()

    event.Event(type=LINKS_UPDATED)

    return utils.jsonify(loc.dict())
Beispiel #56
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

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

    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 = 2000

    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,
            onc_hostname=onc_hostname,
            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 onc_hostname_def:
            svr.onc_hostname = onc_hostname
        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())