def server_put_post(server_id=None): network_used = set() interface_used = set() port_used = set() for server in Server.iter_servers(): if server.id == server_id: continue network_used.add(server.network) interface_used.add(server.interface) port_used.add('%s%s' % (server.port, server.protocol)) 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 network not in SAFE_PUB_SUBNETS: network_split = network.split('/') if len(network_split) != 2: return _network_invalid() address = network_split[0].split('.') if len(address) != 4: return _network_invalid() for i, value in enumerate(address): try: address[i] = int(value) except ValueError: return _network_invalid() if address[0] != 10: return _network_invalid() if address[1] > 255 or address[1] < 0 or \ address[2] > 255 or address[2] < 0: return _network_invalid() if address[3] != 0: return _network_invalid() try: subnet = int(network_split[1]) except ValueError: return _network_invalid() if subnet < 8 or subnet > 24: return _network_invalid() interface = None interface_def = False if 'interface' in flask.request.json: interface_def = True interface = flask.request.json['interface'] if not re.match('^[a-z0-9]+$', interface): return _interface_invalid() if interface[:3] != 'tun': return _interface_invalid() try: interface_num = int(interface[3:]) except ValueError: return _interface_invalid() if interface_num > 64: return _interface_invalid() interface = interface[:3] + str(interface_num) 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 'dh_param_bits' in flask.request.json: 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) 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 < 8 or subnet > 30: 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']) public_address = None public_address_def = False if 'public_address' in flask.request.json: public_address_def = True public_address = utils.filter_str(flask.request.json['public_address']) 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 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 for i in xrange(5000): rand_network = '10.%s.%s.0/24' % ( random.randint(15,250), random.randint(15,250)) if rand_network not in 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 interface_def: interface_def = True for i in xrange(64): rand_interface = 'tun%s' % i if rand_interface not in interface_used: interface = rand_interface break if not interface: return utils.jsonify({ 'error': INTERFACE_IN_USE, 'error_msg': INTERFACE_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 = 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 not public_address_def: public_address_def = True public_address = app_server.public_ip if network_def: if network in network_used: return utils.jsonify({ 'error': NETWORK_IN_USE, 'error_msg': NETWORK_IN_USE_MSG, }, 400) if interface_def: if interface in interface_used: return utils.jsonify({ 'error': INTERFACE_IN_USE, 'error_msg': INTERFACE_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: server = Server.new_server( name=name, network=network, interface=interface, port=port, protocol=protocol, dh_param_bits=dh_param_bits, mode=mode, local_networks=local_networks, dns_servers=dns_servers, search_domain=search_domain, public_address=public_address, otp_auth=otp_auth, lzo_compression=lzo_compression, debug=debug, ) else: server = Server.get_server(id=server_id) if server.status: return utils.jsonify({ 'error': SERVER_NOT_OFFLINE, 'error_msg': SERVER_NOT_OFFLINE_SETTINGS_MSG, }, 400) if name_def: server.name = name if network_def: server.network = network if interface_def: server.interface = interface if port_def: server.port = port if protocol_def: server.protocol = protocol if dh_param_bits_def and server.dh_param_bits != dh_param_bits: server.dh_param_bits = dh_param_bits server.generate_dh_param() if mode_def: server.mode = mode if local_networks_def: server.local_networks = local_networks if dns_servers_def: server.dns_servers = dns_servers if search_domain_def: server.search_domain = search_domain if public_address_def: server.public_address = public_address if otp_auth_def: server.otp_auth = otp_auth if lzo_compression_def: server.lzo_compression = lzo_compression if debug_def: server.debug = debug server.commit() LogEntry(message='Created server "%s".' % server.name) Event(type=SERVERS_UPDATED) for org in server.iter_orgs(): Event(type=USERS_UPDATED, resource_id=org.id) return utils.jsonify(server.dict())