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 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 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 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 _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)
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
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 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 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 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 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)
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 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
class RadiusReq(object): 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 sendDisconnectPacket(self, user, session): params = {'User_Name': user, 'Acct_Session_Id': session} request = self.client.CreateCoAPacket(code=packet.DisconnectRequest, **params) result = self.client.SendPacket(request) if result.code != packet.DisconnectACK: self.logger.warning( 'Failed to disconnect %s. Got result %s with code %d', user, result, result.code) return False return True
def rad_disconnect(id_port: int): port = EqptPort.query.get(id_port) rad_acct = RadAcct.query \ .filter_by(username=port.radius_user, acctstoptime=None) \ .order_by( RadAcct.radacctid.desc() ).first() if rad_acct is not None: """ # TO-DO: Need testing ------------------------------------ """ acct_session_id = rad_acct.acctsessionid nas_ip_address = rad_acct.nasipaddress # create coa client client = RadClient( server=current_app.config['RADIUS_ADDRESS'], secret=current_app.config['RADIUS_SECRET'], dict=dictionary.Dictionary("dictionary") ) # set coa timeout client.timeout = current_app.config['RADIUS_TIMEOUT'] attr = { "Acct-Session-Id": acct_session_id, "User-Name": port.radius_user, "NAS-IP-Address": nas_ip_address, } # create coa request packet attributes = {k.replace("-", "_"): attr[k] for k in attr} request = client.CreateCoAPacket(code=packet.DisconnectRequest, **attributes) return client.SendPacket(request) # return 'Off CoA paket - need testing. User online.' else: return 'No active user session found. User offline.'
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
#!/usr/bin/python from __future__ import print_function from pyrad.client import Client from pyrad import dictionary from pyrad import packet import sys if len(sys.argv) != 4: print("usage: disconnect.py <host> <secret> <session-id>") sys.exit(1) ADDRESS = sys.argv[1] SECRET = sys.argv[2] ATTRIBUTES = {"Acct-Session-Id": sys.argv[3]} client = Client(server=ADDRESS, secret=SECRET, dict=dictionary.Dictionary("dictionary")) client.timeout = 30 attributes = {k.replace("-", "_"): ATTRIBUTES[k] for k in ATTRIBUTES} request = client.CreateCoAPacket(code=packet.DisconnectRequest, **attributes) result = client.SendPacket(request) print(result.code)
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
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
class Rasta: def __init__(self): self.cfg = None def load_config(self, config_file): fnm = config_file try: f = open(fnm, 'r') self.cfg = json.load(f) except IOError as e: print("Failed to open config file: %s" % (str(e), )) sys.exit(-1) return True def create_client(self, dictfile): self.server = Client(server=str(self.cfg["settings"]["acct"]['host']), secret=str( self.cfg["settings"]["acct"]["secret"]), dict=Dictionary(dictfile)) def expand_var(self, s): return s def create_packets(self, username, packet_type): reqs = [] if username in self.cfg["users"].keys(): # print("user " + username + " in database") req = self.server.CreateAcctPacket(User_Name=str(username)) req[r"Acct-Status-Type"] = str(packet_type) for att in self.cfg["users"][username]["Acct"][packet_type].keys(): val = self.cfg["users"][username]["Acct"][packet_type][att] if type(val) == type(u"some string"): req[str(att)] = self.expand_var(str(val)) else: req[str(att)] = self.expand_var(val) reqs.append(req) else: pass # print("user " + username + " NOT in database") return reqs def send_one(self, req): try: print("Sending accounting start packet") self.server.SendPacket(req) except pyrad.client.Timeout: print("RADIUS server does not reply") return False except socket.error, error: print("Network error: " + error[1]) return False return True