Exemple #1
0
def db_admin_serialize_node(session, tid, language, config_node='admin_node'):
    config = ConfigFactory(session, tid).serialize(config_node)

    # Contexts and Receivers relationship
    configured = session.query(models.ReceiverContext).filter(
        models.ReceiverContext.context_id == models.Context.id,
        models.Context.tid).count() > 0

    misc_dict = {
        'encryption_available': GCE.ENCRYPTION_AVAILABLE,
        'languages_supported': LANGUAGES_SUPPORTED,
        'languages_enabled': models.EnabledLanguage.list(session, tid),
        'configured': configured,
        'root_tenant': tid == 1,
        'https_possible': tid == 1 or State.tenant_cache[1].reachable_via_web,
    }

    if tid != 1:
        root_tenant_node = ConfigFactory(session, 1)
        misc_dict['version'] = root_tenant_node.get_val(u'version')
        misc_dict['latest_version'] = root_tenant_node.get_val(
            u'latest_version')

    l10n_dict = ConfigL10NFactory(session, tid).serialize('node', language)

    return utils.sets.merge_dicts(config, misc_dict, l10n_dict)
Exemple #2
0
def db_acme_cert_issuance(session, tid):
    priv_fact = ConfigFactory(session, tid, 'node')
    hostname = State.tenant_cache[tid].hostname

    raw_accnt_key = priv_fact.get_val(u'acme_accnt_key')
    accnt_key = serialization.load_pem_private_key(str(raw_accnt_key),
                                                   password=None,
                                                   backend=default_backend())

    priv_key = priv_fact.get_val(u'https_priv_key')
    regr_uri = priv_fact.get_val(u'acme_accnt_uri')

    csr_fields = {'CN': hostname}
    # NOTE sha256 is always employed as hash fnc here.
    csr = tls.gen_x509_csr(priv_key, csr_fields, 256)

    tmp_chall_dict = State.tenant_state[tid].acme_tmp_chall_dict

    # Run ACME registration all the way to resolution
    cert_str, chain_str = letsencrypt.run_acme_reg_to_finish(
        hostname, regr_uri, accnt_key, priv_key, csr, tmp_chall_dict,
        Settings.acme_directory_url)

    priv_fact.set_val(u'https_cert', cert_str)
    priv_fact.set_val(u'https_chain', chain_str)
    State.tenant_cache[tid].https_cert = cert_str
    State.tenant_cache[tid].https_chain = chain_str
def db_admin_serialize_node(session, tid, language):
    config = ConfigFactory(session, tid, 'admin_node').serialize()

    # Contexts and Receivers relationship
    configured = session.query(models.ReceiverContext).filter(
        models.ReceiverContext.context_id == models.Context.id,
        models.Context.tid).count() > 0

    misc_dict = {
        'languages_supported': LANGUAGES_SUPPORTED,
        'languages_enabled': models.EnabledLanguage.list(session, tid),
        'configured': configured,
        'root_tenant': tid == 1,
        'https_possible': tid == 1 or State.tenant_cache[1].reachable_via_web,
    }

    if tid != 1:
        root_tenant_node = ConfigFactory(session, 1, 'node')
        misc_dict['version'] = root_tenant_node.get_val(u'version')
        misc_dict['latest_version'] = root_tenant_node.get_val(
            u'latest_version')
        misc_dict['enable_footer_customization'] = root_tenant_node.get_val(
            u'enable_footer_customization')

    l10n_dict = NodeL10NFactory(session, tid).localized_dict(language)

    return utils.sets.merge_dicts(config, misc_dict, l10n_dict)
Exemple #4
0
def db_admin_serialize_node(session, tid, language, config_node='admin_node'):
    """
    Transaction for fetching the node configuration as admin

    :param session: An ORM session
    :param tid: A tenant ID
    :param language: The language to be used on serialization
    :param config_node: The set of variables to be serialized
    :return: Return the serialized configuration for the specified tenant
    """
    config = ConfigFactory(session, tid).serialize(config_node)

    logo = session.query(models.File.data).filter(models.File.tid == tid, models.File.id == 'logo').one_or_none()

    misc_dict = {
        'languages_supported': LANGUAGES_SUPPORTED,
        'languages_enabled': db_get_languages(session, tid),
        'root_tenant': tid == 1,
        'https_possible': tid == 1 or State.tenant_cache[1].reachable_via_web,
        'encryption_possible': tid == 1 or State.tenant_cache[1].encryption,
        'logo': logo if logo else ''
    }

    if tid != 1:
        root_tenant_node = ConfigFactory(session, 1)
        misc_dict['version'] = root_tenant_node.get_val('version')
        misc_dict['latest_version'] = root_tenant_node.get_val('latest_version')

    l10n_dict = ConfigL10NFactory(session, tid).serialize('node', language)

    return utils.sets.merge_dicts(config, misc_dict, l10n_dict)
Exemple #5
0
def db_admin_serialize_node(session, tid, language, config_node='admin_node'):
    """
    Transaction for fetching the node configuration as admin

    :param session: An ORM session
    :param tid: A tenant ID
    :param language: The language to be used on serialization
    :param config_node: The set of variables to be serialized
    :return: Return the serialized configuration for the specified tenant
    """
    config = ConfigFactory(session, tid).serialize(config_node)

    misc_dict = {
        'languages_supported': LANGUAGES_SUPPORTED,
        'languages_enabled': models.EnabledLanguage.list(session, tid),
        'root_tenant': tid == 1,
        'https_possible': tid == 1 or State.tenant_cache[1].reachable_via_web,
    }

    if tid != 1:
        root_tenant_node = ConfigFactory(session, 1)
        misc_dict['version'] = root_tenant_node.get_val('version')
        misc_dict['latest_version'] = root_tenant_node.get_val(
            'latest_version')

    l10n_dict = ConfigL10NFactory(session, tid).serialize('node', language)

    return utils.sets.merge_dicts(config, misc_dict, l10n_dict)
