pyrad.server_async – asyncio server

class pyrad.server_async.ServerAsync(auth_port=1812, acct_port=1813, coa_port=3799, hosts=None, dictionary=None, loop=None, logger_name='pyrad', enable_pkt_verify=True, debug=False, enforce_ma=False)[source]

Basic asyncio RADIUS server.

Derive from this class and implement all four packet handlers, handle_auth_packet(), handle_acct_packet(), handle_coa_packet() and handle_disconnect_packet(); instantiating a class that lacks one of them raises a TypeError. Then create the server and await initialize_transports() in the running event loop to start listening.

The handlers are plain methods called for each received request, not coroutines: an async def handler is never run (Python warns that the coroutine was never awaited and the client times out). For asynchronous work, start a task from the handler and send the reply from that task.

Parameters:
  • auth_port (int) – port to listen on for authentication packets

  • acct_port (int) – port to listen on for accounting packets

  • coa_port (int) – port to listen on for CoA and Disconnect packets

  • hosts (dict[str, pyrad.server.RemoteHost]) – clients allowed to send requests, mapping their IP address to a RemoteHost with the shared secret. The entry '0.0.0.0' is used for all other clients. IPv4 clients of a socket bound to '::' are looked up by their IPv4 address. Requests of other clients are dropped.

  • dictionary (pyrad.dictionary.Dictionary) – RADIUS dictionary used to decode the requests

  • loop (asyncio.AbstractEventLoop) – event loop, by default the loop running when it is used

  • logger_name (str) – name of the logger

  • enable_pkt_verify (bool) – drop Accounting, CoA and Disconnect requests with an invalid Request Authenticator

  • debug (bool) – log a traceback for packets that fail verification or in a handler, instead of a one-line message

  • enforce_ma (bool) – drop Access-Requests without a Message-Authenticator (an invalid Message-Authenticator is always dropped)

static CreateReplyPacket(pkt, **attributes)[source]

Create a reply to a received request.

The reply is an Access-Accept for an Access-Request, an Accounting-Response for an Accounting-Request, a CoA-ACK for a CoA-Request and a Disconnect-ACK for a Disconnect-Request; change reply.code for another reply, e.g. pyrad.packet.AccessReject or pyrad.packet.CoANAK. The Proxy-State attributes of the request are copied and replies to Access-Requests get a Message-Authenticator. Send it with DatagramProtocolServer.send_response().

Parameters:
Returns:

reply packet

Return type:

pyrad.packet.Packet

async deinitialize_transports(deinit_coa=True, deinit_auth=True, deinit_acct=True)[source]

Close the sockets opened by initialize_transports().

Parameters:
  • deinit_coa (bool) – close the CoA transports

  • deinit_auth (bool) – close the authentication transports

  • deinit_acct (bool) – close the accounting transports

abstractmethod handle_acct_packet(protocol, pkt, addr)[source]

Handle an Accounting-Request.

Called for each Accounting-Request from a known client. With enable_pkt_verify its Request Authenticator has been verified. Reply as described for handle_auth_packet().

Parameters:
abstractmethod handle_auth_packet(protocol, pkt, addr)[source]

Handle an Access-Request.

Called for each Access-Request from a known client (a client in hosts or, if present, the '0.0.0.0' entry). A Message-Authenticator in the request has been verified, and with enforce_ma requests without one have been dropped. The User-Password is not verified: decrypt it with pkt.PwDecrypt and check it yourself.

This is a plain method, not a coroutine (see ServerAsync). To answer, send a reply with protocol.send_response(self.CreateReplyPacket(pkt), addr). If the handler doesn’t reply, the request is dropped. An exception raised by the handler is logged and the request is dropped.

Parameters:
abstractmethod handle_coa_packet(protocol, pkt, addr)[source]

Handle a CoA-Request.

Called for each CoA-Request from a known client. With enable_pkt_verify its Request Authenticator has been verified. Reply as described for handle_auth_packet().

Parameters:
abstractmethod handle_disconnect_packet(protocol, pkt, addr)[source]

Handle a Disconnect-Request.

Called for each Disconnect-Request from a known client. With enable_pkt_verify its Request Authenticator has been verified. Reply as described for handle_auth_packet(). CreateReplyPacket() creates a Disconnect-ACK; set reply.code to pyrad.packet.DisconnectNAK to refuse it.

Parameters:
async initialize_transports(enable_acct=False, enable_auth=False, enable_coa=False, addresses=None)[source]

Open the sockets and start listening.

Opens a socket for each address and enabled port in the running event loop. At least one of the ports has to be enabled, otherwise an Exception is raised. Addresses which are already listened on for a port are skipped, so this method can be called again to add addresses, or to retry after a socket couldn’t be opened (the error of the socket is raised).

Parameters:
  • enable_acct (bool) – listen for accounting packets

  • enable_auth (bool) – listen for authentication packets

  • enable_coa (bool) – listen for CoA and Disconnect packets

  • addresses (list[str]) – IP addresses to listen on, by default ['127.0.0.1']

property loop

The event loop, the running one if none was passed.

class pyrad.server_async.DatagramProtocolServer(ip, port, logger, server, server_type, hosts, request_callback)[source]

The transport of one listening socket of a ServerAsync.

ServerAsync.initialize_transports() creates one for each address and port it listens on, and passes it to the packet handlers as protocol. Don’t create it yourself.

Variables:
  • ip (str) – address the socket is bound to

  • port (int) – port the socket is bound to

send_response(reply, addr)[source]

Send a reply packet to a client.

Parameters: