blob: d615aee0d8d2a7e567d7dcbb00a2f1a9824b4990 [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 */
alshabib6d527452016-06-01 18:00:47 -070016package org.opencord.aaa;
Ari Saha89831742015-06-26 10:31:48 -070017
Jonathan Hart092dfb22015-11-16 23:05:21 -080018import com.google.common.base.Charsets;
Ari Saha89831742015-06-26 10:31:48 -070019import org.junit.After;
20import org.junit.Before;
21import org.junit.Test;
Jonathan Hart5db44532018-07-12 18:13:54 -070022import org.onlab.junit.TestUtils;
Ray Milkey967776a2015-10-07 14:37:17 -070023import org.onlab.packet.BasePacket;
Ray Milkeyea366452015-09-30 10:56:43 -070024import org.onlab.packet.DeserializationException;
25import org.onlab.packet.EAP;
Ray Milkeyea366452015-09-30 10:56:43 -070026import org.onlab.packet.Ethernet;
Ray Milkeyea366452015-09-30 10:56:43 -070027import org.onlab.packet.IpAddress;
Ray Milkeyea366452015-09-30 10:56:43 -070028import org.onlab.packet.RADIUS;
29import org.onlab.packet.RADIUSAttribute;
Ray Milkeyea366452015-09-30 10:56:43 -070030import org.onosproject.core.CoreServiceAdapter;
Jonathan Hart5db44532018-07-12 18:13:54 -070031import org.onosproject.event.DefaultEventSinkRegistry;
32import org.onosproject.event.Event;
33import org.onosproject.event.EventDeliveryService;
34import org.onosproject.event.EventSink;
Ray Milkeyfcb623d2015-10-01 16:48:18 -070035import org.onosproject.net.config.Config;
36import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010037import org.onosproject.net.packet.InboundPacket;
Ray Milkeyea366452015-09-30 10:56:43 -070038
Jonathan Hart5db44532018-07-12 18:13:54 -070039import java.lang.reflect.Field;
Jonathan Hart092dfb22015-11-16 23:05:21 -080040import java.net.InetAddress;
41import java.net.UnknownHostException;
Ray Milkeyea366452015-09-30 10:56:43 -070042
Jonathan Hart5db44532018-07-12 18:13:54 -070043import static com.google.common.base.Preconditions.checkState;
Ray Milkeyea366452015-09-30 10:56:43 -070044import static org.hamcrest.Matchers.is;
45import static org.hamcrest.Matchers.notNullValue;
46import 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;
Ray Milkeyea366452015-09-30 10:56:43 -070056
Jonathan Hart092dfb22015-11-16 23:05:21 -080057 class AaaManagerWithoutRadiusServer extends AaaManager {
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010058 protected void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
Ray Milkey967776a2015-10-07 14:37:17 -070059 savePacket(radiusPacket);
60 }
Ray Milkeyea366452015-09-30 10:56:43 -070061 }
62
63 /**
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 {
94
95 @Override
96 @SuppressWarnings("unchecked")
97 public synchronized void post(Event event) {
98 EventSink sink = getSink(event.getClass());
99 checkState(sink != null, "No sink for event %s", event);
100 sink.process(event);
101 }
102
103 @Override
104 public void setDispatchTimeLimit(long millis) {
105 }
106
107 @Override
108 public long getDispatchTimeLimit() {
109 return 0;
110 }
111 }
112
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700113 /**
Ray Milkeyea366452015-09-30 10:56:43 -0700114 * Constructs an Ethernet packet containing a RADIUS challenge
115 * packet.
116 *
117 * @param challengeCode code to use in challenge packet
118 * @param challengeType type to use in challenge packet
119 * @return Ethernet packet
120 */
Jonathan Hart092dfb22015-11-16 23:05:21 -0800121 private RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType) {
Ray Milkeyea366452015-09-30 10:56:43 -0700122
Ray Milkey967776a2015-10-07 14:37:17 -0700123 String challenge = "12345678901234567";
Ray Milkeyea366452015-09-30 10:56:43 -0700124
125 EAP eap = new EAP(challengeType, (byte) 1, challengeType,
126 challenge.getBytes(Charsets.US_ASCII));
127 eap.setIdentifier((byte) 1);
128
129 RADIUS radius = new RADIUS();
130 radius.setCode(challengeCode);
131
132 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
133 challenge.getBytes(Charsets.US_ASCII));
134
135 radius.setPayload(eap);
136 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE,
137 eap.serialize());
138
Ray Milkey967776a2015-10-07 14:37:17 -0700139 return radius;
Ray Milkeyea366452015-09-30 10:56:43 -0700140 }
141
Jonathan Hart5db44532018-07-12 18:13:54 -0700142 public static void injectEventDispatcher(Object manager, EventDeliveryService svc) {
143 Class mc = manager.getClass();
144 for (Field f : mc.getSuperclass().getDeclaredFields()) {
145 if (f.getType().equals(EventDeliveryService.class)) {
146 try {
147 TestUtils.setField(manager, f.getName(), svc);
148 } catch (TestUtils.TestUtilsException e) {
149 throw new IllegalArgumentException("Unable to inject reference", e);
150 }
151 break;
152 }
153 }
154 }
155
Ray Milkeyea366452015-09-30 10:56:43 -0700156 /**
157 * Sets up the services required by the AAA application.
158 */
Ari Saha89831742015-06-26 10:31:48 -0700159 @Before
160 public void setUp() {
Jonathan Hart092dfb22015-11-16 23:05:21 -0800161 aaaManager = new AaaManagerWithoutRadiusServer();
162 aaaManager.netCfgService = new TestNetworkConfigRegistry();
163 aaaManager.coreService = new CoreServiceAdapter();
164 aaaManager.packetService = new MockPacketService();
Amit Ghoshf739be52017-09-21 15:49:37 +0100165 aaaManager.deviceService = new TestDeviceService();
166 aaaManager.subsService = new MockSubService();
Jonathan Hart5db44532018-07-12 18:13:54 -0700167 TestUtils.setField(aaaManager, "eventDispatcher", new TestEventDispatcher());
Jonathan Hart092dfb22015-11-16 23:05:21 -0800168 aaaManager.activate();
Ari Saha89831742015-06-26 10:31:48 -0700169 }
170
Ray Milkeyea366452015-09-30 10:56:43 -0700171 /**
172 * Tears down the AAA application.
173 */
Ari Saha89831742015-06-26 10:31:48 -0700174 @After
175 public void tearDown() {
Jonathan Hart092dfb22015-11-16 23:05:21 -0800176 aaaManager.deactivate();
Ari Saha89831742015-06-26 10:31:48 -0700177 }
178
Ray Milkeyea366452015-09-30 10:56:43 -0700179 /**
180 * Extracts the RADIUS packet from a packet sent by the supplicant.
181 *
Ray Milkey967776a2015-10-07 14:37:17 -0700182 * @param radius RADIUS packet sent by the supplicant
Ray Milkeyea366452015-09-30 10:56:43 -0700183 * @throws DeserializationException if deserialization of the packet contents
184 * fails.
185 */
Jonathan Hart092dfb22015-11-16 23:05:21 -0800186 private void checkRadiusPacketFromSupplicant(RADIUS radius)
Ray Milkeyea366452015-09-30 10:56:43 -0700187 throws DeserializationException {
Ray Milkeyea366452015-09-30 10:56:43 -0700188 assertThat(radius, notNullValue());
Ray Milkeyea366452015-09-30 10:56:43 -0700189
Ray Milkey967776a2015-10-07 14:37:17 -0700190 EAP eap = radius.decapsulateMessage();
Ray Milkeyea366452015-09-30 10:56:43 -0700191 assertThat(eap, notNullValue());
Ray Milkeyea366452015-09-30 10:56:43 -0700192 }
193
194 /**
195 * Fetches the sent packet at the given index. The requested packet
196 * must be the last packet on the list.
197 *
198 * @param index index into sent packets array
199 * @return packet
200 */
Ray Milkey967776a2015-10-07 14:37:17 -0700201 private BasePacket fetchPacket(int index) {
202 BasePacket packet = savedPackets.get(index);
203 assertThat(packet, notNullValue());
204 return packet;
Ray Milkeyea366452015-09-30 10:56:43 -0700205 }
206
207 /**
208 * Tests the authentication path through the AAA application.
209 *
210 * @throws DeserializationException if packed deserialization fails.
211 */
Ari Saha89831742015-06-26 10:31:48 -0700212 @Test
Ray Milkey967776a2015-10-07 14:37:17 -0700213 public void testAuthentication() throws Exception {
Ray Milkeyea366452015-09-30 10:56:43 -0700214
215 // (1) Supplicant start up
216
217 Ethernet startPacket = constructSupplicantStartPacket();
218 sendPacket(startPacket);
219
Ray Milkey967776a2015-10-07 14:37:17 -0700220 Ethernet responsePacket = (Ethernet) fetchPacket(0);
Jonathan Hart092dfb22015-11-16 23:05:21 -0800221 checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY);
Ray Milkeyea366452015-09-30 10:56:43 -0700222
223 // (2) Supplicant identify
224
Ray Milkey967776a2015-10-07 14:37:17 -0700225 Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
Ray Milkeyea366452015-09-30 10:56:43 -0700226 sendPacket(identifyPacket);
227
Ray Milkey967776a2015-10-07 14:37:17 -0700228 RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
Ray Milkeyea366452015-09-30 10:56:43 -0700229
Jonathan Hart092dfb22015-11-16 23:05:21 -0800230 checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
Ray Milkey967776a2015-10-07 14:37:17 -0700231
232 assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
233 assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()),
234 is("testuser"));
Ray Milkeyea366452015-09-30 10:56:43 -0700235
236 IpAddress nasIp =
237 IpAddress.valueOf(IpAddress.Version.INET,
Ray Milkey967776a2015-10-07 14:37:17 -0700238 radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP)
Ray Milkeyea366452015-09-30 10:56:43 -0700239 .getValue());
Jonathan Hart092dfb22015-11-16 23:05:21 -0800240 assertThat(nasIp.toString(), is(aaaManager.nasIpAddress.getHostAddress()));
Ray Milkeyea366452015-09-30 10:56:43 -0700241
242 // State machine should have been created by now
243
244 StateMachine stateMachine =
Ray Milkey967776a2015-10-07 14:37:17 -0700245 StateMachine.lookupStateMachineBySessionId(SESSION_ID);
Ray Milkeyea366452015-09-30 10:56:43 -0700246 assertThat(stateMachine, notNullValue());
247 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
248
249 // (3) RADIUS MD5 challenge
250
Ray Milkey967776a2015-10-07 14:37:17 -0700251 RADIUS radiusCodeAccessChallengePacket =
Jonathan Hart092dfb22015-11-16 23:05:21 -0800252 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100253 aaaManager.handleRadiusPacket(radiusCodeAccessChallengePacket);
Ray Milkeyea366452015-09-30 10:56:43 -0700254
Ray Milkey967776a2015-10-07 14:37:17 -0700255 Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2);
Jonathan Hart092dfb22015-11-16 23:05:21 -0800256 checkRadiusPacket(aaaManager, radiusChallengeMD5Packet, EAP.ATTR_MD5);
Ray Milkeyea366452015-09-30 10:56:43 -0700257
258 // (4) Supplicant MD5 response
259
Ray Milkey967776a2015-10-07 14:37:17 -0700260 Ethernet md5RadiusPacket =
261 constructSupplicantIdentifyPacket(stateMachine,
262 EAP.ATTR_MD5,
263 stateMachine.challengeIdentifier(),
264 radiusChallengeMD5Packet);
Ray Milkeyea366452015-09-30 10:56:43 -0700265 sendPacket(md5RadiusPacket);
Ray Milkey967776a2015-10-07 14:37:17 -0700266
267 RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3);
268
Jonathan Hart092dfb22015-11-16 23:05:21 -0800269 checkRadiusPacketFromSupplicant(responseMd5RadiusPacket);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100270 assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 3));
Ray Milkeyea366452015-09-30 10:56:43 -0700271 assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
272
273 // State machine should be in pending state
274
275 assertThat(stateMachine, notNullValue());
276 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
277
Ray Milkey967776a2015-10-07 14:37:17 -0700278 // (5) RADIUS Success
Ray Milkeyea366452015-09-30 10:56:43 -0700279
Ray Milkey967776a2015-10-07 14:37:17 -0700280 RADIUS successPacket =
Jonathan Hart092dfb22015-11-16 23:05:21 -0800281 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT, EAP.SUCCESS);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100282 aaaManager.handleRadiusPacket((successPacket));
Ray Milkey967776a2015-10-07 14:37:17 -0700283 Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4);
Ray Milkeyea366452015-09-30 10:56:43 -0700284
Jonathan Hart092dfb22015-11-16 23:05:21 -0800285 checkRadiusPacket(aaaManager, supplicantSuccessPacket, EAP.SUCCESS);
Ray Milkeyea366452015-09-30 10:56:43 -0700286
287 // State machine should be in authorized state
288
289 assertThat(stateMachine, notNullValue());
290 assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED));
Ray Milkey967776a2015-10-07 14:37:17 -0700291
Ari Saha89831742015-06-26 10:31:48 -0700292 }
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700293
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700294 /**
295 * Tests the default configuration.
296 */
297 @Test
298 public void testConfig() {
Jonathan Hart092dfb22015-11-16 23:05:21 -0800299 assertThat(aaaManager.nasIpAddress.getHostAddress(), is(AaaConfig.DEFAULT_NAS_IP));
300 assertThat(aaaManager.nasMacAddress, is(AaaConfig.DEFAULT_NAS_MAC));
301 assertThat(aaaManager.radiusIpAddress.getHostAddress(), is(BAD_IP_ADDRESS));
302 assertThat(aaaManager.radiusMacAddress, is(AaaConfig.DEFAULT_RADIUS_MAC));
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700303 }
Ari Saha89831742015-06-26 10:31:48 -0700304}