blob: e3bcd9e4d4d4d00e11716c9f010a369c2bc9411c [file] [log] [blame]
Ari Saha79d7c252015-06-26 10:31:48 -07001/*
2 * Copyright 2014 Open Networking Laboratory
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.onosproject.aaa;
17
Jonathan Hartb92cc512015-11-16 23:05:21 -080018import com.google.common.base.Charsets;
Ari Saha79d7c252015-06-26 10:31:48 -070019import org.junit.After;
20import org.junit.Before;
21import org.junit.Test;
Ray Milkey4ed93692015-10-07 14:37:17 -070022import org.onlab.packet.BasePacket;
Ray Milkey911c5192015-09-30 10:56:43 -070023import org.onlab.packet.DeserializationException;
24import org.onlab.packet.EAP;
Ray Milkey911c5192015-09-30 10:56:43 -070025import org.onlab.packet.Ethernet;
Ray Milkey911c5192015-09-30 10:56:43 -070026import org.onlab.packet.IpAddress;
Ray Milkey911c5192015-09-30 10:56:43 -070027import org.onlab.packet.RADIUS;
28import org.onlab.packet.RADIUSAttribute;
Ray Milkey911c5192015-09-30 10:56:43 -070029import org.onosproject.core.CoreServiceAdapter;
Ray Milkey57f2e142015-10-01 16:48:18 -070030import org.onosproject.net.config.Config;
31import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Ray Milkey911c5192015-09-30 10:56:43 -070032
Jonathan Hartb92cc512015-11-16 23:05:21 -080033import java.net.InetAddress;
34import java.net.UnknownHostException;
Ray Milkey911c5192015-09-30 10:56:43 -070035
Ray Milkey911c5192015-09-30 10:56:43 -070036import static org.hamcrest.Matchers.is;
37import static org.hamcrest.Matchers.notNullValue;
38import static org.junit.Assert.assertThat;
Ari Saha79d7c252015-06-26 10:31:48 -070039
40/**
41 * Set of tests of the ONOS application component.
42 */
Jonathan Hartb92cc512015-11-16 23:05:21 -080043public class AaaManagerTest extends AaaTestBase {
Ari Saha79d7c252015-06-26 10:31:48 -070044
Ray Milkey4ed93692015-10-07 14:37:17 -070045 static final String BAD_IP_ADDRESS = "198.51.100.0";
Ari Saha79d7c252015-06-26 10:31:48 -070046
Jonathan Hartb92cc512015-11-16 23:05:21 -080047 private AaaManager aaaManager;
Ray Milkey911c5192015-09-30 10:56:43 -070048
Jonathan Hartb92cc512015-11-16 23:05:21 -080049 class AaaManagerWithoutRadiusServer extends AaaManager {
50 protected void sendRadiusPacket(RADIUS radiusPacket) {
Ray Milkey4ed93692015-10-07 14:37:17 -070051 savePacket(radiusPacket);
52 }
Ray Milkey911c5192015-09-30 10:56:43 -070053 }
54
55 /**
Ray Milkey4ed93692015-10-07 14:37:17 -070056 * Mocks the AAAConfig class to force usage of an unroutable address for the
57 * RADIUS server.
Ray Milkey911c5192015-09-30 10:56:43 -070058 */
Jonathan Hartb92cc512015-11-16 23:05:21 -080059 static class MockAaaConfig extends AaaConfig {
Ray Milkey911c5192015-09-30 10:56:43 -070060 @Override
Ray Milkey4ed93692015-10-07 14:37:17 -070061 public InetAddress radiusIp() {
Ray Milkey911c5192015-09-30 10:56:43 -070062 try {
Ray Milkey4ed93692015-10-07 14:37:17 -070063 return InetAddress.getByName(BAD_IP_ADDRESS);
64 } catch (UnknownHostException ex) {
65 // can't happen
66 throw new IllegalStateException(ex);
Ray Milkey911c5192015-09-30 10:56:43 -070067 }
68 }
69 }
70
71 /**
Ray Milkey57f2e142015-10-01 16:48:18 -070072 * Mocks the network config registry.
73 */
74 @SuppressWarnings("unchecked")
75 private static final class TestNetworkConfigRegistry
76 extends NetworkConfigRegistryAdapter {
77 @Override
78 public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
Jonathan Hartb92cc512015-11-16 23:05:21 -080079 AaaConfig aaaConfig = new MockAaaConfig();
Ray Milkey4ed93692015-10-07 14:37:17 -070080 return (C) aaaConfig;
Ray Milkey57f2e142015-10-01 16:48:18 -070081 }
82 }
83
84 /**
Ray Milkey911c5192015-09-30 10:56:43 -070085 * Constructs an Ethernet packet containing a RADIUS challenge
86 * packet.
87 *
88 * @param challengeCode code to use in challenge packet
89 * @param challengeType type to use in challenge packet
90 * @return Ethernet packet
91 */
Jonathan Hartb92cc512015-11-16 23:05:21 -080092 private RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType) {
Ray Milkey911c5192015-09-30 10:56:43 -070093
Ray Milkey4ed93692015-10-07 14:37:17 -070094 String challenge = "12345678901234567";
Ray Milkey911c5192015-09-30 10:56:43 -070095
96 EAP eap = new EAP(challengeType, (byte) 1, challengeType,
97 challenge.getBytes(Charsets.US_ASCII));
98 eap.setIdentifier((byte) 1);
99
100 RADIUS radius = new RADIUS();
101 radius.setCode(challengeCode);
102
103 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
104 challenge.getBytes(Charsets.US_ASCII));
105
106 radius.setPayload(eap);
107 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE,
108 eap.serialize());
109
Ray Milkey4ed93692015-10-07 14:37:17 -0700110 return radius;
Ray Milkey911c5192015-09-30 10:56:43 -0700111 }
112
113 /**
114 * Sets up the services required by the AAA application.
115 */
Ari Saha79d7c252015-06-26 10:31:48 -0700116 @Before
117 public void setUp() {
Jonathan Hartb92cc512015-11-16 23:05:21 -0800118 aaaManager = new AaaManagerWithoutRadiusServer();
119 aaaManager.netCfgService = new TestNetworkConfigRegistry();
120 aaaManager.coreService = new CoreServiceAdapter();
121 aaaManager.packetService = new MockPacketService();
122 aaaManager.activate();
Ari Saha79d7c252015-06-26 10:31:48 -0700123 }
124
Ray Milkey911c5192015-09-30 10:56:43 -0700125 /**
126 * Tears down the AAA application.
127 */
Ari Saha79d7c252015-06-26 10:31:48 -0700128 @After
129 public void tearDown() {
Jonathan Hartb92cc512015-11-16 23:05:21 -0800130 aaaManager.deactivate();
Ari Saha79d7c252015-06-26 10:31:48 -0700131 }
132
Ray Milkey911c5192015-09-30 10:56:43 -0700133 /**
134 * Extracts the RADIUS packet from a packet sent by the supplicant.
135 *
Ray Milkey4ed93692015-10-07 14:37:17 -0700136 * @param radius RADIUS packet sent by the supplicant
Ray Milkey911c5192015-09-30 10:56:43 -0700137 * @throws DeserializationException if deserialization of the packet contents
138 * fails.
139 */
Jonathan Hartb92cc512015-11-16 23:05:21 -0800140 private void checkRadiusPacketFromSupplicant(RADIUS radius)
Ray Milkey911c5192015-09-30 10:56:43 -0700141 throws DeserializationException {
Ray Milkey911c5192015-09-30 10:56:43 -0700142 assertThat(radius, notNullValue());
Ray Milkey911c5192015-09-30 10:56:43 -0700143
Ray Milkey4ed93692015-10-07 14:37:17 -0700144 EAP eap = radius.decapsulateMessage();
Ray Milkey911c5192015-09-30 10:56:43 -0700145 assertThat(eap, notNullValue());
Ray Milkey911c5192015-09-30 10:56:43 -0700146 }
147
148 /**
149 * Fetches the sent packet at the given index. The requested packet
150 * must be the last packet on the list.
151 *
152 * @param index index into sent packets array
153 * @return packet
154 */
Ray Milkey4ed93692015-10-07 14:37:17 -0700155 private BasePacket fetchPacket(int index) {
156 BasePacket packet = savedPackets.get(index);
157 assertThat(packet, notNullValue());
158 return packet;
Ray Milkey911c5192015-09-30 10:56:43 -0700159 }
160
161 /**
162 * Tests the authentication path through the AAA application.
163 *
164 * @throws DeserializationException if packed deserialization fails.
165 */
Ari Saha79d7c252015-06-26 10:31:48 -0700166 @Test
Ray Milkey4ed93692015-10-07 14:37:17 -0700167 public void testAuthentication() throws Exception {
Ray Milkey911c5192015-09-30 10:56:43 -0700168
169 // (1) Supplicant start up
170
171 Ethernet startPacket = constructSupplicantStartPacket();
172 sendPacket(startPacket);
173
Ray Milkey4ed93692015-10-07 14:37:17 -0700174 Ethernet responsePacket = (Ethernet) fetchPacket(0);
Jonathan Hartb92cc512015-11-16 23:05:21 -0800175 checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY);
Ray Milkey911c5192015-09-30 10:56:43 -0700176
177 // (2) Supplicant identify
178
Ray Milkey4ed93692015-10-07 14:37:17 -0700179 Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
Ray Milkey911c5192015-09-30 10:56:43 -0700180 sendPacket(identifyPacket);
181
Ray Milkey4ed93692015-10-07 14:37:17 -0700182 RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
Ray Milkey911c5192015-09-30 10:56:43 -0700183
Jonathan Hartb92cc512015-11-16 23:05:21 -0800184 checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
Ray Milkey4ed93692015-10-07 14:37:17 -0700185
186 assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
187 assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()),
188 is("testuser"));
Ray Milkey911c5192015-09-30 10:56:43 -0700189
190 IpAddress nasIp =
191 IpAddress.valueOf(IpAddress.Version.INET,
Ray Milkey4ed93692015-10-07 14:37:17 -0700192 radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP)
Ray Milkey911c5192015-09-30 10:56:43 -0700193 .getValue());
Jonathan Hartb92cc512015-11-16 23:05:21 -0800194 assertThat(nasIp.toString(), is(aaaManager.nasIpAddress.getHostAddress()));
Ray Milkey911c5192015-09-30 10:56:43 -0700195
196 // State machine should have been created by now
197
198 StateMachine stateMachine =
Ray Milkey4ed93692015-10-07 14:37:17 -0700199 StateMachine.lookupStateMachineBySessionId(SESSION_ID);
Ray Milkey911c5192015-09-30 10:56:43 -0700200 assertThat(stateMachine, notNullValue());
201 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
202
203 // (3) RADIUS MD5 challenge
204
Ray Milkey4ed93692015-10-07 14:37:17 -0700205 RADIUS radiusCodeAccessChallengePacket =
Jonathan Hartb92cc512015-11-16 23:05:21 -0800206 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5);
207 aaaManager.radiusListener.handleRadiusPacket(radiusCodeAccessChallengePacket);
Ray Milkey911c5192015-09-30 10:56:43 -0700208
Ray Milkey4ed93692015-10-07 14:37:17 -0700209 Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2);
Jonathan Hartb92cc512015-11-16 23:05:21 -0800210 checkRadiusPacket(aaaManager, radiusChallengeMD5Packet, EAP.ATTR_MD5);
Ray Milkey911c5192015-09-30 10:56:43 -0700211
212 // (4) Supplicant MD5 response
213
Ray Milkey4ed93692015-10-07 14:37:17 -0700214 Ethernet md5RadiusPacket =
215 constructSupplicantIdentifyPacket(stateMachine,
216 EAP.ATTR_MD5,
217 stateMachine.challengeIdentifier(),
218 radiusChallengeMD5Packet);
Ray Milkey911c5192015-09-30 10:56:43 -0700219 sendPacket(md5RadiusPacket);
Ray Milkey4ed93692015-10-07 14:37:17 -0700220
221 RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3);
222
Jonathan Hartb92cc512015-11-16 23:05:21 -0800223 checkRadiusPacketFromSupplicant(responseMd5RadiusPacket);
Ray Milkey4ed93692015-10-07 14:37:17 -0700224 assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 0));
Ray Milkey911c5192015-09-30 10:56:43 -0700225 assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
226
227 // State machine should be in pending state
228
229 assertThat(stateMachine, notNullValue());
230 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
231
Ray Milkey4ed93692015-10-07 14:37:17 -0700232 // (5) RADIUS Success
Ray Milkey911c5192015-09-30 10:56:43 -0700233
Ray Milkey4ed93692015-10-07 14:37:17 -0700234 RADIUS successPacket =
Jonathan Hartb92cc512015-11-16 23:05:21 -0800235 constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT, EAP.SUCCESS);
236 aaaManager.radiusListener.handleRadiusPacket((successPacket));
Ray Milkey4ed93692015-10-07 14:37:17 -0700237 Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4);
Ray Milkey911c5192015-09-30 10:56:43 -0700238
Jonathan Hartb92cc512015-11-16 23:05:21 -0800239 checkRadiusPacket(aaaManager, supplicantSuccessPacket, EAP.SUCCESS);
Ray Milkey911c5192015-09-30 10:56:43 -0700240
241 // State machine should be in authorized state
242
243 assertThat(stateMachine, notNullValue());
244 assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED));
Ray Milkey4ed93692015-10-07 14:37:17 -0700245
Ari Saha79d7c252015-06-26 10:31:48 -0700246 }
Ray Milkey57f2e142015-10-01 16:48:18 -0700247
Ray Milkey57f2e142015-10-01 16:48:18 -0700248 /**
249 * Tests the default configuration.
250 */
251 @Test
252 public void testConfig() {
Jonathan Hartb92cc512015-11-16 23:05:21 -0800253 assertThat(aaaManager.nasIpAddress.getHostAddress(), is(AaaConfig.DEFAULT_NAS_IP));
254 assertThat(aaaManager.nasMacAddress, is(AaaConfig.DEFAULT_NAS_MAC));
255 assertThat(aaaManager.radiusIpAddress.getHostAddress(), is(BAD_IP_ADDRESS));
256 assertThat(aaaManager.radiusMacAddress, is(AaaConfig.DEFAULT_RADIUS_MAC));
Ray Milkey57f2e142015-10-01 16:48:18 -0700257 }
Ari Saha79d7c252015-06-26 10:31:48 -0700258}