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 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
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 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 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_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 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
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 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, 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 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 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 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 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 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 }
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 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 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 can_auth(config, username, password): """ Performs authentication against a RADIUS server. """ log = logging.getLogger('radius_source.can_auth') log.debug("Attempting RADIUS auth to %s for user %s" % ( config['rad_server'], username, )) processed_user = ldap_source.get_auth_username(config, username) # Create a RADIUS client to communicate with the server. srv = Client( server=config['rad_server'], secret=config['rad_secret'], dict=Dictionary(config['rad_dictionary']), ) req = srv.CreateAuthPacket( code=pyrad.packet.AccessRequest, User_Name=processed_user, NAS_Identifier=gethostname(), ) req['User-Password'] = req.PwCrypt(password) try: reply = srv.SendPacket(req) except Exception: log.exception("Problem contacting RADIUS server") return False if reply.code == pyrad.packet.AccessAccept: log.info("User %s accepted by RADIUS" % (username, )) return True log.info("User %s rejected by RADIUS" % (username, )) return False
def _connect_radius(host, port, config, toolbox): """Spin up test client and send a Status-Server packet to check if we can reach the radius server""" secret = config.get_protected_str('secret_protected', 'secret').encode() client = Client(server=host, authport=port, secret=secret, dict=base.radius_dictionary()) client.timeout = const.DEFAULT_RADIUS_RETRY_WAIT request = client.CreateAuthPacket(code=pyrad.packet.StatusServer) # The request must contain a message authenticator. request.add_message_authenticator() try: nas_ip = config.get_str('nas_ip') except ConfigError: nas_ip = util.get_authproxy_ip() request.AddAttribute('NAS-IP-Address', nas_ip) return toolbox.test_connect_radius(client, request)
def get_authorization(authenticator_id, login, source): 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=authorize'.format( authenticator_id, source)) reply = srv.SendPacket(req) authz = {} for attr in reply.get(18, []): # 18 -> Reply-Message key, value = attr.split('=', 1) if key == 'ELAN-Auth-Provider': key = 'provider' authz[key] = value return authz
from pyrad.client import Client from pyrad.dictionary import Dictionary import pyrad.packet from secrets import token_hex import getpass SERVER = "localhost" USERNAME = "******" PASSWORD = getpass.getpass(prompt="Enter the password for {}: ".format(USERNAME)) RADIUS_SECRET = b"$upers3cret" srv = Client(server=SERVER, secret=RADIUS_SECRET, dict=Dictionary("dictionary")) # create request req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=USERNAME, NAS_Identifier="localhost") req["User-Password"] = req.PwCrypt(PASSWORD) req["Proxy-State"] = token_hex(8).encode("ascii") # send request reply = srv.SendPacket(req) if reply.code == pyrad.packet.AccessAccept: print("access accepted") else: print("access denied") print("Attributes returned by server:") for i in reply.keys(): print("%s: %s" % (i, reply[i]))
def do_request(self, user, password, options=None): """ run the radius request against the remote host :param user: the requesting user (required) :param password: the password which should be checked on the remote host :param options: dict which provides additional request parameter. e.g for challenge response :return: Tuple of (success, and reply=remote response) """ reply = {} res = False for server in self.config.keys(): server_config = self.config[server] radiusServer = server_config['netloc'] radiusUser = user.login # Read the secret!!! - currently in plain text radiusSecret = server_config['secret'] # here we also need to check for radius.user log.debug("Checking OTP len:%s on radius server %s," "User: %s", len(password), radiusServer, radiusUser) try: # pyrad does not allow to set timeout and retries. # it defaults to retries=3, timeout=5 server = radiusServer.split(':') r_server = server[0] r_authport = 1812 nas_identifier = self.sysconfig.get("radius.nas_identifier", "LinOTP") r_dict = self.sysconfig.get("radius.dictfile", "/etc/linotp2/dictionary") if len(server) >= 2: r_authport = int(server[1]) log.debug("Radius: NAS Identifier: %r, " "Dictionary: %r", nas_identifier, r_dict) log.debug( "Radius: constructing client object " "with server: %r, port: %r, secret: %r", r_server, r_authport, radiusSecret) srv = Client(server=r_server, authport=r_authport, secret=radiusSecret, dict=Dictionary(r_dict)) req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=radiusUser.\ encode('ascii'), NAS_Identifier=nas_identifier.\ encode('ascii')) req["User-Password"] = req.PwCrypt(password) if "transactionid" in options or 'state' in options: req["State"] = str( options.get('transactionid', options.get('state'))) response = srv.SendPacket(req) if response.code == pyrad.packet.AccessChallenge: opt = {} for attr in response.keys(): opt[attr] = response[attr] res = False log.debug("Radius: challenge returned %r ", opt) # now we map this to a linotp challenge if "State" in opt: reply["transactionid"] = opt["State"][0] if "Reply-Message" in opt: reply["message"] = opt["Reply-Message"][0] elif response.code == pyrad.packet.AccessAccept: log.info("Radius: Server %s granted " "access to user %s.", r_server, radiusUser) res = True else: log.warning( "Radius: Server %s" "rejected access to user %s.", r_server, radiusUser) res = False # we break the servers look if one request ended up here break except Exception as ex: log.exception("Error contacting " "radius Server: %r", ex) return (res, reply)
def _check_radius(self, otpval, options=None, radius_state=None): """ run the RADIUS request against the RADIUS server :param otpval: the OTP value :param options: additional token specific options :type options: dict :return: counter of the matching OTP value. :rtype: AccessAccept, AccessReject, AccessChallenge """ result = AccessReject radius_message = None if options is None: options = {} radius_dictionary = None radius_identifier = self.get_tokeninfo("radius.identifier") radius_user = self.get_tokeninfo("radius.user") system_radius_settings = self.get_tokeninfo("radius.system_settings") radius_timeout = 5 radius_retries = 3 if radius_identifier: # New configuration radius_server_object = get_radius(radius_identifier) radius_server = radius_server_object.config.server radius_port = radius_server_object.config.port radius_server = u"{0!s}:{1!s}".format(radius_server, radius_port) radius_secret = radius_server_object.get_secret() radius_dictionary = radius_server_object.config.dictionary radius_timeout = int(radius_server_object.config.timeout or 10) radius_retries = int(radius_server_object.config.retries or 1) elif system_radius_settings: # system configuration radius_server = get_from_config("radius.server") radius_secret = get_from_config("radius.secret") else: # individual token settings radius_server = self.get_tokeninfo("radius.server") # Read the secret secret = self.token.get_otpkey() radius_secret = binascii.unhexlify(secret.getKey()) # here we also need to check for radius.user log.debug(u"checking OTP len:{0!s} on radius server: " u"{1!s}, user: {2!r}".format(len(otpval), radius_server, radius_user)) try: # pyrad does not allow to set timeout and retries. # it defaults to retries=3, timeout=5 # TODO: At the moment we support only one radius server. # No round robin. server = radius_server.split(':') r_server = server[0] r_authport = 1812 if len(server) >= 2: r_authport = int(server[1]) nas_identifier = get_from_config("radius.nas_identifier", "privacyIDEA") if not radius_dictionary: radius_dictionary = get_from_config( "radius.dictfile", "/etc/privacyidea/dictionary") log.debug(u"NAS Identifier: %r, " u"Dictionary: %r" % (nas_identifier, radius_dictionary)) log.debug(u"constructing client object " u"with server: %r, port: %r, secret: %r" % (r_server, r_authport, to_unicode(radius_secret))) srv = Client(server=r_server, authport=r_authport, secret=to_bytes(radius_secret), dict=Dictionary(radius_dictionary)) # Set retries and timeout of the client srv.timeout = radius_timeout srv.retries = radius_retries req = srv.CreateAuthPacket( code=pyrad.packet.AccessRequest, User_Name=radius_user.encode('utf-8'), NAS_Identifier=nas_identifier.encode('ascii')) req["User-Password"] = req.PwCrypt(otpval) if radius_state: req["State"] = radius_state log.info( u"Sending saved challenge to radius server: {0!r} ".format( radius_state)) try: response = srv.SendPacket(req) except Timeout: log.warning( u"The remote RADIUS server {0!s} timeout out for user {1!s}." .format(r_server, radius_user)) return AccessReject # handle the RADIUS challenge if response.code == pyrad.packet.AccessChallenge: # now we map this to a privacyidea challenge if "State" in response: radius_state = response["State"][0] if "Reply-Message" in response: radius_message = response["Reply-Message"][0] result = AccessChallenge elif response.code == pyrad.packet.AccessAccept: radius_state = '<SUCCESS>' radius_message = 'RADIUS authentication succeeded' log.info(u"RADIUS server {0!s} granted " u"access to user {1!s}.".format( r_server, radius_user)) result = AccessAccept else: radius_state = '<REJECTED>' radius_message = 'RADIUS authentication failed' log.debug(u'radius response code {0!s}'.format(response.code)) log.info(u"Radiusserver {0!s} " u"rejected access to user {1!s}.".format( r_server, radius_user)) result = AccessReject except Exception as ex: # pragma: no cover log.error("Error contacting radius Server: {0!r}".format((ex))) log.info("{0!s}".format(traceback.format_exc())) options.update({'radius_result': result}) options.update({'radius_state': radius_state}) options.update({'radius_message': radius_message}) return result
path_to_dictionary = os.path.join(currentdir,'..',"dictionary") def SendPacket(srv, req): try: reply = srv.SendPacket(req) except pyrad.client.Timeout: print("ERROR: RADIUS server does not reply") sys.exit(1) except socket.error as error: print("ERROR: Network error: " + error[1]) sys.exit(1) else: if reply.code == pyrad.packet.AccessAccept: print("Access accepted") else: print("ERROR: Access denied") print(reply) srv = Client(server="127.0.0.1", secret=b"56rmkuri92d8a0wvi9divyxvn1nku3", dict=Dictionary(path_to_dictionary)) req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name="VZJ9VTB662KI7F1ZHFF8YBW8PNV1ECEQD3FZAMSY") req["User-Password"] = req.PwCrypt("GHRZ88B1QMWPV6GKI91DHZFTZBKC0NDZBMVKJ36R") req["Calling-Station-Id"] = "f2:ff:11:22:33:44" SendPacket(srv,req)
def check_otp(self, otpval, counter=None, window=None, options=None): """ run the RADIUS request against the RADIUS server :param otpval: the OTP value :param counter: The counter for counter based otp values :type counter: int :param window: a counter window :type counter: int :param options: additional token specific options :type options: dict :return: counter of the matching OTP value. :rtype: int """ otp_count = -1 options = options or {} radius_dictionary = None radius_identifier = self.get_tokeninfo("radius.identifier") radius_user = self.get_tokeninfo("radius.user") system_radius_settings = self.get_tokeninfo("radius.system_settings") if radius_identifier: # New configuration radius_server_object = get_radius(radius_identifier) radius_server = radius_server_object.config.server radius_port = radius_server_object.config.port radius_server = "{0!s}:{1!s}".format(radius_server, radius_port) radius_secret = radius_server_object.get_secret() radius_dictionary = radius_server_object.config.dictionary elif system_radius_settings: # system configuration radius_server = get_from_config("radius.server") radius_secret = get_from_config("radius.secret") # Is returned as unicode, so we convert it to utf-8 radius_secret = radius_secret.encode("utf-8") else: # individual token settings radius_server = self.get_tokeninfo("radius.server") # Read the secret secret = self.token.get_otpkey() radius_secret = binascii.unhexlify(secret.getKey()) # here we also need to check for radius.user log.debug( "checking OTP len:{0!s} on radius server: {1!s}, user: {2!r}". format(len(otpval), radius_server, radius_user)) try: # pyrad does not allow to set timeout and retries. # it defaults to retries=3, timeout=5 # TODO: At the moment we support only one radius server. # No round robin. server = radius_server.split(':') r_server = server[0] r_authport = 1812 if len(server) >= 2: r_authport = int(server[1]) nas_identifier = get_from_config("radius.nas_identifier", "privacyIDEA") if not radius_dictionary: radius_dictionary = get_from_config( "radius.dictfile", "/etc/privacyidea/" "dictionary") log.debug("NAS Identifier: %r, " "Dictionary: %r" % (nas_identifier, radius_dictionary)) log.debug("constructing client object " "with server: %r, port: %r, secret: %r" % (r_server, r_authport, radius_secret)) srv = Client(server=r_server, authport=r_authport, secret=radius_secret, dict=Dictionary(radius_dictionary)) req = srv.CreateAuthPacket( code=pyrad.packet.AccessRequest, User_Name=radius_user.encode('ascii'), NAS_Identifier=nas_identifier.encode('ascii')) req["User-Password"] = req.PwCrypt(otpval) if "transactionid" in options: req["State"] = str(options.get("transactionid")) response = srv.SendPacket(req) c = response.code # TODO: handle the RADIUS challenge """ if response.code == pyrad.packet.AccessChallenge: opt = {} for attr in response.keys(): opt[attr] = response[attr] res = False log.debug("challenge returned %r " % opt) # now we map this to a privacyidea challenge if "State" in opt: reply["transactionid"] = opt["State"][0] if "Reply-Message" in opt: reply["message"] = opt["Reply-Message"][0] """ if response.code == pyrad.packet.AccessAccept: log.info("Radiusserver %s granted " "access to user %s." % (r_server, radius_user)) otp_count = 0 else: log.warning("Radiusserver %s" "rejected access to user %s." % (r_server, radius_user)) except Exception as ex: # pragma: no cover log.error("Error contacting radius Server: {0!r}".format((ex))) log.debug("{0!s}".format(traceback.format_exc())) return otp_count
#!/usr/bin/python import socket, sys import pyrad.packet from pyrad.client import Client from pyrad.dictionary import Dictionary srv = Client(server="localhost", secret="Kah3choteereethiejeimaeziecumi", dict=Dictionary("dictionary")) req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name="wichert") req["NAS-IP-Address"] = "192.168.1.10" req["NAS-Port"] = 0 req["Service-Type"] = "Login-User" 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"] = "10.0.0.100" try: print "Sending authentication request" reply = srv.SendPacket(req) except pyrad.client.Timeout: print "RADIUS server does not reply" sys.exit(1) except socket.error, error: print "Network error: " + error[1] sys.exit(1)
def do_request(self, anOtpVal, transactionid=None, user=None): ''' Here we contact the Radius Server to verify the pass ''' reply = {} res = False otp_count = -1 radiusServer = self.getFromTokenInfo("radius.server") radiusUser = self.getFromTokenInfo("radius.user") # Read the secret!!! secObj = self._get_secret_object() radiusSecret = binascii.unhexlify(secObj.getKey()) if radiusSecret == VOID_RADIUS_SECRET: log.warning("Usage of default radius secret is not recomended!!") # here we also need to check for radius.user log.debug("[do_request] checking OTP len:%s on radius server: %s," " user: %s" % (len(anOtpVal), radiusServer, radiusUser)) try: # pyrad does not allow to set timeout and retries. # it defaults to retries=3, timeout=5 # TODO: At the moment we support only one radius server. # No round robin. server = radiusServer.split(':') r_server = server[0] r_authport = 1812 nas_identifier = env.get("radius.nas_identifier", "LinOTP") r_dict = env.get("radius.dictfile", "/etc/linotp2/dictionary") if len(server) >= 2: r_authport = int(server[1]) log.debug("[do_request] [RadiusToken] NAS Identifier: %r, " "Dictionary: %r" % (nas_identifier, r_dict)) log.debug("[do_request] [RadiusToken] constructing client object " "with server: %r, port: %r, secret: %r" % (r_server, r_authport, radiusSecret)) srv = Client(server=r_server, authport=r_authport, secret=radiusSecret, dict=Dictionary(r_dict)) req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=radiusUser.encode('ascii'), NAS_Identifier=nas_identifier.encode('ascii')) req["User-Password"] = req.PwCrypt(anOtpVal) if transactionid is not None: req["State"] = str(transactionid) response = srv.SendPacket(req) if response.code == pyrad.packet.AccessChallenge: opt = {} for attr in response.keys(): opt[attr] = response[attr] res = False log.debug("challenge returned %r " % opt) # now we map this to a linotp challenge if "State" in opt: reply["transactionid"] = opt["State"][0] if "Reply-Message" in opt: reply["message"] = opt["Reply-Message"][0] # preserve challenge reply for later self.isRemoteChallengeRequest = True self.remote_challenge_response = reply elif response.code == pyrad.packet.AccessAccept: log.info("[do_request] [RadiusToken] Radiusserver %s granted " "access to user %s." % (r_server, radiusUser)) otp_count = 0 res = True else: log.warning("[do_request] [RadiusToken] Radiusserver %s" "rejected access to user %s." % (r_server, radiusUser)) res = False except Exception as ex: log.exception( "[do_request] [RadiusToken] Error contacting radius Server: %r" % (ex)) return (res, otp_count, reply)