blob: d2bbeb1f3280d3a23d17b1a9da20ee1d6552e356 [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) {
Amit Ghoshf739be52017-09-21 15:49:37 +0100224 this.setHardwareIdentifier(hardId);
225 this.setId(id);
226 this.setIPAddress(ipAddress);
Amit Ghoshf739be52017-09-21 15:49:37 +0100227 this.setNasPortId(nasPortId);
228 this.setCircuitId(circuitId);
229 }
230 }
231
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000232 final class MockSadisService implements SadisService {
233
234 @Override
235 public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
236 return new MockSubService();
237 }
238
239 @Override
240 public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
241 return null;
242 }
243 }
244
kartikey dubeye1545422019-05-22 12:53:45 +0000245 final class MockCfgService implements ComponentConfigService {
246 @Override
247 public Set<String> getComponentNames() {
248 // TODO Auto-generated method stub
249 return null;
250 }
251
252 @Override
253 public void registerProperties(Class<?> componentClass) {
254 // TODO Auto-generated method stub
255 }
256
257 @Override
258 public void unregisterProperties(Class<?> componentClass, boolean clear) {
259 // TODO Auto-generated method stub
260 }
261
262 @Override
263 public Set<ConfigProperty> getProperties(String componentName) {
264 return null;
265 }
266
267 @Override
268 public void setProperty(String componentName, String name, String value) {
269 // TODO Auto-generated method stub
270 }
271
272 @Override
273 public void preSetProperty(String componentName, String name, String value) {
274 // TODO Auto-generated method stub
275 }
276
277 @Override
278 public void preSetProperty(String componentName, String name, String value, boolean override) {
279 // TODO Auto-generated method stub
280 }
281
282 @Override
283 public void unsetProperty(String componentName, String name) {
284 // TODO Auto-generated method stub
285 }
286
287 @Override
288 public ConfigProperty getProperty(String componentName, String attribute) {
289 return null;
290 }
291
292}
293
Gamze Abaka1cfdb192018-10-25 11:39:19 +0000294 final class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
Amit Ghoshf739be52017-09-21 15:49:37 +0100295 private final VlanId clientCtag = VlanId.vlanId((short) 999);
296 private final VlanId clientStag = VlanId.vlanId((short) 111);
297 private final String clientNasPortId = "PON 1/1";
298 private final String clientCircuitId = "CIR-PON 1/1";
299
300 MockSubscriberAndDeviceInformation sub =
301 new MockSubscriberAndDeviceInformation(clientNasPortId, clientCtag,
302 clientStag, clientNasPortId, clientCircuitId, null, null);
303 @Override
304 public SubscriberAndDeviceInformation get(String id) {
305
306 return sub;
307
308 }
309
310 @Override
311 public void invalidateAll() {}
312 public void invalidateId(String id) {}
313 public SubscriberAndDeviceInformation getfromCache(String id) {
314 return null;
315 }
316 }
317 /**
Ray Milkey967776a2015-10-07 14:37:17 -0700318 * Mocks the DefaultPacketContext.
319 */
320 final class TestPacketContext extends DefaultPacketContext {
321
Shubham Sharmacf5e5032019-11-26 11:09:21 +0000322 TestPacketContext(long time, InboundPacket inPkt,
Ray Milkey967776a2015-10-07 14:37:17 -0700323 OutboundPacket outPkt, boolean block) {
324 super(time, inPkt, outPkt, block);
325 }
326
327 @Override
328 public void send() {
329 // We don't send anything out.
330 }
331 }
332
333 /**
334 * Sends an Ethernet packet to the process method of the Packet Processor.
335 *
336 * @param reply Ethernet packet
337 */
338 void sendPacket(Ethernet reply) {
339 final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
340 InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
341 reply,
342 byteBuffer);
343
344 PacketContext context = new TestPacketContext(127L, inPacket, null, false);
345 packetProcessor.process(context);
346 }
347
348 /**
349 * Constructs an Ethernet packet containing identification payload.
350 *
351 * @return Ethernet packet
352 */
353 Ethernet constructSupplicantIdentifyPacket(StateMachine stateMachine,
354 byte type,
355 byte id,
356 Ethernet radiusChallenge)
357 throws Exception {
358 Ethernet eth = new Ethernet();
359 eth.setDestinationMACAddress(clientMac.toBytes());
360 eth.setSourceMACAddress(serverMac.toBytes());
361 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
362 eth.setVlanID((short) 2);
363
364 String username = "testuser";
365 byte[] data = username.getBytes();
366
367
368 if (type == EAP.ATTR_MD5) {
369 String password = "testpassword";
370 EAPOL eapol = (EAPOL) radiusChallenge.getPayload();
371 EAP eap = (EAP) eapol.getPayload();
372
373 byte[] identifier = new byte[password.length() + eap.getData().length];
374
375 identifier[0] = stateMachine.challengeIdentifier();
376 System.arraycopy(password.getBytes(), 0, identifier, 1, password.length());
377 System.arraycopy(eap.getData(), 1, identifier, 1 + password.length(), 16);
378
379 MessageDigest md = MessageDigest.getInstance("MD5");
380 byte[] hash = md.digest(identifier);
381 data = new byte[17];
382 data[0] = (byte) 16;
383 System.arraycopy(hash, 0, data, 1, 16);
384 }
385 EAP eap = new EAP(EAP.RESPONSE, (byte) 1, type,
386 data);
387 eap.setIdentifier(id);
388
389 // eapol header
390 EAPOL eapol = new EAPOL();
391 eapol.setEapolType(EAPOL.EAPOL_PACKET);
392 eapol.setPacketLength(eap.getLength());
393
394 // eap part
395 eapol.setPayload(eap);
396
397 eth.setPayload(eapol);
398 eth.setPad(true);
399 return eth;
400 }
401
402 /**
403 * Constructs an Ethernet packet containing a EAPOL_START Payload.
404 *
405 * @return Ethernet packet
406 */
407 Ethernet constructSupplicantStartPacket() {
408 Ethernet eth = new Ethernet();
409 eth.setDestinationMACAddress(clientMac.toBytes());
410 eth.setSourceMACAddress(serverMac.toBytes());
411 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
412 eth.setVlanID((short) 2);
413
Shubham Sharma4900ce62019-06-19 14:18:50 +0000414 EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 3, EAPOL.EAPOL_START, null);
Ray Milkey967776a2015-10-07 14:37:17 -0700415
416 // eapol header
417 EAPOL eapol = new EAPOL();
418 eapol.setEapolType(EAPOL.EAPOL_START);
419 eapol.setPacketLength(eap.getLength());
420
421 // eap part
422 eapol.setPayload(eap);
423
424 eth.setPayload(eapol);
425 eth.setPad(true);
426 return eth;
427 }
428
429 /**
430 * Checks the contents of a RADIUS packet being sent to the RADIUS server.
431 *
432 * @param radiusPacket packet to check
433 * @param code expected code
434 */
Jonathan Hart092dfb22015-11-16 23:05:21 -0800435 void checkRadiusPacket(AaaManager aaaManager, Ethernet radiusPacket, byte code) {
Ray Milkey967776a2015-10-07 14:37:17 -0700436
437 assertThat(radiusPacket.getSourceMAC(),
Jonathan Hart092dfb22015-11-16 23:05:21 -0800438 is(MacAddress.valueOf(aaaManager.nasMacAddress)));
Ray Milkey967776a2015-10-07 14:37:17 -0700439 assertThat(radiusPacket.getDestinationMAC(), is(serverMac));
440
441 assertThat(radiusPacket.getPayload(), instanceOf(EAPOL.class));
442 EAPOL eapol = (EAPOL) radiusPacket.getPayload();
443 assertThat(eapol, notNullValue());
444
445 assertThat(eapol.getEapolType(), is(EAPOL.EAPOL_PACKET));
446 assertThat(eapol.getPayload(), instanceOf(EAP.class));
447 EAP eap = (EAP) eapol.getPayload();
448 assertThat(eap, notNullValue());
449
450 assertThat(eap.getCode(), is(code));
451 }
Shubham Sharma2b3fb692019-12-12 10:19:10 +0000452
453 /**
454 * Constructs an Ethernet packet containing a EAPOL_LOGOFF Payload.
455 *
456 * @return Ethernet packet
457 */
458 Ethernet constructSupplicantLogoffPacket() {
459 Ethernet eth = new Ethernet();
460 eth.setDestinationMACAddress(clientMac.toBytes());
461 eth.setSourceMACAddress(serverMac.toBytes());
462 eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
463 eth.setVlanID((short) 2);
464
465 EAP eap = new EAP(EAPOL.EAPOL_LOGOFF, (byte) 2, EAPOL.EAPOL_LOGOFF, null);
466
467 // eapol header
468 EAPOL eapol = new EAPOL();
469 eapol.setEapolType(EAPOL.EAPOL_LOGOFF);
470 eapol.setPacketLength(eap.getLength());
471
472 // eap part
473 eapol.setPayload(eap);
474
475 eth.setPayload(eapol);
476 eth.setPad(true);
477 return eth;
478 }
479
Jonathan Hart612651f2019-11-25 09:21:43 -0800480 /**
481 * Constructs an Ethernet packet containing a RADIUS challenge
482 * packet.
483 *
484 * @param challengeCode code to use in challenge packet
485 * @param challengeType type to use in challenge packet
486 * @return Ethernet packet
487 */
488 RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType,
489 byte identifier, byte[] messageAuth) {
490
491 String challenge = "12345678901234567";
492
493 EAP eap = new EAP(challengeType, (byte) 4, challengeType,
494 challenge.getBytes(Charsets.US_ASCII));
495 //eap.setIdentifier((byte) 4);
496 eap.setIdentifier(identifier);
497
498 RADIUS radius = new RADIUS();
499 radius.setCode(challengeCode);
500 //radius.setIdentifier((byte) 4);
501 radius.setIdentifier(identifier);
502 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
503 challenge.getBytes(Charsets.US_ASCII));
504
505 radius.setPayload(eap);
506 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE, eap.serialize());
507 radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_MESSAGE_AUTH, messageAuth);
508 return radius;
509 }
Ray Milkey967776a2015-10-07 14:37:17 -0700510}