diff options
Diffstat (limited to 'framework/src/onos/apps/aaa')
13 files changed, 0 insertions, 2513 deletions
diff --git a/framework/src/onos/apps/aaa/app.xml b/framework/src/onos/apps/aaa/app.xml deleted file mode 100644 index 167a4192..00000000 --- a/framework/src/onos/apps/aaa/app.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ Copyright 2015 Open Networking Laboratory - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License. - --> -<app name="org.onosproject.aaa" origin="ATT" version="${project.version}" - featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features" - features="${project.artifactId}"> - <description>${project.description}</description> - <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact> - <artifact>mvn:${project.groupId}/onos-app-xos-integration/${project.version}</artifact> - <bundle>mvn:com.sun.jersey/jersey-client/1.19</bundle> -</app> diff --git a/framework/src/onos/apps/aaa/features.xml b/framework/src/onos/apps/aaa/features.xml deleted file mode 100644 index e965d41a..00000000 --- a/framework/src/onos/apps/aaa/features.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<!-- - ~ Copyright 2015 Open Networking Laboratory - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License. - --> -<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}"> - <feature name="${project.artifactId}" version="${project.version}" - description="${project.description}"> - <feature>onos-api</feature> - <bundle>mvn:com.sun.jersey/jersey-client/1.19</bundle> - <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle> - <bundle>mvn:${project.groupId}/onos-app-xos-integration/${project.version}</bundle> - </feature> -</features> diff --git a/framework/src/onos/apps/aaa/pom.xml b/framework/src/onos/apps/aaa/pom.xml deleted file mode 100644 index 78c18ed7..00000000 --- a/framework/src/onos/apps/aaa/pom.xml +++ /dev/null @@ -1,98 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ Copyright 2014 Open Networking Laboratory - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License. - --> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - - - <parent> - <groupId>org.onosproject</groupId> - <artifactId>onos-apps</artifactId> - <version>1.4.0-rc1</version> - <relativePath>../pom.xml</relativePath> - </parent> - - <artifactId>onos-app-aaa</artifactId> - <packaging>bundle</packaging> - - <description>ONOS authentication application</description> - - <properties> - <onos.app.name>org.onosproject.aaa</onos.app.name> - </properties> - - <dependencies> - <dependency> - <groupId>org.osgi</groupId> - <artifactId>org.osgi.compendium</artifactId> - </dependency> - - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onos-api</artifactId> - <version>${project.version}</version> - </dependency> - - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onos-app-xos-integration</artifactId> - <version>${project.version}</version> - </dependency> - - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onlab-junit</artifactId> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onlab-osgi</artifactId> - <version>${project.version}</version> - <classifier>tests</classifier> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onos-api</artifactId> - <version>${project.version}</version> - <classifier>tests</classifier> - <scope>test</scope> - </dependency> - </dependencies> - - - <build> - <plugins> - <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-bundle-plugin</artifactId> - </plugin> - - <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-scr-plugin</artifactId> - </plugin> - <plugin> - <groupId>org.onosproject</groupId> - <artifactId>onos-maven-plugin</artifactId> - </plugin> - </plugins> - </build> -</project> diff --git a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaConfig.java b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaConfig.java deleted file mode 100644 index db821ca2..00000000 --- a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaConfig.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.onosproject.aaa; - -import org.onosproject.core.ApplicationId; -import org.onosproject.net.config.Config; -import org.onosproject.net.config.basics.BasicElementConfig; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * Network config for the AAA app. - */ -public class AaaConfig extends Config<ApplicationId> { - - private static final String RADIUS_IP = "radiusIp"; - private static final String RADIUS_SERVER_PORT = "1812"; - private static final String RADIUS_MAC = "radiusMac"; - private static final String NAS_IP = "nasIp"; - private static final String NAS_MAC = "nasMac"; - private static final String RADIUS_SECRET = "radiusSecret"; - private static final String RADIUS_SWITCH = "radiusSwitch"; - private static final String RADIUS_PORT = "radiusPort"; - - // RADIUS server IP address - protected static final String DEFAULT_RADIUS_IP = "10.128.10.4"; - - // RADIUS MAC address - protected static final String DEFAULT_RADIUS_MAC = "00:00:00:00:01:10"; - - // NAS IP address - protected static final String DEFAULT_NAS_IP = "10.128.9.244"; - - // NAS MAC address - protected static final String DEFAULT_NAS_MAC = "00:00:00:00:10:01"; - - // RADIUS server shared secret - protected static final String DEFAULT_RADIUS_SECRET = "ONOSecret"; - - // Radius Switch Id - protected static final String DEFAULT_RADIUS_SWITCH = "of:90e2ba82f97791e9"; - - // Radius Port Number - protected static final String DEFAULT_RADIUS_PORT = "129"; - - // Radius Server UDP Port Number - protected static final String DEFAULT_RADIUS_SERVER_PORT = "1812"; - - /** - * Gets the value of a string property, protecting for an empty - * JSON object. - * - * @param name name of the property - * @param defaultValue default value if none has been specified - * @return String value if one os found, default value otherwise - */ - private String getStringProperty(String name, String defaultValue) { - if (object == null) { - return defaultValue; - } - return get(name, defaultValue); - } - - /** - * Returns the NAS ip. - * - * @return ip address or null if not set - */ - public InetAddress nasIp() { - try { - return InetAddress.getByName(getStringProperty(NAS_IP, DEFAULT_NAS_IP)); - } catch (UnknownHostException e) { - return null; - } - } - - /** - * Sets the NAS ip. - * - * @param ip new ip address; null to clear - * @return self - */ - public BasicElementConfig nasIp(String ip) { - return (BasicElementConfig) setOrClear(NAS_IP, ip); - } - - /** - * Returns the RADIUS server ip. - * - * @return ip address or null if not set - */ - public InetAddress radiusIp() { - try { - return InetAddress.getByName(getStringProperty(RADIUS_IP, DEFAULT_RADIUS_IP)); - } catch (UnknownHostException e) { - return null; - } - } - - /** - * Sets the RADIUS server ip. - * - * @param ip new ip address; null to clear - * @return self - */ - public BasicElementConfig radiusIp(String ip) { - return (BasicElementConfig) setOrClear(RADIUS_IP, ip); - } - - /** - * Returns the RADIUS MAC address. - * - * @return mac address or null if not set - */ - public String radiusMac() { - return getStringProperty(RADIUS_MAC, DEFAULT_RADIUS_MAC); - } - - /** - * Sets the RADIUS MAC address. - * - * @param mac new MAC address; null to clear - * @return self - */ - public BasicElementConfig radiusMac(String mac) { - return (BasicElementConfig) setOrClear(RADIUS_MAC, mac); - } - - /** - * Returns the RADIUS MAC address. - * - * @return mac address or null if not set - */ - public String nasMac() { - return getStringProperty(NAS_MAC, DEFAULT_NAS_MAC); - } - - /** - * Sets the RADIUS MAC address. - * - * @param mac new MAC address; null to clear - * @return self - */ - public BasicElementConfig nasMac(String mac) { - return (BasicElementConfig) setOrClear(NAS_MAC, mac); - } - - /** - * Returns the RADIUS secret. - * - * @return radius secret or null if not set - */ - public String radiusSecret() { - return getStringProperty(RADIUS_SECRET, DEFAULT_RADIUS_SECRET); - } - - /** - * Sets the RADIUS secret. - * - * @param secret new MAC address; null to clear - * @return self - */ - public BasicElementConfig radiusSecret(String secret) { - return (BasicElementConfig) setOrClear(RADIUS_SECRET, secret); - } - - /** - * Returns the ID of the RADIUS switch. - * - * @return radius switch ID or null if not set - */ - public String radiusSwitch() { - return getStringProperty(RADIUS_SWITCH, DEFAULT_RADIUS_SWITCH); - } - - /** - * Sets the ID of the RADIUS switch. - * - * @param switchId new RADIUS switch ID; null to clear - * @return self - */ - public BasicElementConfig radiusSwitch(String switchId) { - return (BasicElementConfig) setOrClear(RADIUS_SWITCH, switchId); - } - - /** - * Returns the RADIUS port. - * - * @return radius port or null if not set - */ - public long radiusPort() { - return Integer.parseInt(getStringProperty(RADIUS_PORT, DEFAULT_RADIUS_PORT)); - } - - /** - * Sets the RADIUS port. - * - * @param port new RADIUS port; null to clear - * @return self - */ - public BasicElementConfig radiusPort(long port) { - return (BasicElementConfig) setOrClear(RADIUS_PORT, port); - } - - /** - * Returns the RADIUS server UDP port. - * - * @return radius server UDP port. - */ - public short radiusServerUdpPort() { - return Short.parseShort(getStringProperty(RADIUS_SERVER_PORT, - DEFAULT_RADIUS_SERVER_PORT)); - } - - /** - * Sets the RADIUS port. - * - * @param port new RADIUS UDP port; -1 to clear - * @return self - */ - public BasicElementConfig radiusServerUdpPort(short port) { - return (BasicElementConfig) setOrClear(RADIUS_SERVER_PORT, (long) port); - } - -} diff --git a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaManager.java b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaManager.java deleted file mode 100644 index dd324eee..00000000 --- a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaManager.java +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Copyright 2015 AT&T Foundry - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.onosproject.aaa; - -import com.google.common.util.concurrent.ThreadFactoryBuilder; -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.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.onlab.packet.DeserializationException; -import org.onlab.packet.EAP; -import org.onlab.packet.EAPOL; -import org.onlab.packet.EthType; -import org.onlab.packet.Ethernet; -import org.onlab.packet.MacAddress; -import org.onlab.packet.RADIUS; -import org.onlab.packet.RADIUSAttribute; -import org.onosproject.core.ApplicationId; -import org.onosproject.core.CoreService; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.DeviceId; -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; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.packet.DefaultOutboundPacket; -import org.onosproject.net.packet.InboundPacket; -import org.onosproject.net.packet.OutboundPacket; -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.slf4j.Logger; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.nio.ByteBuffer; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -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 AaaManager { - - // 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) - protected CoreService coreService; - - // to receive Packet-in events that we'll respond to - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected PacketService packetService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected VoltTenantService voltTenantService; - - @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(); - - // our unique identifier - private ApplicationId appId; - - // Socket used for UDP communications with RADIUS server - private DatagramSocket radiusSocket; - - // Executor for RADIUS communication thread - private ExecutorService executor; - - // Configuration properties factory - private final ConfigFactory factory = - new ConfigFactory<ApplicationId, AaaConfig>(APP_SUBJECT_FACTORY, - AaaConfig.class, - "AAA") { - @Override - public AaaConfig createConfig() { - return new AaaConfig(); - } - }; - - // Listener for config changes - private final InternalConfigListener cfgListener = new InternalConfigListener(); - - /** - * 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; - } - - @Activate - 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(); - - StateMachine.initializeMaps(); - - try { - radiusSocket = new DatagramSocket(radiusServerPort); - } catch (Exception ex) { - log.error("Can't open RADIUS socket", ex); - } - - executor = Executors.newSingleThreadExecutor( - new ThreadFactoryBuilder() - .setNameFormat("AAA-radius-%d").build()); - executor.execute(radiusListener); - } - - @Deactivate - public void deactivate() { - appId = coreService.registerApplication("org.onosproject.aaa"); - withdrawIntercepts(); - // de-register and null our handler - packetService.removeProcessor(processor); - processor = null; - StateMachine.destroyMaps(); - radiusSocket.close(); - executor.shutdownNow(); - } - - protected void sendRadiusPacket(RADIUS radiusPacket) { - - try { - final byte[] data = radiusPacket.serialize(); - final DatagramSocket socket = radiusSocket; - - DatagramPacket packet = - new DatagramPacket(data, data.length, - radiusIpAddress, radiusServerPort); - - socket.send(packet); - } catch (IOException e) { - log.info("Cannot send packet to RADIUS server", e); - } - } - - /** - * Request packet in via PacketService. - */ - private void requestIntercepts() { - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); - selector.matchEthType(EthType.EtherType.EAPOL.ethType().toShort()); - packetService.requestPackets(selector.build(), - CONTROL, appId); - } - - /** - * Cancel request for packet in via PacketService. - */ - private void withdrawIntercepts() { - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); - selector.matchEthType(EthType.EtherType.EAPOL.ethType().toShort()); - packetService.cancelPackets(selector.build(), CONTROL, appId); - } - - /** - * Send the ethernet packet to the supplicant. - * - * @param ethernetPkt the ethernet packet - * @param connectPoint the connect point to send out - */ - private void sendPacketToSupplicant(Ethernet ethernetPkt, ConnectPoint connectPoint) { - TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(connectPoint.port()).build(); - OutboundPacket packet = new DefaultOutboundPacket(connectPoint.deviceId(), - treatment, ByteBuffer.wrap(ethernetPkt.serialize())); - packetService.emit(packet); - } - - // our handler defined as a private inner class - - /** - * Packet processor responsible for forwarding packets along their paths. - */ - private class ReactivePacketProcessor implements PacketProcessor { - @Override - public void process(PacketContext context) { - - // Extract the original Ethernet frame from the packet information - InboundPacket pkt = context.inPacket(); - Ethernet ethPkt = pkt.parsed(); - if (ethPkt == null) { - return; - } - try { - // identify if incoming packet comes from supplicant (EAP) or RADIUS - switch (EthType.EtherType.lookup(ethPkt.getEtherType())) { - case EAPOL: - handleSupplicantPacket(context.inPacket()); - break; - default: - log.trace("Skipping Ethernet packet type {}", - EthType.EtherType.lookup(ethPkt.getEtherType())); - } - } catch (StateMachineException e) { - log.warn("Unable to process RADIUS packet:", e); - } - } - - /** - * Creates and initializes common fields of a RADIUS packet. - * - * @param stateMachine state machine for the request - * @param eapPacket EAP packet - * @return RADIUS packet - */ - private RADIUS getRadiusPayload(StateMachine stateMachine, byte identifier, EAP eapPacket) { - RADIUS radiusPayload = - new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST, - eapPacket.getIdentifier()); - - // set Request Authenticator in StateMachine - stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode()); - - radiusPayload.setIdentifier(identifier); - radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME, - stateMachine.username()); - - radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP, - AaaManager.this.nasIpAddress.getAddress()); - - radiusPayload.encapsulateMessage(eapPacket); - - return radiusPayload; - } - - /** - * Handles PAE packets (supplicant). - * - * @param inPacket Ethernet packet coming from the supplicant - */ - private void handleSupplicantPacket(InboundPacket inPacket) throws StateMachineException { - Ethernet ethPkt = inPacket.parsed(); - // Where does it come from? - MacAddress srcMac = ethPkt.getSourceMAC(); - - DeviceId deviceId = inPacket.receivedFrom().deviceId(); - PortNumber portNumber = inPacket.receivedFrom().port(); - String sessionId = deviceId.toString() + portNumber.toString(); - 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: - 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(nasMacAddress), - ethPkt.getVlanID(), EAPOL.EAPOL_PACKET, - eapPayload); - stateMachine.setSupplicantAddress(srcMac); - stateMachine.setVlanId(ethPkt.getVlanID()); - - sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint()); - - break; - case EAPOL.EAPOL_PACKET: - 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: - // request id access to RADIUS - stateMachine.setUsername(eapPacket.getData()); - - radiusPayload = getRadiusPayload(stateMachine, stateMachine.identifier(), eapPacket); - radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret); - - sendRadiusPacket(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.challengeIdentifier()) { - //send the RADIUS challenge response - radiusPayload = - getRadiusPayload(stateMachine, - stateMachine.identifier(), - eapPacket); - - radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE, - stateMachine.challengeState()); - radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret); - sendRadiusPacket(radiusPayload); - } - break; - case EAP.ATTR_TLS: - // request id access to RADIUS - radiusPayload = getRadiusPayload(stateMachine, stateMachine.identifier(), eapPacket); - - radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE, - stateMachine.challengeState()); - stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode()); - - radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret); - sendRadiusPacket(radiusPayload); - - if (stateMachine.state() != StateMachine.STATE_PENDING) { - stateMachine.requestAccess(); - } - - break; - default: - return; - } - break; - default: - log.trace("Skipping EAPOL message {}", eapol.getEapolType()); - } - - } - } - - class RadiusListener implements Runnable { - - /** - * Handles RADIUS packets. - * - * @param radiusPacket RADIUS packet coming from the RADIUS server. - * @throws StateMachineException if an illegal state transition is triggered - */ - protected void handleRadiusPacket(RADIUS radiusPacket) throws StateMachineException { - StateMachine stateMachine = StateMachine.lookupStateMachineById(radiusPacket.getIdentifier()); - if (stateMachine == null) { - log.error("Invalid session identifier, exiting..."); - return; - } - - 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(nasMacAddress), - stateMachine.vlanId(), - EAPOL.EAPOL_PACKET, - eapPayload); - sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint()); - break; - case RADIUS.RADIUS_CODE_ACCESS_ACCEPT: - //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(nasMacAddress), - stateMachine.vlanId(), - EAPOL.EAPOL_PACKET, - eapPayload); - sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint()); - - stateMachine.authorizeAccess(); - break; - case RADIUS.RADIUS_CODE_ACCESS_REJECT: - stateMachine.denyAccess(); - break; - default: - log.warn("Unknown RADIUS message received with code: {}", radiusPacket.getCode()); - } - } - - - @Override - public void run() { - boolean done = false; - int packetNumber = 1; - - log.info("UDP listener thread starting up"); - RADIUS inboundRadiusPacket; - while (!done) { - try { - byte[] packetBuffer = new byte[RADIUS.RADIUS_MAX_LENGTH]; - DatagramPacket inboundBasePacket = - new DatagramPacket(packetBuffer, packetBuffer.length); - DatagramSocket socket = radiusSocket; - socket.receive(inboundBasePacket); - log.info("Packet #{} received", packetNumber++); - try { - inboundRadiusPacket = - RADIUS.deserializer() - .deserialize(inboundBasePacket.getData(), - 0, - inboundBasePacket.getLength()); - handleRadiusPacket(inboundRadiusPacket); - } catch (DeserializationException dex) { - log.error("Cannot deserialize packet", dex); - } catch (StateMachineException sme) { - log.error("Illegal state machine operation", sme); - } - - } catch (IOException e) { - log.info("Socket was closed, exiting listener thread"); - done = true; - } - } - } - } - - RadiusListener radiusListener = new RadiusListener(); - - 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"); - } - } - } - - -} diff --git a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/StateMachine.java b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/StateMachine.java deleted file mode 100644 index 84f69241..00000000 --- a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/StateMachine.java +++ /dev/null @@ -1,537 +0,0 @@ -/* - * - * Copyright 2015 AT&T Foundry - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.onosproject.aaa; - -import java.util.BitSet; -import java.util.Map; - -import org.onlab.packet.MacAddress; -import org.onosproject.net.ConnectPoint; -import org.onosproject.xosintegration.VoltTenant; -import org.onosproject.xosintegration.VoltTenantService; -import org.slf4j.Logger; - -import com.google.common.collect.Maps; - -import static org.slf4j.LoggerFactory.getLogger; - -/** - * AAA Finite State Machine. - */ - -class StateMachine { - //INDEX to identify the state in the transition table - static final int STATE_IDLE = 0; - static final int STATE_STARTED = 1; - static final int STATE_PENDING = 2; - static final int STATE_AUTHORIZED = 3; - static final int STATE_UNAUTHORIZED = 4; - - //INDEX to identify the transition in the transition table - static final int TRANSITION_START = 0; // --> started - static final int TRANSITION_REQUEST_ACCESS = 1; - static final int TRANSITION_AUTHORIZE_ACCESS = 2; - static final int TRANSITION_DENY_ACCESS = 3; - static final int TRANSITION_LOGOFF = 4; - - //map of access identifiers (issued at EAPOL START) - static BitSet bitSet = new BitSet(); - private final VoltTenantService voltService; - - private int identifier = -1; - private byte challengeIdentifier; - private byte[] challengeState; - private byte[] username; - private byte[] requestAuthenticator; - - // Supplicant connectivity info - private ConnectPoint supplicantConnectpoint; - private MacAddress supplicantAddress; - private short vlanId; - - private String sessionId = null; - - private final Logger log = getLogger(getClass()); - - - private State[] states = { - new Idle(), new Started(), new Pending(), new Authorized(), new Unauthorized() - }; - - - //State transition table - /* - - state IDLE | STARTED | PENDING | AUTHORIZED | UNAUTHORIZED - //// - input - ---------------------------------------------------------------------------------------------------- - - START STARTED | _ | _ | _ | _ - - REQUEST_ACCESS _ | PENDING | _ | _ | _ - - AUTHORIZE_ACCESS _ | _ | AUTHORIZED | _ | _ - - DENY_ACCESS _ | - | UNAUTHORIZED | _ | _ - - LOGOFF _ | _ | _ | IDLE | IDLE - */ - - private int[] idleTransition = - {STATE_STARTED, STATE_IDLE, STATE_IDLE, STATE_IDLE, STATE_IDLE}; - private int[] startedTransition = - {STATE_STARTED, STATE_PENDING, STATE_STARTED, STATE_STARTED, STATE_STARTED}; - private int[] pendingTransition = - {STATE_PENDING, STATE_PENDING, STATE_AUTHORIZED, STATE_UNAUTHORIZED, STATE_PENDING}; - private int[] authorizedTransition = - {STATE_AUTHORIZED, STATE_AUTHORIZED, STATE_AUTHORIZED, STATE_AUTHORIZED, STATE_IDLE}; - private int[] unauthorizedTransition = - {STATE_UNAUTHORIZED, STATE_UNAUTHORIZED, STATE_UNAUTHORIZED, STATE_UNAUTHORIZED, STATE_IDLE}; - - //THE TRANSITION TABLE - private int[][] transition = - {idleTransition, startedTransition, pendingTransition, authorizedTransition, - unauthorizedTransition}; - - private int currentState = STATE_IDLE; - - // Maps of state machines. Each state machine is represented by an - // unique identifier on the switch: dpid + port number - private static Map<String, StateMachine> sessionIdMap; - private static Map<Integer, StateMachine> identifierMap; - - public static void initializeMaps() { - sessionIdMap = Maps.newConcurrentMap(); - identifierMap = Maps.newConcurrentMap(); - } - - public static void destroyMaps() { - sessionIdMap = null; - identifierMap = null; - } - - public static StateMachine lookupStateMachineById(byte identifier) { - return identifierMap.get((int) identifier); - } - - public static StateMachine lookupStateMachineBySessionId(String sessionId) { - return sessionIdMap.get(sessionId); - } /** - * State Machine Constructor. - * - * @param sessionId session Id represented by the switch dpid + port number - * @param voltService volt service reference - */ - public StateMachine(String sessionId, VoltTenantService voltService) { - log.info("Creating a new state machine for {}", sessionId); - this.sessionId = sessionId; - this.voltService = voltService; - sessionIdMap.put(sessionId, this); - } - - /** - * Gets the connect point for the supplicant side. - * - * @return supplicant connect point - */ - public ConnectPoint supplicantConnectpoint() { - return supplicantConnectpoint; - } - - /** - * Sets the supplicant side connect point. - * - * @param supplicantConnectpoint supplicant select point. - */ - public void setSupplicantConnectpoint(ConnectPoint supplicantConnectpoint) { - this.supplicantConnectpoint = supplicantConnectpoint; - } - - /** - * Gets the MAC address of the supplicant. - * - * @return supplicant MAC address - */ - public MacAddress supplicantAddress() { - return supplicantAddress; - } - - /** - * Sets the supplicant MAC address. - * - * @param supplicantAddress new supplicant MAC address - */ - public void setSupplicantAddress(MacAddress supplicantAddress) { - this.supplicantAddress = supplicantAddress; - } - - /** - * Gets the client's Vlan ID. - * - * @return client vlan ID - */ - public short vlanId() { - return vlanId; - } - - /** - * Sets the client's vlan ID. - * - * @param vlanId new client vlan ID - */ - public void setVlanId(short vlanId) { - this.vlanId = vlanId; - } - - /** - * Gets the client id that is requesting for access. - * - * @return The client id. - */ - public String sessionId() { - return this.sessionId; - } - - /** - * Create the identifier for the state machine (happens when goes to STARTED state). - */ - private void createIdentifier() throws StateMachineException { - log.debug("Creating Identifier."); - int index; - - try { - //find the first available spot for identifier assignment - index = StateMachine.bitSet.nextClearBit(0); - - //there is a limit of 256 identifiers - if (index == 256) { - throw new StateMachineException("Cannot handle any new identifier. Limit is 256."); - } - } catch (IndexOutOfBoundsException e) { - throw new StateMachineException(e.getMessage()); - } - - log.info("Assigning identifier {}", index); - StateMachine.bitSet.set(index); - this.identifier = index; - } - - /** - * Set the challenge identifier and the state issued by the RADIUS. - * - * @param challengeIdentifier The challenge identifier set into the EAP packet from the RADIUS message. - * @param challengeState The challenge state from the RADIUS. - */ - protected void setChallengeInfo(byte challengeIdentifier, byte[] challengeState) { - this.challengeIdentifier = challengeIdentifier; - this.challengeState = challengeState; - } - - /** - * Set the challenge identifier issued by the RADIUS on the access challenge request. - * - * @param challengeIdentifier The challenge identifier set into the EAP packet from the RADIUS message. - */ - protected void setChallengeIdentifier(byte challengeIdentifier) { - log.info("Set Challenge Identifier to {}", challengeIdentifier); - this.challengeIdentifier = challengeIdentifier; - } - - /** - * Gets the challenge EAP identifier set by the RADIUS. - * - * @return The challenge EAP identifier. - */ - protected byte challengeIdentifier() { - return this.challengeIdentifier; - } - - - /** - * Set the challenge state info issued by the RADIUS. - * - * @param challengeState The challenge state from the RADIUS. - */ - protected void setChallengeState(byte[] challengeState) { - log.info("Set Challenge State"); - this.challengeState = challengeState; - } - - /** - * Gets the challenge state set by the RADIUS. - * - * @return The challenge state. - */ - protected byte[] challengeState() { - return this.challengeState; - } - - /** - * Set the username. - * - * @param username The username sent to the RADIUS upon access request. - */ - protected void setUsername(byte[] username) { - this.username = username; - } - - - /** - * Gets the username. - * - * @return The requestAuthenticator. - */ - protected byte[] requestAuthenticator() { - return this.requestAuthenticator; - } - - /** - * Sets the authenticator. - * - * @param authenticator The username sent to the RADIUS upon access request. - */ - protected void setRequestAuthenticator(byte[] authenticator) { - this.requestAuthenticator = authenticator; - } - - - /** - * Gets the username. - * - * @return The username. - */ - protected byte[] username() { - return this.username; - } - - /** - * Return the identifier of the state machine. - * - * @return The state machine identifier. - */ - public byte identifier() { - return (byte) this.identifier; - } - - - protected void deleteIdentifier() { - if (this.identifier != -1) { - log.info("Freeing up " + this.identifier); - //this state machine should be deleted and free up the identifier - StateMachine.bitSet.clear(this.identifier); - this.identifier = -1; - } - } - - - /** - * Move to the next state. - * - * @param msg message - */ - private void next(int msg) { - currentState = transition[currentState][msg]; - log.info("Current State " + currentState); - } - - /** - * Client has requested the start action to allow network access. - * - * @throws StateMachineException if authentication protocol is violated - */ - public void start() throws StateMachineException { - states[currentState].start(); - //move to the next state - next(TRANSITION_START); - createIdentifier(); - identifierMap.put(identifier, this); - } - - /** - * An Identification information has been sent by the supplicant. - * Move to the next state if possible. - * - * @throws StateMachineException if authentication protocol is violated - */ - public void requestAccess() throws StateMachineException { - states[currentState].requestAccess(); - //move to the next state - next(TRANSITION_REQUEST_ACCESS); - } - - /** - * RADIUS has accepted the identification. - * Move to the next state if possible. - * - * @throws StateMachineException if authentication protocol is violated - */ - public void authorizeAccess() throws StateMachineException { - states[currentState].radiusAccepted(); - //move to the next state - next(TRANSITION_AUTHORIZE_ACCESS); - - if (voltService != null) { - voltService.addTenant( - VoltTenant.builder() - .withHumanReadableName("VCPE-" + this.identifier) - .withId(this.identifier) - .withProviderService(1) - .withServiceSpecificId(String.valueOf(this.identifier)) - .withPort(this.supplicantConnectpoint) - .withVlanId(String.valueOf(this.vlanId)).build()); - } - - deleteIdentifier(); - } - - /** - * RADIUS has denied the identification. - * Move to the next state if possible. - * - * @throws StateMachineException if authentication protocol is violated - */ - public void denyAccess() throws StateMachineException { - states[currentState].radiusDenied(); - //move to the next state - next(TRANSITION_DENY_ACCESS); - deleteIdentifier(); - } - - /** - * Logoff request has been requested. - * Move to the next state if possible. - * - * @throws StateMachineException if authentication protocol is violated - */ - public void logoff() throws StateMachineException { - states[currentState].logoff(); - //move to the next state - next(TRANSITION_LOGOFF); - } - - /** - * Gets the current state. - * - * @return The current state. Could be STATE_IDLE, STATE_STARTED, STATE_PENDING, STATE_AUTHORIZED, - * STATE_UNAUTHORIZED. - */ - public int state() { - return currentState; - } - - @Override - public String toString() { - return ("sessionId: " + this.sessionId) + "\t" + ("identifier: " + this.identifier) + "\t" + - ("state: " + this.currentState); - } - - abstract class State { - private final Logger log = getLogger(getClass()); - - private String name = "State"; - - public void start() throws StateMachineInvalidTransitionException { - log.warn("START transition from this state is not allowed."); - } - - public void requestAccess() throws StateMachineInvalidTransitionException { - log.warn("REQUEST ACCESS transition from this state is not allowed."); - } - - public void radiusAccepted() throws StateMachineInvalidTransitionException { - log.warn("AUTHORIZE ACCESS transition from this state is not allowed."); - } - - public void radiusDenied() throws StateMachineInvalidTransitionException { - log.warn("DENY ACCESS transition from this state is not allowed."); - } - - public void logoff() throws StateMachineInvalidTransitionException { - log.warn("LOGOFF transition from this state is not allowed."); - } - } - - /** - * Idle state: supplicant is logged of from the network. - */ - class Idle extends State { - private final Logger log = getLogger(getClass()); - private String name = "IDLE_STATE"; - - public void start() { - log.info("Moving from IDLE state to STARTED state."); - } - } - - /** - * Started state: supplicant has entered the network and informed the authenticator. - */ - class Started extends State { - private final Logger log = getLogger(getClass()); - private String name = "STARTED_STATE"; - - public void requestAccess() { - log.info("Moving from STARTED state to PENDING state."); - } - } - - /** - * Pending state: supplicant has been identified by the authenticator but has not access yet. - */ - class Pending extends State { - private final Logger log = getLogger(getClass()); - private String name = "PENDING_STATE"; - - public void radiusAccepted() { - log.info("Moving from PENDING state to AUTHORIZED state."); - } - - public void radiusDenied() { - log.info("Moving from PENDING state to UNAUTHORIZED state."); - } - } - - /** - * Authorized state: supplicant port has been accepted, access is granted. - */ - class Authorized extends State { - private final Logger log = getLogger(getClass()); - private String name = "AUTHORIZED_STATE"; - - public void logoff() { - - log.info("Moving from AUTHORIZED state to IDLE state."); - } - } - - /** - * Unauthorized state: supplicant port has been rejected, access is denied. - */ - class Unauthorized extends State { - private final Logger log = getLogger(getClass()); - private String name = "UNAUTHORIZED_STATE"; - - public void logoff() { - log.info("Moving from UNAUTHORIZED state to IDLE state."); - } - } - - -} diff --git a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/StateMachineException.java b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/StateMachineException.java deleted file mode 100644 index d4a4da77..00000000 --- a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/StateMachineException.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * Copyright 2015 AT&T Foundry - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.onosproject.aaa; - -/** - * Exception for the State Machine. - */ -class StateMachineException extends Exception { - public StateMachineException(String message) { - super(message); - - } -} diff --git a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/StateMachineInvalidTransitionException.java b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/StateMachineInvalidTransitionException.java deleted file mode 100644 index 9f41a34f..00000000 --- a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/StateMachineInvalidTransitionException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * - * Copyright 2015 AT&T Foundry - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.onosproject.aaa; - -/** - * Exception raised when the transition from one state to another is invalid. - */ -class StateMachineInvalidTransitionException extends StateMachineException { - public StateMachineInvalidTransitionException(String message) { - super(message); - } -} diff --git a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/package-info.java b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/package-info.java deleted file mode 100644 index 19c5a5d6..00000000 --- a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2014 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * AAA implmentation. - */ -package org.onosproject.aaa; diff --git a/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaIntegrationTest.java b/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaIntegrationTest.java deleted file mode 100644 index 6d708fef..00000000 --- a/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaIntegrationTest.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2014 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.onosproject.aaa; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.onlab.packet.EAP; -import org.onlab.packet.EAPOL; -import org.onlab.packet.Ethernet; -import org.onosproject.core.CoreServiceAdapter; -import org.onosproject.net.config.Config; -import org.onosproject.net.config.NetworkConfigRegistryAdapter; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertThat; - -/** - * Set of tests of the ONOS application component. These use an existing RADIUS - * server and sends live packets over the network to it. - */ -@Ignore ("This should not be run as part of the standard build") -public class AaaIntegrationTest extends AaaTestBase { - - private AaaManager aaa; - - /** - * Mocks the network config registry. - */ - @SuppressWarnings("unchecked") - static final class TestNetworkConfigRegistry - extends NetworkConfigRegistryAdapter { - @Override - public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) { - return (C) new AaaConfig(); - } - } - - /** - * Sets up the services required by the AAA application. - */ - @Before - public void setUp() { - aaa = new AaaManager(); - aaa.netCfgService = new TestNetworkConfigRegistry(); - aaa.coreService = new CoreServiceAdapter(); - aaa.packetService = new MockPacketService(); - aaa.activate(); - } - - /** - * Fetches the sent packet at the given index. The requested packet - * must be the last packet on the list. - * - * @param index index into sent packets array - * @return packet - */ - private Ethernet fetchPacket(int index) { - for (int iteration = 0; iteration < 20; iteration++) { - if (savedPackets.size() > index) { - return (Ethernet) savedPackets.get(index); - } else { - try { - Thread.sleep(250); - } catch (Exception ex) { - return null; - } - } - } - return null; - } - - /** - * Tests the authentication path through the AAA application by sending - * packets to the RADIUS server and checking the state machine - * transitions. - * - * @throws Exception when an unhandled error occurs - */ - @Test - public void testAuthentication() throws Exception { - - // (1) Supplicant start up - - Ethernet startPacket = constructSupplicantStartPacket(); - sendPacket(startPacket); - - Ethernet responsePacket = fetchPacket(0); - assertThat(responsePacket, notNullValue()); - checkRadiusPacket(aaa, responsePacket, EAP.REQUEST); - - // (2) Supplicant identify - - Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null); - sendPacket(identifyPacket); - - // State machine should have been created by now - - StateMachine stateMachine = - StateMachine.lookupStateMachineBySessionId(SESSION_ID); - assertThat(stateMachine, notNullValue()); - assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING)); - - // (3) RADIUS MD5 challenge - - Ethernet radiusChallengeMD5Packet = fetchPacket(1); - assertThat(radiusChallengeMD5Packet, notNullValue()); - checkRadiusPacket(aaa, radiusChallengeMD5Packet, EAP.REQUEST); - - - // (4) Supplicant MD5 response - - Ethernet md5RadiusPacket = - constructSupplicantIdentifyPacket(stateMachine, - EAP.ATTR_MD5, - stateMachine.challengeIdentifier(), - radiusChallengeMD5Packet); - sendPacket(md5RadiusPacket); - - - // (5) RADIUS Success - - Ethernet successRadiusPacket = fetchPacket(2); - assertThat(successRadiusPacket, notNullValue()); - EAPOL successEapol = (EAPOL) successRadiusPacket.getPayload(); - EAP successEap = (EAP) successEapol.getPayload(); - assertThat(successEap.getCode(), is(EAP.SUCCESS)); - - // State machine should be in authorized state - - assertThat(stateMachine, notNullValue()); - assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED)); - - } - -} - diff --git a/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaManagerTest.java b/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaManagerTest.java deleted file mode 100644 index e3bcd9e4..00000000 --- a/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaManagerTest.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2014 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.onosproject.aaa; - -import com.google.common.base.Charsets; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.onlab.packet.BasePacket; -import org.onlab.packet.DeserializationException; -import org.onlab.packet.EAP; -import org.onlab.packet.Ethernet; -import org.onlab.packet.IpAddress; -import org.onlab.packet.RADIUS; -import org.onlab.packet.RADIUSAttribute; -import org.onosproject.core.CoreServiceAdapter; -import org.onosproject.net.config.Config; -import org.onosproject.net.config.NetworkConfigRegistryAdapter; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertThat; - -/** - * Set of tests of the ONOS application component. - */ -public class AaaManagerTest extends AaaTestBase { - - static final String BAD_IP_ADDRESS = "198.51.100.0"; - - private AaaManager aaaManager; - - class AaaManagerWithoutRadiusServer extends AaaManager { - protected void sendRadiusPacket(RADIUS radiusPacket) { - savePacket(radiusPacket); - } - } - - /** - * Mocks the AAAConfig class to force usage of an unroutable address for the - * RADIUS server. - */ - static class MockAaaConfig extends AaaConfig { - @Override - public InetAddress radiusIp() { - try { - return InetAddress.getByName(BAD_IP_ADDRESS); - } catch (UnknownHostException ex) { - // can't happen - throw new IllegalStateException(ex); - } - } - } - - /** - * Mocks the network config registry. - */ - @SuppressWarnings("unchecked") - private static final class TestNetworkConfigRegistry - extends NetworkConfigRegistryAdapter { - @Override - public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) { - AaaConfig aaaConfig = new MockAaaConfig(); - return (C) aaaConfig; - } - } - - /** - * Constructs an Ethernet packet containing a RADIUS challenge - * packet. - * - * @param challengeCode code to use in challenge packet - * @param challengeType type to use in challenge packet - * @return Ethernet packet - */ - private RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType) { - - String challenge = "12345678901234567"; - - EAP eap = new EAP(challengeType, (byte) 1, challengeType, - challenge.getBytes(Charsets.US_ASCII)); - eap.setIdentifier((byte) 1); - - RADIUS radius = new RADIUS(); - radius.setCode(challengeCode); - - radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE, - challenge.getBytes(Charsets.US_ASCII)); - - radius.setPayload(eap); - radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE, - eap.serialize()); - - return radius; - } - - /** - * Sets up the services required by the AAA application. - */ - @Before - public void setUp() { - aaaManager = new AaaManagerWithoutRadiusServer(); - aaaManager.netCfgService = new TestNetworkConfigRegistry(); - aaaManager.coreService = new CoreServiceAdapter(); - aaaManager.packetService = new MockPacketService(); - aaaManager.activate(); - } - - /** - * Tears down the AAA application. - */ - @After - public void tearDown() { - aaaManager.deactivate(); - } - - /** - * Extracts the RADIUS packet from a packet sent by the supplicant. - * - * @param radius RADIUS packet sent by the supplicant - * @throws DeserializationException if deserialization of the packet contents - * fails. - */ - private void checkRadiusPacketFromSupplicant(RADIUS radius) - throws DeserializationException { - assertThat(radius, notNullValue()); - - EAP eap = radius.decapsulateMessage(); - assertThat(eap, notNullValue()); - } - - /** - * Fetches the sent packet at the given index. The requested packet - * must be the last packet on the list. - * - * @param index index into sent packets array - * @return packet - */ - private BasePacket fetchPacket(int index) { - BasePacket packet = savedPackets.get(index); - assertThat(packet, notNullValue()); - return packet; - } - - /** - * Tests the authentication path through the AAA application. - * - * @throws DeserializationException if packed deserialization fails. - */ - @Test - public void testAuthentication() throws Exception { - - // (1) Supplicant start up - - Ethernet startPacket = constructSupplicantStartPacket(); - sendPacket(startPacket); - - Ethernet responsePacket = (Ethernet) fetchPacket(0); - checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY); - - // (2) Supplicant identify - - Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null); - sendPacket(identifyPacket); - - RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1); - - checkRadiusPacketFromSupplicant(radiusIdentifyPacket); - - assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST)); - assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()), - is("testuser")); - - IpAddress nasIp = - IpAddress.valueOf(IpAddress.Version.INET, - radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP) - .getValue()); - assertThat(nasIp.toString(), is(aaaManager.nasIpAddress.getHostAddress())); - - // State machine should have been created by now - - StateMachine stateMachine = - StateMachine.lookupStateMachineBySessionId(SESSION_ID); - assertThat(stateMachine, notNullValue()); - assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING)); - - // (3) RADIUS MD5 challenge - - RADIUS radiusCodeAccessChallengePacket = - constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5); - aaaManager.radiusListener.handleRadiusPacket(radiusCodeAccessChallengePacket); - - Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2); - checkRadiusPacket(aaaManager, radiusChallengeMD5Packet, EAP.ATTR_MD5); - - // (4) Supplicant MD5 response - - Ethernet md5RadiusPacket = - constructSupplicantIdentifyPacket(stateMachine, - EAP.ATTR_MD5, - stateMachine.challengeIdentifier(), - radiusChallengeMD5Packet); - sendPacket(md5RadiusPacket); - - RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3); - - checkRadiusPacketFromSupplicant(responseMd5RadiusPacket); - assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 0)); - assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST)); - - // State machine should be in pending state - - assertThat(stateMachine, notNullValue()); - assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING)); - - // (5) RADIUS Success - - RADIUS successPacket = - constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT, EAP.SUCCESS); - aaaManager.radiusListener.handleRadiusPacket((successPacket)); - Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4); - - checkRadiusPacket(aaaManager, supplicantSuccessPacket, EAP.SUCCESS); - - // State machine should be in authorized state - - assertThat(stateMachine, notNullValue()); - assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED)); - - } - - /** - * Tests the default configuration. - */ - @Test - public void testConfig() { - assertThat(aaaManager.nasIpAddress.getHostAddress(), is(AaaConfig.DEFAULT_NAS_IP)); - assertThat(aaaManager.nasMacAddress, is(AaaConfig.DEFAULT_NAS_MAC)); - assertThat(aaaManager.radiusIpAddress.getHostAddress(), is(BAD_IP_ADDRESS)); - assertThat(aaaManager.radiusMacAddress, is(AaaConfig.DEFAULT_RADIUS_MAC)); - } -} diff --git a/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaTestBase.java b/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaTestBase.java deleted file mode 100644 index b076a2e3..00000000 --- a/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaTestBase.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.onosproject.aaa; - -import org.onlab.packet.BasePacket; -import org.onlab.packet.EAP; -import org.onlab.packet.EAPOL; -import org.onlab.packet.EthType; -import org.onlab.packet.Ethernet; -import org.onlab.packet.MacAddress; -import org.onosproject.net.packet.DefaultInboundPacket; -import org.onosproject.net.packet.DefaultPacketContext; -import org.onosproject.net.packet.InboundPacket; -import org.onosproject.net.packet.OutboundPacket; -import org.onosproject.net.packet.PacketContext; -import org.onosproject.net.packet.PacketProcessor; -import org.onosproject.net.packet.PacketServiceAdapter; - -import java.nio.ByteBuffer; -import java.security.MessageDigest; -import java.util.LinkedList; -import java.util.List; - -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; -import static org.onosproject.net.NetTestTools.connectPoint; - -/** - * Common methods for AAA app testing. - */ -public class AaaTestBase { - - MacAddress clientMac = MacAddress.valueOf("1a:1a:1a:1a:1a:1a"); - MacAddress serverMac = MacAddress.valueOf("2a:2a:2a:2a:2a:2a"); - - // Our session id will be the device ID ("of:1") with the port ("1") concatenated - static final String SESSION_ID = "of:11"; - - List<BasePacket> savedPackets = new LinkedList<>(); - PacketProcessor packetProcessor; - - /** - * Saves the given packet onto the saved packets list. - * - * @param packet packet to save - */ - void savePacket(BasePacket packet) { - savedPackets.add(packet); - } - - /** - * Keeps a reference to the PacketProcessor and saves the OutboundPackets. - */ - class MockPacketService extends PacketServiceAdapter { - - @Override - public void addProcessor(PacketProcessor processor, int priority) { - packetProcessor = processor; - } - - @Override - public void emit(OutboundPacket packet) { - try { - Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(), - 0, packet.data().array().length); - savePacket(eth); - } catch (Exception e) { - fail(e.getMessage()); - } - } - } - - /** - * Mocks the DefaultPacketContext. - */ - final class TestPacketContext extends DefaultPacketContext { - - private TestPacketContext(long time, InboundPacket inPkt, - OutboundPacket outPkt, boolean block) { - super(time, inPkt, outPkt, block); - } - - @Override - public void send() { - // We don't send anything out. - } - } - - /** - * Sends an Ethernet packet to the process method of the Packet Processor. - * - * @param reply Ethernet packet - */ - void sendPacket(Ethernet reply) { - final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize()); - InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1), - reply, - byteBuffer); - - PacketContext context = new TestPacketContext(127L, inPacket, null, false); - packetProcessor.process(context); - } - - /** - * Constructs an Ethernet packet containing identification payload. - * - * @return Ethernet packet - */ - Ethernet constructSupplicantIdentifyPacket(StateMachine stateMachine, - byte type, - byte id, - Ethernet radiusChallenge) - throws Exception { - Ethernet eth = new Ethernet(); - eth.setDestinationMACAddress(clientMac.toBytes()); - eth.setSourceMACAddress(serverMac.toBytes()); - eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort()); - eth.setVlanID((short) 2); - - String username = "testuser"; - byte[] data = username.getBytes(); - - - if (type == EAP.ATTR_MD5) { - String password = "testpassword"; - EAPOL eapol = (EAPOL) radiusChallenge.getPayload(); - EAP eap = (EAP) eapol.getPayload(); - - byte[] identifier = new byte[password.length() + eap.getData().length]; - - identifier[0] = stateMachine.challengeIdentifier(); - System.arraycopy(password.getBytes(), 0, identifier, 1, password.length()); - System.arraycopy(eap.getData(), 1, identifier, 1 + password.length(), 16); - - MessageDigest md = MessageDigest.getInstance("MD5"); - byte[] hash = md.digest(identifier); - data = new byte[17]; - data[0] = (byte) 16; - System.arraycopy(hash, 0, data, 1, 16); - } - EAP eap = new EAP(EAP.RESPONSE, (byte) 1, type, - data); - eap.setIdentifier(id); - - // eapol header - EAPOL eapol = new EAPOL(); - eapol.setEapolType(EAPOL.EAPOL_PACKET); - eapol.setPacketLength(eap.getLength()); - - // eap part - eapol.setPayload(eap); - - eth.setPayload(eapol); - eth.setPad(true); - return eth; - } - - /** - * Constructs an Ethernet packet containing a EAPOL_START Payload. - * - * @return Ethernet packet - */ - Ethernet constructSupplicantStartPacket() { - Ethernet eth = new Ethernet(); - eth.setDestinationMACAddress(clientMac.toBytes()); - eth.setSourceMACAddress(serverMac.toBytes()); - eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort()); - eth.setVlanID((short) 2); - - EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 2, EAPOL.EAPOL_START, null); - - // eapol header - EAPOL eapol = new EAPOL(); - eapol.setEapolType(EAPOL.EAPOL_START); - eapol.setPacketLength(eap.getLength()); - - // eap part - eapol.setPayload(eap); - - eth.setPayload(eapol); - eth.setPad(true); - return eth; - } - - /** - * Checks the contents of a RADIUS packet being sent to the RADIUS server. - * - * @param radiusPacket packet to check - * @param code expected code - */ - void checkRadiusPacket(AaaManager aaaManager, Ethernet radiusPacket, byte code) { - - assertThat(radiusPacket.getSourceMAC(), - is(MacAddress.valueOf(aaaManager.nasMacAddress))); - assertThat(radiusPacket.getDestinationMAC(), is(serverMac)); - - assertThat(radiusPacket.getPayload(), instanceOf(EAPOL.class)); - EAPOL eapol = (EAPOL) radiusPacket.getPayload(); - assertThat(eapol, notNullValue()); - - assertThat(eapol.getEapolType(), is(EAPOL.EAPOL_PACKET)); - assertThat(eapol.getPayload(), instanceOf(EAP.class)); - EAP eap = (EAP) eapol.getPayload(); - assertThat(eap, notNullValue()); - - assertThat(eap.getCode(), is(code)); - } -} diff --git a/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/StateMachineTest.java b/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/StateMachineTest.java deleted file mode 100644 index 1838c63e..00000000 --- a/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/StateMachineTest.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * - * Copyright 2015 AT&T Foundry - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.onosproject.aaa; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - - -public class StateMachineTest { - StateMachine stateMachine = null; - - @Before - public void setUp() { - System.out.println("Set Up."); - StateMachine.bitSet.clear(); - StateMachine.initializeMaps(); - stateMachine = new StateMachine("session0", null); - } - - @After - public void tearDown() { - System.out.println("Tear Down."); - StateMachine.bitSet.clear(); - StateMachine.destroyMaps(); - stateMachine = null; - } - - @Test - /** - * Test all the basic inputs from state to state: IDLE -> STARTED -> PENDING -> AUTHORIZED -> IDLE - */ - public void basic() throws StateMachineException { - System.out.println("======= BASIC =======."); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); - - stateMachine.start(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED); - - stateMachine.requestAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); - - stateMachine.authorizeAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED); - - stateMachine.logoff(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); - } - - @Test - /** - * Test all inputs from an IDLE state (starting with the ones that are not impacting the current state) - */ - public void testIdleState() throws StateMachineException { - System.out.println("======= IDLE STATE TEST =======."); - stateMachine.requestAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); - - stateMachine.authorizeAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); - - stateMachine.denyAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); - - stateMachine.logoff(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); - - stateMachine.start(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED); - } - - @Test - /** - * Test all inputs from an STARTED state (starting with the ones that are not impacting the current state) - */ - public void testStartedState() throws StateMachineException { - System.out.println("======= STARTED STATE TEST =======."); - stateMachine.start(); - - stateMachine.authorizeAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED); - - stateMachine.denyAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED); - - stateMachine.logoff(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED); - - stateMachine.start(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED); - - stateMachine.requestAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); - } - - @Test - /** - * Test all inputs from a PENDING state (starting with the ones that are not impacting the current state). - * The next valid state for this test is AUTHORIZED - */ - public void testPendingStateToAuthorized() throws StateMachineException { - System.out.println("======= PENDING STATE TEST (AUTHORIZED) =======."); - stateMachine.start(); - stateMachine.requestAccess(); - - stateMachine.logoff(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); - - stateMachine.start(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); - - stateMachine.requestAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); - - stateMachine.authorizeAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED); - - stateMachine.denyAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED); - } - - @Test - /** - * Test all inputs from an PENDING state (starting with the ones that are not impacting the current state). - * The next valid state for this test is UNAUTHORIZED - */ - public void testPendingStateToUnauthorized() throws StateMachineException { - System.out.println("======= PENDING STATE TEST (DENIED) =======."); - stateMachine.start(); - stateMachine.requestAccess(); - - stateMachine.logoff(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); - - stateMachine.start(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); - - stateMachine.requestAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); - - stateMachine.denyAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED); - - stateMachine.authorizeAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED); - } - - @Test - /** - * Test all inputs from an AUTHORIZED state (starting with the ones that are not impacting the current state). - */ - public void testAuthorizedState() throws StateMachineException { - System.out.println("======= AUTHORIZED STATE TEST =======."); - stateMachine.start(); - stateMachine.requestAccess(); - stateMachine.authorizeAccess(); - - stateMachine.start(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED); - - stateMachine.requestAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED); - - stateMachine.authorizeAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED); - - stateMachine.denyAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED); - - stateMachine.logoff(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); - } - - @Test - /** - * Test all inputs from an UNAUTHORIZED state (starting with the ones that are not impacting the current state). - */ - public void testUnauthorizedState() throws StateMachineException { - System.out.println("======= UNAUTHORIZED STATE TEST =======."); - stateMachine.start(); - stateMachine.requestAccess(); - stateMachine.denyAccess(); - - stateMachine.start(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED); - - stateMachine.requestAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED); - - stateMachine.authorizeAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED); - - stateMachine.denyAccess(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED); - - stateMachine.logoff(); - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); - } - - - @Test - public void testIdentifierAvailability() throws StateMachineException { - System.out.println("======= IDENTIFIER TEST =======."); - byte identifier = stateMachine.identifier(); - System.out.println("State: " + stateMachine.state()); - System.out.println("Identifier: " + Byte.toUnsignedInt(identifier)); - Assert.assertEquals(-1, identifier); - stateMachine.start(); - - - StateMachine sm247 = null; - StateMachine sm3 = null; - - - //create 255 others state machines - for (int i = 1; i <= 255; i++) { - StateMachine sm = new StateMachine("session" + i, null); - sm.start(); - byte id = sm.identifier(); - Assert.assertEquals(i, Byte.toUnsignedInt(id)); - if (i == 3) { - sm3 = sm; - System.out.println("SM3: " + sm3.toString()); - } - if (i == 247) { - sm247 = sm; - System.out.println("SM247: " + sm247.toString()); - } - } - - //simulate the state machine for a specific session and logoff so we can free up a spot for an identifier - //let's choose identifier 247 then we free up 3 - Assert.assertNotNull(sm247); - sm247.requestAccess(); - sm247.authorizeAccess(); - sm247.logoff(); - - Assert.assertNotNull(sm3); - sm3.requestAccess(); - sm3.authorizeAccess(); - sm3.logoff(); - - StateMachine otherSM3 = new StateMachine("session3b", null); - otherSM3.start(); - otherSM3.requestAccess(); - byte id3 = otherSM3.identifier(); - Assert.assertEquals(3, Byte.toUnsignedInt(id3)); - - StateMachine otherSM247 = new StateMachine("session247b", null); - otherSM247.start(); - otherSM247.requestAccess(); - byte id247 = otherSM247.identifier(); - Assert.assertEquals(247, Byte.toUnsignedInt(id247)); - } - - @Test - public void testSessionIdLookups() { - String sessionId1 = "session1"; - String sessionId2 = "session2"; - String sessionId3 = "session3"; - - StateMachine machine1ShouldBeNull = - StateMachine.lookupStateMachineBySessionId(sessionId1); - assertNull(machine1ShouldBeNull); - StateMachine machine2ShouldBeNull = - StateMachine.lookupStateMachineBySessionId(sessionId2); - assertNull(machine2ShouldBeNull); - - StateMachine stateMachine1 = new StateMachine(sessionId1, null); - StateMachine stateMachine2 = new StateMachine(sessionId2, null); - - assertEquals(stateMachine1, - StateMachine.lookupStateMachineBySessionId(sessionId1)); - assertEquals(stateMachine2, - StateMachine.lookupStateMachineBySessionId(sessionId2)); - assertNull(StateMachine.lookupStateMachineBySessionId(sessionId3)); - } - - @Test - public void testIdentifierLookups() throws StateMachineException { - String sessionId1 = "session1"; - String sessionId2 = "session2"; - - StateMachine machine1ShouldBeNull = - StateMachine.lookupStateMachineById((byte) 1); - assertNull(machine1ShouldBeNull); - StateMachine machine2ShouldBeNull = - StateMachine.lookupStateMachineById((byte) 2); - assertNull(machine2ShouldBeNull); - - StateMachine stateMachine1 = new StateMachine(sessionId1, null); - stateMachine1.start(); - StateMachine stateMachine2 = new StateMachine(sessionId2, null); - stateMachine2.start(); - - assertEquals(stateMachine1, - StateMachine.lookupStateMachineById(stateMachine1.identifier())); - assertEquals(stateMachine2, - StateMachine.lookupStateMachineById(stateMachine2.identifier())); - } -} |