Esempio n. 1
0
    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)
Esempio n. 2
0
 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'))
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
0
 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 = "******"
Esempio n. 6
0
 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)
Esempio n. 7
0
 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')
Esempio n. 8
0
 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')])
Esempio n. 9
0
 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'))
Esempio n. 10
0
    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
Esempio n. 12
0
    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
Esempio n. 13
0
    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()
Esempio n. 14
0
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()
Esempio n. 15
0
    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)
Esempio n. 16
0
    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()
Esempio n. 17
0
    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