1 // SoftEther VPN Source Code - Stable Edition Repository
2 // Cedar Communication Module
3 //
4 // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
5 //
6 // Copyright (c) Daiyuu Nobori.
7 // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
8 // Copyright (c) SoftEther Corporation.
9 // Copyright (c) all contributors on SoftEther VPN project in GitHub.
10 //
11 // All Rights Reserved.
12 //
13 // http://www.softether.org/
14 //
15 // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
16 // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
17 //
18 // License: The Apache License, Version 2.0
19 // https://www.apache.org/licenses/LICENSE-2.0
20 //
21 // DISCLAIMER
22 // ==========
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 // SOFTWARE.
31 //
32 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
33 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
34 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
35 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
36 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
37 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
38 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
39 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
40 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
41 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
42 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
43 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
44 // LAW OR COURT RULE.
45 //
46 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
47 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
48 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
49 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
50 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
51 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
52 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
53 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
54 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
55 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
56 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
57 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
58 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
59 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
60 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
61 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
62 // STATEMENT FOR WARNING AND DISCLAIMER.
63 //
64 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
65 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
66 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
67 //
68 //
69 // SOURCE CODE CONTRIBUTION
70 // ------------------------
71 //
72 // Your contribution to SoftEther VPN Project is much appreciated.
73 // Please send patches to us through GitHub.
74 // Read the SoftEther VPN Patch Acceptance Policy in advance:
75 // http://www.softether.org/5-download/src/9.patch
76 //
77 //
78 // DEAR SECURITY EXPERTS
79 // ---------------------
80 //
81 // If you find a bug or a security vulnerability please kindly inform us
82 // about the problem immediately so that we can fix the security problem
83 // to protect a lot of users around the world as soon as possible.
84 //
85 // Our e-mail address for security reports is:
86 // softether-vpn-security [at] softether.org
87 //
88 // Please note that the above e-mail address is not a technical support
89 // inquiry address. If you need technical assistance, please visit
90 // http://www.softether.org/ and ask your question on the users forum.
91 //
92 // Thank you for your cooperation.
93 //
94 //
95 // NO MEMORY OR RESOURCE LEAKS
96 // ---------------------------
97 //
98 // The memory-leaks and resource-leaks verification under the stress
99 // test has been passed before release this source code.
100 
101 
102 // Server.c
103 // VPN Server module
104 
105 #include "CedarPch.h"
106 
107 static SERVER *server = NULL;
108 static LOCK *server_lock = NULL;
109 char *SERVER_CONFIG_FILE_NAME = "$vpn_server.config";
110 char *SERVER_CONFIG_FILE_NAME_IN_CLIENT = "$vpn_gate_svc.config";
111 char *SERVER_CONFIG_FILE_NAME_IN_CLIENT_RELAY = "$vpn_gate_relay.config";
112 char *BRIDGE_CONFIG_FILE_NAME = "$vpn_bridge.config";
113 char *SERVER_CONFIG_TEMPLATE_NAME = "$vpn_server_template.config";
114 char *BRIDGE_CONFIG_TEMPLATE_NAME = "$vpn_server_template.config";
115 
116 static bool server_reset_setting = false;
117 
118 static volatile UINT global_server_flags[NUM_GLOBAL_SERVER_FLAGS] = {0};
119 
120 UINT vpn_global_parameters[NUM_GLOBAL_PARAMS] = {0};
121 
122 // Set the OpenVPN and SSTP setting
SiSetOpenVPNAndSSTPConfig(SERVER * s,OPENVPN_SSTP_CONFIG * c)123 void SiSetOpenVPNAndSSTPConfig(SERVER *s, OPENVPN_SSTP_CONFIG *c)
124 {
125 	// Validate arguments
126 	if (s == NULL || c == NULL)
127 	{
128 		return;
129 	}
130 
131 	Lock(s->OpenVpnSstpConfigLock);
132 	{
133 		// Save the settings
134 		if (s->Cedar->Bridge || s->ServerType != SERVER_TYPE_STANDALONE)
135 		{
136 			s->DisableSSTPServer = true;
137 			s->DisableOpenVPNServer = true;
138 		}
139 		else
140 		{
141 			s->DisableSSTPServer = !c->EnableSSTP;
142 			s->DisableOpenVPNServer = !c->EnableOpenVPN;
143 		}
144 
145 		NormalizeIntListStr(s->OpenVpnServerUdpPorts, sizeof(s->OpenVpnServerUdpPorts),
146 			c->OpenVPNPortList, true, ", ");
147 
148 		// Apply the OpenVPN configuration
149 		if (s->OpenVpnServerUdp != NULL)
150 		{
151 			if (s->DisableOpenVPNServer)
152 			{
153 				OvsApplyUdpPortList(s->OpenVpnServerUdp, "");
154 			}
155 			else
156 			{
157 				OvsApplyUdpPortList(s->OpenVpnServerUdp, s->OpenVpnServerUdpPorts);
158 			}
159 		}
160 	}
161 	Unlock(s->OpenVpnSstpConfigLock);
162 }
163 
164 // Get the OpenVPN and SSTP setting
SiGetOpenVPNAndSSTPConfig(SERVER * s,OPENVPN_SSTP_CONFIG * c)165 void SiGetOpenVPNAndSSTPConfig(SERVER *s, OPENVPN_SSTP_CONFIG *c)
166 {
167 	// Validate arguments
168 	if (s == NULL || c == NULL)
169 	{
170 		return;
171 	}
172 
173 	Zero(c, sizeof(OPENVPN_SSTP_CONFIG));
174 
175 	Lock(s->OpenVpnSstpConfigLock);
176 	{
177 		if (s->DisableOpenVPNServer == false)
178 		{
179 			c->EnableOpenVPN = true;
180 		}
181 
182 		if (s->DisableSSTPServer == false)
183 		{
184 			c->EnableSSTP = true;
185 		}
186 
187 		StrCpy(c->OpenVPNPortList, sizeof(c->OpenVPNPortList), s->OpenVpnServerUdpPorts);
188 	}
189 	Unlock(s->OpenVpnSstpConfigLock);
190 }
191 
192 // Get whether the number of user objects that are registered in the VPN Server is too many
SiTooManyUserObjectsInServer(SERVER * s,bool oneMore)193 bool SiTooManyUserObjectsInServer(SERVER *s, bool oneMore)
194 {
195 	return false;
196 }
197 
198 // Get the number of user objects that are registered in the VPN Server
SiGetServerNumUserObjects(SERVER * s)199 UINT SiGetServerNumUserObjects(SERVER *s)
200 {
201 	CEDAR *c;
202 	UINT ret = 0;
203 	// Validate arguments
204 	if (s == NULL)
205 	{
206 		return 0;
207 	}
208 
209 	c = s->Cedar;
210 
211 	LockList(c->HubList);
212 	{
213 		UINT i;
214 		for (i = 0;i < LIST_NUM(c->HubList);i++)
215 		{
216 			HUB *h = LIST_DATA(c->HubList, i);
217 
218 			if (h->HubDb != NULL)
219 			{
220 				ret += LIST_NUM(h->HubDb->UserList);
221 			}
222 		}
223 	}
224 	UnlockList(c->HubList);
225 
226 	return ret;
227 }
228 
229 
230 typedef struct SI_DEBUG_PROC_LIST
231 {
232 	UINT Id;
233 	char *Description;
234 	char *Args;
235 	SI_DEBUG_PROC *Proc;
236 } SI_DEBUG_PROC_LIST;
237 
238 // Debugging function
SiDebug(SERVER * s,RPC_TEST * ret,UINT i,char * str)239 UINT SiDebug(SERVER *s, RPC_TEST *ret, UINT i, char *str)
240 {
241 	SI_DEBUG_PROC_LIST proc_list[] =
242 	{
243 		{1, "Hello World", "<test string>", SiDebugProcHelloWorld},
244 		{2, "Terminate process now", "", SiDebugProcExit},
245 		{3, "Write memory dumpfile", "", SiDebugProcDump},
246 		{4, "Restore process priority", "", SiDebugProcRestorePriority},
247 		{5, "Set the process priority high", "", SiDebugProcSetHighPriority},
248 		{6, "Get the .exe filename of the process", "", SiDebugProcGetExeFileName},
249 		{7, "Crash the process", "", SiDebugProcCrash},
250 		{8, "Get IPsecMessageDisplayed Flag", "", SiDebugProcGetIPsecMessageDisplayedValue},
251 		{9, "Set IPsecMessageDisplayed Flag", "", SiDebugProcSetIPsecMessageDisplayedValue},
252 		{10, "Get VgsMessageDisplayed Flag", "", SiDebugProcGetVgsMessageDisplayedValue},
253 		{11, "Set VgsMessageDisplayed Flag", "", SiDebugProcSetVgsMessageDisplayedValue},
254 		{12, "Get the current TCP send queue length", "", SiDebugProcGetCurrentTcpSendQueueLength},
255 		{13, "Get the current GetIP thread count", "", SiDebugProcGetCurrentGetIPThreadCount},
256 	};
257 	UINT num_proc_list = sizeof(proc_list) / sizeof(proc_list[0]);
258 	UINT j;
259 	UINT ret_value = ERR_NO_ERROR;
260 	// Validate arguments
261 	if (s == NULL || ret == NULL)
262 	{
263 		return ERR_INVALID_PARAMETER;
264 	}
265 
266 	if (i == 0)
267 	{
268 		char tmp[MAX_SIZE];
269 		Zero(ret, sizeof(RPC_TEST));
270 
271 		StrCat(ret->StrValue, sizeof(ret->StrValue),
272 			"\n--- Debug Functions List --\n");
273 
274 		for (j = 0;j < num_proc_list;j++)
275 		{
276 			SI_DEBUG_PROC_LIST *p = &proc_list[j];
277 
278 			if (IsEmptyStr(p->Args) == false)
279 			{
280 				Format(tmp, sizeof(tmp),
281 					" %u: %s - Usage: %u /ARG:\"%s\"\n",
282 					p->Id, p->Description, p->Id, p->Args);
283 			}
284 			else
285 			{
286 				Format(tmp, sizeof(tmp),
287 					" %u: %s - Usage: %u\n",
288 					p->Id, p->Description, p->Id);
289 			}
290 
291 			StrCat(ret->StrValue, sizeof(ret->StrValue), tmp);
292 		}
293 	}
294 	else
295 	{
296 		ret_value = ERR_NOT_SUPPORTED;
297 
298 		for (j = 0;j < num_proc_list;j++)
299 		{
300 			SI_DEBUG_PROC_LIST *p = &proc_list[j];
301 
302 			if (p->Id == i)
303 			{
304 				ret_value = p->Proc(s, str, ret->StrValue, sizeof(ret->StrValue));
305 
306 				if (ret_value == ERR_NO_ERROR && IsEmptyStr(ret->StrValue))
307 				{
308 					StrCpy(ret->StrValue, sizeof(ret->StrValue), "Ok.");
309 				}
310 				break;
311 			}
312 		}
313 	}
314 
315 	return ret_value;
316 }
SiDebugProcHelloWorld(SERVER * s,char * in_str,char * ret_str,UINT ret_str_size)317 UINT SiDebugProcHelloWorld(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)
318 {
319 	// Validate arguments
320 	if (s == NULL || in_str == NULL || ret_str == NULL)
321 	{
322 		return ERR_INVALID_PARAMETER;
323 	}
324 
325 	Format(ret_str, ret_str_size, "Hello World %s\n", in_str);
326 
327 	return ERR_NO_ERROR;
328 }
SiDebugProcExit(SERVER * s,char * in_str,char * ret_str,UINT ret_str_size)329 UINT SiDebugProcExit(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)
330 {
331 	// Validate arguments
332 	if (s == NULL || in_str == NULL || ret_str == NULL)
333 	{
334 		return ERR_INVALID_PARAMETER;
335 	}
336 
337 	_exit(1);
338 
339 	return ERR_NO_ERROR;
340 }
SiDebugProcDump(SERVER * s,char * in_str,char * ret_str,UINT ret_str_size)341 UINT SiDebugProcDump(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)
342 {
343 	// Validate arguments
344 	if (s == NULL || in_str == NULL || ret_str == NULL)
345 	{
346 		return ERR_INVALID_PARAMETER;
347 	}
348 
349 #ifdef	OS_WIN32
350 	MsWriteMinidump(NULL, NULL);
351 #else	// OS_WIN32
352 	return ERR_NOT_SUPPORTED;
353 #endif	// OS_WIN32
354 
355 	return ERR_NO_ERROR;
356 }
SiDebugProcRestorePriority(SERVER * s,char * in_str,char * ret_str,UINT ret_str_size)357 UINT SiDebugProcRestorePriority(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)
358 {
359 	// Validate arguments
360 	if (s == NULL || in_str == NULL || ret_str == NULL)
361 	{
362 		return ERR_INVALID_PARAMETER;
363 	}
364 
365 	OSRestorePriority();
366 
367 	return ERR_NO_ERROR;
368 }
SiDebugProcSetHighPriority(SERVER * s,char * in_str,char * ret_str,UINT ret_str_size)369 UINT SiDebugProcSetHighPriority(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)
370 {
371 	// Validate arguments
372 	if (s == NULL || in_str == NULL || ret_str == NULL)
373 	{
374 		return ERR_INVALID_PARAMETER;
375 	}
376 
377 	OSSetHighPriority();
378 
379 	return ERR_NO_ERROR;
380 }
SiDebugProcGetExeFileName(SERVER * s,char * in_str,char * ret_str,UINT ret_str_size)381 UINT SiDebugProcGetExeFileName(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)
382 {
383 	// Validate arguments
384 	if (s == NULL || in_str == NULL || ret_str == NULL)
385 	{
386 		return ERR_INVALID_PARAMETER;
387 	}
388 
389 	GetExeName(ret_str, ret_str_size);
390 
391 	return ERR_NO_ERROR;
392 }
SiDebugProcCrash(SERVER * s,char * in_str,char * ret_str,UINT ret_str_size)393 UINT SiDebugProcCrash(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)
394 {
395 	// Validate arguments
396 	if (s == NULL || in_str == NULL || ret_str == NULL)
397 	{
398 		return ERR_INVALID_PARAMETER;
399 	}
400 
401 	CrashNow();
402 
403 	return ERR_NO_ERROR;
404 }
SiDebugProcGetIPsecMessageDisplayedValue(SERVER * s,char * in_str,char * ret_str,UINT ret_str_size)405 UINT SiDebugProcGetIPsecMessageDisplayedValue(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)
406 {
407 	// Validate arguments
408 	if (s == NULL || in_str == NULL || ret_str == NULL)
409 	{
410 		return ERR_INVALID_PARAMETER;
411 	}
412 
413 	ToStr(ret_str, s->IPsecMessageDisplayed);
414 
415 	return ERR_NO_ERROR;
416 }
SiDebugProcSetIPsecMessageDisplayedValue(SERVER * s,char * in_str,char * ret_str,UINT ret_str_size)417 UINT SiDebugProcSetIPsecMessageDisplayedValue(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)
418 {
419 	// Validate arguments
420 	if (s == NULL || in_str == NULL || ret_str == NULL)
421 	{
422 		return ERR_INVALID_PARAMETER;
423 	}
424 
425 	s->IPsecMessageDisplayed = ToInt(in_str);
426 
427 	return ERR_NO_ERROR;
428 }
SiDebugProcGetVgsMessageDisplayedValue(SERVER * s,char * in_str,char * ret_str,UINT ret_str_size)429 UINT SiDebugProcGetVgsMessageDisplayedValue(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)
430 {
431 	// Validate arguments
432 	if (s == NULL || in_str == NULL || ret_str == NULL)
433 	{
434 		return ERR_INVALID_PARAMETER;
435 	}
436 
437 #if	0
438 	if (VgDoNotPopupMessage() == false)
439 	{
440 		ToStr(ret_str, s->VgsMessageDisplayed);
441 	}
442 	else
443 	{
444 		ToStr(ret_str, 1);
445 	}
446 #else
447 	// Do not show the VGS message in VPN Server of the current version
448 	ToStr(ret_str, 1);
449 #endif
450 
451 	return ERR_NO_ERROR;
452 }
SiDebugProcGetCurrentTcpSendQueueLength(SERVER * s,char * in_str,char * ret_str,UINT ret_str_size)453 UINT SiDebugProcGetCurrentTcpSendQueueLength(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)
454 {
455 	char tmp1[64], tmp2[64], tmp3[64];
456 	// Validate arguments
457 	if (s == NULL || in_str == NULL || ret_str == NULL)
458 	{
459 		return ERR_INVALID_PARAMETER;
460 	}
461 
462 	ToStr3(tmp1, 0, CedarGetCurrentTcpQueueSize(s->Cedar));
463 	ToStr3(tmp2, 0, CedarGetQueueBudgetConsuming(s->Cedar));
464 	ToStr3(tmp3, 0, CedarGetFifoBudgetConsuming(s->Cedar));
465 
466 	Format(ret_str, 0,
467 		"CurrentTcpQueueSize  = %s\n"
468 		"QueueBudgetConsuming = %s\n"
469 		"FifoBudgetConsuming  = %s\n",
470 		tmp1, tmp2, tmp3);
471 
472 	return ERR_NO_ERROR;
473 }
SiDebugProcGetCurrentGetIPThreadCount(SERVER * s,char * in_str,char * ret_str,UINT ret_str_size)474 UINT SiDebugProcGetCurrentGetIPThreadCount(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)
475 {
476 	char tmp1[64], tmp2[64];
477 	// Validate arguments
478 	if (s == NULL || in_str == NULL || ret_str == NULL)
479 	{
480 		return ERR_INVALID_PARAMETER;
481 	}
482 
483 	ToStr3(tmp1, 0, GetCurrentGetIpThreadNum());
484 	ToStr3(tmp2, 0, GetGetIpThreadMaxNum());
485 
486 	Format(ret_str, 0,
487 		"Current threads = %s\n"
488 		"Quota           = %s\n",
489 		tmp1, tmp2);
490 
491 	return ERR_NO_ERROR;
492 }
SiDebugProcSetVgsMessageDisplayedValue(SERVER * s,char * in_str,char * ret_str,UINT ret_str_size)493 UINT SiDebugProcSetVgsMessageDisplayedValue(SERVER *s, char *in_str, char *ret_str, UINT ret_str_size)
494 {
495 	// Validate arguments
496 	if (s == NULL || in_str == NULL || ret_str == NULL)
497 	{
498 		return ERR_INVALID_PARAMETER;
499 	}
500 
501 
502 	return ERR_NO_ERROR;
503 }
504 
505 // Write the debug log
SiDebugLog(SERVER * s,char * msg)506 void SiDebugLog(SERVER *s, char *msg)
507 {
508 	// Validate arguments
509 	if (s == NULL || msg == NULL)
510 	{
511 		return;
512 	}
513 
514 	if (s->DebugLog != NULL)
515 	{
516 		WriteTinyLog(s->DebugLog, msg);
517 	}
518 }
519 
520 // Deadlock inspection main
SiCheckDeadLockMain(SERVER * s,UINT timeout)521 void SiCheckDeadLockMain(SERVER *s, UINT timeout)
522 {
523 	CEDAR *cedar;
524 	// Validate arguments
525 	if (s == NULL)
526 	{
527 		return;
528 	}
529 
530 	//Debug("SiCheckDeadLockMain Start.\n");
531 
532 
533 	cedar = s->Cedar;
534 
535 	if (s->ServerListenerList != NULL)
536 	{
537 		CheckDeadLock(s->ServerListenerList->lock, timeout, "s->ServerListenerList->lock");
538 	}
539 
540 	CheckDeadLock(s->lock, timeout, "s->lock");
541 
542 	if (s->FarmMemberList != NULL)
543 	{
544 		CheckDeadLock(s->FarmMemberList->lock, timeout, "s->FarmMemberList->lock");
545 	}
546 
547 	if (s->HubCreateHistoryList != NULL)
548 	{
549 		CheckDeadLock(s->HubCreateHistoryList->lock, timeout, "s->HubCreateHistoryList->lock");
550 	}
551 
552 	CheckDeadLock(s->CapsCacheLock, timeout, "s->CapsCacheLock");
553 
554 	CheckDeadLock(s->TasksFromFarmControllerLock, timeout, "s->TasksFromFarmControllerLock");
555 
556 	if (cedar != NULL)
557 	{
558 		if (cedar->HubList != NULL)
559 		{
560 			CheckDeadLock(cedar->HubList->lock, timeout, "cedar->HubList->lock");
561 		}
562 
563 		if (cedar->ListenerList != NULL)
564 		{
565 			UINT i;
566 			LIST *o = NewListFast(NULL);
567 
568 			CheckDeadLock(cedar->ListenerList->lock, timeout, "cedar->ListenerList->lock");
569 
570 			LockList(cedar->ListenerList);
571 			{
572 				for (i = 0;i < LIST_NUM(cedar->ListenerList);i++)
573 				{
574 					LISTENER *r = LIST_DATA(cedar->ListenerList, i);
575 
576 					AddRef(r->ref);
577 
578 					Add(o, r);
579 				}
580 			}
581 			UnlockList(cedar->ListenerList);
582 
583 			for (i = 0;i < LIST_NUM(o);i++)
584 			{
585 				LISTENER *r = LIST_DATA(o, i);
586 
587 
588 				ReleaseListener(r);
589 			}
590 
591 			ReleaseList(o);
592 		}
593 
594 		if (cedar->ConnectionList != NULL)
595 		{
596 			CheckDeadLock(cedar->ConnectionList->lock, timeout, "cedar->ConnectionList->lock");
597 		}
598 
599 		if (cedar->CaList != NULL)
600 		{
601 			CheckDeadLock(cedar->CaList->lock, timeout, "cedar->CaList->lock");
602 		}
603 
604 		if (cedar->TrafficLock != NULL)
605 		{
606 			CheckDeadLock(cedar->TrafficLock, timeout, "cedar->TrafficLock");
607 		}
608 
609 		if (cedar->TrafficDiffList != NULL)
610 		{
611 			CheckDeadLock(cedar->TrafficDiffList->lock, timeout, "cedar->TrafficDiffList->lock");
612 		}
613 
614 		if (cedar->LocalBridgeList != NULL)
615 		{
616 			CheckDeadLock(cedar->LocalBridgeList->lock, timeout, "cedar->LocalBridgeList->lock");
617 		}
618 
619 		if (cedar->L3SwList != NULL)
620 		{
621 			CheckDeadLock(cedar->L3SwList->lock, timeout, "cedar->L3SwList->lock");
622 		}
623 	}
624 
625 	//Debug("SiCheckDeadLockMain Finish.\n");
626 }
627 
628 // Deadlock check thread
SiDeadLockCheckThread(THREAD * t,void * param)629 void SiDeadLockCheckThread(THREAD *t, void *param)
630 {
631 	SERVER *s = (SERVER *)param;
632 	// Validate arguments
633 	if (s == NULL || t == NULL)
634 	{
635 		return;
636 	}
637 
638 	while (true)
639 	{
640 		Wait(s->DeadLockWaitEvent, SERVER_DEADLOCK_CHECK_SPAN);
641 
642 		if (s->HaltDeadLockThread)
643 		{
644 			break;
645 		}
646 
647 		SiCheckDeadLockMain(s, SERVER_DEADLOCK_CHECK_TIMEOUT);
648 	}
649 }
650 
651 // Initialize the deadlock check
SiInitDeadLockCheck(SERVER * s)652 void SiInitDeadLockCheck(SERVER *s)
653 {
654 	// Validate arguments
655 	if (s == NULL)
656 	{
657 		return;
658 	}
659 	if (s->DisableDeadLockCheck)
660 	{
661 		return;
662 	}
663 
664 	s->HaltDeadLockThread = false;
665 	s->DeadLockWaitEvent = NewEvent();
666 	s->DeadLockCheckThread = NewThread(SiDeadLockCheckThread, s);
667 }
668 
669 // Release the deadlock check
SiFreeDeadLockCheck(SERVER * s)670 void SiFreeDeadLockCheck(SERVER *s)
671 {
672 	// Validate arguments
673 	if (s == NULL)
674 	{
675 		return;
676 	}
677 
678 	if (s->DeadLockCheckThread == NULL)
679 	{
680 		return;
681 	}
682 
683 	s->HaltDeadLockThread = true;
684 	Set(s->DeadLockWaitEvent);
685 
686 	WaitThread(s->DeadLockCheckThread, INFINITE);
687 
688 	ReleaseThread(s->DeadLockCheckThread);
689 	s->DeadLockCheckThread = NULL;
690 
691 	ReleaseEvent(s->DeadLockWaitEvent);
692 	s->DeadLockWaitEvent = NULL;
693 
694 	s->HaltDeadLockThread = false;
695 }
696 
697 // Check whether the specified virtual HUB has been registered to creation history
SiIsHubRegistedOnCreateHistory(SERVER * s,char * name)698 bool SiIsHubRegistedOnCreateHistory(SERVER *s, char *name)
699 {
700 	UINT i;
701 	bool ret = false;
702 	// Validate arguments
703 	if (s == NULL || name == NULL)
704 	{
705 		return false;
706 	}
707 
708 	SiDeleteOldHubCreateHistory(s);
709 
710 	LockList(s->HubCreateHistoryList);
711 	{
712 		for (i = 0;i < LIST_NUM(s->HubCreateHistoryList);i++)
713 		{
714 			SERVER_HUB_CREATE_HISTORY *h = LIST_DATA(s->HubCreateHistoryList, i);
715 
716 			if (StrCmpi(h->HubName, name) == 0)
717 			{
718 				ret = true;
719 				break;
720 			}
721 		}
722 	}
723 	UnlockList(s->HubCreateHistoryList);
724 
725 	return ret;
726 }
727 
728 // Delete the Virtual HUB creation history
SiDelHubCreateHistory(SERVER * s,char * name)729 void SiDelHubCreateHistory(SERVER *s, char *name)
730 {
731 	UINT i;
732 	// Validate arguments
733 	if (s == NULL || name == NULL)
734 	{
735 		return;
736 	}
737 
738 	LockList(s->HubCreateHistoryList);
739 	{
740 		SERVER_HUB_CREATE_HISTORY *hh = NULL;
741 		for (i = 0;i < LIST_NUM(s->HubCreateHistoryList);i++)
742 		{
743 			SERVER_HUB_CREATE_HISTORY *h = LIST_DATA(s->HubCreateHistoryList, i);
744 
745 			if (StrCmpi(h->HubName, name) == 0)
746 			{
747 				Delete(s->HubCreateHistoryList, h);
748 				Free(h);
749 				break;
750 			}
751 		}
752 	}
753 	UnlockList(s->HubCreateHistoryList);
754 
755 	SiDeleteOldHubCreateHistory(s);
756 }
757 
758 // Register to the Virtual HUB creation history
SiAddHubCreateHistory(SERVER * s,char * name)759 void SiAddHubCreateHistory(SERVER *s, char *name)
760 {
761 	UINT i;
762 	// Validate arguments
763 	if (s == NULL || name == NULL)
764 	{
765 		return;
766 	}
767 
768 	LockList(s->HubCreateHistoryList);
769 	{
770 		SERVER_HUB_CREATE_HISTORY *hh = NULL;
771 		for (i = 0;i < LIST_NUM(s->HubCreateHistoryList);i++)
772 		{
773 			SERVER_HUB_CREATE_HISTORY *h = LIST_DATA(s->HubCreateHistoryList, i);
774 
775 			if (StrCmpi(h->HubName, name) == 0)
776 			{
777 				hh = h;
778 				break;
779 			}
780 		}
781 
782 		if (hh == NULL)
783 		{
784 			hh = ZeroMalloc(sizeof(SERVER_HUB_CREATE_HISTORY));
785 			StrCpy(hh->HubName, sizeof(hh->HubName), name);
786 
787 			Add(s->HubCreateHistoryList, hh);
788 		}
789 
790 		hh->CreatedTime = Tick64();
791 	}
792 	UnlockList(s->HubCreateHistoryList);
793 
794 	SiDeleteOldHubCreateHistory(s);
795 }
796 
797 // Delete outdated Virtual HUB creation histories
SiDeleteOldHubCreateHistory(SERVER * s)798 void SiDeleteOldHubCreateHistory(SERVER *s)
799 {
800 	UINT i;
801 	LIST *o;
802 	// Validate arguments
803 	if (s == NULL)
804 	{
805 		return;
806 	}
807 
808 	LockList(s->HubCreateHistoryList);
809 	{
810 		o = NewListFast(NULL);
811 
812 		for (i = 0;i < LIST_NUM(s->HubCreateHistoryList);i++)
813 		{
814 			SERVER_HUB_CREATE_HISTORY *h = LIST_DATA(s->HubCreateHistoryList, i);
815 
816 			if ((h->CreatedTime + ((UINT64)TICKET_EXPIRES)) <= Tick64())
817 			{
818 				// Expired
819 				Add(o, h);
820 			}
821 		}
822 
823 		for (i = 0;i < LIST_NUM(o);i++)
824 		{
825 			SERVER_HUB_CREATE_HISTORY *h = LIST_DATA(o, i);
826 
827 			Delete(s->HubCreateHistoryList, h);
828 
829 			Free(h);
830 		}
831 
832 		ReleaseList(o);
833 	}
834 	UnlockList(s->HubCreateHistoryList);
835 }
836 
837 // Initialize the Virtual HUB creation history
SiInitHubCreateHistory(SERVER * s)838 void SiInitHubCreateHistory(SERVER *s)
839 {
840 	// Validate arguments
841 	if (s == NULL)
842 	{
843 		return;
844 	}
845 
846 	s->HubCreateHistoryList = NewList(NULL);
847 }
848 
849 // Release the Virtual HUB creation history
SiFreeHubCreateHistory(SERVER * s)850 void SiFreeHubCreateHistory(SERVER *s)
851 {
852 	UINT i;
853 	// Validate arguments
854 	if (s == NULL)
855 	{
856 		return;
857 	}
858 
859 	for (i = 0;i < LIST_NUM(s->HubCreateHistoryList);i++)
860 	{
861 		SERVER_HUB_CREATE_HISTORY *h = LIST_DATA(s->HubCreateHistoryList, i);
862 
863 		Free(h);
864 	}
865 
866 	ReleaseList(s->HubCreateHistoryList);
867 
868 	s->HubCreateHistoryList = NULL;
869 }
870 
871 // Identify whether the server can be connected from the VPN Client that is
872 // created by the installer creating kit of Admin Pack
IsAdminPackSupportedServerProduct(char * name)873 bool IsAdminPackSupportedServerProduct(char *name)
874 {
875 	return true;
876 }
877 
878 
879 // Get the saving status of syslog
SiGetSysLogSaveStatus(SERVER * s)880 UINT SiGetSysLogSaveStatus(SERVER *s)
881 {
882 	SYSLOG_SETTING set;
883 	// Validate arguments
884 	if (s == NULL)
885 	{
886 		return SYSLOG_NONE;
887 	}
888 
889 	SiGetSysLogSetting(s, &set);
890 
891 	return set.SaveType;
892 }
893 
894 // Send a syslog
SiWriteSysLog(SERVER * s,char * typestr,char * hubname,wchar_t * message)895 void SiWriteSysLog(SERVER *s, char *typestr, char *hubname, wchar_t *message)
896 {
897 	wchar_t tmp[1024];
898 	char machinename[MAX_HOST_NAME_LEN + 1];
899 	char datetime[MAX_PATH];
900 	SYSTEMTIME st;
901 	// Validate arguments
902 	if (s == NULL || typestr == NULL || message == NULL)
903 	{
904 		return;
905 	}
906 
907 	if (GetGlobalServerFlag(GSF_DISABLE_SYSLOG) != 0)
908 	{
909 		return;
910 	}
911 
912 	// Host name
913 	GetMachineName(machinename, sizeof(machinename));
914 
915 	// Date and time
916 	LocalTime(&st);
917 	if(s->StrictSyslogDatetimeFormat){
918 		GetDateTimeStrRFC3339(datetime, sizeof(datetime), &st, GetCurrentTimezone());
919 	}else{
920 		GetDateTimeStrMilli(datetime, sizeof(datetime), &st);
921 	}
922 
923 	if (IsEmptyStr(hubname) == false)
924 	{
925 		UniFormat(tmp, sizeof(tmp), L"[%S/VPN/%S] (%S) <%S>: %s",
926 			machinename, hubname, datetime, typestr, message);
927 	}
928 	else
929 	{
930 		UniFormat(tmp, sizeof(tmp), L"[%S/VPN] (%S) <%S>: %s",
931 			machinename, datetime, typestr, message);
932 	}
933 
934 	Debug("Syslog send: %S\n",tmp);
935 
936 	SendSysLog(s->Syslog, tmp);
937 }
938 
939 // Write the syslog configuration
SiSetSysLogSetting(SERVER * s,SYSLOG_SETTING * setting)940 void SiSetSysLogSetting(SERVER *s, SYSLOG_SETTING *setting)
941 {
942 	SYSLOG_SETTING set;
943 	// Validate arguments
944 	if (s == NULL || setting == NULL)
945 	{
946 		return;
947 	}
948 
949 	Zero(&set, sizeof(set));
950 	Copy(&set, setting, sizeof(SYSLOG_SETTING));
951 
952 	if (IsEmptyStr(set.Hostname) || set.Port == 0)
953 	{
954 		set.SaveType = SYSLOG_NONE;
955 	}
956 
957 	Lock(s->SyslogLock);
958 	{
959 		Copy(&s->SyslogSetting, &set, sizeof(SYSLOG_SETTING));
960 
961 		SetSysLog(s->Syslog, set.Hostname, set.Port);
962 	}
963 	Unlock(s->SyslogLock);
964 }
965 
966 // Read the syslog configuration
SiGetSysLogSetting(SERVER * s,SYSLOG_SETTING * setting)967 void SiGetSysLogSetting(SERVER *s, SYSLOG_SETTING *setting)
968 {
969 	// Validate arguments
970 	if (s == NULL || setting == NULL)
971 	{
972 		return;
973 	}
974 
975 	//Lock(s->SyslogLock);
976 	{
977 		Copy(setting, &s->SyslogSetting, sizeof(SYSLOG_SETTING));
978 	}
979 	//Unlock(s->SyslogLock);
980 }
981 
982 
983 // Get the server product name
GetServerProductName(SERVER * s,char * name,UINT size)984 void GetServerProductName(SERVER *s, char *name, UINT size)
985 {
986 	char *cpu;
987 	// Validate arguments
988 	if (s == NULL || name == NULL)
989 	{
990 		return;
991 	}
992 
993 	GetServerProductNameInternal(s, name, size);
994 
995 #ifdef	CPU_64
996 	cpu = " (64 bit)";
997 #else	// CPU_64
998 	cpu = " (32 bit)";
999 #endif	// CPU_64
1000 
1001 	StrCat(name, size, cpu);
1002 
1003 	StrCat(name, size, " (Open Source)");
1004 }
GetServerProductNameInternal(SERVER * s,char * name,UINT size)1005 void GetServerProductNameInternal(SERVER *s, char *name, UINT size)
1006 {
1007 	// Validate arguments
1008 	if (s == NULL || name == NULL)
1009 	{
1010 		return;
1011 	}
1012 
1013 #ifdef	BETA_NUMBER
1014 	if (s->Cedar->Bridge)
1015 	{
1016 		StrCpy(name, size, CEDAR_BRIDGE_STR);
1017 	}
1018 	else
1019 	{
1020 		StrCpy(name, size, CEDAR_BETA_SERVER);
1021 	}
1022 	return;
1023 #else	// BETA_NUMBER
1024 	if (s->Cedar->Bridge)
1025 	{
1026 		StrCpy(name, size, CEDAR_BRIDGE_STR);
1027 	}
1028 	else
1029 	{
1030 		StrCpy(name, size, CEDAR_SERVER_STR);
1031 	}
1032 #endif	// BETA_NUMBER
1033 }
1034 
1035 // Adjoin the enumerations of log files
AdjoinEnumLogFile(LIST * o,LIST * src)1036 void AdjoinEnumLogFile(LIST *o, LIST *src)
1037 {
1038 	UINT i;
1039 	// Validate arguments
1040 	if (o == NULL || src == NULL)
1041 	{
1042 		return;
1043 	}
1044 
1045 	for (i = 0;i < LIST_NUM(src);i++)
1046 	{
1047 		LOG_FILE *f = LIST_DATA(src, i);
1048 
1049 		Insert(o, Clone(f, sizeof(LOG_FILE)));
1050 	}
1051 }
1052 
1053 // Check whether the log file with the specified name is contained in the enumerated list
CheckLogFileNameFromEnumList(LIST * o,char * name,char * server_name)1054 bool CheckLogFileNameFromEnumList(LIST *o, char *name, char *server_name)
1055 {
1056 	LOG_FILE t;
1057 	// Validate arguments
1058 	if (o == NULL || name == NULL || server_name == NULL)
1059 	{
1060 		return false;
1061 	}
1062 
1063 	Zero(&t, sizeof(t));
1064 	StrCpy(t.Path, sizeof(t.Path), name);
1065 	StrCpy(t.ServerName, sizeof(t.ServerName), server_name);
1066 
1067 	if (Search(o, &t) == NULL)
1068 	{
1069 		return false;
1070 	}
1071 
1072 	return true;
1073 }
1074 
1075 // Release the log file enumeration
FreeEnumLogFile(LIST * o)1076 void FreeEnumLogFile(LIST *o)
1077 {
1078 	UINT i;
1079 	// Validate arguments
1080 	if (o == NULL)
1081 	{
1082 		return;
1083 	}
1084 
1085 	for (i = 0;i < LIST_NUM(o);i++)
1086 	{
1087 		LOG_FILE *f = LIST_DATA(o, i);
1088 
1089 		Free(f);
1090 	}
1091 
1092 	ReleaseList(o);
1093 }
1094 
1095 // Enumerate the log files associated with the virtual HUB (All logs are listed in the case of server administrator)
EnumLogFile(char * hubname)1096 LIST *EnumLogFile(char *hubname)
1097 {
1098 	char exe_dir[MAX_PATH];
1099 	char tmp[MAX_PATH];
1100 	LIST *o = NewListFast(CmpLogFile);
1101 	DIRLIST *dir;
1102 
1103 	if (StrLen(hubname) == 0)
1104 	{
1105 		hubname = NULL;
1106 	}
1107 
1108 	GetLogDir(exe_dir, sizeof(exe_dir));
1109 
1110 	// Enumerate in the server_log
1111 	if (hubname == NULL)
1112 	{
1113 		EnumLogFileDir(o, SERVER_LOG_DIR);
1114 	}
1115 
1116 	// Enumerate in the packet_log
1117 	Format(tmp, sizeof(tmp), "%s/"HUB_PACKET_LOG_DIR, exe_dir);
1118 
1119 	if (hubname == NULL)
1120 	{
1121 		dir = EnumDir(tmp);
1122 		if (dir != NULL)
1123 		{
1124 			UINT i;
1125 			for (i = 0;i < dir->NumFiles;i++)
1126 			{
1127 				DIRENT *e = dir->File[i];
1128 
1129 				if (e->Folder)
1130 				{
1131 					char dir_name[MAX_PATH];
1132 
1133 					Format(dir_name, sizeof(dir_name), HUB_PACKET_LOG_DIR"/%s", e->FileName);
1134 
1135 					EnumLogFileDir(o, dir_name);
1136 				}
1137 			}
1138 
1139 			FreeDir(dir);
1140 		}
1141 	}
1142 	else
1143 	{
1144 		char dir_name[MAX_PATH];
1145 
1146 		Format(dir_name, sizeof(dir_name), HUB_PACKET_LOG_DIR"/%s", hubname);
1147 
1148 		EnumLogFileDir(o, dir_name);
1149 	}
1150 
1151 	// Enumerate in the security_log
1152 	Format(tmp, sizeof(tmp), "%s/"HUB_SECURITY_LOG_DIR, exe_dir);
1153 
1154 	if (hubname == NULL)
1155 	{
1156 		dir = EnumDir(tmp);
1157 		if (dir != NULL)
1158 		{
1159 			UINT i;
1160 			for (i = 0;i < dir->NumFiles;i++)
1161 			{
1162 				DIRENT *e = dir->File[i];
1163 
1164 				if (e->Folder)
1165 				{
1166 					char dir_name[MAX_PATH];
1167 
1168 					Format(dir_name, sizeof(dir_name), HUB_SECURITY_LOG_DIR"/%s", e->FileName);
1169 
1170 					EnumLogFileDir(o, dir_name);
1171 				}
1172 			}
1173 
1174 			FreeDir(dir);
1175 		}
1176 	}
1177 	else
1178 	{
1179 		char dir_name[MAX_PATH];
1180 
1181 		Format(dir_name, sizeof(dir_name), HUB_SECURITY_LOG_DIR"/%s", hubname);
1182 
1183 		EnumLogFileDir(o, dir_name);
1184 	}
1185 
1186 	return o;
1187 }
1188 
1189 // Enumerate log files in the specified directory
EnumLogFileDir(LIST * o,char * dirname)1190 void EnumLogFileDir(LIST *o, char *dirname)
1191 {
1192 	UINT i;
1193 	char exe_dir[MAX_PATH];
1194 	char dir_full_path[MAX_PATH];
1195 	DIRLIST *dir;
1196 	// Validate arguments
1197 	if (o == NULL || dirname == NULL)
1198 	{
1199 		return;
1200 	}
1201 
1202 	GetLogDir(exe_dir, sizeof(exe_dir));
1203 	Format(dir_full_path, sizeof(dir_full_path), "%s/%s", exe_dir, dirname);
1204 
1205 	dir = EnumDir(dir_full_path);
1206 	if (dir == NULL)
1207 	{
1208 		return;
1209 	}
1210 
1211 	for (i = 0;i < dir->NumFiles;i++)
1212 	{
1213 		DIRENT *e = dir->File[i];
1214 
1215 		if (e->Folder == false && e->FileSize > 0)
1216 		{
1217 			char full_path[MAX_PATH];
1218 			char file_path[MAX_PATH];
1219 
1220 			Format(file_path, sizeof(file_path), "%s/%s", dirname, e->FileName);
1221 			Format(full_path, sizeof(full_path), "%s/%s", exe_dir, file_path);
1222 
1223 			if (EndWith(file_path, ".log"))
1224 			{
1225 				LOG_FILE *f = ZeroMalloc(sizeof(LOG_FILE));
1226 
1227 				StrCpy(f->Path, sizeof(f->Path), file_path);
1228 				f->FileSize = (UINT)(MIN(e->FileSize, 0xffffffffUL));
1229 				f->UpdatedTime = e->UpdateDate;
1230 
1231 				GetMachineName(f->ServerName, sizeof(f->ServerName));
1232 
1233 				Insert(o, f);
1234 			}
1235 		}
1236 	}
1237 
1238 	FreeDir(dir);
1239 }
1240 
1241 // Log file list entry comparison
CmpLogFile(void * p1,void * p2)1242 int CmpLogFile(void *p1, void *p2)
1243 {
1244 	LOG_FILE *f1, *f2;
1245 	UINT i;
1246 	if (p1 == NULL || p2 == NULL)
1247 	{
1248 		return 0;
1249 	}
1250 	f1 = *(LOG_FILE **)p1;
1251 	f2 = *(LOG_FILE **)p2;
1252 	if (f1 == NULL || f2 == NULL)
1253 	{
1254 		return 0;
1255 	}
1256 
1257 	i = StrCmpi(f1->Path, f2->Path);
1258 	if (i != 0)
1259 	{
1260 		return i;
1261 	}
1262 
1263 	return StrCmpi(f1->ServerName, f2->ServerName);
1264 }
1265 
1266 // Get the Caps of the server
GetServerCapsInt(SERVER * s,char * name)1267 UINT GetServerCapsInt(SERVER *s, char *name)
1268 {
1269 	CAPSLIST t;
1270 	UINT ret;
1271 	// Validate arguments
1272 	if (s == NULL || name == NULL)
1273 	{
1274 		return 0;
1275 	}
1276 
1277 	Zero(&t, sizeof(t));
1278 	GetServerCaps(s, &t);
1279 
1280 	ret = GetCapsInt(&t, name);
1281 
1282 	return ret;
1283 }
GetServerCapsBool(SERVER * s,char * name)1284 bool GetServerCapsBool(SERVER *s, char *name)
1285 {
1286 	return (GetServerCapsInt(s, name) == 0) ? false : true;
1287 }
1288 
1289 // Initialize the Caps cache of the server
InitServerCapsCache(SERVER * s)1290 void InitServerCapsCache(SERVER *s)
1291 {
1292 	// Validate arguments
1293 	if (s == NULL)
1294 	{
1295 		return;
1296 	}
1297 
1298 	s->CapsCacheLock = NewLock();
1299 	s->CapsListCache = NULL;
1300 }
1301 
1302 // Release the Caps cache of the server
FreeServerCapsCache(SERVER * s)1303 void FreeServerCapsCache(SERVER *s)
1304 {
1305 	// Validate arguments
1306 	if (s == NULL)
1307 	{
1308 		return;
1309 	}
1310 
1311 	if (s->CapsListCache != NULL)
1312 	{
1313 		FreeCapsList(s->CapsListCache);
1314 		s->CapsListCache = NULL;
1315 	}
1316 	DeleteLock(s->CapsCacheLock);
1317 }
1318 
1319 // Dispose the Caps cache of the server
DestroyServerCapsCache(SERVER * s)1320 void DestroyServerCapsCache(SERVER *s)
1321 {
1322 	// Validate arguments
1323 	if (s == NULL)
1324 	{
1325 		return;
1326 	}
1327 
1328 	Lock(s->CapsCacheLock);
1329 	{
1330 		if (s->CapsListCache != NULL)
1331 		{
1332 			FreeCapsList(s->CapsListCache);
1333 			s->CapsListCache = NULL;
1334 		}
1335 	}
1336 	Unlock(s->CapsCacheLock);
1337 }
1338 
1339 // Flush the Caps list for this server
FlushServerCaps(SERVER * s)1340 void FlushServerCaps(SERVER *s)
1341 {
1342 	CAPSLIST t;
1343 	// Validate arguments
1344 	if (s == NULL)
1345 	{
1346 		return;
1347 	}
1348 
1349 	DestroyServerCapsCache(s);
1350 
1351 	Zero(&t, sizeof(t));
1352 	GetServerCaps(s, &t);
1353 }
1354 
1355 // Get the Caps list for this server
GetServerCaps(SERVER * s,CAPSLIST * t)1356 void GetServerCaps(SERVER *s, CAPSLIST *t)
1357 {
1358 	// Validate arguments
1359 	if (s == NULL || t == NULL)
1360 	{
1361 		return;
1362 	}
1363 
1364 	Lock(s->CapsCacheLock);
1365 	{
1366 
1367 		if (s->CapsListCache == NULL)
1368 		{
1369 			s->CapsListCache = ZeroMalloc(sizeof(CAPSLIST));
1370 			GetServerCapsMain(s, s->CapsListCache);
1371 		}
1372 
1373 		Copy(t, s->CapsListCache, sizeof(CAPSLIST));
1374 	}
1375 	Unlock(s->CapsCacheLock);
1376 }
1377 
1378 // Update the global server flags
UpdateGlobalServerFlags(SERVER * s,CAPSLIST * t)1379 void UpdateGlobalServerFlags(SERVER *s, CAPSLIST *t)
1380 {
1381 	bool is_restricted = false;
1382 	// Validate arguments
1383 	if (s == NULL || t == NULL)
1384 	{
1385 		return;
1386 	}
1387 
1388 	is_restricted = SiIsEnterpriseFunctionsRestrictedOnOpenSource(s->Cedar);
1389 
1390 	SetGlobalServerFlag(GSF_DISABLE_PUSH_ROUTE, is_restricted);
1391 	SetGlobalServerFlag(GSF_DISABLE_RADIUS_AUTH, is_restricted);
1392 	SetGlobalServerFlag(GSF_DISABLE_CERT_AUTH, is_restricted);
1393 	SetGlobalServerFlag(GSF_DISABLE_DEEP_LOGGING, is_restricted);
1394 	SetGlobalServerFlag(GSF_DISABLE_AC, is_restricted);
1395 	SetGlobalServerFlag(GSF_DISABLE_SYSLOG, is_restricted);
1396 }
1397 
1398 // Set a global server flag
SetGlobalServerFlag(UINT index,UINT value)1399 void SetGlobalServerFlag(UINT index, UINT value)
1400 {
1401 	// Validate arguments
1402 	if (index >= NUM_GLOBAL_SERVER_FLAGS)
1403 	{
1404 		return;
1405 	}
1406 
1407 	global_server_flags[index] = value;
1408 }
1409 
1410 // Get a global server flag
GetGlobalServerFlag(UINT index)1411 UINT GetGlobalServerFlag(UINT index)
1412 {
1413 	// Validate arguments
1414 	if (index >= NUM_GLOBAL_SERVER_FLAGS)
1415 	{
1416 		return 0;
1417 	}
1418 
1419 	return global_server_flags[index];
1420 }
1421 
1422 // Main of the aquisition of Caps of the server
GetServerCapsMain(SERVER * s,CAPSLIST * t)1423 void GetServerCapsMain(SERVER *s, CAPSLIST *t)
1424 {
1425 	bool is_restricted = false;
1426 
1427 	// Validate arguments
1428 	if (s == NULL || t == NULL)
1429 	{
1430 		return;
1431 	}
1432 
1433 	is_restricted = SiIsEnterpriseFunctionsRestrictedOnOpenSource(s->Cedar);
1434 
1435 	// Initialize
1436 	InitCapsList(t);
1437 
1438 	// Maximum Ethernet packet size
1439 	AddCapsInt(t, "i_max_packet_size", MAX_PACKET_SIZE);
1440 
1441 	if (s->Cedar->Bridge == false)
1442 	{
1443 		UINT max_sessions, max_clients, max_bridges, max_user_creations;
1444 
1445 		max_clients = INFINITE;
1446 		max_bridges = INFINITE;
1447 		max_sessions = SERVER_MAX_SESSIONS_FOR_CARRIER_EDITION;
1448 		max_user_creations = INFINITE;
1449 
1450 		// Maximum number of virtual HUBs
1451 		AddCapsInt(t, "i_max_hubs", SERVER_MAX_SESSIONS_FOR_CARRIER_EDITION);
1452 
1453 		// The maximum number of concurrent sessions
1454 		AddCapsInt(t, "i_max_sessions", max_sessions);
1455 
1456 		// Maximum number of creatable users
1457 		AddCapsInt(t, "i_max_user_creation", max_user_creations);
1458 
1459 		// Maximum number of clients
1460 		AddCapsInt(t, "i_max_clients", max_clients);
1461 
1462 		// Maximum number of bridges
1463 		AddCapsInt(t, "i_max_bridges", max_bridges);
1464 
1465 		if (s->ServerType != SERVER_TYPE_FARM_MEMBER)
1466 		{
1467 			// Maximum number of registrable users / Virtual HUB
1468 			AddCapsInt(t, "i_max_users_per_hub", MAX_USERS);
1469 
1470 			// Maximum number of registrable groups / Virtual HUB
1471 			AddCapsInt(t, "i_max_groups_per_hub", MAX_GROUPS);
1472 
1473 			// Maximum number of registrable access list entries / Virtual HUB
1474 			AddCapsInt(t, "i_max_access_lists", MAX_ACCESSLISTS);
1475 		}
1476 		else
1477 		{
1478 			// Maximum number of registrable users / Virtual HUB
1479 			AddCapsInt(t, "i_max_users_per_hub", 0);
1480 
1481 			// Maximum number of registrable groups / Virtual HUB
1482 			AddCapsInt(t, "i_max_groups_per_hub", 0);
1483 
1484 			// Maximum number of registrable access list entries / Virtual HUB
1485 			AddCapsInt(t, "i_max_access_lists", 0);
1486 		}
1487 
1488 		// The policy related to multiple logins
1489 		AddCapsBool(t, "b_support_limit_multilogin", true);
1490 
1491 		// QoS / VoIP
1492 		AddCapsBool(t, "b_support_qos", true);
1493 
1494 		// syslog
1495 		AddCapsBool(t, "b_support_syslog", true);
1496 
1497 		// IPsec
1498 		// (Only works in stand-alone mode currently)
1499 		AddCapsBool(t, "b_support_ipsec", (s->ServerType == SERVER_TYPE_STANDALONE));
1500 
1501 		// SSTP
1502 		// (Only works in stand-alone mode currently)
1503 		AddCapsBool(t, "b_support_sstp", (s->ServerType == SERVER_TYPE_STANDALONE));
1504 
1505 		// OpenVPN
1506 		// (Only works in stand-alone mode currently)
1507 		AddCapsBool(t, "b_support_openvpn", (s->ServerType == SERVER_TYPE_STANDALONE));
1508 
1509 		// DDNS
1510 		AddCapsBool(t, "b_support_ddns", (s->DDnsClient != NULL));
1511 
1512 		if (s->DDnsClient != NULL)
1513 		{
1514 			// DDNS via Proxy
1515 			AddCapsBool(t, "b_support_ddns_proxy", true);
1516 		}
1517 
1518 		// VPN over ICMP, VPN over DNS
1519 		AddCapsBool(t, "b_support_special_listener", true);
1520 	}
1521 	else
1522 	{
1523 		// Maximum number of virtual HUBs
1524 		AddCapsInt(t, "i_max_hubs", 0);
1525 
1526 		// The maximum number of concurrent sessions
1527 		AddCapsInt(t, "i_max_sessions", 0);
1528 
1529 		// Maximum number of clients
1530 		AddCapsInt(t, "i_max_clients", 0);
1531 
1532 		// Maximum number of bridges
1533 		AddCapsInt(t, "i_max_bridges", 0);
1534 
1535 		// Maximum number of registrable users / Virtual HUB
1536 		AddCapsInt(t, "i_max_users_per_hub", 0);
1537 
1538 		// Maximum number of registrable groups / Virtual HUB
1539 		AddCapsInt(t, "i_max_groups_per_hub", 0);
1540 
1541 		// Maximum number of registrable access list entries / Virtual HUB
1542 		AddCapsInt(t, "i_max_access_lists", 0);
1543 
1544 		// QoS / VoIP
1545 		AddCapsBool(t, "b_support_qos", true);
1546 
1547 		// syslog
1548 		AddCapsBool(t, "b_support_syslog", true);
1549 
1550 		// IPsec
1551 		AddCapsBool(t, "b_support_ipsec", false);
1552 
1553 		// SSTP
1554 		AddCapsBool(t, "b_support_sstp", false);
1555 
1556 		// OpenVPN
1557 		AddCapsBool(t, "b_support_openvpn", false);
1558 
1559 		// DDNS
1560 		AddCapsBool(t, "b_support_ddns", false);
1561 
1562 		// VPN over ICMP, VPN over DNS
1563 		AddCapsBool(t, "b_support_special_listener", false);
1564 	}
1565 
1566 	// Changing the type of Virtual HUB in cluster is prohibited
1567 	AddCapsBool(t, "b_cluster_hub_type_fixed", true);
1568 
1569 	// Maximum MAC address table  size / Virtual HUB
1570 	AddCapsInt(t, "i_max_mac_tables", MAX_MAC_TABLES);
1571 
1572 	// Maximum IP address table  size / Virtual HUB
1573 	AddCapsInt(t, "i_max_ip_tables", MAX_IP_TABLES);
1574 
1575 	// SecureNAT function is available
1576 	AddCapsBool(t, "b_support_securenat", true);
1577 
1578 	// Pushing routing table function of SecureNAT Virtual DHCP Server is available
1579 	AddCapsBool(t, "b_suppport_push_route", !is_restricted);
1580 	AddCapsBool(t, "b_suppport_push_route_config", true);
1581 
1582 	if (s->ServerType != SERVER_TYPE_STANDALONE)
1583 	{
1584 		AddCapsBool(t, "b_virtual_nat_disabled", true);
1585 	}
1586 
1587 	// Maximum NAT table size / Virtual HUB
1588 	AddCapsInt(t, "i_max_secnat_tables", NAT_MAX_SESSIONS);
1589 
1590 	// Cascade connction
1591 	if (s->ServerType == SERVER_TYPE_STANDALONE)
1592 	{
1593 		AddCapsBool(t, "b_support_cascade", true);
1594 	}
1595 	else
1596 	{
1597 		AddCapsBool(t, "b_support_cascade", false);
1598 	}
1599 
1600 	if (s->Cedar->Bridge)
1601 	{
1602 		// Bridge mode
1603 		AddCapsBool(t, "b_bridge", true);
1604 	}
1605 	else if (s->ServerType == SERVER_TYPE_STANDALONE)
1606 	{
1607 		// Stand-alone mode
1608 		AddCapsBool(t, "b_standalone", true);
1609 	}
1610 	else if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
1611 	{
1612 		// Cluster controller mode
1613 		AddCapsBool(t, "b_cluster_controller", true);
1614 	}
1615 	else
1616 	{
1617 		// Cluster member mode
1618 		AddCapsBool(t, "b_cluster_member", true);
1619 	}
1620 
1621 	// Virtual HUB is modifiable
1622 	AddCapsBool(t, "b_support_config_hub", s->ServerType != SERVER_TYPE_FARM_MEMBER &&
1623 		s->Cedar->Bridge == false);
1624 
1625 	// VPN client can be connected
1626 	AddCapsBool(t, "b_vpn_client_connect", s->Cedar->Bridge == false ? true : false);
1627 
1628 	// External authentication server is available
1629 	AddCapsBool(t, "b_support_radius", s->ServerType != SERVER_TYPE_FARM_MEMBER &&
1630 		s->Cedar->Bridge == false);
1631 
1632 	// Local-bridge function is available
1633 	AddCapsBool(t, "b_local_bridge", IsBridgeSupported());
1634 
1635 	if (OS_IS_WINDOWS(GetOsInfo()->OsType))
1636 	{
1637 		// Packet capture driver is not installed
1638 		AddCapsBool(t, "b_must_install_pcap", IsEthSupported() == false ? true : false);
1639 	}
1640 	else
1641 	{
1642 		// Regard that the driver is installed in the Linux version
1643 		AddCapsBool(t, "b_must_install_pcap", false);
1644 	}
1645 
1646 	if (IsBridgeSupported())
1647 	{
1648 		// Tun / tap device is available (only Linux)
1649 		AddCapsBool(t, "b_tap_supported", GetOsInfo()->OsType == OSTYPE_LINUX ? true : false);
1650 	}
1651 
1652 	// Cascade connction
1653 	if (s->ServerType == SERVER_TYPE_STANDALONE)
1654 	{
1655 		AddCapsBool(t, "b_support_cascade", true);
1656 	}
1657 	else
1658 	{
1659 		AddCapsBool(t, "b_support_cascade", false);
1660 	}
1661 
1662 	// Server authentication can be used in cascade connection
1663 	AddCapsBool(t, "b_support_cascade_cert", true);
1664 
1665 	//  the log file settings is modifiable
1666 	AddCapsBool(t, "b_support_config_log", s->ServerType != SERVER_TYPE_FARM_MEMBER);
1667 
1668 	// Automatic deletion of log file is available
1669 	AddCapsBool(t, "b_support_autodelete", true);
1670 
1671 	// Config file operation is available
1672 	AddCapsBool(t, "b_support_config_rw", true);
1673 
1674 	// Attribute of each Virtual HUB can be set
1675 	AddCapsBool(t, "b_support_hub_admin_option", true);
1676 
1677 	// Client certificate can be set in a cascade connection
1678 	AddCapsBool(t, "b_support_cascade_client_cert", true);
1679 
1680 	// Virtual HUB can be hidden
1681 	AddCapsBool(t, "b_support_hide_hub", true);
1682 
1683 	// Integrated management
1684 	AddCapsBool(t, "b_support_cluster_admin", true);
1685 
1686 	// Flag of open-source version
1687 	AddCapsBool(t, "b_is_softether", true);
1688 
1689 	if (s->Cedar->Bridge == false)
1690 	{
1691 
1692 		// The virtual layer 3 switch function is available
1693 		AddCapsBool(t, "b_support_layer3", true);
1694 
1695 		AddCapsInt(t, "i_max_l3_sw", MAX_NUM_L3_SWITCH);
1696 		AddCapsInt(t, "i_max_l3_if", MAX_NUM_L3_IF);
1697 		AddCapsInt(t, "i_max_l3_table", MAX_NUM_L3_TABLE);
1698 
1699 		// Can act as a part of a cluster
1700 		AddCapsBool(t, "b_support_cluster", true);
1701 	}
1702 	else
1703 	{
1704 		AddCapsBool(t, "b_support_layer3", false);
1705 
1706 		AddCapsInt(t, "i_max_l3_sw", 0);
1707 		AddCapsInt(t, "i_max_l3_if", 0);
1708 		AddCapsInt(t, "i_max_l3_table", 0);
1709 
1710 		AddCapsBool(t, "b_support_cluster", false);
1711 	}
1712 
1713 	if (s->ServerType != SERVER_TYPE_FARM_MEMBER && s->Cedar->Bridge == false)
1714 	{
1715 		// Support for CRL
1716 		AddCapsBool(t, "b_support_crl", true);
1717 
1718 		// Supports AC
1719 		AddCapsBool(t, "b_support_ac", true);
1720 	}
1721 
1722 	// Supports downloading a log file
1723 	AddCapsBool(t, "b_support_read_log", true);
1724 
1725 	// Cascade connection can be renamed
1726 	AddCapsBool(t, "b_support_rename_cascade", true);
1727 
1728 
1729 	if (s->Cedar->Beta)
1730 	{
1731 		// Beta version
1732 		AddCapsBool(t, "b_beta_version", true);
1733 	}
1734 
1735 	// VM discrimination
1736 	AddCapsBool(t, "b_is_in_vm", s->IsInVm);
1737 
1738 	// Support for display name of the network connection for the local bridge
1739 #ifdef	OS_WIN32
1740 	if (IsBridgeSupported() && IsNt() && GetOsInfo()->OsType >= OSTYPE_WINDOWS_2000_PROFESSIONAL)
1741 	{
1742 		AddCapsBool(t, "b_support_network_connection_name", true);
1743 	}
1744 #else	// OS_WIN32
1745 	if (IsBridgeSupported() && EthIsInterfaceDescriptionSupportedUnix())
1746 	{
1747 		AddCapsBool(t, "b_support_network_connection_name", true);
1748 	}
1749 #endif	// OS_WIN32
1750 
1751 	// Support for MAC address filtering
1752 	AddCapsBool(t, "b_support_check_mac", true);
1753 
1754 	// Support for status check of the TCP connection
1755 	AddCapsBool(t, "b_support_check_tcp_state", true);
1756 
1757 	// Can specify multiple server and retry intervals in Radius authentication
1758 	AddCapsBool(t, "b_support_radius_retry_interval_and_several_servers", s->ServerType != SERVER_TYPE_FARM_MEMBER &&
1759 		s->Cedar->Bridge == false);
1760 
1761 	// Can manage the ID of the tagged VLAN in the MAC address table
1762 	AddCapsBool(t, "b_support_vlan", true);
1763 
1764 	// Support for Virtual HUB extended options
1765 	if ((s->Cedar->Bridge == false) &&
1766 		(s->ServerType == SERVER_TYPE_STANDALONE || s->ServerType == SERVER_TYPE_FARM_CONTROLLER))
1767 	{
1768 		AddCapsBool(t, "b_support_hub_ext_options", true);
1769 	}
1770 	else
1771 	{
1772 		AddCapsBool(t, "b_support_hub_ext_options", false);
1773 	}
1774 
1775 	// Support for Security Policy version 3.0
1776 	AddCapsBool(t, "b_support_policy_ver_3", true);
1777 
1778 	// Support for IPv6 access list
1779 	AddCapsBool(t, "b_support_ipv6_acl", true);
1780 
1781 	// Support for setting of delay, jitter and packet loss in the access list
1782 	AddCapsBool(t, "b_support_ex_acl", true);
1783 
1784 	// Support for URL redirection in the access list
1785 	AddCapsBool(t, "b_support_redirect_url_acl", true);
1786 
1787 	// Supports the specification by the group name in the access list
1788 	AddCapsBool(t, "b_support_acl_group", true);
1789 
1790 	// Support for IPv6 in connection source IP restriction list
1791 	AddCapsBool(t, "b_support_ipv6_ac", true);
1792 
1793 	// Support for VLAN tagged packet transmission configuration tool
1794 	AddCapsBool(t, "b_support_eth_vlan", (OS_IS_WINDOWS_NT(GetOsType()) && GET_KETA(GetOsType(), 100) >= 2));
1795 
1796 	// Support for the message display function when the VPN connect to the Virtual HUB
1797 	AddCapsBool(t, "b_support_msg", true);
1798 
1799 	// UDP acceleration feature
1800 	AddCapsBool(t, "b_support_udp_acceleration", true);
1801 
1802 	// Intel AES Acceleration function
1803 	AddCapsBool(t, "b_support_intel_aes", IsIntelAesNiSupported());
1804 
1805 #ifdef	OS_WIN32
1806 	// SeLow driver
1807 	AddCapsBool(t, "b_using_selow_driver", Win32IsUsingSeLow());
1808 #endif	// OS_WIN32
1809 
1810 	// VPN Azure function
1811 	AddCapsBool(t, "b_support_azure", SiIsAzureSupported(s));
1812 
1813 	// VPN3
1814 	AddCapsBool(t, "b_vpn3", true);
1815 
1816 	// VPN4
1817 	AddCapsBool(t, "b_vpn4", true);
1818 
1819 
1820 	UpdateGlobalServerFlags(s, t);
1821 }
1822 
1823 // SYSLOG_SETTING
InRpcSysLogSetting(SYSLOG_SETTING * t,PACK * p)1824 void InRpcSysLogSetting(SYSLOG_SETTING *t, PACK *p)
1825 {
1826 	// Validate arguments
1827 	if (t == NULL || p == NULL)
1828 	{
1829 		return;
1830 	}
1831 
1832 	Zero(t, sizeof(SYSLOG_SETTING));
1833 	t->SaveType = PackGetInt(p, "SaveType");
1834 	t->Port = PackGetInt(p, "Port");
1835 	PackGetStr(p, "Hostname", t->Hostname, sizeof(t->Hostname));
1836 }
OutRpcSysLogSetting(PACK * p,SYSLOG_SETTING * t)1837 void OutRpcSysLogSetting(PACK *p, SYSLOG_SETTING *t)
1838 {
1839 	// Validate arguments
1840 	if (t == NULL || p == NULL)
1841 	{
1842 		return;
1843 	}
1844 
1845 	PackAddInt(p, "SaveType", t->SaveType);
1846 	PackAddInt(p, "Port", t->Port);
1847 	PackAddStr(p, "Hostname", t->Hostname);
1848 }
1849 
1850 // CAPSLIST
InitCapsList(CAPSLIST * t)1851 void InitCapsList(CAPSLIST *t)
1852 {
1853 	// Validate arguments
1854 	if (t == NULL)
1855 	{
1856 		return;
1857 	}
1858 
1859 	Zero(t, sizeof(CAPSLIST));
1860 	t->CapsList = NewListFast(NULL);
1861 }
InRpcCapsList(CAPSLIST * t,PACK * p)1862 void InRpcCapsList(CAPSLIST *t, PACK *p)
1863 {
1864 	UINT i;
1865 	// Validate arguments
1866 	if (t == NULL || p == NULL)
1867 	{
1868 		return;
1869 	}
1870 
1871 	Zero(t, sizeof(CAPSLIST));
1872 	t->CapsList = NewListFast(CompareCaps);
1873 
1874 	for (i = 0;i < LIST_NUM(p->elements);i++)
1875 	{
1876 		ELEMENT *e = LIST_DATA(p->elements, i);
1877 
1878 		if (StartWith(e->name, "caps_") && e->type == VALUE_INT && e->num_value == 1)
1879 		{
1880 			CAPS *c = NewCaps(e->name + 5, e->values[0]->IntValue);
1881 			Insert(t->CapsList, c);
1882 		}
1883 	}
1884 }
OutRpcCapsList(PACK * p,CAPSLIST * t)1885 void OutRpcCapsList(PACK *p, CAPSLIST *t)
1886 {
1887 	UINT i;
1888 	// Validate arguments
1889 	if (t == NULL || p == NULL)
1890 	{
1891 		return;
1892 	}
1893 
1894 	PackSetCurrentJsonGroupName(p, "CapsList");
1895 	for (i = 0;i < LIST_NUM(t->CapsList);i++)
1896 	{
1897 		char tmp[MAX_SIZE];
1898 		char ct_key[MAX_PATH];
1899 		wchar_t ct_description[MAX_PATH];
1900 		wchar_t *w;
1901 		CAPS *c = LIST_DATA(t->CapsList, i);
1902 
1903 		Format(tmp, sizeof(tmp), "caps_%s", c->Name);
1904 
1905 		Format(ct_key, sizeof(ct_key), "CT_%s", c->Name);
1906 
1907 		Zero(ct_description, sizeof(ct_description));
1908 		w = _UU(ct_key);
1909 		if (UniIsEmptyStr(w) == false)
1910 		{
1911 			UniStrCpy(ct_description, sizeof(ct_description), w);
1912 		}
1913 		else
1914 		{
1915 			StrToUni(ct_description, sizeof(ct_description), c->Name);
1916 		}
1917 
1918 		PackAddInt(p, tmp, c->Value);
1919 
1920 		PackAddStrEx(p, "CapsName", c->Name, i, LIST_NUM(t->CapsList));
1921 		PackAddIntEx(p, "CapsValue", c->Value, i, LIST_NUM(t->CapsList));
1922 		PackAddUniStrEx(p, "CapsDescrption", ct_description, i, LIST_NUM(t->CapsList));
1923 	}
1924 	PackSetCurrentJsonGroupName(p, NULL);
1925 }
FreeRpcCapsList(CAPSLIST * t)1926 void FreeRpcCapsList(CAPSLIST *t)
1927 {
1928 	UINT i;
1929 	// Validate arguments
1930 	if (t == NULL)
1931 	{
1932 		return;
1933 	}
1934 
1935 	for (i = 0;i < LIST_NUM(t->CapsList);i++)
1936 	{
1937 		CAPS *c = LIST_DATA(t->CapsList, i);
1938 
1939 		FreeCaps(c);
1940 	}
1941 
1942 	ReleaseList(t->CapsList);
1943 }
1944 
1945 // Add a bool type to Caps list
AddCapsBool(CAPSLIST * caps,char * name,bool b)1946 void AddCapsBool(CAPSLIST *caps, char *name, bool b)
1947 {
1948 	CAPS *c;
1949 	// Validate arguments
1950 	if (caps == NULL || name == NULL)
1951 	{
1952 		return;
1953 	}
1954 
1955 	c = NewCaps(name, b == false ? 0 : 1);
1956 	AddCaps(caps, c);
1957 }
1958 
1959 // Add the int type to Caps list
AddCapsInt(CAPSLIST * caps,char * name,UINT i)1960 void AddCapsInt(CAPSLIST *caps, char *name, UINT i)
1961 {
1962 	CAPS *c;
1963 	// Validate arguments
1964 	if (caps == NULL || name == NULL)
1965 	{
1966 		return;
1967 	}
1968 
1969 	c = NewCaps(name, i);
1970 	AddCaps(caps, c);
1971 }
1972 
1973 // Get the int type from the Caps list
GetCapsInt(CAPSLIST * caps,char * name)1974 UINT GetCapsInt(CAPSLIST *caps, char *name)
1975 {
1976 	CAPS *c;
1977 	// Validate arguments
1978 	if (caps == NULL || name == NULL)
1979 	{
1980 		return 0;
1981 	}
1982 
1983 	c = GetCaps(caps, name);
1984 	if (c == NULL)
1985 	{
1986 		return 0;
1987 	}
1988 
1989 	return c->Value;
1990 }
1991 
1992 // Get bool type from the Caps list
GetCapsBool(CAPSLIST * caps,char * name)1993 bool GetCapsBool(CAPSLIST *caps, char *name)
1994 {
1995 	CAPS *c;
1996 	// Validate arguments
1997 	if (caps == NULL || name == NULL)
1998 	{
1999 		return false;
2000 	}
2001 
2002 	c = GetCaps(caps, name);
2003 	if (c == NULL)
2004 	{
2005 		return false;
2006 	}
2007 
2008 	return c->Value == 0 ? false : true;
2009 }
2010 
2011 // Release the Caps list
FreeCapsList(CAPSLIST * caps)2012 void FreeCapsList(CAPSLIST *caps)
2013 {
2014 	UINT i;
2015 	// Validate arguments
2016 	if (caps == NULL)
2017 	{
2018 		return;
2019 	}
2020 
2021 	for (i = 0;i < LIST_NUM(caps->CapsList);i++)
2022 	{
2023 		CAPS *c = LIST_DATA(caps->CapsList, i);
2024 
2025 		FreeCaps(c);
2026 	}
2027 
2028 	ReleaseList(caps->CapsList);
2029 	Free(caps);
2030 }
2031 
2032 // Get the Caps
GetCaps(CAPSLIST * caps,char * name)2033 CAPS *GetCaps(CAPSLIST *caps, char *name)
2034 {
2035 	UINT i;
2036 	// Validate arguments
2037 	if (caps == NULL || name == NULL)
2038 	{
2039 		return NULL;
2040 	}
2041 
2042 	for (i = 0;i < LIST_NUM(caps->CapsList);i++)
2043 	{
2044 		CAPS *c = LIST_DATA(caps->CapsList, i);
2045 
2046 		if (StrCmpi(c->Name, name) == 0)
2047 		{
2048 			return c;
2049 		}
2050 	}
2051 
2052 	return NULL;
2053 }
2054 
2055 // Add to the Caps
AddCaps(CAPSLIST * caps,CAPS * c)2056 void AddCaps(CAPSLIST *caps, CAPS *c)
2057 {
2058 	// Validate arguments
2059 	if (caps == NULL || c == NULL)
2060 	{
2061 		return;
2062 	}
2063 
2064 	Insert(caps->CapsList, c);
2065 }
2066 
2067 // Comparison of Caps
CompareCaps(void * p1,void * p2)2068 int CompareCaps(void *p1, void *p2)
2069 {
2070 	CAPS *c1, *c2;
2071 	if (p1 == NULL || p2 == NULL)
2072 	{
2073 		return 0;
2074 	}
2075 	c1 = *(CAPS **)p1;
2076 	c2 = *(CAPS **)p2;
2077 	if (c1 == NULL || c2 == NULL)
2078 	{
2079 		return 0;
2080 	}
2081 
2082 	return StrCmpi(c1->Name, c2->Name);
2083 }
2084 
2085 // Create a Caps list
NewCapsList()2086 CAPSLIST *NewCapsList()
2087 {
2088 	CAPSLIST *caps = ZeroMalloc(sizeof(CAPSLIST));
2089 
2090 	caps->CapsList = NewListFast(CompareCaps);
2091 
2092 	return caps;
2093 }
2094 
2095 // Release the Caps
FreeCaps(CAPS * c)2096 void FreeCaps(CAPS *c)
2097 {
2098 	// Validate arguments
2099 	if (c == NULL)
2100 	{
2101 		return;
2102 	}
2103 
2104 	Free(c->Name);
2105 	Free(c);
2106 }
2107 
2108 // Create a Caps
NewCaps(char * name,UINT value)2109 CAPS *NewCaps(char *name, UINT value)
2110 {
2111 	CAPS *c;
2112 	// Validate arguments
2113 	if (name == NULL)
2114 	{
2115 		return NULL;
2116 	}
2117 
2118 	c = ZeroMalloc(sizeof(CAPS));
2119 	c->Name = CopyStr(name);
2120 	c->Value = value;
2121 
2122 	return c;
2123 }
2124 
2125 // Calculate the score from the current number of connections and weight
SiCalcPoint(SERVER * s,UINT num,UINT weight)2126 UINT SiCalcPoint(SERVER *s, UINT num, UINT weight)
2127 {
2128 	UINT server_max_sessions = SERVER_MAX_SESSIONS;
2129 	if (s == NULL)
2130 	{
2131 		return 0;
2132 	}
2133 	if (weight == 0)
2134 	{
2135 		weight = 100;
2136 	}
2137 
2138 	server_max_sessions = GetServerCapsInt(s, "i_max_sessions");
2139 
2140 	if (server_max_sessions == 0)
2141 	{
2142 		// Avoid divide by zero
2143 		server_max_sessions = 1;
2144 	}
2145 
2146 	return (UINT)(((double)server_max_sessions -
2147 		MIN((double)num * 100.0 / (double)weight, (double)server_max_sessions))
2148 		* (double)FARM_BASE_POINT / (double)server_max_sessions);
2149 }
2150 
2151 // Get the server score
SiGetPoint(SERVER * s)2152 UINT SiGetPoint(SERVER *s)
2153 {
2154 	UINT num_session;
2155 	// Validate arguments
2156 	if (s == NULL)
2157 	{
2158 		return 0;
2159 	}
2160 
2161 	num_session = Count(s->Cedar->CurrentSessions);
2162 
2163 	return SiCalcPoint(s, num_session, s->Weight);
2164 }
2165 
2166 // Generate the default certificate
SiGenerateDefaultCert(X ** server_x,K ** server_k)2167 void SiGenerateDefaultCert(X **server_x, K **server_k)
2168 {
2169 	SiGenerateDefaultCertEx(server_x, server_k, NULL);
2170 }
SiGenerateDefaultCertEx(X ** server_x,K ** server_k,char * common_name)2171 void SiGenerateDefaultCertEx(X **server_x, K **server_k, char *common_name)
2172 {
2173 	X *x;
2174 	K *private_key, *public_key;
2175 	NAME *name;
2176 	char tmp[MAX_SIZE];
2177 	wchar_t cn[MAX_SIZE];
2178 	// Validate arguments
2179 	if (server_x == NULL || server_k == NULL)
2180 	{
2181 		return;
2182 	}
2183 
2184 	// Create a key pair
2185 	RsaGen(&private_key, &public_key, 2048);
2186 
2187 	if (IsEmptyStr(common_name))
2188 	{
2189 		// Get the host name
2190 		StrCpy(tmp, sizeof(tmp), "server.softether.vpn");
2191 		GetMachineName(tmp, sizeof(tmp));
2192 		StrToUni(cn, sizeof(cn), tmp);
2193 	}
2194 	else
2195 	{
2196 		StrToUni(cn, sizeof(cn), common_name);
2197 	}
2198 
2199 	name = NewName(cn, cn, cn,
2200 		L"US", NULL, NULL);
2201 	x = NewRootX(public_key, private_key, name, GetDaysUntil2038Ex(), NULL);
2202 
2203 	*server_x = x;
2204 	*server_k = private_key;
2205 
2206 	FreeName(name);
2207 
2208 	FreeK(public_key);
2209 }
2210 
2211 // Set the server certificate to default
SiInitDefaultServerCert(SERVER * s)2212 void SiInitDefaultServerCert(SERVER *s)
2213 {
2214 	X *x = NULL;
2215 	K *k = NULL;
2216 	// Validate arguments
2217 	if (s == NULL)
2218 	{
2219 		return;
2220 	}
2221 
2222 	// Generate a server certificate and private key
2223 	SiGenerateDefaultCert(&x, &k);
2224 
2225 	// Configure
2226 	SetCedarCert(s->Cedar, x, k);
2227 
2228 	FreeX(x);
2229 	FreeK(k);
2230 }
2231 
2232 // Set the encryption algorithm name to default
SiInitCipherName(SERVER * s)2233 void SiInitCipherName(SERVER *s)
2234 {
2235 	// Validate arguments
2236 	if (s == NULL)
2237 	{
2238 		return;
2239 	}
2240 
2241 	SetCedarCipherList(s->Cedar, SERVER_DEFAULT_CIPHER_NAME);
2242 }
2243 
2244 // Initialize the listener list
SiInitListenerList(SERVER * s)2245 void SiInitListenerList(SERVER *s)
2246 {
2247 	// Validate arguments
2248 	if (s == NULL)
2249 	{
2250 		return;
2251 	}
2252 
2253 	SiLockListenerList(s);
2254 	{
2255 		{
2256 			// Register the 4 ports (443, 992, 1194, 8888) as the default port
2257 			SiAddListener(s, SERVER_DEF_PORTS_1, true);
2258 			SiAddListener(s, SERVER_DEF_PORTS_2, true);
2259 			SiAddListener(s, SERVER_DEF_PORTS_3, true);
2260 			SiAddListener(s, SERVER_DEF_PORTS_4, true);
2261 		}
2262 	}
2263 	SiUnlockListenerList(s);
2264 }
2265 
2266 // Remove the listener
SiDeleteListener(SERVER * s,UINT port)2267 bool SiDeleteListener(SERVER *s, UINT port)
2268 {
2269 	SERVER_LISTENER *e;
2270 	// Validate arguments
2271 	if (s == NULL || port == 0)
2272 	{
2273 		return false;
2274 	}
2275 
2276 	e = SiGetListener(s, port);
2277 	if (e == NULL)
2278 	{
2279 		return false;
2280 	}
2281 
2282 	// Stop if still alive
2283 	SiDisableListener(s, port);
2284 
2285 	if (e->Listener != NULL)
2286 	{
2287 		ReleaseListener(e->Listener);
2288 	}
2289 
2290 	Delete(s->ServerListenerList, e);
2291 	Free(e);
2292 
2293 	return true;
2294 }
2295 
2296 // Compare the SERVER_LISTENER
CompareServerListener(void * p1,void * p2)2297 int CompareServerListener(void *p1, void *p2)
2298 {
2299 	SERVER_LISTENER *s1, *s2;
2300 	if (p1 == NULL || p2 == NULL)
2301 	{
2302 		return 0;
2303 	}
2304 	s1 = *(SERVER_LISTENER **)p1;
2305 	s2 = *(SERVER_LISTENER **)p2;
2306 	if (s1 == NULL || s2 == NULL)
2307 	{
2308 		return 0;
2309 	}
2310 
2311 	if (s1->Port > s2->Port)
2312 	{
2313 		return 1;
2314 	}
2315 	else if (s1->Port < s2->Port)
2316 	{
2317 		return -1;
2318 	}
2319 	else
2320 	{
2321 		return 0;
2322 	}
2323 }
2324 
2325 // Stop the listener
SiDisableListener(SERVER * s,UINT port)2326 bool SiDisableListener(SERVER *s, UINT port)
2327 {
2328 	SERVER_LISTENER *e;
2329 	// Validate arguments
2330 	if (s == NULL || port == 0)
2331 	{
2332 		return false;
2333 	}
2334 
2335 	// Get the listener
2336 	e = SiGetListener(s, port);
2337 	if (e == NULL)
2338 	{
2339 		return false;
2340 	}
2341 
2342 	if (e->Enabled == false || e->Listener == NULL)
2343 	{
2344 		// Already stopped
2345 		return true;
2346 	}
2347 
2348 	// Stop the listener
2349 	StopListener(e->Listener);
2350 
2351 	// Release the listener
2352 	ReleaseListener(e->Listener);
2353 	e->Listener = NULL;
2354 
2355 	e->Enabled = false;
2356 
2357 	return true;
2358 }
2359 
2360 // Start the listener
SiEnableListener(SERVER * s,UINT port)2361 bool SiEnableListener(SERVER *s, UINT port)
2362 {
2363 	SERVER_LISTENER *e;
2364 	// Validate arguments
2365 	if (s == NULL || port == 0)
2366 	{
2367 		return false;
2368 	}
2369 
2370 	// Get the listener
2371 	e = SiGetListener(s, port);
2372 	if (e == NULL)
2373 	{
2374 		return false;
2375 	}
2376 
2377 	if (e->Enabled)
2378 	{
2379 		// It has already started
2380 		return true;
2381 	}
2382 
2383 	// Create a listener
2384 	e->Listener = NewListener(s->Cedar, LISTENER_TCP, e->Port);
2385 	if (e->Listener == NULL)
2386 	{
2387 		// Failure
2388 		return false;
2389 	}
2390 
2391 	e->Listener->DisableDos = e->DisableDos;
2392 
2393 	e->Enabled = true;
2394 
2395 	return true;
2396 }
2397 
2398 // Get the listener
SiGetListener(SERVER * s,UINT port)2399 SERVER_LISTENER *SiGetListener(SERVER *s, UINT port)
2400 {
2401 	UINT i;
2402 	// Validate arguments
2403 	if (s == NULL || port == 0)
2404 	{
2405 		return NULL;
2406 	}
2407 
2408 	for (i = 0;i < LIST_NUM(s->ServerListenerList);i++)
2409 	{
2410 		SERVER_LISTENER *e = LIST_DATA(s->ServerListenerList, i);
2411 		if (e->Port == port)
2412 		{
2413 			return e;
2414 		}
2415 	}
2416 
2417 	return NULL;
2418 }
2419 
2420 // Add a listener
SiAddListener(SERVER * s,UINT port,bool enabled)2421 bool SiAddListener(SERVER *s, UINT port, bool enabled)
2422 {
2423 	return SiAddListenerEx(s, port, enabled, false);
2424 }
SiAddListenerEx(SERVER * s,UINT port,bool enabled,bool disable_dos)2425 bool SiAddListenerEx(SERVER *s, UINT port, bool enabled, bool disable_dos)
2426 {
2427 	SERVER_LISTENER *e;
2428 	UINT i;
2429 	// Validate arguments
2430 	if (s == NULL || port == 0)
2431 	{
2432 		return false;
2433 	}
2434 
2435 	// Check whether the listener exists already
2436 	for (i = 0;i < LIST_NUM(s->ServerListenerList);i++)
2437 	{
2438 		e = LIST_DATA(s->ServerListenerList, i);
2439 		if (e->Port == port)
2440 		{
2441 			// Already exist
2442 			return false;
2443 		}
2444 	}
2445 
2446 	// Register by initializing a new listener
2447 	e = ZeroMalloc(sizeof(SERVER_LISTENER));
2448 	e->Enabled = enabled;
2449 	e->Port = port;
2450 	e->DisableDos = disable_dos;
2451 
2452 	if (e->Enabled)
2453 	{
2454 		// Create a listener
2455 		e->Listener = NewListener(s->Cedar, LISTENER_TCP, e->Port);
2456 		if (e->Listener != NULL)
2457 		{
2458 			e->Listener->DisableDos = e->DisableDos;
2459 		}
2460 	}
2461 
2462 	Insert(s->ServerListenerList, e);
2463 
2464 	return true;
2465 }
2466 
2467 // Lock the listener list
SiLockListenerList(SERVER * s)2468 void SiLockListenerList(SERVER *s)
2469 {
2470 	// Validate arguments
2471 	if (s == NULL)
2472 	{
2473 		return;
2474 	}
2475 
2476 	LockList(s->ServerListenerList);
2477 }
2478 
2479 // Unlock the listener list
SiUnlockListenerList(SERVER * s)2480 void SiUnlockListenerList(SERVER *s)
2481 {
2482 	// Validate arguments
2483 	if (s == NULL)
2484 	{
2485 		return;
2486 	}
2487 
2488 	UnlockList(s->ServerListenerList);
2489 }
2490 
2491 // Initialize the Bridge
SiInitBridge(SERVER * s)2492 void SiInitBridge(SERVER *s)
2493 {
2494 	HUB *h;
2495 	HUB_OPTION o;
2496 	HUB_LOG g;
2497 	// Validate arguments
2498 	if (s == NULL)
2499 	{
2500 		return;
2501 	}
2502 
2503 	Zero(&o, sizeof(o));
2504 	o.MaxSession = 0;
2505 
2506 	h = NewHub(s->Cedar, SERVER_DEFAULT_BRIDGE_NAME, &o);
2507 	AddHub(s->Cedar, h);
2508 
2509 	h->Offline = true;
2510 	SetHubOnline(h);
2511 
2512 	// Log settings
2513 	SiSetDefaultLogSetting(&g);
2514 	SetHubLogSetting(h, &g);
2515 
2516 	ReleaseHub(h);
2517 }
2518 
2519 // Set the default value of the Virtual HUB options
SiSetDefaultHubOption(HUB_OPTION * o)2520 void SiSetDefaultHubOption(HUB_OPTION *o)
2521 {
2522 	// Validate arguments
2523 	if (o == NULL)
2524 	{
2525 		return;
2526 	}
2527 
2528 	o->MaxSession = 0;
2529 	o->VlanTypeId = MAC_PROTO_TAGVLAN;
2530 	o->NoIPv6DefaultRouterInRAWhenIPv6 = true;
2531 	o->ManageOnlyPrivateIP = true;
2532 	o->ManageOnlyLocalUnicastIPv6 = true;
2533 	o->NoMacAddressLog = true;
2534 	o->NoDhcpPacketLogOutsideHub = true;
2535 	o->AccessListIncludeFileCacheLifetime = ACCESS_LIST_INCLUDE_FILE_CACHE_LIFETIME;
2536 	o->RemoveDefGwOnDhcpForLocalhost = true;
2537 	o->FloodingSendQueueBufferQuota = DEFAULT_FLOODING_QUEUE_LENGTH;
2538 }
2539 
2540 // Create a default virtual HUB
SiInitDefaultHubList(SERVER * s)2541 void SiInitDefaultHubList(SERVER *s)
2542 {
2543 	HUB *h;
2544 	HUB_OPTION o;
2545 	HUB_LOG g;
2546 	// Validate arguments
2547 	if (s == NULL)
2548 	{
2549 		return;
2550 	}
2551 
2552 	Zero(&o, sizeof(o));
2553 
2554 	// Configure a default Virtual HUB management options
2555 	SiSetDefaultHubOption(&o);
2556 
2557 	h = NewHub(s->Cedar, s->Cedar->Bridge == false ? SERVER_DEFAULT_HUB_NAME : SERVER_DEFAULT_BRIDGE_NAME, &o);
2558 	h->CreatedTime = SystemTime64();
2559 	AddHub(s->Cedar, h);
2560 
2561 	if (s->Cedar->Bridge)
2562 	{
2563 		// Randomize the password
2564 		Rand(h->HashedPassword, sizeof(h->HashedPassword));
2565 		Rand(h->SecurePassword, sizeof(h->SecurePassword));
2566 	}
2567 
2568 	h->Offline = true;
2569 	SetHubOnline(h);
2570 
2571 	// Log settings
2572 	SiSetDefaultLogSetting(&g);
2573 	SetHubLogSetting(h, &g);
2574 
2575 	ReleaseHub(h);
2576 }
2577 
2578 // Set the log settings to default
SiSetDefaultLogSetting(HUB_LOG * g)2579 void SiSetDefaultLogSetting(HUB_LOG *g)
2580 {
2581 	// Validate arguments
2582 	if (g == NULL)
2583 	{
2584 		return;
2585 	}
2586 
2587 	Zero(g, sizeof(HUB_LOG));
2588 	g->SaveSecurityLog = true;
2589 	g->SecurityLogSwitchType = LOG_SWITCH_DAY;
2590 	g->SavePacketLog = true;
2591 	g->PacketLogSwitchType = LOG_SWITCH_DAY;
2592 	g->PacketLogConfig[PACKET_LOG_TCP_CONN] =
2593 		g->PacketLogConfig[PACKET_LOG_DHCP] = PACKET_LOG_HEADER;
2594 }
2595 
2596 // Test
SiTest(SERVER * s)2597 void SiTest(SERVER *s)
2598 {
2599 }
2600 
2601 // Set the initial configuration
SiLoadInitialConfiguration(SERVER * s)2602 void SiLoadInitialConfiguration(SERVER *s)
2603 {
2604 	RPC_KEEP k;
2605 	// Validate arguments
2606 	if (s == NULL)
2607 	{
2608 		return;
2609 	}
2610 
2611 	// Default to TLS only; mitigates CVE-2016-0800
2612 	s->Cedar->SslAcceptSettings.AcceptOnlyTls = true;
2613 
2614 	// Auto saving interval related
2615 	s->AutoSaveConfigSpan = SERVER_FILE_SAVE_INTERVAL_DEFAULT;
2616 	s->BackupConfigOnlyWhenModified = true;
2617 
2618 	s->Weight = FARM_DEFAULT_WEIGHT;
2619 
2620 	SiLoadGlobalParamsCfg(NULL);
2621 
2622 	// KEEP related
2623 	Zero(&k, sizeof(k));
2624 
2625 	{
2626 		k.UseKeepConnect = true;
2627 	}
2628 	k.KeepConnectPort = 80;
2629 	StrCpy(k.KeepConnectHost, sizeof(k.KeepConnectHost), CLIENT_DEFAULT_KEEPALIVE_HOST);
2630 	k.KeepConnectInterval = KEEP_INTERVAL_DEFAULT * 1000;
2631 	k.KeepConnectProtocol = CONNECTION_UDP;
2632 
2633 	Lock(s->Keep->lock);
2634 	{
2635 		KEEP *keep = s->Keep;
2636 		keep->Enable = k.UseKeepConnect;
2637 		keep->Server = true;
2638 		StrCpy(keep->ServerName, sizeof(keep->ServerName), k.KeepConnectHost);
2639 		keep->ServerPort = k.KeepConnectPort;
2640 		keep->UdpMode = k.KeepConnectProtocol;
2641 		keep->Interval = k.KeepConnectInterval;
2642 	}
2643 	Unlock(s->Keep->lock);
2644 
2645 	// Initialize the password
2646 	{
2647 		Hash(s->HashedPassword, "", 0, true);
2648 	}
2649 
2650 	// Set the encryption algorithm name to default
2651 	SiInitCipherName(s);
2652 
2653 	// Set the server certificate to default
2654 	SiInitDefaultServerCert(s);
2655 
2656 	// Create a default HUB
2657 	{
2658 		SiInitDefaultHubList(s);
2659 	}
2660 
2661 	if (s->Cedar->Bridge == false)
2662 	{
2663 		// Create a DDNS client
2664 		s->DDnsClient = NewDDNSClient(s->Cedar, NULL, NULL);
2665 	}
2666 
2667 
2668 	// Set the listener list to default setting
2669 	SiInitListenerList(s);
2670 
2671 	if (s->Cedar->Bridge)
2672 	{
2673 		// SSTP, OpenVPN, and NAT traversal function can not be used in the bridge environment
2674 		s->DisableNatTraversal = true;
2675 		s->DisableSSTPServer = true;
2676 		s->DisableOpenVPNServer = true;
2677 	}
2678 	else
2679 	{
2680 		// Enable the SSTP and OpenVPN for default setting
2681 		OPENVPN_SSTP_CONFIG c;
2682 
2683 		Zero(&c, sizeof(c));
2684 		c.EnableOpenVPN = true;
2685 		c.EnableSSTP = true;
2686 
2687 		{
2688 			ToStr(c.OpenVPNPortList, OPENVPN_UDP_PORT);
2689 		}
2690 
2691 		SiSetOpenVPNAndSSTPConfig(s, &c);
2692 
2693 		{
2694 			// Enable VPN-over-ICMP" and VPN-over-DNS for default setting
2695 			s->EnableVpnOverIcmp = false;
2696 			s->EnableVpnOverDns = false;
2697 		}
2698 	}
2699 
2700 	s->Eraser = NewEraser(s->Logger, 0);
2701 }
2702 
2703 // Check whether the ports required for VPN-over-ICMP can be opened
SiCanOpenVpnOverIcmpPort()2704 bool SiCanOpenVpnOverIcmpPort()
2705 {
2706 	// Whether the ICMP can be opened
2707 	SOCK *s = NewUDP(MAKE_SPECIAL_PORT(IP_PROTO_ICMPV4));
2708 
2709 	if (s == NULL)
2710 	{
2711 		// Failure
2712 		return false;
2713 	}
2714 
2715 	Disconnect(s);
2716 	ReleaseSock(s);
2717 
2718 	return true;
2719 }
2720 
2721 // Check whether the ports required for VPN-over-DNS can be opened
SiCanOpenVpnOverDnsPort()2722 bool SiCanOpenVpnOverDnsPort()
2723 {
2724 	// Whether UDP Port 53 can be listen on
2725 	SOCK *s = NewUDP(53);
2726 
2727 	if (s == NULL)
2728 	{
2729 		// Listening failure
2730 		return false;
2731 	}
2732 
2733 	Disconnect(s);
2734 	ReleaseSock(s);
2735 
2736 	return true;
2737 }
2738 
2739 // Read the configuration file (main)
SiLoadConfigurationFileMain(SERVER * s,FOLDER * root)2740 bool SiLoadConfigurationFileMain(SERVER *s, FOLDER *root)
2741 {
2742 	// Validate arguments
2743 	if (s == NULL || root == NULL)
2744 	{
2745 		return false;
2746 	}
2747 
2748 	return SiLoadConfigurationCfg(s, root);
2749 }
2750 
2751 // Read the configuration file
SiLoadConfigurationFile(SERVER * s)2752 bool SiLoadConfigurationFile(SERVER *s)
2753 {
2754 	// Validate arguments
2755 	bool ret = false;
2756 	FOLDER *root;
2757 	char *server_config_filename = SERVER_CONFIG_FILE_NAME;
2758 	if (s == NULL)
2759 	{
2760 		return false;
2761 	}
2762 
2763 
2764 	s->CfgRw = NewCfgRwEx2A(&root,
2765 		s->Cedar->Bridge == false ? server_config_filename : BRIDGE_CONFIG_FILE_NAME, false,
2766 		s->Cedar->Bridge == false ? SERVER_CONFIG_TEMPLATE_NAME : BRIDGE_CONFIG_TEMPLATE_NAME);
2767 
2768 	if (server_reset_setting)
2769 	{
2770 		CfgDeleteFolder(root);
2771 		root = NULL;
2772 		server_reset_setting = false;
2773 	}
2774 
2775 	if (root == NULL)
2776 	{
2777 		return false;
2778 	}
2779 
2780 	ret = SiLoadConfigurationFileMain(s, root);
2781 
2782 	CfgDeleteFolder(root);
2783 
2784 	return ret;
2785 }
2786 
2787 // Initialize the configuration
SiInitConfiguration(SERVER * s)2788 void SiInitConfiguration(SERVER *s)
2789 {
2790 	// Validate arguments
2791 	if (s == NULL)
2792 	{
2793 		return;
2794 	}
2795 
2796 	s->AutoSaveConfigSpan = SERVER_FILE_SAVE_INTERVAL_DEFAULT;
2797 	s->BackupConfigOnlyWhenModified = true;
2798 
2799 	// IPsec server
2800 	if (s->Cedar->Bridge == false)
2801 	{
2802 		s->IPsecServer = NewIPsecServer(s->Cedar);
2803 	}
2804 
2805 	// OpenVPN server (UDP)
2806 	if (s->Cedar->Bridge == false)
2807 	{
2808 		s->OpenVpnServerUdp = NewOpenVpnServerUdp(s->Cedar);
2809 	}
2810 
2811 	SLog(s->Cedar, "LS_LOAD_CONFIG_1");
2812 	if (SiLoadConfigurationFile(s) == false)
2813 	{
2814 		// Ethernet initialization
2815 		InitEth();
2816 
2817 		SLog(s->Cedar, "LS_LOAD_CONFIG_3");
2818 		SiLoadInitialConfiguration(s);
2819 
2820 		SetFifoCurrentReallocMemSize(MEM_FIFO_REALLOC_MEM_SIZE);
2821 
2822 		server_reset_setting = false;
2823 	}
2824 	else
2825 	{
2826 		SLog(s->Cedar, "LS_LOAD_CONFIG_2");
2827 	}
2828 
2829 	s->CfgRw->DontBackup = s->DontBackupConfig;
2830 
2831 	// The arp_filter in Linux
2832 	if (GetOsInfo()->OsType == OSTYPE_LINUX)
2833 	{
2834 		if (s->NoLinuxArpFilter == false)
2835 		{
2836 			SetLinuxArpFilter();
2837 		}
2838 	}
2839 
2840 	if (s->DisableDosProction)
2841 	{
2842 		DisableDosProtect();
2843 	}
2844 	else
2845 	{
2846 		EnableDosProtect();
2847 	}
2848 
2849 	s->AutoSaveConfigSpanSaved = s->AutoSaveConfigSpan;
2850 
2851 	// Create a VPN Azure client
2852 	if (s->DDnsClient != NULL && s->Cedar->Bridge == false && s->ServerType == SERVER_TYPE_STANDALONE)
2853 	{
2854 		s->AzureClient = NewAzureClient(s->Cedar, s);
2855 
2856 		AcSetEnable(s->AzureClient, s->EnableVpnAzure);
2857 	}
2858 
2859 	// Reduce the storage interval in the case of user mode
2860 #ifdef	OS_WIN32
2861 	if (MsIsUserMode())
2862 	{
2863 		s->AutoSaveConfigSpan = MIN(s->AutoSaveConfigSpan, SERVER_FILE_SAVE_INTERVAL_USERMODE);
2864 	}
2865 #endif	//OS_WIN32
2866 
2867 	// Create a saving thread
2868 	SLog(s->Cedar, "LS_INIT_SAVE_THREAD", s->AutoSaveConfigSpan / 1000);
2869 	s->SaveHaltEvent = NewEvent();
2870 	s->SaveThread = NewThread(SiSaverThread, s);
2871 }
2872 
2873 // Set the state of Enabled / Disabled of Azure Client
SiSetAzureEnable(SERVER * s,bool enabled)2874 void SiSetAzureEnable(SERVER *s, bool enabled)
2875 {
2876 	// Validate arguments
2877 	if (s == NULL)
2878 	{
2879 		return;
2880 	}
2881 
2882 	if (s->AzureClient != NULL)
2883 	{
2884 		AcSetEnable(s->AzureClient, enabled);
2885 	}
2886 
2887 	s->EnableVpnAzure = enabled;
2888 }
2889 
2890 // Get the state of Enabled / Disabled of Azure Client
SiGetAzureEnable(SERVER * s)2891 bool SiGetAzureEnable(SERVER *s)
2892 {
2893 	// Validate arguments
2894 	if (s == NULL)
2895 	{
2896 		return false;
2897 	}
2898 
2899 	if (s->AzureClient != NULL)
2900 	{
2901 		return AcGetEnable(s->AzureClient);
2902 	}
2903 	else
2904 	{
2905 		return false;
2906 	}
2907 }
2908 
2909 // Apply the Config to the Azure Client
SiApplyAzureConfig(SERVER * s,DDNS_CLIENT_STATUS * ddns_status)2910 void SiApplyAzureConfig(SERVER *s, DDNS_CLIENT_STATUS *ddns_status)
2911 {
2912 	// Validate arguments
2913 	if (s == NULL)
2914 	{
2915 		return;
2916 	}
2917 
2918 	AcApplyCurrentConfig(s->AzureClient, ddns_status);
2919 }
2920 
2921 // Get whether the Azure Client is enabled
SiIsAzureEnabled(SERVER * s)2922 bool SiIsAzureEnabled(SERVER *s)
2923 {
2924 	// Validate arguments
2925 	if (s == NULL)
2926 	{
2927 		return false;
2928 	}
2929 
2930 	if (s->AzureClient == NULL)
2931 	{
2932 		return false;
2933 	}
2934 
2935 	return s->EnableVpnAzure;
2936 }
2937 
2938 // Get whether the Azure Client is supported
SiIsAzureSupported(SERVER * s)2939 bool SiIsAzureSupported(SERVER *s)
2940 {
2941 	// Validate arguments
2942 	if (s == NULL)
2943 	{
2944 		return false;
2945 	}
2946 
2947 	if (s->AzureClient == NULL)
2948 	{
2949 		return false;
2950 	}
2951 
2952 	return true;
2953 }
2954 
2955 // Read the server settings from the CFG
SiLoadConfigurationCfg(SERVER * s,FOLDER * root)2956 bool SiLoadConfigurationCfg(SERVER *s, FOLDER *root)
2957 {
2958 	FOLDER *f1, *f2, *f3, *f4, *f5, *f6, *f7, *f8, *f;
2959 	bool is_vgs_enabled = false;
2960 	// Validate arguments
2961 	if (s == NULL || root == NULL)
2962 	{
2963 		return false;
2964 	}
2965 
2966 	f = NULL;
2967 
2968 
2969 	f1 = CfgGetFolder(root, "ServerConfiguration");
2970 	f2 = CfgGetFolder(root, "VirtualHUB");
2971 	f3 = CfgGetFolder(root, "ListenerList");
2972 	f4 = CfgGetFolder(root, "LocalBridgeList");
2973 	f5 = CfgGetFolder(root, "VirtualLayer3SwitchList");
2974 	f6 = CfgGetFolder(root, "LicenseManager");
2975 	f7 = CfgGetFolder(root, "IPsec");
2976 	f8 = CfgGetFolder(root, "DDnsClient");
2977 
2978 	if (f1 == NULL)
2979 	{
2980 		SLog(s->Cedar, "LS_BAD_CONFIG");
2981 		return false;
2982 	}
2983 
2984 #ifdef	OS_WIN32
2985 	if (f4 != NULL)
2986 	{
2987 		// Read the flag of using the SeLow driver
2988 		bool b = true;
2989 
2990 		if (CfgIsItem(f4, "EnableSoftEtherKernelModeDriver"))
2991 		{
2992 			b = CfgGetBool(f4, "EnableSoftEtherKernelModeDriver");
2993 		}
2994 
2995 		Win32SetEnableSeLow(b);
2996 	}
2997 #endif	// OS_WIN32
2998 
2999 	// Ethernet initialization
3000 	InitEth();
3001 
3002 	s->ConfigRevision = CfgGetInt(root, "ConfigRevision");
3003 
3004 	if (s->Cedar->Bridge == false && f6 != NULL)
3005 	{
3006 		if (GetServerCapsBool(s, "b_support_license"))
3007 		{
3008 			SiLoadLicenseManager(s, f6);
3009 		}
3010 	}
3011 
3012 	DestroyServerCapsCache(s);
3013 
3014 	SiLoadServerCfg(s, f1);
3015 
3016 	if (s->ServerType != SERVER_TYPE_FARM_MEMBER)
3017 	{
3018 		SiLoadHubs(s, f2);
3019 	}
3020 
3021 	SiLoadListeners(s, f3);
3022 
3023 	if (f4 != NULL)
3024 	{
3025 		SiLoadLocalBridges(s, f4);
3026 	}
3027 
3028 	if (s->Cedar->Bridge == false && f5 != NULL)
3029 	{
3030 		SiLoadL3Switchs(s, f5);
3031 	}
3032 
3033 	if (f7 != NULL && GetServerCapsBool(s, "b_support_ipsec"))
3034 	{
3035 		SiLoadIPsec(s, f7);
3036 	}
3037 
3038 	if (s->Cedar->Bridge == false)
3039 	{
3040 		if (f8 == NULL)
3041 		{
3042 			// Create a DDNS client with a new key
3043 			s->DDnsClient = NewDDNSClient(s->Cedar, NULL, NULL);
3044 		}
3045 		else
3046 		{
3047 			// Create by reading the setting of the DDNS client
3048 			UCHAR key[SHA1_SIZE];
3049 			if (CfgGetBool(f8, "Disabled"))
3050 			{
3051 				// Disabled
3052 			}
3053 			else
3054 			{
3055 				char machine_name[MAX_SIZE];
3056 				char machine_name2[MAX_SIZE];
3057 				INTERNET_SETTING t;
3058 				BUF *pw;
3059 
3060 				// Proxy Setting
3061 				Zero(&t, sizeof(t));
3062 				t.ProxyType = CfgGetInt(f8, "ProxyType");
3063 				CfgGetStr(f8, "ProxyHostName", t.ProxyHostName, sizeof(t.ProxyHostName));
3064 				t.ProxyPort = CfgGetInt(f8, "ProxyPort");
3065 				CfgGetStr(f8, "ProxyUsername", t.ProxyUsername, sizeof(t.ProxyUsername));
3066 				pw = CfgGetBuf(f8, "ProxyPassword");
3067 				if (pw != NULL)
3068 				{
3069 					char *pw_str = DecryptPassword(pw);
3070 					StrCpy(t.ProxyPassword, sizeof(t.ProxyPassword), pw_str);
3071 
3072 					Free(pw_str);
3073 					FreeBuf(pw);
3074 				}
3075 
3076 				GetMachineHostName(machine_name, sizeof(machine_name));
3077 
3078 				CfgGetStr(f8, "LocalHostname", machine_name2, sizeof(machine_name2));
3079 
3080 				if (CfgGetByte(f8, "Key", key, sizeof(key)) != sizeof(key) || StrCmpi(machine_name, machine_name2) != 0)
3081 				{
3082 					// Create a DDNS client with a new key
3083 					s->DDnsClient = NewDDNSClient(s->Cedar, NULL, &t);
3084 				}
3085 				else
3086 				{
3087 					// Create the DDNS client with stored key
3088 					s->DDnsClient = NewDDNSClient(s->Cedar, key, &t);
3089 				}
3090 			}
3091 		}
3092 	}
3093 
3094 
3095 	{
3096 		HUB *h = NULL;
3097 
3098 		// Remove the virtual HUB "VPNGATE" when VGS disabled
3099 		LockHubList(s->Cedar);
3100 		{
3101 			h = GetHub(s->Cedar, VG_HUBNAME);
3102 		}
3103 		UnlockHubList(s->Cedar);
3104 
3105 		if (h != NULL)
3106 		{
3107 			StopHub(h);
3108 			DelHub(s->Cedar, h);
3109 			ReleaseHub(h);
3110 		}
3111 	}
3112 
3113 	s->IPsecMessageDisplayed = CfgGetBool(root, "IPsecMessageDisplayed");
3114 
3115 
3116 	return true;
3117 }
3118 
3119 // Write the listener configuration
SiWriteListenerCfg(FOLDER * f,SERVER_LISTENER * r)3120 void SiWriteListenerCfg(FOLDER *f, SERVER_LISTENER *r)
3121 {
3122 	// Validate arguments
3123 	if (f == NULL || r == NULL)
3124 	{
3125 		return;
3126 	}
3127 
3128 	CfgAddBool(f, "Enabled", r->Enabled);
3129 	CfgAddInt(f, "Port", r->Port);
3130 	CfgAddBool(f, "DisableDos", r->DisableDos);
3131 }
3132 
3133 // Read the listener configuration
SiLoadListenerCfg(SERVER * s,FOLDER * f)3134 void SiLoadListenerCfg(SERVER *s, FOLDER *f)
3135 {
3136 	bool enable;
3137 	UINT port;
3138 	bool disable_dos;
3139 	// Validate arguments
3140 	if (s == NULL || f == NULL)
3141 	{
3142 		return;
3143 	}
3144 
3145 	enable = CfgGetBool(f, "Enabled");
3146 	port = CfgGetInt(f, "Port");
3147 	disable_dos = CfgGetBool(f, "DisableDos");
3148 
3149 	if (port == 0)
3150 	{
3151 		return;
3152 	}
3153 
3154 	SiAddListenerEx(s, port, enable, disable_dos);
3155 }
3156 
3157 // Read the listener list
SiLoadListeners(SERVER * s,FOLDER * f)3158 void SiLoadListeners(SERVER *s, FOLDER *f)
3159 {
3160 	TOKEN_LIST *t;
3161 	UINT i;
3162 	// Validate arguments
3163 	if (s == NULL || f == NULL)
3164 	{
3165 		return;
3166 	}
3167 
3168 	t = CfgEnumFolderToTokenList(f);
3169 	for (i = 0;i < t->NumTokens;i++)
3170 	{
3171 		FOLDER *ff = CfgGetFolder(f, t->Token[i]);
3172 		if (ff != NULL)
3173 		{
3174 			SiLoadListenerCfg(s, ff);
3175 		}
3176 	}
3177 	FreeToken(t);
3178 }
3179 
3180 // Write the listener list
SiWriteListeners(FOLDER * f,SERVER * s)3181 void SiWriteListeners(FOLDER *f, SERVER *s)
3182 {
3183 	// Validate arguments
3184 	if (f == NULL || s == NULL)
3185 	{
3186 		return;
3187 	}
3188 
3189 	LockList(s->ServerListenerList);
3190 	{
3191 		UINT i;
3192 		for (i = 0;i < LIST_NUM(s->ServerListenerList);i++)
3193 		{
3194 			SERVER_LISTENER *r = LIST_DATA(s->ServerListenerList, i);
3195 			char name[MAX_SIZE];
3196 			Format(name, sizeof(name), "Listener%u", i);
3197 			SiWriteListenerCfg(CfgCreateFolder(f, name), r);
3198 		}
3199 	}
3200 	UnlockList(s->ServerListenerList);
3201 }
3202 
3203 // Write the bridge
SiWriteLocalBridgeCfg(FOLDER * f,LOCALBRIDGE * br)3204 void SiWriteLocalBridgeCfg(FOLDER *f, LOCALBRIDGE *br)
3205 {
3206 	// Validate arguments
3207 	if (f == NULL || br == NULL)
3208 	{
3209 		return;
3210 	}
3211 
3212 	CfgAddStr(f, "DeviceName", br->DeviceName);
3213 	CfgAddStr(f, "HubName", br->HubName);
3214 	CfgAddBool(f, "NoPromiscuousMode", br->Local);
3215 	CfgAddBool(f, "MonitorMode", br->Monitor);
3216 	CfgAddBool(f, "LimitBroadcast", br->LimitBroadcast);
3217 
3218 	if (OS_IS_UNIX(GetOsInfo()->OsType))
3219 	{
3220 		CfgAddBool(f, "TapMode", br->TapMode);
3221 
3222 		if (br->TapMode)
3223 		{
3224 			char tmp[MAX_SIZE];
3225 			MacToStr(tmp, sizeof(tmp), br->TapMacAddress);
3226 			CfgAddStr(f, "TapMacAddress", tmp);
3227 		}
3228 	}
3229 }
3230 
3231 // Write the bridge list
SiWriteLocalBridges(FOLDER * f,SERVER * s)3232 void SiWriteLocalBridges(FOLDER *f, SERVER *s)
3233 {
3234 	// Validate arguments
3235 	if (s == NULL || f == NULL)
3236 	{
3237 		return;
3238 	}
3239 
3240 #ifdef	OS_WIN32
3241 	CfgAddBool(f, "ShowAllInterfaces", Win32EthGetShowAllIf());
3242 
3243 	CfgAddBool(f, "EnableSoftEtherKernelModeDriver", Win32GetEnableSeLow());
3244 #endif	// OS_WIN32
3245 
3246 #ifdef	UNIX_LINUX
3247 	CfgAddBool(f, "DoNotDisableOffloading", GetGlobalServerFlag(GSF_LOCALBRIDGE_NO_DISABLE_OFFLOAD));
3248 #endif	// UNIX_LINUX
3249 
3250 	LockList(s->Cedar->LocalBridgeList);
3251 	{
3252 		UINT i;
3253 		for (i = 0;i < LIST_NUM(s->Cedar->LocalBridgeList);i++)
3254 		{
3255 			LOCALBRIDGE *br = LIST_DATA(s->Cedar->LocalBridgeList, i);
3256 			char name[MAX_SIZE];
3257 
3258 			Format(name, sizeof(name), "LocalBridge%u", i);
3259 			SiWriteLocalBridgeCfg(CfgCreateFolder(f, name), br);
3260 		}
3261 	}
3262 	UnlockList(s->Cedar->LocalBridgeList);
3263 }
3264 
3265 // Read the bridge
SiLoadLocalBridgeCfg(SERVER * s,FOLDER * f)3266 void SiLoadLocalBridgeCfg(SERVER *s, FOLDER *f)
3267 {
3268 	char hub[MAX_SIZE];
3269 	char nic[MAX_SIZE];
3270 	bool tapmode = false;
3271 	UCHAR tapaddr[6];
3272 	// Validate arguments
3273 	if (s == NULL || f == NULL)
3274 	{
3275 		return;
3276 	}
3277 
3278 	Zero(hub, sizeof(hub));
3279 	Zero(nic, sizeof(nic));
3280 
3281 	CfgGetStr(f, "HubName", hub, sizeof(hub));
3282 	CfgGetStr(f, "DeviceName", nic, sizeof(nic));
3283 
3284 	if (IsEmptyStr(hub) || IsEmptyStr(nic)
3285 		)
3286 	{
3287 		return;
3288 	}
3289 
3290 	if (OS_IS_UNIX(GetOsInfo()->OsType))
3291 	{
3292 		if (CfgGetBool(f, "TapMode"))
3293 		{
3294 			char tmp[MAX_SIZE];
3295 			tapmode = true;
3296 			Zero(tapaddr, sizeof(tapaddr));
3297 			if (CfgGetStr(f, "TapMacAddress", tmp, sizeof(tmp)))
3298 			{
3299 				BUF *b;
3300 				b = StrToBin(tmp);
3301 				if (b != NULL && b->Size == 6)
3302 				{
3303 					Copy(tapaddr, b->Buf, sizeof(tapaddr));
3304 				}
3305 				FreeBuf(b);
3306 			}
3307 		}
3308 	}
3309 
3310 	AddLocalBridge(s->Cedar, hub, nic, CfgGetBool(f, "NoPromiscuousMode"), CfgGetBool(f, "MonitorMode"),
3311 		tapmode, tapaddr, CfgGetBool(f, "LimitBroadcast"));
3312 }
3313 
3314 // Read the bridge list
SiLoadLocalBridges(SERVER * s,FOLDER * f)3315 void SiLoadLocalBridges(SERVER *s, FOLDER *f)
3316 {
3317 	TOKEN_LIST *t;
3318 	UINT i;
3319 	// Validate arguments
3320 	if (s == NULL || f == NULL)
3321 	{
3322 		return;
3323 	}
3324 
3325 #ifdef	OS_WIN32
3326 	Win32EthSetShowAllIf(CfgGetBool(f, "ShowAllInterfaces"));
3327 #endif	// OS_WIN32
3328 
3329 #ifdef	UNIX_LINUX
3330 	SetGlobalServerFlag(GSF_LOCALBRIDGE_NO_DISABLE_OFFLOAD, CfgGetBool(f, "DoNotDisableOffloading"));
3331 #endif	// UNIX_LINUX
3332 
3333 	t = CfgEnumFolderToTokenList(f);
3334 
3335 	for (i = 0;i < t->NumTokens;i++)
3336 	{
3337 		char *name = t->Token[i];
3338 
3339 		SiLoadLocalBridgeCfg(s, CfgGetFolder(f, name));
3340 	}
3341 
3342 	FreeToken(t);
3343 }
3344 
3345 // Increment the configuration revision of the server
IncrementServerConfigRevision(SERVER * s)3346 void IncrementServerConfigRevision(SERVER *s)
3347 {
3348 	// Validate arguments
3349 	if (s == NULL)
3350 	{
3351 		return;
3352 	}
3353 
3354 	s->ConfigRevision++;
3355 }
3356 
3357 // Write the server settings to CFG
SiWriteConfigurationToCfg(SERVER * s)3358 FOLDER *SiWriteConfigurationToCfg(SERVER *s)
3359 {
3360 	FOLDER *root;
3361 	char region[128];
3362 	// Validate arguments
3363 	if (s == NULL)
3364 	{
3365 		return NULL;
3366 	}
3367 
3368 	root = CfgCreateFolder(NULL, TAG_ROOT);
3369 
3370 	SiGetCurrentRegion(s->Cedar, region, sizeof(region));
3371 
3372 	CfgAddStr(root, "Region", region);
3373 
3374 	CfgAddInt(root, "ConfigRevision", s->ConfigRevision);
3375 
3376 	SiWriteListeners(CfgCreateFolder(root, "ListenerList"), s);
3377 
3378 	SiWriteLocalBridges(CfgCreateFolder(root, "LocalBridgeList"), s);
3379 
3380 	SiWriteServerCfg(CfgCreateFolder(root, "ServerConfiguration"), s);
3381 
3382 
3383 	if (s->UpdatedServerType != SERVER_TYPE_FARM_MEMBER)
3384 	{
3385 		SiWriteHubs(CfgCreateFolder(root, "VirtualHUB"), s);
3386 	}
3387 
3388 	if (s->Cedar->Bridge == false)
3389 	{
3390 		SiWriteL3Switchs(CfgCreateFolder(root, "VirtualLayer3SwitchList"), s);
3391 
3392 		if (GetServerCapsBool(s, "b_support_license"))
3393 		{
3394 			SiWriteLicenseManager(CfgCreateFolder(root, "LicenseManager"), s);
3395 		}
3396 	}
3397 
3398 	if (s->Led)
3399 	{
3400 		CfgAddBool(root, "Led", true);
3401 		CfgAddBool(root, "LedSpecial", s->LedSpecial);
3402 	}
3403 
3404 	if (GetServerCapsBool(s, "b_support_ipsec"))
3405 	{
3406 		SiWriteIPsec(CfgCreateFolder(root, "IPsec"), s);
3407 	}
3408 
3409 	if (s->Cedar->Bridge == false)
3410 	{
3411 		FOLDER *ddns_folder = CfgCreateFolder(root, "DDnsClient");
3412 
3413 		if (s->DDnsClient == NULL)
3414 		{
3415 			// Disabled
3416 			CfgAddBool(ddns_folder, "Disabled", true);
3417 		}
3418 		else
3419 		{
3420 			char machine_name[MAX_SIZE];
3421 			BUF *pw;
3422 			INTERNET_SETTING *t;
3423 			// Enabled
3424 			CfgAddBool(ddns_folder, "Disabled", false);
3425 			CfgAddByte(ddns_folder, "Key", s->DDnsClient->Key, SHA1_SIZE);
3426 
3427 			GetMachineHostName(machine_name, sizeof(machine_name));
3428 			CfgAddStr(ddns_folder, "LocalHostname", machine_name);
3429 
3430 			t = &s->DDnsClient->InternetSetting;
3431 
3432 			CfgAddInt(ddns_folder, "ProxyType", t->ProxyType);
3433 			CfgAddStr(ddns_folder, "ProxyHostName", t->ProxyHostName);
3434 			CfgAddInt(ddns_folder, "ProxyPort", t->ProxyPort);
3435 			CfgAddStr(ddns_folder, "ProxyUsername", t->ProxyUsername);
3436 
3437 			if (IsEmptyStr(t->ProxyPassword) == false)
3438 			{
3439 				pw = EncryptPassword(t->ProxyPassword);
3440 
3441 				CfgAddBuf(ddns_folder, "ProxyPassword", pw);
3442 
3443 				FreeBuf(pw);
3444 			}
3445 		}
3446 	}
3447 
3448 	CfgAddBool(root, "IPsecMessageDisplayed", s->IPsecMessageDisplayed);
3449 
3450 
3451 	return root;
3452 }
3453 
3454 // Read the policy
SiLoadPolicyCfg(POLICY * p,FOLDER * f)3455 void SiLoadPolicyCfg(POLICY *p, FOLDER *f)
3456 {
3457 	// Validate arguments
3458 	if (f == NULL || p == NULL)
3459 	{
3460 		return;
3461 	}
3462 
3463 	Zero(p, sizeof(POLICY));
3464 
3465 	// Ver 2
3466 	p->Access = CfgGetBool(f, "Access");
3467 	p->DHCPFilter = CfgGetBool(f, "DHCPFilter");
3468 	p->DHCPNoServer = CfgGetBool(f, "DHCPNoServer");
3469 	p->DHCPForce = CfgGetBool(f, "DHCPForce");
3470 	p->NoBridge = CfgGetBool(f, "NoBridge");
3471 	p->NoRouting = CfgGetBool(f, "NoRouting");
3472 	p->CheckMac = CfgGetBool(f, "CheckMac");
3473 	p->CheckIP = CfgGetBool(f, "CheckIP");
3474 	p->ArpDhcpOnly = CfgGetBool(f, "ArpDhcpOnly");
3475 	p->PrivacyFilter = CfgGetBool(f, "PrivacyFilter");
3476 	p->NoServer = CfgGetBool(f, "NoServer");
3477 	p->NoBroadcastLimiter = CfgGetBool(f, "NoBroadcastLimiter");
3478 	p->MonitorPort = CfgGetBool(f, "MonitorPort");
3479 	p->MaxConnection = CfgGetInt(f, "MaxConnection");
3480 	p->TimeOut = CfgGetInt(f, "TimeOut");
3481 	p->MaxMac = CfgGetInt(f, "MaxMac");
3482 	p->MaxIP = CfgGetInt(f, "MaxIP");
3483 	p->MaxUpload = CfgGetInt(f, "MaxUpload");
3484 	p->MaxDownload = CfgGetInt(f, "MaxDownload");
3485 	p->FixPassword = CfgGetBool(f, "FixPassword");
3486 	p->MultiLogins = CfgGetInt(f, "MultiLogins");
3487 	p->NoQoS = CfgGetBool(f, "NoQoS");
3488 
3489 	// Ver 3
3490 	p->RSandRAFilter = CfgGetBool(f, "RSandRAFilter");
3491 	p->RAFilter = CfgGetBool(f, "RAFilter");
3492 	p->DHCPv6Filter = CfgGetBool(f, "DHCPv6Filter");
3493 	p->DHCPv6NoServer = CfgGetBool(f, "DHCPv6NoServer");
3494 	p->NoRoutingV6 = CfgGetBool(f, "NoRoutingV6");
3495 	p->CheckIPv6 = CfgGetBool(f, "CheckIPv6");
3496 	p->NoServerV6 = CfgGetBool(f, "NoServerV6");
3497 	p->MaxIPv6 = CfgGetInt(f, "MaxIPv6");
3498 	p->NoSavePassword = CfgGetBool(f, "NoSavePassword");
3499 	p->AutoDisconnect = CfgGetInt(f, "AutoDisconnect");
3500 	p->FilterIPv4 = CfgGetBool(f, "FilterIPv4");
3501 	p->FilterIPv6 = CfgGetBool(f, "FilterIPv6");
3502 	p->FilterNonIP = CfgGetBool(f, "FilterNonIP");
3503 	p->NoIPv6DefaultRouterInRA = CfgGetBool(f, "NoIPv6DefaultRouterInRA");
3504 	p->NoIPv6DefaultRouterInRAWhenIPv6 = CfgGetBool(f, "NoIPv6DefaultRouterInRAWhenIPv6");
3505 	p->VLanId = CfgGetInt(f, "VLanId");
3506 }
3507 
3508 // Write the policy
SiWritePolicyCfg(FOLDER * f,POLICY * p,bool cascade_mode)3509 void SiWritePolicyCfg(FOLDER *f, POLICY *p, bool cascade_mode)
3510 {
3511 	// Validate arguments
3512 	if (f == NULL || p == NULL)
3513 	{
3514 		return;
3515 	}
3516 
3517 	// Ver 2.0
3518 	if (cascade_mode == false)
3519 	{
3520 		CfgAddBool(f, "Access", p->Access);
3521 	}
3522 
3523 	CfgAddBool(f, "DHCPFilter", p->DHCPFilter);
3524 	CfgAddBool(f, "DHCPNoServer", p->DHCPNoServer);
3525 	CfgAddBool(f, "DHCPForce", p->DHCPForce);
3526 
3527 	if (cascade_mode == false)
3528 	{
3529 		CfgAddBool(f, "NoBridge", p->NoBridge);
3530 		CfgAddBool(f, "NoRouting", p->NoRouting);
3531 	}
3532 
3533 	CfgAddBool(f, "CheckMac", p->CheckMac);
3534 	CfgAddBool(f, "CheckIP", p->CheckIP);
3535 	CfgAddBool(f, "ArpDhcpOnly", p->ArpDhcpOnly);
3536 
3537 	if (cascade_mode == false)
3538 	{
3539 		CfgAddBool(f, "PrivacyFilter", p->PrivacyFilter);
3540 	}
3541 
3542 	CfgAddBool(f, "NoServer", p->NoServer);
3543 	CfgAddBool(f, "NoBroadcastLimiter", p->NoBroadcastLimiter);
3544 
3545 	if (cascade_mode == false)
3546 	{
3547 		CfgAddBool(f, "MonitorPort", p->MonitorPort);
3548 		CfgAddInt(f, "MaxConnection", p->MaxConnection);
3549 		CfgAddInt(f, "TimeOut", p->TimeOut);
3550 	}
3551 
3552 	CfgAddInt(f, "MaxMac", p->MaxMac);
3553 	CfgAddInt(f, "MaxIP", p->MaxIP);
3554 	CfgAddInt(f, "MaxUpload", p->MaxUpload);
3555 	CfgAddInt(f, "MaxDownload", p->MaxDownload);
3556 
3557 	if (cascade_mode == false)
3558 	{
3559 		CfgAddBool(f, "FixPassword", p->FixPassword);
3560 		CfgAddInt(f, "MultiLogins", p->MultiLogins);
3561 		CfgAddBool(f, "NoQoS", p->NoQoS);
3562 	}
3563 
3564 	// Ver 3.0
3565 	CfgAddBool(f, "RSandRAFilter", p->RSandRAFilter);
3566 	CfgAddBool(f, "RAFilter", p->RAFilter);
3567 	CfgAddBool(f, "DHCPv6Filter", p->DHCPv6Filter);
3568 	CfgAddBool(f, "DHCPv6NoServer", p->DHCPv6NoServer);
3569 
3570 	if (cascade_mode == false)
3571 	{
3572 		CfgAddBool(f, "NoRoutingV6", p->NoRoutingV6);
3573 	}
3574 
3575 	CfgAddBool(f, "CheckIPv6", p->CheckIPv6);
3576 	CfgAddBool(f, "NoServerV6", p->NoServerV6);
3577 	CfgAddInt(f, "MaxIPv6", p->MaxIPv6);
3578 
3579 	if (cascade_mode == false)
3580 	{
3581 		CfgAddBool(f, "NoSavePassword", p->NoSavePassword);
3582 		CfgAddInt(f, "AutoDisconnect", p->AutoDisconnect);
3583 	}
3584 
3585 	CfgAddBool(f, "FilterIPv4", p->FilterIPv4);
3586 	CfgAddBool(f, "FilterIPv6", p->FilterIPv6);
3587 	CfgAddBool(f, "FilterNonIP", p->FilterNonIP);
3588 	CfgAddBool(f, "NoIPv6DefaultRouterInRA", p->NoIPv6DefaultRouterInRA);
3589 	CfgAddBool(f, "NoIPv6DefaultRouterInRAWhenIPv6", p->NoIPv6DefaultRouterInRAWhenIPv6);
3590 	CfgAddInt(f, "VLanId", p->VLanId);
3591 }
3592 
3593 // Write the link information of the Virtual HUB
SiWriteHubLinkCfg(FOLDER * f,LINK * k)3594 void SiWriteHubLinkCfg(FOLDER *f, LINK *k)
3595 {
3596 	// Validate arguments
3597 	if (f == NULL || k == NULL)
3598 	{
3599 		return;
3600 	}
3601 
3602 	Lock(k->lock);
3603 	{
3604 		// Online
3605 		CfgAddBool(f, "Online", k->Offline ? false : true);
3606 
3607 		// Client options
3608 		CiWriteClientOption(CfgCreateFolder(f, "ClientOption"), k->Option);
3609 
3610 		// Client authentication data
3611 		CiWriteClientAuth(CfgCreateFolder(f, "ClientAuth"), k->Auth);
3612 
3613 		// Policy
3614 		if (k->Policy != NULL)
3615 		{
3616 			SiWritePolicyCfg(CfgCreateFolder(f, "Policy"), k->Policy, true);
3617 		}
3618 
3619 		CfgAddBool(f, "CheckServerCert", k->CheckServerCert);
3620 
3621 		if (k->ServerCert != NULL)
3622 		{
3623 			BUF *b = XToBuf(k->ServerCert, false);
3624 			CfgAddBuf(f, "ServerCert", b);
3625 			FreeBuf(b);
3626 		}
3627 	}
3628 	Unlock(k->lock);
3629 }
3630 
3631 // Read the link information
SiLoadHubLinkCfg(FOLDER * f,HUB * h)3632 void SiLoadHubLinkCfg(FOLDER *f, HUB *h)
3633 {
3634 	bool online;
3635 	CLIENT_OPTION *o;
3636 	CLIENT_AUTH *a;
3637 	FOLDER *pf;
3638 	POLICY p;
3639 	LINK *k;
3640 	// Validate arguments
3641 	if (f == NULL || h == NULL)
3642 	{
3643 		return;
3644 	}
3645 
3646 	pf = CfgGetFolder(f, "Policy");
3647 	if (pf == NULL)
3648 	{
3649 		return;
3650 	}
3651 
3652 	SiLoadPolicyCfg(&p, pf);
3653 
3654 	online = CfgGetBool(f, "Online");
3655 
3656 	o = CiLoadClientOption(CfgGetFolder(f, "ClientOption"));
3657 	a = CiLoadClientAuth(CfgGetFolder(f, "ClientAuth"));
3658 	if (o == NULL || a == NULL)
3659 	{
3660 		Free(o);
3661 		CiFreeClientAuth(a);
3662 		return;
3663 	}
3664 
3665 	k = NewLink(h->Cedar, h, o, a, &p);
3666 	if (k != NULL)
3667 	{
3668 		BUF *b;
3669 		k->CheckServerCert = CfgGetBool(f, "CheckServerCert");
3670 		b = CfgGetBuf(f, "ServerCert");
3671 		if (b != NULL)
3672 		{
3673 			k->ServerCert = BufToX(b, false);
3674 			FreeBuf(b);
3675 		}
3676 
3677 		if (online)
3678 		{
3679 			k->Offline = true;
3680 			SetLinkOnline(k);
3681 		}
3682 		else
3683 		{
3684 			k->Offline = false;
3685 			SetLinkOffline(k);
3686 		}
3687 		ReleaseLink(k);
3688 	}
3689 
3690 	Free(o);
3691 	CiFreeClientAuth(a);
3692 }
3693 
3694 // Write the SecureNAT of the Virtual HUB
SiWriteSecureNAT(HUB * h,FOLDER * f)3695 void SiWriteSecureNAT(HUB *h, FOLDER *f)
3696 {
3697 	// Validate arguments
3698 	if (h == NULL || f == NULL)
3699 	{
3700 		return;
3701 	}
3702 
3703 	CfgAddBool(f, "Disabled", h->EnableSecureNAT ? false : true);
3704 
3705 	NiWriteVhOptionEx(h->SecureNATOption, f);
3706 }
3707 
3708 // Read the administration options for the virtual HUB
SiLoadHubAdminOptions(HUB * h,FOLDER * f)3709 void SiLoadHubAdminOptions(HUB *h, FOLDER *f)
3710 {
3711 	TOKEN_LIST *t;
3712 	// Validate arguments
3713 	if (h == NULL || f == NULL)
3714 	{
3715 		return;
3716 	}
3717 
3718 	t = CfgEnumItemToTokenList(f);
3719 	if (t != NULL)
3720 	{
3721 		UINT i;
3722 
3723 		LockList(h->AdminOptionList);
3724 		{
3725 			DeleteAllHubAdminOption(h, false);
3726 
3727 			for (i = 0;i < t->NumTokens;i++)
3728 			{
3729 				char *name = t->Token[i];
3730 				ADMIN_OPTION *a;
3731 				UINT value = CfgGetInt(f, name);;
3732 
3733 				Trim(name);
3734 
3735 				a = ZeroMalloc(sizeof(ADMIN_OPTION));
3736 				StrCpy(a->Name, sizeof(a->Name), name);
3737 				a->Value = value;
3738 
3739 				Insert(h->AdminOptionList, a);
3740 			}
3741 
3742 			AddHubAdminOptionsDefaults(h, false);
3743 		}
3744 		UnlockList(h->AdminOptionList);
3745 
3746 		FreeToken(t);
3747 	}
3748 }
3749 
3750 // Write the administration options for the virtual HUB
SiWriteHubAdminOptions(FOLDER * f,HUB * h)3751 void SiWriteHubAdminOptions(FOLDER *f, HUB *h)
3752 {
3753 	// Validate arguments
3754 	if (f == NULL || h == NULL)
3755 	{
3756 		return;
3757 	}
3758 
3759 	LockList(h->AdminOptionList);
3760 	{
3761 		UINT i;
3762 		for (i = 0;i < LIST_NUM(h->AdminOptionList);i++)
3763 		{
3764 			ADMIN_OPTION *a = LIST_DATA(h->AdminOptionList, i);
3765 
3766 			CfgAddInt(f, a->Name, a->Value);
3767 		}
3768 	}
3769 	UnlockList(h->AdminOptionList);
3770 }
3771 
3772 // Write the link list of the Virtual HUB
SiWriteHubLinks(FOLDER * f,HUB * h)3773 void SiWriteHubLinks(FOLDER *f, HUB *h)
3774 {
3775 	// Validate arguments
3776 	if (f == NULL || h == NULL)
3777 	{
3778 		return;
3779 	}
3780 
3781 	LockList(h->LinkList);
3782 	{
3783 		UINT i;
3784 		for (i = 0;i < LIST_NUM(h->LinkList);i++)
3785 		{
3786 			LINK *k = LIST_DATA(h->LinkList, i);
3787 			char name[MAX_SIZE];
3788 			Format(name, sizeof(name), "Cascade%u", i);
3789 			SiWriteHubLinkCfg(CfgCreateFolder(f, name), k);
3790 		}
3791 	}
3792 	UnlockList(h->LinkList);
3793 }
3794 
3795 // Read the link list
SiLoadHubLinks(HUB * h,FOLDER * f)3796 void SiLoadHubLinks(HUB *h, FOLDER *f)
3797 {
3798 	TOKEN_LIST *t;
3799 	UINT i;
3800 	// Validate arguments
3801 	if (h == NULL || f == NULL)
3802 	{
3803 		return;
3804 	}
3805 
3806 	t = CfgEnumFolderToTokenList(f);
3807 
3808 	for (i = 0;i < t->NumTokens;i++)
3809 	{
3810 		char *name = t->Token[i];
3811 		SiLoadHubLinkCfg(CfgGetFolder(f, name), h);
3812 	}
3813 
3814 	FreeToken(t);
3815 }
3816 
3817 // Write an item of the access list
SiWriteHubAccessCfg(FOLDER * f,ACCESS * a)3818 void SiWriteHubAccessCfg(FOLDER *f, ACCESS *a)
3819 {
3820 	// Validate arguments
3821 	if (f == NULL || a == NULL)
3822 	{
3823 		return;
3824 	}
3825 
3826 	CfgAddUniStr(f, "Note", a->Note);
3827 	CfgAddBool(f, "Active", a->Active);
3828 	CfgAddInt(f, "Priority", a->Priority);
3829 	CfgAddBool(f, "Discard", a->Discard);
3830 	CfgAddBool(f, "IsIPv6", a->IsIPv6);
3831 
3832 	if (a->IsIPv6 == false)
3833 	{
3834 		CfgAddIp32(f, "SrcIpAddress", a->SrcIpAddress);
3835 		CfgAddIp32(f, "SrcSubnetMask", a->SrcSubnetMask);
3836 		CfgAddIp32(f, "DestIpAddress", a->DestIpAddress);
3837 		CfgAddIp32(f, "DestSubnetMask", a->DestSubnetMask);
3838 	}
3839 	else
3840 	{
3841 		CfgAddIp6Addr(f, "SrcIpAddress6", &a->SrcIpAddress6);
3842 		CfgAddIp6Addr(f, "SrcSubnetMask6", &a->SrcSubnetMask6);
3843 		CfgAddIp6Addr(f, "DestIpAddress6", &a->DestIpAddress6);
3844 		CfgAddIp6Addr(f, "DestSubnetMask6", &a->DestSubnetMask6);
3845 	}
3846 
3847 	CfgAddInt(f, "Protocol", a->Protocol);
3848 	CfgAddInt(f, "SrcPortStart", a->SrcPortStart);
3849 	CfgAddInt(f, "SrcPortEnd", a->SrcPortEnd);
3850 	CfgAddInt(f, "DestPortStart", a->DestPortStart);
3851 	CfgAddInt(f, "DestPortEnd", a->DestPortEnd);
3852 	CfgAddStr(f, "SrcUsername", a->SrcUsername);
3853 	CfgAddStr(f, "DestUsername", a->DestUsername);
3854 	CfgAddBool(f, "CheckSrcMac", a->CheckSrcMac);
3855 
3856 	if (a->CheckSrcMac)
3857 	{
3858 		char tmp[MAX_PATH];
3859 
3860 		MacToStr(tmp, sizeof(tmp), a->SrcMacAddress);
3861 		CfgAddStr(f, "SrcMacAddress", tmp);
3862 
3863 		MacToStr(tmp, sizeof(tmp), a->SrcMacMask);
3864 		CfgAddStr(f, "SrcMacMask", tmp);
3865 	}
3866 
3867 	CfgAddBool(f, "CheckDstMac", a->CheckDstMac);
3868 
3869 	if (a->CheckDstMac)
3870 	{
3871 		char tmp[MAX_PATH];
3872 
3873 		MacToStr(tmp, sizeof(tmp), a->DstMacAddress);
3874 		CfgAddStr(f, "DstMacAddress", tmp);
3875 
3876 		MacToStr(tmp, sizeof(tmp), a->DstMacMask);
3877 		CfgAddStr(f, "DstMacMask", tmp);
3878 	}
3879 
3880 	CfgAddBool(f, "CheckTcpState", a->CheckTcpState);
3881 	CfgAddBool(f, "Established", a->Established);
3882 
3883 	CfgAddStr(f, "RedirectUrl", a->RedirectUrl);
3884 
3885 	CfgAddInt(f, "Delay", a->Delay);
3886 	CfgAddInt(f, "Jitter", a->Jitter);
3887 	CfgAddInt(f, "Loss", a->Loss);
3888 }
3889 
3890 // Read an item of the access list
SiLoadHubAccessCfg(HUB * h,FOLDER * f)3891 void SiLoadHubAccessCfg(HUB *h, FOLDER *f)
3892 {
3893 	ACCESS a;
3894 	char tmp[MAX_PATH];
3895 	// Validate arguments
3896 	if (h == NULL || f == NULL)
3897 	{
3898 		return;
3899 	}
3900 
3901 	Zero(&a, sizeof(a));
3902 
3903 	CfgGetUniStr(f, "Note", a.Note, sizeof(a.Note));
3904 	a.Active = CfgGetBool(f, "Active");
3905 	a.Priority = CfgGetInt(f, "Priority");
3906 	a.Discard = CfgGetBool(f, "Discard");
3907 	a.IsIPv6 = CfgGetBool(f, "IsIPv6");
3908 
3909 	if (a.IsIPv6 == false)
3910 	{
3911 		a.SrcIpAddress = CfgGetIp32(f, "SrcIpAddress");
3912 		a.SrcSubnetMask = CfgGetIp32(f, "SrcSubnetMask");
3913 		a.DestIpAddress = CfgGetIp32(f, "DestIpAddress");
3914 		a.DestSubnetMask = CfgGetIp32(f, "DestSubnetMask");
3915 	}
3916 	else
3917 	{
3918 		CfgGetIp6Addr(f, "SrcIpAddress6", &a.SrcIpAddress6);
3919 		CfgGetIp6Addr(f, "SrcSubnetMask6", &a.SrcSubnetMask6);
3920 		CfgGetIp6Addr(f, "DestIpAddress6", &a.DestIpAddress6);
3921 		CfgGetIp6Addr(f, "DestSubnetMask6", &a.DestSubnetMask6);
3922 	}
3923 
3924 	a.Protocol = CfgGetInt(f, "Protocol");
3925 	a.SrcPortStart = CfgGetInt(f, "SrcPortStart");
3926 	a.SrcPortEnd = CfgGetInt(f, "SrcPortEnd");
3927 	a.DestPortStart = CfgGetInt(f, "DestPortStart");
3928 	a.DestPortEnd = CfgGetInt(f, "DestPortEnd");
3929 	CfgGetStr(f, "SrcUsername", a.SrcUsername, sizeof(a.SrcUsername));
3930 	CfgGetStr(f, "DestUsername", a.DestUsername, sizeof(a.DestUsername));
3931 	a.CheckSrcMac = CfgGetBool(f, "CheckSrcMac");
3932 
3933 	if (CfgGetByte(f, "SrcMacAddress", a.SrcMacAddress, sizeof(a.SrcMacAddress)) == 0)
3934 	{
3935 		CfgGetStr(f, "SrcMacAddress", tmp, sizeof(tmp));
3936 		if (StrToMac(a.SrcMacAddress, tmp) == false)
3937 		{
3938 			a.CheckSrcMac = false;
3939 		}
3940 	}
3941 
3942 	if (CfgGetByte(f, "SrcMacMask", a.SrcMacMask, sizeof(a.SrcMacMask)) == 0)
3943 	{
3944 		CfgGetStr(f, "SrcMacMask", tmp, sizeof(tmp));
3945 		if (StrToMac(a.SrcMacMask, tmp) == false)
3946 		{
3947 			a.CheckSrcMac = false;
3948 		}
3949 	}
3950 
3951 	a.CheckDstMac = CfgGetBool(f, "CheckDstMac");
3952 
3953 	if (CfgGetByte(f, "DstMacAddress", a.DstMacAddress, sizeof(a.DstMacAddress)) == 0)
3954 	{
3955 		CfgGetStr(f, "DstMacAddress", tmp, sizeof(tmp));
3956 		if (StrToMac(a.DstMacAddress, tmp) == false)
3957 		{
3958 			a.CheckDstMac = false;
3959 		}
3960 	}
3961 
3962 	if (CfgGetByte(f, "DstMacMask", a.DstMacMask, sizeof(a.DstMacMask)) == 0)
3963 	{
3964 		CfgGetStr(f, "DstMacMask", tmp, sizeof(tmp));
3965 		if (StrToMac(a.DstMacMask, tmp) == false)
3966 		{
3967 			a.CheckDstMac = false;
3968 		}
3969 	}
3970 
3971 	a.CheckTcpState = CfgGetBool(f, "CheckTcpState");
3972 	a.Established = CfgGetBool(f, "Established");
3973 	a.Delay = MAKESURE(CfgGetInt(f, "Delay"), 0, HUB_ACCESSLIST_DELAY_MAX);
3974 	a.Jitter = MAKESURE(CfgGetInt(f, "Jitter"), 0, HUB_ACCESSLIST_JITTER_MAX);
3975 	a.Loss = MAKESURE(CfgGetInt(f, "Loss"), 0, HUB_ACCESSLIST_LOSS_MAX);
3976 
3977 	CfgGetStr(f, "RedirectUrl", a.RedirectUrl, sizeof(a.RedirectUrl));
3978 
3979 	AddAccessList(h, &a);
3980 }
3981 
3982 // Write the access list
SiWriteHubAccessLists(FOLDER * f,HUB * h)3983 void SiWriteHubAccessLists(FOLDER *f, HUB *h)
3984 {
3985 	// Validate arguments
3986 	if (f == NULL || h == NULL)
3987 	{
3988 		return;
3989 	}
3990 
3991 	LockList(h->AccessList);
3992 	{
3993 		UINT i;
3994 		for (i = 0;i < LIST_NUM(h->AccessList);i++)
3995 		{
3996 			ACCESS *a = LIST_DATA(h->AccessList, i);
3997 			char name[MAX_SIZE];
3998 			ToStr(name, a->Id);
3999 			SiWriteHubAccessCfg(CfgCreateFolder(f, name), a);
4000 		}
4001 	}
4002 	UnlockList(h->AccessList);
4003 }
4004 
4005 // Read the access list
SiLoadHubAccessLists(HUB * h,FOLDER * f)4006 void SiLoadHubAccessLists(HUB *h, FOLDER *f)
4007 {
4008 	TOKEN_LIST *t;
4009 	UINT i;
4010 	// Validate arguments
4011 	if (f == NULL || h == NULL)
4012 	{
4013 		return;
4014 	}
4015 
4016 	t = CfgEnumFolderToTokenList(f);
4017 
4018 	for (i = 0;i < t->NumTokens;i++)
4019 	{
4020 		char *name = t->Token[i];
4021 		UINT id = ToInt(name);
4022 		SiLoadHubAccessCfg(h, CfgGetFolder(f, name));
4023 	}
4024 
4025 	FreeToken(t);
4026 }
4027 
4028 // Read the HUB_OPTION
SiLoadHubOptionCfg(FOLDER * f,HUB_OPTION * o)4029 void SiLoadHubOptionCfg(FOLDER *f, HUB_OPTION *o)
4030 {
4031 	char tmp[MAX_SIZE];
4032 	// Validate arguments
4033 	if (f == NULL || o == NULL)
4034 	{
4035 		return;
4036 	}
4037 
4038 	o->MaxSession = CfgGetInt(f, "MaxSession");
4039 	o->NoArpPolling = CfgGetBool(f, "NoArpPolling");
4040 	o->NoIPv6AddrPolling = CfgGetBool(f, "NoIPv6AddrPolling");
4041 	o->NoIpTable = CfgGetBool(f, "NoIpTable");
4042 	o->NoEnum = CfgGetBool(f, "NoEnum");
4043 	o->FilterPPPoE = CfgGetBool(f, "FilterPPPoE");
4044 	o->FilterOSPF = CfgGetBool(f, "FilterOSPF");
4045 	o->FilterIPv4 = CfgGetBool(f, "FilterIPv4");
4046 	o->FilterIPv6 = CfgGetBool(f, "FilterIPv6");
4047 	o->FilterNonIP = CfgGetBool(f, "FilterNonIP");
4048 	o->FilterBPDU = CfgGetBool(f, "FilterBPDU");
4049 	o->NoIPv4PacketLog = CfgGetBool(f, "NoIPv4PacketLog");
4050 	o->NoIPv6PacketLog = CfgGetBool(f, "NoIPv6PacketLog");
4051 	o->NoIPv6DefaultRouterInRAWhenIPv6 = CfgGetBool(f, "NoIPv6DefaultRouterInRAWhenIPv6");
4052 	o->DisableIPParsing = CfgGetBool(f, "DisableIPParsing");
4053 	o->YieldAfterStorePacket = CfgGetBool(f, "YieldAfterStorePacket");
4054 	o->NoSpinLockForPacketDelay = CfgGetBool(f, "NoSpinLockForPacketDelay");
4055 	o->BroadcastStormDetectionThreshold = CfgGetInt(f, "BroadcastStormDetectionThreshold");
4056 	o->ClientMinimumRequiredBuild = CfgGetInt(f, "ClientMinimumRequiredBuild");
4057 	o->RequiredClientId = CfgGetInt(f, "RequiredClientId");
4058 	o->NoManageVlanId = CfgGetBool(f, "NoManageVlanId");
4059 	o->VlanTypeId = 0;
4060 	if (CfgGetStr(f, "VlanTypeId", tmp, sizeof(tmp)))
4061 	{
4062 		o->VlanTypeId = HexToInt(tmp);
4063 	}
4064 	if (o->VlanTypeId == 0)
4065 	{
4066 		o->VlanTypeId = MAC_PROTO_TAGVLAN;
4067 	}
4068 	o->FixForDLinkBPDU = CfgGetBool(f, "FixForDLinkBPDU");
4069 	o->BroadcastLimiterStrictMode = CfgGetBool(f, "BroadcastLimiterStrictMode");
4070 	o->MaxLoggedPacketsPerMinute = CfgGetInt(f, "MaxLoggedPacketsPerMinute");
4071 	if (CfgIsItem(f, "FloodingSendQueueBufferQuota"))
4072 	{
4073 		o->FloodingSendQueueBufferQuota = CfgGetInt(f, "FloodingSendQueueBufferQuota");
4074 	}
4075 	else
4076 	{
4077 		o->FloodingSendQueueBufferQuota = DEFAULT_FLOODING_QUEUE_LENGTH;
4078 	}
4079 	o->DoNotSaveHeavySecurityLogs = CfgGetBool(f, "DoNotSaveHeavySecurityLogs");
4080 
4081 	if (CfgIsItem(f, "DropBroadcastsInPrivacyFilterMode"))
4082 	{
4083 		o->DropBroadcastsInPrivacyFilterMode = CfgGetBool(f, "DropBroadcastsInPrivacyFilterMode");
4084 	}
4085 	else
4086 	{
4087 		o->DropBroadcastsInPrivacyFilterMode = true;
4088 	}
4089 
4090 	if (CfgIsItem(f, "DropArpInPrivacyFilterMode"))
4091 	{
4092 		o->DropArpInPrivacyFilterMode = CfgGetBool(f, "DropArpInPrivacyFilterMode");
4093 	}
4094 	else
4095 	{
4096 		o->DropArpInPrivacyFilterMode = true;
4097 	}
4098 
4099 	o->NoLookBPDUBridgeId = CfgGetBool(f, "NoLookBPDUBridgeId");
4100 	o->AdjustTcpMssValue = CfgGetInt(f, "AdjustTcpMssValue");
4101 	o->DisableAdjustTcpMss = CfgGetBool(f, "DisableAdjustTcpMss");
4102 	if (CfgIsItem(f, "NoDhcpPacketLogOutsideHub"))
4103 	{
4104 		o->NoDhcpPacketLogOutsideHub = CfgGetBool(f, "NoDhcpPacketLogOutsideHub");
4105 	}
4106 	else
4107 	{
4108 		o->NoDhcpPacketLogOutsideHub = true;
4109 	}
4110 	o->DisableHttpParsing = CfgGetBool(f, "DisableHttpParsing");
4111 	o->DisableUdpAcceleration = CfgGetBool(f, "DisableUdpAcceleration");
4112 	o->DisableUdpFilterForLocalBridgeNic = CfgGetBool(f, "DisableUdpFilterForLocalBridgeNic");
4113 	o->ApplyIPv4AccessListOnArpPacket = CfgGetBool(f, "ApplyIPv4AccessListOnArpPacket");
4114 	if (CfgIsItem(f, "RemoveDefGwOnDhcpForLocalhost"))
4115 	{
4116 		o->RemoveDefGwOnDhcpForLocalhost = CfgGetBool(f, "RemoveDefGwOnDhcpForLocalhost");
4117 	}
4118 	else
4119 	{
4120 		o->RemoveDefGwOnDhcpForLocalhost = true;
4121 	}
4122 	o->SecureNAT_MaxTcpSessionsPerIp = CfgGetInt(f, "SecureNAT_MaxTcpSessionsPerIp");
4123 	o->SecureNAT_MaxTcpSynSentPerIp = CfgGetInt(f, "SecureNAT_MaxTcpSynSentPerIp");
4124 	o->SecureNAT_MaxUdpSessionsPerIp = CfgGetInt(f, "SecureNAT_MaxUdpSessionsPerIp");
4125 	o->SecureNAT_MaxDnsSessionsPerIp = CfgGetInt(f, "SecureNAT_MaxDnsSessionsPerIp");
4126 	o->SecureNAT_MaxIcmpSessionsPerIp = CfgGetInt(f, "SecureNAT_MaxIcmpSessionsPerIp");
4127 	o->AccessListIncludeFileCacheLifetime = CfgGetInt(f, "AccessListIncludeFileCacheLifetime");
4128 
4129 	if (o->AccessListIncludeFileCacheLifetime == 0)
4130 	{
4131 		o->AccessListIncludeFileCacheLifetime = ACCESS_LIST_INCLUDE_FILE_CACHE_LIFETIME;
4132 	}
4133 
4134 	o->DisableKernelModeSecureNAT = CfgGetBool(f, "DisableKernelModeSecureNAT");
4135 	o->DisableIpRawModeSecureNAT = CfgGetBool(f, "DisableIpRawModeSecureNAT");
4136 	o->DisableUserModeSecureNAT = CfgGetBool(f, "DisableUserModeSecureNAT");
4137 	o->DisableCheckMacOnLocalBridge = CfgGetBool(f, "DisableCheckMacOnLocalBridge");
4138 	o->DisableCorrectIpOffloadChecksum = CfgGetBool(f, "DisableCorrectIpOffloadChecksum");
4139 	o->SuppressClientUpdateNotification = CfgGetBool(f, "SuppressClientUpdateNotification");
4140 	o->AssignVLanIdByRadiusAttribute = CfgGetBool(f, "AssignVLanIdByRadiusAttribute");
4141 	o->DenyAllRadiusLoginWithNoVlanAssign = CfgGetBool(f, "DenyAllRadiusLoginWithNoVlanAssign");
4142 	o->SecureNAT_RandomizeAssignIp = CfgGetBool(f, "SecureNAT_RandomizeAssignIp");
4143 	o->DetectDormantSessionInterval = CfgGetInt(f, "DetectDormantSessionInterval");
4144 	o->NoPhysicalIPOnPacketLog = CfgGetBool(f, "NoPhysicalIPOnPacketLog");
4145 	o->UseHubNameAsDhcpUserClassOption = CfgGetBool(f, "UseHubNameAsDhcpUserClassOption");
4146 	o->UseHubNameAsRadiusNasId = CfgGetBool(f, "UseHubNameAsRadiusNasId");
4147 
4148 	// Enabled by default
4149 	if (CfgIsItem(f, "ManageOnlyPrivateIP"))
4150 	{
4151 		o->ManageOnlyPrivateIP = CfgGetBool(f, "ManageOnlyPrivateIP");
4152 	}
4153 	else
4154 	{
4155 		o->ManageOnlyPrivateIP = true;
4156 	}
4157 	if (CfgIsItem(f, "ManageOnlyLocalUnicastIPv6"))
4158 	{
4159 		o->ManageOnlyLocalUnicastIPv6 = CfgGetBool(f, "ManageOnlyLocalUnicastIPv6");
4160 	}
4161 	else
4162 	{
4163 		o->ManageOnlyLocalUnicastIPv6 = true;
4164 	}
4165 	if (CfgIsItem(f, "NoMacAddressLog"))
4166 	{
4167 		o->NoMacAddressLog = CfgGetBool(f, "NoMacAddressLog");
4168 	}
4169 	else
4170 	{
4171 		o->NoMacAddressLog = true;
4172 	}
4173 }
4174 
4175 // Write the HUB_OPTION
SiWriteHubOptionCfg(FOLDER * f,HUB_OPTION * o)4176 void SiWriteHubOptionCfg(FOLDER *f, HUB_OPTION *o)
4177 {
4178 	char tmp[MAX_SIZE];
4179 	// Validate arguments
4180 	if (f == NULL || o == NULL)
4181 	{
4182 		return;
4183 	}
4184 
4185 	CfgAddInt(f, "MaxSession", o->MaxSession);
4186 	CfgAddBool(f, "NoArpPolling", o->NoArpPolling);
4187 	CfgAddBool(f, "NoIPv6AddrPolling", o->NoIPv6AddrPolling);
4188 	CfgAddBool(f, "NoIpTable", o->NoIpTable);
4189 	CfgAddBool(f, "NoEnum", o->NoEnum);
4190 	CfgAddBool(f, "FilterPPPoE", o->FilterPPPoE);
4191 	CfgAddBool(f, "FilterOSPF", o->FilterOSPF);
4192 	CfgAddBool(f, "FilterIPv4", o->FilterIPv4);
4193 	CfgAddBool(f, "FilterIPv6", o->FilterIPv6);
4194 	CfgAddBool(f, "FilterNonIP", o->FilterNonIP);
4195 	CfgAddBool(f, "NoIPv4PacketLog", o->NoIPv4PacketLog);
4196 	CfgAddBool(f, "NoIPv6PacketLog", o->NoIPv6PacketLog);
4197 	CfgAddBool(f, "FilterBPDU", o->FilterBPDU);
4198 	CfgAddBool(f, "NoIPv6DefaultRouterInRAWhenIPv6", o->NoIPv6DefaultRouterInRAWhenIPv6);
4199 	CfgAddBool(f, "NoMacAddressLog", o->NoMacAddressLog);
4200 	CfgAddBool(f, "ManageOnlyPrivateIP", o->ManageOnlyPrivateIP);
4201 	CfgAddBool(f, "ManageOnlyLocalUnicastIPv6", o->ManageOnlyLocalUnicastIPv6);
4202 	CfgAddBool(f, "DisableIPParsing", o->DisableIPParsing);
4203 	CfgAddBool(f, "YieldAfterStorePacket", o->YieldAfterStorePacket);
4204 	CfgAddBool(f, "NoSpinLockForPacketDelay", o->NoSpinLockForPacketDelay);
4205 	CfgAddInt(f, "BroadcastStormDetectionThreshold", o->BroadcastStormDetectionThreshold);
4206 	CfgAddInt(f, "ClientMinimumRequiredBuild", o->ClientMinimumRequiredBuild);
4207 	CfgAddInt(f, "RequiredClientId", o->RequiredClientId);
4208 	CfgAddBool(f, "NoManageVlanId", o->NoManageVlanId);
4209 	Format(tmp, sizeof(tmp), "0x%x", o->VlanTypeId);
4210 	CfgAddStr(f, "VlanTypeId", tmp);
4211 	if (o->FixForDLinkBPDU)
4212 	{
4213 		CfgAddBool(f, "FixForDLinkBPDU", o->FixForDLinkBPDU);
4214 	}
4215 	CfgAddBool(f, "BroadcastLimiterStrictMode", o->BroadcastLimiterStrictMode);
4216 	CfgAddInt(f, "MaxLoggedPacketsPerMinute", o->MaxLoggedPacketsPerMinute);
4217 	CfgAddInt(f, "FloodingSendQueueBufferQuota", o->FloodingSendQueueBufferQuota);
4218 	CfgAddBool(f, "DoNotSaveHeavySecurityLogs", o->DoNotSaveHeavySecurityLogs);
4219 	CfgAddBool(f, "DropBroadcastsInPrivacyFilterMode", o->DropBroadcastsInPrivacyFilterMode);
4220 	CfgAddBool(f, "DropArpInPrivacyFilterMode", o->DropArpInPrivacyFilterMode);
4221 	CfgAddBool(f, "SuppressClientUpdateNotification", o->SuppressClientUpdateNotification);
4222 	CfgAddBool(f, "AssignVLanIdByRadiusAttribute", o->AssignVLanIdByRadiusAttribute);
4223 	CfgAddBool(f, "DenyAllRadiusLoginWithNoVlanAssign", o->DenyAllRadiusLoginWithNoVlanAssign);
4224 	CfgAddBool(f, "SecureNAT_RandomizeAssignIp", o->SecureNAT_RandomizeAssignIp);
4225 	CfgAddBool(f, "NoPhysicalIPOnPacketLog", o->NoPhysicalIPOnPacketLog);
4226 	CfgAddInt(f, "DetectDormantSessionInterval", o->DetectDormantSessionInterval);
4227 	CfgAddBool(f, "NoLookBPDUBridgeId", o->NoLookBPDUBridgeId);
4228 	CfgAddInt(f, "AdjustTcpMssValue", o->AdjustTcpMssValue);
4229 	CfgAddBool(f, "DisableAdjustTcpMss", o->DisableAdjustTcpMss);
4230 	CfgAddBool(f, "NoDhcpPacketLogOutsideHub", o->NoDhcpPacketLogOutsideHub);
4231 	CfgAddBool(f, "DisableHttpParsing", o->DisableHttpParsing);
4232 	CfgAddBool(f, "DisableUdpAcceleration", o->DisableUdpAcceleration);
4233 	CfgAddBool(f, "DisableUdpFilterForLocalBridgeNic", o->DisableUdpFilterForLocalBridgeNic);
4234 	CfgAddBool(f, "ApplyIPv4AccessListOnArpPacket", o->ApplyIPv4AccessListOnArpPacket);
4235 	CfgAddBool(f, "RemoveDefGwOnDhcpForLocalhost", o->RemoveDefGwOnDhcpForLocalhost);
4236 	CfgAddInt(f, "SecureNAT_MaxTcpSessionsPerIp", o->SecureNAT_MaxTcpSessionsPerIp);
4237 	CfgAddInt(f, "SecureNAT_MaxTcpSynSentPerIp", o->SecureNAT_MaxTcpSynSentPerIp);
4238 	CfgAddInt(f, "SecureNAT_MaxUdpSessionsPerIp", o->SecureNAT_MaxUdpSessionsPerIp);
4239 	CfgAddInt(f, "SecureNAT_MaxDnsSessionsPerIp", o->SecureNAT_MaxDnsSessionsPerIp);
4240 	CfgAddInt(f, "SecureNAT_MaxIcmpSessionsPerIp", o->SecureNAT_MaxIcmpSessionsPerIp);
4241 	CfgAddInt(f, "AccessListIncludeFileCacheLifetime", o->AccessListIncludeFileCacheLifetime);
4242 	CfgAddBool(f, "DisableKernelModeSecureNAT", o->DisableKernelModeSecureNAT);
4243 	CfgAddBool(f, "DisableIpRawModeSecureNAT", o->DisableIpRawModeSecureNAT);
4244 	CfgAddBool(f, "DisableUserModeSecureNAT", o->DisableUserModeSecureNAT);
4245 	CfgAddBool(f, "DisableCheckMacOnLocalBridge", o->DisableCheckMacOnLocalBridge);
4246 	CfgAddBool(f, "DisableCorrectIpOffloadChecksum", o->DisableCorrectIpOffloadChecksum);
4247 	CfgAddBool(f, "UseHubNameAsDhcpUserClassOption", o->UseHubNameAsDhcpUserClassOption);
4248 	CfgAddBool(f, "UseHubNameAsRadiusNasId", o->UseHubNameAsRadiusNasId);
4249 }
4250 
4251 // Write the user
SiWriteUserCfg(FOLDER * f,USER * u)4252 void SiWriteUserCfg(FOLDER *f, USER *u)
4253 {
4254 	BUF *b;
4255 	AUTHPASSWORD *password;
4256 	AUTHRADIUS *radius;
4257 	AUTHNT *nt;
4258 	AUTHUSERCERT *usercert;
4259 	AUTHROOTCERT *rootcert;
4260 	// Validate arguments
4261 	if (f == NULL || u == NULL)
4262 	{
4263 		return;
4264 	}
4265 
4266 	Lock(u->lock);
4267 	{
4268 		CfgAddUniStr(f, "RealName", u->RealName);
4269 		CfgAddUniStr(f, "Note", u->Note);
4270 		if (u->Group != NULL)
4271 		{
4272 			CfgAddStr(f, "GroupName", u->GroupName);
4273 		}
4274 		CfgAddInt64(f, "CreatedTime", u->CreatedTime);
4275 		CfgAddInt64(f, "UpdatedTime", u->UpdatedTime);
4276 		CfgAddInt64(f, "ExpireTime", u->ExpireTime);
4277 		CfgAddInt64(f, "LastLoginTime", u->LastLoginTime);
4278 		CfgAddInt(f, "NumLogin", u->NumLogin);
4279 		if (u->Policy != NULL)
4280 		{
4281 			SiWritePolicyCfg(CfgCreateFolder(f, "Policy"), u->Policy, false);
4282 		}
4283 		SiWriteTraffic(f, "Traffic", u->Traffic);
4284 
4285 		CfgAddInt(f, "AuthType", u->AuthType);
4286 		if (u->AuthData != NULL)
4287 		{
4288 			switch (u->AuthType)
4289 			{
4290 			case AUTHTYPE_ANONYMOUS:
4291 				break;
4292 
4293 			case AUTHTYPE_PASSWORD:
4294 				password = (AUTHPASSWORD *)u->AuthData;
4295 				CfgAddByte(f, "AuthPassword", password->HashedKey, sizeof(password->HashedKey));
4296 
4297 				if (IsZero(password->NtLmSecureHash, sizeof(password->NtLmSecureHash)) == false)
4298 				{
4299 					CfgAddByte(f, "AuthNtLmSecureHash", password->NtLmSecureHash, sizeof(password->NtLmSecureHash));
4300 				}
4301 				break;
4302 
4303 			case AUTHTYPE_NT:
4304 				nt = (AUTHNT *)u->AuthData;
4305 				CfgAddUniStr(f, "AuthNtUserName", nt->NtUsername);
4306 				break;
4307 
4308 			case AUTHTYPE_RADIUS:
4309 				radius = (AUTHRADIUS *)u->AuthData;
4310 				CfgAddUniStr(f, "AuthRadiusUsername", radius->RadiusUsername);
4311 				break;
4312 
4313 			case AUTHTYPE_USERCERT:
4314 				usercert = (AUTHUSERCERT *)u->AuthData;
4315 				b = XToBuf(usercert->UserX, false);
4316 				if (b != NULL)
4317 				{
4318 					CfgAddBuf(f, "AuthUserCert", b);
4319 					FreeBuf(b);
4320 				}
4321 				break;
4322 
4323 			case AUTHTYPE_ROOTCERT:
4324 				rootcert = (AUTHROOTCERT *)u->AuthData;
4325 				if (rootcert->Serial != NULL && rootcert->Serial->size >= 1)
4326 				{
4327 					CfgAddByte(f, "AuthSerial", rootcert->Serial->data, rootcert->Serial->size);
4328 				}
4329 				if (rootcert->CommonName != NULL && UniIsEmptyStr(rootcert->CommonName) == false)
4330 				{
4331 					CfgAddUniStr(f, "AuthCommonName", rootcert->CommonName);
4332 				}
4333 				break;
4334 			}
4335 		}
4336 	}
4337 	Unlock(u->lock);
4338 }
4339 
4340 // Read an user
SiLoadUserCfg(HUB * h,FOLDER * f)4341 void SiLoadUserCfg(HUB *h, FOLDER *f)
4342 {
4343 	char *username;
4344 	wchar_t realname[MAX_SIZE];
4345 	wchar_t note[MAX_SIZE];
4346 	char groupname[MAX_SIZE];
4347 	FOLDER *pf;
4348 	UINT64 created_time;
4349 	UINT64 updated_time;
4350 	UINT64 expire_time;
4351 	UINT64 last_login_time;
4352 	UINT num_login;
4353 	POLICY p;
4354 	TRAFFIC t;
4355 	BUF *b;
4356 	UINT authtype;
4357 	void *authdata;
4358 	X_SERIAL *serial = NULL;
4359 	wchar_t common_name[MAX_SIZE];
4360 	UCHAR hashed_password[SHA1_SIZE];
4361 	UCHAR md4_password[MD5_SIZE];
4362 	wchar_t tmp[MAX_SIZE];
4363 	USER *u;
4364 	USERGROUP *g;
4365 	// Validate arguments
4366 	if (h == NULL || f == NULL)
4367 	{
4368 		return;
4369 	}
4370 
4371 	username = f->Name;
4372 	CfgGetUniStr(f, "RealName", realname, sizeof(realname));
4373 	CfgGetUniStr(f, "Note", note, sizeof(note));
4374 	CfgGetStr(f, "GroupName", groupname, sizeof(groupname));
4375 
4376 	created_time = CfgGetInt64(f, "CreatedTime");
4377 	updated_time = CfgGetInt64(f, "UpdatedTime");
4378 	expire_time = CfgGetInt64(f, "ExpireTime");
4379 	last_login_time = CfgGetInt64(f, "LastLoginTime");
4380 	num_login = CfgGetInt(f, "NumLogin");
4381 	pf = CfgGetFolder(f, "Policy");
4382 	if (pf != NULL)
4383 	{
4384 		SiLoadPolicyCfg(&p, pf);
4385 	}
4386 	SiLoadTraffic(f, "Traffic", &t);
4387 
4388 	authtype = CfgGetInt(f, "AuthType");
4389 	authdata = NULL;
4390 
4391 	switch (authtype)
4392 	{
4393 	case AUTHTYPE_PASSWORD:
4394 		Zero(hashed_password, sizeof(hashed_password));
4395 		Zero(md4_password, sizeof(md4_password));
4396 		CfgGetByte(f, "AuthPassword", hashed_password, sizeof(hashed_password));
4397 		CfgGetByte(f, "AuthNtLmSecureHash", md4_password, sizeof(md4_password));
4398 		authdata = NewPasswordAuthDataRaw(hashed_password, md4_password);
4399 		break;
4400 
4401 	case AUTHTYPE_NT:
4402 		if (CfgGetUniStr(f, "AuthNtUserName", tmp, sizeof(tmp)))
4403 		{
4404 			authdata = NewNTAuthData(tmp);
4405 		}
4406 		else
4407 		{
4408 			authdata = NewNTAuthData(NULL);
4409 		}
4410 		break;
4411 
4412 	case AUTHTYPE_RADIUS:
4413 		if (CfgGetUniStr(f, "AuthRadiusUsername", tmp, sizeof(tmp)))
4414 		{
4415 			authdata = NewRadiusAuthData(tmp);
4416 		}
4417 		else
4418 		{
4419 			authdata = NewRadiusAuthData(NULL);
4420 		}
4421 		break;
4422 
4423 	case AUTHTYPE_USERCERT:
4424 		b = CfgGetBuf(f, "AuthUserCert");
4425 		if (b != NULL)
4426 		{
4427 			X *x = BufToX(b, false);
4428 			if (x != NULL)
4429 			{
4430 				authdata = NewUserCertAuthData(x);
4431 				FreeX(x);
4432 			}
4433 			FreeBuf(b);
4434 		}
4435 		break;
4436 
4437 	case AUTHTYPE_ROOTCERT:
4438 		b = CfgGetBuf(f, "AuthSerial");
4439 		if (b != NULL)
4440 		{
4441 			serial = NewXSerial(b->Buf, b->Size);
4442 			FreeBuf(b);
4443 		}
4444 		CfgGetUniStr(f, "AuthCommonName", common_name, sizeof(common_name));
4445 		authdata = NewRootCertAuthData(serial, common_name);
4446 		break;
4447 	}
4448 
4449 	// Add an user
4450 	AcLock(h);
4451 	{
4452 		if (StrLen(groupname) > 0)
4453 		{
4454 			g = AcGetGroup(h, groupname);
4455 		}
4456 		else
4457 		{
4458 			g = NULL;
4459 		}
4460 
4461 		u = NewUser(username, realname, note, authtype, authdata);
4462 		if (u != NULL)
4463 		{
4464 			if (g != NULL)
4465 			{
4466 				JoinUserToGroup(u, g);
4467 			}
4468 
4469 			SetUserTraffic(u, &t);
4470 
4471 			if (pf != NULL)
4472 			{
4473 				SetUserPolicy(u, &p);
4474 			}
4475 
4476 			Lock(u->lock);
4477 			{
4478 				u->CreatedTime = created_time;
4479 				u->UpdatedTime = updated_time;
4480 				u->ExpireTime = expire_time;
4481 				u->LastLoginTime = last_login_time;
4482 				u->NumLogin = num_login;
4483 			}
4484 			Unlock(u->lock);
4485 
4486 			AcAddUser(h, u);
4487 
4488 			ReleaseUser(u);
4489 		}
4490 
4491 		if (g != NULL)
4492 		{
4493 			ReleaseGroup(g);
4494 		}
4495 	}
4496 	AcUnlock(h);
4497 
4498 	if (serial != NULL)
4499 	{
4500 		FreeXSerial(serial);
4501 	}
4502 }
4503 
4504 // Write the user list
SiWriteUserList(FOLDER * f,LIST * o)4505 void SiWriteUserList(FOLDER *f, LIST *o)
4506 {
4507 	// Validate arguments
4508 	if (f == NULL || o == NULL)
4509 	{
4510 		return;
4511 	}
4512 
4513 	LockList(o);
4514 	{
4515 		UINT i;
4516 		for (i = 0;i < LIST_NUM(o);i++)
4517 		{
4518 			USER *u = LIST_DATA(o, i);
4519 			SiWriteUserCfg(CfgCreateFolder(f, u->Name), u);
4520 		}
4521 	}
4522 	UnlockList(o);
4523 }
4524 
4525 // Read the user list
SiLoadUserList(HUB * h,FOLDER * f)4526 void SiLoadUserList(HUB *h, FOLDER *f)
4527 {
4528 	TOKEN_LIST *t;
4529 	UINT i;
4530 	char *name;
4531 	// Validate arguments
4532 	if (f == NULL || h == NULL)
4533 	{
4534 		return;
4535 	}
4536 
4537 	t = CfgEnumFolderToTokenList(f);
4538 
4539 	for (i = 0;i < t->NumTokens;i++)
4540 	{
4541 		FOLDER *ff;
4542 		name = t->Token[i];
4543 		ff = CfgGetFolder(f, name);
4544 		SiLoadUserCfg(h, ff);
4545 	}
4546 
4547 	FreeToken(t);
4548 }
4549 
4550 // Write the group information
SiWriteGroupCfg(FOLDER * f,USERGROUP * g)4551 void SiWriteGroupCfg(FOLDER *f, USERGROUP *g)
4552 {
4553 	// Validate arguments
4554 	if (f == NULL || g == NULL)
4555 	{
4556 		return;
4557 	}
4558 
4559 	Lock(g->lock);
4560 	{
4561 		CfgAddUniStr(f, "RealName", g->RealName);
4562 		CfgAddUniStr(f, "Note", g->Note);
4563 		if (g->Policy != NULL)
4564 		{
4565 			SiWritePolicyCfg(CfgCreateFolder(f, "Policy"), g->Policy, false);
4566 		}
4567 		SiWriteTraffic(f, "Traffic", g->Traffic);
4568 	}
4569 	Unlock(g->lock);
4570 }
4571 
4572 // Read the group information
SiLoadGroupCfg(HUB * h,FOLDER * f)4573 void SiLoadGroupCfg(HUB *h, FOLDER *f)
4574 {
4575 	wchar_t realname[MAX_SIZE];
4576 	wchar_t note[MAX_SIZE];
4577 	char *name;
4578 	FOLDER *pf;
4579 	POLICY p;
4580 	TRAFFIC t;
4581 	USERGROUP *g;
4582 	// Validate arguments
4583 	if (h == NULL || f == NULL)
4584 	{
4585 		return;
4586 	}
4587 
4588 	name = f->Name;
4589 
4590 	CfgGetUniStr(f, "RealName", realname, sizeof(realname));
4591 	CfgGetUniStr(f, "Note", note, sizeof(note));
4592 
4593 	pf = CfgGetFolder(f, "Policy");
4594 	if (pf != NULL)
4595 	{
4596 		SiLoadPolicyCfg(&p, pf);
4597 	}
4598 
4599 	SiLoadTraffic(f, "Traffic", &t);
4600 
4601 	g = NewGroup(name, realname, note);
4602 	if (g == NULL)
4603 	{
4604 		return;
4605 	}
4606 
4607 	if (pf != NULL)
4608 	{
4609 		SetGroupPolicy(g, &p);
4610 	}
4611 
4612 	SetGroupTraffic(g, &t);
4613 
4614 	AcLock(h);
4615 	{
4616 		AcAddGroup(h, g);
4617 	}
4618 	AcUnlock(h);
4619 
4620 	ReleaseGroup(g);
4621 }
4622 
4623 // Write the group list
SiWriteGroupList(FOLDER * f,LIST * o)4624 void SiWriteGroupList(FOLDER *f, LIST *o)
4625 {
4626 	// Validate arguments
4627 	if (f == NULL || o == NULL)
4628 	{
4629 		return;
4630 	}
4631 
4632 	LockList(o);
4633 	{
4634 		UINT i;
4635 		for (i = 0;i < LIST_NUM(o);i++)
4636 		{
4637 			USERGROUP *g = LIST_DATA(o, i);
4638 			SiWriteGroupCfg(CfgCreateFolder(f, g->Name), g);
4639 		}
4640 	}
4641 	UnlockList(o);
4642 }
4643 
4644 // Read the group List
SiLoadGroupList(HUB * h,FOLDER * f)4645 void SiLoadGroupList(HUB *h, FOLDER *f)
4646 {
4647 	TOKEN_LIST *t;
4648 	UINT i;
4649 	char *name;
4650 	// Validate arguments
4651 	if (f == NULL || h == NULL)
4652 	{
4653 		return;
4654 	}
4655 
4656 	t = CfgEnumFolderToTokenList(f);
4657 
4658 	for (i = 0;i < t->NumTokens;i++)
4659 	{
4660 		name = t->Token[i];
4661 		SiLoadGroupCfg(h, CfgGetFolder(f, name));
4662 	}
4663 
4664 	FreeToken(t);
4665 }
4666 
4667 // Write the AC list
SiWriteAcList(FOLDER * f,LIST * o)4668 void SiWriteAcList(FOLDER *f, LIST *o)
4669 {
4670 	// Validate arguments
4671 	if (f == NULL || o == NULL)
4672 	{
4673 		return;
4674 	}
4675 
4676 	LockList(o);
4677 	{
4678 		UINT i;
4679 		for (i = 0;i < LIST_NUM(o);i++)
4680 		{
4681 			char name[MAX_SIZE];
4682 			AC *ac = LIST_DATA(o, i);
4683 			FOLDER *ff;
4684 
4685 			Format(name, sizeof(name), "Acl%u", i + 1);
4686 
4687 			ff = CfgCreateFolder(f, name);
4688 
4689 			CfgAddBool(ff, "Deny", ac->Deny);
4690 			CfgAddInt(ff, "Priority", ac->Priority);
4691 			CfgAddIp(ff, "IpAddress", &ac->IpAddress);
4692 
4693 			if (ac->Masked)
4694 			{
4695 				CfgAddIp(ff, "NetMask", &ac->SubnetMask);
4696 			}
4697 		}
4698 	}
4699 	UnlockList(o);
4700 }
4701 
4702 // Read the AC list
SiLoadAcList(LIST * o,FOLDER * f)4703 void SiLoadAcList(LIST *o, FOLDER *f)
4704 {
4705 	// Validate arguments
4706 	if (o == NULL || f == NULL)
4707 	{
4708 		return;
4709 	}
4710 
4711 	LockList(o);
4712 	{
4713 		TOKEN_LIST *t = CfgEnumFolderToTokenList(f);
4714 
4715 		if (t != NULL)
4716 		{
4717 			UINT i;
4718 
4719 			for (i = 0;i < t->NumTokens;i++)
4720 			{
4721 				FOLDER *ff = CfgGetFolder(f, t->Token[i]);
4722 
4723 				if (ff != NULL)
4724 				{
4725 					AC ac;
4726 
4727 					Zero(&ac, sizeof(ac));
4728 					ac.Deny = CfgGetBool(ff, "Deny");
4729 					ac.Priority = CfgGetInt(ff, "Priority");
4730 					CfgGetIp(ff, "IpAddress", &ac.IpAddress);
4731 
4732 					if (CfgGetIp(ff, "NetMask", &ac.SubnetMask))
4733 					{
4734 						ac.Masked = true;
4735 					}
4736 
4737 					AddAc(o, &ac);
4738 				}
4739 			}
4740 
4741 			FreeToken(t);
4742 		}
4743 	}
4744 	UnlockList(o);
4745 }
4746 
4747 // Write the certificate revocation list
SiWriteCrlList(FOLDER * f,LIST * o)4748 void SiWriteCrlList(FOLDER *f, LIST *o)
4749 {
4750 	// Validate arguments
4751 	if (f == NULL || o == NULL)
4752 	{
4753 		return;
4754 	}
4755 
4756 	LockList(o);
4757 	{
4758 		UINT i;
4759 		for (i = 0;i < LIST_NUM(o);i++)
4760 		{
4761 			char name[MAX_SIZE];
4762 			CRL *crl = LIST_DATA(o, i);
4763 			FOLDER *ff;
4764 			NAME *n;
4765 
4766 			Format(name, sizeof(name), "Crl%u", i);
4767 
4768 			ff = CfgCreateFolder(f, name);
4769 			n = crl->Name;
4770 
4771 			if (UniIsEmptyStr(n->CommonName) == false)
4772 			{
4773 				CfgAddUniStr(ff, "CommonName", n->CommonName);
4774 			}
4775 
4776 			if (UniIsEmptyStr(n->Organization) == false)
4777 			{
4778 				CfgAddUniStr(ff, "Organization", n->Organization);
4779 			}
4780 
4781 			if (UniIsEmptyStr(n->Unit) == false)
4782 			{
4783 				CfgAddUniStr(ff, "Unit", n->Unit);
4784 			}
4785 
4786 			if (UniIsEmptyStr(n->Country) == false)
4787 			{
4788 				CfgAddUniStr(ff, "Country", n->Country);
4789 			}
4790 
4791 			if (UniIsEmptyStr(n->State) == false)
4792 			{
4793 				CfgAddUniStr(ff, "State", n->State);
4794 			}
4795 
4796 			if (UniIsEmptyStr(n->Local) == false)
4797 			{
4798 				CfgAddUniStr(ff, "Local", n->Local);
4799 			}
4800 
4801 			if (IsZero(crl->DigestMD5, MD5_SIZE) == false)
4802 			{
4803 				char tmp[MAX_SIZE];
4804 
4805 				BinToStr(tmp, sizeof(tmp), crl->DigestMD5, MD5_SIZE);
4806 				CfgAddStr(ff, "DigestMD5", tmp);
4807 			}
4808 
4809 			if (IsZero(crl->DigestSHA1, SHA1_SIZE) == false)
4810 			{
4811 				char tmp[MAX_SIZE];
4812 
4813 				BinToStr(tmp, sizeof(tmp), crl->DigestSHA1, SHA1_SIZE);
4814 				CfgAddStr(ff, "DigestSHA1", tmp);
4815 			}
4816 
4817 			if (crl->Serial != NULL)
4818 			{
4819 				char tmp[MAX_SIZE];
4820 
4821 				BinToStr(tmp, sizeof(tmp), crl->Serial->data, crl->Serial->size);
4822 				CfgAddStr(ff, "Serial", tmp);
4823 			}
4824 		}
4825 	}
4826 	UnlockList(o);
4827 }
4828 
4829 // Read the certificate revocation list
SiLoadCrlList(LIST * o,FOLDER * f)4830 void SiLoadCrlList(LIST *o, FOLDER *f)
4831 {
4832 	// Validate arguments
4833 	if (o == NULL || f == NULL)
4834 	{
4835 		return;
4836 	}
4837 
4838 	LockList(o);
4839 	{
4840 		UINT i;
4841 		TOKEN_LIST *t;
4842 
4843 		t = CfgEnumFolderToTokenList(f);
4844 
4845 		for (i = 0;i < t->NumTokens;i++)
4846 		{
4847 			CRL *crl;
4848 			FOLDER *ff = CfgGetFolder(f, t->Token[i]);
4849 			wchar_t cn[MAX_SIZE], org[MAX_SIZE], u[MAX_SIZE], c[MAX_SIZE],
4850 				st[MAX_SIZE], l[MAX_SIZE];
4851 			char tmp[MAX_SIZE];
4852 
4853 			if (ff != NULL)
4854 			{
4855 				BUF *b;
4856 
4857 				crl = ZeroMalloc(sizeof(CRL));
4858 
4859 				CfgGetUniStr(ff, "CommonName", cn, sizeof(cn));
4860 				CfgGetUniStr(ff, "Organization", org, sizeof(org));
4861 				CfgGetUniStr(ff, "Unit", u, sizeof(u));
4862 				CfgGetUniStr(ff, "Country", c, sizeof(c));
4863 				CfgGetUniStr(ff, "State", st, sizeof(st));
4864 				CfgGetUniStr(ff, "Local", l, sizeof(l));
4865 
4866 				crl->Name = NewName(cn, org, u, c, st, l);
4867 
4868 				if (CfgGetStr(ff, "Serial", tmp, sizeof(tmp)))
4869 				{
4870 					b = StrToBin(tmp);
4871 
4872 					if (b != NULL)
4873 					{
4874 						if (b->Size >= 1)
4875 						{
4876 							crl->Serial = NewXSerial(b->Buf, b->Size);
4877 						}
4878 
4879 						FreeBuf(b);
4880 					}
4881 				}
4882 
4883 				if (CfgGetStr(ff, "DigestMD5", tmp, sizeof(tmp)))
4884 				{
4885 					b = StrToBin(tmp);
4886 
4887 					if (b != NULL)
4888 					{
4889 						if (b->Size == MD5_SIZE)
4890 						{
4891 							Copy(crl->DigestMD5, b->Buf, MD5_SIZE);
4892 						}
4893 
4894 						FreeBuf(b);
4895 					}
4896 				}
4897 
4898 				if (CfgGetStr(ff, "DigestSHA1", tmp, sizeof(tmp)))
4899 				{
4900 					b = StrToBin(tmp);
4901 
4902 					if (b != NULL)
4903 					{
4904 						if (b->Size == SHA1_SIZE)
4905 						{
4906 							Copy(crl->DigestSHA1, b->Buf, SHA1_SIZE);
4907 						}
4908 
4909 						FreeBuf(b);
4910 					}
4911 				}
4912 
4913 				Insert(o, crl);
4914 			}
4915 		}
4916 
4917 		FreeToken(t);
4918 	}
4919 	UnlockList(o);
4920 }
4921 
4922 // Write the certificates list
SiWriteCertList(FOLDER * f,LIST * o)4923 void SiWriteCertList(FOLDER *f, LIST *o)
4924 {
4925 	// Validate arguments
4926 	if (f == NULL || o == NULL)
4927 	{
4928 		return;
4929 	}
4930 
4931 	LockList(o);
4932 	{
4933 		UINT i;
4934 		X *x;
4935 		for (i = 0;i < LIST_NUM(o);i++)
4936 		{
4937 			char name[MAX_SIZE];
4938 			BUF *b;
4939 			x = LIST_DATA(o, i);
4940 			Format(name, sizeof(name), "Cert%u", i);
4941 			b = XToBuf(x, false);
4942 			if (b != NULL)
4943 			{
4944 				CfgAddBuf(CfgCreateFolder(f, name), "X509", b);
4945 				FreeBuf(b);
4946 			}
4947 		}
4948 	}
4949 	UnlockList(o);
4950 }
4951 
4952 // Read the certificates list
SiLoadCertList(LIST * o,FOLDER * f)4953 void SiLoadCertList(LIST *o, FOLDER *f)
4954 {
4955 	// Validate arguments
4956 	if (o == NULL || f == NULL)
4957 	{
4958 		return;
4959 	}
4960 
4961 	LockList(o);
4962 	{
4963 		UINT i;
4964 		TOKEN_LIST *t;
4965 
4966 		t = CfgEnumFolderToTokenList(f);
4967 
4968 		for (i = 0;i < t->NumTokens;i++)
4969 		{
4970 			FOLDER *ff = CfgGetFolder(f, t->Token[i]);
4971 			BUF *b;
4972 
4973 			b = CfgGetBuf(ff, "X509");
4974 			if (b != NULL)
4975 			{
4976 				X *x = BufToX(b, false);
4977 				if (x != NULL)
4978 				{
4979 					Insert(o, x);
4980 				}
4981 				FreeBuf(b);
4982 			}
4983 		}
4984 
4985 		FreeToken(t);
4986 	}
4987 	UnlockList(o);
4988 }
4989 
4990 // Write the database
SiWriteHubDb(FOLDER * f,HUBDB * db,bool no_save_ac_list)4991 void SiWriteHubDb(FOLDER *f, HUBDB *db, bool no_save_ac_list)
4992 {
4993 	// Validate arguments
4994 	if (f == NULL || db == NULL)
4995 	{
4996 		return;
4997 	}
4998 
4999 	SiWriteUserList(CfgCreateFolder(f, "UserList"), db->UserList);
5000 	SiWriteGroupList(CfgCreateFolder(f, "GroupList"), db->GroupList);
5001 	SiWriteCertList(CfgCreateFolder(f, "CertList"), db->RootCertList);
5002 	SiWriteCrlList(CfgCreateFolder(f, "CrlList"), db->CrlList);
5003 
5004 	if (no_save_ac_list == false)
5005 	{
5006 		SiWriteAcList(CfgCreateFolder(f, "IPAccessControlList"), db->AcList);
5007 	}
5008 }
5009 
5010 // Read the database
SiLoadHubDb(HUB * h,FOLDER * f)5011 void SiLoadHubDb(HUB *h, FOLDER *f)
5012 {
5013 	// Validate arguments
5014 	if (f == NULL || h == NULL)
5015 	{
5016 		return;
5017 	}
5018 
5019 	SiLoadGroupList(h, CfgGetFolder(f, "GroupList"));
5020 	SiLoadUserList(h, CfgGetFolder(f, "UserList"));
5021 
5022 	if (h->HubDb != NULL)
5023 	{
5024 		SiLoadCertList(h->HubDb->RootCertList, CfgGetFolder(f, "CertList"));
5025 		SiLoadCrlList(h->HubDb->CrlList, CfgGetFolder(f, "CrlList"));
5026 		SiLoadAcList(h->HubDb->AcList, CfgGetFolder(f, "IPAccessControlList"));
5027 	}
5028 }
5029 
5030 // Write the Virtual HUB setting
SiWriteHubCfg(FOLDER * f,HUB * h)5031 void SiWriteHubCfg(FOLDER *f, HUB *h)
5032 {
5033 	// Validate arguments
5034 	if (f == NULL || h == NULL)
5035 	{
5036 		return;
5037 	}
5038 
5039 	// Radius server name
5040 	Lock(h->RadiusOptionLock);
5041 	{
5042 		if (h->RadiusServerName != NULL)
5043 		{
5044 			CfgAddStr(f, "RadiusServerName", h->RadiusServerName);
5045 			CfgAddBuf(f, "RadiusSecret", h->RadiusSecret);
5046 		}
5047 		CfgAddInt(f, "RadiusServerPort", h->RadiusServerPort);
5048 		CfgAddInt(f, "RadiusRetryInterval", h->RadiusRetryInterval);
5049 		CfgAddStr(f, "RadiusSuffixFilter", h->RadiusSuffixFilter);
5050 		CfgAddStr(f, "RadiusRealm", h->RadiusRealm);
5051 
5052 		CfgAddBool(f, "RadiusConvertAllMsChapv2AuthRequestToEap", h->RadiusConvertAllMsChapv2AuthRequestToEap);
5053 		CfgAddBool(f, "RadiusUsePeapInsteadOfEap", h->RadiusUsePeapInsteadOfEap);
5054 	}
5055 	Unlock(h->RadiusOptionLock);
5056 
5057 	// Password
5058 	CfgAddByte(f, "HashedPassword", h->HashedPassword, sizeof(h->HashedPassword));
5059 	CfgAddByte(f, "SecurePassword", h->SecurePassword, sizeof(h->SecurePassword));
5060 
5061 	// Online / Offline flag
5062 	if (h->Cedar->Bridge == false)
5063 	{
5064 		CfgAddBool(f, "Online", (h->Offline && (h->HubIsOnlineButHalting == false)) ? false : true);
5065 	}
5066 
5067 	// Traffic information
5068 	SiWriteTraffic(f, "Traffic", h->Traffic);
5069 
5070 	// HUB options
5071 	SiWriteHubOptionCfg(CfgCreateFolder(f, "Option"), h->Option);
5072 
5073 	// Message
5074 	{
5075 		FOLDER *folder = CfgCreateFolder(f, "Message");
5076 
5077 		if (IsEmptyUniStr(h->Msg) == false)
5078 		{
5079 			CfgAddUniStr(folder, "MessageText", h->Msg);
5080 		}
5081 	}
5082 
5083 	// HUB_LOG
5084 	SiWriteHubLogCfg(CfgCreateFolder(f, "LogSetting"), &h->LogSetting);
5085 
5086 	if (h->Type == HUB_TYPE_STANDALONE)
5087 	{
5088 		// Link list
5089 		SiWriteHubLinks(CfgCreateFolder(f, "CascadeList"), h);
5090 	}
5091 
5092 	if (h->Type != HUB_TYPE_FARM_STATIC)
5093 	{
5094 		if (GetServerCapsBool(h->Cedar->Server, "b_support_securenat"))
5095 		{
5096 			// SecureNAT
5097 			SiWriteSecureNAT(h, CfgCreateFolder(f, "SecureNAT"));
5098 		}
5099 	}
5100 
5101 	// Access list
5102 	SiWriteHubAccessLists(CfgCreateFolder(f, "AccessList"), h);
5103 
5104 	// Administration options
5105 	SiWriteHubAdminOptions(CfgCreateFolder(f, "AdminOption"), h);
5106 
5107 	// Type of HUB
5108 	CfgAddInt(f, "Type", h->Type);
5109 
5110 	// Database
5111 	if (h->Cedar->Bridge == false)
5112 	{
5113 		SiWriteHubDb(CfgCreateFolder(f, "SecurityAccountDatabase"), h->HubDb,
5114 			false
5115 			);
5116 	}
5117 
5118 	// Usage status
5119 	CfgAddInt64(f, "LastCommTime", h->LastCommTime);
5120 	CfgAddInt64(f, "LastLoginTime", h->LastLoginTime);
5121 	CfgAddInt64(f, "CreatedTime", h->CreatedTime);
5122 	CfgAddInt(f, "NumLogin", h->NumLogin);
5123 }
5124 
5125 // Read the logging options
SiLoadHubLogCfg(HUB_LOG * g,FOLDER * f)5126 void SiLoadHubLogCfg(HUB_LOG *g, FOLDER *f)
5127 {
5128 	// Validate arguments
5129 	if (f == NULL || g == NULL)
5130 	{
5131 		return;
5132 	}
5133 
5134 	Zero(g, sizeof(HUB_LOG));
5135 	g->SaveSecurityLog = CfgGetBool(f, "SaveSecurityLog");
5136 	g->SecurityLogSwitchType = CfgGetInt(f, "SecurityLogSwitchType");
5137 	g->SavePacketLog = CfgGetBool(f, "SavePacketLog");
5138 	g->PacketLogSwitchType = CfgGetInt(f, "PacketLogSwitchType");
5139 
5140 	g->PacketLogConfig[PACKET_LOG_TCP_CONN] = CfgGetInt(f, "PACKET_LOG_TCP_CONN");
5141 	g->PacketLogConfig[PACKET_LOG_TCP] = CfgGetInt(f, "PACKET_LOG_TCP");
5142 	g->PacketLogConfig[PACKET_LOG_DHCP] = CfgGetInt(f, "PACKET_LOG_DHCP");
5143 	g->PacketLogConfig[PACKET_LOG_UDP] = CfgGetInt(f, "PACKET_LOG_UDP");
5144 	g->PacketLogConfig[PACKET_LOG_ICMP] = CfgGetInt(f, "PACKET_LOG_ICMP");
5145 	g->PacketLogConfig[PACKET_LOG_IP] = CfgGetInt(f, "PACKET_LOG_IP");
5146 	g->PacketLogConfig[PACKET_LOG_ARP] = CfgGetInt(f, "PACKET_LOG_ARP");
5147 	g->PacketLogConfig[PACKET_LOG_ETHERNET] = CfgGetInt(f, "PACKET_LOG_ETHERNET");
5148 }
5149 
5150 // Write the logging options
SiWriteHubLogCfg(FOLDER * f,HUB_LOG * g)5151 void SiWriteHubLogCfg(FOLDER *f, HUB_LOG *g)
5152 {
5153 	SiWriteHubLogCfgEx(f, g, false);
5154 }
SiWriteHubLogCfgEx(FOLDER * f,HUB_LOG * g,bool el_mode)5155 void SiWriteHubLogCfgEx(FOLDER *f, HUB_LOG *g, bool el_mode)
5156 {
5157 	// Validate arguments
5158 	if (f == NULL || g == NULL)
5159 	{
5160 		return;
5161 	}
5162 
5163 	if (el_mode == false)
5164 	{
5165 		CfgAddBool(f, "SaveSecurityLog", g->SaveSecurityLog);
5166 		CfgAddInt(f, "SecurityLogSwitchType", g->SecurityLogSwitchType);
5167 		CfgAddBool(f, "SavePacketLog", g->SavePacketLog);
5168 	}
5169 
5170 	CfgAddInt(f, "PacketLogSwitchType", g->PacketLogSwitchType);
5171 
5172 	CfgAddInt(f, "PACKET_LOG_TCP_CONN", g->PacketLogConfig[PACKET_LOG_TCP_CONN]);
5173 	CfgAddInt(f, "PACKET_LOG_TCP", g->PacketLogConfig[PACKET_LOG_TCP]);
5174 	CfgAddInt(f, "PACKET_LOG_DHCP", g->PacketLogConfig[PACKET_LOG_DHCP]);
5175 	CfgAddInt(f, "PACKET_LOG_UDP", g->PacketLogConfig[PACKET_LOG_UDP]);
5176 	CfgAddInt(f, "PACKET_LOG_ICMP", g->PacketLogConfig[PACKET_LOG_ICMP]);
5177 	CfgAddInt(f, "PACKET_LOG_IP", g->PacketLogConfig[PACKET_LOG_IP]);
5178 	CfgAddInt(f, "PACKET_LOG_ARP", g->PacketLogConfig[PACKET_LOG_ARP]);
5179 	CfgAddInt(f, "PACKET_LOG_ETHERNET", g->PacketLogConfig[PACKET_LOG_ETHERNET]);
5180 }
5181 
5182 // Read the Virtual HUB settings
SiLoadHubCfg(SERVER * s,FOLDER * f,char * name)5183 void SiLoadHubCfg(SERVER *s, FOLDER *f, char *name)
5184 {
5185 	HUB *h;
5186 	CEDAR *c;
5187 	HUB_OPTION o;
5188 	bool online;
5189 	UINT hub_old_type = 0;
5190 	// Validate arguments
5191 	if (s == NULL || f == NULL || name == NULL)
5192 	{
5193 		return;
5194 	}
5195 
5196 	c = s->Cedar;
5197 
5198 	// Get the option
5199 	Zero(&o, sizeof(o));
5200 	SiLoadHubOptionCfg(CfgGetFolder(f, "Option"), &o);
5201 
5202 	// Create a HUB
5203 	h = NewHub(c, name, &o);
5204 	if (h != NULL)
5205 	{
5206 		HUB_LOG g;
5207 		// Radius server settings
5208 		Lock(h->RadiusOptionLock);
5209 		{
5210 			char name[MAX_SIZE];
5211 			BUF *secret;
5212 			UINT port;
5213 			UINT interval;
5214 
5215 			port = CfgGetInt(f, "RadiusServerPort");
5216 			interval = CfgGetInt(f, "RadiusRetryInterval");
5217 
5218 			CfgGetStr(f, "RadiusSuffixFilter", h->RadiusSuffixFilter, sizeof(h->RadiusSuffixFilter));
5219 			CfgGetStr(f, "RadiusRealm", h->RadiusRealm, sizeof(h->RadiusRealm));
5220 
5221 			h->RadiusConvertAllMsChapv2AuthRequestToEap = CfgGetBool(f, "RadiusConvertAllMsChapv2AuthRequestToEap");
5222 			h->RadiusUsePeapInsteadOfEap = CfgGetBool(f, "RadiusUsePeapInsteadOfEap");
5223 
5224 			if (interval == 0)
5225 			{
5226 				interval = RADIUS_RETRY_INTERVAL;
5227 			}
5228 
5229 			if (port != 0 && CfgGetStr(f, "RadiusServerName", name, sizeof(name)))
5230 			{
5231 				secret = CfgGetBuf(f, "RadiusSecret");
5232 				if (secret != NULL)
5233 				{
5234 					char secret_str[MAX_SIZE];
5235 					Zero(secret_str, sizeof(secret_str));
5236 					if (secret->Size < sizeof(secret_str))
5237 					{
5238 						Copy(secret_str, secret->Buf, secret->Size);
5239 					}
5240 					secret_str[sizeof(secret_str) - 1] = 0;
5241 					//SetRadiusServer(h, name, port, secret_str);
5242 					SetRadiusServerEx(h, name, port, secret_str, interval);
5243 					FreeBuf(secret);
5244 				}
5245 			}
5246 		}
5247 		Unlock(h->RadiusOptionLock);
5248 
5249 		// Password
5250 		if (CfgGetByte(f, "HashedPassword", h->HashedPassword, sizeof(h->HashedPassword)) != sizeof(h->HashedPassword))
5251 		{
5252 			Hash(h->HashedPassword, "", 0, true);
5253 		}
5254 		if (CfgGetByte(f, "SecurePassword", h->SecurePassword, sizeof(h->SecurePassword)) != sizeof(h->SecurePassword))
5255 		{
5256 			HashPassword(h->SecurePassword, ADMINISTRATOR_USERNAME, "");
5257 		}
5258 
5259 		// Log Settings
5260 		Zero(&g, sizeof(g));
5261 		SiLoadHubLogCfg(&g, CfgGetFolder(f, "LogSetting"));
5262 		SetHubLogSetting(h, &g);
5263 
5264 		// Online / Offline flag
5265 		if (h->Cedar->Bridge == false)
5266 		{
5267 			online = CfgGetBool(f, "Online");
5268 		}
5269 		else
5270 		{
5271 			online = true;
5272 		}
5273 
5274 		// Traffic information
5275 		SiLoadTraffic(f, "Traffic", h->Traffic);
5276 
5277 		// Access list
5278 		SiLoadHubAccessLists(h, CfgGetFolder(f, "AccessList"));
5279 
5280 		// Type of HUB
5281 		hub_old_type = h->Type = CfgGetInt(f, "Type");
5282 
5283 		if (s->ServerType == SERVER_TYPE_STANDALONE)
5284 		{
5285 			if (h->Type != HUB_TYPE_STANDALONE)
5286 			{
5287 				// Change the type of all HUB to a stand-alone if the server is a stand-alone
5288 				h->Type = HUB_TYPE_STANDALONE;
5289 			}
5290 		}
5291 		else
5292 		{
5293 			if (h->Type == HUB_TYPE_STANDALONE)
5294 			{
5295 				// If the server is a farm controller, change the type of HUB to the farm supported types
5296 				h->Type = HUB_TYPE_FARM_DYNAMIC;
5297 			}
5298 		}
5299 
5300 		if (h->Type == HUB_TYPE_FARM_DYNAMIC)
5301 		{
5302 			h->CurrentVersion = h->LastVersion = 1;
5303 		}
5304 
5305 		// Message
5306 		{
5307 			FOLDER *folder = CfgGetFolder(f, "Message");
5308 			if (folder != NULL)
5309 			{
5310 				wchar_t *tmp = Malloc(sizeof(wchar_t) * (HUB_MAXMSG_LEN + 1));
5311 				if (CfgGetUniStr(folder, "MessageText", tmp, sizeof(wchar_t) * (HUB_MAXMSG_LEN + 1)))
5312 				{
5313 					SetHubMsg(h, tmp);
5314 				}
5315 				Free(tmp);
5316 			}
5317 		}
5318 
5319 		// Link list
5320 		if (h->Type == HUB_TYPE_STANDALONE)
5321 		{
5322 			// The link list is used only on stand-alone HUB
5323 			// In VPN Gate hubs, don't load this
5324 			{
5325 				SiLoadHubLinks(h, CfgGetFolder(f, "CascadeList"));
5326 			}
5327 		}
5328 
5329 		// SecureNAT
5330 		if (GetServerCapsBool(h->Cedar->Server, "b_support_securenat"))
5331 		{
5332 			if (h->Type == HUB_TYPE_STANDALONE || h->Type == HUB_TYPE_FARM_DYNAMIC)
5333 			{
5334 				// SecureNAT is used only in the case of dynamic HUB or standalone HUB
5335 				SiLoadSecureNAT(h, CfgGetFolder(f, "SecureNAT"));
5336 
5337 				if (h->Type != HUB_TYPE_STANDALONE && h->Cedar != NULL && h->Cedar->Server != NULL &&
5338 					h->Cedar->Server->ServerType == SERVER_TYPE_FARM_CONTROLLER)
5339 				{
5340 					NiClearUnsupportedVhOptionForDynamicHub(h->SecureNATOption,
5341 						hub_old_type == HUB_TYPE_STANDALONE);
5342 				}
5343 
5344 			}
5345 		}
5346 
5347 		// Administration options
5348 		SiLoadHubAdminOptions(h, CfgGetFolder(f, "AdminOption"));
5349 
5350 		// Database
5351 		if (h->Cedar->Bridge == false)
5352 		{
5353 			SiLoadHubDb(h, CfgGetFolder(f, "SecurityAccountDatabase"));
5354 		}
5355 
5356 		// Usage status
5357 		h->LastCommTime = CfgGetInt64(f, "LastCommTime");
5358 		if (h->LastCommTime == 0)
5359 		{
5360 			h->LastCommTime = SystemTime64();
5361 		}
5362 		h->LastLoginTime = CfgGetInt64(f, "LastLoginTime");
5363 		if (h->LastLoginTime == 0)
5364 		{
5365 			h->LastLoginTime = SystemTime64();
5366 		}
5367 		h->CreatedTime = CfgGetInt64(f, "CreatedTime");
5368 		h->NumLogin = CfgGetInt(f, "NumLogin");
5369 
5370 		// Start the operation of the HUB
5371 		AddHub(c, h);
5372 
5373 		if (online)
5374 		{
5375 			h->Offline = true;
5376 			SetHubOnline(h);
5377 		}
5378 		else
5379 		{
5380 			h->Offline = false;
5381 			SetHubOffline(h);
5382 		}
5383 
5384 		WaitLogFlush(h->SecurityLogger);
5385 		WaitLogFlush(h->PacketLogger);
5386 
5387 		ReleaseHub(h);
5388 	}
5389 }
5390 
5391 // Read the SecureNAT configuration
SiLoadSecureNAT(HUB * h,FOLDER * f)5392 void SiLoadSecureNAT(HUB *h, FOLDER *f)
5393 {
5394 	VH_OPTION o;
5395 	// Validate arguments
5396 	if (h == NULL || f == NULL)
5397 	{
5398 		return;
5399 	}
5400 
5401 	// Read the VH_OPTION
5402 	NiLoadVhOptionEx(&o, f);
5403 
5404 	// Set the VH_OPTION
5405 	Copy(h->SecureNATOption, &o, sizeof(VH_OPTION));
5406 
5407 	EnableSecureNAT(h, CfgGetBool(f, "Disabled") ? false : true);
5408 }
5409 
5410 // Read the virtual layer 3 switch settings
SiLoadL3SwitchCfg(L3SW * sw,FOLDER * f)5411 void SiLoadL3SwitchCfg(L3SW *sw, FOLDER *f)
5412 {
5413 	UINT i;
5414 	FOLDER *if_folder, *table_folder;
5415 	TOKEN_LIST *t;
5416 	bool active = false;
5417 	// Validate arguments
5418 	if (sw == NULL || f == NULL)
5419 	{
5420 		return;
5421 	}
5422 
5423 	active = CfgGetBool(f, "Active");
5424 
5425 	// Interface list
5426 	if_folder = CfgGetFolder(f, "InterfaceList");
5427 	if (if_folder != NULL)
5428 	{
5429 		t = CfgEnumFolderToTokenList(if_folder);
5430 		if (t != NULL)
5431 		{
5432 			for (i = 0;i < t->NumTokens;i++)
5433 			{
5434 				FOLDER *ff = CfgGetFolder(if_folder, t->Token[i]);
5435 				char name[MAX_HUBNAME_LEN + 1];
5436 				UINT ip, subnet;
5437 
5438 				CfgGetStr(ff, "HubName", name, sizeof(name));
5439 				ip = CfgGetIp32(ff, "IpAddress");
5440 				subnet = CfgGetIp32(ff, "SubnetMask");
5441 
5442 				{
5443 					L3AddIf(sw, name, ip, subnet);
5444 				}
5445 			}
5446 			FreeToken(t);
5447 		}
5448 	}
5449 
5450 	// Routing table
5451 	table_folder = CfgGetFolder(f, "RoutingTable");
5452 	if (table_folder != NULL)
5453 	{
5454 		t = CfgEnumFolderToTokenList(table_folder);
5455 		if (t != NULL)
5456 		{
5457 			for (i = 0;i < t->NumTokens;i++)
5458 			{
5459 				FOLDER *ff = CfgGetFolder(table_folder, t->Token[i]);
5460 				L3TABLE tbl;
5461 
5462 				Zero(&tbl, sizeof(tbl));
5463 				tbl.NetworkAddress = CfgGetIp32(ff, "NetworkAddress");
5464 				tbl.SubnetMask = CfgGetIp32(ff, "SubnetMask");
5465 				tbl.GatewayAddress = CfgGetIp32(ff, "GatewayAddress");
5466 				tbl.Metric = CfgGetInt(ff, "Metric");
5467 
5468 				L3AddTable(sw, &tbl);
5469 			}
5470 			FreeToken(t);
5471 		}
5472 	}
5473 
5474 	if (active)
5475 	{
5476 		L3SwStart(sw);
5477 	}
5478 }
5479 
5480 // Write the virtual layer 3 switch settings
SiWriteL3SwitchCfg(FOLDER * f,L3SW * sw)5481 void SiWriteL3SwitchCfg(FOLDER *f, L3SW *sw)
5482 {
5483 	UINT i;
5484 	FOLDER *if_folder, *table_folder;
5485 	char tmp[MAX_SIZE];
5486 	// Validate arguments
5487 	if (f == NULL || sw == NULL)
5488 	{
5489 		return;
5490 	}
5491 
5492 	// Active flag
5493 	CfgAddBool(f, "Active", sw->Active);
5494 
5495 	// Interface list
5496 	if_folder = CfgCreateFolder(f, "InterfaceList");
5497 	for (i = 0;i < LIST_NUM(sw->IfList);i++)
5498 	{
5499 		L3IF *e = LIST_DATA(sw->IfList, i);
5500 		FOLDER *ff;
5501 
5502 		Format(tmp, sizeof(tmp), "Interface%u", i);
5503 		ff = CfgCreateFolder(if_folder, tmp);
5504 
5505 		CfgAddStr(ff, "HubName", e->HubName);
5506 		CfgAddIp32(ff, "IpAddress", e->IpAddress);
5507 		CfgAddIp32(ff, "SubnetMask", e->SubnetMask);
5508 	}
5509 
5510 	// Routing table
5511 	table_folder = CfgCreateFolder(f, "RoutingTable");
5512 	for (i = 0;i < LIST_NUM(sw->TableList);i++)
5513 	{
5514 		L3TABLE *e = LIST_DATA(sw->TableList, i);
5515 		FOLDER *ff;
5516 
5517 		Format(tmp, sizeof(tmp), "Entry%u", i);
5518 		ff = CfgCreateFolder(table_folder, tmp);
5519 
5520 		CfgAddIp32(ff, "NetworkAddress", e->NetworkAddress);
5521 		CfgAddIp32(ff, "SubnetMask", e->SubnetMask);
5522 		CfgAddIp32(ff, "GatewayAddress", e->GatewayAddress);
5523 		CfgAddInt(ff, "Metric", e->Metric);
5524 	}
5525 }
5526 
5527 // Read the Virtual Layer 3 switch list
SiLoadL3Switchs(SERVER * s,FOLDER * f)5528 void SiLoadL3Switchs(SERVER *s, FOLDER *f)
5529 {
5530 	UINT i;
5531 	TOKEN_LIST *t;
5532 	CEDAR *c;
5533 	// Validate arguments
5534 	if (s == NULL || f == NULL)
5535 	{
5536 		return;
5537 	}
5538 	c = s->Cedar;
5539 
5540 	t = CfgEnumFolderToTokenList(f);
5541 	if (t != NULL)
5542 	{
5543 		for (i = 0;i < t->NumTokens;i++)
5544 		{
5545 			char *name = t->Token[i];
5546 			L3SW *sw = L3AddSw(c, name);
5547 
5548 			SiLoadL3SwitchCfg(sw, CfgGetFolder(f, name));
5549 
5550 			ReleaseL3Sw(sw);
5551 		}
5552 	}
5553 	FreeToken(t);
5554 }
5555 
5556 // Write the Virtual Layer 3 switch list
SiWriteL3Switchs(FOLDER * f,SERVER * s)5557 void SiWriteL3Switchs(FOLDER *f, SERVER *s)
5558 {
5559 	UINT i;
5560 	FOLDER *folder;
5561 	CEDAR *c;
5562 	// Validate arguments
5563 	if (f == NULL || s == NULL)
5564 	{
5565 		return;
5566 	}
5567 	c = s->Cedar;
5568 
5569 	LockList(c->L3SwList);
5570 	{
5571 		for (i = 0;i < LIST_NUM(c->L3SwList);i++)
5572 		{
5573 			L3SW *sw = LIST_DATA(c->L3SwList, i);
5574 
5575 			Lock(sw->lock);
5576 			{
5577 				folder = CfgCreateFolder(f, sw->Name);
5578 
5579 				SiWriteL3SwitchCfg(folder, sw);
5580 			}
5581 			Unlock(sw->lock);
5582 		}
5583 	}
5584 	UnlockList(c->L3SwList);
5585 }
5586 
5587 // Read the IPsec server configuration
SiLoadIPsec(SERVER * s,FOLDER * f)5588 void SiLoadIPsec(SERVER *s, FOLDER *f)
5589 {
5590 	IPSEC_SERVICES sl;
5591 	FOLDER *list_folder;
5592 	// Validate arguments
5593 	if (s == NULL || f == NULL)
5594 	{
5595 		return;
5596 	}
5597 
5598 	Zero(&sl, sizeof(sl));
5599 
5600 	CfgGetStr(f, "IPsec_Secret", sl.IPsec_Secret, sizeof(sl.IPsec_Secret));
5601 	CfgGetStr(f, "L2TP_DefaultHub", sl.L2TP_DefaultHub, sizeof(sl.L2TP_DefaultHub));
5602 
5603 	if (s->ServerType == SERVER_TYPE_STANDALONE)
5604 	{
5605 		// IPsec feature only be enabled on a standalone server
5606 		sl.L2TP_Raw = CfgGetBool(f, "L2TP_Raw");
5607 		sl.L2TP_IPsec = CfgGetBool(f, "L2TP_IPsec");
5608 		sl.EtherIP_IPsec = CfgGetBool(f, "EtherIP_IPsec");
5609 	}
5610 
5611 	IPsecServerSetServices(s->IPsecServer, &sl);
5612 
5613 	list_folder = CfgGetFolder(f, "EtherIP_IDSettingsList");
5614 
5615 	if (list_folder != NULL)
5616 	{
5617 		TOKEN_LIST *t = CfgEnumFolderToTokenList(list_folder);
5618 		if (t != NULL)
5619 		{
5620 			UINT i;
5621 
5622 			for (i = 0;i < t->NumTokens;i++)
5623 			{
5624 				char *name = t->Token[i];
5625 				FOLDER *f = CfgGetFolder(list_folder, name);
5626 
5627 				if (f != NULL)
5628 				{
5629 					ETHERIP_ID d;
5630 					BUF *b;
5631 
5632 					Zero(&d, sizeof(d));
5633 
5634 					StrCpy(d.Id, sizeof(d.Id), name);
5635 					CfgGetStr(f, "HubName", d.HubName, sizeof(d.HubName));
5636 					CfgGetStr(f, "UserName", d.UserName, sizeof(d.UserName));
5637 
5638 					b = CfgGetBuf(f, "EncryptedPassword");
5639 					if (b != NULL)
5640 					{
5641 						char *pass = DecryptPassword2(b);
5642 
5643 						StrCpy(d.Password, sizeof(d.Password), pass);
5644 
5645 						Free(pass);
5646 
5647 						AddEtherIPId(s->IPsecServer, &d);
5648 
5649 						FreeBuf(b);
5650 					}
5651 				}
5652 			}
5653 
5654 			FreeToken(t);
5655 		}
5656 	}
5657 }
5658 
5659 // Write the IPsec server configuration
SiWriteIPsec(FOLDER * f,SERVER * s)5660 void SiWriteIPsec(FOLDER *f, SERVER *s)
5661 {
5662 	IPSEC_SERVICES sl;
5663 	FOLDER *list_folder;
5664 	UINT i;
5665 	// Validate arguments
5666 	if (s == NULL || f == NULL)
5667 	{
5668 		return;
5669 	}
5670 
5671 	if (s->IPsecServer == NULL)
5672 	{
5673 		return;
5674 	}
5675 
5676 	Zero(&sl, sizeof(sl));
5677 	IPsecServerGetServices(s->IPsecServer, &sl);
5678 
5679 	CfgAddStr(f, "IPsec_Secret", sl.IPsec_Secret);
5680 	CfgAddStr(f, "L2TP_DefaultHub", sl.L2TP_DefaultHub);
5681 
5682 	CfgAddBool(f, "L2TP_Raw", sl.L2TP_Raw);
5683 	CfgAddBool(f, "L2TP_IPsec", sl.L2TP_IPsec);
5684 	CfgAddBool(f, "EtherIP_IPsec", sl.EtherIP_IPsec);
5685 
5686 	list_folder = CfgCreateFolder(f, "EtherIP_IDSettingsList");
5687 
5688 	Lock(s->IPsecServer->LockSettings);
5689 	{
5690 		for (i = 0;i < LIST_NUM(s->IPsecServer->EtherIPIdList);i++)
5691 		{
5692 			ETHERIP_ID *d = LIST_DATA(s->IPsecServer->EtherIPIdList, i);
5693 			FOLDER *f;
5694 			BUF *b;
5695 
5696 			f = CfgCreateFolder(list_folder, d->Id);
5697 
5698 			CfgAddStr(f, "HubName", d->HubName);
5699 			CfgAddStr(f, "UserName", d->UserName);
5700 
5701 			b = EncryptPassword2(d->Password);
5702 
5703 			CfgAddBuf(f, "EncryptedPassword", b);
5704 
5705 			FreeBuf(b);
5706 		}
5707 	}
5708 	Unlock(s->IPsecServer->LockSettings);
5709 }
5710 
5711 // Write the license list
SiWriteLicenseManager(FOLDER * f,SERVER * s)5712 void SiWriteLicenseManager(FOLDER *f, SERVER *s)
5713 {
5714 }
5715 
5716 // Read the license list
SiLoadLicenseManager(SERVER * s,FOLDER * f)5717 void SiLoadLicenseManager(SERVER *s, FOLDER *f)
5718 {
5719 }
5720 
5721 // Write the Virtual HUB list
SiWriteHubs(FOLDER * f,SERVER * s)5722 void SiWriteHubs(FOLDER *f, SERVER *s)
5723 {
5724 	UINT i;
5725 	FOLDER *hub_folder;
5726 	CEDAR *c;
5727 	UINT num;
5728 	HUB **hubs;
5729 	// Validate arguments
5730 	if (f == NULL || s == NULL)
5731 	{
5732 		return;
5733 	}
5734 	c = s->Cedar;
5735 
5736 	LockList(c->HubList);
5737 	{
5738 		hubs = ToArray(c->HubList);
5739 		num = LIST_NUM(c->HubList);
5740 
5741 		for (i = 0;i < num;i++)
5742 		{
5743 			AddRef(hubs[i]->ref);
5744 		}
5745 	}
5746 	UnlockList(c->HubList);
5747 
5748 	for (i = 0;i < num;i++)
5749 	{
5750 		HUB *h = hubs[i];
5751 
5752 		Lock(h->lock);
5753 		{
5754 			hub_folder = CfgCreateFolder(f, h->Name);
5755 			SiWriteHubCfg(hub_folder, h);
5756 		}
5757 		Unlock(h->lock);
5758 
5759 		ReleaseHub(h);
5760 
5761 		if ((i % 30) == 1)
5762 		{
5763 			YieldCpu();
5764 		}
5765 	}
5766 
5767 	Free(hubs);
5768 }
5769 
5770 // Read the Virtual HUB list
SiLoadHubs(SERVER * s,FOLDER * f)5771 void SiLoadHubs(SERVER *s, FOLDER *f)
5772 {
5773 	UINT i;
5774 	FOLDER *hub_folder;
5775 	CEDAR *c;
5776 	TOKEN_LIST *t;
5777 	bool b = false;
5778 	// Validate arguments
5779 	if (f == NULL || s == NULL)
5780 	{
5781 		return;
5782 	}
5783 	c = s->Cedar;
5784 
5785 	t = CfgEnumFolderToTokenList(f);
5786 	for (i = 0;i < t->NumTokens;i++)
5787 	{
5788 		char *name = t->Token[i];
5789 
5790 
5791 		if (s->Cedar->Bridge)
5792 		{
5793 			if (StrCmpi(name, SERVER_DEFAULT_BRIDGE_NAME) == 0)
5794 			{
5795 				// Read only the setting of Virtual HUB named "BRIDGE"
5796 				// in the case of the Bridge
5797 				b = true;
5798 			}
5799 			else
5800 			{
5801 				continue;
5802 			}
5803 		}
5804 		hub_folder = CfgGetFolder(f, name);
5805 		if (hub_folder != NULL)
5806 		{
5807 			SiLoadHubCfg(s, hub_folder, name);
5808 		}
5809 	}
5810 	FreeToken(t);
5811 
5812 	if (s->Cedar->Bridge && b == false)
5813 	{
5814 		// If there isn't "BRIDGE" virtual HUB setting, create it newly
5815 		SiInitDefaultHubList(s);
5816 	}
5817 }
5818 
5819 // Read the server-specific settings
SiLoadServerCfg(SERVER * s,FOLDER * f)5820 void SiLoadServerCfg(SERVER *s, FOLDER *f)
5821 {
5822 	BUF *b;
5823 	CEDAR *c;
5824 	char tmp[MAX_SIZE];
5825 	X *x = NULL;
5826 	K *k = NULL;
5827 	bool cluster_allowed = false;
5828 	UINT num_connections_per_ip = 0;
5829 	FOLDER *params_folder;
5830 	UINT i;
5831 	// Validate arguments
5832 	if (s == NULL || f == NULL)
5833 	{
5834 		return;
5835 	}
5836 
5837 	// Save interval related
5838 	s->AutoSaveConfigSpan = CfgGetInt(f, "AutoSaveConfigSpan") * 1000;
5839 	if (s->AutoSaveConfigSpan == 0)
5840 	{
5841 		s->AutoSaveConfigSpan = SERVER_FILE_SAVE_INTERVAL_DEFAULT;
5842 	}
5843 	else
5844 	{
5845 		s->AutoSaveConfigSpan = MAKESURE(s->AutoSaveConfigSpan, SERVER_FILE_SAVE_INTERVAL_MIN, SERVER_FILE_SAVE_INTERVAL_MAX);
5846 	}
5847 
5848 	i = CfgGetInt(f, "MaxConcurrentDnsClientThreads");
5849 	if (i != 0)
5850 	{
5851 		SetGetIpThreadMaxNum(i);
5852 	}
5853 	else
5854 	{
5855 		SetGetIpThreadMaxNum(DEFAULT_GETIP_THREAD_MAX_NUM);
5856 	}
5857 
5858 	s->DontBackupConfig = CfgGetBool(f, "DontBackupConfig");
5859 
5860 	if (CfgIsItem(f, "BackupConfigOnlyWhenModified"))
5861 	{
5862 		s->BackupConfigOnlyWhenModified = CfgGetBool(f, "BackupConfigOnlyWhenModified");
5863 	}
5864 	else
5865 	{
5866 		s->BackupConfigOnlyWhenModified = true;
5867 	}
5868 
5869 	// Server log switch type
5870 	if (CfgIsItem(f, "ServerLogSwitchType"))
5871 	{
5872 		UINT st = CfgGetInt(f, "ServerLogSwitchType");
5873 
5874 		SetLogSwitchType(s->Logger, st);
5875 	}
5876 
5877 	SetMaxLogSize(CfgGetInt64(f, "LoggerMaxLogSize"));
5878 
5879 	params_folder = CfgGetFolder(f, "GlobalParams");
5880 	SiLoadGlobalParamsCfg(params_folder);
5881 
5882 	c = s->Cedar;
5883 	Lock(c->lock);
5884 	{
5885 		OPENVPN_SSTP_CONFIG config;
5886 		FOLDER *syslog_f;
5887 		{
5888 			RPC_KEEP k;
5889 
5890 			// Keep-alive related
5891 			Zero(&k, sizeof(k));
5892 			k.UseKeepConnect = CfgGetBool(f, "UseKeepConnect");
5893 			CfgGetStr(f, "KeepConnectHost", k.KeepConnectHost, sizeof(k.KeepConnectHost));
5894 			k.KeepConnectPort = CfgGetInt(f, "KeepConnectPort");
5895 			k.KeepConnectProtocol = CfgGetInt(f, "KeepConnectProtocol");
5896 			k.KeepConnectInterval = CfgGetInt(f, "KeepConnectInterval") * 1000;
5897 			if (k.KeepConnectPort == 0)
5898 			{
5899 				k.KeepConnectPort = 80;
5900 			}
5901 			if (StrLen(k.KeepConnectHost) == 0)
5902 			{
5903 				StrCpy(k.KeepConnectHost, sizeof(k.KeepConnectHost), CLIENT_DEFAULT_KEEPALIVE_HOST);
5904 			}
5905 			if (k.KeepConnectInterval == 0)
5906 			{
5907 				k.KeepConnectInterval = KEEP_INTERVAL_DEFAULT * 1000;
5908 			}
5909 			if (k.KeepConnectInterval < 5000)
5910 			{
5911 				k.KeepConnectInterval = 5000;
5912 			}
5913 			if (k.KeepConnectInterval > 600000)
5914 			{
5915 				k.KeepConnectInterval = 600000;
5916 			}
5917 
5918 			Lock(s->Keep->lock);
5919 			{
5920 				KEEP *keep = s->Keep;
5921 				keep->Enable = k.UseKeepConnect;
5922 				keep->Server = true;
5923 				StrCpy(keep->ServerName, sizeof(keep->ServerName), k.KeepConnectHost);
5924 				keep->ServerPort = k.KeepConnectPort;
5925 				keep->UdpMode = k.KeepConnectProtocol;
5926 				keep->Interval = k.KeepConnectInterval;
5927 			}
5928 			Unlock(s->Keep->lock);
5929 		}
5930 
5931 		// syslog
5932 		syslog_f = CfgGetFolder(f, "SyslogSettings");
5933 		if (syslog_f != NULL && GetServerCapsBool(s, "b_support_syslog"))
5934 		{
5935 			SYSLOG_SETTING set;
5936 
5937 			Zero(&set, sizeof(set));
5938 
5939 			set.SaveType = CfgGetInt(syslog_f, "SaveType");
5940 			CfgGetStr(syslog_f, "HostName", set.Hostname, sizeof(set.Hostname));
5941 			set.Port = CfgGetInt(syslog_f, "Port");
5942 
5943 			SiSetSysLogSetting(s, &set);
5944 		}
5945 
5946 		// Whether to disable the IPv6 listener
5947 		s->Cedar->DisableIPv6Listener = CfgGetBool(f, "DisableIPv6Listener");
5948 
5949 		// DoS
5950 		s->DisableDosProction = CfgGetBool(f, "DisableDosProction");
5951 
5952 		// Num Connections Per IP
5953 		SetMaxConnectionsPerIp(CfgGetInt(f, "MaxConnectionsPerIP"));
5954 
5955 		// MaxUnestablishedConnections
5956 		SetMaxUnestablishedConnections(CfgGetInt(f, "MaxUnestablishedConnections"));
5957 
5958 		// DeadLock
5959 		s->DisableDeadLockCheck = CfgGetBool(f, "DisableDeadLockCheck");
5960 
5961 		// Eraser
5962 		SetEraserCheckInterval(CfgGetInt(f, "AutoDeleteCheckIntervalSecs"));
5963 		s->Eraser = NewEraser(s->Logger, CfgGetInt64(f, "AutoDeleteCheckDiskFreeSpaceMin"));
5964 
5965 		// WebUI
5966 		s->UseWebUI = CfgGetBool(f, "UseWebUI");
5967 
5968 
5969 		// WebTimePage
5970 		s->UseWebTimePage = CfgGetBool(f, "UseWebTimePage");
5971 
5972 		// NoLinuxArpFilter
5973 		s->NoLinuxArpFilter = CfgGetBool(f, "NoLinuxArpFilter");
5974 
5975 		// NoHighPriorityProcess
5976 		s->NoHighPriorityProcess = CfgGetBool(f, "NoHighPriorityProcess");
5977 
5978 		// NoDebugDump
5979 		s->NoDebugDump = CfgGetBool(f, "NoDebugDump");
5980 		if (s->NoDebugDump)
5981 		{
5982 #ifdef	OS_WIN32
5983 			MsSetEnableMinidump(false);
5984 #endif	// OS_WIN32
5985 		}
5986 
5987 		// Disable the SSTP server function
5988 		s->DisableSSTPServer = CfgGetBool(f, "DisableSSTPServer");
5989 
5990 		// Disable the OpenVPN server function
5991 		s->DisableOpenVPNServer = CfgGetBool(f, "DisableOpenVPNServer");
5992 
5993 		// OpenVPN Default Option String
5994 		if (CfgGetStr(f, "OpenVPNDefaultClientOption", tmp, sizeof(tmp)))
5995 		{
5996 			if (IsEmptyStr(tmp) == false)
5997 			{
5998 				StrCpy(c->OpenVPNDefaultClientOption,
5999 					sizeof(c->OpenVPNDefaultClientOption), tmp);
6000 			}
6001 		}
6002 
6003 		// Disable the NAT-traversal feature
6004 		s->DisableNatTraversal = CfgGetBool(f, "DisableNatTraversal");
6005 
6006 		// Disable IPsec Aggressive Mode
6007 		s->DisableIPsecAggressiveMode = CfgGetBool(f, "DisableIPsecAggressiveMode");
6008 
6009 		// Intel AES
6010 		s->DisableIntelAesAcceleration = CfgGetBool(f, "DisableIntelAesAcceleration");
6011 
6012 		if (s->Cedar->Bridge == false)
6013 		{
6014 			// Enable the VPN-over-ICMP
6015 			if (CfgIsItem(f, "EnableVpnOverIcmp"))
6016 			{
6017 				s->EnableVpnOverIcmp = CfgGetBool(f, "EnableVpnOverIcmp");
6018 			}
6019 			else
6020 			{
6021 				s->EnableVpnOverIcmp = false;
6022 			}
6023 
6024 			// Enable the VPN-over-DNS
6025 			if (CfgIsItem(f, "EnableVpnOverDns"))
6026 			{
6027 				s->EnableVpnOverDns = CfgGetBool(f, "EnableVpnOverDns");
6028 			}
6029 			else
6030 			{
6031 				s->EnableVpnOverDns = false;
6032 			}
6033 		}
6034 
6035 		// Debug log
6036 		s->SaveDebugLog = CfgGetBool(f, "SaveDebugLog");
6037 		if (s->SaveDebugLog)
6038 		{
6039 			s->DebugLog = NewTinyLog();
6040 		}
6041 
6042 		// Let the client not to send a signature
6043 		s->NoSendSignature = CfgGetBool(f, "NoSendSignature");
6044 
6045 		// Server certificate
6046 		b = CfgGetBuf(f, "ServerCert");
6047 		if (b != NULL)
6048 		{
6049 			x = BufToX(b, false);
6050 			FreeBuf(b);
6051 		}
6052 
6053 		// Server private key
6054 		b = CfgGetBuf(f, "ServerKey");
6055 		if (b != NULL)
6056 		{
6057 			k = BufToK(b, true, false, NULL);
6058 			FreeBuf(b);
6059 		}
6060 
6061 		if (x == NULL || k == NULL || CheckXandK(x, k) == false)
6062 		{
6063 			FreeX(x);
6064 			FreeK(k);
6065 			SiGenerateDefaultCert(&x, &k);
6066 
6067 			SetCedarCert(c, x, k);
6068 
6069 			FreeX(x);
6070 			FreeK(k);
6071 		}
6072 		else
6073 		{
6074 			SetCedarCert(c, x, k);
6075 
6076 			FreeX(x);
6077 			FreeK(k);
6078 		}
6079 
6080 		// Cipher Name
6081 		if (CfgGetStr(f, "CipherName", tmp, sizeof(tmp)))
6082 		{
6083 			StrUpper(tmp);
6084 			if (CheckCipherListName(tmp))
6085 			{
6086 				SetCedarCipherList(c, tmp);
6087 			}
6088 		}
6089 
6090 		// Traffic information
6091 		Lock(c->TrafficLock);
6092 		{
6093 			SiLoadTraffic(f, "ServerTraffic", c->Traffic);
6094 		}
6095 		Unlock(c->TrafficLock);
6096 
6097 		// Get whether the current license allows cluster mode
6098 		cluster_allowed = true;
6099 
6100 
6101 		// Type of server
6102 		s->UpdatedServerType = s->ServerType =
6103 			cluster_allowed ? CfgGetInt(f, "ServerType") : SERVER_TYPE_STANDALONE;
6104 
6105 		// Password
6106 		if (CfgGetByte(f, "HashedPassword", s->HashedPassword, sizeof(s->HashedPassword)) != sizeof(s->HashedPassword))
6107 		{
6108 			Hash(s->HashedPassword, "", 0, true);
6109 		}
6110 
6111 		if (s->ServerType != SERVER_TYPE_STANDALONE)
6112 		{
6113 			// Performance ratio of the server
6114 			s->Weight = CfgGetInt(f, "ClusterMemberWeight");
6115 			if (s->Weight == 0)
6116 			{
6117 				s->Weight = FARM_DEFAULT_WEIGHT;
6118 			}
6119 		}
6120 		else
6121 		{
6122 			s->Weight = FARM_DEFAULT_WEIGHT;
6123 		}
6124 
6125 		if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
6126 		{
6127 			s->ControllerOnly = CfgGetBool(f, "ControllerOnly");
6128 		}
6129 
6130 		if (s->ServerType != SERVER_TYPE_STANDALONE)
6131 		{
6132 			// SSTP, OpenVPN, and NAT traversal can not be used in a cluster environment
6133 			s->DisableNatTraversal = true;
6134 			s->DisableSSTPServer = true;
6135 			s->DisableOpenVPNServer = true;
6136 		}
6137 
6138 		if (s->Cedar->Bridge)
6139 		{
6140 			// SSTP, OpenVPN, and NAT traversal function can not be used in the bridge environment
6141 			s->DisableNatTraversal = true;
6142 			s->DisableSSTPServer = true;
6143 			s->DisableOpenVPNServer = true;
6144 		}
6145 
6146 		// Read the OpenVPN Port List
6147 		if (CfgGetStr(f, "OpenVPN_UdpPortList", tmp, sizeof(tmp)) == false)
6148 		{
6149 			{
6150 				ToStr(tmp, OPENVPN_UDP_PORT);
6151 			}
6152 		}
6153 
6154 		// Apply the configuration of SSTP and OpenVPN
6155 		Zero(&config, sizeof(config));
6156 		config.EnableOpenVPN = !s->DisableOpenVPNServer;
6157 		config.EnableSSTP = !s->DisableSSTPServer;
6158 		StrCpy(config.OpenVPNPortList, sizeof(config.OpenVPNPortList), tmp);
6159 
6160 		SiSetOpenVPNAndSSTPConfig(s, &config);
6161 
6162 		if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
6163 		{
6164 			char tmp[6 * MAX_PUBLIC_PORT_NUM + 1];
6165 			// Load the settings item in the case of farm members
6166 			CfgGetStr(f, "ControllerName", s->ControllerName, sizeof(s->ControllerName));
6167 			s->ControllerPort = CfgGetInt(f, "ControllerPort");
6168 			CfgGetByte(f, "MemberPassword", s->MemberPassword, SHA1_SIZE);
6169 			s->PublicIp = CfgGetIp32(f, "PublicIp");
6170 			if (CfgGetStr(f, "PublicPorts", tmp, sizeof(tmp)))
6171 			{
6172 				TOKEN_LIST *t = ParseToken(tmp, ", ");
6173 				UINT i;
6174 				s->NumPublicPort = t->NumTokens;
6175 				s->PublicPorts = ZeroMalloc(s->NumPublicPort * sizeof(UINT));
6176 				for (i = 0;i < s->NumPublicPort;i++)
6177 				{
6178 					s->PublicPorts[i] = ToInt(t->Token[i]);
6179 				}
6180 				FreeToken(t);
6181 			}
6182 		}
6183 
6184 		// Configuration of VPN Azure Client
6185 		s->EnableVpnAzure = CfgGetBool(f, "EnableVpnAzure");
6186 
6187 		// Disable GetHostName when accepting TCP
6188 		s->DisableGetHostNameWhenAcceptTcp = CfgGetBool(f, "DisableGetHostNameWhenAcceptTcp");
6189 
6190 		if (s->DisableGetHostNameWhenAcceptTcp)
6191 		{
6192 			DisableGetHostNameWhenAcceptInit();
6193 		}
6194 
6195 		// Disable core dump on UNIX
6196 		s->DisableCoreDumpOnUnix = CfgGetBool(f, "DisableCoreDumpOnUnix");
6197 
6198 		// Disable session reconnect
6199 		SetGlobalServerFlag(GSF_DISABLE_SESSION_RECONNECT, CfgGetBool(f, "DisableSessionReconnect"));
6200 
6201 		// AcceptOnlyTls
6202 		if (CfgIsItem(f, "AcceptOnlyTls"))
6203 		{
6204 			c->SslAcceptSettings.AcceptOnlyTls = CfgGetBool(f, "AcceptOnlyTls");
6205 		}
6206 		else
6207 		{
6208 			// Default to TLS only; mitigates CVE-2016-0800
6209 			c->SslAcceptSettings.AcceptOnlyTls = true;
6210 		}
6211 		c->SslAcceptSettings.Tls_Disable1_0 = CfgGetBool(f, "Tls_Disable1_0");
6212 		c->SslAcceptSettings.Tls_Disable1_1 = CfgGetBool(f, "Tls_Disable1_1");
6213 		c->SslAcceptSettings.Tls_Disable1_2 = CfgGetBool(f, "Tls_Disable1_2");
6214 		c->SslAcceptSettings.Tls_Disable1_3 = CfgGetBool(f, "Tls_Disable1_3");
6215 
6216 		s->StrictSyslogDatetimeFormat = CfgGetBool(f, "StrictSyslogDatetimeFormat");
6217 
6218 		// Disable JSON-RPC Web API
6219 		s->DisableJsonRpcWebApi = CfgGetBool(f, "DisableJsonRpcWebApi");
6220 	}
6221 	Unlock(c->lock);
6222 
6223 #ifdef	OS_UNIX
6224 	if (s->DisableCoreDumpOnUnix)
6225 	{
6226 		UnixDisableCoreDump();
6227 	}
6228 #endif	// OS_UNIX
6229 }
6230 
6231 // Load global params
SiLoadGlobalParamsCfg(FOLDER * f)6232 void SiLoadGlobalParamsCfg(FOLDER *f)
6233 {
6234 	SiLoadGlobalParamItem(GP_MAX_SEND_SOCKET_QUEUE_SIZE, CfgGetInt(f, "MAX_SEND_SOCKET_QUEUE_SIZE"));
6235 	SiLoadGlobalParamItem(GP_MIN_SEND_SOCKET_QUEUE_SIZE, CfgGetInt(f, "MIN_SEND_SOCKET_QUEUE_SIZE"));
6236 	SiLoadGlobalParamItem(GP_MAX_SEND_SOCKET_QUEUE_NUM, CfgGetInt(f, "MAX_SEND_SOCKET_QUEUE_NUM"));
6237 	SiLoadGlobalParamItem(GP_SELECT_TIME, CfgGetInt(f, "SELECT_TIME"));
6238 	SiLoadGlobalParamItem(GP_SELECT_TIME_FOR_NAT, CfgGetInt(f, "SELECT_TIME_FOR_NAT"));
6239 	SiLoadGlobalParamItem(GP_MAX_STORED_QUEUE_NUM, CfgGetInt(f, "MAX_STORED_QUEUE_NUM"));
6240 	SiLoadGlobalParamItem(GP_MAX_BUFFERING_PACKET_SIZE, CfgGetInt(f, "MAX_BUFFERING_PACKET_SIZE"));
6241 	SiLoadGlobalParamItem(GP_HUB_ARP_SEND_INTERVAL, CfgGetInt(f, "HUB_ARP_SEND_INTERVAL"));
6242 	SiLoadGlobalParamItem(GP_MAC_TABLE_EXPIRE_TIME, CfgGetInt(f, "MAC_TABLE_EXPIRE_TIME"));
6243 	SiLoadGlobalParamItem(GP_IP_TABLE_EXPIRE_TIME, CfgGetInt(f, "IP_TABLE_EXPIRE_TIME"));
6244 	SiLoadGlobalParamItem(GP_IP_TABLE_EXPIRE_TIME_DHCP, CfgGetInt(f, "IP_TABLE_EXPIRE_TIME_DHCP"));
6245 	SiLoadGlobalParamItem(GP_STORM_CHECK_SPAN, CfgGetInt(f, "STORM_CHECK_SPAN"));
6246 	SiLoadGlobalParamItem(GP_STORM_DISCARD_VALUE_START, CfgGetInt(f, "STORM_DISCARD_VALUE_START"));
6247 	SiLoadGlobalParamItem(GP_STORM_DISCARD_VALUE_END, CfgGetInt(f, "STORM_DISCARD_VALUE_END"));
6248 	SiLoadGlobalParamItem(GP_MAX_MAC_TABLES, CfgGetInt(f, "MAX_MAC_TABLES"));
6249 	SiLoadGlobalParamItem(GP_MAX_IP_TABLES, CfgGetInt(f, "MAX_IP_TABLES"));
6250 	SiLoadGlobalParamItem(GP_MAX_HUB_LINKS, CfgGetInt(f, "MAX_HUB_LINKS"));
6251 	SiLoadGlobalParamItem(GP_MEM_FIFO_REALLOC_MEM_SIZE, CfgGetInt(f, "MEM_FIFO_REALLOC_MEM_SIZE"));
6252 	SiLoadGlobalParamItem(GP_QUEUE_BUDGET, CfgGetInt(f, "QUEUE_BUDGET"));
6253 	SiLoadGlobalParamItem(GP_FIFO_BUDGET, CfgGetInt(f, "FIFO_BUDGET"));
6254 
6255 	SetFifoCurrentReallocMemSize(MEM_FIFO_REALLOC_MEM_SIZE);
6256 }
6257 
6258 // Load global param itesm
SiLoadGlobalParamItem(UINT id,UINT value)6259 void SiLoadGlobalParamItem(UINT id, UINT value)
6260 {
6261 	// Validate arguments
6262 	if (id == 0)
6263 	{
6264 		return;
6265 	}
6266 
6267 	vpn_global_parameters[id] = value;
6268 }
6269 
6270 // Write global params
SiWriteGlobalParamsCfg(FOLDER * f)6271 void SiWriteGlobalParamsCfg(FOLDER *f)
6272 {
6273 	// Validate arguments
6274 	if (f == NULL)
6275 	{
6276 		return;
6277 	}
6278 
6279 	CfgAddInt(f, "MAX_SEND_SOCKET_QUEUE_SIZE", MAX_SEND_SOCKET_QUEUE_SIZE);
6280 	CfgAddInt(f, "MIN_SEND_SOCKET_QUEUE_SIZE", MIN_SEND_SOCKET_QUEUE_SIZE);
6281 	CfgAddInt(f, "MAX_SEND_SOCKET_QUEUE_NUM", MAX_SEND_SOCKET_QUEUE_NUM);
6282 	CfgAddInt(f, "SELECT_TIME", SELECT_TIME);
6283 	CfgAddInt(f, "SELECT_TIME_FOR_NAT", SELECT_TIME_FOR_NAT);
6284 	CfgAddInt(f, "MAX_STORED_QUEUE_NUM", MAX_STORED_QUEUE_NUM);
6285 	CfgAddInt(f, "MAX_BUFFERING_PACKET_SIZE", MAX_BUFFERING_PACKET_SIZE);
6286 	CfgAddInt(f, "HUB_ARP_SEND_INTERVAL", HUB_ARP_SEND_INTERVAL);
6287 	CfgAddInt(f, "MAC_TABLE_EXPIRE_TIME", MAC_TABLE_EXPIRE_TIME);
6288 	CfgAddInt(f, "IP_TABLE_EXPIRE_TIME", IP_TABLE_EXPIRE_TIME);
6289 	CfgAddInt(f, "IP_TABLE_EXPIRE_TIME_DHCP", IP_TABLE_EXPIRE_TIME_DHCP);
6290 	CfgAddInt(f, "STORM_CHECK_SPAN", STORM_CHECK_SPAN);
6291 	CfgAddInt(f, "STORM_DISCARD_VALUE_START", STORM_DISCARD_VALUE_START);
6292 	CfgAddInt(f, "STORM_DISCARD_VALUE_END", STORM_DISCARD_VALUE_END);
6293 	CfgAddInt(f, "MAX_MAC_TABLES", MAX_MAC_TABLES);
6294 	CfgAddInt(f, "MAX_IP_TABLES", MAX_IP_TABLES);
6295 	CfgAddInt(f, "MAX_HUB_LINKS", MAX_HUB_LINKS);
6296 	CfgAddInt(f, "MEM_FIFO_REALLOC_MEM_SIZE", MEM_FIFO_REALLOC_MEM_SIZE);
6297 	CfgAddInt(f, "QUEUE_BUDGET", QUEUE_BUDGET);
6298 	CfgAddInt(f, "FIFO_BUDGET", FIFO_BUDGET);
6299 }
6300 
6301 // Write the server-specific settings
SiWriteServerCfg(FOLDER * f,SERVER * s)6302 void SiWriteServerCfg(FOLDER *f, SERVER *s)
6303 {
6304 	BUF *b;
6305 	CEDAR *c;
6306 	FOLDER *params_folder;
6307 	// Validate arguments
6308 	if (f == NULL || s == NULL)
6309 	{
6310 		return;
6311 	}
6312 
6313 	CfgAddInt(f, "MaxConcurrentDnsClientThreads", GetGetIpThreadMaxNum());
6314 
6315 	CfgAddInt(f, "CurrentBuild", s->Cedar->Build);
6316 
6317 	CfgAddInt(f, "AutoSaveConfigSpan", s->AutoSaveConfigSpanSaved / 1000);
6318 
6319 	CfgAddBool(f, "DontBackupConfig", s->DontBackupConfig);
6320 	CfgAddBool(f, "BackupConfigOnlyWhenModified", s->BackupConfigOnlyWhenModified);
6321 
6322 	if (s->Logger != NULL)
6323 	{
6324 		CfgAddInt(f, "ServerLogSwitchType", s->Logger->SwitchType);
6325 	}
6326 
6327 	CfgAddInt64(f, "LoggerMaxLogSize", GetMaxLogSize());
6328 
6329 	params_folder = CfgCreateFolder(f, "GlobalParams");
6330 
6331 	if (params_folder != NULL)
6332 	{
6333 		SiWriteGlobalParamsCfg(params_folder);
6334 	}
6335 
6336 	c = s->Cedar;
6337 
6338 	Lock(c->lock);
6339 	{
6340 		bool is_vgs_cert = false;
6341 		FOLDER *syslog_f;
6342 		Lock(s->Keep->lock);
6343 		{
6344 			KEEP *k = s->Keep;
6345 			CfgAddBool(f, "UseKeepConnect", k->Enable);
6346 			CfgAddStr(f, "KeepConnectHost", k->ServerName);
6347 			CfgAddInt(f, "KeepConnectPort", k->ServerPort);
6348 			CfgAddInt(f, "KeepConnectProtocol", k->UdpMode);
6349 			CfgAddInt(f, "KeepConnectInterval", k->Interval / 1000);
6350 		}
6351 		Unlock(s->Keep->lock);
6352 
6353 		// syslog
6354 		syslog_f = CfgCreateFolder(f, "SyslogSettings");
6355 		if (syslog_f != NULL)
6356 		{
6357 			SYSLOG_SETTING set;
6358 
6359 			SiGetSysLogSetting(s, &set);
6360 
6361 			CfgAddInt(syslog_f, "SaveType", set.SaveType);
6362 			CfgAddStr(syslog_f, "HostName", set.Hostname);
6363 			CfgAddInt(syslog_f, "Port", set.Port);
6364 		}
6365 
6366 		// IPv6 listener disable setting
6367 		CfgAddBool(f, "DisableIPv6Listener", s->Cedar->DisableIPv6Listener);
6368 
6369 		// DoS
6370 		CfgAddBool(f, "DisableDosProction", s->DisableDosProction);
6371 
6372 		// MaxConnectionsPerIP
6373 		CfgAddInt(f, "MaxConnectionsPerIP", GetMaxConnectionsPerIp());
6374 
6375 		// MaxUnestablishedConnections
6376 		CfgAddInt(f, "MaxUnestablishedConnections", GetMaxUnestablishedConnections());
6377 
6378 		// DeadLock
6379 		CfgAddBool(f, "DisableDeadLockCheck", s->DisableDeadLockCheck);
6380 
6381 		// Eraser related
6382 		CfgAddInt64(f, "AutoDeleteCheckDiskFreeSpaceMin", s->Eraser->MinFreeSpace);
6383 		CfgAddInt(f, "AutoDeleteCheckIntervalSecs", GetEraserCheckInterval());
6384 
6385 		// WebUI
6386 		CfgAddBool(f, "UseWebUI", s->UseWebUI);
6387 
6388 
6389 		// NoLinuxArpFilter
6390 		if (GetOsInfo()->OsType == OSTYPE_LINUX)
6391 		{
6392 			CfgAddBool(f, "NoLinuxArpFilter", s->NoLinuxArpFilter);
6393 		}
6394 
6395 		// NoHighPriorityProcess
6396 		CfgAddBool(f, "NoHighPriorityProcess", s->NoHighPriorityProcess);
6397 
6398 #ifdef	OS_WIN32
6399 		CfgAddBool(f, "NoDebugDump", s->NoDebugDump);
6400 #endif	// OS_WIN32
6401 
6402 		if (s->ServerType == SERVER_TYPE_STANDALONE)
6403 		{
6404 			if (c->Bridge == false)
6405 			{
6406 				// Disable the NAT-traversal feature
6407 				CfgAddBool(f, "DisableNatTraversal", s->DisableNatTraversal);
6408 
6409 				// Disable the SSTP server function
6410 				CfgAddBool(f, "DisableSSTPServer", s->DisableSSTPServer);
6411 
6412 				// Disable the OpenVPN server function
6413 				CfgAddBool(f, "DisableOpenVPNServer", s->DisableOpenVPNServer);
6414 			}
6415 		}
6416 
6417 		CfgAddBool(f, "DisableIPsecAggressiveMode", s->DisableIPsecAggressiveMode);
6418 
6419 		CfgAddStr(f, "OpenVPNDefaultClientOption", c->OpenVPNDefaultClientOption);
6420 
6421 		if (c->Bridge == false)
6422 		{
6423 			// VPN over ICMP
6424 			CfgAddBool(f, "EnableVpnOverIcmp", s->EnableVpnOverIcmp);
6425 
6426 			// VPN over DNS
6427 			CfgAddBool(f, "EnableVpnOverDns", s->EnableVpnOverDns);
6428 		}
6429 
6430 		// Intel AES
6431 		CfgAddBool(f, "DisableIntelAesAcceleration", s->DisableIntelAesAcceleration);
6432 
6433 		if (c->Bridge == false)
6434 		{
6435 			OPENVPN_SSTP_CONFIG config;
6436 
6437 			SiGetOpenVPNAndSSTPConfig(s, &config);
6438 
6439 			CfgAddStr(f, "OpenVPN_UdpPortList", config.OpenVPNPortList);
6440 		}
6441 
6442 		// WebTimePage
6443 		CfgAddBool(f, "UseWebTimePage", s->UseWebTimePage);
6444 
6445 		// Debug log
6446 		CfgAddBool(f, "SaveDebugLog", s->SaveDebugLog);
6447 
6448 		// Let the client not to send a signature
6449 		CfgAddBool(f, "NoSendSignature", s->NoSendSignature);
6450 
6451 
6452 		if (is_vgs_cert == false)
6453 		{
6454 			// Server certificate
6455 			b = XToBuf(c->ServerX, false);
6456 			CfgAddBuf(f, "ServerCert", b);
6457 			FreeBuf(b);
6458 
6459 			// Server private key
6460 			b = KToBuf(c->ServerK, false, NULL);
6461 			CfgAddBuf(f, "ServerKey", b);
6462 			FreeBuf(b);
6463 		}
6464 
6465 		// Traffic information
6466 		Lock(c->TrafficLock);
6467 		{
6468 			SiWriteTraffic(f, "ServerTraffic", c->Traffic);
6469 		}
6470 		Unlock(c->TrafficLock);
6471 
6472 		// Type of server
6473 		if (s->Cedar->Bridge == false)
6474 		{
6475 			CfgAddInt(f, "ServerType", s->UpdatedServerType);
6476 		}
6477 
6478 		// Cipher Name
6479 		CfgAddStr(f, "CipherName", s->Cedar->CipherList);
6480 
6481 		// Password
6482 		CfgAddByte(f, "HashedPassword", s->HashedPassword, sizeof(s->HashedPassword));
6483 
6484 		if (s->UpdatedServerType == SERVER_TYPE_FARM_MEMBER)
6485 		{
6486 			char tmp[6 * MAX_PUBLIC_PORT_NUM + 1];
6487 			UINT i;
6488 			// Setting items in the case of farm members
6489 			CfgAddStr(f, "ControllerName", s->ControllerName);
6490 			CfgAddInt(f, "ControllerPort", s->ControllerPort);
6491 			CfgAddByte(f, "MemberPassword", s->MemberPassword, SHA1_SIZE);
6492 			CfgAddIp32(f, "PublicIp", s->PublicIp);
6493 			tmp[0] = 0;
6494 			for (i = 0;i < s->NumPublicPort;i++)
6495 			{
6496 				char tmp2[MAX_SIZE];
6497 				ToStr(tmp2, s->PublicPorts[i]);
6498 				StrCat(tmp, sizeof(tmp), tmp2);
6499 				StrCat(tmp, sizeof(tmp), ",");
6500 			}
6501 			if (StrLen(tmp) >= 1)
6502 			{
6503 				if (tmp[StrLen(tmp) - 1] == ',')
6504 				{
6505 					tmp[StrLen(tmp) - 1] = 0;
6506 				}
6507 			}
6508 			CfgAddStr(f, "PublicPorts", tmp);
6509 		}
6510 
6511 		if (s->UpdatedServerType != SERVER_TYPE_STANDALONE)
6512 		{
6513 			CfgAddInt(f, "ClusterMemberWeight", s->Weight);
6514 		}
6515 
6516 		if (s->UpdatedServerType == SERVER_TYPE_FARM_CONTROLLER)
6517 		{
6518 			CfgAddBool(f, "ControllerOnly", s->ControllerOnly);
6519 		}
6520 
6521 		// VPN Azure Client
6522 		if (s->AzureClient != NULL)
6523 		{
6524 			CfgAddBool(f, "EnableVpnAzure", s->EnableVpnAzure);
6525 		}
6526 
6527 		CfgAddBool(f, "DisableGetHostNameWhenAcceptTcp", s->DisableGetHostNameWhenAcceptTcp);
6528 		CfgAddBool(f, "DisableCoreDumpOnUnix", s->DisableCoreDumpOnUnix);
6529 
6530 		CfgAddBool(f, "AcceptOnlyTls", c->SslAcceptSettings.AcceptOnlyTls);
6531 		CfgAddBool(f, "Tls_Disable1_0", c->SslAcceptSettings.Tls_Disable1_0);
6532 		CfgAddBool(f, "Tls_Disable1_1", c->SslAcceptSettings.Tls_Disable1_1);
6533 		CfgAddBool(f, "Tls_Disable1_2", c->SslAcceptSettings.Tls_Disable1_2);
6534 		CfgAddBool(f, "Tls_Disable1_3", c->SslAcceptSettings.Tls_Disable1_3);
6535 
6536 		// Disable session reconnect
6537 		CfgAddBool(f, "DisableSessionReconnect", GetGlobalServerFlag(GSF_DISABLE_SESSION_RECONNECT));
6538 
6539 		CfgAddBool(f, "StrictSyslogDatetimeFormat", s->StrictSyslogDatetimeFormat);
6540 
6541 		// Disable JSON-RPC Web API
6542 		CfgAddBool(f, "DisableJsonRpcWebApi", s->DisableJsonRpcWebApi);
6543 	}
6544 	Unlock(c->lock);
6545 }
6546 
6547 // Read the traffic information
SiLoadTraffic(FOLDER * parent,char * name,TRAFFIC * t)6548 void SiLoadTraffic(FOLDER *parent, char *name, TRAFFIC *t)
6549 {
6550 	FOLDER *f;
6551 	// Validate arguments
6552 	if (t != NULL)
6553 	{
6554 		Zero(t, sizeof(TRAFFIC));
6555 	}
6556 	if (parent == NULL || name == NULL || t == NULL)
6557 	{
6558 		return;
6559 	}
6560 
6561 	f = CfgGetFolder(parent, name);
6562 
6563 	if (f == NULL)
6564 	{
6565 		return;
6566 	}
6567 
6568 	SiLoadTrafficInner(f, "SendTraffic", &t->Send);
6569 	SiLoadTrafficInner(f, "RecvTraffic", &t->Recv);
6570 }
SiLoadTrafficInner(FOLDER * parent,char * name,TRAFFIC_ENTRY * e)6571 void SiLoadTrafficInner(FOLDER *parent, char *name, TRAFFIC_ENTRY *e)
6572 {
6573 	FOLDER *f;
6574 	// Validate arguments
6575 	if (e != NULL)
6576 	{
6577 		Zero(e, sizeof(TRAFFIC_ENTRY));
6578 	}
6579 	if (parent == NULL || name == NULL || e == NULL)
6580 	{
6581 		return;
6582 	}
6583 
6584 	f = CfgGetFolder(parent, name);
6585 	if (f == NULL)
6586 	{
6587 		return;
6588 	}
6589 
6590 	e->BroadcastCount = CfgGetInt64(f, "BroadcastCount");
6591 	e->BroadcastBytes = CfgGetInt64(f, "BroadcastBytes");
6592 	e->UnicastCount = CfgGetInt64(f, "UnicastCount");
6593 	e->UnicastBytes = CfgGetInt64(f, "UnicastBytes");
6594 }
6595 
6596 // Write the traffic information
SiWriteTraffic(FOLDER * parent,char * name,TRAFFIC * t)6597 void SiWriteTraffic(FOLDER *parent, char *name, TRAFFIC *t)
6598 {
6599 	FOLDER *f;
6600 	// Validate arguments
6601 	if (parent == NULL || name == NULL || t == NULL)
6602 	{
6603 		return;
6604 	}
6605 
6606 	f = CfgCreateFolder(parent, name);
6607 
6608 	SiWriteTrafficInner(f, "SendTraffic", &t->Send);
6609 	SiWriteTrafficInner(f, "RecvTraffic", &t->Recv);
6610 }
SiWriteTrafficInner(FOLDER * parent,char * name,TRAFFIC_ENTRY * e)6611 void SiWriteTrafficInner(FOLDER *parent, char *name, TRAFFIC_ENTRY *e)
6612 {
6613 	FOLDER *f;
6614 	// Validate arguments
6615 	if (parent == NULL || name == NULL || e == NULL)
6616 	{
6617 		return;
6618 	}
6619 
6620 	f = CfgCreateFolder(parent, name);
6621 	CfgAddInt64(f, "BroadcastCount", e->BroadcastCount);
6622 	CfgAddInt64(f, "BroadcastBytes", e->BroadcastBytes);
6623 	CfgAddInt64(f, "UnicastCount", e->UnicastCount);
6624 	CfgAddInt64(f, "UnicastBytes", e->UnicastBytes);
6625 }
6626 
6627 // Thread for writing configuration file
SiSaverThread(THREAD * thread,void * param)6628 void SiSaverThread(THREAD *thread, void *param)
6629 {
6630 	SERVER *s = (SERVER *)param;
6631 	// Validate arguments
6632 	if (thread == NULL || param == NULL)
6633 	{
6634 		return;
6635 	}
6636 
6637 	while (s->Halt == false)
6638 	{
6639 		// Save to the configuration file
6640 		if (s->NoMoreSave == false)
6641 		{
6642 			SiWriteConfigurationFile(s);
6643 		}
6644 
6645 		Wait(s->SaveHaltEvent, s->AutoSaveConfigSpan);
6646 	}
6647 }
6648 
6649 // Write to the configuration file
SiWriteConfigurationFile(SERVER * s)6650 UINT SiWriteConfigurationFile(SERVER *s)
6651 {
6652 	UINT ret;
6653 	// Validate arguments
6654 	if (s == NULL)
6655 	{
6656 		return 0;
6657 	}
6658 
6659 	if (s->CfgRw == NULL)
6660 	{
6661 		return 0;
6662 	}
6663 
6664 	if (s->NoMoreSave)
6665 	{
6666 		return 0;
6667 	}
6668 
6669 	Lock(s->SaveCfgLock);
6670 	{
6671 		FOLDER *f;
6672 
6673 		Debug("save: SiWriteConfigurationToCfg() start.\n");
6674 		f = SiWriteConfigurationToCfg(s);
6675 		Debug("save: SiWriteConfigurationToCfg() finished.\n");
6676 
6677 		Debug("save: SaveCfgRw() start.\n");
6678 		ret = SaveCfgRwEx(s->CfgRw, f, s->BackupConfigOnlyWhenModified ? s->ConfigRevision : INFINITE);
6679 		Debug("save: SaveCfgRw() finished.\n");
6680 
6681 		Debug("save: CfgDeleteFolder() start.\n");
6682 		CfgDeleteFolder(f);
6683 		Debug("save: CfgDeleteFolder() finished.\n");
6684 	}
6685 	Unlock(s->SaveCfgLock);
6686 
6687 	return ret;
6688 }
6689 
6690 // Release the configuration
SiFreeConfiguration(SERVER * s)6691 void SiFreeConfiguration(SERVER *s)
6692 {
6693 	// Validate arguments
6694 	if (s == NULL)
6695 	{
6696 		return;
6697 	}
6698 
6699 	// Write to the configuration file
6700 	SiWriteConfigurationFile(s);
6701 
6702 	// Terminate the configuration file saving thread
6703 	s->NoMoreSave = true;
6704 	s->Halt = true;
6705 	Set(s->SaveHaltEvent);
6706 	WaitThread(s->SaveThread, INFINITE);
6707 
6708 	ReleaseEvent(s->SaveHaltEvent);
6709 	ReleaseThread(s->SaveThread);
6710 
6711 	s->SaveHaltEvent = NULL;
6712 	s->SaveThread = NULL;
6713 
6714 
6715 	// Stop the IPsec server
6716 	if (s->IPsecServer != NULL)
6717 	{
6718 		FreeIPsecServer(s->IPsecServer);
6719 		s->IPsecServer = NULL;
6720 	}
6721 
6722 	// Terminate the OpenVPN server
6723 	if (s->OpenVpnServerUdp != NULL)
6724 	{
6725 		FreeOpenVpnServerUdp(s->OpenVpnServerUdp);
6726 		s->OpenVpnServerUdp = NULL;
6727 	}
6728 
6729 
6730 	// Terminate the DDNS client
6731 	if (s->DDnsClient != NULL)
6732 	{
6733 		FreeDDNSClient(s->DDnsClient);
6734 		s->DDnsClient = NULL;
6735 	}
6736 
6737 	// Terminate the VPN Azure client
6738 	if (s->AzureClient != NULL)
6739 	{
6740 		FreeAzureClient(s->AzureClient);
6741 		s->AzureClient = NULL;
6742 	}
6743 
6744 	FreeCfgRw(s->CfgRw);
6745 	s->CfgRw = NULL;
6746 
6747 	// Release the Ethernet
6748 	FreeEth();
6749 }
6750 
6751 // Initialize the StXxx related function
StInit()6752 void StInit()
6753 {
6754 	if (server_lock != NULL)
6755 	{
6756 		return;
6757 	}
6758 
6759 	server_lock = NewLock();
6760 }
6761 
6762 // Release the StXxx related function
StFree()6763 void StFree()
6764 {
6765 	DeleteLock(server_lock);
6766 	server_lock = NULL;
6767 }
6768 
6769 // Start the server
StStartServer(bool bridge)6770 void StStartServer(bool bridge)
6771 {
6772 	Lock(server_lock);
6773 	{
6774 		if (server != NULL)
6775 		{
6776 			// It has already started
6777 			Unlock(server_lock);
6778 			return;
6779 		}
6780 
6781 		// Create a server
6782 		server = SiNewServer(bridge);
6783 	}
6784 	Unlock(server_lock);
6785 
6786 //	StartCedarLog();
6787 }
6788 
6789 // Get the server
StGetServer()6790 SERVER *StGetServer()
6791 {
6792 	if (server == NULL)
6793 	{
6794 		return NULL;
6795 	}
6796 	return server;
6797 }
6798 
6799 // Stop the server
StStopServer()6800 void StStopServer()
6801 {
6802 	Lock(server_lock);
6803 	{
6804 		if (server == NULL)
6805 		{
6806 			// Not started
6807 			Unlock(server_lock);
6808 			return;
6809 		}
6810 
6811 		// Release the server
6812 		SiReleaseServer(server);
6813 		server = NULL;
6814 	}
6815 	Unlock(server_lock);
6816 
6817 	StopCedarLog();
6818 }
6819 
6820 // Set the type of server
SiSetServerType(SERVER * s,UINT type,UINT ip,UINT num_port,UINT * ports,char * controller_name,UINT controller_port,UCHAR * password,UINT weight,bool controller_only)6821 void SiSetServerType(SERVER *s, UINT type,
6822 					 UINT ip, UINT num_port, UINT *ports,
6823 					 char *controller_name, UINT controller_port, UCHAR *password, UINT weight, bool controller_only)
6824 {
6825 	bool bridge;
6826 	// Validate arguments
6827 	if (s == NULL)
6828 	{
6829 		return;
6830 	}
6831 	if (type == SERVER_TYPE_FARM_MEMBER &&
6832 		(num_port == 0 || ports == NULL || controller_name == NULL ||
6833 		controller_port == 0 || password == NULL || num_port > MAX_PUBLIC_PORT_NUM))
6834 	{
6835 		return;
6836 	}
6837 	if (weight == 0)
6838 	{
6839 		weight = FARM_DEFAULT_WEIGHT;
6840 	}
6841 
6842 	bridge = s->Cedar->Bridge;
6843 
6844 	Lock(s->lock);
6845 	{
6846 		// Update types
6847 		s->UpdatedServerType = type;
6848 
6849 		s->Weight = weight;
6850 
6851 		// Set the value
6852 		if (type == SERVER_TYPE_FARM_MEMBER)
6853 		{
6854 			StrCpy(s->ControllerName, sizeof(s->ControllerName), controller_name);
6855 			s->ControllerPort = controller_port;
6856 			if (IsZero(password, SHA1_SIZE) == false)
6857 			{
6858 				Copy(s->MemberPassword, password, SHA1_SIZE);
6859 			}
6860 			s->PublicIp = ip;
6861 			s->NumPublicPort = num_port;
6862 			if (s->PublicPorts != NULL)
6863 			{
6864 				Free(s->PublicPorts);
6865 			}
6866 			s->PublicPorts = ZeroMalloc(num_port * sizeof(UINT));
6867 			Copy(s->PublicPorts, ports, num_port * sizeof(UINT));
6868 		}
6869 
6870 		if (type == SERVER_TYPE_FARM_CONTROLLER)
6871 		{
6872 			s->ControllerOnly = controller_only;
6873 		}
6874 	}
6875 	Unlock(s->lock);
6876 
6877 	// Restart the server
6878 	SiRebootServer(bridge);
6879 }
6880 
6881 // Thread to restart the server
SiRebootServerThread(THREAD * thread,void * param)6882 void SiRebootServerThread(THREAD *thread, void *param)
6883 {
6884 	// Validate arguments
6885 	if (thread == NULL)
6886 	{
6887 		return;
6888 	}
6889 
6890 	if (server == NULL)
6891 	{
6892 		return;
6893 	}
6894 
6895 	// Stop the server
6896 	StStopServer();
6897 
6898 	// Start the server
6899 	StStartServer((bool)param);
6900 }
6901 
6902 // Restart the server
SiRebootServer(bool bridge)6903 void SiRebootServer(bool bridge)
6904 {
6905 	SiRebootServerEx(bridge, false);
6906 }
SiRebootServerEx(bool bridge,bool reset_setting)6907 void SiRebootServerEx(bool bridge, bool reset_setting)
6908 {
6909 	THREAD *t;
6910 
6911 	server_reset_setting = reset_setting;
6912 
6913 	t = NewThread(SiRebootServerThread, (void *)bridge);
6914 	ReleaseThread(t);
6915 }
6916 
6917 // Set the state of the special listener
SiApplySpecialListenerStatus(SERVER * s)6918 void SiApplySpecialListenerStatus(SERVER *s)
6919 {
6920 	// Validate arguments
6921 	if (s == NULL)
6922 	{
6923 		return;
6924 	}
6925 
6926 	if (s->DynListenerDns != NULL)
6927 	{
6928 		*s->DynListenerDns->EnablePtr = s->EnableVpnOverDns;
6929 		ApplyDynamicListener(s->DynListenerDns);
6930 	}
6931 
6932 	if (s->DynListenerIcmp != NULL)
6933 	{
6934 		*s->DynListenerIcmp->EnablePtr = s->EnableVpnOverIcmp;
6935 		ApplyDynamicListener(s->DynListenerIcmp);
6936 	}
6937 }
6938 
6939 // Stop all listeners
SiStopAllListener(SERVER * s)6940 void SiStopAllListener(SERVER *s)
6941 {
6942 	// Validate arguments
6943 	if (s == NULL)
6944 	{
6945 		return;
6946 	}
6947 
6948 	SiLockListenerList(s);
6949 	{
6950 		UINT i;
6951 		LIST *o = NewListFast(NULL);
6952 		for (i = 0;i < LIST_NUM(s->ServerListenerList);i++)
6953 		{
6954 			SERVER_LISTENER *e = LIST_DATA(s->ServerListenerList, i);
6955 			Add(o, e);
6956 		}
6957 
6958 		for (i = 0;i < LIST_NUM(o);i++)
6959 		{
6960 			SERVER_LISTENER *e = LIST_DATA(o, i);
6961 			SiDeleteListener(s, e->Port);
6962 		}
6963 
6964 		ReleaseList(o);
6965 	}
6966 	SiUnlockListenerList(s);
6967 
6968 	ReleaseList(s->ServerListenerList);
6969 
6970 	// Stop the VPN over ICMP listener
6971 	FreeDynamicListener(s->DynListenerIcmp);
6972 	s->DynListenerIcmp = NULL;
6973 
6974 	// Stop the VPN over DNS listener
6975 	FreeDynamicListener(s->DynListenerDns);
6976 	s->DynListenerDns = NULL;
6977 }
6978 
6979 // Clean-up the server
SiCleanupServer(SERVER * s)6980 void SiCleanupServer(SERVER *s)
6981 {
6982 	UINT i;
6983 	CEDAR *c;
6984 	LISTENER **listener_list;
6985 	UINT num_listener;
6986 	HUB **hub_list;
6987 	UINT num_hub;
6988 	// Validate arguments
6989 	if (s == NULL)
6990 	{
6991 		return;
6992 	}
6993 
6994 	SiFreeDeadLockCheck(s);
6995 
6996 
6997 	c = s->Cedar;
6998 
6999 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
7000 	{
7001 		// In the case of farm members, stop the connection to the farm controller
7002 		SLog(c, "LS_STOP_FARM_MEMBER");
7003 		SiStopConnectToController(s->FarmController);
7004 		s->FarmController = NULL;
7005 		SLog(c, "LS_STOP_FARM_MEMBER_2");
7006 	}
7007 
7008 	IncrementServerConfigRevision(s);
7009 
7010 	SLog(c, "LS_END_2");
7011 
7012 	SLog(c, "LS_STOP_ALL_LISTENER");
7013 	// Stop all listeners
7014 	LockList(c->ListenerList);
7015 	{
7016 		listener_list = ToArray(c->ListenerList);
7017 		num_listener = LIST_NUM(c->ListenerList);
7018 		for (i = 0;i < num_listener;i++)
7019 		{
7020 			AddRef(listener_list[i]->ref);
7021 		}
7022 	}
7023 	UnlockList(c->ListenerList);
7024 
7025 	for (i = 0;i < num_listener;i++)
7026 	{
7027 		StopListener(listener_list[i]);
7028 		ReleaseListener(listener_list[i]);
7029 	}
7030 	Free(listener_list);
7031 	SLog(c, "LS_STOP_ALL_LISTENER_2");
7032 
7033 	SLog(c, "LS_STOP_ALL_HUB");
7034 	// Stop all HUBs
7035 	LockList(c->HubList);
7036 	{
7037 		hub_list = ToArray(c->HubList);
7038 		num_hub = LIST_NUM(c->HubList);
7039 		for (i = 0;i < num_hub;i++)
7040 		{
7041 			AddRef(hub_list[i]->ref);
7042 		}
7043 	}
7044 	UnlockList(c->HubList);
7045 
7046 	for (i = 0;i < num_hub;i++)
7047 	{
7048 		StopHub(hub_list[i]);
7049 		ReleaseHub(hub_list[i]);
7050 	}
7051 	Free(hub_list);
7052 	SLog(c, "LS_STOP_ALL_HUB_2");
7053 
7054 	// Release the configuration
7055 	SiFreeConfiguration(s);
7056 
7057 	// Stop the Cedar
7058 	SLog(c, "LS_STOP_CEDAR");
7059 	StopCedar(s->Cedar);
7060 	SLog(c, "LS_STOP_CEDAR_2");
7061 
7062 	// Stop all listeners
7063 	SiStopAllListener(s);
7064 
7065 	if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
7066 	{
7067 		// In the case of farm controller
7068 		UINT i;
7069 
7070 		SLog(c, "LS_STOP_FARM_CONTROL");
7071 
7072 		// Stop the farm controling
7073 		SiStopFarmControl(s);
7074 
7075 		// Release the farm member information
7076 		ReleaseList(s->FarmMemberList);
7077 		s->FarmMemberList = NULL;
7078 
7079 		for (i = 0;i < LIST_NUM(s->Me->HubList);i++)
7080 		{
7081 			Free(LIST_DATA(s->Me->HubList, i));
7082 		}
7083 		ReleaseList(s->Me->HubList);
7084 
7085 		Free(s->Me);
7086 
7087 		SLog(c, "LS_STOP_FARM_CONTROL_2");
7088 	}
7089 
7090 	if (s->PublicPorts != NULL)
7091 	{
7092 		Free(s->PublicPorts);
7093 	}
7094 
7095 	SLog(s->Cedar, "LS_END_1");
7096 	SLog(s->Cedar, "L_LINE");
7097 
7098 #ifdef	ENABLE_AZURE_SERVER
7099 	if (s->AzureServer != NULL)
7100 	{
7101 		FreeAzureServer(s->AzureServer);
7102 	}
7103 #endif	// ENABLE_AZURE_SERVER
7104 
7105 	ReleaseCedar(s->Cedar);
7106 	DeleteLock(s->lock);
7107 	DeleteLock(s->SaveCfgLock);
7108 
7109 	StopKeep(s->Keep);
7110 
7111 	FreeEraser(s->Eraser);
7112 
7113 
7114 	FreeLog(s->Logger);
7115 
7116 	FreeSysLog(s->Syslog);
7117 	DeleteLock(s->SyslogLock);
7118 
7119 	FreeServerCapsCache(s);
7120 
7121 	SiFreeHubCreateHistory(s);
7122 
7123 	// Stop the debug log
7124 	FreeTinyLog(s->DebugLog);
7125 
7126 	DeleteLock(s->TasksFromFarmControllerLock);
7127 	DeleteLock(s->OpenVpnSstpConfigLock);
7128 
7129 
7130 	Free(s);
7131 }
7132 
7133 // Release the server
SiReleaseServer(SERVER * s)7134 void SiReleaseServer(SERVER *s)
7135 {
7136 	// Validate arguments
7137 	if (s == NULL)
7138 	{
7139 		return;
7140 	}
7141 
7142 	if (Release(s->ref) == 0)
7143 	{
7144 		SiCleanupServer(s);
7145 	}
7146 }
7147 
7148 // Get the URL of the member selector
SiGetMemberSelectorUrl(char * url,UINT url_size)7149 bool SiGetMemberSelectorUrl(char *url, UINT url_size)
7150 {
7151 	BUF *b;
7152 	bool ret = false;
7153 	// Validate arguments
7154 	if (url == NULL)
7155 	{
7156 		return false;
7157 	}
7158 
7159 	b = ReadDump(MEMBER_SELECTOR_TXT_FILENAME);
7160 	if (b == NULL)
7161 	{
7162 		return false;
7163 	}
7164 
7165 	while (true)
7166 	{
7167 		char *line = CfgReadNextLine(b);
7168 		if (line == NULL)
7169 		{
7170 			break;
7171 		}
7172 
7173 		Trim(line);
7174 
7175 		if (IsEmptyStr(line) == false && ret == false)
7176 		{
7177 			StrCpy(url, url_size, line);
7178 			ret = true;
7179 		}
7180 
7181 		Free(line);
7182 	}
7183 
7184 	FreeBuf(b);
7185 
7186 	return ret;
7187 }
7188 
7189 // Specify the farm member for the next processing
SiGetNextFarmMember(SERVER * s,CONNECTION * c,HUB * h)7190 FARM_MEMBER *SiGetNextFarmMember(SERVER *s, CONNECTION *c, HUB *h)
7191 {
7192 	UINT i, num;
7193 	UINT min_point = 0;
7194 	FARM_MEMBER *ret = NULL;
7195 	PACK *p;
7196 	char url[MAX_SIZE];
7197 	// Validate arguments
7198 	if (s == NULL || s->ServerType != SERVER_TYPE_FARM_CONTROLLER || c == NULL || h == NULL)
7199 	{
7200 		return NULL;
7201 	}
7202 
7203 	num = LIST_NUM(s->FarmMemberList);
7204 	if (num == 0)
7205 	{
7206 		return NULL;
7207 	}
7208 
7209 	if (SiGetMemberSelectorUrl(url, sizeof(url)))
7210 	{
7211 		UINT64 ret_key = 0;
7212 		// Generate the data for the member selector
7213 		p = NewPack();
7214 		for (i = 0;i < num;i++)
7215 		{
7216 			UINT num_sessions;
7217 			UINT max_sessions;
7218 			FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
7219 			bool do_not_select = false;
7220 			if (s->ControllerOnly)
7221 			{
7222 				if (f->Me)
7223 				{
7224 					// No to select myself in the case of ControllerOnly
7225 					do_not_select = true;
7226 				}
7227 			}
7228 
7229 			if (f->Me == false)
7230 			{
7231 				num_sessions = f->NumSessions;
7232 				max_sessions = f->MaxSessions;
7233 			}
7234 			else
7235 			{
7236 				num_sessions = Count(s->Cedar->CurrentSessions);
7237 				max_sessions = GetServerCapsInt(s, "i_max_sessions");
7238 			}
7239 
7240 			if (max_sessions == 0)
7241 			{
7242 				max_sessions = GetServerCapsInt(s, "i_max_sessions");
7243 			}
7244 
7245 			if (num_sessions >= max_sessions)
7246 			{
7247 				do_not_select = true;
7248 			}
7249 
7250 			if (true)
7251 			{
7252 				UINT point = f->Point;
7253 				char public_ip_str[MAX_SIZE];
7254 
7255 				IPToStr32(public_ip_str, sizeof(public_ip_str), f->Ip);
7256 
7257 				PackAddIntEx(p, "Point", point, i, num);
7258 				PackAddInt64Ex(p, "Key", (UINT64)f, i, num);
7259 				PackAddStrEx(p, "Hostname", f->hostname, i, num);
7260 				PackAddStrEx(p, "PublicIp", public_ip_str, i, num);
7261 				PackAddIntEx(p, "NumSessions", num_sessions, i, num);
7262 				PackAddIntEx(p, "MaxSessions", max_sessions, i, num);
7263 				PackAddIntEx(p, "AssignedClientLicense", f->AssignedClientLicense, i, num);
7264 				PackAddIntEx(p, "AssignedBridgeLicense", f->AssignedBridgeLicense, i, num);
7265 				PackAddIntEx(p, "Weight", f->Weight, i, num);
7266 				PackAddDataEx(p, "RandomKey", f->RandomKey, SHA1_SIZE, i, num);
7267 				PackAddIntEx(p, "NumTcpConnections", f->NumTcpConnections, i, num);
7268 				PackAddIntEx(p, "NumHubs", LIST_NUM(f->HubList), i, num);
7269 				PackAddBoolEx(p, "Me", f->Me, i, num);
7270 				PackAddTime64Ex(p, "ConnectedTime", f->ConnectedTime, i, num);
7271 				PackAddInt64Ex(p, "SystemId", f->SystemId, i, num);
7272 				PackAddBoolEx(p, "DoNotSelect", do_not_select, i, num);
7273 			}
7274 		}
7275 
7276 		if (true)
7277 		{
7278 			char client_ip_str[MAX_SIZE];
7279 			UINT client_port = 0;
7280 			UINT server_port = 0;
7281 			SOCK *s = c->FirstSock;
7282 
7283 			Zero(client_ip_str, sizeof(client_ip_str));
7284 			if (s != NULL)
7285 			{
7286 				IPToStr(client_ip_str, sizeof(client_ip_str), &s->RemoteIP);
7287 				client_port = s->RemotePort;
7288 				server_port = s->LocalPort;
7289 			}
7290 
7291 			PackAddStr(p, "ClientIp", client_ip_str);
7292 			PackAddInt(p, "ClientPort", client_port);
7293 			PackAddInt(p, "ServerPort", server_port);
7294 
7295 			PackAddInt(p, "ClientBuild", c->ClientBuild);
7296 			PackAddStr(p, "CipherName", c->CipherName);
7297 			PackAddStr(p, "ClientStr", c->ClientStr);
7298 			PackAddInt(p, "ClientVer", c->ClientVer);
7299 			PackAddTime64(p, "ConnectedTime", Tick64ToTime64(c->ConnectedTick));
7300 
7301 			PackAddStr(p, "HubName", h->Name);
7302 			PackAddBool(p, "StaticHub", h->Type == HUB_TYPE_FARM_STATIC);
7303 		}
7304 
7305 		PackAddInt(p, "NumMembers", num);
7306 
7307 		// Make the member selector choose a member
7308 		UnlockList(s->FarmMemberList);
7309 		Unlock(s->Cedar->CedarSuperLock);
7310 		{
7311 			PACK *ret;
7312 
7313 			Debug("Calling %s ...\n", url);
7314 
7315 			ret = WpcCall(url, NULL, MEMBER_SELECTOR_CONNECT_TIMEOUT, MEMBER_SELECTOR_DATA_TIMEOUT,
7316 				"Select", p, NULL, NULL, NULL);
7317 
7318 			if (GetErrorFromPack(ret) == ERR_NO_ERROR)
7319 			{
7320 				ret_key = PackGetInt64(ret, "Key");
7321 				Debug("Ret Key = %I64u\n", ret_key);
7322 			}
7323 			else
7324 			{
7325 				Debug("Error: %u\n", GetErrorFromPack(ret));
7326 			}
7327 
7328 			FreePack(ret);
7329 		}
7330 		Lock(s->Cedar->CedarSuperLock);
7331 		LockList(s->FarmMemberList);
7332 
7333 		FreePack(p);
7334 
7335 		if (ret_key != 0)
7336 		{
7337 			FARM_MEMBER *f = (FARM_MEMBER *)ret_key;
7338 			if (IsInList(s->FarmMemberList, f))
7339 			{
7340 				Debug("Farm Member Selected by Selector: %s\n", f->hostname);
7341 
7342 				return f;
7343 			}
7344 			else
7345 			{
7346 				Debug("Farm Member Key = %I64u Not Found.\n", ret_key);
7347 			}
7348 		}
7349 		else
7350 		{
7351 			// The member selector failed to select a member
7352 			return NULL;
7353 		}
7354 	}
7355 
7356 	num = LIST_NUM(s->FarmMemberList);
7357 	if (num == 0)
7358 	{
7359 		return NULL;
7360 	}
7361 
7362 	for (i = 0;i < num;i++)
7363 	{
7364 		UINT num_sessions;
7365 		UINT max_sessions;
7366 		FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
7367 		if (s->ControllerOnly)
7368 		{
7369 			if (f->Me)
7370 			{
7371 				// No to select myself in the case of ControllerOnly
7372 				continue;
7373 			}
7374 		}
7375 
7376 		if (f->Me == false)
7377 		{
7378 			num_sessions = f->NumSessions;
7379 			max_sessions = f->MaxSessions;
7380 		}
7381 		else
7382 		{
7383 			num_sessions = Count(s->Cedar->CurrentSessions);
7384 			max_sessions = GetServerCapsInt(s, "i_max_sessions");
7385 		}
7386 
7387 		if (max_sessions == 0)
7388 		{
7389 			max_sessions = GetServerCapsInt(s, "i_max_sessions");
7390 		}
7391 
7392 		if (num_sessions < max_sessions)
7393 		{
7394 			if (f->Point >= min_point)
7395 			{
7396 				min_point = f->Point;
7397 				ret = f;
7398 			}
7399 		}
7400 	}
7401 
7402 	return ret;
7403 }
7404 
7405 // Receive a HUB enumeration directive
SiCalledEnumHub(SERVER * s,PACK * p,PACK * req)7406 void SiCalledEnumHub(SERVER *s, PACK *p, PACK *req)
7407 {
7408 	UINT i;
7409 	CEDAR *c;
7410 	UINT num = 0;
7411 	// Validate arguments
7412 	if (s == NULL || p == NULL || req == NULL)
7413 	{
7414 		return;
7415 	}
7416 
7417 
7418 	c = s->Cedar;
7419 
7420 	LockList(c->HubList);
7421 	{
7422 		UINT num = LIST_NUM(c->HubList);
7423 		for (i = 0;i < num;i++)
7424 		{
7425 			HUB *h = LIST_DATA(c->HubList, i);
7426 			Lock(h->lock);
7427 			{
7428 				PackAddStrEx(p, "HubName", h->Name, i, num);
7429 				PackAddIntEx(p, "HubType", h->Type, i, num);
7430 				PackAddIntEx(p, "NumSession", Count(h->NumSessions), i, num);
7431 
7432 				PackAddIntEx(p, "NumSessions", LIST_NUM(h->SessionList), i, num);
7433 				PackAddIntEx(p, "NumSessionsClient", Count(h->NumSessionsClient), i, num);
7434 				PackAddIntEx(p, "NumSessionsBridge", Count(h->NumSessionsBridge), i, num);
7435 
7436 				PackAddIntEx(p, "NumMacTables", HASH_LIST_NUM(h->MacHashTable), i, num);
7437 
7438 				PackAddIntEx(p, "NumIpTables", LIST_NUM(h->IpTable), i, num);
7439 
7440 				PackAddTime64Ex(p, "LastCommTime", h->LastCommTime, i, num);
7441 				PackAddTime64Ex(p, "CreatedTime", h->CreatedTime, i, num);
7442 			}
7443 			Unlock(h->lock);
7444 		}
7445 	}
7446 	UnlockList(c->HubList);
7447 
7448 	PackAddInt(p, "Point", SiGetPoint(s));
7449 	PackAddInt(p, "NumTcpConnections", Count(s->Cedar->CurrentTcpConnections));
7450 	PackAddInt(p, "NumTotalSessions", Count(s->Cedar->CurrentSessions));
7451 	PackAddInt(p, "MaxSessions", GetServerCapsInt(s, "i_max_sessions"));
7452 
7453 	PackAddInt(p, "AssignedClientLicense", Count(s->Cedar->AssignedClientLicense));
7454 	PackAddInt(p, "AssignedBridgeLicense", Count(s->Cedar->AssignedBridgeLicense));
7455 
7456 	PackAddData(p, "RandomKey", s->MyRandomKey, SHA1_SIZE);
7457 
7458 
7459 	Lock(c->TrafficLock);
7460 	{
7461 		OutRpcTraffic(p, c->Traffic);
7462 	}
7463 	Unlock(c->TrafficLock);
7464 
7465 	LockList(c->TrafficDiffList);
7466 	{
7467 		UINT num = LIST_NUM(c->TrafficDiffList);
7468 		UINT i;
7469 
7470 		for (i = 0;i < num;i++)
7471 		{
7472 			TRAFFIC_DIFF *d = LIST_DATA(c->TrafficDiffList, i);
7473 
7474 			PackAddIntEx(p, "TdType", d->Type, i, num);
7475 			PackAddStrEx(p, "TdHubName", d->HubName, i, num);
7476 			PackAddStrEx(p, "TdName", d->Name, i, num);
7477 
7478 			OutRpcTrafficEx(&d->Traffic, p, i, num);
7479 
7480 			Free(d->HubName);
7481 			Free(d->Name);
7482 			Free(d);
7483 		}
7484 
7485 		DeleteAll(c->TrafficDiffList);
7486 	}
7487 	UnlockList(c->TrafficDiffList);
7488 }
7489 
7490 // Receive a HUB delete directive
SiCalledDeleteHub(SERVER * s,PACK * p)7491 void SiCalledDeleteHub(SERVER *s, PACK *p)
7492 {
7493 	char name[MAX_SIZE];
7494 	HUB *h;
7495 	// Validate arguments
7496 	if (s == NULL || p == NULL)
7497 	{
7498 		return;
7499 	}
7500 
7501 	if (PackGetStr(p, "HubName", name, sizeof(name)) == false)
7502 	{
7503 		return;
7504 	}
7505 
7506 	LockHubList(s->Cedar);
7507 
7508 	h = GetHub(s->Cedar, name);
7509 	if (h == NULL)
7510 	{
7511 		UnlockHubList(s->Cedar);
7512 		return;
7513 	}
7514 	UnlockHubList(s->Cedar);
7515 
7516 	SetHubOffline(h);
7517 
7518 	LockHubList(s->Cedar);
7519 
7520 	DelHubEx(s->Cedar, h, true);
7521 
7522 	UnlockHubList(s->Cedar);
7523 
7524 	ReleaseHub(h);
7525 }
7526 
7527 // Receive a HUB update directive
SiCalledUpdateHub(SERVER * s,PACK * p)7528 void SiCalledUpdateHub(SERVER *s, PACK *p)
7529 {
7530 	char name[MAX_SIZE];
7531 	UINT type;
7532 	HUB_OPTION o;
7533 	HUB_LOG log;
7534 	bool save_packet_log;
7535 	UINT packet_log_switch_type;
7536 	UINT packet_log_config[NUM_PACKET_LOG];
7537 	bool save_security_log;
7538 	bool type_changed = false;
7539 	UINT security_log_switch_type;
7540 	UINT i;
7541 	HUB *h;
7542 	// Validate arguments
7543 	if (s == NULL || p == NULL)
7544 	{
7545 		return;
7546 	}
7547 
7548 	PackGetStr(p, "HubName", name, sizeof(name));
7549 	type = PackGetInt(p, "HubType");
7550 	Zero(&o, sizeof(o));
7551 	o.MaxSession = PackGetInt(p, "MaxSession");
7552 	o.NoArpPolling = PackGetBool(p, "NoArpPolling");
7553 	o.NoIPv6AddrPolling = PackGetBool(p, "NoIPv6AddrPolling");
7554 	o.FilterPPPoE = PackGetBool(p, "FilterPPPoE");
7555 	o.YieldAfterStorePacket = PackGetBool(p, "YieldAfterStorePacket");
7556 	o.NoSpinLockForPacketDelay = PackGetBool(p, "NoSpinLockForPacketDelay");
7557 	o.BroadcastStormDetectionThreshold = PackGetInt(p, "BroadcastStormDetectionThreshold");
7558 	o.ClientMinimumRequiredBuild = PackGetInt(p, "ClientMinimumRequiredBuild");
7559 	o.FixForDLinkBPDU = PackGetBool(p, "FixForDLinkBPDU");
7560 	o.BroadcastLimiterStrictMode = PackGetBool(p, "BroadcastLimiterStrictMode");
7561 	o.NoLookBPDUBridgeId = PackGetBool(p, "NoLookBPDUBridgeId");
7562 	o.NoManageVlanId = PackGetBool(p, "NoManageVlanId");
7563 	o.MaxLoggedPacketsPerMinute = PackGetInt(p, "MaxLoggedPacketsPerMinute");
7564 	o.FloodingSendQueueBufferQuota = PackGetInt(p, "FloodingSendQueueBufferQuota");
7565 	o.DoNotSaveHeavySecurityLogs = PackGetBool(p, "DoNotSaveHeavySecurityLogs");
7566 	o.DropBroadcastsInPrivacyFilterMode = PackGetBool(p, "DropBroadcastsInPrivacyFilterMode");
7567 	o.DropArpInPrivacyFilterMode = PackGetBool(p, "DropArpInPrivacyFilterMode");
7568 	o.SuppressClientUpdateNotification = PackGetBool(p, "SuppressClientUpdateNotification");
7569 	o.AssignVLanIdByRadiusAttribute = PackGetBool(p, "AssignVLanIdByRadiusAttribute");
7570 	o.DenyAllRadiusLoginWithNoVlanAssign = PackGetBool(p, "DenyAllRadiusLoginWithNoVlanAssign");
7571 	o.SecureNAT_RandomizeAssignIp = PackGetBool(p, "SecureNAT_RandomizeAssignIp");
7572 	o.DetectDormantSessionInterval = PackGetInt(p, "DetectDormantSessionInterval");
7573 	o.VlanTypeId = PackGetInt(p, "VlanTypeId");
7574 	o.NoPhysicalIPOnPacketLog = PackGetBool(p, "NoPhysicalIPOnPacketLog");
7575 	if (o.VlanTypeId == 0)
7576 	{
7577 		o.VlanTypeId = MAC_PROTO_TAGVLAN;
7578 	}
7579 	o.FilterOSPF = PackGetBool(p, "FilterOSPF");
7580 	o.FilterIPv4 = PackGetBool(p, "FilterIPv4");
7581 	o.FilterIPv6 = PackGetBool(p, "FilterIPv6");
7582 	o.FilterNonIP = PackGetBool(p, "FilterNonIP");
7583 	o.NoIPv4PacketLog = PackGetBool(p, "NoIPv4PacketLog");
7584 	o.NoIPv6PacketLog = PackGetBool(p, "NoIPv6PacketLog");
7585 	o.FilterBPDU = PackGetBool(p, "FilterBPDU");
7586 	o.NoIPv6DefaultRouterInRAWhenIPv6 = PackGetBool(p, "NoIPv6DefaultRouterInRAWhenIPv6");
7587 	o.NoMacAddressLog = PackGetBool(p, "NoMacAddressLog");
7588 	o.ManageOnlyPrivateIP = PackGetBool(p, "ManageOnlyPrivateIP");
7589 	o.ManageOnlyLocalUnicastIPv6 = PackGetBool(p, "ManageOnlyLocalUnicastIPv6");
7590 	o.DisableIPParsing = PackGetBool(p, "DisableIPParsing");
7591 	o.NoIpTable = PackGetBool(p, "NoIpTable");
7592 	o.NoEnum = PackGetBool(p, "NoEnum");
7593 	o.AdjustTcpMssValue = PackGetInt(p, "AdjustTcpMssValue");
7594 	o.DisableAdjustTcpMss = PackGetBool(p, "DisableAdjustTcpMss");
7595 	o.NoDhcpPacketLogOutsideHub = PackGetBool(p, "NoDhcpPacketLogOutsideHub");
7596 	o.DisableHttpParsing = PackGetBool(p, "DisableHttpParsing");
7597 	o.DisableUdpAcceleration = PackGetBool(p, "DisableUdpAcceleration");
7598 	o.DisableUdpFilterForLocalBridgeNic = PackGetBool(p, "DisableUdpFilterForLocalBridgeNic");
7599 	o.ApplyIPv4AccessListOnArpPacket = PackGetBool(p, "ApplyIPv4AccessListOnArpPacket");
7600 	o.RemoveDefGwOnDhcpForLocalhost = PackGetBool(p, "RemoveDefGwOnDhcpForLocalhost");
7601 	o.SecureNAT_MaxTcpSessionsPerIp = PackGetInt(p, "SecureNAT_MaxTcpSessionsPerIp");
7602 	o.SecureNAT_MaxTcpSynSentPerIp = PackGetInt(p, "SecureNAT_MaxTcpSynSentPerIp");
7603 	o.SecureNAT_MaxUdpSessionsPerIp = PackGetInt(p, "SecureNAT_MaxUdpSessionsPerIp");
7604 	o.SecureNAT_MaxDnsSessionsPerIp = PackGetInt(p, "SecureNAT_MaxDnsSessionsPerIp");
7605 	o.SecureNAT_MaxIcmpSessionsPerIp = PackGetInt(p, "SecureNAT_MaxIcmpSessionsPerIp");
7606 	o.AccessListIncludeFileCacheLifetime = PackGetInt(p, "AccessListIncludeFileCacheLifetime");
7607 	if (o.AccessListIncludeFileCacheLifetime == 0)
7608 	{
7609 		o.AccessListIncludeFileCacheLifetime = ACCESS_LIST_INCLUDE_FILE_CACHE_LIFETIME;
7610 	}
7611 	o.DisableKernelModeSecureNAT = PackGetBool(p, "DisableKernelModeSecureNAT");
7612 	o.DisableIpRawModeSecureNAT = PackGetBool(p, "DisableIpRawModeSecureNAT");
7613 	o.DisableUserModeSecureNAT = PackGetBool(p, "DisableUserModeSecureNAT");
7614 	o.DisableCheckMacOnLocalBridge = PackGetBool(p, "DisableCheckMacOnLocalBridge");
7615 	o.DisableCorrectIpOffloadChecksum = PackGetBool(p, "DisableCorrectIpOffloadChecksum");
7616 	o.UseHubNameAsDhcpUserClassOption = PackGetBool(p, "UseHubNameAsDhcpUserClassOption");
7617 	o.UseHubNameAsRadiusNasId = PackGetBool(p, "UseHubNameAsRadiusNasId");
7618 
7619 	save_packet_log = PackGetInt(p, "SavePacketLog");
7620 	packet_log_switch_type = PackGetInt(p, "PacketLogSwitchType");
7621 	for (i = 0;i < NUM_PACKET_LOG;i++)
7622 	{
7623 		packet_log_config[i] = PackGetIntEx(p, "PacketLogConfig", i);
7624 	}
7625 	save_security_log = PackGetInt(p, "SaveSecurityLog");
7626 	security_log_switch_type = PackGetInt(p, "SecurityLogSwitchType");
7627 
7628 	Zero(&log, sizeof(log));
7629 	log.SavePacketLog = save_packet_log;
7630 	log.PacketLogSwitchType = packet_log_switch_type;
7631 	Copy(log.PacketLogConfig, packet_log_config, sizeof(log.PacketLogConfig));
7632 	log.SaveSecurityLog = save_security_log;
7633 	log.SecurityLogSwitchType = security_log_switch_type;
7634 
7635 	h = GetHub(s->Cedar, name);
7636 	if (h == NULL)
7637 	{
7638 		return;
7639 	}
7640 
7641 	h->FarmMember_MaxSessionClient = PackGetInt(p, "MaxSessionClient");
7642 	h->FarmMember_MaxSessionBridge = PackGetInt(p, "MaxSessionBridge");
7643 	h->FarmMember_MaxSessionClientBridgeApply = PackGetBool(p, "MaxSessionClientBridgeApply");
7644 
7645 	if (h->FarmMember_MaxSessionClientBridgeApply == false)
7646 	{
7647 		h->FarmMember_MaxSessionClient = INFINITE;
7648 		h->FarmMember_MaxSessionBridge = INFINITE;
7649 	}
7650 
7651 	Lock(h->lock);
7652 	{
7653 		Copy(h->Option, &o, sizeof(HUB_OPTION));
7654 		PackGetData2(p, "SecurePassword", h->SecurePassword, SHA1_SIZE);
7655 		PackGetData2(p, "HashedPassword", h->HashedPassword, SHA1_SIZE);
7656 	}
7657 	Unlock(h->lock);
7658 
7659 	SetHubLogSetting(h, &log);
7660 
7661 	if (h->Type != type)
7662 	{
7663 		h->Type = type;
7664 		type_changed = true;
7665 	}
7666 
7667 	LockList(h->AccessList);
7668 	{
7669 		UINT i;
7670 		for (i = 0;i < LIST_NUM(h->AccessList);i++)
7671 		{
7672 			ACCESS *a = LIST_DATA(h->AccessList, i);
7673 			Free(a);
7674 		}
7675 		DeleteAll(h->AccessList);
7676 	}
7677 	UnlockList(h->AccessList);
7678 
7679 	for (i = 0;i < SiNumAccessFromPack(p);i++)
7680 	{
7681 		ACCESS *a = SiPackToAccess(p, i);
7682 		AddAccessList(h, a);
7683 		Free(a);
7684 	}
7685 
7686 	if (PackGetBool(p, "EnableSecureNAT"))
7687 	{
7688 		VH_OPTION t;
7689 		bool changed;
7690 
7691 		InVhOption(&t, p);
7692 
7693 		changed = Cmp(h->SecureNATOption, &t, sizeof(VH_OPTION)) == 0 ? false : true;
7694 		Copy(h->SecureNATOption, &t, sizeof(VH_OPTION));
7695 
7696 		EnableSecureNAT(h, true);
7697 
7698 		if (changed)
7699 		{
7700 			Lock(h->lock_online);
7701 			{
7702 				if (h->SecureNAT != NULL)
7703 				{
7704 					SetVirtualHostOption(h->SecureNAT->Nat->Virtual, &t);
7705 					Debug("SiCalledUpdateHub: SecureNAT Updated.\n");
7706 				}
7707 			}
7708 			Unlock(h->lock_online);
7709 		}
7710 	}
7711 	else
7712 	{
7713 		EnableSecureNAT(h, false);
7714 		Debug("SiCalledUpdateHub: SecureNAT Disabled.\n");
7715 	}
7716 
7717 	if (type_changed)
7718 	{
7719 		// Remove all sessions since the type of HUB has been changed
7720 		if (h->Offline == false)
7721 		{
7722 			SetHubOffline(h);
7723 			SetHubOnline(h);
7724 		}
7725 	}
7726 
7727 	ReleaseHub(h);
7728 }
7729 
7730 // Inspect the ticket
SiCheckTicket(HUB * h,UCHAR * ticket,char * username,UINT username_size,char * usernamereal,UINT usernamereal_size,POLICY * policy,char * sessionname,UINT sessionname_size,char * groupname,UINT groupname_size)7731 bool SiCheckTicket(HUB *h, UCHAR *ticket, char *username, UINT username_size, char *usernamereal, UINT usernamereal_size, POLICY *policy, char *sessionname, UINT sessionname_size, char *groupname, UINT groupname_size)
7732 {
7733 	bool ret = false;
7734 	// Validate arguments
7735 	if (h == NULL || ticket == NULL || username == NULL || usernamereal == NULL || policy == NULL || sessionname == NULL)
7736 	{
7737 		return false;
7738 	}
7739 
7740 	LockList(h->TicketList);
7741 	{
7742 		UINT i;
7743 		for (i = 0;i < LIST_NUM(h->TicketList);i++)
7744 		{
7745 			TICKET *t = LIST_DATA(h->TicketList, i);
7746 			if (Cmp(t->Ticket, ticket, SHA1_SIZE) == 0)
7747 			{
7748 				ret = true;
7749 				StrCpy(username, username_size, t->Username);
7750 				StrCpy(usernamereal, usernamereal_size, t->UsernameReal);
7751 				StrCpy(sessionname, sessionname_size, t->SessionName);
7752 				StrCpy(groupname, groupname_size, t->GroupName);
7753 				Copy(policy, &t->Policy, sizeof(POLICY));
7754 				Delete(h->TicketList, t);
7755 				Free(t);
7756 				break;
7757 			}
7758 		}
7759 	}
7760 	UnlockList(h->TicketList);
7761 
7762 	return ret;
7763 }
7764 
7765 // Receive a MAC address deletion directive
SiCalledDeleteMacTable(SERVER * s,PACK * p)7766 void SiCalledDeleteMacTable(SERVER *s, PACK *p)
7767 {
7768 	UINT key;
7769 	char hubname[MAX_HUBNAME_LEN + 1];
7770 	HUB *h;
7771 	// Validate arguments
7772 	if (s == NULL || p == NULL)
7773 	{
7774 		return;
7775 	}
7776 
7777 	if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)
7778 	{
7779 		return;
7780 	}
7781 	key = PackGetInt(p, "Key");
7782 
7783 	LockHubList(s->Cedar);
7784 	{
7785 		h = GetHub(s->Cedar, hubname);
7786 	}
7787 	UnlockHubList(s->Cedar);
7788 
7789 	if (h == NULL)
7790 	{
7791 		return;
7792 	}
7793 
7794 	LockHashList(h->MacHashTable);
7795 	{
7796 		MAC_TABLE_ENTRY *e = HashListKeyToPointer(h->MacHashTable, key);
7797 		DeleteHash(h->MacHashTable, e);
7798 		Free(e);
7799 	}
7800 	UnlockHashList(h->MacHashTable);
7801 
7802 	ReleaseHub(h);
7803 }
7804 
7805 // Receive an IP address delete directive
SiCalledDeleteIpTable(SERVER * s,PACK * p)7806 void SiCalledDeleteIpTable(SERVER *s, PACK *p)
7807 {
7808 	UINT key;
7809 	char hubname[MAX_HUBNAME_LEN + 1];
7810 	HUB *h;
7811 	// Validate arguments
7812 	if (s == NULL || p == NULL)
7813 	{
7814 		return;
7815 	}
7816 
7817 	if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)
7818 	{
7819 		return;
7820 	}
7821 	key = PackGetInt(p, "Key");
7822 
7823 	LockHubList(s->Cedar);
7824 	{
7825 		h = GetHub(s->Cedar, hubname);
7826 	}
7827 	UnlockHubList(s->Cedar);
7828 
7829 	if (h == NULL)
7830 	{
7831 		return;
7832 	}
7833 
7834 	LockList(h->IpTable);
7835 	{
7836 		if (IsInList(h->IpTable, (void *)key))
7837 		{
7838 			IP_TABLE_ENTRY *e = (IP_TABLE_ENTRY *)key;
7839 			Delete(h->IpTable, e);
7840 			Free(e);
7841 		}
7842 	}
7843 	UnlockList(h->IpTable);
7844 
7845 	ReleaseHub(h);
7846 }
7847 
7848 // Receive a session deletion directive
SiCalledDeleteSession(SERVER * s,PACK * p)7849 void SiCalledDeleteSession(SERVER *s, PACK *p)
7850 {
7851 	char name[MAX_SESSION_NAME_LEN + 1];
7852 	char hubname[MAX_HUBNAME_LEN + 1];
7853 	HUB *h;
7854 	SESSION *sess;
7855 	// Validate arguments
7856 	if (s == NULL || p == NULL)
7857 	{
7858 		return;
7859 	}
7860 
7861 	if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)
7862 	{
7863 		return;
7864 	}
7865 	if (PackGetStr(p, "SessionName", name, sizeof(name)) == false)
7866 	{
7867 		return;
7868 	}
7869 
7870 	LockHubList(s->Cedar);
7871 	{
7872 		h = GetHub(s->Cedar, hubname);
7873 	}
7874 	UnlockHubList(s->Cedar);
7875 
7876 	if (h == NULL)
7877 	{
7878 		return;
7879 	}
7880 
7881 	sess = GetSessionByName(h, name);
7882 
7883 	if (sess != NULL)
7884 	{
7885 		if (sess->BridgeMode == false && sess->LinkModeServer == false && sess->SecureNATMode == false)
7886 		{
7887 			StopSession(sess);
7888 		}
7889 		ReleaseSession(sess);
7890 	}
7891 
7892 	ReleaseHub(h);
7893 }
7894 
7895 // Receive a log file reading directive
SiCalledReadLogFile(SERVER * s,PACK * p)7896 PACK *SiCalledReadLogFile(SERVER *s, PACK *p)
7897 {
7898 	RPC_READ_LOG_FILE t;
7899 	PACK *ret;
7900 	char filepath[MAX_PATH];
7901 	UINT offset;
7902 	// Validate arguments
7903 	if (s == NULL || p == NULL)
7904 	{
7905 		return NULL;
7906 	}
7907 
7908 	PackGetStr(p, "FilePath", filepath, sizeof(filepath));
7909 	offset = PackGetInt(p, "Offset");
7910 
7911 	Zero(&t, sizeof(t));
7912 
7913 	SiReadLocalLogFile(s, filepath, offset, &t);
7914 
7915 	ret = NewPack();
7916 
7917 	OutRpcReadLogFile(ret, &t);
7918 	FreeRpcReadLogFile(&t);
7919 
7920 	return ret;
7921 }
7922 
7923 // Receive a log file enumeration directive
SiCalledEnumLogFileList(SERVER * s,PACK * p)7924 PACK *SiCalledEnumLogFileList(SERVER *s, PACK *p)
7925 {
7926 	RPC_ENUM_LOG_FILE t;
7927 	PACK *ret;
7928 	char hubname[MAX_HUBNAME_LEN + 1];
7929 	// Validate arguments
7930 	if (s == NULL || p == NULL)
7931 	{
7932 		return NULL;
7933 	}
7934 
7935 	PackGetStr(p, "HubName", hubname, sizeof(hubname));
7936 
7937 	Zero(&t, sizeof(t));
7938 
7939 	SiEnumLocalLogFileList(s, hubname, &t);
7940 
7941 	ret = NewPack();
7942 
7943 	OutRpcEnumLogFile(ret, &t);
7944 	FreeRpcEnumLogFile(&t);
7945 
7946 	return ret;
7947 }
7948 
7949 // Receive a session information directive
SiCalledGetSessionStatus(SERVER * s,PACK * p)7950 PACK *SiCalledGetSessionStatus(SERVER *s, PACK *p)
7951 {
7952 	RPC_SESSION_STATUS t;
7953 	ADMIN a;
7954 	PACK *ret;
7955 	// Validate arguments
7956 	if (s == NULL || p == NULL)
7957 	{
7958 		return NULL;
7959 	}
7960 
7961 	Zero(&t, sizeof(t));
7962 	InRpcSessionStatus(&t, p);
7963 
7964 	Zero(&a, sizeof(a));
7965 	a.Server = s;
7966 	a.ServerAdmin = true;
7967 
7968 	if (StGetSessionStatus(&a, &t) != ERR_NO_ERROR)
7969 	{
7970 		FreeRpcSessionStatus(&t);
7971 		return NULL;
7972 	}
7973 
7974 	ret = NewPack();
7975 
7976 	OutRpcSessionStatus(ret, &t);
7977 
7978 	FreeRpcSessionStatus(&t);
7979 
7980 	return ret;
7981 }
7982 
7983 // IP table enumeration directive
SiCalledEnumIpTable(SERVER * s,PACK * p)7984 PACK *SiCalledEnumIpTable(SERVER *s, PACK *p)
7985 {
7986 	char hubname[MAX_HUBNAME_LEN + 1];
7987 	RPC_ENUM_IP_TABLE t;
7988 	PACK *ret;
7989 	// Validate arguments
7990 	if (s == NULL || p == NULL)
7991 	{
7992 		return NewPack();
7993 	}
7994 	if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)
7995 	{
7996 		return NewPack();
7997 	}
7998 	Zero(&t, sizeof(t));
7999 
8000 	SiEnumIpTable(s, hubname, &t);
8001 
8002 	ret = NewPack();
8003 	OutRpcEnumIpTable(ret, &t);
8004 	FreeRpcEnumIpTable(&t);
8005 
8006 	return ret;
8007 }
8008 
8009 // MAC table enumeration directive
SiCalledEnumMacTable(SERVER * s,PACK * p)8010 PACK *SiCalledEnumMacTable(SERVER *s, PACK *p)
8011 {
8012 	char hubname[MAX_HUBNAME_LEN + 1];
8013 	RPC_ENUM_MAC_TABLE t;
8014 	PACK *ret;
8015 	// Validate arguments
8016 	if (s == NULL || p == NULL)
8017 	{
8018 		return NewPack();
8019 	}
8020 	if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)
8021 	{
8022 		return NewPack();
8023 	}
8024 	Zero(&t, sizeof(t));
8025 
8026 	SiEnumMacTable(s, hubname, &t);
8027 
8028 	ret = NewPack();
8029 	OutRpcEnumMacTable(ret, &t);
8030 	FreeRpcEnumMacTable(&t);
8031 
8032 	return ret;
8033 }
8034 
8035 // NAT status acquisition directive
SiCalledGetNatStatus(SERVER * s,PACK * p)8036 PACK *SiCalledGetNatStatus(SERVER *s, PACK *p)
8037 {
8038 	char hubname[MAX_HUBNAME_LEN + 1];
8039 	RPC_NAT_STATUS t;
8040 	PACK *ret;
8041 	HUB *h;
8042 	// Validate arguments
8043 	if (s == NULL || p == NULL)
8044 	{
8045 		return NewPack();
8046 	}
8047 	if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)
8048 	{
8049 		return NewPack();
8050 	}
8051 	Zero(&t, sizeof(t));
8052 
8053 	LockHubList(s->Cedar);
8054 	{
8055 		h = GetHub(s->Cedar, hubname);
8056 	}
8057 	UnlockHubList(s->Cedar);
8058 
8059 	if (h != NULL)
8060 	{
8061 		Lock(h->lock_online);
8062 		{
8063 			if (h->SecureNAT != NULL)
8064 			{
8065 				NtGetStatus(h->SecureNAT->Nat, &t);
8066 			}
8067 		}
8068 		Unlock(h->lock_online);
8069 	}
8070 
8071 	ReleaseHub(h);
8072 
8073 	ret = NewPack();
8074 	OutRpcNatStatus(ret, &t);
8075 	FreeRpcNatStatus(&t);
8076 
8077 	return ret;
8078 }
8079 
8080 // DHCP table enumeration directive
SiCalledEnumDhcp(SERVER * s,PACK * p)8081 PACK *SiCalledEnumDhcp(SERVER *s, PACK *p)
8082 {
8083 	char hubname[MAX_HUBNAME_LEN + 1];
8084 	RPC_ENUM_DHCP t;
8085 	PACK *ret;
8086 	HUB *h;
8087 	// Validate arguments
8088 	if (s == NULL || p == NULL)
8089 	{
8090 		return NewPack();
8091 	}
8092 	if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)
8093 	{
8094 		return NewPack();
8095 	}
8096 	Zero(&t, sizeof(t));
8097 
8098 	LockHubList(s->Cedar);
8099 	{
8100 		h = GetHub(s->Cedar, hubname);
8101 	}
8102 	UnlockHubList(s->Cedar);
8103 
8104 	if (h != NULL)
8105 	{
8106 		Lock(h->lock_online);
8107 		{
8108 			if (h->SecureNAT != NULL)
8109 			{
8110 				NtEnumDhcpList(h->SecureNAT->Nat, &t);
8111 			}
8112 		}
8113 		Unlock(h->lock_online);
8114 	}
8115 
8116 	ReleaseHub(h);
8117 
8118 	ret = NewPack();
8119 	OutRpcEnumDhcp(ret, &t);
8120 	FreeRpcEnumDhcp(&t);
8121 
8122 	return ret;
8123 }
8124 
8125 // NAT table enumeration directive
SiCalledEnumNat(SERVER * s,PACK * p)8126 PACK *SiCalledEnumNat(SERVER *s, PACK *p)
8127 {
8128 	char hubname[MAX_HUBNAME_LEN + 1];
8129 	RPC_ENUM_NAT t;
8130 	PACK *ret;
8131 	HUB *h;
8132 	// Validate arguments
8133 	if (s == NULL || p == NULL)
8134 	{
8135 		return NewPack();
8136 	}
8137 	if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)
8138 	{
8139 		return NewPack();
8140 	}
8141 	Zero(&t, sizeof(t));
8142 
8143 	LockHubList(s->Cedar);
8144 	{
8145 		h = GetHub(s->Cedar, hubname);
8146 	}
8147 	UnlockHubList(s->Cedar);
8148 
8149 	if (h != NULL)
8150 	{
8151 		Lock(h->lock_online);
8152 		{
8153 			if (h->SecureNAT != NULL)
8154 			{
8155 				NtEnumNatList(h->SecureNAT->Nat, &t);
8156 			}
8157 		}
8158 		Unlock(h->lock_online);
8159 	}
8160 
8161 	ReleaseHub(h);
8162 
8163 	ret = NewPack();
8164 	OutRpcEnumNat(ret, &t);
8165 	FreeRpcEnumNat(&t);
8166 
8167 	return ret;
8168 }
8169 
8170 // Receive a session enumeration directive
SiCalledEnumSession(SERVER * s,PACK * p)8171 PACK *SiCalledEnumSession(SERVER *s, PACK *p)
8172 {
8173 	char hubname[MAX_HUBNAME_LEN + 1];
8174 	RPC_ENUM_SESSION t;
8175 	PACK *ret;
8176 	// Validate arguments
8177 	if (s == NULL || p == NULL)
8178 	{
8179 		return NewPack();
8180 	}
8181 	if (PackGetStr(p, "HubName", hubname, sizeof(hubname)) == false)
8182 	{
8183 		return NewPack();
8184 	}
8185 	Zero(&t, sizeof(t));
8186 
8187 	SiEnumLocalSession(s, hubname, &t);
8188 
8189 	ret = NewPack();
8190 	OutRpcEnumSession(ret, &t);
8191 	FreeRpcEnumSession(&t);
8192 
8193 	return ret;
8194 }
8195 
8196 // Receive a ticket creation directive
SiCalledCreateTicket(SERVER * s,PACK * p)8197 PACK *SiCalledCreateTicket(SERVER *s, PACK *p)
8198 {
8199 	char username[MAX_SIZE];
8200 	char hubname[MAX_SIZE];
8201 	char groupname[MAX_SIZE];
8202 	char realusername[MAX_SIZE];
8203 	char sessionname[MAX_SESSION_NAME_LEN + 1];
8204 	POLICY policy;
8205 	UCHAR ticket[SHA1_SIZE];
8206 	char ticket_str[MAX_SIZE];
8207 	HUB *h;
8208 	UINT i;
8209 	PACK *ret;
8210 	TICKET *t;
8211 	// Validate arguments
8212 	if (s == NULL || p == NULL)
8213 	{
8214 		return NewPack();
8215 	}
8216 
8217 	PackGetStr(p, "UserName", username, sizeof(username));
8218 	PackGetStr(p, "GroupName", groupname, sizeof(groupname));
8219 	PackGetStr(p, "HubName", hubname, sizeof(hubname));
8220 	PackGetStr(p, "RealUserName", realusername, sizeof(realusername));
8221 	PackGetStr(p, "SessionName", sessionname, sizeof(sessionname));
8222 
8223 	InRpcPolicy(&policy, p);
8224 	if (PackGetDataSize(p, "Ticket") == SHA1_SIZE)
8225 	{
8226 		PackGetData(p, "Ticket", ticket);
8227 	}
8228 
8229 	BinToStr(ticket_str, sizeof(ticket_str), ticket, SHA1_SIZE);
8230 
8231 	SLog(s->Cedar, "LS_TICKET_2", hubname, username, realusername, sessionname,
8232 		ticket_str, TICKET_EXPIRES / 1000);
8233 
8234 	// Get the HUB
8235 	h = GetHub(s->Cedar, hubname);
8236 	if (h == NULL)
8237 	{
8238 		return NewPack();
8239 	}
8240 
8241 	LockList(h->TicketList);
8242 	{
8243 		LIST *o = NewListFast(NULL);
8244 		// Discard old tickets
8245 		for (i = 0;i < LIST_NUM(h->TicketList);i++)
8246 		{
8247 			TICKET *t = LIST_DATA(h->TicketList, i);
8248 			if ((t->CreatedTick + TICKET_EXPIRES) < Tick64())
8249 			{
8250 				Add(o, t);
8251 			}
8252 		}
8253 		for (i = 0;i < LIST_NUM(o);i++)
8254 		{
8255 			TICKET *t = LIST_DATA(o, i);
8256 			Delete(h->TicketList, t);
8257 			Free(t);
8258 		}
8259 		ReleaseList(o);
8260 
8261 		// Create a ticket
8262 		t = ZeroMalloc(sizeof(TICKET));
8263 		t->CreatedTick = Tick64();
8264 		Copy(&t->Policy, &policy, sizeof(POLICY));
8265 		Copy(t->Ticket, ticket, SHA1_SIZE);
8266 		StrCpy(t->Username, sizeof(t->Username), username);
8267 		StrCpy(t->UsernameReal, sizeof(t->UsernameReal), realusername);
8268 		StrCpy(t->GroupName, sizeof(t->GroupName), groupname);
8269 		StrCpy(t->SessionName, sizeof(t->SessionName), sessionname);
8270 
8271 		Add(h->TicketList, t);
8272 	}
8273 	UnlockList(h->TicketList);
8274 
8275 	ReleaseHub(h);
8276 
8277 	ret = NewPack();
8278 
8279 	PackAddInt(ret, "Point", SiGetPoint(s));
8280 
8281 	return ret;
8282 }
8283 
8284 // Receive a HUB creation directive
SiCalledCreateHub(SERVER * s,PACK * p)8285 void SiCalledCreateHub(SERVER *s, PACK *p)
8286 {
8287 	char name[MAX_SIZE];
8288 	UINT type;
8289 	HUB_OPTION o;
8290 	HUB_LOG log;
8291 	bool save_packet_log;
8292 	UINT packet_log_switch_type;
8293 	UINT packet_log_config[NUM_PACKET_LOG];
8294 	bool save_security_log;
8295 	UINT security_log_switch_type;
8296 	UINT i;
8297 	HUB *h;
8298 	// Validate arguments
8299 	if (s == NULL || p == NULL)
8300 	{
8301 		return;
8302 	}
8303 
8304 	PackGetStr(p, "HubName", name, sizeof(name));
8305 	type = PackGetInt(p, "HubType");
8306 	Zero(&o, sizeof(o));
8307 	o.MaxSession = PackGetInt(p, "MaxSession");
8308 	save_packet_log = PackGetInt(p, "SavePacketLog");
8309 	packet_log_switch_type = PackGetInt(p, "PacketLogSwitchType");
8310 	for (i = 0;i < NUM_PACKET_LOG;i++)
8311 	{
8312 		packet_log_config[i] = PackGetIntEx(p, "PacketLogConfig", i);
8313 	}
8314 	save_security_log = PackGetInt(p, "SaveSecurityLog");
8315 	security_log_switch_type = PackGetInt(p, "SecurityLogSwitchType");
8316 
8317 	Zero(&log, sizeof(log));
8318 	log.SavePacketLog = save_packet_log;
8319 	log.PacketLogSwitchType = packet_log_switch_type;
8320 	Copy(log.PacketLogConfig, packet_log_config, sizeof(log.PacketLogConfig));
8321 	log.SaveSecurityLog = save_security_log;
8322 	log.SecurityLogSwitchType = security_log_switch_type;
8323 
8324 	h = NewHub(s->Cedar, name, &o);
8325 	h->LastCommTime = h->LastLoginTime = h->CreatedTime = 0;
8326 	SetHubLogSetting(h, &log);
8327 	h->Type = type;
8328 	h->FarmMember_MaxSessionClient = PackGetInt(p, "MaxSessionClient");
8329 	h->FarmMember_MaxSessionBridge = PackGetInt(p, "MaxSessionBridge");
8330 	h->FarmMember_MaxSessionClientBridgeApply = PackGetBool(p, "MaxSessionClientBridgeApply");
8331 
8332 	if (h->FarmMember_MaxSessionClientBridgeApply == false)
8333 	{
8334 		h->FarmMember_MaxSessionClient = INFINITE;
8335 		h->FarmMember_MaxSessionBridge = INFINITE;
8336 	}
8337 
8338 	PackGetData2(p, "SecurePassword", h->SecurePassword, SHA1_SIZE);
8339 	PackGetData2(p, "HashedPassword", h->HashedPassword, SHA1_SIZE);
8340 
8341 	for (i = 0;i < SiNumAccessFromPack(p);i++)
8342 	{
8343 		ACCESS *a = SiPackToAccess(p, i);
8344 		AddAccessList(h, a);
8345 		Free(a);
8346 	}
8347 
8348 	if (PackGetBool(p, "EnableSecureNAT"))
8349 	{
8350 		VH_OPTION t;
8351 
8352 		InVhOption(&t, p);
8353 
8354 		Copy(h->SecureNATOption, &t, sizeof(VH_OPTION));
8355 		EnableSecureNAT(h, true);
8356 
8357 		Debug("SiCalledCreateHub: SecureNAT Created.\n");
8358 	}
8359 
8360 	AddHub(s->Cedar, h);
8361 	h->Offline = true;
8362 	SetHubOnline(h);
8363 
8364 	ReleaseHub(h);
8365 }
8366 
8367 // Farm control thread
SiFarmControlThread(THREAD * thread,void * param)8368 void SiFarmControlThread(THREAD *thread, void *param)
8369 {
8370 	SERVER *s;
8371 	CEDAR *c;
8372 	EVENT *e;
8373 	LIST *o;
8374 	UINT i;
8375 	char tmp[MAX_PATH];
8376 	// Validate arguments
8377 	if (thread == NULL || param == NULL)
8378 	{
8379 		return;
8380 	}
8381 
8382 	s = (SERVER *)param;
8383 	c = s->Cedar;
8384 	e = s->FarmControlThreadHaltEvent;
8385 
8386 	while (true)
8387 	{
8388 		Lock(c->CedarSuperLock);
8389 
8390 		// Enumerate HUB list which is hosted by each farm member
8391 		Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);
8392 		SiDebugLog(s, tmp);
8393 
8394 		LockList(s->FarmMemberList);
8395 		{
8396 			UINT i;
8397 			UINT num;
8398 			UINT assigned_client_license = 0;
8399 			UINT assigned_bridge_license = 0;
8400 			LIST *fm_list = NewListFast(NULL);
8401 
8402 			Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);
8403 			SiDebugLog(s, tmp);
8404 
8405 			num = 0;
8406 
8407 			while (true)
8408 			{
8409 				bool escape = true;
8410 				for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
8411 				{
8412 					FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
8413 
8414 					if (IsInList(fm_list, f) == false)
8415 					{
8416 						SiCallEnumHub(s, f);
8417 						// Get the total number of sessions across the server farm
8418 						num += f->NumSessions;
8419 
8420 						assigned_client_license += f->AssignedClientLicense;
8421 						assigned_bridge_license += f->AssignedBridgeLicense;
8422 
8423 						escape = false;
8424 
8425 						Add(fm_list, f);
8426 						break;
8427 					}
8428 				}
8429 
8430 				if (escape)
8431 				{
8432 					break;
8433 				}
8434 
8435 				UnlockList(s->FarmMemberList);
8436 				LockList(s->FarmMemberList);
8437 			}
8438 
8439 			ReleaseList(fm_list);
8440 
8441 			s->CurrentTotalNumSessionsOnFarm = num;
8442 
8443 			// Update the number of assigned licenses
8444 			s->CurrentAssignedBridgeLicense = assigned_bridge_license;
8445 			s->CurrentAssignedClientLicense = assigned_client_license;
8446 
8447 			Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);
8448 			SiDebugLog(s, tmp);
8449 		}
8450 		UnlockList(s->FarmMemberList);
8451 
8452 		Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);
8453 		SiDebugLog(s, tmp);
8454 
8455 		o = NewListFast(NULL);
8456 
8457 		Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);
8458 		SiDebugLog(s, tmp);
8459 
8460 		// Emit an update notification for each HUB
8461 		LockList(c->HubList);
8462 		{
8463 			UINT i;
8464 			for (i = 0;i < LIST_NUM(c->HubList);i++)
8465 			{
8466 				HUB *h = LIST_DATA(c->HubList, i);
8467 				AddRef(h->ref);
8468 				Add(o, h);
8469 			}
8470 		}
8471 		UnlockList(c->HubList);
8472 
8473 		Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);
8474 		SiDebugLog(s, tmp);
8475 
8476 		for (i = 0;i < LIST_NUM(o);i++)
8477 		{
8478 			HUB *h = LIST_DATA(o, i);
8479 			SiHubUpdateProc(h);
8480 			ReleaseHub(h);
8481 		}
8482 
8483 		Format(tmp, sizeof(tmp), "CONTROLLER: %s %u", __FILE__, __LINE__);
8484 		SiDebugLog(s, tmp);
8485 
8486 		ReleaseList(o);
8487 
8488 		Unlock(c->CedarSuperLock);
8489 
8490 		Wait(e, SERVER_FARM_CONTROL_INTERVAL);
8491 		if (s->Halt)
8492 		{
8493 			break;
8494 		}
8495 	}
8496 }
8497 
8498 // Start the farm controling
SiStartFarmControl(SERVER * s)8499 void SiStartFarmControl(SERVER *s)
8500 {
8501 	// Validate arguments
8502 	if (s == NULL || s->ServerType != SERVER_TYPE_FARM_CONTROLLER)
8503 	{
8504 		return;
8505 	}
8506 
8507 	s->FarmControlThreadHaltEvent = NewEvent();
8508 	s->FarmControlThread = NewThread(SiFarmControlThread, s);
8509 }
8510 
8511 // Stop the farm controling
SiStopFarmControl(SERVER * s)8512 void SiStopFarmControl(SERVER *s)
8513 {
8514 	// Validate arguments
8515 	if (s == NULL || s->ServerType != SERVER_TYPE_FARM_CONTROLLER)
8516 	{
8517 		return;
8518 	}
8519 
8520 	Set(s->FarmControlThreadHaltEvent);
8521 	WaitThread(s->FarmControlThread, INFINITE);
8522 	ReleaseEvent(s->FarmControlThreadHaltEvent);
8523 	ReleaseThread(s->FarmControlThread);
8524 }
8525 
8526 // HUB enumeration directive (asynchronous start)
SiCallEnumHubBegin(SERVER * s,FARM_MEMBER * f)8527 void SiCallEnumHubBegin(SERVER *s, FARM_MEMBER *f)
8528 {
8529 	// Validate arguments
8530 	if (s == NULL || f == NULL)
8531 	{
8532 		return;
8533 	}
8534 }
8535 
8536 // HUB enumeration directive (asynchronous end)
SiCallEnumHubEnd(SERVER * s,FARM_MEMBER * f)8537 void SiCallEnumHubEnd(SERVER *s, FARM_MEMBER *f)
8538 {
8539 	// Validate arguments
8540 	if (s == NULL || f == NULL)
8541 	{
8542 		return;
8543 	}
8544 }
8545 
8546 
8547 // HUB enumeration directive
SiCallEnumHub(SERVER * s,FARM_MEMBER * f)8548 void SiCallEnumHub(SERVER *s, FARM_MEMBER *f)
8549 {
8550 	CEDAR *c;
8551 	// Validate arguments
8552 	if (s == NULL || f == NULL)
8553 	{
8554 		return;
8555 	}
8556 
8557 	c = s->Cedar;
8558 
8559 	if (f->Me)
8560 	{
8561 
8562 		// Enumerate local HUBs
8563 		LockList(f->HubList);
8564 		{
8565 			// For a local HUB, re-enumerate by erasing all STATIC HUB list once first
8566 			UINT i;
8567 			LIST *o = NewListFast(NULL);
8568 			for (i = 0;i < LIST_NUM(f->HubList);i++)
8569 			{
8570 				HUB_LIST *h = LIST_DATA(f->HubList, i);
8571 				if (h->DynamicHub == false)
8572 				{
8573 					Add(o, h);
8574 				}
8575 			}
8576 
8577 			// Clear all the STATIC HUB
8578 			for (i = 0;i < LIST_NUM(o);i++)
8579 			{
8580 				HUB_LIST *h = LIST_DATA(o, i);
8581 				Free(h);
8582 				Delete(f->HubList, h);
8583 			}
8584 			ReleaseList(o);
8585 
8586 			// Second, stop DYNAMIC HUBs without user
8587 			o = NewListFast(NULL);
8588 			for (i = 0;i < LIST_NUM(f->HubList);i++)
8589 			{
8590 				HUB_LIST *h = LIST_DATA(f->HubList, i);
8591 				if (h->DynamicHub == true)
8592 				{
8593 					LockList(c->HubList);
8594 					{
8595 						HUB *hub = GetHub(s->Cedar, h->Name);
8596 						if (hub != NULL)
8597 						{
8598 							if (Count(hub->NumSessions) == 0 || hub->Type != HUB_TYPE_FARM_DYNAMIC)
8599 							{
8600 								Add(o, h);
8601 							}
8602 							ReleaseHub(hub);
8603 						}
8604 					}
8605 					UnlockList(c->HubList);
8606 				}
8607 			}
8608 
8609 			for (i = 0;i < LIST_NUM(o);i++)
8610 			{
8611 				HUB_LIST *h = LIST_DATA(o, i);
8612 				Debug("Delete HUB: %s\n", h->Name);
8613 				Free(h);
8614 				Delete(f->HubList, h);
8615 			}
8616 
8617 			ReleaseList(o);
8618 
8619 			// Set the enumeration results
8620 			LockList(c->HubList);
8621 			{
8622 				for (i = 0;i < LIST_NUM(c->HubList);i++)
8623 				{
8624 					HUB *h = LIST_DATA(c->HubList, i);
8625 					if (h->Offline == false)
8626 					{
8627 						if (h->Type == HUB_TYPE_FARM_STATIC)
8628 						{
8629 							HUB_LIST *hh = ZeroMalloc(sizeof(HUB_LIST));
8630 							hh->FarmMember = f;
8631 							hh->DynamicHub = false;
8632 							StrCpy(hh->Name, sizeof(hh->Name), h->Name);
8633 							Add(f->HubList, hh);
8634 
8635 							LockList(h->SessionList);
8636 							{
8637 								hh->NumSessions = LIST_NUM(h->SessionList);
8638 								hh->NumSessionsBridge = Count(h->NumSessionsBridge);
8639 								hh->NumSessionsClient = Count(h->NumSessionsClient);
8640 							}
8641 							UnlockList(h->SessionList);
8642 
8643 							LockHashList(h->MacHashTable);
8644 							{
8645 								hh->NumMacTables = HASH_LIST_NUM(h->MacHashTable);
8646 							}
8647 							UnlockHashList(h->MacHashTable);
8648 
8649 							LockList(h->IpTable);
8650 							{
8651 								hh->NumIpTables = LIST_NUM(h->IpTable);
8652 							}
8653 							UnlockList(h->IpTable);
8654 						}
8655 					}
8656 				}
8657 			}
8658 			UnlockList(c->HubList);
8659 		}
8660 		UnlockList(f->HubList);
8661 
8662 		// Point
8663 		f->Point = SiGetPoint(s);
8664 		f->NumSessions = Count(s->Cedar->CurrentSessions);
8665 		f->MaxSessions = GetServerCapsInt(s, "i_max_sessions");
8666 		f->NumTcpConnections = Count(s->Cedar->CurrentTcpConnections);
8667 
8668 		Lock(s->Cedar->TrafficLock);
8669 		{
8670 			Copy(&f->Traffic, s->Cedar->Traffic, sizeof(TRAFFIC));
8671 		}
8672 		Unlock(s->Cedar->TrafficLock);
8673 
8674 		f->AssignedBridgeLicense = Count(s->Cedar->AssignedBridgeLicense);
8675 		f->AssignedClientLicense = Count(s->Cedar->AssignedClientLicense);
8676 
8677 		Copy(f->RandomKey, s->MyRandomKey, SHA1_SIZE);
8678 
8679 
8680 		Debug("Server %s: Point %u\n", f->hostname, f->Point);
8681 	}
8682 	else
8683 	{
8684 		// Enumerate HUBs which are remote member
8685 		PACK *p = NewPack();
8686 		UINT i, num, j;
8687 		LIST *o = NewListFast(NULL);
8688 
8689 		num = 0;
8690 
8691 		for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
8692 		{
8693 			FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
8694 
8695 			if (IsZero(f->RandomKey, SHA1_SIZE) == false && f->SystemId != 0)
8696 			{
8697 				num++;
8698 			}
8699 		}
8700 
8701 		j = 0;
8702 
8703 		for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
8704 		{
8705 			FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
8706 
8707 			if (IsZero(f->RandomKey, SHA1_SIZE) == false && f->SystemId != 0)
8708 			{
8709 				PackAddDataEx(p, "MemberRandomKey", f->RandomKey, SHA1_SIZE, j, num);
8710 				PackAddInt64Ex(p, "MemberSystemId", f->SystemId, j, num);
8711 				j++;
8712 			}
8713 		}
8714 		PackAddInt(p, "MemberSystemIdNum", num);
8715 
8716 		p = SiCallTask(f, p, "enumhub");
8717 		if (p != NULL)
8718 		{
8719 			LockList(f->HubList);
8720 			{
8721 				UINT i;
8722 				// Erase the list
8723 				for (i = 0;i < LIST_NUM(f->HubList);i++)
8724 				{
8725 					HUB_LIST *hh = LIST_DATA(f->HubList, i);
8726 					Free(hh);
8727 				}
8728 				DeleteAll(f->HubList);
8729 
8730 				for (i = 0;i < PackGetIndexCount(p, "HubName");i++)
8731 				{
8732 					HUB_LIST *hh = ZeroMalloc(sizeof(HUB_LIST));
8733 					UINT num;
8734 					UINT64 LastCommTime;
8735 
8736 					PackGetStrEx(p, "HubName", hh->Name, sizeof(hh->Name), i);
8737 					num = PackGetIntEx(p, "NumSession", i);
8738 					hh->DynamicHub = ((PackGetIntEx(p, "HubType", i) == HUB_TYPE_FARM_DYNAMIC) ? true : false);
8739 					hh->FarmMember = f;
8740 					hh->NumSessions = PackGetIntEx(p, "NumSessions", i);
8741 					hh->NumSessionsClient = PackGetIntEx(p, "NumSessionsClient", i);
8742 					hh->NumSessionsBridge = PackGetIntEx(p, "NumSessionsBridge", i);
8743 					hh->NumIpTables = PackGetIntEx(p, "NumIpTables", i);
8744 					hh->NumMacTables = PackGetIntEx(p, "NumMacTables", i);
8745 					LastCommTime = PackGetInt64Ex(p, "LastCommTime", i);
8746 					Add(f->HubList, hh);
8747 					//Debug("%s\n", hh->Name);
8748 
8749 					LockList(c->HubList);
8750 					{
8751 						HUB *h = GetHub(c, hh->Name);
8752 
8753 						if (h != NULL)
8754 						{
8755 							// Update the LastCommTime of the Virtual HUB
8756 							Lock(h->lock);
8757 							{
8758 								if (h->LastCommTime < LastCommTime)
8759 								{
8760 									h->LastCommTime = LastCommTime;
8761 								}
8762 							}
8763 							Unlock(h->lock);
8764 
8765 							ReleaseHub(h);
8766 						}
8767 					}
8768 					UnlockList(c->HubList);
8769 
8770 					if (hh->DynamicHub && num >= 1)
8771 					{
8772 						// It is not necessary to be registered in the virtual HUB creation
8773 						// history list because user session is already connected.
8774 						// Remove from the Virtual HUB creation history list
8775 						SiDelHubCreateHistory(s, hh->Name);
8776 					}
8777 
8778 					if (hh->DynamicHub && num == 0)
8779 					{
8780 						// Check the Virtual HUB creation history list.
8781 						// If it is created within 60 seconds of the most recent
8782 						// in the case of Virtual HUB which the first user is not
8783 						// connected yet, not to remove because there is no user
8784 						if (SiIsHubRegistedOnCreateHistory(s, hh->Name) == false)
8785 						{
8786 							// Stop because all uses have gone in the dynamic HUB
8787 							HUB *h;
8788 							LockList(c->HubList);
8789 							{
8790 								h = GetHub(c, hh->Name);
8791 							}
8792 							UnlockList(c->HubList);
8793 
8794 							if (h != NULL)
8795 							{
8796 								Add(o, h);
8797 							}
8798 						}
8799 					}
8800 				}
8801 			}
8802 			UnlockList(f->HubList);
8803 			f->Point = PackGetInt(p, "Point");
8804 			Debug("Server %s: Point %u\n", f->hostname, f->Point);
8805 			f->NumSessions = PackGetInt(p, "NumTotalSessions");
8806 			if (f->NumSessions == 0)
8807 			{
8808 				f->NumSessions = PackGetInt(p, "NumSessions");
8809 			}
8810 			f->MaxSessions = PackGetInt(p, "MaxSessions");
8811 			f->NumTcpConnections = PackGetInt(p, "NumTcpConnections");
8812 			InRpcTraffic(&f->Traffic, p);
8813 
8814 			f->AssignedBridgeLicense = PackGetInt(p, "AssignedBridgeLicense");
8815 			f->AssignedClientLicense = PackGetInt(p, "AssignedClientLicense");
8816 
8817 			if (PackGetDataSize(p, "RandomKey") == SHA1_SIZE)
8818 			{
8819 				PackGetData(p, "RandomKey", f->RandomKey);
8820 			}
8821 
8822 			f->SystemId = PackGetInt64(p, "SystemId");
8823 
8824 			// Apply the traffic difference information
8825 			num = PackGetIndexCount(p, "TdType");
8826 			for (i = 0;i < num;i++)
8827 			{
8828 				TRAFFIC traffic;
8829 				UINT type;
8830 				HUB *h;
8831 				char name[MAX_SIZE];
8832 				char hubname[MAX_SIZE];
8833 
8834 				type = PackGetIntEx(p, "TdType", i);
8835 				PackGetStrEx(p, "TdName", name, sizeof(name), i);
8836 				PackGetStrEx(p, "TdHubName", hubname, sizeof(hubname), i);
8837 				InRpcTrafficEx(&traffic, p, i);
8838 
8839 				LockList(c->HubList);
8840 				{
8841 					h = GetHub(c, hubname);
8842 					if (h != NULL)
8843 					{
8844 						if (type == TRAFFIC_DIFF_HUB)
8845 						{
8846 							Lock(h->TrafficLock);
8847 							{
8848 								AddTraffic(h->Traffic, &traffic);
8849 							}
8850 							Unlock(h->TrafficLock);
8851 						}
8852 						else
8853 						{
8854 							AcLock(h);
8855 							{
8856 								USER *u = AcGetUser(h, name);
8857 								if (u != NULL)
8858 								{
8859 									Lock(u->lock);
8860 									{
8861 										AddTraffic(u->Traffic, &traffic);
8862 									}
8863 									Unlock(u->lock);
8864 									if (u->Group != NULL)
8865 									{
8866 										Lock(u->Group->lock);
8867 										{
8868 											AddTraffic(u->Group->Traffic, &traffic);
8869 										}
8870 										Unlock(u->Group->lock);
8871 									}
8872 									ReleaseUser(u);
8873 								}
8874 							}
8875 							AcUnlock(h);
8876 						}
8877 						ReleaseHub(h);
8878 					}
8879 					UnlockList(c->HubList);
8880 				}
8881 			}
8882 
8883 			FreePack(p);
8884 		}
8885 
8886 		for (i = 0;i < LIST_NUM(o);i++)
8887 		{
8888 			HUB *h = LIST_DATA(o, i);
8889 			SiCallDeleteHub(s, f, h);
8890 			Debug("Delete HUB: %s\n", h->Name);
8891 			ReleaseHub(h);
8892 		}
8893 
8894 		ReleaseList(o);
8895 	}
8896 }
8897 
8898 // Send a session information directive
SiCallGetSessionStatus(SERVER * s,FARM_MEMBER * f,RPC_SESSION_STATUS * t)8899 bool SiCallGetSessionStatus(SERVER *s, FARM_MEMBER *f, RPC_SESSION_STATUS *t)
8900 {
8901 	PACK *p;
8902 	// Validate arguments
8903 	if (s == NULL || f == NULL)
8904 	{
8905 		return false;
8906 	}
8907 
8908 	p = NewPack();
8909 	OutRpcSessionStatus(p, t);
8910 	FreeRpcSessionStatus(t);
8911 	Zero(t, sizeof(RPC_SESSION_STATUS));
8912 
8913 	p = SiCallTask(f, p, "getsessionstatus");
8914 
8915 	if (p == NULL)
8916 	{
8917 		return false;
8918 	}
8919 
8920 	InRpcSessionStatus(t, p);
8921 	FreePack(p);
8922 
8923 	return true;
8924 }
8925 
8926 // Log file reading directive
SiCallReadLogFile(SERVER * s,FARM_MEMBER * f,RPC_READ_LOG_FILE * t)8927 bool SiCallReadLogFile(SERVER *s, FARM_MEMBER *f, RPC_READ_LOG_FILE *t)
8928 {
8929 	PACK *p;
8930 	// Validate arguments
8931 	if (s == NULL || f == NULL)
8932 	{
8933 		return false;
8934 	}
8935 
8936 	p = NewPack();
8937 	OutRpcReadLogFile(p, t);
8938 	FreeRpcReadLogFile(t);
8939 	Zero(t, sizeof(RPC_READ_LOG_FILE));
8940 
8941 	p = SiCallTask(f, p, "readlogfile");
8942 
8943 	if (p == NULL)
8944 	{
8945 		return false;
8946 	}
8947 
8948 	InRpcReadLogFile(t, p);
8949 	FreePack(p);
8950 
8951 	return true;
8952 }
8953 
8954 // Log file enumeration directive
SiCallEnumLogFileList(SERVER * s,FARM_MEMBER * f,RPC_ENUM_LOG_FILE * t,char * hubname)8955 bool SiCallEnumLogFileList(SERVER *s, FARM_MEMBER *f, RPC_ENUM_LOG_FILE *t, char *hubname)
8956 {
8957 	PACK *p;
8958 	// Validate arguments
8959 	if (s == NULL || f == NULL)
8960 	{
8961 		return false;
8962 	}
8963 
8964 	p = NewPack();
8965 	OutRpcEnumLogFile(p, t);
8966 	FreeRpcEnumLogFile(t);
8967 	Zero(t, sizeof(RPC_ENUM_LOG_FILE));
8968 
8969 	PackAddStr(p, "HubName", hubname);
8970 
8971 	p = SiCallTask(f, p, "enumlogfilelist");
8972 
8973 	if (p == NULL)
8974 	{
8975 		return false;
8976 	}
8977 
8978 	InRpcEnumLogFile(t, p);
8979 	FreePack(p);
8980 
8981 	return true;
8982 }
8983 
8984 // HUB delete directive
SiCallDeleteHub(SERVER * s,FARM_MEMBER * f,HUB * h)8985 void SiCallDeleteHub(SERVER *s, FARM_MEMBER *f, HUB *h)
8986 {
8987 	PACK *p;
8988 	UINT i;
8989 	// Validate arguments
8990 	if (s == NULL || f == NULL)
8991 	{
8992 		return;
8993 	}
8994 
8995 	if (f->Me == false)
8996 	{
8997 		p = NewPack();
8998 
8999 		PackAddStr(p, "HubName", h->Name);
9000 
9001 		p = SiCallTask(f, p, "deletehub");
9002 		FreePack(p);
9003 	}
9004 
9005 	LockList(f->HubList);
9006 	{
9007 		for (i = 0;i < LIST_NUM(f->HubList);i++)
9008 		{
9009 			HUB_LIST *hh = LIST_DATA(f->HubList, i);
9010 			if (StrCmpi(hh->Name, h->Name) == 0)
9011 			{
9012 				Free(hh);
9013 				Delete(f->HubList, hh);
9014 			}
9015 		}
9016 	}
9017 	UnlockList(f->HubList);
9018 }
9019 
9020 // Submit a HUB update directive
SiCallUpdateHub(SERVER * s,FARM_MEMBER * f,HUB * h)9021 void SiCallUpdateHub(SERVER *s, FARM_MEMBER *f, HUB *h)
9022 {
9023 	PACK *p;
9024 	// Validate arguments
9025 	if (s == NULL || f == NULL)
9026 	{
9027 		return;
9028 	}
9029 
9030 	if (f->Me == false)
9031 	{
9032 		p = NewPack();
9033 
9034 		SiPackAddCreateHub(p, h);
9035 
9036 		p = SiCallTask(f, p, "updatehub");
9037 		FreePack(p);
9038 	}
9039 }
9040 
9041 // Send a ticket creation directive
SiCallCreateTicket(SERVER * s,FARM_MEMBER * f,char * hubname,char * username,char * realusername,POLICY * policy,UCHAR * ticket,UINT counter,char * groupname)9042 void SiCallCreateTicket(SERVER *s, FARM_MEMBER *f, char *hubname, char *username, char *realusername, POLICY *policy, UCHAR *ticket, UINT counter, char *groupname)
9043 {
9044 	PACK *p;
9045 	char name[MAX_SESSION_NAME_LEN + 1];
9046 	char hub_name_upper[MAX_SIZE];
9047 	char user_name_upper[MAX_USERNAME_LEN + 1];
9048 	char ticket_str[MAX_SIZE];
9049 	UINT point;
9050 	// Validate arguments
9051 	if (s == NULL || f == NULL || realusername == NULL || hubname == NULL || username == NULL || policy == NULL || ticket == NULL)
9052 	{
9053 		return;
9054 	}
9055 	if (groupname == NULL)
9056 	{
9057 		groupname = "";
9058 	}
9059 
9060 	p = NewPack();
9061 	PackAddStr(p, "HubName", hubname);
9062 	PackAddStr(p, "UserName", username);
9063 	PackAddStr(p, "groupname", groupname);
9064 	PackAddStr(p, "RealUserName", realusername);
9065 	OutRpcPolicy(p, policy);
9066 	PackAddData(p, "Ticket", ticket, SHA1_SIZE);
9067 
9068 	BinToStr(ticket_str, sizeof(ticket_str), ticket, SHA1_SIZE);
9069 
9070 	StrCpy(hub_name_upper, sizeof(hub_name_upper), hubname);
9071 	StrUpper(hub_name_upper);
9072 	StrCpy(user_name_upper, sizeof(user_name_upper), username);
9073 	StrUpper(user_name_upper);
9074 	Format(name, sizeof(name), "SID-%s-%u", user_name_upper,
9075 		counter);
9076 	PackAddStr(p, "SessionName", name);
9077 
9078 	p = SiCallTask(f, p, "createticket");
9079 
9080 	SLog(s->Cedar, "LS_TICKET_1", f->hostname, hubname, username, realusername, name, ticket_str);
9081 
9082 	point = PackGetInt(p, "Point");
9083 	if (point != 0)
9084 	{
9085 		f->Point = point;
9086 		f->NumSessions++;
9087 	}
9088 
9089 	FreePack(p);
9090 }
9091 
9092 // Send a MAC address deletion directive
SiCallDeleteMacTable(SERVER * s,FARM_MEMBER * f,char * hubname,UINT key)9093 void SiCallDeleteMacTable(SERVER *s, FARM_MEMBER *f, char *hubname, UINT key)
9094 {
9095 	PACK *p;
9096 	// Validate arguments
9097 	if (s == NULL || f == NULL || hubname == NULL)
9098 	{
9099 		return;
9100 	}
9101 
9102 	p = NewPack();
9103 	PackAddStr(p, "HubName", hubname);
9104 	PackAddInt(p, "Key", key);
9105 
9106 	p = SiCallTask(f, p, "deletemactable");
9107 
9108 	FreePack(p);
9109 }
9110 
9111 // Send an IP address delete directive
SiCallDeleteIpTable(SERVER * s,FARM_MEMBER * f,char * hubname,UINT key)9112 void SiCallDeleteIpTable(SERVER *s, FARM_MEMBER *f, char *hubname, UINT key)
9113 {
9114 	PACK *p;
9115 	// Validate arguments
9116 	if (s == NULL || f == NULL || hubname == NULL)
9117 	{
9118 		return;
9119 	}
9120 
9121 	p = NewPack();
9122 	PackAddStr(p, "HubName", hubname);
9123 	PackAddInt(p, "Key", key);
9124 
9125 	p = SiCallTask(f, p, "deleteiptable");
9126 
9127 	FreePack(p);
9128 }
9129 
9130 // Send a session deletion directive
SiCallDeleteSession(SERVER * s,FARM_MEMBER * f,char * hubname,char * session_name)9131 void SiCallDeleteSession(SERVER *s, FARM_MEMBER *f, char *hubname, char *session_name)
9132 {
9133 	PACK *p;
9134 	// Validate arguments
9135 	if (s == NULL || f == NULL || hubname == NULL || session_name == NULL)
9136 	{
9137 		return;
9138 	}
9139 
9140 	p = NewPack();
9141 	PackAddStr(p, "HubName", hubname);
9142 	PackAddStr(p, "SessionName", session_name);
9143 
9144 	p = SiCallTask(f, p, "deletesession");
9145 
9146 	FreePack(p);
9147 }
9148 
9149 // Send an IP table enumeration directive
SiCallEnumIpTable(SERVER * s,FARM_MEMBER * f,char * hubname,RPC_ENUM_IP_TABLE * t)9150 void SiCallEnumIpTable(SERVER *s, FARM_MEMBER *f, char *hubname, RPC_ENUM_IP_TABLE *t)
9151 {
9152 	PACK *p;
9153 	UINT i;
9154 	// Validate arguments
9155 	if (s == NULL || f == NULL || hubname == NULL || t == NULL)
9156 	{
9157 		return;
9158 	}
9159 
9160 	p = NewPack();
9161 	PackAddStr(p, "HubName", hubname);
9162 
9163 	p = SiCallTask(f, p, "enumiptable");
9164 
9165 	Zero(t, sizeof(RPC_ENUM_IP_TABLE));
9166 	InRpcEnumIpTable(t, p);
9167 
9168 	for (i = 0;i < t->NumIpTable;i++)
9169 	{
9170 		t->IpTables[i].RemoteItem = true;
9171 		StrCpy(t->IpTables[i].RemoteHostname, sizeof(t->IpTables[i].RemoteHostname),
9172 			f->hostname);
9173 	}
9174 
9175 	FreePack(p);
9176 }
9177 
9178 // Submit a MAC table enumeration directive
SiCallEnumMacTable(SERVER * s,FARM_MEMBER * f,char * hubname,RPC_ENUM_MAC_TABLE * t)9179 void SiCallEnumMacTable(SERVER *s, FARM_MEMBER *f, char *hubname, RPC_ENUM_MAC_TABLE *t)
9180 {
9181 	PACK *p;
9182 	UINT i;
9183 	// Validate arguments
9184 	if (s == NULL || f == NULL || hubname == NULL || t == NULL)
9185 	{
9186 		return;
9187 	}
9188 
9189 	p = NewPack();
9190 	PackAddStr(p, "HubName", hubname);
9191 
9192 	p = SiCallTask(f, p, "enummactable");
9193 
9194 	Zero(t, sizeof(RPC_ENUM_MAC_TABLE));
9195 	InRpcEnumMacTable(t, p);
9196 
9197 	for (i = 0;i < t->NumMacTable;i++)
9198 	{
9199 		t->MacTables[i].RemoteItem = true;
9200 		StrCpy(t->MacTables[i].RemoteHostname, sizeof(t->MacTables[i].RemoteHostname),
9201 			f->hostname);
9202 	}
9203 
9204 	FreePack(p);
9205 }
9206 
9207 // Send a SecureNAT status acquisition directive
SiCallGetNatStatus(SERVER * s,FARM_MEMBER * f,char * hubname,RPC_NAT_STATUS * t)9208 void SiCallGetNatStatus(SERVER *s, FARM_MEMBER *f, char *hubname, RPC_NAT_STATUS *t)
9209 {
9210 	PACK *p;
9211 	// Validate arguments
9212 	if (s == NULL || f == NULL || hubname == NULL || t == NULL)
9213 	{
9214 		return;
9215 	}
9216 
9217 	p = NewPack();
9218 	PackAddStr(p, "HubName", hubname);
9219 
9220 	p = SiCallTask(f, p, "getnatstatus");
9221 
9222 	Zero(t, sizeof(RPC_NAT_STATUS));
9223 	InRpcNatStatus(t, p);
9224 
9225 	FreePack(p);
9226 }
9227 
9228 // Submit a DHCP entry enumeration directive
SiCallEnumDhcp(SERVER * s,FARM_MEMBER * f,char * hubname,RPC_ENUM_DHCP * t)9229 void SiCallEnumDhcp(SERVER *s, FARM_MEMBER *f, char *hubname, RPC_ENUM_DHCP *t)
9230 {
9231 	PACK *p;
9232 	// Validate arguments
9233 	if (s == NULL || f == NULL || hubname == NULL || t == NULL)
9234 	{
9235 		return;
9236 	}
9237 
9238 	p = NewPack();
9239 	PackAddStr(p, "HubName", hubname);
9240 
9241 	p = SiCallTask(f, p, "enumdhcp");
9242 
9243 	Zero(t, sizeof(RPC_ENUM_DHCP));
9244 	InRpcEnumDhcp(t, p);
9245 
9246 	FreePack(p);
9247 }
9248 
9249 // Submit a NAT entry enumeration directive
SiCallEnumNat(SERVER * s,FARM_MEMBER * f,char * hubname,RPC_ENUM_NAT * t)9250 void SiCallEnumNat(SERVER *s, FARM_MEMBER *f, char *hubname, RPC_ENUM_NAT *t)
9251 {
9252 	PACK *p;
9253 	// Validate arguments
9254 	if (s == NULL || f == NULL || hubname == NULL || t == NULL)
9255 	{
9256 		return;
9257 	}
9258 
9259 	p = NewPack();
9260 	PackAddStr(p, "HubName", hubname);
9261 
9262 	p = SiCallTask(f, p, "enumnat");
9263 
9264 	Zero(t, sizeof(RPC_ENUM_NAT));
9265 	InRpcEnumNat(t, p);
9266 
9267 	FreePack(p);
9268 }
9269 
9270 // Send a session enumeration directive
SiCallEnumSession(SERVER * s,FARM_MEMBER * f,char * hubname,RPC_ENUM_SESSION * t)9271 void SiCallEnumSession(SERVER *s, FARM_MEMBER *f, char *hubname, RPC_ENUM_SESSION *t)
9272 {
9273 	PACK *p;
9274 	UINT i;
9275 	// Validate arguments
9276 	if (s == NULL || f == NULL || hubname == NULL || t == NULL)
9277 	{
9278 		return;
9279 	}
9280 
9281 	p = NewPack();
9282 	PackAddStr(p, "HubName", hubname);
9283 
9284 	p = SiCallTask(f, p, "enumsession");
9285 
9286 	Zero(t, sizeof(RPC_ENUM_SESSION));
9287 	InRpcEnumSession(t, p);
9288 
9289 	for (i = 0;i < t->NumSession;i++)
9290 	{
9291 		t->Sessions[i].RemoteSession = true;
9292 		StrCpy(t->Sessions[i].RemoteHostname, sizeof(t->Sessions[i].RemoteHostname),
9293 			f->hostname);
9294 	}
9295 
9296 	FreePack(p);
9297 }
9298 
9299 // Send a HUB creation directive
SiCallCreateHub(SERVER * s,FARM_MEMBER * f,HUB * h)9300 void SiCallCreateHub(SERVER *s, FARM_MEMBER *f, HUB *h)
9301 {
9302 	PACK *p;
9303 	HUB_LIST *hh;
9304 	// Validate arguments
9305 	if (s == NULL || f == NULL)
9306 	{
9307 		return;
9308 	}
9309 
9310 	if (f->Me == false)
9311 	{
9312 		p = NewPack();
9313 
9314 		SiPackAddCreateHub(p, h);
9315 
9316 		p = SiCallTask(f, p, "createhub");
9317 		FreePack(p);
9318 	}
9319 
9320 	hh = ZeroMalloc(sizeof(HUB_LIST));
9321 	hh->DynamicHub = (h->Type == HUB_TYPE_FARM_DYNAMIC ? true : false);
9322 	StrCpy(hh->Name, sizeof(hh->Name), h->Name);
9323 	hh->FarmMember = f;
9324 
9325 	LockList(f->HubList);
9326 	{
9327 		bool exists = false;
9328 		UINT i;
9329 		for (i = 0;i < LIST_NUM(f->HubList);i++)
9330 		{
9331 			HUB_LIST *t = LIST_DATA(f->HubList, i);
9332 			if (StrCmpi(t->Name, hh->Name) == 0)
9333 			{
9334 				exists = true;
9335 			}
9336 		}
9337 		if (exists == false)
9338 		{
9339 			Add(f->HubList, hh);
9340 		}
9341 		else
9342 		{
9343 			Free(hh);
9344 		}
9345 	}
9346 	UnlockList(f->HubList);
9347 }
9348 
9349 // Write the PACK for creating HUB
SiPackAddCreateHub(PACK * p,HUB * h)9350 void SiPackAddCreateHub(PACK *p, HUB *h)
9351 {
9352 	UINT i;
9353 	UINT max_session;
9354 	SERVER *s;
9355 
9356 
9357 	// Validate arguments
9358 	if (p == NULL || h == NULL)
9359 	{
9360 		return;
9361 	}
9362 
9363 
9364 	s = h->Cedar->Server;
9365 	if (s != NULL)
9366 	{
9367 	}
9368 
9369 	PackAddStr(p, "HubName", h->Name);
9370 	PackAddInt(p, "HubType", h->Type);
9371 
9372 	max_session = h->Option->MaxSession;
9373 
9374 	if (GetHubAdminOption(h, "max_sessions") != 0)
9375 	{
9376 		if (max_session == 0)
9377 		{
9378 			max_session = GetHubAdminOption(h, "max_sessions");
9379 		}
9380 		else
9381 		{
9382 			UINT r = GetHubAdminOption(h, "max_sessions");
9383 			max_session = MIN(max_session, r);
9384 		}
9385 	}
9386 
9387 	PackAddInt(p, "MaxSession", max_session);
9388 
9389 	if (GetHubAdminOption(h, "max_sessions_client_bridge_apply") != 0
9390 		)
9391 	{
9392 		PackAddInt(p, "MaxSessionClient", GetHubAdminOption(h, "max_sessions_client"));
9393 		PackAddInt(p, "MaxSessionBridge", GetHubAdminOption(h, "max_sessions_bridge"));
9394 		PackAddBool(p, "MaxSessionClientBridgeApply", true);
9395 	}
9396 	else
9397 	{
9398 		PackAddInt(p, "MaxSessionClient", INFINITE);
9399 		PackAddInt(p, "MaxSessionBridge", INFINITE);
9400 	}
9401 
9402 	PackAddBool(p, "NoArpPolling", h->Option->NoArpPolling);
9403 	PackAddBool(p, "NoIPv6AddrPolling", h->Option->NoIPv6AddrPolling);
9404 	PackAddBool(p, "NoIpTable", h->Option->NoIpTable);
9405 	PackAddBool(p, "NoEnum", h->Option->NoEnum);
9406 	PackAddBool(p, "FilterPPPoE", h->Option->FilterPPPoE);
9407 	PackAddBool(p, "YieldAfterStorePacket", h->Option->YieldAfterStorePacket);
9408 	PackAddBool(p, "NoSpinLockForPacketDelay", h->Option->NoSpinLockForPacketDelay);
9409 	PackAddInt(p, "BroadcastStormDetectionThreshold", h->Option->BroadcastStormDetectionThreshold);
9410 	PackAddInt(p, "MaxLoggedPacketsPerMinute", h->Option->MaxLoggedPacketsPerMinute);
9411 	PackAddInt(p, "FloodingSendQueueBufferQuota", h->Option->FloodingSendQueueBufferQuota);
9412 	PackAddBool(p, "DoNotSaveHeavySecurityLogs", h->Option->DoNotSaveHeavySecurityLogs);
9413 	PackAddBool(p, "DropBroadcastsInPrivacyFilterMode", h->Option->DropBroadcastsInPrivacyFilterMode);
9414 	PackAddBool(p, "DropArpInPrivacyFilterMode", h->Option->DropArpInPrivacyFilterMode);
9415 	PackAddBool(p, "SuppressClientUpdateNotification", h->Option->SuppressClientUpdateNotification);
9416 	PackAddBool(p, "AssignVLanIdByRadiusAttribute", h->Option->AssignVLanIdByRadiusAttribute);
9417 	PackAddBool(p, "DenyAllRadiusLoginWithNoVlanAssign", h->Option->DenyAllRadiusLoginWithNoVlanAssign);
9418 	PackAddInt(p, "ClientMinimumRequiredBuild", h->Option->ClientMinimumRequiredBuild);
9419 	PackAddBool(p, "SecureNAT_RandomizeAssignIp", h->Option->SecureNAT_RandomizeAssignIp);
9420 	PackAddBool(p, "NoPhysicalIPOnPacketLog", h->Option->NoPhysicalIPOnPacketLog);
9421 	PackAddInt(p, "DetectDormantSessionInterval", h->Option->DetectDormantSessionInterval);
9422 	PackAddBool(p, "FixForDLinkBPDU", h->Option->FixForDLinkBPDU);
9423 	PackAddBool(p, "BroadcastLimiterStrictMode", h->Option->BroadcastLimiterStrictMode);
9424 	PackAddBool(p, "NoLookBPDUBridgeId", h->Option->NoLookBPDUBridgeId);
9425 	PackAddBool(p, "NoManageVlanId", h->Option->NoManageVlanId);
9426 	PackAddInt(p, "VlanTypeId", h->Option->VlanTypeId);
9427 	PackAddBool(p, "FilterOSPF", h->Option->FilterOSPF);
9428 	PackAddBool(p, "FilterIPv4", h->Option->FilterIPv4);
9429 	PackAddBool(p, "FilterIPv6", h->Option->FilterIPv6);
9430 	PackAddBool(p, "FilterNonIP", h->Option->FilterNonIP);
9431 	PackAddBool(p, "NoIPv4PacketLog", h->Option->NoIPv4PacketLog);
9432 	PackAddBool(p, "NoIPv6PacketLog", h->Option->NoIPv6PacketLog);
9433 	PackAddBool(p, "FilterBPDU", h->Option->FilterBPDU);
9434 	PackAddBool(p, "NoIPv6DefaultRouterInRAWhenIPv6", h->Option->NoIPv6DefaultRouterInRAWhenIPv6);
9435 	PackAddBool(p, "NoMacAddressLog", h->Option->NoMacAddressLog);
9436 	PackAddBool(p, "ManageOnlyPrivateIP", h->Option->ManageOnlyPrivateIP);
9437 	PackAddBool(p, "ManageOnlyLocalUnicastIPv6", h->Option->ManageOnlyLocalUnicastIPv6);
9438 	PackAddBool(p, "DisableIPParsing", h->Option->DisableIPParsing);
9439 	PackAddInt(p, "AdjustTcpMssValue", h->Option->AdjustTcpMssValue);
9440 	PackAddBool(p, "DisableAdjustTcpMss", h->Option->DisableAdjustTcpMss);
9441 	PackAddBool(p, "NoDhcpPacketLogOutsideHub", h->Option->NoDhcpPacketLogOutsideHub);
9442 	PackAddBool(p, "DisableHttpParsing", h->Option->DisableHttpParsing);
9443 	PackAddBool(p, "DisableUdpAcceleration", h->Option->DisableUdpAcceleration);
9444 	PackAddBool(p, "DisableUdpFilterForLocalBridgeNic", h->Option->DisableUdpFilterForLocalBridgeNic);
9445 	PackAddBool(p, "ApplyIPv4AccessListOnArpPacket", h->Option->ApplyIPv4AccessListOnArpPacket);
9446 	PackAddBool(p, "RemoveDefGwOnDhcpForLocalhost", h->Option->RemoveDefGwOnDhcpForLocalhost);
9447 
9448 	PackAddInt(p, "SecureNAT_MaxTcpSessionsPerIp", h->Option->SecureNAT_MaxTcpSessionsPerIp);
9449 	PackAddInt(p, "SecureNAT_MaxTcpSynSentPerIp", h->Option->SecureNAT_MaxTcpSynSentPerIp);
9450 	PackAddInt(p, "SecureNAT_MaxUdpSessionsPerIp", h->Option->SecureNAT_MaxUdpSessionsPerIp);
9451 	PackAddInt(p, "SecureNAT_MaxDnsSessionsPerIp", h->Option->SecureNAT_MaxDnsSessionsPerIp);
9452 	PackAddInt(p, "SecureNAT_MaxIcmpSessionsPerIp", h->Option->SecureNAT_MaxIcmpSessionsPerIp);
9453 	PackAddInt(p, "AccessListIncludeFileCacheLifetime", h->Option->AccessListIncludeFileCacheLifetime);
9454 	PackAddBool(p, "DisableKernelModeSecureNAT", h->Option->DisableKernelModeSecureNAT);
9455 	PackAddBool(p, "DisableIpRawModeSecureNAT", h->Option->DisableIpRawModeSecureNAT);
9456 	PackAddBool(p, "DisableUserModeSecureNAT", h->Option->DisableUserModeSecureNAT);
9457 	PackAddBool(p, "DisableCheckMacOnLocalBridge", h->Option->DisableCheckMacOnLocalBridge);
9458 	PackAddBool(p, "DisableCorrectIpOffloadChecksum", h->Option->DisableCorrectIpOffloadChecksum);
9459 
9460 	PackAddInt(p, "SavePacketLog", h->LogSetting.SavePacketLog);
9461 	PackAddInt(p, "PacketLogSwitchType", h->LogSetting.PacketLogSwitchType);
9462 	for (i = 0;i < NUM_PACKET_LOG;i++)
9463 	{
9464 		PackAddIntEx(p, "PacketLogConfig", h->LogSetting.PacketLogConfig[i], i, NUM_PACKET_LOG);
9465 	}
9466 	PackAddInt(p, "SaveSecurityLog", h->LogSetting.SaveSecurityLog);
9467 	PackAddInt(p, "SecurityLogSwitchType", h->LogSetting.SecurityLogSwitchType);
9468 	PackAddData(p, "HashedPassword", h->HashedPassword, SHA1_SIZE);
9469 	PackAddData(p, "SecurePassword", h->SecurePassword, SHA1_SIZE);
9470 	PackAddBool(p, "UseHubNameAsDhcpUserClassOption", h->Option->UseHubNameAsDhcpUserClassOption);
9471 	PackAddBool(p, "UseHubNameAsRadiusNasId", h->Option->UseHubNameAsRadiusNasId);
9472 
9473 	SiAccessListToPack(p, h->AccessList);
9474 
9475 	if (h->EnableSecureNAT)
9476 	{
9477 		PackAddBool(p, "EnableSecureNAT", h->EnableSecureNAT);
9478 		OutVhOption(p, h->SecureNATOption);
9479 	}
9480 }
9481 
9482 // Setting of the HUB has been updated
SiHubUpdateProc(HUB * h)9483 void SiHubUpdateProc(HUB *h)
9484 {
9485 	SERVER *s;
9486 	UINT i;
9487 	// Validate arguments
9488 	if (h == NULL || h->Cedar == NULL || h->Cedar->Server == NULL || h->Cedar->Server->ServerType != SERVER_TYPE_FARM_CONTROLLER)
9489 	{
9490 		return;
9491 	}
9492 
9493 	s = h->Cedar->Server;
9494 
9495 	if (s->FarmMemberList == NULL)
9496 	{
9497 		return;
9498 	}
9499 
9500 	if (h->LastVersion != h->CurrentVersion || h->CurrentVersion == 0)
9501 	{
9502 		LIST *fm_list;
9503 		if (h->CurrentVersion == 0)
9504 		{
9505 			h->CurrentVersion = 1;
9506 		}
9507 		h->LastVersion = h->CurrentVersion;
9508 
9509 		Debug("SiHubUpdateProc HUB=%s, Ver=%u, Type=%u, Offline=%u\n", h->Name, h->CurrentVersion,
9510 			h->Type, h->Offline);
9511 
9512 		fm_list = NewListFast(NULL);
9513 
9514 		LockList(s->FarmMemberList);
9515 		{
9516 			while (true)
9517 			{
9518 				bool escape = true;
9519 				// Update the HUB on all members
9520 				for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
9521 				{
9522 					FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
9523 
9524 					if (IsInList(fm_list, f) == false)
9525 					{
9526 						Add(fm_list, f);
9527 						escape = false;
9528 
9529 						if (f->Me == false)
9530 						{
9531 							SiCallUpdateHub(s, f, h);
9532 						}
9533 
9534 						break;
9535 					}
9536 				}
9537 
9538 				if (escape)
9539 				{
9540 					break;
9541 				}
9542 
9543 				UnlockList(s->FarmMemberList);
9544 				LockList(s->FarmMemberList);
9545 			}
9546 		}
9547 		UnlockList(s->FarmMemberList);
9548 
9549 		ReleaseList(fm_list);
9550 	}
9551 
9552 	if (h->Offline == false)
9553 	{
9554 		SiHubOnlineProc(h);
9555 	}
9556 }
9557 
9558 // HUB turns to online
SiHubOnlineProc(HUB * h)9559 void SiHubOnlineProc(HUB *h)
9560 {
9561 	SERVER *s;
9562 	UINT i;
9563 	// Validate arguments
9564 	if (h == NULL || h->Cedar->Server == NULL || h->Cedar->Server->ServerType != SERVER_TYPE_FARM_CONTROLLER)
9565 	{
9566 		// Process only on the farm controller
9567 		return;
9568 	}
9569 
9570 	s = h->Cedar->Server;
9571 
9572 	if (s->FarmMemberList == NULL)
9573 	{
9574 		return;
9575 	}
9576 
9577 	LockList(s->FarmMemberList);
9578 	{
9579 		if (h->Type == HUB_TYPE_FARM_STATIC)
9580 		{
9581 			// Static HUB
9582 			// Create the HUB on all members
9583 			for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
9584 			{
9585 				UINT j;
9586 				bool exists = false;
9587 				FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
9588 
9589 				LockList(f->HubList);
9590 				{
9591 					for (j = 0;j < LIST_NUM(f->HubList);j++)
9592 					{
9593 						HUB_LIST *hh = LIST_DATA(f->HubList, j);
9594 						if (StrCmpi(hh->Name, h->Name) == 0)
9595 						{
9596 							exists = true;
9597 						}
9598 					}
9599 				}
9600 				UnlockList(f->HubList);
9601 
9602 				if (exists == false)
9603 				{
9604 					SiCallCreateHub(s, f, h);
9605 				}
9606 			}
9607 		}
9608 	}
9609 	UnlockList(s->FarmMemberList);
9610 }
9611 
9612 // HUB turns to offline
SiHubOfflineProc(HUB * h)9613 void SiHubOfflineProc(HUB *h)
9614 {
9615 	SERVER *s;
9616 	char hubname[MAX_HUBNAME_LEN + 1];
9617 	UINT i;
9618 	LIST *fm_list;
9619 	// Validate arguments
9620 	if (h == NULL || h->Cedar->Server == NULL || h->Cedar->Server->ServerType != SERVER_TYPE_FARM_CONTROLLER)
9621 	{
9622 		// Process only on the farm controller
9623 		return;
9624 	}
9625 
9626 	s = h->Cedar->Server;
9627 
9628 	if (s->FarmMemberList == NULL)
9629 	{
9630 		return;
9631 	}
9632 
9633 	StrCpy(hubname, sizeof(hubname), h->Name);
9634 
9635 	fm_list = NewListFast(NULL);
9636 
9637 	LockList(s->FarmMemberList);
9638 	{
9639 		while (true)
9640 		{
9641 			bool escape = true;
9642 
9643 			// Stop the HUB on all members
9644 			for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
9645 			{
9646 				FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
9647 
9648 				if (IsInList(fm_list, f) == false)
9649 				{
9650 					Add(fm_list, f);
9651 					escape = false;
9652 
9653 					SiCallDeleteHub(s, f, h);
9654 
9655 					break;
9656 				}
9657 			}
9658 
9659 			if (escape)
9660 			{
9661 				break;
9662 			}
9663 
9664 			UnlockList(s->FarmMemberList);
9665 			LockList(s->FarmMemberList);
9666 		}
9667 	}
9668 	UnlockList(s->FarmMemberList);
9669 
9670 	ReleaseList(fm_list);
9671 }
9672 
9673 // Convert an access to PACK
SiAccessToPack(PACK * p,ACCESS * a,UINT i,UINT total)9674 void SiAccessToPack(PACK *p, ACCESS *a, UINT i, UINT total)
9675 {
9676 	// Validate arguments
9677 	if (p == NULL || a == NULL)
9678 	{
9679 		return;
9680 	}
9681 
9682 	PackAddUniStrEx(p, "Note", a->Note, i, total);
9683 	PackAddIntEx(p, "Active", a->Active, i, total);
9684 	PackAddIntEx(p, "Priority", a->Priority, i, total);
9685 	PackAddIntEx(p, "Discard", a->Discard, i, total);
9686 	if (a->IsIPv6)
9687 	{
9688 		PackAddIp32Ex(p, "SrcIpAddress", 0xFDFFFFDF, i, total);
9689 		PackAddIp32Ex(p, "SrcSubnetMask", 0xFFFFFFFF, i, total);
9690 		PackAddIp32Ex(p, "DestIpAddress", 0xFDFFFFDF, i, total);
9691 		PackAddIp32Ex(p, "DestSubnetMask", 0xFFFFFFFF, i, total);
9692 	}
9693 	else
9694 	{
9695 		PackAddIp32Ex(p, "SrcIpAddress", a->SrcIpAddress, i, total);
9696 		PackAddIp32Ex(p, "SrcSubnetMask", a->SrcSubnetMask, i, total);
9697 		PackAddIp32Ex(p, "DestIpAddress", a->DestIpAddress, i, total);
9698 		PackAddIp32Ex(p, "DestSubnetMask", a->DestSubnetMask, i, total);
9699 	}
9700 	PackAddIntEx(p, "Protocol", a->Protocol, i, total);
9701 	PackAddIntEx(p, "SrcPortStart", a->SrcPortStart, i, total);
9702 	PackAddIntEx(p, "SrcPortEnd", a->SrcPortEnd, i, total);
9703 	PackAddIntEx(p, "DestPortStart", a->DestPortStart, i, total);
9704 	PackAddIntEx(p, "DestPortEnd", a->DestPortEnd, i, total);
9705 	PackAddStrEx(p, "SrcUsername", a->SrcUsername, i, total);
9706 	PackAddStrEx(p, "DestUsername", a->DestUsername, i, total);
9707 	PackAddBoolEx(p, "CheckSrcMac", a->CheckSrcMac, i, total);
9708 	PackAddDataEx(p, "SrcMacAddress", a->SrcMacAddress, sizeof(a->SrcMacAddress), i, total);
9709 	PackAddDataEx(p, "SrcMacMask", a->SrcMacMask, sizeof(a->SrcMacMask), i, total);
9710 	PackAddBoolEx(p, "CheckDstMac", a->CheckDstMac, i, total);
9711 	PackAddDataEx(p, "DstMacAddress", a->DstMacAddress, sizeof(a->DstMacAddress), i, total);
9712 	PackAddDataEx(p, "DstMacMask", a->DstMacMask, sizeof(a->DstMacMask), i, total);
9713 	PackAddBoolEx(p, "CheckTcpState", a->CheckTcpState, i, total);
9714 	PackAddBoolEx(p, "Established", a->Established, i, total);
9715 	PackAddIntEx(p, "Delay", a->Delay, i, total);
9716 	PackAddIntEx(p, "Jitter", a->Jitter, i, total);
9717 	PackAddIntEx(p, "Loss", a->Loss, i, total);
9718 	PackAddStrEx(p, "RedirectUrl", a->RedirectUrl, i, total);
9719 	PackAddBoolEx(p, "IsIPv6", a->IsIPv6, i, total);
9720 	if (a->IsIPv6)
9721 	{
9722 		PackAddIp6AddrEx(p, "SrcIpAddress6", &a->SrcIpAddress6, i, total);
9723 		PackAddIp6AddrEx(p, "SrcSubnetMask6", &a->SrcSubnetMask6, i, total);
9724 		PackAddIp6AddrEx(p, "DestIpAddress6", &a->DestIpAddress6, i, total);
9725 		PackAddIp6AddrEx(p, "DestSubnetMask6", &a->DestSubnetMask6, i, total);
9726 	}
9727 	else
9728 	{
9729 		IPV6_ADDR zero;
9730 
9731 		Zero(&zero, sizeof(zero));
9732 
9733 		PackAddIp6AddrEx(p, "SrcIpAddress6", &zero, i, total);
9734 		PackAddIp6AddrEx(p, "SrcSubnetMask6", &zero, i, total);
9735 		PackAddIp6AddrEx(p, "DestIpAddress6", &zero, i, total);
9736 		PackAddIp6AddrEx(p, "DestSubnetMask6", &zero, i, total);
9737 	}
9738 }
9739 
9740 // Get number of access contained in the PACK
SiNumAccessFromPack(PACK * p)9741 UINT SiNumAccessFromPack(PACK *p)
9742 {
9743 	// Validate arguments
9744 	if (p == NULL)
9745 	{
9746 		return 0;
9747 	}
9748 
9749 	return PackGetIndexCount(p, "Active");
9750 }
9751 
9752 // Convert the PACK to access
SiPackToAccess(PACK * p,UINT i)9753 ACCESS *SiPackToAccess(PACK *p, UINT i)
9754 {
9755 	ACCESS *a;
9756 	// Validate arguments
9757 	if (p == NULL)
9758 	{
9759 		return NULL;
9760 	}
9761 
9762 	a = ZeroMalloc(sizeof(ACCESS));
9763 
9764 	PackGetUniStrEx(p, "Note", a->Note, sizeof(a->Note), i);
9765 	a->Active = PackGetIntEx(p, "Active", i);
9766 	a->Priority = PackGetIntEx(p, "Priority", i);
9767 	a->Discard = PackGetIntEx(p, "Discard", i);
9768 	a->SrcIpAddress = PackGetIp32Ex(p, "SrcIpAddress", i);
9769 	a->SrcSubnetMask = PackGetIp32Ex(p, "SrcSubnetMask", i);
9770 	a->DestIpAddress = PackGetIp32Ex(p, "DestIpAddress", i);
9771 	a->DestSubnetMask = PackGetIp32Ex(p, "DestSubnetMask", i);
9772 	a->Protocol = PackGetIntEx(p, "Protocol", i);
9773 	a->SrcPortStart = PackGetIntEx(p, "SrcPortStart", i);
9774 	a->SrcPortEnd = PackGetIntEx(p, "SrcPortEnd", i);
9775 	a->DestPortStart = PackGetIntEx(p, "DestPortStart", i);
9776 	a->DestPortEnd = PackGetIntEx(p, "DestPortEnd", i);
9777 	PackGetStrEx(p, "SrcUsername", a->SrcUsername, sizeof(a->SrcUsername), i);
9778 	PackGetStrEx(p, "DestUsername", a->DestUsername, sizeof(a->DestUsername), i);
9779 	a->CheckSrcMac = PackGetBoolEx(p, "CheckSrcMac", i);
9780 	PackGetDataEx2(p, "SrcMacAddress", a->SrcMacAddress, sizeof(a->SrcMacAddress), i);
9781 	PackGetDataEx2(p, "SrcMacMask", a->SrcMacMask, sizeof(a->SrcMacMask), i);
9782 	a->CheckDstMac = PackGetBoolEx(p, "CheckDstMac", i);
9783 	PackGetDataEx2(p, "DstMacAddress", a->DstMacAddress, sizeof(a->DstMacAddress), i);
9784 	PackGetDataEx2(p, "DstMacMask", a->DstMacMask, sizeof(a->DstMacMask), i);
9785 	a->CheckTcpState = PackGetBoolEx(p, "CheckTcpState", i);
9786 	a->Established = PackGetBoolEx(p, "Established", i);
9787 	a->Delay = PackGetIntEx(p, "Delay", i);
9788 	a->Jitter = PackGetIntEx(p, "Jitter", i);
9789 	a->Loss = PackGetIntEx(p, "Loss", i);
9790 	a->IsIPv6 = PackGetBoolEx(p, "IsIPv6", i);
9791 	PackGetStrEx(p, "RedirectUrl", a->RedirectUrl, sizeof(a->RedirectUrl), i);
9792 	if (a->IsIPv6)
9793 	{
9794 		PackGetIp6AddrEx(p, "SrcIpAddress6", &a->SrcIpAddress6, i);
9795 		PackGetIp6AddrEx(p, "SrcSubnetMask6", &a->SrcSubnetMask6, i);
9796 		PackGetIp6AddrEx(p, "DestIpAddress6", &a->DestIpAddress6, i);
9797 		PackGetIp6AddrEx(p, "DestSubnetMask6", &a->DestSubnetMask6, i);
9798 	}
9799 
9800 	return a;
9801 }
9802 
9803 // Convert the PACK to an access list
SiAccessListToPack(PACK * p,LIST * o)9804 void SiAccessListToPack(PACK *p, LIST *o)
9805 {
9806 	// Validate arguments
9807 	if (p == NULL || o == NULL)
9808 	{
9809 		return;
9810 	}
9811 
9812 	LockList(o);
9813 	{
9814 		UINT i;
9815 		for (i = 0;i < LIST_NUM(o);i++)
9816 		{
9817 			ACCESS *a = LIST_DATA(o, i);
9818 			SiAccessToPack(p, a, i, LIST_NUM(o));
9819 		}
9820 	}
9821 	UnlockList(o);
9822 }
9823 
9824 // Get the member that is hosting the specified HUB
SiGetHubHostingMember(SERVER * s,HUB * h,bool admin_mode,CONNECTION * c)9825 FARM_MEMBER *SiGetHubHostingMember(SERVER *s, HUB *h, bool admin_mode, CONNECTION *c)
9826 {
9827 	FARM_MEMBER *ret = NULL;
9828 	char name[MAX_SIZE];
9829 	UINT i;
9830 	// Validate arguments
9831 	if (s == NULL || h == NULL || c == NULL)
9832 	{
9833 		return NULL;
9834 	}
9835 
9836 	StrCpy(name, sizeof(name), h->Name);
9837 
9838 	if (h->Type == HUB_TYPE_FARM_STATIC)
9839 	{
9840 		// It is good to select any member in the case of static HUB
9841 		if (admin_mode == false)
9842 		{
9843 			ret = SiGetNextFarmMember(s, c, h);
9844 		}
9845 		else
9846 		{
9847 			UINT i;
9848 			ret = NULL;
9849 
9850 			for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
9851 			{
9852 				FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
9853 				if (f->Me)
9854 				{
9855 					ret = f;
9856 					break;
9857 				}
9858 			}
9859 		}
9860 	}
9861 	else
9862 	{
9863 		// Examine whether there is a member that is hosting the HUB already in the case of dynamic HUB
9864 		for (i = 0;i < LIST_NUM(s->FarmMemberList);i++)
9865 		{
9866 			FARM_MEMBER *f = LIST_DATA(s->FarmMemberList, i);
9867 			HUB_LIST *hh, t;
9868 			StrCpy(t.Name, sizeof(t.Name), name);
9869 			LockList(f->HubList);
9870 			{
9871 				hh = Search(f->HubList, &t);
9872 				if (hh != NULL)
9873 				{
9874 					// Found
9875 					ret = f;
9876 				}
9877 			}
9878 			UnlockList(f->HubList);
9879 		}
9880 
9881 		if (ret == NULL)
9882 		{
9883 			// Let host the new HUB
9884 			FARM_MEMBER *f;
9885 
9886 			// Select the member to host
9887 			ret = SiGetNextFarmMember(s, c, h);
9888 
9889 			f = ret;
9890 			if (f != NULL)
9891 			{
9892 				// HUB creation directive
9893 				SiAddHubCreateHistory(s, name);
9894 				SiCallCreateHub(s, f, h);
9895 				SiCallUpdateHub(s, f, h);
9896 			}
9897 		}
9898 	}
9899 
9900 	return ret;
9901 }
9902 
9903 // Task is called
SiCalledTask(FARM_CONTROLLER * f,PACK * p,char * taskname)9904 PACK *SiCalledTask(FARM_CONTROLLER *f, PACK *p, char *taskname)
9905 {
9906 	PACK *ret;
9907 	SERVER *s;
9908 	// Validate arguments
9909 	if (f == NULL || p == NULL || taskname == NULL)
9910 	{
9911 		return NULL;
9912 	}
9913 
9914 	ret = NULL;
9915 	s = f->Server;
9916 
9917 	if (StrCmpi(taskname, "noop") == 0)
9918 	{
9919 		// NO OPERATION
9920 		ret = NewPack();
9921 	}
9922 	else
9923 	{
9924 		Debug("Task Called: [%s].\n", taskname);
9925 		if (StrCmpi(taskname, "createhub") == 0)
9926 		{
9927 			SiCalledCreateHub(s, p);
9928 			ret = NewPack();
9929 		}
9930 		else if (StrCmpi(taskname, "deletehub") == 0)
9931 		{
9932 			SiCalledDeleteHub(s, p);
9933 			ret = NewPack();
9934 		}
9935 		else if (StrCmpi(taskname, "enumhub") == 0)
9936 		{
9937 			ret = NewPack();
9938 			SiCalledEnumHub(s, ret, p);
9939 		}
9940 		else if (StrCmpi(taskname, "updatehub") == 0)
9941 		{
9942 			SiCalledUpdateHub(s, p);
9943 			ret = NewPack();
9944 		}
9945 		else if (StrCmpi(taskname, "createticket") == 0)
9946 		{
9947 			ret = SiCalledCreateTicket(s, p);
9948 		}
9949 		else if (StrCmpi(taskname, "enumnat") == 0)
9950 		{
9951 			ret = SiCalledEnumNat(s, p);
9952 		}
9953 		else if (StrCmpi(taskname, "enumdhcp") == 0)
9954 		{
9955 			ret = SiCalledEnumDhcp(s, p);
9956 		}
9957 		else if (StrCmpi(taskname, "getnatstatus") == 0)
9958 		{
9959 			ret = SiCalledGetNatStatus(s, p);
9960 		}
9961 		else if (StrCmpi(taskname, "enumsession") == 0)
9962 		{
9963 			ret = SiCalledEnumSession(s, p);
9964 		}
9965 		else if (StrCmpi(taskname, "deletesession") == 0)
9966 		{
9967 			SiCalledDeleteSession(s, p);
9968 			ret = NewPack();
9969 		}
9970 		else if (StrCmpi(taskname, "deletemactable") == 0)
9971 		{
9972 			SiCalledDeleteMacTable(s, p);
9973 			ret = NewPack();
9974 		}
9975 		else if (StrCmpi(taskname, "deleteiptable") == 0)
9976 		{
9977 			SiCalledDeleteIpTable(s, p);
9978 			ret = NewPack();
9979 		}
9980 		else if (StrCmpi(taskname, "enummactable") == 0)
9981 		{
9982 			ret = SiCalledEnumMacTable(s, p);
9983 		}
9984 		else if (StrCmpi(taskname, "enumiptable") == 0)
9985 		{
9986 			ret = SiCalledEnumIpTable(s, p);
9987 		}
9988 		else if (StrCmpi(taskname, "getsessionstatus") == 0)
9989 		{
9990 			ret = SiCalledGetSessionStatus(s, p);
9991 		}
9992 		else if (StrCmpi(taskname, "enumlogfilelist") == 0)
9993 		{
9994 			ret = SiCalledEnumLogFileList(s, p);
9995 		}
9996 		else if (StrCmpi(taskname, "readlogfile") == 0)
9997 		{
9998 			ret = SiCalledReadLogFile(s, p);
9999 		}
10000 	}
10001 
10002 	return ret;
10003 }
10004 
10005 // Call the task (asynchronous)
SiCallTaskAsyncBegin(FARM_MEMBER * f,PACK * p,char * taskname)10006 FARM_TASK *SiCallTaskAsyncBegin(FARM_MEMBER *f, PACK *p, char *taskname)
10007 {
10008 	char tmp[MAX_PATH];
10009 	FARM_TASK *t;
10010 	// Validate arguments
10011 	if (f == NULL || p == NULL || taskname == NULL)
10012 	{
10013 		return NULL;
10014 	}
10015 
10016 	PackAddStr(p, "taskname", taskname);
10017 
10018 	Debug("Call Async Task [%s] (%s)\n", taskname, f->hostname);
10019 
10020 	Format(tmp, sizeof(tmp), "CLUSTER_CALL_ASYNC: Entering Call [%s] to %s", taskname, f->hostname);
10021 	SiDebugLog(f->Cedar->Server, tmp);
10022 
10023 	t = SiFarmServPostTask(f, p);
10024 	StrCpy(t->TaskName, sizeof(t->TaskName), taskname);
10025 	StrCpy(t->HostName, sizeof(t->HostName), f->hostname);
10026 	t->FarmMember = f;
10027 
10028 	return t;
10029 }
10030 
10031 // Get the results of the asynchronous task
SiCallTaskAsyncEnd(CEDAR * c,FARM_TASK * t)10032 PACK *SiCallTaskAsyncEnd(CEDAR *c, FARM_TASK *t)
10033 {
10034 	PACK *p;
10035 	char taskname[MAX_PATH];
10036 	char hostname[MAX_PATH];
10037 	char tmp[MAX_SIZE];
10038 	// Validate arguments
10039 	if (t == NULL || c == NULL)
10040 	{
10041 		return NULL;
10042 	}
10043 
10044 	StrCpy(taskname, sizeof(taskname), t->TaskName);
10045 	StrCpy(hostname, sizeof(hostname), t->HostName);
10046 
10047 	p = SiFarmServWaitTask(t);
10048 	if (p == NULL)
10049 	{
10050 		Format(tmp, sizeof(tmp), "CLUSTER_CALL_ASYNC: Call ERROR [%s] to %s", taskname, hostname);
10051 		SiDebugLog(c->Server, tmp);
10052 		return NULL;
10053 	}
10054 
10055 	Format(tmp, sizeof(tmp), "CLUSTER_CALL_ASYNC: Retrieving Call Result [%s] to %s", taskname, hostname);
10056 	SiDebugLog(c->Server, tmp);
10057 
10058 	return p;
10059 }
10060 
10061 // Call the task
SiCallTask(FARM_MEMBER * f,PACK * p,char * taskname)10062 PACK *SiCallTask(FARM_MEMBER *f, PACK *p, char *taskname)
10063 {
10064 	PACK *ret;
10065 	char tmp[MAX_PATH];
10066 	// Validate arguments
10067 	if (f == NULL || p == NULL || taskname == NULL)
10068 	{
10069 		return NULL;
10070 	}
10071 
10072 	PackAddStr(p, "taskname", taskname);
10073 
10074 	Debug("Call Task [%s] (%s)\n", taskname, f->hostname);
10075 
10076 	Format(tmp, sizeof(tmp), "CLUSTER_CALL: Entering Call [%s] to %s", taskname, f->hostname);
10077 	SiDebugLog(f->Cedar->Server, tmp);
10078 
10079 	ret = SiExecTask(f, p);
10080 
10081 	Format(tmp, sizeof(tmp), "CLUSTER_CALL: Leaving Call [%s] to %s", taskname, f->hostname);
10082 	SiDebugLog(f->Cedar->Server, tmp);
10083 
10084 	return ret;
10085 }
10086 
10087 // Task listening procedure (Main Process)
SiAcceptTasksFromControllerMain(FARM_CONTROLLER * f,SOCK * sock)10088 void SiAcceptTasksFromControllerMain(FARM_CONTROLLER *f, SOCK *sock)
10089 {
10090 	PACK *request;
10091 	PACK *response;
10092 	char taskname[MAX_SIZE];
10093 	// Validate arguments
10094 	if (f == NULL || sock == NULL)
10095 	{
10096 		return;
10097 	}
10098 
10099 	f->IsConnected = true;
10100 
10101 	while (true)
10102 	{
10103 		bool ret;
10104 		// Receive the PACK
10105 		request = HttpClientRecv(sock);
10106 		if (request == NULL)
10107 		{
10108 			// Disconnect
10109 			break;
10110 		}
10111 
10112 		response = NULL;
10113 
10114 		// Get the name
10115 		if (PackGetStr(request, "taskname", taskname, sizeof(taskname)))
10116 		{
10117 			Lock(f->Server->TasksFromFarmControllerLock);
10118 			{
10119 				response = SiCalledTask(f, request, taskname);
10120 			}
10121 			Unlock(f->Server->TasksFromFarmControllerLock);
10122 		}
10123 
10124 		FreePack(request);
10125 
10126 		// Return a response
10127 		if (response == NULL)
10128 		{
10129 			response = NewPack();
10130 		}
10131 		else
10132 		{
10133 			PackAddInt(response, "succeed", 1);
10134 		}
10135 
10136 		ret = HttpClientSend(sock, response);
10137 		FreePack(response);
10138 
10139 		if (ret == false)
10140 		{
10141 			// Disconnect
10142 			break;
10143 		}
10144 	}
10145 
10146 	f->IsConnected = false;
10147 }
10148 
10149 // Task waiting procedure
SiAcceptTasksFromController(FARM_CONTROLLER * f,SOCK * sock)10150 void SiAcceptTasksFromController(FARM_CONTROLLER *f, SOCK *sock)
10151 {
10152 	UINT i;
10153 	HUB **hubs;
10154 	UINT num_hubs;
10155 	CEDAR *c;
10156 	SERVER *s;
10157 	// Validate arguments
10158 	if (f == NULL || sock == NULL)
10159 	{
10160 		return;
10161 	}
10162 
10163 	s = f->Server;
10164 	c = s->Cedar;
10165 
10166 	// Main process
10167 	SiAcceptTasksFromControllerMain(f, sock);
10168 
10169 	// Stop all Virtual HUBs since the connection to the controller is disconnected
10170 	LockList(c->HubList);
10171 	{
10172 		hubs = ToArray(c->HubList);
10173 		num_hubs = LIST_NUM(c->HubList);
10174 		for (i = 0;i < num_hubs;i++)
10175 		{
10176 			AddRef(hubs[i]->ref);
10177 		}
10178 	}
10179 	UnlockList(c->HubList);
10180 
10181 	for (i = 0;i < num_hubs;i++)
10182 	{
10183 		SetHubOffline(hubs[i]);
10184 		DelHub(c, hubs[i]);
10185 		ReleaseHub(hubs[i]);
10186 	}
10187 
10188 	Free(hubs);
10189 }
10190 
10191 // Execute the task
SiExecTask(FARM_MEMBER * f,PACK * p)10192 PACK *SiExecTask(FARM_MEMBER *f, PACK *p)
10193 {
10194 	FARM_TASK *t;
10195 	// Validate arguments
10196 	if (f == NULL || p == NULL)
10197 	{
10198 		return NULL;
10199 	}
10200 
10201 	t = SiFarmServPostTask(f, p);
10202 	if (t == NULL)
10203 	{
10204 		return NULL;
10205 	}
10206 
10207 	return SiFarmServWaitTask(t);
10208 }
10209 
10210 // Task queuing
SiFarmServPostTask(FARM_MEMBER * f,PACK * request)10211 FARM_TASK *SiFarmServPostTask(FARM_MEMBER *f, PACK *request)
10212 {
10213 	FARM_TASK *t;
10214 	// Validate arguments
10215 	if (f == NULL || request == NULL)
10216 	{
10217 		return NULL;
10218 	}
10219 
10220 	t = ZeroMalloc(sizeof(FARM_TASK));
10221 	t->CompleteEvent = NewEvent();
10222 	t->Request = request;
10223 
10224 	LockQueue(f->TaskQueue);
10225 	{
10226 		if (f->Halting)
10227 		{
10228 			// Halting (failure)
10229 			UnlockQueue(f->TaskQueue);
10230 			ReleaseEvent(t->CompleteEvent);
10231 			Free(t);
10232 			return NULL;
10233 		}
10234 
10235 		InsertQueue(f->TaskQueue, t);
10236 	}
10237 	UnlockQueue(f->TaskQueue);
10238 
10239 	Set(f->TaskPostEvent);
10240 
10241 	return t;
10242 }
10243 
10244 // Wait for task results
SiFarmServWaitTask(FARM_TASK * t)10245 PACK *SiFarmServWaitTask(FARM_TASK *t)
10246 {
10247 	PACK *response;
10248 	// Validate arguments
10249 	if (t == NULL)
10250 	{
10251 		return NULL;
10252 	}
10253 
10254 	Wait(t->CompleteEvent, INFINITE);
10255 	ReleaseEvent(t->CompleteEvent);
10256 	FreePack(t->Request);
10257 
10258 	response = t->Response;
10259 	Free(t);
10260 
10261 	if (PackGetInt(response, "succeed") == 0)
10262 	{
10263 		// Task calling fails for any reason
10264 		FreePack(response);
10265 		return NULL;
10266 	}
10267 
10268 	return response;
10269 }
10270 
10271 // Server farm processing main
SiFarmServMain(SERVER * server,SOCK * sock,FARM_MEMBER * f)10272 void SiFarmServMain(SERVER *server, SOCK *sock, FARM_MEMBER *f)
10273 {
10274 	UINT wait_time = SERVER_CONTROL_TCP_TIMEOUT / 2;
10275 	bool send_noop = false;
10276 	UINT i;
10277 	CEDAR *c;
10278 	// Validate arguments
10279 	if (server == NULL || sock == NULL || f == NULL)
10280 	{
10281 		Debug("SiFarmServMain Failed.\n");
10282 		return;
10283 	}
10284 
10285 	Debug("SiFarmServMain Started.\n");
10286 
10287 	c = server->Cedar;
10288 
10289 	// Send a directive to create all static HUBs at the stage
10290 	// where the members have been connected to the controller
10291 	LockList(c->HubList);
10292 	{
10293 		for (i = 0;i < LIST_NUM(c->HubList);i++)
10294 		{
10295 			HUB *h = LIST_DATA(c->HubList, i);
10296 			if (h->Offline == false)
10297 			{
10298 				if (h->Type == HUB_TYPE_FARM_STATIC)
10299 				{
10300 					PACK *p;
10301 					HUB_LIST *hh;
10302 					p = NewPack();
10303 					SiPackAddCreateHub(p, h);
10304 					PackAddStr(p, "taskname", "createhub");
10305 					HttpServerSend(sock, p);
10306 					FreePack(p);
10307 					p = HttpServerRecv(sock);
10308 					FreePack(p);
10309 
10310 					p = NewPack();
10311 					SiPackAddCreateHub(p, h);
10312 					PackAddStr(p, "taskname", "updatehub");
10313 					HttpServerSend(sock, p);
10314 					FreePack(p);
10315 					p = HttpServerRecv(sock);
10316 					FreePack(p);
10317 
10318 					hh = ZeroMalloc(sizeof(HUB_LIST));
10319 					hh->DynamicHub = false;
10320 					hh->FarmMember = f;
10321 					StrCpy(hh->Name, sizeof(hh->Name), h->Name);
10322 					LockList(f->HubList);
10323 					{
10324 						Add(f->HubList, hh);
10325 					}
10326 					UnlockList(f->HubList);
10327 				}
10328 			}
10329 		}
10330 	}
10331 	UnlockList(c->HubList);
10332 
10333 	Debug("SiFarmServMain: while (true)\n");
10334 
10335 	while (true)
10336 	{
10337 		FARM_TASK *t;
10338 		UINT64 tick;
10339 
10340 		do
10341 		{
10342 			// Check whether a new task arrived
10343 			LockQueue(f->TaskQueue);
10344 			{
10345 				t = GetNext(f->TaskQueue);
10346 			}
10347 			UnlockQueue(f->TaskQueue);
10348 
10349 			if (t != NULL)
10350 			{
10351 				// Handle this task
10352 				PACK *p = t->Request;
10353 				bool ret;
10354 
10355 				// Transmission
10356 				ret = HttpServerSend(sock, p);
10357 				send_noop = false;
10358 
10359 				if (ret == false)
10360 				{
10361 					// Disconnected
10362 					// Cancel this task
10363 					Set(t->CompleteEvent);
10364 					goto DISCONNECTED;
10365 				}
10366 
10367 				// Receive
10368 				p = HttpServerRecvEx(sock, FIRM_SERV_RECV_PACK_MAX_SIZE);
10369 
10370 				t->Response = p;
10371 				Set(t->CompleteEvent);
10372 
10373 				if (p == NULL)
10374                 {
10375                     Disconnect(sock);
10376                     goto DISCONNECTED;
10377                 }
10378 			}
10379 		}
10380 		while (t != NULL);
10381 
10382 		if (send_noop)
10383 		{
10384 			// Send a NOOP
10385 			PACK *p;
10386 			bool ret;
10387 			p = NewPack();
10388 			PackAddStr(p, "taskname", "noop");
10389 
10390 			ret = HttpServerSend(sock, p);
10391 			FreePack(p);
10392 
10393 			if (ret == false)
10394 			{
10395 				goto DISCONNECTED;
10396 			}
10397 
10398 			p = HttpServerRecv(sock);
10399 			if (p == NULL)
10400 			{
10401 				goto DISCONNECTED;
10402 			}
10403 
10404 			FreePack(p);
10405 		}
10406 
10407 		tick = Tick64();
10408 
10409 		while (true)
10410 		{
10411 			bool break_flag;
10412 			if ((tick + wait_time) <= Tick64())
10413 			{
10414 				break;
10415 			}
10416 
10417 			Wait(f->TaskPostEvent, 250);
10418 
10419 			break_flag = false;
10420 			LockQueue(f->TaskQueue);
10421 			{
10422 				if (f->TaskQueue->num_item != 0)
10423 				{
10424 					break_flag = true;
10425 				}
10426 			}
10427 			UnlockQueue(f->TaskQueue);
10428 
10429 			if (break_flag || f->Halting || server->Halt)
10430 			{
10431 				break;
10432 			}
10433 		}
10434 		send_noop = true;
10435 	}
10436 
10437 DISCONNECTED:
10438 
10439 	Debug("SiFarmServMain: DISCONNECTED\n");
10440 
10441 	f->Halting = true;
10442 	// Cancel all outstanding tasks
10443 	LockQueue(f->TaskQueue);
10444 	{
10445 		FARM_TASK *t;
10446 
10447 		while (t = GetNext(f->TaskQueue))
10448 		{
10449 			Set(t->CompleteEvent);
10450 		}
10451 	}
10452 	UnlockQueue(f->TaskQueue);
10453 }
10454 
10455 // Farm server function that handles the connection from farm members
SiFarmServ(SERVER * server,SOCK * sock,X * cert,UINT ip,UINT num_port,UINT * ports,char * hostname,UINT point,UINT weight,UINT max_sessions)10456 void SiFarmServ(SERVER *server, SOCK *sock, X *cert, UINT ip, UINT num_port, UINT *ports, char *hostname, UINT point, UINT weight, UINT max_sessions)
10457 {
10458 	PACK *p;
10459 	FARM_MEMBER *f;
10460 	UINT i;
10461 	char tmp[MAX_SIZE];
10462 	// Validate arguments
10463 	if (server == NULL || sock == NULL || cert == NULL || num_port == 0 || ports == NULL || hostname == NULL)
10464 	{
10465 		return;
10466 	}
10467 
10468 	if (weight == 0)
10469 	{
10470 		weight = FARM_DEFAULT_WEIGHT;
10471 	}
10472 
10473 	if (max_sessions == 0)
10474 	{
10475 		max_sessions = SERVER_MAX_SESSIONS;
10476 	}
10477 
10478 	if (ip == 0)
10479 	{
10480 		// If the public IP address is not specified, specify the connection
10481 		// source IP address of this farm member server
10482 		ip = IPToUINT(&sock->RemoteIP);
10483 	}
10484 
10485 	IPToStr32(tmp, sizeof(tmp), ip);
10486 	SLog(server->Cedar, "LS_FARM_SERV_START", tmp, hostname);
10487 
10488 	// Inform the success
10489 	p = NewPack();
10490 	HttpServerSend(sock, p);
10491 	FreePack(p);
10492 
10493 	IPToStr32(tmp, sizeof(tmp), ip);
10494 	Debug("Farm Member %s Connected. IP: %s\n", hostname, tmp);
10495 
10496 	SetTimeout(sock, SERVER_CONTROL_TCP_TIMEOUT);
10497 
10498 	f = ZeroMalloc(sizeof(FARM_MEMBER));
10499 	f->Cedar = server->Cedar;
10500 	f->Ip = ip;
10501 	f->NumPort = num_port;
10502 	f->Ports = ports;
10503 	StrCpy(f->hostname, sizeof(f->hostname), hostname);
10504 	f->ServerCert = cert;
10505 	f->ConnectedTime = SystemTime64();
10506 	f->Weight = weight;
10507 	f->MaxSessions = max_sessions;
10508 
10509 	f->HubList = NewList(CompareHubList);
10510 	f->Point = point;
10511 
10512 	f->TaskQueue = NewQueue();
10513 	f->TaskPostEvent = NewEvent();
10514 
10515 	// Add to the list
10516 	LockList(server->FarmMemberList);
10517 	{
10518 		Add(server->FarmMemberList, f);
10519 	}
10520 	UnlockList(server->FarmMemberList);
10521 
10522 	// Main process
10523 	SiFarmServMain(server, sock, f);
10524 
10525 	// Remove from the list
10526 	LockList(server->FarmMemberList);
10527 	{
10528 		Delete(server->FarmMemberList, f);
10529 	}
10530 	UnlockList(server->FarmMemberList);
10531 
10532 	ReleaseQueue(f->TaskQueue);
10533 	ReleaseEvent(f->TaskPostEvent);
10534 
10535 	for (i = 0;i < LIST_NUM(f->HubList);i++)
10536 	{
10537 		HUB_LIST *hh = LIST_DATA(f->HubList, i);
10538 		Free(hh);
10539 	}
10540 
10541 	ReleaseList(f->HubList);
10542 
10543 	Free(f);
10544 
10545 	SLog(server->Cedar, "LS_FARM_SERV_END", hostname);
10546 }
10547 
10548 // Search in HUB list
CompareHubList(void * p1,void * p2)10549 int CompareHubList(void *p1, void *p2)
10550 {
10551 	HUB_LIST *h1, *h2;
10552 	if (p1 == NULL || p2 == NULL)
10553 	{
10554 		return 0;
10555 	}
10556 	h1 = *(HUB_LIST **)p1;
10557 	h2 = *(HUB_LIST **)p2;
10558 	if (h1 == NULL || h2 == NULL)
10559 	{
10560 		return 0;
10561 	}
10562 	return StrCmpi(h1->Name, h2->Name);
10563 }
10564 
10565 // Connection thread to the controller
SiConnectToControllerThread(THREAD * thread,void * param)10566 void SiConnectToControllerThread(THREAD *thread, void *param)
10567 {
10568 	FARM_CONTROLLER *f;
10569 	SESSION *s;
10570 	CONNECTION *c;
10571 	SERVER *server;
10572 	bool first_failed;
10573 	// Validate arguments
10574 	if (thread == NULL || param == NULL)
10575 	{
10576 		return;
10577 	}
10578 
10579 #ifdef	OS_WIN32
10580 	MsSetThreadPriorityRealtime();
10581 #endif	// OS_WIN32
10582 
10583 	f = (FARM_CONTROLLER *)param;
10584 	f->Thread = thread;
10585 	AddRef(f->Thread->ref);
10586 	NoticeThreadInit(thread);
10587 
10588 	f->StartedTime = SystemTime64();
10589 
10590 	server = f->Server;
10591 
10592 	f->StartedTime = SystemTime64();
10593 
10594 	SLog(server->Cedar, "LS_FARM_CONNECT_1", server->ControllerName);
10595 
10596 	first_failed = true;
10597 
10598 	while (true)
10599 	{
10600 		// Attempt to connect
10601 		CLIENT_OPTION o;
10602 
10603 		f->LastError = ERR_TRYING_TO_CONNECT;
10604 
10605 		Zero(&o, sizeof(CLIENT_OPTION));
10606 		StrCpy(o.Hostname, sizeof(o.Hostname), server->ControllerName);
10607 		o.Port = server->ControllerPort;
10608 		f->NumTry++;
10609 
10610 		Debug("Try to Connect %s (Controller).\n", server->ControllerName);
10611 
10612 		s = NewRpcSessionEx(server->Cedar, &o, NULL, CEDAR_SERVER_FARM_STR);
10613 
10614 		if (s != NULL)
10615 		{
10616 			// Connection success: send the authentication data
10617 			PACK *p = NewPack();
10618 			UCHAR secure_password[SHA1_SIZE];
10619 			BUF *b;
10620 
10621 			c = s->Connection;
10622 
10623 			Lock(f->lock);
10624 			{
10625 				f->Sock = c->FirstSock;
10626 				AddRef(f->Sock->ref);
10627 				SetTimeout(f->Sock, SERVER_CONTROL_TCP_TIMEOUT);
10628 			}
10629 			Unlock(f->lock);
10630 
10631 			// Method
10632 			PackAddStr(p, "method", "farm_connect");
10633 			PackAddClientVersion(p, s->Connection);
10634 
10635 			// Password
10636 			SecurePassword(secure_password, server->MemberPassword, s->Connection->Random);
10637 			PackAddData(p, "SecurePassword", secure_password, sizeof(secure_password));
10638 
10639 			Lock(server->Cedar->lock);
10640 			{
10641 				b = XToBuf(server->Cedar->ServerX, false);
10642 			}
10643 			Unlock(server->Cedar->lock);
10644 
10645 			if (b != NULL)
10646 			{
10647 				char tmp[MAX_SIZE];
10648 				bool ret;
10649 				UINT i;
10650 				// Server certificate
10651 				PackAddBuf(p, "ServerCert", b);
10652 				FreeBuf(b);
10653 
10654 				// Maximum number of sessions
10655 				PackAddInt(p, "MaxSessions", GetServerCapsInt(server, "i_max_sessions"));
10656 
10657 				// Point
10658 				PackAddInt(p, "Point", SiGetPoint(server));
10659 				PackAddInt(p, "Weight", server->Weight);
10660 
10661 				// Host name
10662 				GetMachineName(tmp, sizeof(tmp));
10663 				PackAddStr(p, "HostName", tmp);
10664 
10665 				// Public IP
10666 				PackAddIp32(p, "PublicIp", server->PublicIp);
10667 
10668 				// Public port
10669 				for (i = 0;i < server->NumPublicPort;i++)
10670 				{
10671 					PackAddIntEx(p, "PublicPort", server->PublicPorts[i], i, server->NumPublicPort);
10672 				}
10673 
10674 				ret = HttpClientSend(c->FirstSock, p);
10675 
10676 				if (ret)
10677 				{
10678 					PACK *p;
10679 					UINT err = ERR_PROTOCOL_ERROR;
10680 
10681 					first_failed = true;
10682 					p = HttpClientRecv(c->FirstSock);
10683 					if (p != NULL && (err = GetErrorFromPack(p)) == 0)
10684 					{
10685 						// Successful connection
10686 						SLog(server->Cedar, "LS_FARM_START");
10687 						f->CurrentConnectedTime = SystemTime64();
10688 						if (f->FirstConnectedTime == 0)
10689 						{
10690 							f->FirstConnectedTime = SystemTime64();
10691 						}
10692 						f->NumConnected++;
10693 						Debug("Connect Succeed.\n");
10694 						f->Online = true;
10695 
10696 						// Main process
10697 						SiAcceptTasksFromController(f, c->FirstSock);
10698 
10699 						f->Online = false;
10700 					}
10701 					else
10702 					{
10703 						// Error
10704 						f->LastError = err;
10705 						SLog(server->Cedar, "LS_FARM_CONNECT_2", server->ControllerName,
10706 							GetUniErrorStr(err), err);
10707 					}
10708 					FreePack(p);
10709 				}
10710 				else
10711 				{
10712 					f->LastError = ERR_DISCONNECTED;
10713 
10714 					if (first_failed)
10715 					{
10716 						SLog(server->Cedar, "LS_FARM_CONNECT_3", server->ControllerName, RETRY_CONNECT_TO_CONTROLLER_INTERVAL / 1000);
10717 						first_failed = false;
10718 					}
10719 				}
10720 			}
10721 
10722 			FreePack(p);
10723 
10724 			// Disconnect
10725 			Lock(f->lock);
10726 			{
10727 				if (f->Sock != NULL)
10728 				{
10729 					ReleaseSock(f->Sock);
10730 					f->Sock = NULL;
10731 				}
10732 			}
10733 			Unlock(f->lock);
10734 
10735 			ReleaseSession(s);
10736 			s = NULL;
10737 
10738 			if (f->LastError == ERR_TRYING_TO_CONNECT)
10739 			{
10740 				f->LastError = ERR_DISCONNECTED;
10741 			}
10742 		}
10743 		else
10744 		{
10745 			// Connection failure
10746 			f->LastError = ERR_CONNECT_TO_FARM_CONTROLLER;
10747 
10748 			if (first_failed)
10749 			{
10750 				SLog(server->Cedar, "LS_FARM_CONNECT_3", server->ControllerName, RETRY_CONNECT_TO_CONTROLLER_INTERVAL / 1000);
10751 				first_failed = false;
10752 			}
10753 		}
10754 
10755 		Debug("Controller Disconnected. ERROR = %S\n", _E(f->LastError));
10756 
10757 		f->NumFailed = f->NumTry - f->NumConnected;
10758 
10759 		// Wait for event
10760 		Wait(f->HaltEvent, RETRY_CONNECT_TO_CONTROLLER_INTERVAL);
10761 
10762 		if (f->Halt)
10763 		{
10764 			// Halting flag
10765 			break;
10766 		}
10767 	}
10768 
10769 	SLog(server->Cedar, "LS_FARM_DISCONNECT");
10770 }
10771 
10772 // Disconnect the connection to the controller
SiStopConnectToController(FARM_CONTROLLER * f)10773 void SiStopConnectToController(FARM_CONTROLLER *f)
10774 {
10775 	// Validate arguments
10776 	if (f == NULL)
10777 	{
10778 		return;
10779 	}
10780 
10781 	f->Halt = true;
10782 
10783 	// Stop the connection
10784 	Lock(f->lock);
10785 	{
10786 		Disconnect(f->Sock);
10787 	}
10788 	Unlock(f->lock);
10789 
10790 	Set(f->HaltEvent);
10791 
10792 	// Wait for the thread termination
10793 	WaitThread(f->Thread, INFINITE);
10794 	ReleaseThread(f->Thread);
10795 
10796 	DeleteLock(f->lock);
10797 	ReleaseEvent(f->HaltEvent);
10798 
10799 	Free(f);
10800 }
10801 
10802 // Start a connection to the controller
SiStartConnectToController(SERVER * s)10803 FARM_CONTROLLER *SiStartConnectToController(SERVER *s)
10804 {
10805 	FARM_CONTROLLER *f;
10806 	THREAD *t;
10807 	// Validate arguments
10808 	if (s == NULL)
10809 	{
10810 		return NULL;
10811 	}
10812 
10813 	f = ZeroMalloc(sizeof(FARM_CONTROLLER));
10814 	f->Server = s;
10815 	f->LastError = ERR_TRYING_TO_CONNECT;
10816 	f->HaltEvent = NewEvent();
10817 	f->lock = NewLock();
10818 
10819 	t = NewThread(SiConnectToControllerThread, f);
10820 	WaitThreadInit(t);
10821 	ReleaseThread(t);
10822 
10823 	return f;
10824 }
10825 
10826 // Get the current version
SiGetCurrentRegion(CEDAR * c,char * region,UINT region_size)10827 void SiGetCurrentRegion(CEDAR *c, char *region, UINT region_size)
10828 {
10829 	ClearStr(region, region_size);
10830 	// Validate arguments
10831 	if (c == NULL || region == NULL)
10832 	{
10833 		return;
10834 	}
10835 
10836 	Lock(c->CurrentRegionLock);
10837 	{
10838 		StrCpy(region, region_size, c->CurrentRegion);
10839 	}
10840 	Unlock(c->CurrentRegionLock);
10841 
10842 	if (IsEmptyStr(region))
10843 	{
10844 		if (GetCurrentLangId() == SE_LANG_JAPANESE)
10845 		{
10846 			StrCpy(region, region_size, "JP");
10847 		}
10848 		else if (GetCurrentLangId() == SE_LANG_CHINESE_ZH)
10849 		{
10850 			StrCpy(region, region_size, "CN");
10851 		}
10852 	}
10853 }
10854 
10855 // Check the current region
SiCheckCurrentRegion(CEDAR * c,char * r)10856 bool SiCheckCurrentRegion(CEDAR *c, char *r)
10857 {
10858 	char tmp[64];
10859 	// Validate arguments
10860 	if (c == NULL || r == NULL)
10861 	{
10862 		return false;
10863 	}
10864 
10865 	SiGetCurrentRegion(c, tmp, sizeof(tmp));
10866 
10867 	return (StrCmpi(r, tmp) == 0);
10868 }
10869 
10870 // Check whether some enterprise functions are restricted
10871 //
10872 // ** Hints by Daiyuu Nobori, written on March 19, 2014 **
10873 //
10874 // The following 'enterprise functions' are implemented on SoftEther VPN Server
10875 // since March 19, 2014. However, these functions are disabled on
10876 // SoftEther VPN Servers which run in Japan and China.
10877 //
10878 // - RADIUS / NT Domain user authentication
10879 // - RSA certificate authentication
10880 // - Deep-inspect packet logging
10881 // - Source IP address control list
10882 // - syslog transfer
10883 //
10884 // The SoftEther VPN Project intentionally disables these functions for users
10885 // in Japan and China. The reason is: Daiyuu Nobori, the chief author of
10886 // SoftEther VPN, has been liable to observe the existing agreements and
10887 // restrictions between him and some companies. The agreements have regulated
10888 // the region-limited restriction to implement and distribute the above
10889 // enterprise functions on the SoftEther VPN open-source program.
10890 //
10891 // Therefore, the SoftEther VPN Project distributes the binary program and
10892 // the source code with the "SiIsEnterpriseFunctionsRestrictedOnOpenSource"
10893 // function. This function identifies whether the SoftEther VPN Server
10894 // program is running in either Japan or China. If the restricted region is
10895 // detected, then the above enterprise functions will be disabled.
10896 //
10897 // Please note that the above restriction has been imposed only on the
10898 // original binaries and source codes from the SoftEther VPN Project.
10899 // Anyone, except Daiyuu Nobori, who understands and writes the C language
10900 // program can remove this restriction at his own risk.
10901 //
SiIsEnterpriseFunctionsRestrictedOnOpenSource(CEDAR * c)10902 bool SiIsEnterpriseFunctionsRestrictedOnOpenSource(CEDAR *c)
10903 {
10904 	return false;
10905 }
10906 
10907 // Update the current region
SiUpdateCurrentRegion(CEDAR * c,char * region,bool force_update)10908 void SiUpdateCurrentRegion(CEDAR *c, char *region, bool force_update)
10909 {
10910 	bool changed = false;
10911 	// Validate arguments
10912 	if (c == NULL)
10913 	{
10914 		return;
10915 	}
10916 
10917 	if (IsEmptyStr(region) == false)
10918 	{
10919 		Lock(c->CurrentRegionLock);
10920 		{
10921 			if (StrCmpi(c->CurrentRegion, region) != 0)
10922 			{
10923 				StrCpy(c->CurrentRegion, sizeof(c->CurrentRegion), region);
10924 				changed = true;
10925 			}
10926 		}
10927 		Unlock(c->CurrentRegionLock);
10928 	}
10929 
10930 	if (force_update)
10931 	{
10932 		changed = true;
10933 	}
10934 
10935 	if (changed)
10936 	{
10937 		FlushServerCaps(c->Server);
10938 	}
10939 }
10940 
10941 // Create a server
SiNewServer(bool bridge)10942 SERVER *SiNewServer(bool bridge)
10943 {
10944 	return SiNewServerEx(bridge, false, false);
10945 }
SiNewServerEx(bool bridge,bool in_client_inner_server,bool relay_server)10946 SERVER *SiNewServerEx(bool bridge, bool in_client_inner_server, bool relay_server)
10947 {
10948 	SERVER *s;
10949 	LISTENER *inproc;
10950 	LISTENER *azure;
10951 	LISTENER *rudp;
10952 
10953 	SetGetIpThreadMaxNum(DEFAULT_GETIP_THREAD_MAX_NUM);
10954 
10955 	s = ZeroMalloc(sizeof(SERVER));
10956 
10957 	SetEraserCheckInterval(0);
10958 
10959 	SiInitHubCreateHistory(s);
10960 
10961 	InitServerCapsCache(s);
10962 
10963 	Rand(s->MyRandomKey, sizeof(s->MyRandomKey));
10964 
10965 	s->lock = NewLock();
10966 
10967 
10968 	s->OpenVpnSstpConfigLock = NewLock();
10969 	s->SaveCfgLock = NewLock();
10970 	s->ref = NewRef();
10971 	s->Cedar = NewCedar(NULL, NULL);
10972 	s->Cedar->Server = s;
10973 
10974 
10975 #ifdef	OS_WIN32
10976 	s->IsInVm = MsIsInVm();
10977 #else	// OS_WIN32
10978 	s->IsInVm = UnixIsInVm();
10979 #endif	// OS_WIN32
10980 
10981 #ifdef	ENABLE_AZURE_SERVER
10982 	if (IsFileExists("@azureserver.config"))
10983 	{
10984 		DisableRDUPServerGlobally();
10985 		s->AzureServer = NewAzureServer(s->Cedar);
10986 
10987 		SleepThread(500);
10988 	}
10989 #endif	// ENABLE_AZURE_SERVER
10990 
10991 	s->Cedar->CheckExpires = true;
10992 	s->ServerListenerList = NewList(CompareServerListener);
10993 	s->StartTime = SystemTime64();
10994 	s->Syslog = NewSysLog(NULL, 0);
10995 	s->SyslogLock = NewLock();
10996 	s->TasksFromFarmControllerLock = NewLock();
10997 
10998 	if (bridge)
10999 	{
11000 		SetCedarVpnBridge(s->Cedar);
11001 	}
11002 
11003 #ifdef OS_WIN32
11004 	if (IsHamMode() == false)
11005 	{
11006 		RegistWindowsFirewallAll();
11007 	}
11008 #endif
11009 
11010 	s->Keep = StartKeep();
11011 
11012 	// Log related
11013 	MakeDir(bridge == false ? SERVER_LOG_DIR_NAME : BRIDGE_LOG_DIR_NAME);
11014 	s->Logger = NewLog(bridge == false ? SERVER_LOG_DIR_NAME : BRIDGE_LOG_DIR_NAME, SERVER_LOG_PERFIX, LOG_SWITCH_DAY);
11015 
11016 	SLog(s->Cedar, "L_LINE");
11017 	SLog(s->Cedar, "LS_START_2", s->Cedar->ServerStr, s->Cedar->VerString);
11018 	SLog(s->Cedar, "LS_START_3", s->Cedar->BuildInfo);
11019 	SLog(s->Cedar, "LS_START_UTF8");
11020 	SLog(s->Cedar, "LS_START_1");
11021 
11022 
11023 
11024 	// Initialize the configuration
11025 	SiInitConfiguration(s);
11026 
11027 	SetFifoCurrentReallocMemSize(MEM_FIFO_REALLOC_MEM_SIZE);
11028 
11029 
11030 	if (s->DisableIntelAesAcceleration)
11031 	{
11032 		// Disable the Intel AES acceleration
11033 		DisableIntelAesAccel();
11034 	}
11035 
11036 	// Raise the priority
11037 	if (s->NoHighPriorityProcess == false)
11038 	{
11039 		OSSetHighPriority();
11040 	}
11041 
11042 #ifdef	OS_UNIX
11043 	UnixSetHighOomScore();
11044 #endif	// OS_UNIX
11045 
11046 	if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
11047 	{
11048 		// Start a connection to the controller
11049 		s->FarmController = SiStartConnectToController(s);
11050 	}
11051 	else if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
11052 	{
11053 		FARM_MEMBER *f;
11054 		// Start operating as a controller
11055 		s->FarmMemberList = NewList(NULL);
11056 
11057 		f = ZeroMalloc(sizeof(FARM_MEMBER));
11058 		f->Cedar = s->Cedar;
11059 		GetMachineName(f->hostname, sizeof(f->hostname));
11060 		f->Me = true;
11061 		f->HubList = NewList(CompareHubList);
11062 		f->Weight = s->Weight;
11063 
11064 		s->Me = f;
11065 
11066 		Add(s->FarmMemberList, f);
11067 
11068 		SiStartFarmControl(s);
11069 
11070 		s->FarmControllerInited = true;
11071 	}
11072 
11073 	// Start a in-processlistener
11074 	inproc = NewListener(s->Cedar, LISTENER_INPROC, 0);
11075 	ReleaseListener(inproc);
11076 
11077 	// Start a listener for Azure
11078 	if (s->AzureClient != NULL)
11079 	{
11080 		azure = NewListener(s->Cedar, LISTENER_REVERSE, 0);
11081 		ReleaseListener(azure);
11082 	}
11083 
11084 	// Start a R-UDP listener
11085 	if (s->DisableNatTraversal == false && s->Cedar->Bridge == false)
11086 	{
11087 		rudp = NewListenerEx4(s->Cedar, LISTENER_RUDP, 0, TCPAcceptedThread, NULL, false, false,
11088 			&s->NatTGlobalUdpPort, RAND_PORT_ID_SERVER_LISTEN);
11089 		ReleaseListener(rudp);
11090 	}
11091 
11092 	// Start a VPN-over-ICMP listener
11093 	s->DynListenerIcmp = NewDynamicListener(s->Cedar, &s->EnableVpnOverIcmp, LISTENER_ICMP, 0);
11094 
11095 	// Start a VPN-over-DNS listener
11096 	s->DynListenerDns = NewDynamicListener(s->Cedar, &s->EnableVpnOverDns, LISTENER_DNS, 53);
11097 
11098 
11099 	SiInitDeadLockCheck(s);
11100 
11101 	SiUpdateCurrentRegion(s->Cedar, "", true);
11102 
11103 	return s;
11104 }
11105 
11106