def org_put(org_id): org = organization.get_org(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 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 user_otp_secret_put(org_id, user_id): org = organization.get_org(id=org_id) user = org.get_user(user_id) user.generate_otp_secret() user.commit() event.Event(type=USERS_UPDATED, resource_id=org.id) return utils.jsonify(user.dict())
def org_delete(org_id): org = organization.get_org(id=org_id) name = org.name org.remove() logger.LogEntry(message='Deleted organization "%s".' % name) event.Event(type=ORGS_UPDATED) return utils.jsonify({})
def org_get(org_id=None): if org_id: return utils.jsonify(organization.get_org(id=org_id).dict()) orgs = [] for org in organization.iter_orgs(): orgs.append(org.dict()) return utils.jsonify(orgs)
def _get_key_archive(org_id, user_id): org = organization.get_org(id=org_id) user = org.get_user(user_id) key_archive = user.build_key_archive() response = flask.Response(response=key_archive, mimetype='application/octet-stream') response.headers.add('Content-Disposition', 'attachment; filename="%s.tar"' % user.name) return response
def org_delete(org_id): org = organization.get_org(id=org_id) name = org.name server_ids = org.remove() logger.LogEntry(message='Deleted organization "%s".' % name) for server_id in server_ids: event.Event(type=SERVER_ORGS_UPDATED, resource_id=server_id) event.Event(type=SERVERS_UPDATED) event.Event(type=ORGS_UPDATED) return utils.jsonify({})
def key_sync_get(org_id, user_id, server_id): org = organization.get_org(id=org_id) user = org.get_user(id=user_id) sync_key = flask.request.json['sync_key'] key_hash = flask.request.json['key_hash'] if sync_key != user.sync_key: raise flask.abort(401) key_conf = user.sync_conf(server_id, key_hash) if key_conf: return key_conf['conf'] return ''
def iter_orgs(self): for org_id in self.organizations: org = organization.get_org(id=org_id) if org: yield org else: logger.error('Removing non-existent organization ' + 'from server. %r' % { 'server_id': self.id, 'org_id': org_id, }) self.remove_org(org_id) self.commit('organizations') event.Event(type=SERVER_ORGS_UPDATED, resource_id=self.id)
def server_org_delete(server_id, org_id): svr = server.get_server(id=server_id) org = organization.get_org(id=org_id) if svr.status: return utils.jsonify({ 'error': SERVER_NOT_OFFLINE, 'error_msg': SERVER_NOT_OFFLINE_DETACH_ORG_MSG, }, 400) svr.remove_org(org) svr.commit(svr.changed) event.Event(type=SERVERS_UPDATED) event.Event(type=SERVER_ORGS_UPDATED, resource_id=svr.id) event.Event(type=USERS_UPDATED, resource_id=org.id) return utils.jsonify({})
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 get_link_user(self, org_id): from pritunl import organization logger.debug('Creating host link user. %r' % { 'host_id': self.id, }) org = organization.get_org(id=org_id) usr = org.find_user(resource_id=self.id) if not usr: usr = org.new_user(name=HOST_USER_PREFIX + str(self.id), type=CERT_SERVER, resource_id=self.id) return usr
def server_org_delete(server_id, org_id): svr = server.get_server(id=server_id) org = organization.get_org(id=org_id) if svr.status: return utils.jsonify( { 'error': SERVER_NOT_OFFLINE, 'error_msg': SERVER_NOT_OFFLINE_DETACH_ORG_MSG, }, 400) svr.remove_org(org) svr.commit(svr.changed) event.Event(type=SERVERS_UPDATED) event.Event(type=SERVER_ORGS_UPDATED, resource_id=svr.id) event.Event(type=USERS_UPDATED, resource_id=org.id) return utils.jsonify({})
def _remove_primary_user(self): logger.debug('Removing primary user. %r' % { 'server_id': self.id, }) if not self.primary_organization or not self.primary_user: return org = organization.get_org(id=self.primary_organization) if org: user = org.get_user(id=self.primary_user) if user: user.remove() self.primary_organization = None self.primary_user = None
def user_delete(org_id, user_id): org = organization.get_org(id=org_id) user = org.get_user(user_id) name = user.name user.remove() event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) for svr in org.iter_servers(fields=('instances',)): for instance in svr.instances: if user_id in instance['clients']: svr.restart() logger.LogEntry(message='Deleted user "%s".' % name) return utils.jsonify({})
def user_delete(org_id, user_id): org = organization.get_org(id=org_id) user = org.get_user(user_id) name = user.name user.remove() event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) for svr in org.iter_servers(): server_clients = svr.clients if user_id in server_clients: svr.restart() logger.LogEntry(message='Deleted user "%s".' % name) return utils.jsonify({})
def server_org_put(server_id, org_id): svr = server.get_server(id=server_id) org = organization.get_org(id=org_id) if svr.status: return utils.jsonify({ 'error': SERVER_NOT_OFFLINE, 'error_msg': SERVER_NOT_OFFLINE_ATTACH_ORG_MSG, }, 400) svr.add_org(org) svr.commit(svr.changed) event.Event(type=SERVERS_UPDATED) event.Event(type=SERVER_ORGS_UPDATED, resource_id=svr.id) event.Event(type=USERS_UPDATED, resource_id=org.id) return utils.jsonify({ 'id': org.id, 'server': svr.id, 'name': org.name, })
def server_org_put(server_id, org_id): svr = server.get_server(id=server_id) org = organization.get_org(id=org_id) if svr.status: return utils.jsonify( { 'error': SERVER_NOT_OFFLINE, 'error_msg': SERVER_NOT_OFFLINE_ATTACH_ORG_MSG, }, 400) svr.add_org(org) svr.commit(svr.changed) event.Event(type=SERVERS_UPDATED) event.Event(type=SERVER_ORGS_UPDATED, resource_id=svr.id) event.Event(type=USERS_UPDATED, resource_id=org.id) return utils.jsonify({ 'id': org.id, 'server': svr.id, 'name': org.name, })
def user_uri_key_page_get(short_id): collection = mongo.get_collection('users_key_link') doc = collection.find_one({ 'short_id': short_id, }) if not doc: time.sleep(settings.app.rate_limit_sleep) return flask.abort(404) org = organization.get_org(id=doc['org_id']) user = org.get_user(id=doc['user_id']) keys = {} for server in org.iter_servers(): key = user.build_key_conf(server.id) keys[key['name']] = key['conf'] return utils.jsonify(keys)
def user_linked_key_conf_get(key_id, server_id): collection = mongo.get_collection('users_key_link') doc = collection.find_one({ 'key_id': key_id, }) if not doc: time.sleep(settings.app.rate_limit_sleep) return flask.abort(404) org = organization.get_org(id=doc['org_id']) user = org.get_user(id=doc['user_id']) key_conf = user.build_key_conf(server_id) response = flask.Response(response=key_conf['conf'], mimetype='application/octet-stream') response.headers.add('Content-Disposition', 'attachment; filename="%s"' % key_conf['name']) return response
def user_linked_key_page_get(short_id): collection = mongo.get_collection('users_key_link') doc = collection.find_one({ 'short_id': short_id, }) if not doc: time.sleep(settings.app.rate_limit_sleep) return flask.abort(404) org = organization.get_org(id=doc['org_id']) user = org.get_user(id=doc['user_id']) key_page = static.StaticFile(settings.conf.www_path, KEY_INDEX_NAME, cache=False).data key_page = key_page.replace('<%= user_name %>', '%s - %s' % (org.name, user.name)) key_page = key_page.replace('<%= user_key_url %>', '/key/%s.tar' % (doc['key_id'])) if org.otp_auth: key_page = key_page.replace('<%= user_otp_key %>', user.otp_secret) key_page = key_page.replace( '<%= user_otp_url %>', 'otpauth://totp/%s@%s?secret=%s' % (user.name, org.name, user.otp_secret)) else: key_page = key_page.replace('<%= user_otp_key %>', '') key_page = key_page.replace('<%= user_otp_url %>', '') key_page = key_page.replace('<%= short_id %>', doc['short_id']) conf_links = '' for server in org.iter_servers(): conf_links += '<a class="sm" title="Download Key" ' + \ 'href="/key/%s/%s.key">Download Key (%s)</a><br>\n' % ( doc['key_id'], server.id, server.name) key_page = key_page.replace('<%= conf_links %>', conf_links) return key_page
def user_linked_key_page_get(short_id): collection = mongo.get_collection('users_key_link') doc = collection.find_one({ 'short_id': short_id, }) if not doc: time.sleep(settings.app.rate_limit_sleep) return flask.abort(404) org = organization.get_org(id=doc['org_id']) user = org.get_user(id=doc['user_id']) key_page = static.StaticFile(settings.conf.www_path, KEY_INDEX_NAME, cache=False).data key_page = key_page.replace('<%= user_name %>', '%s - %s' % ( org.name, user.name)) key_page = key_page.replace('<%= user_key_url %>', '/key/%s.tar' % ( doc['key_id'])) if org.otp_auth: key_page = key_page.replace('<%= user_otp_key %>', user.otp_secret) key_page = key_page.replace('<%= user_otp_url %>', 'otpauth://totp/%s@%s?secret=%s' % ( user.name, org.name, user.otp_secret)) else: key_page = key_page.replace('<%= user_otp_key %>', '') key_page = key_page.replace('<%= user_otp_url %>', '') key_page = key_page.replace('<%= short_id %>', doc['short_id']) conf_links = '' for server in org.iter_servers(): conf_links += '<a class="sm" title="Download Key" ' + \ 'href="/key/%s/%s.key">Download Key (%s)</a><br>\n' % ( doc['key_id'], server.id, server.name) key_page = key_page.replace('<%= conf_links %>', conf_links) return key_page
def generate_ovpn_conf(self): from pritunl.server.utils import get_by_id logger.debug('Generating server ovpn conf. %r' % { 'server_id': self.server.id, }) if not self.server.primary_organization or \ not self.server.primary_user: self.server.create_primary_user() primary_org = organization.get_org(id=self.server.primary_organization) if not primary_org: self.server.create_primary_user() primary_org = organization.get_org( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) if not self.primary_user: self.server.create_primary_user() primary_org = organization.get_org( id=self.server.primary_organization) self.primary_user = primary_org.get_user(self.server.primary_user) with open(self.auth_log_path, 'w') as auth_log: os.chmod(self.auth_log_path, 0600) auth_host = settings.conf.bind_addr if auth_host == '0.0.0.0': auth_host = 'localhost' for script, script_path in ( (TLS_VERIFY_SCRIPT, self.tls_verify_path), (USER_PASS_VERIFY_SCRIPT, self.user_pass_verify_path), (CLIENT_CONNECT_SCRIPT, self.client_connect_path), (CLIENT_DISCONNECT_SCRIPT, self.client_disconnect_path), ): with open(script_path, 'w') as script_file: os.chmod(script_path, 0755) # TODO script_file.write(script % ( settings.app.server_api_key, self.auth_log_path, 'https' if settings.conf.ssl else 'http', auth_host, settings.conf.port, self.server.id, )) push = '' if self.server.mode == LOCAL_TRAFFIC: for network in self.server.local_networks: push += 'push "route %s %s"\n' % utils.parse_network(network) elif self.server.mode == VPN_TRAFFIC: pass else: push += 'push "redirect-gateway"\n' for dns_server in self.server.dns_servers: push += 'push "dhcp-option DNS %s"\n' % dns_server if self.server.search_domain: push += 'push "dhcp-option DOMAIN %s"\n' % ( self.server.search_domain) for link_doc in self.server.links: link_svr = get_by_id(link_doc['server_id']) push += 'push "route %s %s"\n' % utils.parse_network( link_svr.network) for local_network in link_svr.local_networks: push += 'push "route %s %s"\n' % utils.parse_network( local_network) server_conf = OVPN_INLINE_SERVER_CONF % ( self.server.port, self.server.protocol, self.interface, self.tls_verify_path, self.client_connect_path, self.client_disconnect_path, '%s %s' % utils.parse_network(self.server.network), CIPHERS[self.server.cipher], self.ovpn_status_path, 4 if self.server.debug else 1, 8 if self.server.debug else 3, ) if self.server.bind_address: server_conf += 'local %s\n' % self.server.bind_address if self.server.otp_auth: server_conf += 'auth-user-pass-verify %s via-file\n' % ( self.user_pass_verify_path) # Pritunl v0.10.x did not include comp-lzo in client conf # if lzo_compression is adaptive dont include comp-lzo in server conf if self.server.lzo_compression == ADAPTIVE: pass elif self.server.lzo_compression: server_conf += 'comp-lzo yes\npush "comp-lzo yes"\n' else: server_conf += 'comp-lzo no\npush "comp-lzo no"\n' if self.server.mode in (LOCAL_TRAFFIC, VPN_TRAFFIC): server_conf += 'client-to-client\n' server_conf += JUMBO_FRAMES[self.server.jumbo_frames] if push: server_conf += push server_conf += '<ca>\n%s\n</ca>\n' % utils.get_cert_block( self.server.ca_certificate) server_conf += '<cert>\n%s\n</cert>\n' % utils.get_cert_block( self.primary_user.certificate) server_conf += '<key>\n%s\n</key>\n' % self.primary_user.private_key server_conf += '<dh>\n%s\n</dh>\n' % self.server.dh_params with open(self.ovpn_conf_path, 'w') as ovpn_conf: os.chmod(self.ovpn_conf_path, 0600) ovpn_conf.write(server_conf)
def get_org(self, org_id, fields=None): if org_id in self.organizations: return organization.get_org(id=org_id, fields=fields)
def user_get(org_id, user_id=None, page=None): org = organization.get_org(id=org_id) if user_id: return utils.jsonify(org.get_user(user_id).dict()) page = flask.request.args.get('page', None) page = int(page) if page else page search = flask.request.args.get('search', None) limit = int(flask.request.args.get('limit', settings.user.page_count)) otp_auth = False search_more = True server_count = 0 clients = {} servers = [] fields = ( 'name', 'clients', 'otp_auth', ) for svr in org.iter_servers(fields=fields): servers.append(svr) server_count += 1 if svr.otp_auth: otp_auth = True server_clients = svr.clients for client, client_id in server_clients.iteritems(): if client_id not in clients: clients[client_id] = {} clients[client_id][svr.id] = client users = [] users_id = [] users_server_data = collections.defaultdict(dict) fields = ( 'organization', 'organization_name', 'name', 'email', 'type', 'otp_secret', 'disabled', ) for user in org.iter_users(page=page, search=search, search_limit=limit, fields=fields): user_id = user.id users_id.append(user_id) is_client = user_id in clients user_dict = user.dict() user_dict['status'] = is_client user_dict['otp_auth'] = otp_auth server_data = [] for svr in servers: server_id = svr.id user_status = is_client and server_id in clients[user_id] data = { 'id': server_id, 'name': svr.name, 'status': user_status, 'local_address': None, 'remote_address': None, 'real_address': None, 'virt_address': None, 'bytes_received': None, 'bytes_sent': None, 'connected_since': None, } users_server_data[user_id][server_id] = data if user_status: data.update(clients[user_id][server_id]) server_data.append(data) user_dict['servers'] = server_data users.append(user_dict) ip_addrs_iter = server.multi_get_ip_addr(org_id, users_id) for user_id, server_id, local_addr, remote_addr in ip_addrs_iter: user_server_data = users_server_data[user_id].get(server_id) if user_server_data: if not user_server_data['local_address']: user_server_data['local_address'] = local_addr if not user_server_data['remote_address']: user_server_data['remote_address'] = remote_addr if page is not None: return utils.jsonify({ 'page': page, 'page_total': org.page_total, 'server_count': server_count, 'users': users, }) elif search is not None: return utils.jsonify({ 'search': search, 'search_more': limit < org.last_search_count, 'search_limit': limit, 'search_count': org.last_search_count, 'search_time': round((time.time() - flask.g.start), 4), 'server_count': server_count, 'users': users, }) else: return utils.jsonify(users)
def _generate_ovpn_conf(self): logger.debug('Generating server ovpn conf. %r' % { 'server_id': self.id, }) if not self.primary_organization or not self.primary_user: self._create_primary_user() primary_org = organization.get_org(id=self.primary_organization) if not primary_org: self._create_primary_user() primary_org = organization.get_org(id=self.primary_organization) primary_user = primary_org.get_user(self.primary_user) if not primary_user: self._create_primary_user() primary_org = organization.get_org(id=self.primary_organization) primary_user = primary_org.get_user(self.primary_user) tls_verify_path = os.path.join(self._temp_path, TLS_VERIFY_NAME) user_pass_verify_path = os.path.join(self._temp_path, USER_PASS_VERIFY_NAME) client_connect_path = os.path.join(self._temp_path, CLIENT_CONNECT_NAME) client_disconnect_path = os.path.join(self._temp_path, CLIENT_DISCONNECT_NAME) ovpn_status_path = os.path.join(self._temp_path, OVPN_STATUS_NAME) ovpn_conf_path = os.path.join(self._temp_path, OVPN_CONF_NAME) auth_host = settings.conf.bind_addr if auth_host == '0.0.0.0': auth_host = 'localhost' for script, script_path in ( (TLS_VERIFY_SCRIPT, tls_verify_path), (USER_PASS_VERIFY_SCRIPT, user_pass_verify_path), (CLIENT_CONNECT_SCRIPT, client_connect_path), (CLIENT_DISCONNECT_SCRIPT, client_disconnect_path), ): with open(script_path, 'w') as script_file: os.chmod(script_path, 0755) # TODO script_file.write(script % ( settings.app.server_api_key, '/dev/null', # TODO 'https' if settings.conf.ssl else 'http', auth_host, settings.conf.port, self.id, )) push = '' if self.mode == LOCAL_TRAFFIC: for network in self.local_networks: push += 'push "route %s %s"\n' % self._parse_network(network) elif self.mode == VPN_TRAFFIC: pass else: push += 'push "redirect-gateway"\n' for dns_server in self.dns_servers: push += 'push "dhcp-option DNS %s"\n' % dns_server if self.search_domain: push += 'push "dhcp-option DOMAIN %s"\n' % self.search_domain server_conf = OVPN_INLINE_SERVER_CONF % ( self.port, self.protocol, self.interface, tls_verify_path, client_connect_path, client_disconnect_path, '%s %s' % self._parse_network(self.network), ovpn_status_path, 4 if self.debug else 1, 8 if self.debug else 3, ) if self.otp_auth: server_conf += 'auth-user-pass-verify %s via-file\n' % ( user_pass_verify_path) if self.lzo_compression: server_conf += 'comp-lzo\npush "comp-lzo"\n' if self.mode in (LOCAL_TRAFFIC, VPN_TRAFFIC): server_conf += 'client-to-client\n' if push: server_conf += push server_conf += '<ca>\n%s\n</ca>\n' % utils.get_cert_block( self.ca_certificate) server_conf += '<cert>\n%s\n</cert>\n' % utils.get_cert_block( primary_user.certificate) server_conf += '<key>\n%s\n</key>\n' % primary_user.private_key server_conf += '<dh>\n%s\n</dh>\n' % self.dh_params with open(ovpn_conf_path, 'w') as ovpn_conf: os.chmod(ovpn_conf_path, 0600) ovpn_conf.write(server_conf)
def user_key_link_get(org_id, user_id): org = organization.get_org(id=org_id) return utils.jsonify(org.create_user_key_link(user_id))
def get_org(self, org_id): if org_id in self.organizations: return organization.get_org(id=org_id)
def assign_ip_pool_org(self, org_id): org = organization.get_org(id=org_id) network = self.server.network server_id = self.server.id org_id = org.id ip_pool_avial = True pool_end = False ip_network = ipaddress.IPv4Network(network) ip_pool = ip_network.iterhosts() ip_pool.next() try: doc = self.collection.find({ 'network': network, 'server_id': server_id, }).sort('_id', pymongo.DESCENDING)[0] if doc: last_addr = doc['_id'] for remote_ip_addr in ip_pool: if int(remote_ip_addr) == last_addr: break except IndexError: pass if mongo.has_bulk: bulk = self.collection.initialize_unordered_bulk_op() bulk_empty = True else: bulk = None bulk_empty = None for user in org.iter_users(include_pool=True): if ip_pool_avial: response = self.collection.update({ 'network': network, 'server_id': server_id, 'user_id': {'$exists': False}, }, {'$set': { 'org_id': org_id, 'user_id': user.id, }}) if response['updatedExisting']: continue ip_pool_avial = False try: remote_ip_addr = ip_pool.next() except StopIteration: pool_end = True break doc_id = int(remote_ip_addr) spec = { '_id': doc_id, } doc = {'$set': { '_id': doc_id, 'network': network, 'server_id': server_id, 'org_id': org_id, 'user_id': user.id, 'address': '%s/%s' % (remote_ip_addr, ip_network.prefixlen), }} if bulk: bulk.find(spec).upsert().update(doc) bulk_empty = False else: self.collection.update(spec, doc, upsert=True) if bulk and not bulk_empty: bulk.execute() if pool_end: logger.warning('Failed to assign ip addresses ' + 'to org, ip pool empty. %r' % { 'org_id': org_id, 'user_id': user_id, })