Пример #1
0
    def verify_message_authentication(radius_packet, secret):
        """
		Verifies authenticity of the message

		When the message integrity check is calculated the signature
		string should be considered to be sixteen octets of zero.  The
		shared secret is used as the key for the HMAC-MD5 message
		integrity check.  The Message-Authenticator is calculated and
		inserted in the packet before the Response Authenticator is
		calculated.
		"""
        radius_packet_copy = radius.RADIUSPacket()
        radius_packet_copy.set_code(radius_packet.get_code())
        radius_packet_copy.set_identifier(radius_packet.get_identifier())
        radius_packet_copy.set_authenticator(radius_packet.get_authenticator())
        #authenticator = radius_packet_copy.get_authenticator();
        attributes = radius_packet.get_attributes()
        authentication_message = None
        for attribute in attributes:
            if attribute.get_type(
            ) == radius.RADIUS_EAP_MESSAGE_AUTHENTICATOR_ATTRIBUTE:
                authentication_message = attribute.get_value()
                # Set Message-Authentication attribute value to 16 zero bytes
                attribute = radius.RADIUSAttribute(
                    radius.RADIUS_EAP_MESSAGE_AUTHENTICATOR_ATTRIBUTE,
                    [0] * radius.RADIUS_AUTHENTICATOR_FIELD_LENGTH)
            radius_packet_copy.add_attribute(attribute)
        md5hmac = digest.HMACMD5()
        #computed_authenticator = md5.digest(bytearray(radius_packet_copy.get_bytes()) + bytearray(secret));
        authenticator_bytes = md5hmac.digest(
            secret, bytearray(radius_packet_copy.get_bytes()))
        return Utils.compare_bytearrays(authenticator_bytes,
                                        authentication_message)
Пример #2
0
    def handle_accounting_response(authenticator, radius_identifier, socket,
                                   address):
        """
		Radius accounting response
		"""
        radius_accounting_response = radius.RADIUSPacket()
        """
		Set the code of the RADIUS packet to challenge type
		"""
        radius_accounting_response.set_code(
            radius.RADIUS_ACCOUNTING_RESPONSE_TYPE)
        """
		Set correct value of the authenticator field
		"""
        radius_accounting_response.set_authenticator(authenticator)
        """
		Set the identifier so that the NAS can match request with response
		"""
        radius_accounting_response.set_identifier(radius_identifier)
        """
		Compute resposne authenticator
		"""
        response_authenticator = Utils.Utils.compute_response_authenticator(
            radius_accounting_response,
            bytearray(config["security"]["radius_master_secret"],
                      encoding='utf8'))
        radius_accounting_response.set_authenticator(response_authenticator)
        """
		Send response packet 
		"""
        bytes_out = socket.sendto(
            bytearray(radius_accounting_response.get_bytes()), address)
        print("Sent %d" % (bytes_out))
Пример #3
0
 def handle_access_reject(authenticator, radius_identifier, socket,
                          address):
     eap_packet = eap.EAPFailure()
     packet = eap_packet.get_bytes()
     radius_reject = radius.RADIUSPacket()
     radius_reject.set_code(radius.RADIUS_ACCESS_REJECT_TYPE)
     radius_reject.set_authenticator(authenticator)
     radius_reject.set_identifier(radius_identifier)
     Utils.Utils.radius_split_message(
         radius_reject, packet,
         config["networking"]["eap_message_attribute_length"])
     message_authenticator_attribute = (radius.RADIUSAttribute(
         radius.RADIUS_EAP_MESSAGE_AUTHENTICATOR_ATTRIBUTE,
         [0] * radius.RADIUS_AUTHENTICATOR_FIELD_LENGTH))
     radius_reject.add_attribute(message_authenticator_attribute)
     message_authentication_bytes = (
         Utils.Utils.compute_message_authentication(
             radius_reject,
             bytearray(config["security"]["radius_master_secret"],
                       encoding='utf8')))
     radius_reject = Utils.Utils.set_message_authentication(
         radius_reject, message_authentication_bytes)
     response_authenticator = Utils.Utils.compute_response_authenticator(
         radius_reject,
         bytearray(config["security"]["radius_master_secret"],
                   encoding='utf8'))
     radius_reject.set_authenticator(response_authenticator)
     bytes_out = socket.sendto(bytearray(radius_reject.get_bytes()),
                               address)
     print("Sent %d" % (bytes_out))
