blob: fdd23e9092d41895d77edcd6717f80f170408027 [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;
Andrea Campanella7e0e7e32020-02-13 14:39:55 +010019import com.google.common.collect.Lists;
Ray Milkey967776a2015-10-07 14:37:17 -070020import org.onlab.packet.BasePacket;
21import org.onlab.packet.EAP;
22import org.onlab.packet.EAPOL;
23import org.onlab.packet.EthType;
24import org.onlab.packet.Ethernet;
Amit Ghoshf739be52017-09-21 15:49:37 +010025import org.onlab.packet.Ip4Address;
Ray Milkey967776a2015-10-07 14:37:17 -070026import org.onlab.packet.MacAddress;
Jonathan Hart612651f2019-11-25 09:21:43 -080027import org.onlab.packet.RADIUS;
28import org.onlab.packet.RADIUSAttribute;
Amit Ghoshf739be52017-09-21 15:49:37 +010029import org.onlab.packet.VlanId;
kartikey dubeye1545422019-05-22 12:53:45 +000030import org.onosproject.cfg.ComponentConfigService;
31import org.onosproject.cfg.ConfigProperty;
Amit Ghoshf739be52017-09-21 15:49:37 +010032import org.onosproject.net.Annotations;
Amit Ghoshf739be52017-09-21 15:49:37 +010033import org.onosproject.net.ConnectPoint;
34import org.onosproject.net.Element;
35import org.onosproject.net.Port;
36import org.onosproject.net.PortNumber;
Jonathan Hart612651f2019-11-25 09:21:43 -080037import org.onosproject.net.device.DeviceServiceAdapter;
Ray Milkey967776a2015-10-07 14:37:17 -070038import org.onosproject.net.packet.DefaultInboundPacket;
39import org.onosproject.net.packet.DefaultPacketContext;
40import org.onosproject.net.packet.InboundPacket;
41import org.onosproject.net.packet.OutboundPacket;
42import org.onosproject.net.packet.PacketContext;
43import org.onosproject.net.packet.PacketProcessor;
44import org.onosproject.net.packet.PacketServiceAdapter;
Gamze Abaka1cfdb192018-10-25 11:39:19 +000045import org.opencord.sadis.BandwidthProfileInformation;
46import org.opencord.sadis.BaseInformationService;
47import org.opencord.sadis.SadisService;
Amit Ghoshf739be52017-09-21 15:49:37 +010048import org.opencord.sadis.SubscriberAndDeviceInformation;
Andrea Campanella7e0e7e32020-02-13 14:39:55 +010049import org.opencord.sadis.UniTagInformation;
kartikey dubeye1545422019-05-22 12:53:45 +000050import org.osgi.framework.Bundle;
51import org.osgi.framework.BundleContext;
52import org.osgi.framework.ServiceReference;
53import org.osgi.service.component.ComponentContext;
54import org.osgi.service.component.ComponentInstance;
Amit Ghoshf739be52017-09-21 15:49:37 +010055
Jonathan Hart092dfb22015-11-16 23:05:21 -080056import java.nio.ByteBuffer;
57import java.security.MessageDigest;
kartikey dubeye1545422019-05-22 12:53:45 +000058import java.util.Dictionary;
59import java.util.Hashtable;
Jonathan Hart092dfb22015-11-16 23:05:21 -080060import java.util.LinkedList;
61import java.util.List;
Amit Ghoshf739be52017-09-21 15:49:37 +010062import java.util.Set;
Jonathan Hart092dfb22015-11-16 23:05:21 -080063
Ray Milkey967776a2015-10-07 14:37:17 -070064import static org.hamcrest.Matchers.instanceOf;
65import static org.hamcrest.Matchers.is;
66import static org.hamcrest.Matchers.notNullValue;
67import static org.junit.Assert.assertThat;
68import static org.junit.Assert.fail;
69import static org.onosproject.net.NetTestTools.connectPoint;
70
71/**
72 * Common methods for AAA app testing.
73 */
Jonathan Hart092dfb22015-11-16 23:05:21 -080074public class AaaTestBase {
Ray Milkey967776a2015-10-07 14:37:17 -070075
Matteo Scandolo9510e5d2020-09-24 17:31:52 -070076 //Time in ms to wait before checking packets
77 static final int ASSERTION_DELAY = 250;
78 //Duration in ms of the assertion for packets
79 static final int ASSERTION_LENGTH = 500;
80
Ray Milkey967776a2015-10-07 14:37:17 -070081 MacAddress clientMac = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
82 MacAddress serverMac = MacAddress.valueOf("2a:2a:2a:2a:2a:2a");
83
84 // Our session id will be the device ID ("of:1") with the port ("1") concatenated
85 static final String SESSION_ID = "of:11";
86
87 List<BasePacket> savedPackets = new LinkedList<>();
88 PacketProcessor packetProcessor;
89
90 /**
91 * Saves the given packet onto the saved packets list.
92 *
93 * @param packet packet to save
94 */
95 void savePacket(BasePacket packet) {
96 savedPackets.add(packet);
97 }
98
99 /**
100 * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
101 */
102 class MockPacketService extends PacketServiceAdapter {
103
104 @Override
105 public void addProcessor(PacketProcessor processor, int priority) {
106 packetProcessor = processor;
107 }
108
109 @Override
110 public void emit(OutboundPacket packet) {
111 try {
112 Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
113 0, packet.data().array().length);
114 savePacket(eth);
115 } catch (Exception e) {
116 fail(e.getMessage());
117 }
118 }
119 }
kartikey dubeye1545422019-05-22 12:53:45 +0000120 class MockComponentContext implements ComponentContext {
121
122 @Override
123 public Dictionary<String, Object> getProperties() {
124 Dictionary<String, Object> cfgDict = new Hashtable<String, Object>();
125 cfgDict.put("statisticsGenerationEvent", 20);
126 return cfgDict;
127 }
128
129 @Override
130 public Object locateService(String name) {
131 // TODO Auto-generated method stub
132 return null;
133 }
134
135 @Override
136 public Object locateService(String name, ServiceReference reference) {
137 // TODO Auto-generated method stub
138 return null;
139 }
140
141 @Override
142 public Object[] locateServices(String name) {
143 // TODO Auto-generated method stub
144 return null;
145 }
146
147 @Override
148 public BundleContext getBundleContext() {
149 // TODO Auto-generated method stub
150 return null;
151 }
152
153 @Override
154 public Bundle getUsingBundle() {
155 // TODO Auto-generated method stub
156 return null;
157 }
158
159 @Override
160 public ComponentInstance getComponentInstance() {
161 // TODO Auto-generated method stub
162 return null;
163 }
164
165 @Override
166 public void enableComponent(String name) {
167 // TODO Auto-generated method stub
168 }
169
170 @Override
171 public void disableComponent(String name) {
172 // TODO Auto-generated method stub
173 }
174
175 @Override
176 public ServiceReference getServiceReference() {
177 // TODO Auto-generated method stub
178 return null;
179 }
180 }
Ray Milkey967776a2015-10-07 14:37:17 -0700181
182 /**
Amit Ghoshf739be52017-09-21 15:49:37 +0100183 * Mocks the DeviceService.
184 */
185 final class TestDeviceService extends DeviceServiceAdapter {
186 @Override
187 public Port getPort(ConnectPoint cp) {
188 return new MockPort();
189 }
190 }
191 private class MockPort implements Port {
192
193 @Override
194 public boolean isEnabled() {
195 return true;
196 }
197 public long portSpeed() {
198 return 1000;
199 }
200 public Element element() {
201 return null;
202 }
203 public PortNumber number() {
204 return null;
205 }
206 public Annotations annotations() {
207 return new MockAnnotations();
208 }
209 public Type type() {
210 return Port.Type.FIBER;
211 }
212
213 private class MockAnnotations implements Annotations {
214
215 @Override
216 public String value(String val) {
217 return "PON 1/1";
218 }
219 public Set<String> keys() {
220 return null;
221 }
222 }
223 }
224
225 private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
226
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100227 MockSubscriberAndDeviceInformation(String id, VlanId uniTagMatch, VlanId ctag,
228 VlanId stag, int dsPonPrio, int upPonPrio,
229 int techProfileId, String dsBpId, String usBpId,
230 String nasPortId, String circuitId, MacAddress hardId,
Amit Ghoshf739be52017-09-21 15:49:37 +0100231 Ip4Address ipAddress) {
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100232 // Builds UniTagInformation
233 UniTagInformation.Builder tagInfoBuilder = new UniTagInformation.Builder();
234 UniTagInformation uniTagInfo = tagInfoBuilder.setUniTagMatch(uniTagMatch)
235 .setPonCTag(ctag)
236 .setPonSTag(stag)
237 .setDsPonCTagPriority(dsPonPrio)
238 .setUsPonSTagPriority(upPonPrio)
239 .setTechnologyProfileId(techProfileId)
240 .setDownstreamBandwidthProfile(dsBpId)
241 .setUpstreamBandwidthProfile(usBpId)
242 .build();
243
Amit Ghoshf739be52017-09-21 15:49:37 +0100244 this.setHardwareIdentifier(hardId);
245 this.setId(id);
246 this.setIPAddress(ipAddress);
Amit Ghoshf739be52017-09-21 15:49:37 +0100247 this.setNasPortId(nasPortId);
248 this.setCircuitId(circuitId);
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100249 this.setUniTagList(Lists.newArrayList(uniTagInfo));
Amit Ghoshf739be52017-09-21 15:49:37 +0100250 }
251 }
252
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000253 final class MockSadisService implements SadisService {
254
255 @Override
256 public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
257 return new MockSubService();
258 }
259
260 @Override
261 public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
262 return null;
263 }
264 }
265
kartikey dubeye1545422019-05-22 12:53:45 +0000266 final class MockCfgService implements ComponentConfigService {
267 @Override
268 public Set<String> getComponentNames() {
269 // TODO Auto-generated method stub
270 return null;
271 }
272
273 @Override
274 public void registerProperties(Class<?> componentClass) {
275 // TODO Auto-generated method stub
276 }
277
278 @Override
279 public void unregisterProperties(Class<?> componentClass, boolean clear) {
280 // TODO Auto-generated method stub
281 }
282
283 @Override
284 public Set<ConfigProperty> getProperties(String componentName) {
285 return null;
286 }
287
288 @Override
289 public void setProperty(String componentName, String name, String value) {
290 // TODO Auto-generated method stub
291 }
292
293 @Override
294 public void preSetProperty(String componentName, String name, String value) {
295 // TODO Auto-generated method stub
296 }
297
298 @Override
299 public void preSetProperty(String componentName, String name, String value, boolean override) {
300 // TODO Auto-generated method stub
301 }
302
303 @Override
304 public void unsetProperty(String componentName, String name) {
305 // TODO Auto-generated method stub
306 }
307
308 @Override
309 public ConfigProperty getProperty(String componentName, String attribute) {
310 return null;
311 }
312
313}
314
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000315 final class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100316 private final VlanId uniTagMatch = VlanId.vlanId((short) 35);
Amit Ghoshf739be52017-09-21 15:49:37 +0100317 private final VlanId clientCtag = VlanId.vlanId((short) 999);
318 private final VlanId clientStag = VlanId.vlanId((short) 111);
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100319 private final int dsPrio = 0;
320 private final int usPrio = 0;
321 private final int techProfileId = 64;
322 private final String usBpId = "HSIA-US";
323 private final String dsBpId = "HSIA-DS";
Amit Ghoshf739be52017-09-21 15:49:37 +0100324 private final String clientNasPortId = "PON 1/1";
325 private final String clientCircuitId = "CIR-PON 1/1";
326
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100327
Amit Ghoshf739be52017-09-21 15:49:37 +0100328 MockSubscriberAndDeviceInformation sub =
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100329 new MockSubscriberAndDeviceInformation(clientNasPortId, uniTagMatch, clientCtag,
330 clientStag, dsPrio, usPrio,
331 techProfileId, dsBpId, usBpId,
332 clientNasPortId, clientCircuitId, null,
333 null);
Amit Ghoshf739be52017-09-21 15:49:37 +0100334 @Override
335 public SubscriberAndDeviceInformation get(String id) {
336
337 return sub;
338
339 }
340
341 @Override
342 public void invalidateAll() {}
343 public void invalidateId(String id) {}
344 public SubscriberAndDeviceInformation getfromCache(String id) {
345 return null;
346 }
347 }
348 /**
Ray Milkey967776a2015-10-07 14:37:17 -0700349 * Mocks the DefaultPacketContext.
350 */
351 final class TestPacketContext extends DefaultPacketContext {
352
Shubham Sharmacf5e5032019-11-26 11:09:21 +0000353 TestPacketContext(long time, InboundPacket inPkt,
Ray Milkey967776a2015-10-07 14:37:17 -0700354 OutboundPacket outPkt, boolean block) {
355 super(time, inPkt, outPkt, block);
356 }
357
358 @Override
359 public void send() {
360 // We don't send anything out.
361 }
362 }
363
364 /**
365 * Sends an Ethernet packet to the process method of the Packet Processor.
366 *
367 * @param reply Ethernet packet
368 */
369 void sendPacket(Ethernet reply) {
370 final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
371 InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
372 reply,
373 byteBuffer);
374
375 PacketContext context = new TestPacketContext(127L, inPacket, null, false);
376 packetProcessor.process(context);
377 }
378
379 /**
380 * Constructs an Ethernet packet containing identification payload.
381 *
382 * @return Ethernet packet
383 */
384 Ethernet constructSupplicantIdentifyPacket(StateMachine stateMachine,
385 byte type,
386 byte id,
387 Ethernet radiusChallenge)
388 throws Exception {
389 Ethernet eth = new Ethernet();
390 eth.setDestinationMACAddress(clientMac.toBytes());
391 eth.setSourceMACAddress(serverMac.toBytes());
392 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
393 eth.setVlanID((short) 2);
394
395 String username = "testuser";
396 byte[] data = username.getBytes();
397
398
399 if (type == EAP.ATTR_MD5) {
400 String password = "testpassword";
401 EAPOL eapol = (EAPOL) radiusChallenge.getPayload();
402 EAP eap = (EAP) eapol.getPayload();
403
404 byte[] identifier = new byte[password.length() + eap.getData().length];
405
406 identifier[0] = stateMachine.challengeIdentifier();
407 System.arraycopy(password.getBytes(), 0, identifier, 1, password.length());
408 System.arraycopy(eap.getData(), 1, identifier, 1 + password.length(), 16);
409
410 MessageDigest md = MessageDigest.getInstance("MD5");
411 byte[] hash = md.digest(identifier);
412 data = new byte[17];
413 data[0] = (byte) 16;
414 System.arraycopy(hash, 0, data, 1, 16);
415 }
416 EAP eap = new EAP(EAP.RESPONSE, (byte) 1, type,
417 data);
418 eap.setIdentifier(id);
419
420 // eapol header
421 EAPOL eapol = new EAPOL();
422 eapol.setEapolType(EAPOL.EAPOL_PACKET);
423 eapol.setPacketLength(eap.getLength());
424
425 // eap part
426 eapol.setPayload(eap);
427
428 eth.setPayload(eapol);
429 eth.setPad(true);
430 return eth;
431 }
432
433 /**
434 * Constructs an Ethernet packet containing a EAPOL_START Payload.
435 *
436 * @return Ethernet packet
437 */
438 Ethernet constructSupplicantStartPacket() {
439 Ethernet eth = new Ethernet();
440 eth.setDestinationMACAddress(clientMac.toBytes());
441 eth.setSourceMACAddress(serverMac.toBytes());
442 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
443 eth.setVlanID((short) 2);
444
Shubham Sharma4900ce62019-06-19 14:18:50 +0000445 EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 3, EAPOL.EAPOL_START, null);
Ray Milkey967776a2015-10-07 14:37:17 -0700446
447 // eapol header
448 EAPOL eapol = new EAPOL();
449 eapol.setEapolType(EAPOL.EAPOL_START);
450 eapol.setPacketLength(eap.getLength());
451
452 // eap part
453 eapol.setPayload(eap);
454
455 eth.setPayload(eapol);
456 eth.setPad(true);
457 return eth;
458 }
459
460 /**
Shubham Sharma8d7a9822020-01-28 10:04:01 +0000461 * Constructs an Ethernet packet containing a EAPOL_ASF Payload.
462 *
463 * @return Ethernet packet
464 */
465 Ethernet constructSupplicantAsfPacket() {
466 Ethernet eth = new Ethernet();
467 eth.setDestinationMACAddress(clientMac.toBytes());
468 eth.setSourceMACAddress(serverMac.toBytes());
469 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
470 eth.setVlanID((short) 2);
471
472 EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 3, EAPOL.EAPOL_START, null);
473
474 // eapol header
475 EAPOL eapol = new EAPOL();
476 eapol.setEapolType(EAPOL.EAPOL_ASF);
477 eapol.setPacketLength(eap.getLength());
478
479 // eap part
480 eapol.setPayload(eap);
481
482 eth.setPayload(eapol);
483 eth.setPad(true);
484 return eth;
485 }
486
487 /**
Ray Milkey967776a2015-10-07 14:37:17 -0700488 * Checks the contents of a RADIUS packet being sent to the RADIUS server.
489 *
490 * @param radiusPacket packet to check
491 * @param code expected code
492 */
Jonathan Hart092dfb22015-11-16 23:05:21 -0800493 void checkRadiusPacket(AaaManager aaaManager, Ethernet radiusPacket, byte code) {
Ray Milkey967776a2015-10-07 14:37:17 -0700494
495 assertThat(radiusPacket.getSourceMAC(),
Jonathan Hart092dfb22015-11-16 23:05:21 -0800496 is(MacAddress.valueOf(aaaManager.nasMacAddress)));
Ray Milkey967776a2015-10-07 14:37:17 -0700497 assertThat(radiusPacket.getDestinationMAC(), is(serverMac));
498
499 assertThat(radiusPacket.getPayload(), instanceOf(EAPOL.class));
500 EAPOL eapol = (EAPOL) radiusPacket.getPayload();
501 assertThat(eapol, notNullValue());
502
503 assertThat(eapol.getEapolType(), is(EAPOL.EAPOL_PACKET));
504 assertThat(eapol.getPayload(), instanceOf(EAP.class));
505 EAP eap = (EAP) eapol.getPayload();
506 assertThat(eap, notNullValue());
507
508 assertThat(eap.getCode(), is(code));
509 }
Shubham Sharma2b3fb692019-12-12 10:19:10 +0000510
511 /**
512 * Constructs an Ethernet packet containing a EAPOL_LOGOFF Payload.
513 *
514 * @return Ethernet packet
515 */
516 Ethernet constructSupplicantLogoffPacket() {
517 Ethernet eth = new Ethernet();
518 eth.setDestinationMACAddress(clientMac.toBytes());
519 eth.setSourceMACAddress(serverMac.toBytes());
520 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
521 eth.setVlanID((short) 2);
522
523 EAP eap = new EAP(EAPOL.EAPOL_LOGOFF, (byte) 2, EAPOL.EAPOL_LOGOFF, null);
524
525 // eapol header
526 EAPOL eapol = new EAPOL();
527 eapol.setEapolType(EAPOL.EAPOL_LOGOFF);
528 eapol.setPacketLength(eap.getLength());
529
530 // eap part
531 eapol.setPayload(eap);
532
533 eth.setPayload(eapol);
534 eth.setPad(true);
535 return eth;
536 }
537
Jonathan Hart612651f2019-11-25 09:21:43 -0800538 /**
539 * Constructs an Ethernet packet containing a RADIUS challenge
540 * packet.
541 *
542 * @param challengeCode code to use in challenge packet
543 * @param challengeType type to use in challenge packet
544 * @return Ethernet packet
545 */
546 RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType,
547 byte identifier, byte[] messageAuth) {
548
549 String challenge = "12345678901234567";
550
551 EAP eap = new EAP(challengeType, (byte) 4, challengeType,
552 challenge.getBytes(Charsets.US_ASCII));
553 //eap.setIdentifier((byte) 4);
554 eap.setIdentifier(identifier);
555
556 RADIUS radius = new RADIUS();
557 radius.setCode(challengeCode);
558 //radius.setIdentifier((byte) 4);
559 radius.setIdentifier(identifier);
560 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
561 challenge.getBytes(Charsets.US_ASCII));
562
563 radius.setPayload(eap);
564 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE, eap.serialize());
565 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, messageAuth);
566 return radius;
567 }
Ray Milkey967776a2015-10-07 14:37:17 -0700568}