def setup_settings(): if not settings.app.oracle_private_key or \ not settings.app.oracle_public_key: private_key, public_key = utils.generate_rsa_key() settings.app.oracle_private_key = private_key settings.app.oracle_public_key = public_key settings.commit()
def auth_put(): admin = flask.g.administrator if 'username' in flask.request.json and flask.request.json['username']: admin.username = utils.filter_str(flask.request.json['username']) if 'password' in flask.request.json and flask.request.json['password']: admin.password = flask.request.json['password'] if 'token' in flask.request.json and flask.request.json['token']: admin.generate_token() if 'secret' in flask.request.json and flask.request.json['secret']: admin.generate_secret() settings_commit = False if 'email_from' in flask.request.json: settings_commit = True email_from = flask.request.json['email_from'] settings.app.email_from_addr = email_from or None if 'email_api_key' in flask.request.json: settings_commit = True email_api_key = flask.request.json['email_api_key'] settings.app.email_api_key = email_api_key or None if settings_commit: settings.commit() admin.commit(admin.changed) response = flask.g.administrator.dict() response.update({ 'email_from': settings.app.email_from_addr, 'email_api_key': settings.app.email_api_key, }) return utils.jsonify(response)
def auth_put(): admin = flask.g.administrator if 'username' in flask.request.json and flask.request.json['username']: admin.username = utils.filter_str( flask.request.json['username']).lower() if 'password' in flask.request.json and flask.request.json['password']: admin.password = flask.request.json['password'] if 'token' in flask.request.json and flask.request.json['token']: admin.generate_token() if 'secret' in flask.request.json and flask.request.json['secret']: admin.generate_secret() settings_commit = False if 'email_from' in flask.request.json: settings_commit = True email_from = flask.request.json['email_from'] settings.app.email_from_addr = email_from or None if 'email_api_key' in flask.request.json: settings_commit = True email_api_key = flask.request.json['email_api_key'] settings.app.email_api_key = email_api_key or None if settings_commit: settings.commit() admin.commit(admin.changed) response = flask.g.administrator.dict() response.update({ 'email_from': settings.app.email_from_addr, 'email_api_key': settings.app.email_api_key, }) return utils.jsonify(response)
def setup_server_cert(): if not settings.app.server_dh_params: utils.create_server_dh_params() settings.commit() if not settings.app.server_cert or not settings.app.server_key: utils.create_server_cert() settings.commit()
def update_license(license): settings.app.license = license settings.app.license_plan = None settings.commit() valid = update() messenger.publish('subscription', 'updated') if not valid: raise LicenseInvalid('License key is invalid')
def setup_server_cert(): commit = False if not settings.app.server_cert or not settings.app.server_key: commit = True utils.create_server_cert() if commit: settings.commit()
def setup_server_cert(): commit = False if not settings.app.server_cert or not settings.app.server_key: commit = True logger.info('Generating server certificate...', 'app') utils.create_server_cert() if commit: settings.commit()
def setup_server_cert(): global _cur_cert global _cur_key if not settings.app.server_cert or not settings.app.server_key: logger.info('Generating server certificate...', 'app') utils.create_server_cert() settings.commit() _cur_cert = settings.app.server_cert _cur_key = settings.app.server_key
def update_acme_cert(): if not settings.app.acme_key: settings.app.acme_key = utils.generate_private_key() settings.commit() private_key = utils.generate_private_ec_key() csr = utils.generate_csr(private_key, settings.app.acme_domain) cert = get_acme_cert(settings.app.acme_key, csr) settings.app.server_key = private_key.strip() settings.app.server_cert = cert.strip() settings.app.acme_timestamp = utils.time_now() settings.commit()
def auth_put(): admin = flask.g.administrator if 'username' in flask.request.json and flask.request.json['username']: admin.username = utils.filter_str( flask.request.json['username']).lower() if 'password' in flask.request.json and flask.request.json['password']: admin.password = flask.request.json['password'] if 'token' in flask.request.json and flask.request.json['token']: admin.generate_token() if 'secret' in flask.request.json and flask.request.json['secret']: admin.generate_secret() settings_commit = False if 'email_from' in flask.request.json: settings_commit = True email_from = flask.request.json['email_from'] settings.app.email_from_addr = email_from or None if 'email_api_key' in flask.request.json: settings_commit = True email_api_key = flask.request.json['email_api_key'] settings.app.email_api_key = email_api_key or None if 'theme' in flask.request.json: settings_commit = True theme = 'dark' if flask.request.json['theme'] == 'dark' else 'light' if theme != settings.app.theme: if theme == 'dark': event.Event(type=THEME_DARK) else: event.Event(type=THEME_LIGHT) settings.app.theme = theme if settings_commit: settings.commit() admin.commit(admin.changed) response = flask.g.administrator.dict() response.update({ 'email_from': settings.app.email_from_addr, 'email_api_key': settings.app.email_api_key, }) return utils.jsonify(response)
def update(): cur_sub_active = settings.local.sub_active license = settings.app.license if not license: settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_cancel_at_period_end = None else: try: response = utils.request.get(SUBSCRIPTION_SERVER, json_data={'license': license}, timeout=max(settings.app.http_request_timeout, 10)) # License key invalid if response.status_code == 470: settings.app.license = None settings.commit() subscription_update() return data = response.json() settings.local.sub_active = data.get('active', False) settings.local.sub_status = data.get('status', 'unknown') settings.local.sub_amount = data.get('amount') settings.local.sub_period_end = data.get('period_end') settings.local.sub_cancel_at_period_end = data.get( 'cancel_at_period_end') except: logger.exception('Failed to check subscription status...') settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_cancel_at_period_end = None if cur_sub_active is not None and \ cur_sub_active != settings.local.sub_active: if settings.local.sub_active: event.Event(type=SUBSCRIPTION_ACTIVE) else: event.Event(type=SUBSCRIPTION_INACTIVE)
def setup_server_cert(): server_cert_path = os.path.join(settings.conf.temp_path, SERVER_CERT_NAME) server_key_path = os.path.join(settings.conf.temp_path, SERVER_KEY_NAME) if not settings.app.server_cert or not settings.app.server_key: logger.info('Generating server ssl cert', 'setup') utils.generate_server_cert(server_cert_path, server_key_path) with open(server_cert_path, 'r') as server_cert_file: settings.app.server_cert = server_cert_file.read().strip() with open(server_key_path, 'r') as server_key_file: settings.app.server_key = server_key_file.read().strip() settings.commit() else: with open(server_cert_path, 'w') as server_cert_file: server_cert_file.write(settings.app.server_cert) with open(server_key_path, 'w') as server_key_file: os.chmod(server_key_path, 0600) server_key_file.write(settings.app.server_key)
def setup_server_cert(): server_cert_path = os.path.join(settings.conf.temp_path, SERVER_CERT_NAME) server_key_path = os.path.join(settings.conf.temp_path, SERVER_KEY_NAME) if not settings.app.server_cert or not settings.app.server_key: logger.info("Generating server ssl cert", "setup") utils.generate_server_cert(server_cert_path, server_key_path) with open(server_cert_path, "r") as server_cert_file: settings.app.server_cert = server_cert_file.read().strip() with open(server_key_path, "r") as server_key_file: settings.app.server_key = server_key_file.read().strip() settings.commit() else: with open(server_cert_path, "w") as server_cert_file: server_cert_file.write(settings.app.server_cert) with open(server_key_path, "w") as server_key_file: os.chmod(server_key_path, 0600) server_key_file.write(settings.app.server_key)
def setup_mongo(): prefix = settings.conf.mongodb_collection_prefix or '' read_pref = _get_read_pref(settings.conf.mongodb_read_preference) max_pool = settings.conf.mongodb_max_pool_size or None last_error = time.time() - 24 while True: try: if read_pref: client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, serverSelectionTimeoutMS=MONGO_SOCKET_TIMEOUT, maxPoolSize=max_pool, read_preference=read_pref, ) else: client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, serverSelectionTimeoutMS=MONGO_SOCKET_TIMEOUT, maxPoolSize=max_pool, ) break except pymongo.errors.ConnectionFailure: time.sleep(0.5) if time.time() - last_error > 30: last_error = time.time() logger.exception('Error connecting to mongodb server') database = client.get_default_database() settings_col = getattr(database, prefix + 'settings') app_settings = settings_col.find_one({'_id': 'app'}) if app_settings: secondary_mongodb_uri = app_settings.get('secondary_mongodb_uri') else: secondary_mongodb_uri = None if secondary_mongodb_uri: while True: try: read_pref = _get_read_pref( settings.conf.mongodb_read_preference) if read_pref: secondary_client = pymongo.MongoClient( secondary_mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, serverSelectionTimeoutMS=MONGO_SOCKET_TIMEOUT, maxPoolSize=max_pool, read_preference=read_pref, ) else: secondary_client = pymongo.MongoClient( secondary_mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, serverSelectionTimeoutMS=MONGO_SOCKET_TIMEOUT, maxPoolSize=max_pool, ) break except pymongo.errors.ConnectionFailure: time.sleep(0.5) if time.time() - last_error > 30: last_error = time.time() logger.exception( 'Error connecting to secondary mongodb server') secondary_database = secondary_client.get_default_database() else: secondary_database = database mongo.database = database mongo.secondary_database = secondary_database cur_collections = database.collection_names() cur_sec_collections = secondary_database.collection_names() if 'authorities' in cur_collections or \ 'authorities' in cur_sec_collections: raise TypeError('Cannot connect to a Pritunl Zero database') mongo.collection_types = { 'transaction': 1, 'queue': 1, 'tasks': 1, 'settings': 1, 'messages': 2, 'administrators': 1, 'users': 1, 'users_audit': 1, 'users_key_link': 2, 'users_net_link': 1, 'clients': 1, 'clients_pool': 1, 'organizations': 1, 'hosts': 1, 'hosts_usage': 1, 'servers': 1, 'servers_output': 1, 'servers_output_link': 1, 'servers_bandwidth': 1, 'servers_ip_pool': 1, 'links': 1, 'links_locations': 1, 'links_hosts': 1, 'routes_reserve': 1, 'dh_params': 1, 'acme_challenges': 1, 'auth_sessions': 2, 'auth_csrf_tokens': 2, 'auth_nonces': 2, 'auth_limiter': 2, 'otp': 2, 'otp_cache': 2, 'yubikey': 2, 'sso_tokens': 2, 'sso_push_cache': 2, 'sso_client_cache': 2, 'sso_passcode_cache': 2, 'vxlans': 1, 'logs': 1, 'log_entries': 1, } cur_collections = mongo.secondary_database.collection_names() if prefix + 'messages' not in cur_collections: mongo.secondary_database.create_collection( prefix + 'messages', capped=True, size=5000192, max=1000) elif not mongo.get_collection('messages').options().get('capped'): mongo.get_collection('messages').drop() mongo.secondary_database.create_collection( prefix + 'messages', capped=True, size=5000192, max=1000) settings.local.mongo_time = None while True: try: utils.sync_time() break except: logger.exception('Failed to sync time', 'setup') time.sleep(30) settings.init() upsert_indexes() if not auth.Administrator.collection.find_one(): default_admin = auth.Administrator( username=DEFAULT_USERNAME, ) default_admin.generate_default_password() default_admin.commit() secret_key = settings.app.cookie_secret secret_key2 = settings.app.cookie_secret2 settings_commit = False if not secret_key: settings_commit = True secret_key = utils.rand_str(64) settings.app.cookie_secret = secret_key if not secret_key2: settings_commit = True settings.app.cookie_secret2 = utils.rand_str(64) if settings_commit: settings.commit() app.app.secret_key = secret_key.encode()
def main(default_conf=None): if len(sys.argv) > 1: cmd = sys.argv[1] else: cmd = 'start' parser = optparse.OptionParser(usage=USAGE) if cmd == 'start': parser.add_option('-d', '--daemon', action='store_true', help='Daemonize process') parser.add_option('-p', '--pidfile', type='string', help='Path to create pid file') parser.add_option('-c', '--conf', type='string', help='Path to configuration file') parser.add_option('-q', '--quiet', action='store_true', help='Suppress logging output') parser.add_option('--dart-url', type='string', help='Dart pub serve url to redirect static requests') elif cmd == 'logs': parser.add_option('--archive', action='store_true', help='Archive log file') parser.add_option('--tail', action='store_true', help='Tail log file') parser.add_option('--limit', type='int', help='Limit log lines') (options, args) = parser.parse_args() if hasattr(options, 'conf') and options.conf: conf_path = options.conf else: conf_path = default_conf pritunl.set_conf_path(conf_path) if cmd == 'version': print '%s v%s' % (pritunl.__title__, pritunl.__version__) sys.exit(0) elif cmd == 'reset-password': from pritunl.constants import DEFAULT_USERNAME, DEFAULT_PASSWORD from pritunl import setup from pritunl import auth setup.setup_db() username, password = auth.reset_password() time.sleep(1) print 'Administrator password successfully reset:\n' + \ ' username: "******"\n password: "******"' % (username, password) sys.exit(0) elif cmd == 'reconfigure': from pritunl import setup from pritunl import settings setup.setup_loc() settings.conf.mongodb_uri = None settings.conf.commit() time.sleep(1) print 'Database configuration successfully reset' sys.exit(0) elif cmd == 'reset-ssl-cert': from pritunl import setup from pritunl import settings setup.setup_db() settings.app.server_cert = None settings.app.server_key = None settings.commit() time.sleep(1) print 'Server ssl certificate successfully reset' sys.exit(0) elif cmd == 'logs': from pritunl.constants import DEFAULT_USERNAME, DEFAULT_PASSWORD from pritunl import setup from pritunl import logger setup.setup_db() log_view = logger.LogView() if options.archive: if len(args) > 1: archive_path = args[1] else: archive_path = './' print 'Log archived to: ' + log_view.archive_log(archive_path, options.limit) elif options.tail: for msg in log_view.tail_log_lines(): print msg else: print log_view.get_log_lines(options.limit) sys.exit(0) elif cmd != 'start': raise ValueError('Invalid command') from pritunl import settings settings.local.dart_url = options.dart_url if options.quiet: settings.local.quiet = True if options.daemon: pid = os.fork() if pid > 0: if options.pidfile: with open(options.pidfile, 'w') as pid_file: pid_file.write('%s' % pid) sys.exit(0) elif not options.quiet: print '##############################################################' print '# #' print '# /$$ /$$ /$$ #' print '# |__/ | $$ | $$ #' print '# /$$$$$$ /$$$$$$ /$$ /$$$$$$ /$$ /$$ /$$$$$$$ | $$ #' print '# /$$__ $$ /$$__ $$| $$|_ $$_/ | $$ | $$| $$__ $$| $$ #' print '# | $$ \ $$| $$ \__/| $$ | $$ | $$ | $$| $$ \ $$| $$ #' print '# | $$ | $$| $$ | $$ | $$ /$$| $$ | $$| $$ | $$| $$ #' print '# | $$$$$$$/| $$ | $$ | $$$$/| $$$$$$/| $$ | $$| $$ #' print '# | $$____/ |__/ |__/ \____/ \______/ |__/ |__/|__/ #' print '# | $$ #' print '# | $$ #' print '# |__/ #' print '# #' print '##############################################################' pritunl.init_server()
def setup_server_cert(): if not settings.app.server_cert or not settings.app.server_key: logger.info("Generating server certificate...", "app") utils.create_server_cert() settings.commit()
def setup_mongo(): prefix = settings.conf.mongodb_collection_prefix or '' last_error = time.time() - 24 while True: try: read_pref = _get_read_pref(settings.conf.mongodb_read_preference) if read_pref: client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, read_preference=read_pref, ) else: client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, ) break except pymongo.errors.ConnectionFailure: time.sleep(0.5) if time.time() - last_error > 30: last_error = time.time() logger.exception('Error connecting to mongodb server') database = client.get_default_database() settings_col = getattr(database, prefix + 'settings') app_settings = settings_col.find_one({'_id': 'app'}) if app_settings: secondary_mongodb_uri = app_settings.get('secondary_mongodb_uri') else: secondary_mongodb_uri = None if secondary_mongodb_uri: while True: try: read_pref = _get_read_pref( settings.conf.mongodb_read_preference) if read_pref: secondary_client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, read_preference=read_pref, ) else: secondary_client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, ) break except pymongo.errors.ConnectionFailure: time.sleep(0.5) if time.time() - last_error > 30: last_error = time.time() logger.exception( 'Error connecting to secondary mongodb server') secondary_database = secondary_client.get_default_database() else: secondary_database = database cur_collections = secondary_database.collection_names() if prefix + 'messages' not in cur_collections: secondary_database.create_collection(prefix + 'messages', capped=True, size=5000192, max=1500) mongo.collections.update({ 'transaction': getattr(database, prefix + 'transaction'), 'queue': getattr(database, prefix + 'queue'), 'tasks': getattr(database, prefix + 'tasks'), 'settings': getattr(database, prefix + 'settings'), 'messages': getattr(secondary_database, prefix + 'messages'), 'administrators': getattr(database, prefix + 'administrators'), 'users': getattr(database, prefix + 'users'), 'users_audit': getattr(database, prefix + 'users_audit'), 'users_key_link': getattr(secondary_database, prefix + 'users_key_link'), 'users_net_link': getattr(database, prefix + 'users_net_link'), 'clients': getattr(database, prefix + 'clients'), 'clients_pool': getattr(database, prefix + 'clients_pool'), 'organizations': getattr(database, prefix + 'organizations'), 'hosts': getattr(database, prefix + 'hosts'), 'hosts_usage': getattr(database, prefix + 'hosts_usage'), 'servers': getattr(database, prefix + 'servers'), 'servers_output': getattr(database, prefix + 'servers_output'), 'servers_output_link': getattr(database, prefix + 'servers_output_link'), 'servers_bandwidth': getattr(database, prefix + 'servers_bandwidth'), 'servers_ip_pool': getattr(database, prefix + 'servers_ip_pool'), 'routes_reserve': getattr(database, prefix + 'routes_reserve'), 'dh_params': getattr(database, prefix + 'dh_params'), 'auth_sessions': getattr(secondary_database, prefix + 'auth_sessions'), 'auth_csrf_tokens': getattr(secondary_database, prefix + 'auth_csrf_tokens'), 'auth_nonces': getattr(secondary_database, prefix + 'auth_nonces'), 'auth_limiter': getattr(secondary_database, prefix + 'auth_limiter'), 'otp': getattr(secondary_database, prefix + 'otp'), 'otp_cache': getattr(secondary_database, prefix + 'otp_cache'), 'sso_tokens': getattr(secondary_database, prefix + 'sso_tokens'), 'sso_cache': getattr(secondary_database, prefix + 'sso_cache'), 'vxlans': getattr(database, prefix + 'vxlans'), }) for collection_name, collection in mongo.collections.items(): collection.name_str = collection_name settings.local.mongo_time = None while True: try: utils.sync_time() break except: logger.exception('Failed to sync time', 'setup') time.sleep(30) settings.init() cur_collections = database.collection_names() if prefix + 'logs' not in cur_collections: log_limit = settings.app.log_limit database.create_collection(prefix + 'logs', capped=True, size=log_limit * 1024, max=log_limit) if prefix + 'log_entries' not in cur_collections: log_entry_limit = settings.app.log_entry_limit database.create_collection(prefix + 'log_entries', capped=True, size=log_entry_limit * 512, max=log_entry_limit) mongo.collections.update({ 'logs': getattr(database, prefix + 'logs'), 'log_entries': getattr(database, prefix + 'log_entries'), }) mongo.collections['logs'].name_str = 'logs' mongo.collections['log_entries'].name_str = 'log_entries' upsert_index(mongo.collections['logs'], 'timestamp', background=True) upsert_index(mongo.collections['transaction'], 'lock_id', background=True, unique=True) upsert_index(mongo.collections['transaction'], [ ('ttl_timestamp', pymongo.ASCENDING), ('state', pymongo.ASCENDING), ('priority', pymongo.DESCENDING), ], background=True) upsert_index(mongo.collections['queue'], 'runner_id', background=True) upsert_index(mongo.collections['queue'], 'ttl_timestamp', background=True) upsert_index(mongo.collections['tasks'], [ ('ttl_timestamp', pymongo.ASCENDING), ('state', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['log_entries'], [ ('timestamp', pymongo.DESCENDING), ], background=True) upsert_index(mongo.collections['messages'], 'channel', background=True) upsert_index(mongo.collections['administrators'], 'username', background=True, unique=True) upsert_index(mongo.collections['users'], 'resource_id', background=True) upsert_index(mongo.collections['users'], [ ('type', pymongo.ASCENDING), ('org_id', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['users'], [ ('org_id', pymongo.ASCENDING), ('name', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['users_audit'], [ ('org_id', pymongo.ASCENDING), ('user_id', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['users_audit'], [ ('timestamp', pymongo.DESCENDING), ], background=True) upsert_index(mongo.collections['users_key_link'], 'key_id', background=True) upsert_index(mongo.collections['users_key_link'], 'short_id', background=True, unique=True) upsert_index(mongo.collections['users_net_link'], 'user_id', background=True) upsert_index(mongo.collections['users_net_link'], 'org_id', background=True) upsert_index(mongo.collections['users_net_link'], 'network', background=True) upsert_index(mongo.collections['clients'], 'user_id', background=True) upsert_index(mongo.collections['clients'], 'domain', background=True) upsert_index(mongo.collections['clients'], 'virt_address_num', background=True) upsert_index(mongo.collections['clients'], [ ('server_id', pymongo.ASCENDING), ('type', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['clients'], [ ('host_id', pymongo.ASCENDING), ('type', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['clients_pool'], 'client_id', background=True) upsert_index(mongo.collections['clients_pool'], 'timestamp', background=True) upsert_index(mongo.collections['clients_pool'], [ ('server_id', pymongo.ASCENDING), ('user_id', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['organizations'], 'type', background=True) upsert_index(mongo.collections['organizations'], 'auth_token', background=True) upsert_index(mongo.collections['hosts'], 'name', background=True) upsert_index(mongo.collections['hosts_usage'], [ ('host_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['servers'], 'name', background=True) upsert_index(mongo.collections['servers'], 'ping_timestamp', background=True) upsert_index(mongo.collections['servers_output'], [ ('server_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['servers_output_link'], [ ('server_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['servers_bandwidth'], [ ('server_id', pymongo.ASCENDING), ('period', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['servers_ip_pool'], [ ('server_id', pymongo.ASCENDING), ('user_id', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['servers_ip_pool'], [ ('server_id', pymongo.ASCENDING), ('_id', pymongo.DESCENDING), ], background=True) upsert_index(mongo.collections['servers_ip_pool'], 'user_id', background=True) upsert_index(mongo.collections['routes_reserve'], 'timestamp', background=True) upsert_index(mongo.collections['dh_params'], 'dh_param_bits', background=True) upsert_index(mongo.collections['auth_nonces'], [ ('token', pymongo.ASCENDING), ('nonce', pymongo.ASCENDING), ], background=True, unique=True) upsert_index(mongo.collections['sso_cache'], [ ('user_id', pymongo.ASCENDING), ('server_id', pymongo.ASCENDING), ('remote_ip', pymongo.ASCENDING), ('mac_addr', pymongo.ASCENDING), ('platform', pymongo.ASCENDING), ('device_name', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['vxlans'], 'server_id', background=True, unique=True) upsert_index(mongo.collections['tasks'], 'timestamp', background=True, expireAfterSeconds=300) upsert_index(mongo.collections['clients'], 'timestamp', background=True, expireAfterSeconds=settings.vpn.client_ttl) upsert_index(mongo.collections['users_key_link'], 'timestamp', background=True, expireAfterSeconds=settings.app.key_link_timeout) upsert_index(mongo.collections['auth_sessions'], 'timestamp', background=True, expireAfterSeconds=settings.app.session_timeout) upsert_index(mongo.collections['auth_nonces'], 'timestamp', background=True, expireAfterSeconds=settings.app.auth_time_window * 2.1) upsert_index(mongo.collections['auth_limiter'], 'timestamp', background=True, expireAfterSeconds=settings.app.auth_limiter_ttl) upsert_index(mongo.collections['otp'], 'timestamp', background=True, expireAfterSeconds=120) upsert_index(mongo.collections['otp_cache'], 'timestamp', background=True, expireAfterSeconds=settings.user.otp_cache_ttl) upsert_index(mongo.collections['sso_tokens'], 'timestamp', background=True, expireAfterSeconds=600) upsert_index(mongo.collections['sso_cache'], 'timestamp', background=True, expireAfterSeconds=settings.app.sso_cache_timeout) if not auth.Administrator.collection.find_one(): auth.Administrator( username=DEFAULT_USERNAME, password=DEFAULT_PASSWORD, default=True, ).commit() secret_key = settings.app.cookie_secret secret_key2 = settings.app.cookie_secret2 settings_commit = False if not secret_key: settings_commit = True secret_key = utils.rand_str(64) settings.app.cookie_secret = secret_key if not secret_key2: settings_commit = True settings.app.cookie_secret2 = utils.rand_str(64) if settings_commit: settings.commit() app.app.secret_key = secret_key.encode()
def update_license(license): settings.app.license = license settings.commit() update()
def main(default_conf=None): if len(sys.argv) > 1: cmd = sys.argv[1] else: cmd = 'start' parser = optparse.OptionParser(usage=USAGE) if cmd == 'start': parser.add_option('-d', '--daemon', action='store_true', help='Daemonize process') parser.add_option('-p', '--pidfile', type='string', help='Path to create pid file') parser.add_option('-c', '--conf', type='string', help='Path to configuration file') parser.add_option('-q', '--quiet', action='store_true', help='Suppress logging output') elif cmd == 'logs': parser.add_option('--archive', action='store_true', help='Archive log file') parser.add_option('--tail', action='store_true', help='Tail log file') parser.add_option('--limit', type='int', help='Limit log lines') elif cmd == 'set': parser.disable_interspersed_args() (options, args) = parser.parse_args() if hasattr(options, 'conf') and options.conf: conf_path = options.conf else: conf_path = default_conf pritunl.set_conf_path(conf_path) if cmd == 'version': print '%s v%s' % (pritunl.__title__, pritunl.__version__) sys.exit(0) elif cmd == 'setup-key': from pritunl import setup from pritunl import settings setup.setup_loc() print settings.local.setup_key sys.exit(0) elif cmd == 'reset-version': from pritunl.constants import MIN_DATABASE_VER from pritunl import setup from pritunl import utils setup.setup_db() utils.set_db_ver(pritunl.__version__, MIN_DATABASE_VER) time.sleep(.2) print 'Database version reset to %s' % pritunl.__version__ sys.exit(0) elif cmd == 'reset-password': from pritunl import setup from pritunl import auth setup.setup_db() username, password = auth.reset_password() time.sleep(.2) print 'Administrator password successfully reset:\n' + \ ' username: "******"\n password: "******"' % (username, password) sys.exit(0) elif cmd == 'reconfigure': from pritunl import setup from pritunl import settings setup.setup_loc() settings.conf.mongodb_uri = None settings.conf.commit() time.sleep(.2) print 'Database configuration successfully reset' sys.exit(0) elif cmd == 'get': from pritunl import setup from pritunl import settings setup.setup_db_host() if len(args) != 2: raise ValueError('Invalid arguments') split = args[1].split('.') key_str = None group_str = split[0] if len(split) > 1: key_str = split[1] if group_str == 'host': group = settings.local.host else: group = getattr(settings, group_str) if key_str: val = getattr(group, key_str) print '%s.%s = %s' % (group_str, key_str, json.dumps(val, default=lambda x: str(x))) else: for field in group.fields: val = getattr(group, field) print '%s.%s = %s' % (group_str, field, json.dumps(val, default=lambda x: str(x))) sys.exit(0) elif cmd == 'set': from pritunl.constants import HOSTS_UPDATED from pritunl import setup from pritunl import settings from pritunl import event from pritunl import messenger setup.setup_db_host() if len(args) != 3: raise ValueError('Invalid arguments') group_str, key_str = args[1].split('.') if group_str == 'host': group = settings.local.host else: group = getattr(settings, group_str) val_str = args[2] try: val = json.loads(val_str) except ValueError: val = json.loads(json.JSONEncoder().encode(val_str)) setattr(group, key_str, val) if group_str == 'host': settings.local.host.commit() event.Event(type=HOSTS_UPDATED) messenger.publish('hosts', 'updated') else: settings.commit() time.sleep(.2) print '%s.%s = %s' % (group_str, key_str, json.dumps(getattr(group, key_str), default=lambda x: str(x))) sys.exit(0) elif cmd == 'unset': from pritunl import setup from pritunl import settings setup.setup_db() if len(args) != 2: raise ValueError('Invalid arguments') group_str, key_str = args[1].split('.') group = getattr(settings, group_str) group.unset(key_str) settings.commit() time.sleep(.2) print '%s.%s = %s' % (group_str, key_str, json.dumps(getattr(group, key_str), default=lambda x: str(x))) sys.exit(0) elif cmd == 'set-mongodb': from pritunl import setup from pritunl import settings setup.setup_loc() if len(args) > 1: mongodb_uri = args[1] else: mongodb_uri = None settings.conf.mongodb_uri = mongodb_uri settings.conf.commit() time.sleep(.2) print 'Database configuration successfully set' sys.exit(0) elif cmd == 'reset-ssl-cert': from pritunl import setup from pritunl import settings setup.setup_db() settings.app.server_cert = None settings.app.server_key = None settings.commit() time.sleep(.2) print 'Server ssl certificate successfully reset' sys.exit(0) elif cmd == 'destroy-secondary': from pritunl import setup from pritunl import logger from pritunl import mongo setup.setup_db() mongo.get_collection('clients').drop() mongo.get_collection('clients_pool').drop() mongo.get_collection('transaction').drop() mongo.get_collection('queue').drop() mongo.get_collection('tasks').drop() mongo.get_collection('messages').drop() mongo.get_collection('users_key_link').drop() mongo.get_collection('auth_sessions').drop() mongo.get_collection('auth_csrf_tokens').drop() mongo.get_collection('auth_nonces').drop() mongo.get_collection('auth_limiter').drop() mongo.get_collection('otp').drop() mongo.get_collection('otp_cache').drop() mongo.get_collection('sso_tokens').drop() mongo.get_collection('sso_cache').drop() server_coll = mongo.get_collection('servers') server_coll.update_many({}, { '$set': { 'status': 'offline', 'instances': [], 'instances_count': 0, }, '$unset': { 'network_lock': '', }, }) sys.exit(0) elif cmd == 'logs': from pritunl import setup from pritunl import logger setup.setup_db() log_view = logger.LogView() if options.archive: if len(args) > 1: archive_path = args[1] else: archive_path = './' print 'Log archived to: ' + log_view.archive_log(archive_path, options.limit) elif options.tail: for msg in log_view.tail_log_lines(): print msg else: print log_view.get_log_lines(options.limit) sys.exit(0) elif cmd != 'start': raise ValueError('Invalid command') from pritunl import settings if options.quiet: settings.local.quiet = True if options.daemon: pid = os.fork() if pid > 0: if options.pidfile: with open(options.pidfile, 'w') as pid_file: pid_file.write('%s' % pid) sys.exit(0) elif not options.quiet: print '##############################################################' print '# #' print '# /$$ /$$ /$$ #' print '# |__/ | $$ | $$ #' print '# /$$$$$$ /$$$$$$ /$$ /$$$$$$ /$$ /$$ /$$$$$$$ | $$ #' print '# /$$__ $$ /$$__ $$| $$|_ $$_/ | $$ | $$| $$__ $$| $$ #' print '# | $$ \ $$| $$ \__/| $$ | $$ | $$ | $$| $$ \ $$| $$ #' print '# | $$ | $$| $$ | $$ | $$ /$$| $$ | $$| $$ | $$| $$ #' print '# | $$$$$$$/| $$ | $$ | $$$$/| $$$$$$/| $$ | $$| $$ #' print '# | $$____/ |__/ |__/ \____/ \______/ |__/ |__/|__/ #' print '# | $$ #' print '# | $$ #' print '# |__/ #' print '# #' print '##############################################################' pritunl.init_server()
def setup_mongo(): prefix = settings.conf.mongodb_collection_prefix or '' last_error = time.time() - 24 while True: try: read_pref = _get_read_pref(settings.conf.mongodb_read_preference) if read_pref: client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, serverSelectionTimeoutMS=MONGO_SOCKET_TIMEOUT, read_preference=read_pref, ) else: client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, serverSelectionTimeoutMS=MONGO_SOCKET_TIMEOUT, ) break except pymongo.errors.ConnectionFailure: time.sleep(0.5) if time.time() - last_error > 30: last_error = time.time() logger.exception('Error connecting to mongodb server') database = client.get_default_database() settings_col = getattr(database, prefix + 'settings') app_settings = settings_col.find_one({'_id': 'app'}) if app_settings: secondary_mongodb_uri = app_settings.get('secondary_mongodb_uri') else: secondary_mongodb_uri = None if secondary_mongodb_uri: while True: try: read_pref = _get_read_pref( settings.conf.mongodb_read_preference) if read_pref: secondary_client = pymongo.MongoClient( secondary_mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, serverSelectionTimeoutMS=MONGO_SOCKET_TIMEOUT, read_preference=read_pref, ) else: secondary_client = pymongo.MongoClient( secondary_mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, serverSelectionTimeoutMS=MONGO_SOCKET_TIMEOUT, ) break except pymongo.errors.ConnectionFailure: time.sleep(0.5) if time.time() - last_error > 30: last_error = time.time() logger.exception( 'Error connecting to secondary mongodb server') secondary_database = secondary_client.get_default_database() else: secondary_database = database mongo.database = database mongo.secondary_database = secondary_database cur_collections = database.collection_names() cur_sec_collections = secondary_database.collection_names() if 'authorities' in cur_collections or \ 'authorities' in cur_sec_collections: raise TypeError('Cannot connect to a Pritunl Zero database') mongo.collection_types = { 'transaction': 1, 'queue': 1, 'tasks': 1, 'settings': 1, 'messages': 2, 'administrators': 1, 'users': 1, 'users_audit': 1, 'users_key_link': 2, 'users_net_link': 1, 'clients': 1, 'clients_pool': 1, 'organizations': 1, 'hosts': 1, 'hosts_usage': 1, 'servers': 1, 'servers_output': 1, 'servers_output_link': 1, 'servers_bandwidth': 1, 'servers_ip_pool': 1, 'links': 1, 'links_locations': 1, 'links_hosts': 1, 'routes_reserve': 1, 'dh_params': 1, 'acme_challenges': 1, 'auth_sessions': 2, 'auth_csrf_tokens': 2, 'auth_nonces': 2, 'auth_limiter': 2, 'otp': 2, 'otp_cache': 2, 'yubikey': 2, 'sso_tokens': 2, 'sso_push_cache': 2, 'sso_client_cache': 2, 'sso_passcode_cache': 2, 'vxlans': 1, 'logs': 1, 'log_entries': 1, } cur_collections = mongo.secondary_database.collection_names() if prefix + 'messages' not in cur_collections: mongo.secondary_database.create_collection( prefix + 'messages', capped=True, size=5000192, max=1000) elif not mongo.get_collection('messages').options().get('capped'): mongo.get_collection('messages').drop() mongo.secondary_database.create_collection( prefix + 'messages', capped=True, size=5000192, max=1000) settings.local.mongo_time = None while True: try: utils.sync_time() break except: logger.exception('Failed to sync time', 'setup') time.sleep(30) settings.init() upsert_indexes() if not auth.Administrator.collection.find_one(): default_admin = auth.Administrator( username=DEFAULT_USERNAME, ) default_admin.generate_default_password() default_admin.commit() secret_key = settings.app.cookie_secret secret_key2 = settings.app.cookie_secret2 settings_commit = False if not secret_key: settings_commit = True secret_key = utils.rand_str(64) settings.app.cookie_secret = secret_key if not secret_key2: settings_commit = True settings.app.cookie_secret2 = utils.rand_str(64) if settings_commit: settings.commit() app.app.secret_key = secret_key.encode()
def update(): license = settings.app.license collection = mongo.get_collection('settings') if not settings.app.id: settings.app.id = utils.random_name() settings.commit() if not license: settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_quantity = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_trial_end = None settings.local.sub_cancel_at_period_end = None settings.local.sub_balance = None settings.local.sub_url_key = None else: for i in xrange(2): try: response = requests.get( 'https://app.pritunl.com/subscription', json={ 'id': settings.app.id, 'license': license, 'version': settings.local.version_int, }, timeout=max(settings.app.http_request_timeout, 10), ) # License key invalid if response.status_code == 470: raise ValueError('License key is invalid') if response.status_code == 473: raise ValueError( ('Version %r not recognized by ' + 'subscription server') % settings.local.version_int) data = response.json() settings.local.sub_active = data['active'] settings.local.sub_status = data['status'] settings.local.sub_plan = data['plan'] settings.local.sub_quantity = data['quantity'] settings.local.sub_amount = data['amount'] settings.local.sub_period_end = data['period_end'] settings.local.sub_trial_end = data['trial_end'] settings.local.sub_cancel_at_period_end = data[ 'cancel_at_period_end'] settings.local.sub_balance = data.get('balance') settings.local.sub_url_key = data.get('url_key') settings.local.sub_styles[data['plan']] = data['styles'] except: if i < 1: logger.exception('Failed to check subscription status', 'subscription, retrying...') time.sleep(1) continue logger.exception('Failed to check subscription status', 'subscription') settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_quantity = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_trial_end = None settings.local.sub_cancel_at_period_end = None settings.local.sub_balance = None settings.local.sub_url_key = None break if settings.app.license_plan != settings.local.sub_plan and \ settings.local.sub_plan: settings.app.license_plan = settings.local.sub_plan settings.commit() response = collection.update( { '_id': 'subscription', '$or': [ { 'active': { '$ne': settings.local.sub_active } }, { 'plan': { '$ne': settings.local.sub_plan } }, ], }, { '$set': { 'active': settings.local.sub_active, 'plan': settings.local.sub_plan, } }) if response['updatedExisting']: if settings.local.sub_active: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_ACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_ACTIVE) elif settings.local.sub_plan == 'enterprise_plus': event.Event(type=SUBSCRIPTION_ENTERPRISE_PLUS_ACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE) else: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_INACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_INACTIVE) elif settings.local.sub_plan == 'enterprise_plus': event.Event(type=SUBSCRIPTION_ENTERPRISE_PLUS_INACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE) return True
def settings_put(): admin = flask.g.administrator if 'username' in flask.request.json and flask.request.json['username']: admin.username = utils.filter_str( flask.request.json['username']).lower() if 'password' in flask.request.json and flask.request.json['password']: admin.password = flask.request.json['password'] if 'token' in flask.request.json and flask.request.json['token']: admin.generate_token() if 'secret' in flask.request.json and flask.request.json['secret']: admin.generate_secret() settings_commit = False if 'email_from' in flask.request.json: settings_commit = True email_from = flask.request.json['email_from'] settings.app.email_from = email_from or None if 'email_server' in flask.request.json: settings_commit = True email_server = flask.request.json['email_server'] settings.app.email_server = email_server or None if 'email_username' in flask.request.json: settings_commit = True email_username = flask.request.json['email_username'] settings.app.email_username = email_username or None if 'email_password' in flask.request.json: settings_commit = True email_password = flask.request.json['email_password'] settings.app.email_password = email_password or None if 'sso' in flask.request.json: settings_commit = True sso = flask.request.json['sso'] settings.app.sso = sso or None if 'sso_match' in flask.request.json: sso_match = flask.request.json['sso_match'] if isinstance(sso_match, list): settings_commit = True settings.app.sso_match = sso_match or None if 'sso_token' in flask.request.json: sso_token = flask.request.json['sso_token'] settings_commit = True settings.app.sso_token = sso_token or None if 'sso_secret' in flask.request.json: sso_secret = flask.request.json['sso_secret'] settings_commit = True settings.app.sso_secret = sso_secret or None if 'sso_host' in flask.request.json: sso_host = flask.request.json['sso_host'] settings_commit = True settings.app.sso_host = sso_host or None if 'sso_admin' in flask.request.json: sso_admin = flask.request.json['sso_admin'] settings_commit = True settings.app.sso_admin = sso_admin or None if 'sso_org' in flask.request.json: settings_commit = True sso_org = flask.request.json['sso_org'] if sso_org: settings.app.sso_org = utils.ObjectId(sso_org) else: settings.app.sso_org = None if 'theme' in flask.request.json: settings_commit = True theme = 'dark' if flask.request.json['theme'] == 'dark' else 'light' if theme != settings.app.theme: if theme == 'dark': event.Event(type=THEME_DARK) else: event.Event(type=THEME_LIGHT) settings.app.theme = theme if 'public_address' in flask.request.json: public_address = flask.request.json['public_address'] settings.local.host.public_address = public_address settings.local.host.commit('public_address') if 'public_address6' in flask.request.json: public_address6 = flask.request.json['public_address6'] settings.local.host.public_address6 = public_address6 settings.local.host.commit('public_address6') if 'routed_subnet6' in flask.request.json: routed_subnet6 = flask.request.json['routed_subnet6'] if routed_subnet6: try: routed_subnet6 = ipaddress.IPv6Network( flask.request.json['routed_subnet6']) except ipaddress.AddressValueError: return utils.jsonify({ 'error': IPV6_SUBNET_INVALID, 'error_msg': IPV6_SUBNET_INVALID_MSG, }, 400) if routed_subnet6.prefixlen > 64: return utils.jsonify({ 'error': IPV6_SUBNET_SIZE_INVALID, 'error_msg': IPV6_SUBNET_SIZE_INVALID_MSG, }, 400) routed_subnet6 = str(routed_subnet6) else: routed_subnet6 = None if settings.local.host.routed_subnet6 != routed_subnet6: if server.get_online_ipv6_count(): return utils.jsonify({ 'error': IPV6_SUBNET_ONLINE, 'error_msg': IPV6_SUBNET_ONLINE_MSG, }, 400) settings.local.host.routed_subnet6 = routed_subnet6 settings.local.host.commit('routed_subnet6') if 'server_cert' in flask.request.json: settings_commit = True server_cert = flask.request.json['server_cert'] if server_cert: settings.app.server_cert = server_cert.strip() else: settings.app.server_cert = None if 'server_key' in flask.request.json: settings_commit = True server_key = flask.request.json['server_key'] if server_key: settings.app.server_key = server_key.strip() else: settings.app.server_key = None if not settings.app.sso: settings.app.sso_match = None settings.app.sso_token = None settings.app.sso_secret = None settings.app.sso_host = None settings.app.sso_admin = None settings.app.sso_org = None if settings_commit: settings.commit() admin.commit(admin.changed) response = flask.g.administrator.dict() response.update({ 'theme': settings.app.theme, 'email_from': settings.app.email_from, 'email_server': settings.app.email_server, 'email_username': settings.app.email_username, 'email_password': bool(settings.app.email_password), 'sso': settings.app.sso, 'sso_match': settings.app.sso_match, 'sso_token': settings.app.sso_token, 'sso_secret': settings.app.sso_secret, 'sso_host': settings.app.sso_host, 'sso_admin': settings.app.sso_admin, 'sso_org': settings.app.sso_org, 'public_address': settings.local.host.public_addr, }) return utils.jsonify(response)
def setup_mongo(): prefix = settings.conf.mongodb_collection_prefix or '' last_error = time.time() - 24 while True: try: read_pref = _get_read_pref(settings.conf.mongodb_read_preference) if read_pref: client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, serverSelectionTimeoutMS=MONGO_SOCKET_TIMEOUT, read_preference=read_pref, ) else: client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, serverSelectionTimeoutMS=MONGO_SOCKET_TIMEOUT, ) break except pymongo.errors.ConnectionFailure: time.sleep(0.5) if time.time() - last_error > 30: last_error = time.time() logger.exception('Error connecting to mongodb server') database = client.get_default_database() settings_col = getattr(database, prefix + 'settings') app_settings = settings_col.find_one({'_id': 'app'}) if app_settings: secondary_mongodb_uri = app_settings.get('secondary_mongodb_uri') else: secondary_mongodb_uri = None if secondary_mongodb_uri: while True: try: read_pref = _get_read_pref( settings.conf.mongodb_read_preference) if read_pref: secondary_client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, serverSelectionTimeoutMS=MONGO_SOCKET_TIMEOUT, read_preference=read_pref, ) else: secondary_client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, socketTimeoutMS=MONGO_SOCKET_TIMEOUT, serverSelectionTimeoutMS=MONGO_SOCKET_TIMEOUT, ) break except pymongo.errors.ConnectionFailure: time.sleep(0.5) if time.time() - last_error > 30: last_error = time.time() logger.exception( 'Error connecting to secondary mongodb server') secondary_database = secondary_client.get_default_database() else: secondary_database = database mongo.database = database mongo.secondary_database = secondary_database cur_collections = secondary_database.collection_names() if prefix + 'messages' not in cur_collections: secondary_database.create_collection(prefix + 'messages', capped=True, size=5000192, max=1000) mongo.collections.update({ 'transaction': getattr(database, prefix + 'transaction'), 'queue': getattr(database, prefix + 'queue'), 'tasks': getattr(database, prefix + 'tasks'), 'settings': getattr(database, prefix + 'settings'), 'messages': getattr(secondary_database, prefix + 'messages'), 'administrators': getattr(database, prefix + 'administrators'), 'users': getattr(database, prefix + 'users'), 'users_audit': getattr(database, prefix + 'users_audit'), 'users_key_link': getattr(secondary_database, prefix + 'users_key_link'), 'users_net_link': getattr(database, prefix + 'users_net_link'), 'clients': getattr(database, prefix + 'clients'), 'clients_pool': getattr(database, prefix + 'clients_pool'), 'organizations': getattr(database, prefix + 'organizations'), 'hosts': getattr(database, prefix + 'hosts'), 'hosts_usage': getattr(database, prefix + 'hosts_usage'), 'servers': getattr(database, prefix + 'servers'), 'servers_output': getattr(database, prefix + 'servers_output'), 'servers_output_link': getattr(database, prefix + 'servers_output_link'), 'servers_bandwidth': getattr(database, prefix + 'servers_bandwidth'), 'servers_ip_pool': getattr(database, prefix + 'servers_ip_pool'), 'links': getattr(database, prefix + 'links'), 'links_locations': getattr(database, prefix + 'links_locations'), 'links_hosts': getattr(database, prefix + 'links_hosts'), 'routes_reserve': getattr(database, prefix + 'routes_reserve'), 'dh_params': getattr(database, prefix + 'dh_params'), 'auth_sessions': getattr(secondary_database, prefix + 'auth_sessions'), 'auth_csrf_tokens': getattr(secondary_database, prefix + 'auth_csrf_tokens'), 'auth_nonces': getattr(secondary_database, prefix + 'auth_nonces'), 'auth_limiter': getattr(secondary_database, prefix + 'auth_limiter'), 'otp': getattr(secondary_database, prefix + 'otp'), 'otp_cache': getattr(secondary_database, prefix + 'otp_cache'), 'yubikey': getattr(secondary_database, prefix + 'yubikey'), 'sso_tokens': getattr(secondary_database, prefix + 'sso_tokens'), 'sso_push_cache': getattr(secondary_database, prefix + 'sso_push_cache'), 'sso_client_cache': getattr(secondary_database, prefix + 'sso_client_cache'), 'sso_passcode_cache': getattr(secondary_database, prefix + 'sso_passcode_cache'), 'vxlans': getattr(database, prefix + 'vxlans'), }) for collection_name, collection in mongo.collections.items(): collection.name_str = collection_name settings.local.mongo_time = None while True: try: utils.sync_time() break except: logger.exception('Failed to sync time', 'setup') time.sleep(30) settings.init() cur_collections = database.collection_names() if prefix + 'logs' not in cur_collections: log_limit = settings.app.log_limit database.create_collection(prefix + 'logs', capped=True, size=log_limit * 1024, max=log_limit) if prefix + 'log_entries' not in cur_collections: log_entry_limit = settings.app.log_entry_limit database.create_collection(prefix + 'log_entries', capped=True, size=log_entry_limit * 512, max=log_entry_limit) mongo.collections.update({ 'logs': getattr(database, prefix + 'logs'), 'log_entries': getattr(database, prefix + 'log_entries'), }) mongo.collections['logs'].name_str = 'logs' mongo.collections['log_entries'].name_str = 'log_entries' upsert_index('logs', 'timestamp', background=True) upsert_index('transaction', 'lock_id', background=True, unique=True) upsert_index('transaction', [ ('ttl_timestamp', pymongo.ASCENDING), ('state', pymongo.ASCENDING), ('priority', pymongo.DESCENDING), ], background=True) upsert_index('queue', 'runner_id', background=True) upsert_index('queue', 'ttl_timestamp', background=True) upsert_index('queue', [ ('priority', pymongo.ASCENDING), ('ttl_timestamp', pymongo.ASCENDING), ], background=True) upsert_index('tasks', [ ('ttl_timestamp', pymongo.ASCENDING), ], background=True) upsert_index('log_entries', [ ('timestamp', pymongo.DESCENDING), ], background=True) upsert_index('messages', 'channel', background=True) upsert_index('administrators', 'username', background=True, unique=True) upsert_index('users', 'resource_id', background=True) upsert_index('users', [ ('type', pymongo.ASCENDING), ('org_id', pymongo.ASCENDING), ], background=True) upsert_index('users', [ ('org_id', pymongo.ASCENDING), ('name', pymongo.ASCENDING), ], background=True) upsert_index('users_audit', [ ('org_id', pymongo.ASCENDING), ('user_id', pymongo.ASCENDING), ], background=True) upsert_index('users_audit', [ ('timestamp', pymongo.DESCENDING), ], background=True) upsert_index('users_key_link', 'key_id', background=True) upsert_index('users_key_link', 'short_id', background=True, unique=True) upsert_index('users_net_link', 'user_id', background=True) upsert_index('users_net_link', 'org_id', background=True) upsert_index('users_net_link', 'network', background=True) upsert_index('clients', 'user_id', background=True) upsert_index('clients', 'domain', background=True) upsert_index('clients', 'virt_address_num', background=True) upsert_index('clients', [ ('server_id', pymongo.ASCENDING), ('type', pymongo.ASCENDING), ], background=True) upsert_index('clients', [ ('host_id', pymongo.ASCENDING), ('type', pymongo.ASCENDING), ], background=True) upsert_index('clients_pool', 'client_id', background=True) upsert_index('clients_pool', 'timestamp', background=True) upsert_index('clients_pool', [ ('server_id', pymongo.ASCENDING), ('user_id', pymongo.ASCENDING), ], background=True) upsert_index('organizations', 'type', background=True) upsert_index('organizations', 'auth_token', background=True) upsert_index('hosts', 'name', background=True) upsert_index('hosts_usage', [ ('host_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) upsert_index('servers', 'name', background=True) upsert_index('servers', 'ping_timestamp', background=True) upsert_index('servers_output', [ ('server_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) upsert_index('servers_output_link', [ ('server_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) upsert_index('servers_bandwidth', [ ('server_id', pymongo.ASCENDING), ('period', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) upsert_index('servers_ip_pool', [ ('server_id', pymongo.ASCENDING), ('user_id', pymongo.ASCENDING), ], background=True) upsert_index('servers_ip_pool', [ ('server_id', pymongo.ASCENDING), ('_id', pymongo.DESCENDING), ], background=True) upsert_index('servers_ip_pool', 'user_id', background=True) upsert_index('links_hosts', 'link_id', background=True) upsert_index('links_hosts', [ ('location_id', pymongo.ASCENDING), ('status', pymongo.ASCENDING), ('active', pymongo.ASCENDING), ('priority', pymongo.DESCENDING), ], background=True) upsert_index('links_hosts', [ ('location_id', pymongo.ASCENDING), ('name', pymongo.ASCENDING), ], background=True) upsert_index('links_hosts', 'ping_timestamp_ttl', background=True) upsert_index('links_locations', 'link_id', background=True) upsert_index('routes_reserve', 'timestamp', background=True) upsert_index('dh_params', 'dh_param_bits', background=True) upsert_index('auth_nonces', [ ('token', pymongo.ASCENDING), ('nonce', pymongo.ASCENDING), ], background=True, unique=True) upsert_index('otp_cache', [ ('user_id', pymongo.ASCENDING), ('server_id', pymongo.ASCENDING), ], background=True) upsert_index('sso_push_cache', [ ('user_id', pymongo.ASCENDING), ('server_id', pymongo.ASCENDING), ], background=True) upsert_index('sso_client_cache', [ ('user_id', pymongo.ASCENDING), ('server_id', pymongo.ASCENDING), ], background=True) upsert_index('sso_passcode_cache', [ ('user_id', pymongo.ASCENDING), ('server_id', pymongo.ASCENDING), ], background=True) upsert_index('vxlans', 'server_id', background=True, unique=True) upsert_index('tasks', 'timestamp', background=True, expireAfterSeconds=300) if settings.app.demo_mode: drop_index(mongo.collections['clients'], 'timestamp', background=True) else: upsert_index('clients', 'timestamp', background=True, expireAfterSeconds=settings.vpn.client_ttl) upsert_index('users_key_link', 'timestamp', background=True, expireAfterSeconds=settings.app.key_link_timeout) upsert_index('auth_sessions', 'timestamp', background=True, expireAfterSeconds=settings.app.session_timeout) upsert_index('auth_nonces', 'timestamp', background=True, expireAfterSeconds=settings.app.auth_time_window * 2.1) upsert_index('auth_csrf_tokens', 'timestamp', background=True, expireAfterSeconds=604800) upsert_index('auth_limiter', 'timestamp', background=True, expireAfterSeconds=settings.app.auth_limiter_ttl) upsert_index('otp', 'timestamp', background=True, expireAfterSeconds=120) upsert_index('otp_cache', 'timestamp', background=True, expireAfterSeconds=settings.vpn.otp_cache_timeout) upsert_index('yubikey', 'timestamp', background=True, expireAfterSeconds=86400) upsert_index('sso_tokens', 'timestamp', background=True, expireAfterSeconds=600) upsert_index('sso_push_cache', 'timestamp', background=True, expireAfterSeconds=settings.app.sso_cache_timeout) upsert_index('sso_client_cache', 'timestamp', background=True, expireAfterSeconds=settings.app.sso_client_cache_timeout + settings.app.sso_client_cache_window) upsert_index('sso_passcode_cache', 'timestamp', background=True, expireAfterSeconds=settings.app.sso_cache_timeout) try: clean_indexes() except: logger.exception('Failed to clean indexes', 'setup') if not auth.Administrator.collection.find_one(): auth.Administrator( username=DEFAULT_USERNAME, password=DEFAULT_PASSWORD, default=True, ).commit() secret_key = settings.app.cookie_secret secret_key2 = settings.app.cookie_secret2 settings_commit = False if not secret_key: settings_commit = True secret_key = utils.rand_str(64) settings.app.cookie_secret = secret_key if not secret_key2: settings_commit = True settings.app.cookie_secret2 = utils.rand_str(64) if settings_commit: settings.commit() app.app.secret_key = secret_key.encode()
def main(default_conf=None): if len(sys.argv) > 1: cmd = sys.argv[1] else: cmd = 'start' parser = optparse.OptionParser(usage=USAGE) if cmd == 'start': parser.add_option('-d', '--daemon', action='store_true', help='Daemonize process') parser.add_option('-p', '--pidfile', type='string', help='Path to create pid file') parser.add_option('-c', '--conf', type='string', help='Path to configuration file') parser.add_option('-q', '--quiet', action='store_true', help='Suppress logging output') elif cmd == 'logs': parser.add_option('--archive', action='store_true', help='Archive log file') parser.add_option('--tail', action='store_true', help='Tail log file') parser.add_option('--limit', type='int', help='Limit log lines') (options, args) = parser.parse_args() if hasattr(options, 'conf') and options.conf: conf_path = options.conf else: conf_path = default_conf pritunl.set_conf_path(conf_path) if cmd == 'version': print '%s v%s' % (pritunl.__title__, pritunl.__version__) sys.exit(0) elif cmd == 'setup-key': from pritunl import setup from pritunl import settings setup.setup_loc() print settings.local.setup_key sys.exit(0) elif cmd == 'reset-version': from pritunl.constants import MIN_DATABASE_VER from pritunl import setup from pritunl import utils setup.setup_db() utils.set_db_ver(pritunl.__version__, MIN_DATABASE_VER) time.sleep(.3) print 'Database version reset to %s' % pritunl.__version__ sys.exit(0) elif cmd == 'reset-password': from pritunl import setup from pritunl import auth setup.setup_db() username, password = auth.reset_password() time.sleep(.3) print 'Administrator password successfully reset:\n' + \ ' username: "******"\n password: "******"' % (username, password) sys.exit(0) elif cmd == 'reconfigure': from pritunl import setup from pritunl import settings setup.setup_loc() settings.conf.mongodb_uri = None settings.conf.commit() time.sleep(.3) print 'Database configuration successfully reset' sys.exit(0) elif cmd == 'get': from pritunl import setup from pritunl import settings setup.setup_db() if len(args) != 2: raise ValueError('Invalid arguments') split = args[1].split('.') key_str = None group_str = split[0] if len(split) > 1: key_str = split[1] group = getattr(settings, group_str) if key_str: val = getattr(group, key_str) print '%s.%s = %s' % (group_str, key_str, json.dumps(val)) else: for field in group.fields: val = getattr(group, field) print '%s.%s = %s' % (group_str, field, json.dumps(val)) sys.exit(0) elif cmd == 'set': from pritunl import setup from pritunl import settings setup.setup_db() if len(args) != 3: raise ValueError('Invalid arguments') group_str, key_str = args[1].split('.') group = getattr(settings, group_str) val_str = args[2] val = json.loads(val_str) setattr(group, key_str, val) settings.commit() time.sleep(.3) print '%s.%s = %s' % (group_str, key_str, json.dumps(getattr(group, key_str))) sys.exit(0) elif cmd == 'unset': from pritunl import setup from pritunl import settings setup.setup_db() if len(args) != 2: raise ValueError('Invalid arguments') group_str, key_str = args[1].split('.') group = getattr(settings, group_str) group.unset(key_str) settings.commit() time.sleep(.3) print '%s.%s = %s' % (group_str, key_str, json.dumps(getattr(group, key_str))) sys.exit(0) elif cmd == 'set-mongodb': from pritunl import setup from pritunl import settings setup.setup_loc() if len(args) > 1: mongodb_uri = args[1] else: mongodb_uri = None settings.conf.mongodb_uri = mongodb_uri settings.conf.commit() time.sleep(.3) print 'Database configuration successfully set' sys.exit(0) elif cmd == 'reset-ssl-cert': from pritunl import setup from pritunl import settings setup.setup_db() settings.app.server_cert = None settings.app.server_key = None settings.app.server_dh_params = None settings.commit() time.sleep(.3) print 'Server ssl certificate successfully reset' sys.exit(0) elif cmd == 'logs': from pritunl import setup from pritunl import logger setup.setup_db() log_view = logger.LogView() if options.archive: if len(args) > 1: archive_path = args[1] else: archive_path = './' print 'Log archived to: ' + log_view.archive_log(archive_path, options.limit) elif options.tail: for msg in log_view.tail_log_lines(): print msg else: print log_view.get_log_lines(options.limit) sys.exit(0) elif cmd != 'start': raise ValueError('Invalid command') from pritunl import settings if options.quiet: settings.local.quiet = True if options.daemon: pid = os.fork() if pid > 0: if options.pidfile: with open(options.pidfile, 'w') as pid_file: pid_file.write('%s' % pid) sys.exit(0) elif not options.quiet: print '##############################################################' print '# #' print '# /$$ /$$ /$$ #' print '# |__/ | $$ | $$ #' print '# /$$$$$$ /$$$$$$ /$$ /$$$$$$ /$$ /$$ /$$$$$$$ | $$ #' print '# /$$__ $$ /$$__ $$| $$|_ $$_/ | $$ | $$| $$__ $$| $$ #' print '# | $$ \ $$| $$ \__/| $$ | $$ | $$ | $$| $$ \ $$| $$ #' print '# | $$ | $$| $$ | $$ | $$ /$$| $$ | $$| $$ | $$| $$ #' print '# | $$$$$$$/| $$ | $$ | $$$$/| $$$$$$/| $$ | $$| $$ #' print '# | $$____/ |__/ |__/ \____/ \______/ |__/ |__/|__/ #' print '# | $$ #' print '# | $$ #' print '# |__/ #' print '# #' print '##############################################################' pritunl.init_server()
def settings_put(): admin = flask.g.administrator if 'username' in flask.request.json and flask.request.json['username']: admin.username = utils.filter_str( flask.request.json['username']).lower() if 'password' in flask.request.json and flask.request.json['password']: admin.password = flask.request.json['password'] if 'token' in flask.request.json and flask.request.json['token']: admin.generate_token() if 'secret' in flask.request.json and flask.request.json['secret']: admin.generate_secret() settings_commit = False if 'email_from' in flask.request.json: settings_commit = True email_from = flask.request.json['email_from'] settings.app.email_from = email_from or None if 'email_server' in flask.request.json: settings_commit = True email_server = flask.request.json['email_server'] settings.app.email_server = email_server or None if 'email_username' in flask.request.json: settings_commit = True email_username = flask.request.json['email_username'] settings.app.email_username = email_username or None if 'email_password' in flask.request.json: settings_commit = True email_password = flask.request.json['email_password'] settings.app.email_password = email_password or None if 'theme' in flask.request.json: settings_commit = True theme = 'dark' if flask.request.json['theme'] == 'dark' else 'light' if theme != settings.app.theme: if theme == 'dark': event.Event(type=THEME_DARK) else: event.Event(type=THEME_LIGHT) settings.app.theme = theme if 'public_address' in flask.request.json: public_address = flask.request.json['public_address'] settings.local.host.public_address = public_address settings.local.host.commit('public_address') if settings_commit: settings.commit() admin.commit(admin.changed) response = flask.g.administrator.dict() response.update({ 'theme': settings.app.theme, 'email_from': settings.app.email_from, 'email_server': settings.app.email_server, 'email_username': settings.app.email_username, 'email_password': bool(settings.app.email_password), 'public_address': settings.local.host.public_addr, }) return utils.jsonify(response)
def update(): license = settings.app.license collection = mongo.get_collection("settings") if not license: settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_trial_end = None settings.local.sub_cancel_at_period_end = None else: for i in xrange(2): try: response = utils.request.get( "https://app.pritunl.com/subscription", json_data={"license": license, "version": settings.local.version_int}, timeout=max(settings.app.http_request_timeout, 10), ) # License key invalid if response.status_code == 470: logger.warning("License key is invalid", "subscription") settings.app.license = None settings.commit() update() return if response.status_code == 473: raise ValueError( ("Version %r not recognized by " + "subscription server") % settings.local.version_int ) data = response.json() settings.local.sub_active = data["active"] settings.local.sub_status = data["status"] settings.local.sub_plan = data["plan"] settings.local.sub_amount = data["amount"] settings.local.sub_period_end = data["period_end"] settings.local.sub_trial_end = data["trial_end"] settings.local.sub_cancel_at_period_end = data["cancel_at_period_end"] settings.local.sub_styles[data["plan"]] = data["styles"] except: if i < 1: logger.exception("Failed to check subscription status", "subscription, retrying...") time.sleep(1) continue logger.exception("Failed to check subscription status", "subscription") settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_trial_end = None settings.local.sub_cancel_at_period_end = None break response = collection.update( { "_id": "subscription", "$or": [{"active": {"$ne": settings.local.sub_active}}, {"plan": {"$ne": settings.local.sub_plan}}], }, {"$set": {"active": settings.local.sub_active, "plan": settings.local.sub_plan}}, ) if response["updatedExisting"]: if settings.local.sub_active: if settings.local.sub_plan == "premium": event.Event(type=SUBSCRIPTION_PREMIUM_ACTIVE) elif settings.local.sub_plan == "enterprise": event.Event(type=SUBSCRIPTION_ENTERPRISE_ACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE) else: if settings.local.sub_plan == "premium": event.Event(type=SUBSCRIPTION_PREMIUM_INACTIVE) elif settings.local.sub_plan == "enterprise": event.Event(type=SUBSCRIPTION_ENTERPRISE_INACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE)
def settings_put(): admin = flask.g.administrator if 'username' in flask.request.json and flask.request.json['username']: admin.username = utils.filter_str( flask.request.json['username']).lower() if 'password' in flask.request.json and flask.request.json['password']: admin.password = flask.request.json['password'] if 'token' in flask.request.json and flask.request.json['token']: admin.generate_token() if 'secret' in flask.request.json and flask.request.json['secret']: admin.generate_secret() settings_commit = False if 'email_from' in flask.request.json: settings_commit = True email_from = flask.request.json['email_from'] settings.app.email_from = email_from or None if 'email_server' in flask.request.json: settings_commit = True email_server = flask.request.json['email_server'] settings.app.email_server = email_server or None if 'email_username' in flask.request.json: settings_commit = True email_username = flask.request.json['email_username'] settings.app.email_username = email_username or None if 'email_password' in flask.request.json: settings_commit = True email_password = flask.request.json['email_password'] settings.app.email_password = email_password or None if 'sso' in flask.request.json: settings_commit = True sso = flask.request.json['sso'] settings.app.sso = sso or None if 'sso_match' in flask.request.json: sso_match = flask.request.json['sso_match'] if isinstance(sso_match, list): settings_commit = True settings.app.sso_match = sso_match or None if 'sso_token' in flask.request.json: sso_token = flask.request.json['sso_token'] settings_commit = True settings.app.sso_token = sso_token or None if 'sso_secret' in flask.request.json: sso_secret = flask.request.json['sso_secret'] settings_commit = True settings.app.sso_secret = sso_secret or None if 'sso_host' in flask.request.json: sso_host = flask.request.json['sso_host'] settings_commit = True settings.app.sso_host = sso_host or None if 'sso_admin' in flask.request.json: sso_admin = flask.request.json['sso_admin'] settings_commit = True settings.app.sso_admin = sso_admin or None if 'sso_org' in flask.request.json: settings_commit = True sso_org = flask.request.json['sso_org'] if sso_org: settings.app.sso_org = utils.ObjectId(sso_org) else: settings.app.sso_org = None if 'theme' in flask.request.json: settings_commit = True theme = 'dark' if flask.request.json['theme'] == 'dark' else 'light' if theme != settings.app.theme: if theme == 'dark': event.Event(type=THEME_DARK) else: event.Event(type=THEME_LIGHT) settings.app.theme = theme if 'public_address' in flask.request.json: public_address = flask.request.json['public_address'] settings.local.host.public_address = public_address settings.local.host.commit('public_address') if 'public_address6' in flask.request.json: public_address6 = flask.request.json['public_address6'] settings.local.host.public_address6 = public_address6 settings.local.host.commit('public_address6') if 'routed_subnet6' in flask.request.json: routed_subnet6 = flask.request.json['routed_subnet6'] if routed_subnet6: try: routed_subnet6 = ipaddress.IPv6Network( flask.request.json['routed_subnet6']) except (ipaddress.AddressValueError, ValueError): return utils.jsonify( { 'error': IPV6_SUBNET_INVALID, 'error_msg': IPV6_SUBNET_INVALID_MSG, }, 400) if routed_subnet6.prefixlen > 64: return utils.jsonify( { 'error': IPV6_SUBNET_SIZE_INVALID, 'error_msg': IPV6_SUBNET_SIZE_INVALID_MSG, }, 400) routed_subnet6 = str(routed_subnet6) else: routed_subnet6 = None if settings.local.host.routed_subnet6 != routed_subnet6: if server.get_online_ipv6_count(): return utils.jsonify( { 'error': IPV6_SUBNET_ONLINE, 'error_msg': IPV6_SUBNET_ONLINE_MSG, }, 400) settings.local.host.routed_subnet6 = routed_subnet6 settings.local.host.commit('routed_subnet6') if 'server_cert' in flask.request.json: settings_commit = True server_cert = flask.request.json['server_cert'] if server_cert: settings.app.server_cert = server_cert.strip() else: settings.app.server_cert = None if 'server_key' in flask.request.json: settings_commit = True server_key = flask.request.json['server_key'] if server_key: settings.app.server_key = server_key.strip() else: settings.app.server_key = None if not settings.app.sso: settings.app.sso_match = None settings.app.sso_token = None settings.app.sso_secret = None settings.app.sso_host = None settings.app.sso_admin = None settings.app.sso_org = None if settings_commit: settings.commit() admin.commit(admin.changed) response = flask.g.administrator.dict() response.update({ 'theme': settings.app.theme, 'email_from': settings.app.email_from, 'email_server': settings.app.email_server, 'email_username': settings.app.email_username, 'email_password': bool(settings.app.email_password), 'sso': settings.app.sso, 'sso_match': settings.app.sso_match, 'sso_token': settings.app.sso_token, 'sso_secret': settings.app.sso_secret, 'sso_host': settings.app.sso_host, 'sso_admin': settings.app.sso_admin, 'sso_org': settings.app.sso_org, 'public_address': settings.local.host.public_addr, }) return utils.jsonify(response)
def update_license(license): settings.app.license = license settings.app.license_plan = None settings.commit() update() messenger.publish('subscription', 'updated')
def update(): license = settings.app.license collection = mongo.get_collection('settings') if not license: settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_trial_end = None settings.local.sub_cancel_at_period_end = None settings.local.sub_url_key = None else: for i in xrange(2): try: response = utils.request.get( 'https://app.pritunl.com/subscription', json_data={ 'license': license, 'version': settings.local.version_int, }, timeout=max(settings.app.http_request_timeout, 10), ) # License key invalid if response.status_code == 470: logger.warning('License key is invalid', 'subscription') update_license(None) update() return if response.status_code == 473: raise ValueError(('Version %r not recognized by ' + 'subscription server') % settings.local.version_int) data = response.json() settings.local.sub_active = data['active'] settings.local.sub_status = data['status'] settings.local.sub_plan = data['plan'] settings.local.sub_amount = data['amount'] settings.local.sub_period_end = data['period_end'] settings.local.sub_trial_end = data['trial_end'] settings.local.sub_cancel_at_period_end = data[ 'cancel_at_period_end'] settings.local.sub_url_key = data.get('url_key') settings.local.sub_styles[data['plan']] = data['styles'] except: if i < 1: logger.exception('Failed to check subscription status', 'subscription, retrying...') time.sleep(1) continue logger.exception('Failed to check subscription status', 'subscription') settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_trial_end = None settings.local.sub_cancel_at_period_end = None settings.local.sub_url_key = None break if settings.app.license_plan != settings.local.sub_plan and \ settings.local.sub_plan: settings.app.license_plan = settings.local.sub_plan settings.commit() response = collection.update({ '_id': 'subscription', '$or': [ {'active': {'$ne': settings.local.sub_active}}, {'plan': {'$ne': settings.local.sub_plan}}, ], }, {'$set': { 'active': settings.local.sub_active, 'plan': settings.local.sub_plan, }}) if response['updatedExisting']: if settings.local.sub_active: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_ACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_ACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE) else: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_INACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_INACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE)
def settings_put(): if settings.app.demo_mode: return utils.demo_blocked() org_event = False admin = flask.g.administrator changes = set() if "username" in flask.request.json and flask.request.json["username"]: username = utils.filter_str(flask.request.json["username"]).lower() if username != admin.username: changes.add("username") admin.username = username if "password" in flask.request.json and flask.request.json["password"]: password = flask.request.json["password"] if password != admin.password: changes.add("password") admin.password = flask.request.json["password"] if "token" in flask.request.json and flask.request.json["token"]: admin.generate_token() changes.add("token") if "secret" in flask.request.json and flask.request.json["secret"]: admin.generate_secret() changes.add("token") settings_commit = False if "auditing" in flask.request.json: settings_commit = True auditing = flask.request.json["auditing"] or None if settings.app.auditing != auditing: org_event = True settings.app.auditing = auditing if "email_from" in flask.request.json: settings_commit = True email_from = flask.request.json["email_from"] or None if email_from != settings.app.email_from: changes.add("smtp") settings.app.email_from = email_from if "email_server" in flask.request.json: settings_commit = True email_server = flask.request.json["email_server"] or None if email_server != settings.app.email_server: changes.add("smtp") settings.app.email_server = email_server if "email_username" in flask.request.json: settings_commit = True email_username = flask.request.json["email_username"] or None if email_username != settings.app.email_username: changes.add("smtp") settings.app.email_username = email_username if "email_password" in flask.request.json: settings_commit = True email_password = flask.request.json["email_password"] or None if email_password != settings.app.email_password: changes.add("smtp") settings.app.email_password = email_password if "sso" in flask.request.json: org_event = True settings_commit = True sso = flask.request.json["sso"] or None if sso != settings.app.sso: changes.add("sso") settings.app.sso = sso if "sso_match" in flask.request.json: settings_commit = True sso_match = flask.request.json["sso_match"] or None if sso_match != settings.app.sso_match: changes.add("sso") if isinstance(sso_match, list): settings.app.sso_match = sso_match else: settings.app.sso_match = None if "sso_token" in flask.request.json: settings_commit = True sso_token = flask.request.json["sso_token"] or None if sso_token != settings.app.sso_token: changes.add("sso") settings.app.sso_token = sso_token if "sso_secret" in flask.request.json: settings_commit = True sso_secret = flask.request.json["sso_secret"] or None if sso_secret != settings.app.sso_secret: changes.add("sso") settings.app.sso_secret = sso_secret if "sso_host" in flask.request.json: settings_commit = True sso_host = flask.request.json["sso_host"] or None if sso_host != settings.app.sso_host: changes.add("sso") settings.app.sso_host = sso_host if "sso_admin" in flask.request.json: settings_commit = True sso_admin = flask.request.json["sso_admin"] or None if sso_admin != settings.app.sso_admin: changes.add("sso") settings.app.sso_admin = sso_admin if "sso_org" in flask.request.json: settings_commit = True sso_org = flask.request.json["sso_org"] if sso_org: sso_org = utils.ObjectId(sso_org) else: sso_org = None if sso_org != settings.app.sso_org: changes.add("sso") settings.app.sso_org = sso_org if "sso_saml_url" in flask.request.json: settings_commit = True sso_saml_url = flask.request.json["sso_saml_url"] or None if sso_saml_url != settings.app.sso_saml_url: changes.add("sso") settings.app.sso_saml_url = sso_saml_url if "sso_saml_issuer_url" in flask.request.json: settings_commit = True sso_saml_issuer_url = flask.request.json["sso_saml_issuer_url"] or None if sso_saml_issuer_url != settings.app.sso_saml_issuer_url: changes.add("sso") settings.app.sso_saml_issuer_url = sso_saml_issuer_url if "sso_saml_cert" in flask.request.json: settings_commit = True sso_saml_cert = flask.request.json["sso_saml_cert"] or None if sso_saml_cert != settings.app.sso_saml_cert: changes.add("sso") settings.app.sso_saml_cert = sso_saml_cert if "sso_okta_token" in flask.request.json: settings_commit = True sso_okta_token = flask.request.json["sso_okta_token"] or None if sso_okta_token != settings.app.sso_okta_token: changes.add("sso") settings.app.sso_okta_token = sso_okta_token if "sso_onelogin_key" in flask.request.json: settings_commit = True sso_onelogin_key = flask.request.json["sso_onelogin_key"] or None if sso_onelogin_key != settings.app.sso_onelogin_key: changes.add("sso") settings.app.sso_onelogin_key = sso_onelogin_key if "theme" in flask.request.json: settings_commit = True theme = "dark" if flask.request.json["theme"] == "dark" else "light" if theme != settings.app.theme: if theme == "dark": event.Event(type=THEME_DARK) else: event.Event(type=THEME_LIGHT) settings.app.theme = theme if "public_address" in flask.request.json: public_address = flask.request.json["public_address"] settings.local.host.public_address = public_address settings.local.host.commit("public_address") if "public_address6" in flask.request.json: public_address6 = flask.request.json["public_address6"] settings.local.host.public_address6 = public_address6 settings.local.host.commit("public_address6") if "routed_subnet6" in flask.request.json: routed_subnet6 = flask.request.json["routed_subnet6"] if routed_subnet6: try: routed_subnet6 = ipaddress.IPv6Network(flask.request.json["routed_subnet6"]) except (ipaddress.AddressValueError, ValueError): return utils.jsonify({"error": IPV6_SUBNET_INVALID, "error_msg": IPV6_SUBNET_INVALID_MSG}, 400) if routed_subnet6.prefixlen > 64: return utils.jsonify( {"error": IPV6_SUBNET_SIZE_INVALID, "error_msg": IPV6_SUBNET_SIZE_INVALID_MSG}, 400 ) routed_subnet6 = str(routed_subnet6) else: routed_subnet6 = None if settings.local.host.routed_subnet6 != routed_subnet6: if server.get_online_ipv6_count(): return utils.jsonify({"error": IPV6_SUBNET_ONLINE, "error_msg": IPV6_SUBNET_ONLINE_MSG}, 400) settings.local.host.routed_subnet6 = routed_subnet6 settings.local.host.commit("routed_subnet6") if "server_cert" in flask.request.json: settings_commit = True server_cert = flask.request.json["server_cert"] if server_cert: settings.app.server_cert = server_cert.strip() else: settings.app.server_cert = None if "server_key" in flask.request.json: settings_commit = True server_key = flask.request.json["server_key"] if server_key: settings.app.server_key = server_key.strip() else: settings.app.server_key = None if not settings.app.sso: settings.app.sso_match = None settings.app.sso_token = None settings.app.sso_secret = None settings.app.sso_host = None settings.app.sso_admin = None settings.app.sso_org = None settings.app.sso_saml_url = None settings.app.sso_saml_issuer_url = None settings.app.sso_saml_cert = None settings.app.sso_okta_token = None settings.app.sso_onelogin_key = None for change in changes: auth.audit_event("admin_settings", _changes_audit_text[change], remote_addr=utils.get_remote_addr()) if settings_commit: settings.commit() admin.commit(admin.changed) if org_event: for org in organization.iter_orgs(fields=("_id")): event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SETTINGS_UPDATED) response = flask.g.administrator.dict() response.update( { "theme": settings.app.theme, "auditing": settings.app.auditing, "email_from": settings.app.email_from, "email_server": settings.app.email_server, "email_username": settings.app.email_username, "email_password": bool(settings.app.email_password), "sso": settings.app.sso, "sso_match": settings.app.sso_match, "sso_token": settings.app.sso_token, "sso_secret": settings.app.sso_secret, "sso_host": settings.app.sso_host, "sso_admin": settings.app.sso_admin, "sso_org": settings.app.sso_org, "sso_saml_url": settings.app.sso_saml_url, "sso_saml_issuer_url": settings.app.sso_saml_issuer_url, "sso_saml_cert": settings.app.sso_saml_cert, "sso_okta_token": settings.app.sso_okta_token, "sso_onelogin_key": settings.app.sso_onelogin_key, "public_address": settings.local.host.public_addr, } ) return utils.jsonify(response)
def update(): license = settings.app.license collection = mongo.get_collection('settings') if not settings.app.id: settings.app.id = utils.random_name() settings.commit() if not license: settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_quantity = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_trial_end = None settings.local.sub_cancel_at_period_end = None settings.local.sub_balance = None settings.local.sub_url_key = None else: for i in xrange(2): try: url = 'https://app.pritunl.com/subscription' if settings.app.dedicated: url = settings.app.dedicated + '/subscription' response = requests.get( url, json={ 'id': settings.app.id, 'license': license, 'version': settings.local.version_int, }, timeout=max(settings.app.http_request_timeout, 10), ) # License key invalid data = response.json() settings.local.sub_active = True settings.local.sub_status = 'active' settings.local.sub_plan = 'enterprise' settings.local.sub_quantity = 1000 settings.local.sub_amount = 1000 settings.local.sub_period_end = 100 settings.local.sub_trial_end = 100 settings.local.sub_cancel_at_period_end = 1000 settings.local.sub_balance = 1000 settings.local.sub_url_key = 'Test' except: if i < 1: logger.exception('Failed to check subscription status', 'subscription, retrying...') time.sleep(1) continue logger.exception('Failed to check subscription status', 'subscription') settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_quantity = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_trial_end = None settings.local.sub_cancel_at_period_end = None settings.local.sub_balance = None settings.local.sub_url_key = None break if settings.app.license_plan != settings.local.sub_plan and \ settings.local.sub_plan: settings.app.license_plan = settings.local.sub_plan settings.commit() response = collection.update({ '_id': 'subscription', '$or': [ {'active': {'$ne': settings.local.sub_active}}, {'plan': {'$ne': settings.local.sub_plan}}, ], }, {'$set': { 'active': settings.local.sub_active, 'plan': settings.local.sub_plan, }}) if response['updatedExisting']: if settings.local.sub_active: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_ACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_ACTIVE) elif settings.local.sub_plan == 'enterprise_plus': event.Event(type=SUBSCRIPTION_ENTERPRISE_PLUS_ACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE) else: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_INACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_INACTIVE) elif settings.local.sub_plan == 'enterprise_plus': event.Event(type=SUBSCRIPTION_ENTERPRISE_PLUS_INACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE) return True
def update(): license = settings.app.license if not license: cur_sub_active = None cur_sub_plan = None settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_cancel_at_period_end = None else: cur_sub_active = settings.local.sub_active cur_sub_plan = settings.local.sub_plan try: response = utils.request.get( SUBSCRIPTION_SERVER, json_data={ 'license': license, 'version': settings.local.version_int, }, timeout=max(settings.app.http_request_timeout, 10)) # License key invalid if response.status_code == 470: settings.app.license = None settings.commit() subscription_update() return if response.status_code == 473: raise ValueError( ('Version %r not recognized by ' + 'subscription server') % settings.local.version_int) data = response.json() settings.local.sub_active = data['active'] settings.local.sub_status = data['status'] settings.local.sub_plan = data['plan'] settings.local.sub_amount = data['amount'] settings.local.sub_period_end = data['period_end'] settings.local.sub_cancel_at_period_end = data[ 'cancel_at_period_end'] settings.local.sub_styles[data['plan']] = data['styles'] except: logger.exception('Failed to check subscription status', 'subscription') settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_cancel_at_period_end = None if cur_sub_active != settings.local.sub_active or \ cur_sub_plan != settings.local.sub_plan: if settings.local.sub_active: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_ACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_ACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE) else: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_INACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_INACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE)
def settings_put(): if settings.app.demo_mode: return utils.demo_blocked() org_event = False admin = flask.g.administrator changes = set() if 'username' in flask.request.json and flask.request.json['username']: username = utils.filter_str(flask.request.json['username']).lower() if username != admin.username: changes.add('username') admin.username = username if 'password' in flask.request.json and flask.request.json['password']: password = flask.request.json['password'] changes.add('password') admin.password = password if 'token' in flask.request.json and flask.request.json['token']: admin.generate_token() changes.add('token') if 'secret' in flask.request.json and flask.request.json['secret']: admin.generate_secret() changes.add('token') settings_commit = False if 'auditing' in flask.request.json: settings_commit = True auditing = flask.request.json['auditing'] or None if settings.app.auditing != auditing: org_event = True settings.app.auditing = auditing if 'monitoring' in flask.request.json: settings_commit = True monitoring = flask.request.json['monitoring'] or None settings.app.monitoring = monitoring if 'datadog_api_key' in flask.request.json: settings_commit = True datadog_api_key = flask.request.json['datadog_api_key'] or None settings.app.datadog_api_key = datadog_api_key if 'email_from' in flask.request.json: settings_commit = True email_from = flask.request.json['email_from'] or None if email_from != settings.app.email_from: changes.add('smtp') settings.app.email_from = email_from if 'email_server' in flask.request.json: settings_commit = True email_server = flask.request.json['email_server'] or None if email_server != settings.app.email_server: changes.add('smtp') settings.app.email_server = email_server if 'email_username' in flask.request.json: settings_commit = True email_username = flask.request.json['email_username'] or None if email_username != settings.app.email_username: changes.add('smtp') settings.app.email_username = email_username if 'email_password' in flask.request.json: settings_commit = True email_password = flask.request.json['email_password'] or None if email_password != settings.app.email_password: changes.add('smtp') settings.app.email_password = email_password if 'pin_mode' in flask.request.json: settings_commit = True pin_mode = flask.request.json['pin_mode'] or None if pin_mode != settings.user.pin_mode: changes.add('pin_mode') settings.user.pin_mode = pin_mode if 'sso' in flask.request.json: org_event = True settings_commit = True sso = flask.request.json['sso'] or None if sso != settings.app.sso: changes.add('sso') settings.app.sso = sso if 'sso_match' in flask.request.json: settings_commit = True sso_match = flask.request.json['sso_match'] or None if sso_match != settings.app.sso_match: changes.add('sso') if isinstance(sso_match, list): settings.app.sso_match = sso_match else: settings.app.sso_match = None if 'sso_token' in flask.request.json: settings_commit = True sso_token = flask.request.json['sso_token'] or None if sso_token != settings.app.sso_token: changes.add('sso') settings.app.sso_token = sso_token if 'sso_secret' in flask.request.json: settings_commit = True sso_secret = flask.request.json['sso_secret'] or None if sso_secret != settings.app.sso_secret: changes.add('sso') settings.app.sso_secret = sso_secret if 'sso_host' in flask.request.json: settings_commit = True sso_host = flask.request.json['sso_host'] or None if sso_host != settings.app.sso_host: changes.add('sso') settings.app.sso_host = sso_host if 'sso_admin' in flask.request.json: settings_commit = True sso_admin = flask.request.json['sso_admin'] or None if sso_admin != settings.app.sso_admin: changes.add('sso') settings.app.sso_admin = sso_admin if 'sso_org' in flask.request.json: settings_commit = True sso_org = flask.request.json['sso_org'] if sso_org: sso_org = utils.ObjectId(sso_org) else: sso_org = None if sso_org != settings.app.sso_org: changes.add('sso') settings.app.sso_org = sso_org if 'sso_saml_url' in flask.request.json: settings_commit = True sso_saml_url = flask.request.json['sso_saml_url'] or None if sso_saml_url != settings.app.sso_saml_url: changes.add('sso') settings.app.sso_saml_url = sso_saml_url if 'sso_saml_issuer_url' in flask.request.json: settings_commit = True sso_saml_issuer_url = flask.request.json['sso_saml_issuer_url'] or None if sso_saml_issuer_url != settings.app.sso_saml_issuer_url: changes.add('sso') settings.app.sso_saml_issuer_url = sso_saml_issuer_url if 'sso_saml_cert' in flask.request.json: settings_commit = True sso_saml_cert = flask.request.json['sso_saml_cert'] or None if sso_saml_cert != settings.app.sso_saml_cert: changes.add('sso') settings.app.sso_saml_cert = sso_saml_cert if 'sso_okta_token' in flask.request.json: settings_commit = True sso_okta_token = flask.request.json['sso_okta_token'] or None if sso_okta_token != settings.app.sso_okta_token: changes.add('sso') settings.app.sso_okta_token = sso_okta_token if 'sso_onelogin_key' in flask.request.json: settings_commit = True sso_onelogin_key = flask.request.json['sso_onelogin_key'] or None if sso_onelogin_key != settings.app.sso_onelogin_key: changes.add('sso') settings.app.sso_onelogin_key = sso_onelogin_key if 'theme' in flask.request.json: settings_commit = True theme = 'dark' if flask.request.json['theme'] == 'dark' else 'light' if theme != settings.app.theme: if theme == 'dark': event.Event(type=THEME_DARK) else: event.Event(type=THEME_LIGHT) settings.app.theme = theme if 'public_address' in flask.request.json: public_address = flask.request.json['public_address'] settings.local.host.public_address = public_address settings.local.host.commit('public_address') if 'public_address6' in flask.request.json: public_address6 = flask.request.json['public_address6'] settings.local.host.public_address6 = public_address6 settings.local.host.commit('public_address6') if 'routed_subnet6' in flask.request.json: routed_subnet6 = flask.request.json['routed_subnet6'] if routed_subnet6: try: routed_subnet6 = ipaddress.IPv6Network( flask.request.json['routed_subnet6']) except (ipaddress.AddressValueError, ValueError): return utils.jsonify( { 'error': IPV6_SUBNET_INVALID, 'error_msg': IPV6_SUBNET_INVALID_MSG, }, 400) if routed_subnet6.prefixlen > 64: return utils.jsonify( { 'error': IPV6_SUBNET_SIZE_INVALID, 'error_msg': IPV6_SUBNET_SIZE_INVALID_MSG, }, 400) routed_subnet6 = str(routed_subnet6) else: routed_subnet6 = None if settings.local.host.routed_subnet6 != routed_subnet6: if server.get_online_ipv6_count(): return utils.jsonify( { 'error': IPV6_SUBNET_ONLINE, 'error_msg': IPV6_SUBNET_ONLINE_MSG, }, 400) settings.local.host.routed_subnet6 = routed_subnet6 settings.local.host.commit('routed_subnet6') if 'server_cert' in flask.request.json: settings_commit = True server_cert = flask.request.json['server_cert'] if server_cert: settings.app.server_cert = server_cert.strip() else: settings.app.server_cert = None if 'server_key' in flask.request.json: settings_commit = True server_key = flask.request.json['server_key'] if server_key: settings.app.server_key = server_key.strip() else: settings.app.server_key = None if not settings.app.sso: settings.app.sso_match = None settings.app.sso_token = None settings.app.sso_secret = None settings.app.sso_host = None settings.app.sso_admin = None settings.app.sso_org = None settings.app.sso_saml_url = None settings.app.sso_saml_issuer_url = None settings.app.sso_saml_cert = None settings.app.sso_okta_token = None settings.app.sso_onelogin_key = None for change in changes: auth.audit_event( 'admin_settings', _changes_audit_text[change], remote_addr=utils.get_remote_addr(), ) if settings_commit: settings.commit() admin.commit(admin.changed) if org_event: for org in organization.iter_orgs(fields=('_id')): event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SETTINGS_UPDATED) response = flask.g.administrator.dict() response.update({ 'theme': settings.app.theme, 'auditing': settings.app.auditing, 'monitoring': settings.app.monitoring, 'datadog_api_key': settings.app.datadog_api_key, 'email_from': settings.app.email_from, 'email_server': settings.app.email_server, 'email_username': settings.app.email_username, 'email_password': bool(settings.app.email_password), 'pin_mode': settings.user.pin_mode, 'sso': settings.app.sso, 'sso_match': settings.app.sso_match, 'sso_token': settings.app.sso_token, 'sso_secret': settings.app.sso_secret, 'sso_host': settings.app.sso_host, 'sso_admin': settings.app.sso_admin, 'sso_org': settings.app.sso_org, 'sso_saml_url': settings.app.sso_saml_url, 'sso_saml_issuer_url': settings.app.sso_saml_issuer_url, 'sso_saml_cert': settings.app.sso_saml_cert, 'sso_okta_token': settings.app.sso_okta_token, 'sso_onelogin_key': settings.app.sso_onelogin_key, 'public_address': settings.local.host.public_addr, }) return utils.jsonify(response)
def settings_put(): if settings.app.demo_mode: return utils.demo_blocked() org_event = False admin_event = False admin = flask.g.administrator changes = set() settings_commit = False update_server = False update_acme = False update_cert = False if 'username' in flask.request.json and flask.request.json['username']: username = utils.filter_str( flask.request.json['username']).lower() if username != admin.username: changes.add('username') admin.username = username if 'password' in flask.request.json and flask.request.json['password']: password = flask.request.json['password'] changes.add('password') admin.password = password if 'token' in flask.request.json and flask.request.json['token']: admin.generate_token() changes.add('token') if 'secret' in flask.request.json and flask.request.json['secret']: admin.generate_secret() changes.add('token') if 'server_cert' in flask.request.json: settings_commit = True server_cert = flask.request.json['server_cert'] if server_cert: server_cert = server_cert.strip() else: server_cert = None if server_cert != settings.app.server_cert: update_server = True settings.app.server_cert = server_cert if 'server_key' in flask.request.json: settings_commit = True server_key = flask.request.json['server_key'] if server_key: server_key = server_key.strip() else: server_key = None if server_key != settings.app.server_key: update_server = True settings.app.server_key = server_key if 'server_port' in flask.request.json: settings_commit = True server_port = flask.request.json['server_port'] if not server_port: server_port = 443 try: server_port = int(server_port) if server_port < 1 or server_port > 65535: raise ValueError('Port invalid') except ValueError: return utils.jsonify({ 'error': PORT_INVALID, 'error_msg': PORT_INVALID_MSG, }, 400) if settings.app.redirect_server and server_port == 80: return utils.jsonify({ 'error': PORT_RESERVED, 'error_msg': PORT_RESERVED_MSG, }, 400) if server_port != settings.app.server_port: update_server = True settings.app.server_port = server_port if 'acme_domain' in flask.request.json: settings_commit = True acme_domain = utils.filter_str( flask.request.json['acme_domain'] or None) if acme_domain: acme_domain = acme_domain.replace('https://', '') acme_domain = acme_domain.replace('http://', '') acme_domain = acme_domain.replace('/', '') if acme_domain != settings.app.acme_domain: if not acme_domain: settings.app.acme_key = None settings.app.acme_timestamp = None settings.app.server_key = None settings.app.server_cert = None update_server = True update_cert = True else: update_acme = True settings.app.acme_domain = acme_domain if 'auditing' in flask.request.json: settings_commit = True auditing = flask.request.json['auditing'] or None if settings.app.auditing != auditing: if not flask.g.administrator.super_user: return utils.jsonify({ 'error': REQUIRES_SUPER_USER, 'error_msg': REQUIRES_SUPER_USER_MSG, }, 400) admin_event = True org_event = True settings.app.auditing = auditing if 'monitoring' in flask.request.json: settings_commit = True monitoring = flask.request.json['monitoring'] or None settings.app.monitoring = monitoring if 'influxdb_uri' in flask.request.json: settings_commit = True influxdb_uri = flask.request.json['influxdb_uri'] or None settings.app.influxdb_uri = influxdb_uri if 'email_from' in flask.request.json: settings_commit = True email_from = flask.request.json['email_from'] or None if email_from != settings.app.email_from: changes.add('smtp') settings.app.email_from = email_from if 'email_server' in flask.request.json: settings_commit = True email_server = flask.request.json['email_server'] or None if email_server != settings.app.email_server: changes.add('smtp') settings.app.email_server = email_server if 'email_username' in flask.request.json: settings_commit = True email_username = flask.request.json['email_username'] or None if email_username != settings.app.email_username: changes.add('smtp') settings.app.email_username = email_username if 'email_password' in flask.request.json: settings_commit = True email_password = flask.request.json['email_password'] or None if email_password != settings.app.email_password: changes.add('smtp') settings.app.email_password = email_password if 'pin_mode' in flask.request.json: settings_commit = True pin_mode = flask.request.json['pin_mode'] or None if pin_mode != settings.user.pin_mode: changes.add('pin_mode') settings.user.pin_mode = pin_mode if 'sso' in flask.request.json: org_event = True settings_commit = True sso = flask.request.json['sso'] or None if sso != settings.app.sso: changes.add('sso') settings.app.sso = sso if 'sso_match' in flask.request.json: settings_commit = True sso_match = flask.request.json['sso_match'] or None if sso_match != settings.app.sso_match: changes.add('sso') if isinstance(sso_match, list): settings.app.sso_match = sso_match else: settings.app.sso_match = None if 'sso_duo_token' in flask.request.json: settings_commit = True sso_duo_token = flask.request.json['sso_duo_token'] or None if sso_duo_token != settings.app.sso_duo_token: changes.add('sso') settings.app.sso_duo_token = sso_duo_token if 'sso_duo_secret' in flask.request.json: settings_commit = True sso_duo_secret = flask.request.json['sso_duo_secret'] or None if sso_duo_secret != settings.app.sso_duo_secret: changes.add('sso') settings.app.sso_duo_secret = sso_duo_secret if 'sso_duo_host' in flask.request.json: settings_commit = True sso_duo_host = flask.request.json['sso_duo_host'] or None if sso_duo_host != settings.app.sso_duo_host: changes.add('sso') settings.app.sso_duo_host = sso_duo_host if 'sso_duo_mode' in flask.request.json: settings_commit = True sso_duo_mode = flask.request.json['sso_duo_mode'] or None if sso_duo_mode != settings.app.sso_duo_mode: changes.add('sso') settings.app.sso_duo_mode = sso_duo_mode if 'sso_radius_secret' in flask.request.json: settings_commit = True sso_radius_secret = flask.request.json['sso_radius_secret'] or None if sso_radius_secret != settings.app.sso_radius_secret: changes.add('sso') settings.app.sso_radius_secret = sso_radius_secret if 'sso_radius_host' in flask.request.json: settings_commit = True sso_radius_host = flask.request.json['sso_radius_host'] or None if sso_radius_host != settings.app.sso_radius_host: changes.add('sso') settings.app.sso_radius_host = sso_radius_host if 'sso_org' in flask.request.json: settings_commit = True sso_org = flask.request.json['sso_org'] or None if sso_org: sso_org = utils.ObjectId(sso_org) else: sso_org = None if sso_org != settings.app.sso_org: changes.add('sso') if settings.app.sso and not sso_org: return utils.jsonify({ 'error': SSO_ORG_NULL, 'error_msg': SSO_ORG_NULL_MSG, }, 400) settings.app.sso_org = sso_org if 'sso_saml_url' in flask.request.json: settings_commit = True sso_saml_url = flask.request.json['sso_saml_url'] or None if sso_saml_url != settings.app.sso_saml_url: changes.add('sso') settings.app.sso_saml_url = sso_saml_url if 'sso_saml_issuer_url' in flask.request.json: settings_commit = True sso_saml_issuer_url = flask.request.json['sso_saml_issuer_url'] or None if sso_saml_issuer_url != settings.app.sso_saml_issuer_url: changes.add('sso') settings.app.sso_saml_issuer_url = sso_saml_issuer_url if 'sso_saml_cert' in flask.request.json: settings_commit = True sso_saml_cert = flask.request.json['sso_saml_cert'] or None if sso_saml_cert != settings.app.sso_saml_cert: changes.add('sso') settings.app.sso_saml_cert = sso_saml_cert if 'sso_okta_token' in flask.request.json: settings_commit = True sso_okta_token = flask.request.json['sso_okta_token'] or None if sso_okta_token != settings.app.sso_okta_token: changes.add('sso') settings.app.sso_okta_token = sso_okta_token if 'sso_onelogin_id' in flask.request.json: settings_commit = True sso_onelogin_id = flask.request.json['sso_onelogin_id'] or None if sso_onelogin_id != settings.app.sso_onelogin_id: changes.add('sso') settings.app.sso_onelogin_id = sso_onelogin_id if 'sso_onelogin_secret' in flask.request.json: settings_commit = True sso_onelogin_secret = \ flask.request.json['sso_onelogin_secret'] or None if sso_onelogin_secret != settings.app.sso_onelogin_secret: changes.add('sso') settings.app.sso_onelogin_secret = sso_onelogin_secret if 'sso_client_cache' in flask.request.json: settings_commit = True sso_client_cache = True if \ flask.request.json['sso_client_cache'] else False if sso_client_cache != settings.app.sso_client_cache: changes.add('sso') settings.app.sso_client_cache = sso_client_cache if flask.request.json.get('theme'): settings_commit = True theme = 'light' if flask.request.json['theme'] == 'light' else 'dark' if theme != settings.app.theme: if theme == 'dark': event.Event(type=THEME_DARK) else: event.Event(type=THEME_LIGHT) settings.app.theme = theme if 'public_address' in flask.request.json: public_address = flask.request.json['public_address'] or None if public_address != settings.local.host.public_addr: settings.local.host.public_address = public_address settings.local.host.commit('public_address') if 'public_address6' in flask.request.json: public_address6 = flask.request.json['public_address6'] or None if public_address6 != settings.local.host.public_addr6: settings.local.host.public_address6 = public_address6 settings.local.host.commit('public_address6') if 'routed_subnet6' in flask.request.json: routed_subnet6 = flask.request.json['routed_subnet6'] if routed_subnet6: try: routed_subnet6 = ipaddress.IPv6Network( flask.request.json['routed_subnet6']) except (ipaddress.AddressValueError, ValueError): return utils.jsonify({ 'error': IPV6_SUBNET_INVALID, 'error_msg': IPV6_SUBNET_INVALID_MSG, }, 400) if routed_subnet6.prefixlen > 64: return utils.jsonify({ 'error': IPV6_SUBNET_SIZE_INVALID, 'error_msg': IPV6_SUBNET_SIZE_INVALID_MSG, }, 400) routed_subnet6 = str(routed_subnet6) else: routed_subnet6 = None if settings.local.host.routed_subnet6 != routed_subnet6: if server.get_online_ipv6_count(): return utils.jsonify({ 'error': IPV6_SUBNET_ONLINE, 'error_msg': IPV6_SUBNET_ONLINE_MSG, }, 400) settings.local.host.routed_subnet6 = routed_subnet6 settings.local.host.commit('routed_subnet6') if 'reverse_proxy' in flask.request.json: settings_commit = True reverse_proxy = flask.request.json['reverse_proxy'] settings.app.reverse_proxy = True if reverse_proxy else False if 'cloud_provider' in flask.request.json: settings_commit = True cloud_provider = flask.request.json['cloud_provider'] or None settings.app.cloud_provider = cloud_provider if 'route53_region' in flask.request.json: settings_commit = True settings.app.route53_region = utils.filter_str( flask.request.json['route53_region']) or None if 'route53_zone' in flask.request.json: settings_commit = True settings.app.route53_zone = utils.filter_str( flask.request.json['route53_zone']) or None for aws_key in ( 'us_east_1_access_key', 'us_east_1_secret_key', 'us_east_2_access_key', 'us_east_2_secret_key', 'us_west_1_access_key', 'us_west_1_secret_key', 'us_west_2_access_key', 'us_west_2_secret_key', 'eu_west_1_access_key', 'eu_west_1_secret_key', 'eu_central_1_access_key', 'eu_central_1_secret_key', 'ap_northeast_1_access_key', 'ap_northeast_1_secret_key', 'ap_northeast_2_access_key', 'ap_northeast_2_secret_key', 'ap_southeast_1_access_key', 'ap_southeast_1_secret_key', 'ap_southeast_2_access_key', 'ap_southeast_2_secret_key', 'ap_south_1_access_key', 'ap_south_1_secret_key', 'sa_east_1_access_key', 'sa_east_1_secret_key', ): if aws_key in flask.request.json: settings_commit = True aws_value = flask.request.json[aws_key] if aws_value: setattr(settings.app, aws_key, utils.filter_str(aws_value)) else: setattr(settings.app, aws_key, None) if not settings.app.sso: settings.app.sso_host = None settings.app.sso_token = None settings.app.sso_secret = None settings.app.sso_match = None settings.app.sso_duo_token = None settings.app.sso_duo_secret = None settings.app.sso_duo_host = None settings.app.sso_org = None settings.app.sso_saml_url = None settings.app.sso_saml_issuer_url = None settings.app.sso_saml_cert = None settings.app.sso_okta_token = None settings.app.sso_onelogin_key = None settings.app.sso_onelogin_id = None settings.app.sso_onelogin_secret = None settings.app.sso_radius_secret = None settings.app.sso_radius_host = None else: if RADIUS_AUTH in settings.app.sso and \ settings.app.sso_duo_mode == 'passcode': return utils.jsonify({ 'error': RADIUS_DUO_PASSCODE, 'error_msg': RADIUS_DUO_PASSCODE_MSG, }, 400) if settings.app.sso == DUO_AUTH and \ settings.app.sso_duo_mode == 'passcode': return utils.jsonify({ 'error': DUO_PASSCODE, 'error_msg': DUO_PASSCODE_MSG, }, 400) for change in changes: flask.g.administrator.audit_event( 'admin_settings', _changes_audit_text[change], remote_addr=utils.get_remote_addr(), ) if settings_commit: settings.commit() admin.commit(admin.changed) if admin_event: event.Event(type=ADMINS_UPDATED) if org_event: for org in organization.iter_orgs(fields=('_id')): event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SETTINGS_UPDATED) if update_acme: try: acme.update_acme_cert() app.update_server(0.5) except: logger.exception('Failed to get LetsEncrypt cert', 'handler', acme_domain=settings.app.acme_domain, ) settings.app.acme_domain = None settings.app.acme_key = None settings.app.acme_timestamp = None settings.commit() return utils.jsonify({ 'error': ACME_ERROR, 'error_msg': ACME_ERROR_MSG, }, 400) elif update_cert: logger.info('Regenerating server certificate...', 'handler') utils.create_server_cert() app.update_server(0.5) elif update_server: app.update_server(0.5) response = flask.g.administrator.dict() response.update(_dict()) return utils.jsonify(response)
def setup_mongo(): prefix = settings.conf.mongodb_collection_prefix or '' last_error = time.time() - 24 while True: try: client = pymongo.MongoClient(settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT) break except pymongo.errors.ConnectionFailure: time.sleep(0.5) if time.time() - last_error > 30: last_error = time.time() logger.exception('Error connecting to mongodb server') database = client.get_default_database() cur_collections = database.collection_names() if prefix + 'messages' not in cur_collections: database.create_collection(prefix + 'messages', capped=True, size=100000, max=1024) mongo.collections.update({ 'time_sync': getattr(database, prefix + 'time_sync'), 'transaction': getattr(database, prefix + 'transaction'), 'queue': getattr(database, prefix + 'queue'), 'task': getattr(database, prefix + 'task'), 'settings': getattr(database, prefix + 'settings'), 'messages': getattr(database, prefix + 'messages'), 'administrators': getattr(database, prefix + 'administrators'), 'users': getattr(database, prefix + 'users'), 'users_key_link': getattr(database, prefix + 'users_key_link'), 'organizations': getattr(database, prefix + 'organizations'), 'hosts': getattr(database, prefix + 'hosts'), 'hosts_usage': getattr(database, prefix + 'hosts_usage'), 'servers': getattr(database, prefix + 'servers'), 'servers_output': getattr(database, prefix + 'servers_output'), 'servers_output_link': getattr(database, prefix + 'servers_output_link'), 'servers_bandwidth': getattr(database, prefix + 'servers_bandwidth'), 'servers_ip_pool': getattr(database, prefix + 'servers_ip_pool'), 'dh_params': getattr(database, prefix + 'dh_params'), 'auth_sessions': getattr(database, prefix + 'auth_sessions'), 'auth_nonces': getattr(database, prefix + 'auth_nonces'), 'auth_limiter': getattr(database, prefix + 'auth_limiter'), 'otp': getattr(database, prefix + 'otp'), 'otp_cache': getattr(database, prefix + 'otp_cache'), }) for collection_name, collection in mongo.collections.items(): collection.name_str = collection_name utils.sync_time() settings.init() if prefix + 'logs' not in cur_collections: log_limit = settings.app.log_limit database.create_collection(prefix + 'logs', capped=True, size=log_limit * 1024, max=log_limit) if prefix + 'log_entries' not in cur_collections: log_entry_limit = settings.app.log_entry_limit database.create_collection(prefix + 'log_entries', capped=True, size=log_entry_limit * 512, max=log_entry_limit) mongo.collections.update({ 'logs': getattr(database, prefix + 'logs'), 'log_entries': getattr(database, prefix + 'log_entries'), }) mongo.collections['logs'].name_str = 'logs' mongo.collections['log_entries'].name_str = 'log_entries' mongo.collections['logs'].ensure_index('timestamp') mongo.collections['transaction'].ensure_index('lock_id', unique=True) mongo.collections['transaction'].ensure_index([ ('ttl_timestamp', pymongo.ASCENDING), ('state', pymongo.ASCENDING), ('priority', pymongo.DESCENDING), ]) mongo.collections['queue'].ensure_index('runner_id') mongo.collections['queue'].ensure_index('ttl_timestamp') mongo.collections['task'].ensure_index('type', unique=True) mongo.collections['task'].ensure_index('ttl_timestamp') mongo.collections['log_entries'].ensure_index([ ('timestamp', pymongo.DESCENDING), ]) mongo.collections['messages'].ensure_index('channel') mongo.collections['administrators'].ensure_index('username', unique=True) mongo.collections['users'].ensure_index('resource_id') mongo.collections['users'].ensure_index([ ('type', pymongo.ASCENDING), ('org_id', pymongo.ASCENDING), ]) mongo.collections['users'].ensure_index([ ('org_id', pymongo.ASCENDING), ('name', pymongo.ASCENDING), ]) mongo.collections['users_key_link'].ensure_index('key_id') mongo.collections['users_key_link'].ensure_index('short_id', unique=True) mongo.collections['organizations'].ensure_index('type') mongo.collections['hosts'].ensure_index('name') mongo.collections['hosts_usage'].ensure_index([ ('host_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ]) mongo.collections['servers'].ensure_index('name') mongo.collections['servers'].ensure_index('ping_timestamp') mongo.collections['servers_output'].ensure_index([ ('server_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ]) mongo.collections['servers_output_link'].ensure_index([ ('server_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ]) mongo.collections['servers_bandwidth'].ensure_index([ ('server_id', pymongo.ASCENDING), ('period', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ]) mongo.collections['servers_ip_pool'].ensure_index([ ('server_id', pymongo.ASCENDING), ('user_id', pymongo.ASCENDING), ]) mongo.collections['servers_ip_pool'].ensure_index('user_id') mongo.collections['dh_params'].ensure_index('dh_param_bits') mongo.collections['auth_nonces'].ensure_index([ ('token', pymongo.ASCENDING), ('nonce', pymongo.ASCENDING), ], unique=True) # TODO check and remove current index when changed mongo.collections['users_key_link'].ensure_index('timestamp', expireAfterSeconds=settings.app.key_link_timeout) mongo.collections['auth_sessions'].ensure_index('timestamp', expireAfterSeconds=settings.app.session_timeout) mongo.collections['auth_nonces'].ensure_index('timestamp', expireAfterSeconds=settings.app.auth_time_window * 2.1) mongo.collections['auth_limiter'].ensure_index('timestamp', expireAfterSeconds=settings.app.auth_limiter_ttl) mongo.collections['otp'].ensure_index('timestamp', expireAfterSeconds=120) mongo.collections['otp_cache'].ensure_index('timestamp', expireAfterSeconds=settings.user.otp_cache_ttl) if not auth.Administrator.collection.find_one(): auth.Administrator( username=DEFAULT_USERNAME, password=DEFAULT_PASSWORD, default=True, ).commit() secret_key = settings.app.cookie_secret if not secret_key: secret_key = re.sub(r'[\W_]+', '', base64.b64encode(os.urandom(128)))[:64] settings.app.cookie_secret = secret_key settings.commit() app.app.secret_key = secret_key.encode() server_api_key = settings.app.server_api_key if not server_api_key: server_api_key = re.sub(r'[\W_]+', '', base64.b64encode(os.urandom(128)))[:64] settings.app.server_api_key = server_api_key settings.commit()
def settings_put(): if settings.app.demo_mode: return utils.demo_blocked() org_event = False admin_event = False admin = flask.g.administrator changes = set() settings_commit = False update_server = False update_acme = False update_cert = False if 'username' in flask.request.json and flask.request.json['username']: username = utils.filter_str(flask.request.json['username']).lower() if username != admin.username: changes.add('username') admin.username = username if 'password' in flask.request.json and flask.request.json['password']: password = flask.request.json['password'] changes.add('password') admin.password = password if 'server_cert' in flask.request.json: settings_commit = True server_cert = flask.request.json['server_cert'] if server_cert: server_cert = server_cert.strip() else: server_cert = None if server_cert != settings.app.server_cert: update_server = True settings.app.server_cert = server_cert if 'server_key' in flask.request.json: settings_commit = True server_key = flask.request.json['server_key'] if server_key: server_key = server_key.strip() else: server_key = None if server_key != settings.app.server_key: update_server = True settings.app.server_key = server_key if 'server_port' in flask.request.json: settings_commit = True server_port = flask.request.json['server_port'] if not server_port: server_port = 443 try: server_port = int(server_port) if server_port < 1 or server_port > 65535: raise ValueError('Port invalid') except ValueError: return utils.jsonify( { 'error': PORT_INVALID, 'error_msg': PORT_INVALID_MSG, }, 400) if settings.app.redirect_server and server_port == 80: return utils.jsonify( { 'error': PORT_RESERVED, 'error_msg': PORT_RESERVED_MSG, }, 400) if server_port != settings.app.server_port: update_server = True settings.app.server_port = server_port if 'acme_domain' in flask.request.json: settings_commit = True acme_domain = utils.filter_str(flask.request.json['acme_domain'] or None) if acme_domain: acme_domain = acme_domain.replace('https://', '') acme_domain = acme_domain.replace('http://', '') acme_domain = acme_domain.replace('/', '') if acme_domain != settings.app.acme_domain: if not acme_domain: settings.app.acme_key = None settings.app.acme_timestamp = None settings.app.server_key = None settings.app.server_cert = None update_server = True update_cert = True else: update_acme = True settings.app.acme_domain = acme_domain if 'auditing' in flask.request.json: settings_commit = True auditing = flask.request.json['auditing'] or None if settings.app.auditing != auditing: if not flask.g.administrator.super_user: return utils.jsonify( { 'error': REQUIRES_SUPER_USER, 'error_msg': REQUIRES_SUPER_USER_MSG, }, 400) admin_event = True org_event = True settings.app.auditing = auditing if 'monitoring' in flask.request.json: settings_commit = True monitoring = flask.request.json['monitoring'] or None settings.app.monitoring = monitoring if 'influxdb_uri' in flask.request.json: settings_commit = True influxdb_uri = flask.request.json['influxdb_uri'] or None settings.app.influxdb_uri = influxdb_uri if 'email_from' in flask.request.json: settings_commit = True email_from = flask.request.json['email_from'] or None if email_from != settings.app.email_from: changes.add('smtp') settings.app.email_from = email_from if 'email_server' in flask.request.json: settings_commit = True email_server = flask.request.json['email_server'] or None if email_server != settings.app.email_server: changes.add('smtp') settings.app.email_server = email_server if 'email_username' in flask.request.json: settings_commit = True email_username = flask.request.json['email_username'] or None if email_username != settings.app.email_username: changes.add('smtp') settings.app.email_username = email_username if 'email_password' in flask.request.json: settings_commit = True email_password = flask.request.json['email_password'] or None if email_password != settings.app.email_password: changes.add('smtp') settings.app.email_password = email_password if 'pin_mode' in flask.request.json: settings_commit = True pin_mode = flask.request.json['pin_mode'] or None if pin_mode != settings.user.pin_mode: changes.add('pin_mode') settings.user.pin_mode = pin_mode if 'sso' in flask.request.json: org_event = True settings_commit = True sso = flask.request.json['sso'] or None if sso != settings.app.sso: changes.add('sso') settings.app.sso = sso if 'sso_match' in flask.request.json: settings_commit = True sso_match = flask.request.json['sso_match'] or None if sso_match != settings.app.sso_match: changes.add('sso') if isinstance(sso_match, list): settings.app.sso_match = sso_match else: settings.app.sso_match = None if 'sso_duo_token' in flask.request.json: settings_commit = True sso_duo_token = flask.request.json['sso_duo_token'] or None if sso_duo_token != settings.app.sso_duo_token: changes.add('sso') settings.app.sso_duo_token = sso_duo_token if 'sso_duo_secret' in flask.request.json: settings_commit = True sso_duo_secret = flask.request.json['sso_duo_secret'] or None if sso_duo_secret != settings.app.sso_duo_secret: changes.add('sso') settings.app.sso_duo_secret = sso_duo_secret if 'sso_duo_host' in flask.request.json: settings_commit = True sso_duo_host = flask.request.json['sso_duo_host'] or None if sso_duo_host != settings.app.sso_duo_host: changes.add('sso') settings.app.sso_duo_host = sso_duo_host if 'sso_duo_mode' in flask.request.json: settings_commit = True sso_duo_mode = flask.request.json['sso_duo_mode'] or None if sso_duo_mode != settings.app.sso_duo_mode: changes.add('sso') settings.app.sso_duo_mode = sso_duo_mode if 'sso_radius_secret' in flask.request.json: settings_commit = True sso_radius_secret = flask.request.json['sso_radius_secret'] or None if sso_radius_secret != settings.app.sso_radius_secret: changes.add('sso') settings.app.sso_radius_secret = sso_radius_secret if 'sso_radius_host' in flask.request.json: settings_commit = True sso_radius_host = flask.request.json['sso_radius_host'] or None if sso_radius_host != settings.app.sso_radius_host: changes.add('sso') settings.app.sso_radius_host = sso_radius_host if 'sso_org' in flask.request.json: settings_commit = True sso_org = flask.request.json['sso_org'] or None if sso_org: sso_org = utils.ObjectId(sso_org) else: sso_org = None if sso_org != settings.app.sso_org: changes.add('sso') if settings.app.sso and not sso_org: return utils.jsonify( { 'error': SSO_ORG_NULL, 'error_msg': SSO_ORG_NULL_MSG, }, 400) settings.app.sso_org = sso_org if 'sso_saml_url' in flask.request.json: settings_commit = True sso_saml_url = flask.request.json['sso_saml_url'] or None if sso_saml_url != settings.app.sso_saml_url: changes.add('sso') settings.app.sso_saml_url = sso_saml_url if 'sso_saml_issuer_url' in flask.request.json: settings_commit = True sso_saml_issuer_url = flask.request.json['sso_saml_issuer_url'] or None if sso_saml_issuer_url != settings.app.sso_saml_issuer_url: changes.add('sso') settings.app.sso_saml_issuer_url = sso_saml_issuer_url if 'sso_saml_cert' in flask.request.json: settings_commit = True sso_saml_cert = flask.request.json['sso_saml_cert'] or None if sso_saml_cert != settings.app.sso_saml_cert: changes.add('sso') settings.app.sso_saml_cert = sso_saml_cert if 'sso_okta_token' in flask.request.json: settings_commit = True sso_okta_token = flask.request.json['sso_okta_token'] or None if sso_okta_token != settings.app.sso_okta_token: changes.add('sso') settings.app.sso_okta_token = sso_okta_token if 'sso_onelogin_id' in flask.request.json: settings_commit = True sso_onelogin_id = flask.request.json['sso_onelogin_id'] or None if sso_onelogin_id != settings.app.sso_onelogin_id: changes.add('sso') settings.app.sso_onelogin_id = sso_onelogin_id if 'sso_onelogin_secret' in flask.request.json: settings_commit = True sso_onelogin_secret = \ flask.request.json['sso_onelogin_secret'] or None if sso_onelogin_secret != settings.app.sso_onelogin_secret: changes.add('sso') settings.app.sso_onelogin_secret = sso_onelogin_secret if 'sso_client_cache' in flask.request.json: settings_commit = True sso_client_cache = True if \ flask.request.json['sso_client_cache'] else False if sso_client_cache != settings.app.sso_client_cache: changes.add('sso') settings.app.sso_client_cache = sso_client_cache if 'sso_yubico_client' in flask.request.json: settings_commit = True sso_yubico_client = \ flask.request.json['sso_yubico_client'] or None if sso_yubico_client != settings.app.sso_yubico_client: changes.add('sso') settings.app.sso_yubico_client = sso_yubico_client if 'sso_yubico_secret' in flask.request.json: settings_commit = True sso_yubico_secret = \ flask.request.json['sso_yubico_secret'] or None if sso_yubico_secret != settings.app.sso_yubico_secret: changes.add('sso') settings.app.sso_yubico_secret = sso_yubico_secret if flask.request.json.get('theme'): settings_commit = True theme = 'light' if flask.request.json['theme'] == 'light' else 'dark' if theme != settings.app.theme: if theme == 'dark': event.Event(type=THEME_DARK) else: event.Event(type=THEME_LIGHT) settings.app.theme = theme if 'public_address' in flask.request.json: public_address = flask.request.json['public_address'] or None if public_address != settings.local.host.public_addr: settings.local.host.public_address = public_address settings.local.host.commit('public_address') if 'public_address6' in flask.request.json: public_address6 = flask.request.json['public_address6'] or None if public_address6 != settings.local.host.public_addr6: settings.local.host.public_address6 = public_address6 settings.local.host.commit('public_address6') if 'routed_subnet6' in flask.request.json: routed_subnet6 = flask.request.json['routed_subnet6'] if routed_subnet6: try: routed_subnet6 = ipaddress.IPv6Network( flask.request.json['routed_subnet6']) except (ipaddress.AddressValueError, ValueError): return utils.jsonify( { 'error': IPV6_SUBNET_INVALID, 'error_msg': IPV6_SUBNET_INVALID_MSG, }, 400) if routed_subnet6.prefixlen > 64: return utils.jsonify( { 'error': IPV6_SUBNET_SIZE_INVALID, 'error_msg': IPV6_SUBNET_SIZE_INVALID_MSG, }, 400) routed_subnet6 = str(routed_subnet6) else: routed_subnet6 = None if settings.local.host.routed_subnet6 != routed_subnet6: if server.get_online_ipv6_count(): return utils.jsonify( { 'error': IPV6_SUBNET_ONLINE, 'error_msg': IPV6_SUBNET_ONLINE_MSG, }, 400) settings.local.host.routed_subnet6 = routed_subnet6 settings.local.host.commit('routed_subnet6') if 'reverse_proxy' in flask.request.json: settings_commit = True reverse_proxy = flask.request.json['reverse_proxy'] settings.app.reverse_proxy = True if reverse_proxy else False if 'cloud_provider' in flask.request.json: settings_commit = True cloud_provider = flask.request.json['cloud_provider'] or None settings.app.cloud_provider = cloud_provider if 'route53_region' in flask.request.json: settings_commit = True settings.app.route53_region = utils.filter_str( flask.request.json['route53_region']) or None if 'route53_zone' in flask.request.json: settings_commit = True settings.app.route53_zone = utils.filter_str( flask.request.json['route53_zone']) or None for aws_key in ( 'us_east_1_access_key', 'us_east_1_secret_key', 'us_east_2_access_key', 'us_east_2_secret_key', 'us_west_1_access_key', 'us_west_1_secret_key', 'us_west_2_access_key', 'us_west_2_secret_key', 'eu_west_1_access_key', 'eu_west_1_secret_key', 'eu_central_1_access_key', 'eu_central_1_secret_key', 'ap_northeast_1_access_key', 'ap_northeast_1_secret_key', 'ap_northeast_2_access_key', 'ap_northeast_2_secret_key', 'ap_southeast_1_access_key', 'ap_southeast_1_secret_key', 'ap_southeast_2_access_key', 'ap_southeast_2_secret_key', 'ap_south_1_access_key', 'ap_south_1_secret_key', 'sa_east_1_access_key', 'sa_east_1_secret_key', ): if aws_key in flask.request.json: settings_commit = True aws_value = flask.request.json[aws_key] if aws_value: setattr(settings.app, aws_key, utils.filter_str(aws_value)) else: setattr(settings.app, aws_key, None) if not settings.app.sso: settings.app.sso_host = None settings.app.sso_token = None settings.app.sso_secret = None settings.app.sso_match = None settings.app.sso_duo_token = None settings.app.sso_duo_secret = None settings.app.sso_duo_host = None settings.app.sso_yubico_client = None settings.app.sso_yubico_secret = None settings.app.sso_org = None settings.app.sso_saml_url = None settings.app.sso_saml_issuer_url = None settings.app.sso_saml_cert = None settings.app.sso_okta_token = None settings.app.sso_onelogin_key = None settings.app.sso_onelogin_id = None settings.app.sso_onelogin_secret = None settings.app.sso_radius_secret = None settings.app.sso_radius_host = None else: if RADIUS_AUTH in settings.app.sso and \ settings.app.sso_duo_mode == 'passcode': return utils.jsonify( { 'error': RADIUS_DUO_PASSCODE, 'error_msg': RADIUS_DUO_PASSCODE_MSG, }, 400) if settings.app.sso == DUO_AUTH and \ settings.app.sso_duo_mode == 'passcode': return utils.jsonify( { 'error': DUO_PASSCODE, 'error_msg': DUO_PASSCODE_MSG, }, 400) for change in changes: flask.g.administrator.audit_event( 'admin_settings', _changes_audit_text[change], remote_addr=utils.get_remote_addr(), ) if settings_commit: settings.commit() admin.commit(admin.changed) if admin_event: event.Event(type=ADMINS_UPDATED) if org_event: for org in organization.iter_orgs(fields=('_id')): event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SETTINGS_UPDATED) if update_acme: try: acme.update_acme_cert() app.update_server(0.5) except: logger.exception( 'Failed to get LetsEncrypt cert', 'handler', acme_domain=settings.app.acme_domain, ) settings.app.acme_domain = None settings.app.acme_key = None settings.app.acme_timestamp = None settings.commit() return utils.jsonify( { 'error': ACME_ERROR, 'error_msg': ACME_ERROR_MSG, }, 400) elif update_cert: logger.info('Regenerating server certificate...', 'handler') utils.create_server_cert() app.update_server(0.5) elif update_server: app.update_server(0.5) response = flask.g.administrator.dict() response.update(_dict()) return utils.jsonify(response)
def update_license(license): settings.app.license = license settings.commit() subscription_update
def update(): license = settings.app.license if not license: cur_sub_active = None cur_sub_plan = None settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_cancel_at_period_end = None else: cur_sub_active = settings.local.sub_active cur_sub_plan = settings.local.sub_plan try: response = utils.request.get(SUBSCRIPTION_SERVER, json_data={ 'license': license, 'version': settings.local.version_int, }, timeout=max(settings.app.http_request_timeout, 10)) # License key invalid if response.status_code == 470: settings.app.license = None settings.commit() subscription_update() return if response.status_code == 473: raise ValueError(('Version %r not recognized by ' + 'subscription server') % settings.local.version_int) data = response.json() settings.local.sub_active = data['active'] settings.local.sub_status = data['status'] settings.local.sub_plan = data['plan'] settings.local.sub_amount = data['amount'] settings.local.sub_period_end = data['period_end'] settings.local.sub_cancel_at_period_end = data[ 'cancel_at_period_end'] settings.local.sub_styles[data['plan']] = data['styles'] except: logger.exception('Failed to check subscription status', 'subscription') settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_cancel_at_period_end = None if cur_sub_active != settings.local.sub_active or \ cur_sub_plan != settings.local.sub_plan: if settings.local.sub_active: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_ACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_ACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE) else: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_INACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_INACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE)
def main(default_conf=None): if len(sys.argv) > 1: cmd = sys.argv[1] else: cmd = 'start' parser = optparse.OptionParser(usage=USAGE) if cmd == 'start': parser.add_option('-d', '--daemon', action='store_true', help='Daemonize process') parser.add_option('-p', '--pidfile', type='string', help='Path to create pid file') parser.add_option('-c', '--conf', type='string', help='Path to configuration file') parser.add_option('-q', '--quiet', action='store_true', help='Suppress logging output') elif cmd == 'logs': parser.add_option('--archive', action='store_true', help='Archive log file') parser.add_option('--tail', action='store_true', help='Tail log file') parser.add_option('--limit', type='int', help='Limit log lines') parser.add_option('--natural', action='store_true', help='Natural log sort') elif cmd == 'set': parser.disable_interspersed_args() (options, args) = parser.parse_args() if hasattr(options, 'conf') and options.conf: conf_path = options.conf else: conf_path = default_conf pritunl.set_conf_path(conf_path) if cmd == 'version': print('%s v%s' % (pritunl.__title__, pritunl.__version__)) sys.exit(0) elif cmd == 'setup-key': from pritunl import setup from pritunl import settings setup.setup_loc() print(settings.local.setup_key) sys.exit(0) elif cmd == 'reset-version': from pritunl.constants import MIN_DATABASE_VER from pritunl import setup from pritunl import utils setup.setup_db() utils.set_db_ver(pritunl.__version__, MIN_DATABASE_VER) time.sleep(.2) print('Database version reset to %s' % pritunl.__version__) sys.exit(0) elif cmd == 'reset-password': from pritunl import setup from pritunl import auth setup.setup_db() username, password = auth.reset_password() print('Administrator password successfully reset:\n' + \ ' username: "******"\n password: "******"' % (username, password)) sys.exit(0) elif cmd == 'default-password': from pritunl import setup from pritunl import auth setup.setup_db() username, password = auth.get_default_password() if not password: print('No default password available, use reset-password') else: print('Administrator default password:\n' + \ ' username: "******"\n password: "******"' % (username, password)) sys.exit(0) elif cmd == 'reconfigure': from pritunl import setup from pritunl import settings setup.setup_loc() settings.conf.mongodb_uri = None settings.conf.commit() time.sleep(.2) print('Database configuration successfully reset') sys.exit(0) elif cmd == 'get': from pritunl import setup from pritunl import settings setup.setup_db_host() if len(args) != 2: raise ValueError('Invalid arguments') split = args[1].split('.') key_str = None group_str = split[0] if len(split) > 1: key_str = split[1] if group_str == 'host': group = settings.local.host else: group = getattr(settings, group_str) if key_str: val = getattr(group, key_str) print('%s.%s = %s' % (group_str, key_str, json.dumps(val, default=lambda x: str(x)))) else: for field in group.fields: val = getattr(group, field) print('%s.%s = %s' % (group_str, field, json.dumps(val, default=lambda x: str(x)))) sys.exit(0) elif cmd == 'set': from pritunl.constants import HOSTS_UPDATED from pritunl import setup from pritunl import settings from pritunl import event from pritunl import messenger setup.setup_db_host() if len(args) != 3: raise ValueError('Invalid arguments') group_str, key_str = args[1].split('.') if group_str == 'host': group = settings.local.host else: group = getattr(settings, group_str) val_str = args[2] try: val = json.loads(val_str) except ValueError: val = json.loads(json.JSONEncoder().encode(val_str)) setattr(group, key_str, val) if group_str == 'host': settings.local.host.commit() event.Event(type=HOSTS_UPDATED) messenger.publish('hosts', 'updated') else: settings.commit() time.sleep(.2) print('%s.%s = %s' % (group_str, key_str, json.dumps(getattr(group, key_str), default=lambda x: str(x)))) print('Successfully updated configuration. This change is ' \ 'stored in the database and has been applied to all hosts ' \ 'in the cluster.') sys.exit(0) elif cmd == 'unset': from pritunl import setup from pritunl import settings setup.setup_db() if len(args) != 2: raise ValueError('Invalid arguments') group_str, key_str = args[1].split('.') group = getattr(settings, group_str) group.unset(key_str) settings.commit() time.sleep(.2) print('%s.%s = %s' % (group_str, key_str, json.dumps(getattr(group, key_str), default=lambda x: str(x)))) print('Successfully updated configuration. This change is ' \ 'stored in the database and has been applied to all hosts ' \ 'in the cluster.') sys.exit(0) elif cmd == 'set-mongodb': from pritunl import setup from pritunl import settings setup.setup_loc() if len(args) > 1: mongodb_uri = args[1] else: mongodb_uri = None settings.conf.mongodb_uri = mongodb_uri settings.conf.commit() time.sleep(.2) print('Database configuration successfully set') sys.exit(0) elif cmd == 'reset-ssl-cert': from pritunl import setup from pritunl import settings setup.setup_db() settings.app.server_cert = None settings.app.server_key = None settings.app.acme_timestamp = None settings.app.acme_key = None settings.app.acme_domain = None settings.commit() time.sleep(.2) print('Server ssl certificate successfully reset') sys.exit(0) elif cmd == 'destroy-secondary': from pritunl import setup from pritunl import logger from pritunl import mongo setup.setup_db() print('Destroying secondary database...') mongo.get_collection('clients').drop() mongo.get_collection('clients_pool').drop() mongo.get_collection('transaction').drop() mongo.get_collection('queue').drop() mongo.get_collection('tasks').drop() mongo.get_collection('messages').drop() mongo.get_collection('users_key_link').drop() mongo.get_collection('auth_sessions').drop() mongo.get_collection('auth_csrf_tokens').drop() mongo.get_collection('auth_limiter').drop() mongo.get_collection('otp').drop() mongo.get_collection('otp_cache').drop() mongo.get_collection('sso_tokens').drop() mongo.get_collection('sso_push_cache').drop() mongo.get_collection('sso_client_cache').drop() mongo.get_collection('sso_passcode_cache').drop() setup.upsert_indexes() server_coll = mongo.get_collection('servers') server_coll.update_many({}, { '$set': { 'status': 'offline', 'instances': [], 'instances_count': 0, }, '$unset': { 'network_lock': '', 'network_lock_ttl': '', }, }) print('Secondary database destroyed') sys.exit(0) elif cmd == 'repair-database': from pritunl import setup from pritunl import logger from pritunl import mongo setup.setup_db() print('Repairing database...') mongo.get_collection('clients').drop() mongo.get_collection('clients_pool').drop() mongo.get_collection('transaction').drop() mongo.get_collection('queue').drop() mongo.get_collection('tasks').drop() mongo.get_collection('messages').drop() mongo.get_collection('users_key_link').drop() mongo.get_collection('auth_sessions').drop() mongo.get_collection('auth_csrf_tokens').drop() mongo.get_collection('auth_limiter').drop() mongo.get_collection('otp').drop() mongo.get_collection('otp_cache').drop() mongo.get_collection('sso_tokens').drop() mongo.get_collection('sso_push_cache').drop() mongo.get_collection('sso_client_cache').drop() mongo.get_collection('sso_passcode_cache').drop() mongo.get_collection('logs').drop() mongo.get_collection('log_entries').drop() mongo.get_collection('servers_ip_pool').drop() setup.upsert_indexes() server_coll = mongo.get_collection('servers') server_coll.update_many({}, { '$set': { 'status': 'offline', 'instances': [], 'instances_count': 0, }, '$unset': { 'network_lock': '', 'network_lock_ttl': '', }, }) from pritunl import server for svr in server.iter_servers(): try: svr.ip_pool.sync_ip_pool() except: logger.exception( 'Failed to sync server IP pool', 'tasks', server_id=svr.id, ) server_coll.update_many({}, { '$set': { 'status': 'offline', 'instances': [], 'instances_count': 0, }, '$unset': { 'network_lock': '', 'network_lock_ttl': '', }, }) print('Database repair complete') sys.exit(0) elif cmd == 'logs': from pritunl import setup from pritunl import logger setup.setup_db() log_view = logger.LogView() if options.archive: if len(args) > 1: archive_path = args[1] else: archive_path = './' print('Log archived to: ' + log_view.archive_log( archive_path, options.natural, options.limit)) elif options.tail: for msg in log_view.tail_log_lines(): print(msg) else: print( log_view.get_log_lines( natural=options.natural, limit=options.limit, )) sys.exit(0) elif cmd == 'clear-auth-limit': from pritunl import setup from pritunl import logger from pritunl import mongo from pritunl import settings setup.setup_db() mongo.get_collection('auth_limiter').delete_many({}) print('Auth limiter cleared') sys.exit(0) elif cmd == 'clear-logs': from pritunl import setup from pritunl import logger from pritunl import mongo from pritunl import settings setup.setup_db() mongo.get_collection('logs').drop() mongo.get_collection('log_entries').drop() prefix = settings.conf.mongodb_collection_prefix or '' log_limit = settings.app.log_limit mongo.database.create_collection(prefix + 'logs', capped=True, size=log_limit * 1024, max=log_limit) log_entry_limit = settings.app.log_entry_limit mongo.database.create_collection(prefix + 'log_entries', capped=True, size=log_entry_limit * 512, max=log_entry_limit) print('Log entries cleared') sys.exit(0) elif cmd != 'start': raise ValueError('Invalid command') from pritunl import settings if options.quiet: settings.local.quiet = True if options.daemon: pid = os.fork() if pid > 0: if options.pidfile: with open(options.pidfile, 'w') as pid_file: pid_file.write('%s' % pid) sys.exit(0) elif not options.quiet: print('##############################################################') print('# #') print('# /$$ /$$ /$$ #') print('# |__/ | $$ | $$ #') print('# /$$$$$$ /$$$$$$ /$$ /$$$$$$ /$$ /$$ /$$$$$$$ | $$ #') print('# /$$__ $$ /$$__ $$| $$|_ $$_/ | $$ | $$| $$__ $$| $$ #') print('# | $$ \ $$| $$ \__/| $$ | $$ | $$ | $$| $$ \ $$| $$ #') print('# | $$ | $$| $$ | $$ | $$ /$$| $$ | $$| $$ | $$| $$ #') print('# | $$$$$$$/| $$ | $$ | $$$$/| $$$$$$/| $$ | $$| $$ #') print('# | $$____/ |__/ |__/ \____/ \______/ |__/ |__/|__/ #') print('# | $$ #') print('# | $$ #') print('# |__/ #') print('# #') print('##############################################################') pritunl.init_server()
def main(default_conf=None): if len(sys.argv) > 1: cmd = sys.argv[1] else: cmd = 'start' parser = optparse.OptionParser(usage=USAGE) if cmd == 'start': parser.add_option('-d', '--daemon', action='store_true', help='Daemonize process') parser.add_option('-p', '--pidfile', type='string', help='Path to create pid file') parser.add_option('-c', '--conf', type='string', help='Path to configuration file') parser.add_option('-q', '--quiet', action='store_true', help='Suppress logging output') parser.add_option('--dart-url', type='string', help='Dart pub serve url to redirect static requests') elif cmd == 'logs': parser.add_option('--archive', action='store_true', help='Archive log file') parser.add_option('--tail', action='store_true', help='Tail log file') parser.add_option('--limit', type='int', help='Limit log lines') (options, args) = parser.parse_args() if hasattr(options, 'conf') and options.conf: conf_path = options.conf else: conf_path = default_conf pritunl.set_conf_path(conf_path) if cmd == 'version': print '%s v%s' % (pritunl.__title__, pritunl.__version__) sys.exit(0) elif cmd == 'reset-password': from pritunl import setup from pritunl import auth setup.setup_db() username, password = auth.reset_password() time.sleep(.5) print 'Administrator password successfully reset:\n' + \ ' username: "******"\n password: "******"' % (username, password) sys.exit(0) elif cmd == 'reconfigure': from pritunl import setup from pritunl import settings setup.setup_loc() settings.conf.mongodb_uri = None settings.conf.commit() time.sleep(.5) print 'Database configuration successfully reset' sys.exit(0) elif cmd == 'set-mongodb': from pritunl import setup from pritunl import settings setup.setup_loc() if len(args) > 1: mongodb_uri = args[1] else: mongodb_uri = None settings.conf.mongodb_uri = mongodb_uri settings.conf.commit() time.sleep(.5) print 'Database configuration successfully set' sys.exit(0) elif cmd == 'reset-ssl-cert': from pritunl import setup from pritunl import settings setup.setup_db() settings.app.server_cert = None settings.app.server_key = None settings.commit() time.sleep(.5) print 'Server ssl certificate successfully reset' sys.exit(0) elif cmd == 'logs': from pritunl import setup from pritunl import logger setup.setup_db() log_view = logger.LogView() if options.archive: if len(args) > 1: archive_path = args[1] else: archive_path = './' print 'Log archived to: ' + log_view.archive_log(archive_path, options.limit) elif options.tail: for msg in log_view.tail_log_lines(): print msg else: print log_view.get_log_lines(options.limit) sys.exit(0) elif cmd != 'start': raise ValueError('Invalid command') from pritunl import settings settings.local.dart_url = options.dart_url if options.quiet: settings.local.quiet = True if options.daemon: pid = os.fork() if pid > 0: if options.pidfile: with open(options.pidfile, 'w') as pid_file: pid_file.write('%s' % pid) sys.exit(0) elif not options.quiet: print '##############################################################' print '# #' print '# /$$ /$$ /$$ #' print '# |__/ | $$ | $$ #' print '# /$$$$$$ /$$$$$$ /$$ /$$$$$$ /$$ /$$ /$$$$$$$ | $$ #' print '# /$$__ $$ /$$__ $$| $$|_ $$_/ | $$ | $$| $$__ $$| $$ #' print '# | $$ \ $$| $$ \__/| $$ | $$ | $$ | $$| $$ \ $$| $$ #' print '# | $$ | $$| $$ | $$ | $$ /$$| $$ | $$| $$ | $$| $$ #' print '# | $$$$$$$/| $$ | $$ | $$$$/| $$$$$$/| $$ | $$| $$ #' print '# | $$____/ |__/ |__/ \____/ \______/ |__/ |__/|__/ #' print '# | $$ #' print '# | $$ #' print '# |__/ #' print '# #' print '##############################################################' pritunl.init_server()
def setup_mongo(): prefix = settings.conf.mongodb_collection_prefix or '' last_error = time.time() - 24 while True: try: read_pref = _get_read_pref(settings.conf.mongodb_read_preference) if read_pref: client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, read_preference=read_pref ) else: client = pymongo.MongoClient( settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT, ) break except pymongo.errors.ConnectionFailure: time.sleep(0.5) if time.time() - last_error > 30: last_error = time.time() logger.exception('Error connecting to mongodb server') database = client.get_default_database() cur_collections = database.collection_names() if prefix + 'messages' not in cur_collections: database.create_collection(prefix + 'messages', capped=True, size=100000, max=1024) mongo.collections.update({ 'time_sync': getattr(database, prefix + 'time_sync'), 'transaction': getattr(database, prefix + 'transaction'), 'queue': getattr(database, prefix + 'queue'), 'task': getattr(database, prefix + 'task'), 'settings': getattr(database, prefix + 'settings'), 'messages': getattr(database, prefix + 'messages'), 'administrators': getattr(database, prefix + 'administrators'), 'users': getattr(database, prefix + 'users'), 'users_audit': getattr(database, prefix + 'users_audit'), 'users_key_link': getattr(database, prefix + 'users_key_link'), 'users_net_link': getattr(database, prefix + 'users_net_link'), 'clients': getattr(database, prefix + 'clients'), 'organizations': getattr(database, prefix + 'organizations'), 'hosts': getattr(database, prefix + 'hosts'), 'hosts_usage': getattr(database, prefix + 'hosts_usage'), 'servers': getattr(database, prefix + 'servers'), 'servers_output': getattr(database, prefix + 'servers_output'), 'servers_output_link': getattr(database, prefix + 'servers_output_link'), 'servers_bandwidth': getattr(database, prefix + 'servers_bandwidth'), 'servers_ip_pool': getattr(database, prefix + 'servers_ip_pool'), 'routes_reserve': getattr(database, prefix + 'routes_reserve'), 'dh_params': getattr(database, prefix + 'dh_params'), 'auth_sessions': getattr(database, prefix + 'auth_sessions'), 'auth_nonces': getattr(database, prefix + 'auth_nonces'), 'auth_limiter': getattr(database, prefix + 'auth_limiter'), 'otp': getattr(database, prefix + 'otp'), 'otp_cache': getattr(database, prefix + 'otp_cache'), 'sso_tokens': getattr(database, prefix + 'sso_tokens'), }) for collection_name, collection in mongo.collections.items(): collection.name_str = collection_name settings.local.mongo_time = None while True: try: utils.sync_time() break except: logger.exception('Failed to sync time', 'setup') time.sleep(30) settings.init() if prefix + 'logs' not in cur_collections: log_limit = settings.app.log_limit database.create_collection(prefix + 'logs', capped=True, size=log_limit * 1024, max=log_limit) if prefix + 'log_entries' not in cur_collections: log_entry_limit = settings.app.log_entry_limit database.create_collection(prefix + 'log_entries', capped=True, size=log_entry_limit * 512, max=log_entry_limit) mongo.collections.update({ 'logs': getattr(database, prefix + 'logs'), 'log_entries': getattr(database, prefix + 'log_entries'), }) mongo.collections['logs'].name_str = 'logs' mongo.collections['log_entries'].name_str = 'log_entries' upsert_index(mongo.collections['logs'], 'timestamp', background=True) upsert_index(mongo.collections['transaction'], 'lock_id', background=True, unique=True) upsert_index(mongo.collections['transaction'], [ ('ttl_timestamp', pymongo.ASCENDING), ('state', pymongo.ASCENDING), ('priority', pymongo.DESCENDING), ], background=True) upsert_index(mongo.collections['queue'], 'runner_id', background=True) upsert_index(mongo.collections['queue'], 'ttl_timestamp', background=True) upsert_index(mongo.collections['task'], 'type', background=True, unique=True) upsert_index(mongo.collections['task'], 'ttl_timestamp', background=True) upsert_index(mongo.collections['log_entries'], [ ('timestamp', pymongo.DESCENDING), ], background=True) upsert_index(mongo.collections['messages'], 'channel', background=True) upsert_index(mongo.collections['administrators'], 'username', background=True, unique=True) upsert_index(mongo.collections['users'], 'resource_id', background=True) upsert_index(mongo.collections['users'], [ ('type', pymongo.ASCENDING), ('org_id', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['users'], [ ('org_id', pymongo.ASCENDING), ('name', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['users_audit'], [ ('org_id', pymongo.ASCENDING), ('user_id', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['users_audit'], [ ('timestamp', pymongo.DESCENDING), ], background=True) upsert_index(mongo.collections['users_key_link'], 'key_id', background=True) upsert_index(mongo.collections['users_key_link'], 'short_id', background=True, unique=True) upsert_index(mongo.collections['users_net_link'], 'user_id', background=True) upsert_index(mongo.collections['users_net_link'], 'org_id', background=True) upsert_index(mongo.collections['users_net_link'], 'network', background=True) upsert_index(mongo.collections['clients'], 'user_id', background=True) upsert_index(mongo.collections['clients'], 'domain', background=True) upsert_index(mongo.collections['clients'], [ ('server_id', pymongo.ASCENDING), ('type', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['clients'], [ ('host_id', pymongo.ASCENDING), ('type', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['organizations'], 'type', background=True) upsert_index(mongo.collections['organizations'], 'auth_token', background=True) upsert_index(mongo.collections['hosts'], 'name', background=True) upsert_index(mongo.collections['hosts_usage'], [ ('host_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['servers'], 'name', background=True) upsert_index(mongo.collections['servers'], 'ping_timestamp', background=True) upsert_index(mongo.collections['servers_output'], [ ('server_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['servers_output_link'], [ ('server_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['servers_bandwidth'], [ ('server_id', pymongo.ASCENDING), ('period', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['servers_ip_pool'], [ ('server_id', pymongo.ASCENDING), ('user_id', pymongo.ASCENDING), ], background=True) upsert_index(mongo.collections['servers_ip_pool'], 'user_id', background=True) upsert_index(mongo.collections['routes_reserve'], 'timestamp', background=True) upsert_index(mongo.collections['dh_params'], 'dh_param_bits', background=True) upsert_index(mongo.collections['auth_nonces'], [ ('token', pymongo.ASCENDING), ('nonce', pymongo.ASCENDING), ], background=True, unique=True) upsert_index(mongo.collections['clients'], 'timestamp', background=True, expireAfterSeconds=settings.vpn.client_ttl) upsert_index(mongo.collections['users_key_link'], 'timestamp', background=True, expireAfterSeconds=settings.app.key_link_timeout) upsert_index(mongo.collections['auth_sessions'], 'timestamp', background=True, expireAfterSeconds=settings.app.session_timeout) upsert_index(mongo.collections['auth_nonces'], 'timestamp', background=True, expireAfterSeconds=settings.app.auth_time_window * 2.1) upsert_index(mongo.collections['auth_limiter'], 'timestamp', background=True, expireAfterSeconds=settings.app.auth_limiter_ttl) upsert_index(mongo.collections['otp'], 'timestamp', background=True, expireAfterSeconds=120) upsert_index(mongo.collections['otp_cache'], 'timestamp', background=True, expireAfterSeconds=settings.user.otp_cache_ttl) upsert_index(mongo.collections['sso_tokens'], 'timestamp', background=True, expireAfterSeconds=600) if not auth.Administrator.collection.find_one(): auth.Administrator( username=DEFAULT_USERNAME, password=DEFAULT_PASSWORD, default=True, ).commit() secret_key = settings.app.cookie_secret if not secret_key: secret_key = utils.rand_str(64) settings.app.cookie_secret = secret_key settings.commit() app.app.secret_key = secret_key.encode()
def setup_mongo(): prefix = settings.conf.mongodb_collection_prefix or '' last_error = time.time() - 24 while True: try: client = pymongo.MongoClient(settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT) break except pymongo.errors.ConnectionFailure: time.sleep(0.5) if time.time() - last_error > 30: last_error = time.time() logger.exception('Error connecting to mongodb server') database = client.get_default_database() cur_collections = database.collection_names() if prefix + 'messages' not in cur_collections: database.create_collection(prefix + 'messages', capped=True, size=100000, max=1024) mongo.collections.update({ 'time_sync': getattr(database, prefix + 'time_sync'), 'transaction': getattr(database, prefix + 'transaction'), 'queue': getattr(database, prefix + 'queue'), 'task': getattr(database, prefix + 'task'), 'settings': getattr(database, prefix + 'settings'), 'messages': getattr(database, prefix + 'messages'), 'administrators': getattr(database, prefix + 'administrators'), 'users': getattr(database, prefix + 'users'), 'users_key_link': getattr(database, prefix + 'users_key_link'), 'organizations': getattr(database, prefix + 'organizations'), 'hosts': getattr(database, prefix + 'hosts'), 'hosts_usage': getattr(database, prefix + 'hosts_usage'), 'servers': getattr(database, prefix + 'servers'), 'servers_output': getattr(database, prefix + 'servers_output'), 'servers_output_link': getattr(database, prefix + 'servers_output_link'), 'servers_bandwidth': getattr(database, prefix + 'servers_bandwidth'), 'servers_ip_pool': getattr(database, prefix + 'servers_ip_pool'), 'dh_params': getattr(database, prefix + 'dh_params'), 'auth_sessions': getattr(database, prefix + 'auth_sessions'), 'auth_nonces': getattr(database, prefix + 'auth_nonces'), 'auth_limiter': getattr(database, prefix + 'auth_limiter'), 'otp': getattr(database, prefix + 'otp'), 'otp_cache': getattr(database, prefix + 'otp_cache'), }) for collection_name, collection in mongo.collections.items(): collection.name_str = collection_name utils.sync_time() settings.init() if prefix + 'logs' not in cur_collections: log_limit = settings.app.log_limit database.create_collection(prefix + 'logs', capped=True, size=log_limit * 1024, max=log_limit) if prefix + 'log_entries' not in cur_collections: log_entry_limit = settings.app.log_entry_limit database.create_collection(prefix + 'log_entries', capped=True, size=log_entry_limit * 512, max=log_entry_limit) mongo.collections.update({ 'logs': getattr(database, prefix + 'logs'), 'log_entries': getattr(database, prefix + 'log_entries'), }) mongo.collections['logs'].name_str = 'logs' mongo.collections['log_entries'].name_str = 'log_entries' mongo.collections['logs'].ensure_index('timestamp', background=True) mongo.collections['transaction'].ensure_index('lock_id', background=True, unique=True) mongo.collections['transaction'].ensure_index([ ('ttl_timestamp', pymongo.ASCENDING), ('state', pymongo.ASCENDING), ('priority', pymongo.DESCENDING), ], background=True) mongo.collections['queue'].ensure_index('runner_id', background=True) mongo.collections['queue'].ensure_index('ttl_timestamp', background=True) mongo.collections['task'].ensure_index('type', background=True, unique=True) mongo.collections['task'].ensure_index('ttl_timestamp', background=True) mongo.collections['log_entries'].ensure_index([ ('timestamp', pymongo.DESCENDING), ], background=True) mongo.collections['messages'].ensure_index('channel', background=True) mongo.collections['administrators'].ensure_index('username', background=True, unique=True) mongo.collections['users'].ensure_index('resource_id', background=True) mongo.collections['users'].ensure_index([ ('type', pymongo.ASCENDING), ('org_id', pymongo.ASCENDING), ], background=True) mongo.collections['users'].ensure_index([ ('org_id', pymongo.ASCENDING), ('name', pymongo.ASCENDING), ], background=True) mongo.collections['users_key_link'].ensure_index('key_id', background=True) mongo.collections['users_key_link'].ensure_index('short_id', background=True, unique=True) mongo.collections['organizations'].ensure_index('type', background=True) mongo.collections['hosts'].ensure_index('name', background=True) mongo.collections['hosts_usage'].ensure_index([ ('host_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) mongo.collections['servers'].ensure_index('name', background=True) mongo.collections['servers'].ensure_index('ping_timestamp', background=True) mongo.collections['servers_output'].ensure_index([ ('server_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) mongo.collections['servers_output_link'].ensure_index([ ('server_id', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) mongo.collections['servers_bandwidth'].ensure_index([ ('server_id', pymongo.ASCENDING), ('period', pymongo.ASCENDING), ('timestamp', pymongo.ASCENDING), ], background=True) mongo.collections['servers_ip_pool'].ensure_index([ ('server_id', pymongo.ASCENDING), ('user_id', pymongo.ASCENDING), ], background=True) mongo.collections['servers_ip_pool'].ensure_index('user_id', background=True) mongo.collections['dh_params'].ensure_index('dh_param_bits', background=True) mongo.collections['auth_nonces'].ensure_index([ ('token', pymongo.ASCENDING), ('nonce', pymongo.ASCENDING), ], background=True, unique=True) mongo.collections['users_key_link'].ensure_index('timestamp', background=True, expireAfterSeconds=settings.app.key_link_timeout) mongo.collections['auth_sessions'].ensure_index('timestamp', background=True, expireAfterSeconds=settings.app.session_timeout) mongo.collections['auth_nonces'].ensure_index('timestamp', background=True, expireAfterSeconds=settings.app.auth_time_window * 2.1) mongo.collections['auth_limiter'].ensure_index('timestamp', background=True, expireAfterSeconds=settings.app.auth_limiter_ttl) mongo.collections['otp'].ensure_index('timestamp', background=True, expireAfterSeconds=120) mongo.collections['otp_cache'].ensure_index('timestamp', background=True, expireAfterSeconds=settings.user.otp_cache_ttl) if not auth.Administrator.collection.find_one(): auth.Administrator( username=DEFAULT_USERNAME, password=DEFAULT_PASSWORD, default=True, ).commit() secret_key = settings.app.cookie_secret if not secret_key: secret_key = re.sub(r'[\W_]+', '', base64.b64encode(os.urandom(128)))[:64] settings.app.cookie_secret = secret_key settings.commit() app.app.secret_key = secret_key.encode()
def setup_mongo(): prefix = settings.conf.mongodb_collection_prefix or "" last_error = time.time() - 24 while True: try: client = pymongo.MongoClient(settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT) break except pymongo.errors.ConnectionFailure: time.sleep(0.5) if time.time() - last_error > 30: last_error = time.time() logger.exception("Error connecting to mongodb server") database = client.get_default_database() cur_collections = database.collection_names() if prefix + "messages" not in cur_collections: database.create_collection(prefix + "messages", capped=True, size=100000, max=1024) mongo.collections.update( { "time_sync": getattr(database, prefix + "time_sync"), "transaction": getattr(database, prefix + "transaction"), "queue": getattr(database, prefix + "queue"), "task": getattr(database, prefix + "task"), "settings": getattr(database, prefix + "settings"), "messages": getattr(database, prefix + "messages"), "administrators": getattr(database, prefix + "administrators"), "users": getattr(database, prefix + "users"), "users_key_link": getattr(database, prefix + "users_key_link"), "clients": getattr(database, prefix + "clients"), "organizations": getattr(database, prefix + "organizations"), "hosts": getattr(database, prefix + "hosts"), "hosts_usage": getattr(database, prefix + "hosts_usage"), "servers": getattr(database, prefix + "servers"), "servers_output": getattr(database, prefix + "servers_output"), "servers_output_link": getattr(database, prefix + "servers_output_link"), "servers_bandwidth": getattr(database, prefix + "servers_bandwidth"), "servers_ip_pool": getattr(database, prefix + "servers_ip_pool"), "dh_params": getattr(database, prefix + "dh_params"), "auth_sessions": getattr(database, prefix + "auth_sessions"), "auth_nonces": getattr(database, prefix + "auth_nonces"), "auth_limiter": getattr(database, prefix + "auth_limiter"), "otp": getattr(database, prefix + "otp"), "otp_cache": getattr(database, prefix + "otp_cache"), "sso_tokens": getattr(database, prefix + "sso_tokens"), } ) for collection_name, collection in mongo.collections.items(): collection.name_str = collection_name utils.sync_time() settings.init() if prefix + "logs" not in cur_collections: log_limit = settings.app.log_limit database.create_collection(prefix + "logs", capped=True, size=log_limit * 1024, max=log_limit) if prefix + "log_entries" not in cur_collections: log_entry_limit = settings.app.log_entry_limit database.create_collection(prefix + "log_entries", capped=True, size=log_entry_limit * 512, max=log_entry_limit) mongo.collections.update( {"logs": getattr(database, prefix + "logs"), "log_entries": getattr(database, prefix + "log_entries")} ) mongo.collections["logs"].name_str = "logs" mongo.collections["log_entries"].name_str = "log_entries" mongo.collections["logs"].ensure_index("timestamp", background=True) mongo.collections["transaction"].ensure_index("lock_id", background=True, unique=True) mongo.collections["transaction"].ensure_index( [("ttl_timestamp", pymongo.ASCENDING), ("state", pymongo.ASCENDING), ("priority", pymongo.DESCENDING)], background=True, ) mongo.collections["queue"].ensure_index("runner_id", background=True) mongo.collections["queue"].ensure_index("ttl_timestamp", background=True) mongo.collections["task"].ensure_index("type", background=True, unique=True) mongo.collections["task"].ensure_index("ttl_timestamp", background=True) mongo.collections["log_entries"].ensure_index([("timestamp", pymongo.DESCENDING)], background=True) mongo.collections["messages"].ensure_index("channel", background=True) mongo.collections["administrators"].ensure_index("username", background=True, unique=True) mongo.collections["users"].ensure_index("resource_id", background=True) mongo.collections["users"].ensure_index( [("type", pymongo.ASCENDING), ("org_id", pymongo.ASCENDING)], background=True ) mongo.collections["users"].ensure_index( [("org_id", pymongo.ASCENDING), ("name", pymongo.ASCENDING)], background=True ) mongo.collections["users_key_link"].ensure_index("key_id", background=True) mongo.collections["users_key_link"].ensure_index("short_id", background=True, unique=True) mongo.collections["clients"].ensure_index("user_id", background=True) mongo.collections["clients"].ensure_index("domain", background=True) mongo.collections["clients"].ensure_index( [("server_id", pymongo.ASCENDING), ("type", pymongo.ASCENDING)], background=True ) mongo.collections["organizations"].ensure_index("type", background=True) mongo.collections["hosts"].ensure_index("name", background=True) mongo.collections["hosts_usage"].ensure_index( [("host_id", pymongo.ASCENDING), ("timestamp", pymongo.ASCENDING)], background=True ) mongo.collections["servers"].ensure_index("name", background=True) mongo.collections["servers"].ensure_index("ping_timestamp", background=True) mongo.collections["servers_output"].ensure_index( [("server_id", pymongo.ASCENDING), ("timestamp", pymongo.ASCENDING)], background=True ) mongo.collections["servers_output_link"].ensure_index( [("server_id", pymongo.ASCENDING), ("timestamp", pymongo.ASCENDING)], background=True ) mongo.collections["servers_bandwidth"].ensure_index( [("server_id", pymongo.ASCENDING), ("period", pymongo.ASCENDING), ("timestamp", pymongo.ASCENDING)], background=True, ) mongo.collections["servers_ip_pool"].ensure_index( [("server_id", pymongo.ASCENDING), ("user_id", pymongo.ASCENDING)], background=True ) mongo.collections["servers_ip_pool"].ensure_index("user_id", background=True) mongo.collections["dh_params"].ensure_index("dh_param_bits", background=True) mongo.collections["auth_nonces"].ensure_index( [("token", pymongo.ASCENDING), ("nonce", pymongo.ASCENDING)], background=True, unique=True ) mongo.collections["clients"].ensure_index("timestamp", background=True, expireAfterSeconds=settings.vpn.client_ttl) mongo.collections["users_key_link"].ensure_index( "timestamp", background=True, expireAfterSeconds=settings.app.key_link_timeout ) mongo.collections["auth_sessions"].ensure_index( "timestamp", background=True, expireAfterSeconds=settings.app.session_timeout ) mongo.collections["auth_nonces"].ensure_index( "timestamp", background=True, expireAfterSeconds=settings.app.auth_time_window * 2.1 ) mongo.collections["auth_limiter"].ensure_index( "timestamp", background=True, expireAfterSeconds=settings.app.auth_limiter_ttl ) mongo.collections["otp"].ensure_index("timestamp", background=True, expireAfterSeconds=120) mongo.collections["otp_cache"].ensure_index( "timestamp", background=True, expireAfterSeconds=settings.user.otp_cache_ttl ) mongo.collections["sso_tokens"].ensure_index("timestamp", background=True, expireAfterSeconds=600) if not auth.Administrator.collection.find_one(): auth.Administrator(username=DEFAULT_USERNAME, password=DEFAULT_PASSWORD, default=True).commit() secret_key = settings.app.cookie_secret if not secret_key: secret_key = utils.rand_str(64) settings.app.cookie_secret = secret_key settings.commit() app.app.secret_key = secret_key.encode()
def main(default_conf=None): if len(sys.argv) > 1: cmd = sys.argv[1] else: cmd = 'start' parser = optparse.OptionParser(usage=USAGE) if cmd == 'start': parser.add_option('-d', '--daemon', action='store_true', help='Daemonize process') parser.add_option('-p', '--pidfile', type='string', help='Path to create pid file') parser.add_option('-c', '--conf', type='string', help='Path to configuration file') parser.add_option('-q', '--quiet', action='store_true', help='Suppress logging output') parser.add_option('--dart-url', type='string', help='Dart pub serve url to redirect static requests') elif cmd == 'logs': parser.add_option('--archive', action='store_true', help='Archive log file') parser.add_option('--tail', action='store_true', help='Tail log file') parser.add_option('--limit', type='int', help='Limit log lines') (options, args) = parser.parse_args() if hasattr(options, 'conf') and options.conf: conf_path = options.conf else: conf_path = default_conf pritunl.set_conf_path(conf_path) if cmd == 'version': print '%s v%s' % (pritunl.__title__, pritunl.__version__) sys.exit(0) elif cmd == 'reset-version': from pritunl import setup from pritunl import utils setup.setup_db() utils.set_db_ver(pritunl.__version__) time.sleep(.5) print 'Database version reset to %s' % pritunl.__version__ sys.exit(0) elif cmd == 'reset-password': from pritunl import setup from pritunl import auth setup.setup_db() username, password = auth.reset_password() time.sleep(.5) print 'Administrator password successfully reset:\n' + \ ' username: "******"\n password: "******"' % (username, password) sys.exit(0) elif cmd == 'reconfigure': from pritunl import setup from pritunl import settings setup.setup_loc() settings.conf.mongodb_uri = None settings.conf.commit() time.sleep(.5) print 'Database configuration successfully reset' sys.exit(0) elif cmd == 'get': from pritunl import setup from pritunl import settings setup.setup_db() if len(args) != 2: raise ValueError('Invalid arguments') split = args[1].split('.') key_str = None group_str = split[0] if len(split) > 1: key_str = split[1] group = getattr(settings, group_str) if key_str: val = getattr(group, key_str) print '%s.%s = %s' % (group_str, key_str, json.dumps(val)) else: for field in group.fields: val = getattr(group, field) print '%s.%s = %s' % (group_str, field, json.dumps(val)) sys.exit(0) elif cmd == 'set': from pritunl import setup from pritunl import settings setup.setup_db() if len(args) != 3: raise ValueError('Invalid arguments') group_str, key_str = args[1].split('.') group = getattr(settings, group_str) val_str = args[2] val = json.loads(val_str) setattr(group, key_str, val) settings.commit() time.sleep(.5) print '%s.%s = %s' % (group_str, key_str, json.dumps(getattr(group, key_str))) sys.exit(0) elif cmd == 'unset': from pritunl import setup from pritunl import settings setup.setup_db() if len(args) != 2: raise ValueError('Invalid arguments') group_str, key_str = args[1].split('.') group = getattr(settings, group_str) group.unset(key_str) settings.commit() time.sleep(.5) print '%s.%s = %s' % (group_str, key_str, json.dumps(getattr(group, key_str))) sys.exit(0) elif cmd == 'set-mongodb': from pritunl import setup from pritunl import settings setup.setup_loc() if len(args) > 1: mongodb_uri = args[1] else: mongodb_uri = None settings.conf.mongodb_uri = mongodb_uri settings.conf.commit() time.sleep(.5) print 'Database configuration successfully set' sys.exit(0) elif cmd == 'reset-ssl-cert': from pritunl import setup from pritunl import settings setup.setup_db() settings.app.server_cert = None settings.app.server_key = None settings.commit() time.sleep(.5) print 'Server ssl certificate successfully reset' sys.exit(0) elif cmd == 'logs': from pritunl import setup from pritunl import logger setup.setup_db() log_view = logger.LogView() if options.archive: if len(args) > 1: archive_path = args[1] else: archive_path = './' print 'Log archived to: ' + log_view.archive_log(archive_path, options.limit) elif options.tail: for msg in log_view.tail_log_lines(): print msg else: print log_view.get_log_lines(options.limit) sys.exit(0) elif cmd != 'start': raise ValueError('Invalid command') from pritunl import settings settings.local.dart_url = options.dart_url if options.quiet: settings.local.quiet = True if options.daemon: pid = os.fork() if pid > 0: if options.pidfile: with open(options.pidfile, 'w') as pid_file: pid_file.write('%s' % pid) sys.exit(0) elif not options.quiet: print '##############################################################' print '# #' print '# /$$ /$$ /$$ #' print '# |__/ | $$ | $$ #' print '# /$$$$$$ /$$$$$$ /$$ /$$$$$$ /$$ /$$ /$$$$$$$ | $$ #' print '# /$$__ $$ /$$__ $$| $$|_ $$_/ | $$ | $$| $$__ $$| $$ #' print '# | $$ \ $$| $$ \__/| $$ | $$ | $$ | $$| $$ \ $$| $$ #' print '# | $$ | $$| $$ | $$ | $$ /$$| $$ | $$| $$ | $$| $$ #' print '# | $$$$$$$/| $$ | $$ | $$$$/| $$$$$$/| $$ | $$| $$ #' print '# | $$____/ |__/ |__/ \____/ \______/ |__/ |__/|__/ #' print '# | $$ #' print '# | $$ #' print '# |__/ #' print '# #' print '##############################################################' pritunl.init_server()
def update(): license = settings.app.license collection = mongo.get_collection('settings') if not settings.app.id: settings.app.id = utils.random_name() settings.commit() if not license: settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_quantity = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_trial_end = None settings.local.sub_cancel_at_period_end = None settings.local.sub_balance = None settings.local.sub_url_key = None else: for i in range(2): try: url = x(b'aHR0cHM6Ly9hcHAucHJpdHVubC5jb20vc3Vic2NyaXB0aW9u') response = requests.get( url, json={ x(b'aWQ='): settings.app.id, x(b'bGljZW5zZQ=='): license, x(b'dmVyc2lvbg=='): settings.local.version_int, }, timeout=max(settings.app.http_request_timeout, 10), ) # License key invalid if response.status_code == 470: raise ValueError('License key is invalid') if response.status_code == 473: raise ValueError(('Version %r not recognized by ' + 'subscription server') % settings.local.version_int) data = response.json() settings.local.sub_active = data[x(b'YWN0aXZl')] settings.local.sub_status = data[x(b'c3RhdHVz')] settings.local.sub_plan = data[x(b'cGxhbg==')] settings.local.sub_quantity = data[x(b'cXVhbnRpdHk=')] settings.local.sub_amount = data[x(b'YW1vdW50')] settings.local.sub_period_end = data[x(b'cGVyaW9kX2VuZA==')] settings.local.sub_trial_end = data[x(b'dHJpYWxfZW5k')] settings.local.sub_cancel_at_period_end = \ data[x(b'Y2FuY2VsX2F0X3BlcmlvZF9lbmQ=')] settings.local.sub_balance = data.get(x(b'YmFsYW5jZQ==')) settings.local.sub_url_key = data.get(x(b'dXJsX2tleQ==')) settings.local.sub_styles[data[x(b'cGxhbg==')]] = \ data[x(b'c3R5bGVz')] except: if i < 1: logger.exception('Failed to check subscription status', 'subscription, retrying...') time.sleep(1) continue logger.exception('Failed to check subscription status', 'subscription') settings.local.sub_active = False settings.local.sub_status = None settings.local.sub_plan = None settings.local.sub_quantity = None settings.local.sub_amount = None settings.local.sub_period_end = None settings.local.sub_trial_end = None settings.local.sub_cancel_at_period_end = None settings.local.sub_balance = None settings.local.sub_url_key = None break if settings.app.license_plan != settings.local.sub_plan and \ settings.local.sub_plan: settings.app.license_plan = settings.local.sub_plan settings.commit() response = collection.update({ '_id': 'subscription', '$or': [ {'active': {'$ne': settings.local.sub_active}}, {'plan': {'$ne': settings.local.sub_plan}}, ], }, {'$set': { 'active': settings.local.sub_active, 'plan': settings.local.sub_plan, }}) if response['updatedExisting']: if settings.local.sub_active: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_ACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_ACTIVE) elif settings.local.sub_plan == 'enterprise_plus': event.Event(type=SUBSCRIPTION_ENTERPRISE_PLUS_ACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE) else: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_INACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_INACTIVE) elif settings.local.sub_plan == 'enterprise_plus': event.Event(type=SUBSCRIPTION_ENTERPRISE_PLUS_INACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE) return True
def update(): license = settings.app.license collection = mongo.get_collection('settings') if not settings.app.id: settings.app.id = utils.random_name() settings.commit() settings.local.sub_active = True settings.local.sub_status = 'active' settings.local.sub_plan = 'enterprise' settings.local.sub_quantity = 1 settings.local.sub_amount = 2500 settings.local.sub_period_end = math.floor(time.time()) + 2592000000 settings.local.sub_trial_end = math.floor(time.time()) + 2592000000 settings.local.sub_cancel_at_period_end = False settings.local.sub_balance = 0 settings.local.sub_url_key = "url" settings.local.sub_styles['enterprise'] = { 'etag': '1c253d-6c2-4e3a2f30b418d', 'last_modified': 'Wed, 23 Oct 2019 07:52:54 GMT', 'data': 'dark' } # if not license: # settings.local.sub_active = False # settings.local.sub_status = None # settings.local.sub_plan = None # settings.local.sub_quantity = None # settings.local.sub_amount = None # settings.local.sub_period_end = None # settings.local.sub_trial_end = None # settings.local.sub_cancel_at_period_end = None # settings.local.sub_balance = None # settings.local.sub_url_key = None # else: # for i in xrange(2): # try: # # url = 'https://app.pritunl.com/subscription' # # if settings.app.dedicated: # # url = settings.app.dedicated + '/subscription' # # response = requests.get( # # url, # # json={ # # 'id': settings.app.id, # # 'license': license, # # 'version': settings.local.version_int, # # }, # # timeout=max(settings.app.http_request_timeout, 10), # # ) # # # License key invalid # # if response.status_code == 470: # # raise ValueError('License key is invalid') # # if response.status_code == 473: # # raise ValueError(('Version %r not recognized by ' + # # 'subscription server') % settings.local.version_int) # # data = response.json() # # settings.local.sub_styles['enterprise'] = 'dark' # except: # if i < 1: # logger.exception('Failed to check subscription status', # 'subscription, retrying...') # time.sleep(1) # continue # logger.exception('Failed to check subscription status', # 'subscription') # settings.local.sub_active = True # settings.local.sub_status = 'active' # settings.local.sub_plan = 'enterprise' # settings.local.sub_quantity = 1 # settings.local.sub_amount = 250 # settings.local.sub_period_end = math.floor(time.time()/1000) + 2592000 # settings.local.sub_trial_end = math.floor(time.time()/1000) + 2592000 # settings.local.sub_cancel_at_period_end = False # settings.local.sub_balance = 0 # settings.local.sub_url_key = True # # settings.local.sub_styles['enterprise'] = 'dark' # break if settings.app.license_plan != settings.local.sub_plan and \ settings.local.sub_plan: settings.app.license_plan = settings.local.sub_plan settings.commit() response = collection.update( { '_id': 'subscription', '$or': [ { 'active': { '$ne': settings.local.sub_active } }, { 'plan': { '$ne': settings.local.sub_plan } }, ], }, { '$set': { 'active': settings.local.sub_active, 'plan': settings.local.sub_plan, } }) if response['updatedExisting']: if settings.local.sub_active: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_ACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_ACTIVE) elif settings.local.sub_plan == 'enterprise_plus': event.Event(type=SUBSCRIPTION_ENTERPRISE_PLUS_ACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE) else: if settings.local.sub_plan == 'premium': event.Event(type=SUBSCRIPTION_PREMIUM_INACTIVE) elif settings.local.sub_plan == 'enterprise': event.Event(type=SUBSCRIPTION_ENTERPRISE_INACTIVE) elif settings.local.sub_plan == 'enterprise_plus': event.Event(type=SUBSCRIPTION_ENTERPRISE_PLUS_INACTIVE) else: event.Event(type=SUBSCRIPTION_NONE_INACTIVE) return True
def settings_put(): admin = flask.g.administrator if 'username' in flask.request.json and flask.request.json['username']: admin.username = utils.filter_str( flask.request.json['username']).lower() if 'password' in flask.request.json and flask.request.json['password']: admin.password = flask.request.json['password'] if 'token' in flask.request.json and flask.request.json['token']: admin.generate_token() if 'secret' in flask.request.json and flask.request.json['secret']: admin.generate_secret() settings_commit = False if 'email_from' in flask.request.json: settings_commit = True email_from = flask.request.json['email_from'] settings.app.email_from = email_from or None if 'email_server' in flask.request.json: settings_commit = True email_server = flask.request.json['email_server'] settings.app.email_server = email_server or None if 'email_username' in flask.request.json: settings_commit = True email_username = flask.request.json['email_username'] settings.app.email_username = email_username or None if 'email_password' in flask.request.json: settings_commit = True email_password = flask.request.json['email_password'] settings.app.email_password = email_password or None if 'sso' in flask.request.json: settings_commit = True sso = flask.request.json['sso'] settings.app.sso = sso or None if 'sso_match' in flask.request.json: sso_match = flask.request.json['sso_match'] if isinstance(sso_match, list): settings_commit = True settings.app.sso_match = sso_match or None if 'sso_org' in flask.request.json: settings_commit = True sso_org = flask.request.json['sso_org'] if sso_org: settings.app.sso_org = utils.ObjectId(sso_org) else: settings.app.sso_org = None if 'theme' in flask.request.json: settings_commit = True theme = 'dark' if flask.request.json['theme'] == 'dark' else 'light' if theme != settings.app.theme: if theme == 'dark': event.Event(type=THEME_DARK) else: event.Event(type=THEME_LIGHT) settings.app.theme = theme if 'public_address' in flask.request.json: public_address = flask.request.json['public_address'] settings.local.host.public_address = public_address settings.local.host.commit('public_address') if 'server_cert' in flask.request.json: settings_commit = True server_cert = flask.request.json['server_cert'] if server_cert: settings.app.server_cert = server_cert.strip() else: settings.app.server_cert = None if 'server_key' in flask.request.json: settings_commit = True server_key = flask.request.json['server_key'] if server_key: settings.app.server_key = server_key.strip() else: settings.app.server_key = None if settings_commit: settings.commit() admin.commit(admin.changed) response = flask.g.administrator.dict() response.update({ 'theme': settings.app.theme, 'email_from': settings.app.email_from, 'email_server': settings.app.email_server, 'email_username': settings.app.email_username, 'email_password': bool(settings.app.email_password), 'sso': bool(settings.app.sso), 'sso_match': settings.app.sso_match, 'sso_org': settings.app.sso_org, 'public_address': settings.local.host.public_addr, }) return utils.jsonify(response)