Пример #4
0
    def acknowledge_client_key_exchange_fragment(authenticator,
                                                 radius_identifier,
                                                 eap_identifier, socket,
                                                 address):

        eap_ttls_packet = eap.EAPTTLSRequest()
        eap_ttls_packet.set_identifier(eap_identifier)
        packet = eap_ttls_packet.get_bytes()
        radius_challenge = radius.RADIUSPacket()
        """
		Set the code of the RADIUS packet to challenge type
		"""
        radius_challenge.set_code(radius.RADIUS_ACCESS_CHALLENGE_TYPE)
        """
		Set correct value of the authenticator field
		"""
        radius_challenge.set_authenticator(authenticator)
        """
		Set the identifier so that the NAS can match request with response
		"""
        radius_challenge.set_identifier(radius_identifier)
        #message = outstanding_packets[calling_station_id][0].get_bytes();
        Utils.Utils.radius_split_message(
            radius_challenge, packet,
            config["networking"]["eap_message_attribute_length"])
        message_authenticator_attribute = (radius.RADIUSAttribute(
            radius.RADIUS_EAP_MESSAGE_AUTHENTICATOR_ATTRIBUTE,
            [0] * radius.RADIUS_AUTHENTICATOR_FIELD_LENGTH))
        radius_challenge.add_attribute(message_authenticator_attribute)
        """
		Compute message authentication
		"""
        message_authentication_bytes = (
            Utils.Utils.compute_message_authentication(
                radius_challenge,
                bytearray(config["security"]["radius_master_secret"],
                          encoding='utf8')))
        """
		Update the message authentication attribute
		"""
        radius_challenge = Utils.Utils.set_message_authentication(
            radius_challenge, message_authentication_bytes)
        """
		Compute and update response authenticator
		"""
        response_authenticator = Utils.Utils.compute_response_authenticator(
            radius_challenge,
            bytearray(config["security"]["radius_master_secret"],
                      encoding='utf8'))
        radius_challenge.set_authenticator(response_authenticator)
        bytes_out = socket.sendto(bytearray(radius_challenge.get_bytes()),
                                  address)
        print("Sent %d" % (bytes_out))
Пример #5
0
 def verify_accounting_authenticator(radius_packet, secret):
     authenticator = radius_packet.get_authenticator()
     radius_packet_copy = radius.RADIUSPacket()
     radius_packet_copy.set_code(radius_packet.get_code())
     radius_packet_copy.set_identifier(radius_packet.get_identifier())
     attributes = radius_packet.get_attributes()
     for attribute in attributes:
         radius_packet_copy.add_attribute(attribute)
     md5 = digest.MD5Digest()
     authenticator_computed = md5.digest(
         bytearray(radius_packet_copy.get_bytes()) + secret)
     return Utils.compare_bytearrays(authenticator_computed, authenticator)
Пример #6
0
    def set_message_authentication(radius_packet, authentication_message):
        """
		Sets the value of the message authentication attribute

		This is rather wrong way of doing things. Perhaps, in future, 
		we may set attribute values directly in the packet.
		"""
        radius_packet_copy = radius.RADIUSPacket()
        radius_packet_copy.set_code(radius_packet.get_code())
        radius_packet_copy.set_identifier(radius_packet.get_identifier())
        radius_packet_copy.set_authenticator(radius_packet.get_authenticator())
        attributes = radius_packet.get_attributes()
        for attribute in attributes:
            if attribute.get_type(
            ) == radius.RADIUS_EAP_MESSAGE_AUTHENTICATOR_ATTRIBUTE:
                attribute = radius.RADIUSAttribute(
                    radius.RADIUS_EAP_MESSAGE_AUTHENTICATOR_ATTRIBUTE,
                    authentication_message)
            radius_packet_copy.add_attribute(attribute)
        return radius_packet_copy
Пример #7
0
    def compute_message_authentication(radius_packet, secret):
        """
		Computes message authentication code for the given RADIUS packet.

		For Access-Challenge, Access-Accept, and Access-Reject packets,
		the Message-Authenticator is calculated as follows, using the
		Request-Authenticator from the Access-Request this packet is in
		reply to:

		Message-Authenticator = HMAC-MD5 (Type, Identifier, Length,
											Request Authenticator, Attributes)
		
		When the message integrity check is calculated the signature
		string should be considered to be sixteen octets of zero.  The
		shared secret is used as the key for the HMAC-MD5 message
		integrity check.  The Message-Authenticator is calculated and
		inserted in the packet before the Response Authenticator is
		calculated.

		"""
        radius_packet_copy = radius.RADIUSPacket()
        radius_packet_copy.set_code(radius_packet.get_code())
        radius_packet_copy.set_identifier(radius_packet.get_identifier())
        radius_packet_copy.set_authenticator(radius_packet.get_authenticator())
        attributes = radius_packet.get_attributes()
        authentication_message = None
        for attribute in attributes:
            if attribute.get_type(
            ) == radius.RADIUS_EAP_MESSAGE_AUTHENTICATOR_ATTRIBUTE:
                authentication_message = attribute.get_value()
                # Set Message-Authentication attribute value to 16 zero bytes
                attribute = radius.RADIUSAttribute(
                    radius.RADIUS_EAP_MESSAGE_AUTHENTICATOR_ATTRIBUTE,
                    [0] * radius.RADIUS_AUTHENTICATOR_FIELD_LENGTH)
            radius_packet_copy.add_attribute(attribute)
        md5hmac = digest.HMACMD5()
        return md5hmac.digest(secret,
                              bytearray(radius_packet_copy.get_bytes()))
