def get_push_type(self): onelogin_mode = utils.get_onelogin_mode() okta_mode = utils.get_okta_mode() if settings.app.sso and DUO_AUTH in self.auth_type and \ DUO_AUTH in settings.app.sso and \ settings.app.sso_duo_mode != 'passcode': return DUO_AUTH elif settings.app.sso and \ SAML_ONELOGIN_AUTH in self.auth_type and \ SAML_ONELOGIN_AUTH in settings.app.sso and \ 'push' in onelogin_mode: return SAML_ONELOGIN_AUTH elif settings.app.sso and \ SAML_OKTA_AUTH in self.auth_type and \ SAML_OKTA_AUTH in settings.app.sso and \ 'push' in okta_mode: return SAML_OKTA_AUTH
def get_push_type(self): onelogin_mode = utils.get_onelogin_mode() okta_mode = utils.get_okta_mode() if settings.app.sso and DUO_AUTH in self.auth_type and \ DUO_AUTH in settings.app.sso: if settings.app.sso_duo_mode != 'passcode': return DUO_AUTH return elif settings.app.sso and \ SAML_ONELOGIN_AUTH in self.auth_type and \ SAML_ONELOGIN_AUTH in settings.app.sso and \ 'push' in onelogin_mode: return SAML_ONELOGIN_AUTH elif settings.app.sso and \ SAML_OKTA_AUTH in self.auth_type and \ SAML_OKTA_AUTH in settings.app.sso and \ 'push' in okta_mode: return SAML_OKTA_AUTH
def has_onelogin_passcode(self): return settings.app.sso and self.auth_type and \ SAML_ONELOGIN_AUTH in self.auth_type and \ SAML_ONELOGIN_AUTH == settings.app.sso and \ 'passcode' in utils.get_onelogin_mode()
def _auth_push_thread(self): info = { 'Server': self.server.name, } platform_name = None if self.platform == 'linux': platform_name = 'Linux' elif self.platform == 'mac': platform_name = 'macOS' elif self.platform == 'ios': platform_name = 'iOS' elif self.platform == 'win': platform_name = 'Windows' elif self.platform == 'chrome': platform_name = 'Chrome OS' if self.device_name: info['Device'] = '%s (%s)' % (self.device_name, platform_name) onelogin_mode = utils.get_onelogin_mode() okta_mode = utils.get_okta_mode() if self.push_type == DUO_AUTH: duo_auth = sso.Duo( username=self.user.name, factor=settings.app.sso_duo_mode, remote_ip=self.remote_ip, auth_type='Connection', info=info, ) allow = duo_auth.authenticate() elif self.push_type == SAML_ONELOGIN_AUTH: allow = sso.auth_onelogin_secondary( username=self.user.name, passcode=None, remote_ip=self.remote_ip, onelogin_mode=onelogin_mode, ) elif self.push_type == SAML_OKTA_AUTH: allow = sso.auth_okta_secondary( username=self.user.name, passcode=None, remote_ip=self.remote_ip, okta_mode=okta_mode, ) else: raise ValueError('Unkown push auth type') if not allow: self.user.audit_event( 'user_connection', ('User connection to "%s" denied. ' + 'Push authentication failed') % (self.server.name), remote_addr=self.remote_ip, ) raise AuthError('User failed push authentication') if settings.app.sso_cache and not self.server_auth_token: self.sso_push_cache_collection.update( { 'user_id': self.user.id, 'server_id': self.server.id, 'mac_addr': self.mac_addr, 'device_id': self.device_id, 'device_name': self.device_name, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'timestamp': utils.now(), }, upsert=True)
def _check_password(self): if settings.vpn.stress_test or self.user.link_server_id: return if self.user.bypass_secondary: logger.info( 'Bypass secondary enabled, skipping password', 'sso', user_name=self.user.name, org_name=self.user.org.name, server_name=self.server.name, ) return if self.has_token: logger.info( 'Client authentication cached, skipping password', 'sso', user_name=self.user.name, org_name=self.user.org.name, server_name=self.server.name, ) return if self.whitelisted: logger.info( 'Client network whitelisted, skipping password', 'sso', user_name=self.user.name, org_name=self.user.org.name, server_name=self.server.name, ) return if not limiter.auth_check(self.user.id): self.user.audit_event( 'user_connection', ('User connection to "%s" denied. Too many ' + 'authentication attempts') % (self.server.name), remote_addr=self.remote_ip, ) raise AuthError('Too many authentication attempts') sso_mode = settings.app.sso or '' duo_mode = settings.app.sso_duo_mode onelogin_mode = utils.get_onelogin_mode() okta_mode = utils.get_okta_mode() auth_type = self.user.auth_type or '' has_duo_passcode = DUO_AUTH in sso_mode and \ DUO_AUTH in auth_type and duo_mode == 'passcode' has_onelogin_passcode = SAML_ONELOGIN_AUTH == sso_mode and \ SAML_ONELOGIN_AUTH in auth_type and onelogin_mode == 'passcode' has_okta_passcode = SAML_OKTA_AUTH == sso_mode and \ SAML_OKTA_AUTH in auth_type and okta_mode == 'passcode' if has_duo_passcode or has_onelogin_passcode or has_okta_passcode: if not self.password and self.has_challenge() and \ self.user.has_pin(): self.user.audit_event( 'user_connection', ('User connection to "%s" denied. ' + 'User failed pin authentication') % (self.server.name), remote_addr=self.remote_ip, ) self.set_challenge(None, 'Enter Pin', False) raise AuthError('Challenge pin') challenge = self.get_challenge() if challenge: self.password = challenge + self.password passcode_len = settings.app.sso_duo_passcode_length orig_password = self.password passcode = self.password[-passcode_len:] self.password = self.password[:-passcode_len] allow = False if settings.app.sso_cache and not self.server_auth_token: doc = self.sso_passcode_cache_collection.find_one({ 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': passcode, }) if doc: self.sso_passcode_cache_collection.update( { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': passcode, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': passcode, 'timestamp': utils.now(), }) allow = True logger.info( 'Authentication cached, skipping secondary passcode', 'sso', user_name=self.user.name, org_name=self.user.org.name, server_name=self.server.name, ) if not allow: if DUO_AUTH in sso_mode: label = 'Duo' duo_auth = sso.Duo( username=self.user.name, factor=duo_mode, remote_ip=self.remote_ip, auth_type='Connection', passcode=passcode, ) allow = duo_auth.authenticate() elif SAML_ONELOGIN_AUTH == sso_mode: label = 'OneLogin' allow = sso.auth_onelogin_secondary( username=self.user.name, passcode=passcode, remote_ip=self.remote_ip, onelogin_mode=onelogin_mode, ) elif SAML_OKTA_AUTH == sso_mode: label = 'Okta' allow = sso.auth_okta_secondary( username=self.user.name, passcode=passcode, remote_ip=self.remote_ip, okta_mode=okta_mode, ) else: raise AuthError('Unknown secondary passcode challenge') if not allow: self.user.audit_event( 'user_connection', ('User connection to "%s" denied. ' + 'User failed %s passcode authentication') % (self.server.name, label), remote_addr=self.remote_ip, ) if self.has_challenge(): if self.user.has_password(self.server): self.set_challenge(orig_password, 'Enter %s Passcode' % label, True) else: self.set_challenge(None, 'Enter %s Passcode' % label, True) raise AuthError('Challenge secondary passcode') raise AuthError('Invalid secondary passcode') if settings.app.sso_cache and not self.server_auth_token: self.sso_passcode_cache_collection.update( { 'user_id': self.user.id, 'server_id': self.server.id, 'mac_addr': self.mac_addr, 'device_id': self.device_id, 'device_name': self.device_name, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': passcode, 'timestamp': utils.now(), }, upsert=True) elif YUBICO_AUTH in sso_mode and YUBICO_AUTH in auth_type: if not self.password and self.has_challenge() and \ self.user.has_pin(): self.user.audit_event( 'user_connection', ('User connection to "%s" denied. ' + 'User failed pin authentication') % (self.server.name), remote_addr=self.remote_ip, ) self.set_challenge(None, 'Enter Pin', False) raise AuthError('Challenge pin') challenge = self.get_challenge() if challenge: self.password = challenge + self.password orig_password = self.password yubikey = self.password[-44:] self.password = self.password[:-44] yubikey_hash = hashlib.sha512() yubikey_hash.update(yubikey) yubikey_hash = base64.b64encode(yubikey_hash.digest()) allow = False if settings.app.sso_cache and not self.server_auth_token: doc = self.sso_passcode_cache_collection.find_one({ 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': yubikey_hash, }) if doc: self.sso_passcode_cache_collection.update( { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': yubikey_hash, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': yubikey_hash, 'timestamp': utils.now(), }) allow = True logger.info( 'Authentication cached, skipping Yubikey', 'sso', user_name=self.user.name, org_name=self.user.org.name, server_name=self.server.name, ) if not allow: valid, yubico_id = sso.auth_yubico(yubikey) if yubico_id != self.user.yubico_id: valid = False if not valid: self.user.audit_event( 'user_connection', ('User connection to "%s" denied. ' + 'User failed Yubico authentication') % (self.server.name), remote_addr=self.remote_ip, ) if self.has_challenge(): if self.user.has_password(self.server): self.set_challenge(orig_password, 'YubiKey', True) else: self.set_challenge(None, 'YubiKey', True) raise AuthError('Challenge YubiKey') raise AuthError('Invalid YubiKey') if settings.app.sso_cache and not self.server_auth_token: self.sso_passcode_cache_collection.update( { 'user_id': self.user.id, 'server_id': self.server.id, 'mac_addr': self.mac_addr, 'device_id': self.device_id, 'device_name': self.device_name, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': yubikey_hash, 'timestamp': utils.now(), }, upsert=True) elif self.server.otp_auth and self.user.type == CERT_CLIENT: if not self.password and self.has_challenge() and \ self.user.has_pin(): self.user.audit_event( 'user_connection', ('User connection to "%s" denied. ' + 'User failed pin authentication') % (self.server.name), remote_addr=self.remote_ip, ) self.set_challenge(None, 'Enter Pin', False) raise AuthError('Challenge pin') challenge = self.get_challenge() if challenge: self.password = challenge + self.password orig_password = self.password otp_code = self.password[-6:] self.password = self.password[:-6] allow = False if settings.app.sso_cache and not self.server_auth_token: doc = self.otp_cache_collection.find_one({ 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': otp_code, }) if doc: self.otp_cache_collection.update( { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': otp_code, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': otp_code, 'timestamp': utils.now(), }) allow = True logger.info( 'Authentication cached, skipping OTP', 'sso', user_name=self.user.name, org_name=self.user.org.name, server_name=self.server.name, ) if not allow: if not self.user.verify_otp_code(otp_code): self.user.audit_event( 'user_connection', ('User connection to "%s" denied. ' + 'User failed two-step authentication') % (self.server.name), remote_addr=self.remote_ip, ) if self.has_challenge(): if self.user.has_password(self.server): self.set_challenge(orig_password, 'Enter OTP Code', True) else: self.set_challenge(None, 'Enter OTP Code', True) raise AuthError('Challenge OTP code') raise AuthError('Invalid OTP code') if settings.app.sso_cache and not self.server_auth_token: self.otp_cache_collection.update( { 'user_id': self.user.id, 'server_id': self.server.id, 'mac_addr': self.mac_addr, 'device_id': self.device_id, 'device_name': self.device_name, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': otp_code, 'timestamp': utils.now(), }, upsert=True) if self.user.has_pin(): if not self.user.check_pin(self.password): self.user.audit_event( 'user_connection', ('User connection to "%s" denied. ' + 'User failed pin authentication') % (self.server.name), remote_addr=self.remote_ip, ) if self.has_challenge(): self.set_challenge(None, 'Enter Pin', False) raise AuthError('Challenge pin') raise AuthError('Invalid pin') elif settings.user.pin_mode == PIN_REQUIRED: self.user.audit_event( 'user_connection', ('User connection to "%s" denied. ' + 'User does not have a pin set') % (self.server.name), remote_addr=self.remote_ip, ) raise AuthError('User does not have a pin set')
def _dict(): if settings.app.demo_mode: return { 'acme_domain': settings.app.acme_domain, 'theme': settings.app.theme, 'auditing': settings.app.auditing, 'monitoring': settings.app.monitoring, 'influxdb_uri': 'demo', 'email_from': settings.app.email_from, 'email_server': 'demo', 'email_username': '******', 'email_password': '******', 'pin_mode': settings.user.pin_mode, 'sso': settings.app.sso, 'sso_match': settings.app.sso_match, 'sso_azure_directory_id': 'demo', 'sso_azure_app_id': 'demo', 'sso_azure_app_secret': 'demo', 'sso_authzero_domain': 'demo', 'sso_authzero_app_id': 'demo', 'sso_authzero_app_secret': 'demo', 'sso_google_key': 'demo', 'sso_google_email': 'demo', 'sso_duo_token': 'demo', 'sso_duo_secret': 'demo', 'sso_duo_host': 'demo', 'sso_duo_mode': settings.app.sso_duo_mode, 'sso_yubico_client': 'demo', 'sso_yubico_secret': 'demo', 'sso_org': settings.app.sso_org, 'sso_saml_url': 'demo', 'sso_saml_issuer_url': 'demo', 'sso_saml_cert': 'demo', 'sso_okta_app_id': settings.app.sso_okta_app_id, 'sso_okta_token': 'demo', 'sso_okta_mode': utils.get_okta_mode(), 'sso_onelogin_app_id': settings.app.sso_onelogin_app_id, 'sso_onelogin_id': 'demo', 'sso_onelogin_secret': 'demo', 'sso_onelogin_mode': utils.get_onelogin_mode(), 'sso_radius_secret': 'demo', 'sso_radius_host': 'demo', 'sso_cache': settings.app.sso_cache, 'sso_client_cache': settings.app.sso_client_cache, 'restrict_import': settings.user.restrict_import, 'client_reconnect': settings.user.reconnect, 'public_address': settings.local.host.public_addr, 'public_address6': settings.local.host.public_addr6, 'routed_subnet6': settings.local.host.routed_subnet6, 'reverse_proxy': settings.app.reverse_proxy, 'server_port': settings.app.server_port, 'server_cert': 'demo', 'server_key': 'demo', 'cloud_provider': settings.app.cloud_provider, 'route53_region': settings.app.route53_region, 'route53_zone': settings.app.route53_zone, 'oracle_user_ocid': settings.app.oracle_user_ocid, 'oracle_public_key': 'demo', 'us_east_1_access_key': 'demo', 'us_east_1_secret_key': 'demo', 'us_east_2_access_key': 'demo', 'us_east_2_secret_key': 'demo', 'us_west_1_access_key': 'demo', 'us_west_1_secret_key': 'demo', 'us_west_2_access_key': 'demo', 'us_west_2_secret_key': 'demo', 'us_gov_east_1_access_key': 'demo', 'us_gov_east_1_secret_key': 'demo', 'us_gov_west_1_access_key': 'demo', 'us_gov_west_1_secret_key': 'demo', 'eu_north_1_access_key': 'demo', 'eu_north_1_secret_key': 'demo', 'eu_west_1_access_key': 'demo', 'eu_west_1_secret_key': 'demo', 'eu_west_2_access_key': 'demo', 'eu_west_2_secret_key': 'demo', 'eu_west_3_access_key': 'demo', 'eu_west_3_secret_key': 'demo', 'eu_central_1_access_key': 'demo', 'eu_central_1_secret_key': 'demo', 'ca_central_1_access_key': 'demo', 'ca_central_1_secret_key': 'demo', 'cn_north_1_access_key': 'demo', 'cn_north_1_secret_key': 'demo', 'cn_northwest_1_access_key': 'demo', 'cn_northwest_1_secret_key': 'demo', 'ap_northeast_1_access_key': 'demo', 'ap_northeast_1_secret_key': 'demo', 'ap_northeast_2_access_key': 'demo', 'ap_northeast_2_secret_key': 'demo', 'ap_southeast_1_access_key': 'demo', 'ap_southeast_1_secret_key': 'demo', 'ap_southeast_2_access_key': 'demo', 'ap_southeast_2_secret_key': 'demo', 'ap_east_1_access_key': 'demo', 'ap_east_1_secret_key': 'demo', 'ap_south_1_access_key': 'demo', 'ap_south_1_secret_key': 'demo', 'sa_east_1_access_key': 'demo', 'sa_east_1_secret_key': 'demo', } else: return { 'acme_domain': settings.app.acme_domain, 'theme': settings.app.theme, 'auditing': settings.app.auditing, 'monitoring': settings.app.monitoring, 'influxdb_uri': settings.app.influxdb_uri, 'email_from': settings.app.email_from, 'email_server': settings.app.email_server, 'email_username': settings.app.email_username, 'email_password': settings.app.email_password, 'pin_mode': settings.user.pin_mode, 'sso': settings.app.sso, 'sso_match': settings.app.sso_match, 'sso_azure_directory_id': settings.app.sso_azure_directory_id, 'sso_azure_app_id': settings.app.sso_azure_app_id, 'sso_azure_app_secret': settings.app.sso_azure_app_secret, 'sso_authzero_domain': settings.app.sso_authzero_domain, 'sso_authzero_app_id': settings.app.sso_authzero_app_id, 'sso_authzero_app_secret': settings.app.sso_authzero_app_secret, 'sso_google_key': settings.app.sso_google_key, 'sso_google_email': settings.app.sso_google_email, 'sso_duo_token': settings.app.sso_duo_token, 'sso_duo_secret': settings.app.sso_duo_secret, 'sso_duo_host': settings.app.sso_duo_host, 'sso_duo_mode': settings.app.sso_duo_mode, 'sso_yubico_client': settings.app.sso_yubico_client, 'sso_yubico_secret': settings.app.sso_yubico_secret, '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_app_id': settings.app.sso_okta_app_id, 'sso_okta_token': settings.app.sso_okta_token, 'sso_okta_mode': utils.get_okta_mode(), 'sso_onelogin_app_id': settings.app.sso_onelogin_app_id, 'sso_onelogin_id': settings.app.sso_onelogin_id, 'sso_onelogin_secret': settings.app.sso_onelogin_secret, 'sso_onelogin_mode': utils.get_onelogin_mode(), 'sso_radius_secret': settings.app.sso_radius_secret, 'sso_radius_host': settings.app.sso_radius_host, 'sso_cache': settings.app.sso_cache, 'sso_client_cache': settings.app.sso_client_cache, 'restrict_import': settings.user.restrict_import, 'client_reconnect': settings.user.reconnect, 'public_address': settings.local.host.public_addr, 'public_address6': settings.local.host.public_addr6, 'routed_subnet6': settings.local.host.routed_subnet6, 'reverse_proxy': settings.app.reverse_proxy, 'server_port': settings.app.server_port, 'server_cert': settings.app.server_cert, 'server_key': settings.app.server_key, 'cloud_provider': settings.app.cloud_provider, 'route53_region': settings.app.route53_region, 'route53_zone': settings.app.route53_zone, 'oracle_user_ocid': settings.app.oracle_user_ocid, 'oracle_public_key': settings.app.oracle_public_key, 'us_east_1_access_key': settings.app.us_east_1_access_key, 'us_east_1_secret_key': settings.app.us_east_1_secret_key, 'us_east_2_access_key': settings.app.us_east_2_access_key, 'us_east_2_secret_key': settings.app.us_east_2_secret_key, 'us_west_1_access_key': settings.app.us_west_1_access_key, 'us_west_1_secret_key': settings.app.us_west_1_secret_key, 'us_west_2_access_key': settings.app.us_west_2_access_key, 'us_west_2_secret_key': settings.app.us_west_2_secret_key, 'us_gov_east_1_access_key': settings.app.us_gov_east_1_access_key, 'us_gov_east_1_secret_key': settings.app.us_gov_east_1_secret_key, 'us_gov_west_1_access_key': settings.app.us_gov_west_1_access_key, 'us_gov_west_1_secret_key': settings.app.us_gov_west_1_secret_key, 'eu_north_1_access_key': settings.app.eu_north_1_access_key, 'eu_north_1_secret_key': settings.app.eu_north_1_secret_key, 'eu_west_1_access_key': settings.app.eu_west_1_access_key, 'eu_west_1_secret_key': settings.app.eu_west_1_secret_key, 'eu_west_2_access_key': settings.app.eu_west_2_access_key, 'eu_west_2_secret_key': settings.app.eu_west_2_secret_key, 'eu_west_3_access_key': settings.app.eu_west_3_access_key, 'eu_west_3_secret_key': settings.app.eu_west_3_secret_key, 'eu_central_1_access_key': settings.app.eu_central_1_access_key, 'eu_central_1_secret_key': settings.app.eu_central_1_secret_key, 'ca_central_1_access_key': settings.app.ca_central_1_access_key, 'ca_central_1_secret_key': settings.app.ca_central_1_secret_key, 'cn_north_1_access_key': settings.app.cn_north_1_access_key, 'cn_north_1_secret_key': settings.app.cn_north_1_secret_key, 'cn_northwest_1_access_key': settings.app.cn_northwest_1_access_key, 'cn_northwest_1_secret_key': settings.app.cn_northwest_1_secret_key, 'ap_northeast_1_access_key': settings.app.ap_northeast_1_access_key, 'ap_northeast_1_secret_key': settings.app.ap_northeast_1_secret_key, 'ap_northeast_2_access_key': settings.app.ap_northeast_2_access_key, 'ap_northeast_2_secret_key': settings.app.ap_northeast_2_secret_key, 'ap_southeast_1_access_key': settings.app.ap_southeast_1_access_key, 'ap_southeast_1_secret_key': settings.app.ap_southeast_1_secret_key, 'ap_southeast_2_access_key': settings.app.ap_southeast_2_access_key, 'ap_southeast_2_secret_key': settings.app.ap_southeast_2_secret_key, 'ap_east_1_access_key': settings.app.ap_east_1_access_key, 'ap_east_1_secret_key': settings.app.ap_east_1_secret_key, 'ap_south_1_access_key': settings.app.ap_south_1_access_key, 'ap_south_1_secret_key': settings.app.ap_south_1_secret_key, 'sa_east_1_access_key': settings.app.sa_east_1_access_key, 'sa_east_1_secret_key': settings.app.sa_east_1_secret_key, }
def _check_password(self): if settings.vpn.stress_test or self.user.link_server_id: return if self.user.bypass_secondary: logger.info( 'Bypass secondary enabled, skipping password', 'sso', user_name=self.user.name, org_name=self.user.org.name, server_name=self.server.name, ) journal.entry( journal.USER_CONNECT_BYPASS, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Bypass secondary enabled, skipping password', ) return if self.has_token: logger.info( 'Client authentication cached, skipping password', 'sso', user_name=self.user.name, org_name=self.user.org.name, server_name=self.server.name, ) journal.entry( journal.USER_CONNECT_CACHE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Client authentication cached, skipping password', ) return if self.whitelisted: logger.info( 'Client network whitelisted, skipping password', 'sso', user_name=self.user.name, org_name=self.user.org.name, server_name=self.server.name, ) journal.entry( journal.USER_CONNECT_WHITELIST, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Client network whitelisted, skipping password', ) return if not limiter.auth_check(self.user.id): self.user.audit_event( 'user_connection', ('User connection to "%s" denied. Too many ' + 'authentication attempts') % (self.server.name), remote_addr=self.remote_ip, ) journal.entry( journal.USER_CONNECT_FAILURE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Too many authentication attempts', ) raise AuthError('Too many authentication attempts') sso_mode = settings.app.sso or '' duo_mode = settings.app.sso_duo_mode onelogin_mode = utils.get_onelogin_mode() okta_mode = utils.get_okta_mode() auth_type = self.user.auth_type or '' has_duo_passcode = DUO_AUTH in sso_mode and \ DUO_AUTH in auth_type and duo_mode == 'passcode' has_onelogin_passcode = SAML_ONELOGIN_AUTH == sso_mode and \ SAML_ONELOGIN_AUTH in auth_type and onelogin_mode == 'passcode' has_okta_passcode = SAML_OKTA_AUTH == sso_mode and \ SAML_OKTA_AUTH in auth_type and okta_mode == 'passcode' if has_duo_passcode or has_onelogin_passcode or has_okta_passcode: if not self.password and self.has_challenge() and \ self.user.has_pin(): journal.entry( journal.USER_CONNECT_FAILURE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Failed pin authentication', ) self.user.audit_event('user_connection', ('User connection to "%s" denied. ' + 'User failed pin authentication') % ( self.server.name), remote_addr=self.remote_ip, ) self.set_challenge(None, 'Enter Pin', False) raise AuthError('Challenge pin') challenge = self.get_challenge() if challenge: self.password = challenge + self.password passcode_len = settings.app.sso_duo_passcode_length orig_password = self.password passcode = self.password[-passcode_len:] self.password = self.password[:-passcode_len] allow = False if settings.app.sso_cache and not self.server_auth_token: doc = self.sso_passcode_cache_collection.find_one({ 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': passcode, }) if doc: self.sso_passcode_cache_collection.update({ 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': passcode, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': passcode, 'timestamp': utils.now(), }) allow = True logger.info( 'Authentication cached, skipping secondary passcode', 'sso', user_name=self.user.name, org_name=self.user.org.name, server_name=self.server.name, ) journal.entry( journal.USER_CONNECT_CACHE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Authentication cached, ' + \ 'skipping secondary passcode', ) if not allow: if DUO_AUTH in sso_mode: label = 'Duo' duo_auth = sso.Duo( username=self.user.name, factor=duo_mode, remote_ip=self.remote_ip, auth_type='Connection', passcode=passcode, ) allow = duo_auth.authenticate() elif SAML_ONELOGIN_AUTH == sso_mode: label = 'OneLogin' allow = sso.auth_onelogin_secondary( username=self.user.name, passcode=passcode, remote_ip=self.remote_ip, onelogin_mode=onelogin_mode, ) elif SAML_OKTA_AUTH == sso_mode: label = 'Okta' allow = sso.auth_okta_secondary( username=self.user.name, passcode=passcode, remote_ip=self.remote_ip, okta_mode=okta_mode, ) else: raise AuthError('Unknown secondary passcode challenge') if not allow: self.user.audit_event('user_connection', ('User connection to "%s" denied. ' + 'User failed %s passcode authentication') % ( self.server.name, label), remote_addr=self.remote_ip, ) journal.entry( journal.USER_CONNECT_FAILURE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Failed passcode authentication', ) if self.has_challenge(): if self.user.has_password(self.server): self.set_challenge( orig_password, 'Enter %s Passcode' % label, True) else: self.set_challenge( None, 'Enter %s Passcode' % label, True) raise AuthError('Challenge secondary passcode') raise AuthError('Invalid secondary passcode') if settings.app.sso_cache and not self.server_auth_token: self.sso_passcode_cache_collection.update({ 'user_id': self.user.id, 'server_id': self.server.id, 'mac_addr': self.mac_addr, 'device_id': self.device_id, 'device_name': self.device_name, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': passcode, 'timestamp': utils.now(), }, upsert=True) elif YUBICO_AUTH in sso_mode and YUBICO_AUTH in auth_type: if not self.password and self.has_challenge() and \ self.user.has_pin(): self.user.audit_event('user_connection', ('User connection to "%s" denied. ' + 'User failed pin authentication') % ( self.server.name), remote_addr=self.remote_ip, ) journal.entry( journal.USER_CONNECT_FAILURE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Failed pin authentication', ) self.set_challenge(None, 'Enter Pin', False) raise AuthError('Challenge pin') challenge = self.get_challenge() if challenge: self.password = challenge + self.password orig_password = self.password yubikey = self.password[-44:] self.password = self.password[:-44] yubikey_hash = hashlib.sha512() yubikey_hash.update(yubikey) yubikey_hash = base64.b64encode(yubikey_hash.digest()) allow = False if settings.app.sso_cache and not self.server_auth_token: doc = self.sso_passcode_cache_collection.find_one({ 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': yubikey_hash, }) if doc: self.sso_passcode_cache_collection.update({ 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': yubikey_hash, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': yubikey_hash, 'timestamp': utils.now(), }) allow = True logger.info( 'Authentication cached, skipping Yubikey', 'sso', user_name=self.user.name, org_name=self.user.org.name, server_name=self.server.name, ) journal.entry( journal.USER_CONNECT_CACHE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Authentication cached, ' + \ 'skipping Yubikey', ) if not allow: valid, yubico_id = sso.auth_yubico(yubikey) if yubico_id != self.user.yubico_id: valid = False if not valid: self.user.audit_event('user_connection', ('User connection to "%s" denied. ' + 'User failed Yubico authentication') % ( self.server.name), remote_addr=self.remote_ip, ) journal.entry( journal.USER_CONNECT_FAILURE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Failed Yubico authentication', ) if self.has_challenge(): if self.user.has_password(self.server): self.set_challenge( orig_password, 'YubiKey', True) else: self.set_challenge( None, 'YubiKey', True) raise AuthError('Challenge YubiKey') raise AuthError('Invalid YubiKey') if settings.app.sso_cache and not self.server_auth_token: self.sso_passcode_cache_collection.update({ 'user_id': self.user.id, 'server_id': self.server.id, 'mac_addr': self.mac_addr, 'device_id': self.device_id, 'device_name': self.device_name, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': yubikey_hash, 'timestamp': utils.now(), }, upsert=True) elif self.server.otp_auth and self.user.type == CERT_CLIENT: if not self.password and self.has_challenge() and \ self.user.has_pin(): self.user.audit_event('user_connection', ('User connection to "%s" denied. ' + 'User failed pin authentication') % ( self.server.name), remote_addr=self.remote_ip, ) journal.entry( journal.USER_CONNECT_FAILURE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Failed pin authentication', ) self.set_challenge(None, 'Enter Pin', False) raise AuthError('Challenge pin') challenge = self.get_challenge() if challenge: self.password = challenge + self.password orig_password = self.password otp_code = self.password[-6:] self.password = self.password[:-6] allow = False if settings.app.sso_cache and not self.server_auth_token: doc = self.otp_cache_collection.find_one({ 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': otp_code, }) if doc: self.otp_cache_collection.update({ 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': otp_code, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': otp_code, 'timestamp': utils.now(), }) allow = True logger.info( 'Authentication cached, skipping OTP', 'sso', user_name=self.user.name, org_name=self.user.org.name, server_name=self.server.name, ) journal.entry( journal.USER_CONNECT_CACHE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Authentication cached, ' + \ 'skipping OTP', ) if not allow: if not self.user.verify_otp_code(otp_code): self.user.audit_event('user_connection', ('User connection to "%s" denied. ' + 'User failed two-step authentication') % ( self.server.name), remote_addr=self.remote_ip, ) journal.entry( journal.USER_CONNECT_FAILURE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Failed two-step authentication', ) if self.has_challenge(): if self.user.has_password(self.server): self.set_challenge( orig_password, 'Enter OTP Code', True) else: self.set_challenge( None, 'Enter OTP Code', True) raise AuthError('Challenge OTP code') raise AuthError('Invalid OTP code') if settings.app.sso_cache and not self.server_auth_token: self.otp_cache_collection.update({ 'user_id': self.user.id, 'server_id': self.server.id, 'mac_addr': self.mac_addr, 'device_id': self.device_id, 'device_name': self.device_name, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'passcode': otp_code, 'timestamp': utils.now(), }, upsert=True) if self.user.has_pin(): if not self.user.check_pin(self.password): self.user.audit_event('user_connection', ('User connection to "%s" denied. ' + 'User failed pin authentication') % ( self.server.name), remote_addr=self.remote_ip, ) journal.entry( journal.USER_CONNECT_FAILURE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='Failed pin authentication', ) if self.has_challenge(): self.set_challenge(None, 'Enter Pin', False) raise AuthError('Challenge pin') raise AuthError('Invalid pin') elif settings.user.pin_mode == PIN_REQUIRED: self.user.audit_event('user_connection', ('User connection to "%s" denied. ' + 'User does not have a pin set') % ( self.server.name), remote_addr=self.remote_ip, ) journal.entry( journal.USER_CONNECT_FAILURE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='User does not have a pin set', ) raise AuthError('User does not have a pin set')
def _auth_push_thread(self): info = { 'Server': self.server.name, } platform_name = None if self.platform == 'linux': platform_name = 'Linux' elif self.platform == 'mac': platform_name = 'macOS' elif self.platform == 'ios': platform_name = 'iOS' elif self.platform == 'win': platform_name = 'Windows' elif self.platform == 'chrome': platform_name = 'Chrome OS' if self.device_name: info['Device'] = '%s (%s)' % (self.device_name, platform_name) onelogin_mode = utils.get_onelogin_mode() okta_mode = utils.get_okta_mode() if self.push_type == DUO_AUTH: duo_auth = sso.Duo( username=self.user.name, factor=settings.app.sso_duo_mode, remote_ip=self.remote_ip, auth_type='Connection', info=info, ) allow = duo_auth.authenticate() elif self.push_type == SAML_ONELOGIN_AUTH: allow = sso.auth_onelogin_secondary( username=self.user.name, passcode=None, remote_ip=self.remote_ip, onelogin_mode=onelogin_mode, ) elif self.push_type == SAML_OKTA_AUTH: allow = sso.auth_okta_secondary( username=self.user.name, passcode=None, remote_ip=self.remote_ip, okta_mode=okta_mode, ) else: raise ValueError('Unkown push auth type') if not allow: self.user.audit_event('user_connection', ('User connection to "%s" denied. ' + 'Push authentication failed') % ( self.server.name), remote_addr=self.remote_ip, ) journal.entry( journal.USER_CONNECT_FAILURE, self.journal_data, self.user.journal_data, self.server.journal_data, event_long='User failed push authentication', ) raise AuthError('User failed push authentication') if settings.app.sso_cache and not self.server_auth_token: self.sso_push_cache_collection.update({ 'user_id': self.user.id, 'server_id': self.server.id, 'mac_addr': self.mac_addr, 'device_id': self.device_id, 'device_name': self.device_name, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'timestamp': utils.now(), }, upsert=True)
def _dict(): if settings.app.demo_mode: return { 'acme_domain': settings.app.acme_domain, 'theme': settings.app.theme, 'auditing': settings.app.auditing, 'monitoring': settings.app.monitoring, 'influxdb_uri': 'demo', 'email_from': settings.app.email_from, 'email_server': 'demo', 'email_username': '******', 'email_password': '******', 'pin_mode': settings.user.pin_mode, 'sso': settings.app.sso, 'sso_match': settings.app.sso_match, 'sso_azure_directory_id': 'demo', 'sso_azure_app_id': 'demo', 'sso_azure_app_secret': 'demo', 'sso_authzero_domain': 'demo', 'sso_authzero_app_id': 'demo', 'sso_authzero_app_secret': 'demo', 'sso_google_key': 'demo', 'sso_google_email': 'demo', 'sso_duo_token': 'demo', 'sso_duo_secret': 'demo', 'sso_duo_host': 'demo', 'sso_duo_mode': settings.app.sso_duo_mode, 'sso_yubico_client': 'demo', 'sso_yubico_secret': 'demo', 'sso_org': settings.app.sso_org, 'sso_saml_url': 'demo', 'sso_saml_issuer_url': 'demo', 'sso_saml_cert': 'demo', 'sso_okta_app_id': settings.app.sso_okta_app_id, 'sso_okta_token': 'demo', 'sso_okta_mode': utils.get_okta_mode(), 'sso_onelogin_app_id': settings.app.sso_onelogin_app_id, 'sso_onelogin_id': 'demo', 'sso_onelogin_secret': 'demo', 'sso_onelogin_mode': utils.get_onelogin_mode(), 'sso_radius_secret': 'demo', 'sso_radius_host': 'demo', 'sso_cache': settings.app.sso_cache, 'sso_client_cache': settings.app.sso_client_cache, 'client_reconnect': settings.user.reconnect, 'public_address': settings.local.host.public_addr, 'public_address6': settings.local.host.public_addr6, 'routed_subnet6': settings.local.host.routed_subnet6, 'reverse_proxy': settings.app.reverse_proxy, 'server_port': settings.app.server_port, 'server_cert': 'demo', 'server_key': 'demo', 'cloud_provider': settings.app.cloud_provider, 'route53_region': settings.app.route53_region, 'route53_zone': settings.app.route53_zone, 'oracle_user_ocid': settings.app.oracle_user_ocid, 'oracle_public_key': 'demo', 'us_east_1_access_key': 'demo', 'us_east_1_secret_key': 'demo', 'us_east_2_access_key': 'demo', 'us_east_2_secret_key': 'demo', 'us_west_1_access_key': 'demo', 'us_west_1_secret_key': 'demo', 'us_west_2_access_key': 'demo', 'us_west_2_secret_key': 'demo', 'us_gov_west_1_access_key': 'demo', 'us_gov_west_1_secret_key': 'demo', 'eu_west_1_access_key': 'demo', 'eu_west_1_secret_key': 'demo', 'eu_west_2_access_key': 'demo', 'eu_west_2_secret_key': 'demo', 'eu_central_1_access_key': 'demo', 'eu_central_1_secret_key': 'demo', 'ca_central_1_access_key': 'demo', 'ca_central_1_secret_key': 'demo', 'ap_northeast_1_access_key': 'demo', 'ap_northeast_1_secret_key': 'demo', 'ap_northeast_2_access_key': 'demo', 'ap_northeast_2_secret_key': 'demo', 'ap_southeast_1_access_key': 'demo', 'ap_southeast_1_secret_key': 'demo', 'ap_southeast_2_access_key': 'demo', 'ap_southeast_2_secret_key': 'demo', 'ap_south_1_access_key': 'demo', 'ap_south_1_secret_key': 'demo', 'sa_east_1_access_key': 'demo', 'sa_east_1_secret_key': 'demo', } else: return { 'acme_domain': settings.app.acme_domain, 'theme': settings.app.theme, 'auditing': settings.app.auditing, 'monitoring': settings.app.monitoring, 'influxdb_uri': settings.app.influxdb_uri, 'email_from': settings.app.email_from, 'email_server': settings.app.email_server, 'email_username': settings.app.email_username, 'email_password': settings.app.email_password, 'pin_mode': settings.user.pin_mode, 'sso': settings.app.sso, 'sso_match': settings.app.sso_match, 'sso_azure_directory_id': settings.app.sso_azure_directory_id, 'sso_azure_app_id': settings.app.sso_azure_app_id, 'sso_azure_app_secret': settings.app.sso_azure_app_secret, 'sso_authzero_domain': settings.app.sso_authzero_domain, 'sso_authzero_app_id': settings.app.sso_authzero_app_id, 'sso_authzero_app_secret': settings.app.sso_authzero_app_secret, 'sso_google_key': settings.app.sso_google_key, 'sso_google_email': settings.app.sso_google_email, 'sso_duo_token': settings.app.sso_duo_token, 'sso_duo_secret': settings.app.sso_duo_secret, 'sso_duo_host': settings.app.sso_duo_host, 'sso_duo_mode': settings.app.sso_duo_mode, 'sso_yubico_client': settings.app.sso_yubico_client, 'sso_yubico_secret': settings.app.sso_yubico_secret, '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_app_id': settings.app.sso_okta_app_id, 'sso_okta_token': settings.app.sso_okta_token, 'sso_okta_mode': utils.get_okta_mode(), 'sso_onelogin_app_id': settings.app.sso_onelogin_app_id, 'sso_onelogin_id': settings.app.sso_onelogin_id, 'sso_onelogin_secret': settings.app.sso_onelogin_secret, 'sso_onelogin_mode': utils.get_onelogin_mode(), 'sso_radius_secret': settings.app.sso_radius_secret, 'sso_radius_host': settings.app.sso_radius_host, 'sso_cache': settings.app.sso_cache, 'sso_client_cache': settings.app.sso_client_cache, 'client_reconnect': settings.user.reconnect, 'public_address': settings.local.host.public_addr, 'public_address6': settings.local.host.public_addr6, 'routed_subnet6': settings.local.host.routed_subnet6, 'reverse_proxy': settings.app.reverse_proxy, 'server_port': settings.app.server_port, 'server_cert': settings.app.server_cert, 'server_key': settings.app.server_key, 'cloud_provider': settings.app.cloud_provider, 'route53_region': settings.app.route53_region, 'route53_zone': settings.app.route53_zone, 'oracle_user_ocid': settings.app.oracle_user_ocid, 'oracle_public_key': settings.app.oracle_public_key, 'us_east_1_access_key': settings.app.us_east_1_access_key, 'us_east_1_secret_key': settings.app.us_east_1_secret_key, 'us_east_2_access_key': settings.app.us_east_2_access_key, 'us_east_2_secret_key': settings.app.us_east_2_secret_key, 'us_west_1_access_key': settings.app.us_west_1_access_key, 'us_west_1_secret_key': settings.app.us_west_1_secret_key, 'us_west_2_access_key': settings.app.us_west_2_access_key, 'us_west_2_secret_key': settings.app.us_west_2_secret_key, 'us_gov_west_1_access_key': settings.app.us_gov_west_1_access_key, 'us_gov_west_1_secret_key': settings.app.us_gov_west_1_secret_key, 'eu_west_1_access_key': settings.app.eu_west_1_access_key, 'eu_west_1_secret_key': settings.app.eu_west_1_secret_key, 'eu_west_2_access_key': settings.app.eu_west_2_access_key, 'eu_west_2_secret_key': settings.app.eu_west_2_secret_key, 'eu_central_1_access_key': settings.app.eu_central_1_access_key, 'eu_central_1_secret_key': settings.app.eu_central_1_secret_key, 'ca_central_1_access_key': settings.app.ca_central_1_access_key, 'ca_central_1_secret_key': settings.app.ca_central_1_secret_key, 'ap_northeast_1_access_key': settings.app.ap_northeast_1_access_key, 'ap_northeast_1_secret_key': settings.app.ap_northeast_1_secret_key, 'ap_northeast_2_access_key': settings.app.ap_northeast_2_access_key, 'ap_northeast_2_secret_key': settings.app.ap_northeast_2_secret_key, 'ap_southeast_1_access_key': settings.app.ap_southeast_1_access_key, 'ap_southeast_1_secret_key': settings.app.ap_southeast_1_secret_key, 'ap_southeast_2_access_key': settings.app.ap_southeast_2_access_key, 'ap_southeast_2_secret_key': settings.app.ap_southeast_2_secret_key, 'ap_south_1_access_key': settings.app.ap_south_1_access_key, 'ap_south_1_secret_key': settings.app.ap_south_1_secret_key, 'sa_east_1_access_key': settings.app.sa_east_1_access_key, 'sa_east_1_secret_key': settings.app.sa_east_1_secret_key, }