Exemple #6
0
def db_acme_cert_request(session, tid):
    priv_fact = ConfigFactory(session, tid)
    hostname = State.tenant_cache[tid].hostname

    raw_accnt_key = priv_fact.get_val('acme_accnt_key')
    if not raw_accnt_key:
        raw_accnt_key = db_create_acme_key(session, tid)

    if isinstance(raw_accnt_key, str):
        raw_accnt_key = raw_accnt_key.encode()

    accnt_key = serialization.load_pem_private_key(raw_accnt_key,
                                                   password=None,
                                                   backend=default_backend())

    priv_key = priv_fact.get_val('https_priv_key')

    cert_str, chain_str = letsencrypt.request_new_certificate(
        hostname, accnt_key, priv_key,
        State.tenant_state[tid].acme_tmp_chall_dict,
        Settings.acme_directory_url)

    priv_fact.set_val('https_cert', cert_str)
    priv_fact.set_val('https_chain', chain_str)
    State.tenant_cache[tid].https_cert = cert_str
    State.tenant_cache[tid].https_chain = chain_str
Exemple #7
0
def db_update_node(session, tid, user_session, request, language):
    """
    Transaction to update the node configuration

    :param session: An ORM session
    :param tid: A tenant ID
    :param user_session: The current user session
    :param request: The request data
    :param language: the language in which to localize data
    :return: Return the serialized configuration for the specified tenant
    """
    config = ConfigFactory(session, tid)

    enable_escrow = not config.get_val('escrow') and request.get('escrow', False)
    disable_escrow = user_session.ek and config.get_val('escrow') and not request.get('escrow', False)

    config.update('node', request)

    if request['enable_ricochet_panel'] and not request['ricochet_address']:
        request['enable_ricochet_panel'] = False

    # Validate that IP addresses/ranges we're getting are goo
    if 'ip_filter_admin' in request and request['ip_filter_admin_enable'] and request['ip_filter_admin']:
        parse_csv_ip_ranges_to_ip_networks(request['ip_filter_admin'])

    if 'languages_enabled' in request and 'default_language' in request:
        db_update_enabled_languages(session,
                                    tid,
                                    request['languages_enabled'],
                                    request['default_language'])

    if language in db_get_languages(session, tid):
        ConfigL10NFactory(session, tid).update('node', request, language)

    if enable_escrow:
        crypto_escrow_prv_key, State.tenant_cache[tid].crypto_escrow_pub_key = GCE.generate_keypair()
        user = db_get(session, models.User, models.User.id == user_session.user_id)
        user.crypto_escrow_prv_key = Base64Encoder.encode(GCE.asymmetric_encrypt(user.crypto_pub_key, crypto_escrow_prv_key))

        if tid == 1:
            session.query(models.User).update({'password_change_needed': True}, synchronize_session=False)
        else:
            session.query(models.User).filter(models.User.tid == tid).update({'password_change_needed': True}, synchronize_session=False)

    if disable_escrow:
        if tid == 1:
            session.query(models.User).update({'crypto_escrow_bkp1_key': ''}, synchronize_session=False)
        else:
            session.query(models.User).update({'crypto_escrow_bkp2_key': ''}, synchronize_session=False)

        session.query(models.User).filter(models.User.tid == tid).update({'crypto_escrow_prv_key': ''}, synchronize_session=False)

    config.set_val('crypto_escrow_pub_key', State.tenant_cache[tid].crypto_escrow_pub_key)

    db_refresh_memory_variables(session, [tid])

    if tid == 1:
        log.setloglevel(config.get_val('log_level'))

    return db_admin_serialize_node(session, tid, language)
Exemple #8
0
def signup_activation(session, state, tid, token, language):
    config = ConfigFactory(session, 1)

    if not config.get_val(u'enable_signup'):
        raise errors.ForbiddenOperation

    signup = session.query(models.Signup).filter(
        models.Signup.activation_token == token).one_or_none()
    if signup is None:
        return {}

    if not session.query(
            models.Config).filter(models.Config.tid == signup.tid).count():
        tenant = session.query(
            models.Tenant).filter(models.Tenant.id == signup.tid).one()

        mode = config.get_val('mode')

        db_initialize_tenant(session, tenant, mode)

        password_admin = generateRandomKey(16)
        password_recipient = generateRandomKey(16)

        node_name = signup.organization_name if signup.organization_name else signup.subdomain

        wizard = {
            'node_language': signup.language,
            'node_name': node_name,
            'admin_name': signup.name + ' ' + signup.surname,
            'admin_password': password_admin,
            'admin_mail_address': signup.email,
            'receiver_name': signup.name + ' ' + signup.surname,
            'receiver_password': password_recipient,
            'receiver_mail_address': signup.email,
            'profile': 'default',
            'enable_developers_exception_notification': True
        }

        db_wizard(session, signup.tid, wizard, False, language)

        ids = [
            r[0] for r in session.query(models.User.id).filter(
                models.UserTenant.user_id == models.User.id,
                models.UserTenant.tenant_id == signup.tid)
        ]

        template_vars = {
            'type': 'activation',
            'node': db_admin_serialize_node(session, 1, language),
            'notification': db_get_notification(session, 1, language),
            'signup': serialize_signup(signup),
            'password_admin': password_admin,
            'password_recipient': password_recipient
        }

        state.format_and_send_mail(session, 1, {'mail_address': signup.email},
                                   template_vars)

    db_refresh_memory_variables(session, [1])