Пример #8
0
def accounting_loop(socket):
	"""
	Runs accounting loop
	"""
	mtu = config["networking"]["mtu"];
	running = True;
	while running:
		data, address = socket.recvfrom(mtu);
		src_ip = address[0];
		src_port = address[1];
		print("Got packet from address %s on port %s" % (src_ip, src_port))
		"""
		RFC 2866 defines attributes which can be used in RADIUS accouting packets
		https://tools.ietf.org/html/rfc2866
		"""
		try:
			radius_packet = radius.RADIUSPacket(data);
			print("Packet type: %s" % (radius_packet.get_code()))
			if radius_packet.get_code() == radius.RADIUS_ACCOUNTING_REQUEST_TYPE:
				print("Got accouting request packet");
				authenticator = radius_packet.get_authenticator();
				radius_identifier = radius_packet.get_identifier();
				"""
				The following steps should be taken:
				(i) verify the authenticity of the packet
				(ii) check the packet's Acct-Status-Type
				(iii) if accouting type is of type Start insert a record into the database
				(iv) if accouting type is of type stop finilize the accounting
				"""
				if not Utils.Utils.verify_accounting_authenticator(radius_packet, bytearray(config["security"]["radius_master_secret"], encoding='utf8')):
					print("Invalid authenticator in RADIUS packet...");
					continue;
				
				PacketProcessor.handle_accounting_response(authenticator, radius_identifier, socket, address);
				continue;
		except Exception as e:
			traceback.print_exc();
