def authenticate(self, username, password, client_ip, pass_through_attrs=None): if pass_through_attrs is None: pass_through_attrs = {} id = yield self.id_list.request() request_packet = packet.AuthPacket(code=packet.AccessRequest, id=id, secret=self.secret.encode(), dict=base.radius_dictionary()) request_packet['NAS-IP-Address'] = self.nas_ip add_packet_attributes(packet=request_packet, attrs=pass_through_attrs) request = ClientRequest(request_packet, self.pw_codec) request.username = username if password is not None: request.password = password if client_ip: request.client_ip = client_ip log.msg('Sending request for user %r to %r with id %r' % (username, self.addrs[0], id)) # Send request; wait for response self.requests[id] = request self._send_request(request) response_packet = yield request.deferred defer.returnValue(response_packet)
def setUp(self): self.path = os.path.join(home, 'tests', 'data') self.dict = Dictionary(os.path.join(self.path, 'full')) self.pkt = packet.AuthPacket(dict=self.dict, auto_crypt=True, secret=six.b('secret'), authenticator=six.b('01234567890ABCDEF'))
def _create_reply_with_duplicate_attributes(self, request): """ Creates a reply to the given request with multiple instances of the same attribute that also do not appear sequentially in the list. Used to ensure that methods providing authenticator and Message-Authenticator verification can handle the case where multiple instances of an given attribute do not appear sequentially in the attributes list. """ # Manually build the packet since using packet.Packet will always group # attributes of the same type together attributes = self._get_attribute_bytes('Test-String', 'test') attributes += self._get_attribute_bytes('Test-Integer', 1) attributes += self._get_attribute_bytes('Test-String', 'test') attributes += self._get_attribute_bytes('Message-Authenticator', 16 * six.b('\00')) header = struct.pack('!BBH', packet.AccessAccept, request.id, (20 + len(attributes))) # Calculate the Message-Authenticator and update the attribute hmac_constructor = hmac.new(request.secret, None, md5_constructor) hmac_constructor.update(header + request.authenticator + attributes) updated_message_authenticator = hmac_constructor.digest() attributes = attributes.replace(six.b('\x00') * 16, updated_message_authenticator) # Calculate the response authenticator authenticator = md5_constructor(header + request.authenticator + attributes + request.secret).digest() reply_bytes = header + authenticator + attributes return packet.AuthPacket(packet=reply_bytes, dict=self.dict)
def _create_request(self, radius_attrs: Dict[str, Any]): """ Creates a fake request packet used to generate a fake response Args: radius_attrs: The attributes to add to the created request Returns: packet.AuthPacket """ request_id = yield self.id_list.request() request_packet = packet.AuthPacket( code=packet.AccessRequest, id=request_id, secret=self.secret.encode(), dict=base.radius_dictionary(), ) add_packet_attributes(packet=request_packet, attrs=radius_attrs) # Turn the request packet into bytes for the wire even though we're not # sending it anywhere because that's when the authenticator gets # generated and set request_packet.RequestPacket() defer.returnValue(request_packet)
def get_pap_pass(self, pkt): try: packet_password = packet.AuthPacket( secret=pkt.secret, authenticator=pkt.authenticator).PwDecrypt( pkt['User-Password'][0]) except Exception, e: packet_password = "******"
def setUp(self): self.path = os.path.join(home, 'data') self.dict = Dictionary(os.path.join(self.path, 'full')) self.packet = packet.AuthPacket( id=0, secret=six.b('secret'), authenticator=six.b('01234567890ABCDEF'), dict=self.dict)
def setUp(self): self.path = os.path.join(home, 'tests', 'data') self.dict = Dictionary(os.path.join(self.path, 'full')) self.packet = packet.AuthPacket( id=0, secret=six.b('secret'), authenticator=six.b('01234567890ABCDEF'), dict=self.dict) self.packet['Test-Password'] = self.packet.PwCrypt('test')
def testConstructPassword(self): pkt = packet.AuthPacket(dict=self.dict, auto_crypt=True, secret=six.b('secret'), authenticator=six.b('01234567890ABCDEF'), Test_Password=six.u('test')) self.assertEqual(pkt['Test-Password'], [six.u('test')]) # Raw access to attribute does not decrypt self.assertEqual( pkt[4], [six.b('\xf4Y%\xb6_b\x7f\xba\x07\xe3\xa8*\xa8x\x14\x01')])
def setUp(self): self.path = os.path.join(home, 'tests', 'data') self.dict = Dictionary(os.path.join(self.path, 'full')) self.packet = packet.AuthPacket( id=0, secret=six.b('secret'), authenticator=six.b('01234567890ABCDEF'), dict=self.dict) self.packet['Test-Tunnel-Pwd'] = \ (1, self.packet.TunnelPwCrypt(six.b('\x80\x01'), 'test'))
def CreateAuthPacket(self, **args): """Create a new authentication RADIUS packet. This utility function creates a new RADIUS authentication packet which can be used to communicate with the RADIUS server this client talks to. This is initializing the new packet with the dictionary and secret used for the client. :return: a new empty packet instance :rtype: pyrad.packet.AuthPacket """ return packet.AuthPacket(dict=self.dict, **args)
def get_pap_pass(self, pkt): """Получение открытого пароля""" try: packet_password = packet.AuthPacket( secret=config.secret, authenticator=pkt.authenticator).PwDecrypt(pkt.get(2)[0]) return packet_password except TypeError: print "Not passw in input" return None
def _create_request(self, alias, code): client = self._get_session(self._client,alias) secret = client['secret'] dictionary = client['dictionary'] if code == packet.AccessRequest: request = packet.AuthPacket(code=code, secret=secret, dict=dictionary) elif code in [packet.AccountingRequest, packet.CoARequest, packet.DisconnectRequest]: request = packet.AcctPacket(code=code, secret=secret, dict=dictionary) client['request'].register(request, str(request.id)) return request
def run(self): addr = self._args[0] secrfile = self._args[1] pswd = self._args[2] outq = self._args[3] if secrfile: with open(secrfile, 'rb') as file: secr = file.read().strip() else: secr = b'' data = self.listen(addr) outq.put("started") (buf, sock, addr) = self.recvRequest(data) pkt = packet.AuthPacket(secret=secr, dict=RadiusDaemon.DICTIONARY, packet=buf) usernm = [] passwd = [] for key in pkt.keys(): if key == 'User-Password': passwd = list(map(pkt.PwDecrypt, pkt[key])) elif key == 'User-Name': usernm = pkt[key] reply = pkt.CreateReply() replyq = {'user': usernm, 'pass': passwd} if passwd == [pswd]: reply.code = packet.AccessAccept replyq['reply'] = True else: reply.code = packet.AccessReject replyq['reply'] = False outq.put(replyq) if addr is None: sock.send(reply.ReplyPacket()) else: sock.sendto(reply.ReplyPacket(), addr) sock.close()
def main(): dct = Dictionary(StringIO(DICTIONARY)) proc = subprocess.Popen(["./ipa-otpd", sys.argv[1]], stdin=subprocess.PIPE, stdout=subprocess.PIPE) pkt = packet.AuthPacket(secret="", dict=dct) pkt["User-Name"] = sys.argv[2] pkt["User-Password"] = pkt.PwCrypt(sys.argv[3]) pkt["NAS-Identifier"] = "localhost" proc.stdin.write(pkt.RequestPacket()) rsp = packet.Packet(secret="", dict=dict) buf = proc.stdout.read(4) buf += proc.stdout.read(struct.unpack("!BBH", buf)[2] - 4) rsp.DecodePacket(buf) pkt.VerifyReply(rsp) proc.terminate() proc.wait()
def handle_response(self, datagram, source): response_packet = packet.AuthPacket(packet=datagram, dict=base.radius_dictionary()) response_packet.source = source # make sure it's from the correct host (or properly ip-spoofed :) if (source[0], int(source[1])) not in self.addrs: raise packet.PacketError( 'response packet from unknown address: %s:%s' % source, ) # look up id try: request = self.requests[response_packet.id] except KeyError: raise packet.PacketError('unrecognized id in response packet: %s' % response_packet.id) # verify reply authentication if not request.packet.VerifyReply(response_packet, datagram): raise packet.PacketError( 'response packet has invalid authenticator') response_packet.secret = self.secret.encode() # Validate Message-Authenticator, if any if response_packet.message_authenticator: if not response_packet.verify_message_authenticator( original_authenticator=request.packet.authenticator): raise packet.PacketError( 'Invalid Message-Authenticator from {0}'.format(source[0])) response_packet.authenticator = request.packet.authenticator # clear request state self._request_done(request) log.msg( 'Got response for id %r from %r; code %r' % (response_packet.id, response_packet.source, response_packet.code)) # callback request.deferred.callback(response_packet)
sys.exit(0) # We could use a dictionary file, but since we need # such few attributes, we'll just include them here DICTIONARY = """ ATTRIBUTE User-Name 1 string ATTRIBUTE User-Password 2 string ATTRIBUTE NAS-Identifier 32 string """ dct = Dictionary(StringIO.StringIO(DICTIONARY)) proc = subprocess.Popen(["./ipa-otpd", sys.argv[1]], stdin=subprocess.PIPE, stdout=subprocess.PIPE) pkt = packet.AuthPacket(secret="", dict=dct) pkt["User-Name"] = sys.argv[2] pkt["User-Password"] = pkt.PwCrypt(sys.argv[3]) pkt["NAS-Identifier"] = "localhost" proc.stdin.write(pkt.RequestPacket()) rsp = packet.Packet(secret="", dict=dict) buf = proc.stdout.read(4) buf += proc.stdout.read(struct.unpack("!BBH", buf)[2] - 4) rsp.DecodePacket(buf) pkt.VerifyReply(rsp) proc.terminate() #pylint: disable=E1101 proc.wait()
def _handle_request(self, datagram, host_port): host, port = host_port request_pkt = packet.AuthPacket(packet=datagram, dict=base.radius_dictionary()) request_pkt.source = (host, port) # make sure it's an AccessRequest if request_pkt.code != packet.AccessRequest: raise packet.PacketError("non-AccessRequest packet received") # lookup secret secret_for_host = self.secret_for_host(host) if secret_for_host is not None: request_pkt.secret = secret_for_host.encode() else: raise packet.PacketError("Unknown Client: %s" % host) # Validate Message-Authenticator, if any if request_pkt.message_authenticator: if not request_pkt.verify_message_authenticator(): raise packet.PacketError( "Invalid Message-Authenticator from {0}".format(host)) # check to see if it's a resend (i.e. client retry) old_request = self.requests.get((request_pkt.source, request_pkt.id)) if old_request: old_request_pkt = old_request.packet if _match_request_packets(request_pkt, old_request_pkt): # enough things (src, id, authenticator, username, # password) match that it's probably safe to assume # it's a resend. so send our result back (if we have # one); otherwise ignore self.log_request(old_request, "Received duplicate request") self._resend_response(old_request) defer.returnValue(old_request) else: self._cleanup_request(old_request) # create request state log.msg("Received new request id %r from %r" % (request_pkt.id, request_pkt.source)) request = _ProxyRequest(request_pkt, self.pw_codec, self.client_ip_attr) self.requests[(request.source, request.id)] = request try: # Check if password property can decrypt using the current secret. if self._can_decode_password(request): # authenticate the user request.response = yield self._get_response(request) else: self.log_request( request, "Cannot decode password using the configured" " radius_secret. Please ensure the client and" " Authentication Proxy use the same shared" " secret.", ) msg = "Cannot decode password" log.auth_standard( msg=msg, username=request.username, auth_stage=log.AUTH_UNKNOWN, status=log.AUTH_ERROR, server_section=self.server_section_name, client_ip=request.client_ip, server_section_ikey=self.server_section_ikey, ) response = self.create_reject_packet(request, msg) request.response = response.ReplyPacket() self._send_response(request) defer.returnValue(request) except Exception as e: # Something went wrong. Clean up the request and raise. self._cleanup_request(request) raise e