blob: cb2c5d13c31508031e27131104da25a37cb881fe [file] [log] [blame]
Ray Milkey967776a2015-10-07 14:37:17 -07001/*
Brian O'Connor4e33be22017-08-03 22:45:46 -07002 * Copyright 2015-present Open Networking Foundation
Ray Milkey967776a2015-10-07 14:37:17 -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;
Ray Milkey967776a2015-10-07 14:37:17 -070017
Ray Milkey967776a2015-10-07 14:37:17 -070018import org.onlab.packet.BasePacket;
19import org.onlab.packet.EAP;
20import org.onlab.packet.EAPOL;
21import org.onlab.packet.EthType;
22import org.onlab.packet.Ethernet;
Amit Ghosh3f8ee432017-09-21 15:49:37 +010023import org.onlab.packet.Ip4Address;
Ray Milkey967776a2015-10-07 14:37:17 -070024import org.onlab.packet.MacAddress;
Amit Ghosh3f8ee432017-09-21 15:49:37 +010025import org.onlab.packet.VlanId;
26
27import org.onosproject.net.Annotations;
28import org.onosproject.net.device.DeviceServiceAdapter;
29import org.onosproject.net.ConnectPoint;
30import org.onosproject.net.Element;
31import org.onosproject.net.Port;
32import org.onosproject.net.PortNumber;
Ray Milkey967776a2015-10-07 14:37:17 -070033import org.onosproject.net.packet.DefaultInboundPacket;
34import org.onosproject.net.packet.DefaultPacketContext;
35import org.onosproject.net.packet.InboundPacket;
36import org.onosproject.net.packet.OutboundPacket;
37import org.onosproject.net.packet.PacketContext;
38import org.onosproject.net.packet.PacketProcessor;
39import org.onosproject.net.packet.PacketServiceAdapter;
40
Amit Ghosh3f8ee432017-09-21 15:49:37 +010041import org.opencord.sadis.SubscriberAndDeviceInformation;
42import org.opencord.sadis.SubscriberAndDeviceInformationService;
43
Jonathan Hart092dfb22015-11-16 23:05:21 -080044import java.nio.ByteBuffer;
45import java.security.MessageDigest;
46import java.util.LinkedList;
47import java.util.List;
Amit Ghosh3f8ee432017-09-21 15:49:37 +010048import java.util.Set;
Jonathan Hart092dfb22015-11-16 23:05:21 -080049
Ray Milkey967776a2015-10-07 14:37:17 -070050import static org.hamcrest.Matchers.instanceOf;
51import static org.hamcrest.Matchers.is;
52import static org.hamcrest.Matchers.notNullValue;
53import static org.junit.Assert.assertThat;
54import static org.junit.Assert.fail;
55import static org.onosproject.net.NetTestTools.connectPoint;
56
57/**
58 * Common methods for AAA app testing.
59 */
Jonathan Hart092dfb22015-11-16 23:05:21 -080060public class AaaTestBase {
Ray Milkey967776a2015-10-07 14:37:17 -070061
62 MacAddress clientMac = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
63 MacAddress serverMac = MacAddress.valueOf("2a:2a:2a:2a:2a:2a");
64
65 // Our session id will be the device ID ("of:1") with the port ("1") concatenated
66 static final String SESSION_ID = "of:11";
67
68 List<BasePacket> savedPackets = new LinkedList<>();
69 PacketProcessor packetProcessor;
70
71 /**
72 * Saves the given packet onto the saved packets list.
73 *
74 * @param packet packet to save
75 */
76 void savePacket(BasePacket packet) {
77 savedPackets.add(packet);
78 }
79
80 /**
81 * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
82 */
83 class MockPacketService extends PacketServiceAdapter {
84
85 @Override
86 public void addProcessor(PacketProcessor processor, int priority) {
87 packetProcessor = processor;
88 }
89
90 @Override
91 public void emit(OutboundPacket packet) {
92 try {
93 Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
94 0, packet.data().array().length);
95 savePacket(eth);
96 } catch (Exception e) {
97 fail(e.getMessage());
98 }
99 }
100 }
101
102 /**
Amit Ghosh3f8ee432017-09-21 15:49:37 +0100103 * Mocks the DeviceService.
104 */
105 final class TestDeviceService extends DeviceServiceAdapter {
106 @Override
107 public Port getPort(ConnectPoint cp) {
108 return new MockPort();
109 }
110 }
111 private class MockPort implements Port {
112
113 @Override
114 public boolean isEnabled() {
115 return true;
116 }
117 public long portSpeed() {
118 return 1000;
119 }
120 public Element element() {
121 return null;
122 }
123 public PortNumber number() {
124 return null;
125 }
126 public Annotations annotations() {
127 return new MockAnnotations();
128 }
129 public Type type() {
130 return Port.Type.FIBER;
131 }
132
133 private class MockAnnotations implements Annotations {
134
135 @Override
136 public String value(String val) {
137 return "PON 1/1";
138 }
139 public Set<String> keys() {
140 return null;
141 }
142 }
143 }
144
145 private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
146
147 MockSubscriberAndDeviceInformation(String id, VlanId ctag,
148 VlanId stag, String nasPortId,
149 String circuitId, MacAddress hardId,
150 Ip4Address ipAddress) {
151 this.setCTag(ctag);
152 this.setHardwareIdentifier(hardId);
153 this.setId(id);
154 this.setIPAddress(ipAddress);
155 this.setSTag(stag);
156 this.setNasPortId(nasPortId);
157 this.setCircuitId(circuitId);
158 }
159 }
160
161 final class MockSubService implements SubscriberAndDeviceInformationService {
162 private final VlanId clientCtag = VlanId.vlanId((short) 999);
163 private final VlanId clientStag = VlanId.vlanId((short) 111);
164 private final String clientNasPortId = "PON 1/1";
165 private final String clientCircuitId = "CIR-PON 1/1";
166
167 MockSubscriberAndDeviceInformation sub =
168 new MockSubscriberAndDeviceInformation(clientNasPortId, clientCtag,
169 clientStag, clientNasPortId, clientCircuitId, null, null);
170 @Override
171 public SubscriberAndDeviceInformation get(String id) {
172
173 return sub;
174
175 }
176
177 @Override
178 public void invalidateAll() {}
179 public void invalidateId(String id) {}
180 public SubscriberAndDeviceInformation getfromCache(String id) {
181 return null;
182 }
183 }
184 /**
Ray Milkey967776a2015-10-07 14:37:17 -0700185 * Mocks the DefaultPacketContext.
186 */
187 final class TestPacketContext extends DefaultPacketContext {
188
189 private TestPacketContext(long time, InboundPacket inPkt,
190 OutboundPacket outPkt, boolean block) {
191 super(time, inPkt, outPkt, block);
192 }
193
194 @Override
195 public void send() {
196 // We don't send anything out.
197 }
198 }
199
200 /**
201 * Sends an Ethernet packet to the process method of the Packet Processor.
202 *
203 * @param reply Ethernet packet
204 */
205 void sendPacket(Ethernet reply) {
206 final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
207 InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
208 reply,
209 byteBuffer);
210
211 PacketContext context = new TestPacketContext(127L, inPacket, null, false);
212 packetProcessor.process(context);
213 }
214
215 /**
216 * Constructs an Ethernet packet containing identification payload.
217 *
218 * @return Ethernet packet
219 */
220 Ethernet constructSupplicantIdentifyPacket(StateMachine stateMachine,
221 byte type,
222 byte id,
223 Ethernet radiusChallenge)
224 throws Exception {
225 Ethernet eth = new Ethernet();
226 eth.setDestinationMACAddress(clientMac.toBytes());
227 eth.setSourceMACAddress(serverMac.toBytes());
228 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
229 eth.setVlanID((short) 2);
230
231 String username = "testuser";
232 byte[] data = username.getBytes();
233
234
235 if (type == EAP.ATTR_MD5) {
236 String password = "testpassword";
237 EAPOL eapol = (EAPOL) radiusChallenge.getPayload();
238 EAP eap = (EAP) eapol.getPayload();
239
240 byte[] identifier = new byte[password.length() + eap.getData().length];
241
242 identifier[0] = stateMachine.challengeIdentifier();
243 System.arraycopy(password.getBytes(), 0, identifier, 1, password.length());
244 System.arraycopy(eap.getData(), 1, identifier, 1 + password.length(), 16);
245
246 MessageDigest md = MessageDigest.getInstance("MD5");
247 byte[] hash = md.digest(identifier);
248 data = new byte[17];
249 data[0] = (byte) 16;
250 System.arraycopy(hash, 0, data, 1, 16);
251 }
252 EAP eap = new EAP(EAP.RESPONSE, (byte) 1, type,
253 data);
254 eap.setIdentifier(id);
255
256 // eapol header
257 EAPOL eapol = new EAPOL();
258 eapol.setEapolType(EAPOL.EAPOL_PACKET);
259 eapol.setPacketLength(eap.getLength());
260
261 // eap part
262 eapol.setPayload(eap);
263
264 eth.setPayload(eapol);
265 eth.setPad(true);
266 return eth;
267 }
268
269 /**
270 * Constructs an Ethernet packet containing a EAPOL_START Payload.
271 *
272 * @return Ethernet packet
273 */
274 Ethernet constructSupplicantStartPacket() {
275 Ethernet eth = new Ethernet();
276 eth.setDestinationMACAddress(clientMac.toBytes());
277 eth.setSourceMACAddress(serverMac.toBytes());
278 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
279 eth.setVlanID((short) 2);
280
281 EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 2, EAPOL.EAPOL_START, null);
282
283 // eapol header
284 EAPOL eapol = new EAPOL();
285 eapol.setEapolType(EAPOL.EAPOL_START);
286 eapol.setPacketLength(eap.getLength());
287
288 // eap part
289 eapol.setPayload(eap);
290
291 eth.setPayload(eapol);
292 eth.setPad(true);
293 return eth;
294 }
295
296 /**
297 * Checks the contents of a RADIUS packet being sent to the RADIUS server.
298 *
299 * @param radiusPacket packet to check
300 * @param code expected code
301 */
Jonathan Hart092dfb22015-11-16 23:05:21 -0800302 void checkRadiusPacket(AaaManager aaaManager, Ethernet radiusPacket, byte code) {
Ray Milkey967776a2015-10-07 14:37:17 -0700303
304 assertThat(radiusPacket.getSourceMAC(),
Jonathan Hart092dfb22015-11-16 23:05:21 -0800305 is(MacAddress.valueOf(aaaManager.nasMacAddress)));
Ray Milkey967776a2015-10-07 14:37:17 -0700306 assertThat(radiusPacket.getDestinationMAC(), is(serverMac));
307
308 assertThat(radiusPacket.getPayload(), instanceOf(EAPOL.class));
309 EAPOL eapol = (EAPOL) radiusPacket.getPayload();
310 assertThat(eapol, notNullValue());
311
312 assertThat(eapol.getEapolType(), is(EAPOL.EAPOL_PACKET));
313 assertThat(eapol.getPayload(), instanceOf(EAP.class));
314 EAP eap = (EAP) eapol.getPayload();
315 assertThat(eap, notNullValue());
316
317 assertThat(eap.getCode(), is(code));
318 }
319}