Пример #9
0
def authentication_loop(socket):
	"""
	Runs the authentication loop. This is the main loop 
	where TLS packets are processed and state is maintained
	"""
	certificate = certs.X509v3Certificate.load(config["security"]["certificate_path"]);
	private_key = certs.RSAPrivateKey.load(config["security"]["private_key"]);
	mtu = config["networking"]["mtu"];
	running = True;
	outstanding_packets = dict();
	handshake_packets = dict();
	duplicates = dict();
	eap_identifier = 1;
	while running:
		data, address = socket.recvfrom(mtu);
		src_ip = address[0];
		src_port = address[1];
		print("Got packet from address %s on port %s" % (src_ip, src_port))
		try:
			radius_packet = radius.RADIUSPacket(data);
			calling_station_id = Utils.Utils.get_calling_station_id(radius_packet);
			"""
			The Identifier field is one octet, and aids in matching requests
			and replies.  The RADIUS server can detect a duplicate request if
			it has the same client source IP address and source UDP port and
			Identifier within a short span of time.
			"""
			if calling_station_id not in duplicates.keys():
				duplicates[calling_station_id] = radius_packet.get_identifier();
			else:
				if duplicates[calling_station_id] == radius_packet.get_identifier():
					print("We have a duplicate. Skipping...");
					continue;
				else:
					duplicates[calling_station_id] = radius_packet.get_identifier();
			print("Packet type: %d" % (radius_packet.get_code()));
			#
			if radius_packet.get_code() == radius.RADIUS_ACCESS_REQUEST_TYPE:
				authenticator = radius_packet.get_authenticator();
				radius_identifier = radius_packet.get_identifier();
				"""
				Check the authenticity of the RADIUS packet
				"""
				if not PacketProcessor.verify_access_request_packet(radius_packet):
					print("RADIUS packet verification failure. Skipping the packet...");
					continue;
				# Construct EAP message from fragments
				fragments = Utils.Utils.get_eap_packet(radius_packet);
				if not calling_station_id:
					print("No calling station ID present in RADIUS packet. Skipping...");
					continue;
				# Non-EAP packet (need to check what to do in case no EAP message is present in RADIUS packet)
				if len(fragments) == 0x0:
					print("No RADIUS encapsulated EAP packet fragments were found. Skipping...");
					continue; # Silently drop the packet for now
				eap_packet = eap.EAPPacket(fragments);
				if eap_packet.get_type() == eap.EAP_IDENTITY_TYPE:
					if tls_state_machine.get_state(calling_station_id):
						print("TLS state already exists. Perhaps this is a duplicate. Skipping.");
						continue;
					print("Sending RADIUS access challenge in response to RADIUS access request...");
					#print("Sending encapsulated EAP Request packet with start flag set to 1...");
					radius_challenge = PacketProcessor.handle_identity_packet(eap_packet, 
						tls_state_machine, 
						calling_station_id,
						authenticator,
						radius_identifier,
						eap_identifier,
						socket,
						address);
					eap_identifier = (eap_identifier + 1) % 0x100;
				elif eap_packet.get_type() == eap.EAP_TTLS_TYPE:
					print("Got EAP TTLS packet");
					# Reconstruct EAP TTLS packet from fragments
					eap_ttls_packet = eap.EAPTTLSPacket(fragments);
					tls_state = tls_state_machine.get_state(calling_station_id);
					if not tls_state:
						print("Invalid TLS state.");
						continue;
					if eap_ttls_packet.get_code() != eap.EAP_TTLS_RESPONSE_CODE:
						print("Should be EAP TTLS response packet. Droping...");
						continue;
					flags = eap_ttls_packet.get_flags();
					has_more_fragments = eap.HAS_MORE_FRAGMENTS(flags);
					# If the packet has more fragments flag set we should 
					# reassemble the TLS packet before we can parse it.
					if not has_more_fragments:
						# If we have not seen client's hello we should process it first
						print("We have received unfragmented packet...");
						if not tls_state.get_client_hello_received():
							handshake_packets[calling_station_id] = [];
							# We are looking for TLS client's hello packet
							tls_packet = tls.TLSPacket(eap_ttls_packet.get_bytes_without_header());
							if tls_packet.get_records()[0].get_content_type() == tls.TLS_CONTENT_TYPE_ALERT:
								print("Error has occured.");
								continue;
							if not (PacketProcessor.handle_client_hello_packet(
								tls_packet, 
								tls_state,
								handshake_packets[calling_station_id]
								)):
								print("Failed to handle client hello packet. Skipping");
								continue;
							outstanding_packets[calling_station_id] = PacketProcessor.process_server_hello_packet(
										tls_state, 
										certificate,
										eap_identifier,
										handshake_packets[calling_station_id]
										);
							packet = outstanding_packets[calling_station_id][0];
							outstanding_packets[calling_station_id] = outstanding_packets[calling_station_id][1:];
							PacketProcessor.send_outstanding_packet(
								packet.get_bytes(), 
								authenticator,
								radius_identifier,
								eap_identifier,
								socket,
								address);
							eap_identifier = (eap_identifier + 1) % 0x100;
						elif not tls_state.get_server_hello_sent():
							# We should now send the server's hello packet
							if len(outstanding_packets[calling_station_id]) > 0:
								packet = outstanding_packets[calling_station_id][0];
								outstanding_packets[calling_station_id] = outstanding_packets[calling_station_id][1:];
								PacketProcessor.send_outstanding_packet(
									packet.get_bytes(), 
									authenticator,
									radius_identifier,
									eap_identifier,
									socket,
									address);
								eap_identifier = (eap_identifier + 1) % 0x100;
								if len(outstanding_packets[calling_station_id]) == 0:
									print("Server hello, certificate and server hello done packets have been sent out.");
									tls_state.set_server_hello_sent(True);
									tls_state.set_server_certificate_sent(True);
									tls_state.set_server_hello_done_sent(True);
							else:
								print("We should have outstanding packets. Error...");
								continue;
						elif not tls_state.get_server_certificate_sent():
							# We should now send the server's certificate
							print("We should never be in this state.");
							pass
						elif not tls_state.get_server_hello_done_sent():
							# We should now send the server's hello done
							print("We should never be in this state.");
							pass
						elif not tls_state.get_client_key_exchange_received():
							# We are expecting the client's key exchange protocol
							outstanding_packets[calling_station_id] += eap_ttls_packet.get_bytes_without_header();
							tls_packet = tls.TLSPacket(outstanding_packets[calling_station_id]);
							if tls_packet.get_records()[0].get_content_type() == tls.TLS_CONTENT_TYPE_ALERT:
								print("Error has occured.");
								continue;
							PacketProcessor.handle_client_key_exchange_packet(
								tls_packet,
								tls_state,
								private_key.get_key_info(),
								handshake_packets[calling_station_id]);
							if not PacketProcessor.handle_client_cipher_spec_change_packet(tls_packet, tls_state):
								# This is an error - client's cipher spec change packet must follow the client 
								# key exchange packet
								continue;
							# Verify the encrypted finished message
							if not PacketProcessor.handle_client_encrypted_finish_message(
								tls_packet,
								tls_state, 
								handshake_packets[calling_station_id]):
								print("Failed to verify the encrypted finish message.");
							else:
								print("Verification succeeded.");	
								#print(hexlify(bytearray(PacketProcessor.get_unencrypted_finished_message(tls_state, tls_packet))))
								handshake_packets[calling_station_id] += PacketProcessor.get_unencrypted_finished_message(tls_state, tls_packet);
								#tls_state.set_client_finished_message_received(True);
								PacketProcessor.process_server_cipher_spec_changed_packet(
									authenticator, 
									radius_identifier,
									eap_identifier,
									socket,
									address);
								eap_identifier = (eap_identifier + 1) % 0x100;
								tls_state.set_client_key_exchange_received(True);
								#tls_state.set_server_cipher_spec_changed_sent(True);
						elif not tls_state.get_server_cipher_spec_changed_sent():
							print("Processing server's encrypted message.");
							PacketProcessor.process_server_encrypted_finish_message(
									tls_state, 
									handshake_packets[calling_station_id],
									authenticator,
									radius_identifier,
									socket,
									address
									);
							tls_state.set_server_cipher_spec_changed_sent(True);
							tls_state.set_server_finished_message_sent(True);
							continue;
						elif tls_state.get_server_finished_message_sent():
							tls_packet = tls.TLSPacket(eap_ttls_packet.get_bytes_without_header());
							if tls_packet.get_records()[0].get_content_type() == tls.TLS_CONTENT_TYPE_ALERT:
								print("Encrypted alert. Skipping.");
								PacketProcessor.process_encrypted_alert(tls_state, tls_packet);
								continue;
							elif tls_packet.get_records()[0].get_content_type() == tls.TLS_CONTENT_TYPE_APPLICATION_DATA:
								print("Expecting PAP packet with AVPs (username and password)");
								attributes = PacketProcessor.process_encrypted_pap_avp(tls_state, tls_packet);
								username = None;
								password = None;
								for attribute in attributes:
									if attribute.get_code() == eap.PAP_USERNAME_ATTRIBUTE_CODE:
										username = utils.Utils.remove_null_bytes(attribute.get_data());
									elif attribute.get_code() == eap.PAP_PASSWORD_ATTRBIUTE_CODE:
										password = utils.Utils.remove_null_bytes(attribute.get_data());
									else:
										print("Unknown attribute");
										continue;
								if database.authenticate(username, password):
									print("Access was granted to the user");
									(bytes_remaining, conn_speed) = database.get_bytes_remaining_and_conn_speed(username);
									PacketProcessor.handle_access_accept(
										tls_state, 
										bytes_remaining,
										conn_speed,
										authenticator, 
										radius_identifier,
										socket,
										address);
								else:
									print("Access was rejected");
									PacketProcessor.handle_access_reject(
										authenticator, 
										radius_identifier,
										socket,
										address);
						else:
							print("Unknonw state. We should never be here.")
					else:
						if not tls_state.get_client_hello_received():
							# We are looking for TLS client's hello packet
							pass
						elif not tls_state.get_server_hello_sent():
							# We should now send the server's hello packet
							pass
						elif not tls_state.get_server_certificate_sent():
							# We should now send the server's certificate
							pass
						elif not tls_state.get_server_hello_done_sent():
							# We should now send the server's hello done
							pass
						elif not tls_state.get_client_key_exchange_received():
							# We are expecting the client's key exchange protocol
							outstanding_packets[calling_station_id] += eap_ttls_packet.get_bytes_without_header();
							PacketProcessor.acknowledge_client_key_exchange_fragment(
								authenticator,
								radius_identifier,
								eap_identifier,
								socket,
								address);
							# This should be done on per client bases
							eap_identifier = (eap_identifier + 1) % 0x100;
						elif not tls_state.get_client_cipher_spec_changed_received():
							# We are expecting the client's cipher spec changed
							pass
						elif not tls_state.get_client_finished_message_received():
							# We are expecting the client's finished message 
							pass
						elif not tls_state.get_server_cipher_spec_changed_sent():
							# We should now
							pass
				else:
					print("Unsupported EAP packet type...");
			else:
				print("Invalid RADIUS packet type recieved. Expected RADIUS Access-Request packet.");
		except Exception as e:
					traceback.print_exc();
