blob: d50be7dbfe40cd31c857bd1699d160267f3f729d [file] [log] [blame]
Ari Saha89831742015-06-26 10:31:48 -07001/*
Brian O'Connor4e33be22017-08-03 22:45:46 -07002 * Copyright 2015-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
18import org.junit.After;
19import org.junit.Before;
20import org.junit.Test;
Jonathan Hart5db44532018-07-12 18:13:54 -070021import org.onlab.junit.TestUtils;
Ray Milkey967776a2015-10-07 14:37:17 -070022import org.onlab.packet.BasePacket;
Ray Milkeyea366452015-09-30 10:56:43 -070023import org.onlab.packet.DeserializationException;
24import org.onlab.packet.EAP;
Ray Milkeyea366452015-09-30 10:56:43 -070025import org.onlab.packet.Ethernet;
Ray Milkeyea366452015-09-30 10:56:43 -070026import org.onlab.packet.IpAddress;
Ray Milkeyea366452015-09-30 10:56:43 -070027import org.onlab.packet.RADIUS;
28import org.onlab.packet.RADIUSAttribute;
Ray Milkeyea366452015-09-30 10:56:43 -070029import org.onosproject.core.CoreServiceAdapter;
Jonathan Hart5db44532018-07-12 18:13:54 -070030import org.onosproject.event.DefaultEventSinkRegistry;
31import org.onosproject.event.Event;
32import org.onosproject.event.EventDeliveryService;
33import org.onosproject.event.EventSink;
Ray Milkeyfcb623d2015-10-01 16:48:18 -070034import org.onosproject.net.config.Config;
35import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010036import org.onosproject.net.packet.InboundPacket;
Matteo Scandolocf847b82019-04-26 15:00:00 -070037import org.opencord.aaa.AaaConfig;
Ray Milkeyea366452015-09-30 10:56:43 -070038
Jonathan Hart092dfb22015-11-16 23:05:21 -080039import java.net.InetAddress;
40import java.net.UnknownHostException;
Ray Milkeyea366452015-09-30 10:56:43 -070041
Jonathan Hart5db44532018-07-12 18:13:54 -070042import static com.google.common.base.Preconditions.checkState;
Ray Milkeyea366452015-09-30 10:56:43 -070043import static org.hamcrest.Matchers.is;
44import static org.hamcrest.Matchers.notNullValue;
Jonathan Hart612651f2019-11-25 09:21:43 -080045import static org.hamcrest.Matchers.nullValue;
Ray Milkeyea366452015-09-30 10:56:43 -070046import static org.junit.Assert.assertThat;
Ari Saha89831742015-06-26 10:31:48 -070047
48/**
49 * Set of tests of the ONOS application component.
50 */
Jonathan Hart092dfb22015-11-16 23:05:21 -080051public class AaaManagerTest extends AaaTestBase {
Ari Saha89831742015-06-26 10:31:48 -070052
Ray Milkey967776a2015-10-07 14:37:17 -070053 static final String BAD_IP_ADDRESS = "198.51.100.0";
Ari Saha89831742015-06-26 10:31:48 -070054
Jonathan Hart092dfb22015-11-16 23:05:21 -080055 private AaaManager aaaManager;
kartikey dubeye1545422019-05-22 12:53:45 +000056 private AaaStatisticsManager aaaStatisticsManager;
Ray Milkeyea366452015-09-30 10:56:43 -070057
Jonathan Hart092dfb22015-11-16 23:05:21 -080058 class AaaManagerWithoutRadiusServer extends AaaManager {
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010059 protected void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
Ray Milkey967776a2015-10-07 14:37:17 -070060 savePacket(radiusPacket);
61 }
Ray Milkeyea366452015-09-30 10:56:43 -070062 }
Ray Milkeyea366452015-09-30 10:56:43 -070063 /**
Ray Milkey967776a2015-10-07 14:37:17 -070064 * Mocks the AAAConfig class to force usage of an unroutable address for the
65 * RADIUS server.
Ray Milkeyea366452015-09-30 10:56:43 -070066 */
Jonathan Hart092dfb22015-11-16 23:05:21 -080067 static class MockAaaConfig extends AaaConfig {
Ray Milkeyea366452015-09-30 10:56:43 -070068 @Override
Ray Milkey967776a2015-10-07 14:37:17 -070069 public InetAddress radiusIp() {
Ray Milkeyea366452015-09-30 10:56:43 -070070 try {
Ray Milkey967776a2015-10-07 14:37:17 -070071 return InetAddress.getByName(BAD_IP_ADDRESS);
72 } catch (UnknownHostException ex) {
73 // can't happen
74 throw new IllegalStateException(ex);
Ray Milkeyea366452015-09-30 10:56:43 -070075 }
76 }
77 }
78
79 /**
Ray Milkeyfcb623d2015-10-01 16:48:18 -070080 * Mocks the network config registry.
81 */
82 @SuppressWarnings("unchecked")
83 private static final class TestNetworkConfigRegistry
84 extends NetworkConfigRegistryAdapter {
85 @Override
86 public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
Jonathan Hart092dfb22015-11-16 23:05:21 -080087 AaaConfig aaaConfig = new MockAaaConfig();
Ray Milkey967776a2015-10-07 14:37:17 -070088 return (C) aaaConfig;
Ray Milkeyfcb623d2015-10-01 16:48:18 -070089 }
90 }
91
Jonathan Hart5db44532018-07-12 18:13:54 -070092 public static class TestEventDispatcher extends DefaultEventSinkRegistry
93 implements EventDeliveryService {
Jonathan Hart5db44532018-07-12 18:13:54 -070094 @Override
95 @SuppressWarnings("unchecked")
96 public synchronized void post(Event event) {
97 EventSink sink = getSink(event.getClass());
98 checkState(sink != null, "No sink for event %s", event);
99 sink.process(event);
100 }
101
102 @Override
103 public void setDispatchTimeLimit(long millis) {
104 }
105
106 @Override
107 public long getDispatchTimeLimit() {
108 return 0;
109 }
110 }
111
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700112 /**
Ray Milkeyea366452015-09-30 10:56:43 -0700113 * Sets up the services required by the AAA application.
114 */
Ari Saha89831742015-06-26 10:31:48 -0700115 @Before
116 public void setUp() {
Jonathan Hart092dfb22015-11-16 23:05:21 -0800117 aaaManager = new AaaManagerWithoutRadiusServer();
118 aaaManager.netCfgService = new TestNetworkConfigRegistry();
119 aaaManager.coreService = new CoreServiceAdapter();
120 aaaManager.packetService = new MockPacketService();
Amit Ghoshf739be52017-09-21 15:49:37 +0100121 aaaManager.deviceService = new TestDeviceService();
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000122 aaaManager.sadisService = new MockSadisService();
kartikey dubeye1545422019-05-22 12:53:45 +0000123 aaaManager.cfgService = new MockCfgService();
124 aaaStatisticsManager = new AaaStatisticsManager();
Shubham Sharma4900ce62019-06-19 14:18:50 +0000125 aaaManager.radiusOperationalStatusService = new RadiusOperationalStatusManager();
kartikey dubeye1545422019-05-22 12:53:45 +0000126 TestUtils.setField(aaaStatisticsManager, "eventDispatcher", new TestEventDispatcher());
127 aaaStatisticsManager.activate();
128 aaaManager.aaaStatisticsManager = this.aaaStatisticsManager;
Jonathan Hart5db44532018-07-12 18:13:54 -0700129 TestUtils.setField(aaaManager, "eventDispatcher", new TestEventDispatcher());
kartikey dubeye1545422019-05-22 12:53:45 +0000130 aaaManager.activate(new AaaTestBase.MockComponentContext());
Ari Saha89831742015-06-26 10:31:48 -0700131 }
132
Ray Milkeyea366452015-09-30 10:56:43 -0700133 /**
134 * Tears down the AAA application.
135 */
Ari Saha89831742015-06-26 10:31:48 -0700136 @After
137 public void tearDown() {
kartikey dubeye1545422019-05-22 12:53:45 +0000138 aaaManager.deactivate(new AaaTestBase.MockComponentContext());
Ari Saha89831742015-06-26 10:31:48 -0700139 }
140
Ray Milkeyea366452015-09-30 10:56:43 -0700141 /**
142 * Extracts the RADIUS packet from a packet sent by the supplicant.
143 *
Ray Milkey967776a2015-10-07 14:37:17 -0700144 * @param radius RADIUS packet sent by the supplicant
Ray Milkeyea366452015-09-30 10:56:43 -0700145 * @throws DeserializationException if deserialization of the packet contents
146 * fails.
147 */
Jonathan Hart092dfb22015-11-16 23:05:21 -0800148 private void checkRadiusPacketFromSupplicant(RADIUS radius)
Ray Milkeyea366452015-09-30 10:56:43 -0700149 throws DeserializationException {
Ray Milkeyea366452015-09-30 10:56:43 -0700150 assertThat(radius, notNullValue());
Ray Milkeyea366452015-09-30 10:56:43 -0700151
Ray Milkey967776a2015-10-07 14:37:17 -0700152 EAP eap = radius.decapsulateMessage();
Ray Milkeyea366452015-09-30 10:56:43 -0700153 assertThat(eap, notNullValue());
Ray Milkeyea366452015-09-30 10:56:43 -0700154 }
155
156 /**
157 * Fetches the sent packet at the given index. The requested packet
158 * must be the last packet on the list.
159 *
160 * @param index index into sent packets array
161 * @return packet
162 */
Ray Milkey967776a2015-10-07 14:37:17 -0700163 private BasePacket fetchPacket(int index) {
164 BasePacket packet = savedPackets.get(index);
165 assertThat(packet, notNullValue());
166 return packet;
Ray Milkeyea366452015-09-30 10:56:43 -0700167 }
168
169 /**
170 * Tests the authentication path through the AAA application.
171 *
172 * @throws DeserializationException if packed deserialization fails.
173 */
Ari Saha89831742015-06-26 10:31:48 -0700174 @Test
Jonathan Hart612651f2019-11-25 09:21:43 -0800175 public void testAuthentication() throws Exception {
Ray Milkeyea366452015-09-30 10:56:43 -0700176
177 // (1) Supplicant start up
178
179 Ethernet startPacket = constructSupplicantStartPacket();
180 sendPacket(startPacket);
181
Ray Milkey967776a2015-10-07 14:37:17 -0700182 Ethernet responsePacket = (Ethernet) fetchPacket(0);
Jonathan Hart092dfb22015-11-16 23:05:21 -0800183 checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY);
Ray Milkeyea366452015-09-30 10:56:43 -0700184
185 // (2) Supplicant identify
186
Jonathan Hart612651f2019-11-25 09:21:43 -0800187 Ethernet identifyPacket = constructSupplicantIdentifyPacket(null,
188 EAP.ATTR_IDENTITY, (byte) 3, null);
Ray Milkeyea366452015-09-30 10:56:43 -0700189 sendPacket(identifyPacket);
190
Ray Milkey967776a2015-10-07 14:37:17 -0700191 RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
Jonathan Hart612651f2019-11-25 09:21:43 -0800192 byte reqId = radiusIdentifyPacket.getIdentifier();
Ray Milkeyea366452015-09-30 10:56:43 -0700193
Jonathan Hart092dfb22015-11-16 23:05:21 -0800194 checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
Ray Milkey967776a2015-10-07 14:37:17 -0700195
196 assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
197 assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()),
198 is("testuser"));
Ray Milkeyea366452015-09-30 10:56:43 -0700199
200 IpAddress nasIp =
201 IpAddress.valueOf(IpAddress.Version.INET,
Ray Milkey967776a2015-10-07 14:37:17 -0700202 radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP)
Ray Milkeyea366452015-09-30 10:56:43 -0700203 .getValue());
Jonathan Hart092dfb22015-11-16 23:05:21 -0800204 assertThat(nasIp.toString(), is(aaaManager.nasIpAddress.getHostAddress()));
Ray Milkeyea366452015-09-30 10:56:43 -0700205
206 // State machine should have been created by now
207
Jonathan Hart612651f2019-11-25 09:21:43 -0800208 StateMachine stateMachine = aaaManager.getStateMachine(SESSION_ID);
Ray Milkeyea366452015-09-30 10:56:43 -0700209 assertThat(stateMachine, notNullValue());
210 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
211
212 // (3) RADIUS MD5 challenge
213
Ray Milkey967776a2015-10-07 14:37:17 -0700214 RADIUS radiusCodeAccessChallengePacket =
Jonathan Hart612651f2019-11-25 09:21:43 -0800215 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5,
216 reqId, aaaManager.radiusSecret.getBytes());
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100217 aaaManager.handleRadiusPacket(radiusCodeAccessChallengePacket);
Ray Milkeyea366452015-09-30 10:56:43 -0700218
Ray Milkey967776a2015-10-07 14:37:17 -0700219 Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2);
Jonathan Hart092dfb22015-11-16 23:05:21 -0800220 checkRadiusPacket(aaaManager, radiusChallengeMD5Packet, EAP.ATTR_MD5);
Ray Milkeyea366452015-09-30 10:56:43 -0700221
222 // (4) Supplicant MD5 response
223
Ray Milkey967776a2015-10-07 14:37:17 -0700224 Ethernet md5RadiusPacket =
225 constructSupplicantIdentifyPacket(stateMachine,
226 EAP.ATTR_MD5,
227 stateMachine.challengeIdentifier(),
228 radiusChallengeMD5Packet);
Ray Milkeyea366452015-09-30 10:56:43 -0700229 sendPacket(md5RadiusPacket);
Ray Milkey967776a2015-10-07 14:37:17 -0700230
231 RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3);
232
Jonathan Hart092dfb22015-11-16 23:05:21 -0800233 checkRadiusPacketFromSupplicant(responseMd5RadiusPacket);
Jonathan Hart612651f2019-11-25 09:21:43 -0800234 //assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 9));
235 reqId = responseMd5RadiusPacket.getIdentifier();
Ray Milkeyea366452015-09-30 10:56:43 -0700236 assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
237
238 // State machine should be in pending state
239
240 assertThat(stateMachine, notNullValue());
241 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
242
Ray Milkey967776a2015-10-07 14:37:17 -0700243 // (5) RADIUS Success
Ray Milkeyea366452015-09-30 10:56:43 -0700244
Ray Milkey967776a2015-10-07 14:37:17 -0700245 RADIUS successPacket =
Jonathan Hart612651f2019-11-25 09:21:43 -0800246 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT,
247 EAP.SUCCESS, reqId, aaaManager.radiusSecret.getBytes());
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100248 aaaManager.handleRadiusPacket((successPacket));
Ray Milkey967776a2015-10-07 14:37:17 -0700249 Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4);
Ray Milkeyea366452015-09-30 10:56:43 -0700250
Jonathan Hart092dfb22015-11-16 23:05:21 -0800251 checkRadiusPacket(aaaManager, supplicantSuccessPacket, EAP.SUCCESS);
Ray Milkeyea366452015-09-30 10:56:43 -0700252
253 // State machine should be in authorized state
254
255 assertThat(stateMachine, notNullValue());
256 assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED));
Jonathan Hart612651f2019-11-25 09:21:43 -0800257 }
Ray Milkey967776a2015-10-07 14:37:17 -0700258
Jonathan Hart612651f2019-11-25 09:21:43 -0800259 @Test
260 public void testRemoveAuthentication() {
261 Ethernet startPacket = constructSupplicantStartPacket();
262 sendPacket(startPacket);
263
264 StateMachine stateMachine = aaaManager.getStateMachine(SESSION_ID);
265
266 assertThat(stateMachine, notNullValue());
267 assertThat(stateMachine.state(), is(StateMachine.STATE_STARTED));
268
269 aaaManager.removeAuthenticationStateByMac(stateMachine.supplicantAddress());
270
271 assertThat(aaaManager.getStateMachine(SESSION_ID), nullValue());
Ari Saha89831742015-06-26 10:31:48 -0700272 }
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700273
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700274 /**
275 * Tests the default configuration.
276 */
277 @Test
278 public void testConfig() {
Jonathan Hart092dfb22015-11-16 23:05:21 -0800279 assertThat(aaaManager.nasIpAddress.getHostAddress(), is(AaaConfig.DEFAULT_NAS_IP));
280 assertThat(aaaManager.nasMacAddress, is(AaaConfig.DEFAULT_NAS_MAC));
281 assertThat(aaaManager.radiusIpAddress.getHostAddress(), is(BAD_IP_ADDRESS));
282 assertThat(aaaManager.radiusMacAddress, is(AaaConfig.DEFAULT_RADIUS_MAC));
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700283 }
Ari Saha89831742015-06-26 10:31:48 -0700284}