/** * Handles packets coming in on the Proxy port. Decides whether * packets coming in on Auth/Acct ports should be proxied. */ protected override RadiusPacket HandlePacket(IPEndPoint localAddress, IPEndPoint remoteAddress, RadiusPacket request, String sharedSecret) { // handle incoming Proxy packet if (localAddress.Port == ProxyPort) { proxyPacketReceived(request, remoteAddress); return(null); } // handle auth/acct packet var radiusClient = new RadiusEndpoint(remoteAddress, sharedSecret); RadiusEndpoint radiusServer = GetProxyServer(request, radiusClient); if (radiusServer != null) { // Proxy incoming packet to other radius server var proxyConnection = new RadiusProxyConnection(radiusServer, radiusClient, request, localAddress.Port); logger.Info("Proxy packet to " + proxyConnection); proxyPacket(request, proxyConnection); return(null); } else { // normal processing return(base.HandlePacket(localAddress, remoteAddress, request, sharedSecret)); } }
/** * Creates a RadiusProxyConnection object. * @param radiusServer server endpoint * @param radiusClient client endpoint * @param port port the proxied packet arrived at originally */ public RadiusProxyConnection(RadiusEndpoint radiusServer, RadiusEndpoint radiusClient, RadiusPacket packet, int port) { RadiusServer = radiusServer; RadiusClient = radiusClient; Packet = packet; Port = port; }
/** * Sends an answer to a proxied packet back to the original host. * Retrieves the RadiusProxyConnection object from the cache employing * the Proxy-State attribute. * @param packet packet to be sent back * @param remote the server the packet arrived from * @throws IOException */ protected void proxyPacketReceived(RadiusPacket packet, IPEndPoint remote) { // retrieve my Proxy-State attribute (the last) IList <RadiusAttribute> proxyStates = packet.GetAttributes(33); if (proxyStates == null || proxyStates.Count == 0) { throw new RadiusException("Proxy packet without Proxy-State attribute"); } RadiusAttribute proxyState = proxyStates[proxyStates.Count - 1]; // retrieve Proxy connection from cache string state = BitConverter.ToString(proxyState.Data); var proxyConnection = (RadiusProxyConnection)proxyConnections[state]; proxyConnections.Remove(state); if (proxyConnection == null) { logger.Warn("received packet on Proxy port without saved Proxy connection - duplicate?"); return; } // retrieve client RadiusEndpoint client = proxyConnection.RadiusClient; if (logger.IsInfoEnabled) { logger.Info("received Proxy packet: " + packet); logger.Info("forward packet to " + client.EndpointAddress + " with secret " + client.SharedSecret); } // remove only own Proxy-State (last attribute) packet.RemoveLastAttribute(33); // re-encode answer packet with authenticator of the original packet var answer = new RadiusPacket(packet.Type, packet.Identifier, packet.Attributes); byte[] datagram = MakeDatagramPacket(answer, client.SharedSecret, proxyConnection.Packet); // send back using correct socket UdpClient socket = proxyConnection.Port == AuthPort?GetAuthSocket() : GetAcctSocket(); socket.Send(datagram, datagram.Length, remote); }
public override RadiusEndpoint GetProxyServer(RadiusPacket packet, RadiusEndpoint client) { // always proxy try { IPAddress address = IPAddress.Parse("127.0. 0. 1 "); int port = 10000; if (typeof(AccountingRequest).IsInstanceOfType(packet)) { port = 10001; } return(new RadiusEndpoint(new IPEndPoint(address, port), "testing123")); } catch { return(null); } }
/** * This method must be implemented to return a RadiusEndpoint * if the given packet is to be proxied. The endpoint represents the * Radius server the packet should be proxied to. * @param packet the packet in question * @param client the client endpoint the packet originated from * (containing the address, port number and shared secret) * @return a RadiusEndpoint or null if the packet should not be * proxied */ public abstract RadiusEndpoint GetProxyServer(RadiusPacket packet, RadiusEndpoint client);