Пример #10
0
    def handle_access_accept(tls_state, bytes_remaining, conn_speed,
                             authenticator, radius_identifier, socket,
                             address):
        eap_packet = eap.EAPSuccess()
        packet = eap_packet.get_bytes()
        radius_success = radius.RADIUSPacket()
        radius_success.set_code(radius.RADIUS_ACCESS_ACCEPT_TYPE)
        radius_success.set_authenticator(authenticator)
        radius_success.set_identifier(radius_identifier)
        Utils.Utils.radius_split_message(
            radius_success, packet,
            config["networking"]["eap_message_attribute_length"])
        keying_material = wpa2.WPA2.generate_keying_material(
            tls_state.get_master_secret(),
            bytearray(tls_state.get_client_random()),
            bytearray(tls_state.get_server_random()))
        # This code was tested and the MSK and EMSK were derived correctly...
        msk_key = wpa2.WPA2.generate_msk(keying_material)
        emsk_key = wpa2.WPA2.generate_emsk(keying_material)

        microsoft_recv_key_attribute = radius.MicrosoftAttribute()
        microsoft_recv_key_attribute.set_value(
            wpa2.WPA2.encrypt_ms_key(
                bytearray(config["security"]["radius_master_secret"],
                          encoding='utf8'), authenticator,
                msk_key[0:wpa2.RECV_KEY_LENGTH]))
        microsoft_recv_key_attribute.set_type(radius.MS_MPPE_RECV_KEY)

        microsoft_send_key_attribute = radius.MicrosoftAttribute()
        microsoft_send_key_attribute.set_value(
            wpa2.WPA2.encrypt_ms_key(
                bytearray(config["security"]["radius_master_secret"],
                          encoding='utf8'), authenticator,
                msk_key[wpa2.RECV_KEY_LENGTH:wpa2.RECV_KEY_LENGTH +
                        wpa2.SEND_KEY_LENGTH]))
        microsoft_send_key_attribute.set_type(radius.MS_MPPE_SEND_KEY)

        mikrotik_conn_speed_attribute = radius.MikroTikAttribute()
        mikrotik_conn_speed_attribute.set_value(
            bytearray(conn_speed.encode("ascii")))
        mikrotik_conn_speed_attribute.set_type(radius.MIKROTIK_RATE_LIMIT)

        mikrotik_total_limit_attribute = radius.MikroTikAttribute()
        mikrotik_total_limit_attribute.set_value(
            struct.pack(">I", int(bytes_remaining % (4 * 1024 * 1024))))
        mikrotik_total_limit_attribute.set_type(radius.MIKROTIK_TOTAL_LIMIT)
        #mikrotik_total_limit_attribute.set_type(radius.MIKROTIK_SEND_LIMIT);

        mikrotik_total_limit_giga_attribute = radius.MikroTikAttribute()
        mikrotik_total_limit_giga_attribute.set_value(
            struct.pack(">I", int(bytes_remaining / (4 * 1024 * 1024))))
        mikrotik_total_limit_giga_attribute.set_type(
            radius.MIKROTIK_TOTAL_GIGAWORDS_LIMIT)

        mikrotik_recv_limit_attribute = radius.MikroTikAttribute()
        mikrotik_recv_limit_attribute.set_value(
            struct.pack(">I", int(bytes_remaining % (4 * 1024 * 1024))))
        mikrotik_recv_limit_attribute.set_type(radius.MIKROTIK_RECV_LIMIT)

        mikrotik_recv_limit_giga_attribute = radius.MikroTikAttribute()
        mikrotik_recv_limit_giga_attribute.set_value(
            struct.pack(">I", int(bytes_remaining / (4 * 1024 * 1024))))
        mikrotik_recv_limit_giga_attribute.set_type(
            radius.MIKROTIK_RECV_GIGAWORDS_LIMIT)

        conn_speed_attribute = (radius.RADIUSVendorSpecificAttribute(
            radius.RADIUS_VENDOR_SPECIFIC_ATTRIBUTE,
            radius.RADIUS_MIKROTIK_VENDOR_ID,
            mikrotik_conn_speed_attribute.get_bytes()))
        radius_success.add_attribute(conn_speed_attribute)

        total_limit_attribute = (radius.RADIUSVendorSpecificAttribute(
            radius.RADIUS_VENDOR_SPECIFIC_ATTRIBUTE,
            radius.RADIUS_MIKROTIK_VENDOR_ID,
            mikrotik_total_limit_attribute.get_bytes()))
        radius_success.add_attribute(total_limit_attribute)

        total_limit_giga_attribute = (radius.RADIUSVendorSpecificAttribute(
            radius.RADIUS_VENDOR_SPECIFIC_ATTRIBUTE,
            radius.RADIUS_MIKROTIK_VENDOR_ID,
            mikrotik_total_limit_giga_attribute.get_bytes()))
        radius_success.add_attribute(total_limit_giga_attribute)

        recv_limit_giga_attribute = (radius.RADIUSVendorSpecificAttribute(
            radius.RADIUS_VENDOR_SPECIFIC_ATTRIBUTE,
            radius.RADIUS_MIKROTIK_VENDOR_ID,
            mikrotik_recv_limit_giga_attribute.get_bytes()))
        #radius_success.add_attribute(recv_limit_giga_attribute);

        send_key_attribute = (radius.RADIUSVendorSpecificAttribute(
            radius.RADIUS_VENDOR_SPECIFIC_ATTRIBUTE,
            radius.RADIUS_MICROSOFT_VENDOR_ID,
            microsoft_send_key_attribute.get_bytes()))
        radius_success.add_attribute(send_key_attribute)

        recv_key_attribute = (radius.RADIUSVendorSpecificAttribute(
            radius.RADIUS_VENDOR_SPECIFIC_ATTRIBUTE,
            radius.RADIUS_MICROSOFT_VENDOR_ID,
            microsoft_recv_key_attribute.get_bytes()))
        radius_success.add_attribute(recv_key_attribute)

        message_authenticator_attribute = (radius.RADIUSAttribute(
            radius.RADIUS_EAP_MESSAGE_AUTHENTICATOR_ATTRIBUTE,
            [0] * radius.RADIUS_AUTHENTICATOR_FIELD_LENGTH))
        radius_success.add_attribute(message_authenticator_attribute)
        message_authentication_bytes = (
            Utils.Utils.compute_message_authentication(
                radius_success,
                bytearray(config["security"]["radius_master_secret"],
                          encoding='utf8')))
        radius_success = Utils.Utils.set_message_authentication(
            radius_success, message_authentication_bytes)
        response_authenticator = Utils.Utils.compute_response_authenticator(
            radius_success,
            bytearray(config["security"]["radius_master_secret"],
                      encoding='utf8'))
        radius_success.set_authenticator(response_authenticator)
        bytes_out = socket.sendto(bytearray(radius_success.get_bytes()),
                                  address)
        print("Sent %d" % (bytes_out))
