blob: 69191d3040f7697b66a462e1ace4e7053613e0d7 [file] [log] [blame]
Jian Li451cea32016-10-04 15:27:50 +09001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
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 */
16package org.onosproject.lisp.ctl;
17
Jian Li24f6cc02016-11-01 16:38:40 +090018import io.netty.buffer.ByteBuf;
19import io.netty.buffer.Unpooled;
20import org.onosproject.lisp.msg.authentication.LispAuthenticationFactory;
21import org.onosproject.lisp.msg.exceptions.LispWriterException;
22import org.onosproject.lisp.msg.protocols.DefaultLispMapNotify.DefaultNotifyBuilder;
23import org.onosproject.lisp.msg.protocols.DefaultLispMapRegister.DefaultRegisterBuilder;
24import org.onosproject.lisp.msg.protocols.LispEidRecord;
Jian Liafe2d3f2016-11-01 02:49:07 +090025import org.onosproject.lisp.msg.protocols.LispMapNotify;
Jian Li24f6cc02016-11-01 16:38:40 +090026import org.onosproject.lisp.msg.protocols.LispMapNotify.NotifyBuilder;
27import org.onosproject.lisp.msg.protocols.LispMapRegister;
28import org.onosproject.lisp.msg.protocols.LispMapRegister.RegisterBuilder;
Jian Li451cea32016-10-04 15:27:50 +090029import org.onosproject.lisp.msg.protocols.LispMessage;
Jian Li24f6cc02016-11-01 16:38:40 +090030import org.slf4j.Logger;
31import org.slf4j.LoggerFactory;
32
33import java.net.InetSocketAddress;
34import java.util.Arrays;
35
36import static org.onosproject.lisp.msg.authentication.LispAuthenticationKeyEnum.valueOf;
Jian Li451cea32016-10-04 15:27:50 +090037
38/**
39 * LISP map server class.
40 * Handles map-register message and acknowledges with map-notify message.
41 */
Jian Li6322a362016-10-31 00:57:19 +090042public class LispMapServer {
43
Jian Li24f6cc02016-11-01 16:38:40 +090044 private static final int NOTIFY_PORT = 4342;
45
46 // TODO: need to be configurable
47 private static final String AUTH_KEY = "onos";
48
49 private static final short AUTH_DATA_LENGTH = 20;
50
51 // TODO: need to be configurable
52 private static final short AUTH_METHOD = 1;
53
54 private static final Logger log = LoggerFactory.getLogger(LispMapServer.class);
55
56 private LispAuthenticationFactory factory;
57 private LispEidRlocMap mapInfo;
58
59 public LispMapServer() {
60 factory = LispAuthenticationFactory.getInstance();
61 mapInfo = LispEidRlocMap.getInstance();
62 }
63
64 /**
65 * Handles map-register message and replies with map-notify message.
66 *
67 * @param message map-register message
68 * @return map-notify message
69 */
Jian Liafe2d3f2016-11-01 02:49:07 +090070 public LispMapNotify processMapRegister(LispMessage message) {
Jian Li24f6cc02016-11-01 16:38:40 +090071
72 LispMapRegister register = (LispMapRegister) message;
73
74 if (!checkAuthData(register)) {
75 log.warn("Unmatched authentication data of Map-Register");
76 return null;
77 }
78
79 // build temp notify message
80 NotifyBuilder authNotifyBuilder = new DefaultNotifyBuilder();
81 authNotifyBuilder.withKeyId(AUTH_METHOD);
82 authNotifyBuilder.withAuthDataLength(AUTH_DATA_LENGTH);
83 authNotifyBuilder.withNonce(register.getNonce());
84 authNotifyBuilder.withMapRecords(register.getMapRecords());
85
86 byte[] authData = new byte[AUTH_DATA_LENGTH];
87 Arrays.fill(authData, (byte) 0);
88 authNotifyBuilder.withAuthenticationData(authData);
89
90 ByteBuf byteBuf = Unpooled.buffer();
91 try {
92 authNotifyBuilder.build().writeTo(byteBuf);
93 } catch (LispWriterException e) {
94 e.printStackTrace();
95 }
96
97 byte[] bytes = new byte[byteBuf.readableBytes()];
98 byteBuf.readBytes(bytes);
99
100 byte[] sha1AuthData =
101 factory.createAuthenticationData(valueOf(register.getKeyId()), AUTH_KEY, bytes);
102
103 NotifyBuilder notifyBuilder = new DefaultNotifyBuilder();
104 notifyBuilder.withKeyId(AUTH_METHOD);
105 notifyBuilder.withAuthDataLength((short) sha1AuthData.length);
106 notifyBuilder.withAuthenticationData(sha1AuthData);
107 notifyBuilder.withNonce(register.getNonce());
108 notifyBuilder.withMapRecords(register.getMapRecords());
109
110 LispMapNotify notify = notifyBuilder.build();
111
112 InetSocketAddress address =
113 new InetSocketAddress(register.getSender().getAddress(), NOTIFY_PORT);
114 notify.configSender(address);
115
116 register.getMapRecords().forEach(record -> {
117 LispEidRecord eidRecord =
118 new LispEidRecord(record.getMaskLength(), record.getEidPrefixAfi());
119 mapInfo.insertMapRecord(eidRecord, record);
120 });
121
122 return notify;
123 }
124
125 /**
126 * Checks the integrity of the received Map-Register message by calculating
127 * authentication data from received Map-Register message.
128 *
129 * @param register Map-Register message
130 * @return evaluation result
131 */
132 private boolean checkAuthData(LispMapRegister register) {
133 ByteBuf byteBuf = Unpooled.buffer();
134 RegisterBuilder registerBuilder = new DefaultRegisterBuilder();
135 registerBuilder.withKeyId(register.getKeyId());
136 registerBuilder.withAuthDataLength(register.getAuthDataLength());
137 registerBuilder.withNonce(register.getNonce());
138 registerBuilder.withIsProxyMapReply(register.isProxyMapReply());
139 registerBuilder.withIsWantMapNotify(register.isWantMapNotify());
140 registerBuilder.withMapRecords(register.getMapRecords());
141
142 byte[] authData = register.getAuthenticationData();
143 if (authData != null) {
144 authData = authData.clone();
145 Arrays.fill(authData, (byte) 0);
146 }
147 registerBuilder.withAuthenticationData(authData);
148 try {
149 registerBuilder.build().writeTo(byteBuf);
150 } catch (LispWriterException e) {
151 e.printStackTrace();
152 }
153
154 byte[] bytes = new byte[byteBuf.readableBytes()];
155 byteBuf.readBytes(bytes);
156
157 byte[] calculatedAuthData =
158 factory.createAuthenticationData(valueOf(register.getKeyId()), AUTH_KEY, bytes);
159 return Arrays.equals(calculatedAuthData, register.getAuthenticationData());
Jian Li451cea32016-10-04 15:27:50 +0900160 }
161}