blob: 839d0b1b25311f7112281a75a35d8c4d255c74a6 [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;
Jonathan Hartc41227c2020-01-28 16:56:49 -080029import org.onosproject.cluster.ClusterServiceAdapter;
30import org.onosproject.cluster.LeadershipServiceAdapter;
31import org.onosproject.cluster.NodeId;
Ray Milkeyea366452015-09-30 10:56:43 -070032import org.onosproject.core.CoreServiceAdapter;
Jonathan Hart5db44532018-07-12 18:13:54 -070033import org.onosproject.event.DefaultEventSinkRegistry;
34import org.onosproject.event.Event;
35import org.onosproject.event.EventDeliveryService;
36import org.onosproject.event.EventSink;
Ray Milkeyfcb623d2015-10-01 16:48:18 -070037import org.onosproject.net.config.Config;
38import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010039import org.onosproject.net.packet.InboundPacket;
Jonathan Hartc41227c2020-01-28 16:56:49 -080040import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter;
Jonathan Hart9d1ce802020-01-28 10:45:08 -080041import org.onosproject.store.service.TestStorageService;
Matteo Scandolocf847b82019-04-26 15:00:00 -070042import org.opencord.aaa.AaaConfig;
Ray Milkeyea366452015-09-30 10:56:43 -070043
Jonathan Hart092dfb22015-11-16 23:05:21 -080044import java.net.InetAddress;
45import java.net.UnknownHostException;
Ray Milkeyea366452015-09-30 10:56:43 -070046
Jonathan Hart5db44532018-07-12 18:13:54 -070047import static com.google.common.base.Preconditions.checkState;
Ray Milkeyea366452015-09-30 10:56:43 -070048import static org.hamcrest.Matchers.is;
49import static org.hamcrest.Matchers.notNullValue;
Jonathan Hart612651f2019-11-25 09:21:43 -080050import static org.hamcrest.Matchers.nullValue;
Ray Milkeyea366452015-09-30 10:56:43 -070051import static org.junit.Assert.assertThat;
Ari Saha89831742015-06-26 10:31:48 -070052
53/**
54 * Set of tests of the ONOS application component.
55 */
Jonathan Hart092dfb22015-11-16 23:05:21 -080056public class AaaManagerTest extends AaaTestBase {
Ari Saha89831742015-06-26 10:31:48 -070057
Ray Milkey967776a2015-10-07 14:37:17 -070058 static final String BAD_IP_ADDRESS = "198.51.100.0";
Ari Saha89831742015-06-26 10:31:48 -070059
Jonathan Hart092dfb22015-11-16 23:05:21 -080060 private AaaManager aaaManager;
kartikey dubeye1545422019-05-22 12:53:45 +000061 private AaaStatisticsManager aaaStatisticsManager;
Ray Milkeyea366452015-09-30 10:56:43 -070062
Jonathan Hart092dfb22015-11-16 23:05:21 -080063 class AaaManagerWithoutRadiusServer extends AaaManager {
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010064 protected void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
Ray Milkey967776a2015-10-07 14:37:17 -070065 savePacket(radiusPacket);
66 }
Ray Milkeyea366452015-09-30 10:56:43 -070067 }
Ray Milkeyea366452015-09-30 10:56:43 -070068 /**
Ray Milkey967776a2015-10-07 14:37:17 -070069 * Mocks the AAAConfig class to force usage of an unroutable address for the
70 * RADIUS server.
Ray Milkeyea366452015-09-30 10:56:43 -070071 */
Jonathan Hart092dfb22015-11-16 23:05:21 -080072 static class MockAaaConfig extends AaaConfig {
Ray Milkeyea366452015-09-30 10:56:43 -070073 @Override
Ray Milkey967776a2015-10-07 14:37:17 -070074 public InetAddress radiusIp() {
Ray Milkeyea366452015-09-30 10:56:43 -070075 try {
Ray Milkey967776a2015-10-07 14:37:17 -070076 return InetAddress.getByName(BAD_IP_ADDRESS);
77 } catch (UnknownHostException ex) {
78 // can't happen
79 throw new IllegalStateException(ex);
Ray Milkeyea366452015-09-30 10:56:43 -070080 }
81 }
82 }
83
Jonathan Hartc41227c2020-01-28 16:56:49 -080084 static final class TestLeadershipService extends LeadershipServiceAdapter {
85 @Override
86 public NodeId getLeader(String path) {
87 return new ClusterServiceAdapter().getLocalNode().id();
88 }
89 }
90
Ray Milkeyea366452015-09-30 10:56:43 -070091 /**
Ray Milkeyfcb623d2015-10-01 16:48:18 -070092 * Mocks the network config registry.
93 */
94 @SuppressWarnings("unchecked")
95 private static final class TestNetworkConfigRegistry
96 extends NetworkConfigRegistryAdapter {
97 @Override
98 public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
Jonathan Hart092dfb22015-11-16 23:05:21 -080099 AaaConfig aaaConfig = new MockAaaConfig();
Ray Milkey967776a2015-10-07 14:37:17 -0700100 return (C) aaaConfig;
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700101 }
102 }
103
Jonathan Hart5db44532018-07-12 18:13:54 -0700104 public static class TestEventDispatcher extends DefaultEventSinkRegistry
105 implements EventDeliveryService {
Jonathan Hart5db44532018-07-12 18:13:54 -0700106 @Override
107 @SuppressWarnings("unchecked")
108 public synchronized void post(Event event) {
109 EventSink sink = getSink(event.getClass());
110 checkState(sink != null, "No sink for event %s", event);
111 sink.process(event);
112 }
113
114 @Override
115 public void setDispatchTimeLimit(long millis) {
116 }
117
118 @Override
119 public long getDispatchTimeLimit() {
120 return 0;
121 }
122 }
123
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700124 /**
Ray Milkeyea366452015-09-30 10:56:43 -0700125 * Sets up the services required by the AAA application.
126 */
Ari Saha89831742015-06-26 10:31:48 -0700127 @Before
128 public void setUp() {
Jonathan Hart092dfb22015-11-16 23:05:21 -0800129 aaaManager = new AaaManagerWithoutRadiusServer();
130 aaaManager.netCfgService = new TestNetworkConfigRegistry();
131 aaaManager.coreService = new CoreServiceAdapter();
132 aaaManager.packetService = new MockPacketService();
Amit Ghoshf739be52017-09-21 15:49:37 +0100133 aaaManager.deviceService = new TestDeviceService();
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000134 aaaManager.sadisService = new MockSadisService();
kartikey dubeye1545422019-05-22 12:53:45 +0000135 aaaManager.cfgService = new MockCfgService();
Jonathan Hart9d1ce802020-01-28 10:45:08 -0800136 aaaManager.storageService = new TestStorageService();
kartikey dubeye1545422019-05-22 12:53:45 +0000137 aaaStatisticsManager = new AaaStatisticsManager();
Jonathan Hartc41227c2020-01-28 16:56:49 -0800138 aaaStatisticsManager.storageService = new TestStorageService();
139 aaaStatisticsManager.clusterService = new ClusterServiceAdapter();
140 aaaStatisticsManager.leadershipService = new TestLeadershipService();
141 aaaStatisticsManager.clusterCommunicationService = new ClusterCommunicationServiceAdapter();
Shubham Sharma4900ce62019-06-19 14:18:50 +0000142 aaaManager.radiusOperationalStatusService = new RadiusOperationalStatusManager();
kartikey dubeye1545422019-05-22 12:53:45 +0000143 TestUtils.setField(aaaStatisticsManager, "eventDispatcher", new TestEventDispatcher());
Jonathan Hartc41227c2020-01-28 16:56:49 -0800144 aaaStatisticsManager.activate(new MockComponentContext());
kartikey dubeye1545422019-05-22 12:53:45 +0000145 aaaManager.aaaStatisticsManager = this.aaaStatisticsManager;
Jonathan Hart5db44532018-07-12 18:13:54 -0700146 TestUtils.setField(aaaManager, "eventDispatcher", new TestEventDispatcher());
kartikey dubeye1545422019-05-22 12:53:45 +0000147 aaaManager.activate(new AaaTestBase.MockComponentContext());
Ari Saha89831742015-06-26 10:31:48 -0700148 }
149
Ray Milkeyea366452015-09-30 10:56:43 -0700150 /**
151 * Tears down the AAA application.
152 */
Ari Saha89831742015-06-26 10:31:48 -0700153 @After
154 public void tearDown() {
kartikey dubeye1545422019-05-22 12:53:45 +0000155 aaaManager.deactivate(new AaaTestBase.MockComponentContext());
Ari Saha89831742015-06-26 10:31:48 -0700156 }
157
Ray Milkeyea366452015-09-30 10:56:43 -0700158 /**
159 * Extracts the RADIUS packet from a packet sent by the supplicant.
160 *
Ray Milkey967776a2015-10-07 14:37:17 -0700161 * @param radius RADIUS packet sent by the supplicant
Ray Milkeyea366452015-09-30 10:56:43 -0700162 * @throws DeserializationException if deserialization of the packet contents
163 * fails.
164 */
Jonathan Hart092dfb22015-11-16 23:05:21 -0800165 private void checkRadiusPacketFromSupplicant(RADIUS radius)
Ray Milkeyea366452015-09-30 10:56:43 -0700166 throws DeserializationException {
Ray Milkeyea366452015-09-30 10:56:43 -0700167 assertThat(radius, notNullValue());
Ray Milkeyea366452015-09-30 10:56:43 -0700168
Ray Milkey967776a2015-10-07 14:37:17 -0700169 EAP eap = radius.decapsulateMessage();
Ray Milkeyea366452015-09-30 10:56:43 -0700170 assertThat(eap, notNullValue());
Ray Milkeyea366452015-09-30 10:56:43 -0700171 }
172
173 /**
174 * Fetches the sent packet at the given index. The requested packet
175 * must be the last packet on the list.
176 *
177 * @param index index into sent packets array
178 * @return packet
179 */
Ray Milkey967776a2015-10-07 14:37:17 -0700180 private BasePacket fetchPacket(int index) {
181 BasePacket packet = savedPackets.get(index);
182 assertThat(packet, notNullValue());
183 return packet;
Ray Milkeyea366452015-09-30 10:56:43 -0700184 }
185
186 /**
187 * Tests the authentication path through the AAA application.
188 *
189 * @throws DeserializationException if packed deserialization fails.
190 */
Ari Saha89831742015-06-26 10:31:48 -0700191 @Test
Jonathan Hart612651f2019-11-25 09:21:43 -0800192 public void testAuthentication() throws Exception {
Ray Milkeyea366452015-09-30 10:56:43 -0700193
194 // (1) Supplicant start up
195
196 Ethernet startPacket = constructSupplicantStartPacket();
197 sendPacket(startPacket);
198
Ray Milkey967776a2015-10-07 14:37:17 -0700199 Ethernet responsePacket = (Ethernet) fetchPacket(0);
Jonathan Hart092dfb22015-11-16 23:05:21 -0800200 checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY);
Ray Milkeyea366452015-09-30 10:56:43 -0700201
202 // (2) Supplicant identify
203
Jonathan Hart612651f2019-11-25 09:21:43 -0800204 Ethernet identifyPacket = constructSupplicantIdentifyPacket(null,
205 EAP.ATTR_IDENTITY, (byte) 3, null);
Ray Milkeyea366452015-09-30 10:56:43 -0700206 sendPacket(identifyPacket);
207
Ray Milkey967776a2015-10-07 14:37:17 -0700208 RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
Jonathan Hart612651f2019-11-25 09:21:43 -0800209 byte reqId = radiusIdentifyPacket.getIdentifier();
Ray Milkeyea366452015-09-30 10:56:43 -0700210
Jonathan Hart092dfb22015-11-16 23:05:21 -0800211 checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
Ray Milkey967776a2015-10-07 14:37:17 -0700212
213 assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
214 assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()),
215 is("testuser"));
Ray Milkeyea366452015-09-30 10:56:43 -0700216
217 IpAddress nasIp =
218 IpAddress.valueOf(IpAddress.Version.INET,
Ray Milkey967776a2015-10-07 14:37:17 -0700219 radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP)
Ray Milkeyea366452015-09-30 10:56:43 -0700220 .getValue());
Jonathan Hart092dfb22015-11-16 23:05:21 -0800221 assertThat(nasIp.toString(), is(aaaManager.nasIpAddress.getHostAddress()));
Ray Milkeyea366452015-09-30 10:56:43 -0700222
223 // State machine should have been created by now
224
Jonathan Hart612651f2019-11-25 09:21:43 -0800225 StateMachine stateMachine = aaaManager.getStateMachine(SESSION_ID);
Ray Milkeyea366452015-09-30 10:56:43 -0700226 assertThat(stateMachine, notNullValue());
227 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
228
229 // (3) RADIUS MD5 challenge
230
Ray Milkey967776a2015-10-07 14:37:17 -0700231 RADIUS radiusCodeAccessChallengePacket =
Jonathan Hart612651f2019-11-25 09:21:43 -0800232 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5,
233 reqId, aaaManager.radiusSecret.getBytes());
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100234 aaaManager.handleRadiusPacket(radiusCodeAccessChallengePacket);
Ray Milkeyea366452015-09-30 10:56:43 -0700235
Ray Milkey967776a2015-10-07 14:37:17 -0700236 Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2);
Jonathan Hart092dfb22015-11-16 23:05:21 -0800237 checkRadiusPacket(aaaManager, radiusChallengeMD5Packet, EAP.ATTR_MD5);
Ray Milkeyea366452015-09-30 10:56:43 -0700238
239 // (4) Supplicant MD5 response
240
Ray Milkey967776a2015-10-07 14:37:17 -0700241 Ethernet md5RadiusPacket =
242 constructSupplicantIdentifyPacket(stateMachine,
243 EAP.ATTR_MD5,
244 stateMachine.challengeIdentifier(),
245 radiusChallengeMD5Packet);
Ray Milkeyea366452015-09-30 10:56:43 -0700246 sendPacket(md5RadiusPacket);
Ray Milkey967776a2015-10-07 14:37:17 -0700247
248 RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3);
249
Jonathan Hart092dfb22015-11-16 23:05:21 -0800250 checkRadiusPacketFromSupplicant(responseMd5RadiusPacket);
Jonathan Hart612651f2019-11-25 09:21:43 -0800251 //assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 9));
252 reqId = responseMd5RadiusPacket.getIdentifier();
Ray Milkeyea366452015-09-30 10:56:43 -0700253 assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
254
255 // State machine should be in pending state
256
257 assertThat(stateMachine, notNullValue());
258 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
259
Ray Milkey967776a2015-10-07 14:37:17 -0700260 // (5) RADIUS Success
Ray Milkeyea366452015-09-30 10:56:43 -0700261
Ray Milkey967776a2015-10-07 14:37:17 -0700262 RADIUS successPacket =
Jonathan Hart612651f2019-11-25 09:21:43 -0800263 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT,
264 EAP.SUCCESS, reqId, aaaManager.radiusSecret.getBytes());
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100265 aaaManager.handleRadiusPacket((successPacket));
Ray Milkey967776a2015-10-07 14:37:17 -0700266 Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4);
Ray Milkeyea366452015-09-30 10:56:43 -0700267
Jonathan Hart092dfb22015-11-16 23:05:21 -0800268 checkRadiusPacket(aaaManager, supplicantSuccessPacket, EAP.SUCCESS);
Ray Milkeyea366452015-09-30 10:56:43 -0700269
270 // State machine should be in authorized state
271
272 assertThat(stateMachine, notNullValue());
273 assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED));
Jonathan Hart612651f2019-11-25 09:21:43 -0800274 }
Ray Milkey967776a2015-10-07 14:37:17 -0700275
Jonathan Hart612651f2019-11-25 09:21:43 -0800276 @Test
277 public void testRemoveAuthentication() {
278 Ethernet startPacket = constructSupplicantStartPacket();
279 sendPacket(startPacket);
280
281 StateMachine stateMachine = aaaManager.getStateMachine(SESSION_ID);
282
283 assertThat(stateMachine, notNullValue());
284 assertThat(stateMachine.state(), is(StateMachine.STATE_STARTED));
285
286 aaaManager.removeAuthenticationStateByMac(stateMachine.supplicantAddress());
287
288 assertThat(aaaManager.getStateMachine(SESSION_ID), nullValue());
Ari Saha89831742015-06-26 10:31:48 -0700289 }
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700290
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700291 /**
292 * Tests the default configuration.
293 */
294 @Test
295 public void testConfig() {
Jonathan Hart092dfb22015-11-16 23:05:21 -0800296 assertThat(aaaManager.nasIpAddress.getHostAddress(), is(AaaConfig.DEFAULT_NAS_IP));
297 assertThat(aaaManager.nasMacAddress, is(AaaConfig.DEFAULT_NAS_MAC));
298 assertThat(aaaManager.radiusIpAddress.getHostAddress(), is(BAD_IP_ADDRESS));
299 assertThat(aaaManager.radiusMacAddress, is(AaaConfig.DEFAULT_RADIUS_MAC));
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700300 }
Ari Saha89831742015-06-26 10:31:48 -0700301}