Exemple #9
0
def db_serialize_node(session, tid, language):
    """
    Serialize the public node configuration.

    :param session: An ORM session
    :param tid: A tenant ID
    :param language: The language to be used during serialization
    :return: The serialization of the public node configuration
    """
    node_dict = ConfigFactory(session, tid).serialize('public_node')
    l10n_dict = ConfigL10NFactory(
        session,
        tid,
    ).serialize('node', language)

    ret_dict = merge_dicts(node_dict, l10n_dict)

    ret_dict['root_tenant'] = tid == 1
    ret_dict['languages_enabled'] = models.EnabledLanguage.list(
        session,
        tid) if node_dict['wizard_done'] else list(LANGUAGES_SUPPORTED_CODES)
    ret_dict['languages_supported'] = LANGUAGES_SUPPORTED

    records = session.query(models.File.id, models.File.data).filter(
        models.File.tid == tid, models.File.id.in_(['css', 'script']))
    for x in records:
        ret_dict[x[0]] = True

    if tid != 1:
        root_tenant_node = ConfigFactory(session, 1)

        for varname in ['version', 'version_db', 'latest_version']:
            ret_dict[varname] = root_tenant_node.get_val(varname)

        if language not in models.EnabledLanguage.list(session, tid):
            language = root_tenant_node.get_val('default_language')

        root_tenant_l10n = ConfigL10NFactory(session, 1)

        if ret_dict['mode'] != 'default':
            ret_dict['footer'] = root_tenant_l10n.get_val('footer', language)
            ret_dict['whistleblowing_question'] = root_tenant_l10n.get_val(
                'whistleblowing_question', language)
            ret_dict['whistleblowing_button'] = root_tenant_l10n.get_val(
                'whistleblowing_button', language)
            ret_dict['enable_disclaimer'] = root_tenant_node.get_val(
                'enable_disclaimer')
            ret_dict['disclaimer_title'] = root_tenant_l10n.get_val(
                'disclaimer_title', language)
            ret_dict['disclaimer_text'] = root_tenant_l10n.get_val(
                'disclaimer_text', language)

            records = session.query(models.File.id, models.File.data).filter(
                models.File.tid == 1, models.File.id.in_(['css', 'script']))
            for x in records:
                if not ret_dict.get(x[0]):
                    ret_dict[x[0]] = True

    return ret_dict
Exemple #10
0
def db_serialize_node(session, tid, language):
    """
    Serialize the public node configuration.
    """
    node_dict = ConfigFactory(session, tid).serialize('public_node')
    l10n_dict = ConfigL10NFactory(
        session,
        tid,
    ).serialize('node', language)

    ret_dict = merge_dicts(node_dict, l10n_dict)

    ret_dict['root_tenant'] = tid == 1
    ret_dict['languages_enabled'] = models.EnabledLanguage.list(
        session,
        tid) if node_dict['wizard_done'] else list(LANGUAGES_SUPPORTED_CODES)
    ret_dict['languages_supported'] = LANGUAGES_SUPPORTED

    files = [u'logo', u'favicon', u'css', u'script']
    records = session.query(models.File.id, models.File.data).filter(
        models.File.tid == tid,
        models.File.id.in_([u'logo', u'favicon', u'css', u'script']))
    for x in records:
        ret_dict[x[0]] = x[1] if x[0] == 'logo' else True

    if tid != 1:
        root_tenant_node = ConfigFactory(session, 1)

        for varname in ['version', 'version_db', 'latest_version']:
            ret_dict[varname] = root_tenant_node.get_val(varname)

        if language not in models.EnabledLanguage.list(session, tid):
            language = root_tenant_node.get_val(u'default_language')

        root_tenant_l10n = ConfigL10NFactory(session, 1)

        if ret_dict['mode'] != u'default':
            ret_dict['footer'] = root_tenant_l10n.get_val(u'footer', language)
            ret_dict['whistleblowing_question'] = root_tenant_l10n.get_val(
                u'whistleblowing_question', language)
            ret_dict['whistleblowing_button'] = root_tenant_l10n.get_val(
                u'whistleblowing_button', language)
            ret_dict['enable_disclaimer'] = root_tenant_node.get_val(
                u'enable_disclaimer')
            ret_dict['disclaimer_title'] = root_tenant_l10n.get_val(
                u'disclaimer_title', language)
            ret_dict['disclaimer_text'] = root_tenant_l10n.get_val(
                u'disclaimer_text', language)

            records = session.query(models.File.id, models.File.data).filter(
                models.File.tid == 1,
                models.File.id.in_([u'logo', u'favicon', u'css', u'script']))
            for x in records:
                if not ret_dict[x[0]]:
                    ret_dict[x[0]] = x[1] if x[0] == 'logo' else True

    return ret_dict
Exemple #11
0
def db_get_onion_service_info(session, tid):
    node = ConfigFactory(session, tid)

    hostname = node.get_val('onionservice')
    key = node.get_val('tor_onion_key')

    old_hostname = node.get_val('old_onionservice')
    old_key = node.get_val('old_tor_onion_key')

    return tid, hostname, key, old_hostname, old_key
Exemple #12
0
def db_serialize_node(session, tid, language):
    """
    Serialize node info.
    """
    # Contexts and Receivers relationship
    configured = session.query(models.ReceiverContext).filter(
        models.ReceiverContext.context_id == models.Context.id,
        models.Context.tid == tid).count() > 0

    node_dict = ConfigFactory(session, tid, 'public_node').serialize()
    l10n_dict = NodeL10NFactory(session, tid).localized_dict(language)

    ret_dict = merge_dicts(node_dict, l10n_dict)

    ret_dict['root_tenant'] = tid == 1
    ret_dict['languages_enabled'] = models.EnabledLanguage.list(
        session,
        tid) if node_dict['wizard_done'] else list(LANGUAGES_SUPPORTED_CODES)
    ret_dict['languages_supported'] = LANGUAGES_SUPPORTED
    ret_dict['configured'] = configured
    ret_dict['accept_submissions'] = State.accept_submissions

    ret_dict['logo'] = db_get_file(session, tid, u'logo')
    ret_dict['favicon'] = db_get_file(session, tid, u'favicon')
    ret_dict['css'] = db_get_file(session, tid, u'css')
    ret_dict['script'] = db_get_file(session, tid, u'script')

    if tid != 1:
        root_tenant_node = ConfigFactory(session, 1, 'public_node')

        if language not in models.EnabledLanguage.list(session, tid):
            language = root_tenant_node.get_val(u'default_language')

        for x in [u'logo', u'favicon', u'css', u'scripts']:
            if not ret_dict[x]:
                ret_dict[x] = db_get_file(session, 1, x)

        root_tenant_l10n = NodeL10NFactory(session, tid)

        if not root_tenant_node.get_val(u'enable_footer_customization'):
            ret_dict['footer'] = root_tenant_l10n.get_val(u'footer', language)

        if ret_dict['mode'] == u'whistleblowing.it':
            ret_dict['whistleblowing_question'] = root_tenant_l10n.get_val(
                u'whistleblowing_question', language)
            ret_dict['whistleblowing_button'] = root_tenant_l10n.get_val(
                u'whistleblowing_button', language)
            ret_dict['enable_disclaimer'] = root_tenant_node.get_val(
                u'enable_disclaimer')
            ret_dict['disclaimer_title'] = root_tenant_l10n.get_val(
                u'disclaimer_title', language)
            ret_dict['disclaimer_text'] = root_tenant_l10n.get_val(
                u'disclaimer_text', language)

    return ret_dict