Пример #11
0
    def handle_identity_packet(eap_packet, tls_state_machine,
                               calling_station_id, authenticator,
                               radius_identifier, eap_identifier, socket,
                               address):
        """
		Handles identity packet
		"""
        user_identity = eap_packet.get_bytes_without_header()
        print("Got EAP Identity: %s" % ("".join(map(chr, user_identity))))
        """
		Create EAP TTLS request packet
		"""
        eap_start = eap.EAPTTLSRequest()
        eap_start.set_is_start_flag()
        eap_start.set_identifier(eap_identifier)
        # Fix me we need to handle identifiers
        #eap_start.set_identifier(eap_identifier);
        #eap_identifier += 1;

        eap_start_bytes = eap_start.get_bytes()

        radius_challenge = radius.RADIUSPacket()
        """
		Set the code of the RADIUS packet to challenge type
		"""
        radius_challenge.set_code(radius.RADIUS_ACCESS_CHALLENGE_TYPE)
        """
		Set correct value of the authenticator field
		"""
        radius_challenge.set_authenticator(authenticator)
        """
		Set the identifier so that the NAS can match request with response
		"""
        radius_challenge.set_identifier(radius_identifier)
        eap_attribute = (radius.RADIUSAttribute(
            radius.RADIUS_EAP_MESSAGE_ATTRIBUTE, eap_start_bytes))
        radius_challenge.add_attribute(eap_attribute)
        message_authenticator_attribute = (radius.RADIUSAttribute(
            radius.RADIUS_EAP_MESSAGE_AUTHENTICATOR_ATTRIBUTE,
            [0] * radius.RADIUS_AUTHENTICATOR_FIELD_LENGTH))
        radius_challenge.add_attribute(message_authenticator_attribute)
        """
		Compute message authentication
		"""
        message_authentication_bytes = (
            Utils.Utils.compute_message_authentication(
                radius_challenge,
                bytearray(config["security"]["radius_master_secret"],
                          encoding='utf8')))
        """
		Update the message authentication attribute
		"""
        radius_challenge = Utils.Utils.set_message_authentication(
            radius_challenge, message_authentication_bytes)
        """
		Compute and update response authenticator
		"""
        response_authenticator = Utils.Utils.compute_response_authenticator(
            radius_challenge,
            bytearray(config["security"]["radius_master_secret"],
                      encoding='utf8'))
        radius_challenge.set_authenticator(response_authenticator)
        """
		Initialize state
		"""
        tls_state_machine.init_state(calling_station_id)
        """
		Send response packet 
		"""
        bytes_out = socket.sendto(bytearray(radius_challenge.get_bytes()),
                                  address)
        print("Sent %d" % (bytes_out))
