def server_route_put(server_id, route_network): if settings.app.demo_mode: return utils.demo_blocked() svr = server.get_by_id(server_id) route_network = route_network.decode('hex') nat_route = True if flask.request.json.get('nat') else False nat_interface = flask.request.json.get('nat_interface') or None vpc_region = utils.filter_str(flask.request.json.get('vpc_region')) or None vpc_id = utils.filter_str(flask.request.json.get('vpc_id')) or None try: route = svr.upsert_route(route_network, nat_route, nat_interface, vpc_region, vpc_id) except ServerOnlineError: return utils.jsonify( { 'error': SERVER_ROUTE_ONLINE, 'error_msg': SERVER_ROUTE_ONLINE_MSG, }, 400) except NetworkInvalid: return utils.jsonify( { 'error': SERVER_ROUTE_INVALID, 'error_msg': SERVER_ROUTE_INVALID_MSG, }, 400) except ServerRouteNatVirtual: return utils.jsonify( { 'error': SERVER_ROUTE_VIRTUAL_NAT, 'error_msg': SERVER_ROUTE_VIRTUAL_NAT_MSG, }, 400) except ServerRouteNatServerLink: return utils.jsonify( { 'error': SERVER_ROUTE_SERVER_LINK_NAT, 'error_msg': SERVER_ROUTE_SERVER_LINK_NAT_MSG, }, 400) except ServerRouteNatNetworkLink: return utils.jsonify( { 'error': SERVER_ROUTE_NETWORK_LINK_NAT, 'error_msg': SERVER_ROUTE_NETWORK_LINK_NAT_MSG, }, 400) err, err_msg = svr.validate_conf() if err: return utils.jsonify({ 'error': err, 'error_msg': err_msg, }, 400) svr.commit('routes') event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr.id) for svr_link in svr.links: event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr_link['server_id']) return utils.jsonify(route)
def sso_duo_post(): sso_mode = settings.app.sso token = utils.filter_str(flask.request.json.get("token")) or None passcode = utils.filter_str(flask.request.json.get("passcode")) or None if not token or not passcode: return utils.jsonify({"error": TOKEN_INVALID, "error_msg": TOKEN_INVALID_MSG}, 401) tokens_collection = mongo.get_collection("sso_tokens") doc = tokens_collection.find_one({"_id": token}) if not doc or doc["_id"] != token: return utils.jsonify({"error": TOKEN_INVALID, "error_msg": TOKEN_INVALID_MSG}, 401) username = doc["username"] email = doc["email"] org_id = doc["org_id"] groups = doc["groups"] duo_auth = sso.Duo( username=username, factor=settings.app.sso_duo_mode, remote_ip=utils.get_remote_addr(), auth_type="Key", passcode=passcode, ) valid = duo_auth.authenticate() if not valid: return utils.jsonify({"error": PASSCODE_INVALID, "error_msg": PASSCODE_INVALID_MSG}, 401) org = organization.get_by_id(org_id) if not org: return flask.abort(405) usr = org.find_user(name=username) if not usr: usr = org.new_user( name=username, email=email, type=CERT_CLIENT, auth_type=sso_mode, groups=list(groups) if groups else None ) usr.audit_event("user_created", "User created with single sign-on", remote_addr=utils.get_remote_addr()) event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SERVERS_UPDATED) else: if usr.disabled: return flask.abort(403) if groups and groups - set(usr.groups or []): usr.groups = list(set(usr.groups or []) | groups) usr.commit("groups") if usr.auth_type != sso_mode: usr.auth_type = sso_mode usr.commit("auth_type") key_link = org.create_user_key_link(usr.id, one_time=True) usr.audit_event("user_profile", "User profile viewed from single sign-on", remote_addr=utils.get_remote_addr()) return utils.jsonify({"redirect": utils.get_url_root() + key_link["view_url"]}, 200)
def user_post(org_id): org = organization.get_org(id=org_id) users = [] if isinstance(flask.request.json, list): users_data = flask.request.json else: users_data = [flask.request.json] for user_data in users_data: name = utils.filter_str(user_data['name']) email = utils.filter_str(user_data.get('email')) disabled = user_data.get('disabled') user = org.new_user(type=CERT_CLIENT, name=name, email=email, disabled=disabled) users.append(user.dict()) event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SERVERS_UPDATED) if isinstance(flask.request.json, list): logger.LogEntry(message='Created %s new users.' % len( flask.request.json)) return utils.jsonify(users) else: logger.LogEntry(message='Created new user "%s".' % users[0]['name']) return utils.jsonify(users[0])
def link_location_host_put(link_id, location_id, host_id): if not settings.local.sub_plan or \ 'enterprise' not in settings.local.sub_plan: return flask.abort(404) if settings.app.demo_mode: return utils.demo_blocked() lnk = link.get_by_id(link_id) if not lnk: return flask.abort(404) loc = lnk.get_location(location_id) if not loc: return flask.abort(404) hst = loc.get_host(host_id) if not hst: return flask.abort(404) hst.name = utils.filter_str(flask.request.json.get('name')) or 'undefined' hst.timeout = abs(int(flask.request.json.get('timeout') or 0)) or None hst.priority = abs(int(flask.request.json.get('priority') or 1)) or 1 hst.static = bool(flask.request.json.get('static')) hst.public_address = utils.filter_str( flask.request.json.get('public_address')) hst.local_address = utils.filter_str( flask.request.json.get('local_address')) hst.commit(('name', 'timeout', 'priority', 'static', 'public_address', 'local_address')) event.Event(type=LINKS_UPDATED) return utils.jsonify(hst.dict())
def link_post(): if not settings.local.sub_plan or \ 'enterprise' not in settings.local.sub_plan: return flask.abort(404) if settings.app.demo_mode: return utils.demo_blocked() name = utils.filter_str(flask.request.json.get('name')) or 'undefined' type = DIRECT if flask.request.json.get('type') == DIRECT \ else SITE_TO_SITE ipv6 = True if flask.request.json.get('ipv6') else False host_check = True if flask.request.json.get('host_check') else False action = RESTART if flask.request.json.get('action') == RESTART else HOLD preferred_ike = utils.filter_str( flask.request.json.get('preferred_ike')) or None preferred_esp = utils.filter_str( flask.request.json.get('preferred_esp')) or None lnk = link.Link( name=name, type=type, status=ONLINE, ipv6=ipv6, host_check=host_check, action=action, preferred_ike=preferred_ike, preferred_esp=preferred_esp, ) lnk.generate_key() lnk.commit() if lnk.type == DIRECT: try: loc = link.Location( link=lnk, name='server', type=DIRECT_SERVER, link_id=lnk.id, ) loc.commit() loc = link.Location( link=lnk, name='client', type=DIRECT_CLIENT, link_id=lnk.id, ) loc.commit() except: lnk.remove() raise event.Event(type=LINKS_UPDATED) return utils.jsonify(lnk.dict())
def user_put(org_id, user_id): org = organization.get_by_id(org_id) user = org.get_user(user_id) if 'name' in flask.request.json: user.name = utils.filter_str(flask.request.json['name']) or None if 'email' in flask.request.json: user.email = utils.filter_str(flask.request.json['email']) or None disabled = flask.request.json.get('disabled') if disabled is not None: user.disabled = disabled user.commit() event.Event(type=USERS_UPDATED, resource_id=user.org.id) if disabled: if user.type == CERT_CLIENT: logger.LogEntry(message='Disabled user "%s".' % user.name) for svr in org.iter_servers(fields=server.dict_fields + \ ['hosts', 'links', 'replica_count', 'tls_auth_key', 'ca_certificate']): for instance in svr.instances: for client in instance['clients']: if client['id'] == user_id: svr.restart() break if user_id in instance['clients']: svr.restart() elif disabled == False and user.type == CERT_CLIENT: logger.LogEntry(message='Enabled user "%s".' % user.name) send_key_email = flask.request.json.get('send_key_email') if send_key_email and user.email: try: user.send_key_email(flask.request.url_root[:-1]) except EmailNotConfiguredError: return utils.jsonify( { 'error': EMAIL_NOT_CONFIGURED, 'error_msg': EMAIL_NOT_CONFIGURED_MSG, }, 400) except EmailFromInvalid: return utils.jsonify( { 'error': EMAIL_FROM_INVALID, 'error_msg': EMAIL_FROM_INVALID_MSG, }, 400) except EmailAuthInvalid: return utils.jsonify( { 'error': EMAIL_AUTH_INVALID, 'error_msg': EMAIL_AUTH_INVALID_MSG, }, 400) return utils.jsonify(user.dict())
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 user_put(org_id, user_id): org = Organization.get_org(id=org_id) user = org.get_user(user_id) name = flask.request.json.get('name') if name: name = utils.filter_str(name) if 'email' in flask.request.json: email = flask.request.json['email'] if email: user.email = utils.filter_str(email) else: user.email = None disabled = flask.request.json.get('disabled') if disabled is not None: user.disabled = disabled if name: user.rename(name) else: user.commit() Event(type=USERS_UPDATED, resource_id=user.org.id) if disabled: if user.type == CERT_CLIENT: LogEntry(message='Disabled user "%s".' % user.name) for server in org.iter_servers(): server_clients = server.clients if user_id in server_clients: server.restart() elif disabled == False and user.type == CERT_CLIENT: LogEntry(message='Enabled user "%s".' % user.name) send_key_email = flask.request.json.get('send_key_email') if send_key_email and user.email: try: user.send_key_email(send_key_email) except EmailNotConfiguredError: return utils.jsonify({ 'error': EMAIL_NOT_CONFIGURED, 'error_msg': EMAIL_NOT_CONFIGURED_MSG, }, 400) except EmailFromInvalid: return utils.jsonify({ 'error': EMAIL_FROM_INVALID, 'error_msg': EMAIL_FROM_INVALID_MSG, }, 400) except EmailApiKeyInvalid: return utils.jsonify({ 'error': EMAIL_API_KEY_INVALID, 'error_msg': EMAIL_API_KEY_INVALID_MSG, }, 400) return utils.jsonify(user.dict())
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 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 sso_yubico_post(): remote_addr = utils.get_remote_addr() sso_mode = settings.app.sso token = utils.filter_str(flask.request.json.get('token')) or None key = utils.filter_str(flask.request.json.get('key')) or None if sso_mode not in (GOOGLE_YUBICO_AUTH, SLACK_YUBICO_AUTH, SAML_YUBICO_AUTH, SAML_OKTA_YUBICO_AUTH, SAML_ONELOGIN_YUBICO_AUTH): return flask.abort(404) if not token or not key: return utils.jsonify({ 'error': TOKEN_INVALID, 'error_msg': TOKEN_INVALID_MSG, }, 401) tokens_collection = mongo.get_collection('sso_tokens') doc = tokens_collection.find_and_modify(query={ '_id': token, }, remove=True) if not doc or doc['_id'] != token or doc['type'] != YUBICO_AUTH: journal.entry( journal.SSO_AUTH_FAILURE, remote_address=remote_addr, reason=journal.SSO_AUTH_REASON_INVALID_TOKEN, reason_long='Invalid Yubikey authentication token', ) return utils.jsonify({ 'error': TOKEN_INVALID, 'error_msg': TOKEN_INVALID_MSG, }, 401) username = doc['username'] email = doc['email'] org_id = doc['org_id'] groups = set(doc['groups'] or []) valid, yubico_id = sso.auth_yubico(key) if not valid or not yubico_id: journal.entry( journal.SSO_AUTH_FAILURE, username=username, remote_address=remote_addr, reason=journal.SSO_AUTH_REASON_YUBIKEY_FAILED, reason_long='Yubikey authentication failed', ) return utils.jsonify({ 'error': YUBIKEY_INVALID, 'error_msg': YUBIKEY_INVALID_MSG, }, 401) return _validate_user(username, email, sso_mode, org_id, groups, remote_addr, yubico_id=yubico_id)
def sso_yubico_post(): remote_addr = utils.get_remote_addr() sso_mode = settings.app.sso token = utils.filter_str(flask.request.json.get('token')) or None key = utils.filter_str(flask.request.json.get('key')) or None if sso_mode not in (AZURE_YUBICO_AUTH, GOOGLE_YUBICO_AUTH, AUTHZERO_YUBICO_AUTH, SLACK_YUBICO_AUTH, SAML_YUBICO_AUTH, SAML_OKTA_YUBICO_AUTH, SAML_ONELOGIN_YUBICO_AUTH): return flask.abort(404) if not token or not key: return utils.jsonify({ 'error': TOKEN_INVALID, 'error_msg': TOKEN_INVALID_MSG, }, 401) tokens_collection = mongo.get_collection('sso_tokens') doc = tokens_collection.find_and_modify(query={ '_id': token, }, remove=True) if not doc or doc['_id'] != token or doc['type'] != YUBICO_AUTH: journal.entry( journal.SSO_AUTH_FAILURE, remote_address=remote_addr, reason=journal.SSO_AUTH_REASON_INVALID_TOKEN, reason_long='Invalid Yubikey authentication token', ) return utils.jsonify({ 'error': TOKEN_INVALID, 'error_msg': TOKEN_INVALID_MSG, }, 401) username = doc['username'] email = doc['email'] org_id = doc['org_id'] groups = set(doc['groups'] or []) valid, yubico_id = sso.auth_yubico(key) if not valid or not yubico_id: journal.entry( journal.SSO_AUTH_FAILURE, username=username, remote_address=remote_addr, reason=journal.SSO_AUTH_REASON_YUBIKEY_FAILED, reason_long='Yubikey authentication failed', ) return utils.jsonify({ 'error': YUBIKEY_INVALID, 'error_msg': YUBIKEY_INVALID_MSG, }, 401) return _validate_user(username, email, sso_mode, org_id, groups, remote_addr, yubico_id=yubico_id)
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_put(org_id, user_id): org = organization.get_by_id(org_id) user = org.get_user(user_id) if 'name' in flask.request.json: user.name = utils.filter_str(flask.request.json['name']) or None if 'email' in flask.request.json: user.email = utils.filter_str(flask.request.json['email']) or None disabled = flask.request.json.get('disabled') if disabled is not None: user.disabled = disabled user.commit() event.Event(type=USERS_UPDATED, resource_id=user.org.id) if disabled: if user.type == CERT_CLIENT: logger.LogEntry(message='Disabled user "%s".' % user.name) for svr in org.iter_servers(fields=server.dict_fields + \ ['hosts', 'links', 'replica_count', 'tls_auth_key', 'ca_certificate']): for instance in svr.instances: for client in instance['clients']: if client['id'] == user_id: svr.restart() break if user_id in instance['clients']: svr.restart() elif disabled == False and user.type == CERT_CLIENT: logger.LogEntry(message='Enabled user "%s".' % user.name) send_key_email = flask.request.json.get('send_key_email') if send_key_email and user.email: try: user.send_key_email(send_key_email) except EmailNotConfiguredError: return utils.jsonify({ 'error': EMAIL_NOT_CONFIGURED, 'error_msg': EMAIL_NOT_CONFIGURED_MSG, }, 400) except EmailFromInvalid: return utils.jsonify({ 'error': EMAIL_FROM_INVALID, 'error_msg': EMAIL_FROM_INVALID_MSG, }, 400) except EmailAuthInvalid: return utils.jsonify({ 'error': EMAIL_AUTH_INVALID, 'error_msg': EMAIL_AUTH_INVALID_MSG, }, 400) return utils.jsonify(user.dict())
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 user_key_pin_put(key_id): doc = _find_doc({ 'key_id': key_id, }) if not doc: return flask.abort(404) if settings.app.demo_mode: return utils.demo_blocked() org = organization.get_by_id(doc['org_id']) usr = org.get_user(doc['user_id']) if usr.disabled: return flask.abort(403) current_pin = utils.filter_str( flask.request.json.get('current_pin')) or None pin = utils.filter_str(flask.request.json.get('pin')) or None if pin: if not pin.isdigit(): return utils.jsonify( { 'error': PIN_NOT_DIGITS, 'error_msg': PIN_NOT_DIGITS_MSG, }, 400) if len(pin) < settings.user.pin_min_length: return utils.jsonify( { 'error': PIN_TOO_SHORT, 'error_msg': PIN_TOO_SHORT_MSG, }, 400) if usr.pin and not usr.check_pin(current_pin): return utils.jsonify( { 'error': PIN_INVALID, 'error_msg': PIN_INVALID_MSG, }, 400) usr.set_pin(pin) usr.audit_event( 'user_updated', 'User pin changed with temporary profile link', remote_addr=utils.get_remote_addr(), ) usr.commit() event.Event(type=USERS_UPDATED, resource_id=org.id) return utils.jsonify({})
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 user_post(org_id): org = Organization.get_org(id=org_id) name = utils.filter_str(flask.request.json["name"]) email = None if "email" in flask.request.json: email = utils.filter_str(flask.request.json["email"]) user = org.new_user(type=CERT_CLIENT, name=name, email=email) disabled = flask.request.json.get("disabled") if disabled is not None: user.disabled = disabled user.commit() return utils.jsonify(user.dict())
def user_put(org_id, user_id): org = organization.get_org(id=org_id) user = org.get_user(user_id) if 'name' in flask.request.json: user.name = utils.filter_str(flask.request.json['name']) or None if 'email' in flask.request.json: user.email = utils.filter_str(flask.request.json['email']) or None disabled = flask.request.json.get('disabled') if disabled is not None: user.disabled = disabled user.commit() event.Event(type=USERS_UPDATED, resource_id=user.org.id) if disabled: if user.type == CERT_CLIENT: logger.LogEntry(message='Disabled user "%s".' % user.name) for svr in org.iter_servers(): server_clients = svr.clients if user_id in server_clients: svr.restart() elif disabled == False and user.type == CERT_CLIENT: logger.LogEntry(message='Enabled user "%s".' % user.name) send_key_email = flask.request.json.get('send_key_email') if send_key_email and user.email: try: user.send_key_email(send_key_email) except EmailNotConfiguredError: return utils.jsonify({ 'error': EMAIL_NOT_CONFIGURED, 'error_msg': EMAIL_NOT_CONFIGURED_MSG, }, 400) except EmailFromInvalid: return utils.jsonify({ 'error': EMAIL_FROM_INVALID, 'error_msg': EMAIL_FROM_INVALID_MSG, }, 400) except EmailApiKeyInvalid: return utils.jsonify({ 'error': EMAIL_API_KEY_INVALID, 'error_msg': EMAIL_API_KEY_INVALID_MSG, }, 400) return utils.jsonify(user.dict())
def user_put(org_id, user_id): org = organization.get_org(id=org_id) user = org.get_user(user_id) if 'name' in flask.request.json: user.name = utils.filter_str(flask.request.json['name']) or None if 'email' in flask.request.json: user.email = utils.filter_str(flask.request.json['email']) or None disabled = flask.request.json.get('disabled') if disabled is not None: user.disabled = disabled user.commit() event.Event(type=USERS_UPDATED, resource_id=user.org.id) if disabled: if user.type == CERT_CLIENT: logger.LogEntry(message='Disabled user "%s".' % user.name) for svr in org.iter_servers(fields=('instances',)): for instance in svr.instances: if user_id in instance['clients']: svr.restart() elif disabled == False and user.type == CERT_CLIENT: logger.LogEntry(message='Enabled user "%s".' % user.name) send_key_email = flask.request.json.get('send_key_email') if send_key_email and user.email: try: user.send_key_email(send_key_email) except EmailNotConfiguredError: return utils.jsonify({ 'error': EMAIL_NOT_CONFIGURED, 'error_msg': EMAIL_NOT_CONFIGURED_MSG, }, 400) except EmailFromInvalid: return utils.jsonify({ 'error': EMAIL_FROM_INVALID, 'error_msg': EMAIL_FROM_INVALID_MSG, }, 400) except EmailApiKeyInvalid: return utils.jsonify({ 'error': EMAIL_API_KEY_INVALID, 'error_msg': EMAIL_API_KEY_INVALID_MSG, }, 400) return utils.jsonify(user.dict())
def host_put(host_id=None): hst = host.get_host(id=host_id) if 'name' in flask.request.json: hst.name = utils.filter_str( flask.request.json['name']) or utils.random_name() if 'public_address' in flask.request.json: hst.public_address = utils.filter_str( flask.request.json['public_address']) hst.commit(hst.changed) event.Event(type=HOSTS_UPDATED) return utils.jsonify(host.dict())
def user_put(org_id, user_id): org = organization.get_by_id(org_id) user = org.get_user(user_id) if 'name' in flask.request.json: user.name = utils.filter_str(flask.request.json['name']) or None if 'email' in flask.request.json: user.email = utils.filter_str(flask.request.json['email']) or None disabled = flask.request.json.get('disabled') if disabled is not None: user.disabled = disabled user.commit() event.Event(type=USERS_UPDATED, resource_id=user.org.id) if disabled: user.disconnect() if user.type == CERT_CLIENT: logger.LogEntry(message='Disabled user "%s".' % user.name) elif disabled == False and user.type == CERT_CLIENT: logger.LogEntry(message='Enabled user "%s".' % user.name) send_key_email = flask.request.json.get('send_key_email') if send_key_email and user.email: try: user.send_key_email(flask.request.url_root[:-1]) except EmailNotConfiguredError: return utils.jsonify( { 'error': EMAIL_NOT_CONFIGURED, 'error_msg': EMAIL_NOT_CONFIGURED_MSG, }, 400) except EmailFromInvalid: return utils.jsonify( { 'error': EMAIL_FROM_INVALID, 'error_msg': EMAIL_FROM_INVALID_MSG, }, 400) except EmailAuthInvalid: return utils.jsonify( { 'error': EMAIL_AUTH_INVALID, 'error_msg': EMAIL_AUTH_INVALID_MSG, }, 400) return utils.jsonify(user.dict())
def sso_yubico_post(): sso_mode = settings.app.sso token = utils.filter_str(flask.request.json.get('token')) or None key = utils.filter_str(flask.request.json.get('key')) or None if sso_mode not in (GOOGLE_YUBICO_AUTH, SLACK_YUBICO_AUTH, SAML_YUBICO_AUTH, SAML_OKTA_YUBICO_AUTH, SAML_ONELOGIN_YUBICO_AUTH): return flask.abort(404) if not token or not key: return utils.jsonify( { 'error': TOKEN_INVALID, 'error_msg': TOKEN_INVALID_MSG, }, 401) tokens_collection = mongo.get_collection('sso_tokens') doc = tokens_collection.find_and_modify(query={ '_id': token, }, remove=True) if not doc or doc['_id'] != token or doc['type'] != YUBICO_AUTH: return utils.jsonify( { 'error': TOKEN_INVALID, 'error_msg': TOKEN_INVALID_MSG, }, 401) username = doc['username'] email = doc['email'] org_id = doc['org_id'] groups = set(doc['groups'] or []) valid, yubico_id = sso.auth_yubico(key) if not valid or not yubico_id: return utils.jsonify( { 'error': YUBIKEY_INVALID, 'error_msg': YUBIKEY_INVALID_MSG, }, 401) return _validate_user(username, email, sso_mode, org_id, groups, yubico_id=yubico_id)
def auth_put(): admin = flask.g.administrator if 'username' in flask.request.json and flask.request.json['username']: admin.username = utils.filter_str(flask.request.json['username']) if 'password' in flask.request.json and flask.request.json['password']: admin.password = flask.request.json['password'] if 'token' in flask.request.json and flask.request.json['token']: admin.generate_token() if 'secret' in flask.request.json and flask.request.json['secret']: admin.generate_secret() settings_commit = False if 'email_from' in flask.request.json: settings_commit = True email_from = flask.request.json['email_from'] settings.app.email_from_addr = email_from or None if 'email_api_key' in flask.request.json: settings_commit = True email_api_key = flask.request.json['email_api_key'] settings.app.email_api_key = email_api_key or None if settings_commit: settings.commit() admin.commit(admin.changed) response = flask.g.administrator.dict() response.update({ 'email_from': settings.app.email_from_addr, 'email_api_key': settings.app.email_api_key, }) return utils.jsonify(response)
def check_auth(username, password, remote_addr=None): username = utils.filter_str(username).lower() if remote_addr: doc = Administrator.limiter_collection.find_and_modify({ '_id': remote_addr, }, { '$inc': {'count': 1}, '$setOnInsert': {'timestamp': utils.now()}, }, new=True, upsert=True) if utils.now() > doc['timestamp'] + datetime.timedelta(minutes=1): doc = { 'count': 1, 'timestamp': utils.now(), } Administrator.limiter_collection.update({ '_id': remote_addr, }, doc, upsert=True) if doc['count'] > settings.app.auth_limiter_count_max: raise flask.abort(403) administrator = find_user(username=username) if not administrator: return if not administrator.test_password(password): return return administrator
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 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 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 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 auth_put(): administrator = flask.request.administrator system_conf = SystemConf() if 'username' in flask.request.json and flask.request.json['username']: administrator.username = utils.filter_str( flask.request.json['username']) if 'password' in flask.request.json and flask.request.json['password']: administrator.password = flask.request.json['password'] if 'token' in flask.request.json and flask.request.json['token']: administrator.generate_token() if 'secret' in flask.request.json and flask.request.json['secret']: administrator.generate_secret() if 'email_from' in flask.request.json: email_from = flask.request.json['email_from'] system_conf.set('email', 'from_addr', email_from or None) if 'email_api_key' in flask.request.json: email_api_key = flask.request.json['email_api_key'] system_conf.set('email', 'api_key', email_api_key or None) system_conf.commit() administrator.commit() response = flask.request.administrator.dict() response.update({ 'email_from': system_conf.get('email', 'from_addr'), 'email_api_key': system_conf.get('email', 'api_key'), }) return utils.jsonify(response)
def auth_put(): username = utils.filter_str(flask.request.json.get('username')) password = flask.request.json['password'] token = flask.request.json.get('token') utils.set_auth(username, password, token) return utils.jsonify(utils.get_auth())
def link_put(link_id): if not settings.local.sub_plan or \ 'enterprise' not in settings.local.sub_plan: return flask.abort(404) if settings.app.demo_mode: return utils.demo_blocked() lnk = link.get_by_id(link_id) if not lnk: return flask.abort(404) lnk.name = utils.filter_str(flask.request.json.get('name')) or 'undefined' status = flask.request.json.get('status') if status in (ONLINE, OFFLINE): lnk.status = status if flask.request.json.get('key'): lnk.generate_key() lnk.commit(('name', 'status', 'key')) event.Event(type=LINKS_UPDATED) return utils.jsonify(lnk.dict())
def link_location_host_post(link_id, location_id): if settings.app.demo_mode: return utils.demo_blocked() lnk = link.get_by_id(link_id) if not lnk: return flask.abort(404) loc = lnk.get_location(location_id) if not loc: return flask.abort(404) name = utils.filter_str(flask.request.json.get('name')) or 'undefined' hst = link.Host( link=lnk, location=loc, name=name, link_id=lnk.id, location_id=loc.id, ) hst.generate_secret() hst.commit() event.Event(type=LINKS_UPDATED) return utils.jsonify(hst.dict())
def org_put(org_id): org = organization.get_by_id(org_id) name = utils.filter_str(flask.request.json['name']) org.name = name org.commit(org.changed) event.Event(type=ORGS_UPDATED) return utils.jsonify(org.dict())
def auth_put(): admin = flask.g.administrator if 'username' in flask.request.json and flask.request.json['username']: admin.username = utils.filter_str( flask.request.json['username']).lower() if 'password' in flask.request.json and flask.request.json['password']: admin.password = flask.request.json['password'] if 'token' in flask.request.json and flask.request.json['token']: admin.generate_token() if 'secret' in flask.request.json and flask.request.json['secret']: admin.generate_secret() settings_commit = False if 'email_from' in flask.request.json: settings_commit = True email_from = flask.request.json['email_from'] settings.app.email_from_addr = email_from or None if 'email_api_key' in flask.request.json: settings_commit = True email_api_key = flask.request.json['email_api_key'] settings.app.email_api_key = email_api_key or None if settings_commit: settings.commit() admin.commit(admin.changed) response = flask.g.administrator.dict() response.update({ 'email_from': settings.app.email_from_addr, 'email_api_key': settings.app.email_api_key, }) return utils.jsonify(response)
def user_put(org_id, user_id): org = Organization.get_org(id=org_id) user = org.get_user(user_id) name = utils.filter_str(flask.request.json['name']) user.rename(name) return utils.jsonify(user.dict())
def user_post(org_id): org = organization.get_by_id(org_id) users = [] if isinstance(flask.request.json, list): users_data = flask.request.json else: users_data = [flask.request.json] try: for user_data in users_data: name = utils.filter_str(user_data['name']) email = utils.filter_str(user_data.get('email')) disabled = user_data.get('disabled') network_links = user_data.get('network_links') user = org.new_user(type=CERT_CLIENT, name=name, email=email, disabled=disabled) if network_links: for network_link in network_links: try: user.add_network_link(network_link) except (ipaddress.AddressValueError, ValueError): return _network_link_invalid() except ServerOnlineError: return utils.jsonify( { 'error': NETWORK_LINK_NOT_OFFLINE, 'error_msg': NETWORK_LINK_NOT_OFFLINE_MSG, }, 400) users.append(user.dict()) finally: event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SERVERS_UPDATED) if isinstance(flask.request.json, list): logger.LogEntry(message='Created %s new users.' % len(flask.request.json)) return utils.jsonify(users) else: logger.LogEntry(message='Created new user "%s".' % users[0]['name']) return utils.jsonify(users[0])
def auth_put(): username = utils.filter_str(flask.request.json.get('username')) password = flask.request.json['password'] utils.set_auth(username, password) return utils.jsonify({ 'username': utils.get_auth(), })
def user_put(org_id, user_id): org = organization.get_by_id(org_id) user = org.get_user(user_id) if 'name' in flask.request.json: user.name = utils.filter_str(flask.request.json['name']) or None if 'email' in flask.request.json: user.email = utils.filter_str(flask.request.json['email']) or None disabled = flask.request.json.get('disabled') if disabled is not None: user.disabled = disabled user.commit() event.Event(type=USERS_UPDATED, resource_id=user.org.id) if disabled: user.disconnect() if user.type == CERT_CLIENT: logger.LogEntry(message='Disabled user "%s".' % user.name) elif disabled == False and user.type == CERT_CLIENT: logger.LogEntry(message='Enabled user "%s".' % user.name) send_key_email = flask.request.json.get('send_key_email') if send_key_email and user.email: try: user.send_key_email(flask.request.url_root[:-1]) except EmailNotConfiguredError: return utils.jsonify({ 'error': EMAIL_NOT_CONFIGURED, 'error_msg': EMAIL_NOT_CONFIGURED_MSG, }, 400) except EmailFromInvalid: return utils.jsonify({ 'error': EMAIL_FROM_INVALID, 'error_msg': EMAIL_FROM_INVALID_MSG, }, 400) except EmailAuthInvalid: return utils.jsonify({ 'error': EMAIL_AUTH_INVALID, 'error_msg': EMAIL_AUTH_INVALID_MSG, }, 400) return utils.jsonify(user.dict())
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 link_location_host_post(link_id, location_id): if not settings.local.sub_plan or \ 'enterprise' not in settings.local.sub_plan: return flask.abort(404) if settings.app.demo_mode: return utils.demo_blocked() lnk = link.get_by_id(link_id) if not lnk: return flask.abort(404) loc = lnk.get_location(location_id) if not loc: return flask.abort(404) name = utils.filter_str(flask.request.json.get('name')) or 'undefined' timeout = int(flask.request.json.get('timeout') or 0) or None priority = abs(int(flask.request.json.get('priority') or 1)) or 1 static = bool(flask.request.json.get('static')) public_address = utils.filter_str( flask.request.json.get('public_address')) local_address = utils.filter_str( flask.request.json.get('local_address')) hst = link.Host( link=lnk, location=loc, link_id=lnk.id, location_id=loc.id, name=name, timeout=timeout, priority=priority, static=static, public_address=public_address, local_address=local_address, ) hst.generate_secret() hst.commit() event.Event(type=LINKS_UPDATED) return utils.jsonify(hst.dict())
def user_post(org_id): org = organization.get_by_id(org_id) users = [] if isinstance(flask.request.json, list): users_data = flask.request.json else: users_data = [flask.request.json] try: for user_data in users_data: name = utils.filter_str(user_data['name']) email = utils.filter_str(user_data.get('email')) disabled = user_data.get('disabled') network_links = user_data.get('network_links') user = org.new_user(type=CERT_CLIENT, name=name, email=email, disabled=disabled) if network_links: for network_link in network_links: try: user.add_network_link(network_link) except (ipaddress.AddressValueError, ValueError): return _network_link_invalid() except ServerOnlineError: return utils.jsonify({ 'error': NETWORK_LINK_NOT_OFFLINE, 'error_msg': NETWORK_LINK_NOT_OFFLINE_MSG, }, 400) users.append(user.dict()) finally: event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SERVERS_UPDATED) if isinstance(flask.request.json, list): logger.LogEntry(message='Created %s new users.' % len( flask.request.json)) return utils.jsonify(users) else: logger.LogEntry(message='Created new user "%s".' % users[0]['name']) return utils.jsonify(users[0])
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 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 link_put(link_id): if not settings.local.sub_plan or \ 'enterprise' not in settings.local.sub_plan: return flask.abort(404) if settings.app.demo_mode: return utils.demo_blocked() lnk = link.get_by_id(link_id) if not lnk: return flask.abort(404) lnk.name = utils.filter_str(flask.request.json.get('name')) or 'undefined' status = flask.request.json.get('status') if status in (ONLINE, OFFLINE): lnk.status = status if flask.request.json.get('key'): lnk.generate_key() lnk.ipv6 = True if flask.request.json.get('ipv6') else False lnk.host_check = True if flask.request.json.get('host_check') else False lnk.action = RESTART if flask.request.json.get( 'action') == RESTART else HOLD lnk.preferred_ike = utils.filter_str( flask.request.json.get('preferred_ike')) or None lnk.preferred_esp = utils.filter_str( flask.request.json.get('preferred_esp')) or None lnk.commit(('name', 'status', 'key', 'ipv6', 'host_check', 'action', 'preferred_ike', 'preferred_esp')) event.Event(type=LINKS_UPDATED) return utils.jsonify(lnk.dict())
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 user_put(org_id, user_id): org = Organization.get_org(id=org_id) user = org.get_user(user_id) name = flask.request.json.get("name") if name: name = utils.filter_str(name) if "email" in flask.request.json: email = flask.request.json["email"] if email: user.email = utils.filter_str(email) else: user.email = None disabled = flask.request.json.get("disabled") if disabled is not None: user.disabled = disabled if name: user.rename(name) else: user.commit() Event(type=USERS_UPDATED, resource_id=user.org.id) if disabled: if user.type == CERT_CLIENT: LogEntry(message='Disabled user "%s".' % user.name) for server in org.iter_servers(): server_clients = server.clients if user_id in server_clients: server.restart() elif disabled == False and user.type == CERT_CLIENT: LogEntry(message='Enabled user "%s".' % user.name) return utils.jsonify(user.dict())
def link_post(): if settings.app.demo_mode: return utils.demo_blocked() name = utils.filter_str(flask.request.json.get('name')) or 'undefined' lnk = link.Link( name=name, status=ONLINE, ) lnk.commit() event.Event(type=LINKS_UPDATED) return utils.jsonify(lnk.dict())
def link_post(): if not settings.local.sub_plan or \ 'enterprise' not in settings.local.sub_plan: return flask.abort(404) if settings.app.demo_mode: return utils.demo_blocked() name = utils.filter_str(flask.request.json.get('name')) or 'undefined' type = DIRECT if flask.request.json.get('type') == DIRECT \ else SITE_TO_SITE lnk = link.Link( name=name, type=type, status=ONLINE, ) lnk.generate_key() lnk.commit() if lnk.type == DIRECT: try: loc = link.Location( link=lnk, name='server', type=DIRECT_SERVER, link_id=lnk.id, ) loc.commit() loc = link.Location( link=lnk, name='client', type=DIRECT_CLIENT, link_id=lnk.id, ) loc.commit() except: lnk.remove() raise event.Event(type=LINKS_UPDATED) return utils.jsonify(lnk.dict())
def org_post(): if settings.app.demo_mode: return utils.demo_blocked() name = utils.filter_str(flask.request.json['name']) auth_api = flask.request.json.get('auth_api', False) org = organization.new_org(name=name, auth_api=None, type=ORG_DEFAULT) if auth_api: org.auth_api = True org.generate_auth_token() org.generate_auth_secret() org.commit() logger.LogEntry(message='Created new organization "%s".' % org.name) event.Event(type=ORGS_UPDATED) return utils.jsonify(org.dict())
def link_location_put(link_id, location_id): if settings.app.demo_mode: return utils.demo_blocked() lnk = link.get_by_id(link_id) if not lnk: return flask.abort(404) loc = lnk.get_location(location_id) if not loc: return flask.abort(404) loc.name = utils.filter_str(flask.request.json.get('name')) or 'undefined' loc.commit('name') event.Event(type=LINKS_UPDATED) return utils.jsonify(loc.dict())
def link_post(): if settings.local.sub_plan != 'enterprise_plus': return flask.abort(404) if settings.app.demo_mode: return utils.demo_blocked() name = utils.filter_str(flask.request.json.get('name')) or 'undefined' lnk = link.Link( name=name, status=ONLINE, ) lnk.generate_key() lnk.commit() event.Event(type=LINKS_UPDATED) return utils.jsonify(lnk.dict())
def check_auth(username, password, remote_addr=None): username = utils.filter_str(username).lower() if remote_addr: doc = Administrator.limiter_collection.find_and_modify( { '_id': remote_addr, }, { '$inc': { 'count': 1 }, '$setOnInsert': { 'timestamp': utils.now() }, }, new=True, upsert=True) if utils.now() > doc['timestamp'] + datetime.timedelta(minutes=1): doc = { 'count': 1, 'timestamp': utils.now(), } Administrator.limiter_collection.update({ '_id': remote_addr, }, doc, upsert=True) if doc['count'] > settings.app.auth_limiter_count_max: raise flask.abort(403) administrator = find_user(username=username) if not administrator: return if not administrator.test_password(password): return return administrator
def link_location_post(link_id): if settings.local.sub_plan != 'enterprise_plus': return flask.abort(404) if settings.app.demo_mode: return utils.demo_blocked() lnk = link.get_by_id(link_id) if not lnk: return flask.abort(404) name = utils.filter_str(flask.request.json.get('name')) or 'undefined' loc = link.Location( link=lnk, name=name, link_id=lnk.id, ) loc.commit() event.Event(type=LINKS_UPDATED) return utils.jsonify(loc.dict())
def server_put_post(server_id=None): if settings.app.demo_mode: return utils.demo_blocked() used_resources = server.get_used_resources(server_id) network_used = used_resources['networks'] port_used = used_resources['ports'] name = None name_def = False if 'name' in flask.request.json: name_def = True name = utils.filter_str(flask.request.json['name']) network = None network_def = False if 'network' in flask.request.json: network_def = True network = flask.request.json['network'] try: if not _check_network_private(network): return _network_invalid() except (ipaddress.AddressValueError, ValueError): return _network_invalid() network_mode = None network_mode_def = False if 'network_mode' in flask.request.json: network_mode_def = True network_mode = flask.request.json['network_mode'] network_start = None network_start_def = False if 'network_start' in flask.request.json: network_start_def = True network_start = flask.request.json['network_start'] network_end = None network_end_def = False if 'network_end' in flask.request.json: network_end_def = True network_end = flask.request.json['network_end'] restrict_routes = None restrict_routes_def = False if 'restrict_routes' in flask.request.json: restrict_routes_def = True restrict_routes = True if flask.request.json['restrict_routes'] \ else False ipv6 = None ipv6_def = False if 'ipv6' in flask.request.json: ipv6_def = True ipv6 = True if flask.request.json['ipv6'] else False ipv6_firewall = None ipv6_firewall_def = False if 'ipv6_firewall' in flask.request.json: ipv6_firewall_def = True ipv6_firewall = True if flask.request.json['ipv6_firewall'] else False bind_address = None bind_address_def = False if 'bind_address' in flask.request.json: bind_address_def = True bind_address = utils.filter_str(flask.request.json['bind_address']) protocol = 'udp' protocol_def = False if 'protocol' in flask.request.json: protocol_def = True protocol = flask.request.json['protocol'].lower() if protocol not in ('udp', 'tcp'): return utils.jsonify({ 'error': PROTOCOL_INVALID, 'error_msg': PROTOCOL_INVALID_MSG, }, 400) port = None port_def = False if 'port' in flask.request.json: port_def = True port = flask.request.json['port'] try: port = int(port) except ValueError: return _port_invalid() if port < 1 or port > 65535: return _port_invalid() dh_param_bits = None dh_param_bits_def = False if flask.request.json.get('dh_param_bits'): dh_param_bits_def = True dh_param_bits = flask.request.json['dh_param_bits'] try: dh_param_bits = int(dh_param_bits) except ValueError: return _dh_param_bits_invalid() if dh_param_bits not in VALID_DH_PARAM_BITS: return _dh_param_bits_invalid() multi_device = False multi_device_def = False if 'multi_device' in flask.request.json: multi_device_def = True multi_device = True if flask.request.json['multi_device'] else False dns_servers = None dns_servers_def = False if 'dns_servers' in flask.request.json: dns_servers_def = True dns_servers = flask.request.json['dns_servers'] or [] for dns_server in dns_servers: try: ipaddress.IPAddress(dns_server) except (ipaddress.AddressValueError, ValueError): return _dns_server_invalid() search_domain = None search_domain_def = False if 'search_domain' in flask.request.json: search_domain_def = True search_domain = utils.filter_str(flask.request.json['search_domain']) inter_client = True inter_client_def = False if 'inter_client' in flask.request.json: inter_client_def = True inter_client = True if flask.request.json['inter_client'] else False ping_interval = None ping_interval_def = False if 'ping_interval' in flask.request.json: ping_interval_def = True ping_interval = flask.request.json['ping_interval'] if ping_interval: ping_interval = int(ping_interval) if not ping_interval: ping_interval = 10 ping_timeout = None ping_timeout_def = False if 'ping_timeout' in flask.request.json: ping_timeout_def = True ping_timeout = flask.request.json['ping_timeout'] if ping_timeout: ping_timeout = int(ping_timeout) if not ping_timeout: ping_timeout = 60 link_ping_interval = None link_ping_interval_def = False if 'link_ping_interval' in flask.request.json: link_ping_interval_def = True link_ping_interval = flask.request.json['link_ping_interval'] if link_ping_interval: link_ping_interval = int(link_ping_interval) if not link_ping_interval: link_ping_interval = 1 link_ping_timeout = None link_ping_timeout_def = False if 'link_ping_timeout' in flask.request.json: link_ping_timeout_def = True link_ping_timeout = flask.request.json['link_ping_timeout'] if link_ping_timeout: link_ping_timeout = int(link_ping_timeout) if not link_ping_timeout: link_ping_timeout = 5 onc_hostname = None onc_hostname_def = False if 'onc_hostname' in flask.request.json: onc_hostname_def = True onc_hostname = utils.filter_str(flask.request.json['onc_hostname']) max_clients = None max_clients_def = False if 'max_clients' in flask.request.json: max_clients_def = True max_clients = flask.request.json['max_clients'] if max_clients: max_clients = int(max_clients) if not max_clients: max_clients = 2000 replica_count = None replica_count_def = False if 'replica_count' in flask.request.json: replica_count_def = True replica_count = flask.request.json['replica_count'] if replica_count: replica_count = int(replica_count) if not replica_count: replica_count = 1 dns_mapping = False dns_mapping_def = False if 'dns_mapping' in flask.request.json: dns_mapping_def = True dns_mapping = True if flask.request.json['dns_mapping'] else False debug = False debug_def = False if 'debug' in flask.request.json: debug_def = True debug = True if flask.request.json['debug'] else False otp_auth = False otp_auth_def = False if 'otp_auth' in flask.request.json: otp_auth_def = True otp_auth = True if flask.request.json['otp_auth'] else False lzo_compression = False lzo_compression_def = False if 'lzo_compression' in flask.request.json: lzo_compression_def = True lzo_compression = True if flask.request.json[ 'lzo_compression'] else False cipher = None cipher_def = False if 'cipher' in flask.request.json: cipher_def = True cipher = flask.request.json['cipher'] if cipher not in CIPHERS: return utils.jsonify({ 'error': CIPHER_INVALID, 'error_msg': CIPHER_INVALID_MSG, }, 400) hash = None hash_def = False if 'hash' in flask.request.json: hash_def = True hash = flask.request.json['hash'] if hash not in HASHES: return utils.jsonify({ 'error': HASH_INVALID, 'error_msg': HASH_INVALID_MSG, }, 400) jumbo_frames = False jumbo_frames_def = False if 'jumbo_frames' in flask.request.json: jumbo_frames_def = True jumbo_frames = True if flask.request.json[ 'jumbo_frames'] else False if not server_id: if not name_def: return utils.jsonify({ 'error': MISSING_PARAMS, 'error_msg': MISSING_PARAMS_MSG, }, 400) if network_def and network_mode == BRIDGE and \ (not network_start or not network_end): return utils.jsonify({ 'error': MISSING_PARAMS, 'error_msg': MISSING_PARAMS_MSG, }, 400) if not network_def: network_def = True rand_range = range(215, 250) rand_range_low = range(15, 215) random.shuffle(rand_range) random.shuffle(rand_range_low) rand_range += rand_range_low for i in rand_range: rand_network = '192.168.%s.0/24' % i if not _check_network_overlap(rand_network, network_used): network = rand_network break if not network: return utils.jsonify({ 'error': NETWORK_IN_USE, 'error_msg': NETWORK_IN_USE_MSG, }, 400) if not port_def: port_def = True rand_ports = range(10000, 19999) random.shuffle(rand_ports) for rand_port in rand_ports: if '%s%s' % (rand_port, protocol) not in port_used: port = rand_port break if not port: return utils.jsonify({ 'error': PORT_PROTOCOL_IN_USE, 'error_msg': PORT_PROTOCOL_IN_USE_MSG, }, 400) if not dh_param_bits_def: dh_param_bits_def = True dh_param_bits = settings.vpn.default_dh_param_bits if network_def: if _check_network_overlap(network, network_used): return utils.jsonify({ 'error': NETWORK_IN_USE, 'error_msg': NETWORK_IN_USE_MSG, }, 400) if port_def: if '%s%s' % (port, protocol) in port_used: return utils.jsonify({ 'error': PORT_PROTOCOL_IN_USE, 'error_msg': PORT_PROTOCOL_IN_USE_MSG, }, 400) if not server_id: if network_mode == BRIDGE: if not _check_network_range(network, network_start, network_end): return utils.jsonify({ 'error': BRIDGE_NETWORK_INVALID, 'error_msg': BRIDGE_NETWORK_INVALID_MSG, }, 400) if ipv6: return utils.jsonify({ 'error': IPV6_BRIDGED_INVALID, 'error_msg': IPV6_BRIDGED_INVALID_MSG, }, 400) svr = server.new_server( name=name, network=network, network_mode=network_mode, network_start=network_start, network_end=network_end, restrict_routes=restrict_routes, ipv6=ipv6, ipv6_firewall=ipv6_firewall, bind_address=bind_address, port=port, protocol=protocol, dh_param_bits=dh_param_bits, multi_device=multi_device, dns_servers=dns_servers, search_domain=search_domain, otp_auth=otp_auth, cipher=cipher, hash=hash, jumbo_frames=jumbo_frames, lzo_compression=lzo_compression, inter_client=inter_client, ping_interval=ping_interval, ping_timeout=ping_timeout, link_ping_interval=link_ping_interval, link_ping_timeout=link_ping_timeout, onc_hostname=onc_hostname, max_clients=max_clients, replica_count=replica_count, dns_mapping=dns_mapping, debug=debug, ) svr.add_host(settings.local.host_id) svr.commit() else: svr = server.get_by_id(server_id) if svr.status == ONLINE: return utils.jsonify({ 'error': SERVER_NOT_OFFLINE, 'error_msg': SERVER_NOT_OFFLINE_SETTINGS_MSG, }, 400) for link_svr in svr.iter_links(fields=('status',)): if link_svr.status == ONLINE: return utils.jsonify({ 'error': SERVER_LINKS_NOT_OFFLINE, 'error_msg': SERVER_LINKS_NOT_OFFLINE_SETTINGS_MSG, }, 400) if name_def: svr.name = name if network_def: svr.network = network if network_start_def: svr.network_start = network_start if network_end_def: svr.network_end = network_end if restrict_routes_def: svr.restrict_routes = restrict_routes if ipv6_def: svr.ipv6 = ipv6 if ipv6_firewall_def: svr.ipv6_firewall = ipv6_firewall if network_mode_def: if network_mode == BRIDGE and ( not network_start or not network_end): return utils.jsonify({ 'error': MISSING_PARAMS, 'error_msg': MISSING_PARAMS_MSG, }, 400) svr.network_mode = network_mode if bind_address_def: svr.bind_address = bind_address if port_def: svr.port = port if protocol_def: svr.protocol = protocol if dh_param_bits_def and svr.dh_param_bits != dh_param_bits: svr.dh_param_bits = dh_param_bits svr.generate_dh_param() if multi_device_def: svr.multi_device = multi_device if dns_servers_def: svr.dns_servers = dns_servers if search_domain_def: svr.search_domain = search_domain if otp_auth_def: svr.otp_auth = otp_auth if cipher_def: svr.cipher = cipher if hash_def: svr.hash = hash if jumbo_frames_def: svr.jumbo_frames = jumbo_frames if lzo_compression_def: svr.lzo_compression = lzo_compression if inter_client_def: svr.inter_client = inter_client if ping_interval_def: svr.ping_interval = ping_interval if ping_timeout_def: svr.ping_timeout = ping_timeout if link_ping_interval_def: svr.link_ping_interval = link_ping_interval if link_ping_timeout_def: svr.link_ping_timeout = link_ping_timeout if onc_hostname_def: svr.onc_hostname = onc_hostname if max_clients_def: svr.max_clients = max_clients if replica_count_def: svr.replica_count = replica_count if dns_mapping_def: svr.dns_mapping = dns_mapping if debug_def: svr.debug = debug if svr.network_mode == BRIDGE: if not _check_network_range(svr.network, svr.network_start, svr.network_end): return utils.jsonify({ 'error': BRIDGE_NETWORK_INVALID, 'error_msg': BRIDGE_NETWORK_INVALID_MSG, }, 400) if svr.ipv6: return utils.jsonify({ 'error': IPV6_BRIDGED_INVALID, 'error_msg': IPV6_BRIDGED_INVALID_MSG, }, 400) if svr.links and svr.replica_count > 1: return utils.jsonify({ 'error': SERVER_LINKS_AND_REPLICA, 'error_msg': SERVER_LINKS_AND_REPLICA_MSG, }, 400) svr.commit(svr.changed) logger.LogEntry(message='Created server "%s".' % svr.name) event.Event(type=SERVERS_UPDATED) event.Event(type=SERVER_ROUTES_UPDATED, resource_id=svr.id) for org in svr.iter_orgs(): event.Event(type=USERS_UPDATED, resource_id=org.id) return utils.jsonify(svr.dict())