Exemple #13
0
def db_get_sites(session):
    sites = []

    root_tenant = ConfigFactory(session, 1)
    root_domain = root_tenant.get_val('rootdomain')
    root_onionservice = root_tenant.get_val('onionservice')

    for tid in session.query(models.Tenant.id).filter(
            models.Tenant.active.is_(True)):
        tenant = ConfigFactory(session, tid[0])

        site = {
            'id': tid[0],
            'name': tenant.get_val('name'),
            'hostname': tenant.get_val('hostname'),
            'onionservice': tenant.get_val('onionservice')
        }

        sites.append(site)

        if tid == 1 or tenant.get_val('mode') == 'default':
            pass

        subdomain = tenant.get_val('subdomain')
        if subdomain:
            site['hostname'] = subdomain + '.' + root_tenant.get_val(
                'rootdomain')
            site['onionservice'] = subdomain + '.' + root_tenant.get_val(
                'onionservice')

    return sites
Exemple #14
0
def serialize_https_config_summary(session, tid):
    config = ConfigFactory(session, tid)

    file_summaries = {}
    for key, file_res_cls in FileHandler.mapped_file_resources.items():
        file_summaries[key] = file_res_cls.db_serialize(session, tid)

    return {
        'enabled': config.get_val('https_enabled'),
        'files': file_summaries,
        'acme': config.get_val('acme')
    }
Exemple #15
0
def db_serialize_node(session, tid, language):
    """
    Serialize the public node configuration.
    """
    # Contexts and Receivers relationship
    node_dict = ConfigFactory(session, tid).serialize('public_node')
    l10n_dict = ConfigL10NFactory(
        session,
        tid,
    ).serialize('node', language)

    ret_dict = merge_dicts(node_dict, l10n_dict)

    ret_dict['root_tenant'] = tid == 1
    ret_dict['languages_enabled'] = models.EnabledLanguage.list(
        session,
        tid) if node_dict['wizard_done'] else list(LANGUAGES_SUPPORTED_CODES)
    ret_dict['languages_supported'] = LANGUAGES_SUPPORTED

    files = [u'logo', u'favicon', u'css', u'script']
    for x in files:
        ret_dict[x] = db_get_file(session, tid, x)

    if tid != 1:
        root_tenant_node = ConfigFactory(session, 1)

        for varname in ['version', 'version_db', 'latest_version']:
            ret_dict[varname] = root_tenant_node.get_val(varname)

        if language not in models.EnabledLanguage.list(session, tid):
            language = root_tenant_node.get_val(u'default_language')

        root_tenant_l10n = ConfigL10NFactory(session, 1)

        if ret_dict['mode'] == u'whistleblowing.it' or ret_dict[
                'mode'] == u'eat':
            ret_dict['footer'] = root_tenant_l10n.get_val(u'footer', language)
            ret_dict['whistleblowing_question'] = root_tenant_l10n.get_val(
                u'whistleblowing_question', language)
            ret_dict['whistleblowing_button'] = root_tenant_l10n.get_val(
                u'whistleblowing_button', language)
            ret_dict['enable_disclaimer'] = root_tenant_node.get_val(
                u'enable_disclaimer')
            ret_dict['disclaimer_title'] = root_tenant_l10n.get_val(
                u'disclaimer_title', language)
            ret_dict['disclaimer_text'] = root_tenant_l10n.get_val(
                u'disclaimer_text', language)

            for x in files:
                if not ret_dict[x]:
                    ret_dict[x] = db_get_file(session, 1, x)

    return ret_dict
Exemple #16
0
def signup_activation(session, state, tid, token, language):
    config = ConfigFactory(session, 1)

    if not config.get_val(u'enable_signup'):
        raise errors.ForbiddenOperation

    signup = session.query(models.Signup).filter(models.Signup.activation_token == token).one_or_none()
    if signup is None:
        return {}

    if not session.query(models.Config).filter(models.Config.tid == signup.tid).count():
        tenant = session.query(models.Tenant).filter(models.Tenant.id == signup.tid).one()

        mode = config.get_val('mode')

        db_initialize_tenant(session, tenant, mode)

        password_admin = generateRandomKey(16)
        password_recipient = generateRandomKey(16)

        node_name = signup.organization_name if signup.organization_name else signup.subdomain

        wizard = {
            'node_language': signup.language,
            'node_name': node_name,
            'admin_name': signup.name + ' ' + signup.surname,
            'admin_password': password_admin,
            'admin_mail_address': signup.email,
            'receiver_name': signup.name + ' ' + signup.surname,
            'receiver_password': password_recipient,
            'receiver_mail_address': signup.email,
            'profile': 'default',
            'enable_developers_exception_notification': True
        }

        db_wizard(session, signup.tid, wizard, False, language)

        ids = [r[0] for r in session.query(models.User.id).filter(models.UserTenant.user_id == models.User.id,
                                                                  models.UserTenant.tenant_id == signup.tid)]

        template_vars = {
            'type': 'activation',
            'node': db_admin_serialize_node(session, 1, language),
            'notification': db_get_notification(session, 1, language),
            'signup': serialize_signup(signup),
            'password_admin': password_admin,
            'password_recipient': password_recipient
        }

        state.format_and_send_mail(session, 1, {'mail_address': signup.email}, template_vars)

    db_refresh_memory_variables(session, [1])
Exemple #17
0
def serialize_https_config_summary(session, tid):
    config = ConfigFactory(session, tid)

    file_summaries = {}
    for key, file_res_cls in FileHandler.mapped_file_resources.items():
        file_summaries[key] = file_res_cls.db_serialize(session, tid)

    return {
        'enabled': config.get_val(u'https_enabled'),
        'running': State.process_supervisor.is_running(),
        'status': State.process_supervisor.get_status(),
        'files': file_summaries,
        'acme': config.get_val(u'acme')
    }
Exemple #18
0
def load_tls_dict(session, tid):
    """
    A quick and dirty function to grab all of the tls config for use in subprocesses
    """
    node = ConfigFactory(session, tid)

    return {
        'tid': tid,
        'ssl_key': node.get_val(u'https_priv_key'),
        'ssl_cert': node.get_val(u'https_cert'),
        'ssl_intermediate': node.get_val(u'https_chain'),
        'https_enabled': node.get_val(u'https_enabled'),
        'hostname': node.get_val(u'hostname'),
    }
Exemple #19
0
def serialize_https_config_summary(session, tid):
    config = ConfigFactory(session, tid)

    file_summaries = {}
    for key, file_res_cls in FileHandler.mapped_file_resources.items():
        file_summaries[key] = file_res_cls.db_serialize(session, tid)

    return {
      'enabled': config.get_val(u'https_enabled'),
      'running': State.process_supervisor.is_running(),
      'status': State.process_supervisor.get_status(),
      'files': file_summaries,
      'acme': config.get_val(u'acme')
    }
Exemple #20
0
    def db_maybe_launch_https_workers(self, session):
        config = ConfigFactory(session, 1)

        # If root_tenant is disabled do not start https
        on = config.get_val(u'https_enabled')
        if not on:
            log.info("Not launching workers")
            return defer.succeed(None)

        site_cfgs = load_tls_dict_list(session)

        valid_cfgs, err = [], None
        # Determine which site_cfgs are valid and only pass those to the child.
        for db_cfg in site_cfgs:
            chnv = tls.ChainValidator()
            ok, err = chnv.validate(db_cfg,
                                    must_be_disabled=False,
                                    check_expiration=False)
            if ok and err is None:
                valid_cfgs.append(db_cfg)

        self.tls_cfg['site_cfgs'] = valid_cfgs

        if not valid_cfgs:
            log.info("Not launching https workers due to %s", err)
            return defer.fail(err)

        log.info("Decided to launch https workers")

        return self.launch_https_workers()
Exemple #21
0
def get_l10n(session, tid, lang):
    """
    Transaction for retrieving the custom texts configured for a specific language

    :param session: An ORM session
    :param tid:  The tenant ID of the tenant on which perform the lookup
    :param lang: A requested language
    :return: A dictionary containing the custom texts configured for a specific language
    """
    if tid != 1:
        config = ConfigFactory(session, tid)

        if config.get_val('mode') != 'default':
            tid = 1

    path = langfile_path(lang)
    directory_traversal_check(Settings.client_path, path)

    custom_texts = session.query(models.CustomTexts).filter(models.CustomTexts.lang == lang, models.CustomTexts.tid == tid).one_or_none()
    custom_texts = custom_texts.texts if custom_texts is not None else {}

    texts = read_json_file(path)

    texts.update(custom_texts)

    return texts
Exemple #22
0
def db_acme_cert_issuance(session, tid):
    priv_fact = ConfigFactory(session, tid)
    hostname = State.tenant_cache[tid].hostname

    # Temporary fix for https://github.com/certbot/certbot/issues/6246
    # raw_accnt_key = priv_fact.get_val(u'acme_accnt_key')
    raw_accnt_key = db_create_acme_key(session, tid)

    if isinstance(raw_accnt_key, text_type):
        raw_accnt_key = raw_accnt_key.encode()

    accnt_key = serialization.load_pem_private_key(raw_accnt_key,
                                                   password=None,
                                                   backend=default_backend())

    priv_key = priv_fact.get_val(u'https_priv_key')

    tmp_chall_dict = State.tenant_state[tid].acme_tmp_chall_dict

    # Run ACME registration all the way to resolution
    cert_str, chain_str = letsencrypt.run_acme_reg_to_finish(hostname,
                                                             accnt_key,
                                                             priv_key,
                                                             hostname,
                                                             tmp_chall_dict,
                                                             Settings.acme_directory_url)

    priv_fact.set_val(u'https_cert', cert_str)
    priv_fact.set_val(u'https_chain', chain_str)
    State.tenant_cache[tid].https_cert = cert_str
    State.tenant_cache[tid].https_chain = chain_str
Exemple #23
0
def db_acme_cert_issuance(session, tid):
    priv_fact = ConfigFactory(session, tid)
    hostname = State.tenant_cache[tid].hostname

    # Temporary fix for https://github.com/certbot/certbot/issues/6246
    # raw_accnt_key = priv_fact.get_val(u'acme_accnt_key')
    raw_accnt_key = db_create_acme_key(session, tid)

    if isinstance(raw_accnt_key, text_type):
        raw_accnt_key = raw_accnt_key.encode()

    accnt_key = serialization.load_pem_private_key(raw_accnt_key,
                                                   password=None,
                                                   backend=default_backend())

    priv_key = priv_fact.get_val(u'https_priv_key')

    tmp_chall_dict = State.tenant_state[tid].acme_tmp_chall_dict

    # Run ACME registration all the way to resolution
    cert_str, chain_str = letsencrypt.run_acme_reg_to_finish(
        hostname, accnt_key, priv_key, hostname, tmp_chall_dict,
        Settings.acme_directory_url)

    priv_fact.set_val(u'https_cert', cert_str)
    priv_fact.set_val(u'https_chain', chain_str)
    State.tenant_cache[tid].https_cert = cert_str
    State.tenant_cache[tid].https_chain = chain_str
