blob: d3ba6fc6c1e8672f06cfb68351659fd7f313f280 [file] [log] [blame]
Ari Saha89831742015-06-26 10:31:48 -07001/*
Amit Ghoshc9ac1e52017-07-28 12:31:18 +01002 * Copyright 2017-present Open Networking Foundation
Ari Saha89831742015-06-26 10:31:48 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Matteo Scandolocf847b82019-04-26 15:00:00 -070016package org.opencord.aaa.impl;
Ari Saha89831742015-06-26 10:31:48 -070017
Saurav Das987441a2018-09-18 16:33:47 -070018import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
19import static org.slf4j.LoggerFactory.getLogger;
20
21import java.net.InetAddress;
kartikey dubeye1545422019-05-22 12:53:45 +000022import java.net.UnknownHostException;
Saurav Das987441a2018-09-18 16:33:47 -070023import java.nio.ByteBuffer;
24import java.util.Map;
kartikey dubeye1545422019-05-22 12:53:45 +000025import java.util.Dictionary;
26import java.util.HashSet;
Saurav Das987441a2018-09-18 16:33:47 -070027
Jonathan Hart932bedc2018-07-12 13:46:09 -070028import org.apache.commons.lang3.builder.ToStringBuilder;
Ari Saha89831742015-06-26 10:31:48 -070029import org.apache.felix.scr.annotations.Component;
30import org.apache.felix.scr.annotations.Deactivate;
kartikey dubeye1545422019-05-22 12:53:45 +000031import org.apache.felix.scr.annotations.Property;
Ari Saha89831742015-06-26 10:31:48 -070032import org.apache.felix.scr.annotations.Reference;
33import org.apache.felix.scr.annotations.ReferenceCardinality;
Jonathan Hart5db44532018-07-12 18:13:54 -070034import org.apache.felix.scr.annotations.Service;
Jonathan Hart4731dd92018-05-02 17:30:05 -070035import org.onlab.packet.DeserializationException;
Jonathan Harta46dddf2015-06-30 15:31:20 -070036import org.onlab.packet.EAP;
37import org.onlab.packet.EAPOL;
38import org.onlab.packet.EthType;
Ari Saha89831742015-06-26 10:31:48 -070039import org.onlab.packet.Ethernet;
Ari Saha89831742015-06-26 10:31:48 -070040import org.onlab.packet.MacAddress;
Jonathan Harta46dddf2015-06-30 15:31:20 -070041import org.onlab.packet.RADIUS;
42import org.onlab.packet.RADIUSAttribute;
kartikey dubeye1545422019-05-22 12:53:45 +000043import org.onlab.util.Tools;
44import org.onosproject.cfg.ComponentConfigService;
Ari Saha89831742015-06-26 10:31:48 -070045import org.onosproject.core.ApplicationId;
46import org.onosproject.core.CoreService;
Jonathan Hart5db44532018-07-12 18:13:54 -070047import org.onosproject.event.AbstractListenerManager;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010048import org.onosproject.mastership.MastershipService;
Ari Saha89831742015-06-26 10:31:48 -070049import org.onosproject.net.ConnectPoint;
50import org.onosproject.net.DeviceId;
Ari Saha89831742015-06-26 10:31:48 -070051import org.onosproject.net.PortNumber;
Ray Milkeyfcb623d2015-10-01 16:48:18 -070052import org.onosproject.net.config.ConfigFactory;
53import org.onosproject.net.config.NetworkConfigEvent;
54import org.onosproject.net.config.NetworkConfigListener;
55import org.onosproject.net.config.NetworkConfigRegistry;
Amit Ghoshf739be52017-09-21 15:49:37 +010056import org.onosproject.net.device.DeviceEvent;
57import org.onosproject.net.device.DeviceListener;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010058import org.onosproject.net.device.DeviceService;
Ari Saha89831742015-06-26 10:31:48 -070059import org.onosproject.net.flow.DefaultTrafficTreatment;
Ari Saha89831742015-06-26 10:31:48 -070060import org.onosproject.net.flow.TrafficTreatment;
Ari Saha89831742015-06-26 10:31:48 -070061import org.onosproject.net.packet.DefaultOutboundPacket;
62import org.onosproject.net.packet.InboundPacket;
63import org.onosproject.net.packet.OutboundPacket;
64import org.onosproject.net.packet.PacketContext;
Ari Saha89831742015-06-26 10:31:48 -070065import org.onosproject.net.packet.PacketProcessor;
66import org.onosproject.net.packet.PacketService;
Matteo Scandolocf847b82019-04-26 15:00:00 -070067import org.opencord.aaa.AaaConfig;
68import org.opencord.aaa.AuthenticationEvent;
69import org.opencord.aaa.AuthenticationEventListener;
70import org.opencord.aaa.AuthenticationService;
kartikey dubeye1545422019-05-22 12:53:45 +000071import org.opencord.aaa.AuthenticationStatisticsEvent;
72import org.opencord.aaa.AuthenticationStatisticsService;
Matteo Scandolocf847b82019-04-26 15:00:00 -070073import org.opencord.aaa.RadiusCommunicator;
74import org.opencord.aaa.StateMachineDelegate;
Gamze Abaka1cfdb192018-10-25 11:39:19 +000075import org.opencord.sadis.BaseInformationService;
76import org.opencord.sadis.SadisService;
77import org.opencord.sadis.SubscriberAndDeviceInformation;
kartikey dubeye1545422019-05-22 12:53:45 +000078import org.osgi.service.component.ComponentContext;
Kartikey Dubeyf72e1952019-06-24 07:09:00 +000079import org.apache.felix.scr.annotations.Modified;
80import org.apache.felix.scr.annotations.Activate;
Ari Saha89831742015-06-26 10:31:48 -070081import org.slf4j.Logger;
kartikey dubeye1545422019-05-22 12:53:45 +000082import com.google.common.base.Strings;
Ari Saha89831742015-06-26 10:31:48 -070083
kartikey dubeye1545422019-05-22 12:53:45 +000084import java.util.concurrent.Executors;
85import java.util.concurrent.ScheduledExecutorService;
86import java.util.concurrent.ScheduledFuture;
87import java.util.concurrent.TimeUnit;
Ari Saha89831742015-06-26 10:31:48 -070088/**
Jonathan Harta46dddf2015-06-30 15:31:20 -070089 * AAA application for ONOS.
Ari Saha89831742015-06-26 10:31:48 -070090 */
Jonathan Hart5db44532018-07-12 18:13:54 -070091@Service
Ari Saha89831742015-06-26 10:31:48 -070092@Component(immediate = true)
Jonathan Hart5db44532018-07-12 18:13:54 -070093public class AaaManager
94 extends AbstractListenerManager<AuthenticationEvent, AuthenticationEventListener>
95 implements AuthenticationService {
96
Charles Chandf7ff862017-01-20 11:22:05 -080097 private static final String APP_NAME = "org.opencord.aaa";
Ray Milkeyf51eba22015-09-25 10:24:23 -070098
Ray Milkeyf61a24e2015-09-24 16:34:02 -070099 private final Logger log = getLogger(getClass());
Ray Milkeyf51eba22015-09-25 10:24:23 -0700100
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 protected CoreService coreService;
Ray Milkeyf51eba22015-09-25 10:24:23 -0700103
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700104 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
105 protected PacketService packetService;
Ray Milkeyf51eba22015-09-25 10:24:23 -0700106
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700107 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700108 protected NetworkConfigRegistry netCfgService;
Ray Milkeyf51eba22015-09-25 10:24:23 -0700109
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100110 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
111 protected DeviceService deviceService;
112
113 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000114 protected SadisService sadisService;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100115
116 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
117 protected MastershipService mastershipService;
118
kartikey dubeye1545422019-05-22 12:53:45 +0000119 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
120 protected AuthenticationStatisticsService aaaStatisticsManager;
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000121
kartikey dubeye1545422019-05-22 12:53:45 +0000122 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
123 protected ComponentConfigService cfgService;
124
125 protected AuthenticationStatisticsEventPublisher authenticationStatisticsPublisher;
126 protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
Amit Ghoshf739be52017-09-21 15:49:37 +0100127 private final DeviceListener deviceListener = new InternalDeviceListener();
128
kartikey dubeye1545422019-05-22 12:53:45 +0000129 private static final int DEFAULT_REPEAT_DELAY = 20;
130 @Property(name = "statisticsGenerationEvent", intValue = DEFAULT_REPEAT_DELAY,
131 label = "statisticsGenerationEvent")
132 private int statisticsGenerationEvent = DEFAULT_REPEAT_DELAY;
133
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700134 // NAS IP address
135 protected InetAddress nasIpAddress;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100136
137 // self MAC address
Jonathan Hart5db44532018-07-12 18:13:54 -0700138 protected String nasMacAddress;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100139
140 // Parsed RADIUS server addresses
141 protected InetAddress radiusIpAddress;
142
143 // MAC address of RADIUS server or net hop router
144 protected String radiusMacAddress;
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700145
146 // RADIUS server secret
147 protected String radiusSecret;
148
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100149 // bindings
150 protected CustomizationInfo customInfo;
Ray Milkey5d99bd12015-10-06 15:41:30 -0700151
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700152 // our application-specific event handler
153 private ReactivePacketProcessor processor = new ReactivePacketProcessor();
Ray Milkeyf51eba22015-09-25 10:24:23 -0700154
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700155 // our unique identifier
156 private ApplicationId appId;
Ray Milkeyf51eba22015-09-25 10:24:23 -0700157
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100158 // Setup specific customization/attributes on the RADIUS packets
159 PacketCustomizer pktCustomizer;
Ray Milkey967776a2015-10-07 14:37:17 -0700160
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100161 // packet customizer to use
162 private String customizer;
163
164 // Type of connection to use to communicate with Radius server, options are
165 // "socket" or "packet_out"
166 private String radiusConnectionType;
167
Jonathan Hart5db44532018-07-12 18:13:54 -0700168 // Object for the specific type of communication with the RADIUS
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100169 // server, socket based or packet_out based
170 RadiusCommunicator impl = null;
171
172 // latest configuration
173 AaaConfig newCfg;
Ray Milkey967776a2015-10-07 14:37:17 -0700174
kartikey dubeye1545422019-05-22 12:53:45 +0000175 ScheduledFuture<?> scheduledFuture;
176
177 ScheduledExecutorService executor;
178 String configuredAaaServerAddress;
179 HashSet<Byte> outPacketSet = new HashSet<Byte>();
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700180 // Configuration properties factory
181 private final ConfigFactory factory =
Jonathan Hart092dfb22015-11-16 23:05:21 -0800182 new ConfigFactory<ApplicationId, AaaConfig>(APP_SUBJECT_FACTORY,
183 AaaConfig.class,
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700184 "AAA") {
185 @Override
Jonathan Hart092dfb22015-11-16 23:05:21 -0800186 public AaaConfig createConfig() {
187 return new AaaConfig();
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700188 }
189 };
Ray Milkeyf51eba22015-09-25 10:24:23 -0700190
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700191 // Listener for config changes
192 private final InternalConfigListener cfgListener = new InternalConfigListener();
Ari Saha89831742015-06-26 10:31:48 -0700193
Jonathan Hart5db44532018-07-12 18:13:54 -0700194 private StateMachineDelegate delegate = new InternalStateMachineDelegate();
195
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700196 /**
197 * Builds an EAPOL packet based on the given parameters.
198 *
199 * @param dstMac destination MAC address
200 * @param srcMac source MAC address
201 * @param vlan vlan identifier
202 * @param eapolType EAPOL type
203 * @param eap EAP payload
204 * @return Ethernet frame
205 */
206 private static Ethernet buildEapolResponse(MacAddress dstMac, MacAddress srcMac,
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100207 short vlan, byte eapolType, EAP eap, byte priorityCode) {
Ari Saha89831742015-06-26 10:31:48 -0700208
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700209 Ethernet eth = new Ethernet();
210 eth.setDestinationMACAddress(dstMac.toBytes());
211 eth.setSourceMACAddress(srcMac.toBytes());
212 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
213 if (vlan != Ethernet.VLAN_UNTAGGED) {
214 eth.setVlanID(vlan);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100215 eth.setPriorityCode(priorityCode);
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700216 }
217 //eapol header
218 EAPOL eapol = new EAPOL();
219 eapol.setEapolType(eapolType);
220 eapol.setPacketLength(eap.getLength());
Ari Saha89831742015-06-26 10:31:48 -0700221
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700222 //eap part
223 eapol.setPayload(eap);
224
225 eth.setPayload(eapol);
226 eth.setPad(true);
227 return eth;
228 }
Ari Saha89831742015-06-26 10:31:48 -0700229
Ari Saha89831742015-06-26 10:31:48 -0700230 @Activate
kartikey dubeye1545422019-05-22 12:53:45 +0000231 public void activate(ComponentContext context) {
Charles Chandf7ff862017-01-20 11:22:05 -0800232 appId = coreService.registerApplication(APP_NAME);
Jonathan Hart5db44532018-07-12 18:13:54 -0700233 eventDispatcher.addSink(AuthenticationEvent.class, listenerRegistry);
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400234 netCfgService.addListener(cfgListener);
235 netCfgService.registerConfigFactory(factory);
kartikey dubeye1545422019-05-22 12:53:45 +0000236 cfgService.registerProperties(getClass());
237 modified(context);
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000238 subsService = sadisService.getSubscriberInfoService();
Deepa Vaddireddye0e10722017-09-27 05:00:10 +0530239 customInfo = new CustomizationInfo(subsService, deviceService);
Jonathan Hart092dfb22015-11-16 23:05:21 -0800240 cfgListener.reconfigureNetwork(netCfgService.getConfig(appId, AaaConfig.class));
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400241 log.info("Starting with config {} {}", this, newCfg);
Deepa Vaddireddye0e10722017-09-27 05:00:10 +0530242 configureRadiusCommunication();
Ari Saha89831742015-06-26 10:31:48 -0700243 // register our event handler
Brian O'Connord9c7da02015-07-29 17:49:24 -0700244 packetService.addProcessor(processor, PacketProcessor.director(2));
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700245 StateMachine.initializeMaps();
Jonathan Hart5db44532018-07-12 18:13:54 -0700246 StateMachine.setDelegate(delegate);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100247 impl.initializeLocalState(newCfg);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100248 impl.requestIntercepts();
Amit Ghoshf739be52017-09-21 15:49:37 +0100249 deviceService.addListener(deviceListener);
kartikey dubeye1545422019-05-22 12:53:45 +0000250 getConfiguredAaaServerAddress();
251 authenticationStatisticsPublisher =
252 new AuthenticationStatisticsEventPublisher();
253 executor = Executors.newScheduledThreadPool(1);
254 scheduledFuture = executor.scheduleAtFixedRate(authenticationStatisticsPublisher,
255 0, statisticsGenerationEvent, TimeUnit.SECONDS);
Amit Ghoshf739be52017-09-21 15:49:37 +0100256
Jian Li13c67162015-12-09 13:20:34 -0800257 log.info("Started");
Ari Saha89831742015-06-26 10:31:48 -0700258 }
259
260 @Deactivate
kartikey dubeye1545422019-05-22 12:53:45 +0000261 public void deactivate(ComponentContext context) {
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100262 impl.withdrawIntercepts();
Ari Saha89831742015-06-26 10:31:48 -0700263 packetService.removeProcessor(processor);
Deepa Vaddireddyb9c24c62017-09-21 13:45:30 +0530264 netCfgService.removeListener(cfgListener);
kartikey dubeye1545422019-05-22 12:53:45 +0000265 cfgService.unregisterProperties(getClass(), false);
Jonathan Hart5db44532018-07-12 18:13:54 -0700266 StateMachine.unsetDelegate(delegate);
Deepa Vaddireddye0e10722017-09-27 05:00:10 +0530267 StateMachine.destroyMaps();
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100268 impl.deactivate();
Amit Ghoshf739be52017-09-21 15:49:37 +0100269 deviceService.removeListener(deviceListener);
Jonathan Hart5db44532018-07-12 18:13:54 -0700270 eventDispatcher.removeSink(AuthenticationEvent.class);
kartikey dubeye1545422019-05-22 12:53:45 +0000271 scheduledFuture.cancel(true);
272 executor.shutdown();
Jian Li13c67162015-12-09 13:20:34 -0800273 log.info("Stopped");
Ray Milkey967776a2015-10-07 14:37:17 -0700274 }
275
kartikey dubeye1545422019-05-22 12:53:45 +0000276 @Modified
277 public void modified(ComponentContext context) {
278 Dictionary<?, ?> properties = context.getProperties();
279 String s = Tools.get(properties, "statisticsGenerationEvent");
280 statisticsGenerationEvent = Strings.isNullOrEmpty(s) ? DEFAULT_REPEAT_DELAY : Integer.parseInt(s.trim());
281 }
282
Deepa Vaddireddye0e10722017-09-27 05:00:10 +0530283 private void configureRadiusCommunication() {
284 if (radiusConnectionType.toLowerCase().equals("socket")) {
285 impl = new SocketBasedRadiusCommunicator(appId, packetService, this);
286 } else {
287 impl = new PortBasedRadiusCommunicator(appId, packetService, mastershipService,
288 deviceService, subsService, pktCustomizer, this);
289 }
290 }
291
292 private void configurePacketCustomizer() {
293 switch (customizer.toLowerCase()) {
294 case "sample":
295 pktCustomizer = new SamplePacketCustomizer(customInfo);
296 log.info("Created SamplePacketCustomizer");
297 break;
Saurav Dase72358a2018-11-13 21:56:46 -0800298 case "att":
299 pktCustomizer = new AttPacketCustomizer(customInfo);
300 log.info("Created AttPacketCustomizer");
301 break;
Deepa Vaddireddye0e10722017-09-27 05:00:10 +0530302 default:
303 pktCustomizer = new PacketCustomizer(customInfo);
304 log.info("Created default PacketCustomizer");
305 break;
306 }
307 }
308
kartikey dubeye1545422019-05-22 12:53:45 +0000309 private void getConfiguredAaaServerAddress() {
310 try {
311 InetAddress address;
312 if (newCfg.radiusHostName() != null) {
313 address = InetAddress.getByName(newCfg.radiusHostName());
314 } else {
315 address = newCfg.radiusIp();
316 }
317
318 configuredAaaServerAddress = address.getHostAddress();
319 } catch (UnknownHostException uhe) {
320 log.warn("Unable to resolve host {}", newCfg.radiusHostName());
321 }
322 }
323
324 private void checkReceivedPacketForValidValidator(RADIUS radiusPacket) {
325 if (!radiusPacket.checkMessageAuthenticator(radiusSecret)) {
326 aaaStatisticsManager.getAaaStats().increaseInvalidValidatorsRx();
327 }
328 }
329 public void checkForPacketFromUnknownServer(String hostAddress) {
330 if (!hostAddress.equals(configuredAaaServerAddress)) {
Vijaykumar Kushwahafffd3d12019-08-01 11:09:59 +0000331 getConfiguredAaaServerAddress();
332 if (!hostAddress.equals(configuredAaaServerAddress)) {
333 aaaStatisticsManager.getAaaStats().incrementUnknownServerRx();
334 }
kartikey dubeye1545422019-05-22 12:53:45 +0000335 }
336 }
337
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100338 /**
339 * Send RADIUS packet to the RADIUS server.
340 *
341 * @param radiusPacket RADIUS packet to be sent to server.
342 * @param inPkt Incoming EAPOL packet
343 */
344 protected void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
kartikey dubeye1545422019-05-22 12:53:45 +0000345 outPacketSet.add(radiusPacket.getIdentifier());
346 aaaStatisticsManager.getAaaStats().increaseOrDecreasePendingRequests(true);
347 aaaStatisticsManager.getAaaStats().increaseAccessRequestsTx();
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100348 impl.sendRadiusPacket(radiusPacket, inPkt);
349 }
Ray Milkey967776a2015-10-07 14:37:17 -0700350
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100351 /**
352 * Handles RADIUS packets.
353 *
354 * @param radiusPacket RADIUS packet coming from the RADIUS server.
355 * @throws StateMachineException if an illegal state transition is triggered
Jonathan Hart4731dd92018-05-02 17:30:05 -0700356 * @throws DeserializationException if packet deserialization fails
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100357 */
Jonathan Hart4731dd92018-05-02 17:30:05 -0700358 public void handleRadiusPacket(RADIUS radiusPacket)
359 throws StateMachineException, DeserializationException {
Saurav Das987441a2018-09-18 16:33:47 -0700360 if (log.isTraceEnabled()) {
361 log.trace("Received RADIUS packet {}", radiusPacket);
362 }
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100363 StateMachine stateMachine = StateMachine.lookupStateMachineById(radiusPacket.getIdentifier());
364 if (stateMachine == null) {
Saurav Das987441a2018-09-18 16:33:47 -0700365 log.error("Invalid packet identifier {}, could not find corresponding "
366 + "state machine ... exiting", radiusPacket.getIdentifier());
kartikey dubeye1545422019-05-22 12:53:45 +0000367 aaaStatisticsManager.getAaaStats().incrementNumberOfSessionsExpired();
368 aaaStatisticsManager.getAaaStats().countDroppedResponsesRx();
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100369 return;
Ray Milkey967776a2015-10-07 14:37:17 -0700370 }
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100371 EAP eapPayload;
372 Ethernet eth;
kartikey dubeye1545422019-05-22 12:53:45 +0000373 checkReceivedPacketForValidValidator(radiusPacket);
374 if (outPacketSet.contains(radiusPacket.getIdentifier())) {
375 aaaStatisticsManager.getAaaStats().increaseOrDecreasePendingRequests(false);
376 outPacketSet.remove(new Byte(radiusPacket.getIdentifier()));
377 }
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100378 switch (radiusPacket.getCode()) {
379 case RADIUS.RADIUS_CODE_ACCESS_CHALLENGE:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400380 log.debug("RADIUS packet: RADIUS_CODE_ACCESS_CHALLENGE");
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100381 RADIUSAttribute radiusAttrState = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_STATE);
382 byte[] challengeState = null;
383 if (radiusAttrState != null) {
384 challengeState = radiusAttrState.getValue();
385 }
386 eapPayload = radiusPacket.decapsulateMessage();
387 stateMachine.setChallengeInfo(eapPayload.getIdentifier(), challengeState);
388 eth = buildEapolResponse(stateMachine.supplicantAddress(),
389 MacAddress.valueOf(nasMacAddress),
390 stateMachine.vlanId(),
391 EAPOL.EAPOL_PACKET,
392 eapPayload, stateMachine.priorityCode());
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400393 log.debug("Send EAP challenge response to supplicant {}", stateMachine.supplicantAddress().toString());
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100394 sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
kartikey dubeye1545422019-05-22 12:53:45 +0000395 aaaStatisticsManager.getAaaStats().increaseChallengeResponsesRx();
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100396 break;
397 case RADIUS.RADIUS_CODE_ACCESS_ACCEPT:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400398 log.debug("RADIUS packet: RADIUS_CODE_ACCESS_ACCEPT");
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100399 //send an EAPOL - Success to the supplicant.
400 byte[] eapMessageSuccess =
401 radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE).getValue();
Jonathan Hart4731dd92018-05-02 17:30:05 -0700402 eapPayload = EAP.deserializer().deserialize(
403 eapMessageSuccess, 0, eapMessageSuccess.length);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100404 eth = buildEapolResponse(stateMachine.supplicantAddress(),
405 MacAddress.valueOf(nasMacAddress),
406 stateMachine.vlanId(),
407 EAPOL.EAPOL_PACKET,
408 eapPayload, stateMachine.priorityCode());
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400409 log.info("Send EAP success message to supplicant {}", stateMachine.supplicantAddress().toString());
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100410 sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
411
412 stateMachine.authorizeAccess();
kartikey dubeye1545422019-05-22 12:53:45 +0000413 aaaStatisticsManager.getAaaStats().increaseAcceptResponsesRx();
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100414 break;
415 case RADIUS.RADIUS_CODE_ACCESS_REJECT:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400416 log.debug("RADIUS packet: RADIUS_CODE_ACCESS_REJECT");
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100417 //send an EAPOL - Failure to the supplicant.
418 byte[] eapMessageFailure;
419 eapPayload = new EAP();
420 RADIUSAttribute radiusAttrEap = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE);
421 if (radiusAttrEap == null) {
422 eapPayload.setCode(EAP.FAILURE);
423 eapPayload.setIdentifier(stateMachine.challengeIdentifier());
424 eapPayload.setLength(EAP.EAP_HDR_LEN_SUC_FAIL);
425 } else {
426 eapMessageFailure = radiusAttrEap.getValue();
Jonathan Hart4731dd92018-05-02 17:30:05 -0700427 eapPayload = EAP.deserializer().deserialize(
428 eapMessageFailure, 0, eapMessageFailure.length);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100429 }
430 eth = buildEapolResponse(stateMachine.supplicantAddress(),
431 MacAddress.valueOf(nasMacAddress),
432 stateMachine.vlanId(),
433 EAPOL.EAPOL_PACKET,
434 eapPayload, stateMachine.priorityCode());
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400435 log.warn("Send EAP failure message to supplicant {}", stateMachine.supplicantAddress().toString());
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100436 sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
437 stateMachine.denyAccess();
kartikey dubeye1545422019-05-22 12:53:45 +0000438 aaaStatisticsManager.getAaaStats().increaseRejectResponsesRx();
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100439 break;
440 default:
441 log.warn("Unknown RADIUS message received with code: {}", radiusPacket.getCode());
kartikey dubeye1545422019-05-22 12:53:45 +0000442 aaaStatisticsManager.getAaaStats().increaseUnknownTypeRx();
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100443 }
kartikey dubeye1545422019-05-22 12:53:45 +0000444 aaaStatisticsManager.getAaaStats().countDroppedResponsesRx();
Aaron Kruglikovd39d99e2015-07-03 13:30:57 -0700445 }
446
Ray Milkey967776a2015-10-07 14:37:17 -0700447 /**
448 * Send the ethernet packet to the supplicant.
449 *
450 * @param ethernetPkt the ethernet packet
451 * @param connectPoint the connect point to send out
452 */
453 private void sendPacketToSupplicant(Ethernet ethernetPkt, ConnectPoint connectPoint) {
454 TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(connectPoint.port()).build();
455 OutboundPacket packet = new DefaultOutboundPacket(connectPoint.deviceId(),
456 treatment, ByteBuffer.wrap(ethernetPkt.serialize()));
Saurav Das987441a2018-09-18 16:33:47 -0700457 if (log.isTraceEnabled()) {
458 EAPOL eap = ((EAPOL) ethernetPkt.getPayload());
459 log.trace("Sending eapol payload {} enclosed in {} to supplicant at {}",
460 eap, ethernetPkt, connectPoint);
461 }
Ray Milkey967776a2015-10-07 14:37:17 -0700462 packetService.emit(packet);
463 }
464
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400465 @Override
466 public String toString() {
467 return ToStringBuilder.reflectionToString(this);
468 }
469
Ari Saha89831742015-06-26 10:31:48 -0700470 // our handler defined as a private inner class
471
472 /**
473 * Packet processor responsible for forwarding packets along their paths.
474 */
475 private class ReactivePacketProcessor implements PacketProcessor {
476 @Override
477 public void process(PacketContext context) {
478
479 // Extract the original Ethernet frame from the packet information
480 InboundPacket pkt = context.inPacket();
481 Ethernet ethPkt = pkt.parsed();
482 if (ethPkt == null) {
483 return;
484 }
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100485
Ray Milkeyf51eba22015-09-25 10:24:23 -0700486 try {
487 // identify if incoming packet comes from supplicant (EAP) or RADIUS
488 switch (EthType.EtherType.lookup(ethPkt.getEtherType())) {
489 case EAPOL:
490 handleSupplicantPacket(context.inPacket());
491 break;
Ray Milkeyf51eba22015-09-25 10:24:23 -0700492 default:
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100493 // any other packets let the specific implementation handle
494 impl.handlePacketFromServer(context);
Ray Milkeyf51eba22015-09-25 10:24:23 -0700495 }
Ray Milkey967776a2015-10-07 14:37:17 -0700496 } catch (StateMachineException e) {
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100497 log.warn("Unable to process packet:", e);
Ari Saha89831742015-06-26 10:31:48 -0700498 }
499 }
500
Ray Milkey9eb293f2015-09-30 15:09:17 -0700501 /**
502 * Creates and initializes common fields of a RADIUS packet.
503 *
Ray Milkey967776a2015-10-07 14:37:17 -0700504 * @param stateMachine state machine for the request
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700505 * @param eapPacket EAP packet
Ray Milkey9eb293f2015-09-30 15:09:17 -0700506 * @return RADIUS packet
507 */
Ray Milkey967776a2015-10-07 14:37:17 -0700508 private RADIUS getRadiusPayload(StateMachine stateMachine, byte identifier, EAP eapPacket) {
Ray Milkey9eb293f2015-09-30 15:09:17 -0700509 RADIUS radiusPayload =
510 new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST,
511 eapPacket.getIdentifier());
Ray Milkey967776a2015-10-07 14:37:17 -0700512
513 // set Request Authenticator in StateMachine
514 stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
515
Ray Milkey9eb293f2015-09-30 15:09:17 -0700516 radiusPayload.setIdentifier(identifier);
517 radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME,
Ray Milkey967776a2015-10-07 14:37:17 -0700518 stateMachine.username());
Ray Milkey9eb293f2015-09-30 15:09:17 -0700519
520 radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP,
Jonathan Hart092dfb22015-11-16 23:05:21 -0800521 AaaManager.this.nasIpAddress.getAddress());
Ray Milkey9eb293f2015-09-30 15:09:17 -0700522
523 radiusPayload.encapsulateMessage(eapPacket);
Ray Milkey9eb293f2015-09-30 15:09:17 -0700524
525 return radiusPayload;
526 }
Ari Saha89831742015-06-26 10:31:48 -0700527
528 /**
Jonathan Harta46dddf2015-06-30 15:31:20 -0700529 * Handles PAE packets (supplicant).
530 *
531 * @param inPacket Ethernet packet coming from the supplicant
Ari Saha89831742015-06-26 10:31:48 -0700532 */
Ray Milkeyf51eba22015-09-25 10:24:23 -0700533 private void handleSupplicantPacket(InboundPacket inPacket) throws StateMachineException {
Jonathan Harta46dddf2015-06-30 15:31:20 -0700534 Ethernet ethPkt = inPacket.parsed();
Ari Saha89831742015-06-26 10:31:48 -0700535 // Where does it come from?
Jonathan Hart092dfb22015-11-16 23:05:21 -0800536 MacAddress srcMac = ethPkt.getSourceMAC();
Ari Saha89831742015-06-26 10:31:48 -0700537
Jonathan Harta46dddf2015-06-30 15:31:20 -0700538 DeviceId deviceId = inPacket.receivedFrom().deviceId();
539 PortNumber portNumber = inPacket.receivedFrom().port();
Ari Saha89831742015-06-26 10:31:48 -0700540 String sessionId = deviceId.toString() + portNumber.toString();
Saurav Das987441a2018-09-18 16:33:47 -0700541 EAPOL eapol = (EAPOL) ethPkt.getPayload();
542 if (log.isTraceEnabled()) {
543 log.trace("Received EAPOL packet {} in enclosing packet {} from "
544 + "dev/port: {}/{}", eapol, ethPkt, deviceId,
545 portNumber);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100546 }
Jonathan Harta46dddf2015-06-30 15:31:20 -0700547
Saurav Das987441a2018-09-18 16:33:47 -0700548 StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(sessionId);
549 if (stateMachine == null) {
550 log.debug("Creating new state machine for sessionId: {} for "
551 + "dev/port: {}/{}", sessionId, deviceId, portNumber);
552 stateMachine = new StateMachine(sessionId);
553 } else {
554 log.debug("Using existing state-machine for sessionId: {}", sessionId);
555 }
556
Ari Saha89831742015-06-26 10:31:48 -0700557 switch (eapol.getEapolType()) {
558 case EAPOL.EAPOL_START:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400559 log.debug("EAP packet: EAPOL_START");
Ray Milkeyf51eba22015-09-25 10:24:23 -0700560 stateMachine.setSupplicantConnectpoint(inPacket.receivedFrom());
Jonathan Hart5db44532018-07-12 18:13:54 -0700561 stateMachine.start();
Ari Saha89831742015-06-26 10:31:48 -0700562
Ray Milkeyf51eba22015-09-25 10:24:23 -0700563 //send an EAP Request/Identify to the supplicant
564 EAP eapPayload = new EAP(EAP.REQUEST, stateMachine.identifier(), EAP.ATTR_IDENTITY, null);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100565 if (ethPkt.getVlanID() != Ethernet.VLAN_UNTAGGED) {
566 stateMachine.setPriorityCode(ethPkt.getPriorityCode());
567 }
Jonathan Hart092dfb22015-11-16 23:05:21 -0800568 Ethernet eth = buildEapolResponse(srcMac, MacAddress.valueOf(nasMacAddress),
Ray Milkeyf51eba22015-09-25 10:24:23 -0700569 ethPkt.getVlanID(), EAPOL.EAPOL_PACKET,
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100570 eapPayload, stateMachine.priorityCode());
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400571
Jonathan Hart092dfb22015-11-16 23:05:21 -0800572 stateMachine.setSupplicantAddress(srcMac);
Ray Milkeyf51eba22015-09-25 10:24:23 -0700573 stateMachine.setVlanId(ethPkt.getVlanID());
Ari Saha89831742015-06-26 10:31:48 -0700574
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400575 log.debug("Getting EAP identity from supplicant {}", stateMachine.supplicantAddress().toString());
Ray Milkey967776a2015-10-07 14:37:17 -0700576 sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
Ari Saha89831742015-06-26 10:31:48 -0700577
578 break;
Qianqian Hub55a1ac2015-12-23 20:44:48 +0800579 case EAPOL.EAPOL_LOGOFF:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400580 log.debug("EAP packet: EAPOL_LOGOFF");
Ray Milkeyb34b4962016-01-04 10:24:43 -0800581 if (stateMachine.state() == StateMachine.STATE_AUTHORIZED) {
582 stateMachine.logoff();
Qianqian Hub55a1ac2015-12-23 20:44:48 +0800583 }
584
585 break;
Ari Saha89831742015-06-26 10:31:48 -0700586 case EAPOL.EAPOL_PACKET:
Ray Milkeyf51eba22015-09-25 10:24:23 -0700587 RADIUS radiusPayload;
Ray Milkey9eb293f2015-09-30 15:09:17 -0700588 // check if this is a Response/Identify or a Response/TLS
Ari Saha89831742015-06-26 10:31:48 -0700589 EAP eapPacket = (EAP) eapol.getPayload();
590
591 byte dataType = eapPacket.getDataType();
592 switch (dataType) {
Ari Saha89831742015-06-26 10:31:48 -0700593
Ray Milkey9eb293f2015-09-30 15:09:17 -0700594 case EAP.ATTR_IDENTITY:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400595 log.debug("EAP packet: EAPOL_PACKET ATTR_IDENTITY");
Ray Milkey9eb293f2015-09-30 15:09:17 -0700596 // request id access to RADIUS
597 stateMachine.setUsername(eapPacket.getData());
Ari Saha89831742015-06-26 10:31:48 -0700598
Ray Milkey967776a2015-10-07 14:37:17 -0700599 radiusPayload = getRadiusPayload(stateMachine, stateMachine.identifier(), eapPacket);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100600 radiusPayload = pktCustomizer.customizePacket(radiusPayload, inPacket);
Jonathan Hart092dfb22015-11-16 23:05:21 -0800601 radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret);
Ari Saha89831742015-06-26 10:31:48 -0700602
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100603 sendRadiusPacket(radiusPayload, inPacket);
Ray Milkeyf51eba22015-09-25 10:24:23 -0700604
Ray Milkey9eb293f2015-09-30 15:09:17 -0700605 // change the state to "PENDING"
kartikey dubeye1545422019-05-22 12:53:45 +0000606 if (stateMachine.state() == StateMachine.STATE_PENDING) {
607 aaaStatisticsManager.getAaaStats().increaseRequestReTx();
608 }
Ray Milkey9eb293f2015-09-30 15:09:17 -0700609 stateMachine.requestAccess();
610 break;
Ari Saha89831742015-06-26 10:31:48 -0700611 case EAP.ATTR_MD5:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400612 log.debug("EAP packet: EAPOL_PACKET ATTR_MD5");
Ray Milkey9eb293f2015-09-30 15:09:17 -0700613 // verify if the EAP identifier corresponds to the
614 // challenge identifier from the client state
615 // machine.
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700616 if (eapPacket.getIdentifier() == stateMachine.challengeIdentifier()) {
Ari Saha89831742015-06-26 10:31:48 -0700617 //send the RADIUS challenge response
Ray Milkey967776a2015-10-07 14:37:17 -0700618 radiusPayload =
619 getRadiusPayload(stateMachine,
620 stateMachine.identifier(),
621 eapPacket);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100622 radiusPayload = pktCustomizer.customizePacket(radiusPayload, inPacket);
Ari Saha89831742015-06-26 10:31:48 -0700623
Qianqian Hub55a1ac2015-12-23 20:44:48 +0800624 if (stateMachine.challengeState() != null) {
625 radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
626 stateMachine.challengeState());
627 }
Jonathan Hart092dfb22015-11-16 23:05:21 -0800628 radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100629 sendRadiusPacket(radiusPayload, inPacket);
Ari Saha89831742015-06-26 10:31:48 -0700630 }
631 break;
632 case EAP.ATTR_TLS:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400633 log.debug("EAP packet: EAPOL_PACKET ATTR_TLS");
Ray Milkey9eb293f2015-09-30 15:09:17 -0700634 // request id access to RADIUS
Ray Milkey967776a2015-10-07 14:37:17 -0700635 radiusPayload = getRadiusPayload(stateMachine, stateMachine.identifier(), eapPacket);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100636 radiusPayload = pktCustomizer.customizePacket(radiusPayload, inPacket);
Ari Saha89831742015-06-26 10:31:48 -0700637
Qianqian Hub55a1ac2015-12-23 20:44:48 +0800638 if (stateMachine.challengeState() != null) {
639 radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
640 stateMachine.challengeState());
641 }
Ray Milkeyf51eba22015-09-25 10:24:23 -0700642 stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
Ari Saha89831742015-06-26 10:31:48 -0700643
Jonathan Hart092dfb22015-11-16 23:05:21 -0800644 radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100645 sendRadiusPacket(radiusPayload, inPacket);
Ray Milkey5493b512015-10-21 12:13:49 -0700646
Ray Milkeyf3790b82015-10-21 16:28:08 -0700647 if (stateMachine.state() != StateMachine.STATE_PENDING) {
648 stateMachine.requestAccess();
649 }
Ray Milkeyf51eba22015-09-25 10:24:23 -0700650
Ari Saha89831742015-06-26 10:31:48 -0700651 break;
652 default:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400653 log.warn("Unknown EAP packet type");
Ari Saha89831742015-06-26 10:31:48 -0700654 return;
655 }
656 break;
657 default:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400658 log.debug("Skipping EAPOL message {}", eapol.getEapolType());
Ari Saha89831742015-06-26 10:31:48 -0700659 }
660 }
Ray Milkey967776a2015-10-07 14:37:17 -0700661 }
662
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100663 /**
Jonathan Hart5db44532018-07-12 18:13:54 -0700664 * Delegate allowing the StateMachine to notify us of events.
665 */
666 private class InternalStateMachineDelegate implements StateMachineDelegate {
667
668 @Override
669 public void notify(AuthenticationEvent authenticationEvent) {
670 log.info("Auth event {} for {}",
671 authenticationEvent.type(), authenticationEvent.subject());
672 post(authenticationEvent);
673 }
674 }
675
676 /**
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100677 * Configuration Listener, handles change in configuration.
678 */
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700679 private class InternalConfigListener implements NetworkConfigListener {
680
681 /**
Ray Milkeyc9e8dcc2015-12-30 10:31:32 -0800682 * Reconfigures the AAA application according to the
683 * configuration parameters passed.
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700684 *
685 * @param cfg configuration object
686 */
Jonathan Hart092dfb22015-11-16 23:05:21 -0800687 private void reconfigureNetwork(AaaConfig cfg) {
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400688 log.info("Reconfiguring AaaConfig from config: {}", cfg);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100689
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700690 if (cfg == null) {
Jonathan Hart092dfb22015-11-16 23:05:21 -0800691 newCfg = new AaaConfig();
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700692 } else {
693 newCfg = cfg;
694 }
695 if (newCfg.nasIp() != null) {
696 nasIpAddress = newCfg.nasIp();
697 }
698 if (newCfg.radiusIp() != null) {
699 radiusIpAddress = newCfg.radiusIp();
700 }
701 if (newCfg.radiusMac() != null) {
702 radiusMacAddress = newCfg.radiusMac();
703 }
704 if (newCfg.nasMac() != null) {
705 nasMacAddress = newCfg.nasMac();
706 }
707 if (newCfg.radiusSecret() != null) {
708 radiusSecret = newCfg.radiusSecret();
709 }
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100710
Deepa Vaddireddye0e10722017-09-27 05:00:10 +0530711 boolean reconfigureCustomizer = false;
712 if (customizer == null || !customizer.equals(newCfg.radiusPktCustomizer())) {
713 customizer = newCfg.radiusPktCustomizer();
714 configurePacketCustomizer();
715 reconfigureCustomizer = true;
716 }
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100717
Deepa Vaddireddye0e10722017-09-27 05:00:10 +0530718 if (radiusConnectionType == null
719 || reconfigureCustomizer
720 || !radiusConnectionType.equals(newCfg.radiusConnectionType())) {
721 radiusConnectionType = newCfg.radiusConnectionType();
722 if (impl != null) {
723 impl.withdrawIntercepts();
724 impl.clearLocalState();
725 }
726 configureRadiusCommunication();
727 impl.initializeLocalState(newCfg);
728 impl.requestIntercepts();
729 } else if (impl != null) {
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100730 impl.clearLocalState();
731 impl.initializeLocalState(newCfg);
Ray Milkey5d99bd12015-10-06 15:41:30 -0700732 }
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700733 }
734
735 @Override
736 public void event(NetworkConfigEvent event) {
737
738 if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
739 event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
Jonathan Hart092dfb22015-11-16 23:05:21 -0800740 event.configClass().equals(AaaConfig.class)) {
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700741
Jonathan Hart092dfb22015-11-16 23:05:21 -0800742 AaaConfig cfg = netCfgService.getConfig(appId, AaaConfig.class);
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700743 reconfigureNetwork(cfg);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100744
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400745 log.info("Reconfigured: {}", cfg.toString());
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700746 }
747 }
748 }
Amit Ghoshf739be52017-09-21 15:49:37 +0100749
750 private class InternalDeviceListener implements DeviceListener {
751 @Override
752 public void event(DeviceEvent event) {
753
754 switch (event.type()) {
755 case PORT_REMOVED:
756 DeviceId devId = event.subject().id();
757 PortNumber portNumber = event.port().number();
758 String sessionId = devId.toString() + portNumber.toString();
759
760 Map<String, StateMachine> sessionIdMap = StateMachine.sessionIdMap();
761 StateMachine removed = sessionIdMap.remove(sessionId);
762 if (removed != null) {
763 StateMachine.deleteStateMachineMapping(removed);
764 }
765
766 break;
767 default:
768 return;
769 }
770 }
771 }
kartikey dubeye1545422019-05-22 12:53:45 +0000772 private class AuthenticationStatisticsEventPublisher implements Runnable {
773 private final Logger log = getLogger(getClass());
774 public void run() {
775 log.info("Notifying AuthenticationStatisticsEvent");
776 aaaStatisticsManager.calculatePacketRoundtripTime();
777 log.debug("AcceptResponsesRx---" + aaaStatisticsManager.getAaaStats().getAcceptResponsesRx());
778 log.debug("AccessRequestsTx---" + aaaStatisticsManager.getAaaStats().getAccessRequestsTx());
779 log.debug("ChallengeResponsesRx---" + aaaStatisticsManager.getAaaStats().getChallengeResponsesRx());
780 log.debug("DroppedResponsesRx---" + aaaStatisticsManager.getAaaStats().getDroppedResponsesRx());
781 log.debug("InvalidValidatorsRx---" + aaaStatisticsManager.getAaaStats().getInvalidValidatorsRx());
782 log.debug("MalformedResponsesRx---" + aaaStatisticsManager.getAaaStats().getMalformedResponsesRx());
783 log.debug("PendingRequests---" + aaaStatisticsManager.getAaaStats().getPendingRequests());
784 log.debug("RejectResponsesRx---" + aaaStatisticsManager.getAaaStats().getRejectResponsesRx());
785 log.debug("RequestReTx---" + aaaStatisticsManager.getAaaStats().getRequestReTx());
786 log.debug("RequestRttMilis---" + aaaStatisticsManager.getAaaStats().getRequestRttMilis());
787 log.debug("UnknownServerRx---" + aaaStatisticsManager.getAaaStats().getUnknownServerRx());
788 log.debug("UnknownTypeRx---" + aaaStatisticsManager.getAaaStats().getUnknownTypeRx());
789 aaaStatisticsManager.getStatsDelegate().
790 notify(new AuthenticationStatisticsEvent(AuthenticationStatisticsEvent.Type.STATS_UPDATE,
791 aaaStatisticsManager.getAaaStats()));
792 }
793 }
Ari Saha89831742015-06-26 10:31:48 -0700794}