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()andhandle_disconnect_packet(); instantiating a class that lacks one of them raises aTypeError. Then create the server and awaitinitialize_transports()in the running event loop to start listening.The handlers are plain methods called for each received request, not coroutines: an
async defhandler 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
RemoteHostwith 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.codefor another reply, e.g.pyrad.packet.AccessRejectorpyrad.packet.CoANAK. The Proxy-State attributes of the request are copied and replies to Access-Requests get a Message-Authenticator. Send it withDatagramProtocolServer.send_response().- Parameters:
pkt (pyrad.packet.Packet) – received request
attributes – attributes to add to the reply, as keyword arguments like for
pyrad.packet.Packet
- Returns:
reply packet
- Return type:
- 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_verifyits Request Authenticator has been verified. Reply as described forhandle_auth_packet().- Parameters:
protocol (DatagramProtocolServer) – transport the request was received on
pkt (pyrad.packet.AcctPacket) – received request, with
pkt.secretset to the secret of the clientaddr (tuple) – address of the client
- abstractmethod handle_auth_packet(protocol, pkt, addr)[source]
Handle an Access-Request.
Called for each Access-Request from a known client (a client in
hostsor, if present, the'0.0.0.0'entry). A Message-Authenticator in the request has been verified, and withenforce_marequests without one have been dropped. The User-Password is not verified: decrypt it withpkt.PwDecryptand check it yourself.This is a plain method, not a coroutine (see
ServerAsync). To answer, send a reply withprotocol.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:
protocol (DatagramProtocolServer) – transport the request was received on
pkt (pyrad.packet.AuthPacket) – received request, with
pkt.secretset to the secret of the clientaddr (tuple) – address of the client
- abstractmethod handle_coa_packet(protocol, pkt, addr)[source]
Handle a CoA-Request.
Called for each CoA-Request from a known client. With
enable_pkt_verifyits Request Authenticator has been verified. Reply as described forhandle_auth_packet().- Parameters:
protocol (DatagramProtocolServer) – transport the request was received on
pkt (pyrad.packet.CoAPacket) – received request, with
pkt.secretset to the secret of the clientaddr (tuple) – address of the client
- abstractmethod handle_disconnect_packet(protocol, pkt, addr)[source]
Handle a Disconnect-Request.
Called for each Disconnect-Request from a known client. With
enable_pkt_verifyits Request Authenticator has been verified. Reply as described forhandle_auth_packet().CreateReplyPacket()creates a Disconnect-ACK; setreply.codetopyrad.packet.DisconnectNAKto refuse it.- Parameters:
protocol (DatagramProtocolServer) – transport the request was received on
pkt (pyrad.packet.CoAPacket) – received request, with
pkt.secretset to the secret of the clientaddr (tuple) – address of the client
- 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
Exceptionis 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 asprotocol. 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:
reply (pyrad.packet.Packet) – reply packet, e.g. created with
ServerAsync.CreateReplyPacket()addr (tuple) – address of the client, as passed to the handler