def evaluate_update_notification(session, state, latest_version):
    priv_fact = ConfigFactory(session, 1)

    stored_latest = priv_fact.get_val('latest_version')

    # Check if the running version is lower than the latest version
    if parse_version(stored_latest) >= parse_version(latest_version):
        return

    Cache.invalidate()

    priv_fact.set_val('latest_version', latest_version)

    # Check to reduce number of email notifications of new updates
    if parse_version(__version__) != parse_version(stored_latest):
        return

    for user_desc in db_get_users(session, 1, 'admin'):
        if not user_desc['notification']:
            continue

        lang = user_desc['language']
        template_vars = {
            'type': 'software_update_available',
            'latest_version': latest_version,
            'node': db_admin_serialize_node(session, 1, lang),
            'notification': db_get_notification(session, 1, lang),
            'user': user_desc,
        }

        state.format_and_send_mail(session, 1, user_desc, template_vars)
Exemple #25
0
    def db_serialize(session, tid):
        config = ConfigFactory(session, tid)

        return {
            'set': config.get_val(u'https_priv_key') != u'',
            'gen': config.get_val(u'https_priv_gen')
        }
Exemple #26
0
    def db_serialize(session, tid):
        config = ConfigFactory(session, tid)

        return {
            'set': config.get_val(u'https_priv_key') != u'',
            'gen': config.get_val(u'https_priv_gen')
        }
Exemple #27
0
def db_serialize_node(session, tid, language):
    """
    Serialize node info.
    """
    # Contexts and Receivers relationship
    configured = session.query(models.ReceiverContext).filter(
        models.ReceiverContext.context_id == models.Context.id,
        models.Context.tid == tid).count() > 0

    node = ConfigFactory(session, tid, 'public_node').serialize()

    misc_dict = {
        'languages_enabled':
        models.EnabledLanguage.list(session, tid)
        if node['wizard_done'] else list(LANGUAGES_SUPPORTED_CODES),
        'languages_supported':
        LANGUAGES_SUPPORTED,
        'configured':
        configured,
        'accept_submissions':
        State.accept_submissions,
        'logo':
        db_get_file(session, tid, u'logo'),
        'favicon':
        db_get_file(session, tid, u'favicon'),
        'css':
        db_get_file(session, tid, u'css'),
        'homepage':
        db_get_file(session, tid, u'homepage'),
        'script':
        db_get_file(session, tid, u'script')
    }

    l10n_dict = NodeL10NFactory(session, tid).localized_dict(language)

    if tid != 1:
        root_tenant_node = ConfigFactory(session, 1, 'public_node')
        misc_dict['enable_footer_customization'] = root_tenant_node.get_val(
            u'enable_footer_customization')

        if language not in models.EnabledLanguage.list(session, tid):
            language = root_tenant_node.get_val(u'default_language')

        root_tenant_l10n = NodeL10NFactory(session, tid)
        l10n_dict['footer'] = root_tenant_l10n.get_val(u'footer', language)

    return merge_dicts(node, l10n_dict, misc_dict)
Exemple #28
0
def load_tls_dict(session, tid):
    """
    Transaction for loading the TLS configuration of a tenant

    :param session: An ORM session
    :param tid: A tenant ID
    :return: The serialized TLS configuration for the specified tenant
    """
    node = ConfigFactory(session, tid)

    return {
        'tid': tid,
        'ssl_key': node.get_val('https_key'),
        'ssl_cert': node.get_val('https_cert'),
        'ssl_intermediate': node.get_val('https_chain'),
        'https_enabled': node.get_val('https_enabled'),
        'hostname': node.get_val('hostname'),
    }
Exemple #29
0
def db_admin_serialize_node(session, tid, language, config_node='admin_node'):
    config = ConfigFactory(session, tid).serialize(config_node)

    misc_dict = {
        'languages_supported': LANGUAGES_SUPPORTED,
        'languages_enabled': models.EnabledLanguage.list(session, tid),
        'root_tenant': tid == 1,
        'https_possible': tid == 1 or State.tenant_cache[1].reachable_via_web,
    }

    if tid != 1:
        root_tenant_node = ConfigFactory(session, 1)
        misc_dict['version'] = root_tenant_node.get_val('version')
        misc_dict['latest_version'] = root_tenant_node.get_val('latest_version')

    l10n_dict = ConfigL10NFactory(session, tid).serialize('node', language)

    return utils.sets.merge_dicts(config, misc_dict, l10n_dict)
Exemple #30
0
def serialize_tenant(session, tenant, signup=None):
    from globaleaks.handlers.signup import serialize_signup

    node = ConfigFactory(session, tenant.id)

    ret = {
        'id': tenant.id,
        'label': tenant.label,
        'active': tenant.active,
        'subdomain': tenant.subdomain,
        'hostname': node.get_val('hostname'),
        'onionservice': node.get_val('onionservice'),
        'mode': node.get_val('mode'),
        'creation_date': tenant.creation_date
    }

    if signup is not None:
        ret['signup'] = serialize_signup(signup)

    return ret
Exemple #31
0
def signup(session, state, tid, request, language):
    config = ConfigFactory(session, 1)

    if not config.get_val(u'enable_signup'):
        raise errors.ForbiddenOperation

    request['activation_token'] = generateRandomKey(32)
    request['language'] = language

    tenant_id = db_preallocate_tenant(session, {
        'label': request['subdomain'],
        'subdomain': request['subdomain']
    }).id

    signup = models.Signup(request)

    signup.tid = tenant_id

    session.add(signup)

    # We need to send two emails
    #
    # The first one is sent to the platform owner with the activation email.
    #
    # The second goes to the instance administrators notifying them that a new
    # platform has been added.

    signup_dict = serialize_signup(signup)

    # Email 1 - Activation Link
    template_vars = {
        'type': 'signup',
        'node': db_admin_serialize_node(session, 1, language),
        'notification': db_get_notification(session, 1, language),
        'signup': signup_dict
    }

    state.format_and_send_mail(session, 1, {'mail_address': signup.email},
                               template_vars)

    # Email 2 - Admin Notification
    for user_desc in db_get_admin_users(session, 1):
        template_vars = {
            'type': 'admin_signup_alert',
            'signup': serialize_signup(signup),
            'node': db_admin_serialize_node(session, 1, user_desc['language']),
            'notification': db_get_notification(session, 1,
                                                user_desc['language']),
            'user': user_desc,
            'signup': signup_dict
        }

        state.format_and_send_mail(session, 1, user_desc, template_vars)
