From b731e2f1dd0972409b136aebc7b463dd72c9cfad Mon Sep 17 00:00:00 2001 From: CNlucius Date: Tue, 13 Sep 2016 11:40:12 +0800 Subject: ONOSFW-171 O/S-SFC-ONOS scenario documentation Change-Id: I51ae1cf736ea24ab6680f8edca1b2bf5dd598365 Signed-off-by: CNlucius --- .../main/java/org/onosproject/aaa/AaaConfig.java | 239 --------- .../main/java/org/onosproject/aaa/AaaManager.java | 562 --------------------- .../java/org/onosproject/aaa/StateMachine.java | 537 -------------------- .../org/onosproject/aaa/StateMachineException.java | 28 - .../StateMachineInvalidTransitionException.java | 27 - .../java/org/onosproject/aaa/package-info.java | 20 - 6 files changed, 1413 deletions(-) delete mode 100644 framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaConfig.java delete mode 100644 framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaManager.java delete mode 100644 framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/StateMachine.java delete mode 100644 framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/StateMachineException.java delete mode 100644 framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/StateMachineInvalidTransitionException.java delete mode 100644 framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/package-info.java (limited to 'framework/src/onos/apps/aaa/src/main/java/org/onosproject') 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 { - - 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(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 sessionIdMap; - private static Map 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; -- cgit 1.2.3-korg