blob: 3be3f4cdc66a89ff2f854979a04d9ae3548b329f [file] [log] [blame]
Shubham Sharma1ad16632019-11-26 11:09:21 +00001/*
2 * Copyright 2015-present Open Networking Foundation
3 *
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 */
16package org.opencord.aaa.impl;
17
18import com.google.common.base.Charsets;
19import org.junit.After;
20import org.junit.Before;
21import org.junit.Test;
22import org.onlab.junit.TestUtils;
23import org.onlab.packet.BasePacket;
24import org.onlab.packet.DeserializationException;
25import org.onlab.packet.EAP;
26import org.onlab.packet.Ethernet;
Sonal Kasliwal6f2246d2020-01-30 08:42:42 +000027import org.onlab.packet.Ip4Address;
Shubham Sharma1ad16632019-11-26 11:09:21 +000028import org.onlab.packet.IpAddress;
29import org.onlab.packet.RADIUS;
30import org.onlab.packet.RADIUSAttribute;
31import org.onosproject.core.ApplicationId;
32import org.onosproject.core.CoreServiceAdapter;
33import org.onosproject.event.DefaultEventSinkRegistry;
34import org.onosproject.event.Event;
35import org.onosproject.event.EventDeliveryService;
36import org.onosproject.event.EventSink;
Sonal Kasliwal6f2246d2020-01-30 08:42:42 +000037import org.onosproject.net.AnnotationKeys;
38import org.onosproject.net.Annotations;
39import org.onosproject.net.DefaultAnnotations;
40import org.onosproject.net.DefaultDevice;
41import org.onosproject.net.DefaultPort;
42import org.onosproject.net.Device;
43import org.onosproject.net.DeviceId;
44import org.onosproject.net.Port;
45import org.onosproject.net.SparseAnnotations;
46import org.onosproject.net.Port.Type;
47import org.onosproject.net.PortNumber;
Shubham Sharma1ad16632019-11-26 11:09:21 +000048import org.onosproject.net.config.Config;
49import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Sonal Kasliwal6f2246d2020-01-30 08:42:42 +000050import org.onosproject.net.device.DeviceEvent;
Shubham Sharma1ad16632019-11-26 11:09:21 +000051import org.onosproject.net.packet.DefaultInboundPacket;
52import org.onosproject.net.packet.InboundPacket;
53import org.onosproject.net.packet.PacketContext;
54import org.onosproject.net.packet.PacketService;
55import org.opencord.aaa.AaaConfig;
Sonal Kasliwal6f2246d2020-01-30 08:42:42 +000056import org.opencord.aaa.AaaSupplicantMachineStats;
Shubham Sharma1ad16632019-11-26 11:09:21 +000057import org.slf4j.Logger;
58
59import java.lang.reflect.Field;
60import java.net.InetAddress;
61import java.net.UnknownHostException;
62import java.nio.ByteBuffer;
63
64import static com.google.common.base.Preconditions.checkState;
65import static org.hamcrest.Matchers.is;
66import static org.hamcrest.Matchers.notNullValue;
Sonal Kasliwal6f2246d2020-01-30 08:42:42 +000067import static org.junit.Assert.assertEquals;
Shubham Sharmac7aa6202019-12-12 10:19:10 +000068import static org.junit.Assert.assertNotEquals;
Shubham Sharma1ad16632019-11-26 11:09:21 +000069import static org.junit.Assert.assertThat;
70import static org.onosproject.net.NetTestTools.connectPoint;
71import static org.slf4j.LoggerFactory.getLogger;
72
73/**
74 * Set of tests of the ONOS application component for AAA Statistics.
75 */
76public class AaaStatisticsTest extends AaaTestBase {
77
78 static final String BAD_IP_ADDRESS = "198.51.100.0";
Shubham Sharmac7aa6202019-12-12 10:19:10 +000079 static final Long ZERO = (long) 0;
Shubham Sharma1ad16632019-11-26 11:09:21 +000080
81 private final Logger log = getLogger(getClass());
82 private AaaManager aaaManager;
83 private AaaStatisticsManager aaaStatisticsManager;
Kartikey Dubeybe14f472019-10-01 12:18:35 +000084 private AaaSupplicantMachineStatsManager aaaSupplicantStatsManager;
Shubham Sharma1ad16632019-11-26 11:09:21 +000085
86 class AaaManagerWithoutRadiusServer extends AaaManager {
87 protected void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
88 super.sendRadiusPacket(radiusPacket, inPkt);
89 aaaManager.aaaStatisticsManager.putOutgoingIdentifierToMap(radiusPacket.getIdentifier());
90 savePacket(radiusPacket);
91 }
92
93 // changed the configuration of parent method to protected
94 protected void configureRadiusCommunication() {
95 PacketService pktService = new MockPacketService();
96 ApplicationId appId = new CoreServiceAdapter().registerApplication("org.opencord.aaa");
97 aaaManager.impl = new TestSocketBasedRadiusCommunicator(appId, pktService, aaaManager);
98 }
99 }
100
101 /**
102 * Mocks the AAAConfig class to force usage of an unroutable address for the
103 * RADIUS server.
104 */
105 static class MockAaaConfig extends AaaConfig {
106 @Override
107 public InetAddress radiusIp() {
108 try {
109 return InetAddress.getByName(BAD_IP_ADDRESS);
110 } catch (UnknownHostException ex) {
111 throw new IllegalStateException(ex);
112 }
113 }
114 }
115
116 /**
117 * Mocks the network config registry.
118 */
119 @SuppressWarnings("unchecked")
120 private static final class TestNetworkConfigRegistry extends NetworkConfigRegistryAdapter {
121 @Override
122 public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
123 AaaConfig aaaConfig = new MockAaaConfig();
124 return (C) aaaConfig;
125 }
126 }
127
128 public static class TestEventDispatcher extends DefaultEventSinkRegistry implements EventDeliveryService {
129
130 @Override
131 @SuppressWarnings("unchecked")
132 public synchronized void post(Event event) {
133 EventSink sink = getSink(event.getClass());
134 checkState(sink != null, "No sink for event %s", event);
135 sink.process(event);
136 }
137
138 @Override
139 public void setDispatchTimeLimit(long millis) {
140 }
141
142 @Override
143 public long getDispatchTimeLimit() {
144 return 0;
145 }
146 }
147
148 /**
149 * Constructs an Ethernet packet containing a RADIUS challenge packet.
150 *
151 * @param challengeCode
152 * code to use in challenge packet
153 * @param challengeType
154 * type to use in challenge packet
155 * @return Ethernet packet
156 */
157 private RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType) {
158
Shubham Sharma048cc262019-06-19 14:18:50 +0000159 String challenge = "12345678901234567";
Shubham Sharma1ad16632019-11-26 11:09:21 +0000160
Shubham Sharma048cc262019-06-19 14:18:50 +0000161 EAP eap = new EAP(challengeType, (byte) 4, challengeType,
162 challenge.getBytes(Charsets.US_ASCII));
163 eap.setIdentifier((byte) 4);
Shubham Sharma1ad16632019-11-26 11:09:21 +0000164
Shubham Sharma048cc262019-06-19 14:18:50 +0000165 RADIUS radius = new RADIUS();
166 radius.setCode(challengeCode);
167 radius.setIdentifier((byte) 4);
168 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
169 challenge.getBytes(Charsets.US_ASCII));
Shubham Sharma1ad16632019-11-26 11:09:21 +0000170
Shubham Sharma048cc262019-06-19 14:18:50 +0000171 radius.setPayload(eap);
172 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE,
173 eap.serialize());
174 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH,
175 aaaManager.radiusSecret.getBytes());
176 return radius;
Shubham Sharma1ad16632019-11-26 11:09:21 +0000177 }
178
179 public static void injectEventDispatcher(Object manager, EventDeliveryService svc) {
180 Class mc = manager.getClass();
181 for (Field f : mc.getSuperclass().getDeclaredFields()) {
182 if (f.getType().equals(EventDeliveryService.class)) {
183 try {
184 TestUtils.setField(manager, f.getName(), svc);
185 } catch (TestUtils.TestUtilsException e) {
186 throw new IllegalArgumentException("Unable to inject reference", e);
187 }
188 break;
189 }
190 }
191 }
192
193/**
194 * Set up the services required by the AAA application.
195 */
196 @Before
197 public void setUp() {
198 aaaManager = new AaaManagerWithoutRadiusServer();
Shubham Sharma048cc262019-06-19 14:18:50 +0000199 aaaManager.radiusOperationalStatusService = new RadiusOperationalStatusManager();
Shubham Sharma1ad16632019-11-26 11:09:21 +0000200 aaaManager.netCfgService = new TestNetworkConfigRegistry();
201 aaaManager.coreService = new CoreServiceAdapter();
202 aaaManager.packetService = new MockPacketService();
203 aaaManager.deviceService = new TestDeviceService();
204 aaaManager.sadisService = new MockSadisService();
205 aaaManager.cfgService = new MockCfgService();
206 aaaStatisticsManager = new AaaStatisticsManager();
Kartikey Dubeybe14f472019-10-01 12:18:35 +0000207 aaaSupplicantStatsManager = new AaaSupplicantMachineStatsManager();
Shubham Sharma1ad16632019-11-26 11:09:21 +0000208 TestUtils.setField(aaaStatisticsManager, "eventDispatcher", new TestEventDispatcher());
209 aaaStatisticsManager.activate();
Kartikey Dubeybe14f472019-10-01 12:18:35 +0000210 TestUtils.setField(aaaSupplicantStatsManager, "eventDispatcher", new TestEventDispatcher());
211 aaaSupplicantStatsManager.activate();
Shubham Sharma1ad16632019-11-26 11:09:21 +0000212 aaaManager.aaaStatisticsManager = this.aaaStatisticsManager;
Kartikey Dubeybe14f472019-10-01 12:18:35 +0000213 aaaManager.aaaSupplicantStatsManager = this.aaaSupplicantStatsManager;
Shubham Sharma1ad16632019-11-26 11:09:21 +0000214 TestUtils.setField(aaaManager, "eventDispatcher", new TestEventDispatcher());
215 aaaManager.activate(new AaaTestBase.MockComponentContext());
216 }
217
218/**
219 * Tear down the AAA application.
220 */
221@After
222public void tearDown() {
223 aaaManager.deactivate(new AaaTestBase.MockComponentContext());
224}
225
226/**
227 * Extracts the RADIUS packet from a packet sent by the supplicant.
228 *
229 * @param radius
230 * RADIUS packet sent by the supplicant
231 * @throws DeserializationException
232 * if deserialization of the packet contents fails.
233 */
234private void checkRadiusPacketFromSupplicant(RADIUS radius) throws DeserializationException {
235 assertThat(radius, notNullValue());
236 EAP eap = radius.decapsulateMessage();
237 assertThat(eap, notNullValue());
238}
239
240/**
241 * Fetches the sent packet at the given index. The requested packet must be the
242 * last packet on the list.
243 *
244 * @param index
245 * index into sent packets array
246 * @return packet
247 */
248private BasePacket fetchPacket(int index) {
249 BasePacket packet = savedPackets.get(index);
250 assertThat(packet, notNullValue());
251 return packet;
252}
253
254 /** Tests the authentication path through the AAA application.
255 * And counts the aaa Stats for successful transmission.
256 * @throws DeserializationException
257 * if packed deserialization fails.
258 */
259 @Test
260 public void testAaaStatisticsForAcceptedPackets() throws Exception {
261
262 // (1) Supplicant start up
263 Ethernet startPacket = constructSupplicantStartPacket();
264 sendPacket(startPacket);
265
266 Ethernet responsePacket = (Ethernet) fetchPacket(0);
267 checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY);
268
269 // (2) Supplicant identify
270
271 Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
272 sendPacket(identifyPacket);
273
274 RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
275 checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
276
277 assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
278 assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()),
279 is("testuser"));
280 IpAddress nasIp = IpAddress.valueOf(IpAddress.Version.INET,
281 radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP).getValue());
282 assertThat(nasIp.toString(), is(aaaManager.nasIpAddress.getHostAddress()));
283
284 // State machine should have been created by now
285
286 StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(SESSION_ID);
287 assertThat(stateMachine, notNullValue());
288 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
289
290 // (3) RADIUS MD5 challenge
291
292 RADIUS radiusCodeAccessChallengePacket = constructRadiusCodeAccessChallengePacket(
293 RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5);
294 aaaManager.handleRadiusPacket(radiusCodeAccessChallengePacket);
295
296 Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2);
297 checkRadiusPacket(aaaManager, radiusChallengeMD5Packet, EAP.ATTR_MD5);
298
299 // (4) Supplicant MD5 response
300
301 Ethernet md5RadiusPacket = constructSupplicantIdentifyPacket(stateMachine, EAP.ATTR_MD5,
302 stateMachine.challengeIdentifier(), radiusChallengeMD5Packet);
303 sendPacket(md5RadiusPacket);
304
305 RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3);
306
307 checkRadiusPacketFromSupplicant(responseMd5RadiusPacket);
Shubham Sharma048cc262019-06-19 14:18:50 +0000308 assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 9));
Shubham Sharma1ad16632019-11-26 11:09:21 +0000309 assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
310
311 // State machine should be in pending state
312
313 assertThat(stateMachine, notNullValue());
314 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
315
316 // (5) RADIUS Success
317
318 RADIUS successPacket =
319 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT, EAP.SUCCESS);
320 aaaManager.handleRadiusPacket((successPacket));
321 Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4);
322
323 checkRadiusPacket(aaaManager, supplicantSuccessPacket, EAP.SUCCESS);
324
325 // State machine should be in authorized state
326
327 assertThat(stateMachine, notNullValue());
328 assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED));
329
Shubham Sharmac7aa6202019-12-12 10:19:10 +0000330 //Check for increase of Stats
331 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolResIdentityMsgTrans(), ZERO);
332 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolAuthSuccessTrans(), ZERO);
333 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolStartReqTrans(), ZERO);
334 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolTransRespNotNak(), ZERO);
335 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapPktTxauthChooseEap(), ZERO);
336
Shubham Sharma1bd890d2019-12-18 07:09:59 +0000337 assertNotEquals(aaaStatisticsManager.getAaaStats().getAcceptResponsesRx(), ZERO);
338 assertNotEquals(aaaStatisticsManager.getAaaStats().getAccessRequestsTx(), ZERO);
339 assertNotEquals(aaaStatisticsManager.getAaaStats().getChallengeResponsesRx(), ZERO);
340 assertNotEquals(aaaStatisticsManager.getAaaStats().getDroppedResponsesRx(), ZERO);
341 assertNotEquals(aaaStatisticsManager.getAaaStats().getInvalidValidatorsRx(), ZERO);
342 assertNotEquals(aaaStatisticsManager.getAaaStats().getPendingRequests(), ZERO);
Shubham Sharma1ad16632019-11-26 11:09:21 +0000343
Shubham Sharma1bd890d2019-12-18 07:09:59 +0000344 // Counts the aaa Statistics count and displays in the log
345 countAaaStatistics();
Shubham Sharma1ad16632019-11-26 11:09:21 +0000346 }
347
348 /** Tests the count for defected packets.
349 *
350 * @throws DeserializationException
351 * if packed deserialization fails.
352 */
353 @Test
354 public void testAaaStatisticsForDefectivePackets() throws Exception {
355 // (1) Supplicant start up
356 Ethernet startPacket = constructSupplicantStartPacket();
357 sendPacket(startPacket);
358
359 // (2) Supplicant identify
360
361 Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
362 sendPacket(identifyPacket);
363
364 RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
365
366 checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
367
368 // Calling the mock test socket based to handle packet
369 aaaManager.impl.handlePacketFromServer(null);
370 // State machine should have been created by now
371
372 StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(SESSION_ID);
373
374 // (3) RADIUS MD5 challenge
375
376 RADIUS radiusCodeAccessChallengePacket = constructRadiusCodeAccessChallengePacket(
377 RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5);
378 aaaManager.handleRadiusPacket(radiusCodeAccessChallengePacket);
379
380 Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2);
381
382 // (4) Supplicant MD5 response
383
384 Ethernet md5RadiusPacket = constructSupplicantIdentifyPacket(stateMachine, EAP.ATTR_MD5,
385 stateMachine.challengeIdentifier(), radiusChallengeMD5Packet);
386 sendPacket(md5RadiusPacket);
387 aaaManager.aaaStatisticsManager.calculatePacketRoundtripTime();
388 // (5) RADIUS Rejected
389
390 RADIUS rejectedPacket =
391 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_REJECT, EAP.FAILURE);
392 aaaManager.handleRadiusPacket((rejectedPacket));
393 Ethernet supplicantRejectedPacket = (Ethernet) fetchPacket(4);
394
395 checkRadiusPacket(aaaManager, supplicantRejectedPacket, EAP.FAILURE);
396
397 // State machine should be in unauthorized state
398 assertThat(stateMachine, notNullValue());
399 assertThat(stateMachine.state(), is(StateMachine.STATE_UNAUTHORIZED));
400 // Calculated the total round trip time
401 aaaManager.aaaStatisticsManager.calculatePacketRoundtripTime();
Shubham Sharmac7aa6202019-12-12 10:19:10 +0000402
403 //Check for increase of Stats
404 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolResIdentityMsgTrans(), ZERO);
405 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolAuthFailureTrans(), ZERO);
406 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolStartReqTrans(), ZERO);
407 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapPktTxauthChooseEap(), ZERO);
408 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolTransRespNotNak(), ZERO);
409
Shubham Sharma1bd890d2019-12-18 07:09:59 +0000410 assertNotEquals(aaaStatisticsManager.getAaaStats().getAccessRequestsTx(), ZERO);
411 assertNotEquals(aaaStatisticsManager.getAaaStats().getChallengeResponsesRx(), ZERO);
412 assertNotEquals(aaaStatisticsManager.getAaaStats().getDroppedResponsesRx(), ZERO);
413 assertNotEquals(aaaStatisticsManager.getAaaStats().getInvalidValidatorsRx(), ZERO);
414 assertNotEquals(aaaStatisticsManager.getAaaStats().getPendingRequests(), ZERO);
415 assertNotEquals(aaaStatisticsManager.getAaaStats().getRejectResponsesRx(), ZERO);
416 assertNotEquals(aaaStatisticsManager.getAaaStats().getRequestRttMilis(), ZERO);
417 assertNotEquals(aaaStatisticsManager.getAaaStats().getUnknownTypeRx(), ZERO);
418
Shubham Sharmac7aa6202019-12-12 10:19:10 +0000419 // Counts the aaa Statistics count
Shubham Sharma1ad16632019-11-26 11:09:21 +0000420 countAaaStatistics();
421
422 }
423
424 /*
425 * Tests the retransmitted packet and malformed packet count
426 *
427 * @throws DeserializationException
428 * if packed deserialization fails.
429 */
430 @Test
431 public void testRequestRetransmittedCount() throws Exception {
432
433 // (1) Supplicant start up
434 Ethernet startPacket = constructSupplicantStartPacket();
435 sendPacket(startPacket);
436
437 // (2) Supplicant identify
438
439 Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
440 sendPacket(identifyPacket);
441
442 RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
443 checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
444
445 // again creating pending state for same packet
446 constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
447 sendPacket(identifyPacket);
448 aaaManager.impl.handlePacketFromServer(null);
449 aaaManager.aaaStatisticsManager.calculatePacketRoundtripTime();
450
451 // creating malformed packet
452 final ByteBuffer byteBuffer = ByteBuffer.wrap(startPacket.serialize());
453 InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
454 startPacket, byteBuffer);
455
456 PacketContext context = new TestPacketContext(127L, inPacket, null, false);
457 aaaManager.impl.handlePacketFromServer(context);
Shubham Sharmac7aa6202019-12-12 10:19:10 +0000458
459 // Check for increase of Stats
460 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolResIdentityMsgTrans(), ZERO);
461 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolStartReqTrans(), ZERO);
462
Shubham Sharma1bd890d2019-12-18 07:09:59 +0000463 assertNotEquals(aaaStatisticsManager.getAaaStats().getAccessRequestsTx(), ZERO);
464 assertNotEquals(aaaStatisticsManager.getAaaStats().getDroppedResponsesRx(), ZERO);
465 assertNotEquals(aaaStatisticsManager.getAaaStats().getPendingRequests(), ZERO);
466 assertNotEquals(aaaStatisticsManager.getAaaStats().getMalformedResponsesRx(), ZERO);
467 assertNotEquals(aaaStatisticsManager.getAaaStats().getRequestReTx(), ZERO);
468 assertNotEquals(aaaStatisticsManager.getAaaStats().getRequestRttMilis(), ZERO);
469 assertNotEquals(aaaStatisticsManager.getAaaStats().getUnknownTypeRx(), ZERO);
470 assertNotEquals(aaaStatisticsManager.getAaaStats().getUnknownServerRx(), ZERO);
Shubham Sharma1ad16632019-11-26 11:09:21 +0000471
Shubham Sharma1bd890d2019-12-18 07:09:59 +0000472 countAaaStatistics();
473 }
Shubham Sharma1ad16632019-11-26 11:09:21 +0000474
Shubham Sharmac7aa6202019-12-12 10:19:10 +0000475 /** Tests the authentication path through the AAA application.
476 * And counts the aaa Stats for logoff transactionXZ.
477 * @throws DeserializationException
478 * if packed deserialization fails.
479 */
480 @Test
481 public void testAaaStatisticsForLogoffPackets() throws Exception {
482
483 // (1) Supplicant start up
484 Ethernet startPacket = constructSupplicantStartPacket();
485 sendPacket(startPacket);
486
487 Ethernet responsePacket = (Ethernet) fetchPacket(0);
488 checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY);
489
490 // (2) Supplicant identify
491
492 Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
493 sendPacket(identifyPacket);
494
495 RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
496 checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
497
498 assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
499 assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()),
500 is("testuser"));
501 IpAddress nasIp = IpAddress.valueOf(IpAddress.Version.INET,
502 radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP).getValue());
503 assertThat(nasIp.toString(), is(aaaManager.nasIpAddress.getHostAddress()));
504
505 // State machine should have been created by now
506
507 StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(SESSION_ID);
508 assertThat(stateMachine, notNullValue());
509 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
510
511 // (3) RADIUS MD5 challenge
512
513 RADIUS radiusCodeAccessChallengePacket = constructRadiusCodeAccessChallengePacket(
514 RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5);
515 aaaManager.handleRadiusPacket(radiusCodeAccessChallengePacket);
516
517 Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2);
518 checkRadiusPacket(aaaManager, radiusChallengeMD5Packet, EAP.ATTR_MD5);
519
520 // (4) Supplicant MD5 response
521
522 Ethernet md5RadiusPacket = constructSupplicantIdentifyPacket(stateMachine, EAP.ATTR_MD5,
523 stateMachine.challengeIdentifier(), radiusChallengeMD5Packet);
524 sendPacket(md5RadiusPacket);
525
526 RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3);
527
528 checkRadiusPacketFromSupplicant(responseMd5RadiusPacket);
529 assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 9));
530 assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
531
532 // State machine should be in pending state
533
534 assertThat(stateMachine, notNullValue());
535 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
536
537 // (5) RADIUS Success
538
539 RADIUS successPacket =
540 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT, EAP.SUCCESS);
541 aaaManager.handleRadiusPacket((successPacket));
542 Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4);
543
544 checkRadiusPacket(aaaManager, supplicantSuccessPacket, EAP.SUCCESS);
545
546 // State machine should be in authorized state
547
548 assertThat(stateMachine, notNullValue());
549 assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED));
550
551 // Supplicant trigger EAP Logoff
552 Ethernet loggoffPacket = constructSupplicantLogoffPacket();
553 sendPacket(loggoffPacket);
554
555 // State machine should be in logoff state
556 assertThat(stateMachine, notNullValue());
557 assertThat(stateMachine.state(), is(StateMachine.STATE_IDLE));
558
559 //Check for increase in stats
560 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolLogoffRx(), ZERO);
561 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolResIdentityMsgTrans(), ZERO);
562 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolAuthSuccessTrans(), ZERO);
563 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolStartReqTrans(), ZERO);
564 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolTransRespNotNak(), ZERO);
565 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapPktTxauthChooseEap(), ZERO);
566 // Counts the aaa Statistics count
567 countAaaStatistics();
568
569 }
570
Arjun E Kac463f62020-02-03 14:05:45 +0000571 /** Tests the authentication path through the AAA application.
572 * And counts the aaa Stats for timeout.
573 * @throws DeserializationException
574 * if packed deserialization fails.
575 */
576 @Test
577 public void testAaaStatisticsForTimeoutPackets() throws Exception {
578
579 // (1) Supplicant start up
580 Ethernet startPacket = constructSupplicantStartPacket();
581 sendPacket(startPacket);
582
583 Ethernet responsePacket = (Ethernet) fetchPacket(0);
584 checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY);
585
586 // (2) Supplicant identify
587
588 Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
589 sendPacket(identifyPacket);
590
591 RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
592 checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
593
594 assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
595 assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()),
596 is("testuser"));
597 IpAddress nasIp = IpAddress.valueOf(IpAddress.Version.INET,
598 radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP).getValue());
599 assertThat(nasIp.toString(), is(aaaManager.nasIpAddress.getHostAddress()));
600
601 // State machine should have been created by now
602
603 StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(SESSION_ID);
604 assertThat(stateMachine, notNullValue());
605 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
606 Thread.sleep((aaaManager.cleanupTimerTimeOutInMins / 2) + 1);
607
608 // State machine should be in timeout state
609 assertThat(stateMachine, notNullValue());
610 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
611
612 //Check for increase in stats
613 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolResIdentityMsgTrans(), ZERO);
614 assertNotEquals(aaaStatisticsManager.getAaaStats().getEapolStartReqTrans(), ZERO);
615 countAaaStatistics();
616
617 }
618
Sonal Kasliwal6f2246d2020-01-30 08:42:42 +0000619
620 /** Tests the authentication path through the AAA application.
621 * And counts the aaa Stats for logoff transactionXZ.
622 * @throws DeserializationException
623 * if packed deserialization fails.
624 */
625 @Test
626 public void testAaaSuplicantStatsForEapolLogOff() throws Exception {
627
628 // (1) Supplicant start up
629 Ethernet startPacket = constructSupplicantStartPacket();
630 sendPacket(startPacket);
631
632 Ethernet responsePacket = (Ethernet) fetchPacket(0);
633 checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY);
634
635 // (2) Supplicant identify
636
637 Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
638 sendPacket(identifyPacket);
639
640 RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
641 checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
642
643 // State machine should have been created by now
644
645 StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(SESSION_ID);
646
647 // (3) RADIUS MD5 challenge
648
649 RADIUS radiusCodeAccessChallengePacket = constructRadiusCodeAccessChallengePacket(
650 RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5);
651 aaaManager.handleRadiusPacket(radiusCodeAccessChallengePacket);
652
653 Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2);
654 checkRadiusPacket(aaaManager, radiusChallengeMD5Packet, EAP.ATTR_MD5);
655
656 // (4) Supplicant MD5 response
657
658 Ethernet md5RadiusPacket = constructSupplicantIdentifyPacket(stateMachine, EAP.ATTR_MD5,
659 stateMachine.challengeIdentifier(), radiusChallengeMD5Packet);
660 sendPacket(md5RadiusPacket);
661
662 RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3);
663
664 checkRadiusPacketFromSupplicant(responseMd5RadiusPacket);
665
666 // (5) RADIUS Success
667
668 RADIUS successPacket =
669 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT, EAP.SUCCESS);
670 aaaManager.handleRadiusPacket((successPacket));
671 Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4);
672
673 checkRadiusPacket(aaaManager, supplicantSuccessPacket, EAP.SUCCESS);
674
675 // Supplicant trigger EAP Logoff
676 Ethernet loggoffPacket = constructSupplicantLogoffPacket();
677 sendPacket(loggoffPacket);
678 AaaSupplicantMachineStats aaaSupplicantObj = aaaSupplicantStatsManager.getSupplicantStats(stateMachine);
679
680 // Check the aaa supplicant stats.
681 assertEquals(aaaSupplicantObj.getSessionTerminateReason(), "SUPPLICANT_LOGOFF");
682 assertEquals(aaaSupplicantObj.getEapolType(), "EAPOL_LOGOFF");
683 assertNotEquals(aaaSupplicantObj.getSessionDuration(), 0);
684 assertEquals(aaaSupplicantObj.getSessionName(), "testuser");
685 assertEquals(aaaSupplicantObj.getSessionId(), SESSION_ID);
686 assertEquals(aaaSupplicantObj.getSrcMacAddress(), serverMac.toString());
687 assertNotEquals(aaaSupplicantObj.getTotalFramesReceived(), 0);
688 assertNotEquals(aaaSupplicantObj.getTotalFramesSent(), 0);
689 assertNotEquals(aaaSupplicantObj.getTotalPacketsRecieved(), 0);
690 assertNotEquals(aaaSupplicantObj.getTotalPacketsSent(), 0);
691 }
692
693
694 @Test
695 public void testAaaSuplicantStatsForPortRemoved() throws Exception {
696
697 // (1) Supplicant start up
698 Ethernet startPacket = constructSupplicantStartPacket();
699 sendPacket(startPacket);
700
701 Ethernet responsePacket = (Ethernet) fetchPacket(0);
702 checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY);
703
704 // (2) Supplicant identify
705
706 Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
707 sendPacket(identifyPacket);
708
709 RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
710 checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
711
712 // State machine should have been created by now
713 StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(SESSION_ID);
714
715 // Device configuration
716 DeviceId deviceId = DeviceId.deviceId("of:1");
717 // Source ip address of two different device.
718 Ip4Address sourceIp = Ip4Address.valueOf("10.177.125.4");
719 DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
720 .set(AnnotationKeys.MANAGEMENT_ADDRESS, sourceIp.toString());
721 SparseAnnotations annotations = annotationsBuilder.build();
722 Annotations[] deviceAnnotations = {annotations };
723 Device deviceA = new DefaultDevice(null, deviceId, Device.Type.OTHER, "", "", "", "", null, deviceAnnotations);
724 Port port =
725 new DefaultPort(null, PortNumber.portNumber(1), true, Type.COPPER, DefaultPort.DEFAULT_SPEED, annotations);
726 DeviceEvent deviceEvent = new DeviceEvent(DeviceEvent.Type.PORT_REMOVED, deviceA, port);
727 aaaManager.deviceListener.event(deviceEvent);
728 AaaSupplicantMachineStats aaaSupplicantObj = aaaSupplicantStatsManager.getSupplicantStats(stateMachine);
729
730 // Check the aaa supplicant stats.
731 assertEquals(aaaSupplicantObj.getSessionTerminateReason(), "PORT_REMOVED");
732 assertEquals(aaaSupplicantObj.getEapolType(), "EAPOL_PACKET");
733 assertNotEquals(aaaSupplicantObj.getSessionDuration(), 0);
734 assertEquals(aaaSupplicantObj.getSessionName(), "testuser");
735 assertEquals(aaaSupplicantObj.getSessionId(), SESSION_ID);
736 assertEquals(aaaSupplicantObj.getSrcMacAddress(), serverMac.toString());
737 assertEquals(aaaSupplicantObj.getTotalFramesReceived(), 0);
738 assertEquals(aaaSupplicantObj.getTotalFramesSent(), 0);
739 assertEquals(aaaSupplicantObj.getTotalPacketsRecieved(), 0);
740 assertEquals(aaaSupplicantObj.getTotalPacketsSent(), 0);
741 }
742
Shubham Sharma1ad16632019-11-26 11:09:21 +0000743 // Calculates the AAA statistics count.
744 public void countAaaStatistics() {
745 assertThat(aaaStatisticsManager.getAaaStats().getAcceptResponsesRx(), notNullValue());
746 assertThat(aaaStatisticsManager.getAaaStats().getAccessRequestsTx(), notNullValue());
747 assertThat(aaaStatisticsManager.getAaaStats().getChallengeResponsesRx(), notNullValue());
748 assertThat(aaaStatisticsManager.getAaaStats().getDroppedResponsesRx(), notNullValue());
749 assertThat(aaaStatisticsManager.getAaaStats().getInvalidValidatorsRx(), notNullValue());
750 assertThat(aaaStatisticsManager.getAaaStats().getMalformedResponsesRx(), notNullValue());
751 assertThat(aaaStatisticsManager.getAaaStats().getPendingRequests(), notNullValue());
752 assertThat(aaaStatisticsManager.getAaaStats().getRejectResponsesRx(), notNullValue());
753 assertThat(aaaStatisticsManager.getAaaStats().getRequestReTx(), notNullValue());
754 assertThat(aaaStatisticsManager.getAaaStats().getRequestRttMilis(), notNullValue());
755 assertThat(aaaStatisticsManager.getAaaStats().getUnknownServerRx(), notNullValue());
756 assertThat(aaaStatisticsManager.getAaaStats().getUnknownTypeRx(), notNullValue());
Shubham Sharmac7aa6202019-12-12 10:19:10 +0000757
Shubham Sharma1ad16632019-11-26 11:09:21 +0000758 }
759
760 /*
761 * Mock implementation of SocketBasedRadiusCommunicator class.
762 *
763 */
764 class TestSocketBasedRadiusCommunicator extends SocketBasedRadiusCommunicator {
765
766 TestSocketBasedRadiusCommunicator(ApplicationId appId, PacketService pktService, AaaManager aaaManager) {
767 super(appId, pktService, aaaManager);
768 }
769
770 // Implementation of socketBasedRadiusCommunicator--> run() method
771 public void handlePacketFromServer(PacketContext context) {
772
773 RADIUS incomingPkt = (RADIUS) fetchPacket(savedPackets.size() - 1);
774 try {
775 if (context == null) {
776 aaaStatisticsManager.handleRoundtripTime(incomingPkt.getIdentifier());
777 aaaManager.handleRadiusPacket(incomingPkt);
778 } else if (null != context) {
779 aaaManager.checkForPacketFromUnknownServer("100.100.100.0");
780 aaaStatisticsManager.handleRoundtripTime(incomingPkt.getIdentifier());
781 aaaManager.handleRadiusPacket(incomingPkt);
782 incomingPkt =
783 RADIUS.deserializer().deserialize(incomingPkt.generateAuthCode(), 0, 1);
784 }
785 } catch (DeserializationException dex) {
786 aaaManager.aaaStatisticsManager.getAaaStats().increaseMalformedResponsesRx();
787 aaaStatisticsManager.getAaaStats().countDroppedResponsesRx();
788 log.error("Cannot deserialize packet", dex);
789 } catch (StateMachineException sme) {
790 log.error("Illegal state machine operation", sme);
791 }
792
793 }
794
795 }
796
Kartikey Dubeybe14f472019-10-01 12:18:35 +0000797}