Exemple #32
0
def db_serialize_node(session, tid, language):
    """
    Serialize the public node configuration.
    """
    # Contexts and Receivers relationship
    node_dict = ConfigFactory(session, tid).serialize('public_node')
    l10n_dict = ConfigL10NFactory(session, tid,).serialize('node', language)

    ret_dict = merge_dicts(node_dict, l10n_dict)

    ret_dict['root_tenant'] = tid == 1
    ret_dict['languages_enabled'] = models.EnabledLanguage.list(session, tid) if node_dict['wizard_done'] else list(LANGUAGES_SUPPORTED_CODES)
    ret_dict['languages_supported'] = LANGUAGES_SUPPORTED

    files = [u'logo', u'favicon', u'css', u'script']
    for x in files:
        ret_dict[x] = db_get_file(session, tid, x)

    if tid != 1:
        root_tenant_node = ConfigFactory(session, 1)

        if language not in models.EnabledLanguage.list(session, tid):
            language = root_tenant_node.get_val(u'default_language')

        root_tenant_l10n = ConfigL10NFactory(session, 1)

        if ret_dict['mode'] == u'whistleblowing.it' or ret_dict['mode'] == u'eat':
            ret_dict['footer'] = root_tenant_l10n.get_val(u'footer', language)
            ret_dict['whistleblowing_question'] = root_tenant_l10n.get_val(u'whistleblowing_question', language)
            ret_dict['whistleblowing_button'] = root_tenant_l10n.get_val(u'whistleblowing_button', language)
            ret_dict['enable_disclaimer'] = root_tenant_node.get_val(u'enable_disclaimer')
            ret_dict['disclaimer_title'] = root_tenant_l10n.get_val(u'disclaimer_title', language)
            ret_dict['disclaimer_text'] = root_tenant_l10n.get_val(u'disclaimer_text', language)

            for x in files:
                if not ret_dict[x]:
                    ret_dict[x] = db_get_file(session, 1, x)

    return ret_dict
Exemple #33
0
def db_acme_cert_issuance(session, tid):
    priv_fact = ConfigFactory(session, tid, 'node')
    hostname = State.tenant_cache[tid].hostname

    raw_accnt_key = priv_fact.get_val(u'acme_accnt_key')
    accnt_key = serialization.load_pem_private_key(raw_accnt_key.encode(),
                                                   password=None,
                                                   backend=default_backend())

    priv_key = priv_fact.get_val(u'https_priv_key')

    tmp_chall_dict = State.tenant_state[tid].acme_tmp_chall_dict

    # Run ACME registration all the way to resolution
    cert_str, chain_str = letsencrypt.run_acme_reg_to_finish(
        hostname, accnt_key, priv_key, hostname, tmp_chall_dict,
        Settings.acme_directory_url)

    priv_fact.set_val(u'https_cert', cert_str)
    priv_fact.set_val(u'https_chain', chain_str)
    State.tenant_cache[tid].https_cert = cert_str
    State.tenant_cache[tid].https_chain = chain_str
Exemple #34
0
def db_update_node(session, tid, request, language):
    """
    Update and serialize the node infos

    :param tid:
    :param request:
    :param session: the session on which perform queries.
    :param language: the language in which to localize data
    :return: a dictionary representing the serialization of the node
    """
    config = ConfigFactory(session, tid)

    config.update('node', request)

    if 'basic_auth' in request and request['basic_auth'] and request[
            'basic_auth_username'] and request['basic_auth_password']:
        config.set_val('basic_auth', True)
        config.set_val('basic_auth_username', request['basic_auth_username'])
        config.set_val('basic_auth_password', request['basic_auth_password'])
    else:
        config.set_val('basic_auth', False)
        config.set_val('basic_auth_username', '')
        config.set_val('basic_auth_password', '')

    if request['enable_ricochet_panel'] and not request['ricochet_address']:
        request['enable_ricochet_panel'] = False

    # Validate that IP addresses/ranges we're getting are goo
    if 'ip_filter_admin' in request and request[
            'ip_filter_admin_enable'] and request['ip_filter_admin']:
        parse_csv_ip_ranges_to_ip_networks(request['ip_filter_admin'])

    if 'ip_filter_whistleblower_enable' in request and request[
            'ip_filter_whistleblower_enable'] and request[
                'ip_filter_whistleblower']:
        parse_csv_ip_ranges_to_ip_networks(request['ip_filter_whistleblower'])

    if 'languages_enabled' in request and 'default_language' in request:
        db_update_enabled_languages(session, tid, request['languages_enabled'],
                                    request['default_language'])

    if language in models.EnabledLanguage.list(session, tid):
        ConfigL10NFactory(session, tid).update('node', request, language)

    db_refresh_memory_variables(session, [tid])

    if tid == 1:
        log.setloglevel(config.get_val('log_level'))

    return db_admin_serialize_node(session, tid, language)
Exemple #35
0
def signup(session, state, tid, request, language):
    config = ConfigFactory(session, 1)

    if not config.get_val(u'enable_signup'):
        raise errors.ForbiddenOperation

    request['activation_token'] = generateRandomKey(32)
    request['language'] = language

    tenant_id = db_preallocate_tenant(session, {'label': request['subdomain'],
                                                'subdomain': request['subdomain']}).id

    signup = models.Signup(request)

    signup.tid = tenant_id

    session.add(signup)

    # We need to send two emails
    #
    # The first one is sent to the platform owner with the activation email.
    #
    # The second goes to the instance administrators notifying them that a new
    # platform has been added.

    signup_dict = serialize_signup(signup)

    # Email 1 - Activation Link
    template_vars = {
        'type': 'signup',
        'node': db_admin_serialize_node(session, 1, language),
        'notification': db_get_notification(session, 1, language),
        'signup': signup_dict
    }

    state.format_and_send_mail(session, 1, {'mail_address': signup.email}, template_vars)

    # Email 2 - Admin Notification
    for user_desc in db_get_admin_users(session, 1):
        template_vars = {
            'type': 'admin_signup_alert',
            'node': db_admin_serialize_node(session, 1, user_desc['language']),
            'notification': db_get_notification(session, 1, user_desc['language']),
            'user': user_desc,
            'signup': signup_dict
        }

        state.format_and_send_mail(session, 1, user_desc, template_vars)