Пример #12
0
    def process_server_encrypted_finish_message(tls_state, handshake_messages,
                                                authenticator,
                                                radius_identifier, socket,
                                                address):
        """
		Processes server's encrypted finish message
		"""
        master_secret = tls_state.get_master_secret()

        verify_data_computed = utils.Utils.verify_server_finshed_message(
            master_secret, handshake_messages,
            tls.FINISHED_MESSAGE_VERIFY_DATA_LENGTH)

        server_sequence_number = tls_state.get_server_sequence_number()

        tls_packet = tls.TLSPacket()
        tls_record = tls.TLSRecordLayer()

        finished_message_protocol = tls.FinishedMessageProtocol()
        finished_message_protocol.set_verify_data(verify_data_computed)

        hmac = utils.Utils.compute_server_finished_message_mac(
            tls_state.get_server_write_mac_key(), server_sequence_number,
            tls.TLS_CONTENT_TYPE_HANDSHAKE, tls.TLS_PROTOCOL_VERSION,
            finished_message_protocol.get_bytes())

        finished_message_protocol_bytes = finished_message_protocol.get_bytes(
        )

        message = bytearray(finished_message_protocol_bytes) + hmac

        # This should be
        # padding = [(aes.BLOCK_SIZE - len(message) % aes.BLOCK_SIZE)] * (aes.BLOCK_SIZE - len(message) % aes.BLOCK_SIZE);
        padding = [0x0f] * (aes.BLOCK_SIZE - len(message) % aes.BLOCK_SIZE)
        padding[len(padding) - 1] = len(padding) - 1

        key = tls_state.get_server_write_cipher_key()
        iv = utils.Utils.generate_random(aes.IV_SIZE)
        cipher = aes.AESCipher(aes.AES_CBC_MODE, key, iv)
        encrypted_bytes = cipher.encrypt((message + bytearray(padding)))

        tls_record.add_encrypted_protocol(bytearray(iv + encrypted_bytes))
        tls_packet.add_record(tls_record)

        eap_ttls_packet = eap.EAPTTLSRequest()
        eap_ttls_packet.set_payload(tls_packet.get_bytes(),
                                    len(tls_packet.get_bytes()))
        packet = eap_ttls_packet.get_bytes()
        radius_challenge = radius.RADIUSPacket()
        """
		Set the code of the RADIUS packet to challenge type
		"""
        radius_challenge.set_code(radius.RADIUS_ACCESS_CHALLENGE_TYPE)
        """
		Set correct value of the authenticator field
		"""
        radius_challenge.set_authenticator(authenticator)
        """
		Set the identifier so that the NAS can match request with response
		"""
        radius_challenge.set_identifier(radius_identifier)
        #message = outstanding_packets[calling_station_id][0].get_bytes();
        Utils.Utils.radius_split_message(
            radius_challenge, packet,
            config["networking"]["eap_message_attribute_length"])
        message_authenticator_attribute = (radius.RADIUSAttribute(
            radius.RADIUS_EAP_MESSAGE_AUTHENTICATOR_ATTRIBUTE,
            [0] * radius.RADIUS_AUTHENTICATOR_FIELD_LENGTH))
        radius_challenge.add_attribute(message_authenticator_attribute)
        """
		Compute message authentication
		"""
        message_authentication_bytes = (
            Utils.Utils.compute_message_authentication(
                radius_challenge,
                bytearray(config["security"]["radius_master_secret"],
                          encoding='utf8')))
        """
		Update the message authentication attribute
		"""
        radius_challenge = Utils.Utils.set_message_authentication(
            radius_challenge, message_authentication_bytes)
        """
		Compute and update response authenticator
		"""
        response_authenticator = Utils.Utils.compute_response_authenticator(
            radius_challenge,
            bytearray(config["security"]["radius_master_secret"],
                      encoding='utf8'))
        radius_challenge.set_authenticator(response_authenticator)
        bytes_out = socket.sendto(bytearray(radius_challenge.get_bytes()),
                                  address)
        print("Sent %d" % (bytes_out))
