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, })
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({})
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({})
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, })
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())
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())
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)
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, })
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)
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())
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({})
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({})
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)
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())
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())
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())
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({})
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())
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)
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({})
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])
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())
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({})
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({})
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({})
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())
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)
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({})
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({})
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())
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
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())
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())
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())
def subscription_delete(): if settings.app.demo_mode: return utils.demo_blocked() subscription.update_license(None) return utils.jsonify({})
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)
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)
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())
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({})
def server_output_delete(server_id): if settings.app.demo_mode: return utils.demo_blocked() server.output_clear(server_id) return utils.jsonify({})
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)
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())
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
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)
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({})
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])
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())
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)
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())
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())
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)