pyrad.server – basic server

class pyrad.server.RemoteHost(address, secret, name, authport=1812, acctport=1813, coaport=3799)[source]

A RADIUS client or server and its shared secret.

Used as the values of the hosts mapping of Server, pyrad.server_async.ServerAsync and pyrad.proxy.Proxy. pyrad only uses secret: the servers look up the client by the key of the hosts mapping (the IP address as the socket reports it), not by address. The address, name and ports are stored for the application and are not used by pyrad.

Parameters:
  • address (str) – IP address of the host (informational)

  • secret (bytes) – RADIUS shared secret

  • name (str) – short name of the host (informational)

  • authport (int) – authentication port of the host (informational)

  • acctport (int) – accounting port of the host (informational)

  • coaport (int) – CoA port of the host (informational)

class pyrad.server.ServerPacketError[source]

A received packet is dropped.

Raised by Server, pyrad.server_async.ServerAsync and pyrad.proxy.Proxy for packets they don’t accept: packets from an unknown client, packets of the wrong type for the port they were received on, and Access-Requests with an invalid or (with enforce_ma) a missing Message-Authenticator.

A packet handler may raise it to drop a request: the server then logs a single line with the message instead of a traceback.

class pyrad.server.Server(addresses=[], authport=1812, acctport=1813, coaport=3799, hosts=None, dict=None, auth_enabled=True, acct_enabled=True, coa_enabled=False, enforce_ma=False, enable_pkt_verify=True)[source]

Bases: Host

Basic blocking RADIUS server.

The server receives and decodes requests, checks that they come from a known client and are valid, and passes them to the packet handlers. Derive from it and override HandleAuthPacket(), HandleAcctPacket(), HandleCoaPacket() and HandleDisconnectPacket(); the default handlers ignore the request. Then call Run().

Variables:
  • hosts (dict[str, RemoteHost]) – clients allowed to send requests, see the hosts parameter

  • MaxPacketSize (int) – size of the receive buffer (RADIUS packets are at most 4096 octets)

Parameters:
  • addresses (list[str]) – IP addresses or host names to listen on. The constructor binds them with BindToAddress(). Without addresses no packets are received unless BindToAddress() is called.

  • authport (int) – port to listen on for authentication packets

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

  • coaport (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.

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

  • auth_enabled (bool) – listen for authentication packets

  • acct_enabled (bool) – listen for accounting packets

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

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

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

BindToAddress(addr)[source]

Listen on an address.

Opens a socket for each enabled port (authentication, accounting, CoA). '0.0.0.0' listens on all IPv4 addresses, '::' on all IPv6 addresses and, on a dual stack host, on all IPv4 addresses as well. A host name is resolved and every address it resolves to is bound; a name that can’t be resolved is ignored silently. Call it before Run().

Parameters:

addr (str) – IP address or host name to listen on

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, replies to Access-Requests get a Message-Authenticator, and reply.source is set to the client address so the reply can be sent with pyrad.host.Host.SendReplyPacket().

Parameters:
Returns:

reply packet

Return type:

pyrad.packet.Packet

HandleAcctPacket(pkt)[source]

Handle an Accounting-Request.

Called by Run() for each Accounting-Request from a known client: a client in hosts or, if present, the '0.0.0.0' entry. With enable_pkt_verify its Request Authenticator has been verified.

To answer, create the reply with CreateReplyPacket() and send it with self.SendReplyPacket(pkt.fd, reply) (pyrad.host.Host.SendReplyPacket()). If the handler doesn’t reply, the request is dropped. An exception raised by the handler is logged with a traceback and the request is dropped; raise ServerPacketError to drop it with a one-line log message.

The packet has the attributes pkt.source (the client address as returned by socket.socket.recvfrom()), pkt.fd (the socket it was received on) and pkt.secret (the secret of the client).

The default implementation ignores the request.

Parameters:

pkt (pyrad.packet.AcctPacket) – received request

HandleAuthPacket(pkt)[source]

Handle an Access-Request.

Called by Run() 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.

To answer, create the reply with CreateReplyPacket() and send it with self.SendReplyPacket(pkt.fd, reply) (pyrad.host.Host.SendReplyPacket()). If the handler doesn’t reply, the request is dropped. An exception raised by the handler is logged with a traceback and the request is dropped; raise ServerPacketError to drop it with a one-line log message.

The packet has the attributes pkt.source (the client address as returned by socket.socket.recvfrom()), pkt.fd (the socket it was received on) and pkt.secret (the secret of the client).

The default implementation ignores the request.

Parameters:

pkt (pyrad.packet.AuthPacket) – received request

HandleCoaPacket(pkt)[source]

Handle a CoA-Request.

Called by Run() for each CoA-Request from a known client: a client in hosts or, if present, the '0.0.0.0' entry. With enable_pkt_verify its Request Authenticator has been verified.

To answer, create the reply with CreateReplyPacket() and send it with self.SendReplyPacket(pkt.fd, reply) (pyrad.host.Host.SendReplyPacket()). If the handler doesn’t reply, the request is dropped. An exception raised by the handler is logged with a traceback and the request is dropped; raise ServerPacketError to drop it with a one-line log message.

The packet has the attributes pkt.source (the client address as returned by socket.socket.recvfrom()), pkt.fd (the socket it was received on) and pkt.secret (the secret of the client).

The default implementation ignores the request.

Parameters:

pkt (pyrad.packet.CoAPacket) – received request

HandleDisconnectPacket(pkt)[source]

Handle a Disconnect-Request.

Called by Run() for each Disconnect-Request from a known client: a client in hosts or, if present, the '0.0.0.0' entry. With enable_pkt_verify its Request Authenticator has been verified. CreateReplyPacket() creates a Disconnect-ACK; set reply.code to pyrad.packet.DisconnectNAK to refuse it.

To answer, create the reply with CreateReplyPacket() and send it with self.SendReplyPacket(pkt.fd, reply) (pyrad.host.Host.SendReplyPacket()). If the handler doesn’t reply, the request is dropped. An exception raised by the handler is logged with a traceback and the request is dropped; raise ServerPacketError to drop it with a one-line log message.

The packet has the attributes pkt.source (the client address as returned by socket.socket.recvfrom()), pkt.fd (the socket it was received on) and pkt.secret (the secret of the client).

The default implementation ignores the request.

Parameters:

pkt (pyrad.packet.CoAPacket) – received request

Run()[source]

Run the server; this method never returns.

Waits for packets on the sockets opened by BindToAddress() and passes valid requests to the packet handlers. Invalid packets are dropped and logged, and so are packets for which a handler raises an exception, so that a malformed packet can’t stop the server. Uses select.poll(), which is not available on Windows.