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