package org.apereo.cas.adaptors.radius; import net.jradius.client.RadiusClient; import net.jradius.dictionary.Attr_NASIPAddress; import net.jradius.dictionary.Attr_NASIPv6Address; import net.jradius.dictionary.Attr_NASIdentifier; import net.jradius.dictionary.Attr_NASPort; import net.jradius.dictionary.Attr_NASPortId; import net.jradius.dictionary.Attr_NASPortType; import net.jradius.dictionary.Attr_UserName; import net.jradius.dictionary.Attr_UserPassword; import net.jradius.dictionary.vsa_redback.Attr_NASRealPort; import net.jradius.packet.AccessAccept; import net.jradius.packet.AccessRequest; import net.jradius.packet.RadiusPacket; import net.jradius.packet.attribute.AttributeFactory; import net.jradius.packet.attribute.AttributeList; import net.jradius.packet.attribute.RadiusAttribute; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.builder.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; /** * Implementation of a RadiusServer that utilizes the JRadius packages available * at <a href="http://jradius.sf.net">http://jradius.sf.net</a>. * * @author Scott Battaglia * @author Marvin S. Addison * @author Misagh Moayyed * @since 3.1 */ public class JRadiusServerImpl implements RadiusServer { /** * Default retry count, {@value}. **/ public static final int DEFAULT_RETRY_COUNT = 3; /** Logger instance. */ private static final Logger LOGGER = LoggerFactory.getLogger(JRadiusServerImpl.class); /** RADIUS protocol. */ private final RadiusProtocol protocol; /** Produces RADIUS client instances for authentication. */ private final RadiusClientFactory radiusClientFactory; /** Number of times to retry authentication when no response is received. */ private int retries = DEFAULT_RETRY_COUNT; private String nasIpAddress; private String nasIpv6Address; private long nasPort = -1; private long nasPortId = -1; private String nasIdentifier; private long nasRealPort = -1; private long nasPortType = -1; static { AttributeFactory.loadAttributeDictionary("net.jradius.dictionary.AttributeDictionaryImpl"); } /** * Instantiates a new server implementation * with the radius protocol and client factory specified. * * @param protocol the protocol * @param clientFactory the client factory * @param retries the new retries * @param nasIpAddress the new nas ip address * @param nasIpv6Address the new nas ipv6 address * @param nasPort the new nas port * @param nasPortId the new nas port id * @param nasIdentifier the new nas identifier * @param nasRealPort the new nas real port */ public JRadiusServerImpl(final RadiusProtocol protocol, final RadiusClientFactory clientFactory, final int retries, final String nasIpAddress, final String nasIpv6Address, final long nasPort, final long nasPortId, final String nasIdentifier, final long nasRealPort) { this.protocol = protocol; this.radiusClientFactory = clientFactory; this.retries = retries; this.nasIpAddress = nasIpAddress; this.nasIpv6Address = nasIpv6Address; this.nasPort = nasPort; this.nasPortId = nasPortId; this.nasIdentifier = nasIdentifier; this.nasRealPort = nasRealPort; } @Override public RadiusResponse authenticate(final String username, final String password) throws Exception { final AttributeList attributeList = new AttributeList(); attributeList.add(new Attr_UserName(username)); attributeList.add(new Attr_UserPassword(password)); if (StringUtils.isNotBlank(this.nasIpAddress)) { attributeList.add(new Attr_NASIPAddress(this.nasIpAddress)); } if (StringUtils.isNotBlank(this.nasIpv6Address)) { attributeList.add(new Attr_NASIPv6Address(this.nasIpv6Address)); } if (this.nasPort != -1) { attributeList.add(new Attr_NASPort(this.nasPort)); } if (this.nasPortId != -1) { attributeList.add(new Attr_NASPortId(this.nasPortId)); } if (StringUtils.isNotBlank(this.nasIdentifier)) { attributeList.add(new Attr_NASIdentifier(this.nasIdentifier)); } if (this.nasRealPort != -1) { attributeList.add(new Attr_NASRealPort(this.nasRealPort)); } if (this.nasPortType != -1) { attributeList.add(new Attr_NASPortType(this.nasPortType)); } RadiusClient client = null; try { client = this.radiusClientFactory.newInstance(); final AccessRequest request = new AccessRequest(client, attributeList); final RadiusPacket response = client.authenticate( request, RadiusClient.getAuthProtocol(this.protocol.getName()), this.retries); LOGGER.debug("RADIUS response from [{}]: [{}]", client.getRemoteInetAddress().getCanonicalHostName(), response.getClass().getName()); if (response instanceof AccessAccept) { final List<RadiusAttribute> attributes = response.getAttributes().getAttributeList(); LOGGER.debug("Radius response code [{}] accepted with attributes [{}] and identifier [{}]", response.getCode(), attributes, response.getIdentifier()); return new RadiusResponse(response.getCode(), response.getIdentifier(), attributes); } LOGGER.debug("Response is not recognized"); } finally { if (client != null) { client.close(); } } return null; } /** * Sets the nas port type. * * @param nasPortType the new nas port type * @since 4.1.0 */ public void setNasPortType(final long nasPortType) { this.nasPortType = nasPortType; } @Override public String toString() { return new ToStringBuilder(this) .append("protocol", this.protocol) .append("radiusClientFactory", this.radiusClientFactory) .append("retries", this.retries) .append("nasIpAddress", this.nasIpAddress) .append("nasIpv6Address", this.nasIpv6Address) .append("nasPort", this.nasPort) .append("nasPortId", this.nasPortId) .append("nasIdentifier", this.nasIdentifier) .append("nasRealPort", this.nasRealPort) .append("nasPortType", this.nasPortType) .toString(); } }