Esempio n. 1
0
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()
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
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()
Esempio n. 5
0
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')
Esempio n. 6
0
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')
Esempio n. 7
0
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()
Esempio n. 8
0
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()
Esempio n. 9
0
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()
Esempio n. 10
0
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()
Esempio n. 11
0
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
Esempio n. 12
0
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
Esempio n. 13
0
File: acme.py Progetto: ijat/pritunl
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()
Esempio n. 14
0
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()
Esempio n. 15
0
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)
Esempio n. 16
0
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)
Esempio n. 17
0
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)
Esempio n. 18
0
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)
Esempio n. 19
0
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()
Esempio n. 20
0
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()
Esempio n. 21
0
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()
Esempio n. 22
0
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()
Esempio n. 23
0
def update_license(license):
    settings.app.license = license
    settings.commit()
    update()
Esempio n. 24
0
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()
Esempio n. 25
0
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()
Esempio n. 26
0
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
Esempio n. 27
0
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)
Esempio n. 28
0
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()
Esempio n. 29
0
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()
Esempio n. 30
0
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)
Esempio n. 31
0
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)
Esempio n. 32
0
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)
Esempio n. 33
0
def update_license(license):
    settings.app.license = license
    settings.app.license_plan = None
    settings.commit()
    update()
    messenger.publish('subscription', 'updated')
Esempio n. 34
0
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)
Esempio n. 35
0
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)
Esempio n. 36
0
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)
Esempio n. 37
0
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
Esempio n. 38
0
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)
Esempio n. 39
0
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)
Esempio n. 40
0
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)
Esempio n. 41
0
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()
Esempio n. 42
0
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)
Esempio n. 43
0
def update_license(license):
    settings.app.license = license
    settings.commit()
    subscription_update
Esempio n. 44
0
def update_license(license):
    settings.app.license = license
    settings.commit()
    update()
Esempio n. 45
0
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)
Esempio n. 46
0
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()
Esempio n. 47
0
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()
Esempio n. 48
0
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()
Esempio n. 49
0
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()
Esempio n. 50
0
def update_license(license):
    settings.app.license = license
    settings.app.license_plan = None
    settings.commit()
    update()
    messenger.publish('subscription', 'updated')
Esempio n. 51
0
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()
Esempio n. 52
0
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()
Esempio n. 53
0
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
Esempio n. 54
0
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
Esempio n. 55
0
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)