Пример #13
0
    def process_server_cipher_spec_changed_packet(authenticator,
                                                  radius_identifier,
                                                  eap_identifier, socket,
                                                  address):

        tls_record_layer = tls.TLSRecordLayer()
        tls_record_layer.set_content_type(
            tls.TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC)
        tls_record_layer.set_message([tls.TLS_CHANGE_CIPHER_SPEC_MESSAGE])

        tls_packet = tls.TLSPacket()
        tls_packet.add_record(tls_record_layer)

        radius_challenge = radius.RADIUSPacket()
        """
		Set the code of the RADIUS packet to challenge type
		"""
        radius_challenge.set_code(radius.RADIUS_ACCESS_CHALLENGE_TYPE)
        """
		Set correct value of the authenticator field
		"""
        radius_challenge.set_authenticator(authenticator)
        """
		Set the identifier so that the NAS can match request with response
		"""
        radius_challenge.set_identifier(radius_identifier)

        tls_packet_bytes = tls_packet.get_bytes()

        eap_ttls_packet = eap.EAPTTLSRequest()

        eap_ttls_packet.set_identifier(eap_identifier)

        eap_ttls_packet.set_payload(tls_packet_bytes, len(tls_packet_bytes))

        #message = outstanding_packets[calling_station_id][0].get_bytes();
        Utils.Utils.radius_split_message(
            radius_challenge, eap_ttls_packet.get_bytes(),
            config["networking"]["eap_message_attribute_length"])
        message_authenticator_attribute = (radius.RADIUSAttribute(
            radius.RADIUS_EAP_MESSAGE_AUTHENTICATOR_ATTRIBUTE,
            [0] * radius.RADIUS_AUTHENTICATOR_FIELD_LENGTH))
        radius_challenge.add_attribute(message_authenticator_attribute)
        """
		Compute message authentication
		"""
        message_authentication_bytes = (
            Utils.Utils.compute_message_authentication(
                radius_challenge,
                bytearray(config["security"]["radius_master_secret"],
                          encoding='utf8')))
        """
		Update the message authentication attribute
		"""
        radius_challenge = Utils.Utils.set_message_authentication(
            radius_challenge, message_authentication_bytes)
        """
		Compute and update response authenticator
		"""
        response_authenticator = Utils.Utils.compute_response_authenticator(
            radius_challenge,
            bytearray(config["security"]["radius_master_secret"],
                      encoding='utf8'))
        radius_challenge.set_authenticator(response_authenticator)
        bytes_out = socket.sendto(bytearray(radius_challenge.get_bytes()),
                                  address)
        print("Sent %d" % (bytes_out))