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