aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java')
-rw-r--r--framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java592
1 files changed, 263 insertions, 329 deletions
diff --git a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java
index 7e3de885..479ec7ed 100644
--- a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java
+++ b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java
@@ -15,13 +15,14 @@
*/
package org.onosproject.aaa;
-import com.google.common.base.Strings;
-import com.google.common.collect.Maps;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.util.Optional;
+import java.util.Set;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Modified;
-import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.DeserializationException;
@@ -38,14 +39,16 @@ import org.onlab.packet.RADIUSAttribute;
import org.onlab.packet.TpPort;
import org.onlab.packet.UDP;
import org.onlab.packet.VlanId;
-import org.onlab.util.Tools;
-import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
@@ -58,28 +61,21 @@ import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.xosintegration.VoltTenantService;
-import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
+import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
import static org.onosproject.net.packet.PacketPriority.CONTROL;
import static org.slf4j.LoggerFactory.getLogger;
-
/**
* AAA application for ONOS.
*/
@Component(immediate = true)
public class AAA {
+
+ // for verbose output
+ private final Logger log = getLogger(getClass());
+
// a list of our dependencies :
// to register with ONOS as an application - described next
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -96,8 +92,28 @@ public class AAA {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected VoltTenantService voltTenantService;
- // for verbose output
- private final Logger log = getLogger(getClass());
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetworkConfigRegistry netCfgService;
+
+ // Parsed RADIUS server addresses
+ protected InetAddress radiusIpAddress;
+ protected String radiusMacAddress;
+
+ // NAS IP address
+ protected InetAddress nasIpAddress;
+ protected String nasMacAddress;
+
+ // RADIUS server secret
+ protected String radiusSecret;
+
+ // ID of RADIUS switch
+ protected String radiusSwitch;
+
+ // RADIUS port number
+ protected long radiusPort;
+
+ // RADIUS server TCP port number
+ protected short radiusServerPort;
// our application-specific event handler
private ReactivePacketProcessor processor = new ReactivePacketProcessor();
@@ -105,124 +121,80 @@ public class AAA {
// our unique identifier
private ApplicationId appId;
- // Map of state machines. Each state machine is represented by an
- // unique identifier on the switch: dpid + port number
- Map stateMachineMap = null;
-
- // RADIUS server IP address
- private static final String DEFAULT_RADIUS_IP = "192.168.1.10";
- // NAS IP address
- private static final String DEFAULT_NAS_IP = "192.168.1.11";
- // RADIUS uplink port
- private static final int DEFAULT_RADIUS_UPLINK = 2;
- // RADIUS server shared secret
- private static final String DEFAULT_RADIUS_SECRET = "ONOSecret";
- // RADIUS MAC address
- private static final String RADIUS_MAC_ADDRESS = "00:00:00:00:01:10";
- // NAS MAC address
- private static final String NAS_MAC_ADDRESS = "00:00:00:00:10:01";
- // Radius Switch Id
- private static final String DEFAULT_RADIUS_SWITCH = "of:90e2ba82f97791e9";
- // Radius Port Number
- private static final String DEFAULT_RADIUS_PORT = "129";
-
- @Property(name = "radiusIpAddress", value = DEFAULT_RADIUS_IP,
- label = "RADIUS IP Address")
- private String radiusIpAddress = DEFAULT_RADIUS_IP;
-
- @Property(name = "nasIpAddress", value = DEFAULT_NAS_IP,
- label = "NAS IP Address")
- private String nasIpAddress = DEFAULT_NAS_IP;
-
- @Property(name = "radiusMacAddress", value = RADIUS_MAC_ADDRESS,
- label = "RADIUS MAC Address")
- private String radiusMacAddress = RADIUS_MAC_ADDRESS;
-
- @Property(name = "nasMacAddress", value = NAS_MAC_ADDRESS,
- label = "NAS MAC Address")
- private String nasMacAddress = NAS_MAC_ADDRESS;
-
- @Property(name = "radiusSecret", value = DEFAULT_RADIUS_SECRET,
- label = "RADIUS shared secret")
- private String radiusSecret = DEFAULT_RADIUS_SECRET;
-
- @Property(name = "radiusSwitchId", value = DEFAULT_RADIUS_SWITCH,
- label = "Radius switch")
- private String radiusSwitch = DEFAULT_RADIUS_SWITCH;
-
- @Property(name = "radiusPortNumber", value = DEFAULT_RADIUS_PORT,
- label = "Radius port")
- private String radiusPort = DEFAULT_RADIUS_PORT;
-
- // Parsed RADIUS server IP address
- protected InetAddress parsedRadiusIpAddress;
-
- // Parsed NAS IP address
- protected InetAddress parsedNasIpAddress;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected ComponentConfigService cfgService;
-
- @Modified
- public void modified(ComponentContext context) {
- Dictionary<?, ?> properties = context.getProperties();
-
- String s = Tools.get(properties, "radiusIpAddress");
- try {
- parsedRadiusIpAddress = InetAddress.getByName(s);
- radiusIpAddress = Strings.isNullOrEmpty(s) ? DEFAULT_RADIUS_IP : s;
- } catch (UnknownHostException e) {
- log.error("Invalid RADIUS IP address specification: {}", s);
- }
- try {
- s = Tools.get(properties, "nasIpAddress");
- parsedNasIpAddress = InetAddress.getByName(s);
- nasIpAddress = Strings.isNullOrEmpty(s) ? DEFAULT_NAS_IP : s;
- } catch (UnknownHostException e) {
- log.error("Invalid NAS IP address specification: {}", s);
- }
+ // Configuration properties factory
+ private final ConfigFactory factory =
+ new ConfigFactory<ApplicationId, AAAConfig>(APP_SUBJECT_FACTORY,
+ AAAConfig.class,
+ "AAA") {
+ @Override
+ public AAAConfig createConfig() {
+ return new AAAConfig();
+ }
+ };
- s = Tools.get(properties, "radiusMacAddress");
- radiusMacAddress = Strings.isNullOrEmpty(s) ? RADIUS_MAC_ADDRESS : s;
+ // Listener for config changes
+ private final InternalConfigListener cfgListener = new InternalConfigListener();
- s = Tools.get(properties, "nasMacAddress");
- nasMacAddress = Strings.isNullOrEmpty(s) ? NAS_MAC_ADDRESS : s;
+ /**
+ * Builds an EAPOL packet based on the given parameters.
+ *
+ * @param dstMac destination MAC address
+ * @param srcMac source MAC address
+ * @param vlan vlan identifier
+ * @param eapolType EAPOL type
+ * @param eap EAP payload
+ * @return Ethernet frame
+ */
+ private static Ethernet buildEapolResponse(MacAddress dstMac, MacAddress srcMac,
+ short vlan, byte eapolType, EAP eap) {
- s = Tools.get(properties, "radiusSecret");
- radiusSecret = Strings.isNullOrEmpty(s) ? DEFAULT_RADIUS_SECRET : s;
+ Ethernet eth = new Ethernet();
+ eth.setDestinationMACAddress(dstMac.toBytes());
+ eth.setSourceMACAddress(srcMac.toBytes());
+ eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
+ if (vlan != Ethernet.VLAN_UNTAGGED) {
+ eth.setVlanID(vlan);
+ }
+ //eapol header
+ EAPOL eapol = new EAPOL();
+ eapol.setEapolType(eapolType);
+ eapol.setPacketLength(eap.getLength());
- s = Tools.get(properties, "radiusSwitchId");
- radiusSwitch = Strings.isNullOrEmpty(s) ? DEFAULT_RADIUS_SWITCH : s;
+ //eap part
+ eapol.setPayload(eap);
- s = Tools.get(properties, "radiusPortNumber");
- radiusPort = Strings.isNullOrEmpty(s) ? DEFAULT_RADIUS_PORT : s;
+ eth.setPayload(eapol);
+ eth.setPad(true);
+ return eth;
}
@Activate
- public void activate(ComponentContext context) {
- cfgService.registerProperties(getClass());
- modified(context);
+ public void activate() {
+ netCfgService.addListener(cfgListener);
+ netCfgService.registerConfigFactory(factory);
+
// "org.onosproject.aaa" is the FQDN of our app
appId = coreService.registerApplication("org.onosproject.aaa");
+
+ cfgListener.reconfigureNetwork(netCfgService.getConfig(appId, AAAConfig.class));
+
// register our event handler
packetService.addProcessor(processor, PacketProcessor.director(2));
requestIntercepts();
- // Instantiate the map of the state machines
- stateMachineMap = Collections.synchronizedMap(Maps.newHashMap());
- hostService.startMonitoringIp(IpAddress.valueOf(radiusIpAddress));
+ StateMachine.initializeMaps();
+ hostService.startMonitoringIp(IpAddress.valueOf(radiusIpAddress));
}
@Deactivate
public void deactivate() {
- cfgService.unregisterProperties(getClass(), false);
-
appId = coreService.registerApplication("org.onosproject.aaa");
withdrawIntercepts();
// de-register and null our handler
packetService.removeProcessor(processor);
processor = null;
+ StateMachine.destroyMaps();
}
/**
@@ -237,8 +209,8 @@ public class AAA {
TrafficSelector radSelector = DefaultTrafficSelector.builder()
.matchEthType(EthType.EtherType.IPV4.ethType().toShort())
.matchIPProtocol(IPv4.PROTOCOL_UDP)
- .matchUdpDst(TpPort.tpPort(1812))
- .matchUdpSrc(TpPort.tpPort(1812))
+ .matchUdpDst(TpPort.tpPort(radiusServerPort))
+ .matchUdpSrc(TpPort.tpPort(radiusServerPort))
.build();
packetService.requestPackets(radSelector, CONTROL, appId);
}
@@ -254,45 +226,12 @@ public class AAA {
TrafficSelector radSelector = DefaultTrafficSelector.builder()
.matchEthType(EthType.EtherType.IPV4.ethType().toShort())
.matchIPProtocol(IPv4.PROTOCOL_UDP)
- .matchUdpDst(TpPort.tpPort(1812))
- .matchUdpSrc(TpPort.tpPort(1812))
+ .matchUdpDst(TpPort.tpPort(radiusServerPort))
+ .matchUdpSrc(TpPort.tpPort(radiusServerPort))
.build();
packetService.cancelPackets(radSelector, CONTROL, appId);
}
- /**
- * Builds an EAPOL packet based on the given parameters.
- *
- * @param dstMac destination MAC address
- * @param srcMac source MAC address
- * @param vlan vlan identifier
- * @param eapolType EAPOL type
- * @param eap EAP payload
- * @return Ethernet frame
- */
- private static Ethernet buildEapolResponse(MacAddress dstMac, MacAddress srcMac,
- short vlan, byte eapolType, EAP eap) {
-
- Ethernet eth = new Ethernet();
- eth.setDestinationMACAddress(dstMac.toBytes());
- eth.setSourceMACAddress(srcMac.toBytes());
- eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
- if (vlan != Ethernet.VLAN_UNTAGGED) {
- eth.setVlanID(vlan);
- }
- //eapol header
- EAPOL eapol = new EAPOL();
- eapol.setEapolType(eapolType);
- eapol.setPacketLength(eap.getLength());
-
- //eap part
- eapol.setPayload(eap);
-
- eth.setPayload(eapol);
- eth.setPad(true);
- return eth;
- }
-
// our handler defined as a private inner class
/**
@@ -308,42 +247,66 @@ public class AAA {
if (ethPkt == null) {
return;
}
- // identify if incoming packet comes from supplicant (EAP) or RADIUS
- switch (EthType.EtherType.lookup(ethPkt.getEtherType())) {
- case EAPOL:
- handleSupplicantPacket(context.inPacket());
- break;
- case IPV4:
- IPv4 ipv4Packet = (IPv4) ethPkt.getPayload();
- Ip4Address srcIp = Ip4Address.valueOf(ipv4Packet.getSourceAddress());
- Ip4Address radiusIp4Address = Ip4Address.valueOf(parsedRadiusIpAddress);
- if (srcIp.equals(radiusIp4Address) && ipv4Packet.getProtocol() == IPv4.PROTOCOL_UDP) {
- // TODO: check for port as well when it's configurable
- UDP udpPacket = (UDP) ipv4Packet.getPayload();
-
- byte[] datagram = udpPacket.getPayload().serialize();
- RADIUS radiusPacket;
- try {
+ try {
+ // identify if incoming packet comes from supplicant (EAP) or RADIUS
+ switch (EthType.EtherType.lookup(ethPkt.getEtherType())) {
+ case EAPOL:
+ handleSupplicantPacket(context.inPacket());
+ break;
+ case IPV4:
+ IPv4 ipv4Packet = (IPv4) ethPkt.getPayload();
+ Ip4Address srcIp = Ip4Address.valueOf(ipv4Packet.getSourceAddress());
+ Ip4Address radiusIp4Address = Ip4Address.valueOf(radiusIpAddress);
+ if (srcIp.equals(radiusIp4Address) && ipv4Packet.getProtocol() == IPv4.PROTOCOL_UDP) {
+ // TODO: check for port as well when it's configurable
+ UDP udpPacket = (UDP) ipv4Packet.getPayload();
+
+ byte[] datagram = udpPacket.getPayload().serialize();
+ RADIUS radiusPacket;
radiusPacket = RADIUS.deserializer().deserialize(datagram, 0, datagram.length);
- } catch (DeserializationException e) {
- log.warn("Unable to deserialize RADIUS packet:", e);
- return;
+ handleRadiusPacket(radiusPacket);
}
- handleRadiusPacket(radiusPacket);
- }
- break;
- default:
- return;
+
+ break;
+ default:
+ log.trace("Skipping Ethernet packet type {}",
+ EthType.EtherType.lookup(ethPkt.getEtherType()));
+ }
+ } catch (DeserializationException | StateMachineException e) {
+ log.warn("Unable to process RADIUS packet:", e);
}
}
+ /**
+ * Creates and initializes common fields of a RADIUS packet.
+ *
+ * @param identifier RADIUS identifier
+ * @param eapPacket EAP packet
+ * @return RADIUS packet
+ */
+ private RADIUS getRadiusPayload(byte identifier, EAP eapPacket) {
+ RADIUS radiusPayload =
+ new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST,
+ eapPacket.getIdentifier());
+ radiusPayload.setIdentifier(identifier);
+ radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME,
+ eapPacket.getData());
+
+ radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP,
+ AAA.this.nasIpAddress.getAddress());
+
+ radiusPayload.encapsulateMessage(eapPacket);
+ radiusPayload.addMessageAuthenticator(AAA.this.radiusSecret);
+
+ return radiusPayload;
+ }
/**
* Handles PAE packets (supplicant).
*
* @param inPacket Ethernet packet coming from the supplicant
*/
- private void handleSupplicantPacket(InboundPacket inPacket) {
+ private void handleSupplicantPacket(InboundPacket inPacket) throws StateMachineException {
Ethernet ethPkt = inPacket.parsed();
// Where does it come from?
MacAddress srcMAC = ethPkt.getSourceMAC();
@@ -351,114 +314,83 @@ public class AAA {
DeviceId deviceId = inPacket.receivedFrom().deviceId();
PortNumber portNumber = inPacket.receivedFrom().port();
String sessionId = deviceId.toString() + portNumber.toString();
- StateMachine stateMachine = getStateMachine(sessionId);
+ StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(sessionId);
+ if (stateMachine == null) {
+ stateMachine = new StateMachine(sessionId, voltTenantService);
+ }
+
EAPOL eapol = (EAPOL) ethPkt.getPayload();
switch (eapol.getEapolType()) {
case EAPOL.EAPOL_START:
- try {
- stateMachine.start();
- stateMachine.supplicantConnectpoint = inPacket.receivedFrom();
-
- //send an EAP Request/Identify to the supplicant
- EAP eapPayload = new EAP(EAP.REQUEST, stateMachine.getIdentifier(), EAP.ATTR_IDENTITY, null);
- Ethernet eth = buildEapolResponse(srcMAC, MacAddress.valueOf(1L),
- ethPkt.getVlanID(), EAPOL.EAPOL_PACKET,
- eapPayload);
- stateMachine.supplicantAddress = srcMAC;
- stateMachine.vlanId = ethPkt.getVlanID();
-
- this.sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint);
- } catch (StateMachineException e) {
- e.printStackTrace();
- }
+ stateMachine.start();
+ stateMachine.setSupplicantConnectpoint(inPacket.receivedFrom());
+
+ //send an EAP Request/Identify to the supplicant
+ EAP eapPayload = new EAP(EAP.REQUEST, stateMachine.identifier(), EAP.ATTR_IDENTITY, null);
+ Ethernet eth = buildEapolResponse(srcMAC, MacAddress.valueOf(1L),
+ ethPkt.getVlanID(), EAPOL.EAPOL_PACKET,
+ eapPayload);
+ stateMachine.setSupplicantAddress(srcMAC);
+ stateMachine.setVlanId(ethPkt.getVlanID());
+
+ this.sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
break;
case EAPOL.EAPOL_PACKET:
- //check if this is a Response/Identify or a Response/TLS
+ RADIUS radiusPayload;
+ // check if this is a Response/Identify or a Response/TLS
EAP eapPacket = (EAP) eapol.getPayload();
byte dataType = eapPacket.getDataType();
switch (dataType) {
+
case EAP.ATTR_IDENTITY:
- try {
- //request id access to RADIUS
- RADIUS radiusPayload = new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST,
- eapPacket.getIdentifier());
- radiusPayload.setIdentifier(stateMachine.getIdentifier());
- radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME,
- eapPacket.getData());
- stateMachine.setUsername(eapPacket.getData());
- radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP,
- AAA.this.parsedNasIpAddress.getAddress());
-
- radiusPayload.encapsulateMessage(eapPacket);
-
- // set Request Authenticator in StateMachine
- stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
- radiusPayload.addMessageAuthenticator(AAA.this.radiusSecret);
- sendRadiusMessage(radiusPayload);
+ // request id access to RADIUS
+ stateMachine.setUsername(eapPacket.getData());
- //change the state to "PENDING"
- stateMachine.requestAccess();
- } catch (StateMachineException e) {
- e.printStackTrace();
- }
+ radiusPayload = getRadiusPayload(stateMachine.identifier(), eapPacket);
+
+ // set Request Authenticator in StateMachine
+ stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
+ sendRadiusMessage(radiusPayload);
+
+ // change the state to "PENDING"
+ stateMachine.requestAccess();
break;
case EAP.ATTR_MD5:
- //verify if the EAP identifier corresponds to the challenge identifier from the client state
- //machine.
- if (eapPacket.getIdentifier() == stateMachine.getChallengeIdentifier()) {
+ // verify if the EAP identifier corresponds to the
+ // challenge identifier from the client state
+ // machine.
+ if (eapPacket.getIdentifier() == stateMachine.challengeIdentifier()) {
//send the RADIUS challenge response
- RADIUS radiusPayload = new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST,
- eapPacket.getIdentifier());
- radiusPayload.setIdentifier(stateMachine.getChallengeIdentifier());
- radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME,
- stateMachine.getUsername());
- radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP,
- AAA.this.parsedNasIpAddress.getAddress());
-
- radiusPayload.encapsulateMessage(eapPacket);
+ radiusPayload = getRadiusPayload(stateMachine.challengeIdentifier(), eapPacket);
radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
- stateMachine.getChallengeState());
- radiusPayload.addMessageAuthenticator(AAA.this.radiusSecret);
+ stateMachine.challengeState());
sendRadiusMessage(radiusPayload);
}
break;
case EAP.ATTR_TLS:
- try {
- //request id access to RADIUS
- RADIUS radiusPayload = new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST,
- eapPacket.getIdentifier());
- radiusPayload.setIdentifier(stateMachine.getIdentifier());
- radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME,
- stateMachine.getUsername());
- radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP,
- AAA.this.parsedNasIpAddress.getAddress());
-
- radiusPayload.encapsulateMessage(eapPacket);
+ // request id access to RADIUS
+ radiusPayload = getRadiusPayload(stateMachine.identifier(), eapPacket);
- radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
- stateMachine.getChallengeState());
- stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
+ radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
+ stateMachine.challengeState());
+ stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
- radiusPayload.addMessageAuthenticator(AAA.this.radiusSecret);
+ sendRadiusMessage(radiusPayload);
+ // TODO: this gets called on every fragment, should only be called at TLS-Start
+ stateMachine.requestAccess();
- sendRadiusMessage(radiusPayload);
- // TODO: this gets called on every fragment, should only be called at TLS-Start
- stateMachine.requestAccess();
- } catch (StateMachineException e) {
- e.printStackTrace();
- }
break;
default:
return;
}
break;
default:
- return;
+ log.trace("Skipping EAPOL message {}", eapol.getEapolType());
}
}
@@ -467,99 +399,46 @@ public class AAA {
*
* @param radiusPacket RADIUS packet coming from the RADIUS server.
*/
- private void handleRadiusPacket(RADIUS radiusPacket) {
- StateMachine stateMachine = getStateMachineById(radiusPacket.getIdentifier());
+ private void handleRadiusPacket(RADIUS radiusPacket) throws StateMachineException {
+ StateMachine stateMachine = StateMachine.lookupStateMachineById(radiusPacket.getIdentifier());
if (stateMachine == null) {
log.error("Invalid session identifier, exiting...");
return;
}
- EAP eapPayload = new EAP();
- Ethernet eth = null;
+ EAP eapPayload;
+ Ethernet eth;
switch (radiusPacket.getCode()) {
case RADIUS.RADIUS_CODE_ACCESS_CHALLENGE:
byte[] challengeState = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_STATE).getValue();
eapPayload = radiusPacket.decapsulateMessage();
stateMachine.setChallengeInfo(eapPayload.getIdentifier(), challengeState);
- eth = buildEapolResponse(stateMachine.supplicantAddress,
- MacAddress.valueOf(1L), stateMachine.vlanId, EAPOL.EAPOL_PACKET,
+ eth = buildEapolResponse(stateMachine.supplicantAddress(),
+ MacAddress.valueOf(1L), stateMachine.vlanId(), EAPOL.EAPOL_PACKET,
eapPayload);
- this.sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint);
+ this.sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
break;
case RADIUS.RADIUS_CODE_ACCESS_ACCEPT:
- try {
- //send an EAPOL - Success to the supplicant.
- byte[] eapMessage =
- radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE).getValue();
- eapPayload = new EAP();
- eapPayload = (EAP) eapPayload.deserialize(eapMessage, 0, eapMessage.length);
- eth = buildEapolResponse(stateMachine.supplicantAddress,
- MacAddress.valueOf(1L), stateMachine.vlanId, EAPOL.EAPOL_PACKET,
- eapPayload);
- this.sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint);
-
- stateMachine.authorizeAccess();
- } catch (StateMachineException e) {
- e.printStackTrace();
- }
+ //send an EAPOL - Success to the supplicant.
+ byte[] eapMessage =
+ radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE).getValue();
+ eapPayload = new EAP();
+ eapPayload = (EAP) eapPayload.deserialize(eapMessage, 0, eapMessage.length);
+ eth = buildEapolResponse(stateMachine.supplicantAddress(),
+ MacAddress.valueOf(1L), stateMachine.vlanId(), EAPOL.EAPOL_PACKET,
+ eapPayload);
+ this.sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
+
+ stateMachine.authorizeAccess();
break;
case RADIUS.RADIUS_CODE_ACCESS_REJECT:
- try {
- stateMachine.denyAccess();
- } catch (StateMachineException e) {
- e.printStackTrace();
- }
+ stateMachine.denyAccess();
break;
default:
log.warn("Unknown RADIUS message received with code: {}", radiusPacket.getCode());
}
}
- private StateMachine getStateMachineById(byte identifier) {
- StateMachine stateMachine = null;
- Set stateMachineSet = stateMachineMap.entrySet();
-
- synchronized (stateMachineMap) {
- Iterator itr = stateMachineSet.iterator();
- while (itr.hasNext()) {
- Map.Entry entry = (Map.Entry) itr.next();
- stateMachine = (StateMachine) entry.getValue();
- if (identifier == stateMachine.getIdentifier()) {
- //the state machine has already been created for this session session
- stateMachine = (StateMachine) entry.getValue();
- break;
- }
- }
- }
-
- return stateMachine;
- }
-
- private StateMachine getStateMachine(String sessionId) {
- StateMachine stateMachine = null;
- Set stateMachineSet = stateMachineMap.entrySet();
-
- synchronized (stateMachineMap) {
- Iterator itr = stateMachineSet.iterator();
- while (itr.hasNext()) {
-
- Map.Entry entry = (Map.Entry) itr.next();
- if (sessionId.equals(entry.getKey())) {
- //the state machine has already been created for this session session
- stateMachine = (StateMachine) entry.getValue();
- break;
- }
- }
- }
-
- if (stateMachine == null) {
- stateMachine = new StateMachine(sessionId, voltTenantService);
- stateMachineMap.put(sessionId, stateMachine);
- }
-
- return stateMachine;
- }
-
private void sendRadiusMessage(RADIUS radiusMessage) {
Set<Host> hosts = hostService.getHostsByIp(IpAddress.valueOf(radiusIpAddress));
Optional<Host> odst = hosts.stream().filter(h -> h.vlan().toShort() == VlanId.UNTAGGED).findFirst();
@@ -576,12 +455,12 @@ public class AAA {
IPv4 ip4Packet = new IPv4();
Ethernet ethPkt = new Ethernet();
radiusMessage.setParent(udp);
- udp.setDestinationPort((short) 1812);
- udp.setSourcePort((short) 1812); // TODO: make this configurable
+ udp.setDestinationPort(radiusServerPort);
+ udp.setSourcePort(radiusServerPort);
udp.setPayload(radiusMessage);
udp.setParent(ip4Packet);
- ip4Packet.setSourceAddress(AAA.this.nasIpAddress);
- ip4Packet.setDestinationAddress(AAA.this.radiusIpAddress);
+ ip4Packet.setSourceAddress(AAA.this.nasIpAddress.getHostAddress());
+ ip4Packet.setDestinationAddress(AAA.this.radiusIpAddress.getHostAddress());
ip4Packet.setProtocol(IPv4.PROTOCOL_UDP);
ip4Packet.setPayload(udp);
ip4Packet.setParent(ethPkt);
@@ -591,7 +470,7 @@ public class AAA {
ethPkt.setPayload(ip4Packet);
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setOutput(PortNumber.portNumber(Integer.parseInt(radiusPort))).build();
+ .setOutput(PortNumber.portNumber(radiusPort)).build();
OutboundPacket packet = new DefaultOutboundPacket(DeviceId.deviceId(radiusSwitch),
treatment, ByteBuffer.wrap(ethPkt.serialize()));
packetService.emit(packet);
@@ -613,4 +492,59 @@ public class AAA {
}
+ private class InternalConfigListener implements NetworkConfigListener {
+
+ /**
+ * Reconfigures the DHCP Server according to the configuration parameters passed.
+ *
+ * @param cfg configuration object
+ */
+ private void reconfigureNetwork(AAAConfig cfg) {
+ AAAConfig newCfg;
+ if (cfg == null) {
+ newCfg = new AAAConfig();
+ } else {
+ newCfg = cfg;
+ }
+ if (newCfg.nasIp() != null) {
+ nasIpAddress = newCfg.nasIp();
+ }
+ if (newCfg.radiusIp() != null) {
+ radiusIpAddress = newCfg.radiusIp();
+ }
+ if (newCfg.radiusMac() != null) {
+ radiusMacAddress = newCfg.radiusMac();
+ }
+ if (newCfg.nasMac() != null) {
+ nasMacAddress = newCfg.nasMac();
+ }
+ if (newCfg.radiusSecret() != null) {
+ radiusSecret = newCfg.radiusSecret();
+ }
+ if (newCfg.radiusSwitch() != null) {
+ radiusSwitch = newCfg.radiusSwitch();
+ }
+ if (newCfg.radiusPort() != -1) {
+ radiusPort = newCfg.radiusPort();
+ }
+ if (newCfg.radiusServerUDPPort() != -1) {
+ radiusServerPort = newCfg.radiusServerUDPPort();
+ }
+ }
+
+ @Override
+ public void event(NetworkConfigEvent event) {
+
+ if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
+ event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
+ event.configClass().equals(AAAConfig.class)) {
+
+ AAAConfig cfg = netCfgService.getConfig(appId, AAAConfig.class);
+ reconfigureNetwork(cfg);
+ log.info("Reconfigured");
+ }
+ }
+ }
+
+
}