class RadiusSession: """ Class that controls a RADIUS authentication session. Responsible for communicating with the RADIUS server. """ 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 auth(self, username, password): """ Request for authentication Returns True if successful, else False. """ request = self.server.CreateAuthPacket( code=pyrad.packet.AccessRequest, User_Name=username, NAS_Identifier=self.nas_identifier) request['User-Password'] = request.PwCrypt(password) reply = self.server.SendPacket(request) if reply.code == pyrad.packet.AccessAccept: return True else: return False
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)
class nassim: 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 send_auth_packet(self): user = User("bob", "passbob") # req = self.srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name="alice", NAS_Identifier="localhost") req = self.srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=user.username, NAS_Identifier="localhost") req["User-Password"] = req.PwCrypt(user.password) reply = self.srv.SendPacket(req) if reply.code == pyrad.packet.AccessAccept: return True return False
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 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 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 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 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 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)
class Rador(object): """Класс для пересылки сообщений из Syslog-ng в Radius.""" 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 send_message(self, attributes_dict): """Send radius packet.""" self.attributes_dict = attributes_dict self.req = self.srv.CreateAcctPacket() # Создаем запрос по всем атрибутам и их значениям for key in self.attributes_dict: self.req[key] = self.attributes_dict[key] # Отправляем запрос reply = self.srv.SendPacket(self.req) # В случае успеха (ответный код 5), отправляем в лог if reply.code == pyrad.packet.AccountingResponse: self.packet_send += 1 self.logging.error('Successfully sent Acct packet to server.') else: # Иначе пишем в лог ошибку self.logging.error('Error with sending packet.')
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 __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 auth( path ): # first look in the arguments username = request.args.get('username', None) password = request.args.get('password', None) # then look in the uri or in the X-Auth-Info header auth_header = app.config.get('AUTH_HEADER', '') if not (username and password) : s1 = path.split('/') path2 = request.headers.get(auth_header, "") s2 = path2.split('/') s = [] if len(s1) >= 2: s = s1 elif len(s2) >= 2: s = s2 if len(s) >= 2: username = s[0] password = s[1] app.logger.debug("Incoming auth request: %s/%s" % (username, password) ) rad_server = app.config.get('FREERADIUS_SERVER') rad_secret = app.config.get('FREERADIUS_SECRET') rad_nas = app.config.get('FREERADIUS_NAS') assert rad_server and rad_secret and rad_nas, "Oops.." if username and password: srv=Client( server = rad_server, secret = rad_secret, dict = Dictionary("dictionary") ) # increase timeout srv.timeout = 30 req=srv.CreateAuthPacket( code = pyrad.packet.AccessRequest, User_Name = username, NAS_Identifier = rad_nas ) req["User-Password"]=req.PwCrypt(password) reply=srv.SendPacket(req) if reply.code==pyrad.packet.AccessAccept: return jsonify(), 200 else: return jsonify(), 403 else: return jsonify(), 403
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 __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 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 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 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 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)
class AuthPacketChapTests(unittest.TestCase): 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 testVerifyChapPasswd(self): chap_id = b'9' chap_challenge = b'987654321' chap_password = b'%s%s' % (chap_id, md5_constructor( b'%s%s%s' % ( chap_id, b'test_password', chap_challenge )).digest()) pkt = self.client.CreateAuthPacket( code=packet.AccessChallenge, authenticator=b'ABCDEFG', User_Name='test_name', CHAP_Challenge=chap_challenge, CHAP_Password=chap_password ) self.assertEqual(pkt['CHAP-Challenge'][0], chap_challenge) self.assertEqual(pkt['CHAP-Password'][0], chap_password) self.assertEqual(pkt.VerifyChapPasswd('test_password'), True)
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 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 _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 _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())
class OtherTests(unittest.TestCase): def setUp(self): self.server = object() self.client = Client(self.server, secret=six.b('zeer geheim')) def testCreateAuthPacket(self): packet = self.client.CreateAuthPacket(id=15) self.failUnless(isinstance(packet, AuthPacket)) self.failUnless(packet.dict is self.client.dict) self.assertEqual(packet.id, 15) self.assertEqual(packet.secret, six.b('zeer geheim')) def testCreateAcctPacket(self): packet = self.client.CreateAcctPacket(id=15) self.failUnless(isinstance(packet, AcctPacket)) self.failUnless(packet.dict is self.client.dict) self.assertEqual(packet.id, 15) self.assertEqual(packet.secret, six.b('zeer geheim'))
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 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)
def authenticate(self, user=None, password=None, **kwargs): radius_server = config.login.radius_server radius_secret = config.login.radius_secret client = Client(server=radius_server, secret=radius_secret, dict=self.RADIUS_DICT) req = client.CreateAuthPacket(code=AccessRequest, User_Name=user, NAS_Identifier="noc") req["User-Password"] = req.PwCrypt(password) try: reply = client.SendPacket(req) except client.Timeout: raise self.LoginError("Timed out") if reply.code != AccessAccept: raise self.LoginError("RADIUS Authentication failed. Code=%s", reply.code) return user
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 * config.retries * config.timeout :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)) # Set retries and timeout of the client if config.timeout: srv.timeout = config.timeout if config.retries: srv.retries = config.retries req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=user.encode('ascii'), NAS_Identifier=nas_identifier.encode('ascii')) req["User-Password"] = req.PwCrypt(password) try: 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)) except Timeout: log.warning("Receiving timeout from remote radius server {0!s}".format(config.server)) return success
def authenticate(self, environ, identity): """authenticator""" try: if check_failed_logins(environ): return None login = identity['login'].decode('utf-8') password = identity['password'].decode('utf-8') username = login domain = None if '@' not in login: return None username, domain = login.split('@') and_clause = and_(self.domainmodel.id == self.aliasmodel.domain_id, self.aliasmodel.name == domain, self.aliasmodel.status == True) radiussettings = self.dbsession.query(self.radsettingsmodel, self.authsettingsmodel.address, self.authsettingsmodel.port, self.authsettingsmodel.split_address, self.authsettingsmodel.user_map_template, self.domainmodel.name)\ .join(self.authsettingsmodel)\ .join(self.domainmodel)\ .filter(self.authsettingsmodel.enabled == True)\ .filter(self.domainmodel.status == True)\ .filter(or_(self.domainmodel.name == domain, func._(and_clause)))\ .all() settings, address, port, split_address, template, \ domain_name = radiussettings[0] if not port: port = 1812 radclient = Client(server=address, authport=port, secret=settings.secret.encode('utf-8'), dict=Dictionary(StringIO(DICTIONARY))) if settings.timeout: radclient.timeout = settings.timeout if split_address: login = username if domain != domain_name: identity['login'] = "******" % (username, domain_name) if not split_address: login = "******" % (username, domain_name) if (template and (USER_TEMPLATE_MAP_RE.search(template) or DOM_TEMPLATE_MAP_RE.search(template))): # domain has user template login = USER_TEMPLATE_MAP_RE.sub(username, template) login = DOM_TEMPLATE_MAP_RE.sub(domain, login) request = radclient.CreateAuthPacket(code=packet.AccessRequest, User_Name=login) request["User-Password"] = request.PwCrypt(password) reply = radclient.SendPacket(request) if reply.code == packet.AccessAccept: return identity['login'] except (KeyError, IndexError, NoResultFound, Timeout): return None return None
#!/usr/bin/python from __future__ import print_function from pyrad.client import Client from pyrad import dictionary from pyrad import packet ADDRESS = "127.0.0.1" SECRET = b"Kah3choteereethiejeimaeziecumi" ATTRIBUTES = {"Acct-Session-Id": "1337"} CODE = packet.CoARequest # 43 # CODE = packet.DisconnectRequest # 40 # create coa client client = Client(server=ADDRESS, secret=SECRET, authport=3799, acctport=3799, dict=dictionary.Dictionary("dictionary")) # set coa timeout client.timeout = 30 # create coa request packet attributes = {k.replace("-", "_"): attributes[k] for k in attributes} request = client.CreateAcctPacket(code=CODE, **attributes) # send coa request result = client.SendPacket(request) print(result)
def setUp(self): self.server = object() self.client = Client(self.server) self.orgsocket = socket.socket socket.socket = MockSocket
class SocketTests(unittest.TestCase): def setUp(self): self.server = object() self.client = Client(self.server) self.orgsocket = socket.socket socket.socket = MockSocket def tearDown(self): socket.socket = self.orgsocket def testReopen(self): self.client._SocketOpen() sock = self.client._socket self.client._SocketOpen() self.failUnless(sock is self.client._socket) def testBind(self): self.client.bind((BIND_IP, BIND_PORT)) self.assertEqual(self.client._socket.address, (BIND_IP, BIND_PORT)) self.assertEqual(self.client._socket.options, [(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)]) def testBindClosesSocket(self): s = MockSocket(socket.AF_INET, socket.SOCK_DGRAM) self.client._socket = s self.client.bind((BIND_IP, BIND_PORT)) self.assertEqual(s.closed, True) def testSendPacket(self): def MockSend(self, pkt, port): self._mock_pkt = pkt self._mock_port = port _SendPacket = Client._SendPacket Client._SendPacket = MockSend self.client.SendPacket(AuthPacket()) self.assertEqual(self.client._mock_port, self.client.authport) self.client.SendPacket(AcctPacket()) self.assertEqual(self.client._mock_port, self.client.acctport) Client._SendPacket = _SendPacket def testNoRetries(self): self.client.retries = 0 self.assertRaises(Timeout, self.client._SendPacket, None, None) def testSingleRetry(self): self.client.retries = 1 self.client.timeout = 0 packet = MockPacket(AccessRequest) self.assertRaises(Timeout, self.client._SendPacket, packet, 432) self.assertEqual(self.client._socket.output, [("request packet", (self.server, 432))]) def testDoubleRetry(self): self.client.retries = 2 self.client.timeout = 0 packet = MockPacket(AccessRequest) self.assertRaises(Timeout, self.client._SendPacket, packet, 432) self.assertEqual(self.client._socket.output, [("request packet", (self.server, 432)), ("request packet", (self.server, 432))]) def testAuthDelay(self): self.client.retries = 2 self.client.timeout = 1 packet = MockPacket(AccessRequest) self.assertRaises(Timeout, self.client._SendPacket, packet, 432) self.failIf("Acct-Delay-Time" in packet) def testSingleAccountDelay(self): self.client.retries = 2 self.client.timeout = 1 packet = MockPacket(AccountingRequest) self.assertRaises(Timeout, self.client._SendPacket, packet, 432) self.assertEqual(packet["Acct-Delay-Time"], [1]) def testDoubleAccountDelay(self): self.client.retries = 3 self.client.timeout = 1 packet = MockPacket(AccountingRequest) self.assertRaises(Timeout, self.client._SendPacket, packet, 432) self.assertEqual(packet["Acct-Delay-Time"], [2]) def testIgnorePacketError(self): self.client.retries = 1 self.client.timeout = 1 self.client._socket = MockSocket(1, 2, six.b("valid reply")) packet = MockPacket(AccountingRequest, verify=True, error=True) self.assertRaises(Timeout, self.client._SendPacket, packet, 432) def testValidReply(self): self.client.retries = 1 self.client.timeout = 1 self.client._socket = MockSocket(1, 2, six.b("valid reply")) packet = MockPacket(AccountingRequest, verify=True) reply = self.client._SendPacket(packet, 432) self.failUnless(reply is packet.reply) def testInvalidReply(self): self.client.retries = 1 self.client.timeout = 1 self.client._socket = MockSocket(1, 2, six.b("invalid reply")) packet = MockPacket(AccountingRequest, verify=False) self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
def ifAccountThread(): """Runs as a thread to account from traffic on an interface""" global _accountingInfo, _runIfAccount, nas_id, nas_ip global radius_update_interval, radius_acct_server, radius_auth_server try: # Is interface accounting enabled enabled = config_getboolean("accounting", "enabled", True) if not enabled: log_info("Interface accounting disabled.") return _runIfAccount = True # What interval shall we check hosts at check_interval = config_get("accounting", "check_interval", DEFAULT_CHECK_INTERVAL) radius_update_interval = config_getint("accounting", "update_interval", DEFAULT_UPDATE_INTERVAL) # Initialise the interface list default_user_file = "%s/accounting_users" % os.path.dirname(DEFAULT_CONFFILE) user_file = config_get("accounting", "user_file", default_user_file) if not os.path.exists(user_file): log_error("Interface accounting disabled. No user file: %s" % user_file) _runIfAccount = False return # Initialise the RADIUS connection try: dummy0 = getInterfaces(returnOne="dummy0")[0] dummy0ip = dummy0["address"].split("/")[0] except: log_error("Could not determine host loopback address!", sys.exc_info()) dummy0ip = "127.0.0.1" acct_server = config_get("accounting", "acct_server", "radius") acct_secret = config_get_required("accounting", "acct_secret") auth_server = config_get("accounting", "auth_server", "radius") auth_secret = config_get_required("accounting", "auth_secret") nas_id = config_get("accounting", "nas_id", getFQDN()) nas_ip = config_get("accounting", "nas_ip", dummy0ip) radius_acct_server = Client(server=acct_server, secret=acct_secret, dict=Dictionary(RADIUS_DICTIONARY)) radius_auth_server = Client(server=auth_server, secret=auth_secret, dict=Dictionary(RADIUS_DICTIONARY)) # FreeRADIUS at least auths based on IP address, make sure our # packets come from the right place radius_acct_server.bind((nas_ip, 0)) radius_auth_server.bind((nas_ip, 0)) # Read and parse the user file parseUserFile(user_file) # Initialise interface state initialiseInterfaceState() # Loop forever reading byte counters as appropriate while _runIfAccount: # wait a bit before checking time.sleep(check_interval) # Send any queued packets processRADIUSQueue() # Try and re-authenticate any dead interfaces for ifname, iface in _accountingInfo.items(): if iface["authenticated"]: continue age = time.time() - iface["last_auth_check"] if age > radius_update_interval: doRADIUSAuthentication(ifname) # Update traffic details updateTrafficCounters() # Generate interim-updates processInterimUpdates() except: (etype, value, tb) = sys.exc_info() log_error("Exception in interface accounting thread! - %s" % value, (etype, value, tb)) log_info("Exiting interface accounting thread")
def authenticate(self, environ, identity): """authenticator""" try: if check_failed_logins(environ): return None login = identity['login'].decode('utf-8') password = identity['password'].decode('utf-8') username = login domain = None is_alias = False if '@' not in login: return None username, domain = login.split('@') try: dma = self.dbsession.query(self.dommodel.name)\ .join(self.dam)\ .filter(self.dam.name == domain).one() domain = dma.name is_alias = True except NoResultFound: pass radiussettings = self.dbsession.query(self.rsm, self.asm.address, self.asm.port, self.asm.split_address, self.asm.user_map_template)\ .join(self.asm)\ .join(self.dommodel)\ .filter(self.asm.enabled == True)\ .filter(self.dommodel.status == True)\ .filter(self.dommodel.name == domain)\ .one() settings, address, port, split_address, template = radiussettings if not port: port = 1812 radclient = Client(server=address, authport=port, secret=settings.secret.encode('utf-8'), dict=Dictionary(StringIO(DICTIONARY))) if settings.timeout: radclient.timeout = settings.timeout if split_address: login = username if is_alias: identity['login'] = "******" % (username, domain) if not split_address: login = "******" % (username, domain) if (template and (USER_TEMPLATE_MAP_RE.search(template) or DOM_TEMPLATE_MAP_RE.search(template))): # domain has user template login = USER_TEMPLATE_MAP_RE.sub(username, template) login = DOM_TEMPLATE_MAP_RE.sub(domain, login) request = radclient.CreateAuthPacket(code=packet.AccessRequest, User_Name=login) request["User-Password"] = request.PwCrypt(password) reply = radclient.SendPacket(request) if reply.code == packet.AccessAccept: identity['login'] = identity['login'].lower() return identity['login'] except (KeyError, IndexError, NoResultFound, Timeout): return None return None