blob: 860a7dbd4513da24f36756b3edba1da4f54af0ea [file] [log] [blame]
Ari Saha89831742015-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
Ray Milkey967776a2015-10-07 14:37:17 -070018import java.net.InetAddress;
19import java.net.UnknownHostException;
Ray Milkeyea366452015-09-30 10:56:43 -070020
Ari Saha89831742015-06-26 10:31:48 -070021import org.junit.After;
22import org.junit.Before;
23import org.junit.Test;
Ray Milkey967776a2015-10-07 14:37:17 -070024import org.onlab.packet.BasePacket;
Ray Milkeyea366452015-09-30 10:56:43 -070025import org.onlab.packet.DeserializationException;
26import org.onlab.packet.EAP;
Ray Milkeyea366452015-09-30 10:56:43 -070027import org.onlab.packet.Ethernet;
Ray Milkeyea366452015-09-30 10:56:43 -070028import org.onlab.packet.IpAddress;
Ray Milkeyea366452015-09-30 10:56:43 -070029import org.onlab.packet.RADIUS;
30import org.onlab.packet.RADIUSAttribute;
Ray Milkeyea366452015-09-30 10:56:43 -070031import org.onosproject.core.CoreServiceAdapter;
Ray Milkeyfcb623d2015-10-01 16:48:18 -070032import org.onosproject.net.config.Config;
33import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Ray Milkeyea366452015-09-30 10:56:43 -070034
35import com.google.common.base.Charsets;
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 */
Ray Milkey967776a2015-10-07 14:37:17 -070044public class AAATest 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
Ray Milkeyea366452015-09-30 10:56:43 -070048 private AAA aaa;
Ray Milkeyea366452015-09-30 10:56:43 -070049
Ray Milkey967776a2015-10-07 14:37:17 -070050 class AAAWithoutRadiusServer extends AAA {
51 protected void sendRADIUSPacket(RADIUS radiusPacket) {
52 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 */
Ray Milkey967776a2015-10-07 14:37:17 -070060 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) {
Ray Milkey967776a2015-10-07 14:37:17 -070080 AAAConfig aaaConfig = new MockAAAConfig();
81 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 */
Ray Milkey967776a2015-10-07 14:37:17 -070093 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() {
Ray Milkey967776a2015-10-07 14:37:17 -0700119 aaa = new AAAWithoutRadiusServer();
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700120 aaa.netCfgService = new TestNetworkConfigRegistry();
Ray Milkeyea366452015-09-30 10:56:43 -0700121 aaa.coreService = new CoreServiceAdapter();
122 aaa.packetService = new MockPacketService();
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700123 aaa.activate();
Ari Saha89831742015-06-26 10:31:48 -0700124 }
125
Ray Milkeyea366452015-09-30 10:56:43 -0700126 /**
127 * Tears down the AAA application.
128 */
Ari Saha89831742015-06-26 10:31:48 -0700129 @After
130 public void tearDown() {
Ray Milkeyea366452015-09-30 10:56:43 -0700131 aaa.deactivate();
Ari Saha89831742015-06-26 10:31:48 -0700132 }
133
Ray Milkeyea366452015-09-30 10:56:43 -0700134 /**
135 * Extracts the RADIUS packet from a packet sent by the supplicant.
136 *
Ray Milkey967776a2015-10-07 14:37:17 -0700137 * @param radius RADIUS packet sent by the supplicant
Ray Milkeyea366452015-09-30 10:56:43 -0700138 * @throws DeserializationException if deserialization of the packet contents
139 * fails.
140 */
Ray Milkey967776a2015-10-07 14:37:17 -0700141 private void checkRADIUSPacketFromSupplicant(RADIUS radius)
Ray Milkeyea366452015-09-30 10:56:43 -0700142 throws DeserializationException {
Ray Milkeyea366452015-09-30 10:56:43 -0700143 assertThat(radius, notNullValue());
Ray Milkeyea366452015-09-30 10:56:43 -0700144
Ray Milkey967776a2015-10-07 14:37:17 -0700145 EAP eap = radius.decapsulateMessage();
Ray Milkeyea366452015-09-30 10:56:43 -0700146 assertThat(eap, notNullValue());
Ray Milkeyea366452015-09-30 10:56:43 -0700147 }
148
149 /**
150 * Fetches the sent packet at the given index. The requested packet
151 * must be the last packet on the list.
152 *
153 * @param index index into sent packets array
154 * @return packet
155 */
Ray Milkey967776a2015-10-07 14:37:17 -0700156 private BasePacket fetchPacket(int index) {
157 BasePacket packet = savedPackets.get(index);
158 assertThat(packet, notNullValue());
159 return packet;
Ray Milkeyea366452015-09-30 10:56:43 -0700160 }
161
162 /**
163 * Tests the authentication path through the AAA application.
164 *
165 * @throws DeserializationException if packed deserialization fails.
166 */
Ari Saha89831742015-06-26 10:31:48 -0700167 @Test
Ray Milkey967776a2015-10-07 14:37:17 -0700168 public void testAuthentication() throws Exception {
Ray Milkeyea366452015-09-30 10:56:43 -0700169
170 // (1) Supplicant start up
171
172 Ethernet startPacket = constructSupplicantStartPacket();
173 sendPacket(startPacket);
174
Ray Milkey967776a2015-10-07 14:37:17 -0700175 Ethernet responsePacket = (Ethernet) fetchPacket(0);
176 checkRadiusPacket(aaa, responsePacket, EAP.ATTR_IDENTITY);
Ray Milkeyea366452015-09-30 10:56:43 -0700177
178 // (2) Supplicant identify
179
Ray Milkey967776a2015-10-07 14:37:17 -0700180 Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
Ray Milkeyea366452015-09-30 10:56:43 -0700181 sendPacket(identifyPacket);
182
Ray Milkey967776a2015-10-07 14:37:17 -0700183 RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
Ray Milkeyea366452015-09-30 10:56:43 -0700184
Ray Milkey967776a2015-10-07 14:37:17 -0700185 checkRADIUSPacketFromSupplicant(radiusIdentifyPacket);
186
187 assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
188 assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()),
189 is("testuser"));
Ray Milkeyea366452015-09-30 10:56:43 -0700190
191 IpAddress nasIp =
192 IpAddress.valueOf(IpAddress.Version.INET,
Ray Milkey967776a2015-10-07 14:37:17 -0700193 radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP)
Ray Milkeyea366452015-09-30 10:56:43 -0700194 .getValue());
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700195 assertThat(nasIp.toString(), is(aaa.nasIpAddress.getHostAddress()));
Ray Milkeyea366452015-09-30 10:56:43 -0700196
197 // State machine should have been created by now
198
199 StateMachine stateMachine =
Ray Milkey967776a2015-10-07 14:37:17 -0700200 StateMachine.lookupStateMachineBySessionId(SESSION_ID);
Ray Milkeyea366452015-09-30 10:56:43 -0700201 assertThat(stateMachine, notNullValue());
202 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
203
204 // (3) RADIUS MD5 challenge
205
Ray Milkey967776a2015-10-07 14:37:17 -0700206 RADIUS radiusCodeAccessChallengePacket =
Ray Milkeyea366452015-09-30 10:56:43 -0700207 constructRADIUSCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5);
Ray Milkey967776a2015-10-07 14:37:17 -0700208 aaa.radiusListener.handleRadiusPacket(radiusCodeAccessChallengePacket);
Ray Milkeyea366452015-09-30 10:56:43 -0700209
Ray Milkey967776a2015-10-07 14:37:17 -0700210 Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2);
211 checkRadiusPacket(aaa, radiusChallengeMD5Packet, EAP.ATTR_MD5);
Ray Milkeyea366452015-09-30 10:56:43 -0700212
213 // (4) Supplicant MD5 response
214
Ray Milkey967776a2015-10-07 14:37:17 -0700215 Ethernet md5RadiusPacket =
216 constructSupplicantIdentifyPacket(stateMachine,
217 EAP.ATTR_MD5,
218 stateMachine.challengeIdentifier(),
219 radiusChallengeMD5Packet);
Ray Milkeyea366452015-09-30 10:56:43 -0700220 sendPacket(md5RadiusPacket);
Ray Milkey967776a2015-10-07 14:37:17 -0700221
222 RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3);
223
224 checkRADIUSPacketFromSupplicant(responseMd5RadiusPacket);
225 assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 0));
Ray Milkeyea366452015-09-30 10:56:43 -0700226 assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
227
228 // State machine should be in pending state
229
230 assertThat(stateMachine, notNullValue());
231 assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
232
Ray Milkey967776a2015-10-07 14:37:17 -0700233 // (5) RADIUS Success
Ray Milkeyea366452015-09-30 10:56:43 -0700234
Ray Milkey967776a2015-10-07 14:37:17 -0700235 RADIUS successPacket =
Ray Milkeyea366452015-09-30 10:56:43 -0700236 constructRADIUSCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT, EAP.SUCCESS);
Ray Milkey967776a2015-10-07 14:37:17 -0700237 aaa.radiusListener.handleRadiusPacket((successPacket));
238 Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4);
Ray Milkeyea366452015-09-30 10:56:43 -0700239
Ray Milkey967776a2015-10-07 14:37:17 -0700240 checkRadiusPacket(aaa, supplicantSuccessPacket, EAP.SUCCESS);
Ray Milkeyea366452015-09-30 10:56:43 -0700241
242 // State machine should be in authorized state
243
244 assertThat(stateMachine, notNullValue());
245 assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED));
Ray Milkey967776a2015-10-07 14:37:17 -0700246
Ari Saha89831742015-06-26 10:31:48 -0700247 }
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700248
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700249 /**
250 * Tests the default configuration.
251 */
252 @Test
253 public void testConfig() {
254 assertThat(aaa.nasIpAddress.getHostAddress(), is(AAAConfig.DEFAULT_NAS_IP));
255 assertThat(aaa.nasMacAddress, is(AAAConfig.DEFAULT_NAS_MAC));
Ray Milkey967776a2015-10-07 14:37:17 -0700256 assertThat(aaa.radiusIpAddress.getHostAddress(), is(BAD_IP_ADDRESS));
Ray Milkeyfcb623d2015-10-01 16:48:18 -0700257 assertThat(aaa.radiusMacAddress, is(AAAConfig.DEFAULT_RADIUS_MAC));
258 }
Ari Saha89831742015-06-26 10:31:48 -0700259}