blob: 456c7b6fb3e64a8accaa858dfc839ddbccfc4424 [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;
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;
Ray Milkeyfcb623d2015-10-01 16:48:18 -070030import org.onosproject.net.config.Config;
31import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010032import org.onosproject.net.packet.InboundPacket;
Ray Milkeyea366452015-09-30 10:56:43 -070033
Jonathan Hart092dfb22015-11-16 23:05:21 -080034import java.net.InetAddress;
35import java.net.UnknownHostException;
Ray Milkeyea366452015-09-30 10:56:43 -070036
Ray Milkeyea366452015-09-30 10:56:43 -070037import static org.hamcrest.Matchers.is;
38import static org.hamcrest.Matchers.notNullValue;
39import static org.junit.Assert.assertThat;
Ari Saha89831742015-06-26 10:31:48 -070040
41/**
42 * Set of tests of the ONOS application component.
43 */
Jonathan Hart092dfb22015-11-16 23:05:21 -080044public class AaaManagerTest extends AaaTestBase {
Ari Saha89831742015-06-26 10:31:48 -070045
Ray Milkey967776a2015-10-07 14:37:17 -070046 static final String BAD_IP_ADDRESS = "198.51.100.0";
Ari Saha89831742015-06-26 10:31:48 -070047
Jonathan Hart092dfb22015-11-16 23:05:21 -080048 private AaaManager aaaManager;
Ray Milkeyea366452015-09-30 10:56:43 -070049
Jonathan Hart092dfb22015-11-16 23:05:21 -080050 class AaaManagerWithoutRadiusServer extends AaaManager {
Amit Ghoshc9ac1e52017-07-28 12:31:18 +010051 protected void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
Ray Milkey967776a2015-10-07 14:37:17 -070052 savePacket(radiusPacket);
53 }
Ray Milkeyea366452015-09-30 10:56:43 -070054 }
55
56 /**
Ray Milkey967776a2015-10-07 14:37:17 -070057 * Mocks the AAAConfig class to force usage of an unroutable address for the
58 * RADIUS server.
Ray Milkeyea366452015-09-30 10:56:43 -070059 */
Jonathan Hart092dfb22015-11-16 23:05:21 -080060 static class MockAaaConfig extends AaaConfig {
Ray Milkeyea366452015-09-30 10:56:43 -070061 @Override
Ray Milkey967776a2015-10-07 14:37:17 -070062 public InetAddress radiusIp() {
Ray Milkeyea366452015-09-30 10:56:43 -070063 try {
Ray Milkey967776a2015-10-07 14:37:17 -070064 return InetAddress.getByName(BAD_IP_ADDRESS);
65 } catch (UnknownHostException ex) {
66 // can't happen
67 throw new IllegalStateException(ex);
Ray Milkeyea366452015-09-30 10:56:43 -070068 }
69 }
70 }
71
72 /**
Ray Milkeyfcb623d2015-10-01 16:48:18 -070073 * Mocks the network config registry.
74 */
75 @SuppressWarnings("unchecked")
76 private static final class TestNetworkConfigRegistry
77 extends NetworkConfigRegistryAdapter {
78 @Override
79 public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
Jonathan Hart092dfb22015-11-16 23:05:21 -080080 AaaConfig aaaConfig = new MockAaaConfig();
Ray Milkey967776a2015-10-07 14:37:17 -070081 return (C) aaaConfig;
Ray Milkeyfcb623d2015-10-01 16:48:18 -070082 }
83 }
84
85 /**
Ray Milkeyea366452015-09-30 10:56:43 -070086 * Constructs an Ethernet packet containing a RADIUS challenge
87 * packet.
88 *
89 * @param challengeCode code to use in challenge packet
90 * @param challengeType type to use in challenge packet
91 * @return Ethernet packet
92 */
Jonathan Hart092dfb22015-11-16 23:05:21 -080093 private RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType) {
Ray Milkeyea366452015-09-30 10:56:43 -070094
Ray Milkey967776a2015-10-07 14:37:17 -070095 String challenge = "12345678901234567";
Ray Milkeyea366452015-09-30 10:56:43 -070096
97 EAP eap = new EAP(challengeType, (byte) 1, challengeType,
98 challenge.getBytes(Charsets.US_ASCII));
99 eap.setIdentifier((byte) 1);
100
101 RADIUS radius = new RADIUS();
102 radius.setCode(challengeCode);
103
104 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
105 challenge.getBytes(Charsets.US_ASCII));
106
107 radius.setPayload(eap);
108 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE,
109 eap.serialize());
110
Ray Milkey967776a2015-10-07 14:37:17 -0700111 return radius;
Ray Milkeyea366452015-09-30 10:56:43 -0700112 }
113
114 /**
115 * Sets up the services required by the AAA application.
116 */
Ari Saha89831742015-06-26 10:31:48 -0700117 @Before
118 public void setUp() {
Jonathan Hart092dfb22015-11-16 23:05:21 -0800119 aaaManager = new AaaManagerWithoutRadiusServer();
120 aaaManager.netCfgService = new TestNetworkConfigRegistry();
121 aaaManager.coreService = new CoreServiceAdapter();
122 aaaManager.packetService = new MockPacketService();
Amit Ghosh3f8ee432017-09-21 15:49:37 +0100123 aaaManager.deviceService = new TestDeviceService();
124 aaaManager.subsService = new MockSubService();
Jonathan Hart092dfb22015-11-16 23:05:21 -0800125 aaaManager.activate();
Ari Saha89831742015-06-26 10:31:48 -0700126 }
127
Ray Milkeyea366452015-09-30 10:56:43 -0700128 /**
129 * Tears down the AAA application.
130 */
Ari Saha89831742015-06-26 10:31:48 -0700131 @After
132 public void tearDown() {
Jonathan Hart092dfb22015-11-16 23:05:21 -0800133 aaaManager.deactivate();
Ari Saha89831742015-06-26 10:31:48 -0700134 }
135
Ray Milkeyea366452015-09-30 10:56:43 -0700136 /**
137 * Extracts the RADIUS packet from a packet sent by the supplicant.
138 *
Ray Milkey967776a2015-10-07 14:37:17 -0700139 * @param radius RADIUS packet sent by the supplicant
Ray Milkeyea366452015-09-30 10:56:43 -0700140 * @throws DeserializationException if deserialization of the packet contents
141 * fails.
142 */
Jonathan Hart092dfb22015-11-16 23:05:21 -0800143 private void checkRadiusPacketFromSupplicant(RADIUS radius)
Ray Milkeyea366452015-09-30 10:56:43 -0700144 throws DeserializationException {
Ray Milkeyea366452015-09-30 10:56:43 -0700145 assertThat(radius, notNullValue());
Ray Milkeyea366452015-09-30 10:56:43 -0700146
Ray Milkey967776a2015-10-07 14:37:17 -0700147 EAP eap = radius.decapsulateMessage();
Ray Milkeyea366452015-09-30 10:56:43 -0700148 assertThat(eap, notNullValue());
Ray Milkeyea366452015-09-30 10:56:43 -0700149 }
150
151 /**
152 * Fetches the sent packet at the given index. The requested packet
153 * must be the last packet on the list.
154 *
155 * @param index index into sent packets array
156 * @return packet
157 */
Ray Milkey967776a2015-10-07 14:37:17 -0700158 private BasePacket fetchPacket(int index) {
159 BasePacket packet = savedPackets.get(index);
160 assertThat(packet, notNullValue());
161 return packet;
Ray Milkeyea366452015-09-30 10:56:43 -0700162 }
163
164 /**
165 * Tests the authentication path through the AAA application.
166 *
167 * @throws DeserializationException if packed deserialization fails.
168 */
Ari Saha89831742015-06-26 10:31:48 -0700169 @Test
Ray Milkey967776a2015-10-07 14:37:17 -0700170 public void testAuthentication() throws Exception {
Ray Milkeyea366452015-09-30 10:56:43 -0700171
172 // (1) Supplicant start up
173
174 Ethernet startPacket = constructSupplicantStartPacket();
175 sendPacket(startPacket);
176
Ray Milkey967776a2015-10-07 14:37:17 -0700177 Ethernet responsePacket = (Ethernet) fetchPacket(0);
Jonathan Hart092dfb22015-11-16 23:05:21 -0800178 checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY);
Ray Milkeyea366452015-09-30 10:56:43 -0700179
180 // (2) Supplicant identify
181
Ray Milkey967776a2015-10-07 14:37:17 -0700182 Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
Ray Milkeyea366452015-09-30 10:56:43 -0700183 sendPacket(identifyPacket);
184
Ray Milkey967776a2015-10-07 14:37:17 -0700185 RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
Ray Milkeyea366452015-09-30 10:56:43 -0700186
Jonathan Hart092dfb22015-11-16 23:05:21 -0800187 checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
Ray Milkey967776a2015-10-07 14:37:17 -0700188
189 assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
190 assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()),
191 is("testuser"));
Ray Milkeyea366452015-09-30 10:56:43 -0700192
193 IpAddress nasIp =
194 IpAddress.valueOf(IpAddress.Version.INET,
Ray Milkey967776a2015-10-07 14:37:17 -0700195 radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP)
Ray Milkeyea366452015-09-30 10:56:43 -0700196 .getValue());
Jonathan Hart092dfb22015-11-16 23:05:21 -0800197 assertThat(nasIp.toString(), is(aaaManager.nasIpAddress.getHostAddress()));
Ray Milkeyea366452015-09-30 10:56:43 -0700198
199 // State machine should have been created by now
200
201 StateMachine stateMachine =
Ray Milkey967776a2015-10-07 14:37:17 -0700202 StateMachine.lookupStateMachineBySessionId(SESSION_ID);
Ray Milkeyea366452015-09-30 10:56:43 -0700203 assertThat(stateMachine, notNullValue());
204 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
205
206 // (3) RADIUS MD5 challenge
207
Ray Milkey967776a2015-10-07 14:37:17 -0700208 RADIUS radiusCodeAccessChallengePacket =
Jonathan Hart092dfb22015-11-16 23:05:21 -0800209 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100210 aaaManager.handleRadiusPacket(radiusCodeAccessChallengePacket);
Ray Milkeyea366452015-09-30 10:56:43 -0700211
Ray Milkey967776a2015-10-07 14:37:17 -0700212 Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2);
Jonathan Hart092dfb22015-11-16 23:05:21 -0800213 checkRadiusPacket(aaaManager, radiusChallengeMD5Packet, EAP.ATTR_MD5);
Ray Milkeyea366452015-09-30 10:56:43 -0700214
215 // (4) Supplicant MD5 response
216
Ray Milkey967776a2015-10-07 14:37:17 -0700217 Ethernet md5RadiusPacket =
218 constructSupplicantIdentifyPacket(stateMachine,
219 EAP.ATTR_MD5,
220 stateMachine.challengeIdentifier(),
221 radiusChallengeMD5Packet);
Ray Milkeyea366452015-09-30 10:56:43 -0700222 sendPacket(md5RadiusPacket);
Ray Milkey967776a2015-10-07 14:37:17 -0700223
224 RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3);
225
Jonathan Hart092dfb22015-11-16 23:05:21 -0800226 checkRadiusPacketFromSupplicant(responseMd5RadiusPacket);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100227 assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 3));
Ray Milkeyea366452015-09-30 10:56:43 -0700228 assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
229
230 // State machine should be in pending state
231
232 assertThat(stateMachine, notNullValue());
233 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
234
Ray Milkey967776a2015-10-07 14:37:17 -0700235 // (5) RADIUS Success
Ray Milkeyea366452015-09-30 10:56:43 -0700236
Ray Milkey967776a2015-10-07 14:37:17 -0700237 RADIUS successPacket =
Jonathan Hart092dfb22015-11-16 23:05:21 -0800238 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT, EAP.SUCCESS);
Amit Ghoshc9ac1e52017-07-28 12:31:18 +0100239 aaaManager.handleRadiusPacket((successPacket));
Ray Milkey967776a2015-10-07 14:37:17 -0700240 Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4);
Ray Milkeyea366452015-09-30 10:56:43 -0700241
Jonathan Hart092dfb22015-11-16 23:05:21 -0800242 checkRadiusPacket(aaaManager, supplicantSuccessPacket, EAP.SUCCESS);
Ray Milkeyea366452015-09-30 10:56:43 -0700243
244 // State machine should be in authorized state
245
246 assertThat(stateMachine, notNullValue());
247 assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED));
Ray Milkey967776a2015-10-07 14:37:17 -0700248
Ari Saha89831742015-06-26 10:31:48 -0700249 }
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700250
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700251 /**
252 * Tests the default configuration.
253 */
254 @Test
255 public void testConfig() {
Jonathan Hart092dfb22015-11-16 23:05:21 -0800256 assertThat(aaaManager.nasIpAddress.getHostAddress(), is(AaaConfig.DEFAULT_NAS_IP));
257 assertThat(aaaManager.nasMacAddress, is(AaaConfig.DEFAULT_NAS_MAC));
258 assertThat(aaaManager.radiusIpAddress.getHostAddress(), is(BAD_IP_ADDRESS));
259 assertThat(aaaManager.radiusMacAddress, is(AaaConfig.DEFAULT_RADIUS_MAC));
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700260 }
Ari Saha89831742015-06-26 10:31:48 -0700261}