Exemple #36
0
def perform_data_update(db_file):
    session = get_session(make_db_uri(db_file), foreign_keys=False)

    enabled_languages = [
        lang.name for lang in session.query(models.EnabledLanguage)
    ]

    removed_languages = list(
        set(enabled_languages) - set(LANGUAGES_SUPPORTED_CODES))

    if removed_languages:
        removed_languages.sort()
        removed_languages = ', '.join(removed_languages)
        raise Exception(
            "FATAL: cannot complete the upgrade because the support for some of the enabled languages is currently incomplete (%s)\n"
            "Read about how to handle this condition at: https://github.com/globaleaks/GlobaLeaks/wiki/Upgrade-Guide#lang-drop"
            % removed_languages)

    try:
        cfg = ConfigFactory(session, 1)

        stored_ver = cfg.get_val(u'version')

        if stored_ver != __version__:
            # The below commands can change the current store based on the what is
            # currently stored in the DB.
            for tid in [t[0] for t in session.query(models.Tenant.id)]:
                appdata = load_appdata()
                config.update_defaults(session, tid, appdata)

            db_update_defaults(session)

            db_fix(session)

            cfg.set_val(u'version', __version__)
            cfg.set_val(u'latest_version', __version__)
            cfg.set_val(u'version_db', DATABASE_VERSION)

        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()
Exemple #37
0
def load_tls_dict(session, tid):
    """
    A quick and dirty function to grab all of the tls config for use in subprocesses
    """
    node = ConfigFactory(session, tid)

    return {
        'ssl_key': node.get_val(u'https_priv_key'),
        'ssl_cert': node.get_val(u'https_cert'),
        'ssl_intermediate': node.get_val(u'https_chain'),
        'ssl_dh': node.get_val(u'https_dh_params'),
        'https_enabled': node.get_val(u'https_enabled'),
        'hostname': node.get_val(u'hostname'),
    }
Exemple #38
0
def get_l10n(session, tid, lang):
    if tid != 1:
        config = ConfigFactory(session, 1)

        if config.get_val(u'mode') == u'whistleblowing.it':
            tid = 1

    path = langfile_path(lang)
    directory_traversal_check(Settings.client_path, path)

    if not os.path.exists(path):
        raise errors.ResourceNotFound()

    texts = read_json_file(path)

    custom_texts = session.query(models.CustomTexts).filter(models.CustomTexts.lang == lang, models.CustomTexts.tid == tid).one_or_none()
    custom_texts = custom_texts.texts if custom_texts is not None else {}

    texts.update(custom_texts)

    return texts
Exemple #39
0
def evaluate_update_notification(session, state, latest_version):
    priv_fact = ConfigFactory(session, 1)

    stored_latest = priv_fact.get_val(u'latest_version')

    if V(stored_latest) < V(latest_version):
        priv_fact.set_val(u'latest_version', latest_version)

        if V(__version__) == V(latest_version):
            return

        for user_desc in db_get_admin_users(session, 1):
            lang = user_desc['language']
            template_vars = {
                'type': 'software_update_available',
                'latest_version': latest_version,
                'node': db_admin_serialize_node(session, 1, lang),
                'notification': db_get_notification(session, 1, lang),
                'user': user_desc,
            }

            state.format_and_send_mail(session, 1, user_desc, template_vars)
Exemple #40
0
def perform_data_update(db_file):
    session = get_session(make_db_uri(db_file), foreign_keys=False)

    enabled_languages = [lang.name for lang in session.query(models.EnabledLanguage)]

    removed_languages = list(set(enabled_languages) - set(LANGUAGES_SUPPORTED_CODES))

    if removed_languages:
        removed_languages.sort()
        removed_languages = ', '.join(removed_languages)
        raise Exception("FATAL: cannot complete the upgrade because the support for some of the enabled languages is currently incomplete (%s)\n"
                        "Read about how to handle this condition at: https://github.com/globaleaks/GlobaLeaks/wiki/Upgrade-Guide#lang-drop" % removed_languages)

    try:
        cfg = ConfigFactory(session, 1)

        stored_ver = cfg.get_val(u'version')

        if stored_ver != __version__:
            # The below commands can change the current store based on the what is
            # currently stored in the DB.
            for tid in [t[0] for t in session.query(models.Tenant.id)]:
                appdata = load_appdata()
                config.update_defaults(session, tid, appdata)

            db_update_defaults(session)

            db_fix(session)

            cfg.set_val(u'version', __version__)
            cfg.set_val(u'latest_version', __version__)
            cfg.set_val(u'version_db', DATABASE_VERSION)

        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()
Exemple #41
0
def can_perform_acme_run(session, tid):
    config = ConfigFactory(session, tid)
    acme = config.get_val(u'acme')
    no_cert_set = config.get_val(u'https_cert') == u''
    return acme and no_cert_set
Exemple #42
0
def is_acme_configured(session, tid):
    config = ConfigFactory(session, tid)
    acme = config.get_val(u'acme')
    cert_set = config.get_val(u'https_cert') != u''
    return acme and cert_set
Exemple #43
0
def can_perform_acme_renewal(session, tid):
    priv_fact = ConfigFactory(session, tid)
    a = is_acme_configured(session, tid)
    b = priv_fact.get_val(u'https_enabled')
    c = priv_fact.get_val(u'https_cert')
    return a and b and c
Exemple #44
0
def db_get_onion_service_info(session, tid):
    node = ConfigFactory(session, tid)
    hostname = node.get_val(u'onionservice')
    key = node.get_val(u'tor_onion_key')

    return tid, hostname, key