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 // Cedar.c
103 // Cedar Communication Module
104 
105 
106 #include "CedarPch.h"
107 
108 static UINT init_cedar_counter = 0;
109 static REF *cedar_log_ref = NULL;
110 static LOG *cedar_log;
111 
112 // Check whether there is any EAP-enabled RADIUS configuration
CedarIsThereAnyEapEnabledRadiusConfig(CEDAR * c)113 bool CedarIsThereAnyEapEnabledRadiusConfig(CEDAR *c)
114 {
115 	bool ret = false;
116 	UINT i;
117 	if (c == NULL)
118 	{
119 		return false;
120 	}
121 
122 	LockHubList(c);
123 	{
124 		for (i = 0;i < LIST_NUM(c->HubList);i++)
125 		{
126 			HUB *hub = LIST_DATA(c->HubList, i);
127 
128 			if (hub->RadiusConvertAllMsChapv2AuthRequestToEap)
129 			{
130 				ret = true;
131 				break;
132 			}
133 		}
134 	}
135 	UnlockHubList(c);
136 
137 	return ret;
138 }
139 
140 // Get build date of current code
GetCurrentBuildDate()141 UINT64 GetCurrentBuildDate()
142 {
143 	SYSTEMTIME st;
144 
145 	Zero(&st, sizeof(st));
146 
147 	st.wYear = BUILD_DATE_Y;
148 	st.wMonth = BUILD_DATE_M;
149 	st.wDay = BUILD_DATE_D;
150 	st.wHour = BUILD_DATE_HO;
151 	st.wMinute = BUILD_DATE_MI;
152 	st.wSecond = BUILD_DATE_SE;
153 
154 	return SystemToUINT64(&st);
155 }
156 
157 // Check current windows version is supported
IsSupportedWinVer(RPC_WINVER * v)158 bool IsSupportedWinVer(RPC_WINVER *v)
159 {
160 	// Validate arguments
161 	if (v == NULL)
162 	{
163 		return false;
164 	}
165 
166 	if (v->IsWindows == false)
167 	{
168 		return true;
169 	}
170 
171 	if (v->IsNT == false)
172 	{
173 		return true;
174 	}
175 
176 	if (v->IsBeta)
177 	{
178 		return true;
179 	}
180 
181 	if (v->VerMajor <= 4)
182 	{
183 		// Windows NT
184 		return true;
185 	}
186 
187 	if (v->VerMajor == 5 && v->VerMinor == 0)
188 	{
189 		// Windows 2000
190 		if (v->ServicePack <= 4)
191 		{
192 			// SP4 or earlier
193 			return true;
194 		}
195 	}
196 
197 	if (v->VerMajor == 5 && v->VerMinor == 1)
198 	{
199 		// Windows XP x86
200 		if (v->ServicePack <= 3)
201 		{
202 			// SP3 or earlier
203 			return true;
204 		}
205 	}
206 
207 	if (v->VerMajor == 5 && v->VerMinor == 2)
208 	{
209 		// Windows XP x64, Windows Server 2003
210 		if (v->ServicePack <= 2)
211 		{
212 			// SP2 or earlier
213 			return true;
214 		}
215 	}
216 
217 	if (v->VerMajor == 6 && v->VerMinor == 0)
218 	{
219 		// Windows Vista, Server 2008
220 		if (v->ServicePack <= 2)
221 		{
222 			// SP2 or earlier
223 			return true;
224 		}
225 	}
226 
227 	if (v->VerMajor == 6 && v->VerMinor == 1)
228 	{
229 		// Windows 7, Server 2008 R2
230 		if (v->ServicePack <= 1)
231 		{
232 			// SP1 or earlier
233 			return true;
234 		}
235 	}
236 
237 	if (v->VerMajor == 6 && v->VerMinor == 2)
238 	{
239 		// Windows 8, Server 2012
240 		if (v->ServicePack <= 0)
241 		{
242 			// SP0 only
243 			return true;
244 		}
245 	}
246 
247 	if (v->VerMajor == 6 && v->VerMinor == 3)
248 	{
249 		// Windows 8.1, Server 2012 R2
250 		if (v->ServicePack <= 0)
251 		{
252 			// SP0 only
253 			return true;
254 		}
255 	}
256 
257 	if ((v->VerMajor == 6 && v->VerMinor == 4) || (v->VerMajor == 10 && v->VerMinor == 0))
258 	{
259 		if (v->IsServer == false)
260 		{
261 			// Windows 10 (not Windows Server 2016)
262 			if (v->ServicePack <= 0)
263 			{
264 				// SP0 only
265 				return true;
266 			}
267 		}
268 		else
269 		{
270 			// Windows Server 2016
271 			if (v->ServicePack <= 0)
272 			{
273 				// SP0 only
274 				return true;
275 			}
276 		}
277 	}
278 
279 	return false;
280 }
281 
282 // Get version of Windows
GetWinVer(RPC_WINVER * v)283 void GetWinVer(RPC_WINVER *v)
284 {
285 	// Validate arguments
286 	if (v == NULL)
287 	{
288 		return;
289 	}
290 
291 #ifdef	OS_WIN32
292 	Win32GetWinVer(v);
293 #else	// OS_WIN32
294 	Zero(v, sizeof(RPC_WINVER));
295 	StrCpy(v->Title, sizeof(v->Title), GetOsInfo()->OsProductName);
296 #endif	// OS_WIN32
297 }
298 
299 // Close tiny log
FreeTinyLog(TINY_LOG * t)300 void FreeTinyLog(TINY_LOG *t)
301 {
302 	// Validate arguments
303 	if (t == NULL)
304 	{
305 		return;
306 	}
307 
308 	FileClose(t->io);
309 	DeleteLock(t->Lock);
310 	Free(t);
311 }
312 
313 // Write to tiny log
WriteTinyLog(TINY_LOG * t,char * str)314 void WriteTinyLog(TINY_LOG *t, char *str)
315 {
316 	BUF *b;
317 	char dt[MAX_PATH];
318 	// Validate arguments
319 	if (t == NULL)
320 	{
321 		return;
322 	}
323 
324 	GetDateTimeStrMilli64(dt, sizeof(dt), LocalTime64());
325 	StrCat(dt, sizeof(dt), ": ");
326 
327 	b = NewBuf();
328 
329 	WriteBuf(b, dt, StrLen(dt));
330 	WriteBuf(b, str, StrLen(str));
331 	WriteBuf(b, "\r\n", 2);
332 
333 	Lock(t->Lock);
334 	{
335 		FileWrite(t->io, b->Buf, b->Size);
336 		//FileFlush(t->io);
337 	}
338 	Unlock(t->Lock);
339 
340 	FreeBuf(b);
341 }
342 
343 // Initialize tiny log
NewTinyLog()344 TINY_LOG *NewTinyLog()
345 {
346 	char name[MAX_PATH];
347 	SYSTEMTIME st;
348 	TINY_LOG *t;
349 
350 	LocalTime(&st);
351 
352 	MakeDir(TINY_LOG_DIRNAME);
353 
354 	Format(name, sizeof(name), TINY_LOG_FILENAME,
355 		st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
356 
357 	t = ZeroMalloc(sizeof(TINY_LOG));
358 
359 	StrCpy(t->FileName, sizeof(t->FileName), name);
360 	t->io = FileCreate(name);
361 	t->Lock = NewLock();
362 
363 	return t;
364 }
365 
366 // Compare entries of No-SSL connection list
CompareNoSslList(void * p1,void * p2)367 int CompareNoSslList(void *p1, void *p2)
368 {
369 	NON_SSL *n1, *n2;
370 	if (p1 == NULL || p2 == NULL)
371 	{
372 		return 0;
373 	}
374 	n1 = *(NON_SSL **)p1;
375 	n2 = *(NON_SSL **)p2;
376 	if (n1 == NULL || n2 == NULL)
377 	{
378 		return 0;
379 	}
380 	return CmpIpAddr(&n1->IpAddress, &n2->IpAddress);
381 }
382 
383 // Check whether the specified IP address is in Non-SSL connection list
IsInNoSsl(CEDAR * c,IP * ip)384 bool IsInNoSsl(CEDAR *c, IP *ip)
385 {
386 	bool ret = false;
387 	// Validate arguments
388 	if (c == NULL || ip == NULL)
389 	{
390 		return false;
391 	}
392 
393 	LockList(c->NonSslList);
394 	{
395 		NON_SSL *n = SearchNoSslList(c, ip);
396 
397 		if (n != NULL)
398 		{
399 			if (n->EntryExpires > Tick64() && n->Count > NON_SSL_MIN_COUNT)
400 			{
401 				n->EntryExpires = Tick64() + (UINT64)NON_SSL_ENTRY_EXPIRES;
402 				ret = true;
403 			}
404 		}
405 	}
406 	UnlockList(c->NonSslList);
407 
408 	return ret;
409 }
410 
411 // Decrement connection count of Non-SSL connection list entry
DecrementNoSsl(CEDAR * c,IP * ip,UINT num_dec)412 void DecrementNoSsl(CEDAR *c, IP *ip, UINT num_dec)
413 {
414 	// Validate arguments
415 	if (c == NULL || ip == NULL)
416 	{
417 		return;
418 	}
419 
420 	LockList(c->NonSslList);
421 	{
422 		NON_SSL *n = SearchNoSslList(c, ip);
423 
424 		if (n != NULL)
425 		{
426 			if (n->Count >= num_dec)
427 			{
428 				n->Count -= num_dec;
429 			}
430 		}
431 	}
432 	UnlockList(c->NonSslList);
433 }
434 
435 // Add new entry to Non-SSL connection list
AddNoSsl(CEDAR * c,IP * ip)436 bool AddNoSsl(CEDAR *c, IP *ip)
437 {
438 	NON_SSL *n;
439 	bool ret = true;
440 	// Validate arguments
441 	if (c == NULL || ip == NULL)
442 	{
443 		return true;
444 	}
445 
446 	LockList(c->NonSslList);
447 	{
448 		DeleteOldNoSsl(c);
449 
450 		n = SearchNoSslList(c, ip);
451 
452 		if (n == NULL)
453 		{
454 			n = ZeroMalloc(sizeof(NON_SSL));
455 			Copy(&n->IpAddress, ip, sizeof(IP));
456 			n->Count = 0;
457 
458 			Add(c->NonSslList, n);
459 		}
460 
461 		n->EntryExpires = Tick64() + (UINT64)NON_SSL_ENTRY_EXPIRES;
462 
463 		n->Count++;
464 
465 		if (n->Count > NON_SSL_MIN_COUNT)
466 		{
467 			ret = false;
468 		}
469 	}
470 	UnlockList(c->NonSslList);
471 
472 	return ret;
473 }
474 
475 // Delete old entries in Non-SSL connection list
DeleteOldNoSsl(CEDAR * c)476 void DeleteOldNoSsl(CEDAR *c)
477 {
478 	UINT i;
479 	LIST *o;
480 	// Validate arguments
481 	if (c == NULL)
482 	{
483 		return;
484 	}
485 
486 	o = NewListFast(NULL);
487 
488 	for (i = 0;i < LIST_NUM(c->NonSslList);i++)
489 	{
490 		NON_SSL *n = LIST_DATA(c->NonSslList, i);
491 
492 		if (n->EntryExpires <= Tick64())
493 		{
494 			Add(o, n);
495 		}
496 	}
497 
498 	for (i = 0;i < LIST_NUM(o);i++)
499 	{
500 		NON_SSL *n = LIST_DATA(o, i);
501 
502 		Delete(c->NonSslList, n);
503 		Free(n);
504 	}
505 
506 	ReleaseList(o);
507 }
508 
509 // Search entry in Non-SSL connection list
SearchNoSslList(CEDAR * c,IP * ip)510 NON_SSL *SearchNoSslList(CEDAR *c, IP *ip)
511 {
512 	NON_SSL *n, t;
513 	// Validate arguments
514 	if (c == NULL || ip == NULL)
515 	{
516 		return NULL;
517 	}
518 
519 	Zero(&t, sizeof(t));
520 	Copy(&t.IpAddress, ip, sizeof(IP));
521 
522 	n = Search(c->NonSslList, &t);
523 
524 	if (n == NULL)
525 	{
526 		return NULL;
527 	}
528 
529 	return n;
530 }
531 
532 // Initialize Non-SSL connection list
InitNoSslList(CEDAR * c)533 void InitNoSslList(CEDAR *c)
534 {
535 	// Validate arguments
536 	if (c == NULL)
537 	{
538 		return;
539 	}
540 
541 	c->NonSslList = NewList(CompareNoSslList);
542 }
543 
544 // Free Non-SSL connection list
FreeNoSslList(CEDAR * c)545 void FreeNoSslList(CEDAR *c)
546 {
547 	UINT i;
548 	// Validate arguments
549 	if (c == NULL)
550 	{
551 		return;
552 	}
553 
554 	for (i = 0;i < LIST_NUM(c->NonSslList);i++)
555 	{
556 		NON_SSL *n = LIST_DATA(c->NonSslList, i);
557 
558 		Free(n);
559 	}
560 
561 	ReleaseList(c->NonSslList);
562 	c->NonSslList = NULL;
563 }
564 
565 // Write a message into Cedar log
CedarLog(char * str)566 void CedarLog(char *str)
567 {
568 	char *tmp;
569 	// Validate arguments
570 	if (str == NULL)
571 	{
572 		return;
573 	}
574 	if (cedar_log_ref == NULL)
575 	{
576 		return;
577 	}
578 
579 	tmp = CopyStr(str);
580 
581 	if (StrLen(tmp) > 1)
582 	{
583 		if (tmp[StrLen(tmp) - 1] == '\n')
584 		{
585 			tmp[StrLen(tmp) - 1] = 0;
586 		}
587 		if (StrLen(tmp) > 1)
588 		{
589 			if (tmp[StrLen(tmp) - 1] == '\r')
590 			{
591 				tmp[StrLen(tmp) - 1] = 0;
592 			}
593 		}
594 	}
595 
596 	InsertStringRecord(cedar_log, tmp);
597 
598 	Free(tmp);
599 }
600 
601 // Start Cedar log
StartCedarLog()602 void StartCedarLog()
603 {
604 	if (cedar_log_ref == NULL)
605 	{
606 		cedar_log_ref = NewRef();
607 	}
608 	else
609 	{
610 		AddRef(cedar_log_ref);
611 	}
612 
613 	cedar_log = NewLog("debug_log", "debug", LOG_SWITCH_DAY);
614 }
615 
616 // Stop Cedar log
StopCedarLog()617 void StopCedarLog()
618 {
619 	if (cedar_log_ref == NULL)
620 	{
621 		return;
622 	}
623 
624 	if (Release(cedar_log_ref) == 0)
625 	{
626 		FreeLog(cedar_log);
627 		cedar_log = NULL;
628 		cedar_log_ref = NULL;
629 	}
630 }
631 
632 
633 // Get sum of traffic data size
GetTrafficPacketSize(TRAFFIC * t)634 UINT64 GetTrafficPacketSize(TRAFFIC *t)
635 {
636 	// Validate arguments
637 	if (t == NULL)
638 	{
639 		return 0;
640 	}
641 
642 	return t->Recv.BroadcastBytes + t->Recv.UnicastBytes +
643 		t->Send.BroadcastBytes + t->Send.UnicastBytes;
644 }
645 
646 // Get sum of the number of packets in traffic
GetTrafficPacketNum(TRAFFIC * t)647 UINT64 GetTrafficPacketNum(TRAFFIC *t)
648 {
649 	// Validate arguments
650 	if (t == NULL)
651 	{
652 		return 0;
653 	}
654 
655 	return t->Recv.BroadcastCount + t->Recv.UnicastCount +
656 		t->Send.BroadcastCount + t->Send.UnicastCount;
657 }
658 
659 // Get whether hidden password is changed in UI
IsHiddenPasswordChanged(char * str)660 bool IsHiddenPasswordChanged(char *str)
661 {
662 	// Validate arguments
663 	if (str == NULL)
664 	{
665 		return true;
666 	}
667 
668 	if (StrCmpi(str, HIDDEN_PASSWORD) == 0)
669 	{
670 		return true;
671 	}
672 	else
673 	{
674 		return false;
675 	}
676 }
677 
678 // Initialize hidden password in UI
InitHiddenPassword(char * str,UINT size)679 void InitHiddenPassword(char *str, UINT size)
680 {
681 	// Validate arguments
682 	if (str == NULL)
683 	{
684 		return;
685 	}
686 
687 	StrCpy(str, size, HIDDEN_PASSWORD);
688 }
689 
690 // Check whether the certificate is signed by CA which is trusted by the hub
CheckSignatureByCaLinkMode(SESSION * s,X * x)691 bool CheckSignatureByCaLinkMode(SESSION *s, X *x)
692 {
693 	LINK *k;
694 	HUB *h;
695 	bool ret = false;
696 	// Validate arguments
697 	if (s == NULL || x == NULL)
698 	{
699 		return false;
700 	}
701 
702 	if (s->LinkModeClient == false || (k = s->Link) == NULL)
703 	{
704 		return false;
705 	}
706 
707 	h = k->Hub;
708 
709 	if (h->HubDb != NULL)
710 	{
711 		LockList(h->HubDb->RootCertList);
712 		{
713 			X *root_cert;
714 			root_cert = GetIssuerFromList(h->HubDb->RootCertList, x);
715 			if (root_cert != NULL)
716 			{
717 				ret = true;
718 			}
719 		}
720 		UnlockList(h->HubDb->RootCertList);
721 	}
722 
723 	return ret;
724 }
725 
726 // Check whether the certificate is signed by CA which is trusted by Cedar
CheckSignatureByCa(CEDAR * cedar,X * x)727 bool CheckSignatureByCa(CEDAR *cedar, X *x)
728 {
729 	X *ca;
730 	// Validate arguments
731 	if (cedar == NULL || x == NULL)
732 	{
733 		return false;
734 	}
735 
736 	// Get the CA which signed the certificate
737 	ca = FindCaSignedX(cedar->CaList, x);
738 	if (ca == NULL)
739 	{
740 		// Not found
741 		return false;
742 	}
743 
744 	// Found
745 	FreeX(ca);
746 	return true;
747 }
748 
749 // Get the CA which signed the certificate
FindCaSignedX(LIST * o,X * x)750 X *FindCaSignedX(LIST *o, X *x)
751 {
752 	X *ret;
753 	// Validate arguments
754 	if (o == NULL || x == NULL)
755 	{
756 		return NULL;
757 	}
758 
759 	ret = NULL;
760 
761 	LockList(o);
762 	{
763 		UINT i;
764 		for (i = 0;i < LIST_NUM(o);i++)
765 		{
766 			X *ca = LIST_DATA(o, i);
767 			if (CheckXDateNow(ca))
768 			{
769 				if (CompareName(ca->subject_name, x->issuer_name))
770 				{
771 					K *k = GetKFromX(ca);
772 					if (k != NULL)
773 					{
774 						if (CheckSignature(x, k))
775 						{
776 							ret = CloneX(ca);
777 						}
778 						FreeK(k);
779 					}
780 				}
781 				else if (CompareX(ca, x))
782 				{
783 					ret = CloneX(ca);
784 				}
785 			}
786 
787 			if (ret != NULL)
788 			{
789 				break;
790 			}
791 		}
792 	}
793 	UnlockList(o);
794 
795 	return ret;
796 }
797 
798 // Delete trusted CA from Cedar
DeleteCa(CEDAR * cedar,UINT ptr)799 bool DeleteCa(CEDAR *cedar, UINT ptr)
800 {
801 	bool b = false;
802 	// Validate arguments
803 	if (cedar == NULL || ptr == 0)
804 	{
805 		return false;
806 	}
807 
808 	LockList(cedar->CaList);
809 	{
810 		UINT i;
811 
812 		for (i = 0;i < LIST_NUM(cedar->CaList);i++)
813 		{
814 			X *x = LIST_DATA(cedar->CaList, i);
815 
816 			if (POINTER_TO_KEY(x) == ptr)
817 			{
818 				Delete(cedar->CaList, x);
819 				FreeX(x);
820 
821 				b = true;
822 
823 				break;
824 			}
825 		}
826 	}
827 	UnlockList(cedar->CaList);
828 
829 	return b;
830 }
831 
832 // Add trusted CA to Cedar
AddCa(CEDAR * cedar,X * x)833 void AddCa(CEDAR *cedar, X *x)
834 {
835 	// Validate arguments
836 	if (cedar == NULL || x == NULL)
837 	{
838 		return;
839 	}
840 
841 	LockList(cedar->CaList);
842 	{
843 		UINT i;
844 		bool ok = true;
845 
846 		for (i = 0;i < LIST_NUM(cedar->CaList);i++)
847 		{
848 			X *exist_x = LIST_DATA(cedar->CaList, i);
849 			if (CompareX(exist_x, x))
850 			{
851 				ok = false;
852 				break;
853 			}
854 		}
855 
856 		if (ok)
857 		{
858 			Insert(cedar->CaList, CloneX(x));
859 		}
860 	}
861 	UnlockList(cedar->CaList);
862 }
863 
864 // Delete connection from Cedar
DelConnection(CEDAR * cedar,CONNECTION * c)865 void DelConnection(CEDAR *cedar, CONNECTION *c)
866 {
867 	// Validate arguments
868 	if (cedar == NULL || c == NULL)
869 	{
870 		return;
871 	}
872 
873 	LockList(cedar->ConnectionList);
874 	{
875 		Debug("Connection %s Deleted from Cedar.\n", c->Name);
876 		if (Delete(cedar->ConnectionList, c))
877 		{
878 			ReleaseConnection(c);
879 		}
880 	}
881 	UnlockList(cedar->ConnectionList);
882 }
883 
884 // Get the number of unestablished connections
GetUnestablishedConnections(CEDAR * cedar)885 UINT GetUnestablishedConnections(CEDAR *cedar)
886 {
887 	UINT i, ret;
888 	// Validate arguments
889 	if (cedar == NULL)
890 	{
891 		return 0;
892 	}
893 
894 	ret = 0;
895 
896 	LockList(cedar->ConnectionList);
897 	{
898 		for (i = 0;i < LIST_NUM(cedar->ConnectionList);i++)
899 		{
900 			CONNECTION *c = LIST_DATA(cedar->ConnectionList, i);
901 
902 			switch (c->Type)
903 			{
904 			case CONNECTION_TYPE_CLIENT:
905 			case CONNECTION_TYPE_INIT:
906 			case CONNECTION_TYPE_LOGIN:
907 			case CONNECTION_TYPE_ADDITIONAL:
908 				switch (c->Status)
909 				{
910 				case CONNECTION_STATUS_ACCEPTED:
911 				case CONNECTION_STATUS_NEGOTIATION:
912 				case CONNECTION_STATUS_USERAUTH:
913 					ret++;
914 					break;
915 				}
916 				break;
917 			}
918 		}
919 	}
920 	UnlockList(cedar->ConnectionList);
921 
922 	return ret + Count(cedar->AcceptingSockets);
923 }
924 
925 // Add connection to Cedar
AddConnection(CEDAR * cedar,CONNECTION * c)926 void AddConnection(CEDAR *cedar, CONNECTION *c)
927 {
928 	char tmp[MAX_SIZE];
929 	UINT i;
930 	// Validate arguments
931 	if (cedar == NULL || c == NULL)
932 	{
933 		return;
934 	}
935 
936 	// Determine the name of the connection
937 	i = Inc(cedar->ConnectionIncrement);
938 	Format(tmp, sizeof(tmp), "CID-%u", i);
939 
940 
941 	Lock(c->lock);
942 	{
943 		Free(c->Name);
944 		c->Name = CopyStr(tmp);
945 	}
946 	Unlock(c->lock);
947 
948 	LockList(cedar->ConnectionList);
949 	{
950 		Add(cedar->ConnectionList, c);
951 		AddRef(c->ref);
952 		Debug("Connection %s Inserted to Cedar.\n", c->Name);
953 	}
954 	UnlockList(cedar->ConnectionList);
955 }
956 
957 // Stop all connections
StopAllConnection(CEDAR * c)958 void StopAllConnection(CEDAR *c)
959 {
960 	UINT num;
961 	UINT i;
962 	CONNECTION **connections;
963 	// Validate arguments
964 	if (c == NULL)
965 	{
966 		return;
967 	}
968 
969 	LockList(c->ConnectionList);
970 	{
971 		connections = ToArray(c->ConnectionList);
972 		num = LIST_NUM(c->ConnectionList);
973 		DeleteAll(c->ConnectionList);
974 	}
975 	UnlockList(c->ConnectionList);
976 
977 	for (i = 0;i < num;i++)
978 	{
979 		StopConnection(connections[i], false);
980 		ReleaseConnection(connections[i]);
981 	}
982 	Free(connections);
983 }
984 
985 // Delete a hub in Cedar
DelHub(CEDAR * c,HUB * h)986 void DelHub(CEDAR *c, HUB *h)
987 {
988 	DelHubEx(c, h, false);
989 }
DelHubEx(CEDAR * c,HUB * h,bool no_lock)990 void DelHubEx(CEDAR *c, HUB *h, bool no_lock)
991 {
992 	// Validate arguments
993 	if (c == NULL || h == NULL)
994 	{
995 		return;
996 	}
997 
998 	if (no_lock == false)
999 	{
1000 		LockHubList(c);
1001 	}
1002 
1003 	if (Delete(c->HubList, h))
1004 	{
1005 		ReleaseHub(h);
1006 	}
1007 
1008 	if (no_lock == false)
1009 	{
1010 		UnlockHubList(c);
1011 	}
1012 }
1013 
1014 // Add a new hub to Cedar
AddHub(CEDAR * c,HUB * h)1015 void AddHub(CEDAR *c, HUB *h)
1016 {
1017 	// Validate arguments
1018 	if (c == NULL || h == NULL)
1019 	{
1020 		return;
1021 	}
1022 
1023 	LockHubList(c);
1024 	{
1025 #if	0
1026 		// We shall not check here the number of hub
1027 		if (LIST_NUM(c->HubList) >= MAX_HUBS)
1028 		{
1029 			// over limit
1030 			UnlockHubList(c);
1031 			return;
1032 		}
1033 #endif
1034 
1035 		// Confirm there is no hub which have same name
1036 		if (IsHub(c, h->Name))
1037 		{
1038 			// exist
1039 			UnlockHubList(c);
1040 			return;
1041 		}
1042 
1043 		// Register the hub
1044 		Insert(c->HubList, h);
1045 		AddRef(h->ref);
1046 	}
1047 	UnlockHubList(c);
1048 }
1049 
1050 // Stop all hubs in Cedar
StopAllHub(CEDAR * c)1051 void StopAllHub(CEDAR *c)
1052 {
1053 	HUB **hubs;
1054 	UINT i, num;
1055 	// Validate arguments
1056 	if (c == NULL)
1057 	{
1058 		return;
1059 	}
1060 
1061 	LockHubList(c);
1062 	{
1063 		hubs = ToArray(c->HubList);
1064 		num = LIST_NUM(c->HubList);
1065 		DeleteAll(c->HubList);
1066 	}
1067 	UnlockHubList(c);
1068 
1069 	for (i = 0;i < num;i++)
1070 	{
1071 		StopHub(hubs[i]);
1072 		ReleaseHub(hubs[i]);
1073 	}
1074 
1075 	Free(hubs);
1076 }
1077 
1078 // Get reverse listener socket in Cedar
GetReverseListeningSock(CEDAR * c)1079 SOCK *GetReverseListeningSock(CEDAR *c)
1080 {
1081 	SOCK *s = NULL;
1082 	// Validate arguments
1083 	if (c == NULL)
1084 	{
1085 		return NULL;
1086 	}
1087 
1088 	LockList(c->ListenerList);
1089 	{
1090 		UINT i;
1091 		for (i = 0;i < LIST_NUM(c->ListenerList);i++)
1092 		{
1093 			LISTENER *r = LIST_DATA(c->ListenerList, i);
1094 
1095 			if (r->Protocol == LISTENER_REVERSE)
1096 			{
1097 				Lock(r->lock);
1098 				{
1099 					s = r->Sock;
1100 
1101 					AddRef(s->ref);
1102 				}
1103 				Unlock(r->lock);
1104 				break;
1105 			}
1106 		}
1107 	}
1108 	UnlockList(c->ListenerList);
1109 
1110 	return s;
1111 }
1112 
1113 // Get in-process listener socket in Cedar
GetInProcListeningSock(CEDAR * c)1114 SOCK *GetInProcListeningSock(CEDAR *c)
1115 {
1116 	SOCK *s = NULL;
1117 	// Validate arguments
1118 	if (c == NULL)
1119 	{
1120 		return NULL;
1121 	}
1122 
1123 	LockList(c->ListenerList);
1124 	{
1125 		UINT i;
1126 		for (i = 0;i < LIST_NUM(c->ListenerList);i++)
1127 		{
1128 			LISTENER *r = LIST_DATA(c->ListenerList, i);
1129 
1130 			if (r->Protocol == LISTENER_INPROC)
1131 			{
1132 				Lock(r->lock);
1133 				{
1134 					s = r->Sock;
1135 
1136 					if (s != NULL)
1137 					{
1138 						AddRef(s->ref);
1139 					}
1140 				}
1141 				Unlock(r->lock);
1142 				break;
1143 			}
1144 		}
1145 	}
1146 	UnlockList(c->ListenerList);
1147 
1148 	return s;
1149 }
1150 
1151 // Add a new listener to Cedar
AddListener(CEDAR * c,LISTENER * r)1152 void AddListener(CEDAR *c, LISTENER *r)
1153 {
1154 	// Validate arguments
1155 	if (c == NULL || r == NULL)
1156 	{
1157 		return;
1158 	}
1159 
1160 	LockList(c->ListenerList);
1161 	{
1162 		Add(c->ListenerList, r);
1163 		AddRef(r->ref);
1164 	}
1165 	UnlockList(c->ListenerList);
1166 }
1167 
1168 // Stop all listener in Cedar
StopAllListener(CEDAR * c)1169 void StopAllListener(CEDAR *c)
1170 {
1171 	LISTENER **array;
1172 	UINT i, num;
1173 	// Validate arguments
1174 	if (c == NULL)
1175 	{
1176 		return;
1177 	}
1178 
1179 	LockList(c->ListenerList);
1180 	{
1181 		array = ToArray(c->ListenerList);
1182 		num = LIST_NUM(c->ListenerList);
1183 		DeleteAll(c->ListenerList);
1184 	}
1185 	UnlockList(c->ListenerList);
1186 
1187 	for (i = 0;i < num;i++)
1188 	{
1189 		StopListener(array[i]);
1190 		ReleaseListener(array[i]);
1191 	}
1192 	Free(array);
1193 }
1194 
1195 // Budget management functions
CedarAddQueueBudget(CEDAR * c,int diff)1196 void CedarAddQueueBudget(CEDAR *c, int diff)
1197 {
1198 	// Validate arguments
1199 	if (c == NULL || diff == 0)
1200 	{
1201 		return;
1202 	}
1203 
1204 	Lock(c->QueueBudgetLock);
1205 	{
1206 		int v = (int)c->QueueBudget;
1207 		v += diff;
1208 		c->QueueBudget = (UINT)v;
1209 	}
1210 	Unlock(c->QueueBudgetLock);
1211 }
CedarAddFifoBudget(CEDAR * c,int diff)1212 void CedarAddFifoBudget(CEDAR *c, int diff)
1213 {
1214 	// Validate arguments
1215 	if (c == NULL || diff == 0)
1216 	{
1217 		return;
1218 	}
1219 
1220 	Lock(c->FifoBudgetLock);
1221 	{
1222 		int v = (int)c->FifoBudget;
1223 		v += diff;
1224 		c->FifoBudget = (UINT)v;
1225 	}
1226 	Unlock(c->FifoBudgetLock);
1227 }
CedarGetQueueBudgetConsuming(CEDAR * c)1228 UINT CedarGetQueueBudgetConsuming(CEDAR *c)
1229 {
1230 	// Validate arguments
1231 	if (c == NULL)
1232 	{
1233 		return 0;
1234 	}
1235 
1236 	return c->QueueBudget;
1237 }
CedarGetFifoBudgetConsuming(CEDAR * c)1238 UINT CedarGetFifoBudgetConsuming(CEDAR *c)
1239 {
1240 	// Validate arguments
1241 	if (c == NULL)
1242 	{
1243 		return 0;
1244 	}
1245 
1246 	return c->FifoBudget;
1247 }
CedarGetQueueBudgetBalance(CEDAR * c)1248 UINT CedarGetQueueBudgetBalance(CEDAR *c)
1249 {
1250 	UINT current = CedarGetQueueBudgetConsuming(c);
1251 	UINT budget = QUEUE_BUDGET;
1252 
1253 	if (current <= budget)
1254 	{
1255 		return budget - current;
1256 	}
1257 	else
1258 	{
1259 		return 0;
1260 	}
1261 }
CedarGetFifoBudgetBalance(CEDAR * c)1262 UINT CedarGetFifoBudgetBalance(CEDAR *c)
1263 {
1264 	UINT current = CedarGetFifoBudgetConsuming(c);
1265 	UINT budget = FIFO_BUDGET;
1266 
1267 	if (current <= budget)
1268 	{
1269 		return budget - current;
1270 	}
1271 	else
1272 	{
1273 		return 0;
1274 	}
1275 }
1276 
1277 // Add the current TCP queue size
CedarAddCurrentTcpQueueSize(CEDAR * c,int diff)1278 void CedarAddCurrentTcpQueueSize(CEDAR *c, int diff)
1279 {
1280 	// Validate arguments
1281 	if (c == NULL || diff == 0)
1282 	{
1283 		return;
1284 	}
1285 
1286 	Lock(c->CurrentTcpQueueSizeLock);
1287 	{
1288 		int v = (int)c->CurrentTcpQueueSize;
1289 		v += diff;
1290 		c->CurrentTcpQueueSize = (UINT)v;
1291 	}
1292 	Unlock(c->CurrentTcpQueueSizeLock);
1293 }
1294 
1295 // Get the current TCP queue size
CedarGetCurrentTcpQueueSize(CEDAR * c)1296 UINT CedarGetCurrentTcpQueueSize(CEDAR *c)
1297 {
1298 	// Validate arguments
1299 	if (c == NULL)
1300 	{
1301 		return 0;
1302 	}
1303 
1304 	return c->CurrentTcpQueueSize;
1305 }
1306 
1307 // Stop Cedar
StopCedar(CEDAR * c)1308 void StopCedar(CEDAR *c)
1309 {
1310 	// Validate arguments
1311 	if (c == NULL)
1312 	{
1313 		return;
1314 	}
1315 
1316 	// Stop flag
1317 	c->Halt = true;
1318 
1319 	// Stop all listener
1320 	StopAllListener(c);
1321 	// Stop all connections
1322 	StopAllConnection(c);
1323 	// Stop all hubs
1324 	StopAllHub(c);
1325 	// Free all virtual L3 switch
1326 	L3FreeAllSw(c);
1327 }
1328 
1329 // Clean up Cedar
CleanupCedar(CEDAR * c)1330 void CleanupCedar(CEDAR *c)
1331 {
1332 	UINT i;
1333 	// Validate arguments
1334 	if (c == NULL)
1335 	{
1336 		return;
1337 	}
1338 
1339 	WuFreeWebUI(c->WebUI);
1340 	FreeCedarLayer3(c);
1341 
1342 /*
1343 	for (i = 0;i < LIST_NUM(c->HubList);i++)
1344 	{
1345 		HUB *h = LIST_DATA(c->HubList, i);
1346 	}
1347 */
1348 	for (i = 0;i < LIST_NUM(c->CaList);i++)
1349 	{
1350 		X *x = LIST_DATA(c->CaList, i);
1351 		FreeX(x);
1352 	}
1353 	ReleaseList(c->CaList);
1354 
1355 	ReleaseList(c->ListenerList);
1356 	ReleaseList(c->HubList);
1357 	ReleaseList(c->ConnectionList);
1358 	//CleanupUDPEntry(c);
1359 	ReleaseList(c->UDPEntryList);
1360 	DeleteLock(c->lock);
1361 	DeleteCounter(c->ConnectionIncrement);
1362 	DeleteCounter(c->CurrentSessions);
1363 
1364 	if (c->DebugLog != NULL)
1365 	{
1366 		FreeLog(c->DebugLog);
1367 	}
1368 
1369 	if (c->ServerX)
1370 	{
1371 		FreeX(c->ServerX);
1372 	}
1373 	if (c->ServerK)
1374 	{
1375 		FreeK(c->ServerK);
1376 	}
1377 
1378 	if (c->CipherList)
1379 	{
1380 		Free(c->CipherList);
1381 	}
1382 
1383 	for (i = 0;i < LIST_NUM(c->TrafficDiffList);i++)
1384 	{
1385 		TRAFFIC_DIFF *d = LIST_DATA(c->TrafficDiffList, i);
1386 		Free(d->Name);
1387 		Free(d->HubName);
1388 		Free(d);
1389 	}
1390 
1391 	ReleaseList(c->TrafficDiffList);
1392 
1393 	Free(c->ServerStr);
1394 	Free(c->MachineName);
1395 
1396 	Free(c->HttpUserAgent);
1397 	Free(c->HttpAccept);
1398 	Free(c->HttpAcceptLanguage);
1399 	Free(c->HttpAcceptEncoding);
1400 
1401 	FreeTraffic(c->Traffic);
1402 
1403 	DeleteLock(c->TrafficLock);
1404 
1405 	FreeNetSvcList(c);
1406 
1407 	Free(c->VerString);
1408 	Free(c->BuildInfo);
1409 
1410 	FreeLocalBridgeList(c);
1411 
1412 	DeleteCounter(c->AssignedBridgeLicense);
1413 	DeleteCounter(c->AssignedClientLicense);
1414 
1415 	FreeNoSslList(c);
1416 
1417 	DeleteLock(c->CedarSuperLock);
1418 
1419 	DeleteCounter(c->AcceptingSockets);
1420 
1421 	ReleaseIntList(c->UdpPortList);
1422 
1423 	DeleteLock(c->OpenVPNPublicPortsLock);
1424 
1425 	DeleteLock(c->CurrentRegionLock);
1426 
1427 	DeleteLock(c->CurrentTcpQueueSizeLock);
1428 	DeleteLock(c->QueueBudgetLock);
1429 	DeleteLock(c->FifoBudgetLock);
1430 
1431 	DeleteCounter(c->CurrentActiveLinks);
1432 
1433 	Free(c);
1434 }
1435 
1436 // Release reference of the Cedar
ReleaseCedar(CEDAR * c)1437 void ReleaseCedar(CEDAR *c)
1438 {
1439 	// Validate arguments
1440 	if (c == NULL)
1441 	{
1442 		return;
1443 	}
1444 
1445 	if (Release(c->ref) == 0)
1446 	{
1447 		CleanupCedar(c);
1448 	}
1449 }
1450 
1451 // Set cipher list entry
SetCedarCipherList(CEDAR * cedar,char * name)1452 void SetCedarCipherList(CEDAR *cedar, char *name)
1453 {
1454 	// Validate arguments
1455 	if (cedar == NULL)
1456 	{
1457 		return;
1458 	}
1459 
1460 	if (cedar->CipherList != NULL)
1461 	{
1462 		Free(cedar->CipherList);
1463 	}
1464 	if (name != NULL)
1465 	{
1466 		cedar->CipherList = CopyStr(name);
1467 	}
1468 	else
1469 	{
1470 		cedar->CipherList = NULL;
1471 	}
1472 }
1473 
1474 // Compare net service list entries
CompareNetSvc(void * p1,void * p2)1475 int CompareNetSvc(void *p1, void *p2)
1476 {
1477 	NETSVC *n1, *n2;
1478 	if (p1 == NULL || p2 == NULL)
1479 	{
1480 		return 0;
1481 	}
1482 	n1 = *(NETSVC **)p1;
1483 	n2 = *(NETSVC **)p2;
1484 	if (n1 == NULL || n2 == NULL)
1485 	{
1486 		return 0;
1487 	}
1488 	if (n1->Port > n2->Port)
1489 	{
1490 		return 1;
1491 	}
1492 	else if (n1->Port < n2->Port)
1493 	{
1494 		return -1;
1495 	}
1496 	else if (n1->Udp > n2->Udp)
1497 	{
1498 		return 1;
1499 	}
1500 	else if (n1->Udp < n2->Udp)
1501 	{
1502 		return -1;
1503 	}
1504 	return 0;
1505 }
1506 
1507 // Initialize net service list
InitNetSvcList(CEDAR * cedar)1508 void InitNetSvcList(CEDAR *cedar)
1509 {
1510 	char filename[MAX_PATH] = "/etc/services";
1511 	BUF *b;
1512 	// Validate arguments
1513 	if (cedar == NULL)
1514 	{
1515 		return;
1516 	}
1517 
1518 #ifdef	OS_WIN32
1519 	Format(filename, sizeof(filename), "%s\\drivers\\etc\\services", MsGetSystem32Dir());
1520 #endif
1521 
1522 	cedar->NetSvcList = NewList(CompareNetSvc);
1523 
1524 	b = ReadDump(filename);
1525 	if (b == NULL)
1526 	{
1527 		return;
1528 	}
1529 
1530 	while (true)
1531 	{
1532 		char *s = CfgReadNextLine(b);
1533 		if (s == NULL)
1534 		{
1535 			break;
1536 		}
1537 
1538 		Trim(s);
1539 		if (s[0] != '#')
1540 		{
1541 			TOKEN_LIST *t = ParseToken(s, " \t/");
1542 			if (t->NumTokens >= 3)
1543 			{
1544 				NETSVC *n = ZeroMalloc(sizeof(NETSVC));
1545 				n->Name = CopyStr(t->Token[0]);
1546 				n->Udp = (StrCmpi(t->Token[2], "udp") == 0 ? true : false);
1547 				n->Port = ToInt(t->Token[1]);
1548 				Add(cedar->NetSvcList, n);
1549 			}
1550 			FreeToken(t);
1551 		}
1552 		Free(s);
1553 	}
1554 
1555 	FreeBuf(b);
1556 }
1557 
1558 // Get net service name
GetSvcName(CEDAR * cedar,bool udp,UINT port)1559 char *GetSvcName(CEDAR *cedar, bool udp, UINT port)
1560 {
1561 	char *ret = NULL;
1562 	NETSVC t;
1563 	// Validate arguments
1564 	if (cedar == NULL)
1565 	{
1566 		return NULL;
1567 	}
1568 
1569 	t.Udp = (udp == 0 ? false : true);
1570 	t.Port = port;
1571 
1572 	LockList(cedar->NetSvcList);
1573 	{
1574 		NETSVC *n = Search(cedar->NetSvcList, &t);
1575 		if (n != NULL)
1576 		{
1577 			ret = n->Name;
1578 		}
1579 	}
1580 	UnlockList(cedar->NetSvcList);
1581 
1582 	return ret;
1583 }
1584 
1585 // Free net service list
FreeNetSvcList(CEDAR * cedar)1586 void FreeNetSvcList(CEDAR *cedar)
1587 {
1588 	UINT i;
1589 	// Validate arguments
1590 	if (cedar == NULL)
1591 	{
1592 		return;
1593 	}
1594 
1595 	for (i = 0;i < LIST_NUM(cedar->NetSvcList);i++)
1596 	{
1597 		NETSVC *n = LIST_DATA(cedar->NetSvcList, i);
1598 		Free(n->Name);
1599 		Free(n);
1600 	}
1601 	ReleaseList(cedar->NetSvcList);
1602 }
1603 
1604 // Change certificate of Cedar
SetCedarCert(CEDAR * c,X * server_x,K * server_k)1605 void SetCedarCert(CEDAR *c, X *server_x, K *server_k)
1606 {
1607 	// Validate arguments
1608 	if (server_x == NULL || server_k == NULL)
1609 	{
1610 		return;
1611 	}
1612 
1613 	Lock(c->lock);
1614 	{
1615 		if (c->ServerX != NULL)
1616 		{
1617 			FreeX(c->ServerX);
1618 		}
1619 
1620 		if (c->ServerK != NULL)
1621 		{
1622 			FreeK(c->ServerK);
1623 		}
1624 
1625 		c->ServerX = CloneX(server_x);
1626 		c->ServerK = CloneK(server_k);
1627 	}
1628 	Unlock(c->lock);
1629 }
1630 
1631 // Enable debug log
EnableDebugLog(CEDAR * c)1632 void EnableDebugLog(CEDAR *c)
1633 {
1634 	// Validate arguments
1635 	if (c == NULL || c->DebugLog != NULL)
1636 	{
1637 		return;
1638 	}
1639 
1640 	c->DebugLog = NewLog("cedar_debug_log", "cedar", LOG_SWITCH_NO);
1641 }
1642 
1643 // Set the Cedar into VPN Bridge mode
SetCedarVpnBridge(CEDAR * c)1644 void SetCedarVpnBridge(CEDAR *c)
1645 {
1646 	// Validate arguments
1647 	if (c == NULL)
1648 	{
1649 		return;
1650 	}
1651 
1652 	c->Bridge = true;
1653 
1654 	Free(c->ServerStr);
1655 	c->ServerStr = CopyStr(CEDAR_BRIDGE_STR);
1656 }
1657 
CedarForceLink()1658 void CedarForceLink()
1659 {
1660 }
1661 
1662 // Get version of the Cedar
GetCedarVersion(char * tmp,UINT size)1663 void GetCedarVersion(char *tmp, UINT size)
1664 {
1665 	// Validate arguments
1666 	if (tmp == NULL)
1667 	{
1668 		return;
1669 	}
1670 
1671 	Format(tmp, size, "%u.%02u.%u",
1672 		CEDAR_VER / 100, CEDAR_VER - (CEDAR_VER / 100) * 100,
1673 		CEDAR_BUILD);
1674 }
1675 
1676 // Create Cedar object
NewCedar(X * server_x,K * server_k)1677 CEDAR *NewCedar(X *server_x, K *server_k)
1678 {
1679 	CEDAR *c;
1680 	char tmp[MAX_SIZE];
1681 	char tmp2[MAX_SIZE];
1682 	char *beta_str;
1683 
1684 	CedarForceLink();
1685 
1686 	c = ZeroMalloc(sizeof(CEDAR));
1687 
1688 	c->CurrentActiveLinks = NewCounter();
1689 
1690 	c->AcceptingSockets = NewCounter();
1691 
1692 	c->CedarSuperLock = NewLock();
1693 
1694 	c->CurrentRegionLock = NewLock();
1695 
1696 	StrCpy(c->OpenVPNDefaultClientOption, sizeof(c->OpenVPNDefaultClientOption), OVPN_DEF_CLIENT_OPTION_STRING);
1697 
1698 #ifdef	BETA_NUMBER
1699 	c->Beta = BETA_NUMBER;
1700 #endif	// BETA_NUMBER
1701 
1702 	InitNoSslList(c);
1703 
1704 	c->AssignedBridgeLicense = NewCounter();
1705 	c->AssignedClientLicense = NewCounter();
1706 
1707 	c->CurrentTcpQueueSizeLock = NewLock();
1708 	c->QueueBudgetLock = NewLock();
1709 	c->FifoBudgetLock = NewLock();
1710 
1711 	Rand(c->UniqueId, sizeof(c->UniqueId));
1712 
1713 	c->CreatedTick = Tick64();
1714 
1715 	c->lock = NewLock();
1716 	c->ref = NewRef();
1717 
1718 	c->OpenVPNPublicPortsLock = NewLock();
1719 	c->CurrentTcpConnections = GetNumTcpConnectionsCounter();
1720 
1721 	c->ListenerList = NewList(CompareListener);
1722 	c->UDPEntryList = NewList(CompareUDPEntry);
1723 	c->HubList = NewList(CompareHub);
1724 	c->ConnectionList = NewList(CompareConnection);
1725 
1726 	c->ConnectionIncrement = NewCounter();
1727 	c->CurrentSessions = NewCounter();
1728 
1729 	if (server_k && server_x)
1730 	{
1731 		c->ServerK = CloneK(server_k);
1732 		c->ServerX = CloneX(server_x);
1733 	}
1734 
1735 	c->Version = CEDAR_VER;
1736 	c->Build = CEDAR_BUILD;
1737 	c->ServerStr = CopyStr(CEDAR_SERVER_STR);
1738 
1739 	GetMachineName(tmp, sizeof(tmp));
1740 	c->MachineName = CopyStr(tmp);
1741 
1742 	c->HttpUserAgent = CopyStr(DEFAULT_USER_AGENT);
1743 	c->HttpAccept = CopyStr(DEFAULT_ACCEPT);
1744 	c->HttpAcceptLanguage = CopyStr("ja");
1745 	c->HttpAcceptEncoding = CopyStr(DEFAULT_ENCODING);
1746 
1747 	c->Traffic = NewTraffic();
1748 	c->TrafficLock = NewLock();
1749 	c->CaList = NewList(CompareCert);
1750 
1751 	c->TrafficDiffList = NewList(NULL);
1752 
1753 	SetCedarCipherList(c, SERVER_DEFAULT_CIPHER_NAME);
1754 
1755 	c->ClientId = _II("CLIENT_ID");
1756 
1757 	c->UdpPortList = NewIntList(false);
1758 
1759 	InitNetSvcList(c);
1760 
1761 	InitLocalBridgeList(c);
1762 
1763 	InitCedarLayer3(c);
1764 
1765 	c->WebUI = WuNewWebUI(c);
1766 
1767 #ifdef	ALPHA_VERSION
1768 	beta_str = "Alpha";
1769 #else	// ALPHA_VERSION
1770 #ifndef	RELEASE_CANDIDATE
1771 	beta_str = "Beta";
1772 #else	// RELEASE_CANDIDATE
1773 	beta_str = "Release Candidate";
1774 #endif	// RELEASE_CANDIDATE
1775 #endif	// ALPHA_VERSION
1776 
1777 	ToStr(tmp2, c->Beta);
1778 
1779 	Format(tmp, sizeof(tmp), "Version %u.%02u Build %u %s %s (%s)",
1780 		CEDAR_VER / 100, CEDAR_VER - (CEDAR_VER / 100) * 100,
1781 		CEDAR_BUILD,
1782 		c->Beta == 0 ? "" : beta_str,
1783 		c->Beta == 0 ? "" : tmp2,
1784 		_SS("LANGSTR"));
1785 	Trim(tmp);
1786 
1787 	if (true)
1788 	{
1789 		SYSTEMTIME st;
1790 		Zero(&st, sizeof(st));
1791 
1792 		st.wYear = BUILD_DATE_Y;
1793 		st.wMonth = BUILD_DATE_M;
1794 		st.wDay = BUILD_DATE_D;
1795 
1796 		c->BuiltDate = SystemToUINT64(&st);
1797 	}
1798 
1799 	c->VerString = CopyStr(tmp);
1800 
1801 	Format(tmp, sizeof(tmp), "Compiled %04u/%02u/%02u %02u:%02u:%02u by %s at %s",
1802 		BUILD_DATE_Y, BUILD_DATE_M, BUILD_DATE_D, BUILD_DATE_HO, BUILD_DATE_MI, BUILD_DATE_SE, BUILDER_NAME, BUILD_PLACE);
1803 
1804 	c->BuildInfo = CopyStr(tmp);
1805 
1806 	return c;
1807 }
1808 
1809 // Check whether the Cedar was build after the specified date
IsLaterBuild(CEDAR * c,UINT64 t)1810 bool IsLaterBuild(CEDAR *c, UINT64 t)
1811 {
1812 	SYSTEMTIME sb, st;
1813 	UINT64 b;
1814 	// Validate arguments
1815 	if (c == NULL)
1816 	{
1817 		return false;
1818 	}
1819 
1820 	Zero(&sb, sizeof(sb));
1821 	Zero(&st, sizeof(st));
1822 
1823 	UINT64ToSystem(&sb, c->BuiltDate);
1824 	UINT64ToSystem(&st, t);
1825 
1826 	// Ignore time of the day
1827 	sb.wHour = sb.wMinute = sb.wSecond = sb.wMilliseconds = 0;
1828 	st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0;
1829 
1830 	b = SystemToUINT64(&sb);
1831 	t = SystemToUINT64(&st);
1832 
1833 	if (b > t)
1834 	{
1835 		return true;
1836 	}
1837 	else
1838 	{
1839 		return false;
1840 	}
1841 }
1842 
1843 // Cumulate traffic size
AddTraffic(TRAFFIC * dst,TRAFFIC * diff)1844 void AddTraffic(TRAFFIC *dst, TRAFFIC *diff)
1845 {
1846 	// Validate arguments
1847 	if (dst == NULL || diff == NULL)
1848 	{
1849 		return;
1850 	}
1851 
1852 	dst->Recv.BroadcastBytes += diff->Recv.BroadcastBytes;
1853 	dst->Recv.BroadcastCount += diff->Recv.BroadcastCount;
1854 	dst->Recv.UnicastBytes += diff->Recv.UnicastBytes;
1855 	dst->Recv.UnicastCount += diff->Recv.UnicastCount;
1856 
1857 	dst->Send.BroadcastBytes += diff->Send.BroadcastBytes;
1858 	dst->Send.BroadcastCount += diff->Send.BroadcastCount;
1859 	dst->Send.UnicastBytes += diff->Send.UnicastBytes;
1860 	dst->Send.UnicastCount += diff->Send.UnicastCount;
1861 }
1862 
1863 // Create new traffic size object
NewTraffic()1864 TRAFFIC *NewTraffic()
1865 {
1866 	TRAFFIC *t;
1867 
1868 	t = ZeroMalloc(sizeof(TRAFFIC));
1869 	return t;
1870 }
1871 
1872 // Free traffic size object
FreeTraffic(TRAFFIC * t)1873 void FreeTraffic(TRAFFIC *t)
1874 {
1875 	// Validate arguments
1876 	if (t == NULL)
1877 	{
1878 		return;
1879 	}
1880 
1881 	Free(t);
1882 }
1883 
1884 // Initialize Cedar communication module
InitCedar()1885 void InitCedar()
1886 {
1887 	if ((init_cedar_counter++) > 0)
1888 	{
1889 		return;
1890 	}
1891 
1892 	// Initialize protocol module
1893 	InitProtocol();
1894 }
1895 
1896 // Free Cedar communication module
FreeCedar()1897 void FreeCedar()
1898 {
1899 	if ((--init_cedar_counter) > 0)
1900 	{
1901 		return;
1902 	}
1903 
1904 	// Free protocol module
1905 	FreeProtocol();
1906 }
1907 
1908