pyrad.client_async – asyncio client
asyncio RADIUS client.
- class pyrad.client_async.ClientAsync(server, auth_port=1812, acct_port=1813, coa_port=3799, secret=b'', dict=None, loop=None, retries=3, timeout=30, logger_name='pyrad', enforce_ma=False)[source]
Basic asyncio RADIUS client.
Sends requests to one RADIUS server, retransmits them if no reply is received and verifies the replies. Await
initialize_transports()before creating and sending packets, anddeinitialize_transports()when done. There is one transport (socket) each for authentication, accounting and CoA packets.- Variables:
server – hostname or IP address of the RADIUS server
secret – RADIUS secret shared with the server
retries – number of times a request is retransmitted, it is sent at most
retries + 1timestimeout – number of seconds to wait for a reply after each send
enforce_ma – require a Message-Authenticator in replies to Access-Request and Status-Server packets
- Parameters:
server (str) – hostname or IP address of the RADIUS server
auth_port (int) – server port for authentication packets
acct_port (int) – server port for accounting packets
coa_port (int) – server port for CoA and Disconnect packets
secret (bytes) – RADIUS secret
dict (pyrad.dictionary.Dictionary) – RADIUS dictionary
loop (asyncio.AbstractEventLoop) – event loop, defaults to the running loop
retries (int) – number of times a request is retransmitted, it is sent at most
retries + 1timestimeout (float) – number of seconds to wait for a reply after each send
logger_name (str) – name of the logger
enforce_ma (bool) – require a Message-Authenticator in replies to Access-Request and Status-Server packets (a Message-Authenticator in a reply is always verified)
- CreateAcctPacket(**args)[source]
Create an accounting packet for the server of this client.
The packet has the dictionary and secret of the client and an id that is not used by a pending request of the accounting transport. The keyword arguments are passed to
pyrad.packet.AcctPacket: packet arguments (code,authenticator,message_authenticator,packet) and attributes to add, with-in the attribute names replaced by_. The default code is Accounting-Request;code=pyrad.packet.StatusServercreates a Status-Server packet to the accounting port.- Returns:
a new packet
- Return type:
- Raises:
Exception – the accounting transport is not initialized, or 256 requests are pending
- CreateAuthPacket(**args)[source]
Create an authentication packet for the server of this client.
The packet has the dictionary and secret of the client and an id that is not used by a pending request of the authentication transport. The keyword arguments are passed to
pyrad.packet.AuthPacket: packet arguments (code,authenticator,message_authenticator,packet) and attributes to add, with-in the attribute names replaced by_. The default code is Access-Request, usecode=pyrad.packet.StatusServerfor a Status-Server packet to the authentication port.A Message-Authenticator is added when the packet is encoded, as countermeasure against the BlastRADIUS attack (CVE-2024-3596); disable it with
message_authenticator=False.For PAP the password must be encrypted:
pkt['User-Password'] = pkt.PwCrypt(password).With
auth_type='eap-md5',SendPacket()authenticates with EAP-MD5 instead; User-Password then holds the cleartext password.- Returns:
a new packet
- Return type:
- Raises:
Exception – the authentication transport is not initialized, or 256 requests are pending
- CreateCoAPacket(**args)[source]
Create a CoA-Request or Disconnect-Request for this client’s server.
The packet has the dictionary and secret of the client and an id that is not used by a pending request of the CoA transport. The keyword arguments are passed to
pyrad.packet.CoAPacket: packet arguments (code,authenticator,message_authenticator,packet) and attributes to add, with-in the attribute names replaced by_. The default code is CoA-Request, passcode=pyrad.packet.DisconnectRequestfor a Disconnect-Request.- Returns:
a new packet
- Return type:
- Raises:
Exception – the CoA transport is not initialized, or 256 requests are pending
- CreatePacket(id, **args)[source]
Create a generic packet with the dictionary and secret of the client.
A generic
pyrad.packet.Packetcannot be sent withSendPacket(), useCreateAuthPacket(),CreateAcctPacket()orCreateCoAPacket()instead.- Parameters:
id (int) – packet identifier
args – further arguments of
pyrad.packet.Packetand attributes to add
- Returns:
a new packet
- Return type:
- Raises:
Exception –
idis None
- SendPacket(pkt)[source]
Send a request to the RADIUS server.
This is not a coroutine: the request is sent right away and a future is returned, await it for the reply. An
AuthPacketis sent with the authentication transport, anAcctPacketwith the accounting transport and aCoAPacketwith the CoA transport.If no valid reply is received within
timeoutseconds, the request is retransmitted (the same bytes as the first attempt), at mostretriestimes. Invalid replies are ignored. Without a valid reply the future fails with the builtinTimeoutErrorafter(retries + 1) * timeoutseconds (on Python 3.10 this is notasyncio.TimeoutError). It fails withConnectionAbortedErrorifdeinitialize_transports()closes the transport first.With
auth_type='eap-md5'the client authenticates with EAP-MD5 (RFC 3748, RFC 3579), likepyrad.client.Client.SendPacket(): the EAP-Response/Identity carries the User-Name, and User-Password holds the cleartext password, which is used for the MD5 response but not sent. The Access-Challenge of the server is answered automatically and the future has the final reply.- Parameters:
pkt (pyrad.packet.Packet) – the request to send
- Returns:
future with the reply packet; check
reply.code- Return type:
asyncio.Future
- Raises:
Exception – the transport is not initialized, the packet class is not supported, or a request with the same id is pending
ValueError – an attribute value cannot be encoded, or
auth_type='eap-md5'without User-Name or User-Password
- async deinitialize_transports(deinit_coa=True, deinit_auth=True, deinit_acct=True)[source]
Close the sockets to the server.
Requests still waiting for a reply on a closed transport fail with
ConnectionAbortedError.- Parameters:
deinit_coa (bool) – close the CoA transport
deinit_auth (bool) – close the authentication transport
deinit_acct (bool) – close the accounting transport
- async initialize_transports(enable_acct=False, enable_auth=False, enable_coa=False, local_addr=None, local_auth_port=None, local_acct_port=None, local_coa_port=None)[source]
Open the sockets to the server.
At least one transport has to be enabled. Packets can only be created and sent for enabled transports. Transports which are already open are left as they are.
- Parameters:
enable_acct (bool) – open the accounting transport
enable_auth (bool) – open the authentication transport
enable_coa (bool) – open the CoA transport
local_addr (str) – local address to bind to, with the local port of a transport or any free port
local_auth_port (int) – local port of the authentication transport, only used with
local_addrlocal_acct_port (int) – local port of the accounting transport, only used with
local_addrlocal_coa_port (int) – local port of the CoA transport, only used with
local_addr
- Raises:
Exception – no transport is enabled
OSError – a socket cannot be opened
- property loop
The event loop, the running one if none was passed.