1 // SoftEther VPN Source Code - Developer Edition Master Branch
2 // Cedar Communication Module
3 
4 
5 // Admin.c
6 // RPC Module for Management
7 
8 #include "Admin.h"
9 
10 #include "Account.h"
11 #include "AzureClient.h"
12 #include "BridgeUnix.h"
13 #include "BridgeWin32.h"
14 #include "Connection.h"
15 #include "DDNS.h"
16 #include "Layer3.h"
17 #include "Link.h"
18 #include "Listener.h"
19 #include "Nat.h"
20 #include "Remote.h"
21 #include "Proto.h"
22 #include "Proto_IPsec.h"
23 #include "Proto_OpenVPN.h"
24 #include "Proto_PPP.h"
25 #include "Protocol.h"
26 #include "Sam.h"
27 #include "SecureNAT.h"
28 #include "Server.h"
29 #include "Session.h"
30 #include "Virtual.h"
31 #include "Wpc.h"
32 
33 #include "Mayaqua/Cfg.h"
34 #include "Mayaqua/FileIO.h"
35 #include "Mayaqua/Internat.h"
36 #include "Mayaqua/HTTP.h"
37 #include "Mayaqua/Memory.h"
38 #include "Mayaqua/Microsoft.h"
39 #include "Mayaqua/Object.h"
40 #include "Mayaqua/Pack.h"
41 #include "Mayaqua/Str.h"
42 #include "Mayaqua/Table.h"
43 #include "Mayaqua/Tick64.h"
44 
45 // Macro for RPC function declaration
46 #define	DECLARE_RPC_EX(rpc_name, data_type, function, in_rpc, out_rpc, free_rpc)		\
47 	else if (StrCmpi(name, rpc_name) == 0)								\
48 	{																	\
49 		data_type *t;													\
50 		t = ZeroMalloc(sizeof(data_type));								\
51 		in_rpc(t, p);													\
52 		err = function(a, t);											\
53 		if (err == ERR_NO_ERROR)										\
54 		{																\
55 			out_rpc(ret, t);											\
56 		}																\
57 		free_rpc(t);													\
58 		Free(t);														\
59 		ok = true;														\
60 	}
61 #define	DECLARE_RPC(rpc_name, data_type, function, in_rpc, out_rpc)		\
62 	else if (StrCmpi(name, rpc_name) == 0)								\
63 	{																	\
64 		data_type *t;													\
65 		t = ZeroMalloc(sizeof(data_type));								\
66 		in_rpc(t, p);													\
67 		err = function(a, t);											\
68 		if (err == ERR_NO_ERROR)										\
69 		{																\
70 			out_rpc(ret, t);											\
71 		}																\
72 		Free(t);														\
73 		ok = true;														\
74 	}
75 #define	DECLARE_SC_EX(rpc_name, data_type, function, in_rpc, out_rpc, free_rpc)	\
76 	UINT function(RPC *r, data_type *t)									\
77 	{																	\
78 		PACK *p, *ret;													\
79 		UINT err;														\
80 		if (r == NULL || t == NULL)										\
81 		{																\
82 			return ERR_INTERNAL_ERROR;									\
83 		}																\
84 		p = NewPack();													\
85 		out_rpc(p, t);													\
86 		free_rpc(t);													\
87 		Zero(t, sizeof(data_type));										\
88 		ret = AdminCall(r, rpc_name, p);								\
89 		err = GetErrorFromPack(ret);									\
90 		if (err == ERR_NO_ERROR)										\
91 		{																\
92 			in_rpc(t, ret);												\
93 		}																\
94 		FreePack(ret);													\
95 		return err;														\
96 	}
97 #define	DECLARE_SC(rpc_name, data_type, function, in_rpc, out_rpc)		\
98 	UINT function(RPC *r, data_type *t)									\
99 	{																	\
100 		PACK *p, *ret;													\
101 		UINT err;														\
102 		if (r == NULL || t == NULL)										\
103 		{																\
104 			return ERR_INTERNAL_ERROR;									\
105 		}																\
106 		p = NewPack();													\
107 		out_rpc(p, t);													\
108 		ret = AdminCall(r, rpc_name, p);								\
109 		err = GetErrorFromPack(ret);									\
110 		if (err == ERR_NO_ERROR)										\
111 		{																\
112 			in_rpc(t, ret);												\
113 		}																\
114 		FreePack(ret);													\
115 		return err;														\
116 	}
117 #define	CHECK_RIGHT														\
118 	if (a->ServerAdmin == false && (StrCmpi(a->HubName, t->HubName) != 0))	\
119 		return ERR_NOT_ENOUGH_RIGHT;	\
120 	if (IsEmptyStr(t->HubName))			\
121 		return ERR_INVALID_PARAMETER;
122 #define	SERVER_ADMIN_ONLY												\
123 	if (a->ServerAdmin == false)										\
124 		return ERR_NOT_ENOUGH_RIGHT;
125 #define	NO_SUPPORT_FOR_BRIDGE											\
126 	if (a->Server->Cedar->Bridge)										\
127 		return ERR_NOT_SUPPORTED;
128 
129 // Get server Caps (Guessing from the build number if failed to get Caps)
ScGetCapsEx(RPC * rpc)130 CAPSLIST *ScGetCapsEx(RPC *rpc)
131 {
132 	RPC_SERVER_INFO info;
133 	CAPSLIST *t;
134 	bool is_bridge = false;
135 	// Validate arguments
136 	if (rpc == NULL)
137 	{
138 		return NULL;
139 	}
140 
141 	Zero(&info, sizeof(info));
142 	ScGetServerInfo(rpc, &info);
143 
144 	t = ZeroMalloc(sizeof(CAPSLIST));
145 
146 	// Try to get Caps by RPC
147 	if (ScGetCaps(rpc, t) != ERR_NO_ERROR)
148 	{
149 		UINT build;
150 
151 		Free(t);
152 		t = NewCapsList();
153 
154 		// Since acquisition of Caps went wrong, get build number
155 		build = info.ServerBuildInt;
156 
157 		is_bridge = (SearchStrEx(info.ServerProductName, "bridge", 0, false) == INFINITE) ? false : true;
158 
159 		AddCapsInt(t, "i_max_packet_size", 1514);
160 
161 		if (is_bridge == false)
162 		{
163 			AddCapsInt(t, "i_max_hubs", 4096);
164 			AddCapsInt(t, "i_max_sessions", 4096);
165 
166 			if (info.ServerType != SERVER_TYPE_FARM_MEMBER)
167 			{
168 				AddCapsInt(t, "i_max_users_per_hub", 10000);
169 				AddCapsInt(t, "i_max_groups_per_hub", 10000);
170 				AddCapsInt(t, "i_max_access_lists", 4096);
171 			}
172 			else
173 			{
174 				AddCapsInt(t, "i_max_users_per_hub", 0);
175 				AddCapsInt(t, "i_max_groups_per_hub", 0);
176 				AddCapsInt(t, "i_max_access_lists", 0);
177 			}
178 		}
179 		else
180 		{
181 			AddCapsInt(t, "i_max_hubs", 0);
182 			AddCapsInt(t, "i_max_sessions", 0);
183 			AddCapsInt(t, "i_max_users_per_hub", 0);
184 			AddCapsInt(t, "i_max_groups_per_hub", 0);
185 			AddCapsInt(t, "i_max_access_lists", 0);
186 		}
187 
188 		AddCapsInt(t, "i_max_mac_tables", 10000);
189 		AddCapsInt(t, "i_max_ip_tables", 10000);
190 
191 		if (info.ServerType == SERVER_TYPE_STANDALONE)
192 		{
193 			AddCapsBool(t, "b_support_securenat", (build >= 3600) ? true : false);
194 			AddCapsInt(t, "i_max_secnat_tables", 4096);
195 		}
196 		else
197 		{
198 			AddCapsBool(t, "b_support_securenat", false);
199 			AddCapsInt(t, "i_max_secnat_tables", 0);
200 		}
201 
202 		if (is_bridge)
203 		{
204 			AddCapsBool(t, "b_bridge", true);
205 		}
206 		else if (info.ServerType == SERVER_TYPE_STANDALONE)
207 		{
208 			AddCapsBool(t, "b_standalone", true);
209 		}
210 		else if (info.ServerType == SERVER_TYPE_FARM_CONTROLLER)
211 		{
212 			AddCapsBool(t, "b_cluster_controller", true);
213 		}
214 		else
215 		{
216 			AddCapsBool(t, "b_cluster_member", true);
217 		}
218 
219 		AddCapsBool(t, "b_support_config_hub", info.ServerType != SERVER_TYPE_FARM_MEMBER &&
220 			is_bridge == false);
221 
222 		AddCapsBool(t, "b_vpn_client_connect", is_bridge == false ? true : false);
223 
224 		AddCapsBool(t, "b_support_radius", info.ServerType != SERVER_TYPE_FARM_MEMBER &&
225 			is_bridge == false);
226 
227 		if (build >= 3600)
228 		{
229 			RPC_BRIDGE_SUPPORT b;
230 			Zero(&b, sizeof(b));
231 			if (ScGetBridgeSupport(rpc, &b) == ERR_NO_ERROR)
232 			{
233 				AddCapsBool(t, "b_local_bridge", b.IsBridgeSupportedOs);
234 				AddCapsBool(t, "b_must_install_pcap", b.IsWinPcapNeeded);
235 			}
236 			else
237 			{
238 				AddCapsBool(t, "b_local_bridge", false);
239 				AddCapsBool(t, "b_must_install_pcap", false);
240 			}
241 		}
242 		else
243 		{
244 			AddCapsBool(t, "b_local_bridge", false);
245 			AddCapsBool(t, "b_must_install_pcap", false);
246 		}
247 
248 		AddCapsBool(t, "b_tap_supported", false);
249 
250 		if (info.ServerType == SERVER_TYPE_STANDALONE)
251 		{
252 			AddCapsBool(t, "b_support_cascade", true);
253 		}
254 		else
255 		{
256 			AddCapsBool(t, "b_support_cascade", false);
257 		}
258 
259 		AddCapsBool(t, "b_support_cascade_cert", false);
260 		AddCapsBool(t, "b_support_config_log", info.ServerType != SERVER_TYPE_FARM_MEMBER);
261 		AddCapsBool(t, "b_support_autodelete", false);
262 	}
263 	else
264 	{
265 		// Success getting Caps
266 		if (info.ServerBuildInt <= 4350)
267 		{
268 			if (is_bridge == false)
269 			{
270 				// b_support_cluster should be true for build 4300 or earlier
271 				CAPS *caps = GetCaps(t, "b_support_cluster");
272 				if (caps == NULL)
273 				{
274 					AddCapsBool(t, "b_support_cluster", true);
275 				}
276 				else
277 				{
278 					caps->Value = 1;
279 				}
280 			}
281 		}
282 	}
283 
284 	if (true)
285 	{
286 		TOKEN_LIST *names;
287 
288 		// Fill items that doesn't exist in server-side as false
289 		names = GetTableNameStartWith("CT_b_");
290 		if (names != NULL)
291 		{
292 			UINT i;
293 			for (i = 0;i < names->NumTokens;i++)
294 			{
295 				char *name = names->Token[i] + 3;
296 
297 				if (GetCaps(t, name) == NULL)
298 				{
299 					AddCapsBool(t, name, false);
300 				}
301 			}
302 
303 			FreeToken(names);
304 		}
305 	}
306 
307 	FreeRpcServerInfo(&info);
308 
309 	return t;
310 }
311 
312 
313 
314 // Process server side include
AdminWebProcessServerSideInclude(BUF * src_txt,char * filename,UINT depth)315 BUF *AdminWebProcessServerSideInclude(BUF *src_txt, char *filename, UINT depth)
316 {
317 	char *src_str;
318 	UINT src_str_size;
319 	UINT i, len;
320 	BUF *ret = NULL;
321 	UINT pos = 0;
322 	char dirname[MAX_PATH];
323 	if (src_txt == NULL || filename == NULL || depth >= 4)
324 	{
325 		return CloneBuf(src_txt);
326 	}
327 	if (EndWith(filename, ".html") == false)
328 	{
329 		// We process only .html files
330 		return CloneBuf(src_txt);
331 	}
332 
333 	GetDirNameFromFilePath(dirname, sizeof(dirname), filename);
334 
335 	src_str_size = src_txt->Size + 1;
336 	src_str = ZeroMalloc(src_str_size);
337 
338 	Copy(src_str, src_txt->Buf, src_txt->Size);
339 
340 	len = StrLen(src_str);
341 
342 	ret = NewBuf();
343 
344 	for (i = 0;i < len;i++)
345 	{
346 		char *start_tag = "<!--#include file=";
347 		bool is_ssi = false;
348 
349 		if (StartWith(src_str + i, start_tag))
350 		{
351 			UINT a = i + StrLen(start_tag);
352 
353 			if (src_str[a] == '\"' || src_str[a] == '\'')
354 			{
355 				char delimier = src_str[a];
356 				char delimier_str[2];
357 				UINT b;
358 
359 				delimier_str[0] = delimier;
360 				delimier_str[1] = 0;
361 				b = SearchStrEx(src_str, delimier_str, i + StrLen(start_tag) + 1, true);
362 
363 				if ((b != INFINITE) && (b >= i + StrLen(start_tag) + 1) && ((b - (i + StrLen(start_tag) + 1)) < 32))
364 				{
365 					char inc_filename[MAX_PATH];
366 					char *end_tag = "-->";
367 					UINT x;
368 
369 					Zero(inc_filename, sizeof(inc_filename));
370 
371 					StrCpy(inc_filename, sizeof(inc_filename), src_str + i + StrLen(start_tag) + 1);
372 					inc_filename[b - (i + StrLen(start_tag) + 1)] = 0;
373 
374 					x = SearchStrEx(src_str, end_tag, b + 1, true);
375 
376 					if ((x != INFINITE) && (x >= (b + 1)))
377 					{
378 						BUF *inc_buf;
379 						char full_inc_filename[MAX_PATH];
380 
381 						if (StartWith(inc_filename, "/"))
382 						{
383 							Format(full_inc_filename, sizeof(full_inc_filename), "|wwwroot/%s", inc_filename + 1);
384 						}
385 						else
386 						{
387 							StrCpy(full_inc_filename, sizeof(full_inc_filename), dirname);
388 							StrCat(full_inc_filename, sizeof(full_inc_filename), "/");
389 							StrCat(full_inc_filename, sizeof(full_inc_filename), inc_filename);
390 						}
391 
392 						Debug("dirname = %s, full_inc_filename (src) = %s\n\n", dirname, full_inc_filename);
393 						NormalizePath(full_inc_filename, sizeof(full_inc_filename), full_inc_filename);
394 
395 						if (StartWith(full_inc_filename, "|wwwroot/") == false
396 							&& StartWith(full_inc_filename, "|wwwroot\\") == false)
397 						{
398 							char tmp[MAX_PATH];
399 							Format(tmp, sizeof(tmp), "|wwwroot/%s", full_inc_filename);
400 							StrCpy(full_inc_filename, sizeof(full_inc_filename), tmp);
401 						}
402 
403 						Debug("inc_filename = %s\nfull_inc_filename = %s\n\n", inc_filename, full_inc_filename);
404 
405 						inc_buf = ReadDump(full_inc_filename);
406 
407 						if (inc_buf != NULL)
408 						{
409 							BUF *inc_buf2;
410 
411 							inc_buf2 = AdminWebProcessServerSideInclude(inc_buf, full_inc_filename, depth + 1);
412 
413 							BufSkipUtf8Bom(inc_buf2);
414 							WriteBufBufWithOffset(ret, inc_buf2);
415 
416 							FreeBuf(inc_buf);
417 							FreeBuf(inc_buf2);
418 						}
419 						else
420 						{
421 							Debug("Loading SSI '%s' error.\n", inc_buf);
422 						}
423 
424 						i = (x + StrLen(end_tag) - 1);
425 
426 						is_ssi = true;
427 					}
428 				}
429 			}
430 		}
431 
432 		if (is_ssi == false)
433 		{
434 			WriteBufChar(ret, src_str[i]);
435 		}
436 	}
437 
438 	Free(src_str);
439 
440 	return ret;
441 }
442 
443 // Handle the file request
AdminWebHandleFileRequest(ADMIN * a,CONNECTION * c,SOCK * s,HTTP_HEADER * h,char * url_src,char * query_string,char * virtual_root_dir,char * physical_root_dir)444 bool AdminWebHandleFileRequest(ADMIN *a, CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_src, char *query_string, char *virtual_root_dir, char *physical_root_dir)
445 {
446 	bool ret = false;
447 	char url[MAX_PATH];
448 	UINT i, len;
449 	if (a == NULL || c == NULL || s == NULL || h == NULL || query_string == NULL ||
450 		virtual_root_dir == NULL || physical_root_dir == NULL)
451 	{
452 		return false;
453 	}
454 
455 	StrCpy(url, sizeof(url), url_src);
456 
457 	len = StrLen(url);
458 	for (i = 0;i < len;i++)
459 	{
460 		if (url[i] == '\\')
461 		{
462 			url[i] = '/';
463 		}
464 	}
465 
466 	// Is dangerous URL?
467 	if (InStr(url, "..") || InStr(url, "//") || InStr(url, "\\\\") || InStr(url, "/\\") || InStr(url, "\\/"))
468 	{
469 		ret = AdminWebSend404Error(s, h);
470 	}
471 	else
472 	{
473 		char filename[MAX_PATH];
474 		bool is_index_file = false;
475 
476 		BUF *b = AdminWebTryFindAndReadFile(virtual_root_dir, physical_root_dir, url,
477 			filename, sizeof(filename), &is_index_file);
478 
479 		if (b == NULL)
480 		{
481 			ret = AdminWebSend404Error(s, h);
482 		}
483 		else
484 		{
485 			if (is_index_file && EndWith(url, "/") == false)
486 			{
487 				char url2[MAX_PATH];
488 				StrCpy(url2, sizeof(url2), url);
489 				StrCat(url2, sizeof(url2), "/");
490 				ret = AdminWebSend302Redirect(s, url2, query_string, h);
491 			}
492 			else if (is_index_file == false && EndWith(url, "/"))
493 			{
494 				char url2[MAX_PATH];
495 				TrimEndWith(url2, sizeof(url2), url, "/");
496 				ret = AdminWebSend302Redirect(s, url2, query_string, h);
497 			}
498 			else
499 			{
500 				BUF *b2 = AdminWebProcessServerSideInclude(b, filename, 0);
501 				char *mime = GetMimeTypeFromFileName(filename);
502 
503 				if (mime == NULL)
504 				{
505 					mime = "application/octet-stream";
506 				}
507 
508 				ret = AdminWebSendBody(s, 200, "OK", b2->Buf, b2->Size, mime, NULL, NULL, h);
509 
510 				FreeBuf(b2);
511 			}
512 			FreeBuf(b);
513 		}
514 	}
515 
516 	return ret;
517 }
518 
519 // Try to find a file, and if exists return the file contents
AdminWebTryFindAndReadFile(char * vroot,char * proot,char * url,char * ret_filename,UINT ret_filename_size,bool * is_index_html)520 BUF *AdminWebTryFindAndReadFile(char *vroot, char *proot, char *url, char *ret_filename, UINT ret_filename_size, bool *is_index_html)
521 {
522 	char tmp[MAX_PATH];
523 	char tmp2[MAX_PATH];
524 	UINT vroot_len;
525 	UINT url_len;
526 	char relative_path[MAX_PATH];
527 	BUF *b;
528 	if (vroot == NULL || proot == NULL || url == NULL || ret_filename == NULL || is_index_html == NULL)
529 	{
530 		return NULL;
531 	}
532 
533 	*is_index_html = false;
534 
535 	if (StartWith(url, vroot) == false)
536 	{
537 		return NULL;
538 	}
539 
540 	vroot_len = StrLen(vroot);
541 	url_len = StrLen(url);
542 
543 	StrCpy(relative_path, sizeof(relative_path), url + vroot_len);
544 
545 	if (StartWith(relative_path, "/"))
546 	{
547 		char tmp3[MAX_PATH];
548 
549 		StrCpy(tmp3, sizeof(tmp3), relative_path + 1);
550 		StrCpy(relative_path, sizeof(relative_path), tmp3);
551 	}
552 
553 	CombinePath(tmp, sizeof(tmp), proot, relative_path);
554 
555 	// index.html
556 	CombinePath(tmp2, sizeof(tmp2), tmp, "index.html");
557 	b = AdminWebTryOneFile(tmp2, ret_filename, ret_filename_size);
558 	if (b != NULL)
559 	{
560 		*is_index_html = true;
561 		return b;
562 	}
563 
564 	// dirname/filename
565 	StrCpy(tmp2, sizeof(tmp2), tmp);
566 	b = AdminWebTryOneFile(tmp2, ret_filename, ret_filename_size);
567 	if (b != NULL)
568 	{
569 		return b;
570 	}
571 
572 	return NULL;
573 }
AdminWebTryOneFile(char * filename,char * ret_filename,UINT ret_filename_size)574 BUF *AdminWebTryOneFile(char *filename, char *ret_filename, UINT ret_filename_size)
575 {
576 	BUF *b;
577 	if (filename == NULL || ret_filename == NULL)
578 	{
579 		return NULL;
580 	}
581 
582 	b = ReadDump(filename);
583 	if (b == NULL)
584 	{
585 		return NULL;
586 	}
587 
588 	StrCpy(ret_filename, ret_filename_size, filename);
589 
590 	return b;
591 }
592 
593 // Send a 401 Unauthorized error
AdminWebSendUnauthorized(SOCK * s,HTTP_HEADER * http_request_headers)594 bool AdminWebSendUnauthorized(SOCK *s, HTTP_HEADER *http_request_headers)
595 {
596 	char *http_401_str = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<html><head>\r\n<title>401 Unauthorized</title>\r\n</head><body>\r\n<h1>" CEDAR_SERVER_STR ": Administrative authentication required.</h1>\r\n<p>This VPN Server could not verify that you are authorized to access to the \r\nserver in administrative mode.</p>\r\n<p><strong>For web browser logins:<br></strong>You must supply the HTTP basic \r\nauthentication credential as following.</p>\r\n<ul>\r\n\t<li>To login to the VPN server as the entire server administrator, specify empty or &quot;administrator&quot; as the username field, and specify the server administrative \r\n\tpassword as the password field.<br></li>\r\n\t<li>To login to a particular Virtual Hub as the hub administrator, specify \r\n\tthe hub name as the username field, and specify the hub administrative \r\n\tpassword as the password field.</li>\r\n</ul>\r\n<p><strong>For JSON-RPC client logins:<br></strong>Instead to HTTP basic \r\nauthentication, you can also specify the HTTP header parameters as following.</p>\r\n<ul>\r\n\t<li>X-VPNADMIN-HUBNAME: Empty to login to the VPN Server as the entire \r\n\tserver administrator, or specify the target Virtual Hub name as the hub \r\n\tadministrator.</li>\r\n\t<li>X-VPNADMIN-PASSWORD: Specify the administrative password.</li>\r\n</ul>\r\n</body></html>\r\n";
597 	bool ret;
598 	// Validate arguments
599 	if (s == NULL || http_request_headers == NULL)
600 	{
601 		return false;
602 	}
603 
604 	// Creating a Data
605 	ret = AdminWebSendBody(s, 401, "Unauthorized", http_401_str, StrLen(http_401_str), HTTP_CONTENT_TYPE,
606 		"WWW-Authenticate",
607 		"Basic realm=\"Username 'administrator' for entire VPN Server privilege, or specify Virtual Hub name as the username for specified Virtual Hub administrative privilege.\"",
608 		http_request_headers);
609 
610 	return ret;
611 }
612 
613 // Send reply
AdminWebSendBody(SOCK * s,UINT status_code,char * status_string,UCHAR * data,UINT data_size,char * content_type,char * add_header_name,char * add_header_value,HTTP_HEADER * request_headers)614 bool AdminWebSendBody(SOCK *s, UINT status_code, char *status_string, UCHAR *data, UINT data_size, char *content_type, char *add_header_name, char *add_header_value,
615 					  HTTP_HEADER *request_headers)
616 {
617 	HTTP_HEADER *h;
618 	char date_str[MAX_SIZE];
619 	char error_code_str[16];
620 	bool ret = false;
621 	HTTP_VALUE *origin;
622 	if (s == NULL || status_string == NULL || (data_size != 0 && data == NULL) || request_headers == NULL)
623 	{
624 		return false;
625 	}
626 	if (content_type == NULL)
627 	{
628 		content_type = "text/html; charset=utf-8";
629 	}
630 
631 	ToStr(error_code_str, status_code);
632 	GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
633 
634 	h = NewHttpHeader("HTTP/1.1", error_code_str, status_string);
635 
636 	if (StrCmpi(request_headers->Method, "OPTIONS") == 0)
637 	{
638 		AddHttpValue(h, NewHttpValue("Allow", "OPTIONS, GET, POST"));
639 	}
640 
641 	AddHttpValue(h, NewHttpValue("Cache-Control", "no-cache"));
642 	AddHttpValue(h, NewHttpValue("Content-Type", content_type));
643 	AddHttpValue(h, NewHttpValue("Date", date_str));
644 	AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
645 	AddHttpValue(h, NewHttpValue("Access-Control-Allow-Methods", "OPTIONS,GET,POST"));
646 	AddHttpValue(h, NewHttpValue("Access-Control-Allow-Headers", "X-VPNADMIN-HUBNAME,X-VPNADMIN-PASSWORD"));
647 	AddHttpValue(h, NewHttpValue("Access-Control-Allow-Credentials", "true"));
648 
649 	origin = GetHttpValue(request_headers, "Origin");
650 	if (origin != NULL)
651 	{
652 		AddHttpValue(h, NewHttpValue("Access-Control-Allow-Origin", origin->Data));
653 	}
654 
655 	if (add_header_name != NULL && add_header_value != NULL)
656 	{
657 		AddHttpValue(h, NewHttpValue(add_header_name, add_header_value));
658 	}
659 
660 	ret = PostHttp(s, h, data, data_size);
661 
662 	FreeHttpHeader(h);
663 
664 	return ret;
665 }
666 
667 // Send 404 error
AdminWebSend404Error(SOCK * s,HTTP_HEADER * request_headers)668 bool AdminWebSend404Error(SOCK *s, HTTP_HEADER *request_headers)
669 {
670 	char *body = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p></body></html>\r\n";
671 	if (s == NULL || request_headers == NULL)
672 	{
673 		return false;
674 	}
675 
676 	return AdminWebSendBody(s, 404, "Not Found", body, StrLen(body), NULL, NULL, NULL, request_headers);
677 }
678 
679 // Send 302 redirect
AdminWebSend302Redirect(SOCK * s,char * url,char * query_string,HTTP_HEADER * request_headers)680 bool AdminWebSend302Redirect(SOCK *s, char *url, char *query_string, HTTP_HEADER *request_headers)
681 {
682 	bool ret = false;
683 	char *txt;
684 	UINT txt_size;
685 	char *url2;
686 	UINT url2_size;
687 	char *body = "<html><head><title>Object moved</title></head><body>\r\n<h2>Object moved to <a href=\"$URL$\">here</a>.</h2>\r\n</body></html>";
688 	if (s == NULL || url == NULL || request_headers == NULL)
689 	{
690 		return false;
691 	}
692 
693 	url2_size = (StrSize(url) + StrSize(query_string) + MAX_SIZE) * 2;
694 	url2 = ZeroMalloc(url2_size);
695 
696 	StrCpy(url2, url2_size, url);
697 	if (IsEmptyStr(query_string) == false)
698 	{
699 		StrCat(url2, url2_size, "?");
700 		StrCat(url2, url2_size, query_string);
701 	}
702 
703 	txt_size = (StrSize(body) + StrSize(url2) + MAX_SIZE) * 2;
704 	txt = ZeroMalloc(txt_size);
705 
706 	ReplaceStrEx(txt, txt_size, body, "$URL$", url2, false);
707 
708 	ret = AdminWebSendBody(s, 302, "Found", txt, StrLen(txt), NULL, "Location", url2, request_headers);
709 
710 	Free(txt);
711 
712 	Free(url2);
713 
714 	return ret;
715 }
716 
717 // "/admin" web page POST handler
AdminWebProcPost(CONNECTION * c,SOCK * s,HTTP_HEADER * h,UINT post_data_size,char * url_target)718 void AdminWebProcPost(CONNECTION *c, SOCK *s, HTTP_HEADER *h, UINT post_data_size, char *url_target)
719 {
720 	ADMIN *a;
721 	UCHAR *data;
722 	char url[MAX_PATH];
723 	char query_string[MAX_SIZE];
724 	UINT i;
725 	if (c == NULL || s == NULL || h == NULL || url_target == NULL)
726 	{
727 		return;
728 	}
729 
730 	a = JsonRpcAuthLogin(c->Cedar, s, h);
731 	if (a == NULL)
732 	{
733 		RecvAllWithDiscard(s, post_data_size, s->SecureMode);
734 		AdminWebSendUnauthorized(s, h);
735 		return;
736 	}
737 
738 	if (post_data_size > a->MaxJsonRpcRecvSize)
739 	{
740 		Disconnect(s);
741 		return;
742 	}
743 
744 	data = ZeroMalloc(post_data_size + 1);
745 
746 	if (RecvAll(s, data, post_data_size, s->SecureMode))
747 	{
748 		c->JsonRpcAuthed = true;
749 #ifndef	GC_SOFTETHER_OSS
750 		RemoveDosEntry(c->Listener, s);
751 #endif	// GC_SOFTETHER_OSS
752 
753 		// Divide url_target into URL and query string
754 		StrCpy(url, sizeof(url), url_target);
755 		Zero(query_string, sizeof(query_string));
756 		i = SearchStr(url, "?", 0);
757 		if (i != INFINITE)
758 		{
759 			StrCpy(query_string, sizeof(query_string), url + i + 1);
760 			url[i] = 0;
761 		}
762 
763 		AdminWebHandleFileRequest(a, c, s, h, url, query_string, "/admin", "|wwwroot/admin");
764 	}
765 
766 	Free(data);
767 	Free(a);
768 }
769 
770 // "/admin" web page GET handler
AdminWebProcGet(CONNECTION * c,SOCK * s,HTTP_HEADER * h,char * url_target)771 void AdminWebProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target)
772 {
773 	ADMIN *a;
774 	char url[MAX_PATH];
775 	char query_string[MAX_SIZE];
776 	UINT i;
777 	if (c == NULL || s == NULL || h == NULL || url_target == NULL)
778 	{
779 		return;
780 	}
781 
782 	a = JsonRpcAuthLogin(c->Cedar, s, h);
783 	if (a == NULL)
784 	{
785 		AdminWebSendUnauthorized(s, h);
786 		return;
787 	}
788 
789 	c->JsonRpcAuthed = true;
790 #ifndef	GC_SOFTETHER_OSS
791 	RemoveDosEntry(c->Listener, s);
792 #endif	// GC_SOFTETHER_OSS
793 
794 	// Divide url_target into URL and query string
795 	StrCpy(url, sizeof(url), url_target);
796 	Zero(query_string, sizeof(query_string));
797 	i = SearchStr(url, "?", 0);
798 	if (i != INFINITE)
799 	{
800 		StrCpy(query_string, sizeof(query_string), url + i + 1);
801 		url[i] = 0;
802 	}
803 
804 	AdminWebHandleFileRequest(a, c, s, h, url, query_string, "/admin", "|wwwroot/admin");
805 
806 	Free(a);
807 }
808 
809 // New JSON-RPC Result
JsonRpcNewResponse(PACK * p)810 JSON_VALUE *JsonRpcNewResponse(PACK *p)
811 {
812 	JSON_VALUE *jv;
813 	JSON_OBJECT *jo;
814 	JSON_VALUE *jv2;
815 
816 	if (p == NULL)
817 	{
818 		return NULL;
819 	}
820 
821 	jv = JsonNewObject();
822 	jo = JsonValueGetObject(jv);
823 
824 	jv2 = PackToJson(p);
825 
826 	JsonSet(jo, "result", jv2);
827 
828 	return jv;
829 }
830 
831 // New JSON-RPC Error
JsonRpcNewError(int code,wchar_t * message)832 JSON_VALUE *JsonRpcNewError(int code, wchar_t *message)
833 {
834 	wchar_t msg[MAX_PATH];
835 	JSON_VALUE *jv;
836 	JSON_OBJECT *jo;
837 	JSON_VALUE *jv2;
838 	JSON_OBJECT *jo2;
839 
840 	if (UniIsEmptyStr(message))
841 	{
842 		UniFormat(msg, sizeof(msg), L"Error code %u", code);
843 	}
844 	else
845 	{
846 		UniFormat(msg, sizeof(msg), L"Error code %u: %s", code, message);
847 	}
848 
849 	jv = JsonNewObject();
850 	jo = JsonValueGetObject(jv);
851 
852 	jv2 = JsonNewObject();
853 	jo2 = JsonValueGetObject(jv2);
854 
855 	JsonSet(jo, "error", jv2);
856 
857 	JsonSetNumber(jo2, "code", (UINT64)code);
858 	JsonSetUniStr(jo2, "message", msg);
859 
860 	return jv;
861 }
862 
863 // JSON-RPC process request object
JsonRpcProcRequestObject(ADMIN * admin,CONNECTION * c,SOCK * s,JSON_VALUE * json_req,char * method_name)864 JSON_VALUE *JsonRpcProcRequestObject(ADMIN *admin, CONNECTION *c, SOCK *s, JSON_VALUE *json_req, char *method_name)
865 {
866 	PACK *pack_request;
867 	JSON_VALUE *ret = NULL;
868 	if (c == NULL || s == NULL || json_req == NULL || admin == NULL)
869 	{
870 		return NULL;
871 	}
872 
873 	pack_request = JsonToPack(json_req);
874 
875 	PackAddStr(pack_request, "function_name", method_name);
876 
877 	if (pack_request != NULL)
878 	{
879 		RPC *rpc;
880 		PACK *pack_response;
881 		UINT err;
882 
883 		// RPC Server
884 		rpc = StartRpcServer(s, AdminDispatch, admin);
885 
886 		admin->Rpc = rpc;
887 
888 		pack_response = CallRpcDispatcher(rpc, pack_request);
889 
890 		if (pack_response == NULL)
891 		{
892 			pack_response = PackError(ERR_NOT_SUPPORTED);
893 		}
894 
895 		RpcFreeEx(rpc, true);
896 
897 		FreePack(pack_request);
898 
899 		// Construct response object
900 		err = GetErrorFromPack(pack_response);
901 		if (err != 0)
902 		{
903 			// Return the error
904 			ret = JsonRpcNewError(err, _E(err));
905 		}
906 		else
907 		{
908 			// Return the PACK
909 			ret = JsonRpcNewResponse(pack_response);
910 		}
911 
912 		SLog(admin->Server->Cedar, "LS_API_RPC_CALL",
913 			&s->RemoteIP, s->RemotePort, s->RemoteHostname,
914 			method_name, err, _E(err));
915 
916 		FreePack(pack_response);
917 	}
918 
919 	return ret;
920 }
921 
922 // JSON-RPC HTTP user authentication
HttpParseBasicAuthHeader(HTTP_HEADER * h,char * username,UINT username_size,char * password,UINT password_size)923 bool HttpParseBasicAuthHeader(HTTP_HEADER *h, char *username, UINT username_size, char *password, UINT password_size)
924 {
925 	bool ret = false;
926 	HTTP_VALUE *auth_value;
927 	HTTP_VALUE *vpnadmin_hubname;
928 	HTTP_VALUE *vpnadmin_password;
929 	if (h == NULL || username == NULL || password == NULL)
930 	{
931 		return false;
932 	}
933 
934 	auth_value = GetHttpValue(h, "Authorization");
935 	vpnadmin_hubname = GetHttpValue(h, "X-VPNADMIN-HUBNAME");
936 	vpnadmin_password = GetHttpValue(h, "X-VPNADMIN-PASSWORD");
937 
938 	if (vpnadmin_password != NULL)
939 	{
940 		if (vpnadmin_hubname == NULL)
941 		{
942 			StrCpy(username, username_size, "");
943 		}
944 		else
945 		{
946 			StrCpy(username, username_size, vpnadmin_hubname->Data);
947 		}
948 
949 		StrCpy(password, password_size, vpnadmin_password->Data);
950 
951 		ret = true;
952 	}
953 
954 	if (ret == false && auth_value != NULL)
955 	{
956 		char key[32], value[MAX_SIZE];
957 
958 		if (GetKeyAndValue(auth_value->Data, key, sizeof(key), value, sizeof(value), " \t"))
959 		{
960 			if (StrCmpi(key, "Basic") == 0 && IsEmptyStr(value) == false)
961 			{
962 				UINT b64_dest_size = StrSize(value) * 2 + 256;
963 				char *b64_dest = ZeroMalloc(b64_dest_size);
964 
965 				Decode64(b64_dest, value);
966 
967 				if (IsEmptyStr(b64_dest) == false)
968 				{
969 					if (b64_dest[0] == ':')
970 					{
971 						// Empty username
972 						StrCpy(username, username_size, "");
973 						StrCpy(password, password_size, b64_dest + 1);
974 						ret = true;
975 					}
976 					else
977 					{
978 						if (GetKeyAndValue(b64_dest, username, username_size, password, password_size, ":"))
979 						{
980 							ret = true;
981 						}
982 					}
983 				}
984 
985 				Free(b64_dest);
986 			}
987 		}
988 	}
989 
990 	return ret;
991 }
992 
993 // JSON-RPC Login
JsonRpcAuthLogin(CEDAR * c,SOCK * sock,HTTP_HEADER * h)994 ADMIN *JsonRpcAuthLogin(CEDAR *c, SOCK *sock, HTTP_HEADER *h)
995 {
996 	ADMIN *a = NULL;
997 	char username[MAX_HUBNAME_LEN + 1];
998 	char password[MAX_PASSWORD_LEN + 1];
999 	SERVER *s;
1000 	char empty_pw_hash[SHA1_SIZE];
1001 
1002 	if (c == NULL || h == NULL || sock == NULL)
1003 	{
1004 		return NULL;
1005 	}
1006 
1007 	s = c->Server;
1008 
1009 	HashAdminPassword(empty_pw_hash, "");
1010 
1011 	Zero(username, sizeof(username));
1012 	Zero(password, sizeof(password));
1013 
1014 	if (HttpParseBasicAuthHeader(h, username, sizeof(username), password, sizeof(password)))
1015 	{
1016 		char pw_hash[SHA1_SIZE];
1017 		bool is_server_admin = false;
1018 		bool is_hub_admin = false;
1019 		char hub_name[MAX_HUBNAME_LEN + 1];
1020 
1021 		HashAdminPassword(pw_hash, password);
1022 
1023 		Zero(hub_name, sizeof(hub_name));
1024 
1025 		// Check if the server administrator password is empty. If yes, login always success.
1026 		if (Cmp(s->HashedPassword, empty_pw_hash, SHA1_SIZE) == 0)
1027 		{
1028 			is_server_admin = true;
1029 		}
1030 		else
1031 		{
1032 			if (IsEmptyStr(username) || StrCmpi(username, ADMINISTRATOR_USERNAME) == 0)
1033 			{
1034 				// If the username is empty or 'administrator', verify with the server admin password.
1035 				if (Cmp(s->HashedPassword, pw_hash, SHA1_SIZE) == 0)
1036 				{
1037 					is_server_admin = true;
1038 				}
1039 			}
1040 		}
1041 
1042 		if (is_server_admin == false)
1043 		{
1044 			HUB *h;
1045 			// Hub admin mode
1046 			LockHubList(c);
1047 			{
1048 				h = GetHub(c, username);
1049 			}
1050 			UnlockHubList(c);
1051 
1052 			if (h != NULL)
1053 			{
1054 				Lock(h->lock);
1055 				{
1056 					if (Cmp(h->HashedPassword, empty_pw_hash, SHA1_SIZE) != 0 && IsZero(h->HashedPassword, sizeof(h->HashedPassword)) == false)
1057 					{
1058 						if (Cmp(pw_hash, h->HashedPassword, SHA1_SIZE) == 0)
1059 						{
1060 							is_hub_admin = true;
1061 
1062 							StrCpy(hub_name, sizeof(hub_name), h->Name);
1063 						}
1064 					}
1065 				}
1066 				Unlock(h->lock);
1067 
1068 				ReleaseHub(h);
1069 			}
1070 		}
1071 
1072 		if (is_server_admin || is_hub_admin)
1073 		{
1074 			if (CheckAdminSourceAddress(sock, hub_name))
1075 			{
1076 				a = ZeroMalloc(sizeof(ADMIN));
1077 
1078 				a->Server = s;
1079 				a->ServerAdmin = is_server_admin;
1080 				a->ClientBuild = c->Build;
1081 
1082 				if (is_hub_admin)
1083 				{
1084 					StrCpy(a->dummy1, sizeof(a->dummy1), hub_name);
1085 					a->HubName = a->dummy1;
1086 				}
1087 			}
1088 		}
1089 	}
1090 
1091 	if (a != NULL)
1092 	{
1093 		char admin_mode[256];
1094 		if (a->ServerAdmin)
1095 		{
1096 			a->MaxJsonRpcRecvSize = ADMIN_RPC_MAX_POST_SIZE_BY_SERVER_ADMIN;
1097 		}
1098 		else
1099 		{
1100 			a->MaxJsonRpcRecvSize = ADMIN_RPC_MAX_POST_SIZE_BY_HUB_ADMIN;
1101 		}
1102 
1103 		if (IsEmptyStr(a->HubName))
1104 		{
1105 			StrCpy(admin_mode, sizeof(admin_mode),
1106 				"Entire VPN Server Admin Mode");
1107 		}
1108 		else
1109 		{
1110 			Format(admin_mode, sizeof(admin_mode),
1111 				"Virtual Hub Admin Mode for '%s'",
1112 				a->HubName);
1113 		}
1114 
1115 		SLog(s->Cedar, "LS_API_AUTH_OK",
1116 			&sock->RemoteIP, sock->RemotePort, sock->RemoteHostname,
1117 			admin_mode, username, h->Method, h->Target);
1118 	}
1119 	else
1120 	{
1121 		SLog(s->Cedar, "LS_API_AUTH_ERROR",
1122 			&sock->RemoteIP, sock->RemotePort, sock->RemoteHostname,
1123 			username, h->Method, h->Target);
1124 	}
1125 
1126 
1127 	return a;
1128 }
1129 
1130 // Query string to JSON list value
QueryStringToJsonListValue(char * qs)1131 JSON_VALUE *QueryStringToJsonListValue(char *qs)
1132 {
1133 	TOKEN_LIST *t;
1134 	UINT i;
1135 	LIST *distinct_list = NULL;
1136 	JSON_VALUE *v = NULL;
1137 	JSON_OBJECT *o = NULL;
1138 	if (qs == NULL)
1139 	{
1140 		return NULL;
1141 	}
1142 
1143 	t = ParseTokenWithoutNullStr(qs, "&");
1144 	if (t == NULL)
1145 	{
1146 		return NULL;
1147 	}
1148 
1149 	distinct_list = NewStrList();
1150 
1151 	v = JsonNewObject();
1152 	o = JsonValueGetObject(v);
1153 
1154 	for (i = 0;i < t->NumTokens;i++)
1155 	{
1156 		char *token = t->Token[i];
1157 		UINT pos;
1158 
1159 		pos = SearchStr(token, "=", 0);
1160 		if (pos != INFINITE)
1161 		{
1162 			char *key_decoded;
1163 			char *value_decoded;
1164 			char *key = CopyStr(token);
1165 			char *value = CopyStr(token + pos + 1);
1166 
1167 			key[pos] = 0;
1168 			key_decoded = UrlDecode(key);
1169 			value_decoded = UrlDecode(value);
1170 
1171 			if (key_decoded != NULL && value_decoded != NULL)
1172 			{
1173 				if (AddStrToStrListDistinct(distinct_list, key_decoded))
1174 				{
1175 					JsonSetStr(o, key_decoded, value_decoded);
1176 				}
1177 			}
1178 
1179 			Free(value_decoded);
1180 			Free(key_decoded);
1181 			Free(key);
1182 			Free(value);
1183 		}
1184 	}
1185 
1186 	FreeToken(t);
1187 
1188 	FreeStrList(distinct_list);
1189 
1190 	return v;
1191 }
1192 
1193 // Construct new JSON-RPC dummy request
ConstructDummyJsonRpcRequest(char * method_name,JSON_VALUE * p)1194 JSON_VALUE *ConstructDummyJsonRpcRequest(char *method_name, JSON_VALUE *p)
1195 {
1196 	JSON_VALUE *ret;
1197 	JSON_OBJECT *ret_object;
1198 	UCHAR rand[16];
1199 	char id_str[64];
1200 
1201 	Rand(rand, sizeof(rand));
1202 
1203 	BinToStr(id_str, sizeof(id_str), rand, sizeof(rand));
1204 
1205 	ret = JsonNewObject();
1206 	ret_object = JsonObject(ret);
1207 
1208 	JsonSetStr(ret_object, "jsonrpc", "2.0");
1209 	JsonSetStr(ret_object, "method", method_name);
1210 	JsonSet(ret_object, "params", p);
1211 	JsonSetStr(ret_object, "id", id_str);
1212 
1213 	return ret;
1214 }
1215 
1216 // JSON-RPC Options Dispatch
JsonRpcProcOptions(CONNECTION * c,SOCK * s,HTTP_HEADER * h,char * url_target)1217 void JsonRpcProcOptions(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target)
1218 {
1219 	if (c == NULL || s == NULL || h == NULL || url_target == NULL)
1220 	{
1221 		return;
1222 	}
1223 
1224 	c->JsonRpcAuthed = true;
1225 
1226 #ifndef	GC_SOFTETHER_OSS
1227 	RemoveDosEntry(c->Listener, s);
1228 #endif	// GC_SOFTETHER_OSS
1229 
1230 	AdminWebSendBody(s, 200, "OK", NULL, 0, NULL, NULL, NULL, h);
1231 }
1232 
1233 // JSON-RPC GET Dispatch
JsonRpcProcGet(CONNECTION * c,SOCK * s,HTTP_HEADER * h,char * url_target)1234 void JsonRpcProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target)
1235 {
1236 	ADMIN *a;
1237 	char url[MAX_PATH];
1238 	char query_string[MAX_SIZE];
1239 	UINT i;
1240 	bool reply_sent = false;
1241 	if (c == NULL || s == NULL || h == NULL || url_target == NULL)
1242 	{
1243 		return;
1244 	}
1245 
1246 	a = JsonRpcAuthLogin(c->Cedar, s, h);
1247 	if (a == NULL)
1248 	{
1249 		AdminWebSendUnauthorized(s, h);
1250 		return;
1251 	}
1252 
1253 	c->JsonRpcAuthed = true;
1254 
1255 #ifndef	GC_SOFTETHER_OSS
1256 	RemoveDosEntry(c->Listener, s);
1257 #endif	// GC_SOFTETHER_OSS
1258 
1259 	// Divide url_target into URL and query string
1260 	StrCpy(url, sizeof(url), url_target);
1261 	Zero(query_string, sizeof(query_string));
1262 	i = SearchStr(url, "?", 0);
1263 	if (i != INFINITE)
1264 	{
1265 		StrCpy(query_string, sizeof(query_string), url + i + 1);
1266 		url[i] = 0;
1267 	}
1268 
1269 	if (StartWith(url, "/api/"))
1270 	{
1271 		// Call a method
1272 		JSON_VALUE *params_value = NULL;
1273 		JSON_OBJECT *params_object = NULL;
1274 		UINT i;
1275 		char method_name[MAX_PATH];
1276 
1277 		StrCpy(method_name, sizeof(method_name), url + 5);
1278 
1279 		i = SearchStr(method_name, "/", 0);
1280 		if (i != INFINITE)
1281 		{
1282 			method_name[i] = 0;
1283 		}
1284 
1285 		if (IsEmptyStr(method_name) == false)
1286 		{
1287 			// Call a method
1288 			params_value = QueryStringToJsonListValue(query_string);
1289 
1290 			if (params_value != NULL)
1291 			{
1292 				JSON_VALUE *json_ret = NULL;
1293 				char id[96];
1294 				char *ret_str = NULL;
1295 
1296 				GetDateTimeStrMilli64(id, sizeof(id), LocalTime64());
1297 
1298 				params_object = JsonObject(params_value);
1299 
1300 				// Process the request
1301 				json_ret = JsonRpcProcRequestObject(a, c, s, params_value, method_name);
1302 
1303 				if (json_ret == NULL)
1304 				{
1305 					json_ret = JsonRpcNewError(ERR_INTERNAL_ERROR, L"Internal error");
1306 				}
1307 
1308 				JsonSetStr(JsonObject(json_ret), "jsonrpc", "2.0");
1309 				JsonSetStr(JsonObject(json_ret), "id", id);
1310 
1311 				ret_str = JsonToStr(json_ret);
1312 
1313 				AdminWebSendBody(s, 200, "OK", ret_str, StrLen(ret_str), "text/plain; charset=UTF-8", NULL, NULL, h);
1314 
1315 				Free(ret_str);
1316 				JsonFree(json_ret);
1317 				JsonFree(params_value);
1318 			}
1319 		}
1320 	}
1321 
1322 
1323 	if (reply_sent == false)
1324 	{
1325 		BUF *html_buf = ReadDump("|vpnserver_api_doc.html");
1326 
1327 		if (html_buf != NULL)
1328 		{
1329 			AdminWebSendBody(s, 200, "OK", html_buf->Buf, html_buf->Size, "text/html; charset=UTF-8", NULL, NULL, h);
1330 
1331 			FreeBuf(html_buf);
1332 		}
1333 		else
1334 		{
1335 			AdminWebSend404Error(s, h);
1336 		}
1337 	}
1338 
1339 	if (a->LogFileList != NULL)
1340 	{
1341 		FreeEnumLogFile(a->LogFileList);
1342 	}
1343 	Free(a);
1344 }
1345 
1346 // JSON-RPC POST Dispatch
JsonRpcProcPost(CONNECTION * c,SOCK * s,HTTP_HEADER * h,UINT post_data_size)1347 void JsonRpcProcPost(CONNECTION *c, SOCK *s, HTTP_HEADER *h, UINT post_data_size)
1348 {
1349 	ADMIN *a;
1350 	UCHAR *data;
1351 	if (c == NULL || s == NULL || h == NULL)
1352 	{
1353 		return;
1354 	}
1355 
1356 	a = JsonRpcAuthLogin(c->Cedar, s, h);
1357 	if (a == NULL)
1358 	{
1359 		RecvAllWithDiscard(s, post_data_size, s->SecureMode);
1360 		AdminWebSendUnauthorized(s, h);
1361 		return;
1362 	}
1363 
1364 	if (post_data_size > a->MaxJsonRpcRecvSize)
1365 	{
1366 		Disconnect(s);
1367 		return;
1368 	}
1369 
1370 	data = ZeroMalloc(post_data_size + 1);
1371 
1372 	if (RecvAll(s, data, post_data_size, s->SecureMode))
1373 	{
1374 		// Parse JSON
1375 		JSON_VALUE *json_req = StrToJson(data);
1376 		JSON_OBJECT *json_req_object = JsonObject(json_req);
1377 		JSON_VALUE *json_ret = NULL;
1378 		char *res = NULL;
1379 		char *request_id = NULL;
1380 		char *method_name = NULL;
1381 
1382 		c->JsonRpcAuthed = true;
1383 
1384 #ifndef	GC_SOFTETHER_OSS
1385 		RemoveDosEntry(c->Listener, s);
1386 #endif	// GC_SOFTETHER_OSS
1387 
1388 		if (json_req == NULL || json_req_object == NULL)
1389 		{
1390 			// Parse error
1391 			json_ret = JsonRpcNewError(ERR_INVALID_PARAMETER, L"Parameter is invalid: JSON-RPC Parse Error");
1392 		}
1393 		else
1394 		{
1395 			// check the JSON-RPC version
1396 			char *ver_str = JsonGetStr(json_req_object, "jsonrpc");
1397 			if (StrCmpi(ver_str, "2.0") != 0)
1398 			{
1399 				// Invalid version
1400 				json_ret = JsonRpcNewError(ERR_INVALID_PARAMETER, L"JSON-RPC version is invalid");
1401 			}
1402 			else
1403 			{
1404 				JSON_VALUE *params_value = NULL;
1405 				JSON_OBJECT *params_object = NULL;
1406 
1407 				// Get Request ID
1408 				request_id = JsonGetStr(json_req_object, "id");
1409 
1410 				// Get method name
1411 				method_name = JsonGetStr(json_req_object, "method");
1412 
1413 				// Get parameters
1414 				params_value = JsonGet(json_req_object, "params");
1415 				params_object = JsonObject(params_value);
1416 
1417 				if (IsEmptyStr(method_name))
1418 				{
1419 					// method is empty
1420 					json_ret = JsonRpcNewError(ERR_INVALID_PARAMETER, L"JSON-RPC method name is empty");
1421 				}
1422 				else if (params_value == NULL || params_object == NULL)
1423 				{
1424 					// params is empty
1425 					json_ret = JsonRpcNewError(ERR_INVALID_PARAMETER, L"JSON-RPC parameter is empty");
1426 				}
1427 				else
1428 				{
1429 					// Process the request
1430 					json_ret = JsonRpcProcRequestObject(a, c, s, params_value, method_name);
1431 				}
1432 			}
1433 		}
1434 
1435 		if (json_ret == NULL)
1436 		{
1437 			json_ret = JsonRpcNewError(ERR_INTERNAL_ERROR, L"Internal error");
1438 		}
1439 
1440 		JsonSetStr(JsonObject(json_ret), "jsonrpc", "2.0");
1441 		if (request_id == NULL)
1442 		{
1443 			request_id = "0";
1444 		}
1445 		JsonSetStr(JsonObject(json_ret), "id", request_id);
1446 
1447 		res = JsonToStr(json_ret);
1448 
1449 		AdminWebSendBody(s, 200, "OK", res, StrLen(res), "application/json", NULL, NULL, h);
1450 
1451 		Free(res);
1452 
1453 		JsonFree(json_ret);
1454 		JsonFree(json_req);
1455 	}
1456 
1457 	Free(data);
1458 
1459 	if (a->LogFileList != NULL)
1460 	{
1461 		FreeEnumLogFile(a->LogFileList);
1462 	}
1463 	Free(a);
1464 }
1465 
1466 // Dispatch routine for Administration RPC
AdminDispatch(RPC * rpc,char * name,PACK * p)1467 PACK *AdminDispatch(RPC *rpc, char *name, PACK *p)
1468 {
1469 	ADMIN *a;
1470 	PACK *ret;
1471 	UINT err;
1472 	SERVER *server = NULL;
1473 	CEDAR *cedar = NULL;
1474 	bool ok = false;
1475 	// Validate arguments
1476 	if (rpc == NULL || name == NULL || p == NULL)
1477 	{
1478 		return NULL;
1479 	}
1480 
1481 	ret = NewPack();
1482 	err = ERR_NO_ERROR;
1483 
1484 	// Administration structure
1485 	a = (ADMIN *)rpc->Param;
1486 	if (a == NULL)
1487 	{
1488 		FreePack(ret);
1489 		return NULL;
1490 	}
1491 
1492 	server = a->Server;
1493 
1494 	if (server == NULL)
1495 	{
1496 		return NULL;
1497 	}
1498 
1499 	cedar = server->Cedar;
1500 	Lock(cedar->CedarSuperLock);
1501 
1502 	if (true)
1503 	{
1504 		char tmp[MAX_PATH];
1505 		char ip[MAX_PATH];
1506 		UINT rpc_id = 0;
1507 
1508 		StrCpy(ip, sizeof(ip), "Unknown");
1509 
1510 		if (rpc->Sock != NULL)
1511 		{
1512 			IPToStr(ip, sizeof(ip), &rpc->Sock->RemoteIP);
1513 			rpc_id = rpc->Sock->socket;
1514 		}
1515 
1516 		Format(tmp, sizeof(tmp), "RPC: RPC-%u (%s): Entering RPC [%s]...",
1517 			rpc_id, ip, name);
1518 
1519 		SiDebugLog(a->Server, tmp);
1520 	}
1521 
1522 	if (0) {}
1523 
1524 	// RPC function declaration: from here
1525 	DECLARE_RPC_EX("Test", RPC_TEST, StTest, InRpcTest, OutRpcTest, FreeRpcTest)
1526 	DECLARE_RPC_EX("GetServerInfo", RPC_SERVER_INFO, StGetServerInfo, InRpcServerInfo, OutRpcServerInfo, FreeRpcServerInfo)
1527 	DECLARE_RPC("GetServerStatus", RPC_SERVER_STATUS, StGetServerStatus, InRpcServerStatus, OutRpcServerStatus)
1528 	DECLARE_RPC("CreateListener", RPC_LISTENER, StCreateListener, InRpcListener, OutRpcListener)
1529 	DECLARE_RPC_EX("EnumListener", RPC_LISTENER_LIST, StEnumListener, InRpcListenerList, OutRpcListenerList, FreeRpcListenerList)
1530 	DECLARE_RPC("DeleteListener", RPC_LISTENER, StDeleteListener, InRpcListener, OutRpcListener)
1531 	DECLARE_RPC("EnableListener", RPC_LISTENER, StEnableListener, InRpcListener, OutRpcListener)
1532 	DECLARE_RPC_EX("SetPortsUDP", RPC_PORTS, StSetPortsUDP, InRpcPorts, OutRpcPorts, FreeRpcPorts)
1533 	DECLARE_RPC_EX("GetPortsUDP", RPC_PORTS, StGetPortsUDP, InRpcPorts, OutRpcPorts, FreeRpcPorts)
1534 	DECLARE_RPC_EX("SetProtoOptions", RPC_PROTO_OPTIONS, StSetProtoOptions, InRpcProtoOptions, OutRpcProtoOptions, FreeRpcProtoOptions)
1535 	DECLARE_RPC_EX("GetProtoOptions", RPC_PROTO_OPTIONS, StGetProtoOptions, InRpcProtoOptions, OutRpcProtoOptions, FreeRpcProtoOptions)
1536 	DECLARE_RPC("SetServerPassword", RPC_SET_PASSWORD, StSetServerPassword, InRpcSetPassword, OutRpcSetPassword)
1537 	DECLARE_RPC_EX("SetFarmSetting", RPC_FARM, StSetFarmSetting, InRpcFarm, OutRpcFarm, FreeRpcFarm)
1538 	DECLARE_RPC_EX("GetFarmSetting", RPC_FARM, StGetFarmSetting, InRpcFarm, OutRpcFarm, FreeRpcFarm)
1539 	DECLARE_RPC_EX("GetFarmInfo", RPC_FARM_INFO, StGetFarmInfo, InRpcFarmInfo, OutRpcFarmInfo, FreeRpcFarmInfo)
1540 	DECLARE_RPC_EX("EnumFarmMember", RPC_ENUM_FARM, StEnumFarmMember, InRpcEnumFarm, OutRpcEnumFarm, FreeRpcEnumFarm)
1541 	DECLARE_RPC("GetFarmConnectionStatus", RPC_FARM_CONNECTION_STATUS, StGetFarmConnectionStatus, InRpcFarmConnectionStatus, OutRpcFarmConnectionStatus)
1542 	DECLARE_RPC_EX("SetServerCert", RPC_KEY_PAIR, StSetServerCert, InRpcKeyPair, OutRpcKeyPair, FreeRpcKeyPair)
1543 	DECLARE_RPC_EX("GetServerCert", RPC_KEY_PAIR, StGetServerCert, InRpcKeyPair, OutRpcKeyPair, FreeRpcKeyPair)
1544 	DECLARE_RPC_EX("GetServerCipherList", RPC_STR, StGetServerCipherList, InRpcStr, OutRpcStr, FreeRpcStr)
1545 	DECLARE_RPC_EX("GetServerCipher", RPC_STR, StGetServerCipher, InRpcStr, OutRpcStr, FreeRpcStr)
1546 	DECLARE_RPC_EX("SetServerCipher", RPC_STR, StSetServerCipher, InRpcStr, OutRpcStr, FreeRpcStr)
1547 	DECLARE_RPC_EX("AddWgk", RPC_WGK, StAddWgk, InRpcWgk, OutRpcWgk, FreeRpcWgk)
1548 	DECLARE_RPC_EX("DeleteWgk", RPC_WGK, StDeleteWgk, InRpcWgk, OutRpcWgk, FreeRpcWgk)
1549 	DECLARE_RPC_EX("EnumWgk", RPC_WGK, StEnumWgk, InRpcWgk, OutRpcWgk, FreeRpcWgk)
1550 	DECLARE_RPC("CreateHub", RPC_CREATE_HUB, StCreateHub, InRpcCreateHub, OutRpcCreateHub)
1551 	DECLARE_RPC("SetHub", RPC_CREATE_HUB, StSetHub, InRpcCreateHub, OutRpcCreateHub)
1552 	DECLARE_RPC("GetHub", RPC_CREATE_HUB, StGetHub, InRpcCreateHub, OutRpcCreateHub)
1553 	DECLARE_RPC_EX("EnumHub", RPC_ENUM_HUB, StEnumHub, InRpcEnumHub, OutRpcEnumHub, FreeRpcEnumHub)
1554 	DECLARE_RPC("DeleteHub", RPC_DELETE_HUB, StDeleteHub, InRpcDeleteHub, OutRpcDeleteHub)
1555 	DECLARE_RPC("GetHubRadius", RPC_RADIUS, StGetHubRadius, InRpcRadius, OutRpcRadius)
1556 	DECLARE_RPC("SetHubRadius", RPC_RADIUS, StSetHubRadius, InRpcRadius, OutRpcRadius)
1557 	DECLARE_RPC_EX("EnumConnection", RPC_ENUM_CONNECTION, StEnumConnection, InRpcEnumConnection, OutRpcEnumConnection, FreeRpcEnumConnection)
1558 	DECLARE_RPC("DisconnectConnection", RPC_DISCONNECT_CONNECTION, StDisconnectConnection, InRpcDisconnectConnection, OutRpcDisconnectConnection)
1559 	DECLARE_RPC("GetConnectionInfo", RPC_CONNECTION_INFO, StGetConnectionInfo, InRpcConnectionInfo, OutRpcConnectionInfo)
1560 	DECLARE_RPC("SetHubOnline", RPC_SET_HUB_ONLINE, StSetHubOnline, InRpcSetHubOnline, OutRpcSetHubOnline)
1561 	DECLARE_RPC("GetHubStatus", RPC_HUB_STATUS, StGetHubStatus, InRpcHubStatus, OutRpcHubStatus)
1562 	DECLARE_RPC("SetHubLog", RPC_HUB_LOG, StSetHubLog, InRpcHubLog, OutRpcHubLog)
1563 	DECLARE_RPC("GetHubLog", RPC_HUB_LOG, StGetHubLog, InRpcHubLog, OutRpcHubLog)
1564 	DECLARE_RPC_EX("AddCa", RPC_HUB_ADD_CA, StAddCa, InRpcHubAddCa, OutRpcHubAddCa, FreeRpcHubAddCa)
1565 	DECLARE_RPC_EX("EnumCa", RPC_HUB_ENUM_CA, StEnumCa, InRpcHubEnumCa, OutRpcHubEnumCa, FreeRpcHubEnumCa)
1566 	DECLARE_RPC_EX("GetCa", RPC_HUB_GET_CA, StGetCa, InRpcHubGetCa, OutRpcHubGetCa, FreeRpcHubGetCa)
1567 	DECLARE_RPC("DeleteCa", RPC_HUB_DELETE_CA, StDeleteCa, InRpcHubDeleteCa, OutRpcHubDeleteCa)
1568 	DECLARE_RPC("SetLinkOnline", RPC_LINK, StSetLinkOnline, InRpcLink, OutRpcLink)
1569 	DECLARE_RPC("SetLinkOffline", RPC_LINK, StSetLinkOffline, InRpcLink, OutRpcLink)
1570 	DECLARE_RPC("DeleteLink", RPC_LINK, StDeleteLink, InRpcLink, OutRpcLink)
1571 	DECLARE_RPC("RenameLink", RPC_RENAME_LINK, StRenameLink, InRpcRenameLink, OutRpcRenameLink)
1572 	DECLARE_RPC_EX("CreateLink", RPC_CREATE_LINK, StCreateLink, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)
1573 	DECLARE_RPC_EX("GetLink", RPC_CREATE_LINK, StGetLink, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)
1574 	DECLARE_RPC_EX("SetLink", RPC_CREATE_LINK, StSetLink, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)
1575 	DECLARE_RPC_EX("EnumLink", RPC_ENUM_LINK, StEnumLink, InRpcEnumLink, OutRpcEnumLink, FreeRpcEnumLink)
1576 	DECLARE_RPC_EX("GetLinkStatus", RPC_LINK_STATUS, StGetLinkStatus, InRpcLinkStatus, OutRpcLinkStatus, FreeRpcLinkStatus)
1577 	DECLARE_RPC("AddAccess", RPC_ADD_ACCESS, StAddAccess, InRpcAddAccess, OutRpcAddAccess)
1578 	DECLARE_RPC("DeleteAccess", RPC_DELETE_ACCESS, StDeleteAccess, InRpcDeleteAccess, OutRpcDeleteAccess)
1579 	DECLARE_RPC_EX("EnumAccess", RPC_ENUM_ACCESS_LIST, StEnumAccess, InRpcEnumAccessList, OutRpcEnumAccessList, FreeRpcEnumAccessList)
1580 	DECLARE_RPC_EX("SetAccessList", RPC_ENUM_ACCESS_LIST, StSetAccessList, InRpcEnumAccessList, OutRpcEnumAccessList, FreeRpcEnumAccessList)
1581 	DECLARE_RPC_EX("CreateUser", RPC_SET_USER, StCreateUser, InRpcSetUser, OutRpcSetUser, FreeRpcSetUser)
1582 	DECLARE_RPC_EX("SetUser", RPC_SET_USER, StSetUser, InRpcSetUser, OutRpcSetUser, FreeRpcSetUser)
1583 	DECLARE_RPC_EX("GetUser", RPC_SET_USER, StGetUser, InRpcSetUser, OutRpcSetUser, FreeRpcSetUser)
1584 	DECLARE_RPC("DeleteUser", RPC_DELETE_USER, StDeleteUser, InRpcDeleteUser, OutRpcDeleteUser)
1585 	DECLARE_RPC_EX("EnumUser", RPC_ENUM_USER, StEnumUser, InRpcEnumUser, OutRpcEnumUser, FreeRpcEnumUser)
1586 	DECLARE_RPC_EX("CreateGroup", RPC_SET_GROUP, StCreateGroup, InRpcSetGroup, OutRpcSetGroup, FreeRpcSetGroup)
1587 	DECLARE_RPC_EX("SetGroup", RPC_SET_GROUP, StSetGroup, InRpcSetGroup, OutRpcSetGroup, FreeRpcSetGroup)
1588 	DECLARE_RPC_EX("GetGroup", RPC_SET_GROUP, StGetGroup, InRpcSetGroup, OutRpcSetGroup, FreeRpcSetGroup)
1589 	DECLARE_RPC("DeleteGroup", RPC_DELETE_USER, StDeleteGroup, InRpcDeleteUser, OutRpcDeleteUser)
1590 	DECLARE_RPC_EX("EnumGroup", RPC_ENUM_GROUP, StEnumGroup, InRpcEnumGroup, OutRpcEnumGroup, FreeRpcEnumGroup)
1591 	DECLARE_RPC_EX("EnumSession", RPC_ENUM_SESSION, StEnumSession, InRpcEnumSession, OutRpcEnumSession, FreeRpcEnumSession)
1592 	DECLARE_RPC_EX("GetSessionStatus", RPC_SESSION_STATUS, StGetSessionStatus, InRpcSessionStatus, OutRpcSessionStatus, FreeRpcSessionStatus)
1593 	DECLARE_RPC("DeleteSession", RPC_DELETE_SESSION, StDeleteSession, InRpcDeleteSession, OutRpcDeleteSession)
1594 	DECLARE_RPC_EX("EnumMacTable", RPC_ENUM_MAC_TABLE, StEnumMacTable, InRpcEnumMacTable, OutRpcEnumMacTable, FreeRpcEnumMacTable)
1595 	DECLARE_RPC("DeleteMacTable", RPC_DELETE_TABLE, StDeleteMacTable, InRpcDeleteTable, OutRpcDeleteTable)
1596 	DECLARE_RPC_EX("EnumIpTable", RPC_ENUM_IP_TABLE, StEnumIpTable, InRpcEnumIpTable, OutRpcEnumIpTable, FreeRpcEnumIpTable)
1597 	DECLARE_RPC("DeleteIpTable", RPC_DELETE_TABLE, StDeleteIpTable, InRpcDeleteTable, OutRpcDeleteTable)
1598 	DECLARE_RPC("SetKeep", RPC_KEEP, StSetKeep, InRpcKeep, OutRpcKeep)
1599 	DECLARE_RPC("GetKeep", RPC_KEEP, StGetKeep, InRpcKeep, OutRpcKeep)
1600 	DECLARE_RPC("EnableSecureNAT", RPC_HUB, StEnableSecureNAT, InRpcHub, OutRpcHub)
1601 	DECLARE_RPC("DisableSecureNAT", RPC_HUB, StDisableSecureNAT, InRpcHub, OutRpcHub)
1602 	DECLARE_RPC("SetSecureNATOption", VH_OPTION, StSetSecureNATOption, InVhOption, OutVhOption)
1603 	DECLARE_RPC("GetSecureNATOption", VH_OPTION, StGetSecureNATOption, InVhOption, OutVhOption)
1604 	DECLARE_RPC_EX("EnumNAT", RPC_ENUM_NAT, StEnumNAT, InRpcEnumNat, OutRpcEnumNat, FreeRpcEnumNat)
1605 	DECLARE_RPC_EX("EnumDHCP", RPC_ENUM_DHCP, StEnumDHCP, InRpcEnumDhcp, OutRpcEnumDhcp, FreeRpcEnumDhcp)
1606 	DECLARE_RPC("GetSecureNATStatus", RPC_NAT_STATUS, StGetSecureNATStatus, InRpcNatStatus, OutRpcNatStatus)
1607 	DECLARE_RPC_EX("EnumEthernet", RPC_ENUM_ETH, StEnumEthernet, InRpcEnumEth, OutRpcEnumEth, FreeRpcEnumEth)
1608 	DECLARE_RPC("AddLocalBridge", RPC_LOCALBRIDGE, StAddLocalBridge, InRpcLocalBridge, OutRpcLocalBridge)
1609 	DECLARE_RPC("DeleteLocalBridge", RPC_LOCALBRIDGE, StDeleteLocalBridge, InRpcLocalBridge, OutRpcLocalBridge)
1610 	DECLARE_RPC_EX("EnumLocalBridge", RPC_ENUM_LOCALBRIDGE, StEnumLocalBridge, InRpcEnumLocalBridge, OutRpcEnumLocalBridge, FreeRpcEnumLocalBridge)
1611 	DECLARE_RPC("GetBridgeSupport", RPC_BRIDGE_SUPPORT, StGetBridgeSupport, InRpcBridgeSupport, OutRpcBridgeSupport)
1612 	DECLARE_RPC("RebootServer", RPC_TEST, StRebootServer, InRpcTest, OutRpcTest)
1613 	DECLARE_RPC_EX("GetCaps", CAPSLIST, StGetCaps, InRpcCapsList, OutRpcCapsList, FreeRpcCapsList)
1614 	DECLARE_RPC_EX("GetConfig", RPC_CONFIG, StGetConfig, InRpcConfig, OutRpcConfig, FreeRpcConfig)
1615 	DECLARE_RPC_EX("SetConfig", RPC_CONFIG, StSetConfig, InRpcConfig, OutRpcConfig, FreeRpcConfig)
1616 	DECLARE_RPC_EX("GetDefaultHubAdminOptions", RPC_ADMIN_OPTION, StGetDefaultHubAdminOptions, InRpcAdminOption, OutRpcAdminOption, FreeRpcAdminOption)
1617 	DECLARE_RPC_EX("GetHubAdminOptions", RPC_ADMIN_OPTION, StGetHubAdminOptions, InRpcAdminOption, OutRpcAdminOption, FreeRpcAdminOption)
1618 	DECLARE_RPC_EX("SetHubAdminOptions", RPC_ADMIN_OPTION, StSetHubAdminOptions, InRpcAdminOption, OutRpcAdminOption, FreeRpcAdminOption)
1619 	DECLARE_RPC_EX("GetHubExtOptions", RPC_ADMIN_OPTION, StGetHubExtOptions, InRpcAdminOption, OutRpcAdminOption, FreeRpcAdminOption)
1620 	DECLARE_RPC_EX("SetHubExtOptions", RPC_ADMIN_OPTION, StSetHubExtOptions, InRpcAdminOption, OutRpcAdminOption, FreeRpcAdminOption)
1621 	DECLARE_RPC("AddL3Switch", RPC_L3SW, StAddL3Switch, InRpcL3Sw, OutRpcL3Sw)
1622 	DECLARE_RPC("DelL3Switch", RPC_L3SW, StDelL3Switch, InRpcL3Sw, OutRpcL3Sw)
1623 	DECLARE_RPC_EX("EnumL3Switch", RPC_ENUM_L3SW, StEnumL3Switch, InRpcEnumL3Sw, OutRpcEnumL3Sw, FreeRpcEnumL3Sw)
1624 	DECLARE_RPC("StartL3Switch", RPC_L3SW, StStartL3Switch, InRpcL3Sw, OutRpcL3Sw)
1625 	DECLARE_RPC("StopL3Switch", RPC_L3SW, StStopL3Switch, InRpcL3Sw, OutRpcL3Sw)
1626 	DECLARE_RPC("AddL3If", RPC_L3IF, StAddL3If, InRpcL3If, OutRpcL3If)
1627 	DECLARE_RPC("DelL3If", RPC_L3IF, StDelL3If, InRpcL3If, OutRpcL3If)
1628 	DECLARE_RPC_EX("EnumL3If", RPC_ENUM_L3IF, StEnumL3If, InRpcEnumL3If, OutRpcEnumL3If, FreeRpcEnumL3If)
1629 	DECLARE_RPC("AddL3Table", RPC_L3TABLE, StAddL3Table, InRpcL3Table, OutRpcL3Table)
1630 	DECLARE_RPC("DelL3Table", RPC_L3TABLE, StDelL3Table, InRpcL3Table, OutRpcL3Table)
1631 	DECLARE_RPC_EX("EnumL3Table", RPC_ENUM_L3TABLE, StEnumL3Table, InRpcEnumL3Table, OutRpcEnumL3Table, FreeRpcEnumL3Table)
1632 	DECLARE_RPC_EX("EnumCrl", RPC_ENUM_CRL, StEnumCrl, InRpcEnumCrl, OutRpcEnumCrl, FreeRpcEnumCrl)
1633 	DECLARE_RPC_EX("AddCrl", RPC_CRL, StAddCrl, InRpcCrl, OutRpcCrl, FreeRpcCrl)
1634 	DECLARE_RPC_EX("DelCrl", RPC_CRL, StDelCrl, InRpcCrl, OutRpcCrl, FreeRpcCrl)
1635 	DECLARE_RPC_EX("GetCrl", RPC_CRL, StGetCrl, InRpcCrl, OutRpcCrl, FreeRpcCrl)
1636 	DECLARE_RPC_EX("SetCrl", RPC_CRL, StSetCrl, InRpcCrl, OutRpcCrl, FreeRpcCrl)
1637 	DECLARE_RPC_EX("SetAcList", RPC_AC_LIST, StSetAcList, InRpcAcList, OutRpcAcList, FreeRpcAcList)
1638 	DECLARE_RPC_EX("GetAcList", RPC_AC_LIST, StGetAcList, InRpcAcList, OutRpcAcList, FreeRpcAcList)
1639 	DECLARE_RPC_EX("EnumLogFile", RPC_ENUM_LOG_FILE, StEnumLogFile, InRpcEnumLogFile, OutRpcEnumLogFile, FreeRpcEnumLogFile)
1640 	DECLARE_RPC_EX("ReadLogFile", RPC_READ_LOG_FILE, StReadLogFile, InRpcReadLogFile, OutRpcReadLogFile, FreeRpcReadLogFile)
1641 	DECLARE_RPC("AddLicenseKey", RPC_TEST, StAddLicenseKey, InRpcTest, OutRpcTest)
1642 	DECLARE_RPC("DelLicenseKey", RPC_TEST, StDelLicenseKey, InRpcTest, OutRpcTest)
1643 	DECLARE_RPC_EX("EnumLicenseKey", RPC_ENUM_LICENSE_KEY, StEnumLicenseKey, InRpcEnumLicenseKey, OutRpcEnumLicenseKey, FreeRpcEnumLicenseKey)
1644 	DECLARE_RPC("GetLicenseStatus", RPC_LICENSE_STATUS, StGetLicenseStatus, InRpcLicenseStatus, OutRpcLicenseStatus)
1645 	DECLARE_RPC("SetSysLog", SYSLOG_SETTING, StSetSysLog, InRpcSysLogSetting, OutRpcSysLogSetting)
1646 	DECLARE_RPC("GetSysLog", SYSLOG_SETTING, StGetSysLog, InRpcSysLogSetting, OutRpcSysLogSetting)
1647 	DECLARE_RPC_EX("EnumEthVLan", RPC_ENUM_ETH_VLAN, StEnumEthVLan, InRpcEnumEthVLan, OutRpcEnumEthVLan, FreeRpcEnumEthVLan)
1648 	DECLARE_RPC("SetEnableEthVLan", RPC_TEST, StSetEnableEthVLan, InRpcTest, OutRpcTest)
1649 	DECLARE_RPC_EX("SetHubMsg", RPC_MSG, StSetHubMsg, InRpcMsg, OutRpcMsg, FreeRpcMsg)
1650 	DECLARE_RPC_EX("GetHubMsg", RPC_MSG, StGetHubMsg, InRpcMsg, OutRpcMsg, FreeRpcMsg)
1651 	DECLARE_RPC("Crash", RPC_TEST, StCrash, InRpcTest, OutRpcTest)
1652 	DECLARE_RPC_EX("GetAdminMsg", RPC_MSG, StGetAdminMsg, InRpcMsg, OutRpcMsg, FreeRpcMsg)
1653 	DECLARE_RPC("Flush", RPC_TEST, StFlush, InRpcTest, OutRpcTest)
1654 	DECLARE_RPC("Debug", RPC_TEST, StDebug, InRpcTest, OutRpcTest)
1655 	DECLARE_RPC("SetIPsecServices", IPSEC_SERVICES, StSetIPsecServices, InIPsecServices, OutIPsecServices)
1656 	DECLARE_RPC("GetIPsecServices", IPSEC_SERVICES, StGetIPsecServices, InIPsecServices, OutIPsecServices)
1657 	DECLARE_RPC("AddEtherIpId", ETHERIP_ID, StAddEtherIpId, InEtherIpId, OutEtherIpId)
1658 	DECLARE_RPC("GetEtherIpId", ETHERIP_ID, StGetEtherIpId, InEtherIpId, OutEtherIpId)
1659 	DECLARE_RPC("DeleteEtherIpId", ETHERIP_ID, StDeleteEtherIpId, InEtherIpId, OutEtherIpId)
1660 	DECLARE_RPC_EX("EnumEtherIpId", RPC_ENUM_ETHERIP_ID, StEnumEtherIpId, InRpcEnumEtherIpId, OutRpcEnumEtherIpId, FreeRpcEnumEtherIpId)
1661 	DECLARE_RPC("SetOpenVpnSstpConfig", OPENVPN_SSTP_CONFIG, StSetOpenVpnSstpConfig, InOpenVpnSstpConfig, OutOpenVpnSstpConfig)
1662 	DECLARE_RPC("GetOpenVpnSstpConfig", OPENVPN_SSTP_CONFIG, StGetOpenVpnSstpConfig, InOpenVpnSstpConfig, OutOpenVpnSstpConfig)
1663 	DECLARE_RPC("GetDDnsClientStatus", DDNS_CLIENT_STATUS, StGetDDnsClientStatus, InDDnsClientStatus, OutDDnsClientStatus)
1664 	DECLARE_RPC("ChangeDDnsClientHostname", RPC_TEST, StChangeDDnsClientHostname, InRpcTest, OutRpcTest)
1665 	DECLARE_RPC("RegenerateServerCert", RPC_TEST, StRegenerateServerCert, InRpcTest, OutRpcTest)
1666 	DECLARE_RPC_EX("MakeOpenVpnConfigFile", RPC_READ_LOG_FILE, StMakeOpenVpnConfigFile, InRpcReadLogFile, OutRpcReadLogFile, FreeRpcReadLogFile)
1667 	DECLARE_RPC("SetSpecialListener", RPC_SPECIAL_LISTENER, StSetSpecialListener, InRpcSpecialListener, OutRpcSpecialListener)
1668 	DECLARE_RPC("GetSpecialListener", RPC_SPECIAL_LISTENER, StGetSpecialListener, InRpcSpecialListener, OutRpcSpecialListener)
1669 	DECLARE_RPC("GetAzureStatus", RPC_AZURE_STATUS, StGetAzureStatus, InRpcAzureStatus, OutRpcAzureStatus)
1670 	DECLARE_RPC("SetAzureStatus", RPC_AZURE_STATUS, StSetAzureStatus, InRpcAzureStatus, OutRpcAzureStatus)
1671 	DECLARE_RPC("GetDDnsInternetSettng", INTERNET_SETTING, StGetDDnsInternetSetting, InRpcInternetSetting, OutRpcInternetSetting)
1672 	DECLARE_RPC("SetDDnsInternetSettng", INTERNET_SETTING, StSetDDnsInternetSetting, InRpcInternetSetting, OutRpcInternetSetting)
1673 	// RPC function declaration: till here
1674 
1675 
1676 	if (ok == false)
1677 	{
1678 		err = ERR_NOT_SUPPORTED;
1679 	}
1680 
1681 	if (err != ERR_NO_ERROR)
1682 	{
1683 		PackAddInt(ret, "error", err);
1684 	}
1685 
1686 	if (true)
1687 	{
1688 		char tmp[MAX_PATH];
1689 		char ip[MAX_PATH];
1690 		UINT rpc_id = 0;
1691 
1692 		StrCpy(ip, sizeof(ip), "Unknown");
1693 
1694 		if (rpc->Sock != NULL)
1695 		{
1696 			IPToStr(ip, sizeof(ip), &rpc->Sock->RemoteIP);
1697 			rpc_id = rpc->Sock->socket;
1698 		}
1699 
1700 		Format(tmp, sizeof(tmp), "RPC: RPC-%u (%s): Leaving RPC [%s] (Error: %u).",
1701 			rpc_id, ip, name, err);
1702 
1703 		SiDebugLog(a->Server, tmp);
1704 	}
1705 
1706 	Unlock(cedar->CedarSuperLock);
1707 
1708 	return ret;
1709 }
1710 
1711 // RPC call function declaration: from here
1712 DECLARE_SC_EX("Test", RPC_TEST, ScTest, InRpcTest, OutRpcTest, FreeRpcTest)
1713 DECLARE_SC_EX("GetServerInfo", RPC_SERVER_INFO, ScGetServerInfo, InRpcServerInfo, OutRpcServerInfo, FreeRpcServerInfo)
1714 DECLARE_SC("GetServerStatus", RPC_SERVER_STATUS, ScGetServerStatus, InRpcServerStatus, OutRpcServerStatus)
1715 DECLARE_SC("CreateListener", RPC_LISTENER, ScCreateListener, InRpcListener, OutRpcListener)
1716 DECLARE_SC_EX("EnumListener", RPC_LISTENER_LIST, ScEnumListener, InRpcListenerList, OutRpcListenerList, FreeRpcListenerList)
1717 DECLARE_SC("DeleteListener", RPC_LISTENER, ScDeleteListener, InRpcListener, OutRpcListener)
1718 DECLARE_SC("EnableListener", RPC_LISTENER, ScEnableListener, InRpcListener, OutRpcListener)
1719 DECLARE_SC_EX("SetPortsUDP", RPC_PORTS, ScSetPortsUDP, InRpcPorts, OutRpcPorts, FreeRpcPorts)
1720 DECLARE_SC_EX("GetPortsUDP", RPC_PORTS, ScGetPortsUDP, InRpcPorts, OutRpcPorts, FreeRpcPorts)
1721 DECLARE_SC_EX("SetProtoOptions", RPC_PROTO_OPTIONS, ScSetProtoOptions, InRpcProtoOptions, OutRpcProtoOptions, FreeRpcProtoOptions)
1722 DECLARE_SC_EX("GetProtoOptions", RPC_PROTO_OPTIONS, ScGetProtoOptions, InRpcProtoOptions, OutRpcProtoOptions, FreeRpcProtoOptions)
1723 DECLARE_SC("SetServerPassword", RPC_SET_PASSWORD, ScSetServerPassword, InRpcSetPassword, OutRpcSetPassword)
1724 DECLARE_SC_EX("SetFarmSetting", RPC_FARM, ScSetFarmSetting, InRpcFarm, OutRpcFarm, FreeRpcFarm)
1725 DECLARE_SC_EX("GetFarmSetting", RPC_FARM, ScGetFarmSetting, InRpcFarm, OutRpcFarm, FreeRpcFarm)
1726 DECLARE_SC_EX("GetFarmInfo", RPC_FARM_INFO, ScGetFarmInfo, InRpcFarmInfo, OutRpcFarmInfo, FreeRpcFarmInfo)
1727 DECLARE_SC_EX("EnumFarmMember", RPC_ENUM_FARM, ScEnumFarmMember, InRpcEnumFarm, OutRpcEnumFarm, FreeRpcEnumFarm)
1728 DECLARE_SC("GetFarmConnectionStatus", RPC_FARM_CONNECTION_STATUS, ScGetFarmConnectionStatus, InRpcFarmConnectionStatus, OutRpcFarmConnectionStatus)
1729 DECLARE_SC_EX("SetServerCert", RPC_KEY_PAIR, ScSetServerCert, InRpcKeyPair, OutRpcKeyPair, FreeRpcKeyPair)
1730 DECLARE_SC_EX("GetServerCert", RPC_KEY_PAIR, ScGetServerCert, InRpcKeyPair, OutRpcKeyPair, FreeRpcKeyPair)
1731 DECLARE_SC_EX("GetServerCipherList", RPC_STR, ScGetServerCipherList, InRpcStr, OutRpcStr, FreeRpcStr)
1732 DECLARE_SC_EX("GetServerCipher", RPC_STR, ScGetServerCipher, InRpcStr, OutRpcStr, FreeRpcStr)
1733 DECLARE_SC_EX("SetServerCipher", RPC_STR, ScSetServerCipher, InRpcStr, OutRpcStr, FreeRpcStr)
1734 DECLARE_SC_EX("AddWgk", RPC_WGK, ScAddWgk, InRpcWgk, OutRpcWgk, FreeRpcWgk)
1735 DECLARE_SC_EX("DeleteWgk", RPC_WGK, ScDeleteWgk, InRpcWgk, OutRpcWgk, FreeRpcWgk)
1736 DECLARE_SC_EX("EnumWgk", RPC_WGK, ScEnumWgk, InRpcWgk, OutRpcWgk, FreeRpcWgk)
1737 DECLARE_SC("CreateHub", RPC_CREATE_HUB, ScCreateHub, InRpcCreateHub, OutRpcCreateHub)
1738 DECLARE_SC("SetHub", RPC_CREATE_HUB, ScSetHub, InRpcCreateHub, OutRpcCreateHub)
1739 DECLARE_SC("GetHub", RPC_CREATE_HUB, ScGetHub, InRpcCreateHub, OutRpcCreateHub)
1740 DECLARE_SC_EX("EnumHub", RPC_ENUM_HUB, ScEnumHub, InRpcEnumHub, OutRpcEnumHub, FreeRpcEnumHub)
1741 DECLARE_SC("DeleteHub", RPC_DELETE_HUB, ScDeleteHub, InRpcDeleteHub, OutRpcDeleteHub)
1742 DECLARE_SC("GetHubRadius", RPC_RADIUS, ScGetHubRadius, InRpcRadius, OutRpcRadius)
1743 DECLARE_SC("SetHubRadius", RPC_RADIUS, ScSetHubRadius, InRpcRadius, OutRpcRadius)
1744 DECLARE_SC_EX("EnumConnection", RPC_ENUM_CONNECTION, ScEnumConnection, InRpcEnumConnection, OutRpcEnumConnection, FreeRpcEnumConnection)
1745 DECLARE_SC("DisconnectConnection", RPC_DISCONNECT_CONNECTION, ScDisconnectConnection, InRpcDisconnectConnection, OutRpcDisconnectConnection)
1746 DECLARE_SC("GetConnectionInfo", RPC_CONNECTION_INFO, ScGetConnectionInfo, InRpcConnectionInfo, OutRpcConnectionInfo)
1747 DECLARE_SC("SetHubOnline", RPC_SET_HUB_ONLINE, ScSetHubOnline, InRpcSetHubOnline, OutRpcSetHubOnline)
1748 DECLARE_SC("GetHubStatus", RPC_HUB_STATUS, ScGetHubStatus, InRpcHubStatus, OutRpcHubStatus)
1749 DECLARE_SC("SetHubLog", RPC_HUB_LOG, ScSetHubLog, InRpcHubLog, OutRpcHubLog)
1750 DECLARE_SC("GetHubLog", RPC_HUB_LOG, ScGetHubLog, InRpcHubLog, OutRpcHubLog)
1751 DECLARE_SC_EX("AddCa", RPC_HUB_ADD_CA, ScAddCa, InRpcHubAddCa, OutRpcHubAddCa, FreeRpcHubAddCa)
1752 DECLARE_SC_EX("EnumCa", RPC_HUB_ENUM_CA, ScEnumCa, InRpcHubEnumCa, OutRpcHubEnumCa, FreeRpcHubEnumCa)
1753 DECLARE_SC_EX("GetCa", RPC_HUB_GET_CA, ScGetCa, InRpcHubGetCa, OutRpcHubGetCa, FreeRpcHubGetCa)
1754 DECLARE_SC("DeleteCa", RPC_HUB_DELETE_CA, ScDeleteCa, InRpcHubDeleteCa, OutRpcHubDeleteCa)
1755 DECLARE_SC_EX("CreateLink", RPC_CREATE_LINK, ScCreateLink, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)
1756 DECLARE_SC_EX("GetLink", RPC_CREATE_LINK, ScGetLink, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)
1757 DECLARE_SC_EX("SetLink", RPC_CREATE_LINK, ScSetLink, InRpcCreateLink, OutRpcCreateLink, FreeRpcCreateLink)
1758 DECLARE_SC_EX("EnumLink", RPC_ENUM_LINK, ScEnumLink, InRpcEnumLink, OutRpcEnumLink, FreeRpcEnumLink)
1759 DECLARE_SC_EX("GetLinkStatus", RPC_LINK_STATUS, ScGetLinkStatus, InRpcLinkStatus, OutRpcLinkStatus, FreeRpcLinkStatus)
1760 DECLARE_SC("SetLinkOnline", RPC_LINK, ScSetLinkOnline, InRpcLink, OutRpcLink)
1761 DECLARE_SC("SetLinkOffline", RPC_LINK, ScSetLinkOffline, InRpcLink, OutRpcLink)
1762 DECLARE_SC("DeleteLink", RPC_LINK, ScDeleteLink, InRpcLink, OutRpcLink)
1763 DECLARE_SC("RenameLink", RPC_RENAME_LINK, ScRenameLink, InRpcRenameLink, OutRpcRenameLink)
1764 DECLARE_SC("AddAccess", RPC_ADD_ACCESS, ScAddAccess, InRpcAddAccess, OutRpcAddAccess)
1765 DECLARE_SC("DeleteAccess", RPC_DELETE_ACCESS, ScDeleteAccess, InRpcDeleteAccess, OutRpcDeleteAccess)
1766 DECLARE_SC_EX("EnumAccess", RPC_ENUM_ACCESS_LIST, ScEnumAccess, InRpcEnumAccessList, OutRpcEnumAccessList, FreeRpcEnumAccessList)
1767 DECLARE_SC_EX("SetAccessList", RPC_ENUM_ACCESS_LIST, ScSetAccessList, InRpcEnumAccessList, OutRpcEnumAccessList, FreeRpcEnumAccessList)
1768 DECLARE_SC_EX("CreateUser", RPC_SET_USER, ScCreateUser, InRpcSetUser, OutRpcSetUser, FreeRpcSetUser)
1769 DECLARE_SC_EX("SetUser", RPC_SET_USER, ScSetUser, InRpcSetUser, OutRpcSetUser, FreeRpcSetUser)
1770 DECLARE_SC_EX("GetUser", RPC_SET_USER, ScGetUser, InRpcSetUser, OutRpcSetUser, FreeRpcSetUser)
1771 DECLARE_SC("DeleteUser", RPC_DELETE_USER, ScDeleteUser, InRpcDeleteUser, OutRpcDeleteUser)
1772 DECLARE_SC_EX("EnumUser", RPC_ENUM_USER, ScEnumUser, InRpcEnumUser, OutRpcEnumUser, FreeRpcEnumUser)
1773 DECLARE_SC_EX("CreateGroup", RPC_SET_GROUP, ScCreateGroup, InRpcSetGroup, OutRpcSetGroup, FreeRpcSetGroup)
1774 DECLARE_SC_EX("SetGroup", RPC_SET_GROUP, ScSetGroup, InRpcSetGroup, OutRpcSetGroup, FreeRpcSetGroup)
1775 DECLARE_SC_EX("GetGroup", RPC_SET_GROUP, ScGetGroup, InRpcSetGroup, OutRpcSetGroup, FreeRpcSetGroup)
1776 DECLARE_SC("DeleteGroup", RPC_DELETE_USER, ScDeleteGroup, InRpcDeleteUser, OutRpcDeleteUser)
1777 DECLARE_SC_EX("EnumGroup", RPC_ENUM_GROUP, ScEnumGroup, InRpcEnumGroup, OutRpcEnumGroup, FreeRpcEnumGroup)
1778 DECLARE_SC_EX("EnumSession", RPC_ENUM_SESSION, ScEnumSession, InRpcEnumSession, OutRpcEnumSession, FreeRpcEnumSession)
1779 DECLARE_SC_EX("GetSessionStatus", RPC_SESSION_STATUS, ScGetSessionStatus, InRpcSessionStatus, OutRpcSessionStatus, FreeRpcSessionStatus)
1780 DECLARE_SC("DeleteSession", RPC_DELETE_SESSION, ScDeleteSession, InRpcDeleteSession, OutRpcDeleteSession)
1781 DECLARE_SC_EX("EnumMacTable", RPC_ENUM_MAC_TABLE, ScEnumMacTable, InRpcEnumMacTable, OutRpcEnumMacTable, FreeRpcEnumMacTable)
1782 DECLARE_SC("DeleteMacTable", RPC_DELETE_TABLE, ScDeleteMacTable, InRpcDeleteTable, OutRpcDeleteTable)
1783 DECLARE_SC_EX("EnumIpTable", RPC_ENUM_IP_TABLE, ScEnumIpTable, InRpcEnumIpTable, OutRpcEnumIpTable, FreeRpcEnumIpTable)
1784 DECLARE_SC("DeleteIpTable", RPC_DELETE_TABLE, ScDeleteIpTable, InRpcDeleteTable, OutRpcDeleteTable)
1785 DECLARE_SC("SetKeep", RPC_KEEP, ScSetKeep, InRpcKeep, OutRpcKeep)
1786 DECLARE_SC("GetKeep", RPC_KEEP, ScGetKeep, InRpcKeep, OutRpcKeep)
1787 DECLARE_SC("EnableSecureNAT", RPC_HUB, ScEnableSecureNAT, InRpcHub, OutRpcHub)
1788 DECLARE_SC("DisableSecureNAT", RPC_HUB, ScDisableSecureNAT, InRpcHub, OutRpcHub)
1789 DECLARE_SC("SetSecureNATOption", VH_OPTION, ScSetSecureNATOption, InVhOption, OutVhOption)
1790 DECLARE_SC("GetSecureNATOption", VH_OPTION, ScGetSecureNATOption, InVhOption, OutVhOption)
1791 DECLARE_SC_EX("EnumNAT", RPC_ENUM_NAT, ScEnumNAT, InRpcEnumNat, OutRpcEnumNat, FreeRpcEnumNat)
1792 DECLARE_SC_EX("EnumDHCP", RPC_ENUM_DHCP, ScEnumDHCP, InRpcEnumDhcp, OutRpcEnumDhcp, FreeRpcEnumDhcp)
1793 DECLARE_SC("GetSecureNATStatus", RPC_NAT_STATUS, ScGetSecureNATStatus, InRpcNatStatus, OutRpcNatStatus)
1794 DECLARE_SC_EX("EnumEthernet", RPC_ENUM_ETH, ScEnumEthernet, InRpcEnumEth, OutRpcEnumEth, FreeRpcEnumEth)
1795 DECLARE_SC("AddLocalBridge", RPC_LOCALBRIDGE, ScAddLocalBridge, InRpcLocalBridge, OutRpcLocalBridge)
1796 DECLARE_SC("DeleteLocalBridge", RPC_LOCALBRIDGE, ScDeleteLocalBridge, InRpcLocalBridge, OutRpcLocalBridge)
1797 DECLARE_SC_EX("EnumLocalBridge", RPC_ENUM_LOCALBRIDGE, ScEnumLocalBridge, InRpcEnumLocalBridge, OutRpcEnumLocalBridge, FreeRpcEnumLocalBridge)
1798 DECLARE_SC("GetBridgeSupport", RPC_BRIDGE_SUPPORT, ScGetBridgeSupport, InRpcBridgeSupport, OutRpcBridgeSupport)
1799 DECLARE_SC("RebootServer", RPC_TEST, ScRebootServer, InRpcTest, OutRpcTest)
1800 DECLARE_SC_EX("GetCaps", CAPSLIST, ScGetCaps, InRpcCapsList, OutRpcCapsList, FreeRpcCapsList)
1801 DECLARE_SC_EX("GetConfig", RPC_CONFIG, ScGetConfig, InRpcConfig, OutRpcConfig, FreeRpcConfig)
1802 DECLARE_SC_EX("SetConfig", RPC_CONFIG, ScSetConfig, InRpcConfig, OutRpcConfig, FreeRpcConfig)
1803 DECLARE_SC_EX("GetHubAdminOptions", RPC_ADMIN_OPTION, ScGetHubAdminOptions, InRpcAdminOption, OutRpcAdminOption, FreeRpcAdminOption)
1804 DECLARE_SC_EX("SetHubAdminOptions", RPC_ADMIN_OPTION, ScSetHubAdminOptions, InRpcAdminOption, OutRpcAdminOption, FreeRpcAdminOption)
1805 DECLARE_SC_EX("GetHubExtOptions", RPC_ADMIN_OPTION, ScGetHubExtOptions, InRpcAdminOption, OutRpcAdminOption, FreeRpcAdminOption)
1806 DECLARE_SC_EX("SetHubExtOptions", RPC_ADMIN_OPTION, ScSetHubExtOptions, InRpcAdminOption, OutRpcAdminOption, FreeRpcAdminOption)
1807 DECLARE_SC_EX("GetDefaultHubAdminOptions", RPC_ADMIN_OPTION, ScGetDefaultHubAdminOptions, InRpcAdminOption, OutRpcAdminOption, FreeRpcAdminOption)
1808 DECLARE_SC("AddL3Switch", RPC_L3SW, ScAddL3Switch, InRpcL3Sw, OutRpcL3Sw)
1809 DECLARE_SC("DelL3Switch", RPC_L3SW, ScDelL3Switch, InRpcL3Sw, OutRpcL3Sw)
1810 DECLARE_SC_EX("EnumL3Switch", RPC_ENUM_L3SW, ScEnumL3Switch, InRpcEnumL3Sw, OutRpcEnumL3Sw, FreeRpcEnumL3Sw)
1811 DECLARE_SC("StartL3Switch", RPC_L3SW, ScStartL3Switch, InRpcL3Sw, OutRpcL3Sw)
1812 DECLARE_SC("StopL3Switch", RPC_L3SW, ScStopL3Switch, InRpcL3Sw, OutRpcL3Sw)
1813 DECLARE_SC("AddL3If", RPC_L3IF, ScAddL3If, InRpcL3If, OutRpcL3If)
1814 DECLARE_SC("DelL3If", RPC_L3IF, ScDelL3If, InRpcL3If, OutRpcL3If)
1815 DECLARE_SC_EX("EnumL3If", RPC_ENUM_L3IF, ScEnumL3If, InRpcEnumL3If, OutRpcEnumL3If, FreeRpcEnumL3If)
1816 DECLARE_SC("AddL3Table", RPC_L3TABLE, ScAddL3Table, InRpcL3Table, OutRpcL3Table)
1817 DECLARE_SC("DelL3Table", RPC_L3TABLE, ScDelL3Table, InRpcL3Table, OutRpcL3Table)
1818 DECLARE_SC_EX("EnumL3Table", RPC_ENUM_L3TABLE, ScEnumL3Table, InRpcEnumL3Table, OutRpcEnumL3Table, FreeRpcEnumL3Table)
1819 DECLARE_SC_EX("EnumCrl", RPC_ENUM_CRL, ScEnumCrl, InRpcEnumCrl, OutRpcEnumCrl, FreeRpcEnumCrl)
1820 DECLARE_SC_EX("AddCrl", RPC_CRL, ScAddCrl, InRpcCrl, OutRpcCrl, FreeRpcCrl)
1821 DECLARE_SC_EX("DelCrl", RPC_CRL, ScDelCrl, InRpcCrl, OutRpcCrl, FreeRpcCrl)
1822 DECLARE_SC_EX("GetCrl", RPC_CRL, ScGetCrl, InRpcCrl, OutRpcCrl, FreeRpcCrl)
1823 DECLARE_SC_EX("SetCrl", RPC_CRL, ScSetCrl, InRpcCrl, OutRpcCrl, FreeRpcCrl)
1824 DECLARE_SC_EX("SetAcList", RPC_AC_LIST, ScSetAcList, InRpcAcList, OutRpcAcList, FreeRpcAcList)
1825 DECLARE_SC_EX("GetAcList", RPC_AC_LIST, ScGetAcList, InRpcAcList, OutRpcAcList, FreeRpcAcList)
1826 DECLARE_SC_EX("EnumLogFile", RPC_ENUM_LOG_FILE, ScEnumLogFile, InRpcEnumLogFile, OutRpcEnumLogFile, FreeRpcEnumLogFile)
1827 DECLARE_SC_EX("ReadLogFile", RPC_READ_LOG_FILE, ScReadLogFile, InRpcReadLogFile, OutRpcReadLogFile, FreeRpcReadLogFile)
1828 DECLARE_SC("AddLicenseKey", RPC_TEST, ScAddLicenseKey, InRpcTest, OutRpcTest)
1829 DECLARE_SC("DelLicenseKey", RPC_TEST, ScDelLicenseKey, InRpcTest, OutRpcTest)
1830 DECLARE_SC_EX("EnumLicenseKey", RPC_ENUM_LICENSE_KEY, ScEnumLicenseKey, InRpcEnumLicenseKey, OutRpcEnumLicenseKey, FreeRpcEnumLicenseKey)
1831 DECLARE_SC("GetLicenseStatus", RPC_LICENSE_STATUS, ScGetLicenseStatus, InRpcLicenseStatus, OutRpcLicenseStatus)
1832 DECLARE_SC("SetSysLog", SYSLOG_SETTING, ScSetSysLog, InRpcSysLogSetting, OutRpcSysLogSetting)
1833 DECLARE_SC("GetSysLog", SYSLOG_SETTING, ScGetSysLog, InRpcSysLogSetting, OutRpcSysLogSetting)
1834 DECLARE_SC_EX("EnumEthVLan", RPC_ENUM_ETH_VLAN, ScEnumEthVLan, InRpcEnumEthVLan, OutRpcEnumEthVLan, FreeRpcEnumEthVLan)
1835 DECLARE_SC("SetEnableEthVLan", RPC_TEST, ScSetEnableEthVLan, InRpcTest, OutRpcTest)
1836 DECLARE_SC_EX("SetHubMsg", RPC_MSG, ScSetHubMsg, InRpcMsg, OutRpcMsg, FreeRpcMsg)
1837 DECLARE_SC_EX("GetHubMsg", RPC_MSG, ScGetHubMsg, InRpcMsg, OutRpcMsg, FreeRpcMsg)
1838 DECLARE_SC("Crash", RPC_TEST, ScCrash, InRpcTest, OutRpcTest)
1839 DECLARE_SC_EX("GetAdminMsg", RPC_MSG, ScGetAdminMsg, InRpcMsg, OutRpcMsg, FreeRpcMsg)
1840 DECLARE_SC("Flush", RPC_TEST, ScFlush, InRpcTest, OutRpcTest)
1841 DECLARE_SC("Debug", RPC_TEST, ScDebug, InRpcTest, OutRpcTest)
1842 DECLARE_SC("SetIPsecServices", IPSEC_SERVICES, ScSetIPsecServices, InIPsecServices, OutIPsecServices)
1843 DECLARE_SC("GetIPsecServices", IPSEC_SERVICES, ScGetIPsecServices, InIPsecServices, OutIPsecServices)
1844 DECLARE_SC("AddEtherIpId", ETHERIP_ID, ScAddEtherIpId, InEtherIpId, OutEtherIpId)
1845 DECLARE_SC("GetEtherIpId", ETHERIP_ID, ScGetEtherIpId, InEtherIpId, OutEtherIpId)
1846 DECLARE_SC("DeleteEtherIpId", ETHERIP_ID, ScDeleteEtherIpId, InEtherIpId, OutEtherIpId)
1847 DECLARE_SC_EX("EnumEtherIpId", RPC_ENUM_ETHERIP_ID, ScEnumEtherIpId, InRpcEnumEtherIpId, OutRpcEnumEtherIpId, FreeRpcEnumEtherIpId)
1848 DECLARE_SC("SetOpenVpnSstpConfig", OPENVPN_SSTP_CONFIG, ScSetOpenVpnSstpConfig, InOpenVpnSstpConfig, OutOpenVpnSstpConfig)
1849 DECLARE_SC("GetOpenVpnSstpConfig", OPENVPN_SSTP_CONFIG, ScGetOpenVpnSstpConfig, InOpenVpnSstpConfig, OutOpenVpnSstpConfig)
1850 DECLARE_SC("GetDDnsClientStatus", DDNS_CLIENT_STATUS, ScGetDDnsClientStatus, InDDnsClientStatus, OutDDnsClientStatus)
1851 DECLARE_SC("ChangeDDnsClientHostname", RPC_TEST, ScChangeDDnsClientHostname, InRpcTest, OutRpcTest)
1852 DECLARE_SC("RegenerateServerCert", RPC_TEST, ScRegenerateServerCert, InRpcTest, OutRpcTest)
1853 DECLARE_SC_EX("MakeOpenVpnConfigFile", RPC_READ_LOG_FILE, ScMakeOpenVpnConfigFile, InRpcReadLogFile, OutRpcReadLogFile, FreeRpcReadLogFile)
1854 DECLARE_SC("SetSpecialListener", RPC_SPECIAL_LISTENER, ScSetSpecialListener, InRpcSpecialListener, OutRpcSpecialListener)
1855 DECLARE_SC("GetSpecialListener", RPC_SPECIAL_LISTENER, ScGetSpecialListener, InRpcSpecialListener, OutRpcSpecialListener)
1856 DECLARE_SC("GetAzureStatus", RPC_AZURE_STATUS, ScGetAzureStatus, InRpcAzureStatus, OutRpcAzureStatus)
1857 DECLARE_SC("SetAzureStatus", RPC_AZURE_STATUS, ScSetAzureStatus, InRpcAzureStatus, OutRpcAzureStatus)
1858 DECLARE_SC("GetDDnsInternetSettng", INTERNET_SETTING, ScGetDDnsInternetSetting, InRpcInternetSetting, OutRpcInternetSetting)
1859 DECLARE_SC("SetDDnsInternetSettng", INTERNET_SETTING, ScSetDDnsInternetSetting, InRpcInternetSetting, OutRpcInternetSetting)
1860 // RPC call function declaration: till here
1861 
1862 // Setting VPN Gate Server Configuration
StSetVgsConfig(ADMIN * a,VGS_CONFIG * t)1863 UINT StSetVgsConfig(ADMIN *a, VGS_CONFIG *t)
1864 {
1865 	return ERR_NOT_SUPPORTED;
1866 }
1867 
1868 // Get VPN Gate configuration
StGetVgsConfig(ADMIN * a,VGS_CONFIG * t)1869 UINT StGetVgsConfig(ADMIN *a, VGS_CONFIG *t)
1870 {
1871 	return ERR_NOT_SUPPORTED;
1872 }
1873 
1874 // Get DDNS proxy configuration
StGetDDnsInternetSetting(ADMIN * a,INTERNET_SETTING * t)1875 UINT StGetDDnsInternetSetting(ADMIN *a, INTERNET_SETTING *t)
1876 {
1877 	SERVER *s = a->Server;
1878 	CEDAR *c = s->Cedar;
1879 	UINT ret = ERR_NO_ERROR;
1880 
1881 	SERVER_ADMIN_ONLY;
1882 	NO_SUPPORT_FOR_BRIDGE;
1883 
1884 	if (s->DDnsClient == NULL)
1885 	{
1886 		return ERR_NOT_SUPPORTED;
1887 	}
1888 
1889 	Zero(t, sizeof(INTERNET_SETTING));
1890 
1891 	DCGetInternetSetting(s->DDnsClient, t);
1892 
1893 	return ret;
1894 }
1895 
1896 // Set DDNS proxy configuration
StSetDDnsInternetSetting(ADMIN * a,INTERNET_SETTING * t)1897 UINT StSetDDnsInternetSetting(ADMIN *a, INTERNET_SETTING *t)
1898 {
1899 	SERVER *s = a->Server;
1900 	CEDAR *c = s->Cedar;
1901 	UINT ret = ERR_NO_ERROR;
1902 
1903 	SERVER_ADMIN_ONLY;
1904 	NO_SUPPORT_FOR_BRIDGE;
1905 
1906 	if (s->DDnsClient == NULL)
1907 	{
1908 		return ERR_NOT_SUPPORTED;
1909 	}
1910 
1911 	DCSetInternetSetting(s->DDnsClient, t);
1912 
1913 	IncrementServerConfigRevision(s);
1914 
1915 	return ret;
1916 }
1917 
1918 // Get Azure status
StGetAzureStatus(ADMIN * a,RPC_AZURE_STATUS * t)1919 UINT StGetAzureStatus(ADMIN *a, RPC_AZURE_STATUS *t)
1920 {
1921 	SERVER *s = a->Server;
1922 	CEDAR *c = s->Cedar;
1923 	UINT ret = ERR_NO_ERROR;
1924 	AZURE_CLIENT *ac;
1925 
1926 	SERVER_ADMIN_ONLY;
1927 	NO_SUPPORT_FOR_BRIDGE;
1928 
1929 	if (SiIsAzureSupported(s) == false)
1930 	{
1931 		return ERR_NOT_SUPPORTED;
1932 	}
1933 
1934 	ac = s->AzureClient;
1935 	if (ac == NULL)
1936 	{
1937 		return ERR_NOT_SUPPORTED;
1938 	}
1939 
1940 	Zero(t, sizeof(RPC_AZURE_STATUS));
1941 
1942 	Lock(ac->Lock);
1943 	{
1944 		t->IsConnected = ac->IsConnected;
1945 		t->IsEnabled = ac->IsEnabled;
1946 	}
1947 	Unlock(ac->Lock);
1948 
1949 	return ERR_NO_ERROR;
1950 }
1951 
1952 // Set Azure status
StSetAzureStatus(ADMIN * a,RPC_AZURE_STATUS * t)1953 UINT StSetAzureStatus(ADMIN *a, RPC_AZURE_STATUS *t)
1954 {
1955 	SERVER *s = a->Server;
1956 	CEDAR *c = s->Cedar;
1957 	UINT ret = ERR_NO_ERROR;
1958 
1959 	SERVER_ADMIN_ONLY;
1960 	NO_SUPPORT_FOR_BRIDGE;
1961 
1962 	if (SiIsAzureSupported(s) == false)
1963 	{
1964 		return ERR_NOT_SUPPORTED;
1965 	}
1966 
1967 	SiSetAzureEnable(s, t->IsEnabled);
1968 
1969 	IncrementServerConfigRevision(s);
1970 
1971 	return ERR_NO_ERROR;
1972 }
1973 
1974 // Get special listener status
StGetSpecialListener(ADMIN * a,RPC_SPECIAL_LISTENER * t)1975 UINT StGetSpecialListener(ADMIN *a, RPC_SPECIAL_LISTENER *t)
1976 {
1977 	SERVER *s = a->Server;
1978 	CEDAR *c = s->Cedar;
1979 	UINT ret = ERR_NO_ERROR;
1980 
1981 	SERVER_ADMIN_ONLY;
1982 	NO_SUPPORT_FOR_BRIDGE;
1983 
1984 	Zero(t, sizeof(RPC_SPECIAL_LISTENER));
1985 	t->VpnOverDnsListener = s->EnableVpnOverDns;
1986 	t->VpnOverIcmpListener = s->EnableVpnOverIcmp;
1987 
1988 	return ERR_NO_ERROR;
1989 }
1990 
1991 // Set special listener status
StSetSpecialListener(ADMIN * a,RPC_SPECIAL_LISTENER * t)1992 UINT StSetSpecialListener(ADMIN *a, RPC_SPECIAL_LISTENER *t)
1993 {
1994 	SERVER *s = a->Server;
1995 	CEDAR *c = s->Cedar;
1996 	UINT ret = ERR_NO_ERROR;
1997 
1998 	SERVER_ADMIN_ONLY;
1999 	NO_SUPPORT_FOR_BRIDGE;
2000 
2001 	// Check ports
2002 	if (t->VpnOverDnsListener && (MAKEBOOL(s->EnableVpnOverDns) != MAKEBOOL(t->VpnOverDnsListener)))
2003 	{
2004 		if (SiCanOpenVpnOverDnsPort() == false)
2005 		{
2006 			return ERR_SPECIAL_LISTENER_DNS_ERROR;
2007 		}
2008 	}
2009 
2010 	if (t->VpnOverIcmpListener && (MAKEBOOL(s->EnableVpnOverIcmp) != MAKEBOOL(t->VpnOverIcmpListener)))
2011 	{
2012 		if (SiCanOpenVpnOverIcmpPort() == false)
2013 		{
2014 			return ERR_SPECIAL_LISTENER_ICMP_ERROR;
2015 		}
2016 	}
2017 
2018 	s->EnableVpnOverDns = t->VpnOverDnsListener;
2019 	s->EnableVpnOverIcmp = t->VpnOverIcmpListener;
2020 
2021 	SiApplySpecialListenerStatus(s);
2022 
2023 	ALog(a, NULL, "LA_SET_SPECIAL_LISTENER");
2024 
2025 	IncrementServerConfigRevision(s);
2026 
2027 	return ERR_NO_ERROR;
2028 }
2029 
2030 // Set configurations for OpenVPN and SSTP
StSetOpenVpnSstpConfig(ADMIN * a,OPENVPN_SSTP_CONFIG * t)2031 UINT StSetOpenVpnSstpConfig(ADMIN *a, OPENVPN_SSTP_CONFIG *t)
2032 {
2033 	PROTO *proto = a->Server->Proto;
2034 	PROTO_CONTAINER *container, tmp_c;
2035 	PROTO_OPTION *option, tmp_o;
2036 	UINT ret = ERR_NO_ERROR;
2037 	bool changed = false;
2038 
2039 	SERVER_ADMIN_ONLY;
2040 
2041 	if (proto == NULL)
2042 	{
2043 		return ERR_NOT_SUPPORTED;
2044 	}
2045 
2046 	tmp_o.Name = PROTO_OPTION_TOGGLE_NAME;
2047 	tmp_c.Name = "OpenVPN";
2048 
2049 	container = Search(proto->Containers, &tmp_c);
2050 	if (container != NULL)
2051 	{
2052 		option = Search(container->Options, &tmp_o);
2053 		if (option != NULL)
2054 		{
2055 			if (option->Type == PROTO_OPTION_BOOL)
2056 			{
2057 				option->Bool = t->EnableOpenVPN;
2058 				changed = true;
2059 			}
2060 			else
2061 			{
2062 				ret = ERR_INVALID_PARAMETER;
2063 			}
2064 		}
2065 		else
2066 		{
2067 			ret = ERR_OBJECT_NOT_FOUND;
2068 		}
2069 	}
2070 	else
2071 	{
2072 		ret = ERR_OBJECT_NOT_FOUND;
2073 	}
2074 
2075 	tmp_c.Name = "SSTP";
2076 
2077 	container = Search(proto->Containers, &tmp_c);
2078 	if (container != NULL)
2079 	{
2080 		option = Search(container->Options, &tmp_o);
2081 		if (option != NULL)
2082 		{
2083 			if (option->Type == PROTO_OPTION_BOOL)
2084 			{
2085 				option->Bool = t->EnableSSTP;
2086 				changed = true;
2087 			}
2088 			else
2089 			{
2090 				ret = ERR_INVALID_PARAMETER;
2091 			}
2092 		}
2093 		else
2094 		{
2095 			ret = ERR_OBJECT_NOT_FOUND;
2096 		}
2097 	}
2098 	else
2099 	{
2100 		ret = ERR_OBJECT_NOT_FOUND;
2101 	}
2102 
2103 	if (changed)
2104 	{
2105 		ALog(a, NULL, "LA_SET_OVPN_SSTP_CONFIG");
2106 		IncrementServerConfigRevision(a->Server);
2107 	}
2108 
2109 	return ret;
2110 }
2111 
2112 // Get configurations for OpenVPN and SSTP
StGetOpenVpnSstpConfig(ADMIN * a,OPENVPN_SSTP_CONFIG * t)2113 UINT StGetOpenVpnSstpConfig(ADMIN *a, OPENVPN_SSTP_CONFIG *t)
2114 {
2115 	PROTO *proto = a->Server->Proto;
2116 	if (proto == NULL)
2117 	{
2118 		return ERR_NOT_SUPPORTED;
2119 	}
2120 
2121 	t->EnableOpenVPN = ProtoEnabled(proto, "OpenVPN");
2122 	t->EnableSSTP = ProtoEnabled(proto, "SSTP");
2123 
2124 	return ERR_NO_ERROR;
2125 }
2126 
2127 // Get status of DDNS client
StGetDDnsClientStatus(ADMIN * a,DDNS_CLIENT_STATUS * t)2128 UINT StGetDDnsClientStatus(ADMIN *a, DDNS_CLIENT_STATUS *t)
2129 {
2130 	SERVER *s = a->Server;
2131 	CEDAR *c = s->Cedar;
2132 	UINT ret = ERR_NO_ERROR;
2133 
2134 	SERVER_ADMIN_ONLY;
2135 	NO_SUPPORT_FOR_BRIDGE;
2136 
2137 	if (s->DDnsClient == NULL)
2138 	{
2139 		return ERR_NOT_SUPPORTED;
2140 	}
2141 
2142 	Zero(t, sizeof(DDNS_CLIENT_STATUS));
2143 	DCGetStatus(s->DDnsClient, t);
2144 
2145 	return ERR_NO_ERROR;
2146 }
2147 
2148 // Change host-name for DDNS client
StChangeDDnsClientHostname(ADMIN * a,RPC_TEST * t)2149 UINT StChangeDDnsClientHostname(ADMIN *a, RPC_TEST *t)
2150 {
2151 	SERVER *s = a->Server;
2152 	CEDAR *c = s->Cedar;
2153 	UINT ret = ERR_NO_ERROR;
2154 
2155 	SERVER_ADMIN_ONLY;
2156 	NO_SUPPORT_FOR_BRIDGE;
2157 
2158 	if (s->DDnsClient == NULL)
2159 	{
2160 		return ERR_NOT_SUPPORTED;
2161 	}
2162 
2163 	ret = DCChangeHostName(s->DDnsClient, t->StrValue);
2164 
2165 	if (ret == ERR_NO_ERROR)
2166 	{
2167 		ALog(a, NULL, "LA_DDNS_HOSTNAME_CHANGED", t->StrValue);
2168 	}
2169 
2170 	IncrementServerConfigRevision(s);
2171 
2172 	return ret;
2173 }
2174 
2175 // Regenerate server certification
StRegenerateServerCert(ADMIN * a,RPC_TEST * t)2176 UINT StRegenerateServerCert(ADMIN *a, RPC_TEST *t)
2177 {
2178 	SERVER *s = a->Server;
2179 	CEDAR *c = s->Cedar;
2180 	UINT ret = ERR_NO_ERROR;
2181 	X *x;
2182 	K *k;
2183 
2184 	SERVER_ADMIN_ONLY;
2185 
2186 	SiGenerateDefaultCertEx(&x, &k, t->StrValue);
2187 
2188 	SetCedarCert(c, x, k);
2189 
2190 	ALog(a, NULL, "LA_REGENERATE_SERVER_CERT", t->StrValue);
2191 
2192 	IncrementServerConfigRevision(s);
2193 
2194 	FreeX(x);
2195 	FreeK(k);
2196 
2197 	return ERR_NO_ERROR;
2198 }
2199 
2200 // Generate OpenVPN configuration files
StMakeOpenVpnConfigFile(ADMIN * a,RPC_READ_LOG_FILE * t)2201 UINT StMakeOpenVpnConfigFile(ADMIN *a, RPC_READ_LOG_FILE *t)
2202 {
2203 	SERVER *s = a->Server;
2204 	CEDAR *c = s->Cedar;
2205 	UINT ret = ERR_NO_ERROR;
2206 	ZIP_PACKER *p;
2207 	FIFO *f;
2208 	BUF *readme_buf;
2209 	BUF *readme_pdf_buf;
2210 	BUF *sample_buf;
2211 	LIST *port_list;
2212 	char my_hostname[MAX_SIZE];
2213 
2214 	SERVER_ADMIN_ONLY;
2215 	NO_SUPPORT_FOR_BRIDGE;
2216 	if (s->ServerType != SERVER_TYPE_STANDALONE)
2217 	{
2218 		return ERR_NOT_SUPPORTED;
2219 	}
2220 
2221 	if (ProtoEnabled(s->Proto, "OpenVPN") == false)
2222 	{
2223 		return ERR_OPENVPN_IS_NOT_ENABLED;
2224 	}
2225 
2226 	port_list = s->PortsUDP;
2227 
2228 	FreeRpcReadLogFile(t);
2229 	Zero(t, sizeof(RPC_READ_LOG_FILE));
2230 
2231 	p = NewZipPacker();
2232 
2233 	// readme.txt
2234 	readme_buf = ReadDump("|openvpn_readme.txt");
2235 
2236 	// readme.pdf
2237 	readme_pdf_buf = ReadDump("|openvpn_readme.pdf");
2238 
2239 	// sample.ovpn
2240 	sample_buf = ReadDump("|openvpn_sample.ovpn");
2241 
2242 	// host name
2243 	GetMachineHostName(my_hostname, sizeof(my_hostname));
2244 	my_hostname[16] = 0;
2245 
2246 	if (readme_buf == NULL || sample_buf == NULL || readme_pdf_buf == NULL)
2247 	{
2248 		ret = ERR_INTERNAL_ERROR;
2249 	}
2250 	else
2251 	{
2252 		BUF *config_l3_buf, *config_l2_buf;
2253 		X *x = NULL;
2254 		BUF *x_buf;
2255 		char protocol[MAX_SIZE];
2256 		UINT port = OPENVPN_UDP_PORT;
2257 		char port_str[MAX_SIZE];
2258 		char hostname[MAX_SIZE];
2259 		char tag_before_hostname[MAX_SIZE];
2260 		DDNS_CLIENT_STATUS ddns;
2261 		UCHAR *zero_buffer;
2262 		UINT zero_buffer_size = 128 * 1024;
2263 		char name_tmp[MAX_SIZE];
2264 
2265 		zero_buffer = ZeroMalloc(zero_buffer_size);
2266 
2267 
2268 		if (x == NULL)
2269 		{
2270 			Lock(c->lock);
2271 			{
2272 				x = CloneX(c->ServerX);
2273 			}
2274 			Unlock(c->lock);
2275 
2276 			if (x != NULL)
2277 			{
2278 				// Get the root certificate
2279 				if (x->root_cert == false)
2280 				{
2281 					X *root_x = NULL;
2282 					LIST *cert_list = NewCertList(true);
2283 
2284 					if (TryGetRootCertChain(cert_list, x, true, &root_x))
2285 					{
2286 						FreeX(x);
2287 						x = root_x;
2288 					}
2289 
2290 					FreeCertList(cert_list);
2291 				}
2292 			}
2293 		}
2294 
2295 		x_buf = XToBuf(x, true);
2296 
2297 		SeekBufToEnd(x_buf);
2298 		WriteBufChar(x_buf, 0);
2299 		SeekBufToBegin(x_buf);
2300 
2301 		FreeX(x);
2302 		Zero(hostname, sizeof(hostname));
2303 		Zero(tag_before_hostname, sizeof(tag_before_hostname));
2304 
2305 		Zero(&ddns, sizeof(ddns));
2306 		if (s->DDnsClient != NULL)
2307 		{
2308 			DCGetStatus(s->DDnsClient, &ddns);
2309 
2310 			if (IsEmptyStr(ddns.CurrentHostName) == false && IsEmptyStr(ddns.DnsSuffix) == false &&
2311 				ddns.Err_IPv4 == ERR_NO_ERROR)
2312 			{
2313 				StrCpy(tag_before_hostname, sizeof(tag_before_hostname),
2314 					"# Note: The below hostname is came from the Dynamic DNS Client function\r\n"
2315 					"#       which is running on the VPN Server. If you don't want to use\r\n"
2316 					"#       the Dynamic DNS hostname, replace it to either IP address or\r\n"
2317 					"#       other domain's hostname.\r\n\r\n");
2318 
2319 				Format(hostname, sizeof(hostname), "%s.v4%s", ddns.CurrentHostName, ddns.DnsSuffix);
2320 			}
2321 		}
2322 
2323 		if (IsEmptyStr(hostname))
2324 		{
2325 			IP myip;
2326 
2327 			Zero(&myip, sizeof(myip));
2328 			GetCurrentGlobalIP(&myip, false);
2329 
2330 			if (IsZeroIP(&myip))
2331 			{
2332 				GetCurrentGlobalIPGuess(&myip, false);
2333 			}
2334 
2335 			IPToStr(hostname, sizeof(hostname), &myip);
2336 		}
2337 
2338 		SeekBuf(sample_buf, sample_buf->Size, 0);
2339 		WriteBuf(sample_buf, zero_buffer, zero_buffer_size);
2340 
2341 		config_l3_buf = CloneBuf(sample_buf);
2342 		config_l2_buf = CloneBuf(sample_buf);
2343 
2344 		// Generate contents of configuration
2345 		if (LIST_NUM(port_list) >= 1)
2346 		{
2347 			StrCpy(protocol, sizeof(protocol), "udp");
2348 
2349 			if (IsIntInList(port_list, OPENVPN_UDP_PORT))
2350 			{
2351 				port = OPENVPN_UDP_PORT;
2352 			}
2353 			else
2354 			{
2355 				port = *((UINT *)(LIST_DATA(port_list, 0)));
2356 			}
2357 		}
2358 		else
2359 		{
2360 			RPC_LISTENER_LIST tt;
2361 			UINT i;
2362 
2363 			port = 0;
2364 
2365 			StrCpy(protocol, sizeof(protocol), "tcp");
2366 
2367 			Zero(&tt, sizeof(tt));
2368 
2369 			StEnumListener(a, &tt);
2370 
2371 			for (i = 0;i < tt.NumPort;i++)
2372 			{
2373 				if (tt.Enables[i] && tt.Errors[i] == false)
2374 				{
2375 					port = tt.Ports[i];
2376 					break;
2377 				}
2378 			}
2379 
2380 			FreeRpcListenerList(&tt);
2381 
2382 			if (port == 0)
2383 			{
2384 				StrCpy(protocol, sizeof(protocol), "udp");
2385 				port = OPENVPN_UDP_PORT;
2386 			}
2387 		}
2388 
2389 		ToStr(port_str, port);
2390 
2391 		if (IsEmptyStr(my_hostname) == false)
2392 		{
2393 			StrCat(my_hostname, sizeof(my_hostname), "_");
2394 
2395 			StrLower(my_hostname);
2396 		}
2397 
2398 		ZipAddFileSimple(p, "readme.txt", LocalTime64(), 0, readme_buf->Buf, readme_buf->Size);
2399 		ZipAddFileSimple(p, "readme.pdf", LocalTime64(), 0, readme_pdf_buf->Buf, readme_pdf_buf->Size);
2400 
2401 		ReplaceStrEx((char *)config_l3_buf->Buf, config_l3_buf->Size, (char *)config_l3_buf->Buf,
2402 			"$TAG_TUN_TAP$", "tun", false);
2403 		ReplaceStrEx((char *)config_l3_buf->Buf, config_l3_buf->Size, (char *)config_l3_buf->Buf,
2404 			"$TAG_PROTO$", protocol, false);
2405 		ReplaceStrEx((char *)config_l3_buf->Buf, config_l3_buf->Size, (char *)config_l3_buf->Buf,
2406 			"$TAG_HOSTNAME$", hostname, false);
2407 		ReplaceStrEx((char *)config_l3_buf->Buf, config_l3_buf->Size, (char *)config_l3_buf->Buf,
2408 			"$TAG_BEFORE_REMOTE$", tag_before_hostname, false);
2409 		ReplaceStrEx((char *)config_l3_buf->Buf, config_l3_buf->Size, (char *)config_l3_buf->Buf,
2410 			"$TAG_PORT$", port_str, false);
2411 
2412 		if (x_buf != NULL)
2413 		{
2414 			ReplaceStrEx((char *)config_l3_buf->Buf, config_l3_buf->Size, (char *)config_l3_buf->Buf,
2415 				"$CA$", x_buf->Buf, false);
2416 		}
2417 
2418 		Format(name_tmp, sizeof(name_tmp), "%sopenvpn_remote_access_l3.ovpn", my_hostname);
2419 		ZipAddFileSimple(p, name_tmp, LocalTime64(), 0, config_l3_buf->Buf, StrLen(config_l3_buf->Buf));
2420 
2421 		ReplaceStrEx((char *)config_l2_buf->Buf, config_l2_buf->Size, (char *)config_l2_buf->Buf,
2422 			"$TAG_TUN_TAP$", "tap", false);
2423 		ReplaceStrEx((char *)config_l2_buf->Buf, config_l2_buf->Size, (char *)config_l2_buf->Buf,
2424 			"$TAG_PROTO$", protocol, false);
2425 		ReplaceStrEx((char *)config_l2_buf->Buf, config_l2_buf->Size, (char *)config_l2_buf->Buf,
2426 			"$TAG_HOSTNAME$", hostname, false);
2427 		ReplaceStrEx((char *)config_l2_buf->Buf, config_l2_buf->Size, (char *)config_l2_buf->Buf,
2428 			"$TAG_BEFORE_REMOTE$", tag_before_hostname, false);
2429 		ReplaceStrEx((char *)config_l2_buf->Buf, config_l2_buf->Size, (char *)config_l2_buf->Buf,
2430 			"$TAG_PORT$", port_str, false);
2431 
2432 		if (x_buf != NULL)
2433 		{
2434 			ReplaceStrEx((char *)config_l2_buf->Buf, config_l2_buf->Size, (char *)config_l2_buf->Buf,
2435 				"$CA$", x_buf->Buf, false);
2436 		}
2437 
2438 		Format(name_tmp, sizeof(name_tmp), "%sopenvpn_site_to_site_bridge_l2.ovpn", my_hostname);
2439 		ZipAddFileSimple(p, name_tmp, LocalTime64(), 0, config_l2_buf->Buf, StrLen(config_l2_buf->Buf));
2440 
2441 		FreeBuf(config_l3_buf);
2442 		FreeBuf(config_l2_buf);
2443 
2444 		f = ZipFinish(p);
2445 
2446 		if (f != NULL)
2447 		{
2448 			t->Buffer = NewBuf();
2449 			WriteBuf(t->Buffer, FifoPtr(f), FifoSize(f));
2450 			SeekBuf(t->Buffer, 0, 0);
2451 		}
2452 
2453 		FreeBuf(readme_buf);
2454 		FreeBuf(sample_buf);
2455 		FreeBuf(readme_pdf_buf);
2456 		FreeBuf(x_buf);
2457 
2458 		Free(zero_buffer);
2459 	}
2460 
2461 	FreeZipPacker(p);
2462 
2463 	return ERR_NO_ERROR;
2464 }
2465 
2466 // Set IPsec service configuration
StSetIPsecServices(ADMIN * a,IPSEC_SERVICES * t)2467 UINT StSetIPsecServices(ADMIN *a, IPSEC_SERVICES *t)
2468 {
2469 	SERVER *s = a->Server;
2470 	CEDAR *c = s->Cedar;
2471 	UINT ret = ERR_NO_ERROR;
2472 
2473 	SERVER_ADMIN_ONLY;
2474 	NO_SUPPORT_FOR_BRIDGE;
2475 	if (GetServerCapsBool(s, "b_support_ipsec") == false || s->IPsecServer == NULL)
2476 	{
2477 		return ERR_NOT_SUPPORTED;
2478 	}
2479 
2480 	IPsecServerSetServices(s->IPsecServer, t);
2481 
2482 	ALog(a, NULL, "LA_SET_IPSEC_CONFIG");
2483 
2484 	IncrementServerConfigRevision(s);
2485 
2486 	return ERR_NO_ERROR;
2487 }
2488 
2489 // Get IPsec service configuration
StGetIPsecServices(ADMIN * a,IPSEC_SERVICES * t)2490 UINT StGetIPsecServices(ADMIN *a, IPSEC_SERVICES *t)
2491 {
2492 	SERVER *s = a->Server;
2493 	CEDAR *c = s->Cedar;
2494 	UINT ret = ERR_NO_ERROR;
2495 
2496 	SERVER_ADMIN_ONLY;
2497 	NO_SUPPORT_FOR_BRIDGE;
2498 	if (GetServerCapsBool(s, "b_support_ipsec") == false || s->IPsecServer == NULL)
2499 	{
2500 		return ERR_NOT_SUPPORTED;
2501 	}
2502 
2503 	Zero(t, sizeof(IPSEC_SERVICES));
2504 	IPsecServerGetServices(s->IPsecServer, t);
2505 
2506 	return ERR_NO_ERROR;
2507 }
2508 
2509 // Add EtherIP ID setting
StAddEtherIpId(ADMIN * a,ETHERIP_ID * t)2510 UINT StAddEtherIpId(ADMIN *a, ETHERIP_ID *t)
2511 {
2512 	SERVER *s = a->Server;
2513 	CEDAR *c = s->Cedar;
2514 	UINT ret = ERR_NO_ERROR;
2515 
2516 	SERVER_ADMIN_ONLY;
2517 	NO_SUPPORT_FOR_BRIDGE;
2518 	if (GetServerCapsBool(s, "b_support_ipsec") == false || s->IPsecServer == NULL)
2519 	{
2520 		return ERR_NOT_SUPPORTED;
2521 	}
2522 
2523 	AddEtherIPId(s->IPsecServer, t);
2524 
2525 	ALog(a, NULL, "LA_ADD_ETHERIP_ID", t->Id);
2526 
2527 	IncrementServerConfigRevision(s);
2528 
2529 	return ERR_NO_ERROR;
2530 }
2531 
2532 // Get EtherIP ID setting
StGetEtherIpId(ADMIN * a,ETHERIP_ID * t)2533 UINT StGetEtherIpId(ADMIN *a, ETHERIP_ID *t)
2534 {
2535 	SERVER *s = a->Server;
2536 	CEDAR *c = s->Cedar;
2537 	UINT ret = ERR_NO_ERROR;
2538 	char id[MAX_SIZE];
2539 
2540 	SERVER_ADMIN_ONLY;
2541 	NO_SUPPORT_FOR_BRIDGE;
2542 	if (GetServerCapsBool(s, "b_support_ipsec") == false || s->IPsecServer == NULL)
2543 	{
2544 		return ERR_NOT_SUPPORTED;
2545 	}
2546 
2547 	StrCpy(id, sizeof(id), t->Id);
2548 
2549 	Zero(t, sizeof(ETHERIP_ID));
2550 	if (SearchEtherIPId(s->IPsecServer, t, id) == false)
2551 	{
2552 		return ERR_OBJECT_NOT_FOUND;
2553 	}
2554 
2555 	return ERR_NO_ERROR;
2556 }
2557 
2558 // Delete EtherIP ID setting
StDeleteEtherIpId(ADMIN * a,ETHERIP_ID * t)2559 UINT StDeleteEtherIpId(ADMIN *a, ETHERIP_ID *t)
2560 {
2561 	SERVER *s = a->Server;
2562 	CEDAR *c = s->Cedar;
2563 	UINT ret = ERR_NO_ERROR;
2564 	char id[MAX_SIZE];
2565 
2566 	SERVER_ADMIN_ONLY;
2567 	NO_SUPPORT_FOR_BRIDGE;
2568 	if (GetServerCapsBool(s, "b_support_ipsec") == false || s->IPsecServer == NULL)
2569 	{
2570 		return ERR_NOT_SUPPORTED;
2571 	}
2572 
2573 	StrCpy(id, sizeof(id), t->Id);
2574 
2575 	if (DeleteEtherIPId(s->IPsecServer, id) == false)
2576 	{
2577 		return ERR_OBJECT_NOT_FOUND;
2578 	}
2579 
2580 	ALog(a, NULL, "LA_DEL_ETHERIP_ID", id);
2581 
2582 	IncrementServerConfigRevision(s);
2583 
2584 	return ERR_NO_ERROR;
2585 }
2586 
2587 // Enumerate EtherIP ID settings
StEnumEtherIpId(ADMIN * a,RPC_ENUM_ETHERIP_ID * t)2588 UINT StEnumEtherIpId(ADMIN *a, RPC_ENUM_ETHERIP_ID *t)
2589 {
2590 	SERVER *s = a->Server;
2591 	CEDAR *c = s->Cedar;
2592 	UINT ret = ERR_NO_ERROR;
2593 	SERVER_ADMIN_ONLY;
2594 	NO_SUPPORT_FOR_BRIDGE;
2595 	if (GetServerCapsBool(s, "b_support_ipsec") == false || s->IPsecServer == NULL)
2596 	{
2597 		return ERR_NOT_SUPPORTED;
2598 	}
2599 
2600 	FreeRpcEnumEtherIpId(t);
2601 	Zero(t, sizeof(RPC_ENUM_ETHERIP_ID));
2602 
2603 	Lock(s->IPsecServer->LockSettings);
2604 	{
2605 		UINT i;
2606 		UINT num;
2607 
2608 		num = LIST_NUM(s->IPsecServer->EtherIPIdList);
2609 
2610 		t->NumItem = num;
2611 		t->IdList = ZeroMalloc(sizeof(ETHERIP_ID) * num);
2612 
2613 		for (i = 0;i < num;i++)
2614 		{
2615 			ETHERIP_ID *d = &t->IdList[i];
2616 			ETHERIP_ID *src = LIST_DATA(s->IPsecServer->EtherIPIdList, i);
2617 
2618 			Copy(d, src, sizeof(ETHERIP_ID));
2619 		}
2620 	}
2621 	Unlock(s->IPsecServer->LockSettings);
2622 
2623 	return ERR_NO_ERROR;
2624 }
2625 
2626 // Set message of today on hub
StSetHubMsg(ADMIN * a,RPC_MSG * t)2627 UINT StSetHubMsg(ADMIN *a, RPC_MSG *t)
2628 {
2629 	SERVER *s = a->Server;
2630 	CEDAR *c = s->Cedar;
2631 	HUB *h;
2632 	UINT ret = ERR_NO_ERROR;
2633 	char hubname[MAX_HUBNAME_LEN + 1];
2634 
2635 	CHECK_RIGHT;
2636 	NO_SUPPORT_FOR_BRIDGE;
2637 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
2638 	{
2639 		return ERR_NOT_SUPPORTED;
2640 	}
2641 	if (UniStrLen(t->Msg) > HUB_MAXMSG_LEN)
2642 	{
2643 		return ERR_MEMORY_NOT_ENOUGH;
2644 	}
2645 
2646 	StrCpy(hubname, sizeof(hubname), t->HubName);
2647 
2648 	h = GetHub(c, hubname);
2649 
2650 	if (h == NULL)
2651 	{
2652 		ret = ERR_HUB_NOT_FOUND;
2653 	}
2654 	else
2655 	{
2656 		if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_msg") != 0)
2657 		{
2658 			ret = ERR_NOT_ENOUGH_RIGHT;
2659 		}
2660 		else
2661 		{
2662 			SetHubMsg(h, t->Msg);
2663 		}
2664 
2665 		ReleaseHub(h);
2666 	}
2667 
2668 	IncrementServerConfigRevision(s);
2669 
2670 	return ret;
2671 }
2672 
2673 // Get message of today on hub
StGetHubMsg(ADMIN * a,RPC_MSG * t)2674 UINT StGetHubMsg(ADMIN *a, RPC_MSG *t)
2675 {
2676 	SERVER *s = a->Server;
2677 	CEDAR *c = s->Cedar;
2678 	HUB *h;
2679 	UINT ret = ERR_NO_ERROR;
2680 	char hubname[MAX_HUBNAME_LEN + 1];
2681 
2682 	CHECK_RIGHT;
2683 	NO_SUPPORT_FOR_BRIDGE;
2684 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
2685 	{
2686 		return ERR_NOT_SUPPORTED;
2687 	}
2688 	if (UniStrLen(t->Msg) > HUB_MAXMSG_LEN)
2689 	{
2690 		return ERR_MEMORY_NOT_ENOUGH;
2691 	}
2692 
2693 	StrCpy(hubname, sizeof(hubname), t->HubName);
2694 
2695 	h = GetHub(c, hubname);
2696 
2697 	if (h == NULL)
2698 	{
2699 		ret = ERR_HUB_NOT_FOUND;
2700 	}
2701 	else
2702 	{
2703 		FreeRpcMsg(t);
2704 		Zero(t, sizeof(RPC_MSG));
2705 
2706 		t->Msg = GetHubMsg(h);
2707 
2708 		ReleaseHub(h);
2709 	}
2710 
2711 	return ret;
2712 }
2713 
2714 // Do debug function
StDebug(ADMIN * a,RPC_TEST * t)2715 UINT StDebug(ADMIN *a, RPC_TEST *t)
2716 {
2717 	SERVER *s = a->Server;
2718 	CEDAR *c = s->Cedar;
2719 	UINT ret = ERR_NO_ERROR;
2720 	RPC_TEST t2;
2721 
2722 	SERVER_ADMIN_ONLY;
2723 
2724 	Zero(&t2, sizeof(t2));
2725 
2726 	ret = SiDebug(s, &t2, t->IntValue, t->StrValue);
2727 
2728 	if (ret == ERR_NO_ERROR)
2729 	{
2730 		Copy(t, &t2, sizeof(RPC_TEST));
2731 	}
2732 	else
2733 	{
2734 		Zero(t, sizeof(RPC_TEST));
2735 	}
2736 
2737 	return ret;
2738 }
2739 
2740 // Flush configuration file
StFlush(ADMIN * a,RPC_TEST * t)2741 UINT StFlush(ADMIN *a, RPC_TEST *t)
2742 {
2743 	SERVER *s = a->Server;
2744 	CEDAR *c = s->Cedar;
2745 	UINT ret = ERR_NO_ERROR;
2746 	UINT size;
2747 
2748 	SERVER_ADMIN_ONLY;
2749 
2750 	size = SiWriteConfigurationFile(s);
2751 
2752 	t->IntValue = size;
2753 
2754 	return ERR_NO_ERROR;
2755 }
2756 
2757 // Do Crash
StCrash(ADMIN * a,RPC_TEST * t)2758 UINT StCrash(ADMIN *a, RPC_TEST *t)
2759 {
2760 	SERVER *s = a->Server;
2761 	CEDAR *c = s->Cedar;
2762 	UINT ret = ERR_NO_ERROR;
2763 
2764 	SERVER_ADMIN_ONLY;
2765 
2766 #ifdef	OS_WIN32
2767 	MsSetEnableMinidump(false);
2768 #endif	// OS_WIN32
2769 
2770 	CrashNow();
2771 
2772 	return ERR_NO_ERROR;
2773 }
2774 
2775 // Get message for administrators
StGetAdminMsg(ADMIN * a,RPC_MSG * t)2776 UINT StGetAdminMsg(ADMIN *a, RPC_MSG *t)
2777 {
2778 	SERVER *s = a->Server;
2779 	CEDAR *c = s->Cedar;
2780 	UINT ret = ERR_NO_ERROR;
2781 	RPC_WINVER server_ver;
2782 	RPC_WINVER client_ver;
2783 	wchar_t winver_msg_client[3800];
2784 	wchar_t winver_msg_server[3800];
2785 	UINT tmpsize;
2786 	wchar_t *tmp;
2787 
2788 	FreeRpcMsg(t);
2789 	Zero(t, sizeof(RPC_MSG));
2790 
2791 	// Check for Windows version
2792 	GetWinVer(&server_ver);
2793 	Copy(&client_ver, &a->ClientWinVer, sizeof(RPC_WINVER));
2794 
2795 	Zero(winver_msg_client, sizeof(winver_msg_client));
2796 	Zero(winver_msg_server, sizeof(winver_msg_server));
2797 
2798 	if (IsSupportedWinVer(&client_ver) == false)
2799 	{
2800 		SYSTEMTIME st;
2801 
2802 		LocalTime(&st);
2803 
2804 		UniFormat(winver_msg_client, sizeof(winver_msg_client), _UU("WINVER_ERROR_FORMAT"),
2805 			_UU("WINVER_ERROR_PC_LOCAL"),
2806 			client_ver.Title,
2807 			_UU("WINVER_ERROR_VPNSERVER"),
2808 			SUPPORTED_WINDOWS_LIST,
2809 			_UU("WINVER_ERROR_PC_LOCAL"),
2810 			_UU("WINVER_ERROR_VPNSERVER"),
2811 			_UU("WINVER_ERROR_VPNSERVER"),
2812 			_UU("WINVER_ERROR_VPNSERVER"),
2813 			st.wYear, st.wMonth);
2814 	}
2815 
2816 	if (IsSupportedWinVer(&server_ver) == false)
2817 	{
2818 		SYSTEMTIME st;
2819 
2820 		LocalTime(&st);
2821 
2822 		UniFormat(winver_msg_server, sizeof(winver_msg_server), _UU("WINVER_ERROR_FORMAT"),
2823 			_UU("WINVER_ERROR_PC_REMOTE"),
2824 			server_ver.Title,
2825 			_UU("WINVER_ERROR_VPNSERVER"),
2826 			SUPPORTED_WINDOWS_LIST,
2827 			_UU("WINVER_ERROR_PC_REMOTE"),
2828 			_UU("WINVER_ERROR_VPNSERVER"),
2829 			_UU("WINVER_ERROR_VPNSERVER"),
2830 			_UU("WINVER_ERROR_VPNSERVER"),
2831 			st.wYear, st.wMonth);
2832 	}
2833 
2834 	tmpsize = UniStrSize(winver_msg_client) + UniStrSize(winver_msg_server) + 10000;
2835 
2836 	tmp = ZeroMalloc(tmpsize);
2837 
2838 	if (
2839 		c->Bridge == false)
2840 	{
2841 		if (GetGlobalServerFlag(GSF_SHOW_OSS_MSG) != 0)
2842 		{
2843 			UniStrCat(tmp, tmpsize, _UU("OSS_MSG"));
2844 		}
2845 	}
2846 
2847 	UniStrCat(tmp, tmpsize, winver_msg_client);
2848 	UniStrCat(tmp, tmpsize, winver_msg_server);
2849 
2850 	t->Msg = tmp;
2851 
2852 	return ERR_NO_ERROR;
2853 }
2854 
2855 // Enumerate VLAN tag transparent setting
StEnumEthVLan(ADMIN * a,RPC_ENUM_ETH_VLAN * t)2856 UINT StEnumEthVLan(ADMIN *a, RPC_ENUM_ETH_VLAN *t)
2857 {
2858 	SERVER *s = a->Server;
2859 	CEDAR *c = s->Cedar;
2860 	UINT ret = ERR_NO_ERROR;
2861 
2862 	SERVER_ADMIN_ONLY;
2863 
2864 #ifdef	OS_WIN32
2865 	if (GetServerCapsBool(s, "b_support_eth_vlan") == false)
2866 	{
2867 		ret = ERR_NOT_SUPPORTED;
2868 	}
2869 	else
2870 	{
2871 		FreeRpcEnumEthVLan(t);
2872 		Zero(t, sizeof(RPC_ENUM_ETH_VLAN));
2873 
2874 		if (EnumEthVLanWin32(t) == false)
2875 		{
2876 			ret = ERR_INTERNAL_ERROR;
2877 		}
2878 	}
2879 #else	// OS_WIN32
2880 	ret = ERR_NOT_SUPPORTED;
2881 #endif	// OS_WIN32
2882 
2883 	return ret;
2884 }
2885 
2886 // Set VLAN tag transparent setting
StSetEnableEthVLan(ADMIN * a,RPC_TEST * t)2887 UINT StSetEnableEthVLan(ADMIN *a, RPC_TEST *t)
2888 {
2889 	SERVER *s = a->Server;
2890 	CEDAR *c = s->Cedar;
2891 	UINT ret = ERR_NO_ERROR;
2892 
2893 	SERVER_ADMIN_ONLY;
2894 
2895 #ifdef	OS_WIN32
2896 	if (GetServerCapsBool(s, "b_support_eth_vlan") == false)
2897 	{
2898 		ret = ERR_NOT_SUPPORTED;
2899 	}
2900 	else if (MsIsAdmin() == false)
2901 	{
2902 		ret = ERR_NOT_ENOUGH_RIGHT;
2903 	}
2904 	else
2905 	{
2906 		if (SetVLanEnableStatus(t->StrValue, MAKEBOOL(t->IntValue)) == false)
2907 		{
2908 			ret = ERR_INTERNAL_ERROR;
2909 		}
2910 	}
2911 #else	// OS_WIN32
2912 	ret = ERR_NOT_SUPPORTED;
2913 #endif	// OS_WIN32
2914 
2915 	return ret;
2916 }
2917 
2918 // Get license status
StGetLicenseStatus(ADMIN * a,RPC_LICENSE_STATUS * t)2919 UINT StGetLicenseStatus(ADMIN *a, RPC_LICENSE_STATUS *t)
2920 {
2921 	return ERR_NOT_SUPPORTED;
2922 }
2923 
2924 // Enumerate license key
StEnumLicenseKey(ADMIN * a,RPC_ENUM_LICENSE_KEY * t)2925 UINT StEnumLicenseKey(ADMIN *a, RPC_ENUM_LICENSE_KEY *t)
2926 {
2927 	return ERR_NOT_SUPPORTED;
2928 }
2929 
2930 // Add new license key
StAddLicenseKey(ADMIN * a,RPC_TEST * t)2931 UINT StAddLicenseKey(ADMIN *a, RPC_TEST *t)
2932 {
2933 	return ERR_NOT_SUPPORTED;
2934 }
2935 
2936 // Delete a license key
StDelLicenseKey(ADMIN * a,RPC_TEST * t)2937 UINT StDelLicenseKey(ADMIN *a, RPC_TEST *t)
2938 {
2939 	return ERR_NOT_SUPPORTED;
2940 }
2941 
2942 // Download a log file
DownloadFileFromServer(RPC * r,char * server_name,char * filepath,UINT total_size,DOWNLOAD_PROC * proc,void * param)2943 BUF *DownloadFileFromServer(RPC *r, char *server_name, char *filepath, UINT total_size, DOWNLOAD_PROC *proc, void *param)
2944 {
2945 	UINT offset;
2946 	BUF *buf;
2947 	// Validate arguments
2948 	if (r == NULL || filepath == NULL)
2949 	{
2950 		return NULL;
2951 	}
2952 
2953 	if (server_name == NULL)
2954 	{
2955 		server_name = "";
2956 	}
2957 
2958 	offset = 0;
2959 
2960 	buf = NewBuf();
2961 
2962 	while (true)
2963 	{
2964 		DOWNLOAD_PROGRESS g;
2965 		RPC_READ_LOG_FILE t;
2966 		UINT ret;
2967 
2968 		Zero(&t, sizeof(t));
2969 		StrCpy(t.FilePath, sizeof(t.FilePath), filepath);
2970 		t.Offset = offset;
2971 		StrCpy(t.ServerName, sizeof(t.ServerName), server_name);
2972 
2973 		ret = ScReadLogFile(r, &t);
2974 
2975 		if (ret != ERR_NO_ERROR)
2976 		{
2977 			// Failed
2978 			FreeRpcReadLogFile(&t);
2979 			FreeBuf(buf);
2980 			return NULL;
2981 		}
2982 
2983 		if (t.Buffer == NULL)
2984 		{
2985 			// read to the end
2986 			break;
2987 		}
2988 
2989 		// Update current progress
2990 		offset += t.Buffer->Size;
2991 		Zero(&g, sizeof(g));
2992 		g.Param = param;
2993 		g.CurrentSize = offset;
2994 		g.TotalSize = MAX(total_size, offset);
2995 		g.ProgressPercent = (UINT)(MAKESURE((UINT64)g.CurrentSize * 100ULL / (UINT64)(MAX(g.TotalSize, 1)), 0, 100ULL));
2996 
2997 		WriteBuf(buf, t.Buffer->Buf, t.Buffer->Size);
2998 
2999 		FreeRpcReadLogFile(&t);
3000 
3001 		if (proc != NULL)
3002 		{
3003 			if (proc(&g) == false)
3004 			{
3005 				// Canceled by user
3006 				FreeBuf(buf);
3007 				return NULL;
3008 			}
3009 		}
3010 	}
3011 
3012 	if (buf->Size == 0)
3013 	{
3014 		// Downloading failed
3015 		FreeBuf(buf);
3016 		return NULL;
3017 	}
3018 
3019 	return buf;
3020 }
3021 
3022 // Read a log file
StReadLogFile(ADMIN * a,RPC_READ_LOG_FILE * t)3023 UINT StReadLogFile(ADMIN *a, RPC_READ_LOG_FILE *t)
3024 {
3025 	SERVER *s = a->Server;
3026 	CEDAR *c = s->Cedar;
3027 	char logfilename[MAX_PATH];
3028 	char servername[MAX_HOST_NAME_LEN + 1];
3029 	UINT offset;
3030 	bool local = true;
3031 
3032 	if (IsEmptyStr(t->FilePath))
3033 	{
3034 		return ERR_INVALID_PARAMETER;
3035 	}
3036 
3037 	StrCpy(logfilename, sizeof(logfilename), t->FilePath);
3038 	StrCpy(servername, sizeof(servername), t->ServerName);
3039 	offset = t->Offset;
3040 
3041 	if (s->ServerType != SERVER_TYPE_FARM_CONTROLLER)
3042 	{
3043 		GetMachineName(servername, sizeof(servername));
3044 	}
3045 
3046 	// Check the permission to read the log file
3047 	if (a->LogFileList == NULL)
3048 	{
3049 		// Enum the log files first
3050 		RPC_ENUM_LOG_FILE elf;
3051 		UINT elf_ret;
3052 
3053 		Zero(&elf, sizeof(elf));
3054 
3055 		elf_ret = StEnumLogFile(a, &elf);
3056 
3057 		FreeRpcEnumLogFile(&elf);
3058 
3059 		if (elf_ret != ERR_NO_ERROR)
3060 		{
3061 			return elf_ret;
3062 		}
3063 	}
3064 	if (CheckLogFileNameFromEnumList(a->LogFileList, logfilename, servername) == false)
3065 	{
3066 		// There is no such file in the log file list
3067 		return ERR_OBJECT_NOT_FOUND;
3068 	}
3069 
3070 	FreeRpcReadLogFile(t);
3071 	Zero(t, sizeof(RPC_READ_LOG_FILE));
3072 
3073 	if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
3074 	{
3075 		UINT i;
3076 
3077 		// When the host name in request is a cluster member, redirect the request
3078 		LockList(s->FarmMemberList);
3079 		{
3080 			for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
3081 			{
3082 				FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
3083 
3084 				if (f->Me == false)
3085 				{
3086 					if (StrCmpi(f->hostname, servername) == 0)
3087 					{
3088 						RPC_READ_LOG_FILE tt;
3089 
3090 						Zero(&tt, sizeof(tt));
3091 						local = false;
3092 
3093 						StrCpy(tt.ServerName, sizeof(tt.ServerName), servername);
3094 						StrCpy(tt.FilePath, sizeof(tt.FilePath), logfilename);
3095 						tt.Offset = offset;
3096 
3097 						if (SiCallReadLogFile(s, f, &tt))
3098 						{
3099 							if (tt.Buffer != NULL && tt.Buffer->Size > 0)
3100 							{
3101 								t->Buffer = NewBuf();
3102 								WriteBuf(t->Buffer, tt.Buffer->Buf, tt.Buffer->Size);
3103 							}
3104 						}
3105 
3106 						FreeRpcReadLogFile(&tt);
3107 
3108 						break;
3109 					}
3110 				}
3111 			}
3112 		}
3113 		UnlockList(s->FarmMemberList);
3114 	}
3115 
3116 	// Read a local file
3117 	if (local)
3118 	{
3119 		SiReadLocalLogFile(s, logfilename, offset, t);
3120 	}
3121 
3122 	if (offset == 0)
3123 	{
3124 		ALog(a, NULL, "LA_READ_LOG_FILE", servername, logfilename);
3125 	}
3126 
3127 	StrCpy(t->FilePath, sizeof(t->FilePath), logfilename);
3128 	StrCpy(t->ServerName, sizeof(t->ServerName), servername);
3129 	t->Offset = offset;
3130 
3131 	return ERR_NO_ERROR;
3132 }
3133 
3134 // Enumerate log files
StEnumLogFile(ADMIN * a,RPC_ENUM_LOG_FILE * t)3135 UINT StEnumLogFile(ADMIN *a, RPC_ENUM_LOG_FILE *t)
3136 {
3137 	SERVER *s = a->Server;
3138 	CEDAR *c = s->Cedar;
3139 	UINT i;
3140 	bool no_access = false;
3141 
3142 	HUB *h;
3143 
3144 	if (a->ServerAdmin == false)
3145 	{
3146 		h = GetHub(c, a->HubName);
3147 
3148 		if (a->ServerAdmin == false && GetHubAdminOption(h, "no_read_log_file") != 0)
3149 		{
3150 			no_access = true;
3151 		}
3152 
3153 		ReleaseHub(h);
3154 	}
3155 	else
3156 	{
3157 		if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
3158 		{
3159 			// Since Management session will become unstable if log files are
3160 			// enumerated on a cluster controller, it forbids.
3161 			return ERR_NOT_SUPPORTED;
3162 		}
3163 	}
3164 
3165 	if (no_access)
3166 	{
3167 		return ERR_NOT_ENOUGH_RIGHT;
3168 	}
3169 
3170 	FreeRpcEnumLogFile(t);
3171 	Zero(t, sizeof(RPC_ENUM_LOG_FILE));
3172 
3173 	// Enumerate local log files
3174 	SiEnumLocalLogFileList(s, a->ServerAdmin ? NULL : a->HubName, t);
3175 
3176 	if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
3177 	{
3178 		UINT i;
3179 		LIST *tt_list = NewListFast(NULL);
3180 
3181 		LockList(s->FarmMemberList);
3182 		{
3183 			for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
3184 			{
3185 				FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
3186 
3187 				if (f->Me == false)
3188 				{
3189 					// Enumerate log files on other cluster members.
3190 					RPC_ENUM_LOG_FILE *tt;
3191 					tt = ZeroMalloc(sizeof(RPC_ENUM_LOG_FILE));
3192 
3193 					if (SiCallEnumLogFileList(s, f, tt, a->ServerAdmin ? "" : a->HubName))
3194 					{
3195 						UINT i;
3196 						for (i = 0;i < tt->NumItem;i++)
3197 						{
3198 							RPC_ENUM_LOG_FILE_ITEM *e = &tt->Items[i];
3199 
3200 							StrCpy(e->ServerName, sizeof(e->ServerName), f->hostname);
3201 						}
3202 
3203 						Add(tt_list, tt);
3204 					}
3205 					else
3206 					{
3207 						Free(tt);
3208 					}
3209 				}
3210 			}
3211 		}
3212 		UnlockList(s->FarmMemberList);
3213 
3214 		for (i = 0;i < LIST_NUM(tt_list);i++)
3215 		{
3216 			RPC_ENUM_LOG_FILE *tt = LIST_DATA(tt_list, i);
3217 
3218 			AdjoinRpcEnumLogFile(t, tt);
3219 			FreeRpcEnumLogFile(tt);
3220 
3221 			Free(tt);
3222 		}
3223 
3224 		ReleaseList(tt_list);
3225 	}
3226 
3227 	// Cache the last list of log files on RPC session
3228 	if (a->LogFileList != NULL)
3229 	{
3230 		FreeEnumLogFile(a->LogFileList);
3231 	}
3232 
3233 	a->LogFileList = NewListFast(CmpLogFile);
3234 
3235 	for (i = 0;i < t->NumItem;i++)
3236 	{
3237 		RPC_ENUM_LOG_FILE_ITEM *e = &t->Items[i];
3238 		LOG_FILE *f = ZeroMalloc(sizeof(LOG_FILE));
3239 
3240 		f->FileSize = e->FileSize;
3241 		f->UpdatedTime = e->UpdatedTime;
3242 		StrCpy(f->Path, sizeof(f->Path), e->FilePath);
3243 		StrCpy(f->ServerName, sizeof(f->ServerName), e->ServerName);
3244 
3245 		Insert(a->LogFileList, f);
3246 	}
3247 
3248 	return ERR_NO_ERROR;
3249 }
3250 
3251 
3252 // Get access control list
StGetAcList(ADMIN * a,RPC_AC_LIST * t)3253 UINT StGetAcList(ADMIN *a, RPC_AC_LIST *t)
3254 {
3255 	SERVER *s = a->Server;
3256 	CEDAR *c = s->Cedar;
3257 	HUB *h;
3258 	UINT ret = ERR_NO_ERROR;
3259 	char hubname[MAX_HUBNAME_LEN + 1];
3260 
3261 	CHECK_RIGHT;
3262 	NO_SUPPORT_FOR_BRIDGE;
3263 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
3264 	{
3265 		return ERR_NOT_SUPPORTED;
3266 	}
3267 
3268 
3269 	StrCpy(hubname, sizeof(hubname), t->HubName);
3270 
3271 	FreeRpcAcList(t);
3272 	Zero(t, sizeof(RPC_AC_LIST));
3273 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
3274 
3275 	h = GetHub(c, hubname);
3276 
3277 	if (h == NULL)
3278 	{
3279 		ret = ERR_HUB_NOT_FOUND;
3280 	}
3281 	else
3282 	{
3283 		if (h->HubDb == NULL)
3284 		{
3285 			ret = ERR_NOT_SUPPORTED;
3286 		}
3287 		else
3288 		{
3289 			HUBDB *db = h->HubDb;
3290 
3291 			LockList(db->AcList);
3292 			{
3293 				t->o = NewAcList();
3294 
3295 				SetAcList(t->o, db->AcList);
3296 			}
3297 			UnlockList(db->AcList);
3298 		}
3299 		ReleaseHub(h);
3300 	}
3301 
3302 	return ret;
3303 }
3304 
3305 // Set access control list
StSetAcList(ADMIN * a,RPC_AC_LIST * t)3306 UINT StSetAcList(ADMIN *a, RPC_AC_LIST *t)
3307 {
3308 	SERVER *s = a->Server;
3309 	CEDAR *c = s->Cedar;
3310 	HUB *h;
3311 	UINT ret = ERR_NO_ERROR;
3312 	char hubname[MAX_HUBNAME_LEN + 1];
3313 
3314 
3315 	if (c->Bridge)
3316 	{
3317 		return ERR_NOT_SUPPORTED;
3318 	}
3319 
3320 	if (GetGlobalServerFlag(GSF_DISABLE_AC) != 0 && LIST_NUM(t->o) >= 1)
3321 	{
3322 		return ERR_NOT_SUPPORTED_FUNCTION_ON_OPENSOURCE;
3323 	}
3324 
3325 	CHECK_RIGHT;
3326 	NO_SUPPORT_FOR_BRIDGE;
3327 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
3328 	{
3329 		return ERR_NOT_SUPPORTED;
3330 	}
3331 
3332 	StrCpy(hubname, sizeof(hubname), t->HubName);
3333 
3334 	h = GetHub(c, hubname);
3335 
3336 	if (h == NULL)
3337 	{
3338 		ret = ERR_HUB_NOT_FOUND;
3339 	}
3340 	else
3341 	{
3342 		if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_access_control_list") != 0)
3343 		{
3344 			ret = ERR_NOT_ENOUGH_RIGHT;
3345 		}
3346 		else
3347 		{
3348 			if (h->HubDb == NULL)
3349 			{
3350 				ret = ERR_NOT_SUPPORTED;
3351 			}
3352 			else
3353 			{
3354 				HUBDB *db = h->HubDb;
3355 
3356 				LockList(db->AcList);
3357 				{
3358 					SetAcList(db->AcList, t->o);
3359 
3360 					{
3361 						ALog(a, h, "LA_SET_AC_LIST", LIST_NUM(t->o));
3362 
3363 						IncrementServerConfigRevision(s);
3364 					}
3365 				}
3366 				UnlockList(db->AcList);
3367 			}
3368 		}
3369 		ReleaseHub(h);
3370 	}
3371 
3372 	return ret;
3373 }
3374 
3375 // Set CRL (Certificate Revocation List) entry
StSetCrl(ADMIN * a,RPC_CRL * t)3376 UINT StSetCrl(ADMIN *a, RPC_CRL *t)
3377 {
3378 	SERVER *s = a->Server;
3379 	CEDAR *c = s->Cedar;
3380 	HUB *h;
3381 	UINT ret = ERR_NO_ERROR;
3382 	UINT key;
3383 	char hubname[MAX_HUBNAME_LEN + 1];
3384 
3385 	CHECK_RIGHT;
3386 	NO_SUPPORT_FOR_BRIDGE;
3387 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
3388 	{
3389 		return ERR_NOT_SUPPORTED;
3390 	}
3391 
3392 	StrCpy(hubname, sizeof(hubname), t->HubName);
3393 	key = t->Key;
3394 
3395 	h = GetHub(c, hubname);
3396 
3397 	if (h == NULL)
3398 	{
3399 		ret = ERR_HUB_NOT_FOUND;
3400 	}
3401 	else
3402 	{
3403 		if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_crl_list") != 0)
3404 		{
3405 			ret = ERR_NOT_ENOUGH_RIGHT;
3406 		}
3407 		else
3408 		{
3409 			if (h->HubDb == NULL)
3410 			{
3411 				ret = ERR_NOT_SUPPORTED;
3412 			}
3413 			else
3414 			{
3415 				LockList(h->HubDb->CrlList);
3416 				{
3417 					CRL *crl = ListKeyToPointer(h->HubDb->CrlList, t->Key);
3418 
3419 					if (crl == NULL)
3420 					{
3421 						ret = ERR_OBJECT_NOT_FOUND;
3422 					}
3423 					else
3424 					{
3425 						CRL *new_crl = CopyCrl(t->Crl);
3426 						if (ReplaceListPointer(h->HubDb->CrlList, crl, new_crl))
3427 						{
3428 							ALog(a, h, "LA_ADD_CRL");
3429 							FreeCrl(crl);
3430 
3431 							IncrementServerConfigRevision(s);
3432 						}
3433 					}
3434 				}
3435 				UnlockList(h->HubDb->CrlList);
3436 			}
3437 		}
3438 
3439 		ReleaseHub(h);
3440 	}
3441 
3442 	return ret;
3443 }
3444 
3445 // Get CRL (Certificate Revocation List) entry
StGetCrl(ADMIN * a,RPC_CRL * t)3446 UINT StGetCrl(ADMIN *a, RPC_CRL *t)
3447 {
3448 	SERVER *s = a->Server;
3449 	CEDAR *c = s->Cedar;
3450 	HUB *h;
3451 	UINT ret = ERR_NO_ERROR;
3452 	UINT key;
3453 	char hubname[MAX_HUBNAME_LEN + 1];
3454 
3455 	CHECK_RIGHT;
3456 	NO_SUPPORT_FOR_BRIDGE;
3457 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
3458 	{
3459 		return ERR_NOT_SUPPORTED;
3460 	}
3461 
3462 	StrCpy(hubname, sizeof(hubname), t->HubName);
3463 	key = t->Key;
3464 
3465 	FreeRpcCrl(t);
3466 	Zero(t, sizeof(RPC_CRL));
3467 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
3468 	t->Key = key;
3469 
3470 	h = GetHub(c, hubname);
3471 
3472 	if (h == NULL)
3473 	{
3474 		ret = ERR_HUB_NOT_FOUND;
3475 	}
3476 	else
3477 	{
3478 		if (h->HubDb == NULL)
3479 		{
3480 			ret = ERR_NOT_SUPPORTED;
3481 		}
3482 		else
3483 		{
3484 			LockList(h->HubDb->CrlList);
3485 			{
3486 				CRL *crl = ListKeyToPointer(h->HubDb->CrlList, t->Key);
3487 
3488 				if (crl == NULL)
3489 				{
3490 					ret = ERR_OBJECT_NOT_FOUND;
3491 				}
3492 				else
3493 				{
3494 					t->Crl = CopyCrl(crl);
3495 				}
3496 			}
3497 			UnlockList(h->HubDb->CrlList);
3498 		}
3499 
3500 		ReleaseHub(h);
3501 	}
3502 
3503 	return ret;
3504 }
3505 
3506 // Delete CRL (Certificate Revocation List) entry
StDelCrl(ADMIN * a,RPC_CRL * t)3507 UINT StDelCrl(ADMIN *a, RPC_CRL *t)
3508 {
3509 	SERVER *s = a->Server;
3510 	CEDAR *c = s->Cedar;
3511 	HUB *h;
3512 	UINT ret = ERR_NO_ERROR;
3513 	char hubname[MAX_HUBNAME_LEN + 1];
3514 
3515 	CHECK_RIGHT;
3516 	NO_SUPPORT_FOR_BRIDGE;
3517 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
3518 	{
3519 		return ERR_NOT_SUPPORTED;
3520 	}
3521 
3522 	StrCpy(hubname, sizeof(hubname), t->HubName);
3523 
3524 	h = GetHub(c, hubname);
3525 
3526 	if (h == NULL)
3527 	{
3528 		ret = ERR_HUB_NOT_FOUND;
3529 	}
3530 	else
3531 	{
3532 		if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_crl_list") != 0)
3533 		{
3534 			ret = ERR_NOT_ENOUGH_RIGHT;
3535 		}
3536 		else
3537 		{
3538 			if (h->HubDb == NULL)
3539 			{
3540 				ret = ERR_NOT_SUPPORTED;
3541 			}
3542 			else
3543 			{
3544 				LockList(h->HubDb->CrlList);
3545 				{
3546 					CRL *crl = ListKeyToPointer(h->HubDb->CrlList, t->Key);
3547 
3548 					if (crl == NULL)
3549 					{
3550 						ret = ERR_OBJECT_NOT_FOUND;
3551 					}
3552 					else
3553 					{
3554 						ALog(a, h, "LA_DEL_CRL");
3555 						FreeCrl(crl);
3556 						Delete(h->HubDb->CrlList, crl);
3557 					}
3558 				}
3559 				UnlockList(h->HubDb->CrlList);
3560 			}
3561 		}
3562 
3563 		ReleaseHub(h);
3564 	}
3565 
3566 	return ret;
3567 }
3568 
3569 // Add new CRL (Certificate Revocation List) entry
StAddCrl(ADMIN * a,RPC_CRL * t)3570 UINT StAddCrl(ADMIN *a, RPC_CRL *t)
3571 {
3572 	SERVER *s = a->Server;
3573 	CEDAR *c = s->Cedar;
3574 	HUB *h;
3575 	UINT ret = ERR_NO_ERROR;
3576 	char hubname[MAX_HUBNAME_LEN + 1];
3577 
3578 	if (c->Bridge)
3579 	{
3580 		return ERR_NOT_SUPPORTED;
3581 	}
3582 
3583 	CHECK_RIGHT;
3584 	NO_SUPPORT_FOR_BRIDGE;
3585 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
3586 	{
3587 		return ERR_NOT_SUPPORTED;
3588 	}
3589 
3590 	StrCpy(hubname, sizeof(hubname), t->HubName);
3591 
3592 	h = GetHub(c, hubname);
3593 
3594 	if (h == NULL)
3595 	{
3596 		ret = ERR_HUB_NOT_FOUND;
3597 	}
3598 	else
3599 	{
3600 		if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_crl_list") != 0)
3601 		{
3602 			ret = ERR_NOT_ENOUGH_RIGHT;
3603 		}
3604 		else
3605 		{
3606 			if (h->HubDb == NULL)
3607 			{
3608 				ret = ERR_NOT_SUPPORTED;
3609 			}
3610 			else
3611 			{
3612 				LockList(h->HubDb->CrlList);
3613 				{
3614 					if (LIST_NUM(h->HubDb->CrlList) < MAX_HUB_CRLS)
3615 					{
3616 						CRL *crl = CopyCrl(t->Crl);
3617 
3618 						Insert(h->HubDb->CrlList, crl);
3619 
3620 						ALog(a, h, "LA_SET_CRL");
3621 
3622 						IncrementServerConfigRevision(s);
3623 					}
3624 				}
3625 				UnlockList(h->HubDb->CrlList);
3626 			}
3627 		}
3628 
3629 		ReleaseHub(h);
3630 	}
3631 
3632 	return ret;
3633 }
3634 
3635 // Get CRL (Certificate Revocation List) index
StEnumCrl(ADMIN * a,RPC_ENUM_CRL * t)3636 UINT StEnumCrl(ADMIN *a, RPC_ENUM_CRL *t)
3637 {
3638 	SERVER *s = a->Server;
3639 	CEDAR *c = s->Cedar;
3640 	HUB *h;
3641 	UINT ret = ERR_NO_ERROR;
3642 	char hubname[MAX_HUBNAME_LEN + 1];
3643 
3644 	CHECK_RIGHT;
3645 	NO_SUPPORT_FOR_BRIDGE;
3646 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
3647 	{
3648 		return ERR_NOT_SUPPORTED;
3649 	}
3650 
3651 	StrCpy(hubname, sizeof(hubname), t->HubName);
3652 	FreeRpcEnumCrl(t);
3653 	Zero(t, sizeof(RPC_ENUM_CRL));
3654 
3655 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
3656 
3657 	h = GetHub(c, hubname);
3658 
3659 	if (h == NULL)
3660 	{
3661 		ret = ERR_HUB_NOT_FOUND;
3662 	}
3663 	else
3664 	{
3665 		if (h->HubDb == NULL)
3666 		{
3667 			ret = ERR_NOT_SUPPORTED;
3668 		}
3669 		else
3670 		{
3671 			LockList(h->HubDb->CrlList);
3672 			{
3673 				UINT i;
3674 
3675 				t->NumItem = LIST_NUM(h->HubDb->CrlList);
3676 				t->Items = ZeroMalloc(sizeof(RPC_ENUM_CRL_ITEM) * t->NumItem);
3677 
3678 				for (i = 0;i < LIST_NUM(h->HubDb->CrlList);i++)
3679 				{
3680 					CRL *crl = LIST_DATA(h->HubDb->CrlList, i);
3681 					wchar_t *info = GenerateCrlStr(crl);
3682 
3683 					UniStrCpy(t->Items[i].CrlInfo, sizeof(t->Items[i].CrlInfo), info);
3684 					Free(info);
3685 
3686 					t->Items[i].Key = POINTER_TO_KEY(crl);
3687 				}
3688 			}
3689 			UnlockList(h->HubDb->CrlList);
3690 		}
3691 
3692 		ReleaseHub(h);
3693 	}
3694 
3695 	return ret;
3696 }
3697 
3698 // Get routing table on virtual L3 switch
StEnumL3Table(ADMIN * a,RPC_ENUM_L3TABLE * t)3699 UINT StEnumL3Table(ADMIN *a, RPC_ENUM_L3TABLE *t)
3700 {
3701 	SERVER *s = a->Server;
3702 	CEDAR *c = s->Cedar;
3703 	UINT ret = ERR_NO_ERROR;
3704 	L3SW *sw;
3705 	char name[MAX_HUBNAME_LEN + 1];
3706 
3707 	if (IsEmptyStr(t->Name))
3708 	{
3709 		return ERR_INVALID_PARAMETER;
3710 	}
3711 
3712 	NO_SUPPORT_FOR_BRIDGE;
3713 
3714 	StrCpy(name, sizeof(name), t->Name);
3715 	FreeRpcEnumL3Table(t);
3716 	Zero(t, sizeof(RPC_ENUM_L3TABLE));
3717 	StrCpy(t->Name, sizeof(t->Name), name);
3718 
3719 	sw = L3GetSw(c, t->Name);
3720 
3721 	if (sw == NULL)
3722 	{
3723 		ret = ERR_LAYER3_SW_NOT_FOUND;
3724 	}
3725 	else
3726 	{
3727 		UINT i;
3728 
3729 		Lock(sw->lock);
3730 		{
3731 			t->NumItem = LIST_NUM(sw->TableList);
3732 			t->Items = ZeroMalloc(sizeof(RPC_L3TABLE) * t->NumItem);
3733 
3734 			for (i = 0;i < t->NumItem;i++)
3735 			{
3736 				L3TABLE *tbl = LIST_DATA(sw->TableList, i);
3737 				RPC_L3TABLE *e = &t->Items[i];
3738 
3739 				StrCpy(e->Name, sizeof(e->Name), name);
3740 				e->NetworkAddress = tbl->NetworkAddress;
3741 				e->SubnetMask = tbl->SubnetMask;
3742 				e->GatewayAddress = tbl->GatewayAddress;
3743 				e->Metric = tbl->Metric;
3744 			}
3745 		}
3746 		Unlock(sw->lock);
3747 
3748 		ReleaseL3Sw(sw);
3749 	}
3750 
3751 	return ret;
3752 }
3753 
3754 // Delete routing table entry on virtual L3 switch
StDelL3Table(ADMIN * a,RPC_L3TABLE * t)3755 UINT StDelL3Table(ADMIN *a, RPC_L3TABLE *t)
3756 {
3757 	SERVER *s = a->Server;
3758 	CEDAR *c = s->Cedar;
3759 	UINT ret = ERR_NO_ERROR;
3760 	L3SW *sw;
3761 
3762 	SERVER_ADMIN_ONLY;
3763 
3764 	NO_SUPPORT_FOR_BRIDGE;
3765 
3766 	sw = L3GetSw(c, t->Name);
3767 
3768 	if (sw == NULL)
3769 	{
3770 		ret = ERR_LAYER3_SW_NOT_FOUND;
3771 	}
3772 	else
3773 	{
3774 		L3TABLE tbl;
3775 
3776 		Zero(&tbl, sizeof(tbl));
3777 		tbl.NetworkAddress = t->NetworkAddress;
3778 		tbl.SubnetMask = t->SubnetMask;
3779 		tbl.GatewayAddress = t->GatewayAddress;
3780 		tbl.Metric = t->Metric;
3781 
3782 		if (L3DelTable(sw, &tbl) == false)
3783 		{
3784 			ret = ERR_LAYER3_TABLE_DEL_FAILED;
3785 		}
3786 		else
3787 		{
3788 			char tmp[MAX_SIZE];
3789 			IPToStr32(tmp, sizeof(tmp), tbl.NetworkAddress);
3790 			ALog(a, NULL, "LA_DEL_L3_TABLE", tmp, t->Name);
3791 
3792 			IncrementServerConfigRevision(s);
3793 		}
3794 
3795 		ReleaseL3Sw(sw);
3796 	}
3797 
3798 	return ret;
3799 }
3800 
3801 // Add new routing table entry on virtual L3 switch
StAddL3Table(ADMIN * a,RPC_L3TABLE * t)3802 UINT StAddL3Table(ADMIN *a, RPC_L3TABLE *t)
3803 {
3804 	SERVER *s = a->Server;
3805 	CEDAR *c = s->Cedar;
3806 	UINT ret = ERR_NO_ERROR;
3807 	L3SW *sw;
3808 
3809 	if (IsNetworkAddress32(t->NetworkAddress, t->SubnetMask) == false ||
3810 		IsHostIPAddress32(t->GatewayAddress) == false)
3811 	{
3812 		return ERR_INVALID_PARAMETER;
3813 	}
3814 
3815 	SERVER_ADMIN_ONLY;
3816 
3817 	NO_SUPPORT_FOR_BRIDGE;
3818 
3819 	sw = L3GetSw(c, t->Name);
3820 
3821 	if (sw == NULL)
3822 	{
3823 		ret = ERR_LAYER3_SW_NOT_FOUND;
3824 	}
3825 	else
3826 	{
3827 		L3TABLE tbl;
3828 
3829 		Zero(&tbl, sizeof(tbl));
3830 		tbl.NetworkAddress = t->NetworkAddress;
3831 		tbl.SubnetMask = t->SubnetMask;
3832 		tbl.GatewayAddress = t->GatewayAddress;
3833 		tbl.Metric = t->Metric;
3834 
3835 		if (L3AddTable(sw, &tbl) == false)
3836 		{
3837 			ret = ERR_LAYER3_TABLE_ADD_FAILED;
3838 		}
3839 		else
3840 		{
3841 			char tmp[MAX_SIZE];
3842 			IPToStr32(tmp, sizeof(tmp), tbl.NetworkAddress);
3843 			ALog(a, NULL, "LA_ADD_L3_TABLE", tmp, t->Name);
3844 
3845 			IncrementServerConfigRevision(s);
3846 		}
3847 
3848 		ReleaseL3Sw(sw);
3849 	}
3850 
3851 	return ret;
3852 }
3853 
3854 // Enumerate virtual interfaces on virtual L3 switch
StEnumL3If(ADMIN * a,RPC_ENUM_L3IF * t)3855 UINT StEnumL3If(ADMIN *a, RPC_ENUM_L3IF *t)
3856 {
3857 	SERVER *s = a->Server;
3858 	CEDAR *c = s->Cedar;
3859 	UINT ret = ERR_NO_ERROR;
3860 	L3SW *sw;
3861 	char name[MAX_HUBNAME_LEN + 1];
3862 
3863 	NO_SUPPORT_FOR_BRIDGE;
3864 
3865 	StrCpy(name, sizeof(name), t->Name);
3866 
3867 	FreeRpcEnumL3If(t);
3868 	Zero(t, sizeof(RPC_ENUM_L3IF));
3869 
3870 	StrCpy(t->Name, sizeof(t->Name), name);
3871 
3872 	sw = L3GetSw(c, t->Name);
3873 
3874 	if (sw == NULL)
3875 	{
3876 		ret = ERR_LAYER3_SW_NOT_FOUND;
3877 	}
3878 	else
3879 	{
3880 		Lock(sw->lock);
3881 		{
3882 			UINT i;
3883 
3884 			t->NumItem = LIST_NUM(sw->IfList);
3885 			t->Items = ZeroMalloc(sizeof(RPC_L3IF) * t->NumItem);
3886 
3887 			for (i = 0;i < t->NumItem;i++)
3888 			{
3889 				L3IF *f = LIST_DATA(sw->IfList, i);
3890 				RPC_L3IF *e = &t->Items[i];
3891 
3892 				StrCpy(e->Name, sizeof(e->Name), sw->Name);
3893 				StrCpy(e->HubName, sizeof(e->HubName), f->HubName);
3894 				e->IpAddress = f->IpAddress;
3895 				e->SubnetMask = f->SubnetMask;
3896 			}
3897 		}
3898 		Unlock(sw->lock);
3899 
3900 		ReleaseL3Sw(sw);
3901 	}
3902 
3903 	return ret;
3904 }
3905 
3906 // Delete a virtual interface on virtual L3 switch
StDelL3If(ADMIN * a,RPC_L3IF * t)3907 UINT StDelL3If(ADMIN *a, RPC_L3IF *t)
3908 {
3909 	SERVER *s = a->Server;
3910 	CEDAR *c = s->Cedar;
3911 	UINT ret = ERR_NO_ERROR;
3912 	L3SW *sw;
3913 
3914 	NO_SUPPORT_FOR_BRIDGE;
3915 
3916 	SERVER_ADMIN_ONLY;
3917 
3918 	sw = L3GetSw(c, t->Name);
3919 
3920 	if (sw == NULL)
3921 	{
3922 		ret = ERR_LAYER3_SW_NOT_FOUND;
3923 	}
3924 	else
3925 	{
3926 		if (L3DelIf(sw, t->HubName) == false)
3927 		{
3928 			ret = ERR_LAYER3_IF_DEL_FAILED;
3929 		}
3930 		else
3931 		{
3932 			ALog(a, NULL, "LA_DEL_L3_IF", t->HubName, t->Name);
3933 
3934 			IncrementServerConfigRevision(s);
3935 		}
3936 		ReleaseL3Sw(sw);
3937 	}
3938 
3939 	return ret;
3940 }
3941 
3942 // Add new virtual interface on virtual L3 switch
StAddL3If(ADMIN * a,RPC_L3IF * t)3943 UINT StAddL3If(ADMIN *a, RPC_L3IF *t)
3944 {
3945 	SERVER *s = a->Server;
3946 	CEDAR *c = s->Cedar;
3947 	UINT ret = ERR_NO_ERROR;
3948 	L3SW *sw;
3949 
3950 
3951 	if (IsSubnetMask32(t->SubnetMask) == false || IsHostIPAddress32(t->IpAddress) == false)
3952 	{
3953 		return ERR_INVALID_PARAMETER;
3954 	}
3955 	if ((t->IpAddress & (~t->SubnetMask)) == 0)
3956 	{
3957 		return ERR_INVALID_PARAMETER;
3958 	}
3959 
3960 	NO_SUPPORT_FOR_BRIDGE;
3961 
3962 	SERVER_ADMIN_ONLY;
3963 
3964 	sw = L3GetSw(c, t->Name);
3965 
3966 	if (sw == NULL)
3967 	{
3968 		ret = ERR_LAYER3_SW_NOT_FOUND;
3969 	}
3970 	else
3971 	{
3972 		Lock(sw->lock);
3973 		{
3974 			if (L3SearchIf(sw, t->HubName) != NULL)
3975 			{
3976 				// Already exists
3977 				ret = ERR_LAYER3_IF_EXISTS;
3978 			}
3979 			else
3980 			{
3981 				if (L3AddIf(sw, t->HubName, t->IpAddress, t->SubnetMask) == false)
3982 				{
3983 					ret = ERR_LAYER3_IF_ADD_FAILED;
3984 				}
3985 				else
3986 				{
3987 					ALog(a, NULL, "LA_ADD_L3_IF", t->HubName, t->Name);
3988 
3989 					IncrementServerConfigRevision(s);
3990 				}
3991 			}
3992 		}
3993 		Unlock(sw->lock);
3994 		ReleaseL3Sw(sw);
3995 	}
3996 
3997 	return ret;
3998 }
3999 
4000 // Stop a virtual layer-3 switch
StStopL3Switch(ADMIN * a,RPC_L3SW * t)4001 UINT StStopL3Switch(ADMIN *a, RPC_L3SW *t)
4002 {
4003 	SERVER *s = a->Server;
4004 	CEDAR *c = s->Cedar;
4005 	UINT ret = ERR_NO_ERROR;
4006 	L3SW *sw;
4007 
4008 	if (IsEmptyStr(t->Name))
4009 	{
4010 		return ERR_INVALID_PARAMETER;
4011 	}
4012 
4013 	NO_SUPPORT_FOR_BRIDGE;
4014 
4015 	SERVER_ADMIN_ONLY;
4016 
4017 	sw = L3GetSw(c, t->Name);
4018 
4019 	if (sw == NULL)
4020 	{
4021 		ret = ERR_LAYER3_SW_NOT_FOUND;
4022 	}
4023 	else
4024 	{
4025 		L3SwStop(sw);
4026 		ALog(a, NULL, "LA_STOP_L3_SW", sw->Name);
4027 		ReleaseL3Sw(sw);
4028 
4029 		IncrementServerConfigRevision(s);
4030 	}
4031 
4032 	return ret;
4033 }
4034 
4035 // Start a virtual layer-3 switch
StStartL3Switch(ADMIN * a,RPC_L3SW * t)4036 UINT StStartL3Switch(ADMIN *a, RPC_L3SW *t)
4037 {
4038 	SERVER *s = a->Server;
4039 	CEDAR *c = s->Cedar;
4040 	UINT ret = ERR_NO_ERROR;
4041 	L3SW *sw;
4042 
4043 	if (IsEmptyStr(t->Name))
4044 	{
4045 		return ERR_INVALID_PARAMETER;
4046 	}
4047 
4048 	NO_SUPPORT_FOR_BRIDGE;
4049 
4050 	SERVER_ADMIN_ONLY;
4051 
4052 	sw = L3GetSw(c, t->Name);
4053 
4054 	if (sw == NULL)
4055 	{
4056 		ret = ERR_LAYER3_SW_NOT_FOUND;
4057 	}
4058 	else
4059 	{
4060 		Lock(sw->lock);
4061 		{
4062 			// Count the registered virtual interfaces
4063 			if (LIST_NUM(sw->IfList) >= 1)
4064 			{
4065 				L3SwStart(sw);
4066 
4067 				ALog(a, NULL, "LA_START_L3_SW", sw->Name);
4068 
4069 				IncrementServerConfigRevision(s);
4070 			}
4071 			else
4072 			{
4073 				ret = ERR_LAYER3_CANT_START_SWITCH;
4074 			}
4075 		}
4076 		Unlock(sw->lock);
4077 
4078 		ReleaseL3Sw(sw);
4079 	}
4080 
4081 	return ret;
4082 }
4083 
4084 // Enumerate virtual layer-3 switches
StEnumL3Switch(ADMIN * a,RPC_ENUM_L3SW * t)4085 UINT StEnumL3Switch(ADMIN *a, RPC_ENUM_L3SW *t)
4086 {
4087 	UINT i;
4088 	SERVER *s = a->Server;
4089 	CEDAR *c = s->Cedar;
4090 	UINT ret = ERR_NO_ERROR;
4091 
4092 	NO_SUPPORT_FOR_BRIDGE;
4093 
4094 	FreeRpcEnumL3Sw(t);
4095 	Zero(t, sizeof(RPC_ENUM_L3SW));
4096 
4097 	LockList(c->L3SwList);
4098 	{
4099 		t->NumItem = LIST_NUM(c->L3SwList);
4100 		t->Items = ZeroMalloc(sizeof(RPC_ENUM_L3SW_ITEM) * t->NumItem);
4101 		for (i = 0;i < LIST_NUM(c->L3SwList);i++)
4102 		{
4103 			L3SW *sw = LIST_DATA(c->L3SwList, i);
4104 			RPC_ENUM_L3SW_ITEM *e = &t->Items[i];
4105 
4106 			Lock(sw->lock);
4107 			{
4108 				StrCpy(e->Name, sizeof(e->Name), sw->Name);
4109 				e->NumInterfaces = LIST_NUM(sw->IfList);
4110 				e->NumTables = LIST_NUM(sw->TableList);
4111 				e->Active = sw->Active;
4112 				e->Online = sw->Online;
4113 			}
4114 			Unlock(sw->lock);
4115 		}
4116 	}
4117 	UnlockList(c->L3SwList);
4118 
4119 	return ret;
4120 }
4121 
4122 // Delete a virtual layer-3 switch
StDelL3Switch(ADMIN * a,RPC_L3SW * t)4123 UINT StDelL3Switch(ADMIN *a, RPC_L3SW *t)
4124 {
4125 	SERVER *s = a->Server;
4126 	CEDAR *c = s->Cedar;
4127 	UINT ret = ERR_NO_ERROR;
4128 
4129 	if (IsEmptyStr(t->Name))
4130 	{
4131 		return ERR_INVALID_PARAMETER;
4132 	}
4133 
4134 	NO_SUPPORT_FOR_BRIDGE;
4135 
4136 	SERVER_ADMIN_ONLY;
4137 
4138 	if (L3DelSw(c, t->Name) == false)
4139 	{
4140 		ret = ERR_LAYER3_SW_NOT_FOUND;
4141 	}
4142 	else
4143 	{
4144 		ALog(a, NULL, "LA_DEL_L3_SW", t->Name);
4145 
4146 		IncrementServerConfigRevision(s);
4147 	}
4148 
4149 	return ret;
4150 }
4151 
4152 // Add a new virtual layer-3 switch
StAddL3Switch(ADMIN * a,RPC_L3SW * t)4153 UINT StAddL3Switch(ADMIN *a, RPC_L3SW *t)
4154 {
4155 	SERVER *s = a->Server;
4156 	CEDAR *c = s->Cedar;
4157 	UINT ret = ERR_NO_ERROR;
4158 	L3SW *sw;
4159 
4160 	NO_SUPPORT_FOR_BRIDGE;
4161 
4162 	if (IsEmptyStr(t->Name))
4163 	{
4164 		return ERR_INVALID_PARAMETER;
4165 	}
4166 
4167 	if (IsSafeStr(t->Name) == false)
4168 	{
4169 		return ERR_INVALID_PARAMETER;
4170 	}
4171 
4172 	SERVER_ADMIN_ONLY;
4173 
4174 	// Duplication check
4175 	sw = L3GetSw(c, t->Name);
4176 	if (sw != NULL)
4177 	{
4178 		// Already exists
4179 		ReleaseL3Sw(sw);
4180 		ret = ERR_LAYER3_SW_EXISTS;
4181 	}
4182 	else
4183 	{
4184 		LockList(c->L3SwList);
4185 		{
4186 			if (LIST_NUM(c->L3SwList) >= GetServerCapsInt(s, "i_max_l3_sw"))
4187 			{
4188 				// No more virtual interfaces
4189 				sw = NULL;
4190 			}
4191 			else
4192 			{
4193 				// Create
4194 				sw = L3AddSw(c, t->Name);
4195 
4196 				if (sw != NULL)
4197 				{
4198 					ALog(a, NULL, "LA_ADD_L3_SW", t->Name);
4199 
4200 					IncrementServerConfigRevision(s);
4201 				}
4202 			}
4203 		}
4204 		UnlockList(c->L3SwList);
4205 
4206 		if (sw == NULL)
4207 		{
4208 			// Failed
4209 			ret = ERR_INTERNAL_ERROR;
4210 		}
4211 		else
4212 		{
4213 			// Success
4214 			ReleaseL3Sw(sw);
4215 		}
4216 	}
4217 
4218 	return ret;
4219 }
4220 
4221 // Set hub extended options
StSetHubExtOptions(ADMIN * a,RPC_ADMIN_OPTION * t)4222 UINT StSetHubExtOptions(ADMIN *a, RPC_ADMIN_OPTION *t)
4223 {
4224 	SERVER *s = a->Server;
4225 	CEDAR *c = s->Cedar;
4226 	HUB *h;
4227 
4228 	bool not_server_admin = false;
4229 
4230 	if (t->NumItem > MAX_HUB_ADMIN_OPTIONS)
4231 	{
4232 		return ERR_TOO_MANT_ITEMS;
4233 	}
4234 
4235 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
4236 	{
4237 		return ERR_NOT_SUPPORTED;
4238 	}
4239 
4240 
4241 	CHECK_RIGHT;
4242 
4243 	if (a->ServerAdmin == false)
4244 	{
4245 		not_server_admin = true;
4246 	}
4247 
4248 	LockHubList(c);
4249 	{
4250 		h = GetHub(c, t->HubName);
4251 	}
4252 	UnlockHubList(c);
4253 
4254 	if (h == NULL)
4255 	{
4256 		return ERR_HUB_NOT_FOUND;
4257 	}
4258 
4259 	if (GetHubAdminOption(h, "deny_hub_admin_change_ext_option") && not_server_admin)
4260 	{
4261 		// Insufficient permission
4262 		ReleaseHub(h);
4263 
4264 		return ERR_NOT_ENOUGH_RIGHT;
4265 	}
4266 
4267 	// Update setting
4268 	Lock(h->lock);
4269 	{
4270 		DataToHubOptionStruct(h->Option, t);
4271 	}
4272 	Unlock(h->lock);
4273 
4274 	ALog(a, NULL, "LA_SET_HUB_EXT_OPTION", h->Name);
4275 
4276 	h->CurrentVersion++;
4277 	SiHubUpdateProc(h);
4278 
4279 	ReleaseHub(h);
4280 
4281 	IncrementServerConfigRevision(s);
4282 
4283 	return ERR_NO_ERROR;
4284 }
4285 
4286 // Get hub extended options
StGetHubExtOptions(ADMIN * a,RPC_ADMIN_OPTION * t)4287 UINT StGetHubExtOptions(ADMIN *a, RPC_ADMIN_OPTION *t)
4288 {
4289 	SERVER *s = a->Server;
4290 	CEDAR *c = s->Cedar;
4291 	HUB *h;
4292 
4293 	CHECK_RIGHT;
4294 
4295 	LockHubList(c);
4296 	{
4297 		h = GetHub(c, t->HubName);
4298 	}
4299 	UnlockHubList(c);
4300 
4301 	if (h == NULL)
4302 	{
4303 		return ERR_HUB_NOT_FOUND;
4304 	}
4305 
4306 	FreeRpcAdminOption(t);
4307 	Zero(t, sizeof(RPC_ADMIN_OPTION));
4308 
4309 	StrCpy(t->HubName, sizeof(t->HubName), h->Name);
4310 
4311 	// Get options
4312 	Lock(h->lock);
4313 	{
4314 		HubOptionStructToData(t, h->Option, h->Name);
4315 	}
4316 	Unlock(h->lock);
4317 
4318 	ReleaseHub(h);
4319 
4320 	return ERR_NO_ERROR;
4321 }
4322 
4323 // Set hub administration options
StSetHubAdminOptions(ADMIN * a,RPC_ADMIN_OPTION * t)4324 UINT StSetHubAdminOptions(ADMIN *a, RPC_ADMIN_OPTION *t)
4325 {
4326 	UINT i;
4327 	SERVER *s = a->Server;
4328 	CEDAR *c = s->Cedar;
4329 	HUB *h;
4330 
4331 	bool not_server_admin = false;
4332 
4333 
4334 	if (t->NumItem > MAX_HUB_ADMIN_OPTIONS)
4335 	{
4336 		return ERR_TOO_MANT_ITEMS;
4337 	}
4338 
4339 	NO_SUPPORT_FOR_BRIDGE;
4340 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
4341 	{
4342 		return ERR_NOT_SUPPORTED;
4343 	}
4344 
4345 	CHECK_RIGHT;
4346 
4347 	if (a->ServerAdmin == false)
4348 	{
4349 		not_server_admin = true;
4350 	}
4351 
4352 	LockHubList(c);
4353 	{
4354 		h = GetHub(c, t->HubName);
4355 	}
4356 	UnlockHubList(c);
4357 
4358 	if (h == NULL)
4359 	{
4360 		return ERR_HUB_NOT_FOUND;
4361 	}
4362 
4363 	if (GetHubAdminOption(h, "allow_hub_admin_change_option") == false
4364 		&& not_server_admin)
4365 	{
4366 		// Insufficient permission
4367 		ReleaseHub(h);
4368 
4369 		return ERR_NOT_ENOUGH_RIGHT;
4370 	}
4371 
4372 	LockList(h->AdminOptionList);
4373 	{
4374 		DeleteAllHubAdminOption(h, false);
4375 
4376 		for (i = 0;i < t->NumItem;i++)
4377 		{
4378 			ADMIN_OPTION *e = &t->Items[i];
4379 			ADMIN_OPTION *a = ZeroMalloc(sizeof(ADMIN_OPTION));
4380 
4381 			StrCpy(a->Name, sizeof(a->Name), e->Name);
4382 			a->Value = e->Value;
4383 
4384 			Insert(h->AdminOptionList, a);
4385 		}
4386 
4387 		AddHubAdminOptionsDefaults(h, false);
4388 	}
4389 	UnlockList(h->AdminOptionList);
4390 
4391 	ALog(a, NULL, "LA_SET_HUB_ADMIN_OPTION", h->Name);
4392 
4393 	h->CurrentVersion++;
4394 	SiHubUpdateProc(h);
4395 
4396 	ReleaseHub(h);
4397 
4398 	IncrementServerConfigRevision(s);
4399 
4400 	return ERR_NO_ERROR;
4401 }
4402 
4403 // Get hub administration options
StGetHubAdminOptions(ADMIN * a,RPC_ADMIN_OPTION * t)4404 UINT StGetHubAdminOptions(ADMIN *a, RPC_ADMIN_OPTION *t)
4405 {
4406 	UINT i;
4407 	SERVER *s = a->Server;
4408 	CEDAR *c = s->Cedar;
4409 	HUB *h;
4410 
4411 	CHECK_RIGHT;
4412 
4413 	NO_SUPPORT_FOR_BRIDGE;
4414 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
4415 	{
4416 		return ERR_NOT_SUPPORTED;
4417 	}
4418 
4419 	LockHubList(c);
4420 	{
4421 		h = GetHub(c, t->HubName);
4422 	}
4423 	UnlockHubList(c);
4424 
4425 	if (h == NULL)
4426 	{
4427 		return ERR_HUB_NOT_FOUND;
4428 	}
4429 
4430 	FreeRpcAdminOption(t);
4431 	Zero(t, sizeof(RPC_ADMIN_OPTION));
4432 
4433 	StrCpy(t->HubName, sizeof(t->HubName), h->Name);
4434 
4435 	LockList(h->AdminOptionList);
4436 	{
4437 		t->NumItem = LIST_NUM(h->AdminOptionList);
4438 		t->Items = ZeroMalloc(sizeof(ADMIN_OPTION) * t->NumItem);
4439 
4440 		for (i = 0;i < t->NumItem;i++)
4441 		{
4442 			ADMIN_OPTION *a = LIST_DATA(h->AdminOptionList, i);
4443 			ADMIN_OPTION *e = &t->Items[i];
4444 
4445 			StrCpy(e->Name, sizeof(e->Name), a->Name);
4446 			e->Value = a->Value;
4447 			UniStrCpy(e->Descrption, sizeof(e->Descrption), GetHubAdminOptionHelpString(e->Name));
4448 		}
4449 	}
4450 	UnlockList(h->AdminOptionList);
4451 
4452 	ReleaseHub(h);
4453 
4454 	return ERR_NO_ERROR;
4455 }
4456 
4457 // Get default hub administration options
StGetDefaultHubAdminOptions(ADMIN * a,RPC_ADMIN_OPTION * t)4458 UINT StGetDefaultHubAdminOptions(ADMIN *a, RPC_ADMIN_OPTION *t)
4459 {
4460 	UINT i;
4461 
4462 	NO_SUPPORT_FOR_BRIDGE;
4463 	if (a->Server->ServerType == SERVER_TYPE_FARM_MEMBER)
4464 	{
4465 		return ERR_NOT_SUPPORTED;
4466 	}
4467 
4468 	FreeRpcAdminOption(t);
4469 	Zero(t, sizeof(RPC_ADMIN_OPTION));
4470 
4471 	t->NumItem = num_admin_options;
4472 	t->Items = ZeroMalloc(sizeof(ADMIN_OPTION) * t->NumItem);
4473 
4474 	for (i = 0;i < t->NumItem;i++)
4475 	{
4476 		ADMIN_OPTION *a = &t->Items[i];
4477 
4478 		StrCpy(a->Name, sizeof(a->Name), admin_options[i].Name);
4479 		a->Value = admin_options[i].Value;
4480 		UniStrCpy(a->Descrption, sizeof(a->Descrption), GetHubAdminOptionHelpString(a->Name));
4481 	}
4482 
4483 	return ERR_NO_ERROR;
4484 }
4485 
4486 // Get configuration file stream
StGetConfig(ADMIN * a,RPC_CONFIG * t)4487 UINT StGetConfig(ADMIN *a, RPC_CONFIG *t)
4488 {
4489 	SERVER *s;
4490 
4491 	SERVER_ADMIN_ONLY;
4492 
4493 	FreeRpcConfig(t);
4494 	Zero(t, sizeof(RPC_CONFIG));
4495 
4496 	s = a->Server;
4497 
4498 	ALog(a, NULL, "LA_GET_CONFIG");
4499 
4500 	if (s->CfgRw != NULL)
4501 	{
4502 		FOLDER *f = SiWriteConfigurationToCfg(s);
4503 		BUF *b = CfgFolderToBuf(f, true);
4504 
4505 		StrCpy(t->FileName, sizeof(t->FileName), s->CfgRw->FileName + (s->CfgRw->FileName[0] == '@' ? 1 : 0));
4506 
4507 		t->FileData = ZeroMalloc(b->Size + 1);
4508 		Copy(t->FileData, b->Buf, b->Size);
4509 
4510 		CfgDeleteFolder(f);
4511 		FreeBuf(b);
4512 
4513 		return ERR_NO_ERROR;
4514 	}
4515 	else
4516 	{
4517 		return ERR_INTERNAL_ERROR;
4518 	}
4519 }
4520 
4521 // Overwrite configuration file by specified data
StSetConfig(ADMIN * a,RPC_CONFIG * t)4522 UINT StSetConfig(ADMIN *a, RPC_CONFIG *t)
4523 {
4524 	SERVER *s;
4525 	IO *o;
4526 	char filename[MAX_PATH];
4527 
4528 	SERVER_ADMIN_ONLY;
4529 
4530 	s = a->Server;
4531 	if (s->CfgRw == NULL)
4532 	{
4533 		return ERR_INTERNAL_ERROR;
4534 	}
4535 
4536 	// Write new configuration file
4537 	Format(filename, sizeof(filename), "%s.new", s->CfgRw->FileName);
4538 
4539 	o = FileCreate(filename);
4540 
4541 	FileWrite(o, t->FileData, StrLen(t->FileData));
4542 
4543 	FileClose(o);
4544 
4545 	IncrementServerConfigRevision(s);
4546 
4547 	ALog(a, NULL, "LA_SET_CONFIG");
4548 
4549 	// Reboot server itself
4550 	SiRebootServer(s->Cedar->Bridge);
4551 
4552 	return ERR_NO_ERROR;
4553 }
4554 
4555 // Get capabilities
StGetCaps(ADMIN * a,CAPSLIST * t)4556 UINT StGetCaps(ADMIN *a, CAPSLIST *t)
4557 {
4558 	FreeRpcCapsList(t);
4559 	Zero(t, sizeof(CAPSLIST));
4560 
4561 	GetServerCapsMain(a->Server, t);
4562 
4563 	return ERR_NO_ERROR;
4564 }
4565 
4566 // Reboot server itself
StRebootServer(ADMIN * a,RPC_TEST * t)4567 UINT StRebootServer(ADMIN *a, RPC_TEST *t)
4568 {
4569 	SERVER_ADMIN_ONLY;
4570 
4571 	ALog(a, NULL, "LA_REBOOT_SERVER");
4572 
4573 	SiRebootServerEx(a->Server->Cedar->Bridge, t->IntValue);
4574 
4575 	return ERR_NO_ERROR;
4576 }
4577 
4578 // Get availability to localbridge function
StGetBridgeSupport(ADMIN * a,RPC_BRIDGE_SUPPORT * t)4579 UINT StGetBridgeSupport(ADMIN *a, RPC_BRIDGE_SUPPORT *t)
4580 {
4581 	Zero(t, sizeof(RPC_BRIDGE_SUPPORT));
4582 
4583 	t->IsBridgeSupportedOs = IsBridgeSupported();
4584 	t->IsWinPcapNeeded = IsNeedWinPcap();
4585 
4586 	return ERR_NO_ERROR;
4587 }
4588 
4589 // Enumerate Ethernet devices
StEnumEthernet(ADMIN * a,RPC_ENUM_ETH * t)4590 UINT StEnumEthernet(ADMIN *a, RPC_ENUM_ETH *t)
4591 {
4592 	TOKEN_LIST *o;
4593 	UINT i;
4594 	char tmp[MAX_SIZE];
4595 	bool unix_support = false;
4596 
4597 	SERVER_ADMIN_ONLY;
4598 
4599 #ifdef	OS_UNIX
4600 	unix_support = EthIsInterfaceDescriptionSupportedUnix();
4601 #endif	// OS_UNIX
4602 
4603 	o = GetEthList();
4604 	if (o == NULL)
4605 	{
4606 		return ERR_NOT_SUPPORTED;
4607 	}
4608 
4609 	FreeRpcEnumEth(t);
4610 	Zero(t, sizeof(RPC_ENUM_ETH));
4611 
4612 	t->NumItem = o->NumTokens;
4613 	t->Items = ZeroMalloc(sizeof(RPC_ENUM_ETH_ITEM) * t->NumItem);
4614 
4615 	for (i = 0;i < t->NumItem;i++)
4616 	{
4617 		RPC_ENUM_ETH_ITEM *e = &t->Items[i];
4618 
4619 		StrCpy(e->DeviceName, sizeof(e->DeviceName), o->Token[i]);
4620 
4621 		StrCpy(tmp, sizeof(tmp), e->DeviceName);
4622 
4623 #ifdef OS_WIN32
4624 		GetEthNetworkConnectionName(e->NetworkConnectionName, sizeof(e->NetworkConnectionName), e->DeviceName);
4625 #else
4626 		if (unix_support == false)
4627 		{
4628 			StrCpy(tmp, sizeof(tmp), "");
4629 		}
4630 		else
4631 		{
4632 			if (EthGetInterfaceDescriptionUnix(e->DeviceName, tmp, sizeof(tmp)) == false)
4633 			{
4634 				StrCpy(tmp, sizeof(tmp), e->DeviceName);
4635 			}
4636 		}
4637 
4638 		StrToUni(e->NetworkConnectionName, sizeof(e->NetworkConnectionName), tmp);
4639 #endif
4640 	}
4641 
4642 	FreeToken(o);
4643 
4644 	return ERR_NO_ERROR;
4645 }
4646 
4647 // Add a new local bridge
StAddLocalBridge(ADMIN * a,RPC_LOCALBRIDGE * t)4648 UINT StAddLocalBridge(ADMIN *a, RPC_LOCALBRIDGE *t)
4649 {
4650 	if (IsEmptyStr(t->DeviceName) || IsEmptyStr(t->HubName))
4651 	{
4652 		return ERR_INVALID_PARAMETER;
4653 	}
4654 
4655 	SERVER_ADMIN_ONLY;
4656 
4657 
4658 	if (IsEthSupported() == false)
4659 	{
4660 		return ERR_LOCAL_BRIDGE_UNSUPPORTED;
4661 	}
4662 
4663 #ifdef	OS_WIN32
4664 	if (true)
4665 	{
4666 		char tmp[MAX_SIZE];
4667 		UINT id = Win32EthGetNameAndIdFromCombinedName(tmp, sizeof(tmp), t->DeviceName);
4668 
4669 		if (id == 0)
4670 		{
4671 			// If a ID is not specified in Win32, adding will fail
4672 			return ERR_OBJECT_NOT_FOUND;
4673 		}
4674 	}
4675 #endif	// OS_WIN32
4676 
4677 	ALog(a, NULL, "LA_ADD_BRIDGE", t->HubName, t->DeviceName);
4678 
4679 	AddLocalBridge(a->Server->Cedar, t->HubName, t->DeviceName, false, false, t->TapMode, NULL, false);
4680 
4681 	IncrementServerConfigRevision(a->Server);
4682 
4683 	return ERR_NO_ERROR;
4684 }
4685 
4686 // Delete a local bridge
StDeleteLocalBridge(ADMIN * a,RPC_LOCALBRIDGE * t)4687 UINT StDeleteLocalBridge(ADMIN *a, RPC_LOCALBRIDGE *t)
4688 {
4689 	if (IsEmptyStr(t->DeviceName) || IsEmptyStr(t->HubName))
4690 	{
4691 		return ERR_INVALID_PARAMETER;
4692 	}
4693 
4694 	SERVER_ADMIN_ONLY;
4695 
4696 	ALog(a, NULL, "LA_DELETE_BRIDGE", t->HubName, t->DeviceName);
4697 
4698 	if (DeleteLocalBridge(a->Server->Cedar, t->HubName, t->DeviceName) == false)
4699 	{
4700 		return ERR_OBJECT_NOT_FOUND;
4701 	}
4702 
4703 	IncrementServerConfigRevision(a->Server);
4704 
4705 	return ERR_NO_ERROR;
4706 }
4707 
4708 // Enumerate local bridges
StEnumLocalBridge(ADMIN * a,RPC_ENUM_LOCALBRIDGE * t)4709 UINT StEnumLocalBridge(ADMIN *a, RPC_ENUM_LOCALBRIDGE *t)
4710 {
4711 	UINT i;
4712 	CEDAR *c;
4713 
4714 	if (IsEthSupported() == false)
4715 	{
4716 		return ERR_LOCAL_BRIDGE_UNSUPPORTED;
4717 	}
4718 
4719 	FreeRpcEnumLocalBridge(t);
4720 	Zero(t, sizeof(RPC_ENUM_LOCALBRIDGE));
4721 
4722 	c = a->Server->Cedar;
4723 
4724 	LockList(c->LocalBridgeList);
4725 	{
4726 		t->NumItem = LIST_NUM(c->LocalBridgeList);
4727 		t->Items = ZeroMalloc(sizeof(RPC_LOCALBRIDGE) * t->NumItem);
4728 
4729 		for (i = 0;i < t->NumItem;i++)
4730 		{
4731 			RPC_LOCALBRIDGE *e = &t->Items[i];
4732 			LOCALBRIDGE *br = LIST_DATA(c->LocalBridgeList, i);
4733 
4734 			if (br->Bridge == false)
4735 			{
4736 				e->Online = e->Active = false;
4737 			}
4738 			else
4739 			{
4740 				e->Online = true;
4741 				if (br->Bridge->Active)
4742 				{
4743 					e->Active = true;
4744 				}
4745 				else
4746 				{
4747 					e->Active = false;
4748 				}
4749 			}
4750 			StrCpy(e->DeviceName, sizeof(e->DeviceName), br->DeviceName);
4751 			StrCpy(e->HubName, sizeof(e->HubName), br->HubName);
4752 
4753 			e->TapMode = br->TapMode;
4754 		}
4755 	}
4756 	UnlockList(c->LocalBridgeList);
4757 
4758 	return ERR_NO_ERROR;
4759 }
4760 
4761 // Set syslog function setting
StSetSysLog(ADMIN * a,SYSLOG_SETTING * t)4762 UINT StSetSysLog(ADMIN *a, SYSLOG_SETTING *t)
4763 {
4764 	SERVER *s = a->Server;
4765 
4766 	SERVER_ADMIN_ONLY;
4767 
4768 	if (GetGlobalServerFlag(GSF_DISABLE_SYSLOG) != 0 && t->SaveType != SYSLOG_NONE)
4769 	{
4770 		return ERR_NOT_SUPPORTED_FUNCTION_ON_OPENSOURCE;
4771 	}
4772 
4773 	if (GetServerCapsBool(s, "b_support_syslog") == false)
4774 	{
4775 		return ERR_NOT_SUPPORTED;
4776 	}
4777 
4778 	SiSetSysLogSetting(s, t);
4779 
4780 	IncrementServerConfigRevision(s);
4781 	ALog(a, NULL, "LA_SET_SYSLOG");
4782 
4783 	return ERR_NO_ERROR;
4784 }
4785 
4786 // Get syslog function setting
StGetSysLog(ADMIN * a,SYSLOG_SETTING * t)4787 UINT StGetSysLog(ADMIN *a, SYSLOG_SETTING *t)
4788 {
4789 	SERVER *s = a->Server;
4790 
4791 	SiGetSysLogSetting(s, t);
4792 
4793 	if (a->ServerAdmin == false)
4794 	{
4795 		// Hide server name for non-administrator
4796 		if (t->SaveType == SYSLOG_NONE)
4797 		{
4798 			StrCpy(t->Hostname, sizeof(t->Hostname), "");
4799 			t->Port = 0;
4800 		}
4801 		else
4802 		{
4803 			StrCpy(t->Hostname, sizeof(t->Hostname), "Secret");
4804 			t->Port = 0;
4805 		}
4806 	}
4807 
4808 	return ERR_NO_ERROR;
4809 }
4810 
4811 // Set keep-alive function setting
StSetKeep(ADMIN * a,RPC_KEEP * t)4812 UINT StSetKeep(ADMIN *a, RPC_KEEP *t)
4813 {
4814 	SERVER *s = a->Server;
4815 
4816 	if (t->UseKeepConnect)
4817 	{
4818 		if (IsEmptyStr(t->KeepConnectHost) ||
4819 			t->KeepConnectPort == 0 ||
4820 			t->KeepConnectPort >= 65536)
4821 		{
4822 			return ERR_INVALID_PARAMETER;
4823 		}
4824 	}
4825 
4826 	SERVER_ADMIN_ONLY;
4827 
4828 	Lock(s->Keep->lock);
4829 	{
4830 		KEEP *keep = s->Keep;
4831 		keep->Enable = t->UseKeepConnect;
4832 		keep->Server = true;
4833 		StrCpy(keep->ServerName, sizeof(keep->ServerName), t->KeepConnectHost);
4834 		keep->ServerPort = t->KeepConnectPort;
4835 		keep->UdpMode = t->KeepConnectProtocol;
4836 		keep->Interval = t->KeepConnectInterval * 1000;
4837 		if (keep->Interval < 5000)
4838 		{
4839 			keep->Interval = 5000;
4840 		}
4841 		else if (keep->Interval > 600000)
4842 		{
4843 			keep->Interval = 600000;
4844 		}
4845 	}
4846 	Unlock(s->Keep->lock);
4847 
4848 	ALog(a, NULL, "LA_SET_KEEP");
4849 
4850 	IncrementServerConfigRevision(s);
4851 
4852 	return ERR_NO_ERROR;
4853 }
4854 
4855 // Get keep-alive function setting
StGetKeep(ADMIN * a,RPC_KEEP * t)4856 UINT StGetKeep(ADMIN *a, RPC_KEEP *t)
4857 {
4858 	SERVER *s = a->Server;
4859 
4860 	Zero(t, sizeof(RPC_KEEP));
4861 
4862 	Lock(s->Keep->lock);
4863 	{
4864 		KEEP *k = s->Keep;
4865 		t->UseKeepConnect = k->Enable;
4866 		StrCpy(t->KeepConnectHost, sizeof(t->KeepConnectHost), k->ServerName);
4867 		t->KeepConnectPort = k->ServerPort;
4868 		t->KeepConnectProtocol = k->UdpMode;
4869 		t->KeepConnectInterval = k->Interval / 1000;
4870 	}
4871 	Unlock(s->Keep->lock);
4872 
4873 	return ERR_NO_ERROR;
4874 }
4875 
4876 // Delete IP address table entry
StDeleteIpTable(ADMIN * a,RPC_DELETE_TABLE * t)4877 UINT StDeleteIpTable(ADMIN *a, RPC_DELETE_TABLE *t)
4878 {
4879 	SERVER *s = a->Server;
4880 	CEDAR *c = s->Cedar;
4881 	HUB *h = NULL;
4882 	UINT ret = ERR_NO_ERROR;
4883 
4884 	CHECK_RIGHT;
4885 
4886 	LockHubList(c);
4887 	{
4888 		h = GetHub(c, t->HubName);
4889 	}
4890 	UnlockHubList(c);
4891 
4892 	if (h == NULL)
4893 	{
4894 		return ERR_HUB_NOT_FOUND;
4895 	}
4896 
4897 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_delete_iptable") != 0)
4898 	{
4899 		ReleaseHub(h);
4900 		return ERR_NOT_ENOUGH_RIGHT;
4901 	}
4902 
4903 	LockList(h->IpTable);
4904 	{
4905 		if (IsInListKey(h->IpTable, t->Key))
4906 		{
4907 			IP_TABLE_ENTRY *e = ListKeyToPointer(h->IpTable, t->Key);
4908 			Free(e);
4909 			Delete(h->IpTable, e);
4910 		}
4911 		else
4912 		{
4913 			ret = ERR_OBJECT_NOT_FOUND;
4914 		}
4915 	}
4916 	UnlockList(h->IpTable);
4917 
4918 	if (ret == ERR_OBJECT_NOT_FOUND)
4919 	{
4920 		if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
4921 		{
4922 			UINT i;
4923 			LockList(s->FarmMemberList);
4924 			{
4925 				for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
4926 				{
4927 					FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
4928 					if (f->Me == false)
4929 					{
4930 						SiCallDeleteIpTable(s, f, t->HubName, t->Key);
4931 						ret = ERR_NO_ERROR;
4932 					}
4933 				}
4934 			}
4935 			UnlockList(s->FarmMemberList);
4936 		}
4937 	}
4938 
4939 	ReleaseHub(h);
4940 
4941 	return ret;
4942 }
4943 
4944 // Get local IP address table
SiEnumIpTable(SERVER * s,char * hubname,RPC_ENUM_IP_TABLE * t)4945 UINT SiEnumIpTable(SERVER *s, char *hubname, RPC_ENUM_IP_TABLE *t)
4946 {
4947 	CEDAR *c;
4948 	UINT i;
4949 	HUB *h = NULL;
4950 	// Validate arguments
4951 	if (s == NULL || hubname == NULL || t == NULL)
4952 	{
4953 		return ERR_INTERNAL_ERROR;
4954 	}
4955 
4956 	c = s->Cedar;
4957 
4958 	LockHubList(c);
4959 	{
4960 		h = GetHub(c, hubname);
4961 	}
4962 	UnlockHubList(c);
4963 
4964 	if (h == NULL)
4965 	{
4966 		return ERR_HUB_NOT_FOUND;
4967 	}
4968 
4969 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
4970 
4971 	LockList(h->IpTable);
4972 	{
4973 		t->NumIpTable = LIST_NUM(h->IpTable);
4974 		t->IpTables = ZeroMalloc(sizeof(RPC_ENUM_IP_TABLE_ITEM) * t->NumIpTable);
4975 
4976 		for (i = 0;i < t->NumIpTable;i++)
4977 		{
4978 			RPC_ENUM_IP_TABLE_ITEM *e = &t->IpTables[i];
4979 			IP_TABLE_ENTRY *table = LIST_DATA(h->IpTable, i);
4980 
4981 			e->Key = POINTER_TO_KEY(table);
4982 			StrCpy(e->SessionName, sizeof(e->SessionName), table->Session->Name);
4983 			e->Ip = IPToUINT(&table->Ip);
4984 			Copy(&e->IpV6, &table->Ip, sizeof(IP));
4985 			Copy(&e->IpAddress, &table->Ip, sizeof(IP));
4986 			e->DhcpAllocated = table->DhcpAllocated;
4987 			e->CreatedTime = TickToTime(table->CreatedTime);
4988 			e->UpdatedTime = TickToTime(table->UpdatedTime);
4989 
4990 			GetMachineName(e->RemoteHostname, sizeof(e->RemoteHostname));
4991 		}
4992 	}
4993 	UnlockList(h->IpTable);
4994 
4995 	ReleaseHub(h);
4996 
4997 	return ERR_NO_ERROR;
4998 }
4999 
5000 // Get IP address table
StEnumIpTable(ADMIN * a,RPC_ENUM_IP_TABLE * t)5001 UINT StEnumIpTable(ADMIN *a, RPC_ENUM_IP_TABLE *t)
5002 {
5003 	SERVER *s = a->Server;
5004 	CEDAR *c = s->Cedar;
5005 	UINT ret = ERR_NO_ERROR;
5006 	char hubname[MAX_HUBNAME_LEN + 1];
5007 	UINT i;
5008 
5009 	CHECK_RIGHT;
5010 
5011 	// Get local IP address table
5012 	StrCpy(hubname, sizeof(hubname), t->HubName);
5013 	FreeRpcEnumIpTable(t);
5014 	Zero(t, sizeof(RPC_ENUM_IP_TABLE));
5015 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
5016 
5017 	ret = SiEnumIpTable(s, hubname, t);
5018 	if (ret != ERR_NO_ERROR)
5019 	{
5020 		return ret;
5021 	}
5022 
5023 	if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
5024 	{
5025 		// Get remote IP address table
5026 		LockList(s->FarmMemberList);
5027 		{
5028 			for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
5029 			{
5030 				FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
5031 				if (f->Me == false)
5032 				{
5033 					RPC_ENUM_IP_TABLE tmp;
5034 
5035 					Zero(&tmp, sizeof(tmp));
5036 
5037 					SiCallEnumIpTable(s, f, hubname, &tmp);
5038 
5039 					AdjoinRpcEnumIpTable(t, &tmp);
5040 					FreeRpcEnumIpTable(&tmp);
5041 				}
5042 			}
5043 		}
5044 		UnlockList(s->FarmMemberList);
5045 	}
5046 
5047 	return ret;
5048 }
5049 
5050 // Delete MAC address table entry
StDeleteMacTable(ADMIN * a,RPC_DELETE_TABLE * t)5051 UINT StDeleteMacTable(ADMIN *a, RPC_DELETE_TABLE *t)
5052 {
5053 	SERVER *s = a->Server;
5054 	CEDAR *c = s->Cedar;
5055 	HUB *h = NULL;
5056 	UINT ret = ERR_NO_ERROR;
5057 
5058 	CHECK_RIGHT;
5059 
5060 	LockHubList(c);
5061 	{
5062 		h = GetHub(c, t->HubName);
5063 	}
5064 	UnlockHubList(c);
5065 
5066 	if (h == NULL)
5067 	{
5068 		return ERR_HUB_NOT_FOUND;
5069 	}
5070 
5071 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_delete_mactable") != 0)
5072 	{
5073 		ReleaseHub(h);
5074 		return ERR_NOT_ENOUGH_RIGHT;
5075 	}
5076 
5077 	LockHashList(h->MacHashTable);
5078 	{
5079 		if (IsInHashListKey(h->MacHashTable, t->Key))
5080 		{
5081 			MAC_TABLE_ENTRY *e = HashListKeyToPointer(h->MacHashTable, t->Key);
5082 			DeleteHash(h->MacHashTable, e);
5083 			Free(e);
5084 		}
5085 		else
5086 		{
5087 			ret = ERR_OBJECT_NOT_FOUND;
5088 		}
5089 	}
5090 	UnlockHashList(h->MacHashTable);
5091 
5092 	if (ret == ERR_OBJECT_NOT_FOUND)
5093 	{
5094 		if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
5095 		{
5096 			UINT i;
5097 			LockList(s->FarmMemberList);
5098 			{
5099 				for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
5100 				{
5101 					FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
5102 					if (f->Me == false)
5103 					{
5104 						SiCallDeleteMacTable(s, f, t->HubName, t->Key);
5105 						ret = ERR_NO_ERROR;
5106 					}
5107 				}
5108 			}
5109 			UnlockList(s->FarmMemberList);
5110 		}
5111 	}
5112 
5113 	ReleaseHub(h);
5114 
5115 	return ret;
5116 }
5117 
5118 // Get local MAC address table
SiEnumMacTable(SERVER * s,char * hubname,RPC_ENUM_MAC_TABLE * t)5119 UINT SiEnumMacTable(SERVER *s, char *hubname, RPC_ENUM_MAC_TABLE *t)
5120 {
5121 	CEDAR *c;
5122 	UINT i;
5123 	HUB *h = NULL;
5124 	// Validate arguments
5125 	if (s == NULL || hubname == NULL || t == NULL)
5126 	{
5127 		return ERR_INTERNAL_ERROR;
5128 	}
5129 
5130 	c = s->Cedar;
5131 
5132 	LockHubList(c);
5133 	{
5134 		h = GetHub(c, hubname);
5135 	}
5136 	UnlockHubList(c);
5137 
5138 	if (h == NULL)
5139 	{
5140 		return ERR_HUB_NOT_FOUND;
5141 	}
5142 
5143 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
5144 
5145 	LockHashList(h->MacHashTable);
5146 	{
5147 		MAC_TABLE_ENTRY **pp = (MAC_TABLE_ENTRY **)HashListToArray(h->MacHashTable, &t->NumMacTable);
5148 		t->MacTables = ZeroMalloc(sizeof(RPC_ENUM_MAC_TABLE_ITEM) * t->NumMacTable);
5149 
5150 		for (i = 0;i < t->NumMacTable;i++)
5151 		{
5152 			RPC_ENUM_MAC_TABLE_ITEM *e = &t->MacTables[i];
5153 			MAC_TABLE_ENTRY *mac = pp[i];
5154 
5155 			e->Key = POINTER_TO_KEY(mac);
5156 			StrCpy(e->SessionName, sizeof(e->SessionName), mac->Session->Name);
5157 			Copy(e->MacAddress, mac->MacAddress, sizeof(e->MacAddress));
5158 			e->CreatedTime = TickToTime(mac->CreatedTime);
5159 			e->UpdatedTime = TickToTime(mac->UpdatedTime);
5160 			e->VlanId = mac->VlanId;
5161 
5162 			GetMachineName(e->RemoteHostname, sizeof(e->RemoteHostname));
5163 		}
5164 
5165 		Free(pp);
5166 	}
5167 	UnlockHashList(h->MacHashTable);
5168 
5169 	ReleaseHub(h);
5170 
5171 	return ERR_NO_ERROR;
5172 }
5173 
5174 // Get MAC address table
StEnumMacTable(ADMIN * a,RPC_ENUM_MAC_TABLE * t)5175 UINT StEnumMacTable(ADMIN *a, RPC_ENUM_MAC_TABLE *t)
5176 {
5177 	SERVER *s = a->Server;
5178 	CEDAR *c = s->Cedar;
5179 	HUB *h = NULL;
5180 	UINT ret = ERR_NO_ERROR;
5181 	char hubname[MAX_HUBNAME_LEN + 1];
5182 	UINT i;
5183 
5184 	CHECK_RIGHT;
5185 
5186 	// Get local MAC address table
5187 	StrCpy(hubname, sizeof(hubname), t->HubName);
5188 	FreeRpcEnumMacTable(t);
5189 	Zero(t, sizeof(RPC_ENUM_MAC_TABLE));
5190 
5191 	ret = SiEnumMacTable(s, hubname, t);
5192 	if (ret != ERR_NO_ERROR)
5193 	{
5194 		return ret;
5195 	}
5196 
5197 	if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
5198 	{
5199 		// Get remote MAC address table
5200 		LockList(s->FarmMemberList);
5201 		{
5202 			for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
5203 			{
5204 				FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
5205 				if (f->Me == false)
5206 				{
5207 					RPC_ENUM_MAC_TABLE tmp;
5208 
5209 					Zero(&tmp, sizeof(tmp));
5210 
5211 					SiCallEnumMacTable(s, f, hubname, &tmp);
5212 
5213 					AdjoinRpcEnumMacTable(t, &tmp);
5214 					FreeRpcEnumMacTable(&tmp);
5215 				}
5216 			}
5217 		}
5218 		UnlockList(s->FarmMemberList);
5219 	}
5220 
5221 	return ret;
5222 }
5223 
5224 // Delete a session
StDeleteSession(ADMIN * a,RPC_DELETE_SESSION * t)5225 UINT StDeleteSession(ADMIN *a, RPC_DELETE_SESSION *t)
5226 {
5227 	SERVER *s = a->Server;
5228 	CEDAR *c = s->Cedar;
5229 	HUB *h = NULL;
5230 	UINT ret = ERR_NO_ERROR;
5231 	char hubname[MAX_HUBNAME_LEN + 1];
5232 	char name[MAX_SESSION_NAME_LEN + 1];
5233 	SESSION *sess;
5234 
5235 	if (IsEmptyStr(t->Name))
5236 	{
5237 		return ERR_INVALID_PARAMETER;
5238 	}
5239 
5240 	StrCpy(hubname, sizeof(hubname), t->HubName);
5241 	StrCpy(name, sizeof(name), t->Name);
5242 
5243 	CHECK_RIGHT;
5244 
5245 	LockHubList(c);
5246 	{
5247 		h = GetHub(c, t->HubName);
5248 	}
5249 	UnlockHubList(c);
5250 
5251 	if (h == NULL)
5252 	{
5253 		return ERR_HUB_NOT_FOUND;
5254 	}
5255 
5256 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_disconnect_session") != 0)
5257 	{
5258 		ReleaseHub(h);
5259 		return ERR_NOT_ENOUGH_RIGHT;
5260 	}
5261 
5262 	sess = GetSessionByName(h, name);
5263 
5264 	if (sess == NULL)
5265 	{
5266 		if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
5267 		{
5268 			// Cluster controller
5269 			UINT i;
5270 			LockList(s->FarmMemberList);
5271 			{
5272 				for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
5273 				{
5274 					FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
5275 					if (f->Me == false)
5276 					{
5277 						// Try to disconnect
5278 						SiCallDeleteSession(s, f, t->HubName, t->Name);
5279 					}
5280 				}
5281 			}
5282 			UnlockList(s->FarmMemberList);
5283 		}
5284 		else
5285 		{
5286 			ret = ERR_OBJECT_NOT_FOUND;
5287 		}
5288 	}
5289 	else
5290 	{
5291 		if (sess->LinkModeServer)
5292 		{
5293 			ret = ERR_LINK_CANT_DISCONNECT;
5294 		}
5295 		else if (sess->SecureNATMode)
5296 		{
5297 			ret = ERR_SNAT_CANT_DISCONNECT;
5298 		}
5299 		else if (sess->BridgeMode)
5300 		{
5301 			ret = ERR_BRIDGE_CANT_DISCONNECT;
5302 		}
5303 		else if (sess->L3SwitchMode)
5304 		{
5305 			ret = ERR_LAYER3_CANT_DISCONNECT;
5306 		}
5307 		else
5308 		{
5309 			StopSession(sess);
5310 		}
5311 		ReleaseSession(sess);
5312 	}
5313 
5314 	if (ret != ERR_NO_ERROR)
5315 	{
5316 		ALog(a, h, "LA_DELETE_SESSION", t->Name);
5317 	}
5318 
5319 	ReleaseHub(h);
5320 
5321 	return ret;
5322 }
5323 
5324 // Get session status
StGetSessionStatus(ADMIN * a,RPC_SESSION_STATUS * t)5325 UINT StGetSessionStatus(ADMIN *a, RPC_SESSION_STATUS *t)
5326 {
5327 	SERVER *s = a->Server;
5328 	CEDAR *c = s->Cedar;
5329 	HUB *h = NULL;
5330 	UINT ret = ERR_NO_ERROR;
5331 	char hubname[MAX_HUBNAME_LEN + 1];
5332 	char name[MAX_SESSION_NAME_LEN + 1];
5333 	SESSION *sess;
5334 
5335 	StrCpy(hubname, sizeof(hubname), t->HubName);
5336 	StrCpy(name, sizeof(name), t->Name);
5337 
5338 	if (IsEmptyStr(t->Name))
5339 	{
5340 		return ERR_INVALID_PARAMETER;
5341 	}
5342 
5343 	CHECK_RIGHT;
5344 
5345 	LockHubList(c);
5346 	{
5347 		h = GetHub(c, t->HubName);
5348 	}
5349 	UnlockHubList(c);
5350 
5351 	if (h == NULL)
5352 	{
5353 		return ERR_HUB_NOT_FOUND;
5354 	}
5355 
5356 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_query_session") != 0)
5357 	{
5358 		ReleaseHub(h);
5359 		return ERR_NOT_ENOUGH_RIGHT;
5360 	}
5361 
5362 	FreeRpcSessionStatus(t);
5363 	Zero(t, sizeof(RPC_SESSION_STATUS));
5364 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
5365 	StrCpy(t->Name, sizeof(t->Name), name);
5366 
5367 	sess = GetSessionByName(h, t->Name);
5368 
5369 	if (sess == NULL)
5370 	{
5371 		if (s->ServerType != SERVER_TYPE_FARM_CONTROLLER)
5372 		{
5373 			// Session is not found
5374 			ret = ERR_OBJECT_NOT_FOUND;
5375 		}
5376 		else
5377 		{
5378 			UINT i;
5379 			// Try to find the session on other cluster member
5380 			LockList(s->FarmMemberList);
5381 			{
5382 				for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
5383 				{
5384 					FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
5385 					if (f->Me == false)
5386 					{
5387 						RPC_SESSION_STATUS tmp;
5388 						Zero(&tmp, sizeof(tmp));
5389 						StrCpy(tmp.HubName, sizeof(tmp.HubName), t->HubName);
5390 						StrCpy(tmp.Name, sizeof(tmp.Name), t->Name);
5391 
5392 						if (SiCallGetSessionStatus(s, f, &tmp))
5393 						{
5394 							if (StrLen(tmp.HubName) != 0)
5395 							{
5396 								// Success to get session status
5397 								Copy(t, &tmp, sizeof(RPC_SESSION_STATUS));
5398 								break;
5399 							}
5400 							else
5401 							{
5402 								FreeRpcSessionStatus(&tmp);
5403 							}
5404 						}
5405 					}
5406 				}
5407 
5408 				if (i == LIST_NUM(s->FarmMemberList))
5409 				{
5410 					// not found after all
5411 					//
5412 					ret = ERR_OBJECT_NOT_FOUND;
5413 				}
5414 			}
5415 			UnlockList(s->FarmMemberList);
5416 		}
5417 	}
5418 	else
5419 	{
5420 		SESSION *s = sess;
5421 
5422 		Lock(s->lock);
5423 		{
5424 			StrCpy(t->Username, sizeof(t->Username), s->Username);
5425 			StrCpy(t->RealUsername, sizeof(t->RealUsername), s->UserNameReal);
5426 			StrCpy(t->GroupName, sizeof(t->GroupName), s->GroupName);
5427 			Copy(&t->NodeInfo, &s->NodeInfo, sizeof(NODE_INFO));
5428 
5429 			if (s->Connection != NULL)
5430 			{
5431 				t->ClientIp = IPToUINT(&s->Connection->ClientIp);
5432 				if (IsIP6(&s->Connection->ClientIp))
5433 				{
5434 					Copy(&t->ClientIp6, &s->Connection->ClientIp.address, sizeof(t->ClientIp6));
5435 				}
5436 
5437 				CopyIP(&t->ClientIpAddress, &s->Connection->ClientIp);
5438 
5439 				StrCpy(t->ClientHostName, sizeof(t->ClientHostName), s->Connection->ClientHostname);
5440 			}
5441 		}
5442 		Unlock(s->lock);
5443 
5444 		CiGetSessionStatus(&t->Status, s);
5445 
5446 		ReleaseSession(s);
5447 	}
5448 
5449 	ReleaseHub(h);
5450 
5451 	return ret;
5452 }
5453 
5454 // Main routine of session enumeration
SiEnumSessionMain(SERVER * s,RPC_ENUM_SESSION * t)5455 void SiEnumSessionMain(SERVER *s, RPC_ENUM_SESSION *t)
5456 {
5457 	char hubname[MAX_HUBNAME_LEN + 1];
5458 	UINT ret = ERR_NO_ERROR;
5459 	UINT num;
5460 	UINT i;
5461 	// Validate arguments
5462 	if (s == NULL || t == NULL)
5463 	{
5464 		return;
5465 	}
5466 
5467 	StrCpy(hubname, sizeof(hubname), t->HubName);
5468 
5469 	FreeRpcEnumSession(t);
5470 	Zero(t, sizeof(RPC_ENUM_SESSION));
5471 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
5472 
5473 	// Local session enumeration
5474 	num = 0;
5475 	SiEnumLocalSession(s, hubname, t);
5476 
5477 	if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
5478 	{
5479 		LIST *fm_list;
5480 
5481 		fm_list = NewListFast(NULL);
5482 
5483 		// Remote session enumeration
5484 		LockList(s->FarmMemberList);
5485 		{
5486 			while (true)
5487 			{
5488 				bool escape = true;
5489 
5490 				for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
5491 				{
5492 					FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
5493 
5494 					if (IsInList(fm_list, f) == false)
5495 					{
5496 						Add(fm_list, f);
5497 						escape = false;
5498 
5499 						if (f->Me == false)
5500 						{
5501 							RPC_ENUM_SESSION tmp;
5502 
5503 							Zero(&tmp, sizeof(tmp));
5504 
5505 							SiCallEnumSession(s, f, hubname, &tmp);
5506 
5507 							AdjoinRpcEnumSession(t, &tmp);
5508 							FreeRpcEnumSession(&tmp);
5509 						}
5510 
5511 						break;
5512 					}
5513 				}
5514 
5515 				if (escape)
5516 				{
5517 					break;
5518 				}
5519 
5520 				UnlockList(s->FarmMemberList);
5521 				LockList(s->FarmMemberList);
5522 			}
5523 		}
5524 		UnlockList(s->FarmMemberList);
5525 
5526 		ReleaseList(fm_list);
5527 	}
5528 }
5529 
5530 // Enumerate sessions
StEnumSession(ADMIN * a,RPC_ENUM_SESSION * t)5531 UINT StEnumSession(ADMIN *a, RPC_ENUM_SESSION *t)
5532 {
5533 	SERVER *s = a->Server;
5534 	CEDAR *c = s->Cedar;
5535 	HUB *h = NULL;
5536 	UINT ret = ERR_NO_ERROR;
5537 
5538 	CHECK_RIGHT;
5539 
5540 	LockHubList(c);
5541 	{
5542 		h = GetHub(c, t->HubName);
5543 	}
5544 	UnlockHubList(c);
5545 
5546 	if (h == NULL)
5547 	{
5548 		return ERR_HUB_NOT_FOUND;
5549 	}
5550 
5551 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_enum_session") != 0)
5552 	{
5553 		ReleaseHub(h);
5554 		return ERR_NOT_ENOUGH_RIGHT;
5555 	}
5556 
5557 	SiEnumSessionMain(s, t);
5558 
5559 	ReleaseHub(h);
5560 
5561 	return ret;
5562 }
5563 
5564 // Enumerate groups
StEnumGroup(ADMIN * a,RPC_ENUM_GROUP * t)5565 UINT StEnumGroup(ADMIN *a, RPC_ENUM_GROUP *t)
5566 {
5567 	SERVER *s = a->Server;
5568 	CEDAR *c = s->Cedar;
5569 	HUB *h = NULL;
5570 	UINT ret = ERR_NO_ERROR;
5571 	char hubname[MAX_HUBNAME_LEN + 1];
5572 
5573 	StrCpy(hubname, sizeof(hubname), t->HubName);
5574 
5575 	CHECK_RIGHT;
5576 
5577 	NO_SUPPORT_FOR_BRIDGE;
5578 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
5579 	{
5580 		return ERR_NOT_SUPPORTED;
5581 	}
5582 
5583 
5584 	LockHubList(c);
5585 	{
5586 		h = GetHub(c, t->HubName);
5587 	}
5588 	UnlockHubList(c);
5589 
5590 	if (h == NULL)
5591 	{
5592 		return ERR_HUB_NOT_FOUND;
5593 	}
5594 
5595 	AcLock(h);
5596 	{
5597 		UINT i, j;
5598 
5599 		FreeRpcEnumGroup(t);
5600 		Zero(t, sizeof(RPC_ENUM_GROUP));
5601 		StrCpy(t->HubName, sizeof(t->HubName), hubname);
5602 
5603 		t->NumGroup = LIST_NUM(h->HubDb->GroupList);
5604 		t->Groups = ZeroMalloc(sizeof(RPC_ENUM_GROUP_ITEM) * t->NumGroup);
5605 
5606 		for (i = 0;i < t->NumGroup;i++)
5607 		{
5608 			RPC_ENUM_GROUP_ITEM *e = &t->Groups[i];
5609 			USERGROUP *g = LIST_DATA(h->HubDb->GroupList, i);
5610 
5611 			Lock(g->lock);
5612 			{
5613 				StrCpy(e->Name, sizeof(e->Name), g->Name);
5614 				UniStrCpy(e->Realname, sizeof(e->Realname), g->RealName);
5615 				UniStrCpy(e->Note, sizeof(e->Note), g->Note);
5616 				if (g->Policy != NULL)
5617 				{
5618 					if (g->Policy->Access == false)
5619 					{
5620 						e->DenyAccess = true;
5621 					}
5622 				}
5623 			}
5624 			Unlock(g->lock);
5625 
5626 			e->NumUsers = 0;
5627 
5628 
5629 			LockList(h->HubDb->UserList);
5630 			{
5631 				for (j = 0;j < LIST_NUM(h->HubDb->UserList);j++)
5632 				{
5633 					USER *u = LIST_DATA(h->HubDb->UserList, j);
5634 
5635 					Lock(u->lock);
5636 					{
5637 						if (u->Group == g)
5638 						{
5639 							e->NumUsers++;
5640 						}
5641 					}
5642 					Unlock(u->lock);
5643 				}
5644 			}
5645 			UnlockList(h->HubDb->UserList);
5646 		}
5647 	}
5648 	AcUnlock(h);
5649 
5650 	ReleaseHub(h);
5651 
5652 	return ERR_NO_ERROR;
5653 }
5654 
5655 // Delete a group
StDeleteGroup(ADMIN * a,RPC_DELETE_USER * t)5656 UINT StDeleteGroup(ADMIN *a, RPC_DELETE_USER *t)
5657 {
5658 	SERVER *s = a->Server;
5659 	CEDAR *c = s->Cedar;
5660 	HUB *h = NULL;
5661 	UINT ret = ERR_NO_ERROR;
5662 
5663 	if (IsEmptyStr(t->Name) || IsSafeStr(t->Name) == false)
5664 	{
5665 		return ERR_INVALID_PARAMETER;
5666 	}
5667 
5668 	CHECK_RIGHT;
5669 
5670 	NO_SUPPORT_FOR_BRIDGE;
5671 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
5672 	{
5673 		return ERR_NOT_SUPPORTED;
5674 	}
5675 
5676 	LockHubList(c);
5677 	{
5678 		h = GetHub(c, t->HubName);
5679 	}
5680 	UnlockHubList(c);
5681 
5682 	if (h == NULL)
5683 	{
5684 		return ERR_HUB_NOT_FOUND;
5685 	}
5686 
5687 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_groups") != 0)
5688 	{
5689 		ReleaseHub(h);
5690 		return ERR_NOT_ENOUGH_RIGHT;
5691 	}
5692 
5693 	AcLock(h);
5694 	{
5695 		if (AcDeleteGroup(h, t->Name) == false)
5696 		{
5697 			ret = ERR_OBJECT_NOT_FOUND;
5698 		}
5699 	}
5700 	AcUnlock(h);
5701 
5702 	if (ret == ERR_NO_ERROR)
5703 	{
5704 		ALog(a, h, "LA_DELETE_GROUP", t->Name);
5705 	}
5706 
5707 	ReleaseHub(h);
5708 
5709 	IncrementServerConfigRevision(s);
5710 
5711 	return ret;
5712 }
5713 
5714 // Get group information
StGetGroup(ADMIN * a,RPC_SET_GROUP * t)5715 UINT StGetGroup(ADMIN *a, RPC_SET_GROUP *t)
5716 {
5717 	SERVER *s = a->Server;
5718 	CEDAR *c = s->Cedar;
5719 	HUB *h = NULL;
5720 	UINT ret = ERR_NO_ERROR;
5721 	char hubname[MAX_HUBNAME_LEN + 1];
5722 
5723 	if (IsEmptyStr(t->Name) || IsSafeStr(t->Name) == false)
5724 	{
5725 		return ERR_INVALID_PARAMETER;
5726 	}
5727 
5728 	CHECK_RIGHT;
5729 	NO_SUPPORT_FOR_BRIDGE;
5730 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
5731 	{
5732 		return ERR_NOT_SUPPORTED;
5733 	}
5734 
5735 	StrCpy(hubname, sizeof(hubname), t->HubName);
5736 
5737 	LockHubList(c);
5738 	{
5739 		h = GetHub(c, t->HubName);
5740 	}
5741 	UnlockHubList(c);
5742 
5743 	if (h == NULL)
5744 	{
5745 		return ERR_HUB_NOT_FOUND;
5746 	}
5747 
5748 	AcLock(h);
5749 	{
5750 		USERGROUP *g = AcGetGroup(h, t->Name);
5751 
5752 		if (g == NULL)
5753 		{
5754 			ret = ERR_OBJECT_NOT_FOUND;
5755 		}
5756 		else
5757 		{
5758 			FreeRpcSetGroup(t);
5759 			Zero(t, sizeof(RPC_SET_GROUP));
5760 
5761 			StrCpy(t->HubName, sizeof(t->HubName), hubname);
5762 
5763 			Lock(g->lock);
5764 			{
5765 				StrCpy(t->Name, sizeof(t->Name), g->Name);
5766 				UniStrCpy(t->Realname, sizeof(t->Realname), g->RealName);
5767 				UniStrCpy(t->Note, sizeof(t->Note), g->Note);
5768 				Copy(&t->Traffic, g->Traffic, sizeof(TRAFFIC));
5769 			}
5770 			Unlock(g->lock);
5771 
5772 			t->Policy = GetGroupPolicy(g);
5773 
5774 			ReleaseGroup(g);
5775 		}
5776 	}
5777 	AcUnlock(h);
5778 
5779 	ReleaseHub(h);
5780 
5781 	return ret;
5782 }
5783 
5784 // Set group setting
StSetGroup(ADMIN * a,RPC_SET_GROUP * t)5785 UINT StSetGroup(ADMIN *a, RPC_SET_GROUP *t)
5786 {
5787 	SERVER *s = a->Server;
5788 	CEDAR *c = s->Cedar;
5789 	HUB *h = NULL;
5790 	UINT ret = ERR_NO_ERROR;
5791 
5792 	if (IsEmptyStr(t->Name) || IsSafeStr(t->Name) == false)
5793 	{
5794 		return ERR_INVALID_PARAMETER;
5795 	}
5796 
5797 	CHECK_RIGHT;
5798 	NO_SUPPORT_FOR_BRIDGE;
5799 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
5800 	{
5801 		return ERR_NOT_SUPPORTED;
5802 	}
5803 
5804 	LockHubList(c);
5805 	{
5806 		h = GetHub(c, t->HubName);
5807 	}
5808 	UnlockHubList(c);
5809 
5810 	if (h == NULL)
5811 	{
5812 		return ERR_HUB_NOT_FOUND;
5813 	}
5814 
5815 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_groups") != 0)
5816 	{
5817 		ReleaseHub(h);
5818 		return ERR_NOT_ENOUGH_RIGHT;
5819 	}
5820 
5821 	AcLock(h);
5822 	{
5823 		USERGROUP *g = AcGetGroup(h, t->Name);
5824 		if (g == NULL)
5825 		{
5826 			ret = ERR_OBJECT_NOT_FOUND;
5827 		}
5828 		else
5829 		{
5830 			Lock(g->lock);
5831 			{
5832 				Free(g->RealName);
5833 				Free(g->Note);
5834 				g->RealName = UniCopyStr(t->Realname);
5835 				g->Note = UniCopyStr(t->Note);
5836 			}
5837 			Unlock(g->lock);
5838 
5839 			SetGroupPolicy(g, t->Policy);
5840 
5841 			ReleaseGroup(g);
5842 
5843 			ALog(a, h, "LA_SET_GROUP", t->Name);
5844 		}
5845 	}
5846 	AcUnlock(h);
5847 
5848 	ReleaseHub(h);
5849 
5850 	IncrementServerConfigRevision(s);
5851 
5852 	return ret;
5853 }
5854 
5855 // Create a group
StCreateGroup(ADMIN * a,RPC_SET_GROUP * t)5856 UINT StCreateGroup(ADMIN *a, RPC_SET_GROUP *t)
5857 {
5858 	SERVER *s = a->Server;
5859 	CEDAR *c = s->Cedar;
5860 	HUB *h = NULL;
5861 	UINT ret = ERR_NO_ERROR;
5862 
5863 	if (IsEmptyStr(t->Name) || IsSafeStr(t->Name) == false)
5864 	{
5865 		return ERR_INVALID_PARAMETER;
5866 	}
5867 
5868 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
5869 	{
5870 		return ERR_NOT_FARM_CONTROLLER;
5871 	}
5872 
5873 	CHECK_RIGHT;
5874 
5875 	NO_SUPPORT_FOR_BRIDGE;
5876 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
5877 	{
5878 		return ERR_NOT_SUPPORTED;
5879 	}
5880 
5881 	LockHubList(c);
5882 	{
5883 		h = GetHub(c, t->HubName);
5884 	}
5885 	UnlockHubList(c);
5886 
5887 	if (h == NULL)
5888 	{
5889 		return ERR_HUB_NOT_FOUND;
5890 	}
5891 
5892 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_groups") != 0)
5893 	{
5894 		ReleaseHub(h);
5895 		return ERR_NOT_ENOUGH_RIGHT;
5896 	}
5897 
5898 	AcLock(h);
5899 	{
5900 		if (AcIsGroup(h, t->Name))
5901 		{
5902 			ret = ERR_GROUP_ALREADY_EXISTS;
5903 		}
5904 		else
5905 		{
5906 			USERGROUP *g = NewGroup(t->Name, t->Realname, t->Note);
5907 			SetGroupPolicy(g, t->Policy);
5908 
5909 			if ((LIST_NUM(h->HubDb->GroupList) >= GetServerCapsInt(a->Server, "i_max_users_per_hub")) ||
5910 				((GetHubAdminOption(h, "max_groups") != 0) && (LIST_NUM(h->HubDb->GroupList) >= GetHubAdminOption(h, "max_groups"))))
5911 			{
5912 				ret = ERR_TOO_MANY_GROUP;
5913 			}
5914 			else
5915 			{
5916 				AcAddGroup(h, g);
5917 			}
5918 
5919 			ReleaseGroup(g);
5920 
5921 			ALog(a, h, "LA_CREATE_GROUP", t->Name);
5922 		}
5923 	}
5924 	AcUnlock(h);
5925 
5926 	ReleaseHub(h);
5927 
5928 	IncrementServerConfigRevision(s);
5929 
5930 	return ret;
5931 }
5932 
5933 // Enumerate users
StEnumUser(ADMIN * a,RPC_ENUM_USER * t)5934 UINT StEnumUser(ADMIN *a, RPC_ENUM_USER *t)
5935 {
5936 	SERVER *s = a->Server;
5937 	CEDAR *c = s->Cedar;
5938 	HUB *h = NULL;
5939 	UINT ret = ERR_NO_ERROR;
5940 	char hubname[MAX_HUBNAME_LEN + 1];
5941 	UINT i, num;
5942 
5943 	CHECK_RIGHT;
5944 	NO_SUPPORT_FOR_BRIDGE;
5945 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
5946 	{
5947 		return ERR_NOT_SUPPORTED;
5948 	}
5949 
5950 	LockHubList(c);
5951 	{
5952 		h = GetHub(c, t->HubName);
5953 	}
5954 	UnlockHubList(c);
5955 
5956 	if (h == NULL)
5957 	{
5958 		return ERR_HUB_NOT_FOUND;
5959 	}
5960 
5961 	FreeRpcEnumUser(t);
5962 
5963 	StrCpy(hubname, sizeof(hubname), t->HubName);
5964 
5965 	Zero(t, sizeof(RPC_ENUM_USER));
5966 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
5967 
5968 	LockList(h->HubDb->UserList);
5969 	{
5970 		num = LIST_NUM(h->HubDb->UserList);
5971 
5972 		t->NumUser = num;
5973 		t->Users = ZeroMalloc(sizeof(RPC_ENUM_USER_ITEM) * num);
5974 
5975 		for (i = 0;i < num;i++)
5976 		{
5977 			USER *u = LIST_DATA(h->HubDb->UserList, i);
5978 
5979 			Lock(u->lock);
5980 			{
5981 				RPC_ENUM_USER_ITEM *e = &t->Users[i];
5982 
5983 				StrCpy(e->Name, sizeof(e->Name), u->Name);
5984 				StrCpy(e->GroupName, sizeof(e->GroupName), u->GroupName);
5985 				UniStrCpy(e->Realname, sizeof(e->Realname), u->RealName);
5986 				UniStrCpy(e->Note, sizeof(e->Note), u->Note);
5987 				e->AuthType = u->AuthType;
5988 				e->LastLoginTime = u->LastLoginTime;
5989 				e->NumLogin = u->NumLogin;
5990 
5991 				if (u->Policy != NULL)
5992 				{
5993 					e->DenyAccess = u->Policy->Access ? false : true;
5994 				}
5995 
5996 				Copy(&e->Traffic, u->Traffic, sizeof(TRAFFIC));
5997 				e->IsTrafficFilled = true;
5998 
5999 				e->Expires = u->ExpireTime;
6000 				e->IsExpiresFilled = true;
6001 			}
6002 			Unlock(u->lock);
6003 		}
6004 	}
6005 	UnlockList(h->HubDb->UserList);
6006 
6007 	ReleaseHub(h);
6008 
6009 	IncrementServerConfigRevision(s);
6010 
6011 	return ERR_NO_ERROR;
6012 }
6013 
6014 // Delete a user
StDeleteUser(ADMIN * a,RPC_DELETE_USER * t)6015 UINT StDeleteUser(ADMIN *a, RPC_DELETE_USER *t)
6016 {
6017 	SERVER *s = a->Server;
6018 	CEDAR *c = s->Cedar;
6019 	HUB *h = NULL;
6020 	UINT ret = ERR_NO_ERROR;
6021 
6022 
6023 	if (IsEmptyStr(t->Name) || IsUserName(t->Name) == false)
6024 	{
6025 		return ERR_INVALID_PARAMETER;
6026 	}
6027 
6028 	CHECK_RIGHT;
6029 	NO_SUPPORT_FOR_BRIDGE;
6030 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
6031 	{
6032 		return ERR_NOT_SUPPORTED;
6033 	}
6034 
6035 	LockHubList(c);
6036 	{
6037 		h = GetHub(c, t->HubName);
6038 	}
6039 	UnlockHubList(c);
6040 
6041 	if (h == NULL)
6042 	{
6043 		return ERR_HUB_NOT_FOUND;
6044 	}
6045 
6046 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_users") != 0)
6047 	{
6048 		ReleaseHub(h);
6049 		return ERR_NOT_ENOUGH_RIGHT;
6050 	}
6051 
6052 	ALog(a, h, "LA_DELETE_USER", t->Name);
6053 
6054 	AcLock(h);
6055 	{
6056 		if (AcDeleteUser(h, t->Name) == false)
6057 		{
6058 			ret = ERR_OBJECT_NOT_FOUND;
6059 		}
6060 	}
6061 	AcUnlock(h);
6062 
6063 	ReleaseHub(h);
6064 
6065 	IncrementServerConfigRevision(s);
6066 
6067 	return ret;
6068 }
6069 
6070 // Get user setting
StGetUser(ADMIN * a,RPC_SET_USER * t)6071 UINT StGetUser(ADMIN *a, RPC_SET_USER *t)
6072 {
6073 	SERVER *s = a->Server;
6074 	CEDAR *c = s->Cedar;
6075 	HUB *h = NULL;
6076 	UINT ret = ERR_NO_ERROR;
6077 	USER *u = NULL;
6078 	USERGROUP *g = NULL;
6079 	char name[MAX_USERNAME_LEN + 1];
6080 	char hubname[MAX_HUBNAME_LEN + 1];
6081 	StrCpy(name, sizeof(name), t->Name);
6082 	StrCpy(hubname, sizeof(hubname), t->HubName);
6083 
6084 	if (IsEmptyStr(t->Name) || IsUserName(t->Name) == false)
6085 	{
6086 		return ERR_INVALID_PARAMETER;
6087 	}
6088 
6089 	CHECK_RIGHT;
6090 	NO_SUPPORT_FOR_BRIDGE;
6091 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
6092 	{
6093 		return ERR_NOT_SUPPORTED;
6094 	}
6095 
6096 	FreeRpcSetUser(t);
6097 	Zero(t, sizeof(RPC_SET_USER));
6098 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
6099 	StrCpy(t->Name, sizeof(t->Name), name);
6100 
6101 	LockHubList(c);
6102 	{
6103 		h = GetHub(c, hubname);
6104 	}
6105 	UnlockHubList(c);
6106 
6107 	if (h == NULL)
6108 	{
6109 		return ERR_HUB_NOT_FOUND;
6110 	}
6111 
6112 	AcLock(h);
6113 	{
6114 		u = AcGetUser(h, name);
6115 		if (u == NULL)
6116 		{
6117 			ret = ERR_OBJECT_NOT_FOUND;
6118 		}
6119 		else
6120 		{
6121 			Lock(u->lock);
6122 			{
6123 				StrCpy(t->GroupName, sizeof(t->GroupName), u->GroupName);
6124 				UniStrCpy(t->Realname, sizeof(t->Realname), u->RealName);
6125 				UniStrCpy(t->Note, sizeof(t->Note), u->Note);
6126 				t->CreatedTime = u->CreatedTime;
6127 				t->UpdatedTime = u->UpdatedTime;
6128 				t->ExpireTime = u->ExpireTime;
6129 
6130 				t->AuthType = u->AuthType;
6131 				t->AuthData = CopyAuthData(u->AuthData, t->AuthType);
6132 				t->NumLogin = u->NumLogin;
6133 				Copy(&t->Traffic, u->Traffic, sizeof(TRAFFIC));
6134 				if (u->Policy != NULL)
6135 				{
6136 					t->Policy = ClonePolicy(u->Policy);
6137 				}
6138 			}
6139 			Unlock(u->lock);
6140 
6141 			ReleaseUser(u);
6142 		}
6143 	}
6144 	AcUnlock(h);
6145 
6146 	ReleaseHub(h);
6147 
6148 	return ret;
6149 }
6150 
6151 // Set user setting
StSetUser(ADMIN * a,RPC_SET_USER * t)6152 UINT StSetUser(ADMIN *a, RPC_SET_USER *t)
6153 {
6154 	SERVER *s = a->Server;
6155 	CEDAR *c = s->Cedar;
6156 	HUB *h = NULL;
6157 	UINT ret = ERR_NO_ERROR;
6158 	USER *u = NULL;
6159 	USERGROUP *g = NULL;
6160 
6161 
6162 	if (IsEmptyStr(t->Name) || IsUserName(t->Name) == false)
6163 	{
6164 		return ERR_INVALID_PARAMETER;
6165 	}
6166 
6167 	NO_SUPPORT_FOR_BRIDGE;
6168 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
6169 	{
6170 		return ERR_NOT_SUPPORTED;
6171 	}
6172 
6173 	CHECK_RIGHT;
6174 
6175 	if (GetGlobalServerFlag(GSF_DISABLE_RADIUS_AUTH) != 0)
6176 	{
6177 		if (t->AuthType == AUTHTYPE_USERCERT || t->AuthType == AUTHTYPE_RADIUS || t->AuthType == AUTHTYPE_ROOTCERT || t->AuthType == AUTHTYPE_NT)
6178 		{
6179 			return ERR_NOT_SUPPORTED_AUTH_ON_OPENSOURCE;
6180 		}
6181 	}
6182 
6183 	if (StrCmpi(t->Name, "*") == 0)
6184 	{
6185 		if (t->AuthType != AUTHTYPE_RADIUS && t->AuthType != AUTHTYPE_NT)
6186 		{
6187 			return ERR_INVALID_PARAMETER;
6188 		}
6189 	}
6190 
6191 	if (t->AuthType == AUTHTYPE_USERCERT)
6192 	{
6193 		AUTHUSERCERT *c = t->AuthData;
6194 		if (c != NULL && c->UserX != NULL &&
6195 			c->UserX->is_compatible_bit == false)
6196 		{
6197 			return ERR_NOT_RSA_1024;
6198 		}
6199 		if (c == NULL || c->UserX == NULL)
6200 		{
6201 			return ERR_INVALID_PARAMETER;
6202 		}
6203 	}
6204 
6205 	LockHubList(c);
6206 	{
6207 		h = GetHub(c, t->HubName);
6208 	}
6209 	UnlockHubList(c);
6210 
6211 	if (h == NULL)
6212 	{
6213 		return ERR_HUB_NOT_FOUND;
6214 	}
6215 
6216 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_users") != 0)
6217 	{
6218 		ReleaseHub(h);
6219 		return ERR_NOT_ENOUGH_RIGHT;
6220 	}
6221 
6222 	AcLock(h);
6223 	{
6224 		u = AcGetUser(h, t->Name);
6225 		if (u == NULL)
6226 		{
6227 			ret = ERR_OBJECT_NOT_FOUND;
6228 		}
6229 		else
6230 		{
6231 			Lock(u->lock);
6232 			{
6233 				if (StrLen(t->GroupName) != 0)
6234 				{
6235 					g = AcGetGroup(h, t->GroupName);
6236 
6237 					if (g != NULL)
6238 					{
6239 						JoinUserToGroup(u, g);
6240 						ReleaseGroup(g);
6241 					}
6242 					else
6243 					{
6244 						ret = ERR_GROUP_NOT_FOUND;
6245 					}
6246 				}
6247 				else
6248 				{
6249 					JoinUserToGroup(u, NULL);
6250 				}
6251 
6252 				if (ret != ERR_GROUP_NOT_FOUND)
6253 				{
6254 					Free(u->RealName);
6255 					Free(u->Note);
6256 					u->RealName = UniCopyStr(t->Realname);
6257 					u->Note = UniCopyStr(t->Note);
6258 					SetUserAuthData(u, t->AuthType, CopyAuthData(t->AuthData, t->AuthType));
6259 					u->ExpireTime = t->ExpireTime;
6260 					u->UpdatedTime = SystemTime64();
6261 
6262 					SetUserPolicy(u, t->Policy);
6263 				}
6264 			}
6265 			Unlock(u->lock);
6266 
6267 			IncrementServerConfigRevision(s);
6268 
6269 			ReleaseUser(u);
6270 		}
6271 	}
6272 	AcUnlock(h);
6273 
6274 	if (ret == ERR_NO_ERROR)
6275 	{
6276 		ALog(a, h, "LA_SET_USER", t->Name);
6277 	}
6278 
6279 	ReleaseHub(h);
6280 
6281 	return ret;
6282 }
6283 
6284 // Create a user
StCreateUser(ADMIN * a,RPC_SET_USER * t)6285 UINT StCreateUser(ADMIN *a, RPC_SET_USER *t)
6286 {
6287 	SERVER *s = a->Server;
6288 	CEDAR *c = s->Cedar;
6289 	HUB *h = NULL;
6290 	UINT ret = ERR_NO_ERROR;
6291 	USER *u;
6292 	USERGROUP *g = NULL;
6293 
6294 
6295 	if (IsEmptyStr(t->Name) || IsUserName(t->Name) == false)
6296 	{
6297 		return ERR_INVALID_PARAMETER;
6298 	}
6299 
6300 	NO_SUPPORT_FOR_BRIDGE;
6301 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
6302 	{
6303 		return ERR_NOT_SUPPORTED;
6304 	}
6305 
6306 	CHECK_RIGHT;
6307 
6308 	if (GetGlobalServerFlag(GSF_DISABLE_RADIUS_AUTH) != 0)
6309 	{
6310 		if (t->AuthType == AUTHTYPE_USERCERT || t->AuthType == AUTHTYPE_RADIUS || t->AuthType == AUTHTYPE_ROOTCERT || t->AuthType == AUTHTYPE_NT)
6311 		{
6312 			return ERR_NOT_SUPPORTED_AUTH_ON_OPENSOURCE;
6313 		}
6314 	}
6315 
6316 	if (t->AuthType == AUTHTYPE_USERCERT)
6317 	{
6318 		AUTHUSERCERT *c = t->AuthData;
6319 		if (c != NULL && c->UserX != NULL &&
6320 			c->UserX->is_compatible_bit == false)
6321 		{
6322 			return ERR_NOT_RSA_1024;
6323 		}
6324 		if (c == NULL || c->UserX == NULL)
6325 		{
6326 			return ERR_INVALID_PARAMETER;
6327 		}
6328 	}
6329 
6330 	if (IsUserName(t->Name) == false)
6331 	{
6332 		return ERR_INVALID_PARAMETER;
6333 	}
6334 
6335 	if (StrCmpi(t->Name, "*") == 0)
6336 	{
6337 		if (t->AuthType != AUTHTYPE_RADIUS && t->AuthType != AUTHTYPE_NT)
6338 		{
6339 			return ERR_INVALID_PARAMETER;
6340 		}
6341 	}
6342 
6343 	LockHubList(c);
6344 	{
6345 		h = GetHub(c, t->HubName);
6346 	}
6347 	UnlockHubList(c);
6348 
6349 	if (h == NULL)
6350 	{
6351 		return ERR_HUB_NOT_FOUND;
6352 	}
6353 
6354 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_users") != 0)
6355 	{
6356 		ReleaseHub(h);
6357 		return ERR_NOT_ENOUGH_RIGHT;
6358 	}
6359 
6360 	u = NewUser(t->Name, t->Realname, t->Note, t->AuthType, CopyAuthData(t->AuthData, t->AuthType));
6361 	if (u == NULL)
6362 	{
6363 		ReleaseHub(h);
6364 		return ERR_INTERNAL_ERROR;
6365 	}
6366 
6367 	u->ExpireTime = t->ExpireTime;
6368 
6369 	SetUserPolicy(u, t->Policy);
6370 
6371 	AcLock(h);
6372 	{
6373 		if ((LIST_NUM(h->HubDb->UserList) >= GetServerCapsInt(a->Server, "i_max_users_per_hub")) ||
6374 			((GetHubAdminOption(h, "max_users") != 0) && (LIST_NUM(h->HubDb->UserList) >= GetHubAdminOption(h, "max_users"))))
6375 		{
6376 			ret = ERR_TOO_MANY_USER;
6377 		}
6378 		else if (SiTooManyUserObjectsInServer(s, false))
6379 		{
6380 			ret = ERR_TOO_MANY_USERS_CREATED;
6381 			ALog(a, h, "ERR_128");
6382 		}
6383 		else if (AcIsUser(h, t->Name))
6384 		{
6385 			ret = ERR_USER_ALREADY_EXISTS;
6386 		}
6387 		else
6388 		{
6389 			if (StrLen(t->GroupName) != 0)
6390 			{
6391 				g = AcGetGroup(h, t->GroupName);
6392 				if (g == NULL)
6393 				{
6394 					ret = ERR_GROUP_NOT_FOUND;
6395 				}
6396 			}
6397 
6398 			if (ret != ERR_GROUP_NOT_FOUND)
6399 			{
6400 				if (g != NULL)
6401 				{
6402 					JoinUserToGroup(u, g);
6403 					ReleaseGroup(g);
6404 				}
6405 
6406 				AcAddUser(h, u);
6407 				ALog(a, h, "LA_CREATE_USER", t->Name);
6408 
6409 				IncrementServerConfigRevision(s);
6410 			}
6411 		}
6412 	}
6413 	AcUnlock(h);
6414 
6415 	ReleaseUser(u);
6416 
6417 	ReleaseHub(h);
6418 
6419 	return ret;
6420 }
6421 
6422 // Get access list
StEnumAccess(ADMIN * a,RPC_ENUM_ACCESS_LIST * t)6423 UINT StEnumAccess(ADMIN *a, RPC_ENUM_ACCESS_LIST *t)
6424 {
6425 	SERVER *s = a->Server;
6426 	CEDAR *c = s->Cedar;
6427 	HUB *h;
6428 	UINT i;
6429 	char hubname[MAX_HUBNAME_LEN + 1];
6430 
6431 	CHECK_RIGHT;
6432 	NO_SUPPORT_FOR_BRIDGE;
6433 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
6434 	{
6435 		return ERR_NOT_SUPPORTED;
6436 	}
6437 
6438 	LockHubList(c);
6439 	{
6440 		h = GetHub(c, t->HubName);
6441 	}
6442 	UnlockHubList(c);
6443 
6444 	if (h == NULL)
6445 	{
6446 		return ERR_HUB_NOT_FOUND;
6447 	}
6448 
6449 	StrCpy(hubname, sizeof(hubname), t->HubName);
6450 	FreeRpcEnumAccessList(t);
6451 	Zero(t, sizeof(RPC_ENUM_ACCESS_LIST));
6452 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
6453 
6454 	LockList(h->AccessList);
6455 	{
6456 		t->NumAccess = LIST_NUM(h->AccessList);
6457 		t->Accesses = ZeroMalloc(sizeof(ACCESS) * t->NumAccess);
6458 
6459 		for (i = 0;i < LIST_NUM(h->AccessList);i++)
6460 		{
6461 			ACCESS *a = &t->Accesses[i];
6462 			Copy(a, LIST_DATA(h->AccessList, i), sizeof(ACCESS));
6463 			a->UniqueId = HashPtrToUINT(LIST_DATA(h->AccessList, i));
6464 		}
6465 	}
6466 	UnlockList(h->AccessList);
6467 
6468 	ReleaseHub(h);
6469 
6470 	return ERR_NO_ERROR;
6471 }
6472 
6473 // Delete access list entry
StDeleteAccess(ADMIN * a,RPC_DELETE_ACCESS * t)6474 UINT StDeleteAccess(ADMIN *a, RPC_DELETE_ACCESS *t)
6475 {
6476 	SERVER *s = a->Server;
6477 	CEDAR *c = s->Cedar;
6478 	HUB *h;
6479 	UINT i;
6480 	bool exists;
6481 
6482 
6483 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
6484 	{
6485 		return ERR_NOT_FARM_CONTROLLER;
6486 	}
6487 
6488 	CHECK_RIGHT;
6489 	NO_SUPPORT_FOR_BRIDGE;
6490 
6491 	LockHubList(c);
6492 	{
6493 		h = GetHub(c, t->HubName);
6494 	}
6495 	UnlockHubList(c);
6496 
6497 	if (h == NULL)
6498 	{
6499 		return ERR_HUB_NOT_FOUND;
6500 	}
6501 
6502 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_access_list") != 0)
6503 	{
6504 		ReleaseHub(h);
6505 		return ERR_NOT_ENOUGH_RIGHT;
6506 	}
6507 
6508 	exists = false;
6509 
6510 	LockList(h->AccessList);
6511 	{
6512 		for (i = 0;i < LIST_NUM(h->AccessList);i++)
6513 		{
6514 			ACCESS *access = LIST_DATA(h->AccessList, i);
6515 
6516 			if ((t->Id < MAX_ACCESSLISTS && access->Id == t->Id) ||
6517 				(t->Id >= MAX_ACCESSLISTS && HashPtrToUINT(access) == t->Id))
6518 			{
6519 				Free(access);
6520 				Delete(h->AccessList, access);
6521 				exists = true;
6522 
6523 				break;
6524 			}
6525 		}
6526 	}
6527 	UnlockList(h->AccessList);
6528 
6529 	if (exists == false)
6530 	{
6531 		ReleaseHub(h);
6532 		return ERR_OBJECT_NOT_FOUND;
6533 	}
6534 
6535 	ALog(a, h, "LA_DELETE_ACCESS");
6536 
6537 	IncrementServerConfigRevision(s);
6538 
6539 	ReleaseHub(h);
6540 
6541 	return ERR_NO_ERROR;
6542 }
6543 
6544 // Set access list
StSetAccessList(ADMIN * a,RPC_ENUM_ACCESS_LIST * t)6545 UINT StSetAccessList(ADMIN *a, RPC_ENUM_ACCESS_LIST *t)
6546 {
6547 	SERVER *s = a->Server;
6548 	CEDAR *c = s->Cedar;
6549 	HUB *h;
6550 	UINT i;
6551 	bool no_jitter = false;
6552 	bool no_include = false;
6553 	UINT ret = ERR_NO_ERROR;
6554 
6555 
6556 	NO_SUPPORT_FOR_BRIDGE;
6557 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
6558 	{
6559 		return ERR_NOT_SUPPORTED;
6560 	}
6561 
6562 	CHECK_RIGHT;
6563 
6564 	if (t->NumAccess > GetServerCapsInt(a->Server, "i_max_access_lists"))
6565 	{
6566 		return ERR_TOO_MANY_ACCESS_LIST;
6567 	}
6568 
6569 	LockHubList(c);
6570 	{
6571 		h = GetHub(c, t->HubName);
6572 	}
6573 	UnlockHubList(c);
6574 
6575 	if (h == NULL)
6576 	{
6577 		return ERR_HUB_NOT_FOUND;
6578 	}
6579 
6580 	no_jitter = GetHubAdminOption(h, "no_delay_jitter_packet_loss");
6581 	no_include = GetHubAdminOption(h, "no_access_list_include_file");
6582 
6583 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_access_list") != 0)
6584 	{
6585 		ReleaseHub(h);
6586 		return ERR_NOT_ENOUGH_RIGHT;
6587 	}
6588 
6589 	if (a->ServerAdmin == false && GetHubAdminOption(h, "max_accesslists") != 0 &&
6590 		t->NumAccess > GetHubAdminOption(h, "max_accesslists"))
6591 	{
6592 		ReleaseHub(h);
6593 		return ERR_TOO_MANY_ACCESS_LIST;
6594 	}
6595 
6596 	LockList(h->AccessList);
6597 	{
6598 		UINT i;
6599 
6600 		if (a->ClientBuild != 0)
6601 		{
6602 			// Confirm whether the access list of form which cannot handle by the old client already exists
6603 			if (a->ClientBuild < 6560)
6604 			{
6605 				for (i = 0;i < LIST_NUM(h->AccessList);i++)
6606 				{
6607 					ACCESS *access = LIST_DATA(h->AccessList, i);
6608 					if (access->IsIPv6 ||
6609 						access->Jitter != 0 || access->Loss != 0 || access->Delay != 0)
6610 					{
6611 						ret = ERR_VERSION_INVALID;
6612 						break;
6613 					}
6614 				}
6615 			}
6616 
6617 			if (a->ClientBuild < 8234)
6618 			{
6619 				for (i = 0;i < LIST_NUM(h->AccessList);i++)
6620 				{
6621 					ACCESS *access = LIST_DATA(h->AccessList, i);
6622 
6623 					if (IsEmptyStr(access->RedirectUrl) == false)
6624 					{
6625 						ret = ERR_VERSION_INVALID;
6626 						break;
6627 					}
6628 				}
6629 			}
6630 		}
6631 
6632 		if (ret == ERR_NO_ERROR)
6633 		{
6634 			// Delete whole access list
6635 			for (i = 0;i < LIST_NUM(h->AccessList);i++)
6636 			{
6637 				ACCESS *access = LIST_DATA(h->AccessList, i);
6638 				Free(access);
6639 			}
6640 
6641 			DeleteAll(h->AccessList);
6642 		}
6643 	}
6644 
6645 	if (ret == ERR_NO_ERROR)
6646 	{
6647 		ALog(a, h, "LA_SET_ACCESS_LIST", t->NumAccess);
6648 
6649 		// Add whole access list
6650 		for (i = 0;i < t->NumAccess;i++)
6651 		{
6652 			ACCESS *a = &t->Accesses[i];
6653 
6654 			if (no_jitter)
6655 			{
6656 				a->Jitter = a->Loss = a->Delay = 0;
6657 			}
6658 
6659 			if (no_include)
6660 			{
6661 				if (StartWith(a->SrcUsername, ACCESS_LIST_INCLUDED_PREFIX) ||
6662 					StartWith(a->SrcUsername, ACCESS_LIST_EXCLUDED_PREFIX))
6663 				{
6664 					ClearStr(a->SrcUsername, sizeof(a->SrcUsername));
6665 				}
6666 
6667 				if (StartWith(a->DestUsername, ACCESS_LIST_INCLUDED_PREFIX) ||
6668 					StartWith(a->DestUsername, ACCESS_LIST_EXCLUDED_PREFIX))
6669 				{
6670 					ClearStr(a->DestUsername, sizeof(a->DestUsername));
6671 				}
6672 			}
6673 
6674 			if (i == (t->NumAccess - 1))
6675 			{
6676 				Sort(h->AccessList);
6677 			}
6678 
6679 			AddAccessListEx(h, a, ((i != (t->NumAccess - 1)) ? true : false), ((i != (t->NumAccess - 1)) ? true : false));
6680 		}
6681 
6682 		UnlockList(h->AccessList);
6683 
6684 		IncrementServerConfigRevision(s);
6685 
6686 		h->CurrentVersion++;
6687 		SiHubUpdateProc(h);
6688 	}
6689 	else
6690 	{
6691 		UnlockList(h->AccessList);
6692 	}
6693 
6694 	ReleaseHub(h);
6695 
6696 	return ret;
6697 }
6698 
6699 // Add access list entry
StAddAccess(ADMIN * a,RPC_ADD_ACCESS * t)6700 UINT StAddAccess(ADMIN *a, RPC_ADD_ACCESS *t)
6701 {
6702 	SERVER *s = a->Server;
6703 	CEDAR *c = s->Cedar;
6704 	HUB *h;
6705 	bool no_jitter = false;
6706 	bool no_include = false;
6707 
6708 
6709 	NO_SUPPORT_FOR_BRIDGE;
6710 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
6711 	{
6712 		return ERR_NOT_SUPPORTED;
6713 	}
6714 
6715 	CHECK_RIGHT;
6716 
6717 	LockHubList(c);
6718 	{
6719 		h = GetHub(c, t->HubName);
6720 	}
6721 	UnlockHubList(c);
6722 
6723 	if (h == NULL)
6724 	{
6725 		return ERR_HUB_NOT_FOUND;
6726 	}
6727 
6728 	no_jitter = GetHubAdminOption(h, "no_delay_jitter_packet_loss");
6729 	no_include = GetHubAdminOption(h, "no_access_list_include_file");
6730 
6731 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_access_list") != 0)
6732 	{
6733 		ReleaseHub(h);
6734 		return ERR_NOT_ENOUGH_RIGHT;
6735 	}
6736 
6737 	if ((LIST_NUM(h->AccessList) >= GetServerCapsInt(a->Server, "i_max_access_lists") ||
6738 		(GetHubAdminOption(h, "max_accesslists") != 0) && (LIST_NUM(h->AccessList) >= GetHubAdminOption(h, "max_accesslists"))))
6739 	{
6740 		ReleaseHub(h);
6741 		return ERR_TOO_MANY_ACCESS_LIST;
6742 	}
6743 
6744 	ALog(a, h, "LA_ADD_ACCESS");
6745 
6746 	if (no_jitter)
6747 	{
6748 		t->Access.Jitter = t->Access.Delay = t->Access.Loss = 0;
6749 	}
6750 
6751 	if (no_include)
6752 	{
6753 		if (StartWith(t->Access.SrcUsername, ACCESS_LIST_INCLUDED_PREFIX) ||
6754 			StartWith(t->Access.SrcUsername, ACCESS_LIST_EXCLUDED_PREFIX))
6755 		{
6756 			ClearStr(t->Access.SrcUsername, sizeof(t->Access.SrcUsername));
6757 		}
6758 
6759 		if (StartWith(t->Access.DestUsername, ACCESS_LIST_INCLUDED_PREFIX) ||
6760 			StartWith(t->Access.DestUsername, ACCESS_LIST_EXCLUDED_PREFIX))
6761 		{
6762 			ClearStr(t->Access.DestUsername, sizeof(t->Access.DestUsername));
6763 		}
6764 	}
6765 
6766 	AddAccessList(h, &t->Access);
6767 
6768 	h->CurrentVersion++;
6769 	SiHubUpdateProc(h);
6770 
6771 	ReleaseHub(h);
6772 
6773 	IncrementServerConfigRevision(s);
6774 
6775 	return ERR_NO_ERROR;
6776 }
6777 
6778 // Rename link (cascade connection)
StRenameLink(ADMIN * a,RPC_RENAME_LINK * t)6779 UINT StRenameLink(ADMIN *a, RPC_RENAME_LINK *t)
6780 {
6781 	UINT i;
6782 	SERVER *s = a->Server;
6783 	CEDAR *c = s->Cedar;
6784 	HUB *h;
6785 	UINT ret = ERR_NO_ERROR;
6786 	LINK *k;
6787 	bool exists = false;
6788 
6789 	if (UniIsEmptyStr(t->OldAccountName) || UniIsEmptyStr(t->NewAccountName))
6790 	{
6791 		return ERR_INVALID_PARAMETER;
6792 	}
6793 
6794 	if (s->ServerType != SERVER_TYPE_STANDALONE)
6795 	{
6796 		return ERR_NOT_SUPPORTED;
6797 	}
6798 
6799 	CHECK_RIGHT;
6800 
6801 	if (UniStrCmpi(t->NewAccountName, t->OldAccountName) == 0)
6802 	{
6803 		// Noop if new name is same to old name
6804 		return ERR_NO_ERROR;
6805 	}
6806 
6807 	h = GetHub(c, t->HubName);
6808 
6809 	if (h == NULL)
6810 	{
6811 		return ERR_HUB_NOT_FOUND;
6812 	}
6813 
6814 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_cascade") != 0)
6815 	{
6816 		ReleaseHub(h);
6817 		return ERR_NOT_ENOUGH_RIGHT;
6818 	}
6819 
6820 	k = NULL;
6821 
6822 	// Find specified link
6823 	LockList(h->LinkList);
6824 	{
6825 		for (i = 0;i < LIST_NUM(h->LinkList);i++)
6826 		{
6827 			LINK *kk = LIST_DATA(h->LinkList, i);
6828 			Lock(kk->lock);
6829 			{
6830 				if (UniStrCmpi(kk->Option->AccountName, t->OldAccountName) == 0)
6831 				{
6832 					k = kk;
6833 					AddRef(kk->ref);
6834 				}
6835 			}
6836 			Unlock(kk->lock);
6837 
6838 			if (k != NULL)
6839 			{
6840 				break;
6841 			}
6842 		}
6843 
6844 		exists = false;
6845 
6846 		if (k != NULL)
6847 		{
6848 			// Check whether the new link name is same to other links
6849 			for (i = 0;i < LIST_NUM(h->LinkList);i++)
6850 			{
6851 				LINK *kk = LIST_DATA(h->LinkList, i);
6852 				Lock(kk->lock);
6853 				{
6854 					if (UniStrCmpi(kk->Option->AccountName, t->NewAccountName) == 0)
6855 					{
6856 						// duplicated
6857 						exists = true;
6858 					}
6859 				}
6860 				Unlock(kk->lock);
6861 			}
6862 
6863 			if (exists)
6864 			{
6865 				// Already same name exists
6866 				ret = ERR_LINK_ALREADY_EXISTS;
6867 			}
6868 			else
6869 			{
6870 				// Do rename
6871 				UniStrCpy(k->Option->AccountName, sizeof(k->Option->AccountName), t->NewAccountName);
6872 
6873 				ALog(a, h, "LA_RENAME_LINK", t->OldAccountName, t->NewAccountName);
6874 
6875 				IncrementServerConfigRevision(s);
6876 			}
6877 		}
6878 	}
6879 	UnlockList(h->LinkList);
6880 
6881 	if (k == NULL)
6882 	{
6883 		// specified link is not found
6884 		ReleaseHub(h);
6885 		return ERR_OBJECT_NOT_FOUND;
6886 	}
6887 
6888 	ReleaseLink(k);
6889 
6890 	ReleaseHub(h);
6891 
6892 	return ret;
6893 }
6894 
6895 // Delete a link
StDeleteLink(ADMIN * a,RPC_LINK * t)6896 UINT StDeleteLink(ADMIN *a, RPC_LINK *t)
6897 {
6898 	UINT i;
6899 	SERVER *s = a->Server;
6900 	CEDAR *c = s->Cedar;
6901 	HUB *h;
6902 	UINT ret = ERR_NO_ERROR;
6903 	char hubname[MAX_HUBNAME_LEN + 1];
6904 	wchar_t accountname[MAX_ACCOUNT_NAME_LEN + 1];
6905 	LINK *k;
6906 
6907 	if (UniIsEmptyStr(t->AccountName))
6908 	{
6909 		return ERR_INVALID_PARAMETER;
6910 	}
6911 
6912 	if (s->ServerType != SERVER_TYPE_STANDALONE)
6913 	{
6914 		return ERR_NOT_SUPPORTED;
6915 	}
6916 
6917 	CHECK_RIGHT;
6918 
6919 	LockHubList(c);
6920 	{
6921 		h = GetHub(c, t->HubName);
6922 	}
6923 	UnlockHubList(c);
6924 
6925 	if (h == NULL)
6926 	{
6927 		return ERR_HUB_NOT_FOUND;
6928 	}
6929 
6930 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_cascade") != 0)
6931 	{
6932 		ReleaseHub(h);
6933 		return ERR_NOT_ENOUGH_RIGHT;
6934 	}
6935 
6936 	StrCpy(hubname, sizeof(hubname), t->HubName);
6937 	UniStrCpy(accountname, sizeof(accountname), t->AccountName);
6938 	k = NULL;
6939 
6940 	// Find specified link
6941 	LockList(h->LinkList);
6942 	{
6943 		for (i = 0;i < LIST_NUM(h->LinkList);i++)
6944 		{
6945 			LINK *kk = LIST_DATA(h->LinkList, i);
6946 			Lock(kk->lock);
6947 			{
6948 				if (UniStrCmpi(kk->Option->AccountName, accountname) == 0)
6949 				{
6950 					k = kk;
6951 					AddRef(kk->ref);
6952 				}
6953 			}
6954 			Unlock(kk->lock);
6955 
6956 			if (k != NULL)
6957 			{
6958 				break;
6959 			}
6960 		}
6961 	}
6962 	UnlockList(h->LinkList);
6963 
6964 	if (k == NULL)
6965 	{
6966 		// Specified link is not found
6967 		ReleaseHub(h);
6968 
6969 		return ERR_OBJECT_NOT_FOUND;
6970 	}
6971 
6972 	k->NoOnline = true;
6973 
6974 	ALog(a, h, "LA_DELETE_LINK", t->AccountName);
6975 
6976 	SetLinkOffline(k);
6977 
6978 	IncrementServerConfigRevision(s);
6979 
6980 	DelLink(h, k);
6981 
6982 	ReleaseLink(k);
6983 	ReleaseHub(h);
6984 
6985 	return ret;
6986 }
6987 
6988 // Make a link into off-line
StSetLinkOffline(ADMIN * a,RPC_LINK * t)6989 UINT StSetLinkOffline(ADMIN *a, RPC_LINK *t)
6990 {
6991 	UINT i;
6992 	SERVER *s = a->Server;
6993 	CEDAR *c = s->Cedar;
6994 	HUB *h;
6995 	UINT ret = ERR_NO_ERROR;
6996 	char hubname[MAX_HUBNAME_LEN + 1];
6997 	wchar_t accountname[MAX_ACCOUNT_NAME_LEN + 1];
6998 	LINK *k;
6999 
7000 
7001 	if (UniIsEmptyStr(t->AccountName))
7002 	{
7003 		return ERR_INVALID_PARAMETER;
7004 	}
7005 
7006 	if (s->ServerType != SERVER_TYPE_STANDALONE)
7007 	{
7008 		return ERR_NOT_SUPPORTED;
7009 	}
7010 
7011 	CHECK_RIGHT;
7012 
7013 	LockHubList(c);
7014 	{
7015 		h = GetHub(c, t->HubName);
7016 	}
7017 	UnlockHubList(c);
7018 
7019 	if (h == NULL)
7020 	{
7021 		return ERR_HUB_NOT_FOUND;
7022 	}
7023 
7024 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_cascade") != 0)
7025 	{
7026 		ReleaseHub(h);
7027 		return ERR_NOT_ENOUGH_RIGHT;
7028 	}
7029 
7030 	StrCpy(hubname, sizeof(hubname), t->HubName);
7031 	UniStrCpy(accountname, sizeof(accountname), t->AccountName);
7032 	k = NULL;
7033 
7034 	// Find specified link
7035 	LockList(h->LinkList);
7036 	{
7037 		for (i = 0;i < LIST_NUM(h->LinkList);i++)
7038 		{
7039 			LINK *kk = LIST_DATA(h->LinkList, i);
7040 			Lock(kk->lock);
7041 			{
7042 				if (UniStrCmpi(kk->Option->AccountName, accountname) == 0)
7043 				{
7044 					k = kk;
7045 					AddRef(kk->ref);
7046 				}
7047 			}
7048 			Unlock(kk->lock);
7049 
7050 			if (k != NULL)
7051 			{
7052 				break;
7053 			}
7054 		}
7055 	}
7056 	UnlockList(h->LinkList);
7057 
7058 	if (k == NULL)
7059 	{
7060 		// Link is not found
7061 		ReleaseHub(h);
7062 
7063 		return ERR_OBJECT_NOT_FOUND;
7064 	}
7065 
7066 	ALog(a, h, "LA_SET_LINK_OFFLINE", t->AccountName);
7067 
7068 	SetLinkOffline(k);
7069 
7070 	IncrementServerConfigRevision(s);
7071 
7072 	ReleaseLink(k);
7073 	ReleaseHub(h);
7074 
7075 	return ret;
7076 }
7077 
7078 // Make a link into on-line
StSetLinkOnline(ADMIN * a,RPC_LINK * t)7079 UINT StSetLinkOnline(ADMIN *a, RPC_LINK *t)
7080 {
7081 	UINT i;
7082 	SERVER *s = a->Server;
7083 	CEDAR *c = s->Cedar;
7084 	HUB *h;
7085 	UINT ret = ERR_NO_ERROR;
7086 	char hubname[MAX_HUBNAME_LEN + 1];
7087 	wchar_t accountname[MAX_ACCOUNT_NAME_LEN + 1];
7088 	LINK *k;
7089 
7090 
7091 	if (UniIsEmptyStr(t->AccountName))
7092 	{
7093 		return ERR_INVALID_PARAMETER;
7094 	}
7095 
7096 	if (s->ServerType != SERVER_TYPE_STANDALONE)
7097 	{
7098 		return ERR_NOT_SUPPORTED;
7099 	}
7100 
7101 	CHECK_RIGHT;
7102 
7103 	LockHubList(c);
7104 	{
7105 		h = GetHub(c, t->HubName);
7106 	}
7107 	UnlockHubList(c);
7108 
7109 	if (h == NULL)
7110 	{
7111 		return ERR_HUB_NOT_FOUND;
7112 	}
7113 
7114 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_cascade") != 0)
7115 	{
7116 		ReleaseHub(h);
7117 		return ERR_NOT_ENOUGH_RIGHT;
7118 	}
7119 
7120 	StrCpy(hubname, sizeof(hubname), t->HubName);
7121 	UniStrCpy(accountname, sizeof(accountname), t->AccountName);
7122 	k = NULL;
7123 
7124 	// Find specified link
7125 	LockList(h->LinkList);
7126 	{
7127 		for (i = 0;i < LIST_NUM(h->LinkList);i++)
7128 		{
7129 			LINK *kk = LIST_DATA(h->LinkList, i);
7130 			Lock(kk->lock);
7131 			{
7132 				if (UniStrCmpi(kk->Option->AccountName, accountname) == 0)
7133 				{
7134 					k = kk;
7135 					AddRef(kk->ref);
7136 				}
7137 			}
7138 			Unlock(kk->lock);
7139 
7140 			if (k != NULL)
7141 			{
7142 				break;
7143 			}
7144 		}
7145 	}
7146 	UnlockList(h->LinkList);
7147 
7148 	if (k == NULL)
7149 	{
7150 		// Specified link is not found
7151 		ReleaseHub(h);
7152 
7153 		return ERR_OBJECT_NOT_FOUND;
7154 	}
7155 
7156 	ALog(a, h, "LA_SET_LINK_ONLINE", t->AccountName);
7157 
7158 	SetLinkOnline(k);
7159 
7160 	ReleaseLink(k);
7161 	ReleaseHub(h);
7162 
7163 	IncrementServerConfigRevision(s);
7164 
7165 	return ret;
7166 }
7167 
7168 // Get link status
StGetLinkStatus(ADMIN * a,RPC_LINK_STATUS * t)7169 UINT StGetLinkStatus(ADMIN *a, RPC_LINK_STATUS *t)
7170 {
7171 	UINT i;
7172 	SERVER *s = a->Server;
7173 	CEDAR *c = s->Cedar;
7174 	HUB *h;
7175 	UINT ret = ERR_NO_ERROR;
7176 	char hubname[MAX_HUBNAME_LEN + 1];
7177 	wchar_t accountname[MAX_ACCOUNT_NAME_LEN + 1];
7178 	LINK *k;
7179 	SESSION *sess;
7180 
7181 	if (UniIsEmptyStr(t->AccountName))
7182 	{
7183 		return ERR_INVALID_PARAMETER;
7184 	}
7185 
7186 	if (s->ServerType != SERVER_TYPE_STANDALONE)
7187 	{
7188 		return ERR_NOT_SUPPORTED;
7189 	}
7190 
7191 	CHECK_RIGHT;
7192 
7193 	LockHubList(c);
7194 	{
7195 		h = GetHub(c, t->HubName);
7196 	}
7197 	UnlockHubList(c);
7198 
7199 	if (h == NULL)
7200 	{
7201 		return ERR_HUB_NOT_FOUND;
7202 	}
7203 
7204 	StrCpy(hubname, sizeof(hubname), t->HubName);
7205 	UniStrCpy(accountname, sizeof(accountname), t->AccountName);
7206 	FreeRpcLinkStatus(t);
7207 	Zero(t, sizeof(RPC_LINK_STATUS));
7208 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
7209 	UniStrCpy(t->AccountName, sizeof(t->AccountName), accountname);
7210 
7211 	k = NULL;
7212 
7213 	// Find the link
7214 	LockList(h->LinkList);
7215 	{
7216 		for (i = 0;i < LIST_NUM(h->LinkList);i++)
7217 		{
7218 			LINK *kk = LIST_DATA(h->LinkList, i);
7219 			Lock(kk->lock);
7220 			{
7221 				if (UniStrCmpi(kk->Option->AccountName, accountname) == 0)
7222 				{
7223 					k = kk;
7224 					AddRef(kk->ref);
7225 				}
7226 			}
7227 			Unlock(kk->lock);
7228 
7229 			if (k != NULL)
7230 			{
7231 				break;
7232 			}
7233 		}
7234 	}
7235 	UnlockList(h->LinkList);
7236 
7237 	if (k == NULL)
7238 	{
7239 		// Specified link is not found
7240 		ReleaseHub(h);
7241 
7242 		return ERR_OBJECT_NOT_FOUND;
7243 	}
7244 
7245 	// Get status information from session
7246 	Lock(k->lock);
7247 	{
7248 		sess = k->ClientSession;
7249 		if (sess != NULL)
7250 		{
7251 			AddRef(sess->ref);
7252 		}
7253 	}
7254 	Unlock(k->lock);
7255 
7256 	if (sess != NULL && k->Offline == false)
7257 	{
7258 		CiGetSessionStatus(&t->Status, sess);
7259 	}
7260 	else
7261 	{
7262 		ret = ERR_LINK_IS_OFFLINE;
7263 	}
7264 	ReleaseSession(sess);
7265 
7266 	ReleaseLink(k);
7267 	ReleaseHub(h);
7268 
7269 	return ret;
7270 }
7271 
7272 // Enumerate links
StEnumLink(ADMIN * a,RPC_ENUM_LINK * t)7273 UINT StEnumLink(ADMIN *a, RPC_ENUM_LINK *t)
7274 {
7275 	SERVER *s = a->Server;
7276 	CEDAR *c = s->Cedar;
7277 	HUB *h;
7278 	char hubname[MAX_HUBNAME_LEN + 1];
7279 	UINT i;
7280 
7281 	if (s->ServerType != SERVER_TYPE_STANDALONE)
7282 	{
7283 		return ERR_NOT_SUPPORTED;
7284 	}
7285 
7286 	CHECK_RIGHT;
7287 
7288 	LockHubList(c);
7289 	{
7290 		h = GetHub(c, t->HubName);
7291 	}
7292 	UnlockHubList(c);
7293 
7294 	if (h == NULL)
7295 	{
7296 		return ERR_HUB_NOT_FOUND;
7297 	}
7298 
7299 	StrCpy(hubname, sizeof(hubname), t->HubName);
7300 	FreeRpcEnumLink(t);
7301 	Zero(t, sizeof(RPC_ENUM_LINK));
7302 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
7303 
7304 	LockList(h->LinkList);
7305 	{
7306 		t->NumLink = LIST_NUM(h->LinkList);
7307 		t->Links = ZeroMalloc(sizeof(RPC_ENUM_LINK_ITEM) * t->NumLink);
7308 
7309 		for (i = 0;i < LIST_NUM(h->LinkList);i++)
7310 		{
7311 			LINK *k = LIST_DATA(h->LinkList, i);
7312 			RPC_ENUM_LINK_ITEM *e = &t->Links[i];
7313 
7314 			Lock(k->lock);
7315 			{
7316 				UniStrCpy(e->AccountName, sizeof(e->AccountName), k->Option->AccountName);
7317 				StrCpy(e->Hostname, sizeof(e->Hostname), k->Option->Hostname);
7318 				StrCpy(e->HubName, sizeof(e->HubName), k->Option->HubName);
7319 				e->Online = k->Offline ? false : true;
7320 
7321 				if (e->Online)
7322 				{
7323 					if (k->ClientSession != NULL)
7324 					{
7325 						e->ConnectedTime = TickToTime(k->ClientSession->CurrentConnectionEstablishTime);
7326 						e->Connected = (k->ClientSession->ClientStatus == CLIENT_STATUS_ESTABLISHED);
7327 						e->LastError = k->ClientSession->Err;
7328 					}
7329 				}
7330 			}
7331 			Unlock(k->lock);
7332 		}
7333 	}
7334 	UnlockList(h->LinkList);
7335 
7336 	ReleaseHub(h);
7337 
7338 	return ERR_NO_ERROR;
7339 }
7340 
7341 // Get link configuration
StGetLink(ADMIN * a,RPC_CREATE_LINK * t)7342 UINT StGetLink(ADMIN *a, RPC_CREATE_LINK *t)
7343 {
7344 	SERVER *s = a->Server;
7345 	CEDAR *c = s->Cedar;
7346 	HUB *h;
7347 	UINT ret = ERR_NO_ERROR;
7348 	UINT i;
7349 	char hubname[MAX_SIZE];
7350 	LINK *k;
7351 
7352 	if (s->ServerType != SERVER_TYPE_STANDALONE)
7353 	{
7354 		return ERR_NOT_SUPPORTED;
7355 	}
7356 
7357 	CHECK_RIGHT;
7358 
7359 	if (s->ServerType != SERVER_TYPE_STANDALONE)
7360 	{
7361 		return ERR_LINK_CANT_CREATE_ON_FARM;
7362 	}
7363 
7364 	LockHubList(c);
7365 	{
7366 		h = GetHub(c, t->HubName);
7367 	}
7368 	UnlockHubList(c);
7369 
7370 	if (h == NULL)
7371 	{
7372 		return ERR_HUB_NOT_FOUND;
7373 	}
7374 
7375 	k = NULL;
7376 
7377 	// Find the link
7378 	LockList(h->LinkList);
7379 	{
7380 		for (i = 0;i < LIST_NUM(h->LinkList);i++)
7381 		{
7382 			LINK *kk = LIST_DATA(h->LinkList, i);
7383 			Lock(kk->lock);
7384 			{
7385 				if (UniStrCmpi(kk->Option->AccountName, t->ClientOption->AccountName) == 0)
7386 				{
7387 					k = kk;
7388 					AddRef(kk->ref);
7389 				}
7390 			}
7391 			Unlock(kk->lock);
7392 
7393 			if (k != NULL)
7394 			{
7395 				break;
7396 			}
7397 		}
7398 	}
7399 	UnlockList(h->LinkList);
7400 
7401 	if (k == NULL)
7402 	{
7403 		// The link is not found
7404 		ReleaseHub(h);
7405 		return ERR_OBJECT_NOT_FOUND;
7406 	}
7407 
7408 	StrCpy(hubname, sizeof(hubname), t->HubName);
7409 	FreeRpcCreateLink(t);
7410 	Zero(t, sizeof(RPC_CREATE_LINK));
7411 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
7412 
7413 	Lock(k->lock);
7414 	{
7415 		// Get configuration
7416 		t->Online = k->Offline ? false : true;
7417 		t->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
7418 		Copy(t->ClientOption, k->Option, sizeof(CLIENT_OPTION));
7419 		t->ClientAuth = CopyClientAuth(k->Auth);
7420 		Copy(&t->Policy, k->Policy, sizeof(POLICY));
7421 
7422 		t->CheckServerCert = k->CheckServerCert;
7423 		t->ServerCert = CloneX(k->ServerCert);
7424 	}
7425 	Unlock(k->lock);
7426 
7427 	ReleaseLink(k);
7428 	ReleaseHub(h);
7429 
7430 	return ret;
7431 }
7432 
7433 // Set link configuration
StSetLink(ADMIN * a,RPC_CREATE_LINK * t)7434 UINT StSetLink(ADMIN *a, RPC_CREATE_LINK *t)
7435 {
7436 	SERVER *s = a->Server;
7437 	CEDAR *c = s->Cedar;
7438 	HUB *h;
7439 	UINT ret = ERR_NO_ERROR;
7440 	UINT i;
7441 	LINK *k;
7442 
7443 
7444 	if (s->ServerType != SERVER_TYPE_STANDALONE)
7445 	{
7446 		return ERR_NOT_SUPPORTED;
7447 	}
7448 
7449 	CHECK_RIGHT;
7450 
7451 	if (s->ServerType != SERVER_TYPE_STANDALONE)
7452 	{
7453 		return ERR_LINK_CANT_CREATE_ON_FARM;
7454 	}
7455 
7456 	LockHubList(c);
7457 	{
7458 		h = GetHub(c, t->HubName);
7459 	}
7460 	UnlockHubList(c);
7461 
7462 	if (h == NULL)
7463 	{
7464 		return ERR_HUB_NOT_FOUND;
7465 	}
7466 
7467 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_cascade") != 0)
7468 	{
7469 		ReleaseHub(h);
7470 		return ERR_NOT_ENOUGH_RIGHT;
7471 	}
7472 
7473 	k = NULL;
7474 
7475 	// Find the link
7476 	LockList(h->LinkList);
7477 	{
7478 		for (i = 0;i < LIST_NUM(h->LinkList);i++)
7479 		{
7480 			LINK *kk = LIST_DATA(h->LinkList, i);
7481 			Lock(kk->lock);
7482 			{
7483 				if (UniStrCmpi(kk->Option->AccountName, t->ClientOption->AccountName) == 0)
7484 				{
7485 					k = kk;
7486 					AddRef(kk->ref);
7487 				}
7488 			}
7489 			Unlock(kk->lock);
7490 
7491 			if (k != NULL)
7492 			{
7493 				break;
7494 			}
7495 		}
7496 	}
7497 	UnlockList(h->LinkList);
7498 
7499 	if (k == NULL)
7500 	{
7501 		// The link is not found
7502 		ReleaseHub(h);
7503 		return ERR_OBJECT_NOT_FOUND;
7504 	}
7505 
7506 	ALog(a, h, "LA_SET_LINK", t->ClientOption->AccountName);
7507 
7508 	Lock(k->lock);
7509 	{
7510 		// Update the configuration of the link
7511 		if (k->ServerCert != NULL)
7512 		{
7513 			FreeX(k->ServerCert);
7514 			k->ServerCert = NULL;
7515 		}
7516 
7517 		Copy(k->Option, t->ClientOption, sizeof(CLIENT_OPTION));
7518 		StrCpy(k->Option->DeviceName, sizeof(k->Option->DeviceName), LINK_DEVICE_NAME);
7519 		k->Option->NumRetry = INFINITE;
7520 		k->Option->RetryInterval = 10;
7521 		k->Option->NoRoutingTracking = true;
7522 		CiFreeClientAuth(k->Auth);
7523 		k->Auth = CopyClientAuth(t->ClientAuth);
7524 
7525 		if (t->Policy.Ver3 == false)
7526 		{
7527 			Copy(k->Policy, &t->Policy, sizeof(UINT) * NUM_POLICY_ITEM_FOR_VER2);
7528 		}
7529 		else
7530 		{
7531 			Copy(k->Policy, &t->Policy, sizeof(POLICY));
7532 		}
7533 
7534 		k->Option->RequireBridgeRoutingMode = true;	// Enable Bridge / Routing mode
7535 		k->Option->RequireMonitorMode = false;	// Disable monitor mode
7536 
7537 		k->CheckServerCert = t->CheckServerCert;
7538 		k->ServerCert = CloneX(t->ServerCert);
7539 	}
7540 	Unlock(k->lock);
7541 
7542 	IncrementServerConfigRevision(s);
7543 
7544 	ReleaseLink(k);
7545 	ReleaseHub(h);
7546 
7547 	return ret;
7548 }
7549 
7550 // Create a new link(cascade)
StCreateLink(ADMIN * a,RPC_CREATE_LINK * t)7551 UINT StCreateLink(ADMIN *a, RPC_CREATE_LINK *t)
7552 {
7553 	SERVER *s = a->Server;
7554 	CEDAR *c = s->Cedar;
7555 	HUB *h;
7556 	UINT ret = ERR_NO_ERROR;
7557 	UINT i;
7558 	LINK *k;
7559 
7560 	CHECK_RIGHT;
7561 
7562 
7563 	if (s->ServerType != SERVER_TYPE_STANDALONE)
7564 	{
7565 		return ERR_LINK_CANT_CREATE_ON_FARM;
7566 	}
7567 
7568 	LockHubList(c);
7569 	{
7570 		h = GetHub(c, t->HubName);
7571 	}
7572 	UnlockHubList(c);
7573 
7574 	if (h == NULL)
7575 	{
7576 		return ERR_HUB_NOT_FOUND;
7577 	}
7578 
7579 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_cascade") != 0)
7580 	{
7581 		ReleaseHub(h);
7582 		return ERR_NOT_ENOUGH_RIGHT;
7583 	}
7584 
7585 	k = NULL;
7586 
7587 	// Check for existing a link which has same name
7588 	LockList(h->LinkList);
7589 	{
7590 		for (i = 0;i < LIST_NUM(h->LinkList);i++)
7591 		{
7592 			LINK *kk = LIST_DATA(h->LinkList, i);
7593 			Lock(kk->lock);
7594 			{
7595 				if (UniStrCmpi(kk->Option->AccountName, t->ClientOption->AccountName) == 0)
7596 				{
7597 					k = kk;
7598 					AddRef(kk->ref);
7599 				}
7600 			}
7601 			Unlock(kk->lock);
7602 
7603 			if (k != NULL)
7604 			{
7605 				break;
7606 			}
7607 		}
7608 	}
7609 	UnlockList(h->LinkList);
7610 
7611 	if (k != NULL)
7612 	{
7613 		// There is a link which has same name
7614 		ReleaseLink(k);
7615 		ReleaseHub(h);
7616 		return ERR_LINK_ALREADY_EXISTS;
7617 	}
7618 
7619 	ALog(a, h, "LA_CREATE_LINK", t->ClientOption->AccountName);
7620 
7621 	// Create a new link
7622 	k = NewLink(c, h, t->ClientOption, t->ClientAuth, &t->Policy);
7623 
7624 	if (k == NULL)
7625 	{
7626 		// Link creation failed
7627 		ret = ERR_INTERNAL_ERROR;
7628 	}
7629 	else
7630 	{
7631 		// setting of verifying server certification
7632 		//
7633 		k->CheckServerCert = t->CheckServerCert;
7634 		k->ServerCert = CloneX(t->ServerCert);
7635 
7636 		// stay this off-line
7637 		k->Offline = false;
7638 		SetLinkOffline(k);
7639 		ReleaseLink(k);
7640 
7641 		IncrementServerConfigRevision(s);
7642 	}
7643 
7644 	ReleaseHub(h);
7645 
7646 	return ret;
7647 }
7648 
7649 // Delete a CA(Certificate Authority) setting from the hub
StDeleteCa(ADMIN * a,RPC_HUB_DELETE_CA * t)7650 UINT StDeleteCa(ADMIN *a, RPC_HUB_DELETE_CA *t)
7651 {
7652 	SERVER *s = a->Server;
7653 	CEDAR *c = s->Cedar;
7654 	HUB *h;
7655 	UINT ret = ERR_NO_ERROR;
7656 
7657 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
7658 	{
7659 		return ERR_NOT_FARM_CONTROLLER;
7660 	}
7661 
7662 	NO_SUPPORT_FOR_BRIDGE;
7663 	CHECK_RIGHT;
7664 
7665 	LockHubList(c);
7666 	{
7667 		h = GetHub(c, t->HubName);
7668 	}
7669 	UnlockHubList(c);
7670 
7671 	if (h == NULL)
7672 	{
7673 		return ERR_HUB_NOT_FOUND;
7674 	}
7675 
7676 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_cert_list") != 0)
7677 	{
7678 		ReleaseHub(h);
7679 		return ERR_NOT_ENOUGH_RIGHT;
7680 	}
7681 
7682 	LockList(h->HubDb->RootCertList);
7683 	{
7684 		if (IsInListKey(h->HubDb->RootCertList, t->Key))
7685 		{
7686 			X *x = ListKeyToPointer(h->HubDb->RootCertList, t->Key);
7687 			Delete(h->HubDb->RootCertList, x);
7688 			FreeX(x);
7689 
7690 			ALog(a, h, "LA_DELETE_CA");
7691 
7692 			IncrementServerConfigRevision(s);
7693 		}
7694 		else
7695 		{
7696 			ret = ERR_OBJECT_NOT_FOUND;
7697 		}
7698 	}
7699 	UnlockList(h->HubDb->RootCertList);
7700 
7701 	ReleaseHub(h);
7702 
7703 	return ret;
7704 }
7705 
7706 // Get CA(Certificate Authority) setting from the hub
StGetCa(ADMIN * a,RPC_HUB_GET_CA * t)7707 UINT StGetCa(ADMIN *a, RPC_HUB_GET_CA *t)
7708 {
7709 	SERVER *s = a->Server;
7710 	CEDAR *c = s->Cedar;
7711 	HUB *h;
7712 	UINT ret = ERR_NO_ERROR;
7713 	char hubname[MAX_HUBNAME_LEN + 1];
7714 	UINT key;
7715 
7716 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
7717 	{
7718 		return ERR_NOT_FARM_CONTROLLER;
7719 	}
7720 
7721 	NO_SUPPORT_FOR_BRIDGE;
7722 
7723 	StrCpy(hubname, sizeof(hubname), t->HubName);
7724 	key = t->Key;
7725 
7726 	FreeRpcHubGetCa(t);
7727 	Zero(t, sizeof(RPC_HUB_GET_CA));
7728 	t->Key = key;
7729 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
7730 
7731 	CHECK_RIGHT;
7732 
7733 	LockHubList(c);
7734 	{
7735 		h = GetHub(c, t->HubName);
7736 	}
7737 	UnlockHubList(c);
7738 
7739 	if (h == NULL)
7740 	{
7741 		return ERR_HUB_NOT_FOUND;
7742 	}
7743 
7744 	LockList(h->HubDb->RootCertList);
7745 	{
7746 		if (IsInListKey(h->HubDb->RootCertList, key))
7747 		{
7748 			X *x = ListKeyToPointer(h->HubDb->RootCertList, key);
7749 
7750 			t->Cert = CloneX(x);
7751 		}
7752 		else
7753 		{
7754 			ret = ERR_OBJECT_NOT_FOUND;
7755 		}
7756 	}
7757 	UnlockList(h->HubDb->RootCertList);
7758 
7759 	ReleaseHub(h);
7760 
7761 	return ret;
7762 }
7763 
7764 // Enumerate CA(Certificate Authority) in the hub
StEnumCa(ADMIN * a,RPC_HUB_ENUM_CA * t)7765 UINT StEnumCa(ADMIN *a, RPC_HUB_ENUM_CA *t)
7766 {
7767 	SERVER *s = a->Server;
7768 	CEDAR *c = s->Cedar;
7769 	HUB *h;
7770 	char hubname[MAX_HUBNAME_LEN + 1];
7771 	UINT i;
7772 
7773 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
7774 	{
7775 		return ERR_NOT_FARM_CONTROLLER;
7776 	}
7777 
7778 	NO_SUPPORT_FOR_BRIDGE;
7779 
7780 	StrCpy(hubname, sizeof(hubname), t->HubName);
7781 
7782 	FreeRpcHubEnumCa(t);
7783 	Zero(t, sizeof(RPC_HUB_ENUM_CA));
7784 
7785 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
7786 	CHECK_RIGHT;
7787 
7788 	LockHubList(c);
7789 	{
7790 		h = GetHub(c, hubname);
7791 	}
7792 	UnlockHubList(c);
7793 
7794 	if (h == NULL)
7795 	{
7796 		return ERR_HUB_NOT_FOUND;
7797 	}
7798 
7799 	Zero(t, sizeof(RPC_HUB_ENUM_CA));
7800 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
7801 
7802 	if (h->HubDb->RootCertList != NULL)
7803 	{
7804 		LockList(h->HubDb->RootCertList);
7805 		{
7806 			t->NumCa = LIST_NUM(h->HubDb->RootCertList);
7807 			t->Ca = ZeroMalloc(sizeof(RPC_HUB_ENUM_CA_ITEM) * t->NumCa);
7808 
7809 			for (i = 0;i < t->NumCa;i++)
7810 			{
7811 				RPC_HUB_ENUM_CA_ITEM *e = &t->Ca[i];
7812 				X *x = LIST_DATA(h->HubDb->RootCertList, i);
7813 
7814 				e->Key = POINTER_TO_KEY(x);
7815 				GetAllNameFromNameEx(e->SubjectName, sizeof(e->SubjectName), x->subject_name);
7816 				GetAllNameFromNameEx(e->IssuerName, sizeof(e->IssuerName), x->issuer_name);
7817 				e->Expires = x->notAfter;
7818 			}
7819 		}
7820 		UnlockList(h->HubDb->RootCertList);
7821 	}
7822 
7823 	ReleaseHub(h);
7824 
7825 	return ERR_NO_ERROR;
7826 }
7827 
7828 // Add CA(Certificate Authority) into the hub
StAddCa(ADMIN * a,RPC_HUB_ADD_CA * t)7829 UINT StAddCa(ADMIN *a, RPC_HUB_ADD_CA *t)
7830 {
7831 	SERVER *s = a->Server;
7832 	CEDAR *c = s->Cedar;
7833 	HUB *h;
7834 
7835 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
7836 	{
7837 		return ERR_NOT_FARM_CONTROLLER;
7838 	}
7839 
7840 	if (c->Bridge)
7841 	{
7842 		return ERR_NOT_SUPPORTED;
7843 	}
7844 
7845 	if (t->Cert == NULL)
7846 	{
7847 		return ERR_INVALID_PARAMETER;
7848 	}
7849 
7850 	if (t->Cert->is_compatible_bit == false)
7851 	{
7852 		return ERR_NOT_RSA_1024;
7853 	}
7854 
7855 	CHECK_RIGHT;
7856 
7857 	LockHubList(c);
7858 	{
7859 		h = GetHub(c, t->HubName);
7860 	}
7861 	UnlockHubList(c);
7862 
7863 	if (h == NULL)
7864 	{
7865 		return ERR_HUB_NOT_FOUND;
7866 	}
7867 
7868 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_cert_list") != 0)
7869 	{
7870 		ReleaseHub(h);
7871 		return ERR_NOT_ENOUGH_RIGHT;
7872 	}
7873 
7874 	IncrementServerConfigRevision(s);
7875 
7876 	ALog(a, h, "LA_ADD_CA");
7877 
7878 	AddRootCert(h, t->Cert);
7879 
7880 	ReleaseHub(h);
7881 
7882 	return ERR_NO_ERROR;
7883 }
7884 
7885 // Get logging configuration of the hub
StGetHubLog(ADMIN * a,RPC_HUB_LOG * t)7886 UINT StGetHubLog(ADMIN *a, RPC_HUB_LOG *t)
7887 {
7888 	SERVER *s = a->Server;
7889 	CEDAR *c = s->Cedar;
7890 	HUB *h;
7891 
7892 	CHECK_RIGHT;
7893 
7894 	LockHubList(c);
7895 	{
7896 		h = GetHub(c, t->HubName);
7897 	}
7898 	UnlockHubList(c);
7899 
7900 	if (h == NULL)
7901 	{
7902 		return ERR_HUB_NOT_FOUND;
7903 	}
7904 
7905 	GetHubLogSetting(h, &t->LogSetting);
7906 
7907 	ReleaseHub(h);
7908 
7909 	return ERR_NO_ERROR;
7910 }
7911 
7912 // Set logging configuration into the hub
StSetHubLog(ADMIN * a,RPC_HUB_LOG * t)7913 UINT StSetHubLog(ADMIN *a, RPC_HUB_LOG *t)
7914 {
7915 	SERVER *s = a->Server;
7916 	CEDAR *c = s->Cedar;
7917 	HUB *h;
7918 
7919 	CHECK_RIGHT;
7920 
7921 
7922 	LockHubList(c);
7923 	{
7924 		h = GetHub(c, t->HubName);
7925 	}
7926 	UnlockHubList(c);
7927 
7928 	if (h == NULL)
7929 	{
7930 		return ERR_HUB_NOT_FOUND;
7931 	}
7932 
7933 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_log_config") != 0)
7934 	{
7935 		ReleaseHub(h);
7936 		return ERR_NOT_ENOUGH_RIGHT;
7937 	}
7938 
7939 	ALog(a, h, "LA_SET_HUB_LOG");
7940 
7941 	SetHubLogSettingEx(h, &t->LogSetting,
7942 		(a->ServerAdmin == false && GetHubAdminOption(h, "no_change_log_switch_type") != 0));
7943 
7944 	h->CurrentVersion++;
7945 	SiHubUpdateProc(h);
7946 
7947 	ReleaseHub(h);
7948 
7949 	IncrementServerConfigRevision(s);
7950 
7951 	return ERR_NO_ERROR;
7952 }
7953 
7954 // Get hub status
StGetHubStatus(ADMIN * a,RPC_HUB_STATUS * t)7955 UINT StGetHubStatus(ADMIN *a, RPC_HUB_STATUS *t)
7956 {
7957 	SERVER *s = a->Server;
7958 	CEDAR *c = s->Cedar;
7959 	HUB *h;
7960 
7961 	CHECK_RIGHT;
7962 
7963 	LockHubList(c);
7964 	{
7965 		h = GetHub(c, t->HubName);
7966 	}
7967 	UnlockHubList(c);
7968 
7969 	if (h == NULL)
7970 	{
7971 		return ERR_HUB_NOT_FOUND;
7972 	}
7973 
7974 	Zero(t, sizeof(RPC_HUB_STATUS));
7975 
7976 	Lock(h->lock);
7977 	{
7978 		StrCpy(t->HubName, sizeof(t->HubName), h->Name);
7979 		t->HubType = h->Type;
7980 		t->Online = h->Offline ? false : true;
7981 		t->NumSessions = LIST_NUM(h->SessionList);
7982 		t->NumSessionsClient = Count(h->NumSessionsClient);
7983 		t->NumSessionsBridge = Count(h->NumSessionsBridge);
7984 		t->NumAccessLists = LIST_NUM(h->AccessList);
7985 
7986 		if (h->HubDb != NULL)
7987 		{
7988 			t->NumUsers = LIST_NUM(h->HubDb->UserList);
7989 			t->NumGroups = LIST_NUM(h->HubDb->GroupList);
7990 		}
7991 
7992 		t->NumMacTables = HASH_LIST_NUM(h->MacHashTable);
7993 		t->NumIpTables = LIST_NUM(h->IpTable);
7994 
7995 		Lock(h->TrafficLock);
7996 		{
7997 			Copy(&t->Traffic, h->Traffic, sizeof(TRAFFIC));
7998 		}
7999 		Unlock(h->TrafficLock);
8000 
8001 		t->NumLogin = h->NumLogin;
8002 		t->LastCommTime = h->LastCommTime;
8003 		t->LastLoginTime = h->LastLoginTime;
8004 		t->CreatedTime = h->CreatedTime;
8005 	}
8006 	Unlock(h->lock);
8007 
8008 	if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
8009 	{
8010 		UINT i;
8011 		LockList(s->FarmMemberList);
8012 		{
8013 			for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
8014 			{
8015 				UINT k;
8016 				FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
8017 
8018 				if (f->Me == false)
8019 				{
8020 					LockList(f->HubList);
8021 					{
8022 						for (k = 0;k < LIST_NUM(f->HubList);k++)
8023 						{
8024 							HUB_LIST *h = LIST_DATA(f->HubList, k);
8025 
8026 							if (StrCmpi(h->Name, t->HubName) == 0)
8027 							{
8028 								t->NumSessions += h->NumSessions;
8029 								t->NumSessionsClient += h->NumSessionsClient;
8030 								t->NumSessionsBridge += h->NumSessionsBridge;
8031 								t->NumMacTables += h->NumMacTables;
8032 								t->NumIpTables += h->NumIpTables;
8033 							}
8034 						}
8035 					}
8036 					UnlockList(f->HubList);
8037 				}
8038 			}
8039 		}
8040 		UnlockList(s->FarmMemberList);
8041 	}
8042 
8043 	if (h->Type != HUB_TYPE_FARM_STATIC)
8044 	{
8045 		t->SecureNATEnabled = h->EnableSecureNAT;
8046 	}
8047 
8048 	ReleaseHub(h);
8049 
8050 	return ERR_NO_ERROR;
8051 }
8052 
8053 // Enable SecureNAT function of the hub
StEnableSecureNAT(ADMIN * a,RPC_HUB * t)8054 UINT StEnableSecureNAT(ADMIN *a, RPC_HUB *t)
8055 {
8056 	SERVER *s = a->Server;
8057 	CEDAR *c = s->Cedar;
8058 	HUB *h;
8059 
8060 	CHECK_RIGHT;
8061 
8062 
8063 	LockHubList(c);
8064 	{
8065 		h = GetHub(c, t->HubName);
8066 	}
8067 	UnlockHubList(c);
8068 
8069 	if (h == NULL)
8070 	{
8071 		return ERR_HUB_NOT_FOUND;
8072 	}
8073 
8074 	if (h->Type == HUB_TYPE_FARM_STATIC || GetServerCapsBool(s, "b_support_securenat") == false)
8075 	{
8076 		ReleaseHub(h);
8077 		return ERR_NOT_SUPPORTED;
8078 	}
8079 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
8080 	{
8081 		ReleaseHub(h);
8082 		return ERR_NOT_FARM_CONTROLLER;
8083 	}
8084 
8085 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_securenat") != 0)
8086 	{
8087 		ReleaseHub(h);
8088 		return ERR_NOT_ENOUGH_RIGHT;
8089 	}
8090 
8091 	ALog(a, h, "LA_ENABLE_SNAT");
8092 
8093 	EnableSecureNAT(h, true);
8094 
8095 	h->CurrentVersion++;
8096 	SiHubUpdateProc(h);
8097 
8098 	IncrementServerConfigRevision(s);
8099 
8100 	ReleaseHub(h);
8101 
8102 	return ERR_NO_ERROR;
8103 }
8104 
8105 // Disable the SecureNAT function of the hub
StDisableSecureNAT(ADMIN * a,RPC_HUB * t)8106 UINT StDisableSecureNAT(ADMIN *a, RPC_HUB *t)
8107 {
8108 	SERVER *s = a->Server;
8109 	CEDAR *c = s->Cedar;
8110 	HUB *h;
8111 
8112 	CHECK_RIGHT;
8113 
8114 
8115 	LockHubList(c);
8116 	{
8117 		h = GetHub(c, t->HubName);
8118 	}
8119 	UnlockHubList(c);
8120 
8121 	if (h == NULL)
8122 	{
8123 		return ERR_HUB_NOT_FOUND;
8124 	}
8125 
8126 	if (h->Type == HUB_TYPE_FARM_STATIC || GetServerCapsBool(s, "b_support_securenat") == false)
8127 	{
8128 		ReleaseHub(h);
8129 		return ERR_NOT_SUPPORTED;
8130 	}
8131 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
8132 	{
8133 		ReleaseHub(h);
8134 		return ERR_NOT_FARM_CONTROLLER;
8135 	}
8136 
8137 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_securenat") != 0)
8138 	{
8139 		ReleaseHub(h);
8140 		return ERR_NOT_ENOUGH_RIGHT;
8141 	}
8142 
8143 	ALog(a, h, "LA_DISABLE_SNAT");
8144 
8145 	EnableSecureNAT(h, false);
8146 
8147 	h->CurrentVersion++;
8148 	SiHubUpdateProc(h);
8149 
8150 	IncrementServerConfigRevision(s);
8151 
8152 	ReleaseHub(h);
8153 
8154 	return ERR_NO_ERROR;
8155 }
8156 
8157 // Enumerate NAT entries of the SecureNAT
StEnumNAT(ADMIN * a,RPC_ENUM_NAT * t)8158 UINT StEnumNAT(ADMIN *a, RPC_ENUM_NAT *t)
8159 {
8160 	SERVER *s = a->Server;
8161 	CEDAR *c = s->Cedar;
8162 	HUB *h;
8163 	UINT ret = ERR_NO_ERROR;
8164 	char hubname[MAX_HUBNAME_LEN + 1];
8165 	UINT i;
8166 
8167 	CHECK_RIGHT;
8168 
8169 	StrCpy(hubname, sizeof(hubname), t->HubName);
8170 
8171 	LockHubList(c);
8172 	{
8173 		h = GetHub(c, t->HubName);
8174 	}
8175 	UnlockHubList(c);
8176 
8177 	if (h == NULL)
8178 	{
8179 		return ERR_HUB_NOT_FOUND;
8180 	}
8181 
8182 	if (h->Type == HUB_TYPE_FARM_STATIC || GetServerCapsBool(s, "b_support_securenat") == false)
8183 	{
8184 		ReleaseHub(h);
8185 		return ERR_NOT_SUPPORTED;
8186 	}
8187 
8188 	Lock(h->lock_online);
8189 	{
8190 		if (h->SecureNAT == NULL)
8191 		{
8192 			ret = ERR_SNAT_NOT_RUNNING;
8193 		}
8194 		else
8195 		{
8196 			NtEnumNatList(h->SecureNAT->Nat, t);
8197 		}
8198 	}
8199 	Unlock(h->lock_online);
8200 
8201 	if (h->Type == HUB_TYPE_FARM_DYNAMIC)
8202 	{
8203 		if (ret == ERR_SNAT_NOT_RUNNING)
8204 		{
8205 			// Get status of remote SecureNAT
8206 			LockList(s->FarmMemberList);
8207 			{
8208 				for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
8209 				{
8210 					FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
8211 					if (f->Me == false)
8212 					{
8213 						RPC_ENUM_NAT tmp;
8214 
8215 						Zero(&tmp, sizeof(tmp));
8216 
8217 						SiCallEnumNat(s, f, hubname, &tmp);
8218 
8219 						if (tmp.NumItem >= 1)
8220 						{
8221 							FreeRpcEnumNat(t);
8222 							Copy(t, &tmp, sizeof(RPC_ENUM_NAT));
8223 							ret = ERR_NO_ERROR;
8224 							break;
8225 						}
8226 						else
8227 						{
8228 							FreeRpcEnumNat(&tmp);
8229 						}
8230 					}
8231 				}
8232 			}
8233 			UnlockList(s->FarmMemberList);
8234 		}
8235 	}
8236 
8237 	ReleaseHub(h);
8238 
8239 	ret = ERR_NO_ERROR;
8240 
8241 	return ret;
8242 }
8243 
8244 // Get status of the SecureNAT
StGetSecureNATStatus(ADMIN * a,RPC_NAT_STATUS * t)8245 UINT StGetSecureNATStatus(ADMIN *a, RPC_NAT_STATUS *t)
8246 {
8247 	SERVER *s = a->Server;
8248 	CEDAR *c = s->Cedar;
8249 	HUB *h;
8250 	UINT ret = ERR_NO_ERROR;
8251 	char hubname[MAX_HUBNAME_LEN + 1];
8252 	UINT i;
8253 
8254 	CHECK_RIGHT;
8255 
8256 	StrCpy(hubname, sizeof(hubname), t->HubName);
8257 
8258 	LockHubList(c);
8259 	{
8260 		h = GetHub(c, t->HubName);
8261 	}
8262 	UnlockHubList(c);
8263 
8264 	if (h == NULL)
8265 	{
8266 		return ERR_HUB_NOT_FOUND;
8267 	}
8268 
8269 	if (h->Type == HUB_TYPE_FARM_STATIC || GetServerCapsBool(s, "b_support_securenat") == false)
8270 	{
8271 		ReleaseHub(h);
8272 		return ERR_NOT_SUPPORTED;
8273 	}
8274 
8275 	Lock(h->lock_online);
8276 	{
8277 		if (h->SecureNAT == NULL)
8278 		{
8279 			ret = ERR_SNAT_NOT_RUNNING;
8280 		}
8281 		else
8282 		{
8283 			NtGetStatus(h->SecureNAT->Nat, t);
8284 		}
8285 	}
8286 	Unlock(h->lock_online);
8287 
8288 	if (h->Type == HUB_TYPE_FARM_DYNAMIC)
8289 	{
8290 		if (ret == ERR_SNAT_NOT_RUNNING)
8291 		{
8292 			// Get status of remote secureNAT
8293 			LockList(s->FarmMemberList);
8294 			{
8295 				for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
8296 				{
8297 					FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
8298 					if (f->Me == false)
8299 					{
8300 						RPC_NAT_STATUS tmp;
8301 
8302 						Zero(&tmp, sizeof(tmp));
8303 
8304 						SiCallGetNatStatus(s, f, hubname, &tmp);
8305 
8306 						if (tmp.NumDhcpClients == 0 && tmp.NumTcpSessions == 0 && tmp.NumUdpSessions == 0)
8307 						{
8308 						}
8309 						else
8310 						{
8311 							Copy(t, &tmp, sizeof(RPC_NAT_STATUS));
8312 							ret = ERR_NO_ERROR;
8313 							break;
8314 						}
8315 					}
8316 				}
8317 			}
8318 			UnlockList(s->FarmMemberList);
8319 		}
8320 	}
8321 
8322 	ReleaseHub(h);
8323 
8324 	StrCpy(t->HubName, sizeof(t->HubName), hubname);
8325 	ret = ERR_NO_ERROR;
8326 
8327 	return ret;
8328 }
8329 
8330 // Enumerate DHCP entries
StEnumDHCP(ADMIN * a,RPC_ENUM_DHCP * t)8331 UINT StEnumDHCP(ADMIN *a, RPC_ENUM_DHCP *t)
8332 {
8333 	SERVER *s = a->Server;
8334 	CEDAR *c = s->Cedar;
8335 	HUB *h;
8336 	UINT ret = ERR_NO_ERROR;
8337 	char hubname[MAX_HUBNAME_LEN + 1];
8338 	UINT i;
8339 	StrCpy(hubname, sizeof(hubname), t->HubName);
8340 
8341 	CHECK_RIGHT;
8342 
8343 	LockHubList(c);
8344 	{
8345 		h = GetHub(c, t->HubName);
8346 	}
8347 	UnlockHubList(c);
8348 
8349 	if (h == NULL)
8350 	{
8351 		return ERR_HUB_NOT_FOUND;
8352 	}
8353 
8354 	if (h->Type == HUB_TYPE_FARM_STATIC || GetServerCapsBool(s, "b_support_securenat") == false)
8355 	{
8356 		ReleaseHub(h);
8357 		return ERR_NOT_SUPPORTED;
8358 	}
8359 
8360 	Lock(h->lock_online);
8361 	{
8362 		if (h->SecureNAT == NULL)
8363 		{
8364 			ret = ERR_SNAT_NOT_RUNNING;
8365 		}
8366 		else
8367 		{
8368 			NtEnumDhcpList(h->SecureNAT->Nat, t);
8369 		}
8370 	}
8371 	Unlock(h->lock_online);
8372 
8373 	if (h->Type == HUB_TYPE_FARM_DYNAMIC)
8374 	{
8375 		if (ret == ERR_SNAT_NOT_RUNNING)
8376 		{
8377 			// Get status of remote DHCP service
8378 			LockList(s->FarmMemberList);
8379 			{
8380 				for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
8381 				{
8382 					FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
8383 					if (f->Me == false)
8384 					{
8385 						RPC_ENUM_DHCP tmp;
8386 
8387 						Zero(&tmp, sizeof(tmp));
8388 
8389 						SiCallEnumDhcp(s, f, hubname, &tmp);
8390 
8391 						if (tmp.NumItem >= 1)
8392 						{
8393 							FreeRpcEnumDhcp(t);
8394 							Copy(t, &tmp, sizeof(RPC_ENUM_DHCP));
8395 							ret = ERR_NO_ERROR;
8396 							break;
8397 						}
8398 						else
8399 						{
8400 							FreeRpcEnumDhcp(&tmp);
8401 						}
8402 					}
8403 				}
8404 			}
8405 			UnlockList(s->FarmMemberList);
8406 		}
8407 	}
8408 
8409 	ReleaseHub(h);
8410 
8411 	ret = ERR_NO_ERROR;
8412 
8413 	return ret;
8414 }
8415 
8416 // Set SecureNAT options
StSetSecureNATOption(ADMIN * a,VH_OPTION * t)8417 UINT StSetSecureNATOption(ADMIN *a, VH_OPTION *t)
8418 {
8419 	SERVER *s = a->Server;
8420 	CEDAR *c = s->Cedar;
8421 	HUB *h;
8422 	char push_routes_str_old[MAX_DHCP_CLASSLESS_ROUTE_TABLE_STR_SIZE];
8423 
8424 
8425 	if (IsZero(t->MacAddress, sizeof(t->MacAddress)) ||
8426 		IsHostIPAddress4(&t->Ip) == false ||
8427 		IsSubnetMask4(&t->Mask) == false)
8428 	{
8429 		return ERR_INVALID_PARAMETER;
8430 	}
8431 	if ((IPToUINT(&t->Ip) & (~(IPToUINT(&t->Mask)))) == 0)
8432 	{
8433 		return ERR_INVALID_PARAMETER;
8434 	}
8435 	if (GetServerCapsBool(s, "b_support_securenat") == false)
8436 	{
8437 		t->ApplyDhcpPushRoutes = false;
8438 	}
8439 	if (t->ApplyDhcpPushRoutes)
8440 	{
8441 		if (NormalizeClasslessRouteTableStr(t->DhcpPushRoutes, sizeof(t->DhcpPushRoutes), t->DhcpPushRoutes) == false)
8442 		{
8443 			return ERR_INVALID_PARAMETER;
8444 		}
8445 	}
8446 
8447 	CHECK_RIGHT;
8448 
8449 	LockHubList(c);
8450 	{
8451 		h = GetHub(c, t->HubName);
8452 	}
8453 	UnlockHubList(c);
8454 
8455 	if (h == NULL)
8456 	{
8457 		return ERR_HUB_NOT_FOUND;
8458 	}
8459 
8460 	if (h->Type == HUB_TYPE_FARM_STATIC || GetServerCapsBool(s, "b_support_securenat") == false)
8461 	{
8462 		ReleaseHub(h);
8463 		return ERR_NOT_SUPPORTED;
8464 	}
8465 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
8466 	{
8467 		ReleaseHub(h);
8468 		return ERR_NOT_FARM_CONTROLLER;
8469 	}
8470 
8471 	if (a->ServerAdmin == false && GetHubAdminOption(h, "no_securenat") != 0)
8472 	{
8473 		ReleaseHub(h);
8474 		return ERR_NOT_ENOUGH_RIGHT;
8475 	}
8476 
8477 	if (h->SecureNATOption->UseNat == false && t->UseNat)
8478 	{
8479 		if (a->ServerAdmin == false && GetHubAdminOption(h, "no_securenat_enablenat") != 0)
8480 		{
8481 			ReleaseHub(h);
8482 			return ERR_NOT_ENOUGH_RIGHT;
8483 		}
8484 	}
8485 
8486 	if (h->SecureNATOption->UseDhcp == false && t->UseDhcp)
8487 	{
8488 		if (a->ServerAdmin == false && GetHubAdminOption(h, "no_securenat_enabledhcp") != 0)
8489 		{
8490 			ReleaseHub(h);
8491 			return ERR_NOT_ENOUGH_RIGHT;
8492 		}
8493 	}
8494 
8495 	StrCpy(push_routes_str_old, sizeof(push_routes_str_old), h->SecureNATOption->DhcpPushRoutes);
8496 	Copy(h->SecureNATOption, t, sizeof(VH_OPTION));
8497 	if (t->ApplyDhcpPushRoutes == false)
8498 	{
8499 		StrCpy(h->SecureNATOption->DhcpPushRoutes, sizeof(h->SecureNATOption->DhcpPushRoutes), push_routes_str_old);
8500 	}
8501 
8502 	if (h->Type != HUB_TYPE_STANDALONE && h->Cedar != NULL && h->Cedar->Server != NULL &&
8503 		h->Cedar->Server->ServerType == SERVER_TYPE_FARM_CONTROLLER)
8504 	{
8505 		NiClearUnsupportedVhOptionForDynamicHub(h->SecureNATOption, false);
8506 	}
8507 
8508 	Lock(h->lock_online);
8509 	{
8510 		if (h->SecureNAT != NULL)
8511 		{
8512 			SetVirtualHostOption(h->SecureNAT->Nat->Virtual, t);
8513 		}
8514 	}
8515 	Unlock(h->lock_online);
8516 
8517 	ALog(a, h, "LA_SET_SNAT_OPTION");
8518 
8519 	h->CurrentVersion++;
8520 	SiHubUpdateProc(h);
8521 
8522 	IncrementServerConfigRevision(s);
8523 
8524 	ReleaseHub(h);
8525 
8526 	return ERR_NO_ERROR;
8527 }
8528 
8529 // Get SecureNAT options
StGetSecureNATOption(ADMIN * a,VH_OPTION * t)8530 UINT StGetSecureNATOption(ADMIN *a, VH_OPTION *t)
8531 {
8532 	SERVER *s = a->Server;
8533 	CEDAR *c = s->Cedar;
8534 	HUB *h;
8535 	char hubname[MAX_HUBNAME_LEN + 1];
8536 
8537 	StrCpy(hubname, sizeof(hubname), t->HubName);
8538 
8539 	CHECK_RIGHT;
8540 
8541 	LockHubList(c);
8542 	{
8543 		h = GetHub(c, t->HubName);
8544 	}
8545 	UnlockHubList(c);
8546 
8547 	if (h == NULL)
8548 	{
8549 		return ERR_HUB_NOT_FOUND;
8550 	}
8551 
8552 	if (h->Type == HUB_TYPE_FARM_STATIC || GetServerCapsBool(s, "b_support_securenat") == false)
8553 	{
8554 		ReleaseHub(h);
8555 		return ERR_NOT_SUPPORTED;
8556 	}
8557 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
8558 	{
8559 		ReleaseHub(h);
8560 		return ERR_NOT_FARM_CONTROLLER;
8561 	}
8562 
8563 	Zero(t, sizeof(VH_OPTION));
8564 	Copy(t, h->SecureNATOption, sizeof(VH_OPTION));
8565 	StrCpy(t->HubName, sizeof(t->HubName), h->Name);
8566 	t->ApplyDhcpPushRoutes = true;
8567 
8568 	ReleaseHub(h);
8569 
8570 	return ERR_NO_ERROR;
8571 }
8572 
8573 // Make a hub on-line or off-line
StSetHubOnline(ADMIN * a,RPC_SET_HUB_ONLINE * t)8574 UINT StSetHubOnline(ADMIN *a, RPC_SET_HUB_ONLINE *t)
8575 {
8576 	SERVER *s = a->Server;
8577 	CEDAR *c = s->Cedar;
8578 	HUB *h;
8579 
8580 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
8581 	{
8582 		return ERR_NOT_FARM_CONTROLLER;
8583 	}
8584 
8585 
8586 	NO_SUPPORT_FOR_BRIDGE;
8587 
8588 	CHECK_RIGHT;
8589 
8590 	LockHubList(c);
8591 	{
8592 		h = GetHub(c, t->HubName);
8593 	}
8594 	UnlockHubList(c);
8595 
8596 	if (h == NULL)
8597 	{
8598 		return ERR_HUB_NOT_FOUND;
8599 	}
8600 
8601 	if (a->ServerAdmin == false && t->Online && GetHubAdminOption(h, "no_online") != 0)
8602 	{
8603 		ReleaseHub(h);
8604 		return ERR_NOT_ENOUGH_RIGHT;
8605 	}
8606 
8607 	if (a->ServerAdmin == false && t->Online == false && GetHubAdminOption(h, "no_offline") != 0)
8608 	{
8609 		ReleaseHub(h);
8610 		return ERR_NOT_ENOUGH_RIGHT;
8611 	}
8612 
8613 	if (t->Online)
8614 	{
8615 		ALog(a, h, "LA_SET_HUB_ONLINE");
8616 		SetHubOnline(h);
8617 	}
8618 	else
8619 	{
8620 		ALog(a, h, "LA_SET_HUB_OFFLINE");
8621 		SetHubOffline(h);
8622 	}
8623 
8624 	h->CurrentVersion++;
8625 	SiHubUpdateProc(h);
8626 
8627 	IncrementServerConfigRevision(s);
8628 
8629 	ReleaseHub(h);
8630 
8631 	return ERR_NO_ERROR;
8632 }
8633 
8634 // Get connection information
StGetConnectionInfo(ADMIN * a,RPC_CONNECTION_INFO * t)8635 UINT StGetConnectionInfo(ADMIN *a, RPC_CONNECTION_INFO *t)
8636 {
8637 	SERVER *s = a->Server;
8638 	CEDAR *c = s->Cedar;
8639 	CONNECTION *connection;
8640 	char name[MAX_CONNECTION_NAME_LEN + 1];
8641 
8642 	if (IsEmptyStr(t->Name))
8643 	{
8644 		return ERR_INVALID_PARAMETER;
8645 	}
8646 
8647 	SERVER_ADMIN_ONLY;
8648 
8649 	LockList(c->ConnectionList);
8650 	{
8651 		CONNECTION tt;
8652 		Zero(&tt, sizeof(tt));
8653 		tt.Name = t->Name;
8654 		StrCpy(name, sizeof(name), t->Name);
8655 
8656 		connection = Search(c->ConnectionList, &tt);
8657 
8658 		if (connection != NULL)
8659 		{
8660 			AddRef(connection->ref);
8661 		}
8662 	}
8663 	UnlockList(c->ConnectionList);
8664 
8665 	if (connection == NULL)
8666 	{
8667 		return ERR_OBJECT_NOT_FOUND;
8668 	}
8669 
8670 	Zero(t, sizeof(RPC_CONNECTION_INFO));
8671 	StrCpy(t->Name, sizeof(t->Name), name);
8672 
8673 	Lock(connection->lock);
8674 	{
8675 		SOCK *s = connection->FirstSock;
8676 
8677 		if (s != NULL)
8678 		{
8679 			t->Ip = IPToUINT(&s->RemoteIP);
8680 			t->Port = s->RemotePort;
8681 			StrCpy(t->Hostname, sizeof(t->Hostname), s->RemoteHostname);
8682 		}
8683 
8684 		StrCpy(t->Name, sizeof(t->Name), connection->Name);
8685 		t->ConnectedTime = TickToTime(connection->ConnectedTick);
8686 		t->Type = connection->Type;
8687 
8688 		StrCpy(t->ServerStr, sizeof(t->ServerStr), connection->ServerStr);
8689 		StrCpy(t->ClientStr, sizeof(t->ClientStr), connection->ClientStr);
8690 		t->ServerVer = connection->ServerVer;
8691 		t->ServerBuild = connection->ServerBuild;
8692 		t->ClientVer = connection->ClientVer;
8693 		t->ClientBuild = connection->ClientBuild;
8694 	}
8695 	Unlock(connection->lock);
8696 
8697 	ReleaseConnection(connection);
8698 
8699 	return ERR_NO_ERROR;
8700 }
8701 
8702 // Disconnect a connection
StDisconnectConnection(ADMIN * a,RPC_DISCONNECT_CONNECTION * t)8703 UINT StDisconnectConnection(ADMIN *a, RPC_DISCONNECT_CONNECTION *t)
8704 {
8705 	SERVER *s = a->Server;
8706 	CEDAR *c = s->Cedar;
8707 	CONNECTION *connection;
8708 
8709 	if (IsEmptyStr(t->Name))
8710 	{
8711 		return ERR_INVALID_PARAMETER;
8712 	}
8713 
8714 	SERVER_ADMIN_ONLY;
8715 
8716 	LockList(c->ConnectionList);
8717 	{
8718 		CONNECTION tt;
8719 		Zero(&tt, sizeof(tt));
8720 		tt.Name = t->Name;
8721 
8722 		connection = Search(c->ConnectionList, &tt);
8723 		if (connection != NULL)
8724 		{
8725 			AddRef(connection->ref);
8726 		}
8727 	}
8728 	UnlockList(c->ConnectionList);
8729 
8730 	if (connection == NULL)
8731 	{
8732 		return ERR_OBJECT_NOT_FOUND;
8733 	}
8734 
8735 	StopConnection(connection, true);
8736 
8737 	ReleaseConnection(connection);
8738 
8739 	ALog(a, NULL, "LA_DISCONNECT_CONN", t->Name);
8740 
8741 	return ERR_NO_ERROR;
8742 }
8743 
8744 // Enumerate connections
StEnumConnection(ADMIN * a,RPC_ENUM_CONNECTION * t)8745 UINT StEnumConnection(ADMIN *a, RPC_ENUM_CONNECTION *t)
8746 {
8747 	SERVER *s = a->Server;
8748 	CEDAR *c = s->Cedar;
8749 
8750 	SERVER_ADMIN_ONLY;
8751 
8752 	FreeRpcEnumConnection(t);
8753 	Zero(t, sizeof(RPC_ENUM_CONNECTION));
8754 
8755 	LockList(c->ConnectionList);
8756 	{
8757 		UINT i;
8758 		t->NumConnection = LIST_NUM(c->ConnectionList);
8759 		t->Connections = ZeroMalloc(sizeof(RPC_ENUM_CONNECTION_ITEM) * t->NumConnection);
8760 
8761 		for (i = 0;i < t->NumConnection;i++)
8762 		{
8763 			RPC_ENUM_CONNECTION_ITEM *e = &t->Connections[i];
8764 			CONNECTION *connection = LIST_DATA(c->ConnectionList, i);
8765 
8766 			Lock(connection->lock);
8767 			{
8768 				SOCK *s = connection->FirstSock;
8769 
8770 				if (s != NULL)
8771 				{
8772 					e->Ip = IPToUINT(&s->RemoteIP);
8773 					e->Port = s->RemotePort;
8774 					StrCpy(e->Hostname, sizeof(e->Hostname), s->RemoteHostname);
8775 				}
8776 
8777 				StrCpy(e->Name, sizeof(e->Name), connection->Name);
8778 				e->ConnectedTime = TickToTime(connection->ConnectedTick);
8779 				e->Type = connection->Type;
8780 			}
8781 			Unlock(connection->lock);
8782 		}
8783 	}
8784 	UnlockList(c->ConnectionList);
8785 
8786 	return ERR_NO_ERROR;
8787 }
8788 
8789 // Set Radius options of the hub
StSetHubRadius(ADMIN * a,RPC_RADIUS * t)8790 UINT StSetHubRadius(ADMIN *a, RPC_RADIUS *t)
8791 {
8792 	SERVER *s = a->Server;
8793 	CEDAR *c = s->Cedar;
8794 	HUB *h = NULL;
8795 
8796 	NO_SUPPORT_FOR_BRIDGE;
8797 
8798 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
8799 	{
8800 		return ERR_NOT_SUPPORTED;
8801 	}
8802 
8803 	if (GetGlobalServerFlag(GSF_DISABLE_RADIUS_AUTH) != 0 && IsEmptyStr(t->RadiusServerName) == false)
8804 	{
8805 		return ERR_NOT_SUPPORTED_FUNCTION_ON_OPENSOURCE;
8806 	}
8807 
8808 	CHECK_RIGHT;
8809 
8810 	LockHubList(c);
8811 	{
8812 		h = GetHub(c, t->HubName);
8813 	}
8814 	UnlockHubList(c);
8815 
8816 	if (h == NULL)
8817 	{
8818 		return ERR_HUB_NOT_FOUND;
8819 	}
8820 
8821 	//SetRadiusServer(h, t->RadiusServerName, t->RadiusPort, t->RadiusSecret);
8822 	SetRadiusServerEx(h, t->RadiusServerName, t->RadiusPort, t->RadiusSecret, t->RadiusRetryInterval);
8823 
8824 	ALog(a, h, "LA_SET_HUB_RADIUS");
8825 
8826 	ReleaseHub(h);
8827 
8828 	IncrementServerConfigRevision(s);
8829 
8830 	return ERR_NO_ERROR;
8831 }
8832 
8833 // Get Radius options of the hub
StGetHubRadius(ADMIN * a,RPC_RADIUS * t)8834 UINT StGetHubRadius(ADMIN *a, RPC_RADIUS *t)
8835 {
8836 	SERVER *s = a->Server;
8837 	CEDAR *c = s->Cedar;
8838 	HUB *h = NULL;
8839 
8840 	CHECK_RIGHT;
8841 
8842 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
8843 	{
8844 		return ERR_NOT_SUPPORTED;
8845 	}
8846 
8847 	LockHubList(c);
8848 	{
8849 		h = GetHub(c, t->HubName);
8850 	}
8851 	UnlockHubList(c);
8852 
8853 	if (h == NULL)
8854 	{
8855 		return ERR_HUB_NOT_FOUND;
8856 	}
8857 
8858 	Zero(t, sizeof(RPC_RADIUS));
8859 	//GetRadiusServer(h, t->RadiusServerName, sizeof(t->RadiusServerName),
8860 	//	&t->RadiusPort, t->RadiusSecret, sizeof(t->RadiusSecret));
8861 	GetRadiusServerEx(h, t->RadiusServerName, sizeof(t->RadiusServerName),
8862 		&t->RadiusPort, t->RadiusSecret, sizeof(t->RadiusSecret), &t->RadiusRetryInterval);
8863 
8864 	ReleaseHub(h);
8865 
8866 	return ERR_NO_ERROR;
8867 }
8868 
8869 // Delete a hub
StDeleteHub(ADMIN * a,RPC_DELETE_HUB * t)8870 UINT StDeleteHub(ADMIN *a, RPC_DELETE_HUB *t)
8871 {
8872 	SERVER *s = a->Server;
8873 	CEDAR *c = s->Cedar;
8874 	HUB *h = NULL;
8875 
8876 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
8877 	{
8878 		return ERR_NOT_FARM_CONTROLLER;
8879 	}
8880 
8881 
8882 	if (IsEmptyStr(t->HubName) || IsSafeStr(t->HubName) == false)
8883 	{
8884 		return ERR_INVALID_PARAMETER;
8885 	}
8886 
8887 	NO_SUPPORT_FOR_BRIDGE;
8888 
8889 	SERVER_ADMIN_ONLY;
8890 
8891 	LockHubList(c);
8892 	{
8893 		h = GetHub(c, t->HubName);
8894 	}
8895 	UnlockHubList(c);
8896 
8897 	if (h == NULL)
8898 	{
8899 		return ERR_HUB_NOT_FOUND;
8900 	}
8901 
8902 	StopHub(h);
8903 
8904 	IncrementServerConfigRevision(s);
8905 
8906 	DelHub(c, h);
8907 	ReleaseHub(h);
8908 
8909 	ALog(a, NULL, "LA_DELETE_HUB", t->HubName);
8910 
8911 	return ERR_NO_ERROR;
8912 }
8913 
8914 // Enumerate hubs
StEnumHub(ADMIN * a,RPC_ENUM_HUB * t)8915 UINT StEnumHub(ADMIN *a, RPC_ENUM_HUB *t)
8916 {
8917 	SERVER *s = a->Server;
8918 	CEDAR *c = s->Cedar;
8919 	HUB *h = NULL;
8920 
8921 	FreeRpcEnumHub(t);
8922 
8923 	Zero(t, sizeof(RPC_ENUM_HUB));
8924 
8925 	LockHubList(c);
8926 	{
8927 		UINT i, num, j;
8928 
8929 		num = 0;
8930 
8931 		for (i = 0;i < LIST_NUM(c->HubList);i++)
8932 		{
8933 			HUB *h = LIST_DATA(c->HubList, i);
8934 
8935 			Lock(h->lock);
8936 
8937 			if (a->ServerAdmin == false &&
8938 				h->Option != NULL &&
8939 				StrCmpi(h->Name, a->HubName) != 0)
8940 			{
8941 				// This hub is not listed
8942 			}
8943 			else
8944 			{
8945 				// This hub is listed
8946 				num++;
8947 			}
8948 		}
8949 
8950 		t->NumHub = num;
8951 
8952 		t->Hubs = ZeroMalloc(sizeof(RPC_ENUM_HUB_ITEM) * num);
8953 
8954 		i = 0;
8955 		for (j = 0;j < LIST_NUM(c->HubList);j++)
8956 		{
8957 			HUB *h = LIST_DATA(c->HubList, j);
8958 
8959 			if (a->ServerAdmin == false &&
8960 				h->Option != NULL &&
8961 				StrCmpi(h->Name, a->HubName) != 0)
8962 			{
8963 				// This hub is not listed
8964 			}
8965 			else
8966 			{
8967 				// This hub is listed
8968 				RPC_ENUM_HUB_ITEM *e = &t->Hubs[i++];
8969 
8970 				StrCpy(e->HubName, sizeof(e->HubName), h->Name);
8971 				e->Online = h->Offline ? false : true;
8972 				e->HubType = h->Type;
8973 
8974 				e->NumSessions = LIST_NUM(h->SessionList);
8975 
8976 				LockHashList(h->MacHashTable);
8977 				{
8978 					e->NumMacTables = HASH_LIST_NUM(h->MacHashTable);
8979 				}
8980 				UnlockHashList(h->MacHashTable);
8981 
8982 				LockList(h->IpTable);
8983 				{
8984 					e->NumIpTables = LIST_NUM(h->IpTable);
8985 				}
8986 				UnlockList(h->IpTable);
8987 
8988 				if (h->HubDb != NULL)
8989 				{
8990 					LockList(h->HubDb->UserList);
8991 					{
8992 						e->NumUsers = LIST_NUM(h->HubDb->UserList);
8993 					}
8994 					UnlockList(h->HubDb->UserList);
8995 
8996 					LockList(h->HubDb->GroupList);
8997 					{
8998 						e->NumGroups = LIST_NUM(h->HubDb->GroupList);
8999 					}
9000 					UnlockList(h->HubDb->GroupList);
9001 				}
9002 
9003 				e->LastCommTime = h->LastCommTime;
9004 				e->LastLoginTime = h->LastLoginTime;
9005 				e->NumLogin = h->NumLogin;
9006 				e->CreatedTime = h->CreatedTime;
9007 
9008 				Lock(h->TrafficLock);
9009 				{
9010 					Copy(&e->Traffic, h->Traffic, sizeof(TRAFFIC));
9011 				}
9012 				Unlock(h->TrafficLock);
9013 
9014 				e->IsTrafficFilled = true;
9015 			}
9016 
9017 			Unlock(h->lock);
9018 		}
9019 	}
9020 	UnlockHubList(c);
9021 
9022 	if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
9023 	{
9024 		UINT i, j, k;
9025 		LockList(s->FarmMemberList);
9026 		{
9027 			for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
9028 			{
9029 				FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
9030 
9031 				LockList(f->HubList);
9032 				{
9033 					if (f->Me == false)
9034 					{
9035 						for (j = 0;j < LIST_NUM(f->HubList);j++)
9036 						{
9037 							HUB_LIST *o = LIST_DATA(f->HubList, j);
9038 
9039 							for (k = 0;k < t->NumHub;k++)
9040 							{
9041 								RPC_ENUM_HUB_ITEM *e = &t->Hubs[k];
9042 
9043 								if (StrCmpi(e->HubName, o->Name) == 0)
9044 								{
9045 									e->NumIpTables += o->NumIpTables;
9046 									e->NumMacTables += o->NumMacTables;
9047 									e->NumSessions += o->NumSessions;
9048 								}
9049 							}
9050 						}
9051 					}
9052 				}
9053 				UnlockList(f->HubList);
9054 			}
9055 		}
9056 		UnlockList(s->FarmMemberList);
9057 	}
9058 
9059 	return ERR_NO_ERROR;
9060 }
9061 
9062 // Get hub configuration
StGetHub(ADMIN * a,RPC_CREATE_HUB * t)9063 UINT StGetHub(ADMIN *a, RPC_CREATE_HUB *t)
9064 {
9065 	SERVER *s = a->Server;
9066 	CEDAR *c = s->Cedar;
9067 	UINT ret = ERR_NO_ERROR;
9068 	HUB *h;
9069 
9070 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
9071 	{
9072 		return ERR_NOT_FARM_CONTROLLER;
9073 	}
9074 
9075 	if (IsEmptyStr(t->HubName) || IsSafeStr(t->HubName) == false)
9076 	{
9077 		return ERR_INVALID_PARAMETER;
9078 	}
9079 
9080 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
9081 	{
9082 		return ERR_NOT_FARM_CONTROLLER;
9083 	}
9084 
9085 	NO_SUPPORT_FOR_BRIDGE;
9086 	CHECK_RIGHT;
9087 
9088 	LockHubList(c);
9089 	{
9090 		h = GetHub(c, t->HubName);
9091 	}
9092 	UnlockHubList(c);
9093 
9094 	Zero(t, sizeof(RPC_CREATE_HUB));
9095 
9096 	if (h == NULL)
9097 	{
9098 		return ERR_HUB_NOT_FOUND;
9099 	}
9100 
9101 	Lock(h->lock);
9102 	{
9103 		StrCpy(t->HubName, sizeof(t->HubName), h->Name);
9104 		t->Online = h->Offline ? false : true;
9105 		t->HubType = h->Type;
9106 
9107 		t->HubOption.DefaultGateway = h->Option->DefaultGateway;
9108 		t->HubOption.DefaultSubnet = h->Option->DefaultSubnet;
9109 		t->HubOption.MaxSession = h->Option->MaxSession;
9110 		t->HubOption.NoEnum = h->Option->NoEnum;
9111 	}
9112 	Unlock(h->lock);
9113 
9114 	ReleaseHub(h);
9115 
9116 	return ret;
9117 }
9118 
9119 // Set hub configuration
StSetHub(ADMIN * a,RPC_CREATE_HUB * t)9120 UINT StSetHub(ADMIN *a, RPC_CREATE_HUB *t)
9121 {
9122 	SERVER *s = a->Server;
9123 	CEDAR *c = s->Cedar;
9124 	HUB *h;
9125 	UINT ret = ERR_NO_ERROR;
9126 
9127 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
9128 	{
9129 		return ERR_NOT_FARM_CONTROLLER;
9130 	}
9131 
9132 	if (IsEmptyStr(t->HubName) || IsSafeStr(t->HubName) == false)
9133 	{
9134 		return ERR_INVALID_PARAMETER;
9135 	}
9136 
9137 	CHECK_RIGHT;
9138 	NO_SUPPORT_FOR_BRIDGE;
9139 
9140 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
9141 	{
9142 		return ERR_NOT_FARM_CONTROLLER;
9143 	}
9144 
9145 	if (s->ServerType == SERVER_TYPE_STANDALONE)
9146 	{
9147 		if (t->HubType != HUB_TYPE_STANDALONE)
9148 		{
9149 			return ERR_INVALID_PARAMETER;
9150 		}
9151 	}
9152 
9153 	if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
9154 	{
9155 		if (t->HubType == HUB_TYPE_STANDALONE)
9156 		{
9157 			return ERR_INVALID_PARAMETER;
9158 		}
9159 	}
9160 
9161 	LockHubList(c);
9162 	{
9163 		h = GetHub(c, t->HubName);
9164 	}
9165 	UnlockHubList(c);
9166 
9167 	if (h == NULL)
9168 	{
9169 		return ERR_HUB_NOT_FOUND;
9170 	}
9171 
9172 	if (h->Type != t->HubType)
9173 	{
9174 		ReleaseHub(h);
9175 		return ERR_NOT_SUPPORTED;
9176 	}
9177 
9178 	// For JSON-RPC
9179 	if (StrLen(t->AdminPasswordPlainText) != 0)
9180 	{
9181 		Sha0(t->HashedPassword, t->AdminPasswordPlainText, StrLen(t->AdminPasswordPlainText));
9182 		HashPassword(t->SecurePassword, ADMINISTRATOR_USERNAME, t->AdminPasswordPlainText);
9183 	}
9184 
9185 	if (IsZero(t->HashedPassword, sizeof(t->HashedPassword)) == false &&
9186 		IsZero(t->SecurePassword, sizeof(t->SecurePassword)) == false)
9187 	{
9188 		if (a->ServerAdmin == false && GetHubAdminOption(h, "no_change_admin_password") != 0)
9189 		{
9190 			ReleaseHub(h);
9191 			return ERR_NOT_ENOUGH_RIGHT;
9192 		}
9193 	}
9194 
9195 	// Is the password to be set blank
9196 	{
9197 		UCHAR hash1[SHA1_SIZE], hash2[SHA1_SIZE];
9198 		HashPassword(hash1, ADMINISTRATOR_USERNAME, "");
9199 		Sha0(hash2, "", 0);
9200 
9201 		if (Cmp(t->HashedPassword, hash2, SHA1_SIZE) == 0 || Cmp(t->SecurePassword, hash1, SHA1_SIZE) == 0)
9202 		{
9203 			if (a->ServerAdmin == false && IsLocalHostIP(&a->Rpc->Sock->RemoteIP) == false)
9204 			{
9205 				// Refuse to set a blank password to hub admin from remote host
9206 				ReleaseHub(h);
9207 				return ERR_INVALID_PARAMETER;
9208 			}
9209 		}
9210 	}
9211 
9212 	Lock(h->lock);
9213 	{
9214 		if (a->ServerAdmin == false && h->Type != t->HubType)
9215 		{
9216 			ret = ERR_NOT_ENOUGH_RIGHT;
9217 		}
9218 		else
9219 		{
9220 			h->Type = t->HubType;
9221 
9222 			h->Option->DefaultGateway = t->HubOption.DefaultGateway;
9223 			h->Option->DefaultSubnet = t->HubOption.DefaultSubnet;
9224 			h->Option->MaxSession = t->HubOption.MaxSession;
9225 			h->Option->NoEnum = t->HubOption.NoEnum;
9226 
9227 			if (IsZero(t->HashedPassword, sizeof(t->HashedPassword)) == false &&
9228 				IsZero(t->SecurePassword, sizeof(t->SecurePassword)) == false)
9229 			{
9230 				Copy(h->HashedPassword, t->HashedPassword, SHA1_SIZE);
9231 				Copy(h->SecurePassword, t->SecurePassword, SHA1_SIZE);
9232 			}
9233 		}
9234 	}
9235 	Unlock(h->lock);
9236 
9237 	if (t->Online)
9238 	{
9239 		if (a->ServerAdmin || GetHubAdminOption(h, "no_online") == 0)
9240 		{
9241 			SetHubOnline(h);
9242 		}
9243 	}
9244 	else
9245 	{
9246 		if (a->ServerAdmin || GetHubAdminOption(h, "no_offline") == 0)
9247 		{
9248 			SetHubOffline(h);
9249 		}
9250 	}
9251 
9252 	if (h->Type == HUB_TYPE_FARM_STATIC)
9253 	{
9254 		EnableSecureNAT(h, false);
9255 	}
9256 
9257 	h->CurrentVersion++;
9258 	SiHubUpdateProc(h);
9259 
9260 	IncrementServerConfigRevision(s);
9261 
9262 	ALog(a, h, "LA_SET_HUB");
9263 
9264 	ReleaseHub(h);
9265 
9266 	return ret;
9267 }
9268 
9269 // Create a hub
StCreateHub(ADMIN * a,RPC_CREATE_HUB * t)9270 UINT StCreateHub(ADMIN *a, RPC_CREATE_HUB *t)
9271 {
9272 	SERVER *s = a->Server;
9273 	CEDAR *c = s->Cedar;
9274 	HUB *h;
9275 	HUB_OPTION o;
9276 	UINT current_hub_num;
9277 	bool b;
9278 
9279 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
9280 	{
9281 		return ERR_NOT_FARM_CONTROLLER;
9282 	}
9283 
9284 	if (IsEmptyStr(t->HubName) || IsSafeStr(t->HubName) == false)
9285 	{
9286 		return ERR_INVALID_PARAMETER;
9287 	}
9288 
9289 	NO_SUPPORT_FOR_BRIDGE;
9290 
9291 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
9292 	{
9293 		return ERR_NOT_FARM_CONTROLLER;
9294 	}
9295 
9296 	SERVER_ADMIN_ONLY;
9297 
9298 	Trim(t->HubName);
9299 	if (StrLen(t->HubName) == 0)
9300 	{
9301 		return ERR_INVALID_PARAMETER;
9302 	}
9303 	if (StartWith(t->HubName, ".") || EndWith(t->HubName, "."))
9304 	{
9305 		return ERR_INVALID_PARAMETER;
9306 	}
9307 
9308 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
9309 	{
9310 		return ERR_NOT_FARM_CONTROLLER;
9311 	}
9312 
9313 	if (s->ServerType == SERVER_TYPE_STANDALONE)
9314 	{
9315 		if (t->HubType != HUB_TYPE_STANDALONE)
9316 		{
9317 			return ERR_INVALID_PARAMETER;
9318 		}
9319 	}
9320 	else if (t->HubType != HUB_TYPE_FARM_DYNAMIC && t->HubType != HUB_TYPE_FARM_STATIC)
9321 	{
9322 		return ERR_INVALID_PARAMETER;
9323 	}
9324 
9325 	// Create a hub object
9326 	Zero(&o, sizeof(o));
9327 	o.DefaultGateway = t->HubOption.DefaultGateway;
9328 	o.DefaultSubnet = t->HubOption.DefaultSubnet;
9329 	o.MaxSession = t->HubOption.MaxSession;
9330 	o.NoEnum = t->HubOption.NoEnum;
9331 
9332 	// Default setting for hub admin options
9333 	SiSetDefaultHubOption(&o);
9334 
9335 	LockList(c->HubList);
9336 	{
9337 		current_hub_num = LIST_NUM(c->HubList);
9338 	}
9339 	UnlockList(c->HubList);
9340 
9341 	if (current_hub_num > GetServerCapsInt(a->Server, "i_max_hubs"))
9342 	{
9343 		return ERR_TOO_MANY_HUBS;
9344 	}
9345 
9346 	LockList(c->HubList);
9347 	{
9348 		b = IsHub(c, t->HubName);
9349 	}
9350 	UnlockList(c->HubList);
9351 
9352 	if (b)
9353 	{
9354 		return ERR_HUB_ALREADY_EXISTS;
9355 	}
9356 
9357 	ALog(a, NULL, "LA_CREATE_HUB", t->HubName);
9358 
9359 	// For JSON-RPC
9360 	if ((IsZero(t->HashedPassword, sizeof(t->HashedPassword)) &&
9361 		IsZero(t->SecurePassword, sizeof(t->SecurePassword))) ||
9362 		StrLen(t->AdminPasswordPlainText) != 0)
9363 	{
9364 		Sha0(t->HashedPassword, t->AdminPasswordPlainText, StrLen(t->AdminPasswordPlainText));
9365 		HashPassword(t->SecurePassword, ADMINISTRATOR_USERNAME, t->AdminPasswordPlainText);
9366 	}
9367 
9368 	h = NewHub(c, t->HubName, &o);
9369 	Copy(h->HashedPassword, t->HashedPassword, SHA1_SIZE);
9370 	Copy(h->SecurePassword, t->SecurePassword, SHA1_SIZE);
9371 
9372 	h->Type = t->HubType;
9373 
9374 	AddHub(c, h);
9375 
9376 	if (t->Online)
9377 	{
9378 		h->Offline = true;
9379 		SetHubOnline(h);
9380 	}
9381 	else
9382 	{
9383 		h->Offline = false;
9384 		SetHubOffline(h);
9385 	}
9386 
9387 	h->CreatedTime = SystemTime64();
9388 
9389 	ReleaseHub(h);
9390 
9391 	IncrementServerConfigRevision(s);
9392 
9393 	return ERR_NO_ERROR;
9394 }
9395 
9396 // Set cipher for SSL to the server
StSetServerCipher(ADMIN * a,RPC_STR * t)9397 UINT StSetServerCipher(ADMIN *a, RPC_STR *t)
9398 {
9399 	SERVER *s = a->Server;
9400 	CEDAR *c = s->Cedar;
9401 
9402 	if (IsEmptyStr(t->String))
9403 	{
9404 		return ERR_INVALID_PARAMETER;
9405 	}
9406 
9407 	SERVER_ADMIN_ONLY;
9408 
9409 	StrUpper(t->String);
9410 
9411 	ALog(a, NULL, "LA_SET_SERVER_CIPHER", t->String);
9412 
9413 	Lock(c->lock);
9414 	{
9415 		SetCedarCipherList(c, t->String);
9416 	}
9417 	Unlock(c->lock);
9418 
9419 	IncrementServerConfigRevision(s);
9420 
9421 	return ERR_NO_ERROR;
9422 }
9423 
9424 // Get cipher for SSL
StGetServerCipher(ADMIN * a,RPC_STR * t)9425 UINT StGetServerCipher(ADMIN *a, RPC_STR *t)
9426 {
9427 	SERVER *s = a->Server;
9428 	CEDAR *c = s->Cedar;
9429 
9430 	FreeRpcStr(t);
9431 	Zero(t, sizeof(RPC_STR));
9432 
9433 	Lock(c->lock);
9434 	{
9435 		t->String = CopyStr(c->CipherList);
9436 	}
9437 	Unlock(c->lock);
9438 
9439 	return ERR_NO_ERROR;
9440 }
9441 
9442 // Get list of available ciphers for SSL
StGetServerCipherList(ADMIN * a,RPC_STR * t)9443 UINT StGetServerCipherList(ADMIN *a, RPC_STR *t)
9444 {
9445 	SERVER *s = a->Server;
9446 	CEDAR *c = s->Cedar;
9447 
9448 	FreeRpcStr(t);
9449 	Zero(t, sizeof(RPC_STR));
9450 
9451 	Lock(c->lock);
9452 	{
9453 		UINT i;
9454 		TOKEN_LIST *ciphers = GetCipherList();
9455 		if (ciphers->NumTokens > 0)
9456 		{
9457 			UINT size = StrSize(ciphers->Token[0]);
9458 			t->String = Malloc(size);
9459 			StrCpy(t->String, size, ciphers->Token[0]);
9460 			i = 1;
9461 
9462 			for (; i < ciphers->NumTokens; i++)
9463 			{
9464 				// We use StrSize() because we need the extra space for ';'
9465 				size += StrSize(ciphers->Token[i]);
9466 				t->String = ReAlloc(t->String, size);
9467 				StrCat(t->String, size, ";");
9468 				StrCat(t->String, size, ciphers->Token[i]);
9469 			}
9470 		}
9471 
9472 		FreeToken(ciphers);
9473 	}
9474 	Unlock(c->lock);
9475 
9476 	return ERR_NO_ERROR;
9477 }
9478 
9479 // Get the server certification
StGetServerCert(ADMIN * a,RPC_KEY_PAIR * t)9480 UINT StGetServerCert(ADMIN *a, RPC_KEY_PAIR *t)
9481 {
9482 	bool admin;
9483 	SERVER *s = a->Server;
9484 	CEDAR *c = s->Cedar;
9485 	bool is_vgs_cert = false;
9486 
9487 	admin = a->ServerAdmin;
9488 
9489 	FreeRpcKeyPair(t);
9490 	Zero(t, sizeof(RPC_KEY_PAIR));
9491 
9492 	Lock(c->lock);
9493 	{
9494 
9495 		t->Cert = CloneX(c->ServerX);
9496 		if (admin && is_vgs_cert == false)
9497 		{
9498 			t->Key = CloneK(c->ServerK);
9499 		}
9500 	}
9501 	Unlock(c->lock);
9502 
9503 	return ERR_NO_ERROR;
9504 }
9505 
9506 // Set the server certification
StSetServerCert(ADMIN * a,RPC_KEY_PAIR * t)9507 UINT StSetServerCert(ADMIN *a, RPC_KEY_PAIR *t)
9508 {
9509 	SERVER *s = a->Server;
9510 	CEDAR *c = s->Cedar;
9511 
9512 	SERVER_ADMIN_ONLY;
9513 
9514 	if (t->Cert == NULL || t->Key == NULL)
9515 	{
9516 		return ERR_PROTOCOL_ERROR;
9517 	}
9518 
9519 	if (t->Cert->is_compatible_bit == false)
9520 	{
9521 		return ERR_NOT_RSA_1024;
9522 	}
9523 
9524 	if (CheckXandK(t->Cert, t->Key) == false)
9525 	{
9526 		return ERR_PROTOCOL_ERROR;
9527 	}
9528 
9529 	t->Flag1 = 1;
9530 	if (t->Cert->root_cert == false)
9531 	{
9532 		if (DownloadAndSaveIntermediateCertificatesIfNecessary(t->Cert) == false)
9533 		{
9534 			t->Flag1 = 0;
9535 		}
9536 	}
9537 
9538 	SetCedarCert(c, t->Cert, t->Key);
9539 
9540 	ALog(a, NULL, "LA_SET_SERVER_CERT");
9541 
9542 	IncrementServerConfigRevision(s);
9543 
9544 	return ERR_NO_ERROR;
9545 }
9546 
9547 // Add a WireGuard key to the allowed key list
StAddWgk(ADMIN * a,RPC_WGK * t)9548 UINT StAddWgk(ADMIN *a, RPC_WGK *t)
9549 {
9550 	UINT ret = ERR_NO_ERROR;
9551 	SERVER *s = a->Server;
9552 	CEDAR *c = s->Cedar;
9553 	LIST *to_add;
9554 
9555 	SERVER_ADMIN_ONLY;
9556 
9557 	to_add = NewListFast(NULL);
9558 
9559 	LockList(c->WgkList);
9560 	{
9561 		UINT i;
9562 		for (i = 0; i < t->Num; ++i)
9563 		{
9564 			WGK *rpc_wgk = &t->Wgks[i];
9565 			WGK *wgk;
9566 
9567 			if (IsEmptyStr(rpc_wgk->Key))
9568 			{
9569 				ret = ERR_INVALID_PARAMETER;
9570 				break;
9571 			}
9572 
9573 			if (Search(c->WgkList, rpc_wgk) != NULL)
9574 			{
9575 				ret = ERR_OBJECT_EXISTS;
9576 				break;
9577 			}
9578 
9579 			wgk = Malloc(sizeof(WGK));
9580 			StrCpy(wgk->Key, sizeof(wgk->Key), rpc_wgk->Key);
9581 			StrCpy(wgk->Hub, sizeof(wgk->Hub), rpc_wgk->Hub);
9582 			StrCpy(wgk->User, sizeof(wgk->User), rpc_wgk->User);
9583 
9584 			Add(to_add, wgk);
9585 		}
9586 
9587 		for (i = 0; i < LIST_NUM(to_add); ++i)
9588 		{
9589 			WGK *wgk = LIST_DATA(to_add, i);
9590 			ret == ERR_NO_ERROR ? Add(c->WgkList, wgk) : Free(wgk);
9591 		}
9592 	}
9593 	UnlockList(c->WgkList);
9594 
9595 	if (ret == ERR_NO_ERROR)
9596 	{
9597 		ALog(a, NULL, "LA_ADD_WGK", LIST_NUM(to_add));
9598 		IncrementServerConfigRevision(a->Server);
9599 	}
9600 
9601 	ReleaseList(to_add);
9602 
9603 	return ret;
9604 }
9605 
9606 // Delete a WireGuard key from the allowed key list
StDeleteWgk(ADMIN * a,RPC_WGK * t)9607 UINT StDeleteWgk(ADMIN *a, RPC_WGK *t)
9608 {
9609 	UINT ret = ERR_NO_ERROR;
9610 	SERVER *s = a->Server;
9611 	CEDAR *c = s->Cedar;
9612 	LIST *to_delete;
9613 
9614 	SERVER_ADMIN_ONLY;
9615 
9616 	to_delete = NewListFast(NULL);
9617 
9618 	LockList(c->WgkList);
9619 	{
9620 		UINT i;
9621 		for (i = 0; i < t->Num; ++i)
9622 		{
9623 			WGK *wgk = Search(c->WgkList, &t->Wgks[i]);
9624 			if (wgk == NULL)
9625 			{
9626 				ret = ERR_OBJECT_NOT_FOUND;
9627 				break;
9628 			}
9629 
9630 			Add(to_delete, wgk);
9631 		}
9632 
9633 		if (ret == ERR_NO_ERROR)
9634 		{
9635 			for (i = 0; i < LIST_NUM(to_delete); ++i)
9636 			{
9637 				WGK *wgk = LIST_DATA(to_delete, i);
9638 				Delete(c->WgkList, wgk);
9639 				Free(wgk);
9640 			}
9641 		}
9642 	}
9643 	UnlockList(c->WgkList);
9644 
9645 	if (ret == ERR_NO_ERROR)
9646 	{
9647 		ALog(a, NULL, "LA_DELETE_WGK", LIST_NUM(to_delete));
9648 		IncrementServerConfigRevision(a->Server);
9649 	}
9650 
9651 	ReleaseList(to_delete);
9652 
9653 	return ret;
9654 }
9655 
9656 // List the allowed WireGuard keys
StEnumWgk(ADMIN * a,RPC_WGK * t)9657 UINT StEnumWgk(ADMIN *a, RPC_WGK *t)
9658 {
9659 	SERVER *s = a->Server;
9660 	CEDAR *c = s->Cedar;
9661 
9662 	SERVER_ADMIN_ONLY;
9663 
9664 	LockList(c->WgkList);
9665 	{
9666 		UINT i;
9667 		t->Num = LIST_NUM(c->WgkList);
9668 		t->Wgks = Malloc(sizeof(WGK) * t->Num);
9669 
9670 		for (i = 0; i < t->Num; ++i)
9671 		{
9672 			WGK *wgk = LIST_DATA(c->WgkList, i);
9673 			WGK *rpc_wgk = &t->Wgks[i];
9674 
9675 			StrCpy(rpc_wgk->Key, sizeof(rpc_wgk->Key), wgk->Key);
9676 			StrCpy(rpc_wgk->Hub, sizeof(rpc_wgk->Hub), wgk->Hub);
9677 			StrCpy(rpc_wgk->User, sizeof(rpc_wgk->User), wgk->User);
9678 		}
9679 	}
9680 	UnlockList(c->WgkList);
9681 
9682 	return ERR_NO_ERROR;
9683 }
9684 
9685 // Get status of connection to cluster controller
StGetFarmConnectionStatus(ADMIN * a,RPC_FARM_CONNECTION_STATUS * t)9686 UINT StGetFarmConnectionStatus(ADMIN *a, RPC_FARM_CONNECTION_STATUS *t)
9687 {
9688 	SERVER *s = a->Server;
9689 	CEDAR *c = s->Cedar;
9690 	FARM_CONTROLLER *fc;
9691 
9692 	if (s->ServerType != SERVER_TYPE_FARM_MEMBER)
9693 	{
9694 		return ERR_NOT_FARM_MEMBER;
9695 	}
9696 
9697 	Zero(t, sizeof(RPC_FARM_CONNECTION_STATUS));
9698 
9699 	fc = s->FarmController;
9700 
9701 	Lock(fc->lock);
9702 	{
9703 		if (fc->Sock != NULL)
9704 		{
9705 			t->Ip = IPToUINT(&fc->Sock->RemoteIP);
9706 			t->Port = fc->Sock->RemotePort;
9707 		}
9708 
9709 		t->Online = fc->Online;
9710 		t->LastError = ERR_NO_ERROR;
9711 
9712 		if (t->Online == false)
9713 		{
9714 			t->LastError = fc->LastError;
9715 		}
9716 		else
9717 		{
9718 			t->CurrentConnectedTime = fc->CurrentConnectedTime;
9719 		}
9720 
9721 		t->StartedTime = fc->StartedTime;
9722 		t->FirstConnectedTime = fc->FirstConnectedTime;
9723 
9724 		t->NumConnected = fc->NumConnected;
9725 		t->NumTry = fc->NumTry;
9726 		t->NumFailed = fc->NumFailed;
9727 	}
9728 	Unlock(fc->lock);
9729 
9730 	return ERR_NO_ERROR;
9731 }
9732 
9733 // Enumerate cluster members
StEnumFarmMember(ADMIN * a,RPC_ENUM_FARM * t)9734 UINT StEnumFarmMember(ADMIN *a, RPC_ENUM_FARM *t)
9735 {
9736 	SERVER *s = a->Server;
9737 	CEDAR *c = s->Cedar;
9738 	UINT i;
9739 
9740 	FreeRpcEnumFarm(t);
9741 	Zero(t, sizeof(RPC_ENUM_FARM));
9742 
9743 	if (s->ServerType != SERVER_TYPE_FARM_CONTROLLER)
9744 	{
9745 		return ERR_NOT_FARM_CONTROLLER;
9746 	}
9747 
9748 	Zero(t, sizeof(RPC_ENUM_FARM));
9749 
9750 	LockList(s->FarmMemberList);
9751 	{
9752 		t->NumFarm = LIST_NUM(s->FarmMemberList);
9753 		t->Farms = ZeroMalloc(sizeof(RPC_ENUM_FARM_ITEM) * t->NumFarm);
9754 
9755 		for (i = 0;i < t->NumFarm;i++)
9756 		{
9757 			FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
9758 			RPC_ENUM_FARM_ITEM *e = &t->Farms[i];
9759 
9760 			e->Id = POINTER_TO_KEY(f);
9761 			e->Controller = f->Me;
9762 
9763 			if (e->Controller)
9764 			{
9765 				e->ConnectedTime = TickToTime(c->CreatedTick);
9766 				e->Ip = 0x0100007f;
9767 				GetMachineName(e->Hostname, sizeof(e->Hostname));
9768 				e->Point = f->Point;
9769 				e->NumSessions = Count(c->CurrentSessions);
9770 				e->NumTcpConnections = Count(c->CurrentTcpConnections);
9771 
9772 				e->AssignedBridgeLicense = Count(c->AssignedBridgeLicense);
9773 				e->AssignedClientLicense = Count(c->AssignedClientLicense);
9774 			}
9775 			else
9776 			{
9777 				e->ConnectedTime = f->ConnectedTime;
9778 				e->Ip = f->Ip;
9779 				StrCpy(e->Hostname, sizeof(e->Hostname), f->hostname);
9780 				e->Point = f->Point;
9781 				e->NumSessions = f->NumSessions;
9782 				e->NumTcpConnections = f->NumTcpConnections;
9783 
9784 				e->AssignedBridgeLicense = f->AssignedBridgeLicense;
9785 				e->AssignedClientLicense = f->AssignedClientLicense;
9786 			}
9787 			e->NumHubs = LIST_NUM(f->HubList);
9788 		}
9789 	}
9790 	UnlockList(s->FarmMemberList);
9791 
9792 	return ERR_NO_ERROR;
9793 }
9794 
9795 // Get cluster member information
StGetFarmInfo(ADMIN * a,RPC_FARM_INFO * t)9796 UINT StGetFarmInfo(ADMIN *a, RPC_FARM_INFO *t)
9797 {
9798 	SERVER *s = a->Server;
9799 	UINT id = t->Id;
9800 	UINT i;
9801 	UINT ret = ERR_NO_ERROR;
9802 
9803 	FreeRpcFarmInfo(t);
9804 	Zero(t, sizeof(RPC_FARM_INFO));
9805 
9806 	if (s->ServerType != SERVER_TYPE_FARM_CONTROLLER)
9807 	{
9808 		return ERR_NOT_FARM_CONTROLLER;
9809 	}
9810 
9811 	LockList(s->FarmMemberList);
9812 	{
9813 		if (IsInListKey(s->FarmMemberList, id))
9814 		{
9815 			FARM_MEMBER *f = ListKeyToPointer(s->FarmMemberList, id);
9816 
9817 			t->Id = id;
9818 			t->Controller = f->Me;
9819 			t->Weight = f->Weight;
9820 
9821 			LockList(f->HubList);
9822 			{
9823 				t->NumFarmHub = LIST_NUM(f->HubList);
9824 				t->FarmHubs = ZeroMalloc(sizeof(RPC_FARM_HUB) * t->NumFarmHub);
9825 
9826 				for (i = 0;i < t->NumFarmHub;i++)
9827 				{
9828 					RPC_FARM_HUB *h = &t->FarmHubs[i];
9829 					HUB_LIST *hh = LIST_DATA(f->HubList, i);
9830 
9831 					h->DynamicHub = hh->DynamicHub;
9832 					StrCpy(h->HubName, sizeof(h->HubName), hh->Name);
9833 				}
9834 			}
9835 			UnlockList(f->HubList);
9836 
9837 			if (t->Controller)
9838 			{
9839 				t->ConnectedTime = TickToTime(s->Cedar->CreatedTick);
9840 				t->Ip = 0x0100007f;
9841 				GetMachineName(t->Hostname, sizeof(t->Hostname));
9842 				t->Point = f->Point;
9843 
9844 				LockList(s->ServerListenerList);
9845 				{
9846 					UINT i, n;
9847 					t->NumPort = 0;
9848 					for (i = 0;i < LIST_NUM(s->ServerListenerList);i++)
9849 					{
9850 						SERVER_LISTENER *o = LIST_DATA(s->ServerListenerList, i);
9851 						if (o->Enabled)
9852 						{
9853 							t->NumPort++;
9854 						}
9855 					}
9856 					t->Ports = ZeroMalloc(sizeof(UINT) * t->NumPort);
9857 					n = 0;
9858 					for (i = 0;i < LIST_NUM(s->ServerListenerList);i++)
9859 					{
9860 						SERVER_LISTENER *o = LIST_DATA(s->ServerListenerList, i);
9861 						if (o->Enabled)
9862 						{
9863 							t->Ports[n++] = o->Port;
9864 						}
9865 					}
9866 				}
9867 				UnlockList(s->ServerListenerList);
9868 
9869 				t->ServerCert = CloneX(s->Cedar->ServerX);
9870 				t->NumSessions = Count(s->Cedar->CurrentSessions);
9871 				t->NumTcpConnections = Count(s->Cedar->CurrentTcpConnections);
9872 			}
9873 			else
9874 			{
9875 				t->ConnectedTime = f->ConnectedTime;
9876 				t->Ip = f->Ip;
9877 				StrCpy(t->Hostname, sizeof(t->Hostname), f->hostname);
9878 				t->Point = f->Point;
9879 				t->NumPort = f->NumPort;
9880 				t->Ports = ZeroMalloc(sizeof(UINT) * t->NumPort);
9881 				Copy(t->Ports, f->Ports, sizeof(UINT) * t->NumPort);
9882 				t->ServerCert = CloneX(f->ServerCert);
9883 				t->NumSessions = f->NumSessions;
9884 				t->NumTcpConnections = f->NumTcpConnections;
9885 			}
9886 		}
9887 		else
9888 		{
9889 			ret = ERR_OBJECT_NOT_FOUND;
9890 		}
9891 	}
9892 	UnlockList(s->FarmMemberList);
9893 
9894 	return ret;
9895 }
9896 
9897 // Get clustering configuration
StGetFarmSetting(ADMIN * a,RPC_FARM * t)9898 UINT StGetFarmSetting(ADMIN *a, RPC_FARM *t)
9899 {
9900 	SERVER *s;
9901 	FreeRpcFarm(t);
9902 	Zero(t, sizeof(RPC_FARM));
9903 
9904 	s = a->Server;
9905 	t->ServerType = s->ServerType;
9906 	t->ControllerOnly = s->ControllerOnly;
9907 	t->Weight = s->Weight;
9908 
9909 	if (t->ServerType == SERVER_TYPE_FARM_MEMBER)
9910 	{
9911 		t->NumPort = s->NumPublicPort;
9912 		t->Ports = ZeroMalloc(sizeof(UINT) * t->NumPort);
9913 		Copy(t->Ports, s->PublicPorts, sizeof(UINT) * t->NumPort);
9914 		t->PublicIp = s->PublicIp;
9915 		StrCpy(t->ControllerName, sizeof(t->ControllerName), s->ControllerName);
9916 		t->ControllerPort = s->ControllerPort;
9917 	}
9918 	else
9919 	{
9920 		t->NumPort = 0;
9921 		t->Ports = ZeroMalloc(0);
9922 	}
9923 
9924 	return ERR_NO_ERROR;
9925 }
9926 
9927 // Set clustering configuration
StSetFarmSetting(ADMIN * a,RPC_FARM * t)9928 UINT StSetFarmSetting(ADMIN *a, RPC_FARM *t)
9929 {
9930 	bool cluster_allowed = false;
9931 
9932 	SERVER_ADMIN_ONLY;
9933 	NO_SUPPORT_FOR_BRIDGE;
9934 
9935 
9936 	cluster_allowed = GetServerCapsInt(a->Server, "b_support_cluster");
9937 
9938 	if (t->ServerType != SERVER_TYPE_STANDALONE && cluster_allowed == false)
9939 	{
9940 		// When clustering function is disabled, deny turning into clustering mode
9941 		return ERR_NOT_SUPPORTED;
9942 	}
9943 
9944 	if (IsZero(t->MemberPassword, sizeof(t->MemberPassword)))
9945 	{
9946 		if (IsEmptyStr(t->MemberPasswordPlaintext) == false)
9947 		{
9948 			// For JSON-RPC
9949 			HashAdminPassword(t->MemberPassword, t->MemberPasswordPlaintext);
9950 		}
9951 	}
9952 
9953 	ALog(a, NULL, "LA_SET_FARM_SETTING");
9954 
9955 	IncrementServerConfigRevision(a->Server);
9956 
9957 	SiSetServerType(a->Server, t->ServerType, t->PublicIp, t->NumPort, t->Ports,
9958 		t->ControllerName, t->ControllerPort, t->MemberPassword, t->Weight, t->ControllerOnly);
9959 
9960 	return ERR_NO_ERROR;
9961 }
9962 
9963 // Set server password
StSetServerPassword(ADMIN * a,RPC_SET_PASSWORD * t)9964 UINT StSetServerPassword(ADMIN *a, RPC_SET_PASSWORD *t)
9965 {
9966 	SERVER_ADMIN_ONLY;
9967 
9968 	if (IsZero(t->HashedPassword, sizeof(t->HashedPassword)))
9969 	{
9970 		// For JSON-RPC
9971 		HashAdminPassword(t->HashedPassword, t->PlainTextPassword);
9972 	}
9973 
9974 	Copy(a->Server->HashedPassword, t->HashedPassword, SHA1_SIZE);
9975 
9976 	ALog(a, NULL, "LA_SET_SERVER_PASSWORD");
9977 
9978 	IncrementServerConfigRevision(a->Server);
9979 
9980 	return ERR_NO_ERROR;
9981 }
9982 
9983 // Enable / Disable listener
StEnableListener(ADMIN * a,RPC_LISTENER * t)9984 UINT StEnableListener(ADMIN *a, RPC_LISTENER *t)
9985 {
9986 	UINT ret = ERR_NO_ERROR;
9987 
9988 	SERVER_ADMIN_ONLY;
9989 
9990 
9991 	LockList(a->Server->ServerListenerList);
9992 	{
9993 		if (t->Enable)
9994 		{
9995 			if (SiEnableListener(a->Server, t->Port) == false)
9996 			{
9997 				ret = ERR_LISTENER_NOT_FOUND;
9998 			}
9999 			else
10000 			{
10001 				ALog(a, NULL, "LA_ENABLE_LISTENER", t->Port);
10002 			}
10003 		}
10004 		else
10005 		{
10006 			if (SiDisableListener(a->Server, t->Port) == false)
10007 			{
10008 				ret = ERR_LISTENER_NOT_FOUND;
10009 			}
10010 			else
10011 			{
10012 				ALog(a, NULL, "LA_DISABLE_LISTENER", t->Port);
10013 			}
10014 		}
10015 	}
10016 	UnlockList(a->Server->ServerListenerList);
10017 
10018 	IncrementServerConfigRevision(a->Server);
10019 
10020 	SleepThread(250);
10021 
10022 	return ret;
10023 }
10024 
10025 // Delete a listener
StDeleteListener(ADMIN * a,RPC_LISTENER * t)10026 UINT StDeleteListener(ADMIN *a, RPC_LISTENER *t)
10027 {
10028 	UINT ret = ERR_NO_ERROR;
10029 
10030 	SERVER_ADMIN_ONLY;
10031 
10032 
10033 	LockList(a->Server->ServerListenerList);
10034 	{
10035 		if (SiDeleteListener(a->Server, t->Port) == false)
10036 		{
10037 			ret = ERR_LISTENER_NOT_FOUND;
10038 		}
10039 		else
10040 		{
10041 			ALog(a, NULL, "LA_DELETE_LISTENER", t->Port);
10042 
10043 			IncrementServerConfigRevision(a->Server);
10044 		}
10045 	}
10046 	UnlockList(a->Server->ServerListenerList);
10047 
10048 	return ret;
10049 }
10050 
10051 // Enumerating listeners
StEnumListener(ADMIN * a,RPC_LISTENER_LIST * t)10052 UINT StEnumListener(ADMIN *a, RPC_LISTENER_LIST *t)
10053 {
10054 	CEDAR *c = a->Server->Cedar;
10055 	UINT i;
10056 
10057 	FreeRpcListenerList(t);
10058 	Zero(t, sizeof(RPC_LISTENER_LIST));
10059 
10060 	LockList(a->Server->ServerListenerList);
10061 	{
10062 		t->NumPort = LIST_NUM(a->Server->ServerListenerList);
10063 		t->Ports = ZeroMalloc(sizeof(UINT) * t->NumPort);
10064 		t->Enables = ZeroMalloc(sizeof(bool) * t->NumPort);
10065 		t->Errors = ZeroMalloc(sizeof(bool) * t->NumPort);
10066 
10067 		for (i = 0;i < t->NumPort;i++)
10068 		{
10069 			SERVER_LISTENER *o = LIST_DATA(a->Server->ServerListenerList, i);
10070 
10071 			t->Ports[i] = o->Port;
10072 			t->Enables[i] = o->Enabled;
10073 			if (t->Enables[i])
10074 			{
10075 				if (o->Listener->Status == LISTENER_STATUS_TRYING)
10076 				{
10077 					t->Errors[i] = true;
10078 				}
10079 			}
10080 		}
10081 	}
10082 	UnlockList(a->Server->ServerListenerList);
10083 
10084 	return ERR_NO_ERROR;
10085 }
10086 
10087 // Create a listener
StCreateListener(ADMIN * a,RPC_LISTENER * t)10088 UINT StCreateListener(ADMIN *a, RPC_LISTENER *t)
10089 {
10090 	UINT ret = ERR_NO_ERROR;
10091 	CEDAR *c = a->Server->Cedar;
10092 
10093 	if (t->Port == 0 || t->Port > 65535)
10094 	{
10095 		return ERR_INVALID_PARAMETER;
10096 	}
10097 
10098 	SERVER_ADMIN_ONLY;
10099 
10100 	LockList(a->Server->ServerListenerList);
10101 	{
10102 		if (SiAddListener(a->Server, t->Port, t->Enable) == false)
10103 		{
10104 			ret = ERR_LISTENER_ALREADY_EXISTS;
10105 		}
10106 		else
10107 		{
10108 			ALog(a, NULL, "LA_CREATE_LISTENER", t->Port);
10109 
10110 			IncrementServerConfigRevision(a->Server);
10111 		}
10112 	}
10113 	UnlockList(a->Server->ServerListenerList);
10114 
10115 	SleepThread(250);
10116 
10117 	return ret;
10118 }
10119 
10120 // Set UDP ports the server should listen on
StSetPortsUDP(ADMIN * a,RPC_PORTS * t)10121 UINT StSetPortsUDP(ADMIN *a, RPC_PORTS *t)
10122 {
10123 	UINT i;
10124 	LIST *ports, *server_ports;
10125 
10126 	SERVER_ADMIN_ONLY;
10127 
10128 	ports = NewIntList(true);
10129 
10130 	for (i = 0; i < t->Num; ++i)
10131 	{
10132 		const UINT port = t->Ports[i];
10133 		if (port < 1 || port > 65535)
10134 		{
10135 			ReleaseIntList(ports);
10136 			return ERR_INVALID_PARAMETER;
10137 		}
10138 
10139 		AddIntDistinct(ports, port);
10140 	}
10141 
10142 	server_ports = a->Server->PortsUDP;
10143 
10144 	LockList(server_ports);
10145 	{
10146 		char tmp[MAX_SIZE];
10147 		wchar_t str[MAX_SIZE];
10148 
10149 		for (i = 0; i < LIST_NUM(server_ports); ++i)
10150 		{
10151 			Free(LIST_DATA(server_ports, i));
10152 		}
10153 		DeleteAll(server_ports);
10154 
10155 		for (i = 0; i < LIST_NUM(ports); ++i)
10156 		{
10157 			const UINT port = *(UINT *)LIST_DATA(ports, i);
10158 			AddInt(server_ports, port);
10159 		}
10160 
10161 		ProtoSetUdpPorts(a->Server->Proto, server_ports);
10162 
10163 		IntListToStr(tmp, sizeof(tmp), server_ports, ", ");
10164 		StrToUni(str, sizeof(str), tmp);
10165 		ALog(a, NULL, "LA_SET_PORTS_UDP", str);
10166 	}
10167 	UnlockList(server_ports);
10168 
10169 	ReleaseIntList(ports);
10170 
10171 	IncrementServerConfigRevision(a->Server);
10172 
10173 	return ERR_NO_ERROR;
10174 }
10175 
10176 // List UDP ports the server is listening on
StGetPortsUDP(ADMIN * a,RPC_PORTS * t)10177 UINT StGetPortsUDP(ADMIN *a, RPC_PORTS *t)
10178 {
10179 	LIST *ports = a->Server->PortsUDP;
10180 
10181 	FreeRpcPorts(t);
10182 
10183 	LockList(ports);
10184 	{
10185 		t->Num = LIST_NUM(ports);
10186 		t->Ports = t->Num > 0 ? Malloc(sizeof(UINT) * t->Num) : NULL;
10187 		if (t->Ports != NULL)
10188 		{
10189 			UINT i;
10190 			for (i = 0; i < t->Num; ++i)
10191 			{
10192 				const UINT port = *(UINT *)LIST_DATA(ports, i);
10193 				t->Ports[i] = port;
10194 			}
10195 		}
10196 	}
10197 	UnlockList(ports);
10198 
10199 	return ERR_NO_ERROR;
10200 }
10201 
StGetProtoOptions(ADMIN * a,RPC_PROTO_OPTIONS * t)10202 UINT StGetProtoOptions(ADMIN *a, RPC_PROTO_OPTIONS *t)
10203 {
10204 	PROTO *proto = a->Server->Proto;
10205 	PROTO_CONTAINER *container, tmp;
10206 	UINT ret = ERR_NO_ERROR;
10207 	LIST *options;
10208 
10209 	SERVER_ADMIN_ONLY;
10210 
10211 	if (proto == NULL)
10212 	{
10213 		return ERR_NOT_SUPPORTED;
10214 	}
10215 
10216 	tmp.Name = t->Protocol;
10217 
10218 	container = Search(proto->Containers, &tmp);
10219 	if (container == NULL)
10220 	{
10221 		return ERR_INVALID_PARAMETER;
10222 	}
10223 
10224 	options = container->Options;
10225 	LockList(options);
10226 	{
10227 		UINT i;
10228 
10229 		t->Num = LIST_NUM(options);
10230 		t->Options = Malloc(sizeof(PROTO_OPTION) * t->Num);
10231 
10232 		for (i = 0; i < t->Num; ++i)
10233 		{
10234 			const PROTO_OPTION *option = LIST_DATA(options, i);
10235 			PROTO_OPTION *rpc_option = &t->Options[i];
10236 
10237 			switch (option->Type)
10238 			{
10239 			case PROTO_OPTION_BOOL:
10240 				rpc_option->Bool = option->Bool;
10241 				break;
10242 			case PROTO_OPTION_UINT32:
10243 				rpc_option->UInt32 = option->UInt32;
10244 				break;
10245 			case PROTO_OPTION_STRING:
10246 				rpc_option->String = CopyStr(option->String);
10247 				break;
10248 			default:
10249 				Debug("StGetProtoOptions(): unhandled option type %u!\n", option->Type);
10250 				ret = ERR_INTERNAL_ERROR;
10251 			}
10252 
10253 			if (ret == ERR_NO_ERROR)
10254 			{
10255 				rpc_option->Name = CopyStr(option->Name);
10256 				rpc_option->Type = option->Type;
10257 			}
10258 			else
10259 			{
10260 				break;
10261 			}
10262 		}
10263 	}
10264 	UnlockList(options);
10265 
10266 	return ret;
10267 }
10268 
StSetProtoOptions(ADMIN * a,RPC_PROTO_OPTIONS * t)10269 UINT StSetProtoOptions(ADMIN *a, RPC_PROTO_OPTIONS *t)
10270 {
10271 	PROTO *proto = a->Server->Proto;
10272 	PROTO_CONTAINER *container, tmp;
10273 	UINT ret = ERR_NO_ERROR;
10274 	bool changed = false;
10275 	LIST *options;
10276 
10277 	SERVER_ADMIN_ONLY;
10278 
10279 	if (proto == NULL)
10280 	{
10281 		return ERR_NOT_SUPPORTED;
10282 	}
10283 
10284 	tmp.Name = t->Protocol;
10285 
10286 	container = Search(proto->Containers, &tmp);
10287 	if (container == NULL)
10288 	{
10289 		return ERR_INVALID_PARAMETER;
10290 	}
10291 
10292 	options = container->Options;
10293 	LockList(options);
10294 	{
10295 		UINT i;
10296 		for (i = 0; i < t->Num; ++i)
10297 		{
10298 			PROTO_OPTION *rpc_option = &t->Options[i];
10299 			PROTO_OPTION *option = Search(options, rpc_option);
10300 			if (option == NULL || rpc_option->Type != option->Type)
10301 			{
10302 				ret = ERR_INVALID_PARAMETER;
10303 				break;
10304 			}
10305 
10306 			switch (option->Type)
10307 			{
10308 				case PROTO_OPTION_BOOL:
10309 					option->Bool = rpc_option->Bool;
10310 					break;
10311 				case PROTO_OPTION_UINT32:
10312 					option->UInt32 = rpc_option->UInt32;
10313 					break;
10314 				case PROTO_OPTION_STRING:
10315 					Free(option->String);
10316 					option->String = CopyStr(rpc_option->String);
10317 					break;
10318 				default:
10319 					Debug("StSetProtoOptions(): unhandled option type %u!\n", option->Type);
10320 					ret = ERR_INTERNAL_ERROR;
10321 			}
10322 
10323 			if (ret == ERR_NO_ERROR)
10324 			{
10325 				changed = true;
10326 			}
10327 			else
10328 			{
10329 				break;
10330 			}
10331 		}
10332 	}
10333 	UnlockList(options);
10334 
10335 	if (changed)
10336 	{
10337 		ALog(a, NULL, "LA_SET_PROTO_OPTIONS", t->Protocol);
10338 		IncrementServerConfigRevision(a->Server);
10339 	}
10340 
10341 	return ret;
10342 }
10343 
10344 // Get server status
StGetServerStatus(ADMIN * a,RPC_SERVER_STATUS * t)10345 UINT StGetServerStatus(ADMIN *a, RPC_SERVER_STATUS *t)
10346 {
10347 	CEDAR *c;
10348 	UINT i;
10349 
10350 	c = a->Server->Cedar;
10351 
10352 	Zero(t, sizeof(RPC_SERVER_STATUS));
10353 
10354 	Lock(c->TrafficLock);
10355 	{
10356 		Copy(&t->Traffic, c->Traffic, sizeof(TRAFFIC));
10357 	}
10358 	Unlock(c->TrafficLock);
10359 
10360 	GetMemInfo(&t->MemInfo);
10361 
10362 	t->ServerType = a->Server->ServerType;
10363 	t->NumTcpConnections = t->NumTcpConnectionsLocal = t->NumTcpConnectionsRemote = 0;
10364 	t->NumSessionsTotal = t->NumSessionsLocal = t->NumSessionsRemote = 0;
10365 
10366 	t->NumTcpConnectionsLocal = Count(c->CurrentTcpConnections);
10367 
10368 	if (a->Server->ServerType == SERVER_TYPE_FARM_CONTROLLER)
10369 	{
10370 		LockList(a->Server->FarmMemberList);
10371 		{
10372 			for (i = 0;i < LIST_NUM(a->Server->FarmMemberList);i++)
10373 			{
10374 				FARM_MEMBER *f = LIST_DATA(a->Server->FarmMemberList, i);
10375 
10376 				if (f->Me == false)
10377 				{
10378 					t->NumTcpConnectionsRemote += f->NumTcpConnections;
10379 					t->NumSessionsRemote += f->NumSessions;
10380 					AddTraffic(&t->Traffic, &f->Traffic);
10381 				}
10382 			}
10383 		}
10384 		UnlockList(a->Server->FarmMemberList);
10385 	}
10386 
10387 	t->NumMacTables = t->NumIpTables = t->NumUsers = t->NumGroups = 0;
10388 
10389 	// The number of hubs
10390 	LockList(c->HubList);
10391 	{
10392 		t->NumHubTotal = LIST_NUM(c->HubList);
10393 
10394 		t->NumHubStandalone = t->NumHubDynamic = t->NumHubStatic = 0;
10395 
10396 		for (i = 0;i < LIST_NUM(c->HubList);i++)
10397 		{
10398 			HUB *h = LIST_DATA(c->HubList, i);
10399 			Lock(h->lock);
10400 			{
10401 				switch (h->Type)
10402 				{
10403 				case HUB_TYPE_STANDALONE:
10404 					t->NumHubStandalone++;
10405 					break;
10406 
10407 				case HUB_TYPE_FARM_STATIC:
10408 					t->NumHubStatic++;
10409 					break;
10410 
10411 				case HUB_TYPE_FARM_DYNAMIC:
10412 					t->NumHubDynamic++;
10413 					break;
10414 				}
10415 			}
10416 
10417 			t->NumMacTables += HASH_LIST_NUM(h->MacHashTable);
10418 			t->NumIpTables += LIST_NUM(h->IpTable);
10419 
10420 			if (h->HubDb != NULL)
10421 			{
10422 				t->NumUsers += LIST_NUM(h->HubDb->UserList);
10423 				t->NumGroups += LIST_NUM(h->HubDb->GroupList);
10424 			}
10425 
10426 			Unlock(h->lock);
10427 		}
10428 	}
10429 	UnlockList(c->HubList);
10430 
10431 	// The number of sessions
10432 	t->NumSessionsLocal = Count(c->CurrentSessions);
10433 	t->NumSessionsTotal = t->NumSessionsLocal + t->NumSessionsRemote;
10434 	t->NumTcpConnections = t->NumTcpConnectionsLocal + t->NumTcpConnectionsRemote;
10435 
10436 	t->AssignedBridgeLicenses = Count(c->AssignedBridgeLicense);
10437 	t->AssignedClientLicenses = Count(c->AssignedClientLicense);
10438 
10439 	t->AssignedBridgeLicensesTotal = a->Server->CurrentAssignedBridgeLicense;
10440 	t->AssignedClientLicensesTotal = a->Server->CurrentAssignedClientLicense;
10441 
10442 	t->CurrentTick = Tick64();
10443 	t->CurrentTime = SystemTime64();
10444 
10445 	t->StartTime = a->Server->StartTime;
10446 
10447 	return ERR_NO_ERROR;
10448 }
10449 
10450 // Get server information
StGetServerInfo(ADMIN * a,RPC_SERVER_INFO * t)10451 UINT StGetServerInfo(ADMIN *a, RPC_SERVER_INFO *t)
10452 {
10453 	CEDAR *c;
10454 	OS_INFO *info;
10455 	SYSTEMTIME st;
10456 	// Validate arguments
10457 	if (a == NULL || t == NULL)
10458 	{
10459 		return ERR_INTERNAL_ERROR;
10460 	}
10461 
10462 	FreeRpcServerInfo(t);
10463 	Zero(t, sizeof(RPC_SERVER_INFO));
10464 
10465 	c = a->Server->Cedar;
10466 
10467 	GetServerProductName(a->Server, t->ServerProductName, sizeof(t->ServerProductName));
10468 
10469 	StrCpy(t->ServerVersionString, sizeof(t->ServerVersionString), c->VerString);
10470 	StrCpy(t->ServerBuildInfoString, sizeof(t->ServerBuildInfoString), c->BuildInfo);
10471 	t->ServerVerInt = c->Version;
10472 	t->ServerBuildInt = c->Build;
10473 	GetMachineName(t->ServerHostName, sizeof(t->ServerHostName));
10474 	t->ServerType = c->Server->ServerType;
10475 
10476 	Zero(&st, sizeof(st));
10477 	st.wYear = BUILD_DATE_Y;
10478 	st.wMonth = BUILD_DATE_M;
10479 	st.wDay = BUILD_DATE_D;
10480 	st.wHour = BUILD_DATE_HO;
10481 	st.wMinute = BUILD_DATE_MI;
10482 	st.wSecond = BUILD_DATE_SE;
10483 
10484 	t->ServerBuildDate = SystemToUINT64(&st);
10485 	StrCpy(t->ServerFamilyName, sizeof(t->ServerFamilyName), UPDATE_FAMILY_NAME);
10486 
10487 	info = GetOsInfo();
10488 	if (info != NULL)
10489 	{
10490 		CopyOsInfo(&t->OsInfo, info);
10491 	}
10492 
10493 	return ERR_NO_ERROR;
10494 }
10495 
10496 // Copy OS_INFO
CopyOsInfo(OS_INFO * dst,OS_INFO * info)10497 void CopyOsInfo(OS_INFO *dst, OS_INFO *info)
10498 {
10499 	// Validate arguments
10500 	if (info == NULL || dst == NULL)
10501 	{
10502 		return;
10503 	}
10504 
10505 	dst->OsType = info->OsType;
10506 	dst->OsServicePack = info->OsServicePack;
10507 	dst->OsSystemName = CopyStr(info->OsSystemName);
10508 	dst->OsProductName = CopyStr(info->OsProductName);
10509 	dst->OsVendorName = CopyStr(info->OsVendorName);
10510 	dst->OsVersion = CopyStr(info->OsVersion);
10511 	dst->KernelName = CopyStr(info->KernelName);
10512 	dst->KernelVersion = CopyStr(info->KernelVersion);
10513 }
10514 
10515 // OPENVPN_SSTP_CONFIG
InOpenVpnSstpConfig(OPENVPN_SSTP_CONFIG * t,PACK * p)10516 void InOpenVpnSstpConfig(OPENVPN_SSTP_CONFIG *t, PACK *p)
10517 {
10518 	// Validate arguments
10519 	if (t == NULL || p == NULL)
10520 	{
10521 		return;
10522 	}
10523 
10524 	Zero(t, sizeof(OPENVPN_SSTP_CONFIG));
10525 
10526 	t->EnableOpenVPN = PackGetBool(p, "EnableOpenVPN");
10527 	t->EnableSSTP = PackGetBool(p, "EnableSSTP");
10528 }
OutOpenVpnSstpConfig(PACK * p,OPENVPN_SSTP_CONFIG * t)10529 void OutOpenVpnSstpConfig(PACK *p, OPENVPN_SSTP_CONFIG *t)
10530 {
10531 	// Validate arguments
10532 	if (t == NULL || p == NULL)
10533 	{
10534 		return;
10535 	}
10536 
10537 	PackAddBool(p, "EnableOpenVPN", t->EnableOpenVPN);
10538 	PackAddBool(p, "EnableSSTP", t->EnableSSTP);
10539 }
10540 
10541 // DDNS_CLIENT_STATUS
InDDnsClientStatus(DDNS_CLIENT_STATUS * t,PACK * p)10542 void InDDnsClientStatus(DDNS_CLIENT_STATUS *t, PACK *p)
10543 {
10544 	// Validate arguments
10545 	if (t == NULL || p == NULL)
10546 	{
10547 		return;
10548 	}
10549 
10550 	Zero(t, sizeof(DDNS_CLIENT_STATUS));
10551 
10552 	t->Err_IPv4 = PackGetInt(p, "Err_IPv4");
10553 	t->Err_IPv6 = PackGetInt(p, "Err_IPv6");
10554 
10555 	PackGetStr(p, "CurrentHostName", t->CurrentHostName, sizeof(t->CurrentHostName));
10556 	PackGetStr(p, "CurrentFqdn", t->CurrentFqdn, sizeof(t->CurrentFqdn));
10557 	PackGetStr(p, "DnsSuffix", t->DnsSuffix, sizeof(t->DnsSuffix));
10558 	PackGetStr(p, "CurrentIPv4", t->CurrentIPv4, sizeof(t->CurrentIPv4));
10559 	PackGetStr(p, "CurrentIPv6", t->CurrentIPv6, sizeof(t->CurrentIPv6));
10560 	PackGetUniStr(p, "ErrStr_IPv4", t->ErrStr_IPv4, sizeof(t->ErrStr_IPv4));
10561 	PackGetUniStr(p, "ErrStr_IPv6", t->ErrStr_IPv6, sizeof(t->ErrStr_IPv6));
10562 }
OutDDnsClientStatus(PACK * p,DDNS_CLIENT_STATUS * t)10563 void OutDDnsClientStatus(PACK *p, DDNS_CLIENT_STATUS *t)
10564 {
10565 	// Validate arguments
10566 	if (t == NULL || p == NULL)
10567 	{
10568 		return;
10569 	}
10570 
10571 	PackAddInt(p, "Err_IPv4", t->Err_IPv4);
10572 	PackAddInt(p, "Err_IPv6", t->Err_IPv6);
10573 	PackAddStr(p, "CurrentHostName", t->CurrentHostName);
10574 	PackAddStr(p, "CurrentFqdn", t->CurrentFqdn);
10575 	PackAddStr(p, "DnsSuffix", t->DnsSuffix);
10576 	PackAddStr(p, "CurrentIPv4", t->CurrentIPv4);
10577 	PackAddStr(p, "CurrentIPv6", t->CurrentIPv6);
10578 	PackAddUniStr(p, "ErrStr_IPv4", t->ErrStr_IPv4);
10579 	PackAddUniStr(p, "ErrStr_IPv6", t->ErrStr_IPv6);
10580 }
10581 
10582 // INTERNET_SETTING
InRpcInternetSetting(INTERNET_SETTING * t,PACK * p)10583 void InRpcInternetSetting(INTERNET_SETTING *t, PACK *p)
10584 {
10585 	// Validate arguments
10586 	if (t == NULL || p == NULL)
10587 	{
10588 		return;
10589 	}
10590 
10591 	t->ProxyType = PackGetInt(p, "ProxyType");
10592 	PackGetStr(p, "ProxyHostName", t->ProxyHostName, sizeof(t->ProxyHostName));
10593 	t->ProxyPort = PackGetInt(p, "ProxyPort");
10594 	PackGetStr(p, "ProxyUsername", t->ProxyUsername, sizeof(t->ProxyUsername));
10595 	PackGetStr(p, "ProxyPassword", t->ProxyPassword, sizeof(t->ProxyPassword));
10596 	PackGetStr(p, "CustomHttpHeader", t->CustomHttpHeader, sizeof(t->CustomHttpHeader));
10597 }
OutRpcInternetSetting(PACK * p,INTERNET_SETTING * t)10598 void OutRpcInternetSetting(PACK *p, INTERNET_SETTING *t)
10599 {
10600 	// Validate arguments
10601 	if (t == NULL || p == NULL)
10602 	{
10603 		return;
10604 	}
10605 
10606 	PackAddInt(p, "ProxyType", t->ProxyType);
10607 	PackAddStr(p, "ProxyHostName", t->ProxyHostName);
10608 	PackAddInt(p, "ProxyPort", t->ProxyPort);
10609 	PackAddStr(p, "ProxyUsername", t->ProxyUsername);
10610 	PackAddStr(p, "ProxyPassword", t->ProxyPassword);
10611 	PackAddStr(p, "CustomHttpHeader", t->CustomHttpHeader);
10612 }
10613 
10614 // RPC_AZURE_STATUS
InRpcAzureStatus(RPC_AZURE_STATUS * t,PACK * p)10615 void InRpcAzureStatus(RPC_AZURE_STATUS *t, PACK *p)
10616 {
10617 	// Validate arguments
10618 	if (t == NULL || p == NULL)
10619 	{
10620 		return;
10621 	}
10622 
10623 	Zero(t, sizeof(RPC_AZURE_STATUS));
10624 
10625 	t->IsConnected = PackGetBool(p, "IsConnected");
10626 	t->IsEnabled = PackGetBool(p, "IsEnabled");
10627 }
OutRpcAzureStatus(PACK * p,RPC_AZURE_STATUS * t)10628 void OutRpcAzureStatus(PACK *p, RPC_AZURE_STATUS *t)
10629 {
10630 	// Validate arguments
10631 	if (t == NULL || p == NULL)
10632 	{
10633 		return;
10634 	}
10635 
10636 	PackAddBool(p, "IsConnected", t->IsConnected);
10637 	PackAddBool(p, "IsEnabled", t->IsEnabled);
10638 }
10639 
10640 // RPC_SPECIAL_LISTENER
InRpcSpecialListener(RPC_SPECIAL_LISTENER * t,PACK * p)10641 void InRpcSpecialListener(RPC_SPECIAL_LISTENER *t, PACK *p)
10642 {
10643 	// Validate arguments
10644 	if (t == NULL || p == NULL)
10645 	{
10646 		return;
10647 	}
10648 
10649 	Zero(t, sizeof(RPC_SPECIAL_LISTENER));
10650 
10651 	t->VpnOverIcmpListener = PackGetBool(p, "VpnOverIcmpListener");
10652 	t->VpnOverDnsListener = PackGetBool(p, "VpnOverDnsListener");
10653 }
OutRpcSpecialListener(PACK * p,RPC_SPECIAL_LISTENER * t)10654 void OutRpcSpecialListener(PACK *p, RPC_SPECIAL_LISTENER *t)
10655 {
10656 	// Validate arguments
10657 	if (t == NULL || p == NULL)
10658 	{
10659 		return;
10660 	}
10661 
10662 	PackAddBool(p, "VpnOverIcmpListener", t->VpnOverIcmpListener);
10663 	PackAddBool(p, "VpnOverDnsListener", t->VpnOverDnsListener);
10664 }
10665 
10666 
10667 // ETHERIP_ID
InEtherIpId(ETHERIP_ID * t,PACK * p)10668 void InEtherIpId(ETHERIP_ID *t, PACK *p)
10669 {
10670 	// Validate arguments
10671 	if (t == NULL || p == NULL)
10672 	{
10673 		return;
10674 	}
10675 
10676 	Zero(t, sizeof(ETHERIP_ID));
10677 
10678 	PackGetStr(p, "Id", t->Id, sizeof(t->Id));
10679 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
10680 	PackGetStr(p, "UserName", t->UserName, sizeof(t->UserName));
10681 	PackGetStr(p, "Password", t->Password, sizeof(t->Password));
10682 }
OutEtherIpId(PACK * p,ETHERIP_ID * t)10683 void OutEtherIpId(PACK *p, ETHERIP_ID *t)
10684 {
10685 	// Validate arguments
10686 	if (t == NULL || p == NULL)
10687 	{
10688 		return;
10689 	}
10690 
10691 	PackAddStr(p, "Id", t->Id);
10692 	PackAddStr(p, "HubName", t->HubName);
10693 	PackAddStr(p, "UserName", t->UserName);
10694 	PackAddStr(p, "Password", t->Password);
10695 }
10696 
10697 // RPC_ENUM_ETHERIP_ID
InRpcEnumEtherIpId(RPC_ENUM_ETHERIP_ID * t,PACK * p)10698 void InRpcEnumEtherIpId(RPC_ENUM_ETHERIP_ID *t, PACK *p)
10699 {
10700 	UINT i;
10701 	// Validate arguments
10702 	if (t == NULL || p == NULL)
10703 	{
10704 		return;
10705 	}
10706 
10707 	Zero(t, sizeof(RPC_ENUM_ETHERIP_ID));
10708 
10709 	t->NumItem = PackGetInt(p, "NumItem");
10710 	t->IdList = ZeroMalloc(sizeof(ETHERIP_ID) * t->NumItem);
10711 
10712 	for (i = 0;i < t->NumItem;i++)
10713 	{
10714 		ETHERIP_ID *e = &t->IdList[i];
10715 
10716 		PackGetStrEx(p, "Id", e->Id, sizeof(e->Id), i);
10717 		PackGetStrEx(p, "HubName", e->HubName, sizeof(e->HubName), i);
10718 		PackGetStrEx(p, "UserName", e->UserName, sizeof(e->UserName), i);
10719 		PackGetStrEx(p, "Password", e->Password, sizeof(e->Password), i);
10720 	}
10721 }
OutRpcEnumEtherIpId(PACK * p,RPC_ENUM_ETHERIP_ID * t)10722 void OutRpcEnumEtherIpId(PACK *p, RPC_ENUM_ETHERIP_ID *t)
10723 {
10724 	UINT i;
10725 	// Validate arguments
10726 	if (p == NULL || t == NULL)
10727 	{
10728 		return;
10729 	}
10730 
10731 	PackAddInt(p, "NumItem", t->NumItem);
10732 
10733 	PackSetCurrentJsonGroupName(p, "Settings");
10734 	for (i = 0;i < t->NumItem;i++)
10735 	{
10736 		ETHERIP_ID *e = &t->IdList[i];
10737 
10738 		PackAddStrEx(p, "Id", e->Id, i, t->NumItem);
10739 		PackAddStrEx(p, "HubName", e->HubName, i, t->NumItem);
10740 		PackAddStrEx(p, "UserName", e->UserName, i, t->NumItem);
10741 		PackAddStrEx(p, "Password", e->Password, i, t->NumItem);
10742 	}
10743 	PackSetCurrentJsonGroupName(p, NULL);
10744 }
FreeRpcEnumEtherIpId(RPC_ENUM_ETHERIP_ID * t)10745 void FreeRpcEnumEtherIpId(RPC_ENUM_ETHERIP_ID *t)
10746 {
10747 	// Validate arguments
10748 	if (t == NULL)
10749 	{
10750 		return;
10751 	}
10752 
10753 	Free(t->IdList);
10754 }
10755 
10756 // IPSEC_SERVICES
InIPsecServices(IPSEC_SERVICES * t,PACK * p)10757 void InIPsecServices(IPSEC_SERVICES *t, PACK *p)
10758 {
10759 	// Validate arguments
10760 	if (t == NULL || p == NULL)
10761 	{
10762 		return;
10763 	}
10764 
10765 	Zero(t, sizeof(IPSEC_SERVICES));
10766 
10767 	t->L2TP_Raw = PackGetBool(p, "L2TP_Raw");
10768 	t->L2TP_IPsec = PackGetBool(p, "L2TP_IPsec");
10769 	t->EtherIP_IPsec = PackGetBool(p, "EtherIP_IPsec");
10770 
10771 	PackGetStr(p, "IPsec_Secret", t->IPsec_Secret, sizeof(t->IPsec_Secret));
10772 	PackGetStr(p, "L2TP_DefaultHub", t->L2TP_DefaultHub, sizeof(t->L2TP_DefaultHub));
10773 }
OutIPsecServices(PACK * p,IPSEC_SERVICES * t)10774 void OutIPsecServices(PACK *p, IPSEC_SERVICES *t)
10775 {
10776 	// Validate arguments
10777 	if (t == NULL || p == NULL)
10778 	{
10779 		return;
10780 	}
10781 
10782 	PackAddBool(p, "L2TP_Raw", t->L2TP_Raw);
10783 	PackAddBool(p, "L2TP_IPsec", t->L2TP_IPsec);
10784 	PackAddBool(p, "EtherIP_IPsec", t->EtherIP_IPsec);
10785 
10786 	PackAddStr(p, "IPsec_Secret", t->IPsec_Secret);
10787 	PackAddStr(p, "L2TP_DefaultHub", t->L2TP_DefaultHub);
10788 }
10789 
10790 // RPC_WINVER
InRpcWinVer(RPC_WINVER * t,PACK * p)10791 void InRpcWinVer(RPC_WINVER *t, PACK *p)
10792 {
10793 	// Validate arguments
10794 	if (t == NULL || p == NULL)
10795 	{
10796 		return;
10797 	}
10798 
10799 	Zero(t, sizeof(RPC_WINVER));
10800 
10801 	t->IsWindows = PackGetBool(p, "V_IsWindows");
10802 	t->IsNT = PackGetBool(p, "V_IsNT");
10803 	t->IsServer = PackGetBool(p, "V_IsServer");
10804 	t->IsBeta = PackGetBool(p, "V_IsBeta");
10805 	t->VerMajor = PackGetInt(p, "V_VerMajor");
10806 	t->VerMinor = PackGetInt(p, "V_VerMinor");
10807 	t->Build = PackGetInt(p, "V_Build");
10808 	t->ServicePack = PackGetInt(p, "V_ServicePack");
10809 	PackGetStr(p, "V_Title", t->Title, sizeof(t->Title));
10810 }
OutRpcWinVer(PACK * p,RPC_WINVER * t)10811 void OutRpcWinVer(PACK *p, RPC_WINVER *t)
10812 {
10813 	// Validate arguments
10814 	if (t == NULL || p == NULL)
10815 	{
10816 		return;
10817 	}
10818 
10819 	PackAddBool(p, "V_IsWindows", t->IsWindows);
10820 	PackAddBool(p, "V_IsNT", t->IsNT);
10821 	PackAddBool(p, "V_IsServer", t->IsServer);
10822 	PackAddBool(p, "V_IsBeta", t->IsBeta);
10823 	PackAddInt(p, "V_VerMajor", t->VerMajor);
10824 	PackAddInt(p, "V_VerMinor", t->VerMinor);
10825 	PackAddInt(p, "V_Build", t->Build);
10826 	PackAddInt(p, "V_ServicePack", t->ServicePack);
10827 	PackAddStr(p, "V_Title", t->Title);
10828 }
10829 
10830 // RPC_MSG
InRpcMsg(RPC_MSG * t,PACK * p)10831 void InRpcMsg(RPC_MSG *t, PACK *p)
10832 {
10833 	UINT size;
10834 	char *utf8;
10835 	// Validate arguments
10836 	if (t == NULL || p == NULL)
10837 	{
10838 		return;
10839 	}
10840 
10841 	Zero(t, sizeof(RPC_MSG));
10842 
10843 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
10844 	size = PackGetDataSize(p, "Msg");
10845 	utf8 = ZeroMalloc(size + 8);
10846 	PackGetData(p, "Msg", utf8);
10847 	t->Msg = CopyUtfToUni(utf8);
10848 	Free(utf8);
10849 }
OutRpcMsg(PACK * p,RPC_MSG * t)10850 void OutRpcMsg(PACK *p, RPC_MSG *t)
10851 {
10852 	UINT size;
10853 	char *utf8;
10854 	// Validate arguments
10855 	if (t == NULL || p == NULL)
10856 	{
10857 		return;
10858 	}
10859 
10860 	PackAddStr(p, "HubName", t->HubName);
10861 	utf8 = CopyUniToUtf(t->Msg);
10862 	size = StrLen(utf8);
10863 	PackAddData(p, "Msg", utf8, size);
10864 	Free(utf8);
10865 }
FreeRpcMsg(RPC_MSG * t)10866 void FreeRpcMsg(RPC_MSG *t)
10867 {
10868 	// Validate arguments
10869 	if (t == NULL)
10870 	{
10871 		return;
10872 	}
10873 
10874 	Free(t->Msg);
10875 }
10876 
10877 // RPC_ENUM_ETH_VLAN
InRpcEnumEthVLan(RPC_ENUM_ETH_VLAN * t,PACK * p)10878 void InRpcEnumEthVLan(RPC_ENUM_ETH_VLAN *t, PACK *p)
10879 {
10880 	UINT i;
10881 	// Validate arguments
10882 	if (t == NULL || p == NULL)
10883 	{
10884 		return;
10885 	}
10886 
10887 	Zero(t, sizeof(RPC_ENUM_ETH_VLAN));
10888 
10889 	t->NumItem = PackGetIndexCount(p, "DeviceName");
10890 	t->Items = ZeroMalloc(sizeof(RPC_ENUM_ETH_VLAN_ITEM) * t->NumItem);
10891 
10892 	for (i = 0;i < t->NumItem;i++)
10893 	{
10894 		RPC_ENUM_ETH_VLAN_ITEM *e = &t->Items[i];
10895 
10896 		PackGetStrEx(p, "DeviceName", e->DeviceName, sizeof(e->DeviceName), i);
10897 		PackGetStrEx(p, "Guid", e->Guid, sizeof(e->Guid), i);
10898 		PackGetStrEx(p, "DeviceInstanceId", e->DeviceInstanceId, sizeof(e->DeviceInstanceId), i);
10899 		PackGetStrEx(p, "DriverName", e->DriverName, sizeof(e->DriverName), i);
10900 		PackGetStrEx(p, "DriverType", e->DriverType, sizeof(e->DriverType), i);
10901 		e->Support = PackGetBoolEx(p, "Support", i);
10902 		e->Enabled = PackGetBoolEx(p, "Enabled", i);
10903 	}
10904 }
OutRpcEnumEthVLan(PACK * p,RPC_ENUM_ETH_VLAN * t)10905 void OutRpcEnumEthVLan(PACK *p, RPC_ENUM_ETH_VLAN *t)
10906 {
10907 	UINT i;
10908 	// Validate arguments
10909 	if (t == NULL || p == NULL)
10910 	{
10911 		return;
10912 	}
10913 
10914 	PackSetCurrentJsonGroupName(p, "Devices");
10915 	for (i = 0;i < t->NumItem;i++)
10916 	{
10917 		RPC_ENUM_ETH_VLAN_ITEM *e = &t->Items[i];
10918 
10919 		PackAddStrEx(p, "DeviceName", e->DeviceName, i, t->NumItem);
10920 		PackAddStrEx(p, "Guid", e->Guid, i, t->NumItem);
10921 		PackAddStrEx(p, "DeviceInstanceId", e->DeviceInstanceId, i, t->NumItem);
10922 		PackAddStrEx(p, "DriverName", e->DriverName, i, t->NumItem);
10923 		PackAddStrEx(p, "DriverType", e->DriverType, i, t->NumItem);
10924 		PackAddBoolEx(p, "Support", e->Support, i, t->NumItem);
10925 		PackAddBoolEx(p, "Enabled", e->Enabled, i, t->NumItem);
10926 	}
10927 	PackSetCurrentJsonGroupName(p, NULL);
10928 }
FreeRpcEnumEthVLan(RPC_ENUM_ETH_VLAN * t)10929 void FreeRpcEnumEthVLan(RPC_ENUM_ETH_VLAN *t)
10930 {
10931 	// Validate arguments
10932 	if (t == NULL)
10933 	{
10934 		return;
10935 	}
10936 
10937 	Free(t->Items);
10938 }
10939 
10940 // RPC_ENUM_LOG_FILE
InRpcEnumLogFile(RPC_ENUM_LOG_FILE * t,PACK * p)10941 void InRpcEnumLogFile(RPC_ENUM_LOG_FILE *t, PACK *p)
10942 {
10943 	UINT i;
10944 	// Validate arguments
10945 	if (t == NULL || p == NULL)
10946 	{
10947 		return;
10948 	}
10949 
10950 	Zero(t, sizeof(RPC_ENUM_LOG_FILE));
10951 	t->NumItem = PackGetInt(p, "NumItem");
10952 	t->Items = ZeroMalloc(sizeof(RPC_ENUM_LOG_FILE_ITEM) * t->NumItem);
10953 
10954 	for (i = 0;i < t->NumItem;i++)
10955 	{
10956 		RPC_ENUM_LOG_FILE_ITEM *e = &t->Items[i];
10957 
10958 		PackGetStrEx(p, "FilePath", e->FilePath, sizeof(e->FilePath), i);
10959 		PackGetStrEx(p, "ServerName", e->ServerName, sizeof(e->ServerName), i);
10960 		e->FileSize = PackGetIntEx(p, "FileSize", i);
10961 		e->UpdatedTime = PackGetInt64Ex(p, "UpdatedTime", i);
10962 	}
10963 }
OutRpcEnumLogFile(PACK * p,RPC_ENUM_LOG_FILE * t)10964 void OutRpcEnumLogFile(PACK *p, RPC_ENUM_LOG_FILE *t)
10965 {
10966 	UINT i;
10967 	// Validate arguments
10968 	if (t == NULL || p == NULL)
10969 	{
10970 		return;
10971 	}
10972 
10973 	PackAddInt(p, "NumItem", t->NumItem);
10974 
10975 	PackSetCurrentJsonGroupName(p, "LogFiles");
10976 	for (i = 0;i < t->NumItem;i++)
10977 	{
10978 		RPC_ENUM_LOG_FILE_ITEM *e = &t->Items[i];
10979 
10980 		PackAddStrEx(p, "FilePath", e->FilePath, i, t->NumItem);
10981 		PackAddStrEx(p, "ServerName", e->ServerName, i, t->NumItem);
10982 		PackAddIntEx(p, "FileSize", e->FileSize, i, t->NumItem);
10983 		PackAddTime64Ex(p, "UpdatedTime", e->UpdatedTime, i, t->NumItem);
10984 	}
10985 	PackSetCurrentJsonGroupName(p, NULL);
10986 }
FreeRpcEnumLogFile(RPC_ENUM_LOG_FILE * t)10987 void FreeRpcEnumLogFile(RPC_ENUM_LOG_FILE *t)
10988 {
10989 	// Validate arguments
10990 	if (t == NULL)
10991 	{
10992 		return;
10993 	}
10994 
10995 	Free(t->Items);
10996 }
AdjoinRpcEnumLogFile(RPC_ENUM_LOG_FILE * t,RPC_ENUM_LOG_FILE * src)10997 void AdjoinRpcEnumLogFile(RPC_ENUM_LOG_FILE *t, RPC_ENUM_LOG_FILE *src)
10998 {
10999 	LIST *o;
11000 	UINT i;
11001 	// Validate arguments
11002 	if (t == NULL || src == NULL)
11003 	{
11004 		return;
11005 	}
11006 
11007 	o = NewListFast(CmpLogFile);
11008 
11009 	for (i = 0;i < t->NumItem;i++)
11010 	{
11011 		RPC_ENUM_LOG_FILE_ITEM *e = &t->Items[i];
11012 		LOG_FILE *f = ZeroMalloc(sizeof(LOG_FILE));
11013 
11014 		f->FileSize = e->FileSize;
11015 		StrCpy(f->Path, sizeof(f->Path), e->FilePath);
11016 		StrCpy(f->ServerName, sizeof(f->ServerName), e->ServerName);
11017 		f->UpdatedTime = e->UpdatedTime;
11018 
11019 		Add(o, f);
11020 	}
11021 
11022 	for (i = 0;i < src->NumItem;i++)
11023 	{
11024 		RPC_ENUM_LOG_FILE_ITEM *e = &src->Items[i];
11025 		LOG_FILE *f = ZeroMalloc(sizeof(LOG_FILE));
11026 
11027 		f->FileSize = e->FileSize;
11028 		StrCpy(f->Path, sizeof(f->Path), e->FilePath);
11029 		StrCpy(f->ServerName, sizeof(f->ServerName), e->ServerName);
11030 		f->UpdatedTime = e->UpdatedTime;
11031 
11032 		Add(o, f);
11033 	}
11034 
11035 	FreeRpcEnumLogFile(t);
11036 
11037 	Sort(o);
11038 
11039 	Zero(t, sizeof(RPC_ENUM_LOG_FILE));
11040 	t->NumItem = LIST_NUM(o);
11041 	t->Items = ZeroMalloc(sizeof(RPC_ENUM_LOG_FILE_ITEM) * t->NumItem);
11042 
11043 	for (i = 0;i < t->NumItem;i++)
11044 	{
11045 		LOG_FILE *f = LIST_DATA(o, i);
11046 		RPC_ENUM_LOG_FILE_ITEM *e = &t->Items[i];
11047 
11048 		StrCpy(e->FilePath, sizeof(e->FilePath), f->Path);
11049 		StrCpy(e->ServerName, sizeof(e->ServerName), f->ServerName);
11050 		e->FileSize = f->FileSize;
11051 		e->UpdatedTime = f->UpdatedTime;
11052 	}
11053 
11054 	FreeEnumLogFile(o);
11055 }
11056 
11057 // RPC_READ_LOG_FILE
InRpcReadLogFile(RPC_READ_LOG_FILE * t,PACK * p)11058 void InRpcReadLogFile(RPC_READ_LOG_FILE *t, PACK *p)
11059 {
11060 	// Validate arguments
11061 	if (t == NULL || p == NULL)
11062 	{
11063 		return;
11064 	}
11065 
11066 	Zero(t, sizeof(RPC_READ_LOG_FILE));
11067 	PackGetStr(p, "FilePath", t->FilePath, sizeof(t->FilePath));
11068 	PackGetStr(p, "ServerName", t->ServerName, sizeof(t->ServerName));
11069 	t->Offset = PackGetInt(p, "Offset");
11070 
11071 	t->Buffer = PackGetBuf(p, "Buffer");
11072 }
OutRpcReadLogFile(PACK * p,RPC_READ_LOG_FILE * t)11073 void OutRpcReadLogFile(PACK *p, RPC_READ_LOG_FILE *t)
11074 {
11075 	// Validate arguments
11076 	if (p == NULL || t == NULL)
11077 	{
11078 		return;
11079 	}
11080 
11081 	PackAddStr(p, "FilePath", t->FilePath);
11082 	PackAddStr(p, "ServerName", t->ServerName);
11083 	PackAddInt(p, "Offset", t->Offset);
11084 
11085 	if (t->Buffer != NULL)
11086 	{
11087 		PackAddBuf(p, "Buffer", t->Buffer);
11088 	}
11089 }
FreeRpcReadLogFile(RPC_READ_LOG_FILE * t)11090 void FreeRpcReadLogFile(RPC_READ_LOG_FILE *t)
11091 {
11092 	// Validate arguments
11093 	if (t == NULL)
11094 	{
11095 		return;
11096 	}
11097 
11098 	if (t->Buffer != NULL)
11099 	{
11100 		FreeBuf(t->Buffer);
11101 	}
11102 }
11103 
11104 // RPC_AC_LIST
InRpcAcList(RPC_AC_LIST * t,PACK * p)11105 void InRpcAcList(RPC_AC_LIST *t, PACK *p)
11106 {
11107 	UINT i;
11108 	LIST *o;
11109 	UINT num;
11110 	// Validate arguments
11111 	if (t == NULL || p == NULL)
11112 	{
11113 		return;
11114 	}
11115 
11116 	Zero(t, sizeof(RPC_AC_LIST));
11117 	o = NewAcList();
11118 
11119 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
11120 	num = PackGetIndexCount(p, "IpAddress");
11121 
11122 	for (i = 0;i < num;i++)
11123 	{
11124 		AC *ac = ZeroMalloc(sizeof(AC));
11125 
11126 		ac->Id = PackGetIntEx(p, "Id", i);
11127 		ac->Deny = PackGetBoolEx(p, "Deny", i);
11128 		PackGetIpEx(p, "IpAddress", &ac->IpAddress, i);
11129 		ac->Masked = PackGetBoolEx(p, "Masked", i);
11130 
11131 		if (ac->Masked)
11132 		{
11133 			PackGetIpEx(p, "SubnetMask", &ac->SubnetMask, i);
11134 		}
11135 
11136 		ac->Priority = PackGetIntEx(p, "Priority", i);
11137 
11138 		AddAc(o, ac);
11139 
11140 		Free(ac);
11141 	}
11142 
11143 	t->o = o;
11144 }
OutRpcAcList(PACK * p,RPC_AC_LIST * t)11145 void OutRpcAcList(PACK *p, RPC_AC_LIST *t)
11146 {
11147 	UINT i, num;
11148 	LIST *o;
11149 	// Validate arguments
11150 	if (t == NULL || p == NULL)
11151 	{
11152 		return;
11153 	}
11154 
11155 	o = t->o;
11156 	num = LIST_NUM(o);
11157 
11158 	PackAddInt(p, "NumItem", num);
11159 
11160 	PackAddStr(p, "HubName", t->HubName);
11161 
11162 	PackSetCurrentJsonGroupName(p, "ACList");
11163 	for (i = 0;i < num;i++)
11164 	{
11165 		AC *ac = LIST_DATA(o, i);
11166 
11167 		PackAddIntEx(p, "Id", ac->Id, i, num);
11168 		PackAddBoolEx(p, "Deny", ac->Deny, i, num);
11169 		PackAddIpEx(p, "IpAddress", &ac->IpAddress, i, num);
11170 		PackAddBoolEx(p, "Masked", ac->Masked, i, num);
11171 
11172 		PackAddIpEx(p, "SubnetMask", &ac->SubnetMask, i, num);
11173 
11174 		PackAddIntEx(p, "Priority", ac->Priority, i, num);
11175 	}
11176 	PackSetCurrentJsonGroupName(p, NULL);
11177 }
FreeRpcAcList(RPC_AC_LIST * t)11178 void FreeRpcAcList(RPC_AC_LIST *t)
11179 {
11180 	// Validate arguments
11181 	if (t == NULL)
11182 	{
11183 		return;
11184 	}
11185 
11186 	FreeAcList(t->o);
11187 }
11188 
11189 // RPC_INT
InRpcInt(RPC_INT * t,PACK * p)11190 void InRpcInt(RPC_INT *t, PACK *p)
11191 {
11192 	// Validate arguments
11193 	if (t == NULL || p == NULL)
11194 	{
11195 		return;
11196 	}
11197 
11198 	Zero(t, sizeof(RPC_INT));
11199 	t->IntValue = PackGetInt(p, "IntValue");
11200 }
OutRpcInt(PACK * p,RPC_INT * t)11201 void OutRpcInt(PACK *p, RPC_INT *t)
11202 {
11203 	// Validate arguments
11204 	if (t == NULL || p == NULL)
11205 	{
11206 		return;
11207 	}
11208 
11209 	PackAddInt(p, "IntValue", t->IntValue);
11210 }
11211 
11212 // RPC_ENUM_CRL
InRpcEnumCrl(RPC_ENUM_CRL * t,PACK * p)11213 void InRpcEnumCrl(RPC_ENUM_CRL *t, PACK *p)
11214 {
11215 	UINT i;
11216 	// Validate arguments
11217 	if (t == NULL || p == NULL)
11218 	{
11219 		return;
11220 	}
11221 
11222 	Zero(t, sizeof(RPC_ENUM_CRL));
11223 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
11224 	t->NumItem = PackGetInt(p, "NumItem");
11225 
11226 	t->Items = ZeroMalloc(sizeof(RPC_ENUM_CRL_ITEM) * t->NumItem);
11227 	for (i = 0;i < t->NumItem;i++)
11228 	{
11229 		RPC_ENUM_CRL_ITEM *e = &t->Items[i];
11230 
11231 		e->Key = PackGetIntEx(p, "Key", i);
11232 		PackGetUniStrEx(p, "CrlInfo", e->CrlInfo, sizeof(e->CrlInfo), i);
11233 	}
11234 }
OutRpcEnumCrl(PACK * p,RPC_ENUM_CRL * t)11235 void OutRpcEnumCrl(PACK *p, RPC_ENUM_CRL *t)
11236 {
11237 	UINT i;
11238 	// Validate arguments
11239 	if (t == NULL || p == NULL)
11240 	{
11241 		return;
11242 	}
11243 
11244 	PackAddStr(p, "HubName", t->HubName);
11245 	PackAddInt(p, "NumItem", t->NumItem);
11246 
11247 	PackSetCurrentJsonGroupName(p, "CRLList");
11248 	for (i = 0;i < t->NumItem;i++)
11249 	{
11250 		RPC_ENUM_CRL_ITEM *e = &t->Items[i];
11251 
11252 		PackAddIntEx(p, "Key", e->Key, i, t->NumItem);
11253 		PackAddUniStrEx(p, "CrlInfo", e->CrlInfo, i, t->NumItem);
11254 	}
11255 	PackSetCurrentJsonGroupName(p, NULL);
11256 }
FreeRpcEnumCrl(RPC_ENUM_CRL * t)11257 void FreeRpcEnumCrl(RPC_ENUM_CRL *t)
11258 {
11259 	// Validate arguments
11260 	if (t == NULL)
11261 	{
11262 		return;
11263 	}
11264 
11265 	Free(t->Items);
11266 }
11267 
11268 // RPC_CRL
InRpcCrl(RPC_CRL * t,PACK * p)11269 void InRpcCrl(RPC_CRL *t, PACK *p)
11270 {
11271 	BUF *b;
11272 	NAME *n;
11273 	wchar_t tmp[MAX_SIZE];
11274 	// Validate arguments
11275 	if (t == NULL || p == NULL)
11276 	{
11277 		return;
11278 	}
11279 
11280 	Zero(t, sizeof(RPC_CRL));
11281 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
11282 	t->Key = PackGetInt(p, "Key");
11283 	b = PackGetBuf(p, "Serial");
11284 	t->Crl = ZeroMalloc(sizeof(CRL));
11285 	if (b != NULL)
11286 	{
11287 		t->Crl->Serial = NewXSerial(b->Buf, b->Size);
11288 		FreeBuf(b);
11289 	}
11290 	t->Crl->Name = ZeroMalloc(sizeof(NAME));
11291 	n = t->Crl->Name;
11292 	if (PackGetUniStr(p, "CommonName", tmp, sizeof(tmp)))
11293 	{
11294 		n->CommonName = CopyUniStr(tmp);
11295 	}
11296 	if (PackGetUniStr(p, "Organization", tmp, sizeof(tmp)))
11297 	{
11298 		n->Organization = CopyUniStr(tmp);
11299 	}
11300 	if (PackGetUniStr(p, "Unit", tmp, sizeof(tmp)))
11301 	{
11302 		n->Unit = CopyUniStr(tmp);
11303 	}
11304 	if (PackGetUniStr(p, "Country", tmp, sizeof(tmp)))
11305 	{
11306 		n->Country = CopyUniStr(tmp);
11307 	}
11308 	if (PackGetUniStr(p, "State", tmp, sizeof(tmp)))
11309 	{
11310 		n->State = CopyUniStr(tmp);
11311 	}
11312 	if (PackGetUniStr(p, "Local", tmp, sizeof(tmp)))
11313 	{
11314 		n->Local = CopyUniStr(tmp);
11315 	}
11316 	if (PackGetDataSize(p, "DigestMD5") == MD5_SIZE)
11317 	{
11318 		PackGetData(p, "DigestMD5", t->Crl->DigestMD5);
11319 	}
11320 	if (PackGetDataSize(p, "DigestSHA1") == SHA1_SIZE)
11321 	{
11322 		PackGetData(p, "DigestSHA1", t->Crl->DigestSHA1);
11323 	}
11324 }
OutRpcCrl(PACK * p,RPC_CRL * t)11325 void OutRpcCrl(PACK *p, RPC_CRL *t)
11326 {
11327 	NAME *n;
11328 	// Validate arguments
11329 	if (p == NULL || t == NULL)
11330 	{
11331 		return;
11332 	}
11333 
11334 	PackAddStr(p, "HubName", t->HubName);
11335 	PackAddInt(p, "Key", t->Key);
11336 
11337 	if (t->Crl == NULL)
11338 	{
11339 		return;
11340 	}
11341 
11342 	if (t->Crl->Serial != NULL)
11343 	{
11344 		PackAddData(p, "Serial", t->Crl->Serial->data, t->Crl->Serial->size);
11345 	}
11346 	n = t->Crl->Name;
11347 	if (n->CommonName != NULL)
11348 	{
11349 		PackAddUniStr(p, "CommonName", n->CommonName);
11350 	}
11351 	if (n->Organization != NULL)
11352 	{
11353 		PackAddUniStr(p, "Organization", n->Organization);
11354 	}
11355 	if (n->Unit != NULL)
11356 	{
11357 		PackAddUniStr(p, "Unit", n->Unit);
11358 	}
11359 	if (n->Country != NULL)
11360 	{
11361 		PackAddUniStr(p, "Country", n->Country);
11362 	}
11363 	if (n->State != NULL)
11364 	{
11365 		PackAddUniStr(p, "State", n->State);
11366 	}
11367 	if (n->Local != NULL)
11368 	{
11369 		PackAddUniStr(p, "Local", n->Local);
11370 	}
11371 	if (IsZero(t->Crl->DigestMD5, MD5_SIZE) == false)
11372 	{
11373 		PackAddData(p, "DigestMD5", t->Crl->DigestMD5, MD5_SIZE);
11374 	}
11375 	if (IsZero(t->Crl->DigestSHA1, SHA1_SIZE) == false)
11376 	{
11377 		PackAddData(p, "DigestSHA1", t->Crl->DigestSHA1, SHA1_SIZE);
11378 	}
11379 }
FreeRpcCrl(RPC_CRL * t)11380 void FreeRpcCrl(RPC_CRL *t)
11381 {
11382 	// Validate arguments
11383 	if (t == NULL)
11384 	{
11385 		return;
11386 	}
11387 
11388 	FreeCrl(t->Crl);
11389 }
11390 
11391 // RPC_ENUM_L3TABLE
InRpcEnumL3Table(RPC_ENUM_L3TABLE * t,PACK * p)11392 void InRpcEnumL3Table(RPC_ENUM_L3TABLE *t, PACK *p)
11393 {
11394 	UINT i;
11395 	// Validate arguments
11396 	if (t == NULL || p == NULL)
11397 	{
11398 		return;
11399 	}
11400 
11401 	Zero(t, sizeof(RPC_ENUM_L3TABLE));
11402 	t->NumItem = PackGetInt(p, "NumItem");
11403 	PackGetStr(p, "Name", t->Name, sizeof(t->Name));
11404 	t->Items = ZeroMalloc(sizeof(RPC_L3TABLE) * t->NumItem);
11405 
11406 	for (i = 0;i < t->NumItem;i++)
11407 	{
11408 		RPC_L3TABLE *e = &t->Items[i];
11409 
11410 		e->NetworkAddress = PackGetIp32Ex(p, "NetworkAddress", i);
11411 		e->SubnetMask = PackGetIp32Ex(p, "SubnetMask", i);
11412 		e->GatewayAddress = PackGetIp32Ex(p, "GatewayAddress", i);
11413 		e->Metric = PackGetIntEx(p, "Metric", i);
11414 	}
11415 }
OutRpcEnumL3Table(PACK * p,RPC_ENUM_L3TABLE * t)11416 void OutRpcEnumL3Table(PACK *p, RPC_ENUM_L3TABLE *t)
11417 {
11418 	UINT i;
11419 	// Validate arguments
11420 	if (p == NULL || t == NULL)
11421 	{
11422 		return;
11423 	}
11424 
11425 	PackAddInt(p, "NumItem", t->NumItem);
11426 	PackAddStr(p, "Name", t->Name);
11427 
11428 	PackSetCurrentJsonGroupName(p, "L3Table");
11429 	for (i = 0;i < t->NumItem;i++)
11430 	{
11431 		RPC_L3TABLE *e = &t->Items[i];
11432 
11433 		PackAddIp32Ex(p, "NetworkAddress", e->NetworkAddress, i, t->NumItem);
11434 		PackAddIp32Ex(p, "SubnetMask", e->SubnetMask, i, t->NumItem);
11435 		PackAddIp32Ex(p, "GatewayAddress", e->GatewayAddress, i, t->NumItem);
11436 		PackAddIntEx(p, "Metric", e->Metric, i, t->NumItem);
11437 	}
11438 	PackSetCurrentJsonGroupName(p, NULL);
11439 }
FreeRpcEnumL3Table(RPC_ENUM_L3TABLE * t)11440 void FreeRpcEnumL3Table(RPC_ENUM_L3TABLE *t)
11441 {
11442 	Free(t->Items);
11443 }
11444 
11445 // RPC_L3TABLE
InRpcL3Table(RPC_L3TABLE * t,PACK * p)11446 void InRpcL3Table(RPC_L3TABLE *t, PACK *p)
11447 {
11448 	// Validate arguments
11449 	if (t == NULL || p == NULL)
11450 	{
11451 		return;
11452 	}
11453 
11454 	Zero(t, sizeof(RPC_L3TABLE));
11455 	PackGetStr(p, "Name", t->Name, sizeof(t->Name));
11456 	t->NetworkAddress = PackGetIp32(p, "NetworkAddress");
11457 	t->SubnetMask = PackGetIp32(p, "SubnetMask");
11458 	t->GatewayAddress = PackGetIp32(p, "GatewayAddress");
11459 	t->Metric = PackGetInt(p, "Metric");
11460 }
OutRpcL3Table(PACK * p,RPC_L3TABLE * t)11461 void OutRpcL3Table(PACK *p, RPC_L3TABLE *t)
11462 {
11463 	// Validate arguments
11464 	if (p == NULL || t == NULL)
11465 	{
11466 		return;
11467 	}
11468 
11469 	PackAddStr(p, "Name", t->Name);
11470 	PackAddIp32(p, "NetworkAddress", t->NetworkAddress);
11471 	PackAddIp32(p, "SubnetMask", t->SubnetMask);
11472 	PackAddIp32(p, "GatewayAddress", t->GatewayAddress);
11473 	PackAddInt(p, "Metric", t->Metric);
11474 }
11475 
11476 // RPC_ENUM_L3IF
InRpcEnumL3If(RPC_ENUM_L3IF * t,PACK * p)11477 void InRpcEnumL3If(RPC_ENUM_L3IF *t, PACK *p)
11478 {
11479 	UINT i;
11480 	// Validate arguments
11481 	if (t == NULL || p == NULL)
11482 	{
11483 		return;
11484 	}
11485 
11486 	Zero(t, sizeof(RPC_ENUM_L3IF));
11487 	t->NumItem = PackGetInt(p, "NumItem");
11488 	PackGetStr(p, "Name", t->Name, sizeof(t->Name));
11489 	t->Items = ZeroMalloc(sizeof(RPC_L3IF) * t->NumItem);
11490 
11491 	for (i = 0;i < t->NumItem;i++)
11492 	{
11493 		RPC_L3IF *f = &t->Items[i];
11494 
11495 		PackGetStrEx(p, "HubName", f->HubName, sizeof(f->HubName), i);
11496 		f->IpAddress = PackGetIp32Ex(p, "IpAddress", i);
11497 		f->SubnetMask = PackGetIp32Ex(p, "SubnetMask", i);
11498 	}
11499 }
OutRpcEnumL3If(PACK * p,RPC_ENUM_L3IF * t)11500 void OutRpcEnumL3If(PACK *p, RPC_ENUM_L3IF *t)
11501 {
11502 	UINT i;
11503 	// Validate arguments
11504 	if (p == NULL || t == NULL)
11505 	{
11506 		return;
11507 	}
11508 
11509 	PackAddInt(p, "NumItem", t->NumItem);
11510 	PackAddStr(p, "Name", t->Name);
11511 
11512 	PackSetCurrentJsonGroupName(p, "L3IFList");
11513 	for (i = 0;i < t->NumItem;i++)
11514 	{
11515 		RPC_L3IF *f = &t->Items[i];
11516 
11517 		PackAddStrEx(p, "HubName", f->HubName, i, t->NumItem);
11518 		PackAddIp32Ex(p, "IpAddress", f->IpAddress, i, t->NumItem);
11519 		PackAddIp32Ex(p, "SubnetMask", f->SubnetMask, i, t->NumItem);
11520 	}
11521 	PackSetCurrentJsonGroupName(p, NULL);
11522 }
FreeRpcEnumL3If(RPC_ENUM_L3IF * t)11523 void FreeRpcEnumL3If(RPC_ENUM_L3IF *t)
11524 {
11525 	// Validate arguments
11526 	if (t == NULL)
11527 	{
11528 		return;
11529 	}
11530 
11531 	Free(t->Items);
11532 }
11533 
11534 // RPC_L3IF
InRpcL3If(RPC_L3IF * t,PACK * p)11535 void InRpcL3If(RPC_L3IF *t, PACK *p)
11536 {
11537 	// Validate arguments
11538 	if (t == NULL || p == NULL)
11539 	{
11540 		return;
11541 	}
11542 
11543 	Zero(t, sizeof(RPC_L3IF));
11544 	PackGetStr(p, "Name", t->Name, sizeof(t->Name));
11545 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
11546 	t->IpAddress = PackGetIp32(p, "IpAddress");
11547 	t->SubnetMask = PackGetIp32(p, "SubnetMask");
11548 }
OutRpcL3If(PACK * p,RPC_L3IF * t)11549 void OutRpcL3If(PACK *p, RPC_L3IF *t)
11550 {
11551 	// Validate arguments
11552 	if (p == NULL || t == NULL)
11553 	{
11554 		return;
11555 	}
11556 
11557 	PackAddStr(p, "Name", t->Name);
11558 	PackAddStr(p, "HubName", t->HubName);
11559 	PackAddIp32(p, "IpAddress", t->IpAddress);
11560 	PackAddIp32(p, "SubnetMask", t->SubnetMask);
11561 }
11562 
11563 // RPC_L3SW
InRpcL3Sw(RPC_L3SW * t,PACK * p)11564 void InRpcL3Sw(RPC_L3SW *t, PACK *p)
11565 {
11566 	// Validate arguments
11567 	if (t == NULL || p == NULL)
11568 	{
11569 		return;
11570 	}
11571 
11572 	Zero(t, sizeof(RPC_L3SW));
11573 	PackGetStr(p, "Name", t->Name, sizeof(t->Name));
11574 }
OutRpcL3Sw(PACK * p,RPC_L3SW * t)11575 void OutRpcL3Sw(PACK *p, RPC_L3SW *t)
11576 {
11577 	// Validate arguments
11578 	if (p == NULL || t == NULL)
11579 	{
11580 		return;
11581 	}
11582 
11583 	PackAddStr(p, "Name", t->Name);
11584 }
11585 
11586 // RPC_ENUM_L3SW
InRpcEnumL3Sw(RPC_ENUM_L3SW * t,PACK * p)11587 void InRpcEnumL3Sw(RPC_ENUM_L3SW *t, PACK *p)
11588 {
11589 	UINT i;
11590 	// Validate arguments
11591 	if (t == NULL || p == NULL)
11592 	{
11593 		return;
11594 	}
11595 
11596 	Zero(t, sizeof(RPC_ENUM_L3SW));
11597 	t->NumItem = PackGetInt(p, "NumItem");
11598 	t->Items = ZeroMalloc(sizeof(RPC_ENUM_L3SW_ITEM) * t->NumItem);
11599 
11600 	for (i = 0;i < t->NumItem;i++)
11601 	{
11602 		RPC_ENUM_L3SW_ITEM *s = &t->Items[i];
11603 
11604 		PackGetStrEx(p, "Name", s->Name, sizeof(s->Name), i);
11605 		s->NumInterfaces = PackGetIntEx(p, "NumInterfaces", i);
11606 		s->NumTables = PackGetIntEx(p, "NumTables", i);
11607 		s->Active = PackGetBoolEx(p, "Active", i);
11608 		s->Online = PackGetBoolEx(p, "Online", i);
11609 	}
11610 }
OutRpcEnumL3Sw(PACK * p,RPC_ENUM_L3SW * t)11611 void OutRpcEnumL3Sw(PACK *p, RPC_ENUM_L3SW *t)
11612 {
11613 	UINT i;
11614 	// Validate arguments
11615 	if (p == NULL || t == NULL)
11616 	{
11617 		return;
11618 	}
11619 
11620 	PackAddInt(p, "NumItem", t->NumItem);
11621 
11622 	PackSetCurrentJsonGroupName(p, "L3SWList");
11623 	for (i = 0;i < t->NumItem;i++)
11624 	{
11625 		RPC_ENUM_L3SW_ITEM *s = &t->Items[i];
11626 
11627 		PackAddStrEx(p, "Name", s->Name, i, t->NumItem);
11628 		PackAddIntEx(p, "NumInterfaces", s->NumInterfaces, i, t->NumItem);
11629 		PackAddIntEx(p, "NumTables", s->NumTables, i, t->NumItem);
11630 		PackAddBoolEx(p, "Active", s->Active, i, t->NumItem);
11631 		PackAddBoolEx(p, "Online", s->Online, i, t->NumItem);
11632 	}
11633 	PackSetCurrentJsonGroupName(p, NULL);
11634 }
FreeRpcEnumL3Sw(RPC_ENUM_L3SW * t)11635 void FreeRpcEnumL3Sw(RPC_ENUM_L3SW *t)
11636 {
11637 	// Validate arguments
11638 	if (t == NULL)
11639 	{
11640 		return;
11641 	}
11642 
11643 	Free(t->Items);
11644 }
11645 
11646 // RPC_ENUM_ETH
InRpcEnumEth(RPC_ENUM_ETH * t,PACK * p)11647 void InRpcEnumEth(RPC_ENUM_ETH *t, PACK *p)
11648 {
11649 	UINT i;
11650 	// Validate arguments
11651 	if (t == NULL || p == NULL)
11652 	{
11653 		return;
11654 	}
11655 
11656 	Zero(t, sizeof(RPC_ENUM_ETH));
11657 	t->NumItem = PackGetInt(p, "NumItem");
11658 	t->Items = ZeroMalloc(sizeof(RPC_ENUM_ETH_ITEM) * t->NumItem);
11659 
11660 	for (i = 0;i < t->NumItem;i++)
11661 	{
11662 		RPC_ENUM_ETH_ITEM *e = &t->Items[i];
11663 		PackGetStrEx(p, "DeviceName", e->DeviceName, sizeof(e->DeviceName), i);
11664 		PackGetUniStrEx(p, "NetworkConnectionName", e->NetworkConnectionName, sizeof(e->NetworkConnectionName), i);
11665 	}
11666 }
OutRpcEnumEth(PACK * p,RPC_ENUM_ETH * t)11667 void OutRpcEnumEth(PACK *p, RPC_ENUM_ETH *t)
11668 {
11669 	UINT i;
11670 	// Validate arguments
11671 	if (p == NULL || t == NULL)
11672 	{
11673 		return;
11674 	}
11675 
11676 	PackAddInt(p, "NumItem", t->NumItem);
11677 
11678 	PackSetCurrentJsonGroupName(p, "EthList");
11679 	for (i = 0;i < t->NumItem;i++)
11680 	{
11681 		RPC_ENUM_ETH_ITEM *e = &t->Items[i];
11682 		PackAddStrEx(p, "DeviceName", e->DeviceName, i, t->NumItem);
11683 		PackAddUniStrEx(p, "NetworkConnectionName", e->NetworkConnectionName, i, t->NumItem);
11684 	}
11685 	PackSetCurrentJsonGroupName(p, NULL);
11686 }
FreeRpcEnumEth(RPC_ENUM_ETH * t)11687 void FreeRpcEnumEth(RPC_ENUM_ETH *t)
11688 {
11689 	// Validate arguments
11690 	if (t == NULL)
11691 	{
11692 		return;
11693 	}
11694 
11695 	Free(t->Items);
11696 }
11697 
11698 // RPC_LOCALBRIDGE
InRpcLocalBridge(RPC_LOCALBRIDGE * t,PACK * p)11699 void InRpcLocalBridge(RPC_LOCALBRIDGE *t, PACK *p)
11700 {
11701 	// Validate arguments
11702 	if (t == NULL || p == NULL)
11703 	{
11704 		return;
11705 	}
11706 
11707 	Zero(t, sizeof(RPC_LOCALBRIDGE));
11708 	PackGetStr(p, "DeviceName", t->DeviceName, sizeof(t->DeviceName));
11709 	PackGetStr(p, "HubNameLB", t->HubName, sizeof(t->HubName));
11710 	t->TapMode = PackGetBool(p, "TapMode");
11711 }
OutRpcLocalBridge(PACK * p,RPC_LOCALBRIDGE * t)11712 void OutRpcLocalBridge(PACK *p, RPC_LOCALBRIDGE *t)
11713 {
11714 	// Validate arguments
11715 	if (t == NULL || p == NULL)
11716 	{
11717 		return;
11718 	}
11719 
11720 	PackAddStr(p, "DeviceName", t->DeviceName);
11721 	PackAddStr(p, "HubNameLB", t->HubName);
11722 	PackAddBool(p, "TapMode", t->TapMode);
11723 }
11724 
11725 // RPC_ENUM_LOCALBRIDGE
InRpcEnumLocalBridge(RPC_ENUM_LOCALBRIDGE * t,PACK * p)11726 void InRpcEnumLocalBridge(RPC_ENUM_LOCALBRIDGE *t, PACK *p)
11727 {
11728 	UINT i;
11729 	// Validate arguments
11730 	if (t == NULL || p == NULL)
11731 	{
11732 		return;
11733 	}
11734 
11735 	Zero(t, sizeof(RPC_ENUM_LOCALBRIDGE));
11736 	t->NumItem = PackGetInt(p, "NumItem");
11737 	t->Items = ZeroMalloc(sizeof(RPC_LOCALBRIDGE) * t->NumItem);
11738 
11739 	for (i = 0;i < t->NumItem;i++)
11740 	{
11741 		RPC_LOCALBRIDGE *e = &t->Items[i];
11742 
11743 		PackGetStrEx(p, "DeviceName", e->DeviceName, sizeof(e->DeviceName), i);
11744 		PackGetStrEx(p, "HubNameLB", e->HubName, sizeof(e->HubName), i);
11745 		e->Online = PackGetBoolEx(p, "Online", i);
11746 		e->Active = PackGetBoolEx(p, "Active", i);
11747 		e->TapMode = PackGetBoolEx(p, "TapMode", i);
11748 	}
11749 }
OutRpcEnumLocalBridge(PACK * p,RPC_ENUM_LOCALBRIDGE * t)11750 void OutRpcEnumLocalBridge(PACK *p, RPC_ENUM_LOCALBRIDGE *t)
11751 {
11752 	UINT i;
11753 	// Validate arguments
11754 	if (t == NULL || p == NULL)
11755 	{
11756 		return;
11757 	}
11758 
11759 	PackAddInt(p, "NumItem", t->NumItem);
11760 
11761 	PackSetCurrentJsonGroupName(p, "LocalBridgeList");
11762 	for (i = 0;i < t->NumItem;i++)
11763 	{
11764 		RPC_LOCALBRIDGE *e = &t->Items[i];
11765 
11766 		PackAddStrEx(p, "DeviceName", e->DeviceName, i, t->NumItem);
11767 		PackAddStrEx(p, "HubNameLB", e->HubName, i, t->NumItem);
11768 		PackAddBoolEx(p, "Online", e->Online, i, t->NumItem);
11769 		PackAddBoolEx(p, "Active", e->Active, i, t->NumItem);
11770 		PackAddBoolEx(p, "TapMode", e->TapMode, i, t->NumItem);
11771 	}
11772 	PackSetCurrentJsonGroupName(p, NULL);
11773 }
FreeRpcEnumLocalBridge(RPC_ENUM_LOCALBRIDGE * t)11774 void FreeRpcEnumLocalBridge(RPC_ENUM_LOCALBRIDGE *t)
11775 {
11776 	// Validate arguments
11777 	if (t == NULL)
11778 	{
11779 		return;
11780 	}
11781 	Free(t->Items);
11782 }
11783 
11784 // MEMINFO
InRpcMemInfo(MEMINFO * t,PACK * p)11785 void InRpcMemInfo(MEMINFO *t, PACK *p)
11786 {
11787 	// Validate arguments
11788 	if (t == NULL || p == NULL)
11789 	{
11790 		return;
11791 	}
11792 
11793 	Zero(t, sizeof(MEMINFO));
11794 	t->TotalMemory = PackGetInt64(p, "TotalMemory");
11795 	t->UsedMemory = PackGetInt64(p, "UsedMemory");
11796 	t->FreeMemory = PackGetInt64(p, "FreeMemory");
11797 	t->TotalPhys = PackGetInt64(p, "TotalPhys");
11798 	t->UsedPhys = PackGetInt64(p, "UsedPhys");
11799 	t->FreePhys = PackGetInt64(p, "FreePhys");
11800 }
OutRpcMemInfo(PACK * p,MEMINFO * t)11801 void OutRpcMemInfo(PACK *p, MEMINFO *t)
11802 {
11803 	// Validate arguments
11804 	if (t == NULL || p == NULL)
11805 	{
11806 		return;
11807 	}
11808 
11809 	PackAddInt64(p, "TotalMemory", t->TotalMemory);
11810 	PackAddInt64(p, "UsedMemory", t->UsedMemory);
11811 	PackAddInt64(p, "FreeMemory", t->FreeMemory);
11812 	PackAddInt64(p, "TotalPhys", t->TotalPhys);
11813 	PackAddInt64(p, "UsedPhys", t->UsedPhys);
11814 	PackAddInt64(p, "FreePhys", t->FreePhys);
11815 }
11816 
11817 // OS_INFO
InRpcOsInfo(OS_INFO * t,PACK * p)11818 void InRpcOsInfo(OS_INFO *t, PACK *p)
11819 {
11820 	char tmp[MAX_SIZE];
11821 	// Validate arguments
11822 	if (t == NULL || p == NULL)
11823 	{
11824 		return;
11825 	}
11826 
11827 	Zero(t, sizeof(OS_INFO));
11828 	t->OsType = PackGetInt(p, "OsType");
11829 	t->OsServicePack = PackGetInt(p, "OsServicePack");
11830 	if (PackGetStr(p, "OsSystemName", tmp, sizeof(tmp)))
11831 	{
11832 		t->OsSystemName = CopyStr(tmp);
11833 	}
11834 	if (PackGetStr(p, "OsProductName", tmp, sizeof(tmp)))
11835 	{
11836 		t->OsProductName = CopyStr(tmp);
11837 	}
11838 	if (PackGetStr(p, "OsVendorName", tmp, sizeof(tmp)))
11839 	{
11840 		t->OsVendorName = CopyStr(tmp);
11841 	}
11842 	if (PackGetStr(p, "OsVersion", tmp, sizeof(tmp)))
11843 	{
11844 		t->OsVersion = CopyStr(tmp);
11845 	}
11846 	if (PackGetStr(p, "KernelName", tmp, sizeof(tmp)))
11847 	{
11848 		t->KernelName = CopyStr(tmp);
11849 	}
11850 	if (PackGetStr(p, "KernelVersion", tmp, sizeof(tmp)))
11851 	{
11852 		t->KernelVersion = CopyStr(tmp);
11853 	}
11854 }
OutRpcOsInfo(PACK * p,OS_INFO * t)11855 void OutRpcOsInfo(PACK *p, OS_INFO *t)
11856 {
11857 	// Validate arguments
11858 	if (t == NULL || p == NULL)
11859 	{
11860 		return;
11861 	}
11862 
11863 	PackAddInt(p, "OsType", t->OsType);
11864 	PackAddInt(p, "OsServicePack", t->OsServicePack);
11865 	PackAddStr(p, "OsSystemName", t->OsSystemName);
11866 	PackAddStr(p, "OsProductName", t->OsProductName);
11867 	PackAddStr(p, "OsVendorName", t->OsVendorName);
11868 	PackAddStr(p, "OsVersion", t->OsVersion);
11869 	PackAddStr(p, "KernelName", t->KernelName);
11870 	PackAddStr(p, "KernelVersion", t->KernelVersion);
11871 }
FreeRpcOsInfo(OS_INFO * t)11872 void FreeRpcOsInfo(OS_INFO *t)
11873 {
11874 	// Validate arguments
11875 	if (t == NULL)
11876 	{
11877 		return;
11878 	}
11879 
11880 	Free(t->OsSystemName);
11881 	Free(t->OsProductName);
11882 	Free(t->OsVendorName);
11883 	Free(t->OsVersion);
11884 	Free(t->KernelName);
11885 	Free(t->KernelVersion);
11886 }
11887 
11888 // Read a local log file
SiReadLocalLogFile(SERVER * s,char * filepath,UINT offset,RPC_READ_LOG_FILE * t)11889 void SiReadLocalLogFile(SERVER *s, char *filepath, UINT offset, RPC_READ_LOG_FILE *t)
11890 {
11891 	char exe_dir[MAX_PATH], full_path[MAX_PATH];
11892 	IO *o;
11893 	// Validate arguments
11894 	if (s == NULL || t == NULL || filepath == NULL)
11895 	{
11896 		return;
11897 	}
11898 
11899 	Zero(t, sizeof(RPC_READ_LOG_FILE));
11900 
11901 	GetLogDir(exe_dir, sizeof(exe_dir));
11902 	Format(full_path, sizeof(full_path), "%s/%s", exe_dir, filepath);
11903 
11904 	// Read file
11905 	o = FileOpenEx(full_path, false, false);
11906 	if (o != NULL)
11907 	{
11908 		UINT filesize = FileSize(o);
11909 
11910 		if (offset < filesize)
11911 		{
11912 			UINT readsize = MIN(filesize - offset, FTP_BLOCK_SIZE);
11913 			void *buf = ZeroMalloc(readsize);
11914 
11915 			FileSeek(o, FILE_BEGIN, offset);
11916 			FileRead(o, buf, readsize);
11917 
11918 			t->Buffer = NewBuf();
11919 			WriteBuf(t->Buffer, buf, readsize);
11920 			Free(buf);
11921 		}
11922 
11923 		FileClose(o);
11924 	}
11925 }
11926 
11927 // Enumerate local log files
SiEnumLocalLogFileList(SERVER * s,char * hubname,RPC_ENUM_LOG_FILE * t)11928 void SiEnumLocalLogFileList(SERVER *s, char *hubname, RPC_ENUM_LOG_FILE *t)
11929 {
11930 	LIST *o;
11931 	UINT i;
11932 	// Validate arguments
11933 	if (s == NULL || t == NULL)
11934 	{
11935 		return;
11936 	}
11937 
11938 	Zero(t, sizeof(RPC_ENUM_LOG_FILE));
11939 
11940 	o = EnumLogFile(hubname);
11941 
11942 	t->NumItem = LIST_NUM(o);
11943 	t->Items = ZeroMalloc(sizeof(RPC_ENUM_LOG_FILE_ITEM) * t->NumItem);
11944 
11945 	for (i = 0;i < LIST_NUM(o);i++)
11946 	{
11947 		LOG_FILE *f = LIST_DATA(o, i);
11948 		RPC_ENUM_LOG_FILE_ITEM *e = &t->Items[i];
11949 
11950 		StrCpy(e->FilePath, sizeof(e->FilePath), f->Path);
11951 		StrCpy(e->ServerName, sizeof(e->ServerName), f->ServerName);
11952 		e->FileSize = f->FileSize;
11953 		e->UpdatedTime = f->UpdatedTime;
11954 	}
11955 
11956 	FreeEnumLogFile(o);
11957 }
11958 
11959 // Enumerate local sessions
SiEnumLocalSession(SERVER * s,char * hubname,RPC_ENUM_SESSION * t)11960 void SiEnumLocalSession(SERVER *s, char *hubname, RPC_ENUM_SESSION *t)
11961 {
11962 	HUB *h;
11963 	UINT64 now = Tick64();
11964 	UINT64 dormant_interval = 0;
11965 	// Validate arguments
11966 	if (s == NULL || hubname == NULL || t == NULL)
11967 	{
11968 		return;
11969 	}
11970 
11971 	LockHubList(s->Cedar);
11972 	h = GetHub(s->Cedar, hubname);
11973 	UnlockHubList(s->Cedar);
11974 
11975 	if (h == NULL)
11976 	{
11977 		t->NumSession = 0;
11978 		t->Sessions = ZeroMalloc(0);
11979 		return;
11980 	}
11981 
11982 	if (h->Option != NULL)
11983 	{
11984 		dormant_interval = h->Option->DetectDormantSessionInterval * (UINT64)1000;
11985 	}
11986 
11987 	LockList(h->SessionList);
11988 	{
11989 		UINT i;
11990 		t->NumSession = LIST_NUM(h->SessionList);
11991 		t->Sessions = ZeroMalloc(sizeof(RPC_ENUM_SESSION_ITEM) * t->NumSession);
11992 
11993 		for (i = 0;i < t->NumSession;i++)
11994 		{
11995 			SESSION *s = LIST_DATA(h->SessionList, i);
11996 			RPC_ENUM_SESSION_ITEM *e = &t->Sessions[i];
11997 			Lock(s->lock);
11998 			{
11999 				StrCpy(e->Name, sizeof(e->Name), s->Name);
12000 				StrCpy(e->Username, sizeof(e->Username), s->Username);
12001 				e->Ip = IPToUINT(&s->Connection->ClientIp);
12002 				CopyIP(&e->ClientIP, &s->Connection->ClientIp);
12003 				StrCpy(e->Hostname, sizeof(e->Hostname), s->Connection->ClientHostname);
12004 				e->MaxNumTcp = s->MaxConnection;
12005 				e->CreatedTime = Tick64ToTime64(s->CreatedTime);
12006 				e->LastCommTime = Tick64ToTime64(s->LastCommTime);
12007 				e->LinkMode = s->LinkModeServer;
12008 				e->SecureNATMode = s->SecureNATMode;
12009 				e->BridgeMode = s->BridgeMode;
12010 				e->Layer3Mode = s->L3SwitchMode;
12011 				e->VLanId = s->VLanId;
12012 				LockList(s->Connection->Tcp->TcpSockList);
12013 				{
12014 					e->CurrentNumTcp = s->Connection->Tcp->TcpSockList->num_item;
12015 				}
12016 				UnlockList(s->Connection->Tcp->TcpSockList);
12017 				Lock(s->TrafficLock);
12018 				{
12019 					e->PacketSize = GetTrafficPacketSize(s->Traffic);
12020 					e->PacketNum = GetTrafficPacketNum(s->Traffic);
12021 				}
12022 				Unlock(s->TrafficLock);
12023 				e->Client_BridgeMode = s->IsBridgeMode;
12024 				e->Client_MonitorMode = s->IsMonitorMode;
12025 				Copy(e->UniqueId, s->NodeInfo.UniqueId, 16);
12026 
12027 				if (s->NormalClient)
12028 				{
12029 					e->IsDormantEnabled = (dormant_interval == 0 ? false : true);
12030 					if (e->IsDormantEnabled)
12031 					{
12032 						if (s->LastCommTimeForDormant == 0)
12033 						{
12034 							e->LastCommDormant = (UINT64)0x7FFFFFFF;
12035 						}
12036 						else
12037 						{
12038 							e->LastCommDormant = now - s->LastCommTimeForDormant;
12039 						}
12040 						if (s->LastCommTimeForDormant == 0)
12041 						{
12042 							e->IsDormant = true;
12043 						}
12044 						else
12045 						{
12046 							if ((s->LastCommTimeForDormant + dormant_interval) < now)
12047 							{
12048 								e->IsDormant = true;
12049 							}
12050 						}
12051 					}
12052 				}
12053 			}
12054 			Unlock(s->lock);
12055 
12056 			GetMachineName(e->RemoteHostname, sizeof(e->RemoteHostname));
12057 		}
12058 	}
12059 	UnlockList(h->SessionList);
12060 
12061 	ReleaseHub(h);
12062 }
12063 
12064 // RPC_ENUM_LICENSE_KEY
InRpcEnumLicenseKey(RPC_ENUM_LICENSE_KEY * t,PACK * p)12065 void InRpcEnumLicenseKey(RPC_ENUM_LICENSE_KEY *t, PACK *p)
12066 {
12067 	UINT i;
12068 	// Validate arguments
12069 	if (t == NULL || p == NULL)
12070 	{
12071 		return;
12072 	}
12073 
12074 	Zero(t, sizeof(RPC_ENUM_LICENSE_KEY));
12075 	t->NumItem = PackGetInt(p, "NumItem");
12076 	t->Items = ZeroMalloc(sizeof(RPC_ENUM_LICENSE_KEY_ITEM) * t->NumItem);
12077 	for (i = 0;i < t->NumItem;i++)
12078 	{
12079 		RPC_ENUM_LICENSE_KEY_ITEM *e = &t->Items[i];
12080 
12081 		e->Id = PackGetIntEx(p, "Id", i);
12082 		PackGetStrEx(p, "LicenseKey", e->LicenseKey, sizeof(e->LicenseKey), i);
12083 		PackGetStrEx(p, "LicenseId", e->LicenseId, sizeof(e->LicenseId), i);
12084 		PackGetStrEx(p, "LicenseName", e->LicenseName, sizeof(e->LicenseName), i);
12085 		e->Expires = PackGetInt64Ex(p, "Expires", i);
12086 		e->Status = PackGetIntEx(p, "Status", i);
12087 		e->ProductId = PackGetIntEx(p, "ProductId", i);
12088 		e->SystemId = PackGetInt64Ex(p, "SystemId", i);
12089 		e->SerialId = PackGetIntEx(p, "SerialId", i);
12090 	}
12091 }
OutRpcEnumLicenseKey(PACK * p,RPC_ENUM_LICENSE_KEY * t)12092 void OutRpcEnumLicenseKey(PACK *p, RPC_ENUM_LICENSE_KEY *t)
12093 {
12094 	UINT i;
12095 	// Validate arguments
12096 	if (t == NULL || p == NULL)
12097 	{
12098 		return;
12099 	}
12100 
12101 	PackAddInt(p, "NumItem", t->NumItem);
12102 
12103 	PackSetCurrentJsonGroupName(p, "LicenseKeyList");
12104 	for (i = 0;i < t->NumItem;i++)
12105 	{
12106 		RPC_ENUM_LICENSE_KEY_ITEM *e = &t->Items[i];
12107 
12108 		PackAddIntEx(p, "Id", e->Id, i, t->NumItem);
12109 		PackAddStrEx(p, "LicenseKey", e->LicenseKey, i, t->NumItem);
12110 		PackAddStrEx(p, "LicenseId", e->LicenseId, i, t->NumItem);
12111 		PackAddStrEx(p, "LicenseName", e->LicenseName, i, t->NumItem);
12112 		PackAddTime64Ex(p, "Expires", e->Expires, i, t->NumItem);
12113 		PackAddIntEx(p, "Status", e->Status, i, t->NumItem);
12114 		PackAddIntEx(p, "ProductId", e->ProductId, i, t->NumItem);
12115 		PackAddInt64Ex(p, "SystemId", e->SystemId, i, t->NumItem);
12116 		PackAddIntEx(p, "SerialId", e->SerialId, i, t->NumItem);
12117 	}
12118 	PackSetCurrentJsonGroupName(p, NULL);
12119 }
FreeRpcEnumLicenseKey(RPC_ENUM_LICENSE_KEY * t)12120 void FreeRpcEnumLicenseKey(RPC_ENUM_LICENSE_KEY *t)
12121 {
12122 	// Validate arguments
12123 	if (t == NULL)
12124 	{
12125 		return;
12126 	}
12127 
12128 	Free(t->Items);
12129 }
12130 
12131 // RPC_LICENSE_STATUS
InRpcLicenseStatus(RPC_LICENSE_STATUS * t,PACK * p)12132 void InRpcLicenseStatus(RPC_LICENSE_STATUS *t, PACK *p)
12133 {
12134 	// Validate arguments
12135 	if (t == NULL || p == NULL)
12136 	{
12137 		return;
12138 	}
12139 
12140 	Zero(t, sizeof(RPC_LICENSE_STATUS));
12141 
12142 	t->EditionId = PackGetInt(p, "EditionId");
12143 	PackGetStr(p, "EditionStr", t->EditionStr, sizeof(t->EditionStr) );
12144 	t->SystemId = PackGetInt64(p, "SystemId");
12145 	t->SystemExpires = PackGetInt64(p, "SystemExpires");
12146 	t->NumClientConnectLicense = PackGetInt(p, "NumClientConnectLicense");
12147 	t->NumBridgeConnectLicense = PackGetInt(p, "NumBridgeConnectLicense");
12148 
12149 	// v3.0
12150 	t->NeedSubscription = PackGetBool(p, "NeedSubscription");
12151 	t->AllowEnterpriseFunction = PackGetBool(p, "AllowEnterpriseFunction");
12152 	t->SubscriptionExpires = PackGetInt64(p, "SubscriptionExpires");
12153 	t->IsSubscriptionExpired = PackGetBool(p, "IsSubscriptionExpired");
12154 	t->NumUserCreationLicense = PackGetInt(p, "NumUserCreationLicense");
12155 	t->ReleaseDate = PackGetInt64(p, "ReleaseDate");
12156 }
OutRpcLicenseStatus(PACK * p,RPC_LICENSE_STATUS * t)12157 void OutRpcLicenseStatus(PACK *p, RPC_LICENSE_STATUS *t)
12158 {
12159 	// Validate arguments
12160 	if (t == NULL || p == NULL)
12161 	{
12162 		return;
12163 	}
12164 
12165 	PackAddInt(p, "EditionId", t->EditionId);
12166 	PackAddStr(p, "EditionStr", t->EditionStr);
12167 	PackAddInt64(p, "SystemId", t->SystemId);
12168 	PackAddTime64(p, "SystemExpires", t->SystemExpires);
12169 	PackAddInt(p, "NumClientConnectLicense", t->NumClientConnectLicense);
12170 	PackAddInt(p, "NumBridgeConnectLicense", t->NumBridgeConnectLicense);
12171 
12172 	// v3.0
12173 	PackAddBool(p, "NeedSubscription", t->NeedSubscription);
12174 	PackAddBool(p, "AllowEnterpriseFunction", t->AllowEnterpriseFunction);
12175 	PackAddTime64(p, "SubscriptionExpires", t->SubscriptionExpires);
12176 	PackAddBool(p, "IsSubscriptionExpired", t->IsSubscriptionExpired);
12177 	PackAddInt(p, "NumUserCreationLicense", t->NumUserCreationLicense);
12178 	PackAddTime64(p, "ReleaseDate", t->ReleaseDate);
12179 }
12180 
12181 // RPC_ADMIN_OPTION
InRpcAdminOption(RPC_ADMIN_OPTION * t,PACK * p)12182 void InRpcAdminOption(RPC_ADMIN_OPTION *t, PACK *p)
12183 {
12184 	UINT i;
12185 	// Validate arguments
12186 	if (t == NULL || p == NULL)
12187 	{
12188 		return;
12189 	}
12190 
12191 	Zero(t, sizeof(RPC_ADMIN_OPTION));
12192 	t->NumItem = PackGetIndexCount(p, "Name");
12193 	t->Items = ZeroMalloc(sizeof(ADMIN_OPTION) * t->NumItem);
12194 
12195 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
12196 
12197 	for (i = 0;i < t->NumItem;i++)
12198 	{
12199 		ADMIN_OPTION *o = &t->Items[i];
12200 
12201 		PackGetStrEx(p, "Name", o->Name, sizeof(o->Name), i);
12202 		o->Value = PackGetIntEx(p, "Value", i);
12203 		PackGetUniStrEx(p, "Descrption", o->Descrption, sizeof(o->Descrption), i);
12204 	}
12205 }
OutRpcAdminOption(PACK * p,RPC_ADMIN_OPTION * t)12206 void OutRpcAdminOption(PACK *p, RPC_ADMIN_OPTION *t)
12207 {
12208 	UINT i;
12209 	// Validate arguments
12210 	if (t == NULL || p == NULL)
12211 	{
12212 		return;
12213 	}
12214 
12215 	PackAddInt(p, "NumItem", t->NumItem);
12216 
12217 	PackAddStr(p, "HubName", t->HubName);
12218 
12219 	PackSetCurrentJsonGroupName(p, "AdminOptionList");
12220 	for (i = 0;i < t->NumItem;i++)
12221 	{
12222 		ADMIN_OPTION *o = &t->Items[i];
12223 
12224 		PackAddStrEx(p, "Name", o->Name, i, t->NumItem);
12225 		PackAddIntEx(p, "Value", o->Value, i, t->NumItem);
12226 		PackAddUniStrEx(p, "Descrption", o->Descrption, i, t->NumItem);
12227 	}
12228 	PackSetCurrentJsonGroupName(p, NULL);
12229 }
FreeRpcAdminOption(RPC_ADMIN_OPTION * t)12230 void FreeRpcAdminOption(RPC_ADMIN_OPTION *t)
12231 {
12232 	// Validate arguments
12233 	if (t == NULL)
12234 	{
12235 		return;
12236 	}
12237 
12238 	Free(t->Items);
12239 }
12240 
12241 // RPC_CONFIG
InRpcConfig(RPC_CONFIG * t,PACK * p)12242 void InRpcConfig(RPC_CONFIG *t, PACK *p)
12243 {
12244 	UINT size;
12245 	// Validate arguments
12246 	if (t == NULL || p == NULL)
12247 	{
12248 		return;
12249 	}
12250 
12251 	Zero(t, sizeof(RPC_CONFIG));
12252 	PackGetStr(p, "FileName", t->FileName, sizeof(t->FileName));
12253 	size = PackGetDataSize(p, "FileData");
12254 	t->FileData = ZeroMalloc(size + 1);
12255 	PackGetData(p, "FileData", t->FileData);
12256 }
OutRpcConfig(PACK * p,RPC_CONFIG * t)12257 void OutRpcConfig(PACK *p, RPC_CONFIG *t)
12258 {
12259 	// Validate arguments
12260 	if (t == NULL || p == NULL)
12261 	{
12262 		return;
12263 	}
12264 
12265 	PackAddStr(p, "FileName", t->FileName);
12266 	PackAddData(p, "FileData", t->FileData, StrLen(t->FileData));
12267 }
FreeRpcConfig(RPC_CONFIG * t)12268 void FreeRpcConfig(RPC_CONFIG *t)
12269 {
12270 	// Validate arguments
12271 	if (t == NULL)
12272 	{
12273 		return;
12274 	}
12275 
12276 	Free(t->FileData);
12277 }
12278 
12279 // RPC_BRIDGE_SUPPORT
InRpcBridgeSupport(RPC_BRIDGE_SUPPORT * t,PACK * p)12280 void InRpcBridgeSupport(RPC_BRIDGE_SUPPORT *t, PACK *p)
12281 {
12282 	// Validate arguments
12283 	if (t == NULL || p == NULL)
12284 	{
12285 		return;
12286 	}
12287 
12288 	Zero(t, sizeof(RPC_BRIDGE_SUPPORT));
12289 
12290 	t->IsBridgeSupportedOs = PackGetBool(p, "IsBridgeSupportedOs");
12291 	t->IsWinPcapNeeded = PackGetBool(p, "IsWinPcapNeeded");
12292 }
OutRpcBridgeSupport(PACK * p,RPC_BRIDGE_SUPPORT * t)12293 void OutRpcBridgeSupport(PACK *p, RPC_BRIDGE_SUPPORT *t)
12294 {
12295 	// Validate arguments
12296 	if (p == NULL || t == NULL)
12297 	{
12298 		return;
12299 	}
12300 
12301 	PackAddBool(p, "IsBridgeSupportedOs", t->IsBridgeSupportedOs);
12302 	PackAddBool(p, "IsWinPcapNeeded",t->IsWinPcapNeeded);
12303 }
12304 
12305 // RPC_ADD_ACCESS
InRpcAddAccess(RPC_ADD_ACCESS * t,PACK * p)12306 void InRpcAddAccess(RPC_ADD_ACCESS *t, PACK *p)
12307 {
12308 	// Validate arguments
12309 	if (t == NULL || p == NULL)
12310 	{
12311 		return;
12312 	}
12313 
12314 	Zero(t, sizeof(RPC_ADD_ACCESS));
12315 
12316 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
12317 	InRpcAccess(&t->Access, p);
12318 }
OutRpcAddAccess(PACK * p,RPC_ADD_ACCESS * t)12319 void OutRpcAddAccess(PACK *p, RPC_ADD_ACCESS *t)
12320 {
12321 	// Validate arguments
12322 	if (t == NULL || p == NULL)
12323 	{
12324 		return;
12325 	}
12326 
12327 	PackAddStr(p, "HubName", t->HubName);
12328 	OutRpcAccess(p, &t->Access);
12329 }
12330 
12331 // RPC_DELETE_ACCESS
InRpcDeleteAccess(RPC_DELETE_ACCESS * t,PACK * p)12332 void InRpcDeleteAccess(RPC_DELETE_ACCESS *t, PACK *p)
12333 {
12334 	// Validate arguments
12335 	if (t == NULL || p == NULL)
12336 	{
12337 		return;
12338 	}
12339 
12340 	Zero(t, sizeof(RPC_DELETE_ACCESS));
12341 
12342 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
12343 	t->Id = PackGetInt(p, "Id");
12344 }
OutRpcDeleteAccess(PACK * p,RPC_DELETE_ACCESS * t)12345 void OutRpcDeleteAccess(PACK *p, RPC_DELETE_ACCESS *t)
12346 {
12347 	// Validate arguments
12348 	if (t == NULL || p == NULL)
12349 	{
12350 		return;
12351 	}
12352 
12353 	PackAddStr(p, "HubName", t->HubName);
12354 	PackAddInt(p, "Id", t->Id);
12355 }
12356 
12357 
12358 // RPC_SERVER_INFO
InRpcServerInfo(RPC_SERVER_INFO * t,PACK * p)12359 void InRpcServerInfo(RPC_SERVER_INFO *t, PACK *p)
12360 {
12361 	// Validate arguments
12362 	if (t == NULL || p == NULL)
12363 	{
12364 		return;
12365 	}
12366 
12367 	Zero(t, sizeof(RPC_SERVER_INFO));
12368 
12369 	PackGetStr(p, "ServerProductName", t->ServerProductName, sizeof(t->ServerProductName));
12370 	PackGetStr(p, "ServerVersionString", t->ServerVersionString, sizeof(t->ServerVersionString));
12371 	PackGetStr(p, "ServerBuildInfoString", t->ServerBuildInfoString, sizeof(t->ServerBuildInfoString));
12372 	t->ServerVerInt = PackGetInt(p, "ServerVerInt");
12373 	t->ServerBuildInt = PackGetInt(p, "ServerBuildInt");
12374 	PackGetStr(p, "ServerHostName", t->ServerHostName, sizeof(t->ServerHostName));
12375 	t->ServerType = PackGetInt(p, "ServerType");
12376 	t->ServerBuildDate = PackGetInt64(p, "ServerBuildDate");
12377 	PackGetStr(p, "ServerFamilyName", t->ServerFamilyName, sizeof(t->ServerFamilyName));
12378 	InRpcOsInfo(&t->OsInfo, p);
12379 }
OutRpcServerInfo(PACK * p,RPC_SERVER_INFO * t)12380 void OutRpcServerInfo(PACK *p, RPC_SERVER_INFO *t)
12381 {
12382 	// Validate arguments
12383 	if (t == NULL || p == NULL)
12384 	{
12385 		return;
12386 	}
12387 
12388 	PackAddStr(p, "ServerProductName", t->ServerProductName);
12389 	PackAddStr(p, "ServerVersionString", t->ServerVersionString);
12390 	PackAddStr(p, "ServerBuildInfoString", t->ServerBuildInfoString);
12391 	PackAddInt(p, "ServerVerInt", t->ServerVerInt);
12392 	PackAddInt(p, "ServerBuildInt", t->ServerBuildInt);
12393 	PackAddStr(p, "ServerHostName", t->ServerHostName);
12394 	PackAddInt(p, "ServerType", t->ServerType);
12395 	PackAddTime64(p, "ServerBuildDate", t->ServerBuildDate);
12396 	PackAddStr(p, "ServerFamilyName", t->ServerFamilyName);
12397 	OutRpcOsInfo(p, &t->OsInfo);
12398 }
FreeRpcServerInfo(RPC_SERVER_INFO * t)12399 void FreeRpcServerInfo(RPC_SERVER_INFO *t)
12400 {
12401 	// Validate arguments
12402 	if (t == NULL)
12403 	{
12404 		return;
12405 	}
12406 
12407 	FreeRpcOsInfo(&t->OsInfo);
12408 }
12409 
12410 // RPC_SERVER_STATUS
InRpcServerStatus(RPC_SERVER_STATUS * t,PACK * p)12411 void InRpcServerStatus(RPC_SERVER_STATUS *t, PACK *p)
12412 {
12413 	// Validate arguments
12414 	if (t == NULL || p == NULL)
12415 	{
12416 		return;
12417 	}
12418 
12419 	Zero(t, sizeof(RPC_SERVER_STATUS));
12420 	t->ServerType = PackGetInt(p, "ServerType");
12421 	t->NumTcpConnections = PackGetInt(p, "NumTcpConnections");
12422 	t->NumTcpConnectionsLocal = PackGetInt(p, "NumTcpConnectionsLocal");
12423 	t->NumTcpConnectionsRemote = PackGetInt(p, "NumTcpConnectionsRemote");
12424 	t->NumHubTotal = PackGetInt(p, "NumHubTotal");
12425 	t->NumHubStandalone = PackGetInt(p, "NumHubStandalone");
12426 	t->NumHubStatic = PackGetInt(p, "NumHubStatic");
12427 	t->NumHubDynamic = PackGetInt(p, "NumHubDynamic");
12428 	t->NumSessionsTotal = PackGetInt(p, "NumSessionsTotal");
12429 	t->NumSessionsLocal = PackGetInt(p, "NumSessionsLocal");
12430 	t->NumSessionsRemote = PackGetInt(p, "NumSessionsRemote");
12431 	t->NumMacTables = PackGetInt(p, "NumMacTables");
12432 	t->NumIpTables = PackGetInt(p, "NumIpTables");
12433 	t->NumUsers = PackGetInt(p, "NumUsers");
12434 	t->NumGroups = PackGetInt(p, "NumGroups");
12435 	t->CurrentTime = PackGetInt64(p, "CurrentTime");
12436 	t->CurrentTick = PackGetInt64(p, "CurrentTick");
12437 	t->AssignedBridgeLicenses = PackGetInt(p, "AssignedBridgeLicenses");
12438 	t->AssignedClientLicenses = PackGetInt(p, "AssignedClientLicenses");
12439 	t->AssignedBridgeLicensesTotal = PackGetInt(p, "AssignedBridgeLicensesTotal");
12440 	t->AssignedClientLicensesTotal = PackGetInt(p, "AssignedClientLicensesTotal");
12441 	t->StartTime = PackGetInt64(p, "StartTime");
12442 
12443 	InRpcTraffic(&t->Traffic, p);
12444 
12445 	InRpcMemInfo(&t->MemInfo, p);
12446 }
OutRpcServerStatus(PACK * p,RPC_SERVER_STATUS * t)12447 void OutRpcServerStatus(PACK *p, RPC_SERVER_STATUS *t)
12448 {
12449 	// Validate arguments
12450 	if (t == NULL || p == NULL)
12451 	{
12452 		return;
12453 	}
12454 
12455 	PackAddInt(p, "ServerType", t->ServerType);
12456 	PackAddInt(p, "NumHubTotal", t->NumHubTotal);
12457 	PackAddInt(p, "NumHubStandalone", t->NumHubStandalone);
12458 	PackAddInt(p, "NumHubStatic", t->NumHubStatic);
12459 	PackAddInt(p, "NumHubDynamic", t->NumHubDynamic);
12460 	PackAddInt(p, "NumSessionsTotal", t->NumSessionsTotal);
12461 	PackAddInt(p, "NumSessionsLocal", t->NumSessionsLocal);
12462 	PackAddInt(p, "NumSessionsRemote", t->NumSessionsRemote);
12463 	PackAddInt(p, "NumTcpConnections", t->NumTcpConnections);
12464 	PackAddInt(p, "NumTcpConnectionsLocal", t->NumTcpConnectionsLocal);
12465 	PackAddInt(p, "NumTcpConnectionsRemote", t->NumTcpConnectionsRemote);
12466 	PackAddInt(p, "NumMacTables", t->NumMacTables);
12467 	PackAddInt(p, "NumIpTables", t->NumIpTables);
12468 	PackAddInt(p, "NumUsers", t->NumUsers);
12469 	PackAddInt(p, "NumGroups", t->NumGroups);
12470 	PackAddTime64(p, "CurrentTime", t->CurrentTime);
12471 	PackAddInt64(p, "CurrentTick", t->CurrentTick);
12472 	PackAddInt(p, "AssignedBridgeLicenses", t->AssignedBridgeLicenses);
12473 	PackAddInt(p, "AssignedClientLicenses", t->AssignedClientLicenses);
12474 	PackAddInt(p, "AssignedBridgeLicensesTotal", t->AssignedBridgeLicensesTotal);
12475 	PackAddInt(p, "AssignedClientLicensesTotal", t->AssignedClientLicensesTotal);
12476 	PackAddTime64(p, "StartTime", t->StartTime);
12477 
12478 	OutRpcTraffic(p, &t->Traffic);
12479 
12480 	OutRpcMemInfo(p, &t->MemInfo);
12481 }
12482 
12483 // RPC_LISTENER
InRpcListener(RPC_LISTENER * t,PACK * p)12484 void InRpcListener(RPC_LISTENER *t, PACK *p)
12485 {
12486 	// Validate arguments
12487 	if (t == NULL || p == NULL)
12488 	{
12489 		return;
12490 	}
12491 
12492 	Zero(t, sizeof(RPC_LISTENER));
12493 	t->Port = PackGetInt(p, "Port");
12494 	t->Enable = PackGetBool(p, "Enable");
12495 }
OutRpcListener(PACK * p,RPC_LISTENER * t)12496 void OutRpcListener(PACK *p, RPC_LISTENER *t)
12497 {
12498 	// Validate arguments
12499 	if (t == NULL || p == NULL)
12500 	{
12501 		return;
12502 	}
12503 
12504 	PackAddInt(p, "Port", t->Port);
12505 	PackAddBool(p, "Enable", t->Enable);
12506 }
12507 
12508 // RPC_LISTENER_LIST
InRpcListenerList(RPC_LISTENER_LIST * t,PACK * p)12509 void InRpcListenerList(RPC_LISTENER_LIST *t, PACK *p)
12510 {
12511 	UINT i;
12512 	// Validate arguments
12513 	if (t == NULL || p == NULL)
12514 	{
12515 		return;
12516 	}
12517 
12518 	Zero(t, sizeof(RPC_LISTENER_LIST));
12519 	t->NumPort = PackGetIndexCount(p, "Ports");
12520 	t->Ports = ZeroMalloc(sizeof(UINT) * t->NumPort);
12521 	t->Enables = ZeroMalloc(sizeof(UINT) * t->NumPort);
12522 	t->Errors = ZeroMalloc(sizeof(UINT) * t->NumPort);
12523 	for (i = 0;i < t->NumPort;i++)
12524 	{
12525 		t->Ports[i] = PackGetIntEx(p, "Ports", i);
12526 		t->Enables[i] = PackGetBoolEx(p, "Enables", i);
12527 		t->Errors[i] = PackGetBoolEx(p, "Errors", i);
12528 	}
12529 }
OutRpcListenerList(PACK * p,RPC_LISTENER_LIST * t)12530 void OutRpcListenerList(PACK *p, RPC_LISTENER_LIST *t)
12531 {
12532 	UINT i;
12533 	// Validate arguments
12534 	if (t == NULL || p == NULL)
12535 	{
12536 		return;
12537 	}
12538 
12539 	PackSetCurrentJsonGroupName(p, "ListenerList");
12540 	for (i = 0;i < t->NumPort;i++)
12541 	{
12542 		PackAddIntEx(p, "Ports", t->Ports[i], i, t->NumPort);
12543 		PackAddBoolEx(p, "Enables", t->Enables[i], i, t->NumPort);
12544 		PackAddBoolEx(p, "Errors", t->Errors[i], i, t->NumPort);
12545 	}
12546 	PackSetCurrentJsonGroupName(p, NULL);
12547 }
FreeRpcListenerList(RPC_LISTENER_LIST * t)12548 void FreeRpcListenerList(RPC_LISTENER_LIST *t)
12549 {
12550 	// Validate arguments
12551 	if (t == NULL)
12552 	{
12553 		return;
12554 	}
12555 
12556 	Free(t->Ports);
12557 	Free(t->Enables);
12558 	Free(t->Errors);
12559 }
12560 
12561 // RPC_PORTS
InRpcPorts(RPC_PORTS * t,PACK * p)12562 void InRpcPorts(RPC_PORTS *t, PACK *p)
12563 {
12564 	UINT i;
12565 	// Validate arguments
12566 	if (t == NULL || p == NULL)
12567 	{
12568 		return;
12569 	}
12570 
12571 	t->Num = PackGetIndexCount(p, "Ports");
12572 	t->Ports = ZeroMalloc(sizeof(UINT) * t->Num);
12573 
12574 	for (i = 0; i < t->Num; ++i)
12575 	{
12576 		t->Ports[i] = PackGetIntEx(p, "Ports", i);
12577 	}
12578 }
OutRpcPorts(PACK * p,RPC_PORTS * t)12579 void OutRpcPorts(PACK *p, RPC_PORTS *t)
12580 {
12581 	UINT i;
12582 	// Validate arguments
12583 	if (t == NULL || p == NULL)
12584 	{
12585 		return;
12586 	}
12587 
12588 	for (i = 0; i < t->Num; ++i)
12589 	{
12590 		PackAddIntEx(p, "Ports", t->Ports[i], i, t->Num);
12591 	}
12592 }
FreeRpcPorts(RPC_PORTS * t)12593 void FreeRpcPorts(RPC_PORTS *t)
12594 {
12595 	// Validate arguments
12596 	if (t == NULL)
12597 	{
12598 		return;
12599 	}
12600 
12601 	Free(t->Ports);
12602 }
12603 
12604 // RPC_STR
InRpcStr(RPC_STR * t,PACK * p)12605 void InRpcStr(RPC_STR *t, PACK *p)
12606 {
12607 	UINT size = 65536;
12608 	char *tmp = Malloc(size);
12609 	// Validate arguments
12610 	if (t == NULL || p == NULL)
12611 	{
12612 		return;
12613 	}
12614 
12615 	Zero(t, sizeof(RPC_STR));
12616 	if (PackGetStr(p, "String", tmp, size) == false)
12617 	{
12618 		t->String = CopyStr("");
12619 	}
12620 	else
12621 	{
12622 		t->String = CopyStr(tmp);
12623 	}
12624 	Free(tmp);
12625 }
OutRpcStr(PACK * p,RPC_STR * t)12626 void OutRpcStr(PACK *p, RPC_STR *t)
12627 {
12628 	// Validate arguments
12629 	if (t == NULL || p == NULL)
12630 	{
12631 		return;
12632 	}
12633 
12634 	PackAddStr(p, "String", t->String);
12635 }
FreeRpcStr(RPC_STR * t)12636 void FreeRpcStr(RPC_STR *t)
12637 {
12638 	// Validate arguments
12639 	if (t == NULL )
12640 	{
12641 		return;
12642 	}
12643 
12644 	Free(t->String);
12645 }
12646 
12647 // RPC_PROTO_OPTIONS
InRpcProtoOptions(RPC_PROTO_OPTIONS * t,PACK * p)12648 void InRpcProtoOptions(RPC_PROTO_OPTIONS *t, PACK *p)
12649 {
12650 	UINT i, size;
12651 	// Validate arguments
12652 	if (t == NULL || p == NULL)
12653 	{
12654 		return;
12655 	}
12656 
12657 	Zero(t, sizeof(RPC_PROTO_OPTIONS));
12658 
12659 	size = PackGetStrSize(p, "Protocol");
12660 	if (size > 0)
12661 	{
12662 		t->Protocol = Malloc(size);
12663 
12664 		if (PackGetStr(p, "Protocol", t->Protocol, size) == false)
12665 		{
12666 			Zero(t->Protocol, size);
12667 		}
12668 	}
12669 
12670 	t->Num = PackGetIndexCount(p, "Name");
12671 	if (t->Num == 0)
12672 	{
12673 		return;
12674 	}
12675 
12676 	t->Options = ZeroMalloc(sizeof(PROTO_OPTION) * t->Num);
12677 
12678 	for (i = 0; i < t->Num; ++i)
12679 	{
12680 		PROTO_OPTION *option = &t->Options[i];
12681 
12682 		size = PackGetStrSizeEx(p, "Name", i);
12683 		if (size > 0)
12684 		{
12685 			option->Name = Malloc(size);
12686 			if (PackGetStrEx(p, "Name", option->Name, size, i) == false)
12687 			{
12688 				Zero(option->Name, size);
12689 			}
12690 		}
12691 
12692 		option->Type = PackGetIntEx(p, "Type", i);
12693 		switch (option->Type)
12694 		{
12695 		case PROTO_OPTION_STRING:
12696 			size = PackGetDataSizeEx(p, "Value", i);
12697 			if (size > 0)
12698 			{
12699 				option->String = Malloc(size);
12700 				if (PackGetDataEx2(p, "Value", option->String, size, i) == false)
12701 				{
12702 					Zero(option->String, size);
12703 				}
12704 			}
12705 			break;
12706 		case PROTO_OPTION_BOOL:
12707 			PackGetDataEx2(p, "Value", &option->Bool, sizeof(option->Bool), i);
12708 			break;
12709 		case PROTO_OPTION_UINT32:
12710 			PackGetDataEx2(p, "Value", &option->UInt32, sizeof(option->UInt32), i);
12711 			break;
12712 		default:
12713 			Debug("InRpcProtoOptions(): unhandled type %u!\n", option->Type);
12714 		}
12715 	}
12716 }
OutRpcProtoOptions(PACK * p,RPC_PROTO_OPTIONS * t)12717 void OutRpcProtoOptions(PACK *p, RPC_PROTO_OPTIONS *t)
12718 {
12719 	UINT i;
12720 	// Validate arguments
12721 	if (t == NULL || p == NULL)
12722 	{
12723 		return;
12724 	}
12725 
12726 	PackAddStr(p, "Protocol", t->Protocol);
12727 
12728 	for (i = 0; i < t->Num; ++i)
12729 	{
12730 		PROTO_OPTION *option = &t->Options[i];
12731 
12732 		PackAddStrEx(p, "Name", option->Name, i, t->Num);
12733 		PackAddIntEx(p, "Type", option->Type, i, t->Num);
12734 
12735 		switch (option->Type)
12736 		{
12737 		case PROTO_OPTION_STRING:
12738 			PackAddDataEx(p, "Value", option->String, StrLen(option->String) + 1, i, t->Num);
12739 			break;
12740 		case PROTO_OPTION_BOOL:
12741 			PackAddDataEx(p, "Value", &option->Bool, sizeof(option->Bool), i, t->Num);
12742 			break;
12743 		case PROTO_OPTION_UINT32:
12744 			PackAddDataEx(p, "Value", &option->UInt32, sizeof(option->UInt32), i, t->Num);
12745 			break;
12746 		default:
12747 			Debug("OutRpcProtoOptions(): unhandled type %u!\n", option->Type);
12748 		}
12749 	}
12750 }
FreeRpcProtoOptions(RPC_PROTO_OPTIONS * t)12751 void FreeRpcProtoOptions(RPC_PROTO_OPTIONS *t)
12752 {
12753 	UINT i;
12754 	// Validate arguments
12755 	if (t == NULL)
12756 	{
12757 		return;
12758 	}
12759 
12760 	Free(t->Protocol);
12761 
12762 	for (i = 0; i < t->Num; ++i)
12763 	{
12764 		PROTO_OPTION *option = &t->Options[i];
12765 
12766 		Free(option->Name);
12767 
12768 		if (option->Type == PROTO_OPTION_STRING)
12769 		{
12770 			Free(option->String);
12771 		}
12772 	}
12773 
12774 	Free(t->Options);
12775 }
12776 
12777 // RPC_SET_PASSWORD
InRpcSetPassword(RPC_SET_PASSWORD * t,PACK * p)12778 void InRpcSetPassword(RPC_SET_PASSWORD *t, PACK *p)
12779 {
12780 	// Validate arguments
12781 	if (t == NULL || p == NULL)
12782 	{
12783 		return;
12784 	}
12785 
12786 	Zero(t, sizeof(RPC_SET_PASSWORD));
12787 	PackGetData2(p, "HashedPassword", t->HashedPassword, sizeof(t->HashedPassword));
12788 	PackGetStr(p, "PlainTextPassword", t->PlainTextPassword, sizeof(t->PlainTextPassword));
12789 }
OutRpcSetPassword(PACK * p,RPC_SET_PASSWORD * t)12790 void OutRpcSetPassword(PACK *p, RPC_SET_PASSWORD *t)
12791 {
12792 	// Validate arguments
12793 	if (t == NULL || p == NULL)
12794 	{
12795 		return;
12796 	}
12797 
12798 	PackAddData(p, "HashedPassword", t->HashedPassword, sizeof(t->HashedPassword));
12799 	PackAddStr(p, "PlainTextPassword", t->PlainTextPassword);
12800 }
12801 
12802 // RPC_FARM
InRpcFarm(RPC_FARM * t,PACK * p)12803 void InRpcFarm(RPC_FARM *t, PACK *p)
12804 {
12805 	UINT i;
12806 	// Validate arguments
12807 	if (t == NULL || p == NULL)
12808 	{
12809 		return;
12810 	}
12811 
12812 	Zero(t, sizeof(RPC_FARM));
12813 	t->ServerType = PackGetInt(p, "ServerType");
12814 	t->NumPort = PackGetIndexCount(p, "Ports");
12815 	t->Ports = ZeroMalloc(sizeof(UINT) * t->NumPort);
12816 	for (i = 0;i < t->NumPort;i++)
12817 	{
12818 		t->Ports[i] = PackGetIntEx(p, "Ports", i);
12819 	}
12820 	t->PublicIp = PackGetIp32(p, "PublicIp");
12821 	PackGetStr(p, "ControllerName", t->ControllerName, sizeof(t->ControllerName));
12822 	t->ControllerPort = PackGetInt(p, "ControllerPort");
12823 	PackGetData2(p, "MemberPassword", t->MemberPassword, sizeof(t->MemberPassword));
12824 	PackGetStr(p, "MemberPasswordPlaintext", t->MemberPasswordPlaintext, sizeof(t->MemberPasswordPlaintext));
12825 	t->Weight = PackGetInt(p, "Weight");
12826 	t->ControllerOnly = PackGetBool(p, "ControllerOnly");
12827 }
OutRpcFarm(PACK * p,RPC_FARM * t)12828 void OutRpcFarm(PACK *p, RPC_FARM *t)
12829 {
12830 	UINT i;
12831 	// Validate arguments
12832 	if (t == NULL || p == NULL)
12833 	{
12834 		return;
12835 	}
12836 
12837 	PackAddInt(p, "ServerType", t->ServerType);
12838 	for (i = 0;i < t->NumPort;i++)
12839 	{
12840 		PackAddIntEx(p, "Ports", t->Ports[i], i, t->NumPort);
12841 	}
12842 	PackAddIp32(p, "PublicIp", t->PublicIp);
12843 	PackAddStr(p, "ControllerName", t->ControllerName);
12844 	PackAddInt(p, "ControllerPort", t->ControllerPort);
12845 	PackAddData(p, "MemberPassword", t->MemberPassword, sizeof(t->MemberPassword));
12846 	PackAddStr(p, "MemberPasswordPlaintext", t->MemberPasswordPlaintext);
12847 	PackAddInt(p, "Weight", t->Weight);
12848 	PackAddBool(p, "ControllerOnly", t->ControllerOnly);
12849 }
FreeRpcFarm(RPC_FARM * t)12850 void FreeRpcFarm(RPC_FARM *t)
12851 {
12852 	// Validate arguments
12853 	if (t == NULL)
12854 	{
12855 		return;
12856 	}
12857 
12858 	Free(t->Ports);
12859 }
12860 
12861 // RPC_FARM_HUB
InRpcFarmHub(RPC_FARM_HUB * t,PACK * p)12862 void InRpcFarmHub(RPC_FARM_HUB *t, PACK *p)
12863 {
12864 	// Validate arguments
12865 	if (t == NULL || p == NULL)
12866 	{
12867 		return;
12868 	}
12869 
12870 	Zero(t, sizeof(RPC_FARM_HUB));
12871 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
12872 	t->DynamicHub = PackGetBool(p, "DynamicHub");
12873 }
OutRpcFarmHub(PACK * p,RPC_FARM_HUB * t)12874 void OutRpcFarmHub(PACK *p, RPC_FARM_HUB *t)
12875 {
12876 	// Validate arguments
12877 	if (t == NULL || p == NULL)
12878 	{
12879 		return;
12880 	}
12881 
12882 	PackAddStr(p, "HubName", t->HubName);
12883 	PackAddBool(p, "DynamicHub", t->DynamicHub);
12884 }
12885 
12886 // RPC_FARM_INFO
InRpcFarmInfo(RPC_FARM_INFO * t,PACK * p)12887 void InRpcFarmInfo(RPC_FARM_INFO *t, PACK *p)
12888 {
12889 	UINT i;
12890 	// Validate arguments
12891 	if (t == NULL)
12892 	{
12893 		return;
12894 	}
12895 
12896 	Zero(t, sizeof(RPC_FARM_INFO));
12897 	t->Id = PackGetInt(p, "Id");
12898 	t->Controller = PackGetBool(p, "Controller");
12899 	t->ConnectedTime = PackGetInt64(p, "ConnectedTime");
12900 	t->Ip = PackGetIp32(p, "Ip");
12901 	PackGetStr(p, "Hostname", t->Hostname, sizeof(t->Hostname));
12902 	t->Point = PackGetInt(p, "Point");
12903 	t->NumPort = PackGetIndexCount(p, "Ports");
12904 	t->Ports = ZeroMalloc(sizeof(UINT) * t->NumPort);
12905 	for (i = 0;i < t->NumPort;i++)
12906 	{
12907 		t->Ports[i] = PackGetIntEx(p, "Ports", i);
12908 	}
12909 	t->ServerCert = PackGetX(p, "ServerCert");
12910 	t->NumFarmHub = PackGetIndexCount(p, "HubName");
12911 	t->FarmHubs = ZeroMalloc(sizeof(RPC_FARM_HUB) * t->NumFarmHub);
12912 	for (i = 0;i < t->NumFarmHub;i++)
12913 	{
12914 		PackGetStrEx(p, "HubName", t->FarmHubs[i].HubName, sizeof(t->FarmHubs[i].HubName), i);
12915 		t->FarmHubs[i].DynamicHub = PackGetBoolEx(p, "DynamicHub", i);
12916 	}
12917 	t->NumSessions = PackGetInt(p, "NumSessions");
12918 	t->NumTcpConnections = PackGetInt(p, "NumTcpConnections");
12919 	t->Weight = PackGetInt(p, "Weight");
12920 }
OutRpcFarmInfo(PACK * p,RPC_FARM_INFO * t)12921 void OutRpcFarmInfo(PACK *p, RPC_FARM_INFO *t)
12922 {
12923 	UINT i;
12924 	// Validate arguments
12925 	if (t == NULL || p == NULL)
12926 	{
12927 		return;
12928 	}
12929 
12930 	PackAddInt(p, "Id", t->Id);
12931 	PackAddBool(p, "Controller", t->Controller);
12932 	PackAddTime64(p, "ConnectedTime", t->ConnectedTime);
12933 	PackAddIp32(p, "Ip", t->Ip);
12934 	PackAddStr(p, "Hostname", t->Hostname);
12935 	PackAddInt(p, "Point", t->Point);
12936 	for (i = 0;i < t->NumPort;i++)
12937 	{
12938 		PackAddIntEx(p, "Ports", t->Ports[i], i, t->NumPort);
12939 	}
12940 	PackAddX(p, "ServerCert", t->ServerCert);
12941 
12942 	PackSetCurrentJsonGroupName(p, "HubsList");
12943 	for (i = 0;i < t->NumFarmHub;i++)
12944 	{
12945 		PackAddStrEx(p, "HubName", t->FarmHubs[i].HubName, i, t->NumFarmHub);
12946 		PackAddBoolEx(p, "DynamicHub", t->FarmHubs[i].DynamicHub, i, t->NumFarmHub);
12947 	}
12948 	PackSetCurrentJsonGroupName(p, NULL);
12949 
12950 	PackAddInt(p, "NumSessions", t->NumSessions);
12951 	PackAddInt(p, "NumTcpConnections", t->NumTcpConnections);
12952 	PackAddInt(p, "Weight", t->Weight);
12953 }
FreeRpcFarmInfo(RPC_FARM_INFO * t)12954 void FreeRpcFarmInfo(RPC_FARM_INFO *t)
12955 {
12956 	// Validate arguments
12957 	if (t == NULL)
12958 	{
12959 		return;
12960 	}
12961 
12962 	Free(t->Ports);
12963 	Free(t->FarmHubs);
12964 	FreeX(t->ServerCert);
12965 }
12966 
InRpcEnumFarm(RPC_ENUM_FARM * t,PACK * p)12967 void InRpcEnumFarm(RPC_ENUM_FARM *t, PACK *p)
12968 {
12969 	UINT i;
12970 	// Validate arguments
12971 	if (t == NULL || p == NULL)
12972 	{
12973 		return;
12974 	}
12975 
12976 	Zero(t, sizeof(RPC_ENUM_FARM));
12977 	t->NumFarm = PackGetIndexCount(p, "Id");
12978 	t->Farms = ZeroMalloc(sizeof(RPC_ENUM_FARM_ITEM) * t->NumFarm);
12979 
12980 	for (i = 0;i < t->NumFarm;i++)
12981 	{
12982 		RPC_ENUM_FARM_ITEM *e = &t->Farms[i];
12983 
12984 		e->Id = PackGetIntEx(p, "Id", i);
12985 		e->Controller = PackGetBoolEx(p, "Controller", i);
12986 		e->ConnectedTime = PackGetInt64Ex(p, "ConnectedTime", i);
12987 		e->Ip = PackGetIp32Ex(p, "Ip", i);
12988 		PackGetStrEx(p, "Hostname", e->Hostname, sizeof(e->Hostname), i);
12989 		e->Point = PackGetIntEx(p, "Point", i);
12990 		e->NumSessions = PackGetIntEx(p, "NumSessions", i);
12991 		e->NumTcpConnections = PackGetIntEx(p, "NumTcpConnections", i);
12992 		e->NumHubs = PackGetIntEx(p, "NumHubs", i);
12993 		e->AssignedClientLicense = PackGetIntEx(p, "AssignedClientLicense", i);
12994 		e->AssignedBridgeLicense = PackGetIntEx(p, "AssignedBridgeLicense", i);
12995 	}
12996 }
OutRpcEnumFarm(PACK * p,RPC_ENUM_FARM * t)12997 void OutRpcEnumFarm(PACK *p, RPC_ENUM_FARM *t)
12998 {
12999 	UINT i;
13000 	// Validate arguments
13001 	if (t == NULL || p == NULL)
13002 	{
13003 		return;
13004 	}
13005 
13006 	PackSetCurrentJsonGroupName(p, "FarmMemberList");
13007 	for (i = 0;i < t->NumFarm;i++)
13008 	{
13009 		RPC_ENUM_FARM_ITEM *e = &t->Farms[i];
13010 
13011 		PackAddIntEx(p, "Id", e->Id, i, t->NumFarm);
13012 		PackAddBoolEx(p, "Controller", e->Controller, i, t->NumFarm);
13013 		PackAddTime64Ex(p, "ConnectedTime", e->ConnectedTime, i, t->NumFarm);
13014 		PackAddIp32Ex(p, "Ip", e->Ip, i, t->NumFarm);
13015 		PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumFarm);
13016 		PackAddIntEx(p, "Point", e->Point, i, t->NumFarm);
13017 		PackAddIntEx(p, "NumSessions", e->NumSessions, i, t->NumFarm);
13018 		PackAddIntEx(p, "NumTcpConnections", e->NumTcpConnections, i, t->NumFarm);
13019 		PackAddIntEx(p, "NumHubs", e->NumHubs, i, t->NumFarm);
13020 		PackAddIntEx(p, "AssignedClientLicense", e->AssignedClientLicense, i, t->NumFarm);
13021 		PackAddIntEx(p, "AssignedBridgeLicense", e->AssignedBridgeLicense, i, t->NumFarm);
13022 	}
13023 	PackSetCurrentJsonGroupName(p, NULL);
13024 }
FreeRpcEnumFarm(RPC_ENUM_FARM * t)13025 void FreeRpcEnumFarm(RPC_ENUM_FARM *t)
13026 {
13027 	// Validate arguments
13028 	if (t == NULL)
13029 	{
13030 		return;
13031 	}
13032 
13033 	Free(t->Farms);
13034 }
13035 
13036 // RPC_FARM_CONNECTION_STATUS
InRpcFarmConnectionStatus(RPC_FARM_CONNECTION_STATUS * t,PACK * p)13037 void InRpcFarmConnectionStatus(RPC_FARM_CONNECTION_STATUS *t, PACK *p)
13038 {
13039 	Zero(t, sizeof(RPC_FARM_CONNECTION_STATUS));
13040 	// Validate arguments
13041 	if (t == NULL || p == NULL)
13042 	{
13043 		return;
13044 	}
13045 
13046 	t->Ip = PackGetIp32(p, "Ip");
13047 	t->Port = PackGetInt(p, "Port");
13048 	t->Online = PackGetBool(p, "Online");
13049 	t->LastError = PackGetInt(p, "LastError");
13050 	t->StartedTime = PackGetInt64(p, "StartedTime");
13051 	t->CurrentConnectedTime = PackGetInt64(p, "CurrentConnectedTime");
13052 	t->FirstConnectedTime = PackGetInt64(p, "FirstConnectedTime");
13053 	t->NumConnected = PackGetInt(p, "NumConnected");
13054 	t->NumTry = PackGetInt(p, "NumTry");
13055 	t->NumFailed = PackGetInt(p, "NumFailed");
13056 }
OutRpcFarmConnectionStatus(PACK * p,RPC_FARM_CONNECTION_STATUS * t)13057 void OutRpcFarmConnectionStatus(PACK *p, RPC_FARM_CONNECTION_STATUS *t)
13058 {
13059 	// Validate arguments
13060 	if (t == NULL || p == NULL)
13061 	{
13062 		return;
13063 	}
13064 
13065 	PackAddIp32(p, "Ip", t->Ip);
13066 	PackAddInt(p, "Port", t->Port);
13067 	PackAddBool(p, "Online", t->Online);
13068 	PackAddInt(p, "LastError", t->LastError);
13069 	PackAddTime64(p, "StartedTime", t->StartedTime);
13070 	PackAddTime64(p, "CurrentConnectedTime", t->CurrentConnectedTime);
13071 	PackAddTime64(p, "FirstConnectedTime", t->FirstConnectedTime);
13072 	PackAddInt(p, "NumConnected", t->NumConnected);
13073 	PackAddInt(p, "NumTry", t->NumTry);
13074 	PackAddInt(p, "NumFailed", t->NumFailed);
13075 }
13076 
13077 // RPC_HUB_OPTION
InRpcHubOption(RPC_HUB_OPTION * t,PACK * p)13078 void InRpcHubOption(RPC_HUB_OPTION *t, PACK *p)
13079 {
13080 	// Validate arguments
13081 	if (t == NULL || p == NULL)
13082 	{
13083 		return;
13084 	}
13085 
13086 	Zero(t, sizeof(RPC_HUB_OPTION));
13087 	t->DefaultGateway = PackGetInt(p, "DefaultGateway");
13088 	t->DefaultSubnet = PackGetInt(p, "DefaultSubnet");
13089 	t->MaxSession = PackGetInt(p, "MaxSession");
13090 	t->NoEnum = PackGetBool(p, "NoEnum");
13091 }
OutRpcHubOption(PACK * p,RPC_HUB_OPTION * t)13092 void OutRpcHubOption(PACK *p, RPC_HUB_OPTION *t)
13093 {
13094 	// Validate arguments
13095 	if (t == NULL || p == NULL)
13096 	{
13097 		return;
13098 	}
13099 
13100 	PackAddInt(p, "DefaultGateway", t->DefaultGateway);
13101 	PackAddInt(p, "DefaultSubnet", t->DefaultSubnet);
13102 	PackAddInt(p, "MaxSession", t->MaxSession);
13103 	PackAddBool(p, "NoEnum", t->NoEnum);
13104 }
13105 
13106 // RPC_RADIUS
InRpcRadius(RPC_RADIUS * t,PACK * p)13107 void InRpcRadius(RPC_RADIUS *t, PACK *p)
13108 {
13109 	// Validate arguments
13110 	if (t == NULL || p == NULL)
13111 	{
13112 		return;
13113 	}
13114 
13115 	Zero(t, sizeof(RPC_RADIUS));
13116 	PackGetStr(p, "RadiusServerName", t->RadiusServerName, sizeof(t->RadiusServerName));
13117 	t->RadiusPort = PackGetInt(p, "RadiusPort");
13118 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13119 	PackGetStr(p, "RadiusSecret", t->RadiusSecret, sizeof(t->RadiusSecret));
13120 	t->RadiusRetryInterval = PackGetInt(p, "RadiusRetryInterval");
13121 }
OutRpcRadius(PACK * p,RPC_RADIUS * t)13122 void OutRpcRadius(PACK *p, RPC_RADIUS *t)
13123 {
13124 	// Validate arguments
13125 	if (t == NULL || p == NULL)
13126 	{
13127 		return;
13128 	}
13129 
13130 	PackAddStr(p, "RadiusServerName", t->RadiusServerName);
13131 	PackAddInt(p, "RadiusPort", t->RadiusPort);
13132 	PackAddStr(p, "HubName", t->HubName);
13133 	PackAddStr(p, "RadiusSecret", t->RadiusSecret);
13134 	PackAddInt(p, "RadiusRetryInterval", t->RadiusRetryInterval);
13135 }
13136 
13137 // RPC_HUB
InRpcHub(RPC_HUB * t,PACK * p)13138 void InRpcHub(RPC_HUB *t, PACK *p)
13139 {
13140 	// Validate arguments
13141 	if (t == NULL || p == NULL)
13142 	{
13143 		return;
13144 	}
13145 
13146 	Zero(t, sizeof(RPC_HUB));
13147 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13148 }
OutRpcHub(PACK * p,RPC_HUB * t)13149 void OutRpcHub(PACK *p, RPC_HUB *t)
13150 {
13151 	// Validate arguments
13152 	if (t == NULL || p == NULL)
13153 	{
13154 		return;
13155 	}
13156 
13157 	PackAddStr(p, "HubName", t->HubName);
13158 }
13159 
13160 // RPC_CREATE_HUB
InRpcCreateHub(RPC_CREATE_HUB * t,PACK * p)13161 void InRpcCreateHub(RPC_CREATE_HUB *t, PACK *p)
13162 {
13163 	// Validate arguments
13164 	if (t == NULL || p == NULL)
13165 	{
13166 		return;
13167 	}
13168 
13169 	Zero(t, sizeof(RPC_CREATE_HUB));
13170 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13171 	PackGetData2(p, "HashedPassword", t->HashedPassword, sizeof(t->HashedPassword));
13172 	PackGetData2(p, "SecurePassword", t->SecurePassword, sizeof(t->SecurePassword));
13173 	PackGetStr(p, "AdminPasswordPlainText", t->AdminPasswordPlainText, sizeof(t->AdminPasswordPlainText));
13174 	t->Online = PackGetBool(p, "Online");
13175 	InRpcHubOption(&t->HubOption, p);
13176 	t->HubType = PackGetInt(p, "HubType");
13177 }
OutRpcCreateHub(PACK * p,RPC_CREATE_HUB * t)13178 void OutRpcCreateHub(PACK *p, RPC_CREATE_HUB *t)
13179 {
13180 	// Validate arguments
13181 	if (t == NULL || p == NULL)
13182 	{
13183 		return;
13184 	}
13185 
13186 	PackAddStr(p, "HubName", t->HubName);
13187 	PackAddData(p, "HashedPassword", t->HashedPassword, sizeof(t->HashedPassword));
13188 	PackAddData(p, "SecurePassword", t->SecurePassword, sizeof(t->SecurePassword));
13189 	PackAddBool(p, "Online", t->Online);
13190 	PackAddStr(p, "AdminPasswordPlainText", t->AdminPasswordPlainText);
13191 	OutRpcHubOption(p, &t->HubOption);
13192 	PackAddInt(p, "HubType", t->HubType);
13193 }
13194 
13195 // RPC_ENUM_HUB
InRpcEnumHub(RPC_ENUM_HUB * t,PACK * p)13196 void InRpcEnumHub(RPC_ENUM_HUB *t, PACK *p)
13197 {
13198 	UINT i;
13199 	// Validate arguments
13200 	if (t == NULL || p == NULL)
13201 	{
13202 		return;
13203 	}
13204 
13205 	Zero(t, sizeof(RPC_ENUM_HUB));
13206 	t->NumHub = PackGetIndexCount(p, "HubName");
13207 	t->Hubs = ZeroMalloc(sizeof(RPC_ENUM_HUB_ITEM) * t->NumHub);
13208 
13209 	for (i = 0;i < t->NumHub;i++)
13210 	{
13211 		RPC_ENUM_HUB_ITEM *e = &t->Hubs[i];
13212 
13213 		PackGetStrEx(p, "HubName", e->HubName, sizeof(e->HubName), i);
13214 		e->Online = PackGetBoolEx(p, "Online", i);
13215 		e->HubType = PackGetIntEx(p, "HubType", i);
13216 		e->NumSessions = PackGetIntEx(p, "NumSessions", i);
13217 		e->NumUsers = PackGetIntEx(p, "NumUsers", i);
13218 		e->NumGroups = PackGetIntEx(p, "NumGroups", i);
13219 		e->NumMacTables = PackGetIntEx(p, "NumMacTables", i);
13220 		e->NumIpTables = PackGetIntEx(p, "NumIpTables", i);
13221 		e->LastCommTime = PackGetInt64Ex(p, "LastCommTime", i);
13222 		e->CreatedTime = PackGetInt64Ex(p, "CreatedTime", i);
13223 		e->LastLoginTime = PackGetInt64Ex(p, "LastLoginTime", i);
13224 		e->NumLogin = PackGetIntEx(p, "NumLogin", i);
13225 		e->IsTrafficFilled = PackGetBoolEx(p, "IsTrafficFilled", i);
13226 
13227 		InRpcTrafficEx(&e->Traffic, p, i);
13228 	}
13229 }
OutRpcEnumHub(PACK * p,RPC_ENUM_HUB * t)13230 void OutRpcEnumHub(PACK *p, RPC_ENUM_HUB *t)
13231 {
13232 	UINT i;
13233 	// Validate arguments
13234 	if (t == NULL || p == NULL)
13235 	{
13236 		return;
13237 	}
13238 
13239 	PackSetCurrentJsonGroupName(p, "HubList");
13240 	for (i = 0;i < t->NumHub;i++)
13241 	{
13242 		RPC_ENUM_HUB_ITEM *e = &t->Hubs[i];
13243 
13244 		PackAddStrEx(p, "HubName", e->HubName, i, t->NumHub);
13245 		PackAddBoolEx(p, "Online", e->Online, i, t->NumHub);
13246 		PackAddIntEx(p, "HubType", e->HubType, i, t->NumHub);
13247 		PackAddIntEx(p, "NumSessions", e->NumSessions, i, t->NumHub);
13248 		PackAddIntEx(p, "NumUsers", e->NumUsers, i, t->NumHub);
13249 		PackAddIntEx(p, "NumGroups", e->NumGroups, i, t->NumHub);
13250 		PackAddIntEx(p, "NumMacTables", e->NumMacTables, i, t->NumHub);
13251 		PackAddIntEx(p, "NumIpTables", e->NumIpTables, i, t->NumHub);
13252 		PackAddTime64Ex(p, "LastCommTime", e->LastCommTime, i, t->NumHub);
13253 		PackAddTime64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumHub);
13254 		PackAddTime64Ex(p, "LastLoginTime", e->LastLoginTime, i, t->NumHub);
13255 		PackAddIntEx(p, "NumLogin", e->NumLogin, i, t->NumHub);
13256 		PackAddBoolEx(p, "IsTrafficFilled", e->IsTrafficFilled, i, t->NumHub);
13257 
13258 		OutRpcTrafficEx(&e->Traffic, p, i, t->NumHub);
13259 	}
13260 	PackSetCurrentJsonGroupName(p, NULL);
13261 }
FreeRpcEnumHub(RPC_ENUM_HUB * t)13262 void FreeRpcEnumHub(RPC_ENUM_HUB *t)
13263 {
13264 	// Validate arguments
13265 	if (t == NULL)
13266 	{
13267 		return;
13268 	}
13269 
13270 	Free(t->Hubs);
13271 }
13272 
13273 // RPC_DELETE_HUB
InRpcDeleteHub(RPC_DELETE_HUB * t,PACK * p)13274 void InRpcDeleteHub(RPC_DELETE_HUB *t, PACK *p)
13275 {
13276 	// Validate arguments
13277 	if (t == NULL || p == NULL)
13278 	{
13279 		return;
13280 	}
13281 
13282 	Zero(t, sizeof(RPC_DELETE_HUB));
13283 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13284 }
OutRpcDeleteHub(PACK * p,RPC_DELETE_HUB * t)13285 void OutRpcDeleteHub(PACK *p, RPC_DELETE_HUB *t)
13286 {
13287 	// Validate arguments
13288 	if (t == NULL || p == NULL)
13289 	{
13290 		return;
13291 	}
13292 
13293 	PackAddStr(p, "HubName", t->HubName);
13294 }
13295 
13296 // RPC_ENUM_CONNECTION
InRpcEnumConnection(RPC_ENUM_CONNECTION * t,PACK * p)13297 void InRpcEnumConnection(RPC_ENUM_CONNECTION *t, PACK *p)
13298 {
13299 	UINT i;
13300 	// Validate arguments
13301 	if (t == NULL || p == NULL)
13302 	{
13303 		return;
13304 	}
13305 
13306 	Zero(t, sizeof(RPC_ENUM_CONNECTION));
13307 	t->NumConnection = PackGetIndexCount(p, "Name");
13308 	t->Connections = ZeroMalloc(sizeof(RPC_ENUM_CONNECTION_ITEM) * t->NumConnection);
13309 
13310 	for (i = 0;i < t->NumConnection;i++)
13311 	{
13312 		RPC_ENUM_CONNECTION_ITEM *e = &t->Connections[i];
13313 
13314 		e->Ip = PackGetIp32Ex(p, "Ip", i);
13315 		e->Port = PackGetIntEx(p, "Port", i);
13316 		PackGetStrEx(p, "Name", e->Name, sizeof(e->Name), i);
13317 		PackGetStrEx(p, "Hostname", e->Hostname, sizeof(e->Hostname), i);
13318 		e->ConnectedTime = PackGetInt64Ex(p, "ConnectedTime", i);
13319 		e->Type = PackGetIntEx(p, "Type", i);
13320 	}
13321 }
OutRpcEnumConnection(PACK * p,RPC_ENUM_CONNECTION * t)13322 void OutRpcEnumConnection(PACK *p, RPC_ENUM_CONNECTION *t)
13323 {
13324 	UINT i;
13325 	// Validate arguments
13326 	if (t == NULL || p == NULL)
13327 	{
13328 		return;
13329 	}
13330 
13331 	PackSetCurrentJsonGroupName(p, "ConnectionList");
13332 	for (i = 0;i < t->NumConnection;i++)
13333 	{
13334 		RPC_ENUM_CONNECTION_ITEM *e = &t->Connections[i];
13335 
13336 		PackAddIp32Ex(p, "Ip", e->Ip, i, t->NumConnection);
13337 		PackAddIntEx(p, "Port", e->Port, i, t->NumConnection);
13338 		PackAddStrEx(p, "Name", e->Name, i, t->NumConnection);
13339 		PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumConnection);
13340 		PackAddTime64Ex(p, "ConnectedTime", e->ConnectedTime, i, t->NumConnection);
13341 		PackAddIntEx(p, "Type", e->Type, i, t->NumConnection);
13342 	}
13343 	PackSetCurrentJsonGroupName(p, NULL);
13344 }
FreeRpcEnumConnection(RPC_ENUM_CONNECTION * t)13345 void FreeRpcEnumConnection(RPC_ENUM_CONNECTION *t)
13346 {
13347 	// Validate arguments
13348 	if (t == NULL)
13349 	{
13350 		return;
13351 	}
13352 
13353 	Free(t->Connections);
13354 }
13355 
13356 // RPC_DISCONNECT_CONNECTION
InRpcDisconnectConnection(RPC_DISCONNECT_CONNECTION * t,PACK * p)13357 void InRpcDisconnectConnection(RPC_DISCONNECT_CONNECTION *t, PACK *p)
13358 {
13359 	// Validate arguments
13360 	if (t == NULL || p == NULL)
13361 	{
13362 		return;
13363 	}
13364 
13365 	Zero(t, sizeof(RPC_DISCONNECT_CONNECTION));
13366 	PackGetStr(p, "Name", t->Name, sizeof(t->Name));
13367 }
OutRpcDisconnectConnection(PACK * p,RPC_DISCONNECT_CONNECTION * t)13368 void OutRpcDisconnectConnection(PACK *p, RPC_DISCONNECT_CONNECTION *t)
13369 {
13370 	// Validate arguments
13371 	if (t == NULL || p == NULL)
13372 	{
13373 		return;
13374 	}
13375 
13376 	PackAddStr(p, "Name", t->Name);
13377 }
13378 
13379 // RPC_CONNECTION_INFO
InRpcConnectionInfo(RPC_CONNECTION_INFO * t,PACK * p)13380 void InRpcConnectionInfo(RPC_CONNECTION_INFO *t, PACK *p)
13381 {
13382 	// Validate arguments
13383 	if (t == NULL || p == NULL)
13384 	{
13385 		return;
13386 	}
13387 
13388 	Zero(t, sizeof(RPC_CONNECTION_INFO));
13389 	PackGetStr(p, "Name", t->Name, sizeof(t->Name));
13390 	t->Ip = PackGetIp32(p, "Ip");
13391 	t->Port = PackGetInt(p, "Port");
13392 	t->ConnectedTime = PackGetInt64(p, "ConnectedTime");
13393 	PackGetStr(p, "Hostname", t->Hostname, sizeof(t->Hostname));
13394 	PackGetStr(p, "ServerStr", t->ServerStr, sizeof(t->ServerStr));
13395 	PackGetStr(p, "ClientStr", t->ClientStr, sizeof(t->ClientStr));
13396 	t->ServerVer = PackGetInt(p, "ServerVer");
13397 	t->ServerBuild = PackGetInt(p, "ServerBuild");
13398 	t->ClientVer = PackGetInt(p, "ClientVer");
13399 	t->ClientBuild = PackGetInt(p, "ClientBuild");
13400 	t->Type = PackGetInt(p, "Type");
13401 }
OutRpcConnectionInfo(PACK * p,RPC_CONNECTION_INFO * t)13402 void OutRpcConnectionInfo(PACK *p, RPC_CONNECTION_INFO *t)
13403 {
13404 	// Validate arguments
13405 	if (t == NULL || p == NULL)
13406 	{
13407 		return;
13408 	}
13409 
13410 	PackAddStr(p, "Name", t->Name);
13411 	PackAddIp32(p, "Ip", t->Ip);
13412 	PackAddInt(p, "Port", t->Port);
13413 	PackAddTime64(p, "ConnectedTime", t->ConnectedTime);
13414 	PackAddStr(p, "Hostname", t->Hostname);
13415 	PackAddStr(p, "ServerStr", t->ServerStr);
13416 	PackAddStr(p, "ClientStr", t->ClientStr);
13417 	PackAddInt(p, "ServerVer", t->ServerVer);
13418 	PackAddInt(p, "ServerBuild", t->ServerBuild);
13419 	PackAddInt(p, "ClientVer", t->ClientVer);
13420 	PackAddInt(p, "ClientBuild", t->ClientBuild);
13421 	PackAddInt(p, "Type", t->Type);
13422 }
13423 
13424 // RPC_SET_HUB_ONLINE
InRpcSetHubOnline(RPC_SET_HUB_ONLINE * t,PACK * p)13425 void InRpcSetHubOnline(RPC_SET_HUB_ONLINE *t, PACK *p)
13426 {
13427 	// Validate arguments
13428 	if (t == NULL || p == NULL)
13429 	{
13430 		return;
13431 	}
13432 
13433 	Zero(t, sizeof(RPC_SET_HUB_ONLINE));
13434 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13435 	t->Online = PackGetBool(p, "Online");
13436 }
OutRpcSetHubOnline(PACK * p,RPC_SET_HUB_ONLINE * t)13437 void OutRpcSetHubOnline(PACK *p, RPC_SET_HUB_ONLINE *t)
13438 {
13439 	// Validate arguments
13440 	if (t == NULL || p == NULL)
13441 	{
13442 		return;
13443 	}
13444 
13445 	PackAddStr(p, "HubName", t->HubName);
13446 	PackAddBool(p, "Online", t->Online);
13447 }
13448 
13449 // RPC_HUB_STATUS
InRpcHubStatus(RPC_HUB_STATUS * t,PACK * p)13450 void InRpcHubStatus(RPC_HUB_STATUS *t, PACK *p)
13451 {
13452 	Zero(t, sizeof(RPC_HUB_STATUS));
13453 	// Validate arguments
13454 	if (t == NULL || p == NULL)
13455 	{
13456 		return;
13457 	}
13458 
13459 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13460 	t->Online = PackGetBool(p, "Online");
13461 	t->HubType = PackGetInt(p, "HubType");
13462 	t->NumSessions = PackGetInt(p, "NumSessions");
13463 	t->NumSessionsClient = PackGetInt(p, "NumSessionsClient");
13464 	t->NumSessionsBridge = PackGetInt(p, "NumSessionsBridge");
13465 	t->NumAccessLists = PackGetInt(p, "NumAccessLists");
13466 	t->NumUsers = PackGetInt(p, "NumUsers");
13467 	t->NumGroups = PackGetInt(p, "NumGroups");
13468 	t->NumMacTables = PackGetInt(p, "NumMacTables");
13469 	t->NumIpTables = PackGetInt(p, "NumIpTables");
13470 	t->SecureNATEnabled = PackGetBool(p, "SecureNATEnabled");
13471 	InRpcTraffic(&t->Traffic, p);
13472 	t->LastCommTime = PackGetInt64(p, "LastCommTime");
13473 	t->CreatedTime = PackGetInt64(p, "CreatedTime");
13474 	t->LastLoginTime = PackGetInt64(p, "LastLoginTime");
13475 	t->NumLogin = PackGetInt(p, "NumLogin");
13476 }
OutRpcHubStatus(PACK * p,RPC_HUB_STATUS * t)13477 void OutRpcHubStatus(PACK *p, RPC_HUB_STATUS *t)
13478 {
13479 	// Validate arguments
13480 	if (t == NULL || p == NULL)
13481 	{
13482 		return;
13483 	}
13484 
13485 	PackAddStr(p, "HubName", t->HubName);
13486 	PackAddBool(p, "Online", t->Online);
13487 	PackAddInt(p, "HubType", t->HubType);
13488 	PackAddInt(p, "NumSessions", t->NumSessions);
13489 	PackAddInt(p, "NumSessionsClient", t->NumSessionsClient);
13490 	PackAddInt(p, "NumSessionsBridge", t->NumSessionsBridge);
13491 	PackAddInt(p, "NumAccessLists", t->NumAccessLists);
13492 	PackAddInt(p, "NumUsers", t->NumUsers);
13493 	PackAddInt(p, "NumGroups", t->NumGroups);
13494 	PackAddInt(p, "NumMacTables", t->NumMacTables);
13495 	PackAddInt(p, "NumIpTables", t->NumIpTables);
13496 	PackAddBool(p, "SecureNATEnabled", t->SecureNATEnabled);
13497 	OutRpcTraffic(p, &t->Traffic);
13498 	PackAddTime64(p, "LastCommTime", t->LastCommTime);
13499 	PackAddTime64(p, "CreatedTime", t->CreatedTime);
13500 	PackAddTime64(p, "LastLoginTime", t->LastLoginTime);
13501 	PackAddInt(p, "NumLogin", t->NumLogin);
13502 }
13503 
13504 // RPC_HUB_LOG
InRpcHubLog(RPC_HUB_LOG * t,PACK * p)13505 void InRpcHubLog(RPC_HUB_LOG *t, PACK *p)
13506 {
13507 	UINT i;
13508 	// Validate arguments
13509 	if (t == NULL || p == NULL)
13510 	{
13511 		return;
13512 	}
13513 
13514 	Zero(t, sizeof(RPC_HUB_LOG));
13515 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13516 	t->LogSetting.SaveSecurityLog = PackGetBool(p, "SaveSecurityLog");
13517 	t->LogSetting.SecurityLogSwitchType = PackGetInt(p, "SecurityLogSwitchType");
13518 	t->LogSetting.SavePacketLog = PackGetBool(p, "SavePacketLog");
13519 	t->LogSetting.PacketLogSwitchType = PackGetInt(p, "PacketLogSwitchType");
13520 	for (i = 0;i < NUM_PACKET_LOG;i++)
13521 	{
13522 		t->LogSetting.PacketLogConfig[i] = PackGetIntEx(p, "PacketLogConfig", i);
13523 	}
13524 }
OutRpcHubLog(PACK * p,RPC_HUB_LOG * t)13525 void OutRpcHubLog(PACK *p, RPC_HUB_LOG *t)
13526 {
13527 	UINT i;
13528 	// Validate arguments
13529 	if (t == NULL || p == NULL)
13530 	{
13531 		return;
13532 	}
13533 
13534 	PackAddStr(p, "HubName", t->HubName);
13535 	PackAddBool(p, "SaveSecurityLog", t->LogSetting.SaveSecurityLog);
13536 	PackAddInt(p, "SecurityLogSwitchType", t->LogSetting.SecurityLogSwitchType);
13537 	PackAddBool(p, "SavePacketLog", t->LogSetting.SavePacketLog);
13538 	PackAddInt(p, "PacketLogSwitchType", t->LogSetting.PacketLogSwitchType);
13539 	for (i = 0;i < NUM_PACKET_LOG;i++)
13540 	{
13541 		PackAddIntEx(p, "PacketLogConfig", t->LogSetting.PacketLogConfig[i], i, NUM_PACKET_LOG);
13542 	}
13543 }
13544 
13545 // RPC_HUB_ADD_CA
InRpcHubAddCa(RPC_HUB_ADD_CA * t,PACK * p)13546 void InRpcHubAddCa(RPC_HUB_ADD_CA *t, PACK *p)
13547 {
13548 	// Validate arguments
13549 	if (t == NULL || p == NULL)
13550 	{
13551 		return;
13552 	}
13553 
13554 	Zero(t, sizeof(RPC_HUB_ADD_CA));
13555 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13556 	t->Cert = PackGetX(p, "Cert");
13557 }
OutRpcHubAddCa(PACK * p,RPC_HUB_ADD_CA * t)13558 void OutRpcHubAddCa(PACK *p, RPC_HUB_ADD_CA *t)
13559 {
13560 	// Validate arguments
13561 	if (t == NULL || p == NULL)
13562 	{
13563 		return;
13564 	}
13565 
13566 	PackAddStr(p, "HubName", t->HubName);
13567 	PackAddX(p, "Cert", t->Cert);
13568 }
FreeRpcHubAddCa(RPC_HUB_ADD_CA * t)13569 void FreeRpcHubAddCa(RPC_HUB_ADD_CA *t)
13570 {
13571 	// Validate arguments
13572 	if (t == NULL)
13573 	{
13574 		return;
13575 	}
13576 
13577 	FreeX(t->Cert);
13578 }
13579 
13580 // RPC_HUB_ENUM_CA
InRpcHubEnumCa(RPC_HUB_ENUM_CA * t,PACK * p)13581 void InRpcHubEnumCa(RPC_HUB_ENUM_CA *t, PACK *p)
13582 {
13583 	UINT i;
13584 	// Validate arguments
13585 	if (t == NULL || p == NULL)
13586 	{
13587 		return;
13588 	}
13589 
13590 	Zero(t, sizeof(RPC_HUB_ENUM_CA));
13591 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13592 	t->NumCa = PackGetIndexCount(p, "Key");
13593 	t->Ca = ZeroMalloc(sizeof(RPC_HUB_ENUM_CA_ITEM) * t->NumCa);
13594 
13595 	for (i = 0;i < t->NumCa;i++)
13596 	{
13597 		RPC_HUB_ENUM_CA_ITEM *e = &t->Ca[i];
13598 
13599 		e->Key = PackGetIntEx(p, "Key", i);
13600 		PackGetUniStrEx(p, "SubjectName", e->SubjectName, sizeof(e->SubjectName), i);
13601 		PackGetUniStrEx(p, "IssuerName", e->IssuerName, sizeof(e->IssuerName), i);
13602 		e->Expires = PackGetInt64Ex(p, "Expires", i);
13603 	}
13604 }
OutRpcHubEnumCa(PACK * p,RPC_HUB_ENUM_CA * t)13605 void OutRpcHubEnumCa(PACK *p, RPC_HUB_ENUM_CA *t)
13606 {
13607 	UINT i;
13608 	// Validate arguments
13609 	if (t == NULL || p == NULL)
13610 	{
13611 		return;
13612 	}
13613 	PackAddStr(p, "HubName", t->HubName);
13614 
13615 	PackSetCurrentJsonGroupName(p, "CAList");
13616 	for (i = 0;i < t->NumCa;i++)
13617 	{
13618 		RPC_HUB_ENUM_CA_ITEM *e = &t->Ca[i];
13619 
13620 		PackAddIntEx(p, "Key", e->Key, i, t->NumCa);
13621 		PackAddUniStrEx(p, "SubjectName", e->SubjectName, i, t->NumCa);
13622 		PackAddUniStrEx(p, "IssuerName", e->IssuerName, i, t->NumCa);
13623 		PackAddTime64Ex(p, "Expires", e->Expires, i, t->NumCa);
13624 	}
13625 	PackSetCurrentJsonGroupName(p, NULL);
13626 }
FreeRpcHubEnumCa(RPC_HUB_ENUM_CA * t)13627 void FreeRpcHubEnumCa(RPC_HUB_ENUM_CA *t)
13628 {
13629 	// Validate arguments
13630 	if (t == NULL)
13631 	{
13632 		return;
13633 	}
13634 
13635 	Free(t->Ca);
13636 }
13637 
13638 // RPC_HUB_GET_CA
InRpcHubGetCa(RPC_HUB_GET_CA * t,PACK * p)13639 void InRpcHubGetCa(RPC_HUB_GET_CA *t, PACK *p)
13640 {
13641 	// Validate arguments
13642 	if (t == NULL || p == NULL)
13643 	{
13644 		return;
13645 	}
13646 
13647 	Zero(t, sizeof(RPC_HUB_GET_CA));
13648 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13649 	t->Key = PackGetInt(p, "Key");
13650 	t->Cert = PackGetX(p, "Cert");
13651 }
OutRpcHubGetCa(PACK * p,RPC_HUB_GET_CA * t)13652 void OutRpcHubGetCa(PACK *p, RPC_HUB_GET_CA *t)
13653 {
13654 	// Validate arguments
13655 	if (t == NULL || p == NULL)
13656 	{
13657 		return;
13658 	}
13659 
13660 	PackAddStr(p, "HubName", t->HubName);
13661 	PackAddInt(p, "Key", t->Key);
13662 	PackAddX(p, "Cert", t->Cert);
13663 }
FreeRpcHubGetCa(RPC_HUB_GET_CA * t)13664 void FreeRpcHubGetCa(RPC_HUB_GET_CA *t)
13665 {
13666 	// Validate arguments
13667 	if (t == NULL)
13668 	{
13669 		return;
13670 	}
13671 
13672 	FreeX(t->Cert);
13673 }
13674 
13675 // RPC_HUB_DELETE_CA
InRpcHubDeleteCa(RPC_HUB_DELETE_CA * t,PACK * p)13676 void InRpcHubDeleteCa(RPC_HUB_DELETE_CA *t, PACK *p)
13677 {
13678 	// Validate arguments
13679 	if (t == NULL || p == NULL)
13680 	{
13681 		return;
13682 	}
13683 
13684 	Zero(t, sizeof(RPC_HUB_DELETE_CA));
13685 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13686 	t->Key = PackGetInt(p, "Key");
13687 }
OutRpcHubDeleteCa(PACK * p,RPC_HUB_DELETE_CA * t)13688 void OutRpcHubDeleteCa(PACK *p, RPC_HUB_DELETE_CA *t)
13689 {
13690 	// Validate arguments
13691 	if (t == NULL || p == NULL)
13692 	{
13693 		return;
13694 	}
13695 
13696 	PackAddStr(p, "HubName", t->HubName);
13697 	PackAddInt(p, "Key", t->Key);
13698 }
13699 
13700 // RPC_CREATE_LINK
InRpcCreateLink(RPC_CREATE_LINK * t,PACK * p)13701 void InRpcCreateLink(RPC_CREATE_LINK *t, PACK *p)
13702 {
13703 	BUF *b;
13704 	// Validate arguments
13705 	if (t == NULL || p == NULL)
13706 	{
13707 		return;
13708 	}
13709 
13710 	Zero(t, sizeof(RPC_CREATE_LINK));
13711 	PackGetStr(p, "HubName_Ex", t->HubName, sizeof(t->HubName));
13712 	t->Online = PackGetBool(p, "Online");
13713 	t->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
13714 	InRpcClientOption(t->ClientOption, p);
13715 	t->ClientAuth  = ZeroMalloc(sizeof(CLIENT_AUTH));
13716 	InRpcClientAuth(t->ClientAuth, p);
13717 	InRpcPolicy(&t->Policy, p);
13718 
13719 	t->CheckServerCert = PackGetBool(p, "CheckServerCert");
13720 	b = PackGetBuf(p, "ServerCert");
13721 	if (b != NULL)
13722 	{
13723 		t->ServerCert = BufToX(b, false);
13724 		FreeBuf(b);
13725 	}
13726 }
OutRpcCreateLink(PACK * p,RPC_CREATE_LINK * t)13727 void OutRpcCreateLink(PACK *p, RPC_CREATE_LINK *t)
13728 {
13729 	// Validate arguments
13730 	if (t == NULL || p == NULL)
13731 	{
13732 		return;
13733 	}
13734 
13735 	PackAddStr(p, "HubName_Ex",t->HubName);
13736 	PackAddBool(p, "Online", t->Online);
13737 	OutRpcClientOption(p, t->ClientOption);
13738 	OutRpcClientAuth(p, t->ClientAuth);
13739 	OutRpcPolicy(p, &t->Policy);
13740 
13741 	PackAddBool(p, "CheckServerCert", t->CheckServerCert);
13742 	if (t->ServerCert != NULL)
13743 	{
13744 		BUF *b;
13745 		b = XToBuf(t->ServerCert, false);
13746 		PackAddBuf(p, "ServerCert", b);
13747 		FreeBuf(b);
13748 	}
13749 }
FreeRpcCreateLink(RPC_CREATE_LINK * t)13750 void FreeRpcCreateLink(RPC_CREATE_LINK *t)
13751 {
13752 	// Validate arguments
13753 	if (t == NULL)
13754 	{
13755 		return;
13756 	}
13757 
13758 	if (t->ServerCert != NULL)
13759 	{
13760 		FreeX(t->ServerCert);
13761 	}
13762 	Free(t->ClientOption);
13763 	CiFreeClientAuth(t->ClientAuth);
13764 }
13765 
13766 // RPC_ENUM_LINK
InRpcEnumLink(RPC_ENUM_LINK * t,PACK * p)13767 void InRpcEnumLink(RPC_ENUM_LINK *t, PACK *p)
13768 {
13769 	UINT i;
13770 	// Validate arguments
13771 	if (t == NULL || p == NULL)
13772 	{
13773 		return;
13774 	}
13775 
13776 	Zero(t, sizeof(RPC_ENUM_LINK));
13777 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13778 	t->NumLink = PackGetIndexCount(p, "AccountName");
13779 	t->Links = ZeroMalloc(sizeof(RPC_ENUM_LINK_ITEM) * t->NumLink);
13780 
13781 	for (i = 0;i < t->NumLink;i++)
13782 	{
13783 		RPC_ENUM_LINK_ITEM *e = &t->Links[i];
13784 
13785 		PackGetUniStrEx(p, "AccountName", e->AccountName, sizeof(e->AccountName), i);
13786 		PackGetStrEx(p, "Hostname", e->Hostname, sizeof(e->Hostname), i);
13787 		PackGetStrEx(p, "ConnectedHubName", e->HubName, sizeof(e->HubName), i);
13788 		e->Online = PackGetBoolEx(p, "Online", i);
13789 		e->ConnectedTime = PackGetInt64Ex(p, "ConnectedTime", i);
13790 		e->Connected = PackGetBoolEx(p, "Connected", i);
13791 		e->LastError = PackGetIntEx(p, "LastError", i);
13792 		PackGetStrEx(p, "LinkHubName", e->HubName, sizeof(e->HubName), i);
13793 	}
13794 }
OutRpcEnumLink(PACK * p,RPC_ENUM_LINK * t)13795 void OutRpcEnumLink(PACK *p, RPC_ENUM_LINK *t)
13796 {
13797 	UINT i;
13798 	// Validate arguments
13799 	if (t == NULL || p == NULL)
13800 	{
13801 		return;
13802 	}
13803 
13804 	PackAddStr(p, "HubName", t->HubName);
13805 
13806 	PackSetCurrentJsonGroupName(p, "LinkList");
13807 	for (i = 0;i < t->NumLink;i++)
13808 	{
13809 		RPC_ENUM_LINK_ITEM *e = &t->Links[i];
13810 
13811 		PackAddUniStrEx(p, "AccountName", e->AccountName, i, t->NumLink);
13812 		PackAddStrEx(p, "ConnectedHubName", e->HubName, i, t->NumLink);
13813 		PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumLink);
13814 		PackAddBoolEx(p, "Online", e->Online, i, t->NumLink);
13815 		PackAddTime64Ex(p, "ConnectedTime", e->ConnectedTime, i, t->NumLink);
13816 		PackAddBoolEx(p, "Connected", e->Connected, i, t->NumLink);
13817 		PackAddIntEx(p, "LastError", e->LastError, i, t->NumLink);
13818 		PackAddStrEx(p, "TargetHubName", e->HubName, i, t->NumLink);
13819 	}
13820 	PackSetCurrentJsonGroupName(p, NULL);
13821 }
FreeRpcEnumLink(RPC_ENUM_LINK * t)13822 void FreeRpcEnumLink(RPC_ENUM_LINK *t)
13823 {
13824 	// Validate arguments
13825 	if (t == NULL)
13826 	{
13827 		return;
13828 	}
13829 
13830 	Free(t->Links);
13831 }
13832 
13833 // RPC_LINK_STATUS
InRpcLinkStatus(RPC_LINK_STATUS * t,PACK * p)13834 void InRpcLinkStatus(RPC_LINK_STATUS *t, PACK *p)
13835 {
13836 	// Validate arguments
13837 	if (t == NULL || p == NULL)
13838 	{
13839 		return;
13840 	}
13841 
13842 	Zero(t, sizeof(RPC_LINK_STATUS));
13843 	PackGetStr(p, "HubName_Ex", t->HubName, sizeof(t->HubName));
13844 	PackGetUniStr(p, "AccountName", t->AccountName, sizeof(t->AccountName));
13845 	InRpcClientGetConnectionStatus(&t->Status, p);
13846 }
OutRpcLinkStatus(PACK * p,RPC_LINK_STATUS * t)13847 void OutRpcLinkStatus(PACK *p, RPC_LINK_STATUS *t)
13848 {
13849 	// Validate arguments
13850 	if (t == NULL || p == NULL)
13851 	{
13852 		return;
13853 	}
13854 
13855 	PackAddStr(p, "HubName_Ex", t->HubName);
13856 	PackAddUniStr(p, "AccountName", t->AccountName);
13857 	OutRpcClientGetConnectionStatus(p, &t->Status);
13858 }
FreeRpcLinkStatus(RPC_LINK_STATUS * t)13859 void FreeRpcLinkStatus(RPC_LINK_STATUS *t)
13860 {
13861 	// Validate arguments
13862 	if (t == NULL)
13863 	{
13864 		return;
13865 	}
13866 
13867 	CiFreeClientGetConnectionStatus(&t->Status);
13868 }
13869 
13870 // RPC_LINK
InRpcLink(RPC_LINK * t,PACK * p)13871 void InRpcLink(RPC_LINK *t, PACK *p)
13872 {
13873 	// Validate arguments
13874 	if (t == NULL || p == NULL)
13875 	{
13876 		return;
13877 	}
13878 
13879 	Zero(t, sizeof(RPC_LINK));
13880 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13881 	PackGetUniStr(p, "AccountName", t->AccountName, sizeof(t->AccountName));
13882 }
OutRpcLink(PACK * p,RPC_LINK * t)13883 void OutRpcLink(PACK *p, RPC_LINK *t)
13884 {
13885 	// Validate arguments
13886 	if (t == NULL)
13887 	{
13888 		return;
13889 	}
13890 
13891 	PackAddStr(p, "HubName", t->HubName);
13892 	PackAddUniStr(p, "AccountName", t->AccountName);
13893 }
13894 
13895 // RPC_RENAME_LINK
InRpcRenameLink(RPC_RENAME_LINK * t,PACK * p)13896 void InRpcRenameLink(RPC_RENAME_LINK *t, PACK *p)
13897 {
13898 	// Validate arguments
13899 	if (t == NULL || p == NULL)
13900 	{
13901 		return;
13902 	}
13903 
13904 	Zero(t, sizeof(RPC_RENAME_LINK));
13905 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
13906 	PackGetUniStr(p, "OldAccountName", t->OldAccountName, sizeof(t->OldAccountName));
13907 	PackGetUniStr(p, "NewAccountName", t->NewAccountName, sizeof(t->NewAccountName));
13908 }
OutRpcRenameLink(PACK * p,RPC_RENAME_LINK * t)13909 void OutRpcRenameLink(PACK *p, RPC_RENAME_LINK *t)
13910 {
13911 	// Validate arguments
13912 	if (p == NULL || t == NULL)
13913 	{
13914 		return;
13915 	}
13916 
13917 	PackAddStr(p, "HubName", t->HubName);
13918 	PackAddUniStr(p, "OldAccountName", t->OldAccountName);
13919 	PackAddUniStr(p, "NewAccountName", t->NewAccountName);
13920 }
13921 
13922 // ACCESS
InRpcAccessEx(ACCESS * a,PACK * p,UINT index)13923 void InRpcAccessEx(ACCESS *a, PACK *p, UINT index)
13924 {
13925 	// Validate arguments
13926 	if (a == NULL || p == NULL)
13927 	{
13928 		return;
13929 	}
13930 
13931 	Zero(a, sizeof(ACCESS));
13932 	a->Id = PackGetIntEx(p, "Id", index);
13933 	PackGetUniStrEx(p, "Note", a->Note, sizeof(a->Note), index);
13934 	a->Active = PackGetBoolEx(p, "Active", index);
13935 	a->Priority = PackGetIntEx(p, "Priority", index);
13936 	a->Discard = PackGetBoolEx(p, "Discard", index);
13937 	a->SrcIpAddress = PackGetIp32Ex(p, "SrcIpAddress", index);
13938 	a->SrcSubnetMask = PackGetIp32Ex(p, "SrcSubnetMask", index);
13939 	a->DestIpAddress = PackGetIp32Ex(p, "DestIpAddress", index);
13940 	a->DestSubnetMask = PackGetIp32Ex(p, "DestSubnetMask", index);
13941 	a->Protocol = PackGetIntEx(p, "Protocol", index);
13942 	a->SrcPortStart = PackGetIntEx(p, "SrcPortStart", index);
13943 	a->SrcPortEnd = PackGetIntEx(p, "SrcPortEnd", index);
13944 	a->DestPortStart = PackGetIntEx(p, "DestPortStart", index);
13945 	a->DestPortEnd = PackGetIntEx(p, "DestPortEnd", index);
13946 	//a->SrcUsernameHash = PackGetIntEx(p, "SrcUsernameHash", index);
13947 	PackGetStrEx(p, "SrcUsername", a->SrcUsername, sizeof(a->SrcUsername), index);
13948 	//a->DestUsernameHash = PackGetIntEx(p, "DestUsernameHash", index);
13949 	PackGetStrEx(p, "DestUsername", a->DestUsername, sizeof(a->DestUsername), index);
13950 	a->CheckSrcMac = PackGetBoolEx(p, "CheckSrcMac", index);
13951 	PackGetDataEx2(p, "SrcMacAddress", a->SrcMacAddress, sizeof(a->SrcMacAddress), index);
13952 	PackGetDataEx2(p, "SrcMacMask", a->SrcMacMask, sizeof(a->SrcMacMask), index);
13953 	a->CheckDstMac = PackGetBoolEx(p, "CheckDstMac", index);
13954 	PackGetDataEx2(p, "DstMacAddress", a->DstMacAddress, sizeof(a->DstMacAddress), index);
13955 	PackGetDataEx2(p, "DstMacMask", a->DstMacMask, sizeof(a->DstMacMask), index);
13956 	a->CheckTcpState = PackGetBoolEx(p, "CheckTcpState", index);
13957 	a->Established = PackGetBoolEx(p, "Established", index);
13958 	a->Delay = PackGetIntEx(p, "Delay", index);
13959 	a->Jitter = PackGetIntEx(p, "Jitter", index);
13960 	a->Loss = PackGetIntEx(p, "Loss", index);
13961 	a->IsIPv6 = PackGetBoolEx(p, "IsIPv6", index);
13962 	a->UniqueId = PackGetIntEx(p, "UniqueId", index);
13963 	PackGetStrEx(p, "RedirectUrl", a->RedirectUrl, sizeof(a->RedirectUrl), index);
13964 	if (a->IsIPv6)
13965 	{
13966 		PackGetIp6AddrEx(p, "SrcIpAddress6", &a->SrcIpAddress6, index);
13967 		PackGetIp6AddrEx(p, "SrcSubnetMask6", &a->SrcSubnetMask6, index);
13968 		PackGetIp6AddrEx(p, "DestIpAddress6", &a->DestIpAddress6, index);
13969 		PackGetIp6AddrEx(p, "DestSubnetMask6", &a->DestSubnetMask6, index);
13970 	}
13971 }
InRpcAccess(ACCESS * a,PACK * p)13972 void InRpcAccess(ACCESS *a, PACK *p)
13973 {
13974 	// Validate arguments
13975 	if (a == NULL || p == NULL)
13976 	{
13977 		return;
13978 	}
13979 
13980 	InRpcAccessEx(a, p, 0);
13981 }
OutRpcAccessEx(PACK * p,ACCESS * a,UINT index,UINT total)13982 void OutRpcAccessEx(PACK *p, ACCESS *a, UINT index, UINT total)
13983 {
13984 	// Validate arguments
13985 	if (a == NULL || p == NULL)
13986 	{
13987 		return;
13988 	}
13989 
13990 	PackAddIntEx(p, "Id", a->Id, index, total);
13991 	PackAddUniStrEx(p, "Note", a->Note, index, total);
13992 	PackAddBoolEx(p, "Active", a->Active, index, total);
13993 	PackAddIntEx(p, "Priority", a->Priority, index, total);
13994 	PackAddBoolEx(p, "Discard", a->Discard, index, total);
13995 	if (a->IsIPv6)
13996 	{
13997 		PackAddIp32Ex(p, "SrcIpAddress", 0xFDFFFFDF, index, total);
13998 		PackAddIp32Ex(p, "SrcSubnetMask", 0xFFFFFFFF, index, total);
13999 		PackAddIp32Ex(p, "DestIpAddress", 0xFDFFFFDF, index, total);
14000 		PackAddIp32Ex(p, "DestSubnetMask", 0xFFFFFFFF, index, total);
14001 	}
14002 	else
14003 	{
14004 		PackAddIp32Ex(p, "SrcIpAddress", a->SrcIpAddress, index, total);
14005 		PackAddIp32Ex(p, "SrcSubnetMask", a->SrcSubnetMask, index, total);
14006 		PackAddIp32Ex(p, "DestIpAddress", a->DestIpAddress, index, total);
14007 		PackAddIp32Ex(p, "DestSubnetMask", a->DestSubnetMask, index, total);
14008 	}
14009 	PackAddIntEx(p, "Protocol", a->Protocol, index, total);
14010 	PackAddIntEx(p, "SrcPortStart", a->SrcPortStart, index, total);
14011 	PackAddIntEx(p, "SrcPortEnd", a->SrcPortEnd, index, total);
14012 	PackAddIntEx(p, "DestPortStart", a->DestPortStart, index, total);
14013 	PackAddIntEx(p, "DestPortEnd", a->DestPortEnd, index, total);
14014 	//PackAddIntEx(p, "SrcUsernameHash", a->SrcUsernameHash, index, total);
14015 	PackAddStrEx(p, "SrcUsername", a->SrcUsername, index, total);
14016 	//PackAddIntEx(p, "DestUsernameHash", a->DestUsernameHash, index, total);
14017 	PackAddStrEx(p, "DestUsername", a->DestUsername, index, total);
14018 	PackAddBoolEx(p, "CheckSrcMac", a->CheckSrcMac, index, total);
14019 	PackAddDataEx(p, "SrcMacAddress", a->SrcMacAddress, sizeof(a->SrcMacAddress), index, total);
14020 	PackAddDataEx(p, "SrcMacMask", a->SrcMacMask, sizeof(a->SrcMacMask), index, total);
14021 	PackAddBoolEx(p, "CheckDstMac", a->CheckDstMac, index, total);
14022 	PackAddDataEx(p, "DstMacAddress", a->DstMacAddress, sizeof(a->DstMacAddress), index, total);
14023 	PackAddDataEx(p, "DstMacMask", a->DstMacMask, sizeof(a->DstMacMask), index, total);
14024 	PackAddBoolEx(p, "CheckTcpState", a->CheckTcpState, index, total);
14025 	PackAddBoolEx(p, "Established", a->Established, index, total);
14026 	PackAddIntEx(p, "Delay", a->Delay, index, total);
14027 	PackAddIntEx(p, "Jitter", a->Jitter, index, total);
14028 	PackAddIntEx(p, "Loss", a->Loss, index, total);
14029 	PackAddBoolEx(p, "IsIPv6", a->IsIPv6, index, total);
14030 	PackAddIntEx(p, "UniqueId", a->UniqueId, index, total);
14031 	PackAddStrEx(p, "RedirectUrl", a->RedirectUrl, index, total);
14032 	if (a->IsIPv6)
14033 	{
14034 		PackAddIp6AddrEx(p, "SrcIpAddress6", &a->SrcIpAddress6, index, total);
14035 		PackAddIp6AddrEx(p, "SrcSubnetMask6", &a->SrcSubnetMask6, index, total);
14036 		PackAddIp6AddrEx(p, "DestIpAddress6", &a->DestIpAddress6, index, total);
14037 		PackAddIp6AddrEx(p, "DestSubnetMask6", &a->DestSubnetMask6, index, total);
14038 	}
14039 	else
14040 	{
14041 		IPV6_ADDR zero;
14042 
14043 		Zero(&zero, sizeof(zero));
14044 
14045 		PackAddIp6AddrEx(p, "SrcIpAddress6", &zero, index, total);
14046 		PackAddIp6AddrEx(p, "SrcSubnetMask6", &zero, index, total);
14047 		PackAddIp6AddrEx(p, "DestIpAddress6", &zero, index, total);
14048 		PackAddIp6AddrEx(p, "DestSubnetMask6", &zero, index, total);
14049 	}
14050 }
OutRpcAccess(PACK * p,ACCESS * a)14051 void OutRpcAccess(PACK *p, ACCESS *a)
14052 {
14053 	// Validate arguments
14054 	if (a == NULL || p == NULL)
14055 	{
14056 		return;
14057 	}
14058 
14059 	OutRpcAccessEx(p, a, 0, 1);
14060 }
14061 
14062 // RPC_ENUM_ACCESS_LIST
InRpcEnumAccessList(RPC_ENUM_ACCESS_LIST * a,PACK * p)14063 void InRpcEnumAccessList(RPC_ENUM_ACCESS_LIST *a, PACK *p)
14064 {
14065 	UINT i;
14066 	// Validate arguments
14067 	if (a == NULL || p == NULL)
14068 	{
14069 		return;
14070 	}
14071 
14072 	Zero(a, sizeof(RPC_ENUM_ACCESS_LIST));
14073 	PackGetStr(p, "HubName", a->HubName, sizeof(a->HubName));
14074 	a->NumAccess = PackGetIndexCount(p, "Protocol");
14075 	a->Accesses = ZeroMalloc(sizeof(ACCESS) * a->NumAccess);
14076 
14077 	for (i = 0;i < a->NumAccess;i++)
14078 	{
14079 		ACCESS *e = &a->Accesses[i];
14080 
14081 		InRpcAccessEx(e, p, i);
14082 	}
14083 }
OutRpcEnumAccessList(PACK * p,RPC_ENUM_ACCESS_LIST * a)14084 void OutRpcEnumAccessList(PACK *p, RPC_ENUM_ACCESS_LIST *a)
14085 {
14086 	UINT i;
14087 	// Validate arguments
14088 	if (a == NULL || p == NULL)
14089 	{
14090 		return;
14091 	}
14092 	PackAddStr(p, "HubName", a->HubName);
14093 
14094 	PackSetCurrentJsonGroupName(p, "AccessList");
14095 	for (i = 0;i < a->NumAccess;i++)
14096 	{
14097 		ACCESS *e = &a->Accesses[i];
14098 
14099 		OutRpcAccessEx(p, e, i, a->NumAccess);
14100 	}
14101 	PackSetCurrentJsonGroupName(p, NULL);
14102 }
FreeRpcEnumAccessList(RPC_ENUM_ACCESS_LIST * a)14103 void FreeRpcEnumAccessList(RPC_ENUM_ACCESS_LIST *a)
14104 {
14105 	// Validate arguments
14106 	if (a == NULL)
14107 	{
14108 		return;
14109 	}
14110 
14111 	Free(a->Accesses);
14112 }
14113 
14114 // AUTHDATA
InRpcAuthData(PACK * p,UINT * authtype,char * username)14115 void *InRpcAuthData(PACK *p, UINT *authtype, char *username)
14116 {
14117 	wchar_t tmp[MAX_SIZE];
14118 	AUTHPASSWORD *pw;
14119 	AUTHUSERCERT *usercert;
14120 	AUTHROOTCERT *rootcert;
14121 	AUTHRADIUS *radius;
14122 	AUTHNT *nt;
14123 	BUF *b;
14124 	char plain_pw[MAX_SIZE];
14125 	// Validate arguments
14126 	if (p == NULL)
14127 	{
14128 		return NULL;
14129 	}
14130 	if (authtype == NULL)
14131 	{
14132 		return NULL;
14133 	}
14134 
14135 	*authtype = PackGetInt(p, "AuthType");
14136 
14137 	switch (*authtype)
14138 	{
14139 	case AUTHTYPE_PASSWORD:
14140 		pw = ZeroMalloc(sizeof(AUTHPASSWORD));
14141 		PackGetData2(p, "HashedKey", pw->HashedKey, sizeof(pw->HashedKey));
14142 		PackGetData2(p, "NtLmSecureHash", pw->NtLmSecureHash, sizeof(pw->NtLmSecureHash));
14143 
14144 		if (PackGetStr(p, "Auth_Password", plain_pw, sizeof(plain_pw)))
14145 		{
14146 			if (IsZero(pw->HashedKey, sizeof(pw->HashedKey)))
14147 			{
14148 				HashPassword(pw->HashedKey, username, plain_pw);
14149 				GenerateNtPasswordHash(pw->NtLmSecureHash, plain_pw);
14150 			}
14151 		}
14152 		return pw;
14153 
14154 	case AUTHTYPE_USERCERT:
14155 		usercert = ZeroMalloc(sizeof(AUTHUSERCERT));
14156 		usercert->UserX = PackGetX(p, "UserX");
14157 		return usercert;
14158 
14159 	case AUTHTYPE_ROOTCERT:
14160 		rootcert = ZeroMalloc(sizeof(AUTHROOTCERT));
14161 		b = PackGetBuf(p, "Serial");
14162 		if (b != NULL)
14163 		{
14164 			rootcert->Serial = NewXSerial(b->Buf, b->Size);
14165 			FreeBuf(b);
14166 		}
14167 		if (PackGetUniStr(p, "CommonName", tmp, sizeof(tmp)))
14168 		{
14169 			rootcert->CommonName = CopyUniStr(tmp);
14170 		}
14171 		return rootcert;
14172 
14173 	case AUTHTYPE_RADIUS:
14174 		radius = ZeroMalloc(sizeof(AUTHRADIUS));
14175 		if (PackGetUniStr(p, "RadiusUsername", tmp, sizeof(tmp)))
14176 		{
14177 			radius->RadiusUsername = CopyUniStr(tmp);
14178 		}
14179 		else
14180 		{
14181 			radius->RadiusUsername = CopyUniStr(L"");
14182 		}
14183 		return radius;
14184 
14185 	case AUTHTYPE_NT:
14186 		nt = ZeroMalloc(sizeof(AUTHNT));
14187 		if (PackGetUniStr(p, "NtUsername", tmp, sizeof(tmp)))
14188 		{
14189 			nt->NtUsername = CopyUniStr(tmp);
14190 		}
14191 		else
14192 		{
14193 			nt->NtUsername = CopyUniStr(L"");
14194 		}
14195 		return nt;
14196 	}
14197 
14198 	return NULL;
14199 }
OutRpcAuthData(PACK * p,void * authdata,UINT authtype)14200 void OutRpcAuthData(PACK *p, void *authdata, UINT authtype)
14201 {
14202 	AUTHPASSWORD *pw = authdata;
14203 	AUTHUSERCERT *usercert = authdata;
14204 	AUTHROOTCERT *rootcert = authdata;
14205 	AUTHRADIUS *radius = authdata;
14206 	AUTHNT *nt = authdata;
14207 	// Validate arguments
14208 	if (p == NULL)
14209 	{
14210 		return;
14211 	}
14212 
14213 	PackAddInt(p, "AuthType", authtype);
14214 
14215 	switch (authtype)
14216 	{
14217 	case AUTHTYPE_PASSWORD:
14218 		PackAddData(p, "HashedKey", pw->HashedKey, sizeof(pw->HashedKey));
14219 		PackAddData(p, "NtLmSecureHash", pw->NtLmSecureHash, sizeof(pw->NtLmSecureHash));
14220 		break;
14221 
14222 	case AUTHTYPE_USERCERT:
14223 		PackAddX(p, "UserX", usercert->UserX);
14224 		break;
14225 
14226 	case AUTHTYPE_ROOTCERT:
14227 		if (rootcert->Serial != NULL)
14228 		{
14229 			PackAddData(p, "Serial", rootcert->Serial->data, rootcert->Serial->size);
14230 		}
14231 		if (rootcert->CommonName != NULL)
14232 		{
14233 			PackAddUniStr(p, "CommonName", rootcert->CommonName);
14234 		}
14235 		break;
14236 
14237 	case AUTHTYPE_RADIUS:
14238 		PackAddUniStr(p, "RadiusUsername", radius->RadiusUsername);
14239 		break;
14240 
14241 	case AUTHTYPE_NT:
14242 		PackAddUniStr(p, "NtUsername", nt->NtUsername);
14243 		break;
14244 	}
14245 }
FreeRpcAuthData(void * authdata,UINT authtype)14246 void FreeRpcAuthData(void *authdata, UINT authtype)
14247 {
14248 	FreeAuthData(authtype, authdata);
14249 }
14250 
14251 // RPC_SET_USER
InRpcSetUser(RPC_SET_USER * t,PACK * p)14252 void InRpcSetUser(RPC_SET_USER *t, PACK *p)
14253 {
14254 	// Validate arguments
14255 	if (t == NULL || p == NULL)
14256 	{
14257 		return;
14258 	}
14259 
14260 	Zero(t, sizeof(RPC_SET_USER));
14261 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
14262 	PackGetStr(p, "Name", t->Name, sizeof(t->Name));
14263 	PackGetStr(p, "GroupName", t->GroupName, sizeof(t->GroupName));
14264 	PackGetUniStr(p, "Realname", t->Realname, sizeof(t->Realname));
14265 	PackGetUniStr(p, "Note", t->Note, sizeof(t->Note));
14266 	t->CreatedTime = PackGetInt64(p, "CreatedTime");
14267 	t->UpdatedTime = PackGetInt64(p, "UpdatedTime");
14268 	t->ExpireTime = PackGetInt64(p, "ExpireTime");
14269 	t->AuthData = InRpcAuthData(p, &t->AuthType, t->Name);
14270 	t->NumLogin = PackGetInt(p, "NumLogin");
14271 	InRpcTraffic(&t->Traffic, p);
14272 
14273 	if (PackGetBool(p, "UsePolicy"))
14274 	{
14275 		t->Policy = ZeroMalloc(sizeof(POLICY));
14276 		InRpcPolicy(t->Policy, p);
14277 	}
14278 }
14279 
OutRpcSetUser(PACK * p,RPC_SET_USER * t)14280 void OutRpcSetUser(PACK *p, RPC_SET_USER *t)
14281 {
14282 	// Validate arguments
14283 	if (t == NULL || p == NULL)
14284 	{
14285 		return;
14286 	}
14287 
14288 	PackAddStr(p, "HubName", t->HubName);
14289 	PackAddStr(p, "Name", t->Name);
14290 	PackAddStr(p, "GroupName", t->GroupName);
14291 	PackAddUniStr(p, "Realname", t->Realname);
14292 	PackAddUniStr(p, "Note", t->Note);
14293 	PackAddTime64(p, "CreatedTime", t->CreatedTime);
14294 	PackAddTime64(p, "UpdatedTime", t->UpdatedTime);
14295 	PackAddTime64(p, "ExpireTime", t->ExpireTime);
14296 	OutRpcAuthData(p, t->AuthData, t->AuthType);
14297 	PackAddInt(p, "NumLogin", t->NumLogin);
14298 	OutRpcTraffic(p, &t->Traffic);
14299 
14300 	if (t->Policy != NULL)
14301 	{
14302 		PackAddBool(p, "UsePolicy", true);
14303 		OutRpcPolicy(p, t->Policy);
14304 	}
14305 }
FreeRpcSetUser(RPC_SET_USER * t)14306 void FreeRpcSetUser(RPC_SET_USER *t)
14307 {
14308 	// Validate arguments
14309 	if (t == NULL)
14310 	{
14311 		return;
14312 	}
14313 
14314 	FreeRpcAuthData(t->AuthData, t->AuthType);
14315 	if (t->Policy)
14316 	{
14317 		Free(t->Policy);
14318 	}
14319 }
14320 
14321 // RPC_ENUM_USER
InRpcEnumUser(RPC_ENUM_USER * t,PACK * p)14322 void InRpcEnumUser(RPC_ENUM_USER *t, PACK *p)
14323 {
14324 	UINT i;
14325 	// Validate arguments
14326 	if (t == NULL || p == NULL)
14327 	{
14328 		return;
14329 	}
14330 
14331 	Zero(t, sizeof(RPC_ENUM_USER));
14332 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
14333 	t->NumUser = PackGetIndexCount(p, "Name");
14334 	t->Users = ZeroMalloc(sizeof(RPC_ENUM_USER_ITEM) * t->NumUser);
14335 
14336 	for (i = 0;i < t->NumUser;i++)
14337 	{
14338 		RPC_ENUM_USER_ITEM *e = &t->Users[i];
14339 
14340 		PackGetStrEx(p, "Name", e->Name, sizeof(e->Name), i);
14341 		PackGetStrEx(p, "GroupName", e->GroupName, sizeof(e->GroupName), i);
14342 		PackGetUniStrEx(p, "Realname", e->Realname, sizeof(e->Realname), i);
14343 		PackGetUniStrEx(p, "Note", e->Note, sizeof(e->Note), i);
14344 		e->AuthType = PackGetIntEx(p, "AuthType", i);
14345 		e->LastLoginTime = PackGetInt64Ex(p, "LastLoginTime", i);
14346 		e->NumLogin = PackGetIntEx(p, "NumLogin", i);
14347 		e->DenyAccess = PackGetBoolEx(p, "DenyAccess", i);
14348 
14349 		e->IsTrafficFilled = PackGetBoolEx(p, "IsTrafficFilled", i);
14350 		InRpcTrafficEx(&e->Traffic, p, i);
14351 
14352 		e->IsExpiresFilled = PackGetBoolEx(p, "IsExpiresFilled", i);
14353 		e->Expires = PackGetInt64Ex(p, "Expires", i);
14354 	}
14355 }
OutRpcEnumUser(PACK * p,RPC_ENUM_USER * t)14356 void OutRpcEnumUser(PACK *p, RPC_ENUM_USER *t)
14357 {
14358 	UINT i;
14359 	// Validate arguments
14360 	if (t == NULL || p == NULL)
14361 	{
14362 		return;
14363 	}
14364 	PackAddStr(p, "HubName", t->HubName);
14365 
14366 	PackSetCurrentJsonGroupName(p, "UserList");
14367 	for (i = 0;i < t->NumUser;i++)
14368 	{
14369 		RPC_ENUM_USER_ITEM *e = &t->Users[i];
14370 
14371 		PackAddStrEx(p, "Name", e->Name, i, t->NumUser);
14372 		PackAddStrEx(p, "GroupName", e->GroupName, i, t->NumUser);
14373 		PackAddUniStrEx(p, "Realname", e->Realname, i, t->NumUser);
14374 		PackAddUniStrEx(p, "Note", e->Note, i, t->NumUser);
14375 		PackAddIntEx(p, "AuthType", e->AuthType, i, t->NumUser);
14376 		PackAddTime64Ex(p, "LastLoginTime", e->LastLoginTime, i, t->NumUser);
14377 		PackAddIntEx(p, "NumLogin", e->NumLogin, i, t->NumUser);
14378 		PackAddBoolEx(p, "DenyAccess", e->DenyAccess, i, t->NumUser);
14379 
14380 		PackAddBoolEx(p, "IsTrafficFilled", e->IsTrafficFilled, i, t->NumUser);
14381 		OutRpcTrafficEx(&e->Traffic, p, i, t->NumUser);
14382 
14383 		PackAddBoolEx(p, "IsExpiresFilled", e->IsExpiresFilled, i, t->NumUser);
14384 		PackAddTime64Ex(p, "Expires", e->Expires, i, t->NumUser);
14385 	}
14386 	PackSetCurrentJsonGroupName(p, NULL);
14387 }
FreeRpcEnumUser(RPC_ENUM_USER * t)14388 void FreeRpcEnumUser(RPC_ENUM_USER *t)
14389 {
14390 	// Validate arguments
14391 	if (t == NULL)
14392 	{
14393 		return;
14394 	}
14395 
14396 	Free(t->Users);
14397 }
14398 
14399 // RPC_SET_GROUP
InRpcSetGroup(RPC_SET_GROUP * t,PACK * p)14400 void InRpcSetGroup(RPC_SET_GROUP *t, PACK *p)
14401 {
14402 	// Validate arguments
14403 	if (t == NULL || p == NULL)
14404 	{
14405 		return;
14406 	}
14407 
14408 	Zero(t, sizeof(RPC_SET_GROUP));
14409 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
14410 	PackGetStr(p, "Name", t->Name, sizeof(t->Name));
14411 	PackGetUniStr(p, "Realname", t->Realname, sizeof(t->Realname));
14412 	PackGetUniStr(p, "Note", t->Note, sizeof(t->Note));
14413 	InRpcTraffic(&t->Traffic, p);
14414 
14415 	if (PackGetBool(p, "UsePolicy"))
14416 	{
14417 		t->Policy = ZeroMalloc(sizeof(POLICY));
14418 		InRpcPolicy(t->Policy, p);
14419 	}
14420 }
OutRpcSetGroup(PACK * p,RPC_SET_GROUP * t)14421 void OutRpcSetGroup(PACK *p, RPC_SET_GROUP *t)
14422 {
14423 	// Validate arguments
14424 	if (t == NULL || p == NULL)
14425 	{
14426 		return;
14427 	}
14428 
14429 	PackAddStr(p, "HubName", t->HubName);
14430 	PackAddStr(p, "Name", t->Name);
14431 	PackAddUniStr(p, "Realname", t->Realname);
14432 	PackAddUniStr(p, "Note", t->Note);
14433 	OutRpcTraffic(p, &t->Traffic);
14434 
14435 	if (t->Policy != NULL)
14436 	{
14437 		PackAddBool(p, "UsePolicy", true);
14438 		OutRpcPolicy(p, t->Policy);
14439 	}
14440 }
FreeRpcSetGroup(RPC_SET_GROUP * t)14441 void FreeRpcSetGroup(RPC_SET_GROUP *t)
14442 {
14443 	Free(t->Policy);
14444 }
14445 
14446 // RPC_ENUM_GROUP
InRpcEnumGroup(RPC_ENUM_GROUP * t,PACK * p)14447 void InRpcEnumGroup(RPC_ENUM_GROUP *t, PACK *p)
14448 {
14449 	UINT i;
14450 	// Validate arguments
14451 	if (t == NULL || p == NULL)
14452 	{
14453 		return;
14454 	}
14455 
14456 	Zero(t, sizeof(RPC_ENUM_GROUP));
14457 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
14458 	t->NumGroup = PackGetIndexCount(p, "Name");
14459 	t->Groups = ZeroMalloc(sizeof(RPC_ENUM_GROUP_ITEM) * t->NumGroup);
14460 
14461 	for (i = 0;i < t->NumGroup;i++)
14462 	{
14463 		RPC_ENUM_GROUP_ITEM *e = &t->Groups[i];
14464 
14465 		PackGetStrEx(p, "Name", e->Name, sizeof(e->Name), i);
14466 		PackGetUniStrEx(p, "Realname", e->Realname, sizeof(e->Realname), i);
14467 		PackGetUniStrEx(p, "Note", e->Note, sizeof(e->Note), i);
14468 		e->NumUsers = PackGetIntEx(p, "NumUsers", i);
14469 		e->DenyAccess = PackGetBoolEx(p, "DenyAccess", i);
14470 	}
14471 }
OutRpcEnumGroup(PACK * p,RPC_ENUM_GROUP * t)14472 void OutRpcEnumGroup(PACK *p, RPC_ENUM_GROUP *t)
14473 {
14474 	UINT i;
14475 	// Validate arguments
14476 	if (t == NULL || p == NULL)
14477 	{
14478 		return;
14479 	}
14480 
14481 	PackAddStr(p, "HubName", t->HubName);
14482 
14483 	PackSetCurrentJsonGroupName(p, "GroupList");
14484 	for (i = 0;i < t->NumGroup;i++)
14485 	{
14486 		RPC_ENUM_GROUP_ITEM *e = &t->Groups[i];
14487 
14488 		PackAddStrEx(p, "Name", e->Name, i, t->NumGroup);
14489 		PackAddUniStrEx(p, "Realname", e->Realname, i, t->NumGroup);
14490 		PackAddUniStrEx(p, "Note", e->Note, i, t->NumGroup);
14491 		PackAddIntEx(p, "NumUsers", e->NumUsers, i, t->NumGroup);
14492 		PackAddBoolEx(p, "DenyAccess", e->DenyAccess, i, t->NumGroup);
14493 	}
14494 	PackSetCurrentJsonGroupName(p, NULL);
14495 }
FreeRpcEnumGroup(RPC_ENUM_GROUP * t)14496 void FreeRpcEnumGroup(RPC_ENUM_GROUP *t)
14497 {
14498 	// Validate arguments
14499 	if (t == NULL)
14500 	{
14501 		return;
14502 	}
14503 
14504 	Free(t->Groups);
14505 }
14506 
14507 // RPC_DELETE_USER
InRpcDeleteUser(RPC_DELETE_USER * t,PACK * p)14508 void InRpcDeleteUser(RPC_DELETE_USER *t, PACK *p)
14509 {
14510 	// Validate arguments
14511 	if (t == NULL || p == NULL)
14512 	{
14513 		return;
14514 	}
14515 
14516 	Zero(t, sizeof(RPC_DELETE_USER));
14517 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
14518 	PackGetStr(p, "Name", t->Name, sizeof(t->Name));
14519 }
OutRpcDeleteUser(PACK * p,RPC_DELETE_USER * t)14520 void OutRpcDeleteUser(PACK *p, RPC_DELETE_USER *t)
14521 {
14522 	// Validate arguments
14523 	if (t == NULL || p == NULL)
14524 	{
14525 		return;
14526 	}
14527 
14528 	PackAddStr(p, "HubName", t->HubName);
14529 	PackAddStr(p, "Name", t->Name);
14530 }
14531 
14532 // RPC_ENUM_SESSION
InRpcEnumSession(RPC_ENUM_SESSION * t,PACK * p)14533 void InRpcEnumSession(RPC_ENUM_SESSION *t, PACK *p)
14534 {
14535 	UINT i;
14536 	// Validate arguments
14537 	if (t == NULL || p == NULL)
14538 	{
14539 		return;
14540 	}
14541 
14542 	Zero(t, sizeof(RPC_ENUM_SESSION));
14543 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
14544 	t->NumSession = PackGetIndexCount(p, "Name");
14545 	t->Sessions = ZeroMalloc(sizeof(RPC_ENUM_SESSION_ITEM) * t->NumSession);
14546 
14547 	for (i = 0;i < t->NumSession;i++)
14548 	{
14549 		RPC_ENUM_SESSION_ITEM *e = &t->Sessions[i];
14550 
14551 		PackGetStrEx(p, "Name", e->Name, sizeof(e->Name), i);
14552 		PackGetStrEx(p, "Username", e->Username, sizeof(e->Username), i);
14553 		e->Ip = PackGetIntEx(p, "Ip", i);
14554 		PackGetIpEx(p, "ClientIP", &e->ClientIP, i);
14555 		PackGetStrEx(p, "Hostname", e->Hostname, sizeof(e->Hostname), i);
14556 		e->MaxNumTcp = PackGetIntEx(p, "MaxNumTcp", i);
14557 		e->CurrentNumTcp = PackGetIntEx(p, "CurrentNumTcp", i);
14558 		e->PacketSize = PackGetInt64Ex(p, "PacketSize", i);
14559 		e->PacketNum = PackGetInt64Ex(p, "PacketNum", i);
14560 		e->RemoteSession = PackGetBoolEx(p, "RemoteSession", i);
14561 		e->LinkMode = PackGetBoolEx(p, "LinkMode", i);
14562 		e->SecureNATMode = PackGetBoolEx(p, "SecureNATMode", i);
14563 		e->BridgeMode = PackGetBoolEx(p, "BridgeMode", i);
14564 		e->Layer3Mode = PackGetBoolEx(p, "Layer3Mode", i);
14565 		e->Client_BridgeMode = PackGetBoolEx(p, "Client_BridgeMode", i);
14566 		e->Client_MonitorMode = PackGetBoolEx(p, "Client_MonitorMode", i);
14567 		PackGetStrEx(p, "RemoteHostname", e->RemoteHostname, sizeof(e->RemoteHostname), i);
14568 		e->VLanId = PackGetIntEx(p, "VLanId", i);
14569 		PackGetDataEx2(p, "UniqueId", e->UniqueId, sizeof(e->UniqueId), i);
14570 		e->IsDormantEnabled = PackGetBoolEx(p, "IsDormantEnabled", i);
14571 		e->IsDormant = PackGetBoolEx(p, "IsDormant", i);
14572 		e->LastCommDormant = PackGetInt64Ex(p, "LastCommDormant", i);
14573 		e->CreatedTime = PackGetInt64Ex(p, "CreatedTime", i);
14574 		e->LastCommTime = PackGetInt64Ex(p, "LastCommTime", i);
14575 	}
14576 }
OutRpcEnumSession(PACK * p,RPC_ENUM_SESSION * t)14577 void OutRpcEnumSession(PACK *p, RPC_ENUM_SESSION *t)
14578 {
14579 	UINT i;
14580 	// Validate arguments
14581 	if (t == NULL || p == NULL)
14582 	{
14583 		return;
14584 	}
14585 	PackAddStr(p, "HubName", t->HubName);
14586 
14587 	PackSetCurrentJsonGroupName(p, "SessionList");
14588 	for (i = 0;i < t->NumSession;i++)
14589 	{
14590 		RPC_ENUM_SESSION_ITEM *e = &t->Sessions[i];
14591 
14592 		PackAddStrEx(p, "Name", e->Name, i, t->NumSession);
14593 		PackAddStrEx(p, "Username", e->Username, i, t->NumSession);
14594 		PackAddIp32Ex(p, "Ip", e->Ip, i, t->NumSession);
14595 		PackAddIpEx(p, "ClientIP", &e->ClientIP, i, t->NumSession);
14596 		PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumSession);
14597 		PackAddIntEx(p, "MaxNumTcp", e->MaxNumTcp, i, t->NumSession);
14598 		PackAddIntEx(p, "CurrentNumTcp", e->CurrentNumTcp, i, t->NumSession);
14599 		PackAddInt64Ex(p, "PacketSize", e->PacketSize, i, t->NumSession);
14600 		PackAddInt64Ex(p, "PacketNum", e->PacketNum, i, t->NumSession);
14601 		PackAddBoolEx(p, "RemoteSession", e->RemoteSession, i, t->NumSession);
14602 		PackAddStrEx(p, "RemoteHostname", e->RemoteHostname, i, t->NumSession);
14603 		PackAddBoolEx(p, "LinkMode", e->LinkMode, i, t->NumSession);
14604 		PackAddBoolEx(p, "SecureNATMode", e->SecureNATMode, i, t->NumSession);
14605 		PackAddBoolEx(p, "BridgeMode", e->BridgeMode, i, t->NumSession);
14606 		PackAddBoolEx(p, "Layer3Mode", e->Layer3Mode, i, t->NumSession);
14607 		PackAddBoolEx(p, "Client_BridgeMode", e->Client_BridgeMode, i, t->NumSession);
14608 		PackAddBoolEx(p, "Client_MonitorMode", e->Client_MonitorMode, i, t->NumSession);
14609 		PackAddIntEx(p, "VLanId", e->VLanId, i, t->NumSession);
14610 		PackAddDataEx(p, "UniqueId", e->UniqueId, sizeof(e->UniqueId), i, t->NumSession);
14611 		PackAddBoolEx(p, "IsDormantEnabled", e->IsDormantEnabled, i, t->NumSession);
14612 		PackAddBoolEx(p, "IsDormant", e->IsDormant, i, t->NumSession);
14613 		PackAddTime64Ex(p, "LastCommDormant", e->LastCommDormant, i, t->NumSession);
14614 		PackAddTime64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumSession);
14615 		PackAddTime64Ex(p, "LastCommTime", e->LastCommTime, i, t->NumSession);
14616 	}
14617 	PackSetCurrentJsonGroupName(p, NULL);
14618 }
FreeRpcEnumSession(RPC_ENUM_SESSION * t)14619 void FreeRpcEnumSession(RPC_ENUM_SESSION *t)
14620 {
14621 	// Validate arguments
14622 	if (t == NULL)
14623 	{
14624 		return;
14625 	}
14626 
14627 	Free(t->Sessions);
14628 }
14629 
14630 // RPC_KEY_PAIR
InRpcKeyPair(RPC_KEY_PAIR * t,PACK * p)14631 void InRpcKeyPair(RPC_KEY_PAIR *t, PACK *p)
14632 {
14633 	// Validate arguments
14634 	if (t == NULL || p == NULL)
14635 	{
14636 		return;
14637 	}
14638 
14639 	t->Cert = PackGetX(p, "Cert");
14640 	t->Key = PackGetK(p, "Key");
14641 	t->Flag1 = PackGetInt(p, "Flag1");
14642 }
OutRpcKeyPair(PACK * p,RPC_KEY_PAIR * t)14643 void OutRpcKeyPair(PACK *p, RPC_KEY_PAIR *t)
14644 {
14645 	// Validate arguments
14646 	if (p == NULL || t == NULL)
14647 	{
14648 		return;
14649 	}
14650 
14651 	PackAddX(p, "Cert", t->Cert);
14652 	PackAddK(p, "Key", t->Key);
14653 	PackAddInt(p, "Flag1", t->Flag1);
14654 }
FreeRpcKeyPair(RPC_KEY_PAIR * t)14655 void FreeRpcKeyPair(RPC_KEY_PAIR *t)
14656 {
14657 	FreeX(t->Cert);
14658 	FreeK(t->Key);
14659 }
14660 
14661 // RPC_WGK
InRpcWgk(RPC_WGK * t,PACK * p)14662 void InRpcWgk(RPC_WGK *t, PACK *p)
14663 {
14664 	UINT i;
14665 	// Validate arguments
14666 	if (t == NULL || p == NULL)
14667 	{
14668 		return;
14669 	}
14670 
14671 	Zero(t, sizeof(RPC_WGK));
14672 
14673 	t->Num = PackGetIndexCount(p, "Key");
14674 	if (t->Num == 0)
14675 	{
14676 		return;
14677 	}
14678 
14679 	t->Wgks = ZeroMalloc(sizeof(WGK) * t->Num);
14680 
14681 	for (i = 0; i < t->Num; ++i)
14682 	{
14683 		WGK *wgk = &t->Wgks[i];
14684 
14685 		PackGetStrEx(p, "Key", wgk->Key, sizeof(wgk->Key), i);
14686 		PackGetStrEx(p, "Hub", wgk->Hub, sizeof(wgk->Hub), i);
14687 		PackGetStrEx(p, "User", wgk->User, sizeof(wgk->User), i);
14688 	}
14689 }
OutRpcWgk(PACK * p,RPC_WGK * t)14690 void OutRpcWgk(PACK *p, RPC_WGK *t)
14691 {
14692 	UINT i;
14693 	// Validate arguments
14694 	if (t == NULL || p == NULL)
14695 	{
14696 		return;
14697 	}
14698 
14699 	for (i = 0; i < t->Num; ++i)
14700 	{
14701 		WGK *wgk = &t->Wgks[i];
14702 
14703 		PackAddStrEx(p, "Key", wgk->Key, i, t->Num);
14704 		PackAddStrEx(p, "Hub", wgk->Hub, i, t->Num);
14705 		PackAddStrEx(p, "User", wgk->User, i, t->Num);
14706 	}
14707 }
FreeRpcWgk(RPC_WGK * t)14708 void FreeRpcWgk(RPC_WGK *t)
14709 {
14710 	// Validate arguments
14711 	if (t == NULL)
14712 	{
14713 		return;
14714 	}
14715 
14716 	Free(t->Wgks);
14717 }
14718 
14719 // NODE_INFO
InRpcNodeInfo(NODE_INFO * t,PACK * p)14720 void InRpcNodeInfo(NODE_INFO *t, PACK *p)
14721 {
14722 	// Validate arguments
14723 	if (t == NULL || p == NULL)
14724 	{
14725 		return;
14726 	}
14727 
14728 	Zero(t, sizeof(NODE_INFO));
14729 	PackGetStr(p, "ClientProductName", t->ClientProductName, sizeof(t->ClientProductName));
14730 	PackGetStr(p, "ServerProductName", t->ServerProductName, sizeof(t->ServerProductName));
14731 	PackGetStr(p, "ClientOsName", t->ClientOsName, sizeof(t->ClientOsName));
14732 	PackGetStr(p, "ClientOsVer", t->ClientOsVer, sizeof(t->ClientOsVer));
14733 	PackGetStr(p, "ClientOsProductId", t->ClientOsProductId, sizeof(t->ClientOsProductId));
14734 	PackGetStr(p, "ClientHostname", t->ClientHostname, sizeof(t->ClientHostname));
14735 	PackGetStr(p, "ServerHostname", t->ServerHostname, sizeof(t->ServerHostname));
14736 	PackGetStr(p, "ProxyHostname", t->ProxyHostname, sizeof(t->ProxyHostname));
14737 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
14738 	PackGetData2(p, "UniqueId", t->UniqueId, sizeof(t->UniqueId));
14739 
14740 	t->ClientProductVer = PackGetInt(p, "ClientProductVer");
14741 	t->ClientProductBuild = PackGetInt(p, "ClientProductBuild");
14742 	t->ServerProductVer = PackGetInt(p, "ServerProductVer");
14743 	t->ServerProductBuild = PackGetInt(p, "ServerProductBuild");
14744 	t->ClientIpAddress = PackGetIp32(p, "ClientIpAddress");
14745 	PackGetData2(p, "ClientIpAddress6", t->ClientIpAddress6, sizeof(t->ClientIpAddress6));
14746 	t->ClientPort = PackGetInt(p, "ClientPort");
14747 	t->ServerIpAddress = PackGetIp32(p, "ServerIpAddress");
14748 	PackGetData2(p, "ServerIpAddress6", t->ServerIpAddress6, sizeof(t->ServerIpAddress6));
14749 	t->ServerPort = PackGetInt(p, "ServerPort2");
14750 	t->ProxyIpAddress = PackGetIp32(p, "ProxyIpAddress");
14751 	PackGetData2(p, "ProxyIpAddress6", t->ProxyIpAddress6, sizeof(t->ProxyIpAddress6));
14752 	t->ProxyPort = PackGetInt(p, "ProxyPort");
14753 }
OutRpcNodeInfo(PACK * p,NODE_INFO * t)14754 void OutRpcNodeInfo(PACK *p, NODE_INFO *t)
14755 {
14756 	// Validate arguments
14757 	if (t == NULL || p == NULL)
14758 	{
14759 		return;
14760 	}
14761 
14762 	PackAddStr(p, "ClientProductName", t->ClientProductName);
14763 	PackAddStr(p, "ServerProductName", t->ServerProductName);
14764 	PackAddStr(p, "ClientOsName", t->ClientOsName);
14765 	PackAddStr(p, "ClientOsVer", t->ClientOsVer);
14766 	PackAddStr(p, "ClientOsProductId", t->ClientOsProductId);
14767 	PackAddStr(p, "ClientHostname", t->ClientHostname);
14768 	PackAddStr(p, "ServerHostname", t->ServerHostname);
14769 	PackAddStr(p, "ProxyHostname", t->ProxyHostname);
14770 	PackAddStr(p, "HubName", t->HubName);
14771 	PackAddData(p, "UniqueId", t->UniqueId, sizeof(t->UniqueId));
14772 
14773 	PackAddInt(p, "ClientProductVer", t->ClientProductVer);
14774 	PackAddInt(p, "ClientProductBuild", t->ClientProductBuild);
14775 	PackAddInt(p, "ServerProductVer", t->ServerProductVer);
14776 	PackAddInt(p, "ServerProductBuild", t->ServerProductBuild);
14777 	PackAddIp32(p, "ClientIpAddress", t->ClientIpAddress);
14778 	PackAddData(p, "ClientIpAddress6", t->ClientIpAddress6, sizeof(t->ClientIpAddress6));
14779 	PackAddInt(p, "ClientPort", t->ClientPort);
14780 	PackAddIp32(p, "ServerIpAddress", t->ServerIpAddress);
14781 	PackAddData(p, "ServerIpAddress6", t->ServerIpAddress6, sizeof(t->ServerIpAddress6));
14782 	PackAddInt(p, "ServerPort2", t->ServerPort);
14783 	PackAddIp32(p, "ProxyIpAddress", t->ProxyIpAddress);
14784 	PackAddData(p, "ProxyIpAddress6", t->ProxyIpAddress6, sizeof(t->ProxyIpAddress6));
14785 	PackAddInt(p, "ProxyPort", t->ProxyPort);
14786 }
14787 
14788 // RPC_SESSION_STATUS
InRpcSessionStatus(RPC_SESSION_STATUS * t,PACK * p)14789 void InRpcSessionStatus(RPC_SESSION_STATUS *t, PACK *p)
14790 {
14791 	// Validate arguments
14792 	if (t == NULL || p == NULL)
14793 	{
14794 		return;
14795 	}
14796 
14797 	Zero(t, sizeof(RPC_SESSION_STATUS));
14798 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
14799 	PackGetStr(p, "Name", t->Name, sizeof(t->Name));
14800 	PackGetStr(p, "Username", t->Username, sizeof(t->Username));
14801 	PackGetStr(p, "GroupName", t->GroupName, sizeof(t->GroupName));
14802 	PackGetStr(p, "RealUsername", t->RealUsername, sizeof(t->RealUsername));
14803 	t->ClientIp = PackGetIp32(p, "SessionStatus_ClientIp");
14804 	PackGetData2(p, "SessionStatus_ClientIp6", t->ClientIp6, sizeof(t->ClientIp6));
14805 	PackGetStr(p, "SessionStatus_ClientHostName", t->ClientHostName, sizeof(t->ClientHostName));
14806 	PackGetIp(p, "Client_Ip_Address", &t->ClientIpAddress);
14807 
14808 	InRpcClientGetConnectionStatus(&t->Status, p);
14809 	InRpcNodeInfo(&t->NodeInfo, p);
14810 }
OutRpcSessionStatus(PACK * p,RPC_SESSION_STATUS * t)14811 void OutRpcSessionStatus(PACK *p, RPC_SESSION_STATUS *t)
14812 {
14813 	// Validate arguments
14814 	if (t == NULL || p == NULL)
14815 	{
14816 		return;
14817 	}
14818 
14819 	PackAddStr(p, "HubName", t->HubName);
14820 	PackAddStr(p, "Name", t->Name);
14821 	PackAddStr(p, "Username", t->Username);
14822 	PackAddStr(p, "GroupName", t->GroupName);
14823 	PackAddStr(p, "RealUsername", t->RealUsername);
14824 	PackAddIp32(p, "SessionStatus_ClientIp", t->ClientIp);
14825 	PackAddData(p, "SessionStatus_ClientIp6", t->ClientIp6, sizeof(t->ClientIp6));
14826 	PackAddStr(p, "SessionStatus_ClientHostName", t->ClientHostName);
14827 	PackAddIp(p, "Client_Ip_Address", &t->ClientIpAddress);
14828 
14829 	OutRpcClientGetConnectionStatus(p, &t->Status);
14830 	OutRpcNodeInfo(p, &t->NodeInfo);
14831 }
FreeRpcSessionStatus(RPC_SESSION_STATUS * t)14832 void FreeRpcSessionStatus(RPC_SESSION_STATUS *t)
14833 {
14834 	// Validate arguments
14835 	if (t == NULL)
14836 	{
14837 		return;
14838 	}
14839 
14840 	CiFreeClientGetConnectionStatus(&t->Status);
14841 }
14842 
14843 // RPC_DELETE_SESSION
InRpcDeleteSession(RPC_DELETE_SESSION * t,PACK * p)14844 void InRpcDeleteSession(RPC_DELETE_SESSION *t, PACK *p)
14845 {
14846 	// Validate arguments
14847 	if (t == NULL || p == NULL)
14848 	{
14849 		return;
14850 	}
14851 
14852 	Zero(t, sizeof(RPC_DELETE_SESSION));
14853 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
14854 	PackGetStr(p, "Name", t->Name, sizeof(t->Name));
14855 }
OutRpcDeleteSession(PACK * p,RPC_DELETE_SESSION * t)14856 void OutRpcDeleteSession(PACK *p, RPC_DELETE_SESSION *t)
14857 {
14858 	// Validate arguments
14859 	if (t == NULL || p == NULL)
14860 	{
14861 		return;
14862 	}
14863 
14864 	PackAddStr(p, "HubName", t->HubName);
14865 	PackAddStr(p, "Name", t->Name);
14866 }
14867 
14868 // RPC_ENUM_MAC_TABLE
InRpcEnumMacTable(RPC_ENUM_MAC_TABLE * t,PACK * p)14869 void InRpcEnumMacTable(RPC_ENUM_MAC_TABLE *t, PACK *p)
14870 {
14871 	UINT i;
14872 	// Validate arguments
14873 	if (t == NULL || p == NULL)
14874 	{
14875 		return;
14876 	}
14877 
14878 	Zero(t, sizeof(RPC_ENUM_MAC_TABLE));
14879 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
14880 	t->NumMacTable = PackGetIndexCount(p, "SessionName");
14881 	t->MacTables = ZeroMalloc(sizeof(RPC_ENUM_MAC_TABLE_ITEM) * t->NumMacTable);
14882 
14883 	for (i = 0;i < t->NumMacTable;i++)
14884 	{
14885 		RPC_ENUM_MAC_TABLE_ITEM *e = &t->MacTables[i];
14886 
14887 		e->Key = PackGetIntEx(p, "Key", i);
14888 		PackGetStrEx(p, "SessionName", e->SessionName, sizeof(e->SessionName), i);
14889 		PackGetDataEx2(p, "MacAddress", e->MacAddress, sizeof(e->MacAddress), i);
14890 		e->VlanId = PackGetIntEx(p, "VlanId", i);
14891 		e->CreatedTime = PackGetInt64Ex(p, "CreatedTime", i);
14892 		e->UpdatedTime = PackGetInt64Ex(p, "UpdatedTime", i);
14893 		e->RemoteItem = PackGetBoolEx(p, "RemoteItem", i);
14894 		PackGetStrEx(p, "RemoteHostname", e->RemoteHostname, sizeof(e->RemoteHostname), i);
14895 	}
14896 }
OutRpcEnumMacTable(PACK * p,RPC_ENUM_MAC_TABLE * t)14897 void OutRpcEnumMacTable(PACK *p, RPC_ENUM_MAC_TABLE *t)
14898 {
14899 	UINT i;
14900 	// Validate arguments
14901 	if (t == NULL || p == NULL)
14902 	{
14903 		return;
14904 	}
14905 
14906 	PackAddStr(p, "HubName", t->HubName);
14907 
14908 	PackSetCurrentJsonGroupName(p, "MacTable");
14909 	for (i = 0;i < t->NumMacTable;i++)
14910 	{
14911 		RPC_ENUM_MAC_TABLE_ITEM *e = &t->MacTables[i];
14912 
14913 		PackAddIntEx(p, "Key", e->Key, i, t->NumMacTable);
14914 		PackAddStrEx(p, "SessionName", e->SessionName, i, t->NumMacTable);
14915 		PackAddDataEx(p, "MacAddress", e->MacAddress, sizeof(e->MacAddress), i, t->NumMacTable);
14916 		PackAddIntEx(p, "VlanId", e->VlanId, i, t->NumMacTable);
14917 		PackAddTime64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumMacTable);
14918 		PackAddTime64Ex(p, "UpdatedTime", e->UpdatedTime, i, t->NumMacTable);
14919 		PackAddBoolEx(p, "RemoteItem", e->RemoteItem, i, t->NumMacTable);
14920 		PackAddStrEx(p, "RemoteHostname", e->RemoteHostname, i, t->NumMacTable);
14921 	}
14922 	PackSetCurrentJsonGroupName(p, NULL);
14923 }
FreeRpcEnumMacTable(RPC_ENUM_MAC_TABLE * t)14924 void FreeRpcEnumMacTable(RPC_ENUM_MAC_TABLE *t)
14925 {
14926 	// Validate arguments
14927 	if (t == NULL)
14928 	{
14929 		return;
14930 	}
14931 
14932 	Free(t->MacTables);
14933 }
14934 
14935 // RPC_ENUM_IP_TABLE
InRpcEnumIpTable(RPC_ENUM_IP_TABLE * t,PACK * p)14936 void InRpcEnumIpTable(RPC_ENUM_IP_TABLE *t, PACK *p)
14937 {
14938 	UINT i;
14939 	// Validate arguments
14940 	if (t == NULL || p == NULL)
14941 	{
14942 		return;
14943 	}
14944 
14945 	Zero(t, sizeof(RPC_ENUM_IP_TABLE));
14946 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
14947 	t->NumIpTable = PackGetIndexCount(p, "SessionName");
14948 	t->IpTables = ZeroMalloc(sizeof(RPC_ENUM_IP_TABLE_ITEM) * t->NumIpTable);
14949 
14950 	for (i = 0;i < t->NumIpTable;i++)
14951 	{
14952 		RPC_ENUM_IP_TABLE_ITEM *e = &t->IpTables[i];
14953 
14954 		e->Key = PackGetIntEx(p, "Key", i);
14955 		PackGetStrEx(p, "SessionName", e->SessionName, sizeof(e->SessionName), i);
14956 		e->Ip = PackGetIp32Ex(p, "Ip", i);
14957 		if (PackGetIpEx(p, "IpV6", &e->IpV6, i) == false)
14958 		{
14959 			UINTToIP(&e->IpV6, e->Ip);
14960 		}
14961 		PackGetIp(p, "IpAddress", &e->IpAddress);
14962 		e->DhcpAllocated = PackGetBoolEx(p, "DhcpAllocated", i);
14963 		e->CreatedTime = PackGetInt64Ex(p, "CreatedTime", i);
14964 		e->UpdatedTime = PackGetInt64Ex(p, "UpdatedTime", i);
14965 		e->RemoteItem = PackGetBoolEx(p, "RemoteItem", i);
14966 		PackGetStrEx(p, "RemoteHostname", e->RemoteHostname, sizeof(e->RemoteHostname), i);
14967 	}
14968 }
OutRpcEnumIpTable(PACK * p,RPC_ENUM_IP_TABLE * t)14969 void OutRpcEnumIpTable(PACK *p, RPC_ENUM_IP_TABLE *t)
14970 {
14971 	UINT i;
14972 	// Validate arguments
14973 	if (t == NULL || p == NULL)
14974 	{
14975 		return;
14976 	}
14977 
14978 	PackAddStr(p, "HubName", t->HubName);
14979 
14980 	PackSetCurrentJsonGroupName(p, "IpTable");
14981 	for (i = 0;i < t->NumIpTable;i++)
14982 	{
14983 		RPC_ENUM_IP_TABLE_ITEM *e = &t->IpTables[i];
14984 
14985 		PackAddIntEx(p, "Key", e->Key, i, t->NumIpTable);
14986 		PackAddStrEx(p, "SessionName", e->SessionName, i, t->NumIpTable);
14987 		PackAddIp32Ex(p, "Ip", e->Ip, i, t->NumIpTable);
14988 		PackAddIpEx(p, "IpV6", &e->IpV6, i, t->NumIpTable);
14989 		PackAddIpEx(p, "IpAddress", &e->IpAddress, i, t->NumIpTable);
14990 		PackAddBoolEx(p, "DhcpAllocated", e->DhcpAllocated, i, t->NumIpTable);
14991 		PackAddTime64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumIpTable);
14992 		PackAddTime64Ex(p, "UpdatedTime", e->UpdatedTime, i, t->NumIpTable);
14993 		PackAddBoolEx(p, "RemoteItem", e->RemoteItem, i, t->NumIpTable);
14994 		PackAddStrEx(p, "RemoteHostname", e->RemoteHostname, i, t->NumIpTable);
14995 	}
14996 	PackSetCurrentJsonGroupName(p, NULL);
14997 }
FreeRpcEnumIpTable(RPC_ENUM_IP_TABLE * t)14998 void FreeRpcEnumIpTable(RPC_ENUM_IP_TABLE *t)
14999 {
15000 	// Validate arguments
15001 	if (t == NULL)
15002 	{
15003 		return;
15004 	}
15005 
15006 	Free(t->IpTables);
15007 }
15008 
15009 // RPC_DELETE_TABLE
InRpcDeleteTable(RPC_DELETE_TABLE * t,PACK * p)15010 void InRpcDeleteTable(RPC_DELETE_TABLE *t, PACK *p)
15011 {
15012 	// Validate arguments
15013 	if (t == NULL || p == NULL)
15014 	{
15015 		return;
15016 	}
15017 
15018 	Zero(t, sizeof(RPC_DELETE_TABLE));
15019 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
15020 	t->Key = PackGetInt(p, "Key");
15021 }
OutRpcDeleteTable(PACK * p,RPC_DELETE_TABLE * t)15022 void OutRpcDeleteTable(PACK *p, RPC_DELETE_TABLE *t)
15023 {
15024 	// Validate arguments
15025 	if (t == NULL || p == NULL)
15026 	{
15027 		return;
15028 	}
15029 
15030 	PackAddStr(p, "HubName", t->HubName);
15031 	PackAddInt(p, "Key", t->Key);
15032 }
15033 
15034 // Adjoin RPC_ENUM_IP_TABLE
AdjoinRpcEnumIpTable(RPC_ENUM_IP_TABLE * dest,RPC_ENUM_IP_TABLE * src)15035 void AdjoinRpcEnumIpTable(RPC_ENUM_IP_TABLE *dest, RPC_ENUM_IP_TABLE *src)
15036 {
15037 	UINT old_num;
15038 	UINT i, n;
15039 	if (dest == NULL || src == NULL)
15040 	{
15041 		return;
15042 	}
15043 
15044 	if (src->NumIpTable == 0)
15045 	{
15046 		return;
15047 	}
15048 
15049 	old_num = dest->NumIpTable;
15050 	dest->NumIpTable += src->NumIpTable;
15051 	dest->IpTables = ReAlloc(dest->IpTables, sizeof(RPC_ENUM_IP_TABLE_ITEM) * dest->NumIpTable);
15052 
15053 	n = 0;
15054 	for (i = old_num;i < dest->NumIpTable;i++)
15055 	{
15056 		Copy(&dest->IpTables[i], &src->IpTables[n++], sizeof(RPC_ENUM_IP_TABLE_ITEM));
15057 	}
15058 }
15059 
15060 // Adjoin RPC_ENUM_MAC_TABLE
AdjoinRpcEnumMacTable(RPC_ENUM_MAC_TABLE * dest,RPC_ENUM_MAC_TABLE * src)15061 void AdjoinRpcEnumMacTable(RPC_ENUM_MAC_TABLE *dest, RPC_ENUM_MAC_TABLE *src)
15062 {
15063 	UINT old_num;
15064 	UINT i, n;
15065 	if (dest == NULL || src == NULL)
15066 	{
15067 		return;
15068 	}
15069 
15070 	if (src->NumMacTable == 0)
15071 	{
15072 		return;
15073 	}
15074 
15075 	old_num = dest->NumMacTable;
15076 	dest->NumMacTable += src->NumMacTable;
15077 	dest->MacTables = ReAlloc(dest->MacTables, sizeof(RPC_ENUM_MAC_TABLE_ITEM) * dest->NumMacTable);
15078 
15079 	n = 0;
15080 	for (i = old_num;i < dest->NumMacTable;i++)
15081 	{
15082 		Copy(&dest->MacTables[i], &src->MacTables[n++], sizeof(RPC_ENUM_MAC_TABLE_ITEM));
15083 	}
15084 }
15085 
15086 // Adjoin RPC_ENUM_SESSION
AdjoinRpcEnumSession(RPC_ENUM_SESSION * dest,RPC_ENUM_SESSION * src)15087 void AdjoinRpcEnumSession(RPC_ENUM_SESSION *dest, RPC_ENUM_SESSION *src)
15088 {
15089 	UINT old_num;
15090 	UINT i, n;
15091 	if (dest == NULL || src == NULL)
15092 	{
15093 		return;
15094 	}
15095 
15096 	if (src->NumSession == 0)
15097 	{
15098 		return;
15099 	}
15100 
15101 	old_num = dest->NumSession;
15102 	dest->NumSession += src->NumSession;
15103 	dest->Sessions = ReAlloc(dest->Sessions, sizeof(RPC_ENUM_SESSION_ITEM) * dest->NumSession);
15104 
15105 	n = 0;
15106 	for (i = old_num;i < dest->NumSession;i++)
15107 	{
15108 		Copy(&dest->Sessions[i], &src->Sessions[n++], sizeof(RPC_ENUM_SESSION_ITEM));
15109 	}
15110 }
15111 
15112 // RPC_KEEP
InRpcKeep(RPC_KEEP * t,PACK * p)15113 void InRpcKeep(RPC_KEEP *t, PACK *p)
15114 {
15115 	// Validate arguments
15116 	if (t == NULL || p == NULL)
15117 	{
15118 		return;
15119 	}
15120 
15121 	Zero(t, sizeof(RPC_KEEP));
15122 	t->UseKeepConnect = PackGetBool(p, "UseKeepConnect");
15123 	PackGetStr(p, "KeepConnectHost", t->KeepConnectHost, sizeof(t->KeepConnectHost));
15124 	t->KeepConnectPort = PackGetInt(p, "KeepConnectPort");
15125 	t->KeepConnectProtocol = PackGetInt(p, "KeepConnectProtocol");
15126 	t->KeepConnectInterval = PackGetInt(p, "KeepConnectInterval");
15127 }
OutRpcKeep(PACK * p,RPC_KEEP * t)15128 void OutRpcKeep(PACK *p, RPC_KEEP *t)
15129 {
15130 	// Validate arguments
15131 	if (t == NULL || p == NULL)
15132 	{
15133 		return;
15134 	}
15135 
15136 	PackAddBool(p, "UseKeepConnect", t->UseKeepConnect);
15137 	PackAddStr(p, "KeepConnectHost", t->KeepConnectHost);
15138 	PackAddInt(p, "KeepConnectPort", t->KeepConnectPort);
15139 	PackAddInt(p, "KeepConnectProtocol", t->KeepConnectProtocol);
15140 	PackAddInt(p, "KeepConnectInterval", t->KeepConnectInterval);
15141 }
15142 
15143 // test RPC function
StTest(ADMIN * a,RPC_TEST * t)15144 UINT StTest(ADMIN *a, RPC_TEST *t)
15145 {
15146 	Format(t->StrValue, sizeof(t->StrValue), "%u", t->IntValue);
15147 
15148 	return ERR_NO_ERROR;
15149 }
15150 
15151 // RPC_TEST
InRpcTest(RPC_TEST * t,PACK * p)15152 void InRpcTest(RPC_TEST *t, PACK *p)
15153 {
15154 	Zero(t, sizeof(RPC_TEST));
15155 	t->IntValue = PackGetInt(p, "IntValue");
15156 	t->Int64Value = PackGetInt64(p, "Int64Value");
15157 	PackGetStr(p, "StrValue", t->StrValue, sizeof(t->StrValue));
15158 	PackGetUniStr(p, "UniStrValue", t->UniStrValue, sizeof(t->UniStrValue));
15159 }
OutRpcTest(PACK * p,RPC_TEST * t)15160 void OutRpcTest(PACK *p, RPC_TEST *t)
15161 {
15162 	PackAddInt(p, "IntValue", t->IntValue);
15163 	PackAddInt64(p, "Int64Value", t->Int64Value);
15164 	PackAddStr(p, "StrValue", t->StrValue);
15165 	PackAddUniStr(p, "UniStrValue", t->UniStrValue);
15166 }
FreeRpcTest(RPC_TEST * t)15167 void FreeRpcTest(RPC_TEST *t)
15168 {
15169 }
15170 
15171 // Admin RPC call
AdminCall(RPC * rpc,char * function_name,PACK * p)15172 PACK *AdminCall(RPC *rpc, char *function_name, PACK *p)
15173 {
15174 	// Validate arguments
15175 	if (rpc == NULL || function_name == NULL)
15176 	{
15177 		return NULL;
15178 	}
15179 	if (p == NULL)
15180 	{
15181 		p = NewPack();
15182 	}
15183 
15184 //	Debug("Admin RPC Call: %s\n", function_name);
15185 
15186 	return RpcCall(rpc, function_name, p);
15187 }
15188 
15189 // Check whether the source IP address is permitted to admin connection
CheckAdminSourceAddress(SOCK * sock,char * hubname)15190 bool CheckAdminSourceAddress(SOCK *sock, char *hubname)
15191 {
15192 	BUF *b;
15193 	char *s;
15194 	bool ok = false;
15195 	// Validate arguments
15196 	if (sock == NULL)
15197 	{
15198 		return false;
15199 	}
15200 
15201 	b = ReadDump(ADMINIP_TXT);
15202 	if (b == NULL)
15203 	{
15204 		return true;
15205 	}
15206 
15207 	while (true)
15208 	{
15209 		UINT i;
15210 		TOKEN_LIST *t;
15211 		IP ip;
15212 		IP mask;
15213 		IP ip1;
15214 		IP ip2;
15215 		s = CfgReadNextLine(b);
15216 
15217 		if (s == NULL)
15218 		{
15219 			break;
15220 		}
15221 
15222 		Trim(s);
15223 
15224 		i = SearchStrEx(s, "//", 0, false);
15225 		if (i != INFINITE)
15226 		{
15227 			s[i] = 0;
15228 		}
15229 
15230 		i = SearchStrEx(s, "#", 0, false);
15231 		if (i != INFINITE)
15232 		{
15233 			s[i] = 0;
15234 		}
15235 
15236 		Trim(s);
15237 
15238 		t = ParseToken(s, " \t");
15239 		if (t != NULL)
15240 		{
15241 			if (t->NumTokens >= 1)
15242 			{
15243 				if (t->NumTokens == 1 || StrCmpi(hubname, t->Token[1]) == 0)
15244 				{
15245 					if (ParseIpAndMask46(t->Token[0], &ip, &mask))
15246 					{
15247 						if (IsIP4(&sock->RemoteIP) && IsIP4(&ip))
15248 						{
15249 							IPAnd4(&ip1, &sock->RemoteIP, &mask);
15250 							IPAnd4(&ip2, &ip, &mask);
15251 
15252 							if (CmpIpAddr(&ip1, &ip2) == 0)
15253 							{
15254 								ok = true;
15255 							}
15256 						}
15257 						else if (IsIP6(&sock->RemoteIP) && IsIP6(&ip))
15258 						{
15259 							IPAnd6(&ip1, &sock->RemoteIP, &mask);
15260 							IPAnd6(&ip2, &ip, &mask);
15261 
15262 							if (CmpIpAddr(&ip1, &ip2) == 0)
15263 							{
15264 								ok = true;
15265 							}
15266 						}
15267 					}
15268 					else if (StrToIP(&ip, t->Token[0]))
15269 					{
15270 						if (CmpIpAddr(&sock->RemoteIP, &ip) == 0)
15271 						{
15272 							ok = true;
15273 						}
15274 					}
15275 
15276 					if (StrCmpi(t->Token[0], "*") == 0)
15277 					{
15278 						ok = true;
15279 					}
15280 				}
15281 			}
15282 
15283 			FreeToken(t);
15284 		}
15285 
15286 		Free(s);
15287 	}
15288 
15289 	FreeBuf(b);
15290 
15291 	return ok;
15292 }
15293 
15294 // Accept admin connection
AdminAccept(CONNECTION * c,PACK * p)15295 UINT AdminAccept(CONNECTION *c, PACK *p)
15296 {
15297 	ADMIN *a;
15298 	UCHAR secure_password[SHA1_SIZE];
15299 	UCHAR null_password[SHA1_SIZE];
15300 	UCHAR secure_null_password[SHA1_SIZE];
15301 	char hubname[MAX_HUBNAME_LEN + 1];
15302 	CEDAR *cedar;
15303 	SOCK *sock;
15304 	RPC *rpc;
15305 	UINT err;
15306 	SERVER *server = NULL;
15307 	RPC_WINVER ver;
15308 	bool accept_empty_password;
15309 	bool is_empty_password = false;
15310 	// Validate arguments
15311 	if (c == NULL || p == NULL)
15312 	{
15313 		return ERR_INTERNAL_ERROR;
15314 	}
15315 
15316 	cedar = c->Cedar;
15317 	sock = c->FirstSock;
15318 
15319 	if (cedar != NULL)
15320 	{
15321 		server = cedar->Server;
15322 	}
15323 
15324 	accept_empty_password = PackGetBool(p, "accept_empty_password");
15325 
15326 	// Get client OS version
15327 	InRpcWinVer(&ver, p);
15328 
15329 	// Get hub name
15330 	if (PackGetStr(p, "hubname", hubname, sizeof(hubname)) == false)
15331 	{
15332 		// without hub name
15333 		StrCpy(hubname, sizeof(hubname), "");
15334 	}
15335 
15336 	// Check source IP address
15337 	if (CheckAdminSourceAddress(sock, hubname) == false)
15338 	{
15339 		SLog(c->Cedar, "LA_IP_DENIED", c->Name);
15340 		return ERR_IP_ADDRESS_DENIED;
15341 	}
15342 
15343 	// Get password information
15344 	if (PackGetDataSize(p, "secure_password") != SHA1_SIZE)
15345 	{
15346 		// Malformed information
15347 		return ERR_PROTOCOL_ERROR;
15348 	}
15349 	PackGetData(p, "secure_password", secure_password);
15350 
15351 	if (StrLen(hubname) == 0)
15352 	{
15353 		// Server admin mode
15354 		SLog(c->Cedar, "LA_CONNECTED_1", c->Name);
15355 	}
15356 	else
15357 	{
15358 		// Hub admin mode
15359 		if (server != NULL && server->ServerType == SERVER_TYPE_FARM_MEMBER)
15360 		{
15361 			// Connection with hub admin mode to cluster member is not permitted
15362 			return ERR_NOT_ENOUGH_RIGHT;
15363 		}
15364 		SLog(c->Cedar, "LA_CONNECTED_2", c->Name, hubname);
15365 	}
15366 
15367 	// Check password
15368 	err = AdminCheckPassword(cedar, c->Random, secure_password,
15369 		StrLen(hubname) != 0 ? hubname : NULL, accept_empty_password, &is_empty_password);
15370 
15371 	if (err != ERR_NO_ERROR)
15372 	{
15373 		// Error occured
15374 		SLog(c->Cedar, "LA_ERROR", c->Name, GetUniErrorStr(err), err);
15375 		return err;
15376 	}
15377 
15378 	SLog(c->Cedar, "LA_OK", c->Name);
15379 
15380 	HashAdminPassword(null_password, "");
15381 	SecurePassword(secure_null_password, null_password, c->Random);
15382 
15383 	if (Cmp(secure_null_password, secure_password, SHA1_SIZE) == 0)
15384 	{
15385 		if (IsLocalHostIP(&sock->RemoteIP) == false)
15386 		{
15387 			// The client tried to use blank password for hub admin mode from remote
15388 			if (StrLen(hubname) != 0)
15389 			{
15390 				return ERR_NULL_PASSWORD_LOCAL_ONLY;
15391 			}
15392 		}
15393 	}
15394 
15395 
15396 	// Reply success result
15397 	p = NewPack();
15398 	if (accept_empty_password && is_empty_password)
15399 	{
15400 		PackAddBool(p, "empty_password", true);
15401 	}
15402 	HttpServerSend(sock, p);
15403 	FreePack(p);
15404 
15405 	// Construct ADMIN object
15406 	a = ZeroMalloc(sizeof(ADMIN));
15407 	a->ServerAdmin = ((StrLen(hubname) == 0) ? true : false);
15408 	a->HubName = (StrLen(hubname) != 0 ? hubname : NULL);
15409 	a->Server = c->Cedar->Server;
15410 	a->ClientBuild = c->ClientBuild;
15411 
15412 	Copy(&a->ClientWinVer, &ver, sizeof(RPC_WINVER));
15413 
15414 	// Timeout setting
15415 	SetTimeout(sock, INFINITE);
15416 
15417 	// RPC Server
15418 	rpc = StartRpcServer(sock, AdminDispatch, a);
15419 
15420 	a->Rpc = rpc;
15421 
15422 	SLog(c->Cedar, "LA_RPC_START", c->Name, rpc->Name);
15423 
15424 	RpcServer(rpc);
15425 	RpcFree(rpc);
15426 
15427 	if (a->LogFileList != NULL)
15428 	{
15429 		// Free cached log file list, if it exists
15430 		FreeEnumLogFile(a->LogFileList);
15431 	}
15432 
15433 	// Free ADMIN object
15434 	Free(a);
15435 
15436 	return ERR_NO_ERROR;
15437 }
15438 
15439 // Check for admin password
AdminCheckPassword(CEDAR * c,void * random,void * secure_password,char * hubname,bool accept_empty_password,bool * is_password_empty)15440 UINT AdminCheckPassword(CEDAR *c, void *random, void *secure_password, char *hubname,
15441 						bool accept_empty_password, bool *is_password_empty)
15442 {
15443 	UCHAR check[SHA1_SIZE];
15444 	bool b_dummy;
15445 	// Validate arguments
15446 	if (c == NULL || random == NULL || secure_password == NULL)
15447 	{
15448 		return ERR_INTERNAL_ERROR;
15449 	}
15450 	if (is_password_empty == NULL)
15451 	{
15452 		is_password_empty = &b_dummy;
15453 	}
15454 
15455 	*is_password_empty = false;
15456 
15457 	if (hubname == NULL || StrLen(hubname) == 0)
15458 	{
15459 		// Server admin mode
15460 		Lock(c->lock);
15461 		{
15462 			if (accept_empty_password && SiIsEmptyPassword(c->Server->HashedPassword))
15463 			{
15464 				// blank password
15465 				*is_password_empty = true;
15466 			}
15467 
15468 			SecurePassword(check, c->Server->HashedPassword, random);
15469 		}
15470 		Unlock(c->lock);
15471 
15472 		if (Cmp(check, secure_password, SHA1_SIZE) != 0)
15473 		{
15474 			// Password incorrect
15475 			return ERR_ACCESS_DENIED;
15476 		}
15477 	}
15478 	else
15479 	{
15480 		HUB *h;
15481 
15482 #if	0
15483 		if (c->Server->ServerType == SERVER_TYPE_FARM_MEMBER)
15484 		{
15485 			// In cluster member mode, hub admin mode is disabled
15486 			return ERR_FARM_MEMBER_HUB_ADMIN;
15487 		}
15488 #endif
15489 
15490 		// Hub admin mode
15491 		LockHubList(c);
15492 		{
15493 			h = GetHub(c, hubname);
15494 		}
15495 		UnlockHubList(c);
15496 
15497 		if (h == NULL)
15498 		{
15499 			// Specified hub is not found
15500 			return ERR_HUB_NOT_FOUND;
15501 		}
15502 
15503 		Lock(h->lock);
15504 		{
15505 			if (accept_empty_password && SiIsEmptyPassword(h->HashedPassword))
15506 			{
15507 				// User specified blank password
15508 				*is_password_empty = true;
15509 			}
15510 
15511 			SecurePassword(check, h->HashedPassword, random);
15512 		}
15513 		Unlock(h->lock);
15514 
15515 		ReleaseHub(h);
15516 
15517 		if (Cmp(check, secure_password, SHA1_SIZE) != 0)
15518 		{
15519 			// Incorrect password
15520 			return ERR_ACCESS_DENIED;
15521 		}
15522 	}
15523 
15524 	return ERR_NO_ERROR;
15525 }
15526 
15527 // Hash admin password
HashAdminPassword(void * hash,char * password)15528 void HashAdminPassword(void *hash, char *password)
15529 {
15530 	// Validate arguments
15531 	if (hash == NULL || password == NULL)
15532 	{
15533 		return;
15534 	}
15535 
15536 	Sha0(hash, password, StrLen(password));
15537 }
15538 
15539 // Disconnect admin connection
AdminDisconnect(RPC * rpc)15540 void AdminDisconnect(RPC *rpc)
15541 {
15542 	SESSION *s;
15543 	SOCK *sock;
15544 	// Validate arguments
15545 	if (rpc == NULL)
15546 	{
15547 		return;
15548 	}
15549 
15550 	s = (SESSION *)rpc->Param;
15551 	sock = rpc->Sock;
15552 
15553 	EndRpc(rpc);
15554 
15555 	Disconnect(sock);
15556 	ReleaseSession(s);
15557 }
15558 
15559 // Admin connection main routine
AdminConnectMain(CEDAR * cedar,CLIENT_OPTION * o,char * hubname,void * hashed_password,UINT * err,char * client_name,void * hWnd,bool * empty_password)15560 SESSION *AdminConnectMain(CEDAR *cedar, CLIENT_OPTION *o, char *hubname, void *hashed_password, UINT *err, char *client_name, void *hWnd, bool *empty_password)
15561 {
15562 	UCHAR secure_password[SHA1_SIZE];
15563 	SESSION *s;
15564 	SOCK *sock;
15565 	PACK *p;
15566 	RPC_WINVER ver;
15567 	// connect
15568 	s = NewRpcSessionEx2(cedar, o, err, client_name, hWnd);
15569 	if (s == NULL)
15570 	{
15571 		return NULL;
15572 	}
15573 
15574 	// Get socket
15575 	sock = s->Connection->FirstSock;
15576 
15577 	// Generate connect method
15578 	p = NewPack();
15579 
15580 	PackAddClientVersion(p, s->Connection);
15581 
15582 	PackAddStr(p, "method", "admin");
15583 	PackAddBool(p, "accept_empty_password", true);
15584 
15585 	// Windows version on client
15586 	GetWinVer(&ver);
15587 	OutRpcWinVer(p, &ver);
15588 
15589 	// Secure Password
15590 	SecurePassword(secure_password, hashed_password, s->Connection->Random);
15591 
15592 	PackAddData(p, "secure_password", secure_password, sizeof(secure_password));
15593 
15594 	// HUB name
15595 	if (hubname != NULL)
15596 	{
15597 		PackAddStr(p, "hubname", hubname);
15598 	}
15599 
15600 	if (HttpClientSend(sock, p) == false)
15601 	{
15602 		// disconnect
15603 		FreePack(p);
15604 		ReleaseSession(s);
15605 		*err = ERR_DISCONNECTED;
15606 		return NULL;
15607 	}
15608 
15609 	FreePack(p);
15610 
15611 	p = HttpClientRecv(sock);
15612 	if (p == NULL)
15613 	{
15614 		// disconnect
15615 		ReleaseSession(s);
15616 		*err = ERR_DISCONNECTED;
15617 		return NULL;
15618 	}
15619 
15620 	if (GetErrorFromPack(p) != 0)
15621 	{
15622 		// error
15623 		ReleaseSession(s);
15624 		*err = GetErrorFromPack(p);
15625 		FreePack(p);
15626 		return NULL;
15627 	}
15628 
15629 	if (empty_password != NULL)
15630 	{
15631 		*empty_password = PackGetBool(p, "empty_password");
15632 	}
15633 
15634 	FreePack(p);
15635 
15636 	return s;
15637 }
15638 
15639 // Admin connection
AdminConnectEx(CEDAR * cedar,CLIENT_OPTION * o,char * hubname,void * hashed_password,UINT * err,char * client_name)15640 RPC *AdminConnectEx(CEDAR *cedar, CLIENT_OPTION *o, char *hubname, void *hashed_password, UINT *err, char *client_name)
15641 {
15642 	return AdminConnectEx2(cedar, o, hubname, hashed_password, err, client_name, NULL);
15643 }
AdminConnectEx2(CEDAR * cedar,CLIENT_OPTION * o,char * hubname,void * hashed_password,UINT * err,char * client_name,void * hWnd)15644 RPC *AdminConnectEx2(CEDAR *cedar, CLIENT_OPTION *o, char *hubname, void *hashed_password, UINT *err, char *client_name, void *hWnd)
15645 {
15646 	SESSION *s;
15647 	SOCK *sock;
15648 	RPC *rpc;
15649 	UCHAR hashed_password_2[SHA1_SIZE];
15650 	bool empty_password = false;
15651 	// Validate arguments
15652 	if (cedar == NULL || o == NULL || hashed_password == NULL || err == NULL)
15653 	{
15654 		return NULL;
15655 	}
15656 
15657 	if (client_name == NULL)
15658 	{
15659 		client_name = CEDAR_MANAGER_STR;
15660 	}
15661 
15662 	Copy(hashed_password_2, hashed_password, SHA1_SIZE);
15663 
15664 	s = AdminConnectMain(cedar, o, hubname, hashed_password_2, err, client_name, hWnd, &empty_password);
15665 
15666 	if (s == NULL)
15667 	{
15668 		return NULL;
15669 	}
15670 
15671 	sock = s->Connection->FirstSock;
15672 
15673 	// RPC start
15674 	rpc = StartRpcClient(sock, s);
15675 
15676 	rpc->IsVpnServer = true;
15677 	Copy(&rpc->VpnServerClientOption, o, sizeof(CLIENT_OPTION));
15678 	StrCpy(rpc->VpnServerHubName, sizeof(rpc->VpnServerHubName), hubname);
15679 	StrCpy(rpc->VpnServerClientName, sizeof(rpc->VpnServerClientName), client_name);
15680 
15681 	if (empty_password == false)
15682 	{
15683 		Copy(rpc->VpnServerHashedPassword, hashed_password_2, SHA1_SIZE);
15684 	}
15685 	else
15686 	{
15687 		HashAdminPassword(rpc->VpnServerHashedPassword, "");
15688 	}
15689 
15690 	// timeout setting
15691 	SetTimeout(sock, INFINITE);
15692 
15693 	return rpc;
15694 }
15695 
15696 // Reconnect admin connection
AdminReconnect(RPC * rpc)15697 UINT AdminReconnect(RPC *rpc)
15698 {
15699 	SESSION *s;
15700 	SOCK *sock;
15701 	CEDAR *cedar;
15702 	UINT err;
15703 	bool empty_password = false;
15704 	// Validate arguments
15705 	if (rpc == NULL || rpc->IsVpnServer == false)
15706 	{
15707 		return ERR_INTERNAL_ERROR;
15708 	}
15709 
15710 	s = (SESSION *)rpc->Param;
15711 	cedar = s->Cedar;
15712 	AddRef(cedar->ref);
15713 
15714 	sock = rpc->Sock;
15715 	Disconnect(sock);
15716 	ReleaseSock(sock);
15717 	ReleaseSession(s);
15718 	rpc->Param = NULL;
15719 
15720 	rpc->Sock = NULL;
15721 
15722 	s = AdminConnectMain(cedar, &rpc->VpnServerClientOption,
15723 		rpc->VpnServerHubName,
15724 		rpc->VpnServerHashedPassword,
15725 		&err,
15726 		rpc->VpnServerClientName, NULL, &empty_password);
15727 
15728 	ReleaseCedar(cedar);
15729 
15730 	if (s == NULL)
15731 	{
15732 		return err;
15733 	}
15734 
15735 	if (empty_password)
15736 	{
15737 		HashAdminPassword(rpc->VpnServerHashedPassword, "");
15738 	}
15739 
15740 	rpc->Param = s;
15741 	rpc->Sock = s->Connection->FirstSock;
15742 	AddRef(rpc->Sock->ref);
15743 
15744 	return ERR_NO_ERROR;
15745 }
15746 
15747 // Identify blank password
SiIsEmptyPassword(void * hash_password)15748 bool SiIsEmptyPassword(void *hash_password)
15749 {
15750 	UCHAR hash[SHA1_SIZE];
15751 	// Validate arguments
15752 	if (hash_password == NULL)
15753 	{
15754 		return false;
15755 	}
15756 
15757 	Sha0(hash, "", 0);
15758 
15759 	if (Cmp(hash_password, hash, SHA1_SIZE) == 0)
15760 	{
15761 		return true;
15762 	}
15763 
15764 	return false;
15765 }
15766 
15767