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