1 /*
2  * Copyright (c)2019 ZeroTier, Inc.
3  *
4  * Use of this software is governed by the Business Source License included
5  * in the LICENSE.TXT file in the project's root directory.
6  *
7  * Change Date: 2025-01-01
8  *
9  * On the date above, in accordance with the Business Source License, use
10  * of this software will be governed by version 2.0 of the Apache License.
11  */
12 /****/
13 
14 #include <stdint.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <time.h>
19 
20 #ifndef _WIN32
21 #include <sys/time.h>
22 #endif
23 #include <sys/types.h>
24 
25 #include <algorithm>
26 #include <utility>
27 #include <stdexcept>
28 #include <map>
29 #include <thread>
30 #include <memory>
31 #include <iomanip>
32 #include <sstream>
33 #include <cctype>
34 
35 #include "../include/ZeroTierOne.h"
36 #include "../version.h"
37 
38 #include "EmbeddedNetworkController.hpp"
39 #include "LFDB.hpp"
40 #include "FileDB.hpp"
41 #ifdef ZT_CONTROLLER_USE_LIBPQ
42 #include "PostgreSQL.hpp"
43 #endif
44 
45 #include "../node/Node.hpp"
46 #include "../node/CertificateOfMembership.hpp"
47 #include "../node/NetworkConfig.hpp"
48 #include "../node/Dictionary.hpp"
49 #include "../node/MAC.hpp"
50 
51 using json = nlohmann::json;
52 
53 // API version reported via JSON control plane
54 #define ZT_NETCONF_CONTROLLER_API_VERSION 4
55 
56 // Min duration between requests for an address/nwid combo to prevent floods
57 #define ZT_NETCONF_MIN_REQUEST_PERIOD 1000
58 
59 // Global maximum size of arrays in JSON objects
60 #define ZT_CONTROLLER_MAX_ARRAY_SIZE 16384
61 
62 namespace ZeroTier {
63 
64 namespace {
65 
url_encode(const std::string & value)66 std::string url_encode(const std::string &value) {
67     std::ostringstream escaped;
68     escaped.fill('0');
69     escaped << std::hex;
70 
71     for (std::string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
72         std::string::value_type c = (*i);
73 
74         // Keep alphanumeric and other accepted characters intact
75         if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
76             escaped << c;
77             continue;
78         }
79 
80         // Any other characters are percent-encoded
81         escaped << std::uppercase;
82         escaped << '%' << std::setw(2) << int((unsigned char) c);
83         escaped << std::nouppercase;
84     }
85 
86     return escaped.str();
87 }
88 
_renderRule(ZT_VirtualNetworkRule & rule)89 static json _renderRule(ZT_VirtualNetworkRule &rule)
90 {
91 	char tmp[128];
92 	json r = json::object();
93 	const ZT_VirtualNetworkRuleType rt = (ZT_VirtualNetworkRuleType)(rule.t & 0x3f);
94 
95 	switch(rt) {
96 		case ZT_NETWORK_RULE_ACTION_DROP:
97 			r["type"] = "ACTION_DROP";
98 			break;
99 		case ZT_NETWORK_RULE_ACTION_ACCEPT:
100 			r["type"] = "ACTION_ACCEPT";
101 			break;
102 		case ZT_NETWORK_RULE_ACTION_TEE:
103 			r["type"] = "ACTION_TEE";
104 			r["address"] = Address(rule.v.fwd.address).toString(tmp);
105 			r["flags"] = (unsigned int)rule.v.fwd.flags;
106 			r["length"] = (unsigned int)rule.v.fwd.length;
107 			break;
108 		case ZT_NETWORK_RULE_ACTION_WATCH:
109 			r["type"] = "ACTION_WATCH";
110 			r["address"] = Address(rule.v.fwd.address).toString(tmp);
111 			r["flags"] = (unsigned int)rule.v.fwd.flags;
112 			r["length"] = (unsigned int)rule.v.fwd.length;
113 			break;
114 		case ZT_NETWORK_RULE_ACTION_REDIRECT:
115 			r["type"] = "ACTION_REDIRECT";
116 			r["address"] = Address(rule.v.fwd.address).toString(tmp);
117 			r["flags"] = (unsigned int)rule.v.fwd.flags;
118 			break;
119 		case ZT_NETWORK_RULE_ACTION_BREAK:
120 			r["type"] = "ACTION_BREAK";
121 			break;
122 		default:
123 			break;
124 	}
125 
126 	if (r.empty()) {
127 		switch(rt) {
128 			case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
129 				r["type"] = "MATCH_SOURCE_ZEROTIER_ADDRESS";
130 				r["zt"] = Address(rule.v.zt).toString(tmp);
131 				break;
132 			case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS:
133 				r["type"] = "MATCH_DEST_ZEROTIER_ADDRESS";
134 				r["zt"] = Address(rule.v.zt).toString(tmp);
135 				break;
136 			case ZT_NETWORK_RULE_MATCH_VLAN_ID:
137 				r["type"] = "MATCH_VLAN_ID";
138 				r["vlanId"] = (unsigned int)rule.v.vlanId;
139 				break;
140 			case ZT_NETWORK_RULE_MATCH_VLAN_PCP:
141 				r["type"] = "MATCH_VLAN_PCP";
142 				r["vlanPcp"] = (unsigned int)rule.v.vlanPcp;
143 				break;
144 			case ZT_NETWORK_RULE_MATCH_VLAN_DEI:
145 				r["type"] = "MATCH_VLAN_DEI";
146 				r["vlanDei"] = (unsigned int)rule.v.vlanDei;
147 				break;
148 			case ZT_NETWORK_RULE_MATCH_MAC_SOURCE:
149 				r["type"] = "MATCH_MAC_SOURCE";
150 				OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)rule.v.mac[0],(unsigned int)rule.v.mac[1],(unsigned int)rule.v.mac[2],(unsigned int)rule.v.mac[3],(unsigned int)rule.v.mac[4],(unsigned int)rule.v.mac[5]);
151 				r["mac"] = tmp;
152 				break;
153 			case ZT_NETWORK_RULE_MATCH_MAC_DEST:
154 				r["type"] = "MATCH_MAC_DEST";
155 				OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)rule.v.mac[0],(unsigned int)rule.v.mac[1],(unsigned int)rule.v.mac[2],(unsigned int)rule.v.mac[3],(unsigned int)rule.v.mac[4],(unsigned int)rule.v.mac[5]);
156 				r["mac"] = tmp;
157 				break;
158 			case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
159 				r["type"] = "MATCH_IPV4_SOURCE";
160 				r["ip"] = InetAddress(&(rule.v.ipv4.ip),4,(unsigned int)rule.v.ipv4.mask).toString(tmp);
161 				break;
162 			case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
163 				r["type"] = "MATCH_IPV4_DEST";
164 				r["ip"] = InetAddress(&(rule.v.ipv4.ip),4,(unsigned int)rule.v.ipv4.mask).toString(tmp);
165 				break;
166 			case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
167 				r["type"] = "MATCH_IPV6_SOURCE";
168 				r["ip"] = InetAddress(rule.v.ipv6.ip,16,(unsigned int)rule.v.ipv6.mask).toString(tmp);
169 				break;
170 			case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
171 				r["type"] = "MATCH_IPV6_DEST";
172 				r["ip"] = InetAddress(rule.v.ipv6.ip,16,(unsigned int)rule.v.ipv6.mask).toString(tmp);
173 				break;
174 			case ZT_NETWORK_RULE_MATCH_IP_TOS:
175 				r["type"] = "MATCH_IP_TOS";
176 				r["mask"] = (unsigned int)rule.v.ipTos.mask;
177 				r["start"] = (unsigned int)rule.v.ipTos.value[0];
178 				r["end"] = (unsigned int)rule.v.ipTos.value[1];
179 				break;
180 			case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL:
181 				r["type"] = "MATCH_IP_PROTOCOL";
182 				r["ipProtocol"] = (unsigned int)rule.v.ipProtocol;
183 				break;
184 			case ZT_NETWORK_RULE_MATCH_ETHERTYPE:
185 				r["type"] = "MATCH_ETHERTYPE";
186 				r["etherType"] = (unsigned int)rule.v.etherType;
187 				break;
188 			case ZT_NETWORK_RULE_MATCH_ICMP:
189 				r["type"] = "MATCH_ICMP";
190 				r["icmpType"] = (unsigned int)rule.v.icmp.type;
191 				if ((rule.v.icmp.flags & 0x01) != 0)
192 					r["icmpCode"] = (unsigned int)rule.v.icmp.code;
193 				else r["icmpCode"] = json();
194 				break;
195 			case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE:
196 				r["type"] = "MATCH_IP_SOURCE_PORT_RANGE";
197 				r["start"] = (unsigned int)rule.v.port[0];
198 				r["end"] = (unsigned int)rule.v.port[1];
199 				break;
200 			case ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE:
201 				r["type"] = "MATCH_IP_DEST_PORT_RANGE";
202 				r["start"] = (unsigned int)rule.v.port[0];
203 				r["end"] = (unsigned int)rule.v.port[1];
204 				break;
205 			case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS:
206 				r["type"] = "MATCH_CHARACTERISTICS";
207 				OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",rule.v.characteristics);
208 				r["mask"] = tmp;
209 				break;
210 			case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
211 				r["type"] = "MATCH_FRAME_SIZE_RANGE";
212 				r["start"] = (unsigned int)rule.v.frameSize[0];
213 				r["end"] = (unsigned int)rule.v.frameSize[1];
214 				break;
215 			case ZT_NETWORK_RULE_MATCH_RANDOM:
216 				r["type"] = "MATCH_RANDOM";
217 				r["probability"] = (unsigned long)rule.v.randomProbability;
218 				break;
219 			case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE:
220 				r["type"] = "MATCH_TAGS_DIFFERENCE";
221 				r["id"] = rule.v.tag.id;
222 				r["value"] = rule.v.tag.value;
223 				break;
224 			case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
225 				r["type"] = "MATCH_TAGS_BITWISE_AND";
226 				r["id"] = rule.v.tag.id;
227 				r["value"] = rule.v.tag.value;
228 				break;
229 			case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR:
230 				r["type"] = "MATCH_TAGS_BITWISE_OR";
231 				r["id"] = rule.v.tag.id;
232 				r["value"] = rule.v.tag.value;
233 				break;
234 			case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR:
235 				r["type"] = "MATCH_TAGS_BITWISE_XOR";
236 				r["id"] = rule.v.tag.id;
237 				r["value"] = rule.v.tag.value;
238 				break;
239 			case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL:
240 				r["type"] = "MATCH_TAGS_EQUAL";
241 				r["id"] = rule.v.tag.id;
242 				r["value"] = rule.v.tag.value;
243 				break;
244 			case ZT_NETWORK_RULE_MATCH_TAG_SENDER:
245 				r["type"] = "MATCH_TAG_SENDER";
246 				r["id"] = rule.v.tag.id;
247 				r["value"] = rule.v.tag.value;
248 				break;
249 			case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER:
250 				r["type"] = "MATCH_TAG_RECEIVER";
251 				r["id"] = rule.v.tag.id;
252 				r["value"] = rule.v.tag.value;
253 				break;
254 			case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE:
255 				r["type"] = "INTEGER_RANGE";
256 				OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",rule.v.intRange.start);
257 				r["start"] = tmp;
258 				OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",rule.v.intRange.start + (uint64_t)rule.v.intRange.end);
259 				r["end"] = tmp;
260 				r["idx"] = rule.v.intRange.idx;
261 				r["little"] = ((rule.v.intRange.format & 0x80) != 0);
262 				r["bits"] = (rule.v.intRange.format & 63) + 1;
263 				break;
264 			default:
265 				break;
266 		}
267 
268 		if (!r.empty()) {
269 			r["not"] = ((rule.t & 0x80) != 0);
270 			r["or"] = ((rule.t & 0x40) != 0);
271 		}
272 	}
273 
274 	return r;
275 }
276 
_parseRule(json & r,ZT_VirtualNetworkRule & rule)277 static bool _parseRule(json &r,ZT_VirtualNetworkRule &rule)
278 {
279 	if (!r.is_object())
280 		return false;
281 
282 	const std::string t(OSUtils::jsonString(r["type"],""));
283 	memset(&rule,0,sizeof(ZT_VirtualNetworkRule));
284 
285 	if (OSUtils::jsonBool(r["not"],false))
286 		rule.t = 0x80;
287 	else rule.t = 0x00;
288 	if (OSUtils::jsonBool(r["or"],false))
289 		rule.t |= 0x40;
290 
291 	bool tag = false;
292 	if (t == "ACTION_DROP") {
293 		rule.t |= ZT_NETWORK_RULE_ACTION_DROP;
294 		return true;
295 	} else if (t == "ACTION_ACCEPT") {
296 		rule.t |= ZT_NETWORK_RULE_ACTION_ACCEPT;
297 		return true;
298 	} else if (t == "ACTION_TEE") {
299 		rule.t |= ZT_NETWORK_RULE_ACTION_TEE;
300 		rule.v.fwd.address = Utils::hexStrToU64(OSUtils::jsonString(r["address"],"0").c_str()) & 0xffffffffffULL;
301 		rule.v.fwd.flags = (uint32_t)(OSUtils::jsonInt(r["flags"],0ULL) & 0xffffffffULL);
302 		rule.v.fwd.length = (uint16_t)(OSUtils::jsonInt(r["length"],0ULL) & 0xffffULL);
303 		return true;
304 	} else if (t == "ACTION_WATCH") {
305 		rule.t |= ZT_NETWORK_RULE_ACTION_WATCH;
306 		rule.v.fwd.address = Utils::hexStrToU64(OSUtils::jsonString(r["address"],"0").c_str()) & 0xffffffffffULL;
307 		rule.v.fwd.flags = (uint32_t)(OSUtils::jsonInt(r["flags"],0ULL) & 0xffffffffULL);
308 		rule.v.fwd.length = (uint16_t)(OSUtils::jsonInt(r["length"],0ULL) & 0xffffULL);
309 		return true;
310 	} else if (t == "ACTION_REDIRECT") {
311 		rule.t |= ZT_NETWORK_RULE_ACTION_REDIRECT;
312 		rule.v.fwd.address = Utils::hexStrToU64(OSUtils::jsonString(r["address"],"0").c_str()) & 0xffffffffffULL;
313 		rule.v.fwd.flags = (uint32_t)(OSUtils::jsonInt(r["flags"],0ULL) & 0xffffffffULL);
314 		return true;
315 	} else if (t == "ACTION_BREAK") {
316 		rule.t |= ZT_NETWORK_RULE_ACTION_BREAK;
317 		return true;
318 	} else if (t == "MATCH_SOURCE_ZEROTIER_ADDRESS") {
319 		rule.t |= ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS;
320 		rule.v.zt = Utils::hexStrToU64(OSUtils::jsonString(r["zt"],"0").c_str()) & 0xffffffffffULL;
321 		return true;
322 	} else if (t == "MATCH_DEST_ZEROTIER_ADDRESS") {
323 		rule.t |= ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS;
324 		rule.v.zt = Utils::hexStrToU64(OSUtils::jsonString(r["zt"],"0").c_str()) & 0xffffffffffULL;
325 		return true;
326 	} else if (t == "MATCH_VLAN_ID") {
327 		rule.t |= ZT_NETWORK_RULE_MATCH_VLAN_ID;
328 		rule.v.vlanId = (uint16_t)(OSUtils::jsonInt(r["vlanId"],0ULL) & 0xffffULL);
329 		return true;
330 	} else if (t == "MATCH_VLAN_PCP") {
331 		rule.t |= ZT_NETWORK_RULE_MATCH_VLAN_PCP;
332 		rule.v.vlanPcp = (uint8_t)(OSUtils::jsonInt(r["vlanPcp"],0ULL) & 0xffULL);
333 		return true;
334 	} else if (t == "MATCH_VLAN_DEI") {
335 		rule.t |= ZT_NETWORK_RULE_MATCH_VLAN_DEI;
336 		rule.v.vlanDei = (uint8_t)(OSUtils::jsonInt(r["vlanDei"],0ULL) & 0xffULL);
337 		return true;
338 	} else if (t == "MATCH_MAC_SOURCE") {
339 		rule.t |= ZT_NETWORK_RULE_MATCH_MAC_SOURCE;
340 		const std::string mac(OSUtils::jsonString(r["mac"],"0"));
341 		Utils::unhex(mac.c_str(),(unsigned int)mac.length(),rule.v.mac,6);
342 		return true;
343 	} else if (t == "MATCH_MAC_DEST") {
344 		rule.t |= ZT_NETWORK_RULE_MATCH_MAC_DEST;
345 		const std::string mac(OSUtils::jsonString(r["mac"],"0"));
346 		Utils::unhex(mac.c_str(),(unsigned int)mac.length(),rule.v.mac,6);
347 		return true;
348 	} else if (t == "MATCH_IPV4_SOURCE") {
349 		rule.t |= ZT_NETWORK_RULE_MATCH_IPV4_SOURCE;
350 		InetAddress ip(OSUtils::jsonString(r["ip"],"0.0.0.0").c_str());
351 		rule.v.ipv4.ip = reinterpret_cast<struct sockaddr_in *>(&ip)->sin_addr.s_addr;
352 		rule.v.ipv4.mask = Utils::ntoh(reinterpret_cast<struct sockaddr_in *>(&ip)->sin_port) & 0xff;
353 		if (rule.v.ipv4.mask > 32) rule.v.ipv4.mask = 32;
354 		return true;
355 	} else if (t == "MATCH_IPV4_DEST") {
356 		rule.t |= ZT_NETWORK_RULE_MATCH_IPV4_DEST;
357 		InetAddress ip(OSUtils::jsonString(r["ip"],"0.0.0.0").c_str());
358 		rule.v.ipv4.ip = reinterpret_cast<struct sockaddr_in *>(&ip)->sin_addr.s_addr;
359 		rule.v.ipv4.mask = Utils::ntoh(reinterpret_cast<struct sockaddr_in *>(&ip)->sin_port) & 0xff;
360 		if (rule.v.ipv4.mask > 32) rule.v.ipv4.mask = 32;
361 		return true;
362 	} else if (t == "MATCH_IPV6_SOURCE") {
363 		rule.t |= ZT_NETWORK_RULE_MATCH_IPV6_SOURCE;
364 		InetAddress ip(OSUtils::jsonString(r["ip"],"::0").c_str());
365 		memcpy(rule.v.ipv6.ip,reinterpret_cast<struct sockaddr_in6 *>(&ip)->sin6_addr.s6_addr,16);
366 		rule.v.ipv6.mask = Utils::ntoh(reinterpret_cast<struct sockaddr_in6 *>(&ip)->sin6_port) & 0xff;
367 		if (rule.v.ipv6.mask > 128) rule.v.ipv6.mask = 128;
368 		return true;
369 	} else if (t == "MATCH_IPV6_DEST") {
370 		rule.t |= ZT_NETWORK_RULE_MATCH_IPV6_DEST;
371 		InetAddress ip(OSUtils::jsonString(r["ip"],"::0").c_str());
372 		memcpy(rule.v.ipv6.ip,reinterpret_cast<struct sockaddr_in6 *>(&ip)->sin6_addr.s6_addr,16);
373 		rule.v.ipv6.mask = Utils::ntoh(reinterpret_cast<struct sockaddr_in6 *>(&ip)->sin6_port) & 0xff;
374 		if (rule.v.ipv6.mask > 128) rule.v.ipv6.mask = 128;
375 		return true;
376 	} else if (t == "MATCH_IP_TOS") {
377 		rule.t |= ZT_NETWORK_RULE_MATCH_IP_TOS;
378 		rule.v.ipTos.mask = (uint8_t)(OSUtils::jsonInt(r["mask"],0ULL) & 0xffULL);
379 		rule.v.ipTos.value[0] = (uint8_t)(OSUtils::jsonInt(r["start"],0ULL) & 0xffULL);
380 		rule.v.ipTos.value[1] = (uint8_t)(OSUtils::jsonInt(r["end"],0ULL) & 0xffULL);
381 		return true;
382 	} else if (t == "MATCH_IP_PROTOCOL") {
383 		rule.t |= ZT_NETWORK_RULE_MATCH_IP_PROTOCOL;
384 		rule.v.ipProtocol = (uint8_t)(OSUtils::jsonInt(r["ipProtocol"],0ULL) & 0xffULL);
385 		return true;
386 	} else if (t == "MATCH_ETHERTYPE") {
387 		rule.t |= ZT_NETWORK_RULE_MATCH_ETHERTYPE;
388 		rule.v.etherType = (uint16_t)(OSUtils::jsonInt(r["etherType"],0ULL) & 0xffffULL);
389 		return true;
390 	} else if (t == "MATCH_ICMP") {
391 		rule.t |= ZT_NETWORK_RULE_MATCH_ICMP;
392 		rule.v.icmp.type = (uint8_t)(OSUtils::jsonInt(r["icmpType"],0ULL) & 0xffULL);
393 		json &code = r["icmpCode"];
394 		if (code.is_null()) {
395 			rule.v.icmp.code = 0;
396 			rule.v.icmp.flags = 0x00;
397 		} else {
398 			rule.v.icmp.code = (uint8_t)(OSUtils::jsonInt(code,0ULL) & 0xffULL);
399 			rule.v.icmp.flags = 0x01;
400 		}
401 		return true;
402 	} else if (t == "MATCH_IP_SOURCE_PORT_RANGE") {
403 		rule.t |= ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE;
404 		rule.v.port[0] = (uint16_t)(OSUtils::jsonInt(r["start"],0ULL) & 0xffffULL);
405 		rule.v.port[1] = (uint16_t)(OSUtils::jsonInt(r["end"],(uint64_t)rule.v.port[0]) & 0xffffULL);
406 		return true;
407 	} else if (t == "MATCH_IP_DEST_PORT_RANGE") {
408 		rule.t |= ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE;
409 		rule.v.port[0] = (uint16_t)(OSUtils::jsonInt(r["start"],0ULL) & 0xffffULL);
410 		rule.v.port[1] = (uint16_t)(OSUtils::jsonInt(r["end"],(uint64_t)rule.v.port[0]) & 0xffffULL);
411 		return true;
412 	} else if (t == "MATCH_CHARACTERISTICS") {
413 		rule.t |= ZT_NETWORK_RULE_MATCH_CHARACTERISTICS;
414 		if (r.count("mask")) {
415 			json &v = r["mask"];
416 			if (v.is_number()) {
417 				rule.v.characteristics = v;
418 			} else {
419 				std::string tmp = v;
420 				rule.v.characteristics = Utils::hexStrToU64(tmp.c_str());
421 			}
422 		}
423 		return true;
424 	} else if (t == "MATCH_FRAME_SIZE_RANGE") {
425 		rule.t |= ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE;
426 		rule.v.frameSize[0] = (uint16_t)(OSUtils::jsonInt(r["start"],0ULL) & 0xffffULL);
427 		rule.v.frameSize[1] = (uint16_t)(OSUtils::jsonInt(r["end"],(uint64_t)rule.v.frameSize[0]) & 0xffffULL);
428 		return true;
429 	} else if (t == "MATCH_RANDOM") {
430 		rule.t |= ZT_NETWORK_RULE_MATCH_RANDOM;
431 		rule.v.randomProbability = (uint32_t)(OSUtils::jsonInt(r["probability"],0ULL) & 0xffffffffULL);
432 		return true;
433 	} else if (t == "MATCH_TAGS_DIFFERENCE") {
434 		rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE;
435 		tag = true;
436 	} else if (t == "MATCH_TAGS_BITWISE_AND") {
437 		rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND;
438 		tag = true;
439 	} else if (t == "MATCH_TAGS_BITWISE_OR") {
440 		rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR;
441 		tag = true;
442 	} else if (t == "MATCH_TAGS_BITWISE_XOR") {
443 		rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR;
444 		tag = true;
445 	} else if (t == "MATCH_TAGS_EQUAL") {
446 		rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_EQUAL;
447 		tag = true;
448 	} else if (t == "MATCH_TAG_SENDER") {
449 		rule.t |= ZT_NETWORK_RULE_MATCH_TAG_SENDER;
450 		tag = true;
451 	} else if (t == "MATCH_TAG_RECEIVER") {
452 		rule.t |= ZT_NETWORK_RULE_MATCH_TAG_RECEIVER;
453 		tag = true;
454 	} else if (t == "INTEGER_RANGE") {
455 		json &s = r["start"];
456 		if (s.is_string()) {
457 			std::string tmp = s;
458 			rule.v.intRange.start = Utils::hexStrToU64(tmp.c_str());
459 		} else {
460 			rule.v.intRange.start = OSUtils::jsonInt(s,0ULL);
461 		}
462 		json &e = r["end"];
463 		if (e.is_string()) {
464 			std::string tmp = e;
465 			rule.v.intRange.end = (uint32_t)(Utils::hexStrToU64(tmp.c_str()) - rule.v.intRange.start);
466 		} else {
467 			rule.v.intRange.end = (uint32_t)(OSUtils::jsonInt(e,0ULL) - rule.v.intRange.start);
468 		}
469 		rule.v.intRange.idx = (uint16_t)OSUtils::jsonInt(r["idx"],0ULL);
470 		rule.v.intRange.format = (OSUtils::jsonBool(r["little"],false)) ? 0x80 : 0x00;
471 		rule.v.intRange.format |= (uint8_t)((OSUtils::jsonInt(r["bits"],1ULL) - 1) & 63);
472 	}
473 
474 	if (tag) {
475 		rule.v.tag.id = (uint32_t)(OSUtils::jsonInt(r["id"],0ULL) & 0xffffffffULL);
476 		rule.v.tag.value = (uint32_t)(OSUtils::jsonInt(r["value"],0ULL) & 0xffffffffULL);
477 		return true;
478 	}
479 
480 	return false;
481 }
482 
483 } // anonymous namespace
484 
EmbeddedNetworkController(Node * node,const char * ztPath,const char * dbPath,int listenPort,RedisConfig * rc)485 EmbeddedNetworkController::EmbeddedNetworkController(Node *node,const char *ztPath,const char *dbPath, int listenPort, RedisConfig *rc) :
486 	_startTime(OSUtils::now()),
487 	_listenPort(listenPort),
488 	_node(node),
489 	_ztPath(ztPath),
490 	_path(dbPath),
491 	_sender((NetworkController::Sender *)0),
492 	_db(this),
493 	_rc(rc)
494 {
495 }
496 
~EmbeddedNetworkController()497 EmbeddedNetworkController::~EmbeddedNetworkController()
498 {
499 	std::lock_guard<std::mutex> l(_threads_l);
500 	_queue.stop();
501 	for(auto t=_threads.begin();t!=_threads.end();++t)
502 		t->join();
503 }
504 
setSSORedirectURL(const std::string & url)505 void EmbeddedNetworkController::setSSORedirectURL(const std::string &url) {
506 	_ssoRedirectURL = url_encode(url);
507 }
508 
init(const Identity & signingId,Sender * sender)509 void EmbeddedNetworkController::init(const Identity &signingId,Sender *sender)
510 {
511 	char tmp[64];
512 	_signingId = signingId;
513 	_sender = sender;
514 	_signingIdAddressString = signingId.address().toString(tmp);
515 
516 #ifdef ZT_CONTROLLER_USE_LIBPQ
517 	if ((_path.length() > 9)&&(_path.substr(0,9) == "postgres:")) {
518 		_db.addDB(std::shared_ptr<DB>(new PostgreSQL(_signingId,_path.substr(9).c_str(), _listenPort, _rc)));
519 	} else {
520 #endif
521 		_db.addDB(std::shared_ptr<DB>(new FileDB(_path.c_str())));
522 #ifdef ZT_CONTROLLER_USE_LIBPQ
523 	}
524 #endif
525 
526 	std::string lfJSON;
527 	OSUtils::readFile((_ztPath + ZT_PATH_SEPARATOR_S "local.conf").c_str(),lfJSON);
528 	if (lfJSON.length() > 0) {
529 		nlohmann::json lfConfig(OSUtils::jsonParse(lfJSON));
530 		nlohmann::json &settings = lfConfig["settings"];
531 		if (settings.is_object()) {
532 			nlohmann::json &controllerDb = settings["controllerDb"];
533 			if (controllerDb.is_object()) {
534 				std::string type = controllerDb["type"];
535 				if (type == "lf") {
536 					std::string lfOwner = controllerDb["owner"];
537 					std::string lfHost = controllerDb["host"];
538 					int lfPort = controllerDb["port"];
539 					bool storeOnlineState = controllerDb["storeOnlineState"];
540 					if ((lfOwner.length())&&(lfHost.length())&&(lfPort > 0)&&(lfPort < 65536)) {
541 						std::size_t pubHdrLoc = lfOwner.find("Public: ");
542 						if ((pubHdrLoc > 0)&&((pubHdrLoc + 8) < lfOwner.length())) {
543 							std::string lfOwnerPublic = lfOwner.substr(pubHdrLoc + 8);
544 							std::size_t pubHdrEnd = lfOwnerPublic.find_first_of("\n\r\t ");
545 							if (pubHdrEnd != std::string::npos) {
546 								lfOwnerPublic = lfOwnerPublic.substr(0,pubHdrEnd);
547 								_db.addDB(std::shared_ptr<DB>(new LFDB(_signingId,_path.c_str(),lfOwner.c_str(),lfOwnerPublic.c_str(),lfHost.c_str(),lfPort,storeOnlineState)));
548 							}
549 						}
550 					}
551 				}
552 			}
553 		}
554 	}
555 
556 	_db.waitForReady();
557 }
558 
request(uint64_t nwid,const InetAddress & fromAddr,uint64_t requestPacketId,const Identity & identity,const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> & metaData)559 void EmbeddedNetworkController::request(
560 	uint64_t nwid,
561 	const InetAddress &fromAddr,
562 	uint64_t requestPacketId,
563 	const Identity &identity,
564 	const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> &metaData)
565 {
566 	if (((!_signingId)||(!_signingId.hasPrivate()))||(_signingId.address().toInt() != (nwid >> 24))||(!_sender))
567 		return;
568 	_startThreads();
569 	_RQEntry *qe = new _RQEntry;
570 	qe->nwid = nwid;
571 	qe->requestPacketId = requestPacketId;
572 	qe->fromAddr = fromAddr;
573 	qe->identity = identity;
574 	qe->metaData = metaData;
575 	qe->type = _RQEntry::RQENTRY_TYPE_REQUEST;
576 	_queue.post(qe);
577 }
578 
handleControlPlaneHttpGET(const std::vector<std::string> & path,const std::map<std::string,std::string> & urlArgs,const std::map<std::string,std::string> & headers,const std::string & body,std::string & responseBody,std::string & responseContentType)579 unsigned int EmbeddedNetworkController::handleControlPlaneHttpGET(
580 	const std::vector<std::string> &path,
581 	const std::map<std::string,std::string> &urlArgs,
582 	const std::map<std::string,std::string> &headers,
583 	const std::string &body,
584 	std::string &responseBody,
585 	std::string &responseContentType)
586 {
587 	if ((!path.empty())&&(path[0] == "network")) {
588 
589 		if ((path.size() >= 2)&&(path[1].length() == 16)) {
590 			const uint64_t nwid = Utils::hexStrToU64(path[1].c_str());
591 			json network;
592 			if (!_db.get(nwid,network))
593 				return 404;
594 
595 			if (path.size() >= 3) {
596 
597 				if (path[2] == "member") {
598 
599 					if (path.size() >= 4) {
600 						// Get member
601 
602 						const uint64_t address = Utils::hexStrToU64(path[3].c_str());
603 						json member;
604 						if (!_db.get(nwid,network,address,member))
605 							return 404;
606 						responseBody = OSUtils::jsonDump(member);
607 						responseContentType = "application/json";
608 
609 					} else {
610 						// List members and their revisions
611 
612 						responseBody = "{";
613 						std::vector<json> members;
614 						if (_db.get(nwid,network,members)) {
615 							responseBody.reserve((members.size() + 2) * 32);
616 							std::string mid;
617 							for(auto member=members.begin();member!=members.end();++member) {
618 								mid = OSUtils::jsonString((*member)["id"], "");
619 								char tmp[128];
620 								OSUtils::ztsnprintf(tmp,sizeof(tmp),"%s\"%s\":%llu",(responseBody.length() > 1) ? "," : "",mid.c_str(),(unsigned long long)OSUtils::jsonInt((*member)["revision"],0));
621 								responseBody.append(tmp);
622 							}
623 						}
624 						responseBody.push_back('}');
625 						responseContentType = "application/json";
626 
627 					}
628 					return 200;
629 
630 				} // else 404
631 
632 			} else {
633 				// Get network
634 
635 				responseBody = OSUtils::jsonDump(network);
636 				responseContentType = "application/json";
637 				return 200;
638 
639 			}
640 		} else if (path.size() == 1) {
641 			// List networks
642 
643 			std::set<uint64_t> networkIds;
644 			_db.networks(networkIds);
645 			char tmp[64];
646 			responseBody = "[";
647 			responseBody.reserve((networkIds.size() + 1) * 24);
648 			for(std::set<uint64_t>::const_iterator i(networkIds.begin());i!=networkIds.end();++i) {
649 				if (responseBody.length() > 1)
650 					responseBody.push_back(',');
651 				OSUtils::ztsnprintf(tmp,sizeof(tmp),"\"%.16llx\"",(unsigned long long)*i);
652 				responseBody.append(tmp);
653 			}
654 			responseBody.push_back(']');
655 			responseContentType = "application/json";
656 
657 			return 200;
658 
659 		} // else 404
660 
661 	} else {
662 		// Controller status
663 
664 		char tmp[4096];
665 		const bool dbOk = _db.isReady();
666 		OSUtils::ztsnprintf(tmp,sizeof(tmp),"{\n\t\"controller\": true,\n\t\"apiVersion\": %d,\n\t\"clock\": %llu,\n\t\"databaseReady\": %s\n}\n",ZT_NETCONF_CONTROLLER_API_VERSION,(unsigned long long)OSUtils::now(),dbOk ? "true" : "false");
667 		responseBody = tmp;
668 		responseContentType = "application/json";
669 		return dbOk ? 200 : 503;
670 
671 	}
672 
673 	return 404;
674 }
675 
handleControlPlaneHttpPOST(const std::vector<std::string> & path,const std::map<std::string,std::string> & urlArgs,const std::map<std::string,std::string> & headers,const std::string & body,std::string & responseBody,std::string & responseContentType)676 unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
677 	const std::vector<std::string> &path,
678 	const std::map<std::string,std::string> &urlArgs,
679 	const std::map<std::string,std::string> &headers,
680 	const std::string &body,
681 	std::string &responseBody,
682 	std::string &responseContentType)
683 {
684 	if (path.empty())
685 		return 404;
686 
687 	json b;
688 	try {
689 		b = OSUtils::jsonParse(body);
690 		if (!b.is_object()) {
691 			responseBody = "{ \"message\": \"body is not a JSON object\" }";
692 			responseContentType = "application/json";
693 			return 400;
694 		}
695 	} catch ( ... ) {
696 		responseBody = "{ \"message\": \"body JSON is invalid\" }";
697 		responseContentType = "application/json";
698 		return 400;
699 	}
700 	const int64_t now = OSUtils::now();
701 
702 	if (path[0] == "network") {
703 
704 		if ((path.size() >= 2)&&(path[1].length() == 16)) {
705 			uint64_t nwid = Utils::hexStrToU64(path[1].c_str());
706 			char nwids[24];
707 			OSUtils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",(unsigned long long)nwid);
708 
709 			if (path.size() >= 3) {
710 
711 				if ((path.size() == 4)&&(path[2] == "member")&&(path[3].length() == 10)) {
712 					uint64_t address = Utils::hexStrToU64(path[3].c_str());
713 					char addrs[24];
714 					OSUtils::ztsnprintf(addrs,sizeof(addrs),"%.10llx",(unsigned long long)address);
715 
716 					json member,network;
717 					_db.get(nwid,network,address,member);
718 					DB::initMember(member);
719 
720 					try {
721 						if (b.count("activeBridge")) member["activeBridge"] = OSUtils::jsonBool(b["activeBridge"], false);
722 						if (b.count("noAutoAssignIps")) member["noAutoAssignIps"] = OSUtils::jsonBool(b["noAutoAssignIps"], false);
723 						if (b.count("authenticationExpiryTime")) member["authenticationExpiryTime"] = (uint64_t)OSUtils::jsonInt(b["authenticationExpiryTime"], 0ULL);
724 						if (b.count("authenticationURL")) member["authenticationURL"] = OSUtils::jsonString(b["authenticationURL"], "");
725 
726 						if (b.count("remoteTraceTarget")) {
727 							const std::string rtt(OSUtils::jsonString(b["remoteTraceTarget"],""));
728 							if (rtt.length() == 10) {
729 								member["remoteTraceTarget"] = rtt;
730 							} else {
731 								member["remoteTraceTarget"] = json();
732 							}
733 						}
734 						if (b.count("remoteTraceLevel")) member["remoteTraceLevel"] = OSUtils::jsonInt(b["remoteTraceLevel"],0ULL);
735 
736 						if (b.count("authorized")) {
737 							const bool newAuth = OSUtils::jsonBool(b["authorized"],false);
738 							if (newAuth != OSUtils::jsonBool(member["authorized"],false)) {
739 								member["authorized"] = newAuth;
740 								member[((newAuth) ? "lastAuthorizedTime" : "lastDeauthorizedTime")] = now;
741 								if (newAuth) {
742 									member["lastAuthorizedCredentialType"] = "api";
743 									member["lastAuthorizedCredential"] = json();
744 								}
745 							}
746 						}
747 
748 						if (b.count("ipAssignments")) {
749 							json &ipa = b["ipAssignments"];
750 							if (ipa.is_array()) {
751 								json mipa(json::array());
752 								for(unsigned long i=0;i<ipa.size();++i) {
753 									std::string ips = ipa[i];
754 									InetAddress ip(ips.c_str());
755 									if ((ip.ss_family == AF_INET)||(ip.ss_family == AF_INET6)) {
756 										char tmpip[64];
757 										mipa.push_back(ip.toIpString(tmpip));
758 										if (mipa.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE)
759 											break;
760 									}
761 								}
762 								member["ipAssignments"] = mipa;
763 							}
764 						}
765 
766 						if (b.count("tags")) {
767 							json &tags = b["tags"];
768 							if (tags.is_array()) {
769 								std::map<uint64_t,uint64_t> mtags;
770 								for(unsigned long i=0;i<tags.size();++i) {
771 									json &tag = tags[i];
772 									if ((tag.is_array())&&(tag.size() == 2))
773 										mtags[OSUtils::jsonInt(tag[0],0ULL) & 0xffffffffULL] = OSUtils::jsonInt(tag[1],0ULL) & 0xffffffffULL;
774 								}
775 								json mtagsa = json::array();
776 								for(std::map<uint64_t,uint64_t>::iterator t(mtags.begin());t!=mtags.end();++t) {
777 									json ta = json::array();
778 									ta.push_back(t->first);
779 									ta.push_back(t->second);
780 									mtagsa.push_back(ta);
781 									if (mtagsa.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE)
782 										break;
783 								}
784 								member["tags"] = mtagsa;
785 							}
786 						}
787 
788 						if (b.count("capabilities")) {
789 							json &capabilities = b["capabilities"];
790 							if (capabilities.is_array()) {
791 								json mcaps = json::array();
792 								for(unsigned long i=0;i<capabilities.size();++i) {
793 									mcaps.push_back(OSUtils::jsonInt(capabilities[i],0ULL));
794 									if (mcaps.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE)
795 										break;
796 								}
797 								std::sort(mcaps.begin(),mcaps.end());
798 								mcaps.erase(std::unique(mcaps.begin(),mcaps.end()),mcaps.end());
799 								member["capabilities"] = mcaps;
800 							}
801 						}
802 					} catch ( ... ) {
803 						responseBody = "{ \"message\": \"exception while processing parameters in JSON body\" }";
804 						responseContentType = "application/json";
805 						return 400;
806 					}
807 
808 					member["id"] = addrs;
809 					member["address"] = addrs; // legacy
810 					member["nwid"] = nwids;
811 
812 					DB::cleanMember(member);
813 					_db.save(member,true);
814 					responseBody = OSUtils::jsonDump(member);
815 					responseContentType = "application/json";
816 
817 					return 200;
818 				} // else 404
819 
820 			} else {
821 				// POST to network ID
822 
823 				// Magic ID ending with ______ picks a random unused network ID
824 				if (path[1].substr(10) == "______") {
825 					nwid = 0;
826 					uint64_t nwidPrefix = (Utils::hexStrToU64(path[1].substr(0,10).c_str()) << 24) & 0xffffffffff000000ULL;
827 					uint64_t nwidPostfix = 0;
828 					for(unsigned long k=0;k<100000;++k) { // sanity limit on trials
829 						Utils::getSecureRandom(&nwidPostfix,sizeof(nwidPostfix));
830 						uint64_t tryNwid = nwidPrefix | (nwidPostfix & 0xffffffULL);
831 						if ((tryNwid & 0xffffffULL) == 0ULL) tryNwid |= 1ULL;
832 						if (!_db.hasNetwork(tryNwid)) {
833 							nwid = tryNwid;
834 							break;
835 						}
836 					}
837 					if (!nwid)
838 						return 503;
839 				}
840 				OSUtils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",(unsigned long long)nwid);
841 
842 				json network;
843 				_db.get(nwid,network);
844 				DB::initNetwork(network);
845 
846 				try {
847 					if (b.count("name")) network["name"] = OSUtils::jsonString(b["name"],"");
848 					if (b.count("private")) network["private"] = OSUtils::jsonBool(b["private"],true);
849 					if (b.count("enableBroadcast")) network["enableBroadcast"] = OSUtils::jsonBool(b["enableBroadcast"],false);
850 					if (b.count("multicastLimit")) network["multicastLimit"] = OSUtils::jsonInt(b["multicastLimit"],32ULL);
851 					if (b.count("mtu")) network["mtu"] = std::max(std::min((unsigned int)OSUtils::jsonInt(b["mtu"],ZT_DEFAULT_MTU),(unsigned int)ZT_MAX_MTU),(unsigned int)ZT_MIN_MTU);
852 
853 					if (b.count("remoteTraceTarget")) {
854 						const std::string rtt(OSUtils::jsonString(b["remoteTraceTarget"],""));
855 						if (rtt.length() == 10) {
856 							network["remoteTraceTarget"] = rtt;
857 						} else {
858 							network["remoteTraceTarget"] = json();
859 						}
860 					}
861 					if (b.count("remoteTraceLevel")) network["remoteTraceLevel"] = OSUtils::jsonInt(b["remoteTraceLevel"],0ULL);
862 
863 					if (b.count("v4AssignMode")) {
864 						json nv4m;
865 						json &v4m = b["v4AssignMode"];
866 						if (v4m.is_string()) { // backward compatibility
867 							nv4m["zt"] = (OSUtils::jsonString(v4m,"") == "zt");
868 						} else if (v4m.is_object()) {
869 							nv4m["zt"] = OSUtils::jsonBool(v4m["zt"],false);
870 						} else nv4m["zt"] = false;
871 						network["v4AssignMode"] = nv4m;
872 					}
873 
874 					if (b.count("v6AssignMode")) {
875 						json nv6m;
876 						json &v6m = b["v6AssignMode"];
877 						if (!nv6m.is_object()) nv6m = json::object();
878 						if (v6m.is_string()) { // backward compatibility
879 							std::vector<std::string> v6ms(OSUtils::split(OSUtils::jsonString(v6m,"").c_str(),",","",""));
880 							std::sort(v6ms.begin(),v6ms.end());
881 							v6ms.erase(std::unique(v6ms.begin(),v6ms.end()),v6ms.end());
882 							nv6m["rfc4193"] = false;
883 							nv6m["zt"] = false;
884 							nv6m["6plane"] = false;
885 							for(std::vector<std::string>::iterator i(v6ms.begin());i!=v6ms.end();++i) {
886 								if (*i == "rfc4193")
887 									nv6m["rfc4193"] = true;
888 								else if (*i == "zt")
889 									nv6m["zt"] = true;
890 								else if (*i == "6plane")
891 									nv6m["6plane"] = true;
892 							}
893 						} else if (v6m.is_object()) {
894 							if (v6m.count("rfc4193")) nv6m["rfc4193"] = OSUtils::jsonBool(v6m["rfc4193"],false);
895 							if (v6m.count("zt")) nv6m["zt"] = OSUtils::jsonBool(v6m["zt"],false);
896 							if (v6m.count("6plane")) nv6m["6plane"] = OSUtils::jsonBool(v6m["6plane"],false);
897 						} else {
898 							nv6m["rfc4193"] = false;
899 							nv6m["zt"] = false;
900 							nv6m["6plane"] = false;
901 						}
902 						network["v6AssignMode"] = nv6m;
903 					}
904 
905 					if (b.count("routes")) {
906 						json &rts = b["routes"];
907 						if (rts.is_array()) {
908 							json nrts = json::array();
909 							for(unsigned long i=0;i<rts.size();++i) {
910 								json &rt = rts[i];
911 								if (rt.is_object()) {
912 									json &target = rt["target"];
913 									json &via = rt["via"];
914 									if (target.is_string()) {
915 										InetAddress t(target.get<std::string>().c_str());
916 										InetAddress v;
917 										if (via.is_string()) v.fromString(via.get<std::string>().c_str());
918 										if ( ((t.ss_family == AF_INET)||(t.ss_family == AF_INET6)) && (t.netmaskBitsValid()) ) {
919 											json tmp;
920 											char tmp2[64];
921 											tmp["target"] = t.toString(tmp2);
922 											if (v.ss_family == t.ss_family)
923 												tmp["via"] = v.toIpString(tmp2);
924 											else tmp["via"] = json();
925 											nrts.push_back(tmp);
926 											if (nrts.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE)
927 												break;
928 										}
929 									}
930 								}
931 							}
932 							network["routes"] = nrts;
933 						}
934 					}
935 
936 					if (b.count("ipAssignmentPools")) {
937 						json &ipp = b["ipAssignmentPools"];
938 						if (ipp.is_array()) {
939 							json nipp = json::array();
940 							for(unsigned long i=0;i<ipp.size();++i) {
941 								json &ip = ipp[i];
942 								if ((ip.is_object())&&(ip.count("ipRangeStart"))&&(ip.count("ipRangeEnd"))) {
943 									InetAddress f(OSUtils::jsonString(ip["ipRangeStart"],"").c_str());
944 									InetAddress t(OSUtils::jsonString(ip["ipRangeEnd"],"").c_str());
945 									if ( ((f.ss_family == AF_INET)||(f.ss_family == AF_INET6)) && (f.ss_family == t.ss_family) ) {
946 										json tmp = json::object();
947 										char tmp2[64];
948 										tmp["ipRangeStart"] = f.toIpString(tmp2);
949 										tmp["ipRangeEnd"] = t.toIpString(tmp2);
950 										nipp.push_back(tmp);
951 										if (nipp.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE)
952 											break;
953 									}
954 								}
955 							}
956 							network["ipAssignmentPools"] = nipp;
957 						}
958 					}
959 
960 					if (b.count("rules")) {
961 						json &rules = b["rules"];
962 						if (rules.is_array()) {
963 							json nrules = json::array();
964 							for(unsigned long i=0;i<rules.size();++i) {
965 								json &rule = rules[i];
966 								if (rule.is_object()) {
967 									ZT_VirtualNetworkRule ztr;
968 									if (_parseRule(rule,ztr)) {
969 										nrules.push_back(_renderRule(ztr));
970 										if (nrules.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE)
971 											break;
972 									}
973 								}
974 							}
975 							network["rules"] = nrules;
976 						}
977 					}
978 
979 					if (b.count("authTokens")) {
980 						json &authTokens = b["authTokens"];
981 						if (authTokens.is_object()) {
982 							json nat;
983 							for(json::iterator t(authTokens.begin());t!=authTokens.end();++t) {
984 								if ((t.value().is_number())&&(t.value() >= 0))
985 									nat[t.key()] = t.value();
986 							}
987 							network["authTokens"] = nat;
988 						} else {
989 							network["authTokens"] = {{}};
990 						}
991 					}
992 
993 					if (b.count("capabilities")) {
994 						json &capabilities = b["capabilities"];
995 						if (capabilities.is_array()) {
996 							std::map< uint64_t,json > ncaps;
997 							for(unsigned long i=0;i<capabilities.size();++i) {
998 								json &cap = capabilities[i];
999 								if (cap.is_object()) {
1000 									json ncap = json::object();
1001 									const uint64_t capId = OSUtils::jsonInt(cap["id"],0ULL);
1002 									ncap["id"] = capId;
1003 									ncap["default"] = OSUtils::jsonBool(cap["default"],false);
1004 
1005 									json &rules = cap["rules"];
1006 									json nrules = json::array();
1007 									if (rules.is_array()) {
1008 										for(unsigned long i=0;i<rules.size();++i) {
1009 											json &rule = rules[i];
1010 											if (rule.is_object()) {
1011 												ZT_VirtualNetworkRule ztr;
1012 												if (_parseRule(rule,ztr)) {
1013 													nrules.push_back(_renderRule(ztr));
1014 													if (nrules.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE)
1015 														break;
1016 												}
1017 											}
1018 										}
1019 									}
1020 									ncap["rules"] = nrules;
1021 
1022 									ncaps[capId] = ncap;
1023 								}
1024 							}
1025 
1026 							json ncapsa = json::array();
1027 							for(std::map< uint64_t,json >::iterator c(ncaps.begin());c!=ncaps.end();++c) {
1028 								ncapsa.push_back(c->second);
1029 								if (ncapsa.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE)
1030 									break;
1031 							}
1032 							network["capabilities"] = ncapsa;
1033 						}
1034 					}
1035 
1036 					if (b.count("tags")) {
1037 						json &tags = b["tags"];
1038 						if (tags.is_array()) {
1039 							std::map< uint64_t,json > ntags;
1040 							for(unsigned long i=0;i<tags.size();++i) {
1041 								json &tag = tags[i];
1042 								if (tag.is_object()) {
1043 									json ntag = json::object();
1044 									const uint64_t tagId = OSUtils::jsonInt(tag["id"],0ULL);
1045 									ntag["id"] = tagId;
1046 									json &dfl = tag["default"];
1047 									if (dfl.is_null())
1048 										ntag["default"] = dfl;
1049 									else ntag["default"] = OSUtils::jsonInt(dfl,0ULL);
1050 									ntags[tagId] = ntag;
1051 								}
1052 							}
1053 
1054 							json ntagsa = json::array();
1055 							for(std::map< uint64_t,json >::iterator t(ntags.begin());t!=ntags.end();++t) {
1056 								ntagsa.push_back(t->second);
1057 								if (ntagsa.size() >= ZT_CONTROLLER_MAX_ARRAY_SIZE)
1058 									break;
1059 							}
1060 							network["tags"] = ntagsa;
1061 						}
1062 					}
1063 
1064 					if (b.count("dns")) {
1065 						json &dns = b["dns"];
1066 						if (dns.is_object()) {
1067 							json nd;
1068 
1069 							nd["domain"] = dns["domain"];
1070 
1071 							json &srv = dns["servers"];
1072 							if (srv.is_array()) {
1073 								json ns = json::array();
1074 								for(unsigned int i=0;i<srv.size();++i) {
1075 									ns.push_back(srv[i]);
1076 								}
1077 								nd["servers"] = ns;
1078 							}
1079 
1080 							network["dns"] = nd;
1081 						}
1082 					}
1083 
1084 				} catch ( ... ) {
1085 					responseBody = "{ \"message\": \"exception occurred while parsing body variables\" }";
1086 					responseContentType = "application/json";
1087 					return 400;
1088 				}
1089 
1090 				network["id"] = nwids;
1091 				network["nwid"] = nwids; // legacy
1092 
1093 				DB::cleanNetwork(network);
1094 				_db.save(network,true);
1095 
1096 				responseBody = OSUtils::jsonDump(network);
1097 				responseContentType = "application/json";
1098 				return 200;
1099 			} // else 404
1100 
1101 		} // else 404
1102 
1103 	}
1104 
1105 	return 404;
1106 }
1107 
handleControlPlaneHttpDELETE(const std::vector<std::string> & path,const std::map<std::string,std::string> & urlArgs,const std::map<std::string,std::string> & headers,const std::string & body,std::string & responseBody,std::string & responseContentType)1108 unsigned int EmbeddedNetworkController::handleControlPlaneHttpDELETE(
1109 	const std::vector<std::string> &path,
1110 	const std::map<std::string,std::string> &urlArgs,
1111 	const std::map<std::string,std::string> &headers,
1112 	const std::string &body,
1113 	std::string &responseBody,
1114 	std::string &responseContentType)
1115 {
1116 	if (path.empty())
1117 		return 404;
1118 
1119 	if (path[0] == "network") {
1120 		if ((path.size() >= 2)&&(path[1].length() == 16)) {
1121 			const uint64_t nwid = Utils::hexStrToU64(path[1].c_str());
1122 			if (path.size() >= 3) {
1123 				if ((path.size() == 4)&&(path[2] == "member")&&(path[3].length() == 10)) {
1124 					const uint64_t address = Utils::hexStrToU64(path[3].c_str());
1125 
1126 					json network,member;
1127 					_db.get(nwid,network,address,member);
1128 					_db.eraseMember(nwid, address);
1129 
1130 					{
1131 						std::lock_guard<std::mutex> l(_memberStatus_l);
1132 						_memberStatus.erase(_MemberStatusKey(nwid,address));
1133 					}
1134 
1135 					if (!member.size())
1136 						return 404;
1137 					responseBody = OSUtils::jsonDump(member);
1138 					responseContentType = "application/json";
1139 					return 200;
1140 				}
1141 			} else {
1142 				json network;
1143 				_db.get(nwid,network);
1144 				_db.eraseNetwork(nwid);
1145 
1146 				{
1147 					std::lock_guard<std::mutex> l(_memberStatus_l);
1148 					for(auto i=_memberStatus.begin();i!=_memberStatus.end();) {
1149 						if (i->first.networkId == nwid)
1150 							_memberStatus.erase(i++);
1151 						else ++i;
1152 					}
1153 				}
1154 
1155 				if (!network.size())
1156 					return 404;
1157 				responseBody = OSUtils::jsonDump(network);
1158 				responseContentType = "application/json";
1159 				return 200;
1160 			}
1161 		} // else 404
1162 
1163 	} // else 404
1164 
1165 	return 404;
1166 }
1167 
handleRemoteTrace(const ZT_RemoteTrace & rt)1168 void EmbeddedNetworkController::handleRemoteTrace(const ZT_RemoteTrace &rt)
1169 {
1170 	static volatile unsigned long idCounter = 0;
1171 	char id[128],tmp[128];
1172 	std::string k,v;
1173 
1174 	try {
1175 		// Convert Dictionary into JSON object
1176 		json d;
1177 		char *saveptr = (char *)0;
1178 		for(char *l=Utils::stok(rt.data,"\n",&saveptr);(l);l=Utils::stok((char *)0,"\n",&saveptr)) {
1179 			char *eq = strchr(l,'=');
1180 			if (eq > l) {
1181 				k.assign(l,(unsigned long)(eq - l));
1182 				v.clear();
1183 				++eq;
1184 				while (*eq) {
1185 					if (*eq == '\\') {
1186 						++eq;
1187 						if (*eq) {
1188 							switch(*eq) {
1189 								case 'r': v.push_back('\r'); break;
1190 								case 'n': v.push_back('\n'); break;
1191 								case '0': v.push_back((char)0); break;
1192 								case 'e': v.push_back('='); break;
1193 								default: v.push_back(*eq); break;
1194 							}
1195 							++eq;
1196 						}
1197 					} else {
1198 						v.push_back(*(eq++));
1199 					}
1200 				}
1201 				if ((k.length() > 0)&&(v.length() > 0))
1202 					d[k] = v;
1203 			}
1204 		}
1205 
1206 		const int64_t now = OSUtils::now();
1207 		OSUtils::ztsnprintf(id,sizeof(id),"%.10llx-%.16llx-%.10llx-%.4x",_signingId.address().toInt(),now,rt.origin,(unsigned int)(idCounter++ & 0xffff));
1208 		d["id"] = id;
1209 		d["objtype"] = "trace";
1210 		d["ts"] = now;
1211 		d["nodeId"] = Utils::hex10(rt.origin,tmp);
1212 		_db.save(d,true);
1213 	} catch ( ... ) {
1214 		// drop invalid trace messages if an error occurs
1215 	}
1216 }
1217 
onNetworkUpdate(const void * db,uint64_t networkId,const nlohmann::json & network)1218 void EmbeddedNetworkController::onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network)
1219 {
1220 	// Send an update to all members of the network that are online
1221 	const int64_t now = OSUtils::now();
1222 	std::lock_guard<std::mutex> l(_memberStatus_l);
1223 	for(auto i=_memberStatus.begin();i!=_memberStatus.end();++i) {
1224 		if ((i->first.networkId == networkId)&&(i->second.online(now))&&(i->second.lastRequestMetaData))
1225 			request(networkId,InetAddress(),0,i->second.identity,i->second.lastRequestMetaData);
1226 	}
1227 }
1228 
onNetworkMemberUpdate(const void * db,uint64_t networkId,uint64_t memberId,const nlohmann::json & member)1229 void EmbeddedNetworkController::onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member)
1230 {
1231 	// Push update to member if online
1232 	try {
1233 		std::lock_guard<std::mutex> l(_memberStatus_l);
1234 		_MemberStatus &ms = _memberStatus[_MemberStatusKey(networkId,memberId)];
1235 		if ((ms.online(OSUtils::now()))&&(ms.lastRequestMetaData))
1236 			request(networkId,InetAddress(),0,ms.identity,ms.lastRequestMetaData);
1237 	} catch ( ... ) {}
1238 }
1239 
onNetworkMemberDeauthorize(const void * db,uint64_t networkId,uint64_t memberId)1240 void EmbeddedNetworkController::onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId)
1241 {
1242 	const int64_t now = OSUtils::now();
1243 	Revocation rev((uint32_t)_node->prng(),networkId,0,now,ZT_REVOCATION_FLAG_FAST_PROPAGATE,Address(memberId),Revocation::CREDENTIAL_TYPE_COM);
1244 	rev.sign(_signingId);
1245 	{
1246 		std::lock_guard<std::mutex> l(_memberStatus_l);
1247 		for(auto i=_memberStatus.begin();i!=_memberStatus.end();++i) {
1248 			if ((i->first.networkId == networkId)&&(i->second.online(now)))
1249 				_node->ncSendRevocation(Address(i->first.nodeId),rev);
1250 		}
1251 	}
1252 }
1253 
_request(uint64_t nwid,const InetAddress & fromAddr,uint64_t requestPacketId,const Identity & identity,const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> & metaData)1254 void EmbeddedNetworkController::_request(
1255 	uint64_t nwid,
1256 	const InetAddress &fromAddr,
1257 	uint64_t requestPacketId,
1258 	const Identity &identity,
1259 	const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> &metaData)
1260 {
1261 	char nwids[24];
1262 	DB::NetworkSummaryInfo ns;
1263 	json network,member;
1264 
1265 	if (((!_signingId)||(!_signingId.hasPrivate()))||(_signingId.address().toInt() != (nwid >> 24))||(!_sender))
1266 		return;
1267 
1268 	const int64_t now = OSUtils::now();
1269 
1270 	if (requestPacketId) {
1271 		std::lock_guard<std::mutex> l(_memberStatus_l);
1272 		_MemberStatus &ms = _memberStatus[_MemberStatusKey(nwid,identity.address().toInt())];
1273 		if ((now - ms.lastRequestTime) <= ZT_NETCONF_MIN_REQUEST_PERIOD)
1274 			return;
1275 		ms.lastRequestTime = now;
1276 	}
1277 
1278 	_db.nodeIsOnline(nwid,identity.address().toInt(),fromAddr);
1279 
1280 	Utils::hex(nwid,nwids);
1281 	_db.get(nwid,network,identity.address().toInt(),member,ns);
1282 	if ((!network.is_object())||(network.empty())) {
1283 		_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_OBJECT_NOT_FOUND, nullptr, 0);
1284 		return;
1285 	}
1286 	const bool newMember = ((!member.is_object())||(member.empty()));
1287 	DB::initMember(member);
1288 
1289 	{
1290 		const std::string haveIdStr(OSUtils::jsonString(member["identity"],""));
1291 		if (haveIdStr.length() > 0) {
1292 			// If we already know this member's identity perform a full compare. This prevents
1293 			// a "collision" from being able to auth onto our network in place of an already
1294 			// known member.
1295 			try {
1296 				if (Identity(haveIdStr.c_str()) != identity) {
1297 					_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0);
1298 					return;
1299 				}
1300 			} catch ( ... ) {
1301 				_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0);
1302 				return;
1303 			}
1304 		} else {
1305 			// If we do not yet know this member's identity, learn it.
1306 			char idtmp[1024];
1307 			member["identity"] = identity.toString(false,idtmp);
1308 		}
1309 	}
1310 
1311 	// These are always the same, but make sure they are set
1312 	{
1313 		char tmpid[128];
1314 		const std::string addrs(identity.address().toString(tmpid));
1315 		member["id"] = addrs;
1316 		member["address"] = addrs;
1317 		member["nwid"] = nwids;
1318 	}
1319 
1320 	// Determine whether and how member is authorized
1321 	bool authorized = false;
1322 	bool autoAuthorized = false;
1323 	json autoAuthCredentialType,autoAuthCredential;
1324 	if (OSUtils::jsonBool(member["authorized"],false)) {
1325 		authorized = true;
1326 	} else if (!OSUtils::jsonBool(network["private"],true)) {
1327 		authorized = true;
1328 		autoAuthorized = true;
1329 		autoAuthCredentialType = "public";
1330 	} else {
1331 		char presentedAuth[512];
1332 		if (metaData.get(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_AUTH,presentedAuth,sizeof(presentedAuth)) > 0) {
1333 			presentedAuth[511] = (char)0; // sanity check
1334 			if ((strlen(presentedAuth) > 6)&&(!strncmp(presentedAuth,"token:",6))) {
1335 				const char *const presentedToken = presentedAuth + 6;
1336 				json authTokens(network["authTokens"]);
1337 				json &tokenExpires = authTokens[presentedToken];
1338 				if (tokenExpires.is_number()) {
1339 					if ((tokenExpires == 0)||(tokenExpires > now)) {
1340 						authorized = true;
1341 						autoAuthorized = true;
1342 						autoAuthCredentialType = "token";
1343 						autoAuthCredential = presentedToken;
1344 					}
1345 				}
1346 			}
1347 		}
1348 	}
1349 
1350 	// If we auto-authorized, update member record
1351 	if ((autoAuthorized)&&(authorized)) {
1352 		member["authorized"] = true;
1353 		member["lastAuthorizedTime"] = now;
1354 		member["lastAuthorizedCredentialType"] = autoAuthCredentialType;
1355 		member["lastAuthorizedCredential"] = autoAuthCredential;
1356 	}
1357 
1358 	// Should we check SSO Stuff?
1359 	// If network is configured with SSO, and the member is not marked exempt: yes
1360 	// Otherwise no, we use standard auth logic.
1361 	bool networkSSOEnabled = OSUtils::jsonBool(network["ssoEnabled"], false);
1362 	bool memberSSOExempt = OSUtils::jsonBool(member["ssoExempt"], false);
1363 	std::string authenticationURL;
1364 	if (networkSSOEnabled && !memberSSOExempt) {
1365 		authenticationURL = _db.getSSOAuthURL(member, _ssoRedirectURL);
1366 		std::string memberId = member["id"];
1367 		//fprintf(stderr, "ssoEnabled && !ssoExempt %s-%s\n", nwids, memberId.c_str());
1368 		uint64_t authenticationExpiryTime = (int64_t)OSUtils::jsonInt(member["authenticationExpiryTime"], 0);
1369 		//fprintf(stderr, "authExpiryTime: %lld\n", authenticationExpiryTime);
1370 		if (authenticationExpiryTime < now) {
1371 			if (!authenticationURL.empty()) {
1372 				_db.networkMemberSSOHasExpired(nwid, now);
1373 				onNetworkMemberDeauthorize(&_db, nwid, identity.address().toInt());
1374 
1375 				Dictionary<3072> authInfo;
1376 				authInfo.add("aU", authenticationURL.c_str());
1377 				//fprintf(stderr, "sending auth URL: %s\n", authenticationURL.c_str());
1378 
1379 				DB::cleanMember(member);
1380 				_db.save(member,true);
1381 
1382 				_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED, authInfo.data(), authInfo.sizeBytes());
1383 				return;
1384 			}
1385 		} else if (authorized) {
1386 			_db.memberWillExpire(authenticationExpiryTime, nwid, identity.address().toInt());
1387 		}
1388 	}
1389 
1390 	if (authorized) {
1391 		// Update version info and meta-data if authorized and if this is a genuine request
1392 		if (requestPacketId) {
1393 			const uint64_t vMajor = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,0);
1394 			const uint64_t vMinor = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,0);
1395 			const uint64_t vRev = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,0);
1396 			const uint64_t vProto = metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,0);
1397 
1398 			member["vMajor"] = vMajor;
1399 			member["vMinor"] = vMinor;
1400 			member["vRev"] = vRev;
1401 			member["vProto"] = vProto;
1402 
1403 			{
1404 				std::lock_guard<std::mutex> l(_memberStatus_l);
1405 				_MemberStatus &ms = _memberStatus[_MemberStatusKey(nwid,identity.address().toInt())];
1406 
1407 				ms.vMajor = (int)vMajor;
1408 				ms.vMinor = (int)vMinor;
1409 				ms.vRev = (int)vRev;
1410 				ms.vProto = (int)vProto;
1411 				ms.lastRequestMetaData = metaData;
1412 				ms.identity = identity;
1413 			}
1414 		}
1415 	} else {
1416 
1417 		// If they are not authorized, STOP!
1418 		DB::cleanMember(member);
1419 		_db.save(member,true);
1420 		_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0);
1421 		return;
1422 	}
1423 
1424 	// -------------------------------------------------------------------------
1425 	// If we made it this far, they are authorized (and authenticated).
1426 	// -------------------------------------------------------------------------
1427 
1428 	int64_t credentialtmd = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA;
1429 	if (now > ns.mostRecentDeauthTime) {
1430 		// If we recently de-authorized a member, shrink credential TTL/max delta to
1431 		// be below the threshold required to exclude it. Cap this to a min/max to
1432 		// prevent jitter or absurdly large values.
1433 		const uint64_t deauthWindow = now - ns.mostRecentDeauthTime;
1434 		if (deauthWindow < ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MIN_MAX_DELTA) {
1435 			credentialtmd = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MIN_MAX_DELTA;
1436 		} else if (deauthWindow < (ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA + 5000ULL)) {
1437 			credentialtmd = deauthWindow - 5000ULL;
1438 		}
1439 	}
1440 
1441 	std::unique_ptr<NetworkConfig> nc(new NetworkConfig());
1442 
1443 	nc->networkId = nwid;
1444 	nc->type = OSUtils::jsonBool(network["private"],true) ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC;
1445 	nc->timestamp = now;
1446 	nc->credentialTimeMaxDelta = credentialtmd;
1447 	nc->revision = OSUtils::jsonInt(network["revision"],0ULL);
1448 	nc->issuedTo = identity.address();
1449 	if (OSUtils::jsonBool(network["enableBroadcast"],true)) nc->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST;
1450 	Utils::scopy(nc->name,sizeof(nc->name),OSUtils::jsonString(network["name"],"").c_str());
1451 	nc->mtu = std::max(std::min((unsigned int)OSUtils::jsonInt(network["mtu"],ZT_DEFAULT_MTU),(unsigned int)ZT_MAX_MTU),(unsigned int)ZT_MIN_MTU);
1452 	nc->multicastLimit = (unsigned int)OSUtils::jsonInt(network["multicastLimit"],32ULL);
1453 
1454 	nc->ssoEnabled = OSUtils::jsonBool(network["ssoEnabled"], false);
1455 	nc->authenticationExpiryTime = OSUtils::jsonInt(member["authenticationExpiryTime"], 0LL);
1456 	if (!authenticationURL.empty())
1457 		Utils::scopy(nc->authenticationURL, sizeof(nc->authenticationURL), authenticationURL.c_str());
1458 
1459 	std::string rtt(OSUtils::jsonString(member["remoteTraceTarget"],""));
1460 	if (rtt.length() == 10) {
1461 		nc->remoteTraceTarget = Address(Utils::hexStrToU64(rtt.c_str()));
1462 		nc->remoteTraceLevel = (Trace::Level)OSUtils::jsonInt(member["remoteTraceLevel"],0ULL);
1463 	} else {
1464 		rtt = OSUtils::jsonString(network["remoteTraceTarget"],"");
1465 		if (rtt.length() == 10) {
1466 			nc->remoteTraceTarget = Address(Utils::hexStrToU64(rtt.c_str()));
1467 		} else {
1468 			nc->remoteTraceTarget.zero();
1469 		}
1470 		nc->remoteTraceLevel = (Trace::Level)OSUtils::jsonInt(network["remoteTraceLevel"],0ULL);
1471 	}
1472 
1473 	for(std::vector<Address>::const_iterator ab(ns.activeBridges.begin());ab!=ns.activeBridges.end();++ab)
1474 		nc->addSpecialist(*ab,ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE);
1475 
1476 	json &v4AssignMode = network["v4AssignMode"];
1477 	json &v6AssignMode = network["v6AssignMode"];
1478 	json &ipAssignmentPools = network["ipAssignmentPools"];
1479 	json &routes = network["routes"];
1480 	json &rules = network["rules"];
1481 	json &capabilities = network["capabilities"];
1482 	json &tags = network["tags"];
1483 	json &memberCapabilities = member["capabilities"];
1484 	json &memberTags = member["tags"];
1485 	json &dns = network["dns"];
1486 
1487 	//fprintf(stderr, "IP Assignment Pools for Network %s: %s\n", nwids, OSUtils::jsonDump(ipAssignmentPools, 2).c_str());
1488 
1489 	if (metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,0) <= 0) {
1490 		// Old versions with no rules engine support get an allow everything rule.
1491 		// Since rules are enforced bidirectionally, newer versions *will* still
1492 		// enforce rules on the inbound side.
1493 		nc->ruleCount = 1;
1494 		nc->rules[0].t = ZT_NETWORK_RULE_ACTION_ACCEPT;
1495 	} else {
1496 		if (rules.is_array()) {
1497 			for(unsigned long i=0;i<rules.size();++i) {
1498 				if (nc->ruleCount >= ZT_MAX_NETWORK_RULES)
1499 					break;
1500 				if (_parseRule(rules[i],nc->rules[nc->ruleCount]))
1501 					++nc->ruleCount;
1502 			}
1503 		}
1504 
1505 		std::map< uint64_t,json * > capsById;
1506 		if (!memberCapabilities.is_array())
1507 			memberCapabilities = json::array();
1508 		if (capabilities.is_array()) {
1509 			for(unsigned long i=0;i<capabilities.size();++i) {
1510 				json &cap = capabilities[i];
1511 				if (cap.is_object()) {
1512 					const uint64_t id = OSUtils::jsonInt(cap["id"],0ULL) & 0xffffffffULL;
1513 					capsById[id] = &cap;
1514 					if ((newMember)&&(OSUtils::jsonBool(cap["default"],false))) {
1515 						bool have = false;
1516 						for(unsigned long i=0;i<memberCapabilities.size();++i) {
1517 							if (id == (OSUtils::jsonInt(memberCapabilities[i],0ULL) & 0xffffffffULL)) {
1518 								have = true;
1519 								break;
1520 							}
1521 						}
1522 						if (!have)
1523 							memberCapabilities.push_back(id);
1524 					}
1525 				}
1526 			}
1527 		}
1528 		for(unsigned long i=0;i<memberCapabilities.size();++i) {
1529 			const uint64_t capId = OSUtils::jsonInt(memberCapabilities[i],0ULL) & 0xffffffffULL;
1530 			std::map< uint64_t,json * >::const_iterator ctmp = capsById.find(capId);
1531 			if (ctmp != capsById.end()) {
1532 				json *cap = ctmp->second;
1533 				if ((cap)&&(cap->is_object())&&(!cap->empty())) {
1534 					ZT_VirtualNetworkRule capr[ZT_MAX_CAPABILITY_RULES];
1535 					unsigned int caprc = 0;
1536 					json &caprj = (*cap)["rules"];
1537 					if ((caprj.is_array())&&(!caprj.empty())) {
1538 						for(unsigned long j=0;j<caprj.size();++j) {
1539 							if (caprc >= ZT_MAX_CAPABILITY_RULES)
1540 								break;
1541 							if (_parseRule(caprj[j],capr[caprc]))
1542 								++caprc;
1543 						}
1544 					}
1545 					nc->capabilities[nc->capabilityCount] = Capability((uint32_t)capId,nwid,now,1,capr,caprc);
1546 					if (nc->capabilities[nc->capabilityCount].sign(_signingId,identity.address()))
1547 						++nc->capabilityCount;
1548 					if (nc->capabilityCount >= ZT_MAX_NETWORK_CAPABILITIES)
1549 						break;
1550 				}
1551 			}
1552 		}
1553 
1554 		std::map< uint32_t,uint32_t > memberTagsById;
1555 		if (memberTags.is_array()) {
1556 			for(unsigned long i=0;i<memberTags.size();++i) {
1557 				json &t = memberTags[i];
1558 				if ((t.is_array())&&(t.size() == 2))
1559 					memberTagsById[(uint32_t)(OSUtils::jsonInt(t[0],0ULL) & 0xffffffffULL)] = (uint32_t)(OSUtils::jsonInt(t[1],0ULL) & 0xffffffffULL);
1560 			}
1561 		}
1562 		if (tags.is_array()) { // check network tags array for defaults that are not present in member tags
1563 			for(unsigned long i=0;i<tags.size();++i) {
1564 				json &t = tags[i];
1565 				if (t.is_object()) {
1566 					const uint32_t id = (uint32_t)(OSUtils::jsonInt(t["id"],0) & 0xffffffffULL);
1567 					json &dfl = t["default"];
1568 					if ((dfl.is_number())&&(memberTagsById.find(id) == memberTagsById.end())) {
1569 						memberTagsById[id] = (uint32_t)(OSUtils::jsonInt(dfl,0) & 0xffffffffULL);
1570 						json mt = json::array();
1571 						mt.push_back(id);
1572 						mt.push_back(dfl);
1573 						memberTags.push_back(mt); // add default to member tags if not present
1574 					}
1575 				}
1576 			}
1577 		}
1578 		for(std::map< uint32_t,uint32_t >::const_iterator t(memberTagsById.begin());t!=memberTagsById.end();++t) {
1579 			if (nc->tagCount >= ZT_MAX_NETWORK_TAGS)
1580 				break;
1581 			nc->tags[nc->tagCount] = Tag(nwid,now,identity.address(),t->first,t->second);
1582 			if (nc->tags[nc->tagCount].sign(_signingId))
1583 				++nc->tagCount;
1584 		}
1585 	}
1586 
1587 	if (routes.is_array()) {
1588 		for(unsigned long i=0;i<routes.size();++i) {
1589 			if (nc->routeCount >= ZT_MAX_NETWORK_ROUTES)
1590 				break;
1591 			json &route = routes[i];
1592 			json &target = route["target"];
1593 			json &via = route["via"];
1594 			if (target.is_string()) {
1595 				const InetAddress t(target.get<std::string>().c_str());
1596 				InetAddress v;
1597 				if (via.is_string()) v.fromString(via.get<std::string>().c_str());
1598 				if ((t.ss_family == AF_INET)||(t.ss_family == AF_INET6)) {
1599 					ZT_VirtualNetworkRoute *r = &(nc->routes[nc->routeCount]);
1600 					*(reinterpret_cast<InetAddress *>(&(r->target))) = t;
1601 					if (v.ss_family == t.ss_family)
1602 						*(reinterpret_cast<InetAddress *>(&(r->via))) = v;
1603 					++nc->routeCount;
1604 				}
1605 			}
1606 		}
1607 	}
1608 
1609 	const bool noAutoAssignIps = OSUtils::jsonBool(member["noAutoAssignIps"],false);
1610 
1611 	if ((v6AssignMode.is_object())&&(!noAutoAssignIps)) {
1612 		if ((OSUtils::jsonBool(v6AssignMode["rfc4193"],false))&&(nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) {
1613 			nc->staticIps[nc->staticIpCount++] = InetAddress::makeIpv6rfc4193(nwid,identity.address().toInt());
1614 			nc->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION;
1615 		}
1616 		if ((OSUtils::jsonBool(v6AssignMode["6plane"],false))&&(nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) {
1617 			nc->staticIps[nc->staticIpCount++] = InetAddress::makeIpv66plane(nwid,identity.address().toInt());
1618 			nc->flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION;
1619 		}
1620 	}
1621 
1622 	bool haveManagedIpv4AutoAssignment = false;
1623 	bool haveManagedIpv6AutoAssignment = false; // "special" NDP-emulated address types do not count
1624 	json ipAssignments = member["ipAssignments"]; // we want to make a copy
1625 	if (ipAssignments.is_array()) {
1626 		for(unsigned long i=0;i<ipAssignments.size();++i) {
1627 			if (ipAssignments[i].is_string()) {
1628 				const std::string ips = ipAssignments[i];
1629 				InetAddress ip(ips.c_str());
1630 
1631 				int routedNetmaskBits = -1;
1632 				for(unsigned int rk=0;rk<nc->routeCount;++rk) {
1633 					if (reinterpret_cast<const InetAddress *>(&(nc->routes[rk].target))->containsAddress(ip)) {
1634 						const int nb = (int)(reinterpret_cast<const InetAddress *>(&(nc->routes[rk].target))->netmaskBits());
1635 						if (nb > routedNetmaskBits)
1636 							routedNetmaskBits = nb;
1637 					}
1638 				}
1639 
1640 				if (routedNetmaskBits >= 0) {
1641 					if (nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) {
1642 						ip.setPort(routedNetmaskBits);
1643 						nc->staticIps[nc->staticIpCount++] = ip;
1644 					}
1645 					if (ip.ss_family == AF_INET)
1646 						haveManagedIpv4AutoAssignment = true;
1647 					else if (ip.ss_family == AF_INET6)
1648 						haveManagedIpv6AutoAssignment = true;
1649 				}
1650 			}
1651 		}
1652 	} else {
1653 		ipAssignments = json::array();
1654 	}
1655 
1656 	if ( (ipAssignmentPools.is_array()) && ((v6AssignMode.is_object())&&(OSUtils::jsonBool(v6AssignMode["zt"],false))) && (!haveManagedIpv6AutoAssignment) && (!noAutoAssignIps) ) {
1657 		for(unsigned long p=0;((p<ipAssignmentPools.size())&&(!haveManagedIpv6AutoAssignment));++p) {
1658 			json &pool = ipAssignmentPools[p];
1659 			if (pool.is_object()) {
1660 				InetAddress ipRangeStart(OSUtils::jsonString(pool["ipRangeStart"],"").c_str());
1661 				InetAddress ipRangeEnd(OSUtils::jsonString(pool["ipRangeEnd"],"").c_str());
1662 				if ( (ipRangeStart.ss_family == AF_INET6) && (ipRangeEnd.ss_family == AF_INET6) ) {
1663 					uint64_t s[2],e[2],x[2],xx[2];
1664 					memcpy(s,ipRangeStart.rawIpData(),16);
1665 					memcpy(e,ipRangeEnd.rawIpData(),16);
1666 					s[0] = Utils::ntoh(s[0]);
1667 					s[1] = Utils::ntoh(s[1]);
1668 					e[0] = Utils::ntoh(e[0]);
1669 					e[1] = Utils::ntoh(e[1]);
1670 					x[0] = s[0];
1671 					x[1] = s[1];
1672 
1673 					for(unsigned int trialCount=0;trialCount<1000;++trialCount) {
1674 						if ((trialCount == 0)&&(e[1] > s[1])&&((e[1] - s[1]) >= 0xffffffffffULL)) {
1675 							// First see if we can just cram a ZeroTier ID into the higher 64 bits. If so do that.
1676 							xx[0] = Utils::hton(x[0]);
1677 							xx[1] = Utils::hton(x[1] + identity.address().toInt());
1678 						} else {
1679 							// Otherwise pick random addresses -- this technically doesn't explore the whole range if the lower 64 bit range is >= 1 but that won't matter since that would be huge anyway
1680 							Utils::getSecureRandom((void *)xx,16);
1681 							if ((e[0] > s[0]))
1682 								xx[0] %= (e[0] - s[0]);
1683 							else xx[0] = 0;
1684 							if ((e[1] > s[1]))
1685 								xx[1] %= (e[1] - s[1]);
1686 							else xx[1] = 0;
1687 							xx[0] = Utils::hton(x[0] + xx[0]);
1688 							xx[1] = Utils::hton(x[1] + xx[1]);
1689 						}
1690 
1691 						InetAddress ip6((const void *)xx,16,0);
1692 
1693 						// Check if this IP is within a local-to-Ethernet routed network
1694 						int routedNetmaskBits = 0;
1695 						for(unsigned int rk=0;rk<nc->routeCount;++rk) {
1696 							if ( (!nc->routes[rk].via.ss_family) && (nc->routes[rk].target.ss_family == AF_INET6) && (reinterpret_cast<const InetAddress *>(&(nc->routes[rk].target))->containsAddress(ip6)) )
1697 								routedNetmaskBits = reinterpret_cast<const InetAddress *>(&(nc->routes[rk].target))->netmaskBits();
1698 						}
1699 
1700 						// If it's routed, then try to claim and assign it and if successful end loop
1701 						if ( (routedNetmaskBits > 0) && (!std::binary_search(ns.allocatedIps.begin(),ns.allocatedIps.end(),ip6)) ) {
1702 							char tmpip[64];
1703 							const std::string ipStr(ip6.toIpString(tmpip));
1704 							if (std::find(ipAssignments.begin(),ipAssignments.end(),ipStr) == ipAssignments.end()) {
1705 								ipAssignments.push_back(ipStr);
1706 								member["ipAssignments"] = ipAssignments;
1707 								ip6.setPort((unsigned int)routedNetmaskBits);
1708 								if (nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)
1709 									nc->staticIps[nc->staticIpCount++] = ip6;
1710 								haveManagedIpv6AutoAssignment = true;
1711 								break;
1712 							}
1713 						}
1714 					}
1715 				}
1716 			}
1717 		}
1718 	}
1719 
1720 	if ( (ipAssignmentPools.is_array()) && ((v4AssignMode.is_object())&&(OSUtils::jsonBool(v4AssignMode["zt"],false))) && (!haveManagedIpv4AutoAssignment) && (!noAutoAssignIps) ) {
1721 		for(unsigned long p=0;((p<ipAssignmentPools.size())&&(!haveManagedIpv4AutoAssignment));++p) {
1722 			json &pool = ipAssignmentPools[p];
1723 			if (pool.is_object()) {
1724 				InetAddress ipRangeStartIA(OSUtils::jsonString(pool["ipRangeStart"],"").c_str());
1725 				InetAddress ipRangeEndIA(OSUtils::jsonString(pool["ipRangeEnd"],"").c_str());
1726 				if ( (ipRangeStartIA.ss_family == AF_INET) && (ipRangeEndIA.ss_family == AF_INET) ) {
1727 					uint32_t ipRangeStart = Utils::ntoh((uint32_t)(reinterpret_cast<struct sockaddr_in *>(&ipRangeStartIA)->sin_addr.s_addr));
1728 					uint32_t ipRangeEnd = Utils::ntoh((uint32_t)(reinterpret_cast<struct sockaddr_in *>(&ipRangeEndIA)->sin_addr.s_addr));
1729 
1730 					if ((ipRangeEnd < ipRangeStart)||(ipRangeStart == 0))
1731 						continue;
1732 					uint32_t ipRangeLen = ipRangeEnd - ipRangeStart;
1733 
1734 					// Start with the LSB of the member's address
1735 					uint32_t ipTrialCounter = (uint32_t)(identity.address().toInt() & 0xffffffff);
1736 
1737 					for(uint32_t k=ipRangeStart,trialCount=0;((k<=ipRangeEnd)&&(trialCount < 1000));++k,++trialCount) {
1738 						uint32_t ip = (ipRangeLen > 0) ? (ipRangeStart + (ipTrialCounter % ipRangeLen)) : ipRangeStart;
1739 						++ipTrialCounter;
1740 						if ((ip & 0x000000ff) == 0x000000ff) {
1741 							continue; // don't allow addresses that end in .255
1742 						}
1743 
1744 						// Check if this IP is within a local-to-Ethernet routed network
1745 						int routedNetmaskBits = -1;
1746 						for(unsigned int rk=0;rk<nc->routeCount;++rk) {
1747 							if (nc->routes[rk].target.ss_family == AF_INET) {
1748 								uint32_t targetIp = Utils::ntoh((uint32_t)(reinterpret_cast<const struct sockaddr_in *>(&(nc->routes[rk].target))->sin_addr.s_addr));
1749 								int targetBits = Utils::ntoh((uint16_t)(reinterpret_cast<const struct sockaddr_in *>(&(nc->routes[rk].target))->sin_port));
1750 								if ((ip & (0xffffffff << (32 - targetBits))) == targetIp) {
1751 									routedNetmaskBits = targetBits;
1752 									break;
1753 								}
1754 							}
1755 						}
1756 
1757 						// If it's routed, then try to claim and assign it and if successful end loop
1758 						const InetAddress ip4(Utils::hton(ip),0);
1759 						if ( (routedNetmaskBits > 0) && (!std::binary_search(ns.allocatedIps.begin(),ns.allocatedIps.end(),ip4)) ) {
1760 							char tmpip[64];
1761 							const std::string ipStr(ip4.toIpString(tmpip));
1762 							if (std::find(ipAssignments.begin(),ipAssignments.end(),ipStr) == ipAssignments.end()) {
1763 								ipAssignments.push_back(ipStr);
1764 								member["ipAssignments"] = ipAssignments;
1765 								if (nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) {
1766 									struct sockaddr_in *const v4ip = reinterpret_cast<struct sockaddr_in *>(&(nc->staticIps[nc->staticIpCount++]));
1767 									v4ip->sin_family = AF_INET;
1768 									v4ip->sin_port = Utils::hton((uint16_t)routedNetmaskBits);
1769 									v4ip->sin_addr.s_addr = Utils::hton(ip);
1770 								}
1771 								haveManagedIpv4AutoAssignment = true;
1772 								break;
1773 							}
1774 						}
1775 					}
1776 				}
1777 			}
1778 		}
1779 	}
1780 
1781 	if(dns.is_object()) {
1782 		std::string domain = OSUtils::jsonString(dns["domain"],"");
1783 		memcpy(nc->dns.domain, domain.c_str(), domain.size());
1784 		json &addrArray = dns["servers"];
1785 		if (addrArray.is_array()) {
1786 			for(unsigned int j = 0; j < addrArray.size() && j < ZT_MAX_DNS_SERVERS; ++j) {
1787 				json &addr = addrArray[j];
1788 				nc->dns.server_addr[j] = InetAddress(OSUtils::jsonString(addr,"").c_str());
1789 			}
1790 		}
1791 	} else {
1792 		dns = json::object();
1793 	}
1794 
1795 	// Issue a certificate of ownership for all static IPs
1796 	if (nc->staticIpCount) {
1797 		nc->certificatesOfOwnership[0] = CertificateOfOwnership(nwid,now,identity.address(),1);
1798 		for(unsigned int i=0;i<nc->staticIpCount;++i)
1799 			nc->certificatesOfOwnership[0].addThing(nc->staticIps[i]);
1800 		nc->certificatesOfOwnership[0].sign(_signingId);
1801 		nc->certificateOfOwnershipCount = 1;
1802 	}
1803 
1804 	CertificateOfMembership com(now,credentialtmd,nwid,identity);
1805 	if (com.sign(_signingId)) {
1806 		nc->com = com;
1807 	} else {
1808 		_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_INTERNAL_SERVER_ERROR, nullptr, 0);
1809 		return;
1810 	}
1811 
1812 	DB::cleanMember(member);
1813 	_db.save(member,true);
1814 	_sender->ncSendConfig(nwid,requestPacketId,identity.address(),*(nc.get()),metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,0) < 6);
1815 }
1816 
_startThreads()1817 void EmbeddedNetworkController::_startThreads()
1818 {
1819 	std::lock_guard<std::mutex> l(_threads_l);
1820 	if (!_threads.empty())
1821 		return;
1822 	const long hwc = std::max((long)std::thread::hardware_concurrency(),(long)1);
1823 	for(long t=0;t<hwc;++t) {
1824 		_threads.emplace_back([this]() {
1825 			for(;;) {
1826 				_RQEntry *qe = (_RQEntry *)0;
1827 				auto timedWaitResult = _queue.get(qe, 1000);
1828 				if (timedWaitResult == BlockingQueue<_RQEntry *>::STOP) {
1829 					break;
1830 				} else if (timedWaitResult == BlockingQueue<_RQEntry *>::OK) {
1831 					if (qe) {
1832 						try {
1833 							_request(qe->nwid,qe->fromAddr,qe->requestPacketId,qe->identity,qe->metaData);
1834 						} catch (std::exception &e) {
1835 							fprintf(stderr,"ERROR: exception in controller request handling thread: %s" ZT_EOL_S,e.what());
1836 						} catch ( ... ) {
1837 							fprintf(stderr,"ERROR: exception in controller request handling thread: unknown exception" ZT_EOL_S);
1838 						}
1839 						delete qe;
1840 					}
1841 				}
1842 
1843 				std::set< std::pair<uint64_t, uint64_t> > soon;
1844 				std::set< std::pair<uint64_t, uint64_t> > expired;
1845 				_db.membersExpiring(soon, expired);
1846 
1847 				for(auto s=soon.begin();s!=soon.end();++s) {
1848 					Identity identity;
1849 					Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> lastMetaData;
1850 					{
1851 						std::unique_lock<std::mutex> ll(_memberStatus_l);
1852 						auto ms = _memberStatus.find(_MemberStatusKey(s->first, s->second));
1853 						if (ms != _memberStatus.end()) {
1854 							lastMetaData = ms->second.lastRequestMetaData;
1855 							identity = ms->second.identity;
1856 						}
1857 					}
1858 					if (identity) {
1859 						request(s->first,InetAddress(),0,identity,lastMetaData);
1860 					}
1861 				}
1862 
1863 				for(auto e=expired.begin();e!=expired.end();++e) {
1864 					onNetworkMemberDeauthorize(nullptr, e->first, e->second);
1865 				}
1866 			}
1867 		});
1868 	}
1869 }
1870 
1871 } // namespace ZeroTier
1872