def peers_alive(config): from pyrad.client import Client from pyrad.dictionary import Dictionary radconfig = config['radius'] localconfig = config['local'] auth_OK = True dictionary = Dictionary(localconfig['raddict']) for server in radconfig['servers']: srv = Client(server=server, secret=str(radconfig['secret']), dict=dictionary) req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=radconfig['username'], NAS_Identifier="localhost") req["User-Password"] = req.PwCrypt(radconfig['password']) try: reply = srv.SendPacket(req) except pyrad.client.Timeout: print "Could not contact:", server auth_OK = False if reply.code != 2: print "Auth failed to", server auth_OK = False return auth_OK
def _radius_auth_func(self, server, **kwargs): """More private method used to authenticate a user and password against the current RADIUS server. Returns False if the user is rejected, True if the user is accepted. Raises CurrentServerFailed if there was an error with the request (such as a timeout).""" try: auth_port = self.server_dict[server]['auth_port'] secret = self.server_dict[server]['secret'] srv = Client(server=server, authport=auth_port, secret=secret, dict=self.dictionary) srv.timeout = self.server_timeout if self.client_bind_ip is not None: # Binding to port 0 is the official way to bind to a OS-assigned random port. srv.bind((self.client_bind_ip, 0)) req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=kwargs['user'], NAS_Identifier=self.nas_identifier) req["User-Password"] = req.PwCrypt(kwargs['password']) reply = srv.SendPacket(req) if reply.code == pyrad.packet.AccessAccept: return True else: return False except (pyrad.packet.PacketError, pyrad.client.Timeout, socket.error): raise CurrentServerFailed
def authenticate(self, username=None, password=None): """Authenticate against the RADIUS server""" # Create a RADIUS client radius_dict = Dictionary(settings.RADIUS_DICT) client = Client(server=settings.RADIUS_HOST, authport=settings.RADIUS_PORT, secret=settings.RADIUS_SECRET.encode('utf-8'), # avoid UnicodeDecodeError dict=radius_dict, ) # Create a packet ... req = client.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=username.encode('utf-8'), ) req["User-Password"] = req.PwCrypt(password) # .. and send it try: reply = client.SendPacket(req) except Exception as e: # Something went wrong with the packet. Just fall through return None # Handle the reply if reply.code == pyrad.packet.AccessReject: # Access was rejected return None elif reply.code != pyrad.packet.AccessAccept: # Some error return None else: backend = self.__module__ + "." + self.__class__.__name__ user, created = get_or_create_user(backend, username) return user
def authenticate_using_radius_server(self, request, callback): """Authenticate a subject using a RADIUS server.""" try: root_dir = os.path.abspath( os.path.join(_conf.install_location(), '..')) client = Client( server=self.sec_conf['authentication']['server_ip'], secret=bytes(self.sec_conf['authentication']['secret']), dict=Dictionary( os.path.join(root_dir, "extras", "pyrad_dicts", "dictionary"), os.path.join(root_dir, "extras", "pyrad_dicts", "dictionary.acc"))) req = client.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=request['subject']['user'], NAS_Identifier=self.node.id) req["User-Password"] = req.PwCrypt(request['subject']['password']) # FIXME: should not block here (use a callback instead) reply = client.SendPacket(req) if reply.code == pyrad.packet.AccessAccept: _log.debug("Security: access accepted") # Save attributes returned by server. self._return_authentication_decision( True, json.loads(reply["Reply-Message"][0]), callback) return _log.debug("Security: access denied") self._return_authentication_decision(False, [], callback) except Exception as err: _log.error("Failed RADIUS authentication, err={}".format(err)) self._return_authentication_decision(False, [], callback)
def do_authentication(self, user, passcode=""): radcli = Client(server=self._server, authport=self._port, secret=self._secret, dict=Dictionary(RADIUS_DICTIONARY)) radcli.retries = self._conn_retries radcli.timeout = self._conn_timeout l = ldap.initialize("ldap://192.168.56.101") try: l.simple_bind_s("*****@*****.**", "Welcome123") ldap_result = l.search("dc=internal,dc=neteas", ldap.SCOPE_SUBTREE, "(&(objectClass=group)(cn=BALABIT_MFA))", None) res_type, data = l.result(ldap_result, 0) user1 = user[1:] a = str(data[0][1]['member']) if user1 in a: ldap_result = l.search( "dc=internal,dc=neteas", ldap.SCOPE_SUBTREE, "(&(objectClass=user)(cn=" + user + "))", None) res_type, data = l.result(ldap_result, 0) user = data[0][1]['userPrincipalName'][0] radpkt = self._createAuthenticationPacket(client=radcli, radius_user=user, radius_pass=passcode) print user else: return True except Exception, error: return True
def eap_auth(self, pkt): # self.print_pkt(pkt) print(binascii.b2a_hex(pkt["EAP-Message"][0])) print(binascii.b2a_hex(pkt["Message-Authenticator"][0])) print(binascii.b2a_hex(pkt.authenticator)) from pyrad.client import Client import six client = Client("172.16.110.4", secret=self.secret, dict=dictionary.Dictionary("dictionary")) kwargs = dict() new_pkt = client.CreateAuthPacket(code=packet.AccessRequest) all_keys = ["User-Name", "NAS-Identifier", "NAS-IP-Address", "NAS-Port", "Framed-MTU", "NAS-Port-Type", "Called-Station-Id", "Calling-Station-Id"] all_keys.append("EAP-Message") all_keys.append("Message-Authenticator") for key in pkt.keys(): if key in all_keys: new_pkt[key] = pkt[key][0] else: print(key) new_pkt.authenticator = pkt.authenticator print(new_pkt.authenticator) reply = client.SendPacket(new_pkt) return self.SendReplyPacket(pkt.fd, reply) reply = self.CreateReplyPacket(pkt) reply.code = packet.AccessAccept return self.SendReplyPacket(pkt.fd, reply)
def test_success_okta(self, a, b): self.server.hosts["127.0.0.1"] = os.getenv('RADIUS_SECRET') self.server.BindToAddress("127.0.0.1") Client(server="127.0.0.1", secret=os.getenv('RADIUS_SECRET').encode(), dict=Dictionary("dictionary")) # create request req = AuthPacket( id=AccessRequest, secret=os.getenv('RADIUS_SECRET').encode(), authenticator=b'01234567890ABCDEF', dict=Dictionary("dictionary") ) req["User-Name"] = '*****@*****.**' req["User-Password"] = req.PwCrypt('fake') req["Proxy-State"] = 'state'.encode("ascii") req.source = ("test", "port") fd = MockFd() req.fd = fd # send request with self.assertLogs('server', level='INFO') as log: self.server.auth_handler(req) self.assertEqual(fd.data, b'\x02\x01\x00\x1b\x82\xb4\x88\xb4G\xbc:\xde\xc1\xe5A\xe0\xe7y\r\x1f!\x07state') self.assertIn('INFO:server:Push approved by [email protected].', log.output)
def test_using_samaccountname_flag(self, o, mock_get, mock_post): self.assertIsNotNone(os.environ.get('OKTA_USE_SAMACCOUNTNAME')) self.server.hosts["127.0.0.1"] = os.getenv('RADIUS_SECRET') self.server.BindToAddress("127.0.0.1") Client(server="127.0.0.1", secret=os.getenv('RADIUS_SECRET').encode(), dict=Dictionary("dictionary")) # create request req = AuthPacket( id=AccessRequest, secret=os.getenv('RADIUS_SECRET').encode(), authenticator=b'01234567890ABCDEF', dict=Dictionary("dictionary") ) req["User-Name"] = 'username' req["User-Password"] = req.PwCrypt('fake') req["Proxy-State"] = 'state'.encode() req.source = ("test", "port") fd = MockFd() req.fd = fd # send request with self.assertLogs('server', level='INFO') as log: o.return_value = '00ub0oNGTSWTBKOLGLNR' self.server.auth_handler(req) o.assert_called_once_with('username') self.assertEqual(fd.data, b'\x02\x01\x00\x1b\x82\xb4\x88\xb4G\xbc:\xde\xc1\xe5A\xe0\xe7y\r\x1f!\x07state') self.assertIn('INFO:server:Push approved by username.', log.output)
def setUp(self): self.path = os.path.join(home, 'tests', 'data') self.dict = Dictionary(os.path.join(self.path, 'chap')) # self.packet = packet.Packet(id=0, secret=six.b('secret'), # dict=self.dict) self.client = Client(server='localhost', secret=six.b('secret'), dict=self.dict)
def execute(self): args = self.args # pylint: disable=W0703 try: username = args.get("username", "") password = args.get("password", "") rad_secret = args.get("secret", "").encode("utf-8") identifier = args.get("identifier", "") dictionary = args.get("dictionary", DEFAULT_DICTIONARY) ip, _port = self.get_address() srv = Client(server=ip, secret=rad_secret, dict=Dictionary(dictionary)) req = srv.CreateAuthPacket( code=pyrad.packet.AccessRequest, User_Name=username, NAS_Identifier=identifier, ) req["User-Password"] = req.PwCrypt(password) srv.SendPacket(req) except Exception as err: return ( Event.DOWN, "Failed connecting to %s: %s)" % (self.get_address(), str(err)), ) version = "FreeRadius 1.0" # Fetch from radiusmonitor later. self.version = version return Event.UP, "Radius: " + version
def testParameterOrder(self): marker = object() client = Client(self.server, 123, 456, "secret", marker) self.failUnless(client.server is self.server) self.assertEqual(client.authport, 123) self.assertEqual(client.acctport, 456) self.assertEqual(client.secret, "secret") self.failUnless(client.dict is marker)
def __init__(self, config): self.logger = logging.getLogger(__name__) dictfile = os.path.dirname( os.path.realpath(__file__)) + "/raddictionary" self.client = Client( server=config['admin']['router_address'], secret=config['admin']['radius_secret'].encode('ascii'), dict=dictionary.Dictionary(dictfile))
def login(): server = app.config['AUTH_SERVER'] secret = app.config['AUTH_SECRET'] nas_id = app.config['NAS_ID'] form = LoginForm() if form.validate_on_submit(): srv = Client(server=server, secret=secret, dict=Dictionary("dictionary.py")) #test account if ('test' in form.username.data): print("access accepted") user = User.query.filter_by(username=form.username.data).first() if user: login_user(user, remember=form.remember.data) else: new_user = User(username=form.username.data) db.session.add(new_user) db.session.commit() login_user(new_user, remember=form.remember.data) logger.info('{}:{} created'.format(current_user.id, new_user.username)) logger.info('{}:{} login'.format(current_user.username, current_user.id)) return redirect(url_for('asset.invest_list')) # create request req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=form.username.data, NAS_Identifier=nas_id) req["User-Password"] = req.PwCrypt(form.password.data) # send request reply = srv.SendPacket(req) if reply.code == pyrad.packet.AccessAccept: print("access accepted") user = User.query.filter_by(username=form.username.data).first() if user: login_user(user, remember=form.remember.data) else: new_user = User(username=form.username.data) db.session.add(new_user) db.session.commit() login_user(new_user, remember=form.remember.data) return redirect(url_for('asset.invest_list')) else: print("access denied") flash('用户名或密码错误,请重新登陆') return redirect(url_for('auth.login')) print("Attributes returned by server:") for i in reply.keys(): print("%s: %s" % (i, reply[i])) return render_template('auth/login.html', form=form)
def __init__(self, server_addr, secret): """ Initialize the connection """ self.server_addr = server_addr self.nas_identifier = self.server_addr self.secret = secret.encode() self.server = Client(server=self.server_addr, secret=self.secret, dict=Dictionary('/etc/ejabberd/dictionary'))
def testSimpleConstruction(self): client = Client(self.server) self.failUnless(client.server is self.server) self.assertEqual(client.authport, 1812) self.assertEqual(client.acctport, 1813) self.assertEqual(client.secret, six.b('')) self.assertEqual(client.retries, 3) self.assertEqual(client.timeout, 5) self.failUnless(client.dict is None)
def _get_client(self, server): """ Get the pyrad client for a given server. RADIUS server is described by a 3-tuple: (<hostname>, <port>, <secret>). """ return Client(server=server[0], authport=server[1], secret=server[2], dict=self._get_dictionary())
def __init__(self, user, password, log): client = Client(server=os.environ.get('RADIUS_SERVER'), secret=os.environ.get('RADIUS_SECRET').encode('ascii'), dict=Dictionary('dictionary')) req = client.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=user) req['User-Password'] = req.PwCrypt(password) reply = client.SendPacket(req) self.auth = reply.code self.log = log
def __init__(self, radius_settings_tuple, logging): """Инициализация объекта из файла ibitial.conf.""" self.packet_send = 0 self.logging = logging radius_ip = radius_settings_tuple[0] radius_secret = radius_settings_tuple[1] radius_dict_path = radius_settings_tuple[2] self.srv = Client( server=radius_ip, secret=radius_secret.encode(), dict=Dictionary(radius_dict_path), )
def check_auth(self, username, password, allowed_roles, resource, method): srv = Client(server="192.168.137.200", secret="wowsuchsecret", dict=Dictionary("/usr/share/freeradius/dictionary")) req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=username, NAS_Identifier="") req["Password"] = req.PwCrypt(password) reply = srv.SendPacket(req) return reply.code == pyrad.packet.AccessAccept
def testNamedParameters(self): marker = object() client = Client(server=self.server, authport=123, acctport=456, secret="secret", dict=marker) self.failUnless(client.server is self.server) self.assertEqual(client.authport, 123) self.assertEqual(client.acctport, 456) self.assertEqual(client.secret, "secret") self.failUnless(client.dict is marker)
def authenticate(cls, form): """ Authenticates to the configured RADIUS server. """ try: username = unicode(form['username'].split('@', 1)[0].strip()) except Exception: flash("{field} is required.".format( field=cls.inputs['username']['label'])) log.error("Username field missing from authentication form!") return None, False try: password = unicode(form['password']) except Exception: flash("{field} is required.".format( field=cls.inputs['password']['label'])) log.error("Password field missing from authentication form!") return username, False srv = Client(server=cls.config.radius_server, secret=cls.config.radius_secret, dict=Dictionary(dict=cls.config.radius_dictionary)) req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest) req["User-Name"] = username req["User-Password"] = req.PwCrypt(password) req["NAS-Identifier"] = cls.config.radius_nas_identifier # The IP address config option could be made optional # and determined from radius_nas_identifier req["NAS-IP-Address"] = cls.config.radius_nas_ip_address log.debug( "Attempting radius auth: Server: {server}; User-Name: {user}; " "NAS-Identifier {nasid}; NAS-IP: {nasip}; Dictionary {dict}". format(server=srv.server, user=req["User-Name"], nasid=req["NAS-Identifier"], nasip=req["NAS-IP-Address"], dict=cls.config.radius_dictionary)) try: reply = srv.SendPacket(req) except pyrad.client.Timeout: flash('An error has occurred. Please try again.') log.error( "Connection to radius server timed out. This may " "be caused by incorrect sever settings. Check the radius " "server logs for more information. {err}".format( err=format_exc())) return username, False except Exception: flash('An error has occurred. Please try again.') log.error( "Radius server connect failed. {err}".format(err=format_exc())) return username, False return username, reply.code == pyrad.packet.AccessAccept
def test_user_connection(self, username, password): """ Method used to perform test search over RADIUS Repository :param username: String with username :param password: String with password """ logger.debug("Radius_authentication_test::Trying to authenticate username {}".format(username.encode('utf-8'))) response = { 'status': None, 'reason': None } try: # Create client srv = Client(server=self.host, secret=self.secret, dict=Dictionary(DICTIONARY_PATH)) srv.retries = self.max_retry srv.timeout = self.max_timeout # create request req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=username, NAS_Identifier=self.nas_id) req["Password"] = req.PwCrypt(password) # send request reply = srv.SendPacket(req) logger.debug("Radius_authentication_test:: Username:{}, return code:{}".format(username, reply.code)) msg = "" if reply.code == pyrad.packet.AccessAccept: response['status'] = True logger.info("RADIUS::Auth: Authentication succeed for user {}".format(username)) for key, item in reply.iteritems(): msg += str(key) + ":" + str(item) else: response['status'] = False msg = "Authentication failed" logger.info("RADIUS::Auth: Authentication failure for user {}".format(username)) response['reason'] = msg except Timeout: response['status'] = False logger.info("RADIUS::Auth: Authentication failure for user {} : Timeout expired while connecting".format(username)) response['reason'] = "Timeout expired while connecting" except Exception as e: response['status'] = False logger.error("Radius_authentication_test::Unable to authenticate username:{}, exception:{}".format(username, str(e))) response['reason'] = "Exception : " + str(e) return response
def login(self): srv = Client(server=self.server, secret=self.secret, dict=Dictionary("dictionary")) req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=self.username) req["User-Password"] = req.PwCrypt(self.password) t = Thread(target=self.authandacct(srv,req)) t.daemon = True t.start() if(self.request == 'auth'): print("Start :",time.strftime("%d/%m/%Y"),time.strftime("%H:%M:%S")) print("Request type : ",self.request) print("Sessions transmitted : ", self.session) print("Responses received : ", self.success) print("Responses received rate: %s %% " % (self.success/self.session*100)) print("Timeout %.4s seconds " % (time.time() - start_time))
def request(config, user, password): """ Perform a RADIUS request to a RADIUS server. The RADIUS configuration contains the IP address, the port and the secret of the RADIUS server. * config.server * config.port * config.secret :param config: The RADIUS configuration :type config: RADIUSServer Database Model :param user: the radius username :param password: the radius password :return: True or False. If any error occurs, an exception is raised. """ success = False nas_identifier = get_from_config("radius.nas_identifier", "privacyIDEA") r_dict = config.dictionary or get_from_config( "radius.dictfile", "/etc/privacyidea/" "dictionary") log.debug("NAS Identifier: %r, " "Dictionary: %r" % (nas_identifier, r_dict)) log.debug("constructing client object " "with server: %r, port: %r, secret: %r" % (config.server, config.port, config.secret)) srv = Client(server=config.server, authport=config.port, secret=decryptPassword(config.secret), dict=Dictionary(r_dict)) req = srv.CreateAuthPacket( code=pyrad.packet.AccessRequest, User_Name=user.encode('ascii'), NAS_Identifier=nas_identifier.encode('ascii')) req["User-Password"] = req.PwCrypt(password) response = srv.SendPacket(req) if response.code == pyrad.packet.AccessAccept: log.info("Radiusserver %s granted " "access to user %s." % (config.server, user)) success = True else: log.warning("Radiusserver %s" "rejected access to user %s." % (config.server, user)) return success
def sendAcct(ns, user, ip, action): server = "172.16.3.1" srv = Client(server=server, secret="sandvine", dict=Dictionary("/etc/ppp/aaa-dictionary")) import types def setRetryTimeout(self, r, t): self.retries = r self.timeout = t srv.setRetryTimeout = types.MethodType(setRetryTimeout, srv) srv.setRetryTimeout(1, 0) req = srv.CreateAcctPacket(User_Name=user) # req["NAS-IP-Address"]="192.168.1.10" # req["NAS-Port"]=0 # req["NAS-Identifier"]="trillian" # req["Called-Station-Id"]="00-04-5F-00-0F-D1" # req["Calling-Station-Id"]="00-01-24-80-B3-9C" req["Framed-IP-Address"] = ip req["User-Name"] = user req["3GPP-IMSI"] = user req["Calling-Station-Id"] = user req["Acct-Status-Type"] = action req["Acct-Session-Id"] = "1" req["3GPP-SGSN-Address"] = server req["3GPP-GGSN-Address"] = server req["Event-Timestamp"] = int(time.time()) pid = os.fork() if (pid == 0): try: x = find_ns.NS(ns) try: srv.SendPacket(req) except: # We expect this error, since we get an ICMP port unreach # back since no one is listening. But that's ok, we just # tee the AAA anyway pass x.__del__() except: # Hmm, namespace is gone pass sys.exit(0) os.waitpid(pid, 0)
def main(): args = docopt.docopt(__doc__) srv = Client(server=args['<server>'], secret=args['<secret>'], dict=Dictionary(args['--dict'])) inf = sys.stdin nas_ip = args['--nas-ip'] or '127.0.0.1' for line in inf: port, in_bytes, out_bytes = json.loads(line) data = { 'username': str(port), 'in_bytes': in_bytes, 'out_bytes': out_bytes, } send_acct(srv, data, nas_ip)
def __init__(self, host, port=None): self.host = host self.port = port self.nas_ip_address = '192.168.155.93' self.nas_port_type = 'virtual' self.nas_called_station_id = '94.74.128.22' self.nas_calling_station_id = '94.74.128.22' self.frame_protocol = 'PPP' self.service_type = 'Framed-User' self.dictionary = Dictionary("dictionary", "dictionary") self.interimupdate = 60 self.shared_secret = "testing123" self.Nas_Identifier = "localhost" self.srv = Client(server=constants.host, secret="testing123", dict=Dictionary("dictionary", "dictionary")) self.userlist = []
def Hangup(server, port, session, user_name): server = Server.objects.get(id=server) print server.get_hash_password client = Client(server=server.ip, secret=server.get_hash_password, acctport=3799, dict=Dictionary("dictionary")) if 'mx80' in server.server_type: req = client.CreateAcctPacket(code=pyrad.packet.DisconnectRequest) req["Acct-Session-Id"] = session reply = client.SendPacket(req) return reply if 'mpd5' in server.server_type: req = client.CreateAcctPacket(code=pyrad.packet.DisconnectRequest) req["User-Name"] = user_name reply = client.SendPacket(req) return reply
def authenticate(self, username, password, **kwargs): # """Authentication method of LDAP repository, which returns dict of specified attributes:their values # :param username: String with username # :param password: String with password # :param oauth2_attributes: List of attributes to retrieve # :return: None and raise if failure, server message otherwise # """ logger.debug("Trying to authenticate username {}".format(username.encode('utf-8'))) # try: # Create client srv = Client(server=self.host, secret=self.secret, dict=Dictionary(DICTIONARY_PATH)) srv.retries = self.max_retry srv.timeout = self.max_timeout # create request req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=username, NAS_Identifier=self.nas_id) req["Password"] = req.PwCrypt(password) # send request reply = srv.SendPacket(req) logger.debug("Radius authentication username:{}, return code : {}".format(username, reply.code)) if reply.code == pyrad.packet.AccessAccept: ret = "" for key, item in reply.iteritems(): ret += str(key) + ":" + str(item) else: logger.error("RADIUS_CLI::authenticate: Authentication failure for user '{}'".format(username)) raise AuthenticationError("Authentication failure on Radius backend for user '{}'".format(username)) logger.debug("RADIUS_CLI::authenticate: Authentication reply from server : '{}'".format(ret)) logger.info("RADIUS_CLI::authenticate: Autentication succeed for user '{}'".format(username)) # except Timeout: # raise Timeout # except Exception, e: # logger.error("Unable to authenticate username {} : exception : {}".format(username, str(e))) return { 'dn': username, 'user_phone': 'N/A', 'user_email': 'N/A', 'password_expired': False, 'account_locked': False }
def pwd_authenticate(authenticator_id, login, password, source): ''' Passsword authentication against RADIUS :param authenticator_id: Authentication ID to be used. :param login: :param password: :param source: Source that is asking for authentication. Used for error notifications :returns: Effective authenticator ID :raises AuthenticationFailed: when auth failed. May contain an error message (Reply Message sent back from RADIUS) ''' srv = Client( server="127.0.0.1", authport=18122, secret=b'a2e4t6u8qmlskdvcbxnw', dict=Dictionary("/elan-agent/authentication/pyradius/dictionary")) req = srv.CreateAuthPacket( code=pyrad.packet.AccessRequest, User_Name=login, Connect_Info='authenticator={},source={},command=authenticate'.format( authenticator_id, source)) req["User-Password"] = req.PwCrypt(password) try: reply = srv.SendPacket(req) except Timeout: raise RequestTimeout except Exception as e: raise RequestError(e) if reply.code == pyrad.packet.AccessAccept: if 'Reply-Message' in reply: m = re.search('provider=(?P<provider_id>\d+)', reply['Reply-Message'][0]) if m: authenticator_id = m.group('provider_id') return authenticator_id errors = [] if 'Reply-Message' in reply: errors = reply['Reply-Message'] raise AuthenticationFailed(*errors)