blob: aca2c76be2976187f5bf754241323515f175d08e [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
Jian Li24f6cc02016-11-01 16:38:40 +090049 // TODO: need to be configurable
50 private static final short AUTH_METHOD = 1;
51
52 private static final Logger log = LoggerFactory.getLogger(LispMapServer.class);
53
54 private LispAuthenticationFactory factory;
55 private LispEidRlocMap mapInfo;
56
57 public LispMapServer() {
58 factory = LispAuthenticationFactory.getInstance();
59 mapInfo = LispEidRlocMap.getInstance();
60 }
61
62 /**
63 * Handles map-register message and replies with map-notify message.
64 *
65 * @param message map-register message
66 * @return map-notify message
67 */
Jian Liafe2d3f2016-11-01 02:49:07 +090068 public LispMapNotify processMapRegister(LispMessage message) {
Jian Li24f6cc02016-11-01 16:38:40 +090069
70 LispMapRegister register = (LispMapRegister) message;
71
72 if (!checkAuthData(register)) {
73 log.warn("Unmatched authentication data of Map-Register");
74 return null;
75 }
76
77 // build temp notify message
78 NotifyBuilder authNotifyBuilder = new DefaultNotifyBuilder();
79 authNotifyBuilder.withKeyId(AUTH_METHOD);
Jian Li51aaca12016-11-11 01:56:15 +090080 authNotifyBuilder.withAuthDataLength(valueOf(AUTH_METHOD).getHashLength());
Jian Li24f6cc02016-11-01 16:38:40 +090081 authNotifyBuilder.withNonce(register.getNonce());
82 authNotifyBuilder.withMapRecords(register.getMapRecords());
83
Jian Li51aaca12016-11-11 01:56:15 +090084 byte[] authData = new byte[valueOf(AUTH_METHOD).getHashLength()];
Jian Li24f6cc02016-11-01 16:38:40 +090085 Arrays.fill(authData, (byte) 0);
86 authNotifyBuilder.withAuthenticationData(authData);
87
88 ByteBuf byteBuf = Unpooled.buffer();
89 try {
90 authNotifyBuilder.build().writeTo(byteBuf);
91 } catch (LispWriterException e) {
92 e.printStackTrace();
93 }
94
95 byte[] bytes = new byte[byteBuf.readableBytes()];
96 byteBuf.readBytes(bytes);
97
Jian Li51aaca12016-11-11 01:56:15 +090098 byte[] calcAuthData = factory.createAuthenticationData(
99 valueOf(register.getKeyId()), AUTH_KEY, bytes);
Jian Li24f6cc02016-11-01 16:38:40 +0900100
101 NotifyBuilder notifyBuilder = new DefaultNotifyBuilder();
102 notifyBuilder.withKeyId(AUTH_METHOD);
Jian Li51aaca12016-11-11 01:56:15 +0900103 notifyBuilder.withAuthDataLength((short) calcAuthData.length);
104 notifyBuilder.withAuthenticationData(calcAuthData);
Jian Li24f6cc02016-11-01 16:38:40 +0900105 notifyBuilder.withNonce(register.getNonce());
106 notifyBuilder.withMapRecords(register.getMapRecords());
107
108 LispMapNotify notify = notifyBuilder.build();
109
110 InetSocketAddress address =
111 new InetSocketAddress(register.getSender().getAddress(), NOTIFY_PORT);
112 notify.configSender(address);
113
114 register.getMapRecords().forEach(record -> {
115 LispEidRecord eidRecord =
116 new LispEidRecord(record.getMaskLength(), record.getEidPrefixAfi());
117 mapInfo.insertMapRecord(eidRecord, record);
118 });
119
120 return notify;
121 }
122
123 /**
Jian Li51aaca12016-11-11 01:56:15 +0900124 * Checks the integrity of the received map-register message by calculating
125 * authentication data from received map-register message.
Jian Li24f6cc02016-11-01 16:38:40 +0900126 *
Jian Li51aaca12016-11-11 01:56:15 +0900127 * @param register map-register message
Jian Li24f6cc02016-11-01 16:38:40 +0900128 * @return evaluation result
129 */
130 private boolean checkAuthData(LispMapRegister register) {
131 ByteBuf byteBuf = Unpooled.buffer();
132 RegisterBuilder registerBuilder = new DefaultRegisterBuilder();
133 registerBuilder.withKeyId(register.getKeyId());
134 registerBuilder.withAuthDataLength(register.getAuthDataLength());
135 registerBuilder.withNonce(register.getNonce());
136 registerBuilder.withIsProxyMapReply(register.isProxyMapReply());
137 registerBuilder.withIsWantMapNotify(register.isWantMapNotify());
138 registerBuilder.withMapRecords(register.getMapRecords());
139
140 byte[] authData = register.getAuthenticationData();
141 if (authData != null) {
142 authData = authData.clone();
143 Arrays.fill(authData, (byte) 0);
144 }
145 registerBuilder.withAuthenticationData(authData);
146 try {
147 registerBuilder.build().writeTo(byteBuf);
148 } catch (LispWriterException e) {
149 e.printStackTrace();
150 }
151
152 byte[] bytes = new byte[byteBuf.readableBytes()];
153 byteBuf.readBytes(bytes);
154
Jian Li51aaca12016-11-11 01:56:15 +0900155 byte[] calculatedAuthData = factory.createAuthenticationData(
156 valueOf(register.getKeyId()), AUTH_KEY, bytes);
Jian Li24f6cc02016-11-01 16:38:40 +0900157 return Arrays.equals(calculatedAuthData, register.getAuthenticationData());
Jian Li451cea32016-10-04 15:27:50 +0900158 }
159}