While the RADIUS server automatically handles proxy requests it is sometimes necessary to modify a packet to force or prevent proxy action. It may be necessary, for example, to strip realm information from the User-Name attribute yet force the packet to be proxied to another server.
There are two types of proxy understood by the server. The most common is explicit proxy where the User-Name hold the proxy realm information. The other is transparent proxy which allow rerouting of a packet without changing any realm information, or perhaps even removing the realm.
The programmer's proxy routing code resides in a class that extends ProxyImpl. The ProxyInfo class object is passed to the changeRequest() method handling requests like Access-Request or the changeResponse() handling responses like Access-Accept. The ProxyInfo class has a number of methods to facilitate attribute editing, logging and other functions. ProxyInfo extends the PacketInfo class. PacketInfo has methods common to AuthInfo, ProxyInfo, AccountingInfo, ExtendedInfo, and other classes. the common methods listed below are not exhaustive but cover most of the methods useful in proxy operations. The section 'Proxy specific methods' covers the methods defined in the ProxyInfo class.
The ProxyImpl class is used to set up the interception and possible modification of proxy actions. There are two methods, one handles requests (like Access-Request) (ProxyImpl.changeRequest()) and the other handles responses (like Access_Accept). Each allows the packet's attributes to be modified and perhaps be transparently re-routed.
The server passes a ProxyInfo class to both methods.
getUserName():
Get the User-Name attribute as a string. This is the raw name as it arrived. It may contain realm information as proxy information. Proxy information customarily appears after an '@' sign as in
vivian@radius3.com.The proxy information is called the realm. If there is no User-Name present a null is returned.getName()
Get only the name portion of the User-Name attribute. This will discard any realm information. GetName() would return
vivianfrom the above example. If there is no User-Name attribute present an empty string is returned.getRealm()
Get the realm information from the User-Name attribute. The will remove the name and only the realm information will be returned. GetRealm() would return
radius3.comfrom the above example. If there is no realm information an empty string is returned.getRequestAttributes() / getRequestAttributeList()
Get the request attributes. If any attributes are modified all the attributes must be returned using setResponseAttributes(). The returned attributes replace those that arrived.
setResponseAttributes()
Return modified attributes. All attributes that must stay with the packet must be returned. If only one attribute is modified all the original attributes should be returned. The returned attributes replace those that arrived. If setResponseAttributes() is not called the original attributes are restored to the packet.
setTransparentProxy()
This method sets the realm the packet will be forced to use regardless of the User-Name realm routing.
The Message-Authenticator attribute will be replaced with one with a correctly calculated value. If you add a Message-Authenticator you may make it zero length. While not generally legal in the outside word it's permissible within the server. The server will delete the current attribute and replace it with a legitimate one.
Often clients will specify different realms for authentication. It is possible to intercept these and process some locally, redirect others, and let some pass through normally. You may also redirect a 'local' name to another server, one with no realm information.
Some criteria is used to determine this, perhaps as simple as examining the realm and making the decision. There are two ways to perform a redirect locally or elsewhere.
Alter the realm in the User-Name. Be aware that servers downstream may be affected by these changes. Changing the realm may be necessary for other servers to accept requests for themselves.
Use the setTransparentProxy() method. This does not require any realm name change and redirects the packet to the named server. The server name is the same as the name used by the RADIUSServer.addProxyTarget() method. It's possible to redirect locally by setting the target name using this example:
public void changeRequest(ProxyInfo prx) {
if (xyz is true then handle locally)
// Handle this locally no matter what the realm.
prx.setTransparentProxy(prx.getHostRealm());
else
// Otherwise send all other requests to the realm "theorem.com".
prx.setTransparentProxy("theorem.com");
}For systems that wish to completely disable all proxy requests there is a quick and final way - use the RADIUSServer. setProxyCharacter(char proxyChar) method. If set to something very unlikely, perhaps a (char)0x01, all proxying based on realms will stop. It has the side effect of rendering methods like getRealm() and getName() useless in ProxyImpl, AccountingImpl and AccessImpl.