blob: d04d0a76904649968e1ef93af7fb322ec188881a [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
Shubham Sharma4900ce62019-06-19 14:18:50 +000018import com.google.common.base.Strings;
Jonathan Hart612651f2019-11-25 09:21:43 -080019import com.google.common.collect.Maps;
Jonathan Hart932bedc2018-07-12 13:46:09 -070020import org.apache.commons.lang3.builder.ToStringBuilder;
Jonathan Hart4731dd92018-05-02 17:30:05 -070021import org.onlab.packet.DeserializationException;
Jonathan Harta46dddf2015-06-30 15:31:20 -070022import org.onlab.packet.EAP;
23import org.onlab.packet.EAPOL;
24import org.onlab.packet.EthType;
Ari Saha89831742015-06-26 10:31:48 -070025import org.onlab.packet.Ethernet;
Ari Saha89831742015-06-26 10:31:48 -070026import org.onlab.packet.MacAddress;
Jonathan Harta46dddf2015-06-30 15:31:20 -070027import org.onlab.packet.RADIUS;
28import org.onlab.packet.RADIUSAttribute;
Jonathan Hart9d1ce802020-01-28 10:45:08 -080029import org.onlab.util.KryoNamespace;
kartikey dubeye1545422019-05-22 12:53:45 +000030import org.onlab.util.Tools;
31import org.onosproject.cfg.ComponentConfigService;
Ari Saha89831742015-06-26 10:31:48 -070032import org.onosproject.core.ApplicationId;
33import org.onosproject.core.CoreService;
Jonathan Hart5db44532018-07-12 18:13:54 -070034import org.onosproject.event.AbstractListenerManager;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010035import org.onosproject.mastership.MastershipService;
Ari Saha89831742015-06-26 10:31:48 -070036import org.onosproject.net.ConnectPoint;
37import org.onosproject.net.DeviceId;
Jonathan Hart9d1ce802020-01-28 10:45:08 -080038import org.onosproject.net.ElementId;
Ari Saha89831742015-06-26 10:31:48 -070039import org.onosproject.net.PortNumber;
Ray Milkeyfcb623d2015-10-01 16:48:18 -070040import org.onosproject.net.config.ConfigFactory;
41import org.onosproject.net.config.NetworkConfigEvent;
42import org.onosproject.net.config.NetworkConfigListener;
43import org.onosproject.net.config.NetworkConfigRegistry;
Amit Ghoshf739be52017-09-21 15:49:37 +010044import org.onosproject.net.device.DeviceEvent;
45import org.onosproject.net.device.DeviceListener;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010046import org.onosproject.net.device.DeviceService;
Ari Saha89831742015-06-26 10:31:48 -070047import org.onosproject.net.flow.DefaultTrafficTreatment;
Ari Saha89831742015-06-26 10:31:48 -070048import org.onosproject.net.flow.TrafficTreatment;
Ari Saha89831742015-06-26 10:31:48 -070049import org.onosproject.net.packet.DefaultOutboundPacket;
50import org.onosproject.net.packet.InboundPacket;
51import org.onosproject.net.packet.OutboundPacket;
52import org.onosproject.net.packet.PacketContext;
Ari Saha89831742015-06-26 10:31:48 -070053import org.onosproject.net.packet.PacketProcessor;
54import org.onosproject.net.packet.PacketService;
Jonathan Hart9d1ce802020-01-28 10:45:08 -080055import org.onosproject.store.service.ConsistentMap;
56import org.onosproject.store.service.MapEvent;
57import org.onosproject.store.service.MapEventListener;
58import org.onosproject.store.service.Serializer;
59import org.onosproject.store.service.StorageService;
60import org.onosproject.store.service.Versioned;
Matteo Scandolocf847b82019-04-26 15:00:00 -070061import org.opencord.aaa.AaaConfig;
Kartikey Dubeyadeb26e2019-10-01 12:18:35 +000062import org.opencord.aaa.AaaMachineStatisticsEvent;
63import org.opencord.aaa.AaaMachineStatisticsService;
64import org.opencord.aaa.AaaSupplicantMachineStats;
Matteo Scandolocf847b82019-04-26 15:00:00 -070065import org.opencord.aaa.AuthenticationEvent;
66import org.opencord.aaa.AuthenticationEventListener;
Jonathan Hart612651f2019-11-25 09:21:43 -080067import org.opencord.aaa.AuthenticationRecord;
Matteo Scandolocf847b82019-04-26 15:00:00 -070068import org.opencord.aaa.AuthenticationService;
kartikey dubeye1545422019-05-22 12:53:45 +000069import org.opencord.aaa.AuthenticationStatisticsEvent;
70import org.opencord.aaa.AuthenticationStatisticsService;
Matteo Scandolocf847b82019-04-26 15:00:00 -070071import org.opencord.aaa.RadiusCommunicator;
Shubham Sharma4900ce62019-06-19 14:18:50 +000072import org.opencord.aaa.RadiusOperationalStatusEvent;
73import org.opencord.aaa.RadiusOperationalStatusService;
74import org.opencord.aaa.RadiusOperationalStatusService.RadiusOperationalStatusEvaluationMode;
Matteo Scandolocf847b82019-04-26 15:00:00 -070075import org.opencord.aaa.StateMachineDelegate;
Gamze Abaka1cfdb192018-10-25 11:39:19 +000076import org.opencord.sadis.BaseInformationService;
77import org.opencord.sadis.SadisService;
78import org.opencord.sadis.SubscriberAndDeviceInformation;
kartikey dubeye1545422019-05-22 12:53:45 +000079import org.osgi.service.component.ComponentContext;
Carmelo Cascone58b53292019-09-30 12:35:31 -070080import org.osgi.service.component.annotations.Activate;
Shubham Sharma4900ce62019-06-19 14:18:50 +000081import org.osgi.service.component.annotations.Component;
82import org.osgi.service.component.annotations.Deactivate;
83import org.osgi.service.component.annotations.Modified;
84import org.osgi.service.component.annotations.Reference;
85import org.osgi.service.component.annotations.ReferenceCardinality;
Ari Saha89831742015-06-26 10:31:48 -070086import org.slf4j.Logger;
87
Shubham Sharma4900ce62019-06-19 14:18:50 +000088import javax.crypto.Mac;
89import javax.crypto.spec.SecretKeySpec;
90import java.net.InetAddress;
Jonathan Hart9d1ce802020-01-28 10:45:08 -080091import java.net.URI;
Shubham Sharma4900ce62019-06-19 14:18:50 +000092import java.net.UnknownHostException;
93import java.nio.ByteBuffer;
94import java.util.Arrays;
95import java.util.Dictionary;
96import java.util.HashSet;
97import java.util.List;
Jonathan Hart9d1ce802020-01-28 10:45:08 -080098import java.util.Optional;
Jonathan Hart612651f2019-11-25 09:21:43 -080099import java.util.concurrent.ConcurrentMap;
kartikey dubeye1545422019-05-22 12:53:45 +0000100import java.util.concurrent.Executors;
101import java.util.concurrent.ScheduledExecutorService;
102import java.util.concurrent.ScheduledFuture;
103import java.util.concurrent.TimeUnit;
Vijaykumar Kushwaha056e4cd2019-08-06 13:16:25 +0000104
Shubham Sharma4900ce62019-06-19 14:18:50 +0000105import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
106import static org.opencord.aaa.impl.OsgiPropertyConstants.OPERATIONAL_STATUS_SERVER_EVENT_GENERATION;
107import static org.opencord.aaa.impl.OsgiPropertyConstants.OPERATIONAL_STATUS_SERVER_EVENT_GENERATION_DEFAULT;
108import static org.opencord.aaa.impl.OsgiPropertyConstants.OPERATIONAL_STATUS_SERVER_TIMEOUT;
109import static org.opencord.aaa.impl.OsgiPropertyConstants.OPERATIONAL_STATUS_SERVER_TIMEOUT_DEFAULT;
110import static org.opencord.aaa.impl.OsgiPropertyConstants.STATISTICS_GENERATION_PERIOD;
111import static org.opencord.aaa.impl.OsgiPropertyConstants.STATISTICS_GENERATION_PERIOD_DEFAULT;
112import static org.opencord.aaa.impl.OsgiPropertyConstants.STATUS_SERVER_MODE;
113import static org.opencord.aaa.impl.OsgiPropertyConstants.STATUS_SERVER_MODE_DEFAULT;
114import static org.slf4j.LoggerFactory.getLogger;
Carmelo Cascone58b53292019-09-30 12:35:31 -0700115
Ari Saha89831742015-06-26 10:31:48 -0700116/**
Jonathan Harta46dddf2015-06-30 15:31:20 -0700117 * AAA application for ONOS.
Ari Saha89831742015-06-26 10:31:48 -0700118 */
Carmelo Cascone58b53292019-09-30 12:35:31 -0700119@Component(immediate = true, property = {
Shubham Sharma4900ce62019-06-19 14:18:50 +0000120 STATISTICS_GENERATION_PERIOD + ":Integer=" + STATISTICS_GENERATION_PERIOD_DEFAULT,
121 OPERATIONAL_STATUS_SERVER_EVENT_GENERATION + ":Integer=" + OPERATIONAL_STATUS_SERVER_EVENT_GENERATION_DEFAULT,
122 OPERATIONAL_STATUS_SERVER_TIMEOUT + ":Integer=" + OPERATIONAL_STATUS_SERVER_TIMEOUT_DEFAULT,
123 STATUS_SERVER_MODE + ":String=" + STATUS_SERVER_MODE_DEFAULT,
Carmelo Cascone58b53292019-09-30 12:35:31 -0700124})
Jonathan Hart5db44532018-07-12 18:13:54 -0700125public class AaaManager
126 extends AbstractListenerManager<AuthenticationEvent, AuthenticationEventListener>
127 implements AuthenticationService {
128
Charles Chandf7ff862017-01-20 11:22:05 -0800129 private static final String APP_NAME = "org.opencord.aaa";
Ray Milkeyf51eba22015-09-25 10:24:23 -0700130
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700131 private final Logger log = getLogger(getClass());
Ray Milkeyf51eba22015-09-25 10:24:23 -0700132
Carmelo Cascone58b53292019-09-30 12:35:31 -0700133 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700134 protected CoreService coreService;
Ray Milkeyf51eba22015-09-25 10:24:23 -0700135
Carmelo Cascone58b53292019-09-30 12:35:31 -0700136 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800137 protected StorageService storageService;
138
139 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700140 protected PacketService packetService;
Ray Milkeyf51eba22015-09-25 10:24:23 -0700141
Carmelo Cascone58b53292019-09-30 12:35:31 -0700142 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700143 protected NetworkConfigRegistry netCfgService;
Ray Milkeyf51eba22015-09-25 10:24:23 -0700144
Carmelo Cascone58b53292019-09-30 12:35:31 -0700145 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100146 protected DeviceService deviceService;
147
Carmelo Cascone58b53292019-09-30 12:35:31 -0700148 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000149 protected SadisService sadisService;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100150
Carmelo Cascone58b53292019-09-30 12:35:31 -0700151 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100152 protected MastershipService mastershipService;
153
Carmelo Cascone58b53292019-09-30 12:35:31 -0700154 @Reference(cardinality = ReferenceCardinality.MANDATORY)
kartikey dubeye1545422019-05-22 12:53:45 +0000155 protected AuthenticationStatisticsService aaaStatisticsManager;
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000156
Carmelo Cascone58b53292019-09-30 12:35:31 -0700157 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Kartikey Dubeyadeb26e2019-10-01 12:18:35 +0000158 protected AaaMachineStatisticsService aaaSupplicantStatsManager;
159
160 @Reference(cardinality = ReferenceCardinality.MANDATORY)
kartikey dubeye1545422019-05-22 12:53:45 +0000161 protected ComponentConfigService cfgService;
162
Shubham Sharma4900ce62019-06-19 14:18:50 +0000163 @Reference(cardinality = ReferenceCardinality.MANDATORY)
164 protected RadiusOperationalStatusService radiusOperationalStatusService;
165
kartikey dubeye1545422019-05-22 12:53:45 +0000166 protected AuthenticationStatisticsEventPublisher authenticationStatisticsPublisher;
167 protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
Amit Ghoshf739be52017-09-21 15:49:37 +0100168 private final DeviceListener deviceListener = new InternalDeviceListener();
169
Shubham Sharma4900ce62019-06-19 14:18:50 +0000170 // Properties
171 private int statisticsGenerationPeriodInSeconds = STATISTICS_GENERATION_PERIOD_DEFAULT;
172 private int operationalStatusEventGenerationPeriodInSeconds = OPERATIONAL_STATUS_SERVER_EVENT_GENERATION_DEFAULT;
173 private int operationalStatusServerTimeoutInSeconds = OPERATIONAL_STATUS_SERVER_TIMEOUT_DEFAULT;
174 protected String operationalStatusEvaluationMode = STATUS_SERVER_MODE_DEFAULT;
kartikey dubeye1545422019-05-22 12:53:45 +0000175
Jonathan Hart612651f2019-11-25 09:21:43 -0800176 private IdentifierManager idManager;
177
178 private ConcurrentMap<String, StateMachine> stateMachines;
179
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800180 private ConsistentMap<ConnectPoint, AuthenticationRecord> authentications;
181
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700182 // NAS IP address
183 protected InetAddress nasIpAddress;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100184
185 // self MAC address
Jonathan Hart5db44532018-07-12 18:13:54 -0700186 protected String nasMacAddress;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100187
188 // Parsed RADIUS server addresses
189 protected InetAddress radiusIpAddress;
190
191 // MAC address of RADIUS server or net hop router
192 protected String radiusMacAddress;
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700193
194 // RADIUS server secret
195 protected String radiusSecret;
196
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100197 // bindings
198 protected CustomizationInfo customInfo;
Ray Milkey5d99bd12015-10-06 15:41:30 -0700199
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700200 // our application-specific event handler
201 private ReactivePacketProcessor processor = new ReactivePacketProcessor();
Ray Milkeyf51eba22015-09-25 10:24:23 -0700202
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700203 // our unique identifier
204 private ApplicationId appId;
Ray Milkeyf51eba22015-09-25 10:24:23 -0700205
Shubham Sharma1e43c562019-06-19 14:18:12 +0000206 // TimeOut time for cleaning up stateMachines stuck due to pending AAA/EAPOL message.
207 protected int cleanupTimerTimeOutInMins;
208
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100209 // Setup specific customization/attributes on the RADIUS packets
210 PacketCustomizer pktCustomizer;
Ray Milkey967776a2015-10-07 14:37:17 -0700211
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100212 // packet customizer to use
213 private String customizer;
214
215 // Type of connection to use to communicate with Radius server, options are
216 // "socket" or "packet_out"
217 private String radiusConnectionType;
218
Jonathan Hart5db44532018-07-12 18:13:54 -0700219 // Object for the specific type of communication with the RADIUS
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100220 // server, socket based or packet_out based
221 RadiusCommunicator impl = null;
222
223 // latest configuration
224 AaaConfig newCfg;
Ray Milkey967776a2015-10-07 14:37:17 -0700225
kartikey dubeye1545422019-05-22 12:53:45 +0000226 ScheduledFuture<?> scheduledFuture;
Shubham Sharma4900ce62019-06-19 14:18:50 +0000227 ScheduledFuture<?> scheduledStatusServerChecker;
kartikey dubeye1545422019-05-22 12:53:45 +0000228 ScheduledExecutorService executor;
229 String configuredAaaServerAddress;
230 HashSet<Byte> outPacketSet = new HashSet<Byte>();
Shubham Sharma3c8c7022019-09-13 10:39:47 +0000231 HashSet<Byte> outPacketSupp = new HashSet<Byte>();
232 static final List<Byte> VALID_EAPOL_TYPE = Arrays.asList(EAPOL.EAPOL_START, EAPOL.EAPOL_LOGOFF, EAPOL.EAPOL_PACKET);
233 static final int HEADER_LENGTH = 4;
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700234 // Configuration properties factory
235 private final ConfigFactory factory =
Jonathan Hart092dfb22015-11-16 23:05:21 -0800236 new ConfigFactory<ApplicationId, AaaConfig>(APP_SUBJECT_FACTORY,
237 AaaConfig.class,
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700238 "AAA") {
239 @Override
Jonathan Hart092dfb22015-11-16 23:05:21 -0800240 public AaaConfig createConfig() {
241 return new AaaConfig();
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700242 }
243 };
Ray Milkeyf51eba22015-09-25 10:24:23 -0700244
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700245 // Listener for config changes
246 private final InternalConfigListener cfgListener = new InternalConfigListener();
Ari Saha89831742015-06-26 10:31:48 -0700247
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800248 private final InternalMapEventListener mapListener = new InternalMapEventListener();
249
Jonathan Hart5db44532018-07-12 18:13:54 -0700250 private StateMachineDelegate delegate = new InternalStateMachineDelegate();
251
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700252 /**
253 * Builds an EAPOL packet based on the given parameters.
254 *
255 * @param dstMac destination MAC address
256 * @param srcMac source MAC address
257 * @param vlan vlan identifier
258 * @param eapolType EAPOL type
259 * @param eap EAP payload
260 * @return Ethernet frame
261 */
262 private static Ethernet buildEapolResponse(MacAddress dstMac, MacAddress srcMac,
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100263 short vlan, byte eapolType, EAP eap, byte priorityCode) {
Ari Saha89831742015-06-26 10:31:48 -0700264
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700265 Ethernet eth = new Ethernet();
266 eth.setDestinationMACAddress(dstMac.toBytes());
267 eth.setSourceMACAddress(srcMac.toBytes());
268 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
269 if (vlan != Ethernet.VLAN_UNTAGGED) {
270 eth.setVlanID(vlan);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100271 eth.setPriorityCode(priorityCode);
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700272 }
273 //eapol header
274 EAPOL eapol = new EAPOL();
275 eapol.setEapolType(eapolType);
276 eapol.setPacketLength(eap.getLength());
Ari Saha89831742015-06-26 10:31:48 -0700277
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700278 //eap part
279 eapol.setPayload(eap);
280
281 eth.setPayload(eapol);
282 eth.setPad(true);
283 return eth;
284 }
Ari Saha89831742015-06-26 10:31:48 -0700285
Ari Saha89831742015-06-26 10:31:48 -0700286 @Activate
kartikey dubeye1545422019-05-22 12:53:45 +0000287 public void activate(ComponentContext context) {
Jonathan Hart612651f2019-11-25 09:21:43 -0800288 idManager = new IdentifierManager();
289 stateMachines = Maps.newConcurrentMap();
Charles Chandf7ff862017-01-20 11:22:05 -0800290 appId = coreService.registerApplication(APP_NAME);
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800291
292 KryoNamespace authSerializer = KryoNamespace.newBuilder()
293 .register(byte[].class)
294 .register(String.class)
295 .register(long.class)
296 .register(boolean.class)
297 .register(URI.class)
298 .register(DeviceId.class)
299 .register(ElementId.class)
300 .register(PortNumber.class)
301 .register(ConnectPoint.class)
302 .register(MacAddress.class)
303 .register(AuthenticationRecord.class)
304 .build();
305
306 authentications = storageService.<ConnectPoint, AuthenticationRecord>consistentMapBuilder()
307 .withApplicationId(appId)
308 .withName("authentications")
309 .withSerializer(Serializer.using(authSerializer))
310 .build();
311 authentications.addListener(mapListener);
312
Jonathan Hart5db44532018-07-12 18:13:54 -0700313 eventDispatcher.addSink(AuthenticationEvent.class, listenerRegistry);
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400314 netCfgService.addListener(cfgListener);
315 netCfgService.registerConfigFactory(factory);
kartikey dubeye1545422019-05-22 12:53:45 +0000316 cfgService.registerProperties(getClass());
317 modified(context);
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000318 subsService = sadisService.getSubscriberInfoService();
Deepa Vaddireddye0e10722017-09-27 05:00:10 +0530319 customInfo = new CustomizationInfo(subsService, deviceService);
Jonathan Hart092dfb22015-11-16 23:05:21 -0800320 cfgListener.reconfigureNetwork(netCfgService.getConfig(appId, AaaConfig.class));
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400321 log.info("Starting with config {} {}", this, newCfg);
Deepa Vaddireddye0e10722017-09-27 05:00:10 +0530322 configureRadiusCommunication();
Ari Saha89831742015-06-26 10:31:48 -0700323 // register our event handler
Brian O'Connord9c7da02015-07-29 17:49:24 -0700324 packetService.addProcessor(processor, PacketProcessor.director(2));
Jonathan Hart5db44532018-07-12 18:13:54 -0700325 StateMachine.setDelegate(delegate);
Shubham Sharma1e43c562019-06-19 14:18:12 +0000326 cleanupTimerTimeOutInMins = newCfg.sessionCleanupTimer();
327 StateMachine.setcleanupTimerTimeOutInMins(cleanupTimerTimeOutInMins);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100328 impl.initializeLocalState(newCfg);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100329 impl.requestIntercepts();
Amit Ghoshf739be52017-09-21 15:49:37 +0100330 deviceService.addListener(deviceListener);
kartikey dubeye1545422019-05-22 12:53:45 +0000331 getConfiguredAaaServerAddress();
Shubham Sharma4900ce62019-06-19 14:18:50 +0000332 radiusOperationalStatusService.initialize(nasIpAddress.getAddress(), radiusSecret, impl);
kartikey dubeye1545422019-05-22 12:53:45 +0000333 authenticationStatisticsPublisher =
334 new AuthenticationStatisticsEventPublisher();
Shubham Sharma4900ce62019-06-19 14:18:50 +0000335 executor = Executors.newScheduledThreadPool(3);
336
kartikey dubeye1545422019-05-22 12:53:45 +0000337 scheduledFuture = executor.scheduleAtFixedRate(authenticationStatisticsPublisher,
Shubham Sharma4900ce62019-06-19 14:18:50 +0000338 0, statisticsGenerationPeriodInSeconds, TimeUnit.SECONDS);
339 scheduledStatusServerChecker = executor.scheduleAtFixedRate(new ServerStatusChecker(), 0,
340 operationalStatusEventGenerationPeriodInSeconds, TimeUnit.SECONDS);
Amit Ghoshf739be52017-09-21 15:49:37 +0100341
Jian Li13c67162015-12-09 13:20:34 -0800342 log.info("Started");
Ari Saha89831742015-06-26 10:31:48 -0700343 }
344
345 @Deactivate
kartikey dubeye1545422019-05-22 12:53:45 +0000346 public void deactivate(ComponentContext context) {
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100347 impl.withdrawIntercepts();
Ari Saha89831742015-06-26 10:31:48 -0700348 packetService.removeProcessor(processor);
Deepa Vaddireddyb9c24c62017-09-21 13:45:30 +0530349 netCfgService.removeListener(cfgListener);
kartikey dubeye1545422019-05-22 12:53:45 +0000350 cfgService.unregisterProperties(getClass(), false);
Jonathan Hart5db44532018-07-12 18:13:54 -0700351 StateMachine.unsetDelegate(delegate);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100352 impl.deactivate();
Amit Ghoshf739be52017-09-21 15:49:37 +0100353 deviceService.removeListener(deviceListener);
Jonathan Hart5db44532018-07-12 18:13:54 -0700354 eventDispatcher.removeSink(AuthenticationEvent.class);
kartikey dubeye1545422019-05-22 12:53:45 +0000355 scheduledFuture.cancel(true);
Shubham Sharma4900ce62019-06-19 14:18:50 +0000356 scheduledStatusServerChecker.cancel(true);
kartikey dubeye1545422019-05-22 12:53:45 +0000357 executor.shutdown();
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800358
359 authentications.removeListener(mapListener);
360
Jian Li13c67162015-12-09 13:20:34 -0800361 log.info("Stopped");
Ray Milkey967776a2015-10-07 14:37:17 -0700362 }
kartikey dubeye1545422019-05-22 12:53:45 +0000363 @Modified
364 public void modified(ComponentContext context) {
Shubham Sharma4900ce62019-06-19 14:18:50 +0000365 Dictionary<String, Object> properties = context.getProperties();
366
367 String s = Tools.get(properties, "statisticsGenerationPeriodInSeconds");
368 statisticsGenerationPeriodInSeconds = Strings.isNullOrEmpty(s) ? STATISTICS_GENERATION_PERIOD_DEFAULT
369 : Integer.parseInt(s.trim());
370
371 s = Tools.get(properties, "operationalStatusEventGenerationPeriodInSeconds");
372 operationalStatusEventGenerationPeriodInSeconds = Strings.isNullOrEmpty(s)
373 ? OPERATIONAL_STATUS_SERVER_EVENT_GENERATION_DEFAULT
374 : Integer.parseInt(s.trim());
375
376 s = Tools.get(properties, "operationalStatusServerTimeoutInSeconds");
377 operationalStatusServerTimeoutInSeconds = Strings.isNullOrEmpty(s) ? OPERATIONAL_STATUS_SERVER_TIMEOUT_DEFAULT
378 : Integer.parseInt(s.trim());
379
380 s = Tools.get(properties, "operationalStatusEvaluationMode");
381 String newEvaluationModeString = Strings.isNullOrEmpty(s) ? STATUS_SERVER_MODE_DEFAULT : s.trim();
382
383 radiusOperationalStatusService
384 .setOperationalStatusServerTimeoutInMillis(operationalStatusServerTimeoutInSeconds * 1000);
385 RadiusOperationalStatusEvaluationMode newEvaluationMode =
386 RadiusOperationalStatusEvaluationMode.getValue(newEvaluationModeString);
387 if (newEvaluationMode != null) {
388 radiusOperationalStatusService.setRadiusOperationalStatusEvaluationMode(newEvaluationMode);
389 operationalStatusEvaluationMode = newEvaluationModeString;
390 } else {
391 properties.put("operationalStatusEvaluationMode", operationalStatusEvaluationMode);
392 }
kartikey dubeye1545422019-05-22 12:53:45 +0000393 }
394
Shubham Sharmacf5e5032019-11-26 11:09:21 +0000395 protected void configureRadiusCommunication() {
Deepa Vaddireddye0e10722017-09-27 05:00:10 +0530396 if (radiusConnectionType.toLowerCase().equals("socket")) {
397 impl = new SocketBasedRadiusCommunicator(appId, packetService, this);
398 } else {
399 impl = new PortBasedRadiusCommunicator(appId, packetService, mastershipService,
400 deviceService, subsService, pktCustomizer, this);
401 }
402 }
403
404 private void configurePacketCustomizer() {
405 switch (customizer.toLowerCase()) {
406 case "sample":
407 pktCustomizer = new SamplePacketCustomizer(customInfo);
408 log.info("Created SamplePacketCustomizer");
409 break;
Saurav Dase72358a2018-11-13 21:56:46 -0800410 case "att":
411 pktCustomizer = new AttPacketCustomizer(customInfo);
412 log.info("Created AttPacketCustomizer");
413 break;
Deepa Vaddireddye0e10722017-09-27 05:00:10 +0530414 default:
415 pktCustomizer = new PacketCustomizer(customInfo);
416 log.info("Created default PacketCustomizer");
417 break;
418 }
419 }
420
kartikey dubeye1545422019-05-22 12:53:45 +0000421 private void getConfiguredAaaServerAddress() {
422 try {
423 InetAddress address;
424 if (newCfg.radiusHostName() != null) {
425 address = InetAddress.getByName(newCfg.radiusHostName());
426 } else {
427 address = newCfg.radiusIp();
428 }
429
430 configuredAaaServerAddress = address.getHostAddress();
431 } catch (UnknownHostException uhe) {
432 log.warn("Unable to resolve host {}", newCfg.radiusHostName());
433 }
434 }
435
Vijaykumar Kushwaha056e4cd2019-08-06 13:16:25 +0000436 private void checkReceivedPacketForValidValidator(RADIUS radiusPacket, byte[] requestAuthenticator) {
437 if (!checkResponseMessageAuthenticator(radiusSecret, radiusPacket, requestAuthenticator)) {
kartikey dubeye1545422019-05-22 12:53:45 +0000438 aaaStatisticsManager.getAaaStats().increaseInvalidValidatorsRx();
439 }
440 }
Vijaykumar Kushwaha056e4cd2019-08-06 13:16:25 +0000441
442 private boolean checkResponseMessageAuthenticator(String key, RADIUS radiusPacket, byte[] requestAuthenticator) {
443 byte[] newHash = new byte[16];
444 Arrays.fill(newHash, (byte) 0);
445 byte[] messageAuthenticator = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH).getValue();
446 byte[] authenticator = radiusPacket.getAuthenticator();
447 radiusPacket.updateAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, newHash);
448 radiusPacket.setAuthenticator(requestAuthenticator);
449 // Calculate the MD5 HMAC based on the message
450 try {
451 SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacMD5");
452 Mac mac = Mac.getInstance("HmacMD5");
453 mac.init(keySpec);
454 newHash = mac.doFinal(radiusPacket.serialize());
455 } catch (Exception e) {
456 log.error("Failed to generate message authenticator: {}", e.getMessage());
457 }
458 radiusPacket.updateAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, messageAuthenticator);
459 radiusPacket.setAuthenticator(authenticator);
460 // Compare the calculated Message-Authenticator with the one in the message
461 return Arrays.equals(newHash, messageAuthenticator);
462 }
kartikey dubeye1545422019-05-22 12:53:45 +0000463 public void checkForPacketFromUnknownServer(String hostAddress) {
464 if (!hostAddress.equals(configuredAaaServerAddress)) {
Vijaykumar Kushwahafffd3d12019-08-01 11:09:59 +0000465 getConfiguredAaaServerAddress();
466 if (!hostAddress.equals(configuredAaaServerAddress)) {
467 aaaStatisticsManager.getAaaStats().incrementUnknownServerRx();
468 }
kartikey dubeye1545422019-05-22 12:53:45 +0000469 }
470 }
471
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100472 /**
473 * Send RADIUS packet to the RADIUS server.
474 *
475 * @param radiusPacket RADIUS packet to be sent to server.
476 * @param inPkt Incoming EAPOL packet
477 */
478 protected void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
kartikey dubeye1545422019-05-22 12:53:45 +0000479 outPacketSet.add(radiusPacket.getIdentifier());
480 aaaStatisticsManager.getAaaStats().increaseOrDecreasePendingRequests(true);
481 aaaStatisticsManager.getAaaStats().increaseAccessRequestsTx();
Shubham Sharma4900ce62019-06-19 14:18:50 +0000482 aaaStatisticsManager.putOutgoingIdentifierToMap(radiusPacket.getIdentifier());
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100483 impl.sendRadiusPacket(radiusPacket, inPkt);
484 }
Ray Milkey967776a2015-10-07 14:37:17 -0700485
Jonathan Hart612651f2019-11-25 09:21:43 -0800486 /**
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100487 * Handles RADIUS packets.
488 *
489 * @param radiusPacket RADIUS packet coming from the RADIUS server.
Jonathan Hart4731dd92018-05-02 17:30:05 -0700490 * @throws DeserializationException if packet deserialization fails
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100491 */
Jonathan Hart612651f2019-11-25 09:21:43 -0800492 public void handleRadiusPacket(RADIUS radiusPacket) throws DeserializationException {
Saurav Das987441a2018-09-18 16:33:47 -0700493 if (log.isTraceEnabled()) {
494 log.trace("Received RADIUS packet {}", radiusPacket);
495 }
Shubham Sharma4900ce62019-06-19 14:18:50 +0000496 if (radiusOperationalStatusService.isRadiusResponseForOperationalStatus(radiusPacket.getIdentifier())) {
497 radiusOperationalStatusService.handleRadiusPacketForOperationalStatus(radiusPacket);
498 return;
499 }
Jonathan Hart612651f2019-11-25 09:21:43 -0800500
501 RequestIdentifier identifier = RequestIdentifier.of(radiusPacket.getIdentifier());
502 String sessionId = idManager.getSessionId(identifier);
503
504 if (sessionId == null) {
505 log.error("Invalid packet identifier {}, could not find corresponding "
506 + "state machine ... exiting", radiusPacket.getIdentifier());
507 aaaStatisticsManager.getAaaStats().incrementNumberOfSessionsExpired();
508 aaaStatisticsManager.getAaaStats().countDroppedResponsesRx();
509 return;
510 }
511
512 idManager.releaseIdentifier(identifier);
513 StateMachine stateMachine = stateMachines.get(sessionId);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100514 if (stateMachine == null) {
Saurav Das987441a2018-09-18 16:33:47 -0700515 log.error("Invalid packet identifier {}, could not find corresponding "
516 + "state machine ... exiting", radiusPacket.getIdentifier());
kartikey dubeye1545422019-05-22 12:53:45 +0000517 aaaStatisticsManager.getAaaStats().incrementNumberOfSessionsExpired();
518 aaaStatisticsManager.getAaaStats().countDroppedResponsesRx();
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100519 return;
Ray Milkey967776a2015-10-07 14:37:17 -0700520 }
Kartikey Dubeyadeb26e2019-10-01 12:18:35 +0000521
522 //instance of StateMachine using the sessionId for updating machine stats
Jonathan Hart612651f2019-11-25 09:21:43 -0800523 StateMachine machineStats = stateMachines.get(stateMachine.sessionId());
Kartikey Dubeyadeb26e2019-10-01 12:18:35 +0000524
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100525 EAP eapPayload;
526 Ethernet eth;
Vijaykumar Kushwaha056e4cd2019-08-06 13:16:25 +0000527 checkReceivedPacketForValidValidator(radiusPacket, stateMachine.requestAuthenticator());
Kartikey Dubeyadeb26e2019-10-01 12:18:35 +0000528
529 //increasing packets and octets received from server
530 machineStats.incrementTotalPacketsReceived();
531 machineStats.incrementTotalOctetReceived(radiusPacket.decapsulateMessage().getLength());
532
kartikey dubeye1545422019-05-22 12:53:45 +0000533 if (outPacketSet.contains(radiusPacket.getIdentifier())) {
534 aaaStatisticsManager.getAaaStats().increaseOrDecreasePendingRequests(false);
535 outPacketSet.remove(new Byte(radiusPacket.getIdentifier()));
536 }
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100537 switch (radiusPacket.getCode()) {
538 case RADIUS.RADIUS_CODE_ACCESS_CHALLENGE:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400539 log.debug("RADIUS packet: RADIUS_CODE_ACCESS_CHALLENGE");
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100540 RADIUSAttribute radiusAttrState = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_STATE);
541 byte[] challengeState = null;
542 if (radiusAttrState != null) {
543 challengeState = radiusAttrState.getValue();
544 }
545 eapPayload = radiusPacket.decapsulateMessage();
546 stateMachine.setChallengeInfo(eapPayload.getIdentifier(), challengeState);
547 eth = buildEapolResponse(stateMachine.supplicantAddress(),
548 MacAddress.valueOf(nasMacAddress),
549 stateMachine.vlanId(),
550 EAPOL.EAPOL_PACKET,
551 eapPayload, stateMachine.priorityCode());
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400552 log.debug("Send EAP challenge response to supplicant {}", stateMachine.supplicantAddress().toString());
Shubham Sharma1f193582019-07-11 12:12:41 +0000553 sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint(), true);
kartikey dubeye1545422019-05-22 12:53:45 +0000554 aaaStatisticsManager.getAaaStats().increaseChallengeResponsesRx();
Shubham Sharma3c8c7022019-09-13 10:39:47 +0000555 outPacketSupp.add(eapPayload.getIdentifier());
556 aaaStatisticsManager.getAaaStats().incrementPendingResSupp();
Kartikey Dubeyadeb26e2019-10-01 12:18:35 +0000557 //increasing packets send to server
558 machineStats.incrementTotalPacketsSent();
559 machineStats.incrementTotalOctetSent(eapPayload.getLength());
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100560 break;
561 case RADIUS.RADIUS_CODE_ACCESS_ACCEPT:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400562 log.debug("RADIUS packet: RADIUS_CODE_ACCESS_ACCEPT");
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100563 //send an EAPOL - Success to the supplicant.
564 byte[] eapMessageSuccess =
565 radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE).getValue();
Jonathan Hart4731dd92018-05-02 17:30:05 -0700566 eapPayload = EAP.deserializer().deserialize(
567 eapMessageSuccess, 0, eapMessageSuccess.length);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100568 eth = buildEapolResponse(stateMachine.supplicantAddress(),
569 MacAddress.valueOf(nasMacAddress),
570 stateMachine.vlanId(),
571 EAPOL.EAPOL_PACKET,
572 eapPayload, stateMachine.priorityCode());
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400573 log.info("Send EAP success message to supplicant {}", stateMachine.supplicantAddress().toString());
Shubham Sharma1f193582019-07-11 12:12:41 +0000574 sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint(), false);
575 aaaStatisticsManager.getAaaStats().incrementEapolAuthSuccessTrans();
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100576
577 stateMachine.authorizeAccess();
kartikey dubeye1545422019-05-22 12:53:45 +0000578 aaaStatisticsManager.getAaaStats().increaseAcceptResponsesRx();
Kartikey Dubeyadeb26e2019-10-01 12:18:35 +0000579 //increasing packets send to server
580 machineStats.incrementTotalPacketsSent();
581 machineStats.incrementTotalOctetSent(eapPayload.getLength());
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100582 break;
583 case RADIUS.RADIUS_CODE_ACCESS_REJECT:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400584 log.debug("RADIUS packet: RADIUS_CODE_ACCESS_REJECT");
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100585 //send an EAPOL - Failure to the supplicant.
586 byte[] eapMessageFailure;
587 eapPayload = new EAP();
588 RADIUSAttribute radiusAttrEap = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE);
589 if (radiusAttrEap == null) {
590 eapPayload.setCode(EAP.FAILURE);
591 eapPayload.setIdentifier(stateMachine.challengeIdentifier());
592 eapPayload.setLength(EAP.EAP_HDR_LEN_SUC_FAIL);
593 } else {
594 eapMessageFailure = radiusAttrEap.getValue();
Jonathan Hart4731dd92018-05-02 17:30:05 -0700595 eapPayload = EAP.deserializer().deserialize(
596 eapMessageFailure, 0, eapMessageFailure.length);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100597 }
598 eth = buildEapolResponse(stateMachine.supplicantAddress(),
599 MacAddress.valueOf(nasMacAddress),
600 stateMachine.vlanId(),
601 EAPOL.EAPOL_PACKET,
602 eapPayload, stateMachine.priorityCode());
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400603 log.warn("Send EAP failure message to supplicant {}", stateMachine.supplicantAddress().toString());
Shubham Sharma1f193582019-07-11 12:12:41 +0000604 sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint(), false);
605 aaaStatisticsManager.getAaaStats().incrementEapolauthFailureTrans();
606
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100607 stateMachine.denyAccess();
kartikey dubeye1545422019-05-22 12:53:45 +0000608 aaaStatisticsManager.getAaaStats().increaseRejectResponsesRx();
Kartikey Dubeyadeb26e2019-10-01 12:18:35 +0000609 //increasing packets send to server
610 machineStats.incrementTotalPacketsSent();
611 machineStats.incrementTotalOctetSent(eapPayload.getLength());
612 //pushing machine stats to kafka
613 AaaSupplicantMachineStats machineObj = aaaSupplicantStatsManager.getSupplicantStats(machineStats);
614 aaaSupplicantStatsManager.getMachineStatsDelegate()
615 .notify(new AaaMachineStatisticsEvent(AaaMachineStatisticsEvent.Type.STATS_UPDATE, machineObj));
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100616 break;
617 default:
618 log.warn("Unknown RADIUS message received with code: {}", radiusPacket.getCode());
kartikey dubeye1545422019-05-22 12:53:45 +0000619 aaaStatisticsManager.getAaaStats().increaseUnknownTypeRx();
Kartikey Dubeyadeb26e2019-10-01 12:18:35 +0000620 //increasing packets received to server
621 machineStats.incrementTotalPacketsReceived();
622 machineStats.incrementTotalOctetReceived(radiusPacket.decapsulateMessage().getLength());
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100623 }
kartikey dubeye1545422019-05-22 12:53:45 +0000624 aaaStatisticsManager.getAaaStats().countDroppedResponsesRx();
Aaron Kruglikovd39d99e2015-07-03 13:30:57 -0700625 }
626
Ray Milkey967776a2015-10-07 14:37:17 -0700627 /**
628 * Send the ethernet packet to the supplicant.
629 *
630 * @param ethernetPkt the ethernet packet
631 * @param connectPoint the connect point to send out
632 */
Shubham Sharma1f193582019-07-11 12:12:41 +0000633 private void sendPacketToSupplicant(Ethernet ethernetPkt, ConnectPoint connectPoint, boolean isChallengeResponse) {
Ray Milkey967776a2015-10-07 14:37:17 -0700634 TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(connectPoint.port()).build();
635 OutboundPacket packet = new DefaultOutboundPacket(connectPoint.deviceId(),
636 treatment, ByteBuffer.wrap(ethernetPkt.serialize()));
Shubham Sharma1f193582019-07-11 12:12:41 +0000637 EAPOL eap = ((EAPOL) ethernetPkt.getPayload());
Saurav Das987441a2018-09-18 16:33:47 -0700638 if (log.isTraceEnabled()) {
Saurav Das987441a2018-09-18 16:33:47 -0700639 log.trace("Sending eapol payload {} enclosed in {} to supplicant at {}",
640 eap, ethernetPkt, connectPoint);
641 }
Ray Milkey967776a2015-10-07 14:37:17 -0700642 packetService.emit(packet);
Shubham Sharma1f193582019-07-11 12:12:41 +0000643 if (isChallengeResponse) {
644 aaaStatisticsManager.getAaaStats().incrementEapPktTxauthEap();
645 }
Shubham Sharma3c8c7022019-09-13 10:39:47 +0000646 aaaStatisticsManager.getAaaStats().incrementEapolFramesTx();
647 aaaStatisticsManager.getAaaStats().countReqEapFramesTx();
Ray Milkey967776a2015-10-07 14:37:17 -0700648 }
649
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400650 @Override
651 public String toString() {
652 return ToStringBuilder.reflectionToString(this);
653 }
654
Jonathan Hart612651f2019-11-25 09:21:43 -0800655 @Override
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800656 public Iterable<AuthenticationRecord> getAuthenticationRecords() {
657 return authentications.asJavaMap().values();
Jonathan Hart612651f2019-11-25 09:21:43 -0800658 }
659
660 @Override
661 public boolean removeAuthenticationStateByMac(MacAddress mac) {
662
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800663 Optional<Versioned<AuthenticationRecord>> r = authentications.values().stream()
664 .filter(v -> v.value().supplicantAddress().equals(mac))
665 .findFirst();
Jonathan Hart612651f2019-11-25 09:21:43 -0800666
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800667 if (r.isEmpty()) {
668 return false;
Jonathan Hart612651f2019-11-25 09:21:43 -0800669 }
670
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800671 Versioned<AuthenticationRecord> removed =
672 authentications.remove(r.get().value().supplicantConnectPoint());
Jonathan Hart612651f2019-11-25 09:21:43 -0800673
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800674 return removed != null;
Jonathan Hart612651f2019-11-25 09:21:43 -0800675 }
676
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800677 StateMachine getStateMachine(String sessionId) {
Jonathan Hart612651f2019-11-25 09:21:43 -0800678 return stateMachines.get(sessionId);
679 }
680
681 private String sessionId(ConnectPoint cp) {
682 return cp.deviceId().toString() + cp.port().toString();
683 }
684
Ari Saha89831742015-06-26 10:31:48 -0700685 // our handler defined as a private inner class
686
687 /**
688 * Packet processor responsible for forwarding packets along their paths.
689 */
690 private class ReactivePacketProcessor implements PacketProcessor {
691 @Override
692 public void process(PacketContext context) {
693
694 // Extract the original Ethernet frame from the packet information
695 InboundPacket pkt = context.inPacket();
696 Ethernet ethPkt = pkt.parsed();
697 if (ethPkt == null) {
698 return;
699 }
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100700
Jonathan Hart612651f2019-11-25 09:21:43 -0800701 // identify if incoming packet comes from supplicant (EAP) or RADIUS
702 switch (EthType.EtherType.lookup(ethPkt.getEtherType())) {
703 case EAPOL:
704 handleSupplicantPacket(context.inPacket());
705 break;
706 default:
707 // any other packets let the specific implementation handle
708 impl.handlePacketFromServer(context);
Ari Saha89831742015-06-26 10:31:48 -0700709 }
710 }
711
Ray Milkey9eb293f2015-09-30 15:09:17 -0700712 /**
713 * Creates and initializes common fields of a RADIUS packet.
714 *
Ray Milkey967776a2015-10-07 14:37:17 -0700715 * @param stateMachine state machine for the request
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700716 * @param eapPacket EAP packet
Ray Milkey9eb293f2015-09-30 15:09:17 -0700717 * @return RADIUS packet
718 */
Ray Milkey967776a2015-10-07 14:37:17 -0700719 private RADIUS getRadiusPayload(StateMachine stateMachine, byte identifier, EAP eapPacket) {
Ray Milkey9eb293f2015-09-30 15:09:17 -0700720 RADIUS radiusPayload =
721 new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST,
722 eapPacket.getIdentifier());
Ray Milkey967776a2015-10-07 14:37:17 -0700723
724 // set Request Authenticator in StateMachine
725 stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
726
Ray Milkey9eb293f2015-09-30 15:09:17 -0700727 radiusPayload.setIdentifier(identifier);
728 radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME,
Ray Milkey967776a2015-10-07 14:37:17 -0700729 stateMachine.username());
Ray Milkey9eb293f2015-09-30 15:09:17 -0700730
731 radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP,
Jonathan Hart092dfb22015-11-16 23:05:21 -0800732 AaaManager.this.nasIpAddress.getAddress());
Ray Milkey9eb293f2015-09-30 15:09:17 -0700733
734 radiusPayload.encapsulateMessage(eapPacket);
Ray Milkey9eb293f2015-09-30 15:09:17 -0700735
736 return radiusPayload;
737 }
Ari Saha89831742015-06-26 10:31:48 -0700738
739 /**
Jonathan Harta46dddf2015-06-30 15:31:20 -0700740 * Handles PAE packets (supplicant).
741 *
742 * @param inPacket Ethernet packet coming from the supplicant
Ari Saha89831742015-06-26 10:31:48 -0700743 */
Jonathan Hart612651f2019-11-25 09:21:43 -0800744 private void handleSupplicantPacket(InboundPacket inPacket) {
Jonathan Harta46dddf2015-06-30 15:31:20 -0700745 Ethernet ethPkt = inPacket.parsed();
Ari Saha89831742015-06-26 10:31:48 -0700746 // Where does it come from?
Jonathan Hart092dfb22015-11-16 23:05:21 -0800747 MacAddress srcMac = ethPkt.getSourceMAC();
Ari Saha89831742015-06-26 10:31:48 -0700748
Jonathan Harta46dddf2015-06-30 15:31:20 -0700749 DeviceId deviceId = inPacket.receivedFrom().deviceId();
750 PortNumber portNumber = inPacket.receivedFrom().port();
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800751 String sessionId = sessionId(inPacket.receivedFrom());
Saurav Das987441a2018-09-18 16:33:47 -0700752 EAPOL eapol = (EAPOL) ethPkt.getPayload();
753 if (log.isTraceEnabled()) {
754 log.trace("Received EAPOL packet {} in enclosing packet {} from "
755 + "dev/port: {}/{}", eapol, ethPkt, deviceId,
756 portNumber);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100757 }
Jonathan Harta46dddf2015-06-30 15:31:20 -0700758
Shubham Sharma3c8c7022019-09-13 10:39:47 +0000759 short pktlen = eapol.getPacketLength();
760 byte[] eapPayLoadBuffer = eapol.serialize();
761 int len = eapPayLoadBuffer.length;
762 if (len != (HEADER_LENGTH + pktlen)) {
763 aaaStatisticsManager.getAaaStats().incrementInvalidBodyLength();
764 return;
765 }
766 if (!VALID_EAPOL_TYPE.contains(eapol.getEapolType())) {
767 aaaStatisticsManager.getAaaStats().incrementInvalidPktType();
768 return;
769 }
770 if (pktlen >= 0 && ethPkt.getEtherType() == EthType.EtherType.EAPOL.ethType().toShort()) {
771 aaaStatisticsManager.getAaaStats().incrementValidEapolFramesRx();
772 }
Jonathan Hart612651f2019-11-25 09:21:43 -0800773
774 StateMachine stateMachine = stateMachines.computeIfAbsent(sessionId, id -> new StateMachine(id, executor));
775 stateMachine.setEapolTypeVal(eapol.getEapolType());
Saurav Das987441a2018-09-18 16:33:47 -0700776
Ari Saha89831742015-06-26 10:31:48 -0700777 switch (eapol.getEapolType()) {
778 case EAPOL.EAPOL_START:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400779 log.debug("EAP packet: EAPOL_START");
Ray Milkeyf51eba22015-09-25 10:24:23 -0700780 stateMachine.setSupplicantConnectpoint(inPacket.receivedFrom());
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800781 stateMachine.setSupplicantAddress(srcMac);
Jonathan Hart5db44532018-07-12 18:13:54 -0700782 stateMachine.start();
Jonathan Hart612651f2019-11-25 09:21:43 -0800783
Shubham Sharma1f193582019-07-11 12:12:41 +0000784 aaaStatisticsManager.getAaaStats().incrementEapolStartReqTrans();
Ray Milkeyf51eba22015-09-25 10:24:23 -0700785 //send an EAP Request/Identify to the supplicant
786 EAP eapPayload = new EAP(EAP.REQUEST, stateMachine.identifier(), EAP.ATTR_IDENTITY, null);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100787 if (ethPkt.getVlanID() != Ethernet.VLAN_UNTAGGED) {
788 stateMachine.setPriorityCode(ethPkt.getPriorityCode());
789 }
Jonathan Hart092dfb22015-11-16 23:05:21 -0800790 Ethernet eth = buildEapolResponse(srcMac, MacAddress.valueOf(nasMacAddress),
Ray Milkeyf51eba22015-09-25 10:24:23 -0700791 ethPkt.getVlanID(), EAPOL.EAPOL_PACKET,
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100792 eapPayload, stateMachine.priorityCode());
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400793
Ray Milkeyf51eba22015-09-25 10:24:23 -0700794 stateMachine.setVlanId(ethPkt.getVlanID());
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400795 log.debug("Getting EAP identity from supplicant {}", stateMachine.supplicantAddress().toString());
Shubham Sharma1f193582019-07-11 12:12:41 +0000796 sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint(), false);
Shubham Sharma3c8c7022019-09-13 10:39:47 +0000797 aaaStatisticsManager.getAaaStats().incrementRequestIdFramesTx();
Ari Saha89831742015-06-26 10:31:48 -0700798
799 break;
Qianqian Hub55a1ac2015-12-23 20:44:48 +0800800 case EAPOL.EAPOL_LOGOFF:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400801 log.debug("EAP packet: EAPOL_LOGOFF");
Kartikey Dubeyadeb26e2019-10-01 12:18:35 +0000802 //posting the machine stat data for current supplicant device.
803 if (stateMachine.getSessionTerminateReason() == null ||
804 stateMachine.getSessionTerminateReason().equals("")) {
805 stateMachine.setSessionTerminateReason(
806 StateMachine.SessionTerminationReasons.SUPPLICANT_LOGOFF.getReason());
807 }
808 AaaSupplicantMachineStats obj = aaaSupplicantStatsManager.getSupplicantStats(stateMachine);
809 aaaSupplicantStatsManager.getMachineStatsDelegate()
810 .notify(new AaaMachineStatisticsEvent(AaaMachineStatisticsEvent.Type.STATS_UPDATE, obj));
Ray Milkeyb34b4962016-01-04 10:24:43 -0800811 if (stateMachine.state() == StateMachine.STATE_AUTHORIZED) {
812 stateMachine.logoff();
Shubham Sharma1f193582019-07-11 12:12:41 +0000813 aaaStatisticsManager.getAaaStats().incrementEapolLogoffRx();
Qianqian Hub55a1ac2015-12-23 20:44:48 +0800814 }
Shubham Sharma3c8c7022019-09-13 10:39:47 +0000815 if (stateMachine.state() == StateMachine.STATE_IDLE) {
816 aaaStatisticsManager.getAaaStats().incrementAuthStateIdle();
817 }
Qianqian Hub55a1ac2015-12-23 20:44:48 +0800818
819 break;
Ari Saha89831742015-06-26 10:31:48 -0700820 case EAPOL.EAPOL_PACKET:
Ray Milkeyf51eba22015-09-25 10:24:23 -0700821 RADIUS radiusPayload;
Ray Milkey9eb293f2015-09-30 15:09:17 -0700822 // check if this is a Response/Identify or a Response/TLS
Ari Saha89831742015-06-26 10:31:48 -0700823 EAP eapPacket = (EAP) eapol.getPayload();
Shubham Sharma3c8c7022019-09-13 10:39:47 +0000824 Byte identifier = new Byte(eapPacket.getIdentifier());
Ari Saha89831742015-06-26 10:31:48 -0700825
Jonathan Hart612651f2019-11-25 09:21:43 -0800826 // get identifier for request and store mapping to session ID
827 RequestIdentifier radiusIdentifier = idManager.getNewIdentifier(sessionId);
828
Ari Saha89831742015-06-26 10:31:48 -0700829 byte dataType = eapPacket.getDataType();
830 switch (dataType) {
Ari Saha89831742015-06-26 10:31:48 -0700831
Ray Milkey9eb293f2015-09-30 15:09:17 -0700832 case EAP.ATTR_IDENTITY:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400833 log.debug("EAP packet: EAPOL_PACKET ATTR_IDENTITY");
Shubham Sharma1e43c562019-06-19 14:18:12 +0000834 //Setting the time of this response from RG, only when its not a re-transmission.
835 if (stateMachine.getLastPacketReceivedTime() == 0) {
836 stateMachine.setLastPacketReceivedTime(System.currentTimeMillis());
837 }
Ray Milkey9eb293f2015-09-30 15:09:17 -0700838 // request id access to RADIUS
839 stateMachine.setUsername(eapPacket.getData());
Ari Saha89831742015-06-26 10:31:48 -0700840
Jonathan Hart612651f2019-11-25 09:21:43 -0800841 radiusPayload = getRadiusPayload(stateMachine, radiusIdentifier.identifier(), eapPacket);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100842 radiusPayload = pktCustomizer.customizePacket(radiusPayload, inPacket);
Jonathan Hart092dfb22015-11-16 23:05:21 -0800843 radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret);
Ari Saha89831742015-06-26 10:31:48 -0700844
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100845 sendRadiusPacket(radiusPayload, inPacket);
Shubham Sharma1e43c562019-06-19 14:18:12 +0000846 stateMachine.setWaitingForRadiusResponse(true);
Shubham Sharma1f193582019-07-11 12:12:41 +0000847 aaaStatisticsManager.getAaaStats().incrementEapolAtrrIdentity();
Ray Milkey9eb293f2015-09-30 15:09:17 -0700848 // change the state to "PENDING"
kartikey dubeye1545422019-05-22 12:53:45 +0000849 if (stateMachine.state() == StateMachine.STATE_PENDING) {
850 aaaStatisticsManager.getAaaStats().increaseRequestReTx();
Kartikey Dubeyadeb26e2019-10-01 12:18:35 +0000851 stateMachine.incrementTotalPacketsSent();
852 stateMachine.incrementTotalOctetSent(eapol.getPacketLength());
kartikey dubeye1545422019-05-22 12:53:45 +0000853 }
Ray Milkey9eb293f2015-09-30 15:09:17 -0700854 stateMachine.requestAccess();
855 break;
Ari Saha89831742015-06-26 10:31:48 -0700856 case EAP.ATTR_MD5:
Shubham Sharma1e43c562019-06-19 14:18:12 +0000857 stateMachine.setLastPacketReceivedTime(System.currentTimeMillis());
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400858 log.debug("EAP packet: EAPOL_PACKET ATTR_MD5");
Ray Milkey9eb293f2015-09-30 15:09:17 -0700859 // verify if the EAP identifier corresponds to the
860 // challenge identifier from the client state
861 // machine.
Ray Milkeyf61a24e2015-09-24 16:34:02 -0700862 if (eapPacket.getIdentifier() == stateMachine.challengeIdentifier()) {
Ari Saha89831742015-06-26 10:31:48 -0700863 //send the RADIUS challenge response
Jonathan Hart612651f2019-11-25 09:21:43 -0800864 radiusPayload = getRadiusPayload(stateMachine,
865 radiusIdentifier.identifier(), eapPacket);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100866 radiusPayload = pktCustomizer.customizePacket(radiusPayload, inPacket);
Ari Saha89831742015-06-26 10:31:48 -0700867
Qianqian Hub55a1ac2015-12-23 20:44:48 +0800868 if (stateMachine.challengeState() != null) {
869 radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
870 stateMachine.challengeState());
871 }
Jonathan Hart092dfb22015-11-16 23:05:21 -0800872 radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret);
Shubham Sharma3c8c7022019-09-13 10:39:47 +0000873 if (outPacketSupp.contains(eapPacket.getIdentifier())) {
874 aaaStatisticsManager.getAaaStats().decrementPendingResSupp();
875 outPacketSupp.remove(identifier);
876 }
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100877 sendRadiusPacket(radiusPayload, inPacket);
Shubham Sharma1e43c562019-06-19 14:18:12 +0000878 stateMachine.setWaitingForRadiusResponse(true);
Shubham Sharma1f193582019-07-11 12:12:41 +0000879 aaaStatisticsManager.getAaaStats().incrementEapolMd5RspChall();
Ari Saha89831742015-06-26 10:31:48 -0700880 }
881 break;
882 case EAP.ATTR_TLS:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400883 log.debug("EAP packet: EAPOL_PACKET ATTR_TLS");
Ray Milkey9eb293f2015-09-30 15:09:17 -0700884 // request id access to RADIUS
Jonathan Hart612651f2019-11-25 09:21:43 -0800885 radiusPayload = getRadiusPayload(stateMachine, radiusIdentifier.identifier(), eapPacket);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100886 radiusPayload = pktCustomizer.customizePacket(radiusPayload, inPacket);
Ari Saha89831742015-06-26 10:31:48 -0700887
Qianqian Hub55a1ac2015-12-23 20:44:48 +0800888 if (stateMachine.challengeState() != null) {
889 radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
890 stateMachine.challengeState());
891 }
Ray Milkeyf51eba22015-09-25 10:24:23 -0700892 stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
Ari Saha89831742015-06-26 10:31:48 -0700893
Jonathan Hart092dfb22015-11-16 23:05:21 -0800894 radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret);
Shubham Sharma3c8c7022019-09-13 10:39:47 +0000895 if (outPacketSupp.contains(eapPacket.getIdentifier())) {
896 aaaStatisticsManager.getAaaStats().decrementPendingResSupp();
897 outPacketSupp.remove(identifier);
898 }
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100899 sendRadiusPacket(radiusPayload, inPacket);
Shubham Sharma1e43c562019-06-19 14:18:12 +0000900 stateMachine.setWaitingForRadiusResponse(true);
Shubham Sharma1f193582019-07-11 12:12:41 +0000901 aaaStatisticsManager.getAaaStats().incrementEapolTlsRespChall();
Ray Milkey5493b512015-10-21 12:13:49 -0700902
Ray Milkeyf3790b82015-10-21 16:28:08 -0700903 if (stateMachine.state() != StateMachine.STATE_PENDING) {
904 stateMachine.requestAccess();
905 }
Ray Milkeyf51eba22015-09-25 10:24:23 -0700906
Ari Saha89831742015-06-26 10:31:48 -0700907 break;
908 default:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400909 log.warn("Unknown EAP packet type");
Ari Saha89831742015-06-26 10:31:48 -0700910 return;
911 }
912 break;
913 default:
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400914 log.debug("Skipping EAPOL message {}", eapol.getEapolType());
Ari Saha89831742015-06-26 10:31:48 -0700915 }
Shubham Sharma1f193582019-07-11 12:12:41 +0000916 aaaStatisticsManager.getAaaStats().countTransRespNotNak();
917 aaaStatisticsManager.getAaaStats().countEapolResIdentityMsgTrans();
Ari Saha89831742015-06-26 10:31:48 -0700918 }
Ray Milkey967776a2015-10-07 14:37:17 -0700919 }
920
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100921 /**
Jonathan Hart5db44532018-07-12 18:13:54 -0700922 * Delegate allowing the StateMachine to notify us of events.
923 */
924 private class InternalStateMachineDelegate implements StateMachineDelegate {
925
926 @Override
927 public void notify(AuthenticationEvent authenticationEvent) {
928 log.info("Auth event {} for {}",
929 authenticationEvent.type(), authenticationEvent.subject());
Jonathan Hart612651f2019-11-25 09:21:43 -0800930
931 if (authenticationEvent.type() == AuthenticationEvent.Type.TIMEOUT) {
932 handleStateMachineTimeout(authenticationEvent.subject());
933 }
934
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800935 AuthenticationRecord record = authenticationEvent.authenticationRecord();
936 if (record == null) {
937 authentications.remove(authenticationEvent.subject());
938 } else {
939 authentications.put(authenticationEvent.subject(), record);
940 }
941
Jonathan Hart5db44532018-07-12 18:13:54 -0700942 post(authenticationEvent);
943 }
944 }
945
Jonathan Hart612651f2019-11-25 09:21:43 -0800946 private void handleStateMachineTimeout(ConnectPoint supplicantConnectPoint) {
947 StateMachine stateMachine = stateMachines.remove(sessionId(supplicantConnectPoint));
948
949 if (stateMachine.state() == StateMachine.STATE_PENDING && stateMachine.isWaitingForRadiusResponse()) {
950 aaaStatisticsManager.getAaaStats().increaseTimedOutPackets();
951 }
952
953 StateMachine.deleteStateMachineMapping(stateMachine);
954 }
955
Jonathan Hart5db44532018-07-12 18:13:54 -0700956 /**
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100957 * Configuration Listener, handles change in configuration.
958 */
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700959 private class InternalConfigListener implements NetworkConfigListener {
960
961 /**
Ray Milkeyc9e8dcc2015-12-30 10:31:32 -0800962 * Reconfigures the AAA application according to the
963 * configuration parameters passed.
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700964 *
965 * @param cfg configuration object
966 */
Jonathan Hart092dfb22015-11-16 23:05:21 -0800967 private void reconfigureNetwork(AaaConfig cfg) {
Matt Jeanneret2ff1a782018-06-13 15:24:25 -0400968 log.info("Reconfiguring AaaConfig from config: {}", cfg);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100969
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700970 if (cfg == null) {
Jonathan Hart092dfb22015-11-16 23:05:21 -0800971 newCfg = new AaaConfig();
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700972 } else {
973 newCfg = cfg;
974 }
975 if (newCfg.nasIp() != null) {
976 nasIpAddress = newCfg.nasIp();
977 }
978 if (newCfg.radiusIp() != null) {
979 radiusIpAddress = newCfg.radiusIp();
980 }
981 if (newCfg.radiusMac() != null) {
982 radiusMacAddress = newCfg.radiusMac();
983 }
984 if (newCfg.nasMac() != null) {
985 nasMacAddress = newCfg.nasMac();
986 }
987 if (newCfg.radiusSecret() != null) {
988 radiusSecret = newCfg.radiusSecret();
989 }
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100990
Deepa Vaddireddye0e10722017-09-27 05:00:10 +0530991 boolean reconfigureCustomizer = false;
992 if (customizer == null || !customizer.equals(newCfg.radiusPktCustomizer())) {
993 customizer = newCfg.radiusPktCustomizer();
994 configurePacketCustomizer();
995 reconfigureCustomizer = true;
996 }
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100997
Deepa Vaddireddye0e10722017-09-27 05:00:10 +0530998 if (radiusConnectionType == null
999 || reconfigureCustomizer
1000 || !radiusConnectionType.equals(newCfg.radiusConnectionType())) {
1001 radiusConnectionType = newCfg.radiusConnectionType();
1002 if (impl != null) {
1003 impl.withdrawIntercepts();
1004 impl.clearLocalState();
1005 }
1006 configureRadiusCommunication();
1007 impl.initializeLocalState(newCfg);
1008 impl.requestIntercepts();
1009 } else if (impl != null) {
Amit Ghoshc9ac1e52017-07-28 12:31:18 +01001010 impl.clearLocalState();
1011 impl.initializeLocalState(newCfg);
Ray Milkey5d99bd12015-10-06 15:41:30 -07001012 }
Ray Milkeyfcb623d2015-10-01 16:48:18 -07001013 }
1014
1015 @Override
1016 public void event(NetworkConfigEvent event) {
1017
1018 if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
1019 event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
Jonathan Hart092dfb22015-11-16 23:05:21 -08001020 event.configClass().equals(AaaConfig.class)) {
Ray Milkeyfcb623d2015-10-01 16:48:18 -07001021
Jonathan Hart092dfb22015-11-16 23:05:21 -08001022 AaaConfig cfg = netCfgService.getConfig(appId, AaaConfig.class);
Ray Milkeyfcb623d2015-10-01 16:48:18 -07001023 reconfigureNetwork(cfg);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +01001024
Matt Jeanneret2ff1a782018-06-13 15:24:25 -04001025 log.info("Reconfigured: {}", cfg.toString());
Ray Milkeyfcb623d2015-10-01 16:48:18 -07001026 }
1027 }
1028 }
Amit Ghoshf739be52017-09-21 15:49:37 +01001029
Jonathan Hart9d1ce802020-01-28 10:45:08 -08001030 private class InternalMapEventListener implements MapEventListener<ConnectPoint, AuthenticationRecord> {
1031 @Override
1032 public void event(MapEvent<ConnectPoint, AuthenticationRecord> event) {
1033 if (event.type() == MapEvent.Type.REMOVE) {
1034 // remove local state machine if user has requested remove
1035 StateMachine sm = stateMachines.remove(sessionId(event.key()));
1036 if (sm != null) {
1037 sm.stop();
1038 }
1039 }
1040 }
1041 }
1042
Amit Ghoshf739be52017-09-21 15:49:37 +01001043 private class InternalDeviceListener implements DeviceListener {
1044 @Override
1045 public void event(DeviceEvent event) {
1046
1047 switch (event.type()) {
1048 case PORT_REMOVED:
1049 DeviceId devId = event.subject().id();
1050 PortNumber portNumber = event.port().number();
1051 String sessionId = devId.toString() + portNumber.toString();
1052
Jonathan Hart612651f2019-11-25 09:21:43 -08001053 StateMachine stateMachine = stateMachines.get(sessionId);
Kartikey Dubeyadeb26e2019-10-01 12:18:35 +00001054 if (stateMachine != null) {
1055 stateMachine.setSessionTerminateReason(
1056 StateMachine.SessionTerminationReasons.PORT_REMOVED.getReason());
1057 }
1058 //pushing captured machine stats to kafka
1059 AaaSupplicantMachineStats obj = aaaSupplicantStatsManager.getSupplicantStats(stateMachine);
1060 aaaSupplicantStatsManager.getMachineStatsDelegate()
1061 .notify(new AaaMachineStatisticsEvent(AaaMachineStatisticsEvent.Type.STATS_UPDATE, obj));
1062
Jonathan Hart612651f2019-11-25 09:21:43 -08001063 StateMachine removed = stateMachines.remove(sessionId);
Amit Ghoshf739be52017-09-21 15:49:37 +01001064 if (removed != null) {
1065 StateMachine.deleteStateMachineMapping(removed);
1066 }
1067
1068 break;
1069 default:
1070 return;
1071 }
1072 }
1073 }
kartikey dubeye1545422019-05-22 12:53:45 +00001074 private class AuthenticationStatisticsEventPublisher implements Runnable {
1075 private final Logger log = getLogger(getClass());
1076 public void run() {
1077 log.info("Notifying AuthenticationStatisticsEvent");
1078 aaaStatisticsManager.calculatePacketRoundtripTime();
1079 log.debug("AcceptResponsesRx---" + aaaStatisticsManager.getAaaStats().getAcceptResponsesRx());
1080 log.debug("AccessRequestsTx---" + aaaStatisticsManager.getAaaStats().getAccessRequestsTx());
1081 log.debug("ChallengeResponsesRx---" + aaaStatisticsManager.getAaaStats().getChallengeResponsesRx());
1082 log.debug("DroppedResponsesRx---" + aaaStatisticsManager.getAaaStats().getDroppedResponsesRx());
1083 log.debug("InvalidValidatorsRx---" + aaaStatisticsManager.getAaaStats().getInvalidValidatorsRx());
1084 log.debug("MalformedResponsesRx---" + aaaStatisticsManager.getAaaStats().getMalformedResponsesRx());
1085 log.debug("PendingRequests---" + aaaStatisticsManager.getAaaStats().getPendingRequests());
1086 log.debug("RejectResponsesRx---" + aaaStatisticsManager.getAaaStats().getRejectResponsesRx());
1087 log.debug("RequestReTx---" + aaaStatisticsManager.getAaaStats().getRequestReTx());
1088 log.debug("RequestRttMilis---" + aaaStatisticsManager.getAaaStats().getRequestRttMilis());
1089 log.debug("UnknownServerRx---" + aaaStatisticsManager.getAaaStats().getUnknownServerRx());
1090 log.debug("UnknownTypeRx---" + aaaStatisticsManager.getAaaStats().getUnknownTypeRx());
Shubham Sharma1e43c562019-06-19 14:18:12 +00001091 log.debug("TimedOutPackets----" + aaaStatisticsManager.getAaaStats().getTimedOutPackets());
Shubham Sharma1f193582019-07-11 12:12:41 +00001092 log.debug("EapolLogoffRx---" + aaaStatisticsManager.getAaaStats().getEapolLogoffRx());
1093 log.debug("EapolAuthSuccessTrans---" + aaaStatisticsManager.getAaaStats().getEapolAuthSuccessTrans());
1094 log.debug("EapolAuthFailureTrans---" +
1095 aaaStatisticsManager.getAaaStats().getEapolAuthFailureTrans());
1096 log.debug("EapolStartReqTrans---" +
1097 aaaStatisticsManager.getAaaStats().getEapolStartReqTrans());
1098 log.debug("EapolTransRespNotNak---" +
1099 aaaStatisticsManager.getAaaStats().getEapolTransRespNotNak());
1100 log.debug("EapPktTxauthChooseEap---" +
1101 aaaStatisticsManager.getAaaStats().getEapPktTxauthChooseEap());
1102 log.debug("EapolResIdentityMsgTrans---" +
1103 aaaStatisticsManager.getAaaStats().getEapolResIdentityMsgTrans());
Shubham Sharma3c8c7022019-09-13 10:39:47 +00001104 log.debug("EapolFramesTx---" + aaaStatisticsManager.getAaaStats().getEapolFramesTx());
1105 log.debug("AuthStateIdle---" + aaaStatisticsManager.getAaaStats().getAuthStateIdle());
1106 log.debug("RequestIdFramesTx---" + aaaStatisticsManager.getAaaStats().getRequestIdFramesTx());
1107 log.debug("ReqEapFramesTx---" + aaaStatisticsManager.getAaaStats().getReqEapFramesTx());
1108 log.debug("InvalidPktType---" + aaaStatisticsManager.getAaaStats().getInvalidPktType());
1109 log.debug("InvalidBodyLength---" + aaaStatisticsManager.getAaaStats().getInvalidBodyLength());
1110 log.debug("ValidEapolFramesRx---" + aaaStatisticsManager.getAaaStats().getValidEapolFramesRx());
1111 log.debug("PendingResSupp---" + aaaStatisticsManager.getAaaStats().getPendingResSupp());
1112 log.debug("ResIdEapFramesRx---" + aaaStatisticsManager.getAaaStats().getEapolattrIdentity());
kartikey dubeye1545422019-05-22 12:53:45 +00001113 aaaStatisticsManager.getStatsDelegate().
1114 notify(new AuthenticationStatisticsEvent(AuthenticationStatisticsEvent.Type.STATS_UPDATE,
1115 aaaStatisticsManager.getAaaStats()));
1116 }
Shubham Sharma4900ce62019-06-19 14:18:50 +00001117 }
1118
1119 private class ServerStatusChecker implements Runnable {
1120 @Override
1121 public void run() {
Matteo Scandolo3498bc02020-01-08 09:54:12 -08001122 log.debug("Notifying RadiusOperationalStatusEvent");
Shubham Sharma4900ce62019-06-19 14:18:50 +00001123 radiusOperationalStatusService.checkServerOperationalStatus();
Matteo Scandolo3498bc02020-01-08 09:54:12 -08001124 log.trace("--POSTING--" + radiusOperationalStatusService.getRadiusServerOperationalStatus());
Shubham Sharma4900ce62019-06-19 14:18:50 +00001125 radiusOperationalStatusService.getRadiusOprStDelegate()
1126 .notify(new RadiusOperationalStatusEvent(
1127 RadiusOperationalStatusEvent.Type.RADIUS_OPERATIONAL_STATUS,
1128 radiusOperationalStatusService.
1129 getRadiusServerOperationalStatus()));
kartikey dubeye1545422019-05-22 12:53:45 +00001130 }
Shubham Sharma4900ce62019-06-19 14:18:50 +00001131
1132 }
Jonathan Hart612651f2019-11-25 09:21:43 -08001133}