blob: 3d7a28b90ca2a557ad951cf2efaa7c032f2efc26 [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
Jonathan Hart612651f2019-11-25 09:21:43 -080018import com.google.common.base.Charsets;
Ray Milkey967776a2015-10-07 14:37:17 -070019import org.onlab.packet.BasePacket;
20import org.onlab.packet.EAP;
21import org.onlab.packet.EAPOL;
22import org.onlab.packet.EthType;
23import org.onlab.packet.Ethernet;
Amit Ghoshf739be52017-09-21 15:49:37 +010024import org.onlab.packet.Ip4Address;
Ray Milkey967776a2015-10-07 14:37:17 -070025import org.onlab.packet.MacAddress;
Jonathan Hart612651f2019-11-25 09:21:43 -080026import org.onlab.packet.RADIUS;
27import org.onlab.packet.RADIUSAttribute;
Amit Ghoshf739be52017-09-21 15:49:37 +010028import org.onlab.packet.VlanId;
kartikey dubeye1545422019-05-22 12:53:45 +000029import org.onosproject.cfg.ComponentConfigService;
30import org.onosproject.cfg.ConfigProperty;
Amit Ghoshf739be52017-09-21 15:49:37 +010031import org.onosproject.net.Annotations;
Amit Ghoshf739be52017-09-21 15:49:37 +010032import org.onosproject.net.ConnectPoint;
33import org.onosproject.net.Element;
34import org.onosproject.net.Port;
35import org.onosproject.net.PortNumber;
Jonathan Hart612651f2019-11-25 09:21:43 -080036import org.onosproject.net.device.DeviceServiceAdapter;
Ray Milkey967776a2015-10-07 14:37:17 -070037import org.onosproject.net.packet.DefaultInboundPacket;
38import org.onosproject.net.packet.DefaultPacketContext;
39import org.onosproject.net.packet.InboundPacket;
40import org.onosproject.net.packet.OutboundPacket;
41import org.onosproject.net.packet.PacketContext;
42import org.onosproject.net.packet.PacketProcessor;
43import org.onosproject.net.packet.PacketServiceAdapter;
Gamze Abaka1cfdb192018-10-25 11:39:19 +000044import org.opencord.sadis.BandwidthProfileInformation;
45import org.opencord.sadis.BaseInformationService;
46import org.opencord.sadis.SadisService;
Amit Ghoshf739be52017-09-21 15:49:37 +010047import org.opencord.sadis.SubscriberAndDeviceInformation;
kartikey dubeye1545422019-05-22 12:53:45 +000048import org.osgi.framework.Bundle;
49import org.osgi.framework.BundleContext;
50import org.osgi.framework.ServiceReference;
51import org.osgi.service.component.ComponentContext;
52import org.osgi.service.component.ComponentInstance;
Amit Ghoshf739be52017-09-21 15:49:37 +010053
Jonathan Hart092dfb22015-11-16 23:05:21 -080054import java.nio.ByteBuffer;
55import java.security.MessageDigest;
kartikey dubeye1545422019-05-22 12:53:45 +000056import java.util.Dictionary;
57import java.util.Hashtable;
Jonathan Hart092dfb22015-11-16 23:05:21 -080058import java.util.LinkedList;
59import java.util.List;
Amit Ghoshf739be52017-09-21 15:49:37 +010060import java.util.Set;
Jonathan Hart092dfb22015-11-16 23:05:21 -080061
Ray Milkey967776a2015-10-07 14:37:17 -070062import static org.hamcrest.Matchers.instanceOf;
63import static org.hamcrest.Matchers.is;
64import static org.hamcrest.Matchers.notNullValue;
65import static org.junit.Assert.assertThat;
66import static org.junit.Assert.fail;
67import static org.onosproject.net.NetTestTools.connectPoint;
68
69/**
70 * Common methods for AAA app testing.
71 */
Jonathan Hart092dfb22015-11-16 23:05:21 -080072public class AaaTestBase {
Ray Milkey967776a2015-10-07 14:37:17 -070073
74 MacAddress clientMac = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
75 MacAddress serverMac = MacAddress.valueOf("2a:2a:2a:2a:2a:2a");
76
77 // Our session id will be the device ID ("of:1") with the port ("1") concatenated
78 static final String SESSION_ID = "of:11";
79
80 List<BasePacket> savedPackets = new LinkedList<>();
81 PacketProcessor packetProcessor;
82
83 /**
84 * Saves the given packet onto the saved packets list.
85 *
86 * @param packet packet to save
87 */
88 void savePacket(BasePacket packet) {
89 savedPackets.add(packet);
90 }
91
92 /**
93 * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
94 */
95 class MockPacketService extends PacketServiceAdapter {
96
97 @Override
98 public void addProcessor(PacketProcessor processor, int priority) {
99 packetProcessor = processor;
100 }
101
102 @Override
103 public void emit(OutboundPacket packet) {
104 try {
105 Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
106 0, packet.data().array().length);
107 savePacket(eth);
108 } catch (Exception e) {
109 fail(e.getMessage());
110 }
111 }
112 }
kartikey dubeye1545422019-05-22 12:53:45 +0000113 class MockComponentContext implements ComponentContext {
114
115 @Override
116 public Dictionary<String, Object> getProperties() {
117 Dictionary<String, Object> cfgDict = new Hashtable<String, Object>();
118 cfgDict.put("statisticsGenerationEvent", 20);
119 return cfgDict;
120 }
121
122 @Override
123 public Object locateService(String name) {
124 // TODO Auto-generated method stub
125 return null;
126 }
127
128 @Override
129 public Object locateService(String name, ServiceReference reference) {
130 // TODO Auto-generated method stub
131 return null;
132 }
133
134 @Override
135 public Object[] locateServices(String name) {
136 // TODO Auto-generated method stub
137 return null;
138 }
139
140 @Override
141 public BundleContext getBundleContext() {
142 // TODO Auto-generated method stub
143 return null;
144 }
145
146 @Override
147 public Bundle getUsingBundle() {
148 // TODO Auto-generated method stub
149 return null;
150 }
151
152 @Override
153 public ComponentInstance getComponentInstance() {
154 // TODO Auto-generated method stub
155 return null;
156 }
157
158 @Override
159 public void enableComponent(String name) {
160 // TODO Auto-generated method stub
161 }
162
163 @Override
164 public void disableComponent(String name) {
165 // TODO Auto-generated method stub
166 }
167
168 @Override
169 public ServiceReference getServiceReference() {
170 // TODO Auto-generated method stub
171 return null;
172 }
173 }
Ray Milkey967776a2015-10-07 14:37:17 -0700174
175 /**
Amit Ghoshf739be52017-09-21 15:49:37 +0100176 * Mocks the DeviceService.
177 */
178 final class TestDeviceService extends DeviceServiceAdapter {
179 @Override
180 public Port getPort(ConnectPoint cp) {
181 return new MockPort();
182 }
183 }
184 private class MockPort implements Port {
185
186 @Override
187 public boolean isEnabled() {
188 return true;
189 }
190 public long portSpeed() {
191 return 1000;
192 }
193 public Element element() {
194 return null;
195 }
196 public PortNumber number() {
197 return null;
198 }
199 public Annotations annotations() {
200 return new MockAnnotations();
201 }
202 public Type type() {
203 return Port.Type.FIBER;
204 }
205
206 private class MockAnnotations implements Annotations {
207
208 @Override
209 public String value(String val) {
210 return "PON 1/1";
211 }
212 public Set<String> keys() {
213 return null;
214 }
215 }
216 }
217
218 private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
219
220 MockSubscriberAndDeviceInformation(String id, VlanId ctag,
221 VlanId stag, String nasPortId,
222 String circuitId, MacAddress hardId,
223 Ip4Address ipAddress) {
224 this.setCTag(ctag);
225 this.setHardwareIdentifier(hardId);
226 this.setId(id);
227 this.setIPAddress(ipAddress);
228 this.setSTag(stag);
229 this.setNasPortId(nasPortId);
230 this.setCircuitId(circuitId);
231 }
232 }
233
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000234 final class MockSadisService implements SadisService {
235
236 @Override
237 public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
238 return new MockSubService();
239 }
240
241 @Override
242 public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
243 return null;
244 }
245 }
246
kartikey dubeye1545422019-05-22 12:53:45 +0000247 final class MockCfgService implements ComponentConfigService {
248 @Override
249 public Set<String> getComponentNames() {
250 // TODO Auto-generated method stub
251 return null;
252 }
253
254 @Override
255 public void registerProperties(Class<?> componentClass) {
256 // TODO Auto-generated method stub
257 }
258
259 @Override
260 public void unregisterProperties(Class<?> componentClass, boolean clear) {
261 // TODO Auto-generated method stub
262 }
263
264 @Override
265 public Set<ConfigProperty> getProperties(String componentName) {
266 return null;
267 }
268
269 @Override
270 public void setProperty(String componentName, String name, String value) {
271 // TODO Auto-generated method stub
272 }
273
274 @Override
275 public void preSetProperty(String componentName, String name, String value) {
276 // TODO Auto-generated method stub
277 }
278
279 @Override
280 public void preSetProperty(String componentName, String name, String value, boolean override) {
281 // TODO Auto-generated method stub
282 }
283
284 @Override
285 public void unsetProperty(String componentName, String name) {
286 // TODO Auto-generated method stub
287 }
288
289 @Override
290 public ConfigProperty getProperty(String componentName, String attribute) {
291 return null;
292 }
293
294}
295
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000296 final class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
Amit Ghoshf739be52017-09-21 15:49:37 +0100297 private final VlanId clientCtag = VlanId.vlanId((short) 999);
298 private final VlanId clientStag = VlanId.vlanId((short) 111);
299 private final String clientNasPortId = "PON 1/1";
300 private final String clientCircuitId = "CIR-PON 1/1";
301
302 MockSubscriberAndDeviceInformation sub =
303 new MockSubscriberAndDeviceInformation(clientNasPortId, clientCtag,
304 clientStag, clientNasPortId, clientCircuitId, null, null);
305 @Override
306 public SubscriberAndDeviceInformation get(String id) {
307
308 return sub;
309
310 }
311
312 @Override
313 public void invalidateAll() {}
314 public void invalidateId(String id) {}
315 public SubscriberAndDeviceInformation getfromCache(String id) {
316 return null;
317 }
318 }
319 /**
Ray Milkey967776a2015-10-07 14:37:17 -0700320 * Mocks the DefaultPacketContext.
321 */
322 final class TestPacketContext extends DefaultPacketContext {
323
Shubham Sharmacf5e5032019-11-26 11:09:21 +0000324 TestPacketContext(long time, InboundPacket inPkt,
Ray Milkey967776a2015-10-07 14:37:17 -0700325 OutboundPacket outPkt, boolean block) {
326 super(time, inPkt, outPkt, block);
327 }
328
329 @Override
330 public void send() {
331 // We don't send anything out.
332 }
333 }
334
335 /**
336 * Sends an Ethernet packet to the process method of the Packet Processor.
337 *
338 * @param reply Ethernet packet
339 */
340 void sendPacket(Ethernet reply) {
341 final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
342 InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
343 reply,
344 byteBuffer);
345
346 PacketContext context = new TestPacketContext(127L, inPacket, null, false);
347 packetProcessor.process(context);
348 }
349
350 /**
351 * Constructs an Ethernet packet containing identification payload.
352 *
353 * @return Ethernet packet
354 */
355 Ethernet constructSupplicantIdentifyPacket(StateMachine stateMachine,
356 byte type,
357 byte id,
358 Ethernet radiusChallenge)
359 throws Exception {
360 Ethernet eth = new Ethernet();
361 eth.setDestinationMACAddress(clientMac.toBytes());
362 eth.setSourceMACAddress(serverMac.toBytes());
363 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
364 eth.setVlanID((short) 2);
365
366 String username = "testuser";
367 byte[] data = username.getBytes();
368
369
370 if (type == EAP.ATTR_MD5) {
371 String password = "testpassword";
372 EAPOL eapol = (EAPOL) radiusChallenge.getPayload();
373 EAP eap = (EAP) eapol.getPayload();
374
375 byte[] identifier = new byte[password.length() + eap.getData().length];
376
377 identifier[0] = stateMachine.challengeIdentifier();
378 System.arraycopy(password.getBytes(), 0, identifier, 1, password.length());
379 System.arraycopy(eap.getData(), 1, identifier, 1 + password.length(), 16);
380
381 MessageDigest md = MessageDigest.getInstance("MD5");
382 byte[] hash = md.digest(identifier);
383 data = new byte[17];
384 data[0] = (byte) 16;
385 System.arraycopy(hash, 0, data, 1, 16);
386 }
387 EAP eap = new EAP(EAP.RESPONSE, (byte) 1, type,
388 data);
389 eap.setIdentifier(id);
390
391 // eapol header
392 EAPOL eapol = new EAPOL();
393 eapol.setEapolType(EAPOL.EAPOL_PACKET);
394 eapol.setPacketLength(eap.getLength());
395
396 // eap part
397 eapol.setPayload(eap);
398
399 eth.setPayload(eapol);
400 eth.setPad(true);
401 return eth;
402 }
403
404 /**
405 * Constructs an Ethernet packet containing a EAPOL_START Payload.
406 *
407 * @return Ethernet packet
408 */
409 Ethernet constructSupplicantStartPacket() {
410 Ethernet eth = new Ethernet();
411 eth.setDestinationMACAddress(clientMac.toBytes());
412 eth.setSourceMACAddress(serverMac.toBytes());
413 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
414 eth.setVlanID((short) 2);
415
Shubham Sharma4900ce62019-06-19 14:18:50 +0000416 EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 3, EAPOL.EAPOL_START, null);
Ray Milkey967776a2015-10-07 14:37:17 -0700417
418 // eapol header
419 EAPOL eapol = new EAPOL();
420 eapol.setEapolType(EAPOL.EAPOL_START);
421 eapol.setPacketLength(eap.getLength());
422
423 // eap part
424 eapol.setPayload(eap);
425
426 eth.setPayload(eapol);
427 eth.setPad(true);
428 return eth;
429 }
430
431 /**
432 * Checks the contents of a RADIUS packet being sent to the RADIUS server.
433 *
434 * @param radiusPacket packet to check
435 * @param code expected code
436 */
Jonathan Hart092dfb22015-11-16 23:05:21 -0800437 void checkRadiusPacket(AaaManager aaaManager, Ethernet radiusPacket, byte code) {
Ray Milkey967776a2015-10-07 14:37:17 -0700438
439 assertThat(radiusPacket.getSourceMAC(),
Jonathan Hart092dfb22015-11-16 23:05:21 -0800440 is(MacAddress.valueOf(aaaManager.nasMacAddress)));
Ray Milkey967776a2015-10-07 14:37:17 -0700441 assertThat(radiusPacket.getDestinationMAC(), is(serverMac));
442
443 assertThat(radiusPacket.getPayload(), instanceOf(EAPOL.class));
444 EAPOL eapol = (EAPOL) radiusPacket.getPayload();
445 assertThat(eapol, notNullValue());
446
447 assertThat(eapol.getEapolType(), is(EAPOL.EAPOL_PACKET));
448 assertThat(eapol.getPayload(), instanceOf(EAP.class));
449 EAP eap = (EAP) eapol.getPayload();
450 assertThat(eap, notNullValue());
451
452 assertThat(eap.getCode(), is(code));
453 }
Shubham Sharma2b3fb692019-12-12 10:19:10 +0000454
455 /**
456 * Constructs an Ethernet packet containing a EAPOL_LOGOFF Payload.
457 *
458 * @return Ethernet packet
459 */
460 Ethernet constructSupplicantLogoffPacket() {
461 Ethernet eth = new Ethernet();
462 eth.setDestinationMACAddress(clientMac.toBytes());
463 eth.setSourceMACAddress(serverMac.toBytes());
464 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
465 eth.setVlanID((short) 2);
466
467 EAP eap = new EAP(EAPOL.EAPOL_LOGOFF, (byte) 2, EAPOL.EAPOL_LOGOFF, null);
468
469 // eapol header
470 EAPOL eapol = new EAPOL();
471 eapol.setEapolType(EAPOL.EAPOL_LOGOFF);
472 eapol.setPacketLength(eap.getLength());
473
474 // eap part
475 eapol.setPayload(eap);
476
477 eth.setPayload(eapol);
478 eth.setPad(true);
479 return eth;
480 }
481
Jonathan Hart612651f2019-11-25 09:21:43 -0800482 /**
483 * Constructs an Ethernet packet containing a RADIUS challenge
484 * packet.
485 *
486 * @param challengeCode code to use in challenge packet
487 * @param challengeType type to use in challenge packet
488 * @return Ethernet packet
489 */
490 RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType,
491 byte identifier, byte[] messageAuth) {
492
493 String challenge = "12345678901234567";
494
495 EAP eap = new EAP(challengeType, (byte) 4, challengeType,
496 challenge.getBytes(Charsets.US_ASCII));
497 //eap.setIdentifier((byte) 4);
498 eap.setIdentifier(identifier);
499
500 RADIUS radius = new RADIUS();
501 radius.setCode(challengeCode);
502 //radius.setIdentifier((byte) 4);
503 radius.setIdentifier(identifier);
504 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
505 challenge.getBytes(Charsets.US_ASCII));
506
507 radius.setPayload(eap);
508 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE, eap.serialize());
509 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, messageAuth);
510 return radius;
511 }
Ray Milkey967776a2015-10-07 14:37:17 -0700512}