blob: 30d235621b857fc9a584de71ad21a60f74b43395 [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
76 MacAddress clientMac = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
77 MacAddress serverMac = MacAddress.valueOf("2a:2a:2a:2a:2a:2a");
78
79 // Our session id will be the device ID ("of:1") with the port ("1") concatenated
80 static final String SESSION_ID = "of:11";
81
82 List<BasePacket> savedPackets = new LinkedList<>();
83 PacketProcessor packetProcessor;
84
85 /**
86 * Saves the given packet onto the saved packets list.
87 *
88 * @param packet packet to save
89 */
90 void savePacket(BasePacket packet) {
91 savedPackets.add(packet);
92 }
93
94 /**
95 * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
96 */
97 class MockPacketService extends PacketServiceAdapter {
98
99 @Override
100 public void addProcessor(PacketProcessor processor, int priority) {
101 packetProcessor = processor;
102 }
103
104 @Override
105 public void emit(OutboundPacket packet) {
106 try {
107 Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
108 0, packet.data().array().length);
109 savePacket(eth);
110 } catch (Exception e) {
111 fail(e.getMessage());
112 }
113 }
114 }
kartikey dubeye1545422019-05-22 12:53:45 +0000115 class MockComponentContext implements ComponentContext {
116
117 @Override
118 public Dictionary<String, Object> getProperties() {
119 Dictionary<String, Object> cfgDict = new Hashtable<String, Object>();
120 cfgDict.put("statisticsGenerationEvent", 20);
121 return cfgDict;
122 }
123
124 @Override
125 public Object locateService(String name) {
126 // TODO Auto-generated method stub
127 return null;
128 }
129
130 @Override
131 public Object locateService(String name, ServiceReference reference) {
132 // TODO Auto-generated method stub
133 return null;
134 }
135
136 @Override
137 public Object[] locateServices(String name) {
138 // TODO Auto-generated method stub
139 return null;
140 }
141
142 @Override
143 public BundleContext getBundleContext() {
144 // TODO Auto-generated method stub
145 return null;
146 }
147
148 @Override
149 public Bundle getUsingBundle() {
150 // TODO Auto-generated method stub
151 return null;
152 }
153
154 @Override
155 public ComponentInstance getComponentInstance() {
156 // TODO Auto-generated method stub
157 return null;
158 }
159
160 @Override
161 public void enableComponent(String name) {
162 // TODO Auto-generated method stub
163 }
164
165 @Override
166 public void disableComponent(String name) {
167 // TODO Auto-generated method stub
168 }
169
170 @Override
171 public ServiceReference getServiceReference() {
172 // TODO Auto-generated method stub
173 return null;
174 }
175 }
Ray Milkey967776a2015-10-07 14:37:17 -0700176
177 /**
Amit Ghoshf739be52017-09-21 15:49:37 +0100178 * Mocks the DeviceService.
179 */
180 final class TestDeviceService extends DeviceServiceAdapter {
181 @Override
182 public Port getPort(ConnectPoint cp) {
183 return new MockPort();
184 }
185 }
186 private class MockPort implements Port {
187
188 @Override
189 public boolean isEnabled() {
190 return true;
191 }
192 public long portSpeed() {
193 return 1000;
194 }
195 public Element element() {
196 return null;
197 }
198 public PortNumber number() {
199 return null;
200 }
201 public Annotations annotations() {
202 return new MockAnnotations();
203 }
204 public Type type() {
205 return Port.Type.FIBER;
206 }
207
208 private class MockAnnotations implements Annotations {
209
210 @Override
211 public String value(String val) {
212 return "PON 1/1";
213 }
214 public Set<String> keys() {
215 return null;
216 }
217 }
218 }
219
220 private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
221
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100222 MockSubscriberAndDeviceInformation(String id, VlanId uniTagMatch, VlanId ctag,
223 VlanId stag, int dsPonPrio, int upPonPrio,
224 int techProfileId, String dsBpId, String usBpId,
225 String nasPortId, String circuitId, MacAddress hardId,
Amit Ghoshf739be52017-09-21 15:49:37 +0100226 Ip4Address ipAddress) {
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100227 // Builds UniTagInformation
228 UniTagInformation.Builder tagInfoBuilder = new UniTagInformation.Builder();
229 UniTagInformation uniTagInfo = tagInfoBuilder.setUniTagMatch(uniTagMatch)
230 .setPonCTag(ctag)
231 .setPonSTag(stag)
232 .setDsPonCTagPriority(dsPonPrio)
233 .setUsPonSTagPriority(upPonPrio)
234 .setTechnologyProfileId(techProfileId)
235 .setDownstreamBandwidthProfile(dsBpId)
236 .setUpstreamBandwidthProfile(usBpId)
237 .build();
238
Amit Ghoshf739be52017-09-21 15:49:37 +0100239 this.setHardwareIdentifier(hardId);
240 this.setId(id);
241 this.setIPAddress(ipAddress);
Amit Ghoshf739be52017-09-21 15:49:37 +0100242 this.setNasPortId(nasPortId);
243 this.setCircuitId(circuitId);
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100244 this.setUniTagList(Lists.newArrayList(uniTagInfo));
Amit Ghoshf739be52017-09-21 15:49:37 +0100245 }
246 }
247
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000248 final class MockSadisService implements SadisService {
249
250 @Override
251 public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
252 return new MockSubService();
253 }
254
255 @Override
256 public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
257 return null;
258 }
259 }
260
kartikey dubeye1545422019-05-22 12:53:45 +0000261 final class MockCfgService implements ComponentConfigService {
262 @Override
263 public Set<String> getComponentNames() {
264 // TODO Auto-generated method stub
265 return null;
266 }
267
268 @Override
269 public void registerProperties(Class<?> componentClass) {
270 // TODO Auto-generated method stub
271 }
272
273 @Override
274 public void unregisterProperties(Class<?> componentClass, boolean clear) {
275 // TODO Auto-generated method stub
276 }
277
278 @Override
279 public Set<ConfigProperty> getProperties(String componentName) {
280 return null;
281 }
282
283 @Override
284 public void setProperty(String componentName, String name, String value) {
285 // TODO Auto-generated method stub
286 }
287
288 @Override
289 public void preSetProperty(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, boolean override) {
295 // TODO Auto-generated method stub
296 }
297
298 @Override
299 public void unsetProperty(String componentName, String name) {
300 // TODO Auto-generated method stub
301 }
302
303 @Override
304 public ConfigProperty getProperty(String componentName, String attribute) {
305 return null;
306 }
307
308}
309
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000310 final class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100311 private final VlanId uniTagMatch = VlanId.vlanId((short) 35);
Amit Ghoshf739be52017-09-21 15:49:37 +0100312 private final VlanId clientCtag = VlanId.vlanId((short) 999);
313 private final VlanId clientStag = VlanId.vlanId((short) 111);
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100314 private final int dsPrio = 0;
315 private final int usPrio = 0;
316 private final int techProfileId = 64;
317 private final String usBpId = "HSIA-US";
318 private final String dsBpId = "HSIA-DS";
Amit Ghoshf739be52017-09-21 15:49:37 +0100319 private final String clientNasPortId = "PON 1/1";
320 private final String clientCircuitId = "CIR-PON 1/1";
321
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100322
Amit Ghoshf739be52017-09-21 15:49:37 +0100323 MockSubscriberAndDeviceInformation sub =
Andrea Campanella7e0e7e32020-02-13 14:39:55 +0100324 new MockSubscriberAndDeviceInformation(clientNasPortId, uniTagMatch, clientCtag,
325 clientStag, dsPrio, usPrio,
326 techProfileId, dsBpId, usBpId,
327 clientNasPortId, clientCircuitId, null,
328 null);
Amit Ghoshf739be52017-09-21 15:49:37 +0100329 @Override
330 public SubscriberAndDeviceInformation get(String id) {
331
332 return sub;
333
334 }
335
336 @Override
337 public void invalidateAll() {}
338 public void invalidateId(String id) {}
339 public SubscriberAndDeviceInformation getfromCache(String id) {
340 return null;
341 }
342 }
343 /**
Ray Milkey967776a2015-10-07 14:37:17 -0700344 * Mocks the DefaultPacketContext.
345 */
346 final class TestPacketContext extends DefaultPacketContext {
347
Shubham Sharmacf5e5032019-11-26 11:09:21 +0000348 TestPacketContext(long time, InboundPacket inPkt,
Ray Milkey967776a2015-10-07 14:37:17 -0700349 OutboundPacket outPkt, boolean block) {
350 super(time, inPkt, outPkt, block);
351 }
352
353 @Override
354 public void send() {
355 // We don't send anything out.
356 }
357 }
358
359 /**
360 * Sends an Ethernet packet to the process method of the Packet Processor.
361 *
362 * @param reply Ethernet packet
363 */
364 void sendPacket(Ethernet reply) {
365 final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
366 InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
367 reply,
368 byteBuffer);
369
370 PacketContext context = new TestPacketContext(127L, inPacket, null, false);
371 packetProcessor.process(context);
372 }
373
374 /**
375 * Constructs an Ethernet packet containing identification payload.
376 *
377 * @return Ethernet packet
378 */
379 Ethernet constructSupplicantIdentifyPacket(StateMachine stateMachine,
380 byte type,
381 byte id,
382 Ethernet radiusChallenge)
383 throws Exception {
384 Ethernet eth = new Ethernet();
385 eth.setDestinationMACAddress(clientMac.toBytes());
386 eth.setSourceMACAddress(serverMac.toBytes());
387 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
388 eth.setVlanID((short) 2);
389
390 String username = "testuser";
391 byte[] data = username.getBytes();
392
393
394 if (type == EAP.ATTR_MD5) {
395 String password = "testpassword";
396 EAPOL eapol = (EAPOL) radiusChallenge.getPayload();
397 EAP eap = (EAP) eapol.getPayload();
398
399 byte[] identifier = new byte[password.length() + eap.getData().length];
400
401 identifier[0] = stateMachine.challengeIdentifier();
402 System.arraycopy(password.getBytes(), 0, identifier, 1, password.length());
403 System.arraycopy(eap.getData(), 1, identifier, 1 + password.length(), 16);
404
405 MessageDigest md = MessageDigest.getInstance("MD5");
406 byte[] hash = md.digest(identifier);
407 data = new byte[17];
408 data[0] = (byte) 16;
409 System.arraycopy(hash, 0, data, 1, 16);
410 }
411 EAP eap = new EAP(EAP.RESPONSE, (byte) 1, type,
412 data);
413 eap.setIdentifier(id);
414
415 // eapol header
416 EAPOL eapol = new EAPOL();
417 eapol.setEapolType(EAPOL.EAPOL_PACKET);
418 eapol.setPacketLength(eap.getLength());
419
420 // eap part
421 eapol.setPayload(eap);
422
423 eth.setPayload(eapol);
424 eth.setPad(true);
425 return eth;
426 }
427
428 /**
429 * Constructs an Ethernet packet containing a EAPOL_START Payload.
430 *
431 * @return Ethernet packet
432 */
433 Ethernet constructSupplicantStartPacket() {
434 Ethernet eth = new Ethernet();
435 eth.setDestinationMACAddress(clientMac.toBytes());
436 eth.setSourceMACAddress(serverMac.toBytes());
437 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
438 eth.setVlanID((short) 2);
439
Shubham Sharma4900ce62019-06-19 14:18:50 +0000440 EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 3, EAPOL.EAPOL_START, null);
Ray Milkey967776a2015-10-07 14:37:17 -0700441
442 // eapol header
443 EAPOL eapol = new EAPOL();
444 eapol.setEapolType(EAPOL.EAPOL_START);
445 eapol.setPacketLength(eap.getLength());
446
447 // eap part
448 eapol.setPayload(eap);
449
450 eth.setPayload(eapol);
451 eth.setPad(true);
452 return eth;
453 }
454
455 /**
Shubham Sharma8d7a9822020-01-28 10:04:01 +0000456 * Constructs an Ethernet packet containing a EAPOL_ASF Payload.
457 *
458 * @return Ethernet packet
459 */
460 Ethernet constructSupplicantAsfPacket() {
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_START, (byte) 3, EAPOL.EAPOL_START, null);
468
469 // eapol header
470 EAPOL eapol = new EAPOL();
471 eapol.setEapolType(EAPOL.EAPOL_ASF);
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
482 /**
Ray Milkey967776a2015-10-07 14:37:17 -0700483 * Checks the contents of a RADIUS packet being sent to the RADIUS server.
484 *
485 * @param radiusPacket packet to check
486 * @param code expected code
487 */
Jonathan Hart092dfb22015-11-16 23:05:21 -0800488 void checkRadiusPacket(AaaManager aaaManager, Ethernet radiusPacket, byte code) {
Ray Milkey967776a2015-10-07 14:37:17 -0700489
490 assertThat(radiusPacket.getSourceMAC(),
Jonathan Hart092dfb22015-11-16 23:05:21 -0800491 is(MacAddress.valueOf(aaaManager.nasMacAddress)));
Ray Milkey967776a2015-10-07 14:37:17 -0700492 assertThat(radiusPacket.getDestinationMAC(), is(serverMac));
493
494 assertThat(radiusPacket.getPayload(), instanceOf(EAPOL.class));
495 EAPOL eapol = (EAPOL) radiusPacket.getPayload();
496 assertThat(eapol, notNullValue());
497
498 assertThat(eapol.getEapolType(), is(EAPOL.EAPOL_PACKET));
499 assertThat(eapol.getPayload(), instanceOf(EAP.class));
500 EAP eap = (EAP) eapol.getPayload();
501 assertThat(eap, notNullValue());
502
503 assertThat(eap.getCode(), is(code));
504 }
Shubham Sharma2b3fb692019-12-12 10:19:10 +0000505
506 /**
507 * Constructs an Ethernet packet containing a EAPOL_LOGOFF Payload.
508 *
509 * @return Ethernet packet
510 */
511 Ethernet constructSupplicantLogoffPacket() {
512 Ethernet eth = new Ethernet();
513 eth.setDestinationMACAddress(clientMac.toBytes());
514 eth.setSourceMACAddress(serverMac.toBytes());
515 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
516 eth.setVlanID((short) 2);
517
518 EAP eap = new EAP(EAPOL.EAPOL_LOGOFF, (byte) 2, EAPOL.EAPOL_LOGOFF, null);
519
520 // eapol header
521 EAPOL eapol = new EAPOL();
522 eapol.setEapolType(EAPOL.EAPOL_LOGOFF);
523 eapol.setPacketLength(eap.getLength());
524
525 // eap part
526 eapol.setPayload(eap);
527
528 eth.setPayload(eapol);
529 eth.setPad(true);
530 return eth;
531 }
532
Jonathan Hart612651f2019-11-25 09:21:43 -0800533 /**
534 * Constructs an Ethernet packet containing a RADIUS challenge
535 * packet.
536 *
537 * @param challengeCode code to use in challenge packet
538 * @param challengeType type to use in challenge packet
539 * @return Ethernet packet
540 */
541 RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType,
542 byte identifier, byte[] messageAuth) {
543
544 String challenge = "12345678901234567";
545
546 EAP eap = new EAP(challengeType, (byte) 4, challengeType,
547 challenge.getBytes(Charsets.US_ASCII));
548 //eap.setIdentifier((byte) 4);
549 eap.setIdentifier(identifier);
550
551 RADIUS radius = new RADIUS();
552 radius.setCode(challengeCode);
553 //radius.setIdentifier((byte) 4);
554 radius.setIdentifier(identifier);
555 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
556 challenge.getBytes(Charsets.US_ASCII));
557
558 radius.setPayload(eap);
559 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE, eap.serialize());
560 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, messageAuth);
561 return radius;
562 }
Ray Milkey967776a2015-10-07 14:37:17 -0700563}