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
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)
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)
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 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 _setUp(self, session): valid_setup = test_tls.get_valid_setup() config = ConfigFactory(session, 1, 'node') config.set_val(u'https_cert', valid_setup['cert']) config.set_val(u'https_enabled', True) db_refresh_memory_variables(session)
def commit_valid_config(session): cfg = get_valid_setup() priv_fact = ConfigFactory(session, 1, 'node') priv_fact.set_val(u'https_dh_params', cfg['dh_params']) priv_fact.set_val(u'https_priv_key', cfg['key']) priv_fact.set_val(u'https_cert', cfg['cert']) priv_fact.set_val(u'https_chain', cfg['chain']) priv_fact.set_val(u'https_enabled', True) ConfigFactory(session, 1, 'node').set_val(u'hostname', 'localhost:9999')
def create_file(session, cls, tid, raw_key): db_cfg = load_tls_dict(session, tid) db_cfg['ssl_key'] = raw_key config = ConfigFactory(session, tid) pkv = cls.validator() ok, _ = pkv.validate(db_cfg) if ok: config.set_val('https_key', raw_key) return ok
def commit_valid_config(session): cfg = get_valid_setup() priv_fact = ConfigFactory(session, 1) priv_fact.set_val(u'https_dh_params', cfg['dh_params']) priv_fact.set_val(u'https_priv_key', cfg['key']) priv_fact.set_val(u'https_cert', cfg['cert']) priv_fact.set_val(u'https_chain', cfg['chain']) priv_fact.set_val(u'https_enabled', True) ConfigFactory(session, 1).set_val(u'hostname', 'localhost:9999')
def create_file(session, cls, tid, raw_chain): config = ConfigFactory(session, tid) db_cfg = load_tls_dict(session, tid) db_cfg['ssl_intermediate'] = raw_chain cv = cls.validator() ok, _ = cv.validate(db_cfg) if ok: config.set_val(u'https_chain', raw_chain) return ok
def create_file(session, cls, tid, raw_key): db_cfg = load_tls_dict(session, tid) db_cfg['ssl_key'] = raw_key config = ConfigFactory(session, tid) pkv = cls.validator() ok, _ = pkv.validate(db_cfg) if ok: config.set_val(u'https_priv_key', raw_key) config.set_val(u'https_priv_gen', False) return ok
def create_file(session, cls, tid, raw_cert): config = ConfigFactory(session, tid) db_cfg = load_tls_dict(session, tid) db_cfg['ssl_cert'] = raw_cert cv = cls.validator() ok, _ = cv.validate(db_cfg) if ok: config.set_val(u'https_cert', raw_cert) State.tenant_cache[tid].https_cert = raw_cert return ok
def try_to_enable_https(session, tid): config = ConfigFactory(session, tid, 'node') cv = tls.ChainValidator() db_cfg = load_tls_dict(session, tid) db_cfg['https_enabled'] = False ok, err = cv.validate(db_cfg) if ok: config.set_val(u'https_enabled', True) State.tenant_cache[tid].https_enabled = True else: raise err
def try_to_enable_https(session, tid): config = ConfigFactory(session, tid) cv = tls.ChainValidator() db_cfg = load_tls_dict(session, tid) db_cfg['https_enabled'] = False ok, _ = cv.validate(db_cfg) if not ok: raise errors.InputValidationError() config.set_val(u'https_enabled', True) State.tenant_cache[tid].https_enabled = True
def db_create_acme_key(session, tid): priv_fact = ConfigFactory(session, tid) key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()) key = key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption(), ) priv_fact.set_val(u'acme', True) priv_fact.set_val(u'acme_accnt_key', key) return key
def perform_data_update(db_file): engine = get_engine(make_db_uri(db_file), foreign_keys=False) session = sessionmaker(bind=engine)() 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: prv = ConfigFactory(session, 1, 'node') stored_ver = prv.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_fields_attrs(session) prv.set_val(u'version', __version__) prv.set_val(u'latest_version', __version__) session.commit() except: session.rollback() raise finally: session.close()
def db_create_acme_key(session, tid): priv_fact = ConfigFactory(session, tid) key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend() ) key = key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption(), ) priv_fact.set_val(u'acme', True) priv_fact.set_val(u'acme_accnt_key', key) return key
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)
def db_update_node(session, tid, request, language): """ Update and serialize the node infos :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 """ node = ConfigFactory(session, tid, 'node') if tid != 1: request['enable_signup'] = False node.update(request) if request['basic_auth'] and request['basic_auth_username'] and request[ 'basic_auth_password']: node.set_val(u'basic_auth', True) node.set_val(u'basic_auth_username', request['basic_auth_username']) node.set_val(u'basic_auth_password', request['basic_auth_password']) else: node.set_val(u'basic_auth', False) db_update_enabled_languages(session, tid, request['languages_enabled'], request['default_language']) if language in request['languages_enabled']: node_l10n = NodeL10NFactory(session, tid) node_l10n.update(request, language) db_refresh_memory_variables(session, [tid]) # TODO pass instance of db_update_node into admin_serialize return db_admin_serialize_node(session, tid, language)
def evaluate_update_notification(session, state, latest_version): priv_fact = ConfigFactory(session, 1, 'node') 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)
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
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)
def create_file(session, cls, tid): log.info("Generating an ACME account key with %d bits" % Settings.key_bits) priv_fact = ConfigFactory(session, tid, 'node') # NOTE key size is hard coded to align with minimum CA requirements # TODO change format to OpenSSL key to normalize types of keys used priv_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()) log.debug("Saving the ACME key") b = priv_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption(), ) priv_fact.set_val(u'acme', True) priv_fact.set_val(u'acme_accnt_key', b) return priv_key
def db_update_node(session, tid, request, language, config_node): """ Update and serialize the node infos :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 """ node = ConfigFactory(session, tid, config_node) node.update(request) if 'basic_auth' in request: if request['basic_auth'] and request[ 'basic_auth_username'] and request['basic_auth_password']: node.set_val(u'basic_auth', True) node.set_val(u'basic_auth_username', request['basic_auth_username']) node.set_val(u'basic_auth_password', request['basic_auth_password']) else: node.set_val(u'basic_auth', False) # Validate that IP addresses/ranges we're getting are goo if 'ip_filter_authenticated' in request: if request['ip_filter_authenticated_enable'] and request[ 'ip_filter_authenticated']: # Make sure we can validate and parse the whole thing parse_csv_ip_ranges_to_ip_networks( request['ip_filter_authenticated']) 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): node_l10n = NodeL10NFactory(session, tid) node_l10n.update(request, language) db_refresh_memory_variables(session, [tid]) return db_admin_serialize_node(session, tid, language)
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()
def reset_https_config(session, tid): config = ConfigFactory(session, tid) config.set_val(u'https_enabled', False) config.set_val(u'https_priv_gen', False) config.set_val(u'https_priv_key', '') config.set_val(u'https_cert', '') config.set_val(u'https_chain', '') config.set_val(u'https_csr', '') config.set_val(u'acme', False) config.set_val(u'acme_accnt_key', '') State.tenant_cache[tid].https_enabled = False
def save_tls_key(session, tid, prv_key): config = ConfigFactory(session, tid) config.set_val(u'https_priv_key', prv_key) config.set_val(u'https_priv_gen', True)
def delete_file(session, tid): config = ConfigFactory(session, tid) config.set_val(u'https_priv_key', u'') config.set_val(u'https_priv_gen', False)
def set_onion_service_info(session, tid, hostname, key): node = ConfigFactory(session, tid) node.set_val(u'onionservice', hostname) node.set_val(u'tor_onion_key', key)
def delete_file(session, tid): config = ConfigFactory(session, tid) config.set_val('https_key', '')
def db_reset_smtp_settings(session, tid): config = ConfigFactory(session, tid) config.set_val('smtp_server', 'mail.globaleaks.org') config.set_val('smtp_port', 587) config.set_val('smtp_username', 'globaleaks') config.set_val('smtp_password', 'globaleaks') config.set_val('smtp_source_email', '*****@*****.**') config.set_val('smtp_security', 'TLS') config.set_val('smtp_authentication', True)