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 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 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 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']: 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 = 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 port_forwarding_event: messenger.publish('port_forwarding', { 'org_id': org.id, 'user_id': user.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 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 _run_thread(self, send_events): from pritunl.server.utils import get_by_id logger.info('Starting vpn server', 'server', server_id=self.server.id, instance_id=self.id, instances=self.server.instances, instances_count=self.server.instances_count, route_count=len(self.server.routes), network=self.server.network, network6=self.server.network6, host_id=settings.local.host.id, host_address=settings.local.host.local_addr, host_address6=settings.local.host.local_addr6, host_networks=settings.local.host.local_networks, cur_timestamp=utils.now(), libipt=settings.vpn.lib_iptables, ) def timeout(): logger.error('Server startup timed out, stopping server', 'server', server_id=self.server.id, instance_id=self.id, state=self.state, ) self.stop_process() startup_keepalive_thread = threading.Thread( target=self._startup_keepalive_thread) startup_keepalive_thread.daemon = True self.state = 'init' timer = threading.Timer(settings.vpn.startup_timeout, timeout) timer.daemon = True timer.start() try: self.resources_acquire() cursor_id = self.get_cursor_id() if self.is_interrupted(): return self.state = 'temp_path' os.makedirs(self._temp_path) if self.is_interrupted(): return self.state = 'ip_forwarding' self.enable_ip_forwarding() if self.is_interrupted(): return self.state = 'bridge_start' self.bridge_start() if self.is_interrupted(): return if self.server.replicating and self.server.vxlan: try: self.state = 'get_vxlan' self.vxlan = vxlan.get_vxlan(self.server.id, self.id, self.server.ipv6) if self.is_interrupted(): return self.state = 'start_vxlan' self.vxlan.start() if self.is_interrupted(): return except: logger.exception('Failed to setup server vxlan', 'vxlan', server_id=self.server.id, instance_id=self.id, ) self.state = 'generate_ovpn_conf' self.generate_ovpn_conf() if self.is_interrupted(): return self.state = 'generate_iptables_rules' self.generate_iptables_rules() if self.is_interrupted(): return self.state = 'publish' self.publish('started') if self.is_interrupted(): return self.state = 'startup_keepalive' startup_keepalive_thread.start() if self.is_interrupted(): return self.state = 'upsert_iptables_rules' self.iptables.upsert_rules() if self.is_interrupted(): return self.state = 'init_route_advertisements' self.init_route_advertisements() if self.is_interrupted(): return self.state = 'openvpn_start' self.process = self.openvpn_start() self.start_threads(cursor_id) if self.is_interrupted(): return self.state = 'instance_com_start' self.instance_com = ServerInstanceCom(self.server, self) self.instance_com.start() if self.is_interrupted(): return if send_events: self.state = 'events' event.Event(type=SERVERS_UPDATED) event.Event(type=SERVER_HOSTS_UPDATED, resource_id=self.server.id) for org_id in self.server.organizations: event.Event(type=USERS_UPDATED, resource_id=org_id) if self.is_interrupted(): return for link_doc in self.server.links: if self.server.id > link_doc['server_id']: self.state = 'instance_link' instance_link = ServerInstanceLink( server=self.server, linked_server=get_by_id(link_doc['server_id']), ) self.server_links.append(instance_link) instance_link.start() if self.is_interrupted(): return self.state = 'running' self.openvpn_output() if self.is_interrupted(): return timer.cancel() self.startup_interrupt = True plugins.caller( 'server_start', host_id=settings.local.host_id, host_name=settings.local.host.name, server_id=self.server.id, server_name=self.server.name, port=self.server.port, protocol=self.server.protocol, ipv6=self.server.ipv6, ipv6_firewall=self.server.ipv6_firewall, network=self.server.network, network6=self.server.network6, network_mode=self.server.network_mode, network_start=self.server.network_start, network_stop=self.server.network_end, restrict_routes=self.server.restrict_routes, bind_address=self.server.bind_address, onc_hostname=None, dh_param_bits=self.server.dh_param_bits, multi_device=self.server.multi_device, dns_servers=self.server.dns_servers, search_domain=self.server.search_domain, otp_auth=self.server.otp_auth, cipher=self.server.cipher, hash=self.server.hash, inter_client=self.server.inter_client, ping_interval=self.server.ping_interval, ping_timeout=self.server.ping_timeout, link_ping_interval=self.server.link_ping_interval, link_ping_timeout=self.server.link_ping_timeout, allowed_devices=self.server.allowed_devices, max_clients=self.server.max_clients, replica_count=self.server.replica_count, dns_mapping=self.server.dns_mapping, debug=self.server.debug, interface=self.interface, bridge_interface=self.bridge_interface, vxlan=self.vxlan, ) try: while True: if self.process.poll() is not None: break if self.is_interrupted(): self.stop_process() time.sleep(0.05) finally: plugins.caller( 'server_stop', host_id=settings.local.host_id, host_name=settings.local.host.name, server_id=self.server.id, server_name=self.server.name, port=self.server.port, protocol=self.server.protocol, ipv6=self.server.ipv6, ipv6_firewall=self.server.ipv6_firewall, network=self.server.network, network6=self.server.network6, network_mode=self.server.network_mode, network_start=self.server.network_start, network_stop=self.server.network_end, restrict_routes=self.server.restrict_routes, bind_address=self.server.bind_address, onc_hostname=None, dh_param_bits=self.server.dh_param_bits, multi_device=self.server.multi_device, dns_servers=self.server.dns_servers, search_domain=self.server.search_domain, otp_auth=self.server.otp_auth, cipher=self.server.cipher, hash=self.server.hash, inter_client=self.server.inter_client, ping_interval=self.server.ping_interval, ping_timeout=self.server.ping_timeout, link_ping_interval=self.server.link_ping_interval, link_ping_timeout=self.server.link_ping_timeout, allowed_devices=self.server.allowed_devices, max_clients=self.server.max_clients, replica_count=self.server.replica_count, dns_mapping=self.server.dns_mapping, debug=self.server.debug, interface=self.interface, bridge_interface=self.bridge_interface, vxlan=self.vxlan, ) if not self.clean_exit: event.Event(type=SERVERS_UPDATED) self.server.send_link_events() logger.LogEntry( message='Server stopped unexpectedly "%s".' % ( self.server.name)) except: try: self.stop_process() except: logger.exception('Server stop error', 'server', server_id=self.server.id, instance_id=self.id, ) logger.exception('Server error occurred while running', 'server', server_id=self.server.id, instance_id=self.id, ) finally: timer.cancel() self.startup_interrupt = True self.interrupt = True self.sock_interrupt = True try: self.bridge_stop() except: logger.exception('Failed to remove server bridge', 'server', server_id=self.server.id, instance_id=self.id, ) try: self.iptables.clear_rules() except: logger.exception('Server iptables clean up error', 'server', server_id=self.server.id, instance_id=self.id, ) if self.vxlan: try: self.vxlan.stop() except: logger.exception('Failed to stop server vxlan', 'server', server_id=self.server.id, instance_id=self.id, ) try: self.collection.update({ '_id': self.server.id, 'instances.instance_id': self.id, }, { '$pull': { 'instances': { 'instance_id': self.id, }, }, '$inc': { 'instances_count': -1, }, }) utils.rmtree(self._temp_path) except: logger.exception('Server clean up error', 'server', server_id=self.server.id, instance_id=self.id, ) try: self.resources_release() except: logger.exception('Failed to release resources', 'server', server_id=self.server.id, instance_id=self.id, )
def server_put_post(server_id=None): 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'] if not _check_network_private(network): 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'] # if not _check_network_private(network_start): # return _network_invalid() 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'] # if not _check_network_private(network_end): # return _network_invalid() 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() mode = None mode_def = False if 'mode' in flask.request.json: mode_def = True mode = flask.request.json['mode'] if mode not in (ALL_TRAFFIC, LOCAL_TRAFFIC, VPN_TRAFFIC): return utils.jsonify( { 'error': MODE_INVALID, 'error_msg': MODE_INVALID_MSG, }, 400) 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 local_networks = None local_networks_def = False if 'local_networks' in flask.request.json: local_networks_def = True local_networks = flask.request.json['local_networks'] or [] for local_network in local_networks: local_network_split = local_network.split('/') if len(local_network_split) != 2: return _local_network_invalid() address = local_network_split[0].split('.') if len(address) != 4: return _local_network_invalid() for i, value in enumerate(address): try: address[i] = int(value) except ValueError: return _local_network_invalid() if address[0] > 255 or address[0] < 0 or \ address[1] > 255 or address[1] < 0 or \ address[2] > 255 or address[2] < 0 or \ address[3] > 254 or address[3] < 0: return _local_network_invalid() try: subnet = int(local_network_split[1]) except ValueError: return _local_network_invalid() if subnet < 1 or subnet > 32: return _local_network_invalid() 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: if not re.match(IP_REGEX, dns_server): 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 flask.request.json.get('ping_interval'): ping_interval_def = True ping_interval = int(flask.request.json['ping_interval']) ping_timeout = None ping_timeout_def = False if flask.request.json.get('ping_timeout'): ping_timeout_def = True ping_timeout = int(flask.request.json['ping_timeout']) max_clients = None max_clients_def = False if flask.request.json.get('max_clients'): max_clients_def = True max_clients = int(flask.request.json['max_clients']) if max_clients < 1: max_clients = 1 replica_count = None replica_count_def = False if flask.request.json.get('replica_count'): replica_count_def = True replica_count = int(flask.request.json['replica_count']) if replica_count < 1: replica_count = 1 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) 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 not mode_def: mode_def = True if local_networks_def and local_networks: mode = LOCAL_TRAFFIC else: mode = ALL_TRAFFIC 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: svr = server.new_server( name=name, network=network, network_mode=network_mode, network_start=network_start, network_end=network_end, bind_address=bind_address, port=port, protocol=protocol, dh_param_bits=dh_param_bits, mode=mode, multi_device=multi_device, local_networks=local_networks, dns_servers=dns_servers, search_domain=search_domain, otp_auth=otp_auth, cipher=cipher, jumbo_frames=jumbo_frames, lzo_compression=lzo_compression, inter_client=inter_client, ping_interval=ping_interval, ping_timeout=ping_timeout, max_clients=max_clients, replica_count=replica_count, 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 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 mode_def: svr.mode = mode if multi_device_def: svr.multi_device = multi_device if local_networks_def: svr.local_networks = local_networks 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 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 max_clients_def: svr.max_clients = max_clients if replica_count_def: svr.replica_count = replica_count if debug_def: svr.debug = debug 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) for org in svr.iter_orgs(): event.Event(type=USERS_UPDATED, resource_id=org.id) return utils.jsonify(svr.dict())
def client_connect(self, client): try: client_id = client['client_id'] org_id = utils.ObjectId(client['org_id']) user_id = utils.ObjectId(client['user_id']) device_id = client.get('device_id') device_name = client.get('device_name') platform = client.get('platform') mac_addr = client.get('mac_addr') otp_code = client.get('otp_code') remote_ip = client.get('remote_ip') devices = self.client_devices[user_id] if not _limiter.validate(remote_ip): self.send_client_deny(client, 'Too many connect requests') return org = self.server.get_org(org_id, fields=['_id']) if not org: self.send_client_deny(client, 'Organization is not valid') return user = org.get_user(user_id, fields=('_id', 'name', 'email', 'type', 'auth_type', 'disabled', 'otp_secret', 'link_server_id')) if not user: self.send_client_deny(client, 'User is not valid') return if user.disabled: logger.LogEntry(message='User failed authentication, ' + 'disabled user "%s".' % (user.name)) self.send_client_deny(client, 'User is disabled') return if not user.auth_check(): logger.LogEntry(message='User failed authentication, ' + 'Google authentication failed "%s".' % (user.name)) self.send_client_deny(client, 'User failed authentication') return if self.server.otp_auth and user.type == CERT_CLIENT and \ not user.verify_otp_code(otp_code, remote_ip): logger.LogEntry(message='User failed two-step ' + 'authentication "%s".' % user.name) self.send_client_deny(client, 'Invalid OTP code') return client_conf = self.generate_client_conf(user) if not self.server.multi_device: virt_address = self.server.get_ip_addr(org.id, user_id) if virt_address and virt_address in self.client_ips: for i, device in enumerate(devices): if device['virt_address'] == virt_address: self.client_kill(device) if virt_address in self.client_ips: self.client_ips.remove(virt_address) del devices[i] else: virt_address = None if devices and device_id: for i, device in enumerate(devices): if device['device_id'] == device_id: virt_address = device['virt_address'] self.client_kill(device) if virt_address in self.client_ips: self.client_ips.remove(virt_address) del devices[i] if not virt_address: virt_address = self.server.get_ip_addr(org.id, user_id) if virt_address and virt_address in self.client_ips: virt_address = None if not virt_address: while True: try: ip_addr = self.ip_pool.pop() except IndexError: break ip_addr = '%s/%s' % ( ip_addr, self.ip_network.prefixlen) if ip_addr not in self.client_ips: virt_address = ip_addr self.client_dyn_ips.add(virt_address) break if virt_address: self.client_ips.add(virt_address) devices.append({ 'user_id': user_id, 'org_id': org_id, 'client_id': client_id, 'device_id': device_id, 'device_name': device_name, 'type': user.type, 'platform': platform, 'mac_addr': mac_addr, 'otp_code': otp_code, 'virt_address': virt_address, 'real_address': remote_ip, }) client_conf += 'ifconfig-push %s %s\n' % utils.parse_network( virt_address) if self.server.debug: self.push_output('Client conf %s:' % user_id) for conf_line in client_conf.split('\n'): if conf_line: self.push_output(' ' + conf_line) self.send_client_auth(client, client_conf) else: self.send_client_deny(client, 'Unable to assign ip address') except: logger.exception('Error parsing client connect', 'server', server_id=self.server.id, instance_id=self.instance.id, ) self.send_client_deny(client, 'Error parsing client connect')
def org_post(): name = utils.filter_str(flask.request.json['name']) org = organization.new_org(name=name, type=ORG_DEFAULT) logger.LogEntry(message='Created new organization "%s".' % org.name) event.Event(type=ORGS_UPDATED) return utils.jsonify(org.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 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 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']) 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) 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 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 policy = None policy_def = False if 'policy' in flask.request.json: policy_def = True if flask.request.json['policy']: policy = flask.request.json['policy'].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 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, onc_hostname=onc_hostname, allowed_devices=allowed_devices, max_clients=max_clients, replica_count=replica_count, vxlan=vxlan, dns_mapping=dns_mapping, debug=debug, policy=policy, ) 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 onc_hostname_def: svr.onc_hostname = onc_hostname if allowed_devices_def: svr.allowed_devices = allowed_devices if max_clients_def: svr.max_clients = max_clients 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 policy_def: svr.policy = policy 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 _run_thread(self, send_events): from pritunl.server.utils import get_by_id logger.debug( 'Starting ovpn process', 'server', server_id=self.server.id, ) self.resources_acquire() try: cursor_id = self.get_cursor_id() os.makedirs(self._temp_path) self.generate_ovpn_conf() self.enable_ip_forwarding() self.set_iptables_rules() self.process = self.openvpn_start() if not self.process: return self.start_threads(cursor_id) self.instance_com = ServerInstanceCom(self.server, self) self.instance_com.start() self.publish('started') if send_events: event.Event(type=SERVERS_UPDATED) event.Event(type=SERVER_HOSTS_UPDATED, resource_id=self.server.id) for org_id in self.server.organizations: event.Event(type=USERS_UPDATED, resource_id=org_id) for link_doc in self.server.links: if self.server.id > link_doc['server_id']: instance_link = ServerInstanceLink( server=self.server, linked_server=get_by_id(link_doc['server_id']), ) self.server_links.append(instance_link) instance_link.start() self.openvpn_watch() self.interrupt = True self.clear_iptables_rules() self.resources_release() if not self.clean_exit: event.Event(type=SERVERS_UPDATED) self.server.send_link_events() logger.LogEntry(message='Server stopped unexpectedly "%s".' % (self.server.name)) except: self.interrupt = True if self.resource_lock: self.clear_iptables_rules() self.resources_release() logger.exception( 'Server error occurred while running', 'server', server_id=self.server.id, ) finally: self.stop_threads() self.collection.update( { '_id': self.server.id, 'instances.instance_id': self.id, }, { '$pull': { 'instances': { 'instance_id': self.id, }, }, '$inc': { 'instances_count': -1, }, }) utils.rmtree(self._temp_path)
def connect(self, client): client_id = None key_id = None try: client_id = client['client_id'] key_id = client['key_id'] org_id = client['org_id'] user_id = client['user_id'] otp_code = client.get('otp_code') remote_ip = client.get('remote_ip') platform = client.get('platform') device_name = client.get('device_name') if not _limiter.validate(remote_ip): self.instance_com.send_client_deny( client_id, key_id, 'Too many connect requests') return org = self.server.get_org(org_id, fields=['_id', 'name']) if not org: self.instance_com.send_client_deny( client_id, key_id, 'Organization is not valid') return user = org.get_user(user_id, fields=('_id', 'name', 'email', 'type', 'auth_type', 'disabled', 'otp_secret', 'link_server_id')) if not user: self.instance_com.send_client_deny(client_id, key_id, 'User is not valid') return if user.disabled: logger.LogEntry(message='User failed authentication, ' + 'disabled user "%s".' % (user.name)) self.instance_com.send_client_deny(client_id, key_id, 'User is disabled') return if not user.auth_check(): logger.LogEntry(message='User failed authentication, ' + 'Google authentication failed "%s".' % (user.name)) self.instance_com.send_client_deny( client_id, key_id, 'User failed authentication') return if self.server.otp_auth and user.type == CERT_CLIENT and \ not user.verify_otp_code(otp_code, remote_ip): logger.LogEntry(message='User failed two-step ' + 'authentication "%s".' % user.name) self.instance_com.send_client_deny(client_id, key_id, 'Invalid OTP code') return if settings.app.sso and user.auth_type == DUO_AUTH and \ DUO_AUTH in settings.app.sso: def duo_auth(): info = { 'Server': self.server.name, } platform_name = None if platform == 'linux': platform_name = 'Linux' elif platform == 'mac': platform_name = 'Apple' elif platform == 'win': platform_name = 'Windows' elif platform == 'chrome': platform_name = 'Chrome OS' if device_name: info['Device'] = '%s (%s)' % (device_name, platform_name) allow = False try: allow, _ = sso.auth_duo( user.name, ipaddr=remote_ip, type='Connection', info=info, ) except: logger.exception( 'Duo server error', 'server', client_id=client_id, user_id=user.id, username=user.name, server_id=self.server.id, ) self.instance_com.push_output( 'ERROR Duo server error client_id=%s' % client_id) try: if allow: self.allow_client(client, org, user) else: logger.LogEntry(message='User failed duo ' + 'authentication "%s".' % user.name) self.instance_com.send_client_deny( client_id, key_id, 'User failed duo authentication', ) except: logger.exception( 'Duo auth error', 'server', client_id=client_id, user_id=user.id, server_id=self.server.id, ) self.instance_com.push_output( 'ERROR Duo auth error client_id=%s' % client_id) thread = threading.Thread(target=duo_auth) thread.daemon = True thread.start() else: self.allow_client(client, org, user) except: logger.exception( 'Error parsing client connect', 'server', server_id=self.server.id, ) if client_id and key_id: self.instance_com.send_client_deny( client_id, key_id, 'Error parsing client connect')
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 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 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: 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 _create_users(org_id, users_data, remote_addr, background): global _users_background org = organization.get_by_id(org_id) users = [] partial_event = len(users_data) <= 100 if background: _users_background_lock.acquire() if _users_background: return _users_background = True _users_background_lock.release() try: for i, user_data in enumerate(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 = True if user_data.get('disabled') else False network_links = user_data.get('network_links') or None bypass_secondary = True if user_data.get( 'bypass_secondary') else False client_to_client = True if user_data.get( 'client_to_client') else False 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 = [] groups = user_data.get('groups') or [] for i, group in enumerate(groups): groups[i] = utils.filter_str(group) groups = list(set(groups)) 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, groups=groups, pin=pin, disabled=disabled, bypass_secondary=bypass_secondary, client_to_client=client_to_client, dns_servers=dns_servers, dns_suffix=dns_suffix, port_forwarding=port_forwarding) user.audit_event( 'user_created', 'User created from web console', remote_addr=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()) if partial_event and i != 0 and i % 10 == 0: event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SERVERS_UPDATED) except: logger.exception('Error creating users', 'users') raise finally: if background: _users_background_lock.acquire() _users_background = False _users_background_lock.release() event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SERVERS_UPDATED) if len(users) > 1: logger.LogEntry(message='Created %s new users.' % len(users)) return utils.jsonify(users) else: logger.LogEntry(message='Created new user "%s".' % users[0]['name']) return utils.jsonify(users[0])
def _run_thread(self, send_events): from pritunl.server.utils import get_by_id self.resources_acquire() try: cursor_id = self.get_cursor_id() os.makedirs(self._temp_path) self.enable_ip_forwarding() self.bridge_start() if self.server.replicating and self.server.vxlan: try: self.vxlan = vxlan.get_vxlan(self.server.id) self.vxlan.start() except: logger.exception( 'Failed to setup server vxlan', 'vxlan', server_id=self.server.id, instance_id=self.id, ) self.generate_ovpn_conf() self.generate_iptables_rules() self.iptables.upsert_rules() self.init_route_advertisements() self.process = self.openvpn_start() if not self.process: return self.start_threads(cursor_id) self.instance_com = ServerInstanceCom(self.server, self) self.instance_com.start() self.publish('started') if send_events: event.Event(type=SERVERS_UPDATED) event.Event(type=SERVER_HOSTS_UPDATED, resource_id=self.server.id) for org_id in self.server.organizations: event.Event(type=USERS_UPDATED, resource_id=org_id) for link_doc in self.server.links: if self.server.id > link_doc['server_id']: instance_link = ServerInstanceLink( server=self.server, linked_server=get_by_id(link_doc['server_id']), ) self.server_links.append(instance_link) instance_link.start() plugins.caller( 'server_start', host_id=settings.local.host_id, host_name=settings.local.host.name, server_id=self.server.id, server_name=self.server.name, port=self.server.port, protocol=self.server.protocol, ipv6=self.server.ipv6, ipv6_firewall=self.server.ipv6_firewall, network=self.server.network, network6=self.server.network6, network_mode=self.server.network_mode, network_start=self.server.network_start, network_stop=self.server.network_end, restrict_routes=self.server.restrict_routes, bind_address=self.server.bind_address, onc_hostname=self.server.onc_hostname, dh_param_bits=self.server.dh_param_bits, multi_device=self.server.multi_device, dns_servers=self.server.dns_servers, search_domain=self.server.search_domain, otp_auth=self.server.otp_auth, cipher=self.server.cipher, hash=self.server.hash, inter_client=self.server.inter_client, ping_interval=self.server.ping_interval, ping_timeout=self.server.ping_timeout, link_ping_interval=self.server.link_ping_interval, link_ping_timeout=self.server.link_ping_timeout, allowed_devices=self.server.allowed_devices, max_clients=self.server.max_clients, replica_count=self.server.replica_count, dns_mapping=self.server.dns_mapping, debug=self.server.debug, interface=self.interface, bridge_interface=self.bridge_interface, vxlan=self.vxlan, ) try: self.openvpn_watch() finally: plugins.caller( 'server_stop', host_id=settings.local.host_id, host_name=settings.local.host.name, server_id=self.server.id, server_name=self.server.name, port=self.server.port, protocol=self.server.protocol, ipv6=self.server.ipv6, ipv6_firewall=self.server.ipv6_firewall, network=self.server.network, network6=self.server.network6, network_mode=self.server.network_mode, network_start=self.server.network_start, network_stop=self.server.network_end, restrict_routes=self.server.restrict_routes, bind_address=self.server.bind_address, onc_hostname=self.server.onc_hostname, dh_param_bits=self.server.dh_param_bits, multi_device=self.server.multi_device, dns_servers=self.server.dns_servers, search_domain=self.server.search_domain, otp_auth=self.server.otp_auth, cipher=self.server.cipher, hash=self.server.hash, inter_client=self.server.inter_client, ping_interval=self.server.ping_interval, ping_timeout=self.server.ping_timeout, link_ping_interval=self.server.link_ping_interval, link_ping_timeout=self.server.link_ping_timeout, allowed_devices=self.server.allowed_devices, max_clients=self.server.max_clients, replica_count=self.server.replica_count, dns_mapping=self.server.dns_mapping, debug=self.server.debug, interface=self.interface, bridge_interface=self.bridge_interface, vxlan=self.vxlan, ) self.interrupt = True self.bridge_stop() self.iptables.clear_rules() self.resources_release() if not self.clean_exit: event.Event(type=SERVERS_UPDATED) self.server.send_link_events() logger.LogEntry(message='Server stopped unexpectedly "%s".' % (self.server.name)) except: self.interrupt = True self.stop_process() if self.resource_lock: self.iptables.clear_rules() self.bridge_stop() self.resources_release() logger.exception( 'Server error occurred while running', 'server', server_id=self.server.id, ) finally: self.stop_threads() self.collection.update( { '_id': self.server.id, 'instances.instance_id': self.id, }, { '$pull': { 'instances': { 'instance_id': self.id, }, }, '$inc': { 'instances_count': -1, }, }) utils.rmtree(self._temp_path)