blob: 43176b46b193bfb41513061a39574c9e2cb3fffc [file] [log] [blame]
Vince Lehmanb8b18062015-07-14 13:07:22 -05001# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2#
Vince Lehman5d5a5662015-12-02 12:33:12 -06003# Copyright (C) 2015-2016, The University of Memphis,
4# Arizona Board of Regents,
5# Regents of the University of California.
Vince Lehmanb8b18062015-07-14 13:07:22 -05006#
7# This file is part of Mini-NDN.
8# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
9#
10# Mini-NDN is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# Mini-NDN is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with Mini-NDN, e.g., in COPYING.md file.
22# If not, see <http://www.gnu.org/licenses/>.
23
Vince Lehman5d5a5662015-12-02 12:33:12 -060024from mininet.clean import sh
25
Ashlesh Gawande792c6aa2015-07-10 12:18:36 -050026from ndn.ndn_application import NdnApplication
ashuef3490b2015-02-17 11:01:04 -060027
Vince Lehman5d5a5662015-12-02 12:33:12 -060028import os
29import shutil
30import textwrap
31
Ashlesh Gawande792c6aa2015-07-10 12:18:36 -050032class Nlsr(NdnApplication):
ashuef3490b2015-02-17 11:01:04 -060033 def __init__(self, node):
Ashlesh Gawande792c6aa2015-07-10 12:18:36 -050034 NdnApplication.__init__(self, node)
ashuef3490b2015-02-17 11:01:04 -060035 self.routerName = "/%sC1.Router/cs/%s" % ('%', node.name)
Ashlesh Gawande1b663692015-10-14 16:38:10 -050036 self.confFile = "%s/nlsr.conf" % node.homeFolder
ashuef3490b2015-02-17 11:01:04 -060037
38 # Make directory for log file
Ashlesh Gawande1b663692015-10-14 16:38:10 -050039 self.logDir = "%s/log" % node.homeFolder
ashuef3490b2015-02-17 11:01:04 -060040 node.cmd("mkdir %s" % self.logDir)
41
ashuef3490b2015-02-17 11:01:04 -060042 def start(self):
Ashlesh Gawandee144ceb2016-11-14 13:56:24 -060043 # Removed & at the end, was giving key not found error
44 # This way NLSR is daemonized fully before continuing
Ashlesh Gawande5518f712016-11-28 13:06:38 -060045 NdnApplication.start(self, "nlsr -d -f {}".format(self.confFile))
ashuef3490b2015-02-17 11:01:04 -060046
Vince Lehman5d5a5662015-12-02 12:33:12 -060047 @staticmethod
48 def createKey(host, name, outputFile):
49 host.cmd("ndnsec-keygen {} > {}".format(name, outputFile))
50
51 @staticmethod
52 def createCertificate(host, name, prefix, keyFile, outputFile, signer=None):
53 if signer is None:
54 host.cmd("ndnsec-certgen -N {} -p {} {} > {}".format(name, prefix, keyFile, outputFile))
55 else:
56 host.cmd("ndnsec-certgen -N {} -p {} -s {} {} > {}".format(name, prefix, signer, keyFile, outputFile))
57
58 @staticmethod
59 def createKeysAndCertificates(net, workDir):
60 securityDir = "{}/security".format(workDir)
61
62 if not os.path.exists(securityDir):
63 os.mkdir(securityDir)
64
65 # Create root certificate
66 rootName = "/ndn"
67 sh("ndnsec-keygen {} > {}/root.keys".format(rootName, securityDir))
68 sh("ndnsec-certgen -N {} -p {} {}/root.keys > {}/root.cert".format(rootName, rootName, securityDir, securityDir))
69
70 # Create necessary certificates for each site
71 for host in net.hosts:
72 nodeSecurityFolder = "{}/security".format(host.homeFolder)
73
74 if not os.path.exists(nodeSecurityFolder):
75 os.mkdir(nodeSecurityFolder)
76
77 shutil.copyfile("{}/root.cert".format(securityDir), "{}/root.cert".format(nodeSecurityFolder))
78
79 # Create site certificate
Ashlesh Gawandee144ceb2016-11-14 13:56:24 -060080 siteName = "ndn/{}-site".format(host.name)
Vince Lehman5d5a5662015-12-02 12:33:12 -060081 siteKeyFile = "{}/site.keys".format(nodeSecurityFolder)
82 siteCertFile = "{}/site.cert".format(nodeSecurityFolder)
83 Nlsr.createKey(host, siteName, siteKeyFile)
84
85 # Root key is in root namespace, must sign site key and then install on host
86 sh("ndnsec-certgen -N {} -s {} -p {} {} > {}".format(siteName, rootName, siteName, siteKeyFile, siteCertFile))
87 host.cmd("ndnsec-cert-install -f {}".format(siteCertFile))
88
89 # Create operator certificate
90 opName = "{}/%C1.Operator/op".format(siteName)
91 opKeyFile = "{}/op.keys".format(nodeSecurityFolder)
92 opCertFile = "{}/op.cert".format(nodeSecurityFolder)
93 Nlsr.createKey(host, opName, opKeyFile)
94 Nlsr.createCertificate(host, opName, opName, opKeyFile, opCertFile, signer=siteName)
95
96 # Create router certificate
97 routerName = "{}/%C1.Router/cs/{}".format(siteName, host.name)
98 routerKeyFile = "{}/router.keys".format(nodeSecurityFolder)
99 routerCertFile = "{}/router.cert".format(nodeSecurityFolder)
100 Nlsr.createKey(host, routerName, routerKeyFile)
101 Nlsr.createCertificate(host, routerName, routerName, routerKeyFile, routerCertFile, signer=opName)
102
ashuef3490b2015-02-17 11:01:04 -0600103class NlsrConfigGenerator:
104
105 ROUTING_LINK_STATE = "ls"
106 ROUTING_HYPERBOLIC = "hr"
107
Vince Lehman5d5a5662015-12-02 12:33:12 -0600108 def __init__(self, node, isSecurityEnabled):
ashu2ad32e22015-05-29 13:37:40 -0500109 node.cmd("sudo cp /usr/local/etc/mini-ndn/nlsr.conf nlsr.conf")
ashuef3490b2015-02-17 11:01:04 -0600110 self.node = node
Vince Lehman5d5a5662015-12-02 12:33:12 -0600111 self.isSecurityEnabled = isSecurityEnabled
ashuef3490b2015-02-17 11:01:04 -0600112
113 parameters = node.nlsrParameters
114
115 self.nFaces = parameters.get("max-faces-per-prefix", 3)
116 self.hyperbolicState = parameters.get("hyperbolic-state", "off")
117 self.hyperRadius = parameters.get("radius", 0.0)
118 self.hyperAngle = parameters.get("angle", 0.0)
Ashlesh Gawandec3ed2b92015-07-01 12:58:08 -0500119 self.logLevel = parameters.get("nlsr-log-level", "DEBUG")
ashuef3490b2015-02-17 11:01:04 -0600120
121 def createConfigFile(self):
122
Ashlesh Gawande1b663692015-10-14 16:38:10 -0500123 filePath = "%s/nlsr.conf" % self.node.homeFolder
ashuef3490b2015-02-17 11:01:04 -0600124
125 configFile = open(filePath, 'r')
126 oldContent = configFile.read()
127 configFile.close()
128
129 newContent = oldContent.replace("$GENERAL_SECTION", self.__getGeneralSection())
130 newContent = newContent.replace("$NEIGHBORS_SECTION", self.__getNeighborsSection())
131 newContent = newContent.replace("$HYPERBOLIC_SECTION", self.__getHyperbolicSection())
132 newContent = newContent.replace("$FIB_SECTION", self.__getFibSection())
133 newContent = newContent.replace("$ADVERTISING_SECTION", self.__getAdvertisingSection())
Vince Lehman5d5a5662015-12-02 12:33:12 -0600134 newContent = newContent.replace("$SECURITY_SECTION", self.__getSecuritySection())
ashuef3490b2015-02-17 11:01:04 -0600135
136 configFile = open(filePath, 'w')
137 configFile.write(newContent)
138 configFile.close()
139
140 def __getConfig(self):
141
142 config = self.__getGeneralSection()
143 config += self.__getNeighborsSection()
144 config += self.__getHyperbolicSection()
145 config += self.__getFibSection()
146 config += self.__getAdvertisingSection()
147 config += self.__getSecuritySection()
148
149 return config
150
151 def __getGeneralSection(self):
152
153 general = "general\n"
154 general += "{\n"
155 general += " network /ndn/\n"
Ashlesh Gawandee144ceb2016-11-14 13:56:24 -0600156 general += " site /{}-site\n".format(self.node.name)
ashuef3490b2015-02-17 11:01:04 -0600157 general += " router /%C1.Router/cs/" + self.node.name + "\n"
Ashlesh Gawandec3ed2b92015-07-01 12:58:08 -0500158 general += " log-level " + self.logLevel + "\n"
Ashlesh Gawande1b663692015-10-14 16:38:10 -0500159 general += " log-dir " + self.node.homeFolder + "/log\n"
160 general += " seq-dir " + self.node.homeFolder + "/log\n"
ashuef3490b2015-02-17 11:01:04 -0600161 general += "}\n"
162
163 return general
164
165 def __getNeighborsSection(self):
166
167 neighbors = "neighbors\n"
168 neighbors += "{\n"
169
170 for intf in self.node.intfList():
171 link = intf.link
172 if link:
173 node1, node2 = link.intf1.node, link.intf2.node
174
175 if node1 == self.node:
176 other = node2
177 ip = other.IP(str(link.intf2))
178 else:
179 other = node1
180 ip = other.IP(str(link.intf1))
181
ashu7b6ba182015-04-17 15:02:37 -0500182 linkCost = intf.params.get("delay", "10ms").replace("ms", "")
ashuef3490b2015-02-17 11:01:04 -0600183
184 neighbors += "neighbor\n"
185 neighbors += "{\n"
Ashlesh Gawandee144ceb2016-11-14 13:56:24 -0600186 neighbors += " name /ndn/" + other.name + "-site/%C1.Router/cs/" + other.name + "\n"
ashuef3490b2015-02-17 11:01:04 -0600187 neighbors += " face-uri udp://" + str(ip) + "\n"
188 neighbors += " link-cost " + linkCost + "\n"
189 neighbors += "}\n"
190
191 neighbors += "}\n"
192
193 return neighbors
194
195 def __getHyperbolicSection(self):
196
197 hyper = "hyperbolic\n"
198 hyper += "{\n"
199 hyper += "state %s\n" % self.hyperbolicState
200 hyper += "radius " + str(self.hyperRadius) + "\n"
201 hyper += "angle " + str(self.hyperAngle) + "\n"
202 hyper += "}\n"
203
204 return hyper
205
206 def __getFibSection(self):
207
208 fib = "fib\n"
209 fib += "{\n"
210 fib += " max-faces-per-prefix " + str(self.nFaces) + "\n"
211 fib += "}\n"
212
213 return fib
214
215 def __getAdvertisingSection(self):
216
217 advertising = "advertising\n"
218 advertising += "{\n"
Ashlesh Gawandee144ceb2016-11-14 13:56:24 -0600219 advertising += " prefix /ndn/" + self.node.name + "-site/" + self.node.name + "\n"
ashuef3490b2015-02-17 11:01:04 -0600220 advertising += "}\n"
221
222 return advertising
223
224 def __getSecuritySection(self):
Vince Lehman5d5a5662015-12-02 12:33:12 -0600225 if self.isSecurityEnabled is False:
226 security = textwrap.dedent("""\
227 security
228 {
229 validator
230 {
231 trust-anchor
232 {
233 type any
234 }
235 }
236 prefix-update-validator
237 {
238 trust-anchor
239 {
240 type any
241 }
242 }
243 }""")
244 else:
245 security = textwrap.dedent("""\
246 security
247 {
248 validator
249 {
250 rule
251 {
252 id "NSLR Hello Rule"
253 for data
254 filter
255 {
256 type name
257 regex ^[^<NLSR><INFO>]*<NLSR><INFO><><>$
258 }
259 checker
260 {
261 type customized
262 sig-type rsa-sha256
263 key-locator
264 {
265 type name
266 hyper-relation
267 {
268 k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$
269 k-expand \\\\1
270 h-relation equal
271 p-regex ^([^<NLSR><INFO>]*)<NLSR><INFO><><>$
272 p-expand \\\\1
273 }
274 }
275 }
276 }
ashuef3490b2015-02-17 11:01:04 -0600277
Vince Lehman5d5a5662015-12-02 12:33:12 -0600278 rule
279 {
280 id "NSLR LSA Rule"
281 for data
282 filter
283 {
284 type name
285 regex ^[^<NLSR><LSA>]*<NLSR><LSA>
286 }
287 checker
288 {
289 type customized
290 sig-type rsa-sha256
291 key-locator
292 {
293 type name
294 hyper-relation
295 {
296 k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$
297 k-expand \\\\1
298 h-relation equal
299 p-regex ^([^<NLSR><LSA>]*)<NLSR><LSA>(<>*)<><><><>$
300 p-expand \\\\1\\\\2
301 }
302 }
303 }
304 }
305
306 rule
307 {
308 id "NSLR Hierarchy Exception Rule"
309 for data
310 filter
311 {
312 type name
313 regex ^[^<KEY><%C1.Router>]*<%C1.Router>[^<KEY><NLSR>]*<KEY><ksk-.*><ID-CERT><>$
314 }
315 checker
316 {
317 type customized
318 sig-type rsa-sha256
319 key-locator
320 {
321 type name
322 hyper-relation
323 {
324 k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$
325 k-expand \\\\1
326 h-relation equal
327 p-regex ^([^<KEY><%C1.Router>]*)<%C1.Router>[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
328 p-expand \\\\1
329 }
330 }
331 }
332 }
333
334 rule
335 {
336 id "NSLR Hierarchical Rule"
337 for data
338 filter
339 {
340 type name
341 regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
342 }
343 checker
344 {
345 type hierarchical
346 sig-type rsa-sha256
347 }
348 }
349
350 trust-anchor
351 {
352 type file
353 file-name "security/root.cert"
354 }
355 }
356
357 prefix-update-validator
358 {
359 rule
360 {
361 id "NLSR ControlCommand Rule"
362 for interest
363 filter
364 {
365 type name
366 regex ^<localhost><nlsr><prefix-update>[<advertise><withdraw>]<>$
367 }
368 checker
369 {
370 type customized
371 sig-type rsa-sha256
372 key-locator
373 {
374 type name
375 regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$
376 }
377 }
378 }
379
380 rule
381 {
382 id "NLSR Hierarchy Rule"
383 for data
384 filter
385 {
386 type name
387 regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
388 }
389 checker
390 {
391 type hierarchical
392 sig-type rsa-sha256
393 }
394 }
395
396 trust-anchor
397 {
398 type file
399 file-name "security/site.cert"
400 }
401 }
402 ; cert-to-publish "security/root.cert" ; optional, a file containing the root certificate
403 ; Only the router that is designated to publish the root cert
404 ; needs to specify this
405
406 cert-to-publish "security/site.cert" ; optional, a file containing the site certificate
407 ; Only the router that is designated to publish the site cert
408 ; needs to specify this
409
410 cert-to-publish "security/op.cert" ; optional, a file containing the operator certificate
411 ; Only the router that is designated to publish the operator
412 ; cert needs to specify this
413
414 cert-to-publish "security/router.cert" ; required, a file containing the router certificate.
415 }""")
ashuef3490b2015-02-17 11:01:04 -0600416
417 return security