1 // SoftEther VPN Source Code - Developer Edition Master Branch
2 // Cedar Communication Module
3 // © 2020 Nokia
4
5 // Client.c
6 // Client Manager
7
8 #include "Client.h"
9
10 #include "Account.h"
11 #include "Admin.h"
12 #include "Cedar.h"
13 #include "CM.h"
14 #include "Connection.h"
15 #include "IPC.h"
16 #include "Listener.h"
17 #include "Logging.h"
18 #include "Protocol.h"
19 #include "Remote.h"
20 #include "Virtual.h"
21 #include "VLanUnix.h"
22 #include "VLanWin32.h"
23 #include "Win32Com.h"
24 #include "WinUi.h"
25
26 #include "Mayaqua/Cfg.h"
27 #include "Mayaqua/Encrypt.h"
28 #include "Mayaqua/FileIO.h"
29 #include "Mayaqua/Internat.h"
30 #include "Mayaqua/Kernel.h"
31 #include "Mayaqua/MayaType.h"
32 #include "Mayaqua/Memory.h"
33 #include "Mayaqua/Microsoft.h"
34 #include "Mayaqua/Network.h"
35 #include "Mayaqua/Object.h"
36 #include "Mayaqua/OS.h"
37 #include "Mayaqua/Pack.h"
38 #include "Mayaqua/Secure.h"
39 #include "Mayaqua/Str.h"
40 #include "Mayaqua/Table.h"
41 #include "Mayaqua/Tick64.h"
42 #include "Mayaqua/Win32.h"
43
44 #include <stdlib.h>
45
46 static CLIENT *client = NULL;
47 static LISTENER *cn_listener = NULL;
48 static LOCK *cn_listener_lock = NULL;
49 static UINT64 cn_next_allow = 0;
50 static LOCK *ci_active_sessions_lock = NULL;
51 static UINT ci_num_active_sessions = 0;
52
53
54 // In Windows 8 or later, change unreasonable setting of WCM to ensure normal VPN communication
CiDisableWcmNetworkMinimize(CLIENT * c)55 void CiDisableWcmNetworkMinimize(CLIENT *c)
56 {
57 #ifdef OS_WIN32
58 // Validate arguments
59 if (c == NULL)
60 {
61 return;
62 }
63
64 if (c->Config.NoChangeWcmNetworkSettingOnWindows8)
65 {
66 return;
67 }
68
69 MsDisableWcmNetworkMinimize();
70 #endif // OS_WIN32
71 }
72
73 // Compare RPC_CLIENT_ENUM_ACCOUNT_ITEM items by last connected date (Reverse)
CiCompareClientAccountEnumItemByLastConnectDateTime(void * p1,void * p2)74 int CiCompareClientAccountEnumItemByLastConnectDateTime(void *p1, void *p2)
75 {
76 RPC_CLIENT_ENUM_ACCOUNT_ITEM *a1, *a2;
77 if (p1 == NULL || p2 == NULL)
78 {
79 return 0;
80 }
81 a1 = *(RPC_CLIENT_ENUM_ACCOUNT_ITEM **)p1;
82 a2 = *(RPC_CLIENT_ENUM_ACCOUNT_ITEM **)p2;
83 if (a1 == NULL || a2 == NULL)
84 {
85 return 0;
86 }
87 if (a1->LastConnectDateTime > a2->LastConnectDateTime)
88 {
89 return -1;
90 }
91 else if (a1->LastConnectDateTime < a2->LastConnectDateTime)
92 {
93 return 1;
94 }
95
96 return 0;
97 }
98
99 // If machine changed, reshuffle MAC address for all virtual NIC
CiChangeAllVLanMacAddressIfMachineChanged(CLIENT * c)100 void CiChangeAllVLanMacAddressIfMachineChanged(CLIENT *c)
101 {
102 UCHAR current_hash_new[SHA1_SIZE];
103 UCHAR current_hash[SHA1_SIZE];
104 UCHAR current_hash_old[SHA1_SIZE];
105 UCHAR saved_hash[SHA1_SIZE];
106 // Validate arguments
107 if (c == NULL)
108 {
109 return;
110 }
111
112 #ifdef OS_WIN32
113 if (MsIsAdmin() == false)
114 {
115 return;
116 }
117 #endif
118
119 CiGetCurrentMachineHashNew(current_hash_new);
120 CiGetCurrentMachineHash(current_hash);
121 CiGetCurrentMachineHashOld(current_hash_old);
122
123 if (CiReadLastMachineHash(saved_hash) == false)
124 {
125 CiWriteLastMachineHash(current_hash_new);
126 return;
127 }
128
129 if (Cmp(saved_hash, current_hash_old, SHA1_SIZE) == 0)
130 {
131 CiWriteLastMachineHash(current_hash_new);
132 return;
133 }
134
135 if (Cmp(saved_hash, current_hash, SHA1_SIZE) == 0)
136 {
137 CiWriteLastMachineHash(current_hash_new);
138 return;
139 }
140
141 if (Cmp(saved_hash, current_hash_new, SHA1_SIZE) == 0)
142 {
143 return;
144 }
145
146 if (CiWriteLastMachineHash(current_hash_new) == false)
147 {
148 return;
149 }
150
151 CiChangeAllVLanMacAddress(c);
152 }
153
154 // Get current machine hash (Old)
CiGetCurrentMachineHashOld(void * data)155 void CiGetCurrentMachineHashOld(void *data)
156 {
157 char name[MAX_PATH];
158 char *product_id = NULL;
159 // Validate arguments
160 if (data == NULL)
161 {
162 return;
163 }
164
165 #ifdef OS_WIN32
166 // Product ID
167 product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");
168 if (product_id == NULL)
169 {
170 product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");
171 }
172
173 StrCpy(name, sizeof(name), product_id);
174
175 Free(product_id);
176
177 #else // OS_WIN32
178 GetMachineName(name, sizeof(name));
179 #endif // OS_WIN32
180
181 Trim(name);
182 StrUpper(name);
183
184 Sha0(data, name, StrLen(name));
185 }
186
187 // Get current machine hash
CiGetCurrentMachineHash(void * data)188 void CiGetCurrentMachineHash(void *data)
189 {
190 char name[MAX_PATH];
191 char *product_id = NULL;
192 // Validate arguments
193 if (data == NULL)
194 {
195 return;
196 }
197
198 GetMachineName(name, sizeof(name));
199
200 Trim(name);
201 StrUpper(name);
202
203 Sha0(data, name, StrLen(name));
204 }
205
206 // Get current machine hash (without using domain name)
CiGetCurrentMachineHashNew(void * data)207 void CiGetCurrentMachineHashNew(void *data)
208 {
209 char name[MAX_PATH];
210 char *p;
211
212 // Validate arguments
213 if (data == NULL)
214 {
215 return;
216 }
217
218 GetMachineName(name, sizeof(name));
219
220 // Ignore after first period(.)
221 for(p=name; *p; p++)
222 if(*p == '.')
223 *p = 0;
224
225 Trim(name);
226 StrUpper(name);
227
228 Sha0(data, name, StrLen(name));
229 }
230
231
232 // Write machine hash
CiWriteLastMachineHash(void * data)233 bool CiWriteLastMachineHash(void *data)
234 {
235 // Validate arguments
236 if (data == NULL)
237 {
238 return false;
239 }
240
241 #ifdef OS_WIN32
242 if (MsRegWriteBinEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "LastMachineHash", data, SHA1_SIZE, true) == false)
243 {
244 return false;
245 }
246
247 return true;
248 #else // OS_WIN32
249 return false;
250 #endif // OS_WIN32
251 }
252
253 // Get previous machine hash
CiReadLastMachineHash(void * data)254 bool CiReadLastMachineHash(void *data)
255 {
256 BUF *b = NULL;
257 // Validate arguments
258 if (data == NULL)
259 {
260 return false;
261 }
262
263 #ifdef OS_WIN32
264 b = MsRegReadBinEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "LastMachineHash", true);
265 if (b == NULL)
266 {
267 return false;
268 }
269 if (b->Size == SHA1_SIZE)
270 {
271 Copy(data, b->Buf, b->Size);
272 FreeBuf(b);
273
274 return true;
275 }
276
277 FreeBuf(b);
278 return false;
279 #else // OS_WIN32
280 return false;
281 #endif // OS_WIN32
282 }
283
284 // If the MAC address of each virtual LAN card has been eliminated, set it to random numbers
285 // (measures for Windows 8 -> 8.1 upgrade problem)
CiChangeAllVLanMacAddressIfCleared(CLIENT * c)286 void CiChangeAllVLanMacAddressIfCleared(CLIENT *c)
287 {
288 #ifdef OS_WIN32
289 RPC_CLIENT_ENUM_VLAN t;
290 // Validate arguments
291 if (c == NULL)
292 {
293 return;
294 }
295
296 if (MsIsInfCatalogRequired() == false)
297 {
298 // Not required for other than Windows 8
299 return;
300 }
301
302 Zero(&t, sizeof(t));
303 if (CtEnumVLan(c, &t))
304 {
305 UINT i;
306
307 for (i = 0;i < t.NumItem;i++)
308 {
309 RPC_CLIENT_ENUM_VLAN_ITEM *e = t.Items[i];
310 UCHAR mac[6];
311
312 if (StrToMac(mac, e->MacAddress))
313 {
314 if (mac[0] == 0x00 &&
315 mac[1] == 0x00 &&
316 mac[2] == 0x01 &&
317 mac[3] == 0x00 &&
318 mac[4] == 0x00 &&
319 mac[5] == 0x01)
320 {
321 char *name = e->DeviceName;
322 RPC_CLIENT_SET_VLAN s;
323 UCHAR mac[6];
324
325 GenMacAddress(mac);
326
327 Zero(&s, sizeof(s));
328 StrCpy(s.DeviceName, sizeof(s.DeviceName), name);
329
330 MacToStr(s.MacAddress, sizeof(s.MacAddress), mac);
331
332 CtSetVLan(c, &s);
333 }
334 }
335 }
336
337 CiFreeClientEnumVLan(&t);
338 }
339 #endif // OS_WIN32
340 }
341
342 // Set the MAC address of all virtual LAN cards to random number
CiChangeAllVLanMacAddress(CLIENT * c)343 void CiChangeAllVLanMacAddress(CLIENT *c)
344 {
345 RPC_CLIENT_ENUM_VLAN t;
346 // Validate arguments
347 if (c == NULL)
348 {
349 return;
350 }
351
352 Zero(&t, sizeof(t));
353 if (CtEnumVLan(c, &t))
354 {
355 UINT i;
356
357 for (i = 0;i < t.NumItem;i++)
358 {
359 RPC_CLIENT_ENUM_VLAN_ITEM *e = t.Items[i];
360 UCHAR mac[6];
361
362 if (StrToMac(mac, e->MacAddress) && ((mac[0] == 0x00 && mac[1] == 0xAC) || (mac[0] == 0x5E)))
363 {
364 char *name = e->DeviceName;
365 RPC_CLIENT_SET_VLAN s;
366 UCHAR mac[6];
367
368 GenMacAddress(mac);
369
370 Zero(&s, sizeof(s));
371 StrCpy(s.DeviceName, sizeof(s.DeviceName), name);
372
373 MacToStr(s.MacAddress, sizeof(s.MacAddress), mac);
374
375 CtSetVLan(c, &s);
376 }
377 }
378
379 CiFreeClientEnumVLan(&t);
380 }
381 }
382
383 // Wait for preparation of notification service to complete
CnWaitForCnServiceReady()384 void CnWaitForCnServiceReady()
385 {
386 UINT64 start_time = Tick64();
387
388 while ((start_time + (UINT64)CLIENT_WAIT_CN_READY_TIMEOUT) >= Tick64())
389 {
390 if (CnIsCnServiceReady())
391 {
392 break;
393 }
394
395 SleepThread(100);
396 }
397 }
398
399 // Check whether preparation of notification service completed
CnIsCnServiceReady()400 bool CnIsCnServiceReady()
401 {
402 SOCK *s;
403 // Confirm running the notification service
404 if (CnCheckAlreadyExists(false) == false)
405 {
406 // Not running
407 return false;
408 }
409
410 // Try to connect to the TCP port
411 s = ConnectEx("localhost", CLIENT_NOTIFY_PORT, 500);
412 if (s == NULL)
413 {
414 // The TCP port is not opened
415 return false;
416 }
417
418 Disconnect(s);
419 ReleaseSock(s);
420
421 // Running
422 return true;
423 }
424
425 // Check whether the notification service is already running
CnCheckAlreadyExists(bool lock)426 bool CnCheckAlreadyExists(bool lock)
427 {
428 #ifdef OS_WIN32
429 return Win32CnCheckAlreadyExists(lock);
430 #else
431 return false;
432 #endif
433 }
434
435 typedef struct CNC_STATUS_PRINTER_WINDOW_PARAM
436 {
437 THREAD *Thread;
438 SESSION *Session;
439 SOCK *Sock;
440 } CNC_STATUS_PRINTER_WINDOW_PARAM;
441
442 typedef struct CNC_CONNECT_ERROR_DLG_THREAD_PARAM
443 {
444 SESSION *Session;
445 SOCK *Sock;
446 bool HaltThread;
447 EVENT *Event;
448 } CNC_CONNECT_ERROR_DLG_THREAD_PARAM;
449
450 // Thread to stop forcibly the Certificate check dialog client
CncCheckCertHaltThread(THREAD * thread,void * param)451 void CncCheckCertHaltThread(THREAD *thread, void *param)
452 {
453 CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp = (CNC_CONNECT_ERROR_DLG_THREAD_PARAM *)param;
454 // Validate arguments
455 if (thread == NULL || param == NULL)
456 {
457 return;
458 }
459
460 while (true)
461 {
462 if (dp->Session->Halt || dp->HaltThread)
463 {
464 break;
465 }
466
467 Wait(dp->Event, 100);
468 }
469
470 Disconnect(dp->Sock);
471 }
472
473 // Show the certification check dialog
CncCheckCert(SESSION * session,UI_CHECKCERT * dlg)474 void CncCheckCert(SESSION *session, UI_CHECKCERT *dlg)
475 {
476 SOCK *s;
477 PACK *p;
478 CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp;
479 THREAD *t;
480 // Validate arguments
481 if (dlg == NULL || session == NULL)
482 {
483 return;
484 }
485
486 s = CncConnect();
487 if (s == NULL)
488 {
489 return;
490 }
491
492 p = NewPack();
493 PackAddStr(p, "function", "check_cert");
494 PackAddUniStr(p, "AccountName", dlg->AccountName);
495 PackAddStr(p, "ServerName", dlg->ServerName);
496 PackAddX(p, "x", dlg->x);
497 PackAddX(p, "parent_x", dlg->parent_x);
498 PackAddX(p, "old_x", dlg->old_x);
499 PackAddBool(p, "DiffWarning", dlg->DiffWarning);
500 PackAddBool(p, "Ok", dlg->Ok);
501 PackAddBool(p, "SaveServerCert", dlg->SaveServerCert);
502
503 SendPack(s, p);
504 FreePack(p);
505
506 dp = ZeroMalloc(sizeof(CNC_CONNECT_ERROR_DLG_THREAD_PARAM));
507 dp->Sock = s;
508 dp->Event = NewEvent();
509 dp->Session = session;
510
511 t = NewThread(CncCheckCertHaltThread, dp);
512
513 p = RecvPack(s);
514 if (p != NULL)
515 {
516 dlg->Ok = PackGetBool(p, "Ok");
517 dlg->DiffWarning = PackGetBool(p, "DiffWarning");
518 dlg->SaveServerCert = PackGetBool(p, "SaveServerCert");
519
520 FreePack(p);
521 }
522
523 dp->HaltThread = true;
524 Set(dp->Event);
525
526 WaitThread(t, INFINITE);
527
528 ReleaseEvent(dp->Event);
529 Free(dp);
530 ReleaseThread(t);
531
532 Disconnect(s);
533 ReleaseSock(s);
534 }
535
536 // Smart card signature dialog
CncSecureSignDlg(SECURE_SIGN * sign)537 bool CncSecureSignDlg(SECURE_SIGN *sign)
538 {
539 SOCK *s;
540 PACK *p;
541 bool ret = false;
542 // Validate arguments
543 if (sign == NULL)
544 {
545 return false;
546 }
547
548 s = CncConnect();
549 if (s == NULL)
550 {
551 return false;
552 }
553
554 p = NewPack();
555 PackAddStr(p, "function", "secure_sign");
556 OutRpcSecureSign(p, sign);
557
558 SendPack(s, p);
559 FreePack(p);
560
561 p = RecvPack(s);
562 if (p != NULL)
563 {
564 ret = PackGetBool(p, "ret");
565
566 if (ret)
567 {
568 FreeRpcSecureSign(sign);
569
570 Zero(sign, sizeof(SECURE_SIGN));
571 InRpcSecureSign(sign, p);
572 }
573
574 FreePack(p);
575 }
576
577 Disconnect(s);
578 ReleaseSock(s);
579
580 return ret;
581 }
582
583 // Show the NIC information dialog
CncNicInfo(UI_NICINFO * info)584 SOCK *CncNicInfo(UI_NICINFO *info)
585 {
586 SOCK *s;
587 PACK *p;
588 // Validate arguments
589 if (info == NULL)
590 {
591 return NULL;
592 }
593
594 s = CncConnectEx(200);
595 if (s == NULL)
596 {
597 return NULL;
598 }
599
600 p = NewPack();
601 PackAddStr(p, "function", "nicinfo");
602 PackAddStr(p, "NicName", info->NicName);
603 PackAddUniStr(p, "AccountName", info->AccountName);
604
605 SendPack(s, p);
606 FreePack(p);
607
608 return s;
609 }
610
611 // Close the NIC information dialog
CncNicInfoFree(SOCK * s)612 void CncNicInfoFree(SOCK *s)
613 {
614 // Validate arguments
615 if (s == NULL)
616 {
617 return;
618 }
619
620 Disconnect(s);
621 ReleaseSock(s);
622 }
623
624 // Show the message dialog
CncMsgDlg(UI_MSG_DLG * dlg)625 SOCK *CncMsgDlg(UI_MSG_DLG *dlg)
626 {
627 SOCK *s;
628 PACK *p;
629 char *utf;
630 // Validate arguments
631 if (dlg == NULL)
632 {
633 return NULL;
634 }
635
636 s = CncConnectEx(200);
637 if (s == NULL)
638 {
639 return NULL;
640 }
641
642 p = NewPack();
643 PackAddStr(p, "function", "msg_dialog");
644 PackAddStr(p, "ServerName", dlg->ServerName);
645 PackAddStr(p, "HubName", dlg->HubName);
646 utf = CopyUniToUtf(dlg->Msg);
647 PackAddData(p, "Msg", utf, StrLen(utf));
648 Free(utf);
649
650 SendPack(s, p);
651 FreePack(p);
652
653 return s;
654 }
655
656 // Close the message dialog
CndMsgDlgFree(SOCK * s)657 void CndMsgDlgFree(SOCK *s)
658 {
659 // Validate arguments
660 if (s == NULL)
661 {
662 return;
663 }
664
665 Disconnect(s);
666 ReleaseSock(s);
667 }
668
669 // Show the password input dialog
CncPasswordDlg(SESSION * session,UI_PASSWORD_DLG * dlg)670 bool CncPasswordDlg(SESSION *session, UI_PASSWORD_DLG *dlg)
671 {
672 SOCK *s;
673 PACK *p;
674 CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp;
675 THREAD *t;
676 bool ret = false;
677 // Validate arguments
678 if (dlg == NULL || session == NULL)
679 {
680 return false;
681 }
682
683 s = CncConnect();
684 if (s == NULL)
685 {
686 Wait(session->HaltEvent, session->RetryInterval);
687 return true;
688 }
689
690 p = NewPack();
691 PackAddStr(p, "function", "password_dialog");
692 PackAddInt(p, "Type", dlg->Type);
693 PackAddStr(p, "Username", dlg->Username);
694 PackAddStr(p, "Password", dlg->Password);
695 PackAddStr(p, "ServerName", dlg->ServerName);
696 PackAddInt(p, "RetryIntervalSec", dlg->RetryIntervalSec);
697 PackAddBool(p, "ProxyServer", dlg->ProxyServer);
698 PackAddBool(p, "AdminMode", dlg->AdminMode);
699 PackAddBool(p, "ShowNoSavePassword", dlg->ShowNoSavePassword);
700 PackAddBool(p, "NoSavePassword", dlg->NoSavePassword);
701
702 SendPack(s, p);
703 FreePack(p);
704
705 dp = ZeroMalloc(sizeof(CNC_CONNECT_ERROR_DLG_THREAD_PARAM));
706 dp->Session = session;
707 dp->Sock = s;
708 dp->Event = NewEvent();
709
710 t = NewThread(CncConnectErrorDlgHaltThread, dp);
711
712 p = RecvPack(s);
713 if (p != NULL)
714 {
715 ret = PackGetBool(p, "ok");
716 dlg->NoSavePassword = PackGetBool(p, "NoSavePassword");
717 dlg->ProxyServer = PackGetBool(p, "ProxyServer");
718 dlg->Type = PackGetInt(p, "Type");
719 PackGetStr(p, "Username", dlg->Username, sizeof(dlg->Username));
720 PackGetStr(p, "Password", dlg->Password, sizeof(dlg->Password));
721
722 FreePack(p);
723 }
724
725 dp->HaltThread = true;
726 Set(dp->Event);
727
728 WaitThread(t, INFINITE);
729
730 ReleaseEvent(dp->Event);
731 Free(dp);
732 ReleaseThread(t);
733
734 Disconnect(s);
735 ReleaseSock(s);
736
737 return ret;
738 }
739
740 // Thread to stop the connection error dialog client forcibly
CncConnectErrorDlgHaltThread(THREAD * thread,void * param)741 void CncConnectErrorDlgHaltThread(THREAD *thread, void *param)
742 {
743 CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp = (CNC_CONNECT_ERROR_DLG_THREAD_PARAM *)param;
744 // Validate arguments
745 if (thread == NULL || param == NULL)
746 {
747 return;
748 }
749
750 while (true)
751 {
752 if (dp->Session->Halt || dp->HaltThread)
753 {
754 break;
755 }
756
757 Wait(dp->Event, 100);
758 }
759
760 Disconnect(dp->Sock);
761 }
762
763 // Show the connection error dialog
CncConnectErrorDlg(SESSION * session,UI_CONNECTERROR_DLG * dlg)764 bool CncConnectErrorDlg(SESSION *session, UI_CONNECTERROR_DLG *dlg)
765 {
766 SOCK *s;
767 PACK *p;
768 CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp;
769 THREAD *t;
770 bool ret = false;
771 // Validate arguments
772 if (dlg == NULL || session == NULL)
773 {
774 return false;
775 }
776
777 s = CncConnect();
778 if (s == NULL)
779 {
780 Wait(session->HaltEvent, session->RetryInterval);
781 return true;
782 }
783
784 p = NewPack();
785 PackAddStr(p, "function", "connecterror_dialog");
786 PackAddUniStr(p, "AccountName", dlg->AccountName);
787 PackAddStr(p, "ServerName", dlg->ServerName);
788 PackAddInt(p, "Err", dlg->Err);
789 PackAddInt(p, "CurrentRetryCount", dlg->CurrentRetryCount);
790 PackAddInt(p, "RetryLimit", dlg->RetryLimit);
791 PackAddInt(p, "RetryIntervalSec", dlg->RetryIntervalSec);
792 PackAddBool(p, "HideWindow", dlg->HideWindow);
793
794 SendPack(s, p);
795 FreePack(p);
796
797 dp = ZeroMalloc(sizeof(CNC_CONNECT_ERROR_DLG_THREAD_PARAM));
798 dp->Session = session;
799 dp->Sock = s;
800 dp->Event = NewEvent();
801
802 t = NewThread(CncConnectErrorDlgHaltThread, dp);
803
804 p = RecvPack(s);
805 if (p != NULL)
806 {
807 ret = PackGetBool(p, "ok");
808 dlg->HideWindow = PackGetBool(p, "HideWindow");
809
810 FreePack(p);
811 }
812
813 dp->HaltThread = true;
814 Set(dp->Event);
815
816 WaitThread(t, INFINITE);
817
818 ReleaseEvent(dp->Event);
819 Free(dp);
820 ReleaseThread(t);
821
822 Disconnect(s);
823 ReleaseSock(s);
824
825 return ret;
826 }
827
828 // Thread for the status indicator client
CncStatusPrinterWindowThreadProc(THREAD * thread,void * param)829 void CncStatusPrinterWindowThreadProc(THREAD *thread, void *param)
830 {
831 CNC_STATUS_PRINTER_WINDOW_PARAM *pp;
832 SOCK *sock;
833 PACK *p;
834 // Validate arguments
835 if (thread == NULL || param == NULL)
836 {
837 return;
838 }
839
840 pp = (CNC_STATUS_PRINTER_WINDOW_PARAM *)param;
841 sock = pp->Sock;
842 pp->Thread = thread;
843 AddRef(pp->Thread->ref);
844
845 NoticeThreadInit(thread);
846
847 p = RecvPack(sock);
848 if (p != NULL)
849 {
850 // Stop the session
851 StopSessionEx(pp->Session, true);
852
853 FreePack(p);
854 }
855 }
856
857 // Create a status indicator client
CncStatusPrinterWindowStart(SESSION * s)858 SOCK *CncStatusPrinterWindowStart(SESSION *s)
859 {
860 SOCK *sock;
861 PACK *p;
862 THREAD *t;
863 CNC_STATUS_PRINTER_WINDOW_PARAM *param;
864 // Validate arguments
865 if (s == NULL)
866 {
867 return NULL;
868 }
869
870 sock = CncConnect();
871
872 if (sock == NULL)
873 {
874 return NULL;
875 }
876
877 p = NewPack();
878 PackAddStr(p, "function", "status_printer");
879 PackAddUniStr(p, "account_name", s->Account->ClientOption->AccountName);
880
881 if (SendPack(sock, p) == false)
882 {
883 FreePack(p);
884 ReleaseSock(sock);
885
886 return NULL;
887 }
888
889 FreePack(p);
890
891 param = ZeroMalloc(sizeof(CNC_STATUS_PRINTER_WINDOW_PARAM));
892 param->Sock = sock;
893 param->Session = s;
894
895 sock->Param = param;
896
897 t = NewThread(CncStatusPrinterWindowThreadProc, param);
898 WaitThreadInit(t);
899
900 ReleaseThread(t);
901
902 return sock;
903 }
904
905 // Send a string to the status indicator
CncStatusPrinterWindowPrint(SOCK * s,wchar_t * str)906 void CncStatusPrinterWindowPrint(SOCK *s, wchar_t *str)
907 {
908 PACK *p;
909 // Validate arguments
910 if (s == NULL || str == NULL)
911 {
912 return;
913 }
914
915 p = NewPack();
916 PackAddUniStr(p, "string", str);
917 SendPack(s, p);
918 FreePack(p);
919 }
920
921 // Stop the status indicator client
CncStatusPrinterWindowStop(SOCK * s)922 void CncStatusPrinterWindowStop(SOCK *s)
923 {
924 CNC_STATUS_PRINTER_WINDOW_PARAM *param;
925 // Validate arguments
926 if (s == NULL)
927 {
928 return;
929 }
930
931 param = (CNC_STATUS_PRINTER_WINDOW_PARAM *)s->Param;
932
933 // Disconnect the client socket
934 Disconnect(s);
935
936 // Terminate the thread
937 WaitThread(param->Thread, INFINITE);
938 ReleaseThread(param->Thread);
939
940 Free(param);
941 ReleaseSock(s);
942 }
943
944 // Start the driver installer for Windows Vista
CncExecDriverInstaller(char * arg)945 bool CncExecDriverInstaller(char *arg)
946 {
947 SOCK *s = CncConnect();
948 PACK *p;
949 bool ret;
950 if (s == NULL)
951 {
952 return false;
953 }
954
955 p = NewPack();
956 PackAddStr(p, "function", "exec_driver_installer");
957 PackAddStr(p, "arg", arg);
958
959 SendPack(s, p);
960 FreePack(p);
961
962 p = RecvPack(s);
963 if (p == NULL)
964 {
965 Disconnect(s);
966 ReleaseSock(s);
967 return false;
968 }
969
970 ret = PackGetBool(p, "ret");
971
972 FreePack(p);
973
974 Disconnect(s);
975 ReleaseSock(s);
976
977 return ret;
978 }
979
980 // Let the current running client notification services releasing the socket
CncReleaseSocket()981 void CncReleaseSocket()
982 {
983 SOCK *s = CncConnect();
984 PACK *p;
985 if (s == NULL)
986 {
987 return;
988 }
989
990 p = NewPack();
991 PackAddStr(p, "function", "release_socket");
992
993 #ifdef OS_WIN32
994 PackAddInt(p, "pid", MsGetProcessId());
995 #endif // OS_WIN32
996
997 SendPack(s, p);
998 FreePack(p);
999
1000 Disconnect(s);
1001 ReleaseSock(s);
1002 }
1003
1004 // Terminate the process of the client notification service
CncExit()1005 void CncExit()
1006 {
1007 SOCK *s = CncConnectEx(256);
1008 PACK *p;
1009 if (s != NULL)
1010 {
1011 p = NewPack();
1012 PackAddStr(p, "function", "exit");
1013
1014 SendPack(s, p);
1015
1016 FreePack(p);
1017
1018 FreePack(RecvPack(s));
1019
1020 Disconnect(s);
1021 ReleaseSock(s);
1022 }
1023
1024 #ifdef OS_WIN32
1025 MsKillOtherInstanceEx("vpnclient");
1026 #endif // OS_WIN32
1027 }
1028
1029 // Connect to the client notification service
CncConnect()1030 SOCK *CncConnect()
1031 {
1032 return CncConnectEx(0);
1033 }
CncConnectEx(UINT timeout)1034 SOCK *CncConnectEx(UINT timeout)
1035 {
1036 SOCK *s = ConnectEx("localhost", CLIENT_NOTIFY_PORT, timeout);
1037
1038 return s;
1039 }
1040
1041 #ifdef OS_WIN32
1042
1043 // Thread for the certificate check dialog
Win32CnCheckCertThreadProc(THREAD * thread,void * param)1044 void Win32CnCheckCertThreadProc(THREAD *thread, void *param)
1045 {
1046 UI_CHECKCERT *dlg;
1047 // Validate arguments
1048 if (thread == NULL || param == NULL)
1049 {
1050 return;
1051 }
1052
1053 dlg = (UI_CHECKCERT *)param;
1054
1055 CheckCertDlg(dlg);
1056 {
1057 PACK *p = NewPack();
1058
1059 PackAddBool(p, "Ok", dlg->Ok);
1060 PackAddBool(p, "SaveServerCert", dlg->SaveServerCert);
1061
1062 SendPack(dlg->Sock, p);
1063 FreePack(p);
1064
1065 FreePack(RecvPack(dlg->Sock));
1066 }
1067
1068 Disconnect(dlg->Sock);
1069 }
1070
1071 // Certificate check dialog
Win32CnCheckCert(SOCK * s,PACK * p)1072 void Win32CnCheckCert(SOCK *s, PACK *p)
1073 {
1074 UI_CHECKCERT dlg;
1075 THREAD *t;
1076 Zero(&dlg, sizeof(dlg));
1077 // Validate arguments
1078 if (s == NULL || p == NULL)
1079 {
1080 return;
1081 }
1082
1083 PackGetUniStr(p, "AccountName", dlg.AccountName, sizeof(dlg.AccountName));
1084 PackGetStr(p, "ServerName", dlg.ServerName, sizeof(dlg.ServerName));
1085 dlg.x = PackGetX(p, "x");
1086 dlg.parent_x = PackGetX(p, "parent_x");
1087 dlg.old_x = PackGetX(p, "old_x");
1088 dlg.DiffWarning = PackGetBool(p, "DiffWarning");
1089 dlg.Ok = PackGetBool(p, "Ok");
1090 dlg.SaveServerCert = PackGetBool(p, "SaveServerCert");
1091 dlg.Sock = s;
1092
1093 t = NewThread(Win32CnCheckCertThreadProc, &dlg);
1094
1095 FreePack(RecvPack(s));
1096
1097 dlg.Halt = true;
1098
1099 WaitThread(t, INFINITE);
1100 ReleaseThread(t);
1101
1102 FreeX(dlg.parent_x);
1103 FreeX(dlg.old_x);
1104 FreeX(dlg.x);
1105 }
1106
1107 // Message display dialog thread procedure
Win32CnMsgDlgThreadProc(THREAD * thread,void * param)1108 void Win32CnMsgDlgThreadProc(THREAD *thread, void *param)
1109 {
1110 UI_MSG_DLG *dlg = (UI_MSG_DLG *)param;
1111 wchar_t tmp[MAX_SIZE];
1112 char url[MAX_SIZE];
1113 // Validate arguments
1114 if (thread == NULL || dlg == NULL)
1115 {
1116 return;
1117 }
1118
1119 UniFormat(tmp, sizeof(tmp), _UU("CM_MSG_TITLE"),
1120 dlg->ServerName, dlg->HubName);
1121
1122 if (IsURLMsg(dlg->Msg, url, sizeof(url)) == false)
1123 {
1124 OnceMsgEx(NULL, tmp, dlg->Msg, true, 167, &dlg->Halt);
1125 }
1126 else
1127 {
1128 if (MsExecute(url, NULL) == false)
1129 {
1130 OnceMsgEx(NULL, tmp, dlg->Msg, true, 167, &dlg->Halt);
1131 }
1132 }
1133
1134 Disconnect(dlg->Sock);
1135 }
1136
1137 // NIC information dialog thread procedure
Win32CnNicInfoThreadProc(THREAD * thread,void * param)1138 void Win32CnNicInfoThreadProc(THREAD *thread, void *param)
1139 {
1140 UI_NICINFO *info = (UI_NICINFO *)param;
1141 // Validate arguments
1142 if (thread == NULL || info == NULL)
1143 {
1144 return;
1145 }
1146
1147 NicInfo(info);
1148
1149 Disconnect(info->Sock);
1150 }
1151
1152 // NIC information dialog
Win32CnNicInfo(SOCK * s,PACK * p)1153 void Win32CnNicInfo(SOCK *s, PACK *p)
1154 {
1155 UI_NICINFO info;
1156 THREAD *t;
1157 Zero(&info, sizeof(info));
1158 // Validate arguments
1159 if (s == NULL || p == NULL)
1160 {
1161 return;
1162 }
1163
1164 PackGetStr(p, "NicName", info.NicName, sizeof(info.NicName));
1165 PackGetUniStr(p, "AccountName", info.AccountName, sizeof(info.AccountName));
1166
1167 info.Sock = s;
1168
1169 t = NewThread(Win32CnNicInfoThreadProc, &info);
1170
1171 FreePack(RecvPack(s));
1172
1173 info.Halt = true;
1174
1175 WaitThread(t, INFINITE);
1176 ReleaseThread(t);
1177 }
1178
1179 // Message display dialog
Win32CnMsgDlg(SOCK * s,PACK * p)1180 void Win32CnMsgDlg(SOCK *s, PACK *p)
1181 {
1182 UI_MSG_DLG dlg;
1183 THREAD *t;
1184 UINT utf_size;
1185 char *utf;
1186 wchar_t *msg;
1187 Zero(&dlg, sizeof(dlg));
1188 // Validate arguments
1189 if (s == NULL || p == NULL)
1190 {
1191 return;
1192 }
1193
1194 PackGetStr(p, "ServerName", dlg.ServerName, sizeof(dlg.ServerName));
1195 PackGetStr(p, "HubName", dlg.HubName, sizeof(dlg.HubName));
1196
1197 utf_size = PackGetDataSize(p, "Msg");
1198 utf = ZeroMalloc(utf_size + 8);
1199
1200 PackGetData(p, "Msg", utf);
1201
1202 msg = CopyUtfToUni(utf);
1203 Free(utf);
1204
1205 dlg.Sock = s;
1206 dlg.Msg = msg;
1207
1208 t = NewThread(Win32CnMsgDlgThreadProc, &dlg);
1209
1210 FreePack(RecvPack(s));
1211
1212 dlg.Halt = true;
1213
1214 WaitThread(t, INFINITE);
1215 ReleaseThread(t);
1216
1217 Free(msg);
1218 }
1219
1220 // Thread for Password input dialog
Win32CnPasswordDlgThreadProc(THREAD * thread,void * param)1221 void Win32CnPasswordDlgThreadProc(THREAD *thread, void *param)
1222 {
1223 UI_PASSWORD_DLG *dlg;
1224 // Validate arguments
1225 if (thread == NULL || param == NULL)
1226 {
1227 return;
1228 }
1229
1230 dlg = (UI_PASSWORD_DLG *)param;
1231
1232 if (PasswordDlg(NULL, dlg))
1233 {
1234 PACK *p = NewPack();
1235
1236 PackAddBool(p, "ok", true);
1237 PackAddStr(p, "Username", dlg->Username);
1238 PackAddStr(p, "Password", dlg->Password);
1239 PackAddInt(p, "Type", dlg->Type);
1240 PackAddBool(p, "ProxyServer", dlg->ProxyServer);
1241 PackAddBool(p, "NoSavePassword", dlg->NoSavePassword);
1242
1243 SendPack(dlg->Sock, p);
1244 FreePack(p);
1245
1246 FreePack(RecvPack(dlg->Sock));
1247 }
1248
1249 Disconnect(dlg->Sock);
1250 }
1251
1252 // Password input dialog
Win32CnPasswordDlg(SOCK * s,PACK * p)1253 void Win32CnPasswordDlg(SOCK *s, PACK *p)
1254 {
1255 UI_PASSWORD_DLG dlg;
1256 THREAD *t = NULL;
1257 Zero(&dlg, sizeof(dlg));
1258 // Validate arguments
1259 if (s == NULL || p == NULL)
1260 {
1261 return;
1262 }
1263
1264 dlg.Type = PackGetInt(p, "Type");
1265 PackGetStr(p, "Username", dlg.Username, sizeof(dlg.Username));
1266 PackGetStr(p, "Password", dlg.Password, sizeof(dlg.Password));
1267 PackGetStr(p, "ServerName", dlg.ServerName, sizeof(dlg.ServerName));
1268 dlg.RetryIntervalSec = PackGetInt(p, "RetryIntervalSec");
1269 dlg.ProxyServer = PackGetBool(p, "ProxyServer");
1270 dlg.AdminMode = PackGetBool(p, "AdminMode");
1271 dlg.ShowNoSavePassword = PackGetBool(p, "ShowNoSavePassword");
1272 dlg.NoSavePassword = PackGetBool(p, "NoSavePassword");
1273 dlg.CancelEvent = NewEvent();
1274 dlg.Sock = s;
1275
1276 t = NewThread(Win32CnPasswordDlgThreadProc, &dlg);
1277
1278 FreePack(RecvPack(s));
1279
1280 Set(dlg.CancelEvent);
1281
1282 WaitThread(t, INFINITE);
1283 ReleaseEvent(dlg.CancelEvent);
1284 ReleaseThread(t);
1285 }
1286
1287 // Thread for the connection error dialog
Win32CnConnectErrorDlgThreadProc(THREAD * thread,void * param)1288 void Win32CnConnectErrorDlgThreadProc(THREAD *thread, void *param)
1289 {
1290 UI_CONNECTERROR_DLG *dlg;
1291 // Validate arguments
1292 if (thread == NULL || param == NULL)
1293 {
1294 return;
1295 }
1296
1297 dlg = (UI_CONNECTERROR_DLG *)param;
1298
1299 if (ConnectErrorDlg(dlg))
1300 {
1301 PACK *p = NewPack();
1302
1303 PackAddBool(p, "ok", true);
1304 PackAddBool(p, "HideWindow", dlg->HideWindow);
1305
1306 SendPack(dlg->Sock, p);
1307 FreePack(p);
1308
1309 FreePack(RecvPack(dlg->Sock));
1310 }
1311
1312 Disconnect(dlg->Sock);
1313 }
1314
1315 // Connection Error dialog (Win32)
Win32CnConnectErrorDlg(SOCK * s,PACK * p)1316 void Win32CnConnectErrorDlg(SOCK *s, PACK *p)
1317 {
1318 UI_CONNECTERROR_DLG dlg;
1319 THREAD *t;
1320 Zero(&dlg, sizeof(dlg));
1321 // Validate arguments
1322 if (s == NULL || p == NULL)
1323 {
1324 return;
1325 }
1326
1327 PackGetUniStr(p, "AccountName", dlg.AccountName, sizeof(dlg.AccountName));
1328 PackGetStr(p, "ServerName", dlg.ServerName, sizeof(dlg.ServerName));
1329 dlg.Err = PackGetInt(p, "Err");
1330 dlg.CurrentRetryCount = PackGetInt(p, "CurrentRetryCount");
1331 dlg.RetryLimit = PackGetInt(p, "RetryLimit");
1332 dlg.RetryIntervalSec = PackGetInt(p, "RetryIntervalSec");
1333 dlg.HideWindow = PackGetBool(p, "HideWindow");
1334 dlg.CancelEvent = NewEvent();
1335 dlg.Sock = s;
1336
1337 t = NewThread(Win32CnConnectErrorDlgThreadProc, &dlg);
1338
1339 FreePack(RecvPack(s));
1340
1341 Set(dlg.CancelEvent);
1342
1343 WaitThread(t, INFINITE);
1344 ReleaseEvent(dlg.CancelEvent);
1345 ReleaseThread(t);
1346 }
1347
1348 // Status indicator (Win32)
Win32CnStatusPrinter(SOCK * s,PACK * p)1349 void Win32CnStatusPrinter(SOCK *s, PACK *p)
1350 {
1351 STATUS_WINDOW *w;
1352 wchar_t account_name[MAX_ACCOUNT_NAME_LEN + 1];
1353 // Validate arguments
1354 if (s == NULL || p == NULL)
1355 {
1356 return;
1357 }
1358
1359 PackGetUniStr(p, "account_name", account_name, sizeof(account_name));
1360
1361 w = StatusPrinterWindowStart(s, account_name);
1362
1363 while (true)
1364 {
1365 PACK *p = RecvPack(s);
1366
1367 if (p == NULL)
1368 {
1369 // Exit the dialog because it is disconnected
1370 break;
1371 }
1372 else
1373 {
1374 wchar_t tmp[MAX_SIZE];
1375
1376 // Rewrite the string
1377 PackGetUniStr(p, "string", tmp, sizeof(tmp));
1378
1379 StatusPrinterWindowPrint(w, tmp);
1380
1381 FreePack(p);
1382 }
1383 }
1384
1385 StatusPrinterWindowStop(w);
1386 }
1387
1388 // Start the driver installer (for Windows Vista)
Win32CnExecDriverInstaller(SOCK * s,PACK * p)1389 void Win32CnExecDriverInstaller(SOCK *s, PACK *p)
1390 {
1391 char arg[MAX_SIZE];
1392 bool ret;
1393 void *helper = NULL;
1394 // Validate arguments
1395 if (s == NULL || p == NULL)
1396 {
1397 return;
1398 }
1399
1400 if (PackGetStr(p, "arg", arg, sizeof(arg)) == false)
1401 {
1402 return;
1403 }
1404
1405 helper = CmStartUacHelper();
1406
1407 ret = MsExecDriverInstaller(arg);
1408
1409 CmStopUacHelper(helper);
1410
1411 p = NewPack();
1412 PackAddBool(p, "ret", ret);
1413 SendPack(s, p);
1414
1415 FreePack(p);
1416 }
1417
1418 #endif // OS_WIN32
1419
1420 // Start the driver installer
CnExecDriverInstaller(SOCK * s,PACK * p)1421 void CnExecDriverInstaller(SOCK *s, PACK *p)
1422 {
1423 // Validate arguments
1424 if (s == NULL || p == NULL)
1425 {
1426 return;
1427 }
1428
1429 #ifdef OS_WIN32
1430 Win32CnExecDriverInstaller(s, p);
1431 #endif // OS_WIN32
1432 }
1433
1434 // Certificate confirmation dialog
CnCheckCert(SOCK * s,PACK * p)1435 void CnCheckCert(SOCK *s, PACK *p)
1436 {
1437 // Validate arguments
1438 if (s == NULL || p == NULL)
1439 {
1440 return;
1441 }
1442
1443 #ifdef OS_WIN32
1444 Win32CnCheckCert(s, p);
1445 #endif // OS_WIN32
1446 }
1447
1448 // NIC information dialog
CnNicInfo(SOCK * s,PACK * p)1449 void CnNicInfo(SOCK *s, PACK *p)
1450 {
1451 // Validate arguments
1452 if (s == NULL || p == NULL)
1453 {
1454 return;
1455 }
1456
1457 #ifdef OS_WIN32
1458 Win32CnNicInfo(s, p);
1459 #endif // OS_WIN32
1460 }
1461
1462 // Message display dialog
CnMsgDlg(SOCK * s,PACK * p)1463 void CnMsgDlg(SOCK *s, PACK *p)
1464 {
1465 // Validate arguments
1466 if (s == NULL || p == NULL)
1467 {
1468 return;
1469 }
1470
1471 #ifdef OS_WIN32
1472 Win32CnMsgDlg(s, p);
1473 #endif // OS_WIN32
1474 }
1475
1476 // Password input dialog
CnPasswordDlg(SOCK * s,PACK * p)1477 void CnPasswordDlg(SOCK *s, PACK *p)
1478 {
1479 // Validate arguments
1480 if (s == NULL || p == NULL)
1481 {
1482 return;
1483 }
1484
1485 #ifdef OS_WIN32
1486 Win32CnPasswordDlg(s, p);
1487 #endif // OS_WIN32
1488 }
1489
1490 // Connection Error dialog
CnConnectErrorDlg(SOCK * s,PACK * p)1491 void CnConnectErrorDlg(SOCK *s, PACK *p)
1492 {
1493 // Validate arguments
1494 if (s == NULL || p == NULL)
1495 {
1496 return;
1497 }
1498
1499 #ifdef OS_WIN32
1500 Win32CnConnectErrorDlg(s, p);
1501 #endif // OS_WIN32
1502 }
1503
1504 // Status indicator
CnStatusPrinter(SOCK * s,PACK * p)1505 void CnStatusPrinter(SOCK *s, PACK *p)
1506 {
1507 // Validate arguments
1508 if (s == NULL || p == NULL)
1509 {
1510 return;
1511 }
1512
1513 #ifdef OS_WIN32
1514 Win32CnStatusPrinter(s, p);
1515 #endif // OS_WIN32
1516 }
1517 // Client notification service listener thread
CnListenerProc(THREAD * thread,void * param)1518 void CnListenerProc(THREAD *thread, void *param)
1519 {
1520 TCP_ACCEPTED_PARAM *data = (TCP_ACCEPTED_PARAM *)param;
1521 SOCK *s;
1522 PACK *p;
1523 // Validate arguments
1524 if (data == NULL || thread == NULL)
1525 {
1526 return;
1527 }
1528
1529 #ifdef OS_WIN32
1530 //Set Application ID
1531 JL_SetCurrentProcessExplicitAppUserModelID(APPID_CM);
1532 #endif // OS_WIN32
1533
1534 s = data->s;
1535 AddRef(s->ref);
1536 NoticeThreadInit(thread);
1537
1538 if (IsLocalHostIP(&s->LocalIP))
1539 {
1540 p = RecvPack(s);
1541
1542 if (p != NULL)
1543 {
1544 char function[MAX_SIZE];
1545
1546 if (PackGetStr(p, "function", function, sizeof(function)))
1547 {
1548 if (StrCmpi(function, "status_printer") == 0)
1549 {
1550 CnStatusPrinter(s, p);
1551 }
1552 else if (StrCmpi(function, "connecterror_dialog") == 0)
1553 {
1554 CnConnectErrorDlg(s, p);
1555 }
1556 else if (StrCmpi(function, "msg_dialog") == 0)
1557 {
1558 CnMsgDlg(s, p);
1559 }
1560 else if (StrCmpi(function, "nicinfo") == 0)
1561 {
1562 CnNicInfo(s, p);
1563 }
1564 else if (StrCmpi(function, "password_dialog") == 0)
1565 {
1566 CnPasswordDlg(s, p);
1567 }
1568 else if (StrCmpi(function, "secure_sign") == 0)
1569 {
1570 CnSecureSign(s, p);
1571 }
1572 else if (StrCmpi(function, "check_cert") == 0)
1573 {
1574 CnCheckCert(s, p);
1575 }
1576 else if (StrCmpi(function, "exit") == 0)
1577 {
1578 #ifdef OS_WIN32
1579 MsTerminateProcess();
1580 #else // OS_WIN32
1581 _exit(0);
1582 #endif // OS_WIN32
1583 }
1584 else if (StrCmpi(function, "get_session_id") == 0)
1585 {
1586 PACK *p = NewPack();
1587 #ifdef OS_WIN32
1588 PackAddInt(p, "session_id", MsGetCurrentTerminalSessionId());
1589 #endif // OS_WIN32
1590 SendPack(s, p);
1591 FreePack(p);
1592 }
1593 else if (StrCmpi(function, "exec_driver_installer") == 0)
1594 {
1595 CnExecDriverInstaller(s, p);
1596 }
1597 else if (StrCmpi(function, "release_socket") == 0)
1598 {
1599 // Stop the listener
1600 CnReleaseSocket(s, p);
1601 }
1602 }
1603
1604 FreePack(p);
1605 }
1606 }
1607
1608 Disconnect(s);
1609 ReleaseSock(s);
1610 }
1611
1612 // Do the Secure Sign
CnSecureSign(SOCK * s,PACK * p)1613 void CnSecureSign(SOCK *s, PACK *p)
1614 {
1615 SECURE_SIGN sign;
1616 bool ret = false;
1617 // Validate arguments
1618 if (s == NULL || p == NULL)
1619 {
1620 return;
1621 }
1622
1623 Zero(&sign, sizeof(sign));
1624 InRpcSecureSign(&sign, p);
1625
1626 #ifdef OS_WIN32
1627 // Win32: Show dialog
1628 ret = Win32CiSecureSign(&sign);
1629 #else // OS_WIN32
1630 // UNIX: not implemented
1631 ret = false;
1632 #endif // OS_WIN32
1633
1634 p = NewPack();
1635
1636 OutRpcSecureSign(p, &sign);
1637 FreeRpcSecureSign(&sign);
1638
1639 PackAddBool(p, "ret", ret);
1640
1641 SendPack(s, p);
1642 FreePack(p);
1643 }
1644
1645 // Stop the listener
CnReleaseSocket(SOCK * s,PACK * p)1646 void CnReleaseSocket(SOCK *s, PACK *p)
1647 {
1648 UINT pid = 0;
1649 UINT current_pid = 0;
1650 // Validate arguments
1651 if (s == NULL || p == NULL)
1652 {
1653 return;
1654 }
1655
1656 pid = PackGetInt(p, "pid");
1657
1658 #ifdef OS_WIN32
1659 current_pid = MsGetProcessId();
1660 #endif // OS_WIN32
1661
1662 if (current_pid == pid)
1663 {
1664 return;
1665 }
1666
1667 Lock(cn_listener_lock);
1668 {
1669 if (cn_listener != NULL)
1670 {
1671 if (cn_listener->Halt == false)
1672 {
1673 StopListener(cn_listener);
1674
1675 cn_next_allow = Tick64() + (6 * 1000);
1676 }
1677 }
1678 }
1679 Unlock(cn_listener_lock);
1680 }
1681
1682 // Start the client notification service
CnStart()1683 void CnStart()
1684 {
1685 CEDAR *cedar;
1686 LISTENER *o;
1687 UINT last_cursor_hash = 0;
1688 bool last_session_active = false;
1689
1690 cn_next_allow = 0;
1691 cn_listener_lock = NewLock();
1692
1693 #ifdef OS_WIN32
1694 MsSetShutdownParameters(0xff, 0x00000001);
1695 InitWinUi(_UU("CN_TITLE"), _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE"));
1696 #endif // OS_WIN32
1697
1698 cedar = NewCedar(NULL, NULL);
1699
1700 if (CnCheckAlreadyExists(true))
1701 {
1702 // Already started
1703 ReleaseCedar(cedar);
1704 #ifdef OS_WIN32
1705 FreeWinUi();
1706 #endif // OS_WIN32
1707 return;
1708 }
1709
1710 #ifdef OS_WIN32
1711 MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY,
1712 "NotifyServerProcessId", MsGetProcessId());
1713 #endif // OS_WIN32
1714
1715 DisableDosProtect();
1716
1717 BEGIN_LISTENER:
1718 Lock(cn_listener_lock);
1719 cn_listener = o = NewListenerEx2(cedar, LISTENER_TCP, CLIENT_NOTIFY_PORT, CnListenerProc, NULL, true);
1720 Unlock(cn_listener_lock);
1721
1722 while (true)
1723 {
1724 UINT current_cursor_hash = 0;
1725 bool cursor_changed = false;
1726
1727 #ifdef OS_WIN32
1728 // Get the current cursor position
1729 current_cursor_hash = MsGetCursorPosHash();
1730 #endif // OS_WIN32
1731
1732 if (last_cursor_hash != current_cursor_hash)
1733 {
1734 // Check the cursor position
1735 cursor_changed = true;
1736 last_cursor_hash = current_cursor_hash;
1737 }
1738
1739 Lock(cn_listener_lock);
1740
1741 // Check the status periodically after that the listener has started
1742 if (cn_listener->Status == LISTENER_STATUS_TRYING || cn_listener->Halt)
1743 {
1744 bool session_active = false;
1745 #ifdef OS_WIN32
1746 session_active = MsIsCurrentTerminalSessionActive();
1747 if (cursor_changed)
1748 {
1749 // If the cursor position is changed but the terminal session is
1750 // not active, the cursor position is regarded as not changed.
1751 if (session_active == false)
1752 {
1753 cursor_changed = false;
1754 }
1755 }
1756 if (last_session_active != session_active)
1757 {
1758 //If the cursor position doesn't changed but the terminal session
1759 // became active than previous, the cursor position is regarded as changed.
1760 last_session_active = session_active;
1761
1762 if (session_active)
1763 {
1764 cursor_changed = true;
1765 }
1766 }
1767 #endif // OS_WIN32
1768
1769 // If the port cannot be opened
1770 if (cn_next_allow <= Tick64())
1771 {
1772 #ifdef OS_WIN32
1773 if (cursor_changed)
1774 {
1775 // It can be judged to have the rights to open the port
1776 // since the mouse cursor is moving.
1777 // So, take over the port which is owned by other process forcibly
1778 CncReleaseSocket();
1779 }
1780 #endif // OS_WIN32
1781
1782 if (cn_listener->Halt)
1783 {
1784 ReleaseListener(cn_listener);
1785 cn_listener = NULL;
1786
1787 Unlock(cn_listener_lock);
1788 goto BEGIN_LISTENER;
1789 }
1790 }
1791 }
1792
1793 Unlock(cn_listener_lock);
1794
1795 SleepThread(1000);
1796 }
1797 }
1798
1799 // Confirm whether the account file is parsed successfully
CiTryToParseAccount(BUF * b)1800 bool CiTryToParseAccount(BUF *b)
1801 {
1802 RPC_CLIENT_CREATE_ACCOUNT *a;
1803 // Validate arguments
1804 if (b == NULL)
1805 {
1806 return false;
1807 }
1808
1809 a = CiCfgToAccount(b);
1810 if (a != NULL)
1811 {
1812 CiFreeClientCreateAccount(a);
1813 Free(a);
1814
1815 return true;
1816 }
1817 else
1818 {
1819 return false;
1820 }
1821 }
CiTryToParseAccountFile(wchar_t * name)1822 bool CiTryToParseAccountFile(wchar_t *name)
1823 {
1824 bool ret;
1825 BUF *b;
1826 // Validate arguments
1827 if (name == NULL)
1828 {
1829 return false;
1830 }
1831
1832 b = ReadDumpW(name);
1833 if (b == NULL)
1834 {
1835 return false;
1836 }
1837
1838 ret = CiTryToParseAccount(b);
1839
1840 FreeBuf(b);
1841
1842 return ret;
1843 }
1844
1845 // Confirm whether the account information includes sensitive information
CiHasAccountSensitiveInformation(BUF * b)1846 bool CiHasAccountSensitiveInformation(BUF *b)
1847 {
1848 RPC_CLIENT_CREATE_ACCOUNT *a;
1849 bool ret = false;
1850 // Validate arguments
1851 if (b == NULL)
1852 {
1853 return false;
1854 }
1855
1856 a = CiCfgToAccount(b);
1857 if (a == NULL)
1858 {
1859 return false;
1860 }
1861
1862 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_PASSWORD)
1863 {
1864 ret = true;
1865 }
1866 else if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_PLAIN_PASSWORD)
1867 {
1868 ret = true;
1869 }
1870
1871 CiFreeClientCreateAccount(a);
1872 Free(a);
1873
1874 return ret;
1875 }
1876
1877 // Delete the sensitive information in the account information
CiEraseSensitiveInAccount(BUF * b)1878 bool CiEraseSensitiveInAccount(BUF *b)
1879 {
1880 RPC_CLIENT_CREATE_ACCOUNT *a;
1881 BUF *b2;
1882 bool ret = false;
1883 // Validate arguments
1884 if (b == NULL)
1885 {
1886 return false;
1887 }
1888
1889 a = CiCfgToAccount(b);
1890 if (a == NULL)
1891 {
1892 return false;
1893 }
1894
1895 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_PASSWORD)
1896 {
1897 Zero(a->ClientAuth->HashedPassword, sizeof(a->ClientAuth->HashedPassword));
1898 ClearStr(a->ClientAuth->Username, sizeof(a->ClientAuth->Username));
1899 }
1900 else if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_PLAIN_PASSWORD)
1901 {
1902 ClearStr(a->ClientAuth->PlainPassword, sizeof(a->ClientAuth->PlainPassword));
1903 ClearStr(a->ClientAuth->Username, sizeof(a->ClientAuth->Username));
1904 }
1905
1906 b2 = CiAccountToCfg(a);
1907 if (b2 != NULL)
1908 {
1909 ret = true;
1910
1911 ClearBuf(b);
1912
1913 WriteBuf(b, b2->Buf, b2->Size);
1914 SeekBuf(b, 0, 0);
1915
1916 FreeBuf(b2);
1917 }
1918
1919 CiFreeClientCreateAccount(a);
1920 Free(a);
1921
1922 return ret;
1923 }
1924
1925 // Read the account information from the buffer
CiCfgToAccount(BUF * b)1926 RPC_CLIENT_CREATE_ACCOUNT *CiCfgToAccount(BUF *b)
1927 {
1928 RPC_CLIENT_CREATE_ACCOUNT *t;
1929 FOLDER *f;
1930 ACCOUNT *a;
1931 // Validate arguments
1932 if (b == NULL)
1933 {
1934 return NULL;
1935 }
1936
1937 f = CfgBufTextToFolder(b);
1938 if (f == NULL)
1939 {
1940 return NULL;
1941 }
1942
1943 a = CiLoadClientAccount(f);
1944
1945 CfgDeleteFolder(f);
1946
1947 if (a == NULL)
1948 {
1949 return NULL;
1950 }
1951
1952 DeleteLock(a->lock);
1953
1954 t = ZeroMalloc(sizeof(RPC_CLIENT_CREATE_ACCOUNT));
1955 t->ClientOption = a->ClientOption;
1956 t->ClientAuth = a->ClientAuth;
1957 t->StartupAccount = a->StartupAccount;
1958 t->CheckServerCert = a->CheckServerCert;
1959 t->RetryOnServerCert = a->RetryOnServerCert;
1960 t->ServerCert = a->ServerCert;
1961 Free(a);
1962
1963 return t;
1964 }
1965
1966 // Write the account information to a buffer
CiAccountToCfg(RPC_CLIENT_CREATE_ACCOUNT * t)1967 BUF *CiAccountToCfg(RPC_CLIENT_CREATE_ACCOUNT *t)
1968 {
1969 BUF *b;
1970 FOLDER *root;
1971 ACCOUNT a;
1972 // Validate arguments
1973 if (t == NULL)
1974 {
1975 return NULL;
1976 }
1977
1978 root = CfgCreateFolder(NULL, TAG_ROOT);
1979 Zero(&a, sizeof(a));
1980 a.ClientOption = t->ClientOption;
1981 a.ClientAuth = t->ClientAuth;
1982 a.CheckServerCert = t->CheckServerCert;
1983 a.RetryOnServerCert = t->RetryOnServerCert;
1984 a.ServerCert = t->ServerCert;
1985 a.StartupAccount = t->StartupAccount;
1986
1987 CiWriteAccountData(root, &a);
1988
1989 b = CfgFolderToBufEx(root, true, true);
1990 CfgDeleteFolder(root);
1991
1992 return b;
1993 }
1994
1995 // RPC dispatch routine
CiRpcDispatch(RPC * rpc,char * name,PACK * p)1996 PACK *CiRpcDispatch(RPC *rpc, char *name, PACK *p)
1997 {
1998 PACK *ret;
1999 CLIENT *c;
2000 // Validate arguments
2001 if (rpc == NULL || name == NULL || p == NULL)
2002 {
2003 return NULL;
2004 }
2005 c = rpc->Param;
2006
2007 ret = NewPack();
2008
2009 if (StrCmpi(name, "GetClientVersion") == 0)
2010 {
2011 RPC_CLIENT_VERSION a;
2012 if (CtGetClientVersion(c, &a) == false)
2013 {
2014 RpcError(ret, c->Err);
2015 }
2016 else
2017 {
2018 OutRpcClientVersion(ret, &a);
2019 }
2020 }
2021 else if (StrCmpi(name, "GetCmSetting") == 0)
2022 {
2023 CM_SETTING a;
2024 if (CtGetCmSetting(c, &a) == false)
2025 {
2026 RpcError(ret, c->Err);
2027 }
2028 else
2029 {
2030 OutRpcCmSetting(ret, &a);
2031 }
2032 }
2033 else if (StrCmpi(name, "SetCmSetting") == 0)
2034 {
2035 CM_SETTING a;
2036 Zero(&a, sizeof(a));
2037 InRpcCmSetting(&a, p);
2038 if (CtSetCmSetting(c, &a) == false)
2039 {
2040 RpcError(ret, c->Err);
2041 }
2042 }
2043 else if (StrCmpi(name, "SetPassword") == 0)
2044 {
2045 RPC_CLIENT_PASSWORD a;
2046 InRpcClientPassword(&a, p);
2047 if (CtSetPassword(c, &a) == false)
2048 {
2049 RpcError(ret, c->Err);
2050 }
2051 }
2052 else if (StrCmpi(name, "GetPasswordSetting") == 0)
2053 {
2054 RPC_CLIENT_PASSWORD_SETTING a;
2055 if (CtGetPasswordSetting(c, &a) == false)
2056 {
2057 RpcError(ret, c->Err);
2058 }
2059 else
2060 {
2061 OutRpcClientPasswordSetting(ret, &a);
2062 }
2063 }
2064 else if (StrCmpi(name, "EnumCa") == 0)
2065 {
2066 RPC_CLIENT_ENUM_CA a;
2067 if (CtEnumCa(c, &a) == false)
2068 {
2069 RpcError(ret, c->Err);
2070 }
2071 else
2072 {
2073 OutRpcClientEnumCa(ret, &a);
2074 CiFreeClientEnumCa(&a);
2075 }
2076 }
2077 else if (StrCmpi(name, "AddCa") == 0)
2078 {
2079 RPC_CERT a;
2080 InRpcCert(&a, p);
2081 if (CtAddCa(c, &a) == false)
2082 {
2083 RpcError(ret, c->Err);
2084 }
2085 FreeX(a.x);
2086 }
2087 else if (StrCmpi(name, "DeleteCa") == 0)
2088 {
2089 RPC_CLIENT_DELETE_CA a;
2090 InRpcClientDeleteCa(&a, p);
2091 if (CtDeleteCa(c, &a) == false)
2092 {
2093 RpcError(ret, c->Err);
2094 }
2095 }
2096 else if (StrCmpi(name, "GetCa") == 0)
2097 {
2098 RPC_GET_CA a;
2099 InRpcGetCa(&a, p);
2100 if (CtGetCa(c, &a) == false)
2101 {
2102 RpcError(ret, c->Err);
2103 }
2104 else
2105 {
2106 OutRpcGetCa(ret, &a);
2107 }
2108 CiFreeGetCa(&a);
2109 }
2110 else if (StrCmpi(name, "EnumSecure") == 0)
2111 {
2112 RPC_CLIENT_ENUM_SECURE a;
2113 if (CtEnumSecure(c, &a) == false)
2114 {
2115 RpcError(ret, c->Err);
2116 }
2117 else
2118 {
2119 OutRpcClientEnumSecure(ret, &a);
2120 CiFreeClientEnumSecure(&a);
2121 }
2122 }
2123 else if (StrCmpi(name, "UseSecure") == 0)
2124 {
2125 RPC_USE_SECURE a;
2126 InRpcUseSecure(&a, p);
2127 if (CtUseSecure(c, &a) == false)
2128 {
2129 RpcError(ret, c->Err);
2130 }
2131 }
2132 else if (StrCmpi(name, "GetUseSecure") == 0)
2133 {
2134 RPC_USE_SECURE a;
2135 Zero(&a, sizeof(a));
2136 if (CtGetUseSecure(c, &a) == false)
2137 {
2138 RpcError(ret, c->Err);
2139 }
2140 else
2141 {
2142 OutRpcUseSecure(ret, &a);
2143 }
2144 }
2145 else if (StrCmpi(name, "EnumObjectInSecure") == 0)
2146 {
2147 RPC_ENUM_OBJECT_IN_SECURE a;
2148 if (CtEnumObjectInSecure(c, &a) == false)
2149 {
2150 RpcError(ret, c->Err);
2151 }
2152 else
2153 {
2154 OutRpcEnumObjectInSecure(ret, &a);
2155 CiFreeEnumObjectInSecure(&a);
2156 }
2157 }
2158 else if (StrCmpi(name, "CreateVLan") == 0)
2159 {
2160 RPC_CLIENT_CREATE_VLAN a;
2161 InRpcCreateVLan(&a, p);
2162 if (CtCreateVLan(c, &a) == false)
2163 {
2164 RpcError(ret, c->Err);
2165 }
2166 }
2167 else if (StrCmpi(name, "UpgradeVLan") == 0)
2168 {
2169 RPC_CLIENT_CREATE_VLAN a;
2170 InRpcCreateVLan(&a, p);
2171 if (CtUpgradeVLan(c, &a) == false)
2172 {
2173 RpcError(ret, c->Err);
2174 }
2175 }
2176 else if (StrCmpi(name, "GetVLan") == 0)
2177 {
2178 RPC_CLIENT_GET_VLAN a;
2179 InRpcClientGetVLan(&a, p);
2180 if (CtGetVLan(c, &a) == false)
2181 {
2182 RpcError(ret, c->Err);
2183 }
2184 else
2185 {
2186 OutRpcClientGetVLan(ret, &a);
2187 }
2188 }
2189 else if (StrCmpi(name, "SetVLan") == 0)
2190 {
2191 RPC_CLIENT_SET_VLAN a;
2192 InRpcClientSetVLan(&a, p);
2193 if (CtSetVLan(c, &a) == false)
2194 {
2195 RpcError(ret, c->Err);
2196 }
2197 }
2198 else if (StrCmpi(name, "EnumVLan") == 0)
2199 {
2200 RPC_CLIENT_ENUM_VLAN a;
2201 if (CtEnumVLan(c, &a) == false)
2202 {
2203 RpcError(ret, c->Err);
2204 }
2205 else
2206 {
2207 OutRpcClientEnumVLan(ret, &a);
2208 CiFreeClientEnumVLan(&a);
2209 }
2210 }
2211 else if (StrCmpi(name, "DeleteVLan") == 0)
2212 {
2213 RPC_CLIENT_CREATE_VLAN a;
2214 InRpcCreateVLan(&a, p);
2215 if (CtDeleteVLan(c, &a) == false)
2216 {
2217 RpcError(ret, c->Err);
2218 }
2219 }
2220 else if (StrCmpi(name, "EnableVLan") == 0)
2221 {
2222 RPC_CLIENT_CREATE_VLAN a;
2223 InRpcCreateVLan(&a, p);
2224 if (CtEnableVLan(c, &a) == false)
2225 {
2226 RpcError(ret, c->Err);
2227 }
2228 }
2229 else if (StrCmpi(name, "DisableVLan") == 0)
2230 {
2231 RPC_CLIENT_CREATE_VLAN a;
2232 InRpcCreateVLan(&a, p);
2233 if (CtDisableVLan(c, &a) == false)
2234 {
2235 RpcError(ret, c->Err);
2236 }
2237 }
2238 else if (StrCmpi(name, "CreateAccount") == 0)
2239 {
2240 RPC_CLIENT_CREATE_ACCOUNT a;
2241 InRpcClientCreateAccount(&a, p);
2242 if (CtCreateAccount(c, &a, false) == false)
2243 {
2244 RpcError(ret, c->Err);
2245 }
2246 CiFreeClientCreateAccount(&a);
2247 }
2248 else if (StrCmpi(name, "EnumAccount") == 0)
2249 {
2250 RPC_CLIENT_ENUM_ACCOUNT a;
2251 if (CtEnumAccount(c, &a) == false)
2252 {
2253 RpcError(ret, c->Err);
2254 }
2255 else
2256 {
2257 OutRpcClientEnumAccount(ret, &a);
2258 CiFreeClientEnumAccount(&a);
2259 }
2260 }
2261 else if (StrCmpi(name, "DeleteAccount") == 0)
2262 {
2263 RPC_CLIENT_DELETE_ACCOUNT a;
2264 InRpcClientDeleteAccount(&a, p);
2265 if (CtDeleteAccount(c, &a, false) == false)
2266 {
2267 RpcError(ret, c->Err);
2268 }
2269 }
2270 else if (StrCmpi(name, "SetStartupAccount") == 0)
2271 {
2272 RPC_CLIENT_DELETE_ACCOUNT a;
2273 InRpcClientDeleteAccount(&a, p);
2274 if (CtSetStartupAccount(c, &a, false) == false)
2275 {
2276 RpcError(ret, c->Err);
2277 }
2278 }
2279 else if (StrCmpi(name, "RemoveStartupAccount") == 0)
2280 {
2281 RPC_CLIENT_DELETE_ACCOUNT a;
2282 InRpcClientDeleteAccount(&a, p);
2283 if (CtRemoveStartupAccount(c, &a) == false)
2284 {
2285 RpcError(ret, c->Err);
2286 }
2287 }
2288 else if (StrCmpi(name, "GetIssuer") == 0)
2289 {
2290 RPC_GET_ISSUER a;
2291 InRpcGetIssuer(&a, p);
2292 if (CtGetIssuer(c, &a))
2293 {
2294 OutRpcGetIssuer(ret, &a);
2295 }
2296 else
2297 {
2298 RpcError(ret, c->Err);
2299 }
2300 CiFreeGetIssuer(&a);
2301 }
2302 else if (StrCmpi(name, "GetCommonProxySetting") == 0)
2303 {
2304 INTERNET_SETTING t;
2305 InRpcInternetSetting(&t, p);
2306 if (CtGetCommonProxySetting(c, &t))
2307 {
2308 OutRpcInternetSetting(ret, &t);
2309 }
2310 else
2311 {
2312 RpcError(ret, c->Err);
2313 }
2314 }
2315 else if (StrCmpi(name, "SetCommonProxySetting") == 0)
2316 {
2317 INTERNET_SETTING t;
2318 InRpcInternetSetting(&t, p);
2319 if (CtSetCommonProxySetting(c, &t))
2320 {
2321 OutRpcInternetSetting(ret, &t);
2322 }
2323 else
2324 {
2325 RpcError(ret, c->Err);
2326 }
2327 }
2328 else if (StrCmpi(name, "SetAccount") == 0)
2329 {
2330 RPC_CLIENT_CREATE_ACCOUNT a;
2331 InRpcClientCreateAccount(&a, p);
2332 if (CtSetAccount(c, &a, false) == false)
2333 {
2334 RpcError(ret, c->Err);
2335 }
2336 CiFreeClientCreateAccount(&a);
2337 }
2338 else if (StrCmpi(name, "GetAccount") == 0)
2339 {
2340 RPC_CLIENT_GET_ACCOUNT a;
2341 InRpcClientGetAccount(&a, p);
2342 if (CtGetAccount(c, &a) == false)
2343 {
2344 RpcError(ret, c->Err);
2345 }
2346 else
2347 {
2348 OutRpcClientGetAccount(ret, &a);
2349 }
2350 CiFreeClientGetAccount(&a);
2351 }
2352 else if (StrCmpi(name, "RenameAccount") == 0)
2353 {
2354 RPC_RENAME_ACCOUNT a;
2355 InRpcRenameAccount(&a, p);
2356 if (CtRenameAccount(c, &a, false) == false)
2357 {
2358 RpcError(ret, c->Err);
2359 }
2360 }
2361 else if (StrCmpi(name, "SetClientConfig") == 0)
2362 {
2363 CLIENT_CONFIG a;
2364 InRpcClientConfig(&a, p);
2365 if (CtSetClientConfig(c, &a) == false)
2366 {
2367 RpcError(ret, c->Err);
2368 }
2369 }
2370 else if (StrCmpi(name, "GetClientConfig") == 0)
2371 {
2372 CLIENT_CONFIG a;
2373 if (CtGetClientConfig(c, &a) == false)
2374 {
2375 RpcError(ret, c->Err);
2376 }
2377 else
2378 {
2379 OutRpcClientConfig(ret, &a);
2380 }
2381 }
2382 else if (StrCmpi(name, "Connect") == 0)
2383 {
2384 RPC_CLIENT_CONNECT a;
2385 InRpcClientConnect(&a, p);
2386 if (CtConnect(c, &a) == false)
2387 {
2388 RpcError(ret, c->Err);
2389 }
2390 }
2391 else if (StrCmpi(name, "Disconnect") == 0)
2392 {
2393 RPC_CLIENT_CONNECT a;
2394 InRpcClientConnect(&a, p);
2395 if (CtDisconnect(c, &a, false) == false)
2396 {
2397 RpcError(ret, c->Err);
2398 }
2399 }
2400 else if (StrCmpi(name, "GetAccountStatus") == 0)
2401 {
2402 RPC_CLIENT_GET_CONNECTION_STATUS a;
2403 InRpcClientGetConnectionStatus(&a, p);
2404 if (CtGetAccountStatus(c, &a) == false)
2405 {
2406 RpcError(ret, c->Err);
2407 }
2408 else
2409 {
2410 OutRpcClientGetConnectionStatus(ret, &a);
2411 }
2412 CiFreeClientGetConnectionStatus(&a);
2413 }
2414 else
2415 {
2416 FreePack(ret);
2417 ret = NULL;
2418 }
2419
2420 return ret;
2421 }
2422
2423 // Set the CM_SETTING
CcSetCmSetting(REMOTE_CLIENT * r,CM_SETTING * a)2424 UINT CcSetCmSetting(REMOTE_CLIENT *r, CM_SETTING *a)
2425 {
2426 PACK *ret, *p;
2427 UINT err;
2428 // Validate arguments
2429 if (r == NULL || a == NULL)
2430 {
2431 return ERR_INTERNAL_ERROR;
2432 }
2433
2434 p = NewPack();
2435 OutRpcCmSetting(p, a);
2436
2437 ret = RpcCall(r->Rpc, "SetCmSetting", p);
2438
2439 if (RpcIsOk(ret))
2440 {
2441 FreePack(ret);
2442 return 0;
2443 }
2444 else
2445 {
2446 err = RpcGetError(ret);
2447 FreePack(ret);
2448 return err;
2449 }
2450 }
2451
2452 // Get the CM_SETTING
CcGetCmSetting(REMOTE_CLIENT * r,CM_SETTING * a)2453 UINT CcGetCmSetting(REMOTE_CLIENT *r, CM_SETTING *a)
2454 {
2455 PACK *ret;
2456 // Validate arguments
2457 if (r == NULL || a == NULL)
2458 {
2459 return ERR_INTERNAL_ERROR;
2460 }
2461
2462 ret = RpcCall(r->Rpc, "GetCmSetting", NULL);
2463
2464 if (RpcIsOk(ret))
2465 {
2466 InRpcCmSetting(a, ret);
2467 FreePack(ret);
2468 return 0;
2469 }
2470 else
2471 {
2472 UINT err = RpcGetError(ret);
2473 FreePack(ret);
2474 return err;
2475 }
2476 }
2477
2478 // Get the client version
CcGetClientVersion(REMOTE_CLIENT * r,RPC_CLIENT_VERSION * a)2479 UINT CcGetClientVersion(REMOTE_CLIENT *r, RPC_CLIENT_VERSION *a)
2480 {
2481 PACK *ret;
2482 // Validate arguments
2483 if (r == NULL || a == NULL)
2484 {
2485 return ERR_INTERNAL_ERROR;
2486 }
2487
2488 ret = RpcCall(r->Rpc, "GetClientVersion", NULL);
2489
2490 if (RpcIsOk(ret))
2491 {
2492 InRpcClientVersion(a, ret);
2493 FreePack(ret);
2494 return 0;
2495 }
2496 else
2497 {
2498 UINT err = RpcGetError(ret);
2499 FreePack(ret);
2500 return err;
2501 }
2502 }
2503
2504 // Set the password
CcSetPassword(REMOTE_CLIENT * r,RPC_CLIENT_PASSWORD * pass)2505 UINT CcSetPassword(REMOTE_CLIENT *r, RPC_CLIENT_PASSWORD *pass)
2506 {
2507 PACK *ret, *p;
2508 // Validate arguments
2509 if (r == NULL || pass == NULL)
2510 {
2511 return ERR_INTERNAL_ERROR;
2512 }
2513
2514 p = NewPack();
2515
2516 OutRpcClientPassword(p, pass);
2517
2518 ret = RpcCall(r->Rpc, "SetPassword", p);
2519
2520 if (RpcIsOk(ret))
2521 {
2522 FreePack(ret);
2523 return 0;
2524 }
2525 else
2526 {
2527 UINT err = RpcGetError(ret);
2528 FreePack(ret);
2529 return err;
2530 }
2531 }
2532
2533 // Get the password setting
CcGetPasswordSetting(REMOTE_CLIENT * r,RPC_CLIENT_PASSWORD_SETTING * a)2534 UINT CcGetPasswordSetting(REMOTE_CLIENT *r, RPC_CLIENT_PASSWORD_SETTING *a)
2535 {
2536 PACK *ret;
2537 UINT err = 0;
2538 // Validate arguments
2539 if (r == NULL || a == NULL)
2540 {
2541 return ERR_INTERNAL_ERROR;
2542 }
2543
2544 ret = RpcCall(r->Rpc, "GetPasswordSetting", NULL);
2545
2546 if (RpcIsOk(ret))
2547 {
2548 InRpcClientPasswordSetting(a, ret);
2549 }
2550 else
2551 {
2552 err = RpcGetError(ret);
2553 }
2554
2555 FreePack(ret);
2556 return err;
2557 }
2558
2559 // Enumerate the CA
CcEnumCa(REMOTE_CLIENT * r,RPC_CLIENT_ENUM_CA * e)2560 UINT CcEnumCa(REMOTE_CLIENT *r, RPC_CLIENT_ENUM_CA *e)
2561 {
2562 PACK *ret;
2563 UINT err = 0;
2564 // Validate arguments
2565 if (r == NULL || e == NULL)
2566 {
2567 return ERR_INTERNAL_ERROR;
2568 }
2569
2570 ret = RpcCall(r->Rpc, "EnumCa", NULL);
2571
2572 if (RpcIsOk(ret))
2573 {
2574 InRpcClientEnumCa(e, ret);
2575 }
2576 else
2577 {
2578 err = RpcGetError(ret);
2579 }
2580
2581 FreePack(ret);
2582
2583 return err;
2584 }
2585
2586 // Add the CA
CcAddCa(REMOTE_CLIENT * r,RPC_CERT * cert)2587 UINT CcAddCa(REMOTE_CLIENT *r, RPC_CERT *cert)
2588 {
2589 PACK *p, *ret;
2590 UINT err = 0;
2591 // Validate arguments
2592 if (r == NULL || cert == NULL)
2593 {
2594 return ERR_INTERNAL_ERROR;
2595 }
2596
2597 p = NewPack();
2598 OutRpcCert(p, cert);
2599
2600 ret = RpcCall(r->Rpc, "AddCa", p);
2601
2602 if (RpcIsOk(ret) == false)
2603 {
2604 err = RpcGetError(ret);
2605 }
2606
2607 FreePack(ret);
2608
2609 return err;
2610 }
2611
2612 // Delete the CA
CcDeleteCa(REMOTE_CLIENT * r,RPC_CLIENT_DELETE_CA * c)2613 UINT CcDeleteCa(REMOTE_CLIENT *r, RPC_CLIENT_DELETE_CA *c)
2614 {
2615 PACK *p, *ret;
2616 UINT err = 0;
2617 // Validate arguments
2618 if (r == NULL || c == NULL)
2619 {
2620 return ERR_INTERNAL_ERROR;
2621 }
2622
2623 p = NewPack();
2624 OutRpcClientDeleteCa(p, c);
2625
2626 ret = RpcCall(r->Rpc, "DeleteCa", p);
2627
2628 if (RpcIsOk(ret) == false)
2629 {
2630 err = RpcGetError(ret);
2631 }
2632
2633 FreePack(ret);
2634
2635 return err;
2636 }
2637
2638 // Get the issuer
CcGetIssuer(REMOTE_CLIENT * r,RPC_GET_ISSUER * a)2639 UINT CcGetIssuer(REMOTE_CLIENT *r, RPC_GET_ISSUER *a)
2640 {
2641 PACK *p, *ret;
2642 UINT err = 0;
2643 // Validate arguments
2644 if (r == NULL || a == NULL)
2645 {
2646 return ERR_INTERNAL_ERROR;
2647 }
2648
2649 p = NewPack();
2650 OutRpcGetIssuer(p, a);
2651
2652 ret = RpcCall(r->Rpc, "GetIssuer", p);
2653
2654 if (RpcIsOk(ret))
2655 {
2656 if (a->x != NULL)
2657 {
2658 FreeX(a->x);
2659 a->x = NULL;
2660 }
2661 InRpcGetIssuer(a, ret);
2662 }
2663 else
2664 {
2665 err = RpcGetError(ret);
2666 }
2667
2668 FreePack(ret);
2669
2670 return err;
2671 }
2672
2673 // Get the CA
CcGetCa(REMOTE_CLIENT * r,RPC_GET_CA * get)2674 UINT CcGetCa(REMOTE_CLIENT *r, RPC_GET_CA *get)
2675 {
2676 PACK *p, *ret;
2677 UINT err = 0;
2678 // Validate arguments
2679 if (r == NULL || get == NULL)
2680 {
2681 return ERR_INTERNAL_ERROR;
2682 }
2683
2684 p = NewPack();
2685 OutRpcGetCa(p, get);
2686
2687 ret = RpcCall(r->Rpc, "GetCa", p);
2688
2689 if (RpcIsOk(ret))
2690 {
2691 InRpcGetCa(get, ret);
2692 }
2693 else
2694 {
2695 err = RpcGetError(ret);
2696 }
2697
2698 FreePack(ret);
2699
2700 return err;
2701 }
2702
2703 // Enumeration of the secure devices
CcEnumSecure(REMOTE_CLIENT * r,RPC_CLIENT_ENUM_SECURE * e)2704 UINT CcEnumSecure(REMOTE_CLIENT *r, RPC_CLIENT_ENUM_SECURE *e)
2705 {
2706 PACK *ret;
2707 UINT err = 0;
2708 // Validate arguments
2709 if (r == NULL || e == NULL)
2710 {
2711 return ERR_INTERNAL_ERROR;
2712 }
2713
2714 ret = RpcCall(r->Rpc, "EnumSecure", NULL);
2715
2716 if (RpcIsOk(ret))
2717 {
2718 InRpcClientEnumSecure(e, ret);
2719 }
2720 else
2721 {
2722 err = RpcGetError(ret);
2723 }
2724
2725 FreePack(ret);
2726
2727 return err;
2728 }
2729
2730 // Get the secure device that the user is using
CcGetUseSecure(REMOTE_CLIENT * r,RPC_USE_SECURE * sec)2731 UINT CcGetUseSecure(REMOTE_CLIENT *r, RPC_USE_SECURE *sec)
2732 {
2733 PACK *p, *ret;
2734 UINT err = 0;
2735 // Validate arguments
2736 if (r == NULL || sec == NULL)
2737 {
2738 return ERR_INTERNAL_ERROR;
2739 }
2740
2741 p = NewPack();
2742
2743 ret = RpcCall(r->Rpc, "GetUseSecure", p);
2744
2745 if (RpcIsOk(ret) == false)
2746 {
2747 err = RpcGetError(ret);
2748 }
2749 else
2750 {
2751 InRpcUseSecure(sec, ret);
2752 }
2753
2754 FreePack(ret);
2755
2756 return err;
2757 }
2758
2759 // Use the secure device
CcUseSecure(REMOTE_CLIENT * r,RPC_USE_SECURE * sec)2760 UINT CcUseSecure(REMOTE_CLIENT *r, RPC_USE_SECURE *sec)
2761 {
2762 PACK *p, *ret;
2763 UINT err = 0;
2764 // Validate arguments
2765 if (r == NULL || sec == NULL)
2766 {
2767 return ERR_INTERNAL_ERROR;
2768 }
2769
2770 p = NewPack();
2771 OutRpcUseSecure(p, sec);
2772
2773 ret = RpcCall(r->Rpc, "UseSecure", p);
2774
2775 if (RpcIsOk(ret) == false)
2776 {
2777 err = RpcGetError(ret);
2778 }
2779
2780 FreePack(ret);
2781
2782 return err;
2783 }
2784
2785 // Get a next recommended virtual LAN card name
CiGetNextRecommendedVLanName(REMOTE_CLIENT * r,char * name,UINT size)2786 bool CiGetNextRecommendedVLanName(REMOTE_CLIENT *r, char *name, UINT size)
2787 {
2788 RPC_CLIENT_ENUM_VLAN t;
2789 UINT i;
2790 bool b;
2791 UINT j;
2792 bool ok = false;
2793 // Validate arguments
2794 if (r == NULL || name == NULL)
2795 {
2796 return false;
2797 }
2798
2799 Zero(&t, sizeof(t));
2800
2801 if (CcEnumVLan(r, &t) != ERR_NO_ERROR)
2802 {
2803 return false;
2804 }
2805
2806 for (i = 1;i < 128;i++)
2807 {
2808 char tmp[MAX_SIZE];
2809
2810 CiGenerateVLanRegulatedName(tmp, sizeof(tmp), i);
2811
2812 b = false;
2813
2814 for (j = 0;j < t.NumItem;j++)
2815 {
2816 if (StrCmpi(t.Items[j]->DeviceName, tmp) == 0)
2817 {
2818 b = true;
2819 break;
2820 }
2821 }
2822
2823 if (b == false)
2824 {
2825 ok = true;
2826
2827 StrCpy(name, size, tmp);
2828 break;
2829 }
2830 }
2831
2832 if (ok)
2833 {
2834 CiFreeClientEnumVLan(&t);
2835 }
2836
2837 return true;
2838 }
2839
2840 // Generate a virtual LAN card name automatically
CiGenerateVLanRegulatedName(char * name,UINT size,UINT i)2841 void CiGenerateVLanRegulatedName(char *name, UINT size, UINT i)
2842 {
2843 // Validate arguments
2844 if (name == NULL)
2845 {
2846 return;
2847 }
2848
2849 if (i == 1)
2850 {
2851 StrCpy(name, size, "VPN");
2852 }
2853 else
2854 {
2855 Format(name, size, "VPN%u", i);
2856 }
2857 }
2858
2859 // Examine whether the specified name is valid as a virtual LAN card name of Windows 8 and later?
CiIsValidVLanRegulatedName(char * name)2860 bool CiIsValidVLanRegulatedName(char *name)
2861 {
2862 UINT i;
2863 // Validate arguments
2864 if (name == NULL)
2865 {
2866 return false;
2867 }
2868
2869 for (i = 1;i < 128;i++)
2870 {
2871 char tmp[MAX_SIZE];
2872
2873 CiGenerateVLanRegulatedName(tmp, sizeof(tmp), i);
2874
2875 if (StrCmpi(name, tmp) == 0)
2876 {
2877 return true;
2878 }
2879 }
2880
2881 return false;
2882 }
2883
2884 // Create a VLAN
CcCreateVLan(REMOTE_CLIENT * r,RPC_CLIENT_CREATE_VLAN * create)2885 UINT CcCreateVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *create)
2886 {
2887 PACK *ret, *p;
2888 UINT err = 0;
2889 char *s = NULL;
2890 // Validate arguments
2891 if (r == NULL || create == NULL)
2892 {
2893 return ERR_INTERNAL_ERROR;
2894 }
2895
2896 p = NewPack();
2897 OutRpcCreateVLan(p, create);
2898
2899 #ifdef OS_WIN32
2900 s = MsNoWarningSoundInit();
2901 #endif // OS_WIN32
2902
2903 ret = RpcCall(r->Rpc, "CreateVLan", p);
2904
2905 #ifdef OS_WIN32
2906 MsNoWarningSoundFree(s);
2907 #endif // OS_WIN32
2908
2909 if (RpcIsOk(ret) == false)
2910 {
2911 err = RpcGetError(ret);
2912 }
2913
2914 FreePack(ret);
2915
2916 return err;
2917 }
2918
2919 // Upgrade the VLAN
CcUpgradeVLan(REMOTE_CLIENT * r,RPC_CLIENT_CREATE_VLAN * create)2920 UINT CcUpgradeVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *create)
2921 {
2922 PACK *ret, *p;
2923 UINT err = 0;
2924 char *s = NULL;
2925 // Validate arguments
2926 if (r == NULL || create == NULL)
2927 {
2928 return ERR_INTERNAL_ERROR;
2929 }
2930
2931 p = NewPack();
2932 OutRpcCreateVLan(p, create);
2933
2934 #ifdef OS_WIN32
2935 s = MsNoWarningSoundInit();
2936 #endif // OS_WIN32
2937
2938 ret = RpcCall(r->Rpc, "UpgradeVLan", p);
2939
2940 #ifdef OS_WIN32
2941 MsNoWarningSoundFree(s);
2942 #endif // OS_WIN32
2943
2944
2945 if (RpcIsOk(ret) == false)
2946 {
2947 err = RpcGetError(ret);
2948 }
2949
2950 FreePack(ret);
2951
2952 return err;
2953 }
2954
2955 // Get the VLAN
CcGetVLan(REMOTE_CLIENT * r,RPC_CLIENT_GET_VLAN * get)2956 UINT CcGetVLan(REMOTE_CLIENT *r, RPC_CLIENT_GET_VLAN *get)
2957 {
2958 PACK *ret, *p;
2959 UINT err = 0;
2960 // Validate arguments
2961 if (r == NULL || get == NULL)
2962 {
2963 return ERR_INTERNAL_ERROR;
2964 }
2965
2966 p = NewPack();
2967 OutRpcClientGetVLan(p, get);
2968
2969 ret = RpcCall(r->Rpc, "GetVLan", p);
2970
2971 if (RpcIsOk(ret))
2972 {
2973 InRpcClientGetVLan(get, ret);
2974 }
2975 else
2976 {
2977 err = RpcGetError(ret);
2978 }
2979
2980 FreePack(ret);
2981
2982 return err;
2983 }
2984
2985 // VLAN configuration
CcSetVLan(REMOTE_CLIENT * r,RPC_CLIENT_SET_VLAN * set)2986 UINT CcSetVLan(REMOTE_CLIENT *r, RPC_CLIENT_SET_VLAN *set)
2987 {
2988 PACK *ret, *p;
2989 UINT err = 0;
2990 // Validate arguments
2991 if (r == NULL || set == NULL)
2992 {
2993 return ERR_INTERNAL_ERROR;
2994 }
2995
2996 p = NewPack();
2997 OutRpcClientSetVLan(p, set);
2998
2999 ret = RpcCall(r->Rpc, "SetVLan", p);
3000
3001 if (RpcIsOk(ret) == false)
3002 {
3003 err = RpcGetError(ret);
3004 }
3005
3006 FreePack(ret);
3007
3008 return err;
3009 }
3010
3011 // Enumeration of VLAN
CcEnumVLan(REMOTE_CLIENT * r,RPC_CLIENT_ENUM_VLAN * e)3012 UINT CcEnumVLan(REMOTE_CLIENT *r, RPC_CLIENT_ENUM_VLAN *e)
3013 {
3014 PACK *ret;
3015 UINT err = 0;
3016 // Validate arguments
3017 if (r == NULL || e == NULL)
3018 {
3019 return ERR_INTERNAL_ERROR;
3020 }
3021
3022 ret = RpcCall(r->Rpc, "EnumVLan", NULL);
3023
3024 if (RpcIsOk(ret))
3025 {
3026 InRpcClientEnumVLan(e, ret);
3027 }
3028 else
3029 {
3030 err = RpcGetError(ret);
3031 }
3032
3033 FreePack(ret);
3034
3035 return err;
3036 }
3037
3038 // Delete the VLAN
CcDeleteVLan(REMOTE_CLIENT * r,RPC_CLIENT_CREATE_VLAN * d)3039 UINT CcDeleteVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *d)
3040 {
3041 PACK *ret, *p;
3042 UINT err = 0;
3043 // Validate arguments
3044 if (r == NULL || d == NULL)
3045 {
3046 return ERR_INTERNAL_ERROR;
3047 }
3048
3049 p = NewPack();
3050 OutRpcCreateVLan(p, d);
3051
3052 ret = RpcCall(r->Rpc, "DeleteVLan", p);
3053
3054 if (RpcIsOk(ret) == false)
3055 {
3056 err = RpcGetError(ret);
3057 }
3058
3059 FreePack(ret);
3060
3061 return err;
3062 }
3063
3064 // Enable the VLAN
CcEnableVLan(REMOTE_CLIENT * r,RPC_CLIENT_CREATE_VLAN * vlan)3065 UINT CcEnableVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *vlan)
3066 {
3067 PACK *ret, *p;
3068 UINT err = 0;
3069 // Validate arguments
3070 if (r == NULL || vlan == NULL)
3071 {
3072 return ERR_INTERNAL_ERROR;
3073 }
3074
3075 p = NewPack();
3076 OutRpcCreateVLan(p, vlan);
3077
3078 ret = RpcCall(r->Rpc, "EnableVLan", p);
3079
3080 if (RpcIsOk(ret) == false)
3081 {
3082 err = RpcGetError(ret);
3083 }
3084
3085 FreePack(ret);
3086
3087 return err;
3088 }
3089
3090 // Disable the VLAN
CcDisableVLan(REMOTE_CLIENT * r,RPC_CLIENT_CREATE_VLAN * vlan)3091 UINT CcDisableVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *vlan)
3092 {
3093 PACK *ret, *p;
3094 UINT err = 0;
3095 // Validate arguments
3096 if (r == NULL || vlan == NULL)
3097 {
3098 return ERR_INTERNAL_ERROR;
3099 }
3100
3101 p = NewPack();
3102 OutRpcCreateVLan(p, vlan);
3103
3104 ret = RpcCall(r->Rpc, "DisableVLan", p);
3105
3106 if (RpcIsOk(ret) == false)
3107 {
3108 err = RpcGetError(ret);
3109 }
3110
3111 FreePack(ret);
3112
3113 return err;
3114 }
3115
3116 // Create an Account
CcCreateAccount(REMOTE_CLIENT * r,RPC_CLIENT_CREATE_ACCOUNT * a)3117 UINT CcCreateAccount(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_ACCOUNT *a)
3118 {
3119 PACK *ret, *p;
3120 UINT err = 0;
3121 // Validate arguments
3122 if (r == NULL || a == NULL)
3123 {
3124 return ERR_INTERNAL_ERROR;
3125 }
3126
3127 p = NewPack();
3128 OutRpcClientCreateAccount(p, a);
3129
3130 ret = RpcCall(r->Rpc, "CreateAccount", p);
3131
3132 if (RpcIsOk(ret) == false)
3133 {
3134 err = RpcGetError(ret);
3135 }
3136
3137 FreePack(ret);
3138
3139 return err;
3140 }
3141
3142 // Enumeration of accounts
CcEnumAccount(REMOTE_CLIENT * r,RPC_CLIENT_ENUM_ACCOUNT * e)3143 UINT CcEnumAccount(REMOTE_CLIENT *r, RPC_CLIENT_ENUM_ACCOUNT *e)
3144 {
3145 PACK *ret;
3146 UINT err = 0;
3147 // Validate arguments
3148 if (r == NULL || e == NULL)
3149 {
3150 return ERR_INTERNAL_ERROR;
3151 }
3152
3153 ret = RpcCall(r->Rpc, "EnumAccount", NULL);
3154
3155 if (RpcIsOk(ret))
3156 {
3157 UINT i;
3158 InRpcClientEnumAccount(e, ret);
3159
3160 for (i = 0;i < e->NumItem;i++)
3161 {
3162 RPC_CLIENT_ENUM_ACCOUNT_ITEM *t = e->Items[i];
3163
3164 if (IsEmptyStr(t->HubName) && t->Port == 0)
3165 {
3166 UINT err2;
3167 RPC_CLIENT_GET_ACCOUNT a;
3168
3169 // Because the Client Manager can not get the port number and HUB name
3170 // when enumerating in the VPN Client of the old version, get these separately.
3171 Zero(&a, sizeof(a));
3172 UniStrCpy(a.AccountName, sizeof(a.AccountName), t->AccountName);
3173 err2 = CcGetAccount(r, &a);
3174 if (err2 == ERR_NO_ERROR)
3175 {
3176 StrCpy(t->HubName, sizeof(t->HubName), a.ClientOption->HubName);
3177 t->Port = a.ClientOption->Port;
3178
3179 CiFreeClientGetAccount(&a);
3180 }
3181 }
3182 }
3183 }
3184 else
3185 {
3186 err = RpcGetError(ret);
3187 }
3188
3189 FreePack(ret);
3190
3191 return err;
3192 }
3193
3194 // Unset the startup flag of the account
CcRemoveStartupAccount(REMOTE_CLIENT * r,RPC_CLIENT_DELETE_ACCOUNT * a)3195 UINT CcRemoveStartupAccount(REMOTE_CLIENT *r, RPC_CLIENT_DELETE_ACCOUNT *a)
3196 {
3197 PACK *ret, *p;
3198 UINT err = 0;
3199 // Validate arguments
3200 if (r == NULL || a == NULL)
3201 {
3202 return ERR_INTERNAL_ERROR;
3203 }
3204
3205 p = NewPack();
3206 OutRpcClientDeleteAccount(p, a);
3207
3208 ret = RpcCall(r->Rpc, "RemoveStartupAccount", p);
3209
3210 if (RpcIsOk(ret) == false)
3211 {
3212 err = RpcGetError(ret);
3213 }
3214
3215 FreePack(ret);
3216
3217 return err;
3218 }
3219
3220 // Set to start-up flag of the account
CcSetStartupAccount(REMOTE_CLIENT * r,RPC_CLIENT_DELETE_ACCOUNT * a)3221 UINT CcSetStartupAccount(REMOTE_CLIENT *r, RPC_CLIENT_DELETE_ACCOUNT *a)
3222 {
3223 PACK *ret, *p;
3224 UINT err = 0;
3225 // Validate arguments
3226 if (r == NULL || a == NULL)
3227 {
3228 return ERR_INTERNAL_ERROR;
3229 }
3230
3231 p = NewPack();
3232 OutRpcClientDeleteAccount(p, a);
3233
3234 ret = RpcCall(r->Rpc, "SetStartupAccount", p);
3235
3236 if (RpcIsOk(ret) == false)
3237 {
3238 err = RpcGetError(ret);
3239 }
3240
3241 FreePack(ret);
3242
3243 return err;
3244 }
3245
3246 // Delete the account
CcDeleteAccount(REMOTE_CLIENT * r,RPC_CLIENT_DELETE_ACCOUNT * a)3247 UINT CcDeleteAccount(REMOTE_CLIENT *r, RPC_CLIENT_DELETE_ACCOUNT *a)
3248 {
3249 PACK *ret, *p;
3250 UINT err = 0;
3251 // Validate arguments
3252 if (r == NULL || a == NULL)
3253 {
3254 return ERR_INTERNAL_ERROR;
3255 }
3256
3257 p = NewPack();
3258 OutRpcClientDeleteAccount(p, a);
3259
3260 ret = RpcCall(r->Rpc, "DeleteAccount", p);
3261
3262 if (RpcIsOk(ret) == false)
3263 {
3264 err = RpcGetError(ret);
3265 }
3266
3267 FreePack(ret);
3268
3269 return err;
3270 }
3271
3272 // Account setting
CcSetAccount(REMOTE_CLIENT * r,RPC_CLIENT_CREATE_ACCOUNT * a)3273 UINT CcSetAccount(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_ACCOUNT *a)
3274 {
3275 PACK *ret, *p;
3276 UINT err = 0;
3277 // Validate arguments
3278 if (r == NULL || a == NULL)
3279 {
3280 return ERR_INTERNAL_ERROR;
3281 }
3282
3283 p = NewPack();
3284 OutRpcClientCreateAccount(p, a);
3285
3286 ret = RpcCall(r->Rpc, "SetAccount", p);
3287
3288 if (RpcIsOk(ret) == false)
3289 {
3290 err = RpcGetError(ret);
3291 }
3292
3293 FreePack(ret);
3294
3295 return err;
3296 }
3297
3298 // Get the account
CcGetAccount(REMOTE_CLIENT * r,RPC_CLIENT_GET_ACCOUNT * a)3299 UINT CcGetAccount(REMOTE_CLIENT *r, RPC_CLIENT_GET_ACCOUNT *a)
3300 {
3301 PACK *ret, *p;
3302 UINT err = 0;
3303 // Validate arguments
3304 if (r == NULL || a == NULL)
3305 {
3306 return ERR_INTERNAL_ERROR;
3307 }
3308
3309 p = NewPack();
3310 OutRpcClientGetAccount(p, a);
3311
3312 ret = RpcCall(r->Rpc, "GetAccount", p);
3313
3314 if (RpcIsOk(ret))
3315 {
3316 InRpcClientGetAccount(a, ret);
3317 }
3318 else
3319 {
3320 err = RpcGetError(ret);
3321 }
3322
3323 FreePack(ret);
3324
3325 return err;
3326 }
3327
3328 // Change the account name
CcRenameAccount(REMOTE_CLIENT * r,RPC_RENAME_ACCOUNT * rename)3329 UINT CcRenameAccount(REMOTE_CLIENT *r, RPC_RENAME_ACCOUNT *rename)
3330 {
3331 PACK *p, *ret;
3332 UINT err = 0;
3333 // Validate arguments
3334 if (r == NULL || rename == NULL)
3335 {
3336 return ERR_INTERNAL_ERROR;
3337 }
3338
3339 p = NewPack();
3340 OutRpcRenameAccount(p, rename);
3341
3342 ret = RpcCall(r->Rpc, "RenameAccount", p);
3343
3344 if (RpcIsOk(ret) == false)
3345 {
3346 err = RpcGetError(ret);
3347 }
3348
3349 FreePack(ret);
3350
3351 return err;
3352 }
3353
3354 // Set the Client configuration
CcSetClientConfig(REMOTE_CLIENT * r,CLIENT_CONFIG * o)3355 UINT CcSetClientConfig(REMOTE_CLIENT *r, CLIENT_CONFIG *o)
3356 {
3357 PACK *p, *ret;
3358 UINT err = 0;
3359 // Validate arguments
3360 if (r == NULL || o == NULL)
3361 {
3362 return ERR_INTERNAL_ERROR;
3363 }
3364
3365 p = NewPack();
3366 OutRpcClientConfig(p, o);
3367
3368 ret = RpcCall(r->Rpc, "SetClientConfig", p);
3369
3370 if (RpcIsOk(ret) == false)
3371 {
3372 err = RpcGetError(ret);
3373 }
3374
3375 FreePack(ret);
3376
3377 return err;
3378 }
3379
3380 // Get the client configuration
CcGetClientConfig(REMOTE_CLIENT * r,CLIENT_CONFIG * o)3381 UINT CcGetClientConfig(REMOTE_CLIENT *r, CLIENT_CONFIG *o)
3382 {
3383 PACK *ret;
3384 UINT err = 0;
3385 // Validate arguments
3386 if (r == NULL || o == NULL)
3387 {
3388 return ERR_INTERNAL_ERROR;
3389 }
3390
3391 ret = RpcCall(r->Rpc, "GetClientConfig", NULL);
3392
3393 if (RpcIsOk(ret))
3394 {
3395 InRpcClientConfig(o, ret);
3396 }
3397 else
3398 {
3399 err = RpcGetError(ret);
3400 }
3401
3402 FreePack(ret);
3403
3404 return err;
3405 }
3406
3407 // Set the service to foreground process
CcSetServiceToForegroundProcess(REMOTE_CLIENT * r)3408 void CcSetServiceToForegroundProcess(REMOTE_CLIENT *r)
3409 {
3410 // Validate arguments
3411 if (r == NULL)
3412 {
3413 return;
3414 }
3415 // Abolition
3416 /*
3417 if (r->Rpc != NULL && r->Rpc->Sock != NULL && r->Rpc->Sock->RemoteIP.addr[0] == 127)
3418 {
3419 if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType) &&
3420 GET_KETA(GetOsInfo()->OsType, 100) >= 2)
3421 {
3422 // Only on a Windows 2000 or later
3423 RPC_CLIENT_VERSION v;
3424 Zero(&v, sizeof(v));
3425
3426 if (r->ClientBuildInt == 0)
3427 {
3428 CcGetClientVersion(r, &v);
3429 r->ClientBuildInt = v.ClientBuildInt;
3430 r->ProcessId = v.ProcessId;
3431 }
3432 if (r->ProcessId != 0 && r->ClientBuildInt <= 5080)
3433 {
3434 #ifdef OS_WIN32
3435 // Set the service process as a foreground window
3436 AllowFGWindow(v.ProcessId);
3437 #endif // OS_WIN32
3438 }
3439 }
3440 }*/
3441 }
3442
3443 // Connect
CcConnect(REMOTE_CLIENT * r,RPC_CLIENT_CONNECT * connect)3444 UINT CcConnect(REMOTE_CLIENT *r, RPC_CLIENT_CONNECT *connect)
3445 {
3446 PACK *ret, *p;
3447 UINT err = 0;
3448 // Validate arguments
3449 if (r == NULL || connect == NULL)
3450 {
3451 return ERR_INTERNAL_ERROR;
3452 }
3453
3454 CcSetServiceToForegroundProcess(r);
3455
3456 p = NewPack();
3457 OutRpcClientConnect(p, connect);
3458
3459 ret = RpcCall(r->Rpc, "Connect", p);
3460
3461 if (RpcIsOk(ret) == false)
3462 {
3463 err = RpcGetError(ret);
3464 }
3465
3466 FreePack(ret);
3467
3468 return err;
3469 }
3470
3471 // Disconnect
CcDisconnect(REMOTE_CLIENT * r,RPC_CLIENT_CONNECT * connect)3472 UINT CcDisconnect(REMOTE_CLIENT *r, RPC_CLIENT_CONNECT *connect)
3473 {
3474 PACK *ret, *p;
3475 UINT err = 0;
3476 // Validate arguments
3477 if (r == NULL || connect == NULL)
3478 {
3479 return ERR_INTERNAL_ERROR;
3480 }
3481
3482 CcSetServiceToForegroundProcess(r);
3483
3484 p = NewPack();
3485 OutRpcClientConnect(p, connect);
3486
3487 ret = RpcCall(r->Rpc, "Disconnect", p);
3488
3489 if (RpcIsOk(ret) == false)
3490 {
3491 err = RpcGetError(ret);
3492 }
3493
3494 FreePack(ret);
3495
3496 return err;
3497 }
3498
3499 // Get the account status
CcGetAccountStatus(REMOTE_CLIENT * r,RPC_CLIENT_GET_CONNECTION_STATUS * st)3500 UINT CcGetAccountStatus(REMOTE_CLIENT *r, RPC_CLIENT_GET_CONNECTION_STATUS *st)
3501 {
3502 PACK *ret, *p;
3503 UINT err = 0;
3504 // Validate arguments
3505 if (r == NULL || st == NULL)
3506 {
3507 return ERR_INTERNAL_ERROR;
3508 }
3509
3510 p = NewPack();
3511 OutRpcClientGetConnectionStatus(p, st);
3512
3513 ret = RpcCall(r->Rpc, "GetAccountStatus", p);
3514
3515 if (RpcIsOk(ret))
3516 {
3517 InRpcClientGetConnectionStatus(st, ret);
3518 }
3519 else
3520 {
3521 err = RpcGetError(ret);
3522 }
3523
3524 FreePack(ret);
3525
3526 return err;
3527 }
3528
3529
3530 // Client service sends a notification to the connection manager
CiNotify(CLIENT * c)3531 void CiNotify(CLIENT *c)
3532 {
3533 CiNotifyInternal(c);
3534 }
CiNotifyInternal(CLIENT * c)3535 void CiNotifyInternal(CLIENT *c)
3536 {
3537 // Validate arguments
3538 if (c == NULL)
3539 {
3540 return;
3541 }
3542
3543 // Set all the notification event
3544 LockList(c->NotifyCancelList);
3545 {
3546 UINT i;
3547 for (i = 0;i < LIST_NUM(c->NotifyCancelList);i++)
3548 {
3549 CANCEL *cancel = LIST_DATA(c->NotifyCancelList, i);
3550 Cancel(cancel);
3551 }
3552 }
3553 UnlockList(c->NotifyCancelList);
3554 }
3555
3556 // Release the RPC_CLIENT_ENUM_ACCOUNT
CiFreeClientEnumAccount(RPC_CLIENT_ENUM_ACCOUNT * a)3557 void CiFreeClientEnumAccount(RPC_CLIENT_ENUM_ACCOUNT *a)
3558 {
3559 UINT i;
3560 // Validate arguments
3561 if (a == NULL)
3562 {
3563 return;
3564 }
3565
3566 for (i = 0;i < a->NumItem;i++)
3567 {
3568 RPC_CLIENT_ENUM_ACCOUNT_ITEM *e = a->Items[i];
3569 Free(e);
3570 }
3571 Free(a->Items);
3572 }
3573
3574
3575 // Thread to save the configuration file periodically
CiSaverThread(THREAD * t,void * param)3576 void CiSaverThread(THREAD *t, void *param)
3577 {
3578 CLIENT *c = (CLIENT *)param;
3579 // Validate arguments
3580 if (t == NULL || param == NULL)
3581 {
3582 return;
3583 }
3584
3585 NoticeThreadInit(t);
3586
3587 // Wait for a certain period of time
3588 while (c->Halt == false)
3589 {
3590 Wait(c->SaverHalter, CLIENT_SAVER_INTERVAL);
3591
3592 // Save
3593 CiSaveConfigurationFile(c);
3594 }
3595 }
3596
3597 // Initialize the Saver
CiInitSaver(CLIENT * c)3598 void CiInitSaver(CLIENT *c)
3599 {
3600 // Validate arguments
3601 if (c == NULL)
3602 {
3603 return;
3604 }
3605
3606 c->SaverHalter = NewEvent();
3607
3608 c->SaverThread = NewThread(CiSaverThread, c);
3609 WaitThreadInit(c->SaverThread);
3610 }
3611
3612 // Release the Saver
CiFreeSaver(CLIENT * c)3613 void CiFreeSaver(CLIENT *c)
3614 {
3615 // Validate arguments
3616 if (c == NULL)
3617 {
3618 return;
3619 }
3620
3621 c->Halt = true;
3622 Set(c->SaverHalter);
3623 WaitThread(c->SaverThread, INFINITE);
3624 ReleaseThread(c->SaverThread);
3625
3626 ReleaseEvent(c->SaverHalter);
3627 }
3628
3629 // CM_SETTING
InRpcCmSetting(CM_SETTING * c,PACK * p)3630 void InRpcCmSetting(CM_SETTING *c, PACK *p)
3631 {
3632 // Validate arguments
3633 if (c == NULL || p == NULL)
3634 {
3635 return;
3636 }
3637
3638 Zero(c, sizeof(CM_SETTING));
3639 c->EasyMode = PackGetBool(p, "EasyMode");
3640 c->LockMode = PackGetBool(p, "LockMode");
3641 PackGetData2(p, "HashedPassword", c->HashedPassword, sizeof(c->HashedPassword));
3642 }
OutRpcCmSetting(PACK * p,CM_SETTING * c)3643 void OutRpcCmSetting(PACK *p, CM_SETTING *c)
3644 {
3645 // Validate arguments
3646 if (c == NULL || p == NULL)
3647 {
3648 return;
3649 }
3650
3651 PackAddBool(p, "EasyMode", c->EasyMode);
3652 PackAddBool(p, "LockMode", c->LockMode);
3653 PackAddData(p, "HashedPassword", c->HashedPassword, sizeof(c->HashedPassword));
3654 }
3655
3656 // CLIENT_CONFIG
InRpcClientConfig(CLIENT_CONFIG * c,PACK * p)3657 void InRpcClientConfig(CLIENT_CONFIG *c, PACK *p)
3658 {
3659 // Validate arguments
3660 if (c == NULL || p == NULL)
3661 {
3662 return;
3663 }
3664
3665 Zero(c, sizeof(CLIENT_CONFIG));
3666 c->UseKeepConnect = PackGetInt(p, "UseKeepConnect") == 0 ? false : true;
3667 c->KeepConnectPort = PackGetInt(p, "KeepConnectPort");
3668 c->KeepConnectProtocol = PackGetInt(p, "KeepConnectProtocol");
3669 c->KeepConnectInterval = PackGetInt(p, "KeepConnectInterval");
3670 c->AllowRemoteConfig = PackGetInt(p, "AllowRemoteConfig") == 0 ? false : true;
3671 PackGetStr(p, "KeepConnectHost", c->KeepConnectHost, sizeof(c->KeepConnectHost));
3672 }
OutRpcClientConfig(PACK * p,CLIENT_CONFIG * c)3673 void OutRpcClientConfig(PACK *p, CLIENT_CONFIG *c)
3674 {
3675 // Validate arguments
3676 if (c == NULL || p == NULL)
3677 {
3678 return;
3679 }
3680
3681 PackAddInt(p, "UseKeepConnect", c->UseKeepConnect);
3682 PackAddInt(p, "KeepConnectPort", c->KeepConnectPort);
3683 PackAddInt(p, "KeepConnectProtocol", c->KeepConnectProtocol);
3684 PackAddInt(p, "KeepConnectInterval", c->KeepConnectInterval);
3685 PackAddInt(p, "AllowRemoteConfig", c->AllowRemoteConfig);
3686 PackAddStr(p, "KeepConnectHost", c->KeepConnectHost);
3687 }
3688
3689 // RPC_CLIENT_VERSION
InRpcClientVersion(RPC_CLIENT_VERSION * ver,PACK * p)3690 void InRpcClientVersion(RPC_CLIENT_VERSION *ver, PACK *p)
3691 {
3692 // Validate arguments
3693 if (ver == NULL || p == NULL)
3694 {
3695 return;
3696 }
3697
3698 Zero(ver, sizeof(RPC_CLIENT_VERSION));
3699 PackGetStr(p, "ClientProductName", ver->ClientProductName, sizeof(ver->ClientProductName));
3700 PackGetStr(p, "ClientVersionString", ver->ClientVersionString, sizeof(ver->ClientVersionString));
3701 PackGetStr(p, "ClientBuildInfoString", ver->ClientBuildInfoString, sizeof(ver->ClientBuildInfoString));
3702 ver->ClientVerInt = PackGetInt(p, "ClientVerInt");
3703 ver->ClientBuildInt = PackGetInt(p, "ClientBuildInt");
3704 ver->ProcessId = PackGetInt(p, "ProcessId");
3705 ver->OsType = PackGetInt(p, "OsType");
3706 ver->IsVLanNameRegulated = PackGetBool(p, "IsVLanNameRegulated");
3707 ver->IsVgcSupported = PackGetBool(p, "IsVgcSupported");
3708 ver->ShowVgcLink = PackGetBool(p, "ShowVgcLink");
3709 PackGetStr(p, "ClientId", ver->ClientId, sizeof(ver->ClientId));
3710 }
OutRpcClientVersion(PACK * p,RPC_CLIENT_VERSION * ver)3711 void OutRpcClientVersion(PACK *p, RPC_CLIENT_VERSION *ver)
3712 {
3713 // Validate arguments
3714 if (ver == NULL || p == NULL)
3715 {
3716 return;
3717 }
3718
3719 PackAddStr(p, "ClientProductName", ver->ClientProductName);
3720 PackAddStr(p, "ClientVersionString", ver->ClientVersionString);
3721 PackAddStr(p, "ClientBuildInfoString", ver->ClientBuildInfoString);
3722 PackAddInt(p, "ClientVerInt", ver->ClientVerInt);
3723 PackAddInt(p, "ClientBuildInt", ver->ClientBuildInt);
3724 PackAddInt(p, "ProcessId", ver->ProcessId);
3725 PackAddInt(p, "OsType", ver->OsType);
3726 PackAddBool(p, "IsVLanNameRegulated", ver->IsVLanNameRegulated);
3727 PackAddBool(p, "IsVgcSupported", ver->IsVgcSupported);
3728 PackAddBool(p, "ShowVgcLink", ver->ShowVgcLink);
3729 PackAddStr(p, "ClientId", ver->ClientId);
3730 }
3731
3732 // RPC_CLIENT_PASSWORD
InRpcClientPassword(RPC_CLIENT_PASSWORD * pw,PACK * p)3733 void InRpcClientPassword(RPC_CLIENT_PASSWORD *pw, PACK *p)
3734 {
3735 // Validate arguments
3736 if (pw == NULL || p == NULL)
3737 {
3738 return;
3739 }
3740
3741 Zero(pw, sizeof(RPC_CLIENT_PASSWORD));
3742 PackGetStr(p, "Password", pw->Password, sizeof(pw->Password));
3743 pw->PasswordRemoteOnly = PackGetInt(p, "PasswordRemoteOnly");
3744 }
OutRpcClientPassword(PACK * p,RPC_CLIENT_PASSWORD * pw)3745 void OutRpcClientPassword(PACK *p, RPC_CLIENT_PASSWORD *pw)
3746 {
3747 // Validate arguments
3748 if (pw == NULL || p == NULL)
3749 {
3750 return;
3751 }
3752
3753 PackAddStr(p, "Password", pw->Password);
3754 PackAddInt(p, "PasswordRemoteOnly", pw->PasswordRemoteOnly);
3755 }
3756
3757 // RPC_CLIENT_PASSWORD_SETTING
InRpcClientPasswordSetting(RPC_CLIENT_PASSWORD_SETTING * a,PACK * p)3758 void InRpcClientPasswordSetting(RPC_CLIENT_PASSWORD_SETTING *a, PACK *p)
3759 {
3760 // Validate arguments
3761 if (a == NULL || p == NULL)
3762 {
3763 return;
3764 }
3765
3766 Zero(a, sizeof(RPC_CLIENT_PASSWORD_SETTING));
3767
3768 a->IsPasswordPresented = PackGetInt(p, "IsPasswordPresented") == 0 ? false : true;
3769 a->PasswordRemoteOnly = PackGetInt(p, "PasswordRemoteOnly") == 0 ? false : true;
3770 }
OutRpcClientPasswordSetting(PACK * p,RPC_CLIENT_PASSWORD_SETTING * a)3771 void OutRpcClientPasswordSetting(PACK *p, RPC_CLIENT_PASSWORD_SETTING *a)
3772 {
3773 // Validate arguments
3774 if (a == NULL || p == NULL)
3775 {
3776 return;
3777 }
3778
3779 PackAddInt(p, "IsPasswordPresented", a->IsPasswordPresented);
3780 PackAddInt(p, "PasswordRemoteOnly", a->PasswordRemoteOnly);
3781 }
3782
3783 // RPC_CLIENT_ENUM_CA
InRpcClientEnumCa(RPC_CLIENT_ENUM_CA * e,PACK * p)3784 void InRpcClientEnumCa(RPC_CLIENT_ENUM_CA *e, PACK *p)
3785 {
3786 UINT i;
3787 // Validate arguments
3788 if (e == NULL || p == NULL)
3789 {
3790 return;
3791 }
3792
3793 Zero(e, sizeof(RPC_CLIENT_ENUM_CA));
3794 e->NumItem = PackGetNum(p, "NumItem");
3795
3796 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_CA_ITEM *) * e->NumItem);
3797 for (i = 0;i < e->NumItem;i++)
3798 {
3799 RPC_CLIENT_ENUM_CA_ITEM *item = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_CA_ITEM));
3800 e->Items[i] = item;
3801
3802 item->Key = PackGetIntEx(p, "Key", i);
3803 PackGetUniStrEx(p, "SubjectName", item->SubjectName, sizeof(item->SubjectName), i);
3804 PackGetUniStrEx(p, "IssuerName", item->IssuerName, sizeof(item->IssuerName), i);
3805 item->Expires = PackGetInt64Ex(p, "Expires", i);
3806 }
3807 }
OutRpcClientEnumCa(PACK * p,RPC_CLIENT_ENUM_CA * e)3808 void OutRpcClientEnumCa(PACK *p, RPC_CLIENT_ENUM_CA *e)
3809 {
3810 UINT i;
3811 // Validate arguments
3812 if (e == NULL || p == NULL)
3813 {
3814 return;
3815 }
3816
3817 PackAddNum(p, "NumItem", e->NumItem);
3818
3819 PackSetCurrentJsonGroupName(p, "CAList");
3820 for (i = 0;i < e->NumItem;i++)
3821 {
3822 RPC_CLIENT_ENUM_CA_ITEM *item = e->Items[i];
3823 PackAddIntEx(p, "Key", item->Key, i, e->NumItem);
3824 PackAddUniStrEx(p, "SubjectName", item->SubjectName, i, e->NumItem);
3825 PackAddUniStrEx(p, "IssuerName", item->IssuerName, i, e->NumItem);
3826 PackAddTime64Ex(p, "Expires", item->Expires, i, e->NumItem);
3827 }
3828 PackSetCurrentJsonGroupName(p, NULL);
3829 }
3830
3831 // RPC_GET_ISSUER
InRpcGetIssuer(RPC_GET_ISSUER * c,PACK * p)3832 void InRpcGetIssuer(RPC_GET_ISSUER *c, PACK *p)
3833 {
3834 BUF *b;
3835 // Validate arguments
3836 if (c == NULL || p == NULL)
3837 {
3838 return;
3839 }
3840
3841 Zero(c, sizeof(RPC_GET_ISSUER));
3842 b = PackGetBuf(p, "x");
3843 if (b != NULL)
3844 {
3845 if (c->x != NULL)
3846 {
3847 FreeX(c->x);
3848 }
3849 c->x = BufToX(b, false);
3850 FreeBuf(b);
3851 }
3852
3853 b = PackGetBuf(p, "issuer_x");
3854 if (b != NULL)
3855 {
3856 c->issuer_x = BufToX(b, false);
3857 FreeBuf(b);
3858 }
3859 }
OutRpcGetIssuer(PACK * p,RPC_GET_ISSUER * c)3860 void OutRpcGetIssuer(PACK *p, RPC_GET_ISSUER *c)
3861 {
3862 BUF *b;
3863 // Validate arguments
3864 if (p == NULL || c == NULL)
3865 {
3866 return;
3867 }
3868
3869 if (c->x != NULL)
3870 {
3871 b = XToBuf(c->x, false);
3872
3873 PackAddBuf(p, "x", b);
3874 FreeBuf(b);
3875 }
3876
3877 if (c->issuer_x != NULL)
3878 {
3879 b = XToBuf(c->issuer_x, false);
3880
3881 PackAddBuf(p, "issuer_x", b);
3882 FreeBuf(b);
3883 }
3884 }
3885
3886 // TRAFFIC_EX
InRpcTrafficEx(TRAFFIC * t,PACK * p,UINT i)3887 void InRpcTrafficEx(TRAFFIC *t, PACK *p, UINT i)
3888 {
3889 // Validate arguments
3890 if (t == NULL || p == NULL)
3891 {
3892 return;
3893 }
3894
3895 Zero(t, sizeof(TRAFFIC));
3896 t->Recv.BroadcastBytes = PackGetInt64Ex(p, "Ex.Recv.BroadcastBytes", i);
3897 t->Recv.BroadcastCount = PackGetInt64Ex(p, "Ex.Recv.BroadcastCount", i);
3898 t->Recv.UnicastBytes = PackGetInt64Ex(p, "Ex.Recv.UnicastBytes", i);
3899 t->Recv.UnicastCount = PackGetInt64Ex(p, "Ex.Recv.UnicastCount", i);
3900 t->Send.BroadcastBytes = PackGetInt64Ex(p, "Ex.Send.BroadcastBytes", i);
3901 t->Send.BroadcastCount = PackGetInt64Ex(p, "Ex.Send.BroadcastCount", i);
3902 t->Send.UnicastBytes = PackGetInt64Ex(p, "Ex.Send.UnicastBytes", i);
3903 t->Send.UnicastCount = PackGetInt64Ex(p, "Ex.Send.UnicastCount", i);
3904 }
OutRpcTrafficEx(TRAFFIC * t,PACK * p,UINT i,UINT num)3905 void OutRpcTrafficEx(TRAFFIC *t, PACK *p, UINT i, UINT num)
3906 {
3907 // Validate arguments
3908 if (t == NULL || p == NULL)
3909 {
3910 return;
3911 }
3912
3913 PackAddInt64Ex(p, "Ex.Recv.BroadcastBytes", t->Recv.BroadcastBytes, i, num);
3914 PackAddInt64Ex(p, "Ex.Recv.BroadcastCount", t->Recv.BroadcastCount, i, num);
3915 PackAddInt64Ex(p, "Ex.Recv.UnicastBytes", t->Recv.UnicastBytes, i, num);
3916 PackAddInt64Ex(p, "Ex.Recv.UnicastCount", t->Recv.UnicastCount, i, num);
3917 PackAddInt64Ex(p, "Ex.Send.BroadcastBytes", t->Send.BroadcastBytes, i, num);
3918 PackAddInt64Ex(p, "Ex.Send.BroadcastCount", t->Send.BroadcastCount, i, num);
3919 PackAddInt64Ex(p, "Ex.Send.UnicastBytes", t->Send.UnicastBytes, i, num);
3920 PackAddInt64Ex(p, "Ex.Send.UnicastCount", t->Send.UnicastCount, i, num);
3921 }
3922
3923 // TRAFFIC
InRpcTraffic(TRAFFIC * t,PACK * p)3924 void InRpcTraffic(TRAFFIC *t, PACK *p)
3925 {
3926 // Validate arguments
3927 if (t == NULL || p == NULL)
3928 {
3929 return;
3930 }
3931
3932 Zero(t, sizeof(TRAFFIC));
3933 t->Recv.BroadcastBytes = PackGetInt64(p, "Recv.BroadcastBytes");
3934 t->Recv.BroadcastCount = PackGetInt64(p, "Recv.BroadcastCount");
3935 t->Recv.UnicastBytes = PackGetInt64(p, "Recv.UnicastBytes");
3936 t->Recv.UnicastCount = PackGetInt64(p, "Recv.UnicastCount");
3937 t->Send.BroadcastBytes = PackGetInt64(p, "Send.BroadcastBytes");
3938 t->Send.BroadcastCount = PackGetInt64(p, "Send.BroadcastCount");
3939 t->Send.UnicastBytes = PackGetInt64(p, "Send.UnicastBytes");
3940 t->Send.UnicastCount = PackGetInt64(p, "Send.UnicastCount");
3941 }
OutRpcTraffic(PACK * p,TRAFFIC * t)3942 void OutRpcTraffic(PACK *p, TRAFFIC *t)
3943 {
3944 // Validate arguments
3945 if (t == NULL || p == NULL)
3946 {
3947 return;
3948 }
3949
3950 PackAddInt64(p, "Recv.BroadcastBytes", t->Recv.BroadcastBytes);
3951 PackAddInt64(p, "Recv.BroadcastCount", t->Recv.BroadcastCount);
3952 PackAddInt64(p, "Recv.UnicastBytes", t->Recv.UnicastBytes);
3953 PackAddInt64(p, "Recv.UnicastCount", t->Recv.UnicastCount);
3954 PackAddInt64(p, "Send.BroadcastBytes", t->Send.BroadcastBytes);
3955 PackAddInt64(p, "Send.BroadcastCount", t->Send.BroadcastCount);
3956 PackAddInt64(p, "Send.UnicastBytes", t->Send.UnicastBytes);
3957 PackAddInt64(p, "Send.UnicastCount", t->Send.UnicastCount);
3958 }
3959
3960 // RPC_CERT
InRpcCert(RPC_CERT * c,PACK * p)3961 void InRpcCert(RPC_CERT *c, PACK *p)
3962 {
3963 BUF *b;
3964 // Validate arguments
3965 if (c == NULL || p == NULL)
3966 {
3967 return;
3968 }
3969
3970 Zero(c, sizeof(RPC_CERT));
3971 b = PackGetBuf(p, "x");
3972 if (b == NULL)
3973 {
3974 return;
3975 }
3976
3977 c->x = BufToX(b, false);
3978 FreeBuf(b);
3979 }
OutRpcCert(PACK * p,RPC_CERT * c)3980 void OutRpcCert(PACK *p, RPC_CERT *c)
3981 {
3982 BUF *b;
3983 // Validate arguments
3984 if (p == NULL || c == NULL)
3985 {
3986 return;
3987 }
3988
3989 if (c->x != NULL)
3990 {
3991 b = XToBuf(c->x, false);
3992
3993 PackAddBuf(p, "x", b);
3994
3995 FreeBuf(b);
3996 }
3997 }
3998
3999 // RPC_CLIENT_DELETE_CA
InRpcClientDeleteCa(RPC_CLIENT_DELETE_CA * c,PACK * p)4000 void InRpcClientDeleteCa(RPC_CLIENT_DELETE_CA *c, PACK *p)
4001 {
4002 // Validate arguments
4003 if (c == NULL || p == NULL)
4004 {
4005 return;
4006 }
4007
4008 Zero(c, sizeof(RPC_CLIENT_DELETE_CA));
4009 c->Key = PackGetInt(p, "Key");
4010 }
OutRpcClientDeleteCa(PACK * p,RPC_CLIENT_DELETE_CA * c)4011 void OutRpcClientDeleteCa(PACK *p, RPC_CLIENT_DELETE_CA *c)
4012 {
4013 // Validate arguments
4014 if (c == NULL || p == NULL)
4015 {
4016 return;
4017 }
4018
4019 PackAddInt(p, "Key", c->Key);
4020 }
4021
4022 // RPC_GET_CA
InRpcGetCa(RPC_GET_CA * c,PACK * p)4023 void InRpcGetCa(RPC_GET_CA *c, PACK *p)
4024 {
4025 BUF *b;
4026 // Validate arguments
4027 if (c == NULL || p == NULL)
4028 {
4029 return;
4030 }
4031
4032 Zero(c, sizeof(RPC_GET_CA));
4033
4034 c->Key = PackGetInt(p, "Key");
4035
4036 b = PackGetBuf(p, "x");
4037 if (b != NULL)
4038 {
4039 c->x = BufToX(b, false);
4040
4041 FreeBuf(b);
4042 }
4043 }
OutRpcGetCa(PACK * p,RPC_GET_CA * c)4044 void OutRpcGetCa(PACK *p, RPC_GET_CA *c)
4045 {
4046 // Validate arguments
4047 if (c == NULL || p == NULL)
4048 {
4049 return;
4050 }
4051
4052 PackAddInt(p, "Key", c->Key);
4053
4054 if (c->x != NULL)
4055 {
4056 BUF *b = XToBuf(c->x, false);
4057
4058 PackAddBuf(p, "x", b);
4059
4060 FreeBuf(b);
4061 }
4062 }
4063
4064 // RPC_CLIENT_ENUM_SECURE
InRpcClientEnumSecure(RPC_CLIENT_ENUM_SECURE * e,PACK * p)4065 void InRpcClientEnumSecure(RPC_CLIENT_ENUM_SECURE *e, PACK *p)
4066 {
4067 UINT i;
4068 // Validate arguments
4069 if (e == NULL || p == NULL)
4070 {
4071 return;
4072 }
4073
4074 Zero(e, sizeof(RPC_CLIENT_ENUM_SECURE));
4075
4076 e->NumItem = PackGetNum(p, "NumItem");
4077 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_SECURE_ITEM *) * e->NumItem);
4078 for (i = 0;i < e->NumItem;i++)
4079 {
4080 RPC_CLIENT_ENUM_SECURE_ITEM *item = e->Items[i] = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_SECURE_ITEM));
4081
4082 item->DeviceId = PackGetIntEx(p, "DeviceId", i);
4083 item->Type = PackGetIntEx(p, "Type", i);
4084 PackGetStrEx(p, "DeviceName", item->DeviceName, sizeof(item->DeviceName), i);
4085 PackGetStrEx(p, "Manufacturer", item->Manufacturer, sizeof(item->Manufacturer), i);
4086 }
4087 }
OutRpcClientEnumSecure(PACK * p,RPC_CLIENT_ENUM_SECURE * e)4088 void OutRpcClientEnumSecure(PACK *p, RPC_CLIENT_ENUM_SECURE *e)
4089 {
4090 UINT i;
4091 // Validate arguments
4092 if (e == NULL || p == NULL)
4093 {
4094 return;
4095 }
4096
4097 PackAddNum(p, "NumItem", e->NumItem);
4098
4099 PackSetCurrentJsonGroupName(p, "SecureDeviceList");
4100 for (i = 0;i < e->NumItem;i++)
4101 {
4102 RPC_CLIENT_ENUM_SECURE_ITEM *item = e->Items[i];
4103
4104 PackAddIntEx(p, "DeviceId", item->DeviceId, i, e->NumItem);
4105 PackAddIntEx(p, "Type", item->Type, i, e->NumItem);
4106 PackAddStrEx(p, "DeviceName", item->DeviceName, i, e->NumItem);
4107 PackAddStrEx(p, "Manufacturer", item->Manufacturer, i, e->NumItem);
4108 }
4109 PackSetCurrentJsonGroupName(p, NULL);
4110 }
4111
4112 // RPC_USE_SECURE
InRpcUseSecure(RPC_USE_SECURE * u,PACK * p)4113 void InRpcUseSecure(RPC_USE_SECURE *u, PACK *p)
4114 {
4115 // Validate arguments
4116 if (u == NULL || p == NULL)
4117 {
4118 return;
4119 }
4120
4121 Zero(u, sizeof(RPC_USE_SECURE));
4122 u->DeviceId = PackGetInt(p, "DeviceId");
4123 }
OutRpcUseSecure(PACK * p,RPC_USE_SECURE * u)4124 void OutRpcUseSecure(PACK *p, RPC_USE_SECURE *u)
4125 {
4126 // Validate arguments
4127 if (u == NULL || p == NULL)
4128 {
4129 return;
4130 }
4131
4132 PackAddInt(p, "DeviceId", u->DeviceId);
4133 }
4134
4135 // Release the RPC_ENUM_OBJECT_IN_SECURE
CiFreeEnumObjectInSecure(RPC_ENUM_OBJECT_IN_SECURE * a)4136 void CiFreeEnumObjectInSecure(RPC_ENUM_OBJECT_IN_SECURE *a)
4137 {
4138 UINT i;
4139 // Validate arguments
4140 if (a == NULL)
4141 {
4142 return;
4143 }
4144
4145 for (i = 0;i < a->NumItem;i++)
4146 {
4147 Free(a->ItemName[i]);
4148 }
4149 Free(a->ItemName);
4150 Free(a->ItemType);
4151 }
4152
4153 // RPC_ENUM_OBJECT_IN_SECURE
OutRpcEnumObjectInSecure(PACK * p,RPC_ENUM_OBJECT_IN_SECURE * e)4154 void OutRpcEnumObjectInSecure(PACK *p, RPC_ENUM_OBJECT_IN_SECURE *e)
4155 {
4156 UINT i;
4157 // Validate arguments
4158 if (e == NULL || p == NULL)
4159 {
4160 return;
4161 }
4162
4163 PackAddNum(p, "NumItem", e->NumItem);
4164 PackAddInt(p, "hWnd", e->hWnd);
4165
4166 PackSetCurrentJsonGroupName(p, "ObjectList");
4167 for (i = 0;i < e->NumItem;i++)
4168 {
4169 PackAddStrEx(p, "ItemName", e->ItemName[i], i, e->NumItem);
4170 PackAddIntEx(p, "ItemType", e->ItemType[i], i, e->NumItem);
4171 }
4172 PackSetCurrentJsonGroupName(p, NULL);
4173 }
4174
4175 // RPC_CLIENT_CREATE_VLAN
InRpcCreateVLan(RPC_CLIENT_CREATE_VLAN * v,PACK * p)4176 void InRpcCreateVLan(RPC_CLIENT_CREATE_VLAN *v, PACK *p)
4177 {
4178 // Validate arguments
4179 if (v == NULL || p == NULL)
4180 {
4181 return;
4182 }
4183
4184 Zero(v, sizeof(RPC_CLIENT_CREATE_VLAN));
4185 PackGetStr(p, "DeviceName", v->DeviceName, sizeof(v->DeviceName));
4186 }
OutRpcCreateVLan(PACK * p,RPC_CLIENT_CREATE_VLAN * v)4187 void OutRpcCreateVLan(PACK *p, RPC_CLIENT_CREATE_VLAN *v)
4188 {
4189 // Validate arguments
4190 if (v == NULL || p == NULL)
4191 {
4192 return;
4193 }
4194
4195 PackAddStr(p, "DeviceName", v->DeviceName);
4196 }
4197
4198 // RPC_CLIENT_GET_VLAN
InRpcClientGetVLan(RPC_CLIENT_GET_VLAN * v,PACK * p)4199 void InRpcClientGetVLan(RPC_CLIENT_GET_VLAN *v, PACK *p)
4200 {
4201 // Validate arguments
4202 if (v == NULL || p == NULL)
4203 {
4204 return;
4205 }
4206
4207 Zero(v, sizeof(RPC_CLIENT_GET_VLAN));
4208 PackGetStr(p, "DeviceName", v->DeviceName, sizeof(v->DeviceName));
4209 v->Enabled = PackGetInt(p, "Enabled") ? true : false;
4210 PackGetStr(p, "MacAddress", v->MacAddress, sizeof(v->MacAddress));
4211 PackGetStr(p, "Version", v->Version, sizeof(v->Version));
4212 PackGetStr(p, "FileName", v->FileName, sizeof(v->FileName));
4213 PackGetStr(p, "Guid", v->Guid, sizeof(v->Guid));
4214 }
OutRpcClientGetVLan(PACK * p,RPC_CLIENT_GET_VLAN * v)4215 void OutRpcClientGetVLan(PACK *p, RPC_CLIENT_GET_VLAN *v)
4216 {
4217 // Validate arguments
4218 if (v == NULL || p == NULL)
4219 {
4220 return;
4221 }
4222
4223 PackAddStr(p, "DeviceName", v->DeviceName);
4224 PackAddInt(p, "Enabled", v->Enabled);
4225 PackAddStr(p, "MacAddress", v->MacAddress);
4226 PackAddStr(p, "Version", v->Version);
4227 PackAddStr(p, "FileName", v->FileName);
4228 PackAddStr(p, "Guid", v->Guid);
4229 }
4230
4231 // RPC_CLIENT_SET_VLAN
InRpcClientSetVLan(RPC_CLIENT_SET_VLAN * v,PACK * p)4232 void InRpcClientSetVLan(RPC_CLIENT_SET_VLAN *v, PACK *p)
4233 {
4234 // Validate arguments
4235 if (v == NULL || p == NULL)
4236 {
4237 return;
4238 }
4239
4240 Zero(v, sizeof(RPC_CLIENT_SET_VLAN));
4241 PackGetStr(p, "DeviceName", v->DeviceName, sizeof(v->DeviceName));
4242 PackGetStr(p, "MacAddress", v->MacAddress, sizeof(v->MacAddress));
4243 }
OutRpcClientSetVLan(PACK * p,RPC_CLIENT_SET_VLAN * v)4244 void OutRpcClientSetVLan(PACK *p, RPC_CLIENT_SET_VLAN *v)
4245 {
4246 // Validate arguments
4247 if (v == NULL || p == NULL)
4248 {
4249 return;
4250 }
4251
4252 PackAddStr(p, "DeviceName", v->DeviceName);
4253 PackAddStr(p, "MacAddress", v->MacAddress);
4254 }
4255
4256 // RPC_CLIENT_ENUM_VLAN
InRpcClientEnumVLan(RPC_CLIENT_ENUM_VLAN * v,PACK * p)4257 void InRpcClientEnumVLan(RPC_CLIENT_ENUM_VLAN *v, PACK *p)
4258 {
4259 UINT i;
4260 // Validate arguments
4261 if (v == NULL || p == NULL)
4262 {
4263 return;
4264 }
4265
4266 Zero(v, sizeof(RPC_CLIENT_ENUM_VLAN));
4267 v->NumItem = PackGetNum(p, "NumItem");
4268 v->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM *) * v->NumItem);
4269
4270 for (i = 0;i < v->NumItem;i++)
4271 {
4272 RPC_CLIENT_ENUM_VLAN_ITEM *item = v->Items[i] =
4273 ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM));
4274
4275 PackGetStrEx(p, "DeviceName", item->DeviceName, sizeof(item->DeviceName), i);
4276 item->Enabled = PackGetIntEx(p, "Enabled", i) ? true : false;
4277 PackGetStrEx(p, "MacAddress", item->MacAddress, sizeof(item->MacAddress), i);
4278 PackGetStrEx(p, "Version", item->Version, sizeof(item->Version), i);
4279 }
4280 }
OutRpcClientEnumVLan(PACK * p,RPC_CLIENT_ENUM_VLAN * v)4281 void OutRpcClientEnumVLan(PACK *p, RPC_CLIENT_ENUM_VLAN *v)
4282 {
4283 UINT i;
4284 // Validate arguments
4285 if (v == NULL || p == NULL)
4286 {
4287 return;
4288 }
4289
4290 PackAddNum(p, "NumItem", v->NumItem);
4291
4292 PackSetCurrentJsonGroupName(p, "VLanList");
4293 for (i = 0;i < v->NumItem;i++)
4294 {
4295 RPC_CLIENT_ENUM_VLAN_ITEM *item = v->Items[i];
4296
4297 PackAddStrEx(p, "DeviceName", item->DeviceName, i, v->NumItem);
4298 PackAddIntEx(p, "Enabled", item->Enabled, i, v->NumItem);
4299 PackAddStrEx(p, "MacAddress", item->MacAddress, i, v->NumItem);
4300 PackAddStrEx(p, "Version", item->Version, i, v->NumItem);
4301 }
4302 PackSetCurrentJsonGroupName(p, NULL);
4303 }
4304
4305 // CLIENT_OPTION
InRpcClientOption(CLIENT_OPTION * c,PACK * p)4306 void InRpcClientOption(CLIENT_OPTION *c, PACK *p)
4307 {
4308 // Validate arguments
4309 if (c == NULL || p == NULL)
4310 {
4311 return;
4312 }
4313
4314 Zero(c, sizeof(CLIENT_OPTION));
4315
4316 PackGetUniStr(p, "AccountName", c->AccountName, sizeof(c->AccountName));
4317 PackGetStr(p, "Hostname", c->Hostname, sizeof(c->Hostname));
4318 c->Port = PackGetInt(p, "Port");
4319 c->PortUDP = PackGetInt(p, "PortUDP");
4320 c->ProxyType = PackGetInt(p, "ProxyType");
4321 c->ProxyPort = PackGetInt(p, "ProxyPort");
4322 c->NumRetry = PackGetInt(p, "NumRetry");
4323 c->RetryInterval = PackGetInt(p, "RetryInterval");
4324 c->MaxConnection = PackGetInt(p, "MaxConnection");
4325 c->AdditionalConnectionInterval = PackGetInt(p, "AdditionalConnectionInterval");
4326 c->ConnectionDisconnectSpan = PackGetInt(p, "ConnectionDisconnectSpan");
4327 c->HideStatusWindow = PackGetBool(p, "HideStatusWindow");
4328 c->HideNicInfoWindow = PackGetBool(p, "HideNicInfoWindow");
4329 c->DisableQoS = PackGetBool(p, "DisableQoS");
4330 PackGetStr(p, "ProxyName", c->ProxyName, sizeof(c->ProxyName));
4331 PackGetStr(p, "ProxyUsername", c->ProxyUsername, sizeof(c->ProxyUsername));
4332 PackGetStr(p, "ProxyPassword", c->ProxyPassword, sizeof(c->ProxyPassword));
4333 PackGetStr(p, "CustomHttpHeader", c->CustomHttpHeader, sizeof(c->CustomHttpHeader));
4334 PackGetStr(p, "HubName", c->HubName, sizeof(c->HubName));
4335 PackGetStr(p, "DeviceName", c->DeviceName, sizeof(c->DeviceName));
4336 c->UseEncrypt = PackGetInt(p, "UseEncrypt") ? true : false;
4337 c->UseCompress = PackGetInt(p, "UseCompress") ? true : false;
4338 c->HalfConnection = PackGetInt(p, "HalfConnection") ? true : false;
4339 c->NoRoutingTracking = PackGetInt(p, "NoRoutingTracking") ? true : false;
4340 c->RequireMonitorMode = PackGetBool(p, "RequireMonitorMode");
4341 c->RequireBridgeRoutingMode = PackGetBool(p, "RequireBridgeRoutingMode");
4342 c->FromAdminPack = PackGetBool(p, "FromAdminPack");
4343 c->NoUdpAcceleration = PackGetBool(p, "NoUdpAcceleration");
4344 PackGetData2(p, "HostUniqueKey", c->HostUniqueKey, SHA1_SIZE);
4345 }
OutRpcClientOption(PACK * p,CLIENT_OPTION * c)4346 void OutRpcClientOption(PACK *p, CLIENT_OPTION *c)
4347 {
4348 // Validate arguments
4349 if (c == NULL || p == NULL)
4350 {
4351 return;
4352 }
4353
4354 PackAddUniStr(p, "AccountName", c->AccountName);
4355 PackAddStr(p, "Hostname", c->Hostname);
4356 PackAddStr(p, "ProxyName", c->ProxyName);
4357 PackAddStr(p, "ProxyUsername", c->ProxyUsername);
4358 PackAddStr(p, "ProxyPassword", c->ProxyPassword);
4359 PackAddStr(p, "CustomHttpHeader", c->CustomHttpHeader);
4360 PackAddStr(p, "HubName", c->HubName);
4361 PackAddStr(p, "DeviceName", c->DeviceName);
4362 PackAddInt(p, "Port", c->Port);
4363 PackAddInt(p, "PortUDP", c->PortUDP);
4364 PackAddInt(p, "ProxyType", c->ProxyType);
4365 PackAddInt(p, "ProxyPort", c->ProxyPort);
4366 PackAddInt(p, "NumRetry", c->NumRetry);
4367 PackAddInt(p, "RetryInterval", c->RetryInterval);
4368 PackAddInt(p, "MaxConnection", c->MaxConnection);
4369 PackAddBool(p, "UseEncrypt", c->UseEncrypt);
4370 PackAddBool(p, "UseCompress", c->UseCompress);
4371 PackAddBool(p, "HalfConnection", c->HalfConnection);
4372 PackAddBool(p, "NoRoutingTracking", c->NoRoutingTracking);
4373 PackAddInt(p, "AdditionalConnectionInterval", c->AdditionalConnectionInterval);
4374 PackAddInt(p, "ConnectionDisconnectSpan", c->ConnectionDisconnectSpan);
4375 PackAddBool(p, "HideStatusWindow", c->HideStatusWindow);
4376 PackAddBool(p, "HideNicInfoWindow", c->HideNicInfoWindow);
4377 PackAddBool(p, "RequireMonitorMode", c->RequireMonitorMode);
4378 PackAddBool(p, "RequireBridgeRoutingMode", c->RequireBridgeRoutingMode);
4379 PackAddBool(p, "DisableQoS", c->DisableQoS);
4380 PackAddBool(p, "FromAdminPack", c->FromAdminPack);
4381 PackAddBool(p, "NoUdpAcceleration", c->NoUdpAcceleration);
4382 PackAddData(p, "HostUniqueKey", c->HostUniqueKey, SHA1_SIZE);
4383 }
4384
4385 // CLIENT_AUTH
InRpcClientAuth(CLIENT_AUTH * c,PACK * p)4386 void InRpcClientAuth(CLIENT_AUTH *c, PACK *p)
4387 {
4388 BUF *b;
4389 // Validate arguments
4390 if (c == NULL || p == NULL)
4391 {
4392 return;
4393 }
4394
4395 Zero(c, sizeof(CLIENT_AUTH));
4396 c->AuthType = PackGetInt(p, "AuthType");
4397 PackGetStr(p, "Username", c->Username, sizeof(c->Username));
4398
4399 switch (c->AuthType)
4400 {
4401 case CLIENT_AUTHTYPE_ANONYMOUS:
4402 break;
4403
4404 case CLIENT_AUTHTYPE_PASSWORD:
4405 if (PackGetDataSize(p, "HashedPassword") == SHA1_SIZE)
4406 {
4407 PackGetData(p, "HashedPassword", c->HashedPassword);
4408 }
4409 break;
4410
4411 case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
4412 PackGetStr(p, "PlainPassword", c->PlainPassword, sizeof(c->PlainPassword));
4413 break;
4414
4415 case CLIENT_AUTHTYPE_CERT:
4416 b = PackGetBuf(p, "ClientX");
4417 if (b != NULL)
4418 {
4419 c->ClientX = BufToX(b, false);
4420 FreeBuf(b);
4421 }
4422 b = PackGetBuf(p, "ClientK");
4423 if (b != NULL)
4424 {
4425 c->ClientK = BufToK(b, true, false, NULL);
4426 FreeBuf(b);
4427 }
4428 break;
4429
4430 case CLIENT_AUTHTYPE_SECURE:
4431 PackGetStr(p, "SecurePublicCertName", c->SecurePublicCertName, sizeof(c->SecurePublicCertName));
4432 PackGetStr(p, "SecurePrivateKeyName", c->SecurePrivateKeyName, sizeof(c->SecurePrivateKeyName));
4433 break;
4434
4435 case CLIENT_AUTHTYPE_OPENSSLENGINE:
4436 b = PackGetBuf(p, "ClientX");
4437 if (b != NULL)
4438 {
4439 c->ClientX = BufToX(b, false);
4440 FreeBuf(b);
4441 }
4442 PackGetStr(p, "OpensslEnginePrivateKeyName", c->OpensslEnginePrivateKeyName, sizeof(c->OpensslEnginePrivateKeyName));
4443 PackGetStr(p, "OpensslEngineName", c->OpensslEngineName, sizeof(c->OpensslEngineName));
4444 break;
4445 }
4446 }
OutRpcClientAuth(PACK * p,CLIENT_AUTH * c)4447 void OutRpcClientAuth(PACK *p, CLIENT_AUTH *c)
4448 {
4449 BUF *b;
4450 // Validate arguments
4451 if (c == NULL || p == NULL)
4452 {
4453 return;
4454 }
4455
4456 PackAddInt(p, "AuthType", c->AuthType);
4457 PackAddStr(p, "Username", c->Username);
4458
4459 switch (c->AuthType)
4460 {
4461 case CLIENT_AUTHTYPE_ANONYMOUS:
4462 break;
4463
4464 case CLIENT_AUTHTYPE_PASSWORD:
4465 PackAddData(p, "HashedPassword", c->HashedPassword, SHA1_SIZE);
4466 break;
4467
4468 case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
4469 PackAddStr(p, "PlainPassword", c->PlainPassword);
4470 break;
4471
4472 case CLIENT_AUTHTYPE_CERT:
4473 b = XToBuf(c->ClientX, false);
4474 if (b != NULL)
4475 {
4476 PackAddBuf(p, "ClientX", b);
4477 FreeBuf(b);
4478 }
4479 b = KToBuf(c->ClientK, false, NULL);
4480 if (b != NULL)
4481 {
4482 PackAddBuf(p, "ClientK", b);
4483 FreeBuf(b);
4484 }
4485 break;
4486
4487 case CLIENT_AUTHTYPE_SECURE:
4488 PackAddStr(p, "SecurePublicCertName", c->SecurePublicCertName);
4489 PackAddStr(p, "SecurePrivateKeyName", c->SecurePrivateKeyName);
4490 break;
4491
4492 case CLIENT_AUTHTYPE_OPENSSLENGINE:
4493 b = XToBuf(c->ClientX, false);
4494 if (b != NULL)
4495 {
4496 PackAddBuf(p, "ClientX", b);
4497 FreeBuf(b);
4498 }
4499 PackAddStr(p, "OpensslEnginePrivateKeyName", c->OpensslEnginePrivateKeyName);
4500 PackAddStr(p, "OpensslEngineName", c->OpensslEngineName);
4501 break;
4502 }
4503 }
4504
4505 // RPC_CLIENT_CREATE_ACCOUNT
InRpcClientCreateAccount(RPC_CLIENT_CREATE_ACCOUNT * c,PACK * p)4506 void InRpcClientCreateAccount(RPC_CLIENT_CREATE_ACCOUNT *c, PACK *p)
4507 {
4508 BUF *b;
4509 // Validate arguments
4510 if (c == NULL || p == NULL)
4511 {
4512 return;
4513 }
4514
4515 Zero(c, sizeof(RPC_CLIENT_CREATE_ACCOUNT));
4516 c->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
4517 c->ClientAuth = ZeroMalloc(sizeof(CLIENT_AUTH));
4518
4519 InRpcClientOption(c->ClientOption, p);
4520 InRpcClientAuth(c->ClientAuth, p);
4521
4522 c->StartupAccount = PackGetInt(p, "StartupAccount") ? true : false;
4523 c->CheckServerCert = PackGetInt(p, "CheckServerCert") ? true : false;
4524 c->RetryOnServerCert = PackGetInt(p, "RetryOnServerCert") ? true : false;
4525 b = PackGetBuf(p, "ServerCert");
4526 if (b != NULL)
4527 {
4528 c->ServerCert = BufToX(b, false);
4529 FreeBuf(b);
4530 }
4531 PackGetData2(p, "ShortcutKey", c->ShortcutKey, sizeof(c->ShortcutKey));
4532 }
OutRpcClientCreateAccount(PACK * p,RPC_CLIENT_CREATE_ACCOUNT * c)4533 void OutRpcClientCreateAccount(PACK *p, RPC_CLIENT_CREATE_ACCOUNT *c)
4534 {
4535 BUF *b;
4536 // Validate arguments
4537 if (c == NULL || p == NULL)
4538 {
4539 return;
4540 }
4541
4542 OutRpcClientOption(p, c->ClientOption);
4543 OutRpcClientAuth(p, c->ClientAuth);
4544
4545 PackAddInt(p, "StartupAccount", c->StartupAccount);
4546 PackAddInt(p, "CheckServerCert", c->CheckServerCert);
4547 PackAddInt(p, "RetryOnServerCert", c->RetryOnServerCert);
4548 if (c->ServerCert != NULL)
4549 {
4550 b = XToBuf(c->ServerCert, false);
4551 if (b != NULL)
4552 {
4553 PackAddBuf(p, "ServerCert", b);
4554 FreeBuf(b);
4555 }
4556 }
4557 PackAddData(p, "ShortcutKey", c->ShortcutKey, sizeof(c->ShortcutKey));
4558 }
4559
4560 // RPC_CLIENT_ENUM_ACCOUNT
InRpcClientEnumAccount(RPC_CLIENT_ENUM_ACCOUNT * e,PACK * p)4561 void InRpcClientEnumAccount(RPC_CLIENT_ENUM_ACCOUNT *e, PACK *p)
4562 {
4563 UINT i;
4564 // Validate arguments
4565 if (e == NULL || p == NULL)
4566 {
4567 return;
4568 }
4569
4570 Zero(e, sizeof(RPC_CLIENT_ENUM_ACCOUNT));
4571
4572 e->NumItem = PackGetNum(p, "NumItem");
4573 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_ACCOUNT_ITEM *) * e->NumItem);
4574
4575 for (i = 0;i < e->NumItem;i++)
4576 {
4577 RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = e->Items[i] =
4578 ZeroMalloc(sizeof(RPC_CLIENT_ENUM_ACCOUNT_ITEM));
4579
4580 PackGetUniStrEx(p, "AccountName", item->AccountName, sizeof(item->AccountName), i);
4581 PackGetStrEx(p, "UserName", item->UserName, sizeof(item->UserName), i);
4582 PackGetStrEx(p, "ServerName", item->ServerName, sizeof(item->ServerName), i);
4583 PackGetStrEx(p, "ProxyName", item->ProxyName, sizeof(item->ProxyName), i);
4584 PackGetStrEx(p, "DeviceName", item->DeviceName, sizeof(item->DeviceName), i);
4585 item->ProxyType = PackGetIntEx(p, "ProxyType", i);
4586 item->Active = PackGetIntEx(p, "Active", i) ? true : false;
4587 item->StartupAccount = PackGetIntEx(p, "StartupAccount", i) ? true : false;
4588 item->Connected = PackGetBoolEx(p, "Connected", i);
4589 item->Port = PackGetIntEx(p, "Port", i);
4590 PackGetStrEx(p, "HubName", item->HubName, sizeof(item->HubName), i);
4591 item->CreateDateTime = PackGetInt64Ex(p, "CreateDateTime", i);
4592 item->UpdateDateTime = PackGetInt64Ex(p, "UpdateDateTime", i);
4593 item->LastConnectDateTime = PackGetInt64Ex(p, "LastConnectDateTime", i);
4594 }
4595 }
OutRpcClientEnumAccount(PACK * p,RPC_CLIENT_ENUM_ACCOUNT * e)4596 void OutRpcClientEnumAccount(PACK *p, RPC_CLIENT_ENUM_ACCOUNT *e)
4597 {
4598 UINT i;
4599 // Validate arguments
4600 if (e == NULL || p == NULL)
4601 {
4602 return;
4603 }
4604
4605 PackAddNum(p, "NumItem", e->NumItem);
4606
4607 PackSetCurrentJsonGroupName(p, "AccountList");
4608 for (i = 0;i < e->NumItem;i++)
4609 {
4610 RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = e->Items[i];
4611
4612 PackAddUniStrEx(p, "AccountName", item->AccountName, i, e->NumItem);
4613 PackAddStrEx(p, "UserName", item->UserName, i, e->NumItem);
4614 PackAddStrEx(p, "ServerName", item->ServerName, i, e->NumItem);
4615 PackAddStrEx(p, "ProxyName", item->ProxyName, i, e->NumItem);
4616 PackAddStrEx(p, "DeviceName", item->DeviceName, i, e->NumItem);
4617 PackAddIntEx(p, "ProxyType", item->ProxyType, i, e->NumItem);
4618 PackAddIntEx(p, "Active", item->Active, i, e->NumItem);
4619 PackAddIntEx(p, "StartupAccount", item->StartupAccount, i, e->NumItem);
4620 PackAddBoolEx(p, "Connected", item->Connected, i, e->NumItem);
4621 PackAddIntEx(p, "Port", item->Port, i, e->NumItem);
4622 PackAddStrEx(p, "HubName", item->HubName, i, e->NumItem);
4623 PackAddTime64Ex(p, "CreateDateTime", item->CreateDateTime, i, e->NumItem);
4624 PackAddTime64Ex(p, "UpdateDateTime", item->UpdateDateTime, i, e->NumItem);
4625 PackAddTime64Ex(p, "LastConnectDateTime", item->LastConnectDateTime, i, e->NumItem);
4626 }
4627 PackSetCurrentJsonGroupName(p, NULL);
4628 }
4629
4630 // RPC_CLIENT_DELETE_ACCOUNT
InRpcClientDeleteAccount(RPC_CLIENT_DELETE_ACCOUNT * a,PACK * p)4631 void InRpcClientDeleteAccount(RPC_CLIENT_DELETE_ACCOUNT *a, PACK *p)
4632 {
4633 // Validate arguments
4634 if (a == NULL || p == NULL)
4635 {
4636 return;
4637 }
4638
4639 Zero(a, sizeof(RPC_CLIENT_DELETE_ACCOUNT));
4640 PackGetUniStr(p, "AccountName", a->AccountName, sizeof(a->AccountName));
4641 }
OutRpcClientDeleteAccount(PACK * p,RPC_CLIENT_DELETE_ACCOUNT * a)4642 void OutRpcClientDeleteAccount(PACK *p, RPC_CLIENT_DELETE_ACCOUNT *a)
4643 {
4644 // Validate arguments
4645 if (a == NULL || p == NULL)
4646 {
4647 return;
4648 }
4649
4650 PackAddUniStr(p, "AccountName", a->AccountName);
4651 }
4652
4653 // RPC_RENAME_ACCOUNT
InRpcRenameAccount(RPC_RENAME_ACCOUNT * a,PACK * p)4654 void InRpcRenameAccount(RPC_RENAME_ACCOUNT *a, PACK *p)
4655 {
4656 // Validate arguments
4657 if (a == NULL || p == NULL)
4658 {
4659 return;
4660 }
4661
4662 Zero(a, sizeof(RPC_RENAME_ACCOUNT));
4663
4664 PackGetUniStr(p, "OldName", a->OldName, sizeof(a->OldName));
4665 PackGetUniStr(p, "NewName", a->NewName, sizeof(a->NewName));
4666 }
OutRpcRenameAccount(PACK * p,RPC_RENAME_ACCOUNT * a)4667 void OutRpcRenameAccount(PACK *p, RPC_RENAME_ACCOUNT *a)
4668 {
4669 // Validate arguments
4670 if (a == NULL || p == NULL)
4671 {
4672 return;
4673 }
4674
4675 PackAddUniStr(p, "OldName", a->OldName);
4676 PackAddUniStr(p, "NewName", a->NewName);
4677 }
4678
4679 // RPC_CLIENT_GET_ACCOUNT
InRpcClientGetAccount(RPC_CLIENT_GET_ACCOUNT * c,PACK * p)4680 void InRpcClientGetAccount(RPC_CLIENT_GET_ACCOUNT *c, PACK *p)
4681 {
4682 BUF *b;
4683 // Validate arguments
4684 if (c == NULL || p == NULL)
4685 {
4686 return;
4687 }
4688
4689 Zero(c, sizeof(RPC_CLIENT_GET_ACCOUNT));
4690
4691 c->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
4692 c->ClientAuth = ZeroMalloc(sizeof(CLIENT_AUTH));
4693
4694 PackGetUniStr(p, "AccountName", c->AccountName, sizeof(c->AccountName));
4695 c->StartupAccount = PackGetInt(p, "StartupAccount") ? true : false;
4696 c->CheckServerCert = PackGetInt(p, "CheckServerCert") ? true : false;
4697 c->RetryOnServerCert = PackGetInt(p, "RetryOnServerCert") ? true : false;
4698 b = PackGetBuf(p, "ServerCert");
4699 if (b != NULL)
4700 {
4701 c->ServerCert = BufToX(b, false);
4702 FreeBuf(b);
4703 }
4704
4705 InRpcClientOption(c->ClientOption, p);
4706 InRpcClientAuth(c->ClientAuth, p);
4707
4708 c->CreateDateTime = PackGetInt64(p, "CreateDateTime");
4709 c->UpdateDateTime = PackGetInt64(p, "UpdateDateTime");
4710 c->LastConnectDateTime = PackGetInt64(p, "LastConnectDateTime");
4711
4712 PackGetData2(p, "ShortcutKey", c->ShortcutKey, SHA1_SIZE);
4713 }
OutRpcClientGetAccount(PACK * p,RPC_CLIENT_GET_ACCOUNT * c)4714 void OutRpcClientGetAccount(PACK *p, RPC_CLIENT_GET_ACCOUNT *c)
4715 {
4716 BUF *b;
4717 // Validate arguments
4718 if (c == NULL || p == NULL)
4719 {
4720 return;
4721 }
4722
4723 PackAddUniStr(p, "AccountName", c->AccountName);
4724 PackAddInt(p, "StartupAccount", c->StartupAccount);
4725 PackAddInt(p, "CheckServerCert", c->CheckServerCert);
4726 PackAddInt(p, "RetryOnServerCert", c->RetryOnServerCert);
4727
4728 if (c->ServerCert != NULL)
4729 {
4730 b = XToBuf(c->ServerCert, false);
4731 if (b != NULL)
4732 {
4733 PackAddBuf(p, "ServerCert", b);
4734 FreeBuf(b);
4735 }
4736 }
4737
4738 OutRpcClientOption(p, c->ClientOption);
4739 OutRpcClientAuth(p, c->ClientAuth);
4740
4741 PackAddData(p, "ShortcutKey", c->ShortcutKey, SHA1_SIZE);
4742
4743 PackAddTime64(p, "CreateDateTime", c->CreateDateTime);
4744 PackAddTime64(p, "UpdateDateTime", c->UpdateDateTime);
4745 PackAddTime64(p, "LastConnectDateTime", c->LastConnectDateTime);
4746 }
4747
4748 // RPC_CLIENT_CONNECT
InRpcClientConnect(RPC_CLIENT_CONNECT * c,PACK * p)4749 void InRpcClientConnect(RPC_CLIENT_CONNECT *c, PACK *p)
4750 {
4751 // Validate arguments
4752 if (c == NULL || p == NULL)
4753 {
4754 return;
4755 }
4756
4757 Zero(c, sizeof(RPC_CLIENT_CONNECT));
4758
4759 PackGetUniStr(p, "AccountName", c->AccountName, sizeof(c->AccountName));
4760 }
OutRpcClientConnect(PACK * p,RPC_CLIENT_CONNECT * c)4761 void OutRpcClientConnect(PACK *p, RPC_CLIENT_CONNECT *c)
4762 {
4763 // Validate arguments
4764 if (c == NULL || p == NULL)
4765 {
4766 return;
4767 }
4768
4769 PackAddUniStr(p, "AccountName", c->AccountName);
4770 }
4771
4772 // POLICY
InRpcPolicy(POLICY * o,PACK * p)4773 void InRpcPolicy(POLICY *o, PACK *p)
4774 {
4775 POLICY *pol;
4776 // Validate arguments
4777 if (o == NULL || p == NULL)
4778 {
4779 return;
4780 }
4781
4782 pol = PackGetPolicy(p);
4783 Copy(o, pol, sizeof(POLICY));
4784 Free(pol);
4785 }
OutRpcPolicy(PACK * p,POLICY * o)4786 void OutRpcPolicy(PACK *p, POLICY *o)
4787 {
4788 // Validate arguments
4789 if (o == NULL || p == NULL)
4790 {
4791 return;
4792 }
4793
4794 PackAddPolicy(p, o);
4795 }
4796
4797 // RPC_CLIENT_GET_CONNECTION_STATUS
InRpcClientGetConnectionStatus(RPC_CLIENT_GET_CONNECTION_STATUS * s,PACK * p)4798 void InRpcClientGetConnectionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *s, PACK *p)
4799 {
4800 BUF *b;
4801 // Validate arguments
4802 if (s == NULL || p == NULL)
4803 {
4804 return;
4805 }
4806
4807 Zero(s, sizeof(RPC_CLIENT_GET_CONNECTION_STATUS));
4808
4809 PackGetUniStr(p, "AccountName", s->AccountName, sizeof(s->AccountName));
4810
4811 PackGetStr(p, "ServerName", s->ServerName, sizeof(s->ServerName));
4812 PackGetStr(p, "ServerProductName", s->ServerProductName, sizeof(s->ServerProductName));
4813 PackGetStr(p, "CipherName", s->CipherName, sizeof(s->CipherName));
4814 PackGetStr(p, "SessionName", s->SessionName, sizeof(s->SessionName));
4815 PackGetStr(p, "ConnectionName", s->ConnectionName, sizeof(s->ConnectionName));
4816
4817 if (PackGetDataSize(p, "SessionKey") == SHA1_SIZE)
4818 {
4819 PackGetData(p, "SessionKey", s->SessionKey);
4820 }
4821
4822 s->SessionStatus = PackGetInt(p, "SessionStatus");
4823 s->ServerPort = PackGetInt(p, "ServerPort");
4824 s->ServerProductVer = PackGetInt(p, "ServerProductVer");
4825 s->ServerProductBuild = PackGetInt(p, "ServerProductBuild");
4826 s->NumConnectionsEstablished = PackGetInt(p, "NumConnectionsEstablished");
4827 s->MaxTcpConnections = PackGetInt(p, "MaxTcpConnections");
4828 s->NumTcpConnections = PackGetInt(p, "NumTcpConnections");
4829 s->NumTcpConnectionsUpload = PackGetInt(p, "NumTcpConnectionsUpload");
4830 s->NumTcpConnectionsDownload = PackGetInt(p, "NumTcpConnectionsDownload");
4831
4832 s->StartTime = PackGetInt64(p, "StartTime");
4833 /* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */
4834 s->FirstConnectionEstablisiedTime = PackGetInt64(p, "FirstConnectionEstablisiedTime");
4835 s->CurrentConnectionEstablishTime = PackGetInt64(p, "CurrentConnectionEstablishTime");
4836 s->TotalSendSize = PackGetInt64(p, "TotalSendSize");
4837 s->TotalRecvSize = PackGetInt64(p, "TotalRecvSize");
4838 s->TotalSendSizeReal = PackGetInt64(p, "TotalSendSizeReal");
4839 s->TotalRecvSizeReal = PackGetInt64(p, "TotalRecvSizeReal");
4840
4841 s->Active = PackGetInt(p, "Active") ? true : false;
4842 s->Connected = PackGetInt(p, "Connected") ? true : false;
4843 s->HalfConnection = PackGetInt(p, "HalfConnection") ? true : false;
4844 s->QoS = PackGetInt(p, "QoS") ? true : false;
4845 s->UseEncrypt = PackGetInt(p, "UseEncrypt") ? true : false;
4846 s->UseCompress = PackGetInt(p, "UseCompress") ? true : false;
4847 s->IsRUDPSession = PackGetInt(p, "IsRUDPSession") ? true : false;
4848 PackGetStr(p, "UnderlayProtocol", s->UnderlayProtocol, sizeof(s->UnderlayProtocol));
4849 s->IsUdpAccelerationEnabled = PackGetInt(p, "IsUdpAccelerationEnabled") ? true : false;
4850 s->IsUsingUdpAcceleration = PackGetInt(p, "IsUsingUdpAcceleration") ? true : false;
4851
4852 s->IsBridgeMode = PackGetBool(p, "IsBridgeMode");
4853 s->IsMonitorMode = PackGetBool(p, "IsMonitorMode");
4854
4855 s->VLanId = PackGetInt(p, "VLanId");
4856
4857 b = PackGetBuf(p, "ServerX");
4858 if (b != NULL)
4859 {
4860 s->ServerX = BufToX(b, false);
4861 FreeBuf(b);
4862 }
4863
4864 b = PackGetBuf(p, "ClientX");
4865 if (b != NULL)
4866 {
4867 s->ClientX = BufToX(b, false);
4868 FreeBuf(b);
4869 }
4870
4871 InRpcPolicy(&s->Policy, p);
4872
4873 InRpcTraffic(&s->Traffic, p);
4874 }
OutRpcClientGetConnectionStatus(PACK * p,RPC_CLIENT_GET_CONNECTION_STATUS * c)4875 void OutRpcClientGetConnectionStatus(PACK *p, RPC_CLIENT_GET_CONNECTION_STATUS *c)
4876 {
4877 BUF *b;
4878 // Validate arguments
4879 if (p == NULL || c == NULL)
4880 {
4881 return;
4882 }
4883
4884 PackAddUniStr(p, "AccountName", c->AccountName);
4885
4886 PackAddStr(p, "ServerName", c->ServerName);
4887 PackAddStr(p, "ServerProductName", c->ServerProductName);
4888 PackAddStr(p, "CipherName", c->CipherName);
4889 PackAddStr(p, "SessionName", c->SessionName);
4890 PackAddStr(p, "ConnectionName", c->ConnectionName);
4891
4892 PackAddData(p, "SessionKey", c->SessionKey, SHA1_SIZE);
4893
4894 PackAddBool(p, "Active", c->Active);
4895 PackAddBool(p, "Connected", c->Connected);
4896 PackAddInt(p, "SessionStatus", c->SessionStatus);
4897 PackAddInt(p, "ServerPort", c->ServerPort);
4898 PackAddInt(p, "ServerProductVer", c->ServerProductVer);
4899 PackAddInt(p, "ServerProductBuild", c->ServerProductBuild);
4900 PackAddInt(p, "NumConnectionsEstablished", c->NumConnectionsEstablished);
4901 PackAddBool(p, "HalfConnection", c->HalfConnection);
4902 PackAddBool(p, "QoS", c->QoS);
4903 PackAddInt(p, "MaxTcpConnections", c->MaxTcpConnections);
4904 PackAddInt(p, "NumTcpConnections", c->NumTcpConnections);
4905 PackAddInt(p, "NumTcpConnectionsUpload", c->NumTcpConnectionsUpload);
4906 PackAddInt(p, "NumTcpConnectionsDownload", c->NumTcpConnectionsDownload);
4907 PackAddBool(p, "UseEncrypt", c->UseEncrypt);
4908 PackAddBool(p, "UseCompress", c->UseCompress);
4909 PackAddBool(p, "IsRUDPSession", c->IsRUDPSession);
4910 PackAddStr(p, "UnderlayProtocol", c->UnderlayProtocol);
4911 PackAddBool(p, "IsUdpAccelerationEnabled", c->IsUdpAccelerationEnabled);
4912 PackAddBool(p, "IsUsingUdpAcceleration", c->IsUsingUdpAcceleration);
4913
4914 PackAddBool(p, "IsBridgeMode", c->IsBridgeMode);
4915 PackAddBool(p, "IsMonitorMode", c->IsMonitorMode);
4916
4917 PackAddTime64(p, "StartTime", c->StartTime);
4918 PackAddTime64(p, "FirstConnectionEstablisiedTime", c->FirstConnectionEstablisiedTime);
4919 PackAddTime64(p, "CurrentConnectionEstablishTime", c->CurrentConnectionEstablishTime);
4920 PackAddInt64(p, "TotalSendSize", c->TotalSendSize);
4921 PackAddInt64(p, "TotalRecvSize", c->TotalRecvSize);
4922 PackAddInt64(p, "TotalSendSizeReal", c->TotalSendSizeReal);
4923 PackAddInt64(p, "TotalRecvSizeReal", c->TotalRecvSizeReal);
4924
4925 PackAddInt(p, "VLanId", c->VLanId);
4926
4927 OutRpcPolicy(p, &c->Policy);
4928
4929 OutRpcTraffic(p, &c->Traffic);
4930
4931 if (c->ServerX != NULL)
4932 {
4933 b = XToBuf(c->ServerX, false);
4934 PackAddBuf(p, "ServerX", b);
4935 FreeBuf(b);
4936 }
4937
4938 if (c->ClientX != NULL)
4939 {
4940 b = XToBuf(c->ClientX, false);
4941 PackAddBuf(p, "ClientX", b);
4942 FreeBuf(b);
4943 }
4944 }
4945
4946 // Notification main
CiNotifyMain(CLIENT * c,SOCK * s)4947 void CiNotifyMain(CLIENT *c, SOCK *s)
4948 {
4949 CANCEL *cancel;
4950 // Validate arguments
4951 if (c == NULL || s == NULL)
4952 {
4953 return;
4954 }
4955
4956 // Register a Cancel
4957 cancel = NewCancel();
4958 LockList(c->NotifyCancelList);
4959 {
4960 Add(c->NotifyCancelList, cancel);
4961 }
4962 UnlockList(c->NotifyCancelList);
4963
4964 // Wait
4965 while (true)
4966 {
4967 char ch = '@';
4968 SOCKSET set;
4969 InitSockSet(&set);
4970 AddSockSet(&set, s);
4971 Select(&set, INFINITE, cancel, NULL);
4972
4973 if (c->Halt)
4974 {
4975 // Abort
4976 break;
4977 }
4978
4979 // 1 byte transmission
4980 if (Send(s, &ch, 1, false) == 0)
4981 {
4982 // Disconnected
4983 break;
4984 }
4985 }
4986
4987 // Disconnect
4988 Disconnect(s);
4989
4990 // Unregister the Cancel
4991 LockList(c->NotifyCancelList);
4992 {
4993 Delete(c->NotifyCancelList, cancel);
4994 }
4995 UnlockList(c->NotifyCancelList);
4996
4997 ReleaseCancel(cancel);
4998 }
4999
5000 // RPC acceptance code
CiRpcAccepted(CLIENT * c,SOCK * s)5001 void CiRpcAccepted(CLIENT *c, SOCK *s)
5002 {
5003 UCHAR hashed_password[SHA1_SIZE];
5004 UINT rpc_mode;
5005 UINT retcode;
5006 RPC *rpc;
5007 // Validate arguments
5008 if (c == NULL || s == NULL)
5009 {
5010 return;
5011 }
5012
5013 // Receive the RPC mode
5014 if (RecvAll(s, &rpc_mode, sizeof(UINT), false) == false)
5015 {
5016 return;
5017 }
5018
5019 rpc_mode = Endian32(rpc_mode);
5020
5021 if (rpc_mode == CLIENT_RPC_MODE_NOTIFY)
5022 {
5023 // Notification mode
5024 CiNotifyMain(c, s);
5025 return;
5026 }
5027 else if (rpc_mode == CLIENT_RPC_MODE_SHORTCUT || rpc_mode == CLIENT_RPC_MODE_SHORTCUT_DISCONNECT)
5028 {
5029 // Shortcut key received
5030 UCHAR key[SHA1_SIZE];
5031 UINT err = ERR_NO_ERROR;
5032 if (RecvAll(s, key, SHA1_SIZE, false))
5033 {
5034 UINT i;
5035 wchar_t title[MAX_ACCOUNT_NAME_LEN + 1];
5036 bool ok = false;
5037 // Connect to the specified setting
5038 LockList(c->AccountList);
5039 {
5040 for (i = 0;i < LIST_NUM(c->AccountList);i++)
5041 {
5042 ACCOUNT *a = LIST_DATA(c->AccountList, i);
5043 Lock(a->lock);
5044 {
5045 if (Cmp(a->ShortcutKey, key, SHA1_SIZE) == 0)
5046 {
5047 ok = true;
5048 UniStrCpy(title, sizeof(title), a->ClientOption->AccountName);
5049 }
5050 }
5051 Unlock(a->lock);
5052 }
5053 }
5054 UnlockList(c->AccountList);
5055
5056 if (ok == false)
5057 {
5058 err = ERR_ACCOUNT_NOT_FOUND;
5059 }
5060 else
5061 {
5062 RPC_CLIENT_CONNECT t;
5063 Zero(&t, sizeof(t));
5064 UniStrCpy(t.AccountName, sizeof(t.AccountName), title);
5065
5066 if (rpc_mode == CLIENT_RPC_MODE_SHORTCUT)
5067 {
5068 // Connect
5069 if (CtConnect(c, &t))
5070 {
5071 err = ERR_NO_ERROR;
5072 }
5073 else
5074 {
5075 err = c->Err;
5076 }
5077 }
5078 else
5079 {
5080 // Connect
5081 if (CtDisconnect(c, &t, false))
5082 {
5083 err = ERR_NO_ERROR;
5084 }
5085 else
5086 {
5087 err = c->Err;
5088 }
5089 }
5090 }
5091
5092 err = Endian32(err);
5093 SendAll(s, &err, sizeof(UINT), false);
5094 (void)RecvAll(s, &err, sizeof(UINT), false);
5095 }
5096 return;
5097 }
5098
5099 // Password reception
5100 if (RecvAll(s, hashed_password, SHA1_SIZE, false) == false)
5101 {
5102 return;
5103 }
5104
5105 retcode = 0;
5106
5107 // Password comparison
5108 if (Cmp(hashed_password, c->EncryptedPassword, SHA1_SIZE) != 0)
5109 {
5110 retcode = 1;
5111 }
5112
5113 if (c->PasswordRemoteOnly && IsLocalHostIP(&s->RemoteIP))
5114 {
5115 // If in a mode that requires a password only remote,
5116 // the password sent from localhost is considered to be always correct
5117 retcode = 0;
5118 }
5119
5120 Lock(c->lock);
5121 {
5122 if (c->Config.AllowRemoteConfig == false)
5123 {
5124 // If the remote control is prohibited,
5125 // identify whether this connection is from remote
5126 if (IsLocalHostIP(&s->RemoteIP) == false)
5127 {
5128 retcode = 2;
5129 }
5130 }
5131 }
5132 Unlock(c->lock);
5133
5134 retcode = Endian32(retcode);
5135 // Error code transmission
5136 if (SendAll(s, &retcode, sizeof(UINT), false) == false)
5137 {
5138 return;
5139 }
5140
5141
5142
5143 if (retcode != 0)
5144 {
5145 // Disconnect due to an error
5146 return;
5147 }
5148
5149 // Create a RPC server
5150 rpc = StartRpcServer(s, CiRpcDispatch, c);
5151
5152 // RPC server operation
5153 RpcServer(rpc);
5154
5155 // Release the RPC server
5156 EndRpc(rpc);
5157 }
5158
5159 // RPC acceptance thread
CiRpcAcceptThread(THREAD * thread,void * param)5160 void CiRpcAcceptThread(THREAD *thread, void *param)
5161 {
5162 CLIENT_RPC_CONNECTION *conn;
5163 CLIENT *c;
5164 SOCK *s;
5165 // Validate arguments
5166 if (thread == NULL || param == NULL)
5167 {
5168 return;
5169 }
5170
5171 conn = (CLIENT_RPC_CONNECTION *)param;
5172 s = conn->Sock;
5173 c = conn->Client;
5174 AddRef(s->ref);
5175
5176 // Add to the RPC connection list
5177 LockList(c->RpcConnectionList);
5178 {
5179 Add(c->RpcConnectionList, conn);
5180 }
5181 UnlockList(c->RpcConnectionList);
5182
5183 NoticeThreadInit(thread);
5184
5185 // Main process
5186 CiRpcAccepted(c, s);
5187
5188 // Release from the connection list
5189 LockList(c->RpcConnectionList);
5190 {
5191 Delete(c->RpcConnectionList, conn);
5192 }
5193 UnlockList(c->RpcConnectionList);
5194
5195 ReleaseSock(conn->Sock);
5196 ReleaseThread(conn->Thread);
5197 Free(conn);
5198
5199 Disconnect(s);
5200 ReleaseSock(s);
5201 }
5202
5203 // RPC server thread
CiRpcServerThread(THREAD * thread,void * param)5204 void CiRpcServerThread(THREAD *thread, void *param)
5205 {
5206 CLIENT *c;
5207 SOCK *listener;
5208 UINT i;
5209 LIST *thread_list;
5210 // Validate arguments
5211 if (thread == NULL || param == NULL)
5212 {
5213 return;
5214 }
5215
5216 c = (CLIENT *)param;
5217
5218 // RPC connection list
5219 c->RpcConnectionList = NewList(NULL);
5220
5221 // Open the port
5222 listener = NULL;
5223 for (i = CLIENT_CONFIG_PORT;i < (CLIENT_CONFIG_PORT + 5);i++)
5224 {
5225 listener = Listen(i);
5226 if (listener != NULL)
5227 {
5228 break;
5229 }
5230 }
5231
5232 if (listener == NULL)
5233 {
5234 // Error
5235 Alert(CEDAR_PRODUCT_STR " VPN Client RPC Port Open Failed.", CEDAR_CLIENT_STR);
5236 return;
5237 }
5238
5239 #ifdef OS_WIN32
5240 MsRegWriteIntEx2(REG_LOCAL_MACHINE, CLIENT_WIN32_REGKEYNAME, CLIENT_WIN32_REGVALUE_PORT, i, false, true);
5241 MsRegWriteIntEx2(REG_LOCAL_MACHINE, CLIENT_WIN32_REGKEYNAME, CLIENT_WIN32_REGVALUE_PID, MsGetCurrentProcessId(), false, true);
5242 #endif // OS_WIN32
5243
5244 c->RpcListener = listener;
5245 AddRef(listener->ref);
5246
5247 NoticeThreadInit(thread);
5248
5249 while (true)
5250 {
5251 // Wait for client connection
5252 CLIENT_RPC_CONNECTION *conn;
5253 SOCK *s = Accept(listener);
5254 if (s == NULL)
5255 {
5256 // Stop
5257 break;
5258 }
5259
5260 // Create a client processing thread
5261 conn = ZeroMalloc(sizeof(CLIENT_RPC_CONNECTION));
5262 conn->Client = c;
5263 conn->Sock = s;
5264 AddRef(s->ref);
5265
5266 conn->Thread = NewThread(CiRpcAcceptThread, (void *)conn);
5267 WaitThreadInit(conn->Thread);
5268
5269 ReleaseSock(s);
5270 }
5271
5272 // Release the listener
5273 ReleaseSock(listener);
5274
5275 thread_list = NewListFast(NULL);
5276
5277 // Set all the event notification
5278 LockList(c->NotifyCancelList);
5279 {
5280 UINT i;
5281 for (i = 0;i < LIST_NUM(c->NotifyCancelList);i++)
5282 {
5283 CANCEL *cancel = LIST_DATA(c->NotifyCancelList, i);
5284 Cancel(cancel);
5285 }
5286 }
5287 UnlockList(c->NotifyCancelList);
5288
5289 // Disconnect all the connections of connected yet
5290 LockList(c->RpcConnectionList);
5291 {
5292 for (i = 0;i < LIST_NUM(c->RpcConnectionList);i++)
5293 {
5294 CLIENT_RPC_CONNECTION *cc = LIST_DATA(c->RpcConnectionList, i);
5295 AddRef(cc->Thread->ref);
5296 Add(thread_list, cc->Thread);
5297 Disconnect(cc->Sock);
5298 }
5299 }
5300 UnlockList(c->RpcConnectionList);
5301
5302 for (i = 0;i < LIST_NUM(thread_list);i++)
5303 {
5304 THREAD *t = LIST_DATA(thread_list, i);
5305 WaitThread(t, INFINITE);
5306 ReleaseThread(t);
5307 }
5308
5309 ReleaseList(c->RpcConnectionList);
5310 ReleaseList(thread_list);
5311
5312 #ifdef OS_WIN32
5313 MsRegDeleteValueEx2(REG_LOCAL_MACHINE, CLIENT_WIN32_REGKEYNAME, CLIENT_WIN32_REGVALUE_PORT, false, true);
5314 MsRegDeleteValueEx2(REG_LOCAL_MACHINE, CLIENT_WIN32_REGKEYNAME, CLIENT_WIN32_REGVALUE_PID, false, true);
5315 #endif // OS_WIN32
5316 }
5317
5318 // Start the Keep
CiInitKeep(CLIENT * c)5319 void CiInitKeep(CLIENT *c)
5320 {
5321 // Validate arguments
5322 if (c == NULL)
5323 {
5324 return;
5325 }
5326
5327 c->Keep = StartKeep();
5328
5329 // Apply settings
5330 if (c->Config.UseKeepConnect)
5331 {
5332 KEEP *k = c->Keep;
5333 Lock(k->lock);
5334 {
5335 StrCpy(k->ServerName, sizeof(k->ServerName), c->Config.KeepConnectHost);
5336 k->ServerPort = c->Config.KeepConnectPort;
5337 k->Interval = c->Config.KeepConnectInterval * 1000;
5338 k->UdpMode = (c->Config.KeepConnectProtocol == CONNECTION_UDP) ? true : false;
5339 k->Enable = true;
5340 }
5341 Unlock(k->lock);
5342 }
5343 }
5344
5345 // Stop the Keep
CiFreeKeep(CLIENT * c)5346 void CiFreeKeep(CLIENT *c)
5347 {
5348 // Validate arguments
5349 if (c == NULL)
5350 {
5351 return;
5352 }
5353
5354 StopKeep(c->Keep);
5355 c->Keep = NULL;
5356 }
5357
5358 // Start the RPC
CiStartRpcServer(CLIENT * c)5359 void CiStartRpcServer(CLIENT *c)
5360 {
5361 // Validate arguments
5362 if (c == NULL)
5363 {
5364 return;
5365 }
5366
5367 c->RpcThread = NewThread(CiRpcServerThread, (void *)c);
5368 WaitThreadInit(c->RpcThread);
5369 }
5370
5371 // Stop the RPC
CiStopRpcServer(CLIENT * c)5372 void CiStopRpcServer(CLIENT *c)
5373 {
5374 // Validate arguments
5375 if (c == NULL)
5376 {
5377 return;
5378 }
5379
5380 Disconnect(c->RpcListener);
5381 ReleaseSock(c->RpcListener);
5382
5383 WaitThread(c->RpcThread, INFINITE);
5384 ReleaseThread(c->RpcThread);
5385 }
5386
5387 // Wait for the next notification
CcWaitNotify(NOTIFY_CLIENT * n)5388 bool CcWaitNotify(NOTIFY_CLIENT *n)
5389 {
5390 UCHAR c;
5391 // Validate arguments
5392 if (n == NULL)
5393 {
5394 return false;
5395 }
5396
5397 // 1 character reception
5398 if (RecvAll(n->Sock, &c, 1, false) == false)
5399 {
5400 // Disconnected
5401 return false;
5402 }
5403
5404 return true;
5405 }
5406
5407 // Connect as a notification client
CcConnectNotify(REMOTE_CLIENT * rc)5408 NOTIFY_CLIENT *CcConnectNotify(REMOTE_CLIENT *rc)
5409 {
5410 NOTIFY_CLIENT *n;
5411 SOCK *s;
5412 char tmp[MAX_SIZE];
5413 bool rpc_mode = false;
5414 UINT port;
5415 // Validate arguments
5416 if (rc == NULL || rc->Rpc == NULL || rc->Rpc->Sock == NULL)
5417 {
5418 return NULL;
5419 }
5420
5421 // Connect
5422 IPToStr(tmp, sizeof(tmp), &rc->Rpc->Sock->RemoteIP);
5423 port = rc->Rpc->Sock->RemotePort;
5424
5425 s = Connect(tmp, port);
5426 if (s == NULL)
5427 {
5428 return NULL;
5429 }
5430
5431 rpc_mode = Endian32(rpc_mode);
5432 if (SendAll(s, &rpc_mode, sizeof(rpc_mode), false) == false)
5433 {
5434 ReleaseSock(s);
5435 return NULL;
5436 }
5437
5438 n = ZeroMalloc(sizeof(NOTIFY_CLIENT));
5439 n->Sock = s;
5440
5441 return n;
5442 }
5443
5444 // Stop the notification client
CcStopNotify(NOTIFY_CLIENT * n)5445 void CcStopNotify(NOTIFY_CLIENT *n)
5446 {
5447 // Validate arguments
5448 if (n == NULL)
5449 {
5450 return;
5451 }
5452
5453 Disconnect(n->Sock);
5454 }
5455
5456 // Delete the notification client
CcDisconnectNotify(NOTIFY_CLIENT * n)5457 void CcDisconnectNotify(NOTIFY_CLIENT *n)
5458 {
5459 // Validate arguments
5460 if (n == NULL)
5461 {
5462 return;
5463 }
5464
5465 // Disconnect
5466 Disconnect(n->Sock);
5467 ReleaseSock(n->Sock);
5468
5469 // Memory release
5470 Free(n);
5471 }
5472
5473 // Disconnect the remote connection
CcDisconnectRpc(REMOTE_CLIENT * rc)5474 void CcDisconnectRpc(REMOTE_CLIENT *rc)
5475 {
5476 // Validate arguments
5477 if (rc == NULL)
5478 {
5479 return;
5480 }
5481
5482 RpcFree(rc->Rpc);
5483 Free(rc);
5484 }
5485
5486 // Connect to the client to start the shortcut connection setting
CcShortcut(UCHAR * key)5487 UINT CcShortcut(UCHAR *key)
5488 {
5489 UINT ret;
5490 // Validate arguments
5491 if (key == NULL)
5492 {
5493 return ERR_INVALID_PARAMETER;
5494 }
5495
5496 CcConnectRpcEx("localhost", NULL, NULL, NULL, key, &ret, false, 0);
5497
5498 return ret;
5499 }
5500
5501 // Disconnect the connected shortcut connection
CcShortcutDisconnect(UCHAR * key)5502 UINT CcShortcutDisconnect(UCHAR *key)
5503 {
5504 UINT ret;
5505 // Validate arguments
5506 if (key == NULL)
5507 {
5508 return ERR_INVALID_PARAMETER;
5509 }
5510
5511 CcConnectRpcEx("localhost", NULL, NULL, NULL, key, &ret, true, 0);
5512
5513 return ret;
5514 }
5515
5516 // Connect to the remote client
CcConnectRpc(char * server_name,char * password,bool * bad_pass,bool * no_remote,UINT wait_retry)5517 REMOTE_CLIENT *CcConnectRpc(char *server_name, char *password, bool *bad_pass, bool *no_remote, UINT wait_retry)
5518 {
5519 return CcConnectRpcEx(server_name, password, bad_pass, no_remote, NULL, NULL, false, wait_retry);
5520 }
CcConnectRpcEx(char * server_name,char * password,bool * bad_pass,bool * no_remote,UCHAR * key,UINT * key_error_code,bool shortcut_disconnect,UINT wait_retry)5521 REMOTE_CLIENT *CcConnectRpcEx(char *server_name, char *password, bool *bad_pass, bool *no_remote, UCHAR *key, UINT *key_error_code, bool shortcut_disconnect, UINT wait_retry)
5522 {
5523 SOCK *s = NULL;
5524 UINT i;
5525 UINT retcode;
5526 UINT rpc_mode = CLIENT_RPC_MODE_MANAGEMENT;
5527 RPC *rpc;
5528 REMOTE_CLIENT *ret;
5529 UCHAR hash_password[SHA1_SIZE];
5530 UINT port_start;
5531 UINT64 try_started = 0;
5532 bool ok;
5533 UINT reg_port = 0;
5534 UINT reg_pid = 0;
5535 // Validate arguments
5536 if (server_name == NULL)
5537 {
5538 return NULL;
5539 }
5540 if (password == NULL)
5541 {
5542 password = "";
5543 }
5544
5545 if (key_error_code != NULL)
5546 {
5547 *key_error_code = ERR_NO_ERROR;
5548 }
5549
5550 if (bad_pass != NULL)
5551 {
5552 *bad_pass = false;
5553 }
5554
5555 if (no_remote != NULL)
5556 {
5557 *no_remote = false;
5558 }
5559
5560 #ifdef OS_WIN32
5561 // read the current port number from the registry of the localhost
5562 if (StrCmpi(server_name, "localhost") == 0)
5563 {
5564 reg_port = MsRegReadIntEx2(REG_LOCAL_MACHINE, CLIENT_WIN32_REGKEYNAME, CLIENT_WIN32_REGVALUE_PORT, false, true);
5565 reg_pid = MsRegReadIntEx2(REG_LOCAL_MACHINE, CLIENT_WIN32_REGKEYNAME, CLIENT_WIN32_REGVALUE_PID, false, true);
5566
5567 if (reg_pid != 0)
5568 {
5569 if (MsIsServiceRunning(GC_SVC_NAME_VPNCLIENT) == false)
5570 {
5571 reg_port = 0;
5572 }
5573 }
5574 else
5575 {
5576 reg_port = 0;
5577 }
5578 }
5579
5580 if (reg_port != 0)
5581 {
5582 s = Connect(server_name, reg_port);
5583
5584 if (s != NULL)
5585 {
5586 goto L_TRY;
5587 }
5588 }
5589
5590 #endif // OS_WIN32
5591
5592 port_start = CLIENT_CONFIG_PORT - 1;
5593
5594 RETRY:
5595 port_start++;
5596
5597 if (port_start >= (CLIENT_CONFIG_PORT + 5))
5598 {
5599 return NULL;
5600 }
5601
5602 ok = false;
5603
5604 while (true)
5605 {
5606 for (i = port_start;i < (CLIENT_CONFIG_PORT + 5);i++)
5607 {
5608 if (CheckTCPPort(server_name, i))
5609 {
5610 ok = true;
5611 break;
5612 }
5613 }
5614
5615 if (ok)
5616 {
5617 break;
5618 }
5619
5620 if (wait_retry == 0)
5621 {
5622 break;
5623 }
5624
5625 if (try_started == 0)
5626 {
5627 try_started = Tick64();
5628 }
5629
5630 if ((try_started + (UINT64)wait_retry) <= Tick64())
5631 {
5632 break;
5633 }
5634 }
5635
5636 if (ok == false)
5637 {
5638 if (key_error_code)
5639 {
5640 *key_error_code = ERR_CONNECT_FAILED;
5641 }
5642 return NULL;
5643 }
5644
5645 port_start = i;
5646
5647 s = Connect(server_name, i);
5648 if (s == NULL)
5649 {
5650 if (key_error_code)
5651 {
5652 *key_error_code = ERR_CONNECT_FAILED;
5653 }
5654 goto RETRY;
5655 }
5656 L_TRY:
5657
5658 SetTimeout(s, 10000);
5659
5660 Sha0(hash_password, password, StrLen(password));
5661
5662 if (key != NULL)
5663 {
5664 if (shortcut_disconnect == false)
5665 {
5666 rpc_mode = CLIENT_RPC_MODE_SHORTCUT;
5667 }
5668 else
5669 {
5670 rpc_mode = CLIENT_RPC_MODE_SHORTCUT_DISCONNECT;
5671 }
5672 }
5673
5674 rpc_mode = Endian32(rpc_mode);
5675 SendAdd(s, &rpc_mode, sizeof(UINT));
5676
5677 if (key != NULL)
5678 {
5679 SendAdd(s, key, SHA1_SIZE);
5680 }
5681 else
5682 {
5683 SendAdd(s, hash_password, SHA1_SIZE);
5684 }
5685
5686 if (SendNow(s, false) == false)
5687 {
5688 ReleaseSock(s);
5689 goto RETRY;
5690 }
5691
5692 if (RecvAll(s, &retcode, sizeof(UINT), false) == false)
5693 {
5694 ReleaseSock(s);
5695 goto RETRY;
5696 }
5697
5698 retcode = Endian32(retcode);
5699
5700 if (retcode >= 1024)
5701 {
5702 ReleaseSock(s);
5703 goto RETRY;
5704 }
5705
5706 if (key != NULL)
5707 {
5708 if (key_error_code)
5709 {
5710 *key_error_code = retcode;
5711 }
5712 SendAll(s, &retcode, sizeof(UINT), false);
5713 ReleaseSock(s);
5714 return NULL;
5715 }
5716
5717 switch (retcode)
5718 {
5719 case 1:
5720 if (bad_pass != NULL)
5721 {
5722 *bad_pass = true;
5723 }
5724 break;
5725 case 2:
5726 if (no_remote != NULL)
5727 {
5728 *no_remote = true;
5729 }
5730 break;
5731 }
5732
5733 if (retcode != 0)
5734 {
5735 ReleaseSock(s);
5736 return NULL;
5737 }
5738
5739 SetTimeout(s, INFINITE);
5740
5741 rpc = StartRpcClient(s, NULL);
5742
5743 ReleaseSock(s);
5744
5745 ret = ZeroMalloc(sizeof(REMOTE_CLIENT));
5746 rpc->Param = ret;
5747
5748 if (ret != NULL)
5749 {
5750 RPC_CLIENT_VERSION t;
5751
5752 ret->Rpc = rpc;
5753 Zero(&t, sizeof(t));
5754 CcGetClientVersion(ret, &t);
5755 ret->OsType = t.OsType;
5756 ret->Unix = OS_IS_UNIX(ret->OsType);
5757 ret->IsVgcSupported = t.IsVgcSupported;
5758 ret->ShowVgcLink = t.ShowVgcLink;
5759 StrCpy(ret->ClientId, sizeof(ret->ClientId), t.ClientId);
5760 }
5761
5762 return ret;
5763 }
5764
5765 // Get a RPC_CLIENT_GET_CONNECTION_STATUS from the session
CiGetSessionStatus(RPC_CLIENT_GET_CONNECTION_STATUS * st,SESSION * s)5766 void CiGetSessionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *st, SESSION *s)
5767 {
5768 // Validate arguments
5769 if (st == NULL || s == NULL)
5770 {
5771 return;
5772 }
5773
5774 Lock(s->lock);
5775 {
5776 // Operation flag
5777 st->Active = true;
5778
5779 // Session status
5780 st->SessionStatus = s->ClientStatus;
5781
5782 // Account name
5783 UniStrCpy(st->AccountName, sizeof(st->AccountName), s->ClientOption->AccountName);
5784
5785 if (s->ClientStatus == CLIENT_STATUS_ESTABLISHED && s->Connection != NULL)
5786 {
5787 Lock(s->Connection->lock);
5788 {
5789 // Connected flag
5790 st->Connected = true;
5791 // Product name
5792 StrCpy(st->ServerProductName, sizeof(st->ServerProductName), s->Connection->ServerStr);
5793 // Version
5794 st->ServerProductVer = s->Connection->ServerVer;
5795 // Build Number
5796 st->ServerProductBuild = s->Connection->ServerBuild;
5797 // Server certificate
5798 st->ServerX = CloneX(s->Connection->ServerX);
5799 // Client certificate
5800 st->ClientX = CloneX(s->Connection->ClientX);
5801 // Connection completion time of this connection
5802 st->CurrentConnectionEstablishTime = TickToTime(s->CurrentConnectionEstablishTime);
5803 // Maximum number of the TCP connections
5804 st->MaxTcpConnections = s->MaxConnection;
5805 // Half-connection
5806 st->HalfConnection = s->HalfConnection;
5807 // VLAN
5808 st->VLanId = s->VLanId;
5809 // VoIP / QoS
5810 st->QoS = s->QoS;
5811 if (s->Connection->Protocol == CONNECTION_TCP)
5812 {
5813 UINT i;
5814 // Number of current TCP connections
5815 LockList(s->Connection->Tcp->TcpSockList);
5816 {
5817 st->NumTcpConnections = LIST_NUM(s->Connection->Tcp->TcpSockList);
5818 if (st->HalfConnection)
5819 {
5820 for (i = 0;i < st->NumTcpConnections;i++)
5821 {
5822 TCPSOCK *ts = LIST_DATA(s->Connection->Tcp->TcpSockList, i);
5823 if (ts->Direction & TCP_SERVER_TO_CLIENT)
5824 {
5825 st->NumTcpConnectionsDownload++;
5826 }
5827 else
5828 {
5829 st->NumTcpConnectionsUpload++;
5830 }
5831 }
5832 }
5833 }
5834 UnlockList(s->Connection->Tcp->TcpSockList);
5835 }
5836 // Use of encryption
5837 st->UseEncrypt = s->UseEncrypt;
5838 if (st->UseEncrypt)
5839 {
5840 StrCpy(st->CipherName, sizeof(st->CipherName), s->Connection->CipherName);
5841 }
5842 // Use of compression
5843 st->UseCompress = s->UseCompress;
5844 // R-UDP
5845 st->IsRUDPSession = s->IsRUDPSession;
5846 // Physical communication protocol
5847 StrCpy(st->UnderlayProtocol, sizeof(st->UnderlayProtocol), s->UnderlayProtocol);
5848 // Protocol details
5849 StrCpy(st->ProtocolDetails, sizeof(st->ProtocolDetails), s->ProtocolDetails);
5850 Trim(st->ProtocolDetails);
5851 // UDP acceleration function
5852 if (s->IpcSessionShared != NULL && IsEmptyStr(s->IpcSessionShared->ProtocolDetails) == false)
5853 {
5854 char tmp[sizeof(s->IpcSessionShared->ProtocolDetails)];
5855 StrCpy(tmp, sizeof(tmp), s->IpcSessionShared->ProtocolDetails);
5856 Trim(tmp);
5857 StrCat(st->ProtocolDetails, sizeof(st->ProtocolDetails), " ");
5858 StrCat(st->ProtocolDetails, sizeof(st->ProtocolDetails), tmp);
5859
5860 st->IsUdpAccelerationEnabled = s->IpcSessionShared->EnableUdpAccel;
5861 st->IsUsingUdpAcceleration = s->IpcSessionShared->UsingUdpAccel;
5862 }
5863 else
5864 {
5865 st->IsUdpAccelerationEnabled = s->UseUdpAcceleration;
5866 st->IsUsingUdpAcceleration = s->IsUsingUdpAcceleration;
5867 }
5868 // Session key
5869 Copy(st->SessionKey, s->SessionKey, SHA1_SIZE);
5870 // Policy
5871 Copy(&st->Policy, s->Policy, sizeof(POLICY));
5872 // Data size
5873 if (s->ServerMode == false)
5874 {
5875 st->TotalSendSize = s->TotalSendSize;
5876 st->TotalRecvSize = s->TotalRecvSize;
5877 st->TotalRecvSizeReal = s->TotalRecvSizeReal;
5878 st->TotalSendSizeReal = s->TotalSendSizeReal;
5879 }
5880 else
5881 {
5882 st->TotalSendSize = s->TotalRecvSize;
5883 st->TotalRecvSize = s->TotalSendSize;
5884 st->TotalRecvSizeReal = s->TotalSendSizeReal;
5885 st->TotalSendSizeReal = s->TotalRecvSizeReal;
5886 }
5887 // Session name
5888 StrCpy(st->SessionName, sizeof(st->SessionName), s->Name);
5889 // Connection name
5890 StrCpy(st->ConnectionName, sizeof(st->ConnectionName), s->Connection->Name);
5891 // Server name
5892 StrCpy(st->ServerName, sizeof(st->ServerName), s->Connection->ServerName);
5893 // Port number
5894 st->ServerPort = s->Connection->ServerPort;
5895 // Traffic data
5896 Lock(s->TrafficLock);
5897 {
5898 Copy(&st->Traffic, s->Traffic, sizeof(TRAFFIC));
5899 }
5900 Unlock(s->TrafficLock);
5901
5902 st->IsBridgeMode = s->IsBridgeMode;
5903 st->IsMonitorMode = s->IsMonitorMode;
5904 }
5905 Unlock(s->Connection->lock);
5906 }
5907 // Connection start time
5908 st->StartTime = TickToTime(s->CreatedTime);
5909 // Connection completion time of the first connection
5910 /* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */
5911 st->FirstConnectionEstablisiedTime = TickToTime(s->FirstConnectionEstablisiedTime);
5912 // Number of connections have been established so far
5913 st->NumConnectionsEstablished = s->NumConnectionsEstablished;
5914 }
5915 Unlock(s->lock);
5916 }
5917
5918 // Get the connection status
CtGetAccountStatus(CLIENT * c,RPC_CLIENT_GET_CONNECTION_STATUS * st)5919 bool CtGetAccountStatus(CLIENT *c, RPC_CLIENT_GET_CONNECTION_STATUS *st)
5920 {
5921 // Validate arguments
5922 if (c == NULL || st == NULL)
5923 {
5924 return false;
5925 }
5926
5927 LockList(c->AccountList);
5928 {
5929 ACCOUNT t, *r;
5930
5931 // Search for account
5932 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
5933 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), st->AccountName);
5934
5935 r = Search(c->AccountList, &t);
5936 if (r == NULL)
5937 {
5938 // Specified account is not found
5939 UnlockList(c->AccountList);
5940
5941 Free(t.ClientOption);
5942 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
5943 return false;
5944 }
5945
5946 Free(t.ClientOption);
5947
5948 Lock(r->lock);
5949 {
5950 Zero(st, sizeof(RPC_CLIENT_GET_CONNECTION_STATUS));
5951 if (r->ClientSession != NULL)
5952 {
5953 SESSION *s = r->ClientSession;
5954 CiGetSessionStatus(st, s);
5955 }
5956 }
5957 Unlock(r->lock);
5958 }
5959 UnlockList(c->AccountList);
5960
5961 return true;
5962 }
5963
5964 // Release the connection status
CiFreeClientGetConnectionStatus(RPC_CLIENT_GET_CONNECTION_STATUS * st)5965 void CiFreeClientGetConnectionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *st)
5966 {
5967 // Validate arguments
5968 if (st == NULL)
5969 {
5970 return;
5971 }
5972
5973 if (st->ServerX != NULL)
5974 {
5975 FreeX(st->ServerX);
5976 }
5977
5978 if (st->ClientX != NULL)
5979 {
5980 FreeX(st->ClientX);
5981 }
5982 }
5983
5984 // Verification procedure of the server certificate
CiCheckCertProc(SESSION * s,CONNECTION * c,X * server_x,bool * expired)5985 bool CiCheckCertProc(SESSION *s, CONNECTION *c, X *server_x, bool *expired)
5986 {
5987 #ifdef OS_WIN32
5988 ACCOUNT *a;
5989 X *old_x = NULL;
5990 UI_CHECKCERT dlg;
5991 // Validate arguments
5992 if (s == NULL || c == NULL || server_x == NULL)
5993 {
5994 return false;
5995 }
5996
5997 if (expired != NULL)
5998 {
5999 *expired = false;
6000 }
6001
6002 Zero(&dlg, sizeof(dlg));
6003
6004 a = s->Account;
6005 if (a == NULL)
6006 {
6007 return false;
6008 }
6009
6010 Lock(a->lock);
6011 {
6012 if (a->CheckServerCert == false)
6013 {
6014 // Not to validate the server certificate
6015 Unlock(a->lock);
6016 return true;
6017 }
6018
6019 if (a->ServerCert != NULL)
6020 {
6021 old_x = CloneX(a->ServerCert);
6022 }
6023 }
6024 Unlock(a->lock);
6025
6026 if (CheckXDateNow(server_x) == false)
6027 {
6028 // Expired
6029 if (old_x != NULL)
6030 {
6031 FreeX(old_x);
6032 }
6033
6034 if (expired != NULL)
6035 {
6036 *expired = true;
6037 }
6038
6039 return false;
6040 }
6041
6042 if (old_x != NULL)
6043 {
6044 if (CompareX(old_x, server_x))
6045 {
6046 // Matched exactly to the certificate that is already registered
6047 if (old_x != NULL)
6048 {
6049 FreeX(old_x);
6050 }
6051 return true;
6052 }
6053 else
6054 {
6055 dlg.DiffWarning = true;
6056 }
6057 }
6058
6059 // Because this certificate can not be trusted, confirm to be trusted by showing a dialog box
6060 UniStrCpy(dlg.AccountName, sizeof(dlg.AccountName), a->ClientOption->AccountName);
6061 StrCpy(dlg.ServerName, sizeof(dlg.ServerName), a->ClientOption->Hostname);
6062 dlg.x = server_x;
6063 dlg.old_x = old_x;
6064
6065 dlg.Session = s;
6066 AddRef(s->ref);
6067
6068 CncCheckCert(s, &dlg);
6069
6070 ReleaseSession(s);
6071
6072 if (old_x != NULL)
6073 {
6074 FreeX(old_x);
6075 }
6076
6077 if (dlg.Ok && dlg.SaveServerCert)
6078 {
6079 // Save the server certificate and trust it from the next time
6080 Lock(a->lock);
6081 {
6082 if (a->ServerCert != NULL)
6083 {
6084 FreeX(a->ServerCert);
6085 }
6086
6087 a->ServerCert = CloneX(server_x);
6088 }
6089 Unlock(a->lock);
6090 CiSaveConfigurationFile(s->Cedar->Client);
6091 }
6092
6093 return dlg.Ok;
6094 #else // OS_WIN32
6095 ACCOUNT *a;
6096 X *old_x = NULL;
6097 // Validate arguments
6098 if (s == NULL || c == NULL || server_x == NULL)
6099 {
6100 return false;
6101 }
6102
6103 if (expired != NULL)
6104 {
6105 *expired = false;
6106 }
6107
6108 a = s->Account;
6109 if (a == NULL)
6110 {
6111 return false;
6112 }
6113
6114 Lock(a->lock);
6115 {
6116 if (a->CheckServerCert == false)
6117 {
6118 // Not to validate the server certificate
6119 Unlock(a->lock);
6120 return true;
6121 }
6122
6123 if (a->ServerCert != NULL)
6124 {
6125 old_x = CloneX(a->ServerCert);
6126 }
6127 }
6128 Unlock(a->lock);
6129
6130 if (CheckXDateNow(server_x) == false)
6131 {
6132 // Expired
6133 if (old_x != NULL)
6134 {
6135 FreeX(old_x);
6136 }
6137
6138 if (expired != NULL)
6139 {
6140 *expired = true;
6141 }
6142
6143 return false;
6144 }
6145
6146 if (old_x != NULL)
6147 {
6148 if (CompareX(old_x, server_x))
6149 {
6150 // Exactly matched to the certificate that is already registered
6151 if (old_x != NULL)
6152 {
6153 FreeX(old_x);
6154 }
6155 return true;
6156 }
6157 else
6158 {
6159 // Mismatch
6160 if (old_x != NULL)
6161 {
6162 FreeX(old_x);
6163 }
6164 return false;
6165 }
6166 }
6167
6168 return false;
6169 #endif // OS_WIN32
6170 }
6171
6172 // Signature procedure with a secure device
CiSecureSignProc(SESSION * s,CONNECTION * c,SECURE_SIGN * sign)6173 bool CiSecureSignProc(SESSION *s, CONNECTION *c, SECURE_SIGN *sign)
6174 {
6175 // The UI is available in Win32
6176 return CncSecureSignDlg(sign);
6177 }
6178
6179 #ifdef OS_WIN32
6180 // Signing procedure (for Win32)
Win32CiSecureSign(SECURE_SIGN * sign)6181 bool Win32CiSecureSign(SECURE_SIGN *sign)
6182 {
6183 bool ret = false;
6184 BUF *random;
6185 // Validate arguments
6186 if (sign == NULL)
6187 {
6188 return false;
6189 }
6190
6191 random = NewBuf();
6192 WriteBuf(random, sign->Random, SHA1_SIZE);
6193
6194 // Batch processing
6195 {
6196 WINUI_SECURE_BATCH batch[] =
6197 {
6198 {WINUI_SECURE_READ_CERT, sign->SecurePublicCertName, true, NULL, NULL, NULL, NULL, NULL, NULL},
6199 {WINUI_SECURE_SIGN_WITH_KEY, sign->SecurePrivateKeyName, true, random, NULL, NULL, NULL, NULL, NULL}
6200 };
6201
6202 if (SecureDeviceWindow(NULL, batch, sizeof(batch) / sizeof(batch[0]),
6203 sign->UseSecureDeviceId, sign->BitmapId) == false)
6204 {
6205 // Failure
6206 if (batch[0].OutputX != 0)
6207 {
6208 FreeX(batch[0].OutputX);
6209 }
6210 ret = false;
6211 }
6212 else
6213 {
6214 // Success
6215 ret = true;
6216 sign->ClientCert = batch[0].OutputX;
6217 Copy(sign->Signature, batch[1].OutputSign, MIN(sizeof(sign->Signature),sizeof(batch[1].OutputSign)));
6218 }
6219 }
6220
6221 FreeBuf(random);
6222
6223 return ret;
6224 }
6225 #endif // OS_WIN32
6226
6227 // Disconnect
CtDisconnect(CLIENT * c,RPC_CLIENT_CONNECT * connect,bool inner)6228 bool CtDisconnect(CLIENT *c, RPC_CLIENT_CONNECT *connect, bool inner)
6229 {
6230 bool ret = false;
6231 ACCOUNT t, *r;
6232 SESSION *s = NULL;
6233 // Validate arguments
6234 if (c == NULL || connect == NULL)
6235 {
6236 return false;
6237 }
6238
6239 LockList(c->AccountList);
6240 {
6241 // Search for account
6242 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
6243 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), connect->AccountName);
6244
6245 r = Search(c->AccountList, &t);
6246 if (r == NULL)
6247 {
6248 // Specified account isn't found
6249 UnlockList(c->AccountList);
6250
6251 Free(t.ClientOption);
6252 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
6253 return false;
6254 }
6255
6256 Free(t.ClientOption);
6257
6258 Lock(r->lock);
6259 {
6260 if (r->ClientSession == NULL)
6261 {
6262 // Not connected
6263 CiSetError(c, ERR_ACCOUNT_INACTIVE);
6264 }
6265 else
6266 {
6267 s = r->ClientSession;
6268 AddRef(s->ref);
6269 // Disconnect complete
6270 r->ClientSession = NULL;
6271 ret = true;
6272 }
6273 }
6274 Unlock(r->lock);
6275 }
6276 UnlockList(c->AccountList);
6277
6278 if (s != NULL)
6279 {
6280 // Disconnect the connection (Wait until the disconnection is complete)
6281 CLog(c, "LC_DISCONNECT", connect->AccountName);
6282 StopSession(s);
6283 ReleaseSession(s);
6284 }
6285
6286
6287 if (ret != false)
6288 {
6289 CiNotify(c);
6290 }
6291
6292 return ret;
6293 }
6294
6295 // Connect
CtConnect(CLIENT * c,RPC_CLIENT_CONNECT * connect)6296 bool CtConnect(CLIENT *c, RPC_CLIENT_CONNECT *connect)
6297 {
6298 bool ret = false;
6299 RPC_CLIENT_ENUM_VLAN t;
6300 // Validate arguments
6301 if (c == NULL || connect == NULL)
6302 {
6303 return false;
6304 }
6305
6306 Lock(c->lockForConnect);
6307 {
6308 Zero(&t, sizeof(t));
6309 if (CtEnumVLan(c, &t))
6310 {
6311 if (t.NumItem == 0)
6312 {
6313 // Create a new virtual LAN card named "VPN" automatically
6314 RPC_CLIENT_CREATE_VLAN t;
6315
6316 Zero(&t, sizeof(t));
6317 StrCpy(t.DeviceName, sizeof(t.DeviceName), "VPN");
6318 CtCreateVLan(c, &t);
6319 }
6320
6321 CiFreeClientEnumVLan(&t);
6322 }
6323 }
6324 Unlock(c->lockForConnect);
6325
6326 CiNormalizeAccountVLan(c);
6327
6328 // Ensure successfully VPN communication by changing the irrational WCM settings in the case of Windows 8 or later
6329 CiDisableWcmNetworkMinimize(c);
6330
6331 LockList(c->AccountList);
6332 {
6333 ACCOUNT t, *r;
6334 bool unix_disabled = false;
6335
6336 // Search for account
6337 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
6338 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), connect->AccountName);
6339
6340 r = Search(c->AccountList, &t);
6341 if (r == NULL)
6342 {
6343 // Specified account isn't found
6344 UnlockList(c->AccountList);
6345
6346 Free(t.ClientOption);
6347 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
6348 return false;
6349 }
6350
6351 Free(t.ClientOption);
6352
6353 #ifndef OS_WIN32
6354 // Search for the virtual LAN card
6355 LockList(c->UnixVLanList);
6356 {
6357 UNIX_VLAN *v, t;
6358
6359 Zero(&t, sizeof(t));
6360 StrCpy(t.Name, sizeof(t.Name), r->ClientOption->DeviceName);
6361
6362 v = Search(c->UnixVLanList, &t);
6363 if (v == NULL)
6364 {
6365 UnlockList(c->UnixVLanList);
6366 CiSetError(c, ERR_OBJECT_NOT_FOUND);
6367 return false;
6368 }
6369
6370 unix_disabled = v->Enabled ? false : true;
6371 }
6372 UnlockList(c->UnixVLanList);
6373 #endif // OS_WIN32
6374
6375 Lock(r->lock);
6376 {
6377 bool already_used = false;
6378 UINT i;
6379
6380 if (r->ClientSession != NULL)
6381 {
6382 // Already in connecting
6383 CiSetError(c, ERR_ACCOUNT_ACTIVE);
6384 }
6385 else if (r->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE &&
6386 c->UseSecureDeviceId == 0)
6387 {
6388 // Secure device is not specified
6389 CiSetError(c, ERR_NO_SECURE_DEVICE_SPECIFIED);
6390 }
6391 #ifdef OS_WIN32
6392 else if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, r->ClientOption->DeviceName) == false &&
6393 MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, r->ClientOption->DeviceName) == false)
6394 {
6395 // Virtual LAN card can not be found
6396 CiSetError(c, ERR_VLAN_FOR_ACCOUNT_NOT_FOUND);
6397 CiNotify(c);
6398 CiSendGlobalPulse(c);
6399 }
6400 else if (MsIsVLanEnabled(r->ClientOption->DeviceName) == false)
6401 {
6402 // The virtual LAN card is disabled
6403 CiSetError(c, ERR_VLAN_FOR_ACCOUNT_DISABLED);
6404 CiNotify(c);
6405 CiSendGlobalPulse(c);
6406 }
6407 #else // OS_WIN32
6408 else if (unix_disabled)
6409 {
6410 // The virtual LAN card is disabled
6411 CiSetError(c, ERR_VLAN_FOR_ACCOUNT_DISABLED);
6412 CiNotify(c);
6413 CiSendGlobalPulse(c);
6414 }
6415 #endif // OS_WIN32
6416 else
6417 {
6418 // Check whether the virtual LAN card is being used by a different account already
6419 for (i = 0;i < LIST_NUM(c->AccountList);i++)
6420 {
6421 ACCOUNT *a = LIST_DATA(c->AccountList, i);
6422 if (a != r)
6423 {
6424 if (StrCmpi(a->ClientOption->DeviceName,
6425 r->ClientOption->DeviceName) == 0)
6426 {
6427 if (a->ClientSession != NULL)
6428 {
6429 already_used = true;
6430 break;
6431 }
6432 }
6433 }
6434 }
6435
6436 if (already_used)
6437 {
6438 CiSetError(c, ERR_VLAN_FOR_ACCOUNT_USED);
6439 }
6440 else
6441 {
6442 // Start the connection
6443 PACKET_ADAPTER *pa = VLanGetPacketAdapter();
6444
6445 if (r->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)
6446 {
6447 // Register a procedure for secure device authentication
6448 r->ClientAuth->SecureSignProc = CiSecureSignProc;
6449 }
6450 else if (r->ClientAuth->AuthType == CLIENT_AUTHTYPE_OPENSSLENGINE)
6451 {
6452 /* r->ClientAuth->ClientK = OpensslEngineToK("asdf"); */
6453 r->ClientAuth->SecureSignProc = NULL;
6454 }
6455 else
6456 {
6457 r->ClientAuth->SecureSignProc = NULL;
6458 }
6459
6460 if (r->CheckServerCert)
6461 {
6462 // Register a procedure to validate the server certificate
6463 r->ClientAuth->CheckCertProc = CiCheckCertProc;
6464 }
6465 else
6466 {
6467 r->ClientAuth->CheckCertProc = NULL;
6468 }
6469
6470 r->StatusPrinter = CiClientStatusPrinter;
6471 r->LastConnectDateTime = SystemTime64();
6472
6473 CLog(c, "LC_CONNECT", connect->AccountName);
6474
6475 r->ClientSession = NewClientSessionEx(c->Cedar, r->ClientOption, r->ClientAuth, pa, r);
6476 Notify(r->ClientSession, CLIENT_NOTIFY_ACCOUNT_CHANGED);
6477
6478 ret = true;
6479 }
6480 }
6481 }
6482 Unlock(r->lock);
6483
6484 }
6485 UnlockList(c->AccountList);
6486
6487 CiSaveConfigurationFile(c);
6488
6489 return ret;
6490 }
6491
6492 // Put all unused TUN interfaces down
6493 // Requires account and VLan lists of the CLIENT argument to be already locked
CtVLansDown(CLIENT * c)6494 bool CtVLansDown(CLIENT *c)
6495 {
6496 #ifndef UNIX_LINUX
6497 return true;
6498 #else
6499 int i;
6500 LIST *tmpVLanList;
6501 UNIX_VLAN t, *r;
6502 bool result = true;
6503
6504 if (c == NULL)
6505 {
6506 return false;
6507 }
6508
6509 tmpVLanList = CloneList(c->UnixVLanList);
6510 if (tmpVLanList == NULL)
6511 {
6512 return false;
6513 }
6514
6515 // Remove from tmpVLanList all VLans corresponding to active sessions
6516 for (i = 0; i < LIST_NUM(c->AccountList); ++i)
6517 {
6518 ACCOUNT *a = LIST_DATA(c->AccountList, i);
6519 if (a->ClientSession == NULL)
6520 {
6521 continue;
6522 }
6523
6524 Zero(&t, sizeof(t));
6525 StrCpy(t.Name, sizeof(t.Name), a->ClientOption->DeviceName);
6526 r = Search(tmpVLanList, &t);
6527 Delete(tmpVLanList, r);
6528 }
6529
6530 // Set down every VLan in tmpVLanList
6531 for (i = 0; i < LIST_NUM(tmpVLanList) && result; ++i)
6532 {
6533 r = LIST_DATA(tmpVLanList, i);
6534 result = UnixVLanSetState(r->Name, false);
6535 // [MP:] Should we report *critical* error on failure?
6536 }
6537
6538 ReleaseList(tmpVLanList);
6539 return result;
6540 #endif
6541 }
6542
6543 // Put all TUN interfaces up
6544 // Requires VLan list of the CLIENT argument to be already locked
CtVLansUp(CLIENT * c)6545 bool CtVLansUp(CLIENT *c)
6546 {
6547 #ifndef UNIX_LINUX
6548 return true;
6549 #else
6550 int i;
6551 UNIX_VLAN *r;
6552
6553 if (c == NULL)
6554 {
6555 return false;
6556 }
6557
6558 for (i = 0; i < LIST_NUM(c->UnixVLanList); ++i)
6559 {
6560 r = LIST_DATA(c->UnixVLanList, i);
6561 UnixVLanSetState(r->Name, true);
6562 }
6563
6564 return true;
6565 #endif
6566 }
6567
6568 // Get the account information
CtGetAccount(CLIENT * c,RPC_CLIENT_GET_ACCOUNT * a)6569 bool CtGetAccount(CLIENT *c, RPC_CLIENT_GET_ACCOUNT *a)
6570 {
6571 // Validate arguments
6572 if (c == NULL || a == NULL)
6573 {
6574 return false;
6575 }
6576
6577 LockList(c->AccountList);
6578 {
6579 ACCOUNT t, *r;
6580
6581 // Search for account
6582 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
6583 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), a->AccountName);
6584
6585 r = Search(c->AccountList, &t);
6586 if (r == NULL)
6587 {
6588 // Specified account can not be found
6589 UnlockList(c->AccountList);
6590
6591 Free(t.ClientOption);
6592 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
6593 return false;
6594 }
6595
6596 Free(t.ClientOption);
6597
6598 Lock(r->lock);
6599 {
6600 // Copy the client option
6601 if (a->ClientOption != NULL)
6602 {
6603 Free(a->ClientOption);
6604 }
6605 a->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
6606 Copy(a->ClientOption, r->ClientOption, sizeof(CLIENT_OPTION));
6607
6608 // Copy the authentication data
6609 if (a->ClientAuth != NULL)
6610 {
6611 CiFreeClientAuth(a->ClientAuth);
6612 }
6613 a->ClientAuth = CopyClientAuth(r->ClientAuth);
6614
6615 a->StartupAccount = r->StartupAccount;
6616
6617 a->CheckServerCert = r->CheckServerCert;
6618 a->RetryOnServerCert = r->RetryOnServerCert;
6619 a->ServerCert = NULL;
6620 if (r->ServerCert != NULL)
6621 {
6622 a->ServerCert = CloneX(r->ServerCert);
6623 }
6624
6625 // Shortcut Key
6626 Copy(a->ShortcutKey, r->ShortcutKey, SHA1_SIZE);
6627
6628 a->CreateDateTime = r->CreateDateTime;
6629 a->LastConnectDateTime = r->LastConnectDateTime;
6630 a->UpdateDateTime = r->UpdateDateTime;
6631 }
6632 Unlock(r->lock);
6633
6634 }
6635 UnlockList(c->AccountList);
6636
6637 return true;
6638 }
6639
6640 // Change the account name
CtRenameAccount(CLIENT * c,RPC_RENAME_ACCOUNT * rename,bool inner)6641 bool CtRenameAccount(CLIENT *c, RPC_RENAME_ACCOUNT *rename, bool inner)
6642 {
6643 bool ret;
6644 // Validate arguments
6645 if (c == NULL || rename == NULL)
6646 {
6647 return false;
6648 }
6649
6650
6651 ret = false;
6652
6653 if (UniStrCmp(rename->NewName, rename->OldName) == 0)
6654 {
6655 // The name has not been changed
6656 return true;
6657 }
6658
6659 LockList(c->AccountList);
6660 {
6661 ACCOUNT t, *r, *r2;
6662
6663 if (UniStrLen(rename->NewName) == 0)
6664 {
6665 // Name is invalid
6666 CiSetError(c, ERR_INVALID_VALUE);
6667 UnlockList(c->AccountList);
6668 return false;
6669 }
6670
6671 // Search for old account name
6672 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
6673 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), rename->OldName);
6674
6675 r = Search(c->AccountList, &t);
6676 if (r == NULL)
6677 {
6678 // Specified account can not be found
6679 UnlockList(c->AccountList);
6680
6681 Free(t.ClientOption);
6682 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
6683 return false;
6684 }
6685
6686 Free(t.ClientOption);
6687
6688 // Search for a new account name
6689 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
6690 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), rename->NewName);
6691
6692 r2 = Search(c->AccountList, &t);
6693 if (r2 != NULL)
6694 {
6695 // Account with the specified name already exists
6696 UnlockList(c->AccountList);
6697
6698 Free(t.ClientOption);
6699 CiSetError(c, ERR_ACCOUNT_ALREADY_EXISTS);
6700 return false;
6701 }
6702
6703 Free(t.ClientOption);
6704
6705 Lock(r->lock);
6706 {
6707 // Check the operating state of the account
6708 if (r->ClientSession != NULL)
6709 {
6710 // The Account is working
6711 Unlock(r->lock);
6712 UnlockList(c->AccountList);
6713 CiSetError(c, ERR_ACCOUNT_ACTIVE);
6714
6715 return false;
6716 }
6717
6718 // Update the account name
6719 UniStrCpy(r->ClientOption->AccountName, sizeof(r->ClientOption->AccountName),
6720 rename->NewName);
6721
6722 CLog(c, "LC_RENAME_ACCOUNT", rename->OldName, rename->NewName);
6723
6724 ret = true;
6725 }
6726 Unlock(r->lock);
6727
6728 Sort(c->AccountList);
6729
6730 }
6731 UnlockList(c->AccountList);
6732
6733 CiSaveConfigurationFile(c);
6734
6735 CiNotify(c);
6736
6737 return ret;
6738 }
6739
6740 // Set the client configuration
CtSetClientConfig(CLIENT * c,CLIENT_CONFIG * o)6741 bool CtSetClientConfig(CLIENT *c, CLIENT_CONFIG *o)
6742 {
6743 KEEP *k;
6744 // Validate arguments
6745 if (c == NULL || o == NULL)
6746 {
6747 return false;
6748 }
6749
6750 if (o->UseKeepConnect)
6751 {
6752 if (IsEmptyStr(o->KeepConnectHost) ||
6753 o->KeepConnectPort == 0 ||
6754 o->KeepConnectPort >= 65536)
6755 {
6756 CiSetError(c, ERR_INVALID_PARAMETER);
6757 return false;
6758 }
6759 }
6760
6761 Lock(c->lock);
6762 {
6763 Copy(&c->Config, o, sizeof(CLIENT_CONFIG));
6764 }
6765 Unlock(c->lock);
6766
6767 // Save the settings
6768 CiSaveConfigurationFile(c);
6769
6770 // Apply the Keep Connect
6771 k = c->Keep;
6772 Lock(k->lock);
6773 {
6774 if (o->UseKeepConnect)
6775 {
6776 StrCpy(k->ServerName, sizeof(k->ServerName), c->Config.KeepConnectHost);
6777 k->ServerPort = c->Config.KeepConnectPort;
6778 k->Interval = c->Config.KeepConnectInterval * 1000;
6779 k->UdpMode = (c->Config.KeepConnectProtocol == CONNECTION_UDP) ? true : false;
6780 k->Enable = true;
6781 }
6782 else
6783 {
6784 k->Enable = false;
6785 }
6786 }
6787 Unlock(k->lock);
6788
6789 // Apply TAP state
6790 LockList(c->AccountList);
6791 LockList(c->UnixVLanList);
6792
6793 CtVLansDown(c);
6794
6795 UnlockList(c->UnixVLanList);
6796 UnlockList(c->AccountList);
6797
6798 return true;
6799 }
6800
6801 // Get the network client configuration
CtGetClientConfig(CLIENT * c,CLIENT_CONFIG * o)6802 bool CtGetClientConfig(CLIENT *c, CLIENT_CONFIG *o)
6803 {
6804 // Validate arguments
6805 if (c == NULL || o == NULL)
6806 {
6807 return false;
6808 }
6809
6810 Lock(c->lock);
6811 {
6812 Copy(o, &c->Config, sizeof(CLIENT_CONFIG));
6813 }
6814 Unlock(c->lock);
6815
6816 return true;
6817 }
6818
6819 // Unset the startup attribute of the account
CtRemoveStartupAccount(CLIENT * c,RPC_CLIENT_DELETE_ACCOUNT * a)6820 bool CtRemoveStartupAccount(CLIENT *c, RPC_CLIENT_DELETE_ACCOUNT *a)
6821 {
6822 bool ret;
6823 // Validate arguments
6824 if (c == NULL || a == NULL)
6825 {
6826 return false;
6827 }
6828
6829 ret = false;
6830
6831 LockList(c->AccountList);
6832 {
6833 ACCOUNT t, *r;
6834 // Search for an Account
6835
6836 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
6837 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), a->AccountName);
6838
6839 r = Search(c->AccountList, &t);
6840 if (r == NULL)
6841 {
6842 // Specified account can not be found
6843 UnlockList(c->AccountList);
6844
6845 Free(t.ClientOption);
6846 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
6847 return false;
6848 }
6849
6850 Free(t.ClientOption);
6851
6852 Lock(r->lock);
6853 {
6854 // Unset the startup account
6855 ret = true;
6856 r->StartupAccount = false;
6857 }
6858 Unlock(r->lock);
6859 }
6860 UnlockList(c->AccountList);
6861
6862 if (ret)
6863 {
6864 CiSaveConfigurationFile(c);
6865 CiNotify(c);
6866 }
6867
6868 return ret;
6869 }
6870
6871 // Set the account as a start-up account
CtSetStartupAccount(CLIENT * c,RPC_CLIENT_DELETE_ACCOUNT * a,bool inner)6872 bool CtSetStartupAccount(CLIENT *c, RPC_CLIENT_DELETE_ACCOUNT *a, bool inner)
6873 {
6874 bool ret;
6875 // Validate arguments
6876 if (c == NULL || a == NULL)
6877 {
6878 return false;
6879 }
6880
6881
6882 ret = false;
6883
6884 LockList(c->AccountList);
6885 {
6886 ACCOUNT t, *r;
6887 // Search for an account
6888
6889 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
6890 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), a->AccountName);
6891
6892 r = Search(c->AccountList, &t);
6893 if (r == NULL)
6894 {
6895 // Specified account can not be found
6896 UnlockList(c->AccountList);
6897
6898 Free(t.ClientOption);
6899 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
6900 return false;
6901 }
6902
6903 Free(t.ClientOption);
6904
6905 Lock(r->lock);
6906 {
6907 // Set to a start-up account
6908 ret = true;
6909 r->StartupAccount = true;
6910 }
6911 Unlock(r->lock);
6912 }
6913 UnlockList(c->AccountList);
6914
6915 if (ret)
6916 {
6917 CiSaveConfigurationFile(c);
6918 CiNotify(c);
6919 }
6920
6921 return ret;
6922 }
6923
6924 // Delete the account
CtDeleteAccount(CLIENT * c,RPC_CLIENT_DELETE_ACCOUNT * a,bool inner)6925 bool CtDeleteAccount(CLIENT *c, RPC_CLIENT_DELETE_ACCOUNT *a, bool inner)
6926 {
6927 bool ret;
6928 // Validate arguments
6929 if (c == NULL || a == NULL)
6930 {
6931 return false;
6932 }
6933
6934 ret = false;
6935
6936 if (c->Halt)
6937 {
6938 // Don't allow the removal of the account in the process of stopping
6939 CiSetError(c, ERR_INTERNAL_ERROR);
6940 return false;
6941 }
6942
6943 LockList(c->AccountList);
6944 {
6945 ACCOUNT t, *r;
6946 // Search for an Account
6947
6948 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
6949 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), a->AccountName);
6950
6951 r = Search(c->AccountList, &t);
6952 if (r == NULL)
6953 {
6954 // Specified account can not be found
6955 UnlockList(c->AccountList);
6956
6957 Free(t.ClientOption);
6958 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
6959 return false;
6960 }
6961
6962 Free(t.ClientOption);
6963
6964 Lock(r->lock);
6965 {
6966 // Check the operating state of the account
6967 if (r->ClientSession != NULL)
6968 {
6969 // The account is active
6970 Unlock(r->lock);
6971 UnlockList(c->AccountList);
6972 CiSetError(c, ERR_ACCOUNT_ACTIVE);
6973
6974 return false;
6975 }
6976
6977 // Remove this account from the list
6978 Delete(c->AccountList, r);
6979 }
6980 Unlock(r->lock);
6981
6982 // Free the memory of this account
6983 CiFreeAccount(r);
6984
6985 CLog(c, "LC_DELETE_ACCOUNT", a->AccountName);
6986 ret = true;
6987
6988 }
6989 UnlockList(c->AccountList);
6990
6991 if (ret)
6992 {
6993 CiSaveConfigurationFile(c);
6994 CiNotify(c);
6995 }
6996
6997 return ret;
6998 }
6999
7000 // Enumeration of accounts
CtEnumAccount(CLIENT * c,RPC_CLIENT_ENUM_ACCOUNT * e)7001 bool CtEnumAccount(CLIENT *c, RPC_CLIENT_ENUM_ACCOUNT *e)
7002 {
7003 // Validate arguments
7004 if (c == NULL || e == NULL)
7005 {
7006 return false;
7007 }
7008
7009 LockList(c->AccountList);
7010 {
7011 UINT i;
7012 // Number of accounts
7013 e->NumItem = LIST_NUM(c->AccountList);
7014 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_ACCOUNT_ITEM *) * e->NumItem);
7015
7016 for (i = 0;i < e->NumItem;i++)
7017 {
7018 ACCOUNT *a = LIST_DATA(c->AccountList, i);
7019 RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_ACCOUNT_ITEM));
7020 e->Items[i] = item;
7021
7022 // Account name
7023 UniStrCpy(item->AccountName, sizeof(item->AccountName), a->ClientOption->AccountName);
7024
7025 // User name
7026 StrCpy(item->UserName, sizeof(item->UserName), a->ClientAuth->Username);
7027
7028 // Server name
7029 StrCpy(item->ServerName, sizeof(item->ServerName), a->ClientOption->Hostname);
7030
7031 // Proxy type
7032 item->ProxyType = a->ClientOption->ProxyType;
7033
7034 // Device name
7035 StrCpy(item->DeviceName, sizeof(item->DeviceName), a->ClientOption->DeviceName);
7036
7037 // Proxy information
7038 if (item->ProxyType != PROXY_DIRECT)
7039 {
7040 StrCpy(item->ProxyName, sizeof(item->ProxyName), a->ClientOption->ProxyName);
7041 }
7042
7043 // Startup
7044 item->StartupAccount = a->StartupAccount;
7045
7046 // Active flag
7047 item->Active = (a->ClientSession == NULL ? false : true);
7048
7049 // Connection flag
7050 item->Connected = (item->Active == false) ? false : a->ClientSession->ConnectSucceed;
7051
7052 // Port number
7053 item->Port = a->ClientOption->Port;
7054
7055 // Virtual HUB name
7056 StrCpy(item->HubName, sizeof(item->HubName), a->ClientOption->HubName);
7057
7058 item->CreateDateTime = a->CreateDateTime;
7059 item->LastConnectDateTime = a->LastConnectDateTime;
7060 item->UpdateDateTime = a->UpdateDateTime;
7061 }
7062 }
7063 UnlockList(c->AccountList);
7064
7065 return true;
7066 }
7067
7068 // Configure the account
CtSetAccount(CLIENT * c,RPC_CLIENT_CREATE_ACCOUNT * a,bool inner)7069 bool CtSetAccount(CLIENT *c, RPC_CLIENT_CREATE_ACCOUNT *a, bool inner)
7070 {
7071 // Validate arguments
7072 if (c == NULL || a == NULL)
7073 {
7074 return false;
7075 }
7076
7077
7078 // Check whether an account already exists
7079 LockList(c->AccountList);
7080 {
7081 ACCOUNT t, *ret;
7082 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
7083 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName),
7084 a->ClientOption->AccountName);
7085
7086 ret = Search(c->AccountList, &t);
7087 if (ret == NULL)
7088 {
7089 // Not exist
7090 UnlockList(c->AccountList);
7091 Free(t.ClientOption);
7092
7093 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
7094
7095 return false;
7096 }
7097 Free(t.ClientOption);
7098
7099 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)
7100 {
7101 if (a->ClientAuth->ClientX == NULL ||
7102 a->ClientAuth->ClientX->is_compatible_bit == false ||
7103 a->ClientAuth->ClientK == NULL)
7104 {
7105 // Client certificate is invalid
7106 UnlockList(c->AccountList);
7107 CiSetError(c, ERR_NOT_RSA_1024);
7108 return false;
7109 }
7110 }
7111
7112 if (a->ServerCert != NULL && a->ServerCert->is_compatible_bit == false)
7113 {
7114 // Server certificate is invalid
7115 UnlockList(c->AccountList);
7116 CiSetError(c, ERR_NOT_RSA_1024);
7117 return false;
7118 }
7119
7120 Lock(ret->lock);
7121 {
7122
7123 #if 0
7124 // Rewriting of the configuration is done even account running in the current version
7125 // (New setting isn't applied until connecting next time)
7126 if (ret->ClientSession != NULL)
7127 {
7128 // The account is operating
7129 Unlock(ret->lock);
7130 UnlockList(c->AccountList);
7131
7132 CiSetError(c, ERR_ACCOUNT_ACTIVE);
7133
7134 return false;
7135 }
7136 #endif
7137
7138 // Delete the client authentication data
7139 CiFreeClientAuth(ret->ClientAuth);
7140
7141 // Copy the client authentication data
7142 ret->ClientAuth = CopyClientAuth(a->ClientAuth);
7143
7144 // Delete the client option
7145 Free(ret->ClientOption);
7146
7147 // Copy the client option
7148 ret->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
7149 Copy(ret->ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
7150
7151 ret->StartupAccount = a->StartupAccount;
7152
7153 ret->CheckServerCert = a->CheckServerCert;
7154 ret->RetryOnServerCert = a->RetryOnServerCert;
7155
7156 if (a->ServerCert != NULL)
7157 {
7158 if (ret->ServerCert != NULL)
7159 {
7160 FreeX(ret->ServerCert);
7161 }
7162 ret->ServerCert = CloneX(a->ServerCert);
7163 }
7164 else
7165 {
7166 if (ret->ServerCert != NULL)
7167 {
7168 FreeX(ret->ServerCert);
7169 }
7170 ret->ServerCert = false;
7171 }
7172
7173 ret->UpdateDateTime = SystemTime64();
7174 }
7175 Unlock(ret->lock);
7176 }
7177 UnlockList(c->AccountList);
7178
7179 CiSaveConfigurationFile(c);
7180
7181 CiNotify(c);
7182
7183 return true;
7184 }
7185
7186 // Create an account
CtCreateAccount(CLIENT * c,RPC_CLIENT_CREATE_ACCOUNT * a,bool inner)7187 bool CtCreateAccount(CLIENT *c, RPC_CLIENT_CREATE_ACCOUNT *a, bool inner)
7188 {
7189 // Validate arguments
7190 if (c == NULL || a == NULL)
7191 {
7192 return false;
7193 }
7194
7195
7196 // Check whether an account already exists
7197 LockList(c->AccountList);
7198 {
7199 ACCOUNT t, *ret, *new_account;
7200 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
7201 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName),
7202 a->ClientOption->AccountName);
7203
7204 ret = Search(c->AccountList, &t);
7205 if (ret != NULL)
7206 {
7207 // Already exist
7208 UnlockList(c->AccountList);
7209 Free(t.ClientOption);
7210
7211 CiSetError(c, ERR_ACCOUNT_ALREADY_EXISTS);
7212
7213 return false;
7214 }
7215
7216 Free(t.ClientOption);
7217
7218 if (UniStrLen(a->ClientOption->AccountName) == 0)
7219 {
7220 // The name is invalid
7221 UnlockList(c->AccountList);
7222 CiSetError(c, ERR_INVALID_VALUE);
7223 return false;
7224 }
7225
7226 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)
7227 {
7228 if (a->ClientAuth->ClientX == NULL ||
7229 a->ClientAuth->ClientX->is_compatible_bit == false ||
7230 a->ClientAuth->ClientK == NULL)
7231 {
7232 // The client certificate is invalid
7233 UnlockList(c->AccountList);
7234 CiSetError(c, ERR_NOT_RSA_1024);
7235 return false;
7236 }
7237 }
7238
7239 if (a->ServerCert != NULL && a->ServerCert->is_compatible_bit == false)
7240 {
7241 // The server certificate is invalid
7242 UnlockList(c->AccountList);
7243 CiSetError(c, ERR_NOT_RSA_1024);
7244 return false;
7245 }
7246
7247 // Add a new account
7248 new_account = ZeroMalloc(sizeof(ACCOUNT));
7249 new_account->lock = NewLock();
7250
7251 // Copy the client authentication data
7252 new_account->ClientAuth = CopyClientAuth(a->ClientAuth);
7253
7254 // Copy the client option
7255 new_account->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
7256 Copy(new_account->ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
7257
7258 new_account->StartupAccount = a->StartupAccount;
7259
7260 new_account->CheckServerCert = a->CheckServerCert;
7261 new_account->RetryOnServerCert = a->RetryOnServerCert;
7262 if (a->ServerCert != NULL)
7263 {
7264 new_account->ServerCert = CloneX(a->ServerCert);
7265 }
7266
7267 // Shortcut Key
7268 if (IsZero(a->ShortcutKey, SHA1_SIZE))
7269 {
7270 Rand(new_account->ShortcutKey, SHA1_SIZE);
7271 }
7272 else
7273 {
7274 Copy(new_account->ShortcutKey, a->ShortcutKey, SHA1_SIZE);
7275 }
7276
7277 new_account->CreateDateTime = new_account->UpdateDateTime = SystemTime64();
7278
7279 // Insert into the list
7280 Insert(c->AccountList, new_account);
7281
7282 CLog(c, "LC_NEW_ACCOUNT", a->ClientOption->AccountName);
7283 }
7284 UnlockList(c->AccountList);
7285
7286 CiNormalizeAccountVLan(c);
7287
7288 CiSaveConfigurationFile(c);
7289
7290 CiNotify(c);
7291
7292 return true;
7293 }
7294
7295 // Release the account acquisition structure
CiFreeClientGetAccount(RPC_CLIENT_GET_ACCOUNT * a)7296 void CiFreeClientGetAccount(RPC_CLIENT_GET_ACCOUNT *a)
7297 {
7298 // Validate arguments
7299 if (a == NULL)
7300 {
7301 return;
7302 }
7303
7304 // Release the account information
7305 if (a->ServerCert != NULL)
7306 {
7307 FreeX(a->ServerCert);
7308 }
7309 CiFreeClientAuth(a->ClientAuth);
7310 Free(a->ClientOption);
7311 }
7312
7313 // Release the account creation structure
CiFreeClientCreateAccount(RPC_CLIENT_CREATE_ACCOUNT * a)7314 void CiFreeClientCreateAccount(RPC_CLIENT_CREATE_ACCOUNT *a)
7315 {
7316 // Validate arguments
7317 if (a == NULL)
7318 {
7319 return;
7320 }
7321
7322 // Release the account information
7323 if (a->ServerCert != NULL)
7324 {
7325 FreeX(a->ServerCert);
7326 }
7327 CiFreeClientAuth(a->ClientAuth);
7328 Free(a->ClientOption);
7329 }
7330
7331 // Stop the virtual LAN card
CtDisableVLan(CLIENT * c,RPC_CLIENT_CREATE_VLAN * vlan)7332 bool CtDisableVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *vlan)
7333 {
7334 UINT i;
7335 bool used;
7336 // Validate arguments
7337 if (c == NULL || vlan == NULL)
7338 {
7339 return false;
7340 }
7341
7342 #ifndef OS_WIN32
7343
7344 #ifdef NO_VLAN
7345 if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
7346 {
7347 // Can not be added or removed the virtual LAN card in MacOS X
7348 CiSetError(c, ERR_NOT_SUPPORTED);
7349 return false;
7350 }
7351 #endif // NO_VLAN
7352
7353 // Check whether the virtual LAN card with the specified name is not
7354 // being used by one or more accounts
7355 used = false;
7356 LockList(c->AccountList);
7357 {
7358 for (i = 0;i < LIST_NUM(c->AccountList);i++)
7359 {
7360 ACCOUNT *a = LIST_DATA(c->AccountList, i);
7361 if (StrCmpi(a->ClientOption->DeviceName, vlan->DeviceName) == 0)
7362 {
7363 Lock(a->lock);
7364 {
7365 if (a->ClientSession != NULL)
7366 {
7367 used = true;
7368 }
7369 }
7370 Unlock(a->lock);
7371 }
7372 }
7373 }
7374 UnlockList(c->AccountList);
7375
7376 // Search for the virtual LAN card
7377 LockList(c->UnixVLanList);
7378 {
7379 UNIX_VLAN *v, t;
7380
7381 Zero(&t, sizeof(t));
7382 StrCpy(t.Name, sizeof(t.Name), vlan->DeviceName);
7383
7384 v = Search(c->UnixVLanList, &t);
7385 if (v == NULL)
7386 {
7387 UnlockList(c->UnixVLanList);
7388 CiSetError(c, ERR_OBJECT_NOT_FOUND);
7389 return false;
7390 }
7391
7392 // Stop
7393 v->Enabled = false;
7394 }
7395 UnlockList(c->UnixVLanList);
7396
7397 CiSaveConfigurationFile(c);
7398 CiNotify(c);
7399 CiSendGlobalPulse(c);
7400
7401 return true;
7402
7403 #else // OS_WIN32
7404
7405 // Check whether the virtual LAN card with the specified name is not
7406 // being used by one or more accounts
7407 used = false;
7408 LockList(c->AccountList);
7409 {
7410 for (i = 0;i < LIST_NUM(c->AccountList);i++)
7411 {
7412 ACCOUNT *a = LIST_DATA(c->AccountList, i);
7413 if (StrCmpi(a->ClientOption->DeviceName, vlan->DeviceName) == 0)
7414 {
7415 Lock(a->lock);
7416 {
7417 if (a->ClientSession != NULL)
7418 {
7419 used = true;
7420 }
7421 }
7422 Unlock(a->lock);
7423 }
7424 }
7425 }
7426 UnlockList(c->AccountList);
7427
7428 #if 0
7429 if (used)
7430 {
7431 // In using
7432 CiSetError(c, ERR_VLAN_IS_USED);
7433 return false;
7434 }
7435 #endif
7436
7437
7438 // Check whether the virtual LAN card are present
7439 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, vlan->DeviceName) == false &&
7440 MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, vlan->DeviceName) == false)
7441 {
7442 CiSetError(c, ERR_OBJECT_NOT_FOUND);
7443 CiNotify(c);
7444 CiSendGlobalPulse(c);
7445 return false;
7446 }
7447
7448
7449 if (MsIs64BitWindows() && Is32() && MsIsAdmin())
7450 {
7451 // Execute the driver_installer to process since this Windows is 64 bit
7452 // but this code is 32 bit
7453 char tmp[MAX_SIZE];
7454
7455 Format(tmp, sizeof(tmp), "disablevlan %s", vlan->DeviceName);
7456
7457 if (MsExecDriverInstaller(tmp) == false)
7458 {
7459 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
7460 CiNotify(c);
7461 CiSendGlobalPulse(c);
7462 return false;
7463 }
7464 }
7465 else
7466 {
7467 // Stop the virtual LAN card
7468 if (MsDisableVLan(vlan->DeviceName) == false)
7469 {
7470 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
7471 CiNotify(c);
7472 CiSendGlobalPulse(c);
7473 return false;
7474 }
7475 }
7476
7477 CiNotify(c);
7478 CiSendGlobalPulse(c);
7479
7480 return true;
7481
7482 #endif // OS_WIN32
7483
7484 }
7485
7486 // Start the virtual LAN card
CtEnableVLan(CLIENT * c,RPC_CLIENT_CREATE_VLAN * vlan)7487 bool CtEnableVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *vlan)
7488 {
7489 // Validate arguments
7490 if (c == NULL || vlan == NULL)
7491 {
7492 return false;
7493 }
7494
7495 #ifndef OS_WIN32
7496
7497 #ifdef NO_VLAN
7498 if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
7499 {
7500 // Can not be added or removed the virtual LAN card in MacOS X
7501 CiSetError(c, ERR_NOT_SUPPORTED);
7502 return false;
7503 }
7504 #endif // NO_VLAN
7505
7506 // Search the virtual LAN card
7507 LockList(c->UnixVLanList);
7508 {
7509 UNIX_VLAN *v, t;
7510
7511 Zero(&t, sizeof(t));
7512 StrCpy(t.Name, sizeof(t.Name), vlan->DeviceName);
7513
7514 v = Search(c->UnixVLanList, &t);
7515 if (v == NULL)
7516 {
7517 UnlockList(c->UnixVLanList);
7518 CiSetError(c, ERR_OBJECT_NOT_FOUND);
7519 return false;
7520 }
7521
7522 // Enable
7523 v->Enabled = true;
7524 }
7525 UnlockList(c->UnixVLanList);
7526
7527 CiSaveConfigurationFile(c);
7528 CiNotify(c);
7529 CiSendGlobalPulse(c);
7530
7531 return true;
7532
7533 #else // OS_WIN32
7534
7535 // Check whether the virtual LAN card are present
7536 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, vlan->DeviceName) == false &&
7537 MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, vlan->DeviceName) == false)
7538 {
7539 CiSetError(c, ERR_OBJECT_NOT_FOUND);
7540 CiNotify(c);
7541 CiSendGlobalPulse(c);
7542 return false;
7543 }
7544
7545 if (MsIs64BitWindows() && Is32() && MsIsAdmin())
7546 {
7547 // Execute the driver_installer to process since this Windows is 64 bit
7548 // but this code is 32 bit
7549 char tmp[MAX_SIZE];
7550
7551 Format(tmp, sizeof(tmp), "enablevlan %s", vlan->DeviceName);
7552
7553 if (MsExecDriverInstaller(tmp) == false)
7554 {
7555 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
7556 CiNotify(c);
7557 CiSendGlobalPulse(c);
7558 return false;
7559 }
7560 }
7561 else
7562 {
7563 // Start the virtual LAN card
7564 if (MsEnableVLan(vlan->DeviceName) == false)
7565 {
7566 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
7567 CiNotify(c);
7568 CiSendGlobalPulse(c);
7569 return false;
7570 }
7571 }
7572
7573 CiNotify(c);
7574 CiSendGlobalPulse(c);
7575
7576 return true;
7577
7578 #endif // OS_WIN32
7579
7580 }
7581
7582 // Delete the virtual LAN card
CtDeleteVLan(CLIENT * c,RPC_CLIENT_CREATE_VLAN * d)7583 bool CtDeleteVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *d)
7584 {
7585 UINT i;
7586 bool used;
7587 // Validate arguments
7588 if (c == NULL || d == NULL)
7589 {
7590 return false;
7591 }
7592
7593 #ifndef OS_WIN32
7594
7595 #ifdef NO_VLAN
7596 if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
7597 {
7598 // Can not be added or removed the virtual LAN card in MacOS X
7599 CiSetError(c, ERR_NOT_SUPPORTED);
7600 return false;
7601 }
7602 #endif // NO_VLAN
7603
7604 // Check whether the virtual LAN card with the specified name is not
7605 // being used by one or more accounts
7606 used = false;
7607 LockList(c->AccountList);
7608 {
7609 for (i = 0;i < LIST_NUM(c->AccountList);i++)
7610 {
7611 ACCOUNT *a = LIST_DATA(c->AccountList, i);
7612 if (StrCmpi(a->ClientOption->DeviceName, d->DeviceName) == 0)
7613 {
7614 used = true;
7615 }
7616 }
7617 }
7618 UnlockList(c->AccountList);
7619
7620 #if 0
7621 if (used)
7622 {
7623 // In using
7624 CiSetError(c, ERR_VLAN_IS_USED);
7625 return false;
7626 }
7627 #endif
7628
7629 // Search for the virtual LAN card
7630 LockList(c->UnixVLanList);
7631 {
7632 UNIX_VLAN *v, t;
7633
7634 Zero(&t, sizeof(t));
7635 StrCpy(t.Name, sizeof(t.Name), d->DeviceName);
7636
7637 v = Search(c->UnixVLanList, &t);
7638 if (v == NULL)
7639 {
7640 UnlockList(c->UnixVLanList);
7641 CiSetError(c, ERR_OBJECT_NOT_FOUND);
7642 return false;
7643 }
7644
7645 // Remove
7646 if (Delete(c->UnixVLanList, v))
7647 {
7648 Free(v);
7649 }
7650
7651 CLog(c, "LC_DELETE_VLAN", d->DeviceName);
7652
7653 UnixVLanDelete(d->DeviceName);
7654 }
7655 UnlockList(c->UnixVLanList);
7656
7657 CiNormalizeAccountVLan(c);
7658
7659 CiSaveConfigurationFile(c);
7660 CiNotify(c);
7661 CiSendGlobalPulse(c);
7662
7663 return true;
7664
7665 #else // OS_WIN32
7666
7667 // Check whether the virtual LAN card are present
7668 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, d->DeviceName) == false &&
7669 MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, d->DeviceName) == false)
7670 {
7671 CiSetError(c, ERR_OBJECT_NOT_FOUND);
7672 return false;
7673 }
7674
7675 // Check whether the virtual LAN card with the specified name is not
7676 // being used by one or more accounts
7677 used = false;
7678 LockList(c->AccountList);
7679 {
7680 for (i = 0;i < LIST_NUM(c->AccountList);i++)
7681 {
7682 ACCOUNT *a = LIST_DATA(c->AccountList, i);
7683 if (StrCmpi(a->ClientOption->DeviceName, d->DeviceName) == 0)
7684 {
7685 used = true;
7686 }
7687 }
7688 }
7689 UnlockList(c->AccountList);
7690
7691 #if 0
7692 if (used)
7693 {
7694 // In using
7695 CiSetError(c, ERR_VLAN_IS_USED);
7696 return false;
7697 }
7698 #endif
7699
7700 if (MsIs64BitWindows() && Is32() && MsIsAdmin())
7701 {
7702 // Execute the driver_installer to process since this Windows is 64 bit
7703 // but this code is 32 bit
7704 char tmp[MAX_SIZE];
7705
7706 Format(tmp, sizeof(tmp), "uninstvlan %s", d->DeviceName);
7707
7708 if (MsExecDriverInstaller(tmp) == false)
7709 {
7710 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
7711 return false;
7712 }
7713 }
7714 else
7715 {
7716 // Delete the virtual LAN card directly
7717 if (MsUninstallVLan(d->DeviceName) == false)
7718 {
7719 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
7720 CiNotify(c);
7721 CiSendGlobalPulse(c);
7722 return false;
7723 }
7724 }
7725
7726 CLog(c, "LC_DELETE_VLAN", d->DeviceName);
7727
7728 CiNormalizeAccountVLan(c);
7729
7730 CiNotify(c);
7731 CiSendGlobalPulse(c);
7732
7733 return true;
7734
7735 #endif // OS_WIN32
7736
7737 }
7738
7739 // Get the name of the first VLAN
CiGetFirstVLan(CLIENT * c)7740 char *CiGetFirstVLan(CLIENT *c)
7741 {
7742 char *ret = NULL;
7743 RPC_CLIENT_ENUM_VLAN t;
7744 // Validate arguments
7745 if (c == NULL)
7746 {
7747 return NULL;
7748 }
7749
7750 Zero(&t, sizeof(t));
7751 if (CtEnumVLan(c, &t) == false)
7752 {
7753 return NULL;
7754 }
7755
7756 if (t.NumItem >= 1)
7757 {
7758 UINT i;
7759 char *tmp = t.Items[0]->DeviceName;
7760
7761 for (i = 0;i < t.NumItem;i++)
7762 {
7763 if (t.Items[i]->Enabled)
7764 {
7765 tmp = t.Items[i]->DeviceName;
7766 }
7767 }
7768
7769 ret = CopyStr(tmp);
7770 }
7771
7772 CiFreeClientEnumVLan(&t);
7773
7774 return ret;
7775 }
7776
7777 // Enumerate virtual LAN cards
CtEnumVLan(CLIENT * c,RPC_CLIENT_ENUM_VLAN * e)7778 bool CtEnumVLan(CLIENT *c, RPC_CLIENT_ENUM_VLAN *e)
7779 {
7780 UINT i;
7781 TOKEN_LIST *t;
7782 // Validate arguments
7783 if (c == NULL || e == NULL)
7784 {
7785 return false;
7786 }
7787
7788 #ifndef OS_WIN32
7789
7790 LockList(c->UnixVLanList);
7791 {
7792 e->NumItem = LIST_NUM(c->UnixVLanList);
7793 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM *) * e->NumItem);
7794
7795 for (i = 0;i < e->NumItem;i++)
7796 {
7797 RPC_CLIENT_ENUM_VLAN_ITEM *item;
7798 UNIX_VLAN *v;
7799
7800 v = LIST_DATA(c->UnixVLanList, i);
7801 e->Items[i] = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM));
7802 item = e->Items[i];
7803
7804 item->Enabled = v->Enabled;
7805 BinToStr(item->MacAddress, sizeof(item->MacAddress), v->MacAddress, 6);
7806 StrCpy(item->DeviceName, sizeof(item->DeviceName), v->Name);
7807 StrCpy(item->Version, sizeof(item->Version), c->Cedar->VerString);
7808 }
7809 }
7810 UnlockList(c->UnixVLanList);
7811
7812 return true;
7813
7814 #else // OS_WIN32
7815
7816 // Enumeration
7817 t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, VLAN_ADAPTER_NAME_OLD);
7818 if (t == NULL)
7819 {
7820 // Enumeration failure
7821 e->NumItem = 0;
7822 e->Items = ZeroMalloc(0);
7823 }
7824 else
7825 {
7826 // Enumeration success
7827 e->NumItem = t->NumTokens;
7828 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM *) * e->NumItem);
7829
7830 for (i = 0;i < e->NumItem;i++)
7831 {
7832 char *tmp;
7833 RPC_CLIENT_ENUM_VLAN_ITEM *item;
7834 e->Items[i] = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM));
7835 item = e->Items[i];
7836
7837 StrCpy(item->DeviceName, sizeof(item->DeviceName), t->Token[i]);
7838 item->Enabled = MsIsVLanEnabled(item->DeviceName);
7839
7840 tmp = MsGetMacAddress(VLAN_ADAPTER_NAME_TAG, item->DeviceName);
7841 if (tmp == NULL)
7842 {
7843 tmp = MsGetMacAddress(VLAN_ADAPTER_NAME_TAG_OLD, item->DeviceName);
7844 }
7845
7846 StrCpy(item->MacAddress, sizeof(item->MacAddress), tmp);
7847 Free(tmp);
7848
7849 tmp = MsGetDriverVersion(VLAN_ADAPTER_NAME_TAG, item->DeviceName);
7850 if (tmp == NULL)
7851 {
7852 tmp = MsGetDriverVersion(VLAN_ADAPTER_NAME_TAG_OLD, item->DeviceName);
7853 }
7854
7855 StrCpy(item->Version, sizeof(item->Version), tmp);
7856 Free(tmp);
7857 }
7858
7859 FreeToken(t);
7860 }
7861
7862 return true;
7863
7864 #endif // OS_WIN32
7865 }
7866
7867 // Release the virtual LAN card enumeration
CiFreeClientEnumVLan(RPC_CLIENT_ENUM_VLAN * e)7868 void CiFreeClientEnumVLan(RPC_CLIENT_ENUM_VLAN *e)
7869 {
7870 UINT i;
7871 // Validate arguments
7872 if (e == NULL)
7873 {
7874 return;
7875 }
7876
7877 for (i = 0;i < e->NumItem;i++)
7878 {
7879 Free(e->Items[i]);
7880 }
7881 Free(e->Items);
7882 }
7883
7884 // Set the information about the virtual LAN card
CtSetVLan(CLIENT * c,RPC_CLIENT_SET_VLAN * set)7885 bool CtSetVLan(CLIENT *c, RPC_CLIENT_SET_VLAN *set)
7886 {
7887 // Validate arguments
7888 if (c == NULL || set == NULL)
7889 {
7890 return false;
7891 }
7892
7893 #ifndef OS_WIN32
7894
7895 LockList(c->UnixVLanList);
7896 {
7897 UNIX_VLAN t, *r;
7898 Zero(&t, sizeof(t));
7899 StrCpy(t.Name, sizeof(t.Name), set->DeviceName);
7900
7901 r = Search(c->UnixVLanList, &t);
7902 if (r == NULL)
7903 {
7904 // Not exist
7905 CiSetError(c, ERR_VLAN_ALREADY_EXISTS);
7906 UnlockList(c->UnixVLanList);
7907 return false;
7908 }
7909
7910 StrToMac(r->MacAddress, set->MacAddress);
7911 }
7912 UnlockList(c->UnixVLanList);
7913
7914 CiSaveConfigurationFile(c);
7915 CiNotify(c);
7916 CiSendGlobalPulse(c);
7917
7918 return true;
7919
7920 #else // OS_WIN32
7921
7922 // Check whether the virtual LAN card with the specified name already exists
7923 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, set->DeviceName) == false &&
7924 MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, set->DeviceName) == false)
7925 {
7926 // Not exist
7927 CiSetError(c, ERR_OBJECT_NOT_FOUND);
7928 return false;
7929 }
7930
7931 // Configuring MAC address
7932 MsSetMacAddress(VLAN_ADAPTER_NAME_TAG, set->DeviceName, set->MacAddress);
7933 MsSetMacAddress(VLAN_ADAPTER_NAME_TAG_OLD, set->DeviceName, set->MacAddress);
7934
7935 CiNotify(c);
7936 CiSendGlobalPulse(c);
7937
7938 return true;
7939
7940 #endif // OS_WIN32
7941 }
7942
7943 // Get the information about the virtual LAN card
CtGetVLan(CLIENT * c,RPC_CLIENT_GET_VLAN * get)7944 bool CtGetVLan(CLIENT *c, RPC_CLIENT_GET_VLAN *get)
7945 {
7946 char *tmp;
7947 // Validate arguments
7948 if (c == NULL || get == NULL)
7949 {
7950 return false;
7951 }
7952
7953 #ifndef OS_WIN32
7954
7955 // Unsupported
7956 CiSetError(c, ERR_NOT_SUPPORTED);
7957 return false;
7958
7959 #else // OS_WIN32
7960
7961 // Check whether the virtual LAN card with the specified name already exists
7962 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, get->DeviceName) == false &&
7963 MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, get->DeviceName) == false)
7964 {
7965 // Not exist
7966 CiSetError(c, ERR_OBJECT_NOT_FOUND);
7967 return false;
7968 }
7969
7970 // Activity
7971 get->Enabled = MsIsVLanEnabled(get->DeviceName);
7972
7973 // MAC address
7974 tmp = MsGetMacAddress(VLAN_ADAPTER_NAME_TAG, get->DeviceName);
7975 if (tmp == NULL)
7976 {
7977 tmp = MsGetMacAddress(VLAN_ADAPTER_NAME_TAG_OLD, get->DeviceName);
7978 }
7979 StrCpy(get->MacAddress, sizeof(get->MacAddress), tmp);
7980 Free(tmp);
7981
7982 // Version
7983 tmp = MsGetDriverVersion(VLAN_ADAPTER_NAME_TAG, get->DeviceName);
7984 if (tmp == NULL)
7985 {
7986 tmp = MsGetDriverVersion(VLAN_ADAPTER_NAME_TAG_OLD, get->DeviceName);
7987 }
7988 StrCpy(get->Version, sizeof(get->Version), tmp);
7989 Free(tmp);
7990
7991 // File name
7992 tmp = MsGetDriverFileName(VLAN_ADAPTER_NAME_TAG, get->DeviceName);
7993 if (tmp == NULL)
7994 {
7995 tmp = MsGetDriverFileName(VLAN_ADAPTER_NAME_TAG_OLD, get->DeviceName);
7996 }
7997 StrCpy(get->FileName, sizeof(get->FileName), tmp);
7998 Free(tmp);
7999
8000 // GUID
8001 tmp = MsGetNetworkAdapterGuid(VLAN_ADAPTER_NAME_TAG, get->DeviceName);
8002 if (tmp == NULL)
8003 {
8004 tmp = MsGetNetworkAdapterGuid(VLAN_ADAPTER_NAME_TAG_OLD, get->DeviceName);
8005 }
8006 StrCpy(get->Guid, sizeof(get->Guid), tmp);
8007 Free(tmp);
8008
8009 return true;
8010
8011 #endif // OS_WIN32
8012 }
8013
8014 #ifdef OS_WIN32
8015 // Initialize the driver version information structure
CiInitDriverVerStruct(MS_DRIVER_VER * ver)8016 void CiInitDriverVerStruct(MS_DRIVER_VER *ver)
8017 {
8018 // Validate arguments
8019 if (ver == NULL)
8020 {
8021 return;
8022 }
8023
8024 Zero(ver, sizeof(MS_DRIVER_VER));
8025
8026 ver->Year = BUILD_DATE_Y;
8027 ver->Month = BUILD_DATE_M;
8028 ver->Day = BUILD_DATE_D;
8029 ver->Major = CEDAR_VERSION_MAJOR;
8030 ver->Minor = CEDAR_VERSION_MINOR;
8031 ver->Build = CEDAR_VERSION_BUILD;
8032 }
8033 #endif // OS_WIN32
8034
8035 // Upgrade the virtual LAN card
CtUpgradeVLan(CLIENT * c,RPC_CLIENT_CREATE_VLAN * create)8036 bool CtUpgradeVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *create)
8037 {
8038 bool use_old_name = false;
8039
8040 #ifdef OS_WIN32
8041 MS_DRIVER_VER ver;
8042 #endif // OS_WIN32
8043
8044 // Validate arguments
8045 if (c == NULL || create == NULL)
8046 {
8047 return false;
8048 }
8049
8050
8051 #ifndef OS_WIN32
8052
8053 // Always succeed
8054 return true;
8055
8056 #else // OS_WIN32
8057
8058 CiInitDriverVerStruct(&ver);
8059
8060 // Check whether the LAN card with the specified name already exists
8061 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, create->DeviceName) == false &&
8062 MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, create->DeviceName) == false)
8063 {
8064 // Not exist
8065 CiSetError(c, ERR_OBJECT_NOT_FOUND);
8066 CiNotify(c);
8067 CiSendGlobalPulse(c);
8068 return false;
8069 }
8070
8071 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, create->DeviceName))
8072 {
8073 use_old_name = true;
8074 }
8075
8076 // Perform the installation
8077 char tmp[MAX_SIZE];
8078 Format(tmp, sizeof(tmp), "upgradevlan %s", create->DeviceName);
8079
8080 if (CncExecDriverInstaller(tmp) == false)
8081 {
8082 // Installation Failed
8083 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
8084 CiNotify(c);
8085 CiSendGlobalPulse(c);
8086 return false;
8087 }
8088
8089 CLog(c, "LC_UPDATE_VLAN", create->DeviceName);
8090
8091 CiNotify(c);
8092 CiSendGlobalPulse(c);
8093
8094 return true;
8095
8096 #endif // OS_WIN32
8097 }
8098
8099 // Create a virtual LAN card
CtCreateVLan(CLIENT * c,RPC_CLIENT_CREATE_VLAN * create)8100 bool CtCreateVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *create)
8101 {
8102 TOKEN_LIST *t;
8103 UINT max_len;
8104
8105 // Validate arguments
8106 if (c == NULL || create == NULL)
8107 {
8108 return false;
8109 }
8110
8111 if (SearchStrEx(create->DeviceName, " ", 0, false) != INFINITE)
8112 {
8113 // Spaces in the name is not allowed
8114 CiSetError(c, ERR_INVALID_PARAMETER);
8115 return false;
8116 }
8117
8118 #ifndef OS_WIN32
8119
8120 // Non-Win32
8121 #ifdef NO_VLAN
8122 if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
8123 {
8124 // A virtual LAN card can not be added or removed in MacOS X
8125 CiSetError(c, ERR_NOT_SUPPORTED);
8126 return false;
8127 }
8128 #endif // NO_VLAN
8129
8130 // Check whether the specified name is valid or not
8131 if (IsSafeStr(create->DeviceName) == false)
8132 {
8133 // Name is invalid
8134 CiSetError(c, ERR_VLAN_INVALID_NAME);
8135 return false;
8136 }
8137
8138 // Check whether the LAN card of the specified name already exists
8139 LockList(c->UnixVLanList);
8140 {
8141 UNIX_VLAN t, *r;
8142 Zero(&t, sizeof(t));
8143 StrCpy(t.Name, sizeof(t.Name), create->DeviceName);
8144
8145 r = Search(c->UnixVLanList, &t);
8146 if (r != NULL)
8147 {
8148 // Already exist
8149 CiSetError(c, ERR_VLAN_ALREADY_EXISTS);
8150 UnlockList(c->UnixVLanList);
8151 return false;
8152 }
8153
8154 // Register
8155 r = ZeroMalloc(sizeof(UNIX_VLAN));
8156 r->Enabled = true;
8157 GenMacAddress(r->MacAddress);
8158 StrCpy(r->Name, sizeof(r->Name), create->DeviceName);
8159
8160 // Create a TUN
8161 if (UnixVLanCreate(r->Name, r->MacAddress, false) == false)
8162 {
8163 // Failure
8164 Free(r);
8165 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
8166 UnlockList(c->UnixVLanList);
8167 return false;
8168 }
8169
8170 CLog(c, "LC_CREATE_VLAN", create->DeviceName);
8171
8172 Add(c->UnixVLanList, r);
8173 }
8174 UnlockList(c->UnixVLanList);
8175
8176 CiNormalizeAccountVLan(c);
8177
8178 CiNotify(c);
8179 CiSendGlobalPulse(c);
8180 CiSaveConfigurationFile(c);
8181
8182 return true;
8183
8184 #else // OS_WIN32
8185 // Check whether the specified name is valid or not
8186 if (IsSafeStr(create->DeviceName) == false)
8187 {
8188 // Name is invalid
8189 CiSetError(c, ERR_VLAN_INVALID_NAME);
8190 return false;
8191 }
8192
8193 max_len = MAX_DEVICE_NAME_LEN;
8194 if (StrLen(create->DeviceName) > max_len)
8195 {
8196 // Name is too long
8197 CiSetError(c, ERR_VLAN_INVALID_NAME);
8198 return false;
8199 }
8200
8201 // Regulation in Windows 8 / 10
8202 if (MsIsInfCatalogRequired())
8203 {
8204 if (CiIsValidVLanRegulatedName(create->DeviceName) == false)
8205 {
8206 // Name is invalid
8207 CiSetError(c, ERR_VLAN_INVALID_NAME);
8208 return false;
8209 }
8210 }
8211
8212 // Check whether the LAN card with the specified name already exists
8213 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, create->DeviceName) ||
8214 MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, create->DeviceName))
8215 {
8216 // Already exist
8217 CiSetError(c, ERR_VLAN_ALREADY_EXISTS);
8218 return false;
8219 }
8220
8221 // Perform the installation (Windows Vista)
8222 char tmp[MAX_SIZE];
8223 Format(tmp, sizeof(tmp), "instvlan %s", create->DeviceName);
8224
8225 if (CncExecDriverInstaller(tmp) == false)
8226 {
8227 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
8228 CiNotify(c);
8229 CiSendGlobalPulse(c);
8230 return false;
8231 }
8232
8233 t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, VLAN_ADAPTER_NAME_OLD);
8234 if (t->NumTokens == 1)
8235 {
8236 UINT i;
8237 // If the result of the installation, virtual LAN card is only one,
8238 // set virtual LAN card setting of all existing accounts to this virtual LAN card
8239 LockList(c->AccountList);
8240 {
8241 for (i = 0;i < LIST_NUM(c->AccountList);i++)
8242 {
8243 ACCOUNT *a = LIST_DATA(c->AccountList, i);
8244 Lock(a->lock);
8245 {
8246 if (a->ClientOption != NULL)
8247 {
8248 StrCpy(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName), create->DeviceName);
8249 }
8250 }
8251 Unlock(a->lock);
8252 }
8253 }
8254 UnlockList(c->AccountList);
8255 }
8256 FreeToken(t);
8257
8258 CLog(c, "LC_CREATE_VLAN", create->DeviceName);
8259
8260 CiNormalizeAccountVLan(c);
8261
8262 CiNotify(c);
8263 CiSendGlobalPulse(c);
8264
8265 CiSaveConfigurationFile(c);
8266
8267 return true;
8268
8269 #endif // OS_WIN32
8270 }
8271
8272 // Enumerate objects in the secure device
CtEnumObjectInSecure(CLIENT * c,RPC_ENUM_OBJECT_IN_SECURE * e)8273 bool CtEnumObjectInSecure(CLIENT *c, RPC_ENUM_OBJECT_IN_SECURE *e)
8274 {
8275 UINT i;
8276 // Validate arguments
8277 if (c == NULL || e == NULL)
8278 {
8279 return false;
8280 }
8281
8282 e->NumItem = 5;
8283 e->ItemName = ZeroMalloc(sizeof(char *) * e->NumItem);
8284 e->ItemType = ZeroMalloc(sizeof(bool) * e->NumItem);
8285
8286 for (i = 0;i < e->NumItem;i++)
8287 {
8288 char tmp[MAX_SIZE];
8289 Format(tmp, sizeof(tmp), "Test Object %u", i);
8290 e->ItemName[i] = CopyStr(tmp);
8291 e->ItemType[i] = (i % 2 == 0) ? false : true;
8292 }
8293
8294 return true;
8295 }
8296
8297 // Get the secure device to be used
CtGetUseSecure(CLIENT * c,RPC_USE_SECURE * sec)8298 bool CtGetUseSecure(CLIENT *c, RPC_USE_SECURE *sec)
8299 {
8300 // Validate arguments
8301 if (c == NULL || sec == NULL)
8302 {
8303 return false;
8304 }
8305
8306 sec->DeviceId = c->UseSecureDeviceId;
8307
8308 return true;
8309 }
8310
8311 // Specifying a secure device to be used
CtUseSecure(CLIENT * c,RPC_USE_SECURE * sec)8312 bool CtUseSecure(CLIENT *c, RPC_USE_SECURE *sec)
8313 {
8314 // Validate arguments
8315 if (c == NULL || sec == NULL)
8316 {
8317 return false;
8318 }
8319
8320 // Do not check whether there is the specified device on the client manager
8321 /* if (CheckSecureDeviceId(sec->DeviceId))
8322 {
8323 c->UseSecureDeviceId = sec->DeviceId;
8324 }
8325 else
8326 {
8327 CiSetError(c, ERR_OBJECT_NOT_FOUND);
8328 return false;
8329 }
8330 */
8331 c->UseSecureDeviceId = sec->DeviceId;
8332
8333 CiSaveConfigurationFile(c);
8334
8335 return true;
8336 }
8337
8338 // Enumeration of secure devices
CtEnumSecure(CLIENT * c,RPC_CLIENT_ENUM_SECURE * e)8339 bool CtEnumSecure(CLIENT *c, RPC_CLIENT_ENUM_SECURE *e)
8340 {
8341 LIST *o;
8342 UINT i;
8343 // Validate arguments
8344 if (c == NULL || e == NULL)
8345 {
8346 return false;
8347 }
8348
8349 o = GetSecureDeviceList();
8350
8351 e->NumItem = LIST_NUM(o);
8352 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_SECURE_ITEM *) * e->NumItem);
8353
8354 for (i = 0;i < LIST_NUM(o);i++)
8355 {
8356 RPC_CLIENT_ENUM_SECURE_ITEM *item = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_SECURE_ITEM));
8357 SECURE_DEVICE *s = LIST_DATA(o, i);
8358
8359 item->DeviceId = s->Id;
8360 StrCpy(item->DeviceName, sizeof(item->DeviceName), s->DeviceName);
8361 StrCpy(item->Manufacturer, sizeof(item->Manufacturer), s->Manufacturer);
8362 item->Type = s->Type;
8363
8364 e->Items[i] = item;
8365 }
8366
8367 return true;
8368 }
8369
8370 // Release the secure device enumeration
CiFreeClientEnumSecure(RPC_CLIENT_ENUM_SECURE * e)8371 void CiFreeClientEnumSecure(RPC_CLIENT_ENUM_SECURE *e)
8372 {
8373 UINT i;
8374 // Validate arguments
8375 if (e == NULL)
8376 {
8377 return;
8378 }
8379
8380 for (i = 0;i < e->NumItem;i++)
8381 {
8382 Free(e->Items[i]);
8383 }
8384 Free(e->Items);
8385 }
8386
8387 // Release the RPC_GET_ISSUER
CiFreeGetIssuer(RPC_GET_ISSUER * a)8388 void CiFreeGetIssuer(RPC_GET_ISSUER *a)
8389 {
8390 // Validate arguments
8391 if (a == NULL)
8392 {
8393 return;
8394 }
8395
8396 if (a->issuer_x != NULL)
8397 {
8398 FreeX(a->issuer_x);
8399 }
8400 if (a->x != NULL)
8401 {
8402 FreeX(a->x);
8403 }
8404 }
8405
8406 // Get the common proxy settings
CtGetCommonProxySetting(CLIENT * c,INTERNET_SETTING * a)8407 bool CtGetCommonProxySetting(CLIENT *c, INTERNET_SETTING *a)
8408 {
8409 // Validate arguments
8410 if (c == NULL || a == NULL)
8411 {
8412 return false;
8413 }
8414
8415 Copy(a, &c->CommonProxySetting, sizeof(INTERNET_SETTING));
8416
8417 return true;
8418 }
8419
8420 // Set the common proxy settings
CtSetCommonProxySetting(CLIENT * c,INTERNET_SETTING * a)8421 bool CtSetCommonProxySetting(CLIENT *c, INTERNET_SETTING *a)
8422 {
8423 // Validate arguments
8424 if (c == NULL || a == NULL)
8425 {
8426 return false;
8427 }
8428
8429 Copy(&c->CommonProxySetting, a, sizeof(INTERNET_SETTING));
8430
8431
8432 CiSaveConfigurationFile(c);
8433
8434 return true;
8435 }
8436
8437 // Get the issuer
CtGetIssuer(CLIENT * c,RPC_GET_ISSUER * a)8438 bool CtGetIssuer(CLIENT *c, RPC_GET_ISSUER *a)
8439 {
8440 X *x;
8441 // Validate arguments
8442 if (c == NULL || a == NULL)
8443 {
8444 return false;
8445 }
8446
8447 x = FindCaSignedX(c->Cedar->CaList, a->x);
8448 if (x == NULL)
8449 {
8450 CiSetError(c, ERR_OBJECT_NOT_FOUND);;
8451 return false;
8452 }
8453 else
8454 {
8455 a->issuer_x = x;
8456 if (a->x != NULL)
8457 {
8458 FreeX(a->x);
8459 a->x = NULL;
8460 }
8461 return true;
8462 }
8463 }
8464
8465 // Get the CA certificate
CtGetCa(CLIENT * c,RPC_GET_CA * get)8466 bool CtGetCa(CLIENT *c, RPC_GET_CA *get)
8467 {
8468 bool ret = true;
8469 X *cert = NULL;
8470 // Validate arguments
8471 if (c == NULL || get == NULL)
8472 {
8473 return false;
8474 }
8475
8476 LockList(c->Cedar->CaList);
8477 {
8478 UINT i;
8479
8480 for (i = 0;i < LIST_NUM(c->Cedar->CaList);i++)
8481 {
8482 X *x = LIST_DATA(c->Cedar->CaList, i);
8483
8484 if (POINTER_TO_KEY(x) == get->Key)
8485 {
8486 cert = CloneX(x);
8487 break;
8488 }
8489 }
8490 }
8491 UnlockList(c->Cedar->CaList);
8492
8493 if (cert == NULL)
8494 {
8495 // Certificate does not exist
8496 ret = false;
8497 CiSetError(c, ERR_OBJECT_NOT_FOUND);
8498 }
8499 else
8500 {
8501 ret = true;
8502 get->x = cert;
8503 }
8504
8505 return ret;
8506 }
8507
8508 // Delete the CA certificate
CtDeleteCa(CLIENT * c,RPC_CLIENT_DELETE_CA * p)8509 bool CtDeleteCa(CLIENT *c, RPC_CLIENT_DELETE_CA *p)
8510 {
8511 bool ret;
8512 // Validate arguments
8513 if (c == NULL || p == NULL)
8514 {
8515 return false;
8516 }
8517
8518 ret = DeleteCa(c->Cedar, p->Key);
8519
8520 if (ret == false)
8521 {
8522 CiSetError(c, ERR_OBJECT_NOT_FOUND);
8523 }
8524
8525 CiSaveConfigurationFile(c);
8526
8527 return ret;
8528 }
8529
8530 // Add a CA certificate
CtAddCa(CLIENT * c,RPC_CERT * cert)8531 bool CtAddCa(CLIENT *c, RPC_CERT *cert)
8532 {
8533 // Validate arguments
8534 if (c == NULL || cert == NULL)
8535 {
8536 return false;
8537 }
8538
8539 if (cert->x->is_compatible_bit == false)
8540 {
8541 CiSetError(c, ERR_NOT_RSA_1024);
8542 return false;
8543 }
8544
8545 AddCa(c->Cedar, cert->x);
8546
8547 CiSaveConfigurationFile(c);
8548
8549 return true;
8550 }
8551
8552 // Enumerate the trusted CA
CtEnumCa(CLIENT * c,RPC_CLIENT_ENUM_CA * e)8553 bool CtEnumCa(CLIENT *c, RPC_CLIENT_ENUM_CA *e)
8554 {
8555 // Validate arguments
8556 if (c == NULL || e == NULL)
8557 {
8558 return false;
8559 }
8560
8561 Zero(e, sizeof(RPC_CLIENT_ENUM_CA));
8562
8563 LockList(c->Cedar->CaList);
8564 {
8565 UINT i;
8566 e->NumItem = LIST_NUM(c->Cedar->CaList);
8567 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_CA_ITEM *) * e->NumItem);
8568
8569 for (i = 0;i < e->NumItem;i++)
8570 {
8571 X *x = LIST_DATA(c->Cedar->CaList, i);
8572 e->Items[i] = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_CA_ITEM));
8573 GetAllNameFromNameEx(e->Items[i]->SubjectName, sizeof(e->Items[i]->SubjectName), x->subject_name);
8574 GetAllNameFromNameEx(e->Items[i]->IssuerName, sizeof(e->Items[i]->IssuerName), x->issuer_name);
8575 e->Items[i]->Expires = x->notAfter;
8576 e->Items[i]->Key = POINTER_TO_KEY(x);
8577 }
8578 }
8579 UnlockList(c->Cedar->CaList);
8580
8581 return true;
8582 }
8583
8584 // Release the CA enumeration
CiFreeClientEnumCa(RPC_CLIENT_ENUM_CA * e)8585 void CiFreeClientEnumCa(RPC_CLIENT_ENUM_CA *e)
8586 {
8587 UINT i;
8588 // Validate arguments
8589 if (e == NULL)
8590 {
8591 return;
8592 }
8593
8594 for (i = 0;i < e->NumItem;i++)
8595 {
8596 RPC_CLIENT_ENUM_CA_ITEM *ca = e->Items[i];
8597 Free(ca);
8598 }
8599 Free(e->Items);
8600 }
8601
8602 // Get the password setting
CtGetPasswordSetting(CLIENT * c,RPC_CLIENT_PASSWORD_SETTING * a)8603 bool CtGetPasswordSetting(CLIENT *c, RPC_CLIENT_PASSWORD_SETTING *a)
8604 {
8605 UCHAR hash[SHA1_SIZE];
8606 // Validate arguments
8607 if (c == NULL || a == NULL)
8608 {
8609 return false;
8610 }
8611
8612 Sha0(hash, "", 0);
8613 if (Cmp(hash, c->EncryptedPassword, SHA1_SIZE) == 0)
8614 {
8615 a->IsPasswordPresented = false;
8616 }
8617 else
8618 {
8619 a->IsPasswordPresented = true;
8620 }
8621
8622 a->PasswordRemoteOnly = c->PasswordRemoteOnly;
8623
8624 return true;
8625 }
8626
8627 // Set the password
CtSetPassword(CLIENT * c,RPC_CLIENT_PASSWORD * pass)8628 bool CtSetPassword(CLIENT *c, RPC_CLIENT_PASSWORD *pass)
8629 {
8630 char *str;
8631 if (c == NULL)
8632 {
8633 return false;
8634 }
8635
8636 str = pass->Password;
8637
8638 if (StrCmp(str, "********") != 0)
8639 {
8640 // Hash the password
8641 Sha0(c->EncryptedPassword, str, StrLen(str));
8642 }
8643
8644 c->PasswordRemoteOnly = pass->PasswordRemoteOnly;
8645
8646 CLog(c, "LC_SET_PASSWORD");
8647
8648 CiSaveConfigurationFile(c);
8649
8650 return true;
8651 }
8652
CiFreeIni(LIST * o)8653 void CiFreeIni(LIST *o)
8654 {
8655 // Validate arguments
8656 if (o == NULL)
8657 {
8658 return;
8659 }
8660
8661 FreeIni(o);
8662 }
8663
8664 // Read the custom.ini file
CiLoadIni()8665 LIST *CiLoadIni()
8666 {
8667 BUF *b = ReadDump(CLIENT_CUSTOM_INI_FILENAME);
8668 LIST *ini;
8669 if (b == NULL)
8670 {
8671 return NULL;
8672 }
8673
8674 ini = ReadIni(b);
8675
8676 FreeBuf(b);
8677
8678 return ini;
8679
8680 }
8681
8682 // Reflect the settings of the custom.ini
CiLoadIniSettings(CLIENT * c)8683 void CiLoadIniSettings(CLIENT *c)
8684 {
8685 LIST *o;
8686 //char *log;
8687 //char *config;
8688
8689 if (c == NULL)
8690 {
8691 return;
8692 }
8693
8694 o = CiLoadIni();
8695
8696 if (o == NULL)
8697 {
8698 return;
8699 }
8700
8701 /*log = IniStrValue(o, "NoSaveLog");
8702 config = IniStrValue(o, "NoSaveConfig");
8703
8704 if(StrCmpi(log, "true") == 0)
8705 {
8706 c->NoSaveLog = true;
8707 }
8708 if(StrCmpi(config, "true") == 0)
8709 {
8710 c->NoSaveConfig = true;
8711 }*/
8712
8713 c->NoSaveLog = ToBool(IniStrValue(o, "NoSaveLog"));
8714 c->NoSaveConfig = ToBool(IniStrValue(o, "NoSaveConfig"));
8715
8716 CiFreeIni(o);
8717
8718 }
8719
CiLoadConfigFilePathFromIni(char * path,UINT size)8720 bool CiLoadConfigFilePathFromIni(char *path, UINT size)
8721 {
8722 char *tmp;
8723 LIST *o;
8724 bool ret = false;
8725
8726 // Validate arguments
8727 if (path == NULL)
8728 {
8729 return false;
8730 }
8731
8732 o = CiLoadIni();
8733
8734 if (o == NULL)
8735 {
8736 return false;
8737 }
8738
8739 StrCpy(path, size, "");
8740
8741 tmp = IniStrValue(o, "ConfigPath");
8742 NormalizePath(path, size, tmp);
8743
8744 if (IsEmptyStr(path) == false)
8745 {
8746 ret = true;
8747 }
8748 else
8749 {
8750 ret = false;
8751 }
8752
8753 CiFreeIni(o);
8754
8755 return ret;
8756 }
8757
8758 // Set the client error code
CiSetError(CLIENT * c,UINT err)8759 void CiSetError(CLIENT *c, UINT err)
8760 {
8761 // Validate arguments
8762 if (c == NULL)
8763 {
8764 return;
8765 }
8766
8767 c->Err = err;
8768 }
8769
8770 // UNIX virtual LAN card comparison function
CiCompareUnixVLan(void * p1,void * p2)8771 int CiCompareUnixVLan(void *p1, void *p2)
8772 {
8773 UNIX_VLAN *v1, *v2;
8774 if (p1 == NULL || p2 == NULL)
8775 {
8776 return 0;
8777 }
8778 v1 = *(UNIX_VLAN **)p1;
8779 v2 = *(UNIX_VLAN **)p2;
8780 if (v1 == NULL || v2 == NULL)
8781 {
8782 return 0;
8783 }
8784
8785 return StrCmpi(v1->Name, v2->Name);
8786 }
8787
8788 // Modify the account settings that an incorrect VLAN name is specified
CiNormalizeAccountVLan(CLIENT * c)8789 void CiNormalizeAccountVLan(CLIENT *c)
8790 {
8791 bool b = false;
8792 char *name;
8793 UINT i;
8794 // Validate arguments
8795 if (c == NULL)
8796 {
8797 return;
8798 }
8799
8800 name = CiGetFirstVLan(c);
8801
8802 if (name != NULL)
8803 {
8804 LockList(c->AccountList);
8805 {
8806 for (i = 0;i < LIST_NUM(c->AccountList);i++)
8807 {
8808 ACCOUNT *a = LIST_DATA(c->AccountList, i);
8809
8810 Lock(a->lock);
8811 {
8812 if (a->ClientOption != NULL)
8813 {
8814 if (CiIsVLan(c, a->ClientOption->DeviceName) == false)
8815 {
8816 StrCpy(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName),
8817 name);
8818 b = true;
8819 }
8820 }
8821 }
8822 Unlock(a->lock);
8823 }
8824 }
8825 UnlockList(c->AccountList);
8826
8827 Free(name);
8828 }
8829
8830 if (b)
8831 {
8832 CiNotify(c);
8833 CiSendGlobalPulse(c);
8834 CiSaveConfigurationFile(c);
8835 }
8836 }
8837
8838 // Check whether a virtual LAN card of the specified name exists
CiIsVLan(CLIENT * c,char * name)8839 bool CiIsVLan(CLIENT *c, char *name)
8840 {
8841 // Validate arguments
8842 if (c == NULL || name == NULL)
8843 {
8844 return false;
8845 }
8846
8847 #ifdef OS_WIN32
8848 {
8849 TOKEN_LIST *t;
8850 UINT i;
8851
8852 t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, VLAN_ADAPTER_NAME_OLD);
8853 if (t == NULL)
8854 {
8855 return false;
8856 }
8857
8858 for (i = 0;i < t->NumTokens;i++)
8859 {
8860 if (StrCmpi(t->Token[i], name) == 0)
8861 {
8862 FreeToken(t);
8863 return true;
8864 }
8865 }
8866
8867 FreeToken(t);
8868
8869 return false;
8870 }
8871 #else // OS_WIN32
8872 {
8873 UNIX_VLAN *v;
8874 UINT i;
8875 bool ret = false;
8876
8877 LockList(c->UnixVLanList);
8878 {
8879 for (i = 0;i < LIST_NUM(c->UnixVLanList);i++)
8880 {
8881 v = (UNIX_VLAN *)LIST_DATA(c->UnixVLanList, i);
8882 if (StrCmpi(v->Name, name) == 0)
8883 {
8884 ret = true;
8885 }
8886 }
8887 }
8888 UnlockList(c->UnixVLanList);
8889
8890 return ret;
8891 }
8892 #endif // OS_WIN32
8893 }
8894
8895 // If a non-existent virtual LAN card is specified in any Account, and only
8896 // one virtual LAN card is installed, set the virtual LAN card to the account
CiSetVLanToDefault(CLIENT * c)8897 void CiSetVLanToDefault(CLIENT *c)
8898 {
8899 char device_name[MAX_SIZE];
8900 // Validate arguments
8901 if (c == NULL)
8902 {
8903 return;
8904 }
8905
8906 #ifdef OS_WIN32
8907 {
8908 TOKEN_LIST *t;
8909
8910 t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, VLAN_ADAPTER_NAME_OLD);
8911 if (t == NULL)
8912 {
8913 return;
8914 }
8915 if (t->NumTokens != 1)
8916 {
8917 FreeToken(t);
8918 return;
8919 }
8920 StrCpy(device_name, sizeof(device_name), t->Token[0]);
8921 FreeToken(t);
8922 }
8923 #else // OS_WIN32
8924 {
8925 UNIX_VLAN *v;
8926
8927 LockList(c->UnixVLanList);
8928
8929 if (LIST_NUM(c->UnixVLanList) != 1)
8930 {
8931 UnlockList(c->UnixVLanList);
8932 return;
8933 }
8934 v = LIST_DATA(c->UnixVLanList, 0);
8935 StrCpy(device_name, sizeof(device_name), v->Name);
8936
8937 UnlockList(c->UnixVLanList);
8938 }
8939 #endif // OS_WIN32
8940
8941 {
8942 UINT i;
8943 LockList(c->AccountList);
8944 {
8945 for (i = 0;i < LIST_NUM(c->AccountList);i++)
8946 {
8947 ACCOUNT *a = LIST_DATA(c->AccountList, i);
8948
8949 Lock(a->lock);
8950 {
8951 if (CiIsVLan(c, a->ClientOption->DeviceName) == false)
8952 {
8953 StrCpy(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName),
8954 device_name);
8955 }
8956 }
8957 Unlock(a->lock);
8958 }
8959 }
8960 UnlockList(c->AccountList);
8961 }
8962 }
8963
8964 // Initialize the settings
CiInitConfiguration(CLIENT * c)8965 void CiInitConfiguration(CLIENT *c)
8966 {
8967 // Validate arguments
8968 if (c == NULL)
8969 {
8970 return;
8971 }
8972
8973 #ifdef OS_UNIX
8974 // Initialize the VLAN
8975 UnixVLanInit();
8976 #endif // OS_UNIX
8977
8978 // Account list
8979 c->AccountList = NewList(CiCompareAccount);
8980
8981 // Unix version VLAN list
8982 if (OS_IS_UNIX(GetOsInfo()->OsType))
8983 {
8984 c->UnixVLanList = NewList(CiCompareUnixVLan);
8985 }
8986
8987 // Read the configuration file
8988 CLog(c, "LC_LOAD_CONFIG_1");
8989 if (CiLoadConfigurationFile(c) == false)
8990 {
8991 CLog(c, "LC_LOAD_CONFIG_3");
8992 // Do the initial setup because the configuration file does not exist
8993 // Clear the password
8994 Sha0(c->EncryptedPassword, "", 0);
8995 // Initialize the client configuration
8996 // Disable remote management
8997 c->Config.AllowRemoteConfig = false;
8998 StrCpy(c->Config.KeepConnectHost, sizeof(c->Config.KeepConnectHost), CLIENT_DEFAULT_KEEPALIVE_HOST);
8999 c->Config.KeepConnectPort = CLIENT_DEFAULT_KEEPALIVE_PORT;
9000 c->Config.KeepConnectProtocol = CONNECTION_UDP;
9001 c->Config.KeepConnectInterval = CLIENT_DEFAULT_KEEPALIVE_INTERVAL;
9002 c->Config.UseKeepConnect = false; // Don't use the connection maintenance function by default in the Client
9003 // Eraser
9004 c->Eraser = NewEraser(c->Logger, 0);
9005 }
9006 else
9007 {
9008 CLog(c, "LC_LOAD_CONFIG_2");
9009 }
9010
9011 // Appropriate setting for virtual LAN card
9012 CiSetVLanToDefault(c);
9013 }
9014
9015 // Release the settings
CiFreeConfiguration(CLIENT * c)9016 void CiFreeConfiguration(CLIENT *c)
9017 {
9018 UINT i;
9019 // Validate arguments
9020 if (c == NULL)
9021 {
9022 return;
9023 }
9024
9025 // Write to the configuration file
9026 CiSaveConfigurationFile(c);
9027
9028 // Release the configuration file
9029 FreeCfgRw(c->CfgRw);
9030
9031 // Release the account list
9032 for (i = 0;i < LIST_NUM(c->AccountList);i++)
9033 {
9034 ACCOUNT *a = LIST_DATA(c->AccountList, i);
9035
9036 CiFreeAccount(a);
9037 }
9038 ReleaseList(c->AccountList);
9039
9040 if (c->UnixVLanList != NULL)
9041 {
9042 // Release of UNIX version VLAN list
9043 for (i = 0;i < LIST_NUM(c->UnixVLanList);i++)
9044 {
9045 UNIX_VLAN *v = LIST_DATA(c->UnixVLanList, i);
9046 Free(v);
9047 }
9048 ReleaseList(c->UnixVLanList);
9049 }
9050 c->UnixVLanList = NULL;
9051
9052 #ifdef OS_UNIX
9053 // Release the VLAN
9054 UnixVLanFree();
9055 #endif // OS_UNIX
9056 }
9057
9058 // Release the certificate data acquisition
CiFreeGetCa(RPC_GET_CA * a)9059 void CiFreeGetCa(RPC_GET_CA *a)
9060 {
9061 // Validate arguments
9062 if (a == NULL)
9063 {
9064 return;
9065 }
9066
9067 FreeX(a->x);
9068 }
9069
9070 // Release the client authentication data
CiFreeClientAuth(CLIENT_AUTH * auth)9071 void CiFreeClientAuth(CLIENT_AUTH *auth)
9072 {
9073 // Validate arguments
9074 if (auth == NULL)
9075 {
9076 return;
9077 }
9078
9079 if (auth->ClientX != NULL)
9080 {
9081 FreeX(auth->ClientX);
9082 }
9083 if (auth->ClientK != NULL)
9084 {
9085 FreeK(auth->ClientK);
9086 }
9087
9088 Free(auth);
9089 }
9090
9091 // Release the account
CiFreeAccount(ACCOUNT * a)9092 void CiFreeAccount(ACCOUNT *a)
9093 {
9094 // Validate arguments
9095 if (a == NULL)
9096 {
9097 return;
9098 }
9099
9100 // Release the lock
9101 DeleteLock(a->lock);
9102
9103 // Release the client option
9104 Free(a->ClientOption);
9105
9106 // Release the client authentication data
9107 CiFreeClientAuth(a->ClientAuth);
9108
9109 if (a->ServerCert != NULL)
9110 {
9111 FreeX(a->ServerCert);
9112 }
9113
9114 Free(a);
9115 }
9116
9117 // Sort accounts
CiCompareAccount(void * p1,void * p2)9118 int CiCompareAccount(void *p1, void *p2)
9119 {
9120 ACCOUNT *a1, *a2;
9121 if (p1 == NULL || p2 == NULL)
9122 {
9123 return 0;
9124 }
9125 a1 = *(ACCOUNT **)p1;
9126 a2 = *(ACCOUNT **)p2;
9127 if (a1 == NULL || a2 == NULL)
9128 {
9129 return 0;
9130 }
9131
9132 return UniStrCmpi(a1->ClientOption->AccountName, a2->ClientOption->AccountName);
9133 }
9134
9135 // Read the client configuration
CiLoadClientConfig(CLIENT_CONFIG * c,FOLDER * f)9136 void CiLoadClientConfig(CLIENT_CONFIG *c, FOLDER *f)
9137 {
9138 // Validate arguments
9139 if (c == NULL || f == NULL)
9140 {
9141 return;
9142 }
9143
9144 c->UseKeepConnect = CfgGetBool(f, "UseKeepConnect");
9145 CfgGetStr(f, "KeepConnectHost", c->KeepConnectHost, sizeof(c->KeepConnectHost));
9146 c->KeepConnectPort = CfgGetInt(f, "KeepConnectPort");
9147 c->KeepConnectProtocol = CfgGetInt(f, "KeepConnectProtocol");
9148 c->AllowRemoteConfig = CfgGetBool(f, "AllowRemoteConfig");
9149 c->KeepConnectInterval = MAKESURE(CfgGetInt(f, "KeepConnectInterval"), KEEP_INTERVAL_MIN, KEEP_INTERVAL_MAX);
9150 c->NoChangeWcmNetworkSettingOnWindows8 = CfgGetBool(f, "NoChangeWcmNetworkSettingOnWindows8");
9151 }
9152
9153 // Read the client authentication data
CiLoadClientAuth(FOLDER * f)9154 CLIENT_AUTH *CiLoadClientAuth(FOLDER *f)
9155 {
9156 CLIENT_AUTH *a;
9157 char *s;
9158 BUF *b;
9159 // Validate arguments
9160 if (f == NULL)
9161 {
9162 return NULL;
9163 }
9164
9165 a = ZeroMalloc(sizeof(CLIENT_AUTH));
9166
9167 a->AuthType = CfgGetInt(f, "AuthType");
9168 CfgGetStr(f, "Username", a->Username, sizeof(a->Username));
9169
9170 switch (a->AuthType)
9171 {
9172 case CLIENT_AUTHTYPE_ANONYMOUS:
9173 break;
9174
9175 case CLIENT_AUTHTYPE_PASSWORD:
9176 CfgGetByte(f, "HashedPassword", a->HashedPassword, SHA1_SIZE);
9177 break;
9178
9179 case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
9180 b = CfgGetBuf(f, "EncryptedPassword");
9181 if (b != NULL)
9182 {
9183 s = DecryptPassword(b);
9184 StrCpy(a->PlainPassword, sizeof(a->PlainPassword), s);
9185 Free(s);
9186 FreeBuf(b);
9187 }
9188 break;
9189
9190 case CLIENT_AUTHTYPE_CERT:
9191 b = CfgGetBuf(f, "ClientCert");
9192 if (b != NULL)
9193 {
9194 a->ClientX = BufToX(b, false);
9195 }
9196 FreeBuf(b);
9197 b = CfgGetBuf(f, "ClientKey");
9198 if (b != NULL)
9199 {
9200 a->ClientK = BufToK(b, true, false, NULL);
9201 }
9202 FreeBuf(b);
9203 break;
9204
9205 case CLIENT_AUTHTYPE_SECURE:
9206 CfgGetStr(f, "SecurePublicCertName", a->SecurePublicCertName, sizeof(a->SecurePublicCertName));
9207 CfgGetStr(f, "SecurePrivateKeyName", a->SecurePrivateKeyName, sizeof(a->SecurePrivateKeyName));
9208 break;
9209
9210 case CLIENT_AUTHTYPE_OPENSSLENGINE:
9211 b = CfgGetBuf(f, "ClientCert");
9212 if (b != NULL)
9213 {
9214 a->ClientX = BufToX(b, false);
9215 }
9216 FreeBuf(b);
9217 if (CfgGetStr(f, "OpensslEnginePrivateKeyName", a->OpensslEnginePrivateKeyName, sizeof(a->OpensslEnginePrivateKeyName)))
9218 {
9219 a->ClientK = OpensslEngineToK(a->OpensslEnginePrivateKeyName, a->OpensslEngineName);
9220 }
9221 CfgGetStr(f, "OpensslEngineName", a->OpensslEngineName, sizeof(a->OpensslEngineName));
9222 break;
9223 }
9224
9225 return a;
9226 }
9227
9228 // Read the client option
CiLoadClientOption(FOLDER * f)9229 CLIENT_OPTION *CiLoadClientOption(FOLDER *f)
9230 {
9231 CLIENT_OPTION *o;
9232 char *s;
9233 BUF *b;
9234 // Validate arguments
9235 if (f == NULL)
9236 {
9237 return NULL;
9238 }
9239
9240 o = ZeroMalloc(sizeof(CLIENT_OPTION));
9241
9242 CfgGetUniStr(f, "AccountName", o->AccountName, sizeof(o->AccountName));
9243 CfgGetStr(f, "Hostname", o->Hostname, sizeof(o->Hostname));
9244 o->Port = CfgGetInt(f, "Port");
9245 o->PortUDP = CfgGetInt(f, "PortUDP");
9246 o->ProxyType = CfgGetInt(f, "ProxyType");
9247 CfgGetStr(f, "ProxyName", o->ProxyName, sizeof(o->ProxyName));
9248 o->ProxyPort = CfgGetInt(f, "ProxyPort");
9249 CfgGetStr(f, "ProxyUsername", o->ProxyUsername, sizeof(o->ProxyUsername));
9250 b = CfgGetBuf(f, "ProxyPassword");
9251 s = DecryptPassword(b);
9252 StrCpy(o->ProxyPassword, sizeof(o->ProxyPassword), s);
9253 Free(s);
9254 FreeBuf(b);
9255 CfgGetStr(f, "CustomHttpHeader", o->CustomHttpHeader, sizeof(o->CustomHttpHeader));
9256 o->NumRetry = CfgGetInt(f, "NumRetry");
9257 o->RetryInterval = CfgGetInt(f, "RetryInterval");
9258 CfgGetStr(f, "HubName", o->HubName, sizeof(o->HubName));
9259 o->MaxConnection = CfgGetInt(f, "MaxConnection");
9260 o->UseEncrypt = CfgGetBool(f, "UseEncrypt");
9261 o->UseCompress = CfgGetBool(f, "UseCompress");
9262 o->HalfConnection = CfgGetBool(f, "HalfConnection");
9263 o->NoRoutingTracking = CfgGetBool(f, "NoRoutingTracking");
9264 CfgGetStr(f, "DeviceName", o->DeviceName, sizeof(o->DeviceName));
9265 o->AdditionalConnectionInterval = CfgGetInt(f, "AdditionalConnectionInterval");
9266 o->HideStatusWindow = CfgGetBool(f, "HideStatusWindow");
9267 o->HideNicInfoWindow = CfgGetBool(f, "HideNicInfoWindow");
9268 o->ConnectionDisconnectSpan = CfgGetInt(f, "ConnectionDisconnectSpan");
9269 o->RequireMonitorMode = CfgGetBool(f, "RequireMonitorMode");
9270 o->RequireBridgeRoutingMode = CfgGetBool(f, "RequireBridgeRoutingMode");
9271 o->DisableQoS = CfgGetBool(f, "DisableQoS");
9272 o->FromAdminPack = CfgGetBool(f, "FromAdminPack");
9273 o->NoUdpAcceleration = CfgGetBool(f, "NoUdpAcceleration");
9274
9275 b = CfgGetBuf(f, "HostUniqueKey");
9276 if (b != NULL)
9277 {
9278 if (b->Size == SHA1_SIZE)
9279 {
9280 Copy(o->HostUniqueKey, b->Buf, SHA1_SIZE);
9281 }
9282
9283 FreeBuf(b);
9284 }
9285
9286 return o;
9287 }
9288
9289 // Read the account data
CiLoadClientAccount(FOLDER * f)9290 ACCOUNT *CiLoadClientAccount(FOLDER *f)
9291 {
9292 ACCOUNT *a;
9293 FOLDER *client_option_folder, *client_auth_folder;
9294 BUF *b;
9295 char tmp[64];
9296 // Validate arguments
9297 if (f == NULL)
9298 {
9299 return NULL;
9300 }
9301
9302 client_option_folder = CfgGetFolder(f, "ClientOption");
9303
9304 if (client_option_folder != NULL)
9305 {
9306 // Compare whether it matches to the account name that is already registered
9307 }
9308
9309 client_auth_folder = CfgGetFolder(f, "ClientAuth");
9310
9311 if (client_option_folder == NULL || client_auth_folder == NULL)
9312 {
9313 return NULL;
9314 }
9315
9316 a = ZeroMalloc(sizeof(ACCOUNT));
9317 a->lock = NewLock();
9318
9319 a->ClientOption = CiLoadClientOption(client_option_folder);
9320 a->ClientAuth = CiLoadClientAuth(client_auth_folder);
9321
9322 a->StartupAccount = CfgGetBool(f, "StartupAccount");
9323 a->CheckServerCert = CfgGetBool(f, "CheckServerCert");
9324 a->RetryOnServerCert = CfgGetBool(f, "RetryOnServerCert");
9325 a->CreateDateTime = CfgGetInt64(f, "CreateDateTime");
9326 a->UpdateDateTime = CfgGetInt64(f, "UpdateDateTime");
9327 a->LastConnectDateTime = CfgGetInt64(f, "LastConnectDateTime");
9328
9329 b = CfgGetBuf(f, "ServerCert");
9330 if (b != NULL)
9331 {
9332 a->ServerCert = BufToX(b, false);
9333 FreeBuf(b);
9334 }
9335
9336 if (CfgGetStr(f, "ShortcutKey", tmp, sizeof(tmp)))
9337 {
9338 BUF *b = StrToBin(tmp);
9339 if (b->Size == SHA1_SIZE)
9340 {
9341 Copy(a->ShortcutKey, b->Buf, SHA1_SIZE);
9342 }
9343 FreeBuf(b);
9344 }
9345
9346 if (IsZero(a->ShortcutKey, SHA1_SIZE))
9347 {
9348 Rand(a->ShortcutKey, SHA1_SIZE);
9349 }
9350
9351 return a;
9352 }
9353
9354 // Read the account database
CiLoadAccountDatabase(CLIENT * c,FOLDER * f)9355 void CiLoadAccountDatabase(CLIENT *c, FOLDER *f)
9356 {
9357 TOKEN_LIST *t;
9358 UINT i;
9359 // Validate arguments
9360 if (c == NULL || f == NULL)
9361 {
9362 return;
9363 }
9364
9365 t = CfgEnumFolderToTokenList(f);
9366 if (t == NULL)
9367 {
9368 return;
9369 }
9370
9371 for (i = 0;i < t->NumTokens;i++)
9372 {
9373 FOLDER *ff = CfgGetFolder(f, t->Token[i]);
9374
9375 if (ff != NULL)
9376 {
9377 ACCOUNT *a = CiLoadClientAccount(ff);
9378 if (a != NULL)
9379 {
9380 {
9381 Add(c->AccountList, a);
9382 }
9383 }
9384 }
9385 }
9386
9387 Sort(c->AccountList);
9388
9389 FreeToken(t);
9390 }
9391
9392 // Read the root CA certificate
CiLoadCACert(CLIENT * c,FOLDER * f)9393 void CiLoadCACert(CLIENT *c, FOLDER *f)
9394 {
9395 BUF *b;
9396 X *x;
9397 // Validate arguments
9398 if (c == NULL || f == NULL)
9399 {
9400 return;
9401 }
9402
9403 b = CfgGetBuf(f, "X509");
9404 if (b == NULL)
9405 {
9406 return;
9407 }
9408
9409 x = BufToX(b, false);
9410
9411 AddCa(c->Cedar, x);
9412
9413 FreeX(x);
9414
9415 FreeBuf(b);
9416 }
9417
9418 // Read the root CA list
CiLoadCAList(CLIENT * c,FOLDER * f)9419 void CiLoadCAList(CLIENT *c, FOLDER *f)
9420 {
9421 CEDAR *cedar;
9422 TOKEN_LIST *t;
9423 // Validate arguments
9424 if (c == NULL || f == NULL)
9425 {
9426 return;
9427 }
9428
9429 t = CfgEnumFolderToTokenList(f);
9430
9431 cedar = c->Cedar;
9432
9433 LockList(cedar->CaList);
9434 {
9435 UINT i;
9436 for (i = 0;i < t->NumTokens;i++)
9437 {
9438 FOLDER *folder = CfgGetFolder(f, t->Token[i]);
9439 CiLoadCACert(c, folder);
9440 }
9441 }
9442 UnlockList(cedar->CaList);
9443
9444 FreeToken(t);
9445 }
9446
9447 // Read a VLAN
CiLoadVLan(CLIENT * c,FOLDER * f)9448 void CiLoadVLan(CLIENT *c, FOLDER *f)
9449 {
9450 char tmp[MAX_SIZE];
9451 UCHAR addr[6];
9452 BUF *b;
9453 UNIX_VLAN *v;
9454 // Validate arguments
9455 if (c == NULL || f == NULL)
9456 {
9457 return;
9458 }
9459
9460 if (CfgGetStr(f, "MacAddress", tmp, sizeof(tmp)) == false)
9461 {
9462 return;
9463 }
9464
9465 b = StrToBin(tmp);
9466 if (b == NULL)
9467 {
9468 return;
9469 }
9470
9471 if (b->Size != 6)
9472 {
9473 FreeBuf(b);
9474 return;
9475 }
9476
9477 Copy(addr, b->Buf, 6);
9478
9479 FreeBuf(b);
9480
9481 if (IsZero(addr, 6))
9482 {
9483 return;
9484 }
9485
9486 v = ZeroMalloc(sizeof(UNIX_VLAN));
9487 Copy(v->MacAddress, addr, 6);
9488 StrCpy(v->Name, sizeof(v->Name), f->Name);
9489 v->Enabled = CfgGetBool(f, "Enabled");
9490
9491 Add(c->UnixVLanList, v);
9492
9493 #ifdef OS_UNIX
9494 UnixVLanCreate(v->Name, v->MacAddress, false);
9495 #endif // OS_UNIX
9496 }
9497
9498 // Read a VLAN list
CiLoadVLanList(CLIENT * c,FOLDER * f)9499 void CiLoadVLanList(CLIENT *c, FOLDER *f)
9500 {
9501 TOKEN_LIST *t;
9502 // Validate arguments
9503 if (c == NULL || f == NULL)
9504 {
9505 return;
9506 }
9507
9508 t = CfgEnumFolderToTokenList(f);
9509
9510 LockList(c->UnixVLanList);
9511 {
9512 UINT i;
9513 for (i = 0;i < t->NumTokens;i++)
9514 {
9515 FOLDER *folder = CfgGetFolder(f, t->Token[i]);
9516 CiLoadVLan(c, folder);
9517 }
9518 }
9519 UnlockList(c->UnixVLanList);
9520
9521 FreeToken(t);
9522 }
9523
9524 // Read the configuration from the configuration file
CiReadSettingFromCfg(CLIENT * c,FOLDER * root)9525 bool CiReadSettingFromCfg(CLIENT *c, FOLDER *root)
9526 {
9527 FOLDER *config;
9528 FOLDER *cert;
9529 FOLDER *db;
9530 FOLDER *vlan;
9531 FOLDER *cmsetting;
9532 FOLDER *proxy;
9533 char user_agent[MAX_SIZE];
9534 // Validate arguments
9535 if (c == NULL || root == NULL)
9536 {
9537 return false;
9538 }
9539
9540 // Initialize the setting if there isn't either of AccountDatabase and Config
9541 config = CfgGetFolder(root, "Config");
9542 if (config == NULL)
9543 {
9544 return false;
9545 }
9546
9547 db = CfgGetFolder(root, "AccountDatabase");
9548 if (db == NULL)
9549 {
9550 return false;
9551 }
9552
9553 cmsetting = CfgGetFolder(root, "ClientManagerSetting");
9554
9555 CiLoadClientConfig(&c->Config, config);
9556
9557
9558 proxy = CfgGetFolder(root, "CommonProxySetting");
9559
9560 if (proxy != NULL)
9561 {
9562 INTERNET_SETTING t;
9563 BUF *pw;
9564
9565 // Proxy Setting
9566 Zero(&t, sizeof(t));
9567 t.ProxyType = CfgGetInt(proxy, "ProxyType");
9568 CfgGetStr(proxy, "ProxyHostName", t.ProxyHostName, sizeof(t.ProxyHostName));
9569 t.ProxyPort = CfgGetInt(proxy, "ProxyPort");
9570 CfgGetStr(proxy, "ProxyUsername", t.ProxyUsername, sizeof(t.ProxyUsername));
9571 pw = CfgGetBuf(proxy, "ProxyPassword");
9572 if (pw != NULL)
9573 {
9574 char *pw_str = DecryptPassword(pw);
9575 StrCpy(t.ProxyPassword, sizeof(t.ProxyPassword), pw_str);
9576
9577 Free(pw_str);
9578 FreeBuf(pw);
9579 }
9580
9581 CfgGetStr(proxy, "CustomHttpHeader", t.CustomHttpHeader, sizeof(t.CustomHttpHeader));
9582
9583 Copy(&c->CommonProxySetting, &t, sizeof(INTERNET_SETTING));
9584 }
9585
9586 // Eraser
9587 c->Eraser = NewEraser(c->Logger, CfgGetInt64(config, "AutoDeleteCheckDiskFreeSpaceMin"));
9588
9589 if (OS_IS_UNIX(GetOsInfo()->OsType)
9590 #ifdef NO_VLAN
9591 && GetOsInfo()->OsType != OSTYPE_MACOS_X
9592 #endif // NO_VLAN
9593 )
9594 {
9595 // Read the UNIX version virtual LAN card list (except MacOS)
9596 vlan = CfgGetFolder(root, "UnixVLan");
9597 if (vlan != NULL)
9598 {
9599 CiLoadVLanList(c, vlan);
9600 }
9601 }
9602
9603 #ifdef NO_VLAN
9604 if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
9605 {
9606 #ifdef OS_UNIX
9607 UNIX_VLAN *uv;
9608
9609 // Create a Tap for MacOS X
9610 if (UnixVLanCreate(CLIENT_MACOS_TAP_NAME, NULL, false) == false)
9611 {
9612 // Fail (abort)
9613 CLog(c, "LC_TAP_NOT_FOUND");
9614 Alert("tun/tap driver not found.", NULL);
9615 exit(0);
9616 }
9617
9618 uv = ZeroMalloc(sizeof(UNIX_VLAN));
9619 uv->Enabled = true;
9620 StrCpy(uv->Name, sizeof(uv->Name), CLIENT_MACOS_TAP_NAME);
9621 Add(c->UnixVLanList, uv);
9622 #endif // OS_UNIX
9623 }
9624 #endif // NO_VLAN
9625 CiLoadAccountDatabase(c, db);
9626
9627 if (CfgGetByte(root, "EncryptedPassword", c->EncryptedPassword, SHA1_SIZE) == false)
9628 {
9629 Sha0(c->EncryptedPassword, "", 0);
9630 }
9631
9632 c->PasswordRemoteOnly = CfgGetBool(root, "PasswordRemoteOnly");
9633 c->UseSecureDeviceId = CfgGetInt(root, "UseSecureDeviceId");
9634
9635 if (CfgGetStr(root, "UserAgent", user_agent, sizeof(user_agent)))
9636 {
9637 if (IsEmptyStr(user_agent) == false)
9638 {
9639 Free(c->Cedar->HttpUserAgent);
9640 c->Cedar->HttpUserAgent = CopyStr(user_agent);
9641 }
9642 }
9643
9644 cert = CfgGetFolder(root, "RootCA");
9645 if (cert != NULL)
9646 {
9647 CiLoadCAList(c, cert);
9648 }
9649
9650 c->DontSavePassword = CfgGetBool(root, "DontSavePassword");
9651
9652 if (cmsetting != NULL)
9653 {
9654 UINT ostype = GetOsInfo()->OsType;
9655 // CM_SETTING
9656 CM_SETTING *s = c->CmSetting;
9657 s->EasyMode = CfgGetBool(cmsetting, "EasyMode");
9658 s->LockMode = CfgGetBool(cmsetting, "LockMode");
9659 CfgGetByte(cmsetting, "HashedPassword", s->HashedPassword, sizeof(s->HashedPassword));
9660 }
9661
9662 return true;
9663 }
9664
9665 // Read the configuration file
CiLoadConfigurationFile(CLIENT * c)9666 bool CiLoadConfigurationFile(CLIENT *c)
9667 {
9668 bool ret;
9669 FOLDER *root;
9670 char path[MAX_SIZE];
9671 // Validate arguments
9672 if (c == NULL)
9673 {
9674 return false;
9675 }
9676
9677 // Read the configuration file
9678 if (CiLoadConfigFilePathFromIni(path, sizeof(path)))
9679 {
9680 c->CfgRw = NewCfgRw(&root, path);
9681 }
9682 else
9683 {
9684 c->CfgRw = NewCfgRw(&root, CLIENT_CONFIG_FILE_NAME);
9685 }
9686
9687 if (root == NULL)
9688 {
9689 return false;
9690 }
9691
9692 ret = CiReadSettingFromCfg(c, root);
9693
9694 CfgDeleteFolder(root);
9695
9696 return ret;
9697 }
9698
9699 // Write the CLIENT_CONFIG
CiWriteClientConfig(FOLDER * cc,CLIENT_CONFIG * config)9700 void CiWriteClientConfig(FOLDER *cc, CLIENT_CONFIG *config)
9701 {
9702 // Validate arguments
9703 if (cc == NULL || config == NULL)
9704 {
9705 return;
9706 }
9707
9708 CfgAddBool(cc, "UseKeepConnect", config->UseKeepConnect);
9709 CfgAddStr(cc, "KeepConnectHost", config->KeepConnectHost);
9710 CfgAddInt(cc, "KeepConnectPort", config->KeepConnectPort);
9711 CfgAddInt(cc, "KeepConnectProtocol", config->KeepConnectProtocol);
9712 CfgAddBool(cc, "AllowRemoteConfig", config->AllowRemoteConfig);
9713 CfgAddInt(cc, "KeepConnectInterval", config->KeepConnectInterval);
9714 CfgAddBool(cc, "NoChangeWcmNetworkSettingOnWindows8", config->NoChangeWcmNetworkSettingOnWindows8);
9715 }
9716
9717 // Write the client authentication data
CiWriteClientAuth(FOLDER * f,CLIENT_AUTH * a)9718 void CiWriteClientAuth(FOLDER *f, CLIENT_AUTH *a)
9719 {
9720 BUF *b;
9721 // Validate arguments
9722 if (f == NULL || a == NULL)
9723 {
9724 return;
9725 }
9726
9727 CfgAddInt(f, "AuthType", a->AuthType);
9728 CfgAddStr(f, "Username", a->Username);
9729
9730 switch (a->AuthType)
9731 {
9732 case CLIENT_AUTHTYPE_ANONYMOUS:
9733 break;
9734
9735 case CLIENT_AUTHTYPE_PASSWORD:
9736 CfgAddByte(f, "HashedPassword", a->HashedPassword, SHA1_SIZE);
9737 break;
9738
9739 case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
9740 b = EncryptPassword(a->PlainPassword);
9741 CfgAddByte(f, "EncryptedPassword", b->Buf, b->Size);
9742 FreeBuf(b);
9743 break;
9744
9745 case CLIENT_AUTHTYPE_CERT:
9746 if (a->ClientK != NULL && a->ClientX != NULL)
9747 {
9748 b = XToBuf(a->ClientX, false);
9749 CfgAddByte(f, "ClientCert", b->Buf, b->Size);
9750 FreeBuf(b);
9751
9752 b = KToBuf(a->ClientK, false, NULL);
9753 CfgAddByte(f, "ClientKey", b->Buf, b->Size);
9754 FreeBuf(b);
9755 }
9756 break;
9757
9758 case CLIENT_AUTHTYPE_SECURE:
9759 CfgAddStr(f, "SecurePublicCertName", a->SecurePublicCertName);
9760 CfgAddStr(f, "SecurePrivateKeyName", a->SecurePrivateKeyName);
9761 break;
9762
9763 case CLIENT_AUTHTYPE_OPENSSLENGINE:
9764 if (a->ClientX != NULL) {
9765 b = XToBuf(a->ClientX, false);
9766 CfgAddByte(f, "ClientCert", b->Buf, b->Size);
9767 FreeBuf(b);
9768 }
9769 CfgAddStr(f, "OpensslEnginePrivateKeyName", a->OpensslEnginePrivateKeyName);
9770 CfgAddStr(f, "OpensslEngineName", a->OpensslEngineName);
9771 break;
9772 }
9773 }
9774
9775 // Write the client option
CiWriteClientOption(FOLDER * f,CLIENT_OPTION * o)9776 void CiWriteClientOption(FOLDER *f, CLIENT_OPTION *o)
9777 {
9778 BUF *b;
9779 // Validate arguments
9780 if (f == NULL || o == NULL)
9781 {
9782 return;
9783 }
9784
9785 CfgAddUniStr(f, "AccountName", o->AccountName);
9786 CfgAddStr(f, "Hostname", o->Hostname);
9787 CfgAddInt(f, "Port", o->Port);
9788 CfgAddInt(f, "PortUDP", o->PortUDP);
9789 CfgAddInt(f, "ProxyType", o->ProxyType);
9790 CfgAddStr(f, "ProxyName", o->ProxyName);
9791 CfgAddInt(f, "ProxyPort", o->ProxyPort);
9792 CfgAddStr(f, "ProxyUsername", o->ProxyUsername);
9793 b = EncryptPassword(o->ProxyPassword);
9794 CfgAddByte(f, "ProxyPassword", b->Buf, b->Size);
9795 FreeBuf(b);
9796 CfgAddStr(f, "CustomHttpHeader", o->CustomHttpHeader);
9797 CfgAddInt(f, "NumRetry", o->NumRetry);
9798 CfgAddInt(f, "RetryInterval", o->RetryInterval);
9799 CfgAddStr(f, "HubName", o->HubName);
9800 CfgAddInt(f, "MaxConnection", o->MaxConnection);
9801 CfgAddBool(f, "UseEncrypt", o->UseEncrypt);
9802 CfgAddBool(f, "UseCompress", o->UseCompress);
9803 CfgAddBool(f, "HalfConnection", o->HalfConnection);
9804 CfgAddBool(f, "NoRoutingTracking", o->NoRoutingTracking);
9805 CfgAddStr(f, "DeviceName", o->DeviceName);
9806 CfgAddInt(f, "AdditionalConnectionInterval", o->AdditionalConnectionInterval);
9807 CfgAddBool(f, "HideStatusWindow", o->HideStatusWindow);
9808 CfgAddBool(f, "HideNicInfoWindow", o->HideNicInfoWindow);
9809 CfgAddInt(f, "ConnectionDisconnectSpan", o->ConnectionDisconnectSpan);
9810 CfgAddBool(f, "RequireMonitorMode", o->RequireMonitorMode);
9811 CfgAddBool(f, "RequireBridgeRoutingMode", o->RequireBridgeRoutingMode);
9812 CfgAddBool(f, "DisableQoS", o->DisableQoS);
9813 CfgAddBool(f, "NoUdpAcceleration", o->NoUdpAcceleration);
9814
9815 if (o->FromAdminPack)
9816 {
9817 CfgAddBool(f, "FromAdminPack", o->FromAdminPack);
9818 }
9819
9820 if (IsZero(o->HostUniqueKey, SHA1_SIZE) == false)
9821 {
9822 BUF *b = MemToBuf(o->HostUniqueKey, SHA1_SIZE);
9823 CfgAddBuf(f, "HostUniqueKey", b);
9824 FreeBuf(b);
9825 }
9826 }
9827
9828 // Decrypt the password
DecryptPassword(BUF * b)9829 char *DecryptPassword(BUF *b)
9830 {
9831 char *str;
9832 char *key = "EncryptPassword";
9833 CRYPT *c;
9834 // Validate arguments
9835 if (b == NULL)
9836 {
9837 return CopyStr("");
9838 }
9839
9840 str = ZeroMalloc(b->Size + 1);
9841 c = NewCrypt(key, sizeof(key)); // NOTE by Daiyuu Nobori 2018-09-28: This is not a bug! Do not try to fix it!!
9842 Encrypt(c, str, b->Buf, b->Size);
9843 FreeCrypt(c);
9844
9845 str[b->Size] = 0;
9846
9847 return str;
9848 }
DecryptPassword2(BUF * b)9849 char *DecryptPassword2(BUF *b)
9850 {
9851 char *str;
9852 char *key = "EncryptPassword2";
9853 CRYPT *c;
9854 // Validate arguments
9855 if (b == NULL)
9856 {
9857 return CopyStr("");
9858 }
9859
9860 str = ZeroMalloc(b->Size + 1);
9861 c = NewCrypt(key, StrLen(key));
9862 Encrypt(c, str, b->Buf, b->Size);
9863 FreeCrypt(c);
9864
9865 str[b->Size] = 0;
9866
9867 return str;
9868 }
9869
9870 // Encrypt the password
EncryptPassword(char * password)9871 BUF *EncryptPassword(char *password)
9872 {
9873 UCHAR *tmp;
9874 UINT size;
9875 char *key = "EncryptPassword";
9876 CRYPT *c;
9877 BUF *b;
9878 // Validate arguments
9879 if (password == NULL)
9880 {
9881 password = "";
9882 }
9883
9884 size = StrLen(password) + 1;
9885 tmp = ZeroMalloc(size);
9886
9887 c = NewCrypt(key, sizeof(key)); // NOTE by Daiyuu Nobori 2018-09-28: This is not a bug! Do not try to fix it!!
9888 Encrypt(c, tmp, password, size - 1);
9889 FreeCrypt(c);
9890
9891 b = NewBuf();
9892 WriteBuf(b, tmp, size - 1);
9893 SeekBuf(b, 0, 0);
9894 Free(tmp);
9895
9896 return b;
9897 }
EncryptPassword2(char * password)9898 BUF *EncryptPassword2(char *password)
9899 {
9900 UCHAR *tmp;
9901 UINT size;
9902 char *key = "EncryptPassword2";
9903 CRYPT *c;
9904 BUF *b;
9905 // Validate arguments
9906 if (password == NULL)
9907 {
9908 password = "";
9909 }
9910
9911 size = StrLen(password) + 1;
9912 tmp = ZeroMalloc(size);
9913
9914 c = NewCrypt(key, StrLen(key));
9915 Encrypt(c, tmp, password, size - 1);
9916 FreeCrypt(c);
9917
9918 b = NewBuf();
9919 WriteBuf(b, tmp, size - 1);
9920 SeekBuf(b, 0, 0);
9921 Free(tmp);
9922
9923 return b;
9924 }
9925
9926 // Write the account data
CiWriteAccountData(FOLDER * f,ACCOUNT * a)9927 void CiWriteAccountData(FOLDER *f, ACCOUNT *a)
9928 {
9929 // Validate arguments
9930 if (f == NULL || a == NULL)
9931 {
9932 return;
9933 }
9934
9935 // Client Option
9936 CiWriteClientOption(CfgCreateFolder(f, "ClientOption"), a->ClientOption);
9937
9938 // Client authentication data
9939 CiWriteClientAuth(CfgCreateFolder(f, "ClientAuth"), a->ClientAuth);
9940
9941 // Startup account
9942 CfgAddBool(f, "StartupAccount", a->StartupAccount);
9943
9944 // Server certificate check flag
9945 CfgAddBool(f, "CheckServerCert", a->CheckServerCert);
9946
9947 // Retry on invalid server certificate flag
9948 CfgAddBool(f, "RetryOnServerCert", a->RetryOnServerCert);
9949
9950 // Date and time
9951 CfgAddInt64(f, "CreateDateTime", a->CreateDateTime);
9952 CfgAddInt64(f, "UpdateDateTime", a->UpdateDateTime);
9953 CfgAddInt64(f, "LastConnectDateTime", a->LastConnectDateTime);
9954
9955 // Server certificate body
9956 if (a->ServerCert != NULL)
9957 {
9958 BUF *b = XToBuf(a->ServerCert, false);
9959 if (b != NULL)
9960 {
9961 CfgAddBuf(f, "ServerCert", b);
9962 FreeBuf(b);
9963 }
9964 }
9965
9966 // Shortcut Key
9967 if (IsZero(a->ShortcutKey, SHA1_SIZE) == false)
9968 {
9969 char tmp[64];
9970 BinToStr(tmp, sizeof(tmp), a->ShortcutKey, SHA1_SIZE);
9971 CfgAddStr(f, "ShortcutKey", tmp);
9972 }
9973 }
9974
9975 // Write the account database
CiWriteAccountDatabase(CLIENT * c,FOLDER * f)9976 void CiWriteAccountDatabase(CLIENT *c, FOLDER *f)
9977 {
9978 char name[MAX_SIZE];
9979 // Validate arguments
9980 if (c == NULL || f == NULL)
9981 {
9982 return;
9983 }
9984
9985 LockList(c->AccountList);
9986 {
9987 UINT i;
9988 for (i = 0;i < LIST_NUM(c->AccountList);i++)
9989 {
9990 ACCOUNT *a = LIST_DATA(c->AccountList, i);
9991
9992 {
9993 Format(name, sizeof(name), "Account%u", i);
9994 Lock(a->lock);
9995 {
9996 CiWriteAccountData(CfgCreateFolder(f, name), a);
9997 }
9998 Unlock(a->lock);
9999 }
10000 }
10001 }
10002 UnlockList(c->AccountList);
10003 }
10004
10005 // Write the CA certificate
CiWriteCACert(CLIENT * c,FOLDER * f,X * x)10006 void CiWriteCACert(CLIENT *c, FOLDER *f, X *x)
10007 {
10008 BUF *b;
10009 // Validate arguments
10010 if (c == NULL || f == NULL || x == NULL)
10011 {
10012 return;
10013 }
10014
10015 b = XToBuf(x, false);
10016 CfgAddBuf(f, "X509", b);
10017 FreeBuf(b);
10018 }
10019
10020 // Write a VLAN
CiWriteVLan(CLIENT * c,FOLDER * f,UNIX_VLAN * v)10021 void CiWriteVLan(CLIENT *c, FOLDER *f, UNIX_VLAN *v)
10022 {
10023 char tmp[MAX_SIZE];
10024 // Validate arguments
10025 if (c == NULL || f == NULL || v == NULL)
10026 {
10027 return;
10028 }
10029
10030 MacToStr(tmp, sizeof(tmp), v->MacAddress);
10031 CfgAddStr(f, "MacAddress", tmp);
10032 CfgAddBool(f, "Enabled", v->Enabled);
10033 }
10034
10035 // Write a VLAN list
CiWriteVLanList(CLIENT * c,FOLDER * f)10036 void CiWriteVLanList(CLIENT *c, FOLDER *f)
10037 {
10038 // Validate arguments
10039 if (c == NULL || f == NULL)
10040 {
10041 return;
10042 }
10043
10044 LockList(c->UnixVLanList);
10045 {
10046 UINT i;
10047 for (i = 0;i < LIST_NUM(c->UnixVLanList);i++)
10048 {
10049 UNIX_VLAN *v = LIST_DATA(c->UnixVLanList, i);
10050 CiWriteVLan(c, CfgCreateFolder(f, v->Name), v);
10051 }
10052 }
10053 UnlockList(c->UnixVLanList);
10054 }
10055
10056 // Write the CA list
CiWriteCAList(CLIENT * c,FOLDER * f)10057 void CiWriteCAList(CLIENT *c, FOLDER *f)
10058 {
10059 CEDAR *cedar;
10060 // Validate arguments
10061 if (c == NULL || f == NULL)
10062 {
10063 return;
10064 }
10065
10066 cedar = c->Cedar;
10067
10068 LockList(cedar->CaList);
10069 {
10070 UINT i;
10071 for (i = 0;i < LIST_NUM(cedar->CaList);i++)
10072 {
10073 char tmp[MAX_SIZE];
10074 X *x = LIST_DATA(cedar->CaList, i);
10075 Format(tmp, sizeof(tmp), "Certificate%u", i);
10076 CiWriteCACert(c, CfgCreateFolder(f, tmp), x);
10077 }
10078 }
10079 UnlockList(cedar->CaList);
10080 }
10081
10082 // Write the current settings to ROOT
CiWriteSettingToCfg(CLIENT * c,FOLDER * root)10083 void CiWriteSettingToCfg(CLIENT *c, FOLDER *root)
10084 {
10085 FOLDER *cc;
10086 FOLDER *account_database;
10087 FOLDER *ca;
10088 FOLDER *vlan;
10089 FOLDER *cmsetting;
10090 FOLDER *proxy;
10091 // Validate arguments
10092 if (c == NULL || root == NULL)
10093 {
10094 return;
10095 }
10096
10097 cmsetting = CfgCreateFolder(root, "ClientManagerSetting");
10098
10099 // CLIENT_CONFIG
10100 cc = CfgCreateFolder(root, "Config");
10101 CiWriteClientConfig(cc, &c->Config);
10102
10103
10104 // Eraser
10105 CfgAddInt64(cc, "AutoDeleteCheckDiskFreeSpaceMin", c->Eraser->MinFreeSpace);
10106
10107 // Account Database
10108 account_database = CfgCreateFolder(root, "AccountDatabase");
10109 CiWriteAccountDatabase(c, account_database);
10110
10111 // Proxy
10112 proxy = CfgCreateFolder(root, "CommonProxySetting");
10113 if (proxy != NULL)
10114 {
10115 INTERNET_SETTING *t = &c->CommonProxySetting;
10116 BUF *pw;
10117
10118 CfgAddInt(proxy, "ProxyType", t->ProxyType);
10119 CfgAddStr(proxy, "ProxyHostName", t->ProxyHostName);
10120 CfgAddInt(proxy, "ProxyPort", t->ProxyPort);
10121 CfgAddStr(proxy, "ProxyUsername", t->ProxyUsername);
10122
10123 if (IsEmptyStr(t->ProxyPassword) == false)
10124 {
10125 pw = EncryptPassword(t->ProxyPassword);
10126
10127 CfgAddBuf(proxy, "ProxyPassword", pw);
10128
10129 FreeBuf(pw);
10130 }
10131
10132 CfgAddStr(proxy, "CustomHttpHeader", t->CustomHttpHeader);
10133 }
10134
10135 // CA
10136 ca = CfgCreateFolder(root, "RootCA");
10137 CiWriteCAList(c, ca);
10138
10139 // VLAN
10140 if (OS_IS_UNIX(GetOsInfo()->OsType)
10141 #ifdef NO_VLAN
10142 && GetOsInfo()->OsType != OSTYPE_MACOS_X
10143 #endif // NO_VLAN
10144 )
10145 {
10146 vlan = CfgCreateFolder(root, "UnixVLan");
10147 CiWriteVLanList(c, vlan);
10148 }
10149
10150 // Password
10151 CfgAddByte(root, "EncryptedPassword", c->EncryptedPassword, SHA1_SIZE);
10152 CfgAddBool(root, "PasswordRemoteOnly", c->PasswordRemoteOnly);
10153
10154 // UseSecureDeviceId
10155 CfgAddInt(root, "UseSecureDeviceId", c->UseSecureDeviceId);
10156
10157 // DontSavePassword
10158 CfgAddBool(root, "DontSavePassword", c->DontSavePassword);
10159
10160 // UserAgent
10161 if (c->Cedar != NULL)
10162 {
10163 CfgAddStr(root, "UserAgent", c->Cedar->HttpUserAgent);
10164 }
10165
10166 if (cmsetting != NULL)
10167 {
10168 CM_SETTING *s = c->CmSetting;
10169
10170 CfgAddBool(cmsetting, "EasyMode", s->EasyMode);
10171 CfgAddBool(cmsetting, "LockMode", s->LockMode);
10172
10173 if (IsZero(s->HashedPassword, sizeof(s->HashedPassword)) == false)
10174 {
10175 CfgAddByte(cmsetting, "HashedPassword", s->HashedPassword, sizeof(s->HashedPassword));
10176 }
10177 }
10178 }
10179
10180 // Apply settings of Inner VPN Server
CiApplyInnerVPNServerConfig(CLIENT * c)10181 void CiApplyInnerVPNServerConfig(CLIENT *c)
10182 {
10183 }
10184
10185 // Write to the configuration file
CiSaveConfigurationFile(CLIENT * c)10186 void CiSaveConfigurationFile(CLIENT *c)
10187 {
10188 FOLDER *root;
10189 // Validate arguments
10190 if (c == NULL)
10191 {
10192 return;
10193 }
10194
10195 // Do not save the configuration file
10196 if(c->NoSaveConfig)
10197 {
10198 return;
10199 }
10200
10201 root = CfgCreateFolder(NULL, TAG_ROOT);
10202 CiWriteSettingToCfg(c, root);
10203
10204 SaveCfgRw(c->CfgRw, root);
10205
10206 CfgDeleteFolder(root);
10207 }
10208
10209 // Set the CM_SETTING
CtSetCmSetting(CLIENT * c,CM_SETTING * s)10210 bool CtSetCmSetting(CLIENT *c, CM_SETTING *s)
10211 {
10212 // Validate arguments
10213 if (c == NULL || s == NULL)
10214 {
10215 return false;
10216 }
10217
10218 Copy(c->CmSetting, s, sizeof(CM_SETTING));
10219
10220 CiSaveConfigurationFile(c);
10221
10222 return true;
10223 }
10224
10225 // Get the CM_SETTING
CtGetCmSetting(CLIENT * c,CM_SETTING * s)10226 bool CtGetCmSetting(CLIENT *c, CM_SETTING *s)
10227 {
10228 // Validate arguments
10229 if (c == NULL || s == NULL)
10230 {
10231 return false;
10232 }
10233
10234 Copy(s, c->CmSetting, sizeof(CM_SETTING));
10235
10236 return true;
10237 }
10238
10239 // Get the client version
CtGetClientVersion(CLIENT * c,RPC_CLIENT_VERSION * ver)10240 bool CtGetClientVersion(CLIENT *c, RPC_CLIENT_VERSION *ver)
10241 {
10242 // Validate arguments
10243 if (ver == NULL)
10244 {
10245 return false;
10246 }
10247
10248 Zero(ver, sizeof(RPC_CLIENT_VERSION));
10249 StrCpy(ver->ClientProductName, sizeof(ver->ClientProductName), CEDAR_CLIENT_STR);
10250 StrCpy(ver->ClientVersionString, sizeof(ver->ClientVersionString), c->Cedar->VerString);
10251 StrCpy(ver->ClientBuildInfoString, sizeof(ver->ClientBuildInfoString), c->Cedar->BuildInfo);
10252 ver->ClientVerInt = c->Cedar->Version;
10253 ver->ClientBuildInt = c->Cedar->Build;
10254
10255
10256 #ifdef OS_WIN32
10257 ver->ProcessId = MsGetProcessId();
10258 ver->IsVLanNameRegulated = MsIsInfCatalogRequired();
10259
10260 #endif // OS_WIN32
10261
10262 ver->OsType = GetOsInfo()->OsType;
10263
10264 return true;
10265 }
10266
10267 // Creating a Client object
CiNewClient()10268 CLIENT *CiNewClient()
10269 {
10270 CLIENT *c = ZeroMalloc(sizeof(CLIENT));
10271
10272 // StartCedarLog();
10273
10274 if (ci_active_sessions_lock == NULL)
10275 {
10276 ci_active_sessions_lock = NewLock();
10277 ci_num_active_sessions = 0;
10278 }
10279
10280 #ifdef OS_WIN32
10281 if (MsIsWindows7())
10282 {
10283 c->MsSuspendHandler = MsNewSuspendHandler();
10284 }
10285 #endif // OS_WIN32
10286
10287
10288 c->CmSetting = ZeroMalloc(sizeof(CM_SETTING));
10289
10290 c->SockList = NewSockList();
10291
10292 c->lock = NewLock();
10293 c->lockForConnect = NewLock();
10294 c->ref = NewRef();
10295
10296 c->Cedar = NewCedar(NULL, NULL);
10297
10298 c->Cedar->Client = c;
10299
10300 c->NotifyCancelList = NewList(NULL);
10301
10302 Sha0(c->EncryptedPassword, "", 0);
10303
10304 #ifdef OS_WIN32
10305 c->GlobalPulse = MsOpenOrCreateGlobalPulse(CLIENT_GLOBAL_PULSE_NAME);
10306 #endif // OS_WIN32
10307
10308 if (c->GlobalPulse != NULL)
10309 {
10310 c->PulseRecvThread = NewThread(CiPulseRecvThread, c);
10311 }
10312
10313 CiLoadIniSettings(c);
10314
10315 // Log Settings
10316 if(c->NoSaveLog == false)
10317 {
10318 MakeDir(CLIENT_LOG_DIR_NAME);
10319 c->Logger = NewLog(CLIENT_LOG_DIR_NAME, CLIENT_LOG_PREFIX, LOG_SWITCH_DAY);
10320 }
10321
10322 CLog(c, "L_LINE");
10323 CLog(c, "LC_START_2", CEDAR_CLIENT_STR, c->Cedar->VerString);
10324 CLog(c, "LC_START_3", c->Cedar->BuildInfo);
10325 CLog(c, "LC_START_1");
10326
10327 #ifdef OS_WIN32
10328 {
10329 // Initialize the Win32 UI
10330 wchar_t tmp[MAX_SIZE];
10331 StrToUni(tmp, sizeof(tmp), CEDAR_CLIENT_STR);
10332
10333 InitWinUi(tmp, _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE"));
10334 }
10335 #endif // OS_WIN32
10336
10337 // Initialize the settings
10338 CiInitConfiguration(c);
10339
10340 // Raise the priority
10341 OSSetHighPriority();
10342
10343 CiChangeAllVLanMacAddressIfMachineChanged(c);
10344
10345 CiChangeAllVLanMacAddressIfCleared(c);
10346
10347 // Initialize the internal VPN server
10348 CiApplyInnerVPNServerConfig(c);
10349
10350 return c;
10351 }
10352
10353 // Send a global pulse
CiSendGlobalPulse(CLIENT * c)10354 void CiSendGlobalPulse(CLIENT *c)
10355 {
10356 // Validate arguments
10357 if (c == NULL)
10358 {
10359 return;
10360 }
10361
10362 #ifdef OS_WIN32
10363 MsSendGlobalPulse(c->GlobalPulse);
10364 #endif // OS_WIN32
10365 }
10366
10367 // Pulse reception thread
CiPulseRecvThread(THREAD * thread,void * param)10368 void CiPulseRecvThread(THREAD *thread, void *param)
10369 {
10370 #ifdef OS_WIN32
10371 CLIENT *c = (CLIENT *)param;
10372
10373 if (c == NULL)
10374 {
10375 return;
10376 }
10377
10378 while (true)
10379 {
10380 if (c->HaltPulseThread)
10381 {
10382 break;
10383 }
10384
10385 MsWaitForGlobalPulse(c->GlobalPulse, INFINITE);
10386
10387 if (c->HaltPulseThread)
10388 {
10389 break;
10390 }
10391
10392 CiNotifyInternal(c);
10393 }
10394 #endif // OS_WIN32
10395 }
10396
10397 // Clean-up the client
CiCleanupClient(CLIENT * c)10398 void CiCleanupClient(CLIENT *c)
10399 {
10400 // Validate arguments
10401 if (c == NULL)
10402 {
10403 return;
10404 }
10405
10406
10407 // Release the settings
10408 CiFreeConfiguration(c);
10409
10410 #ifdef OS_WIN32
10411 // Release the Win32 UI
10412 FreeWinUi();
10413 #endif // OS_WIN32
10414
10415 CLog(c, "LC_END");
10416 CLog(c, "L_LINE");
10417 FreeEraser(c->Eraser);
10418 FreeLog(c->Logger);
10419 c->Logger = NULL;
10420
10421
10422 ReleaseCedar(c->Cedar);
10423
10424 DeleteLock(c->lockForConnect);
10425 DeleteLock(c->lock);
10426
10427 c->HaltPulseThread = true;
10428
10429 if (c->GlobalPulse != NULL)
10430 {
10431 #ifdef OS_WIN32
10432 MsSendGlobalPulse(c->GlobalPulse);
10433 #endif // OS_WIN32
10434 }
10435
10436 if (c->PulseRecvThread != NULL)
10437 {
10438 WaitThread(c->PulseRecvThread, INFINITE);
10439 ReleaseThread(c->PulseRecvThread);
10440 }
10441
10442 if (c->GlobalPulse != NULL)
10443 {
10444 #ifdef OS_WIN32
10445 MsCloseGlobalPulse(c->GlobalPulse);
10446 #endif // OS_WIN32
10447 }
10448
10449 ReleaseList(c->NotifyCancelList);
10450
10451 FreeSockList(c->SockList);
10452
10453 Free(c->CmSetting);
10454
10455
10456 #ifdef OS_WIN32
10457 if (c->MsSuspendHandler != NULL)
10458 {
10459 MsFreeSuspendHandler(c->MsSuspendHandler);
10460 }
10461 #endif // OS_WIN32
10462
10463 Free(c);
10464
10465 StopCedarLog();
10466
10467 if (ci_active_sessions_lock != NULL)
10468 {
10469 DeleteLock(ci_active_sessions_lock);
10470 ci_active_sessions_lock = NULL;
10471
10472 ci_num_active_sessions = 0;
10473 }
10474 }
10475
10476 // Increment of the number of active sessions
CiIncrementNumActiveSessions()10477 void CiIncrementNumActiveSessions()
10478 {
10479 Lock(ci_active_sessions_lock);
10480 {
10481 ci_num_active_sessions++;
10482 }
10483 Unlock(ci_active_sessions_lock);
10484 }
10485
10486 // Decrement of the number of active sessions
CiDecrementNumActiveSessions()10487 void CiDecrementNumActiveSessions()
10488 {
10489 Lock(ci_active_sessions_lock);
10490 {
10491 if (ci_num_active_sessions >= 1)
10492 {
10493 ci_num_active_sessions--;
10494 }
10495 }
10496 Unlock(ci_active_sessions_lock);
10497 }
10498
10499 // Release the client
CtReleaseClient(CLIENT * c)10500 void CtReleaseClient(CLIENT *c)
10501 {
10502 // Validate arguments
10503 if (c == NULL)
10504 {
10505 return;
10506 }
10507
10508 if (Release(c->ref) == 0)
10509 {
10510 CiCleanupClient(c);
10511 }
10512 }
10513
10514 // Start the operation of the client program
CtStartClient()10515 void CtStartClient()
10516 {
10517 UINT i;
10518 LIST *o;
10519 if (client != NULL)
10520 {
10521 // It is already in running
10522 return;
10523 }
10524
10525 #ifdef OS_WIN32
10526 RegistWindowsFirewallAll();
10527 #endif
10528
10529 // Creating a client
10530 client = CiNewClient();
10531
10532 // Start the Keep
10533 CiInitKeep(client);
10534
10535 // Start the RPC server
10536 CiStartRpcServer(client);
10537
10538 // Start the Saver
10539 CiInitSaver(client);
10540
10541 // Start the startup connection
10542 o = NewListFast(NULL);
10543 LockList(client->AccountList);
10544 {
10545 for (i = 0;i < LIST_NUM(client->AccountList);i++)
10546 {
10547 ACCOUNT *a = LIST_DATA(client->AccountList, i);
10548 Lock(a->lock);
10549 {
10550 if (a->StartupAccount)
10551 {
10552 Add(o, CopyUniStr(a->ClientOption->AccountName));
10553 }
10554 }
10555 Unlock(a->lock);
10556 }
10557 }
10558 UnlockList(client->AccountList);
10559
10560 for (i = 0;i < LIST_NUM(o);i++)
10561 {
10562 wchar_t *s = LIST_DATA(o, i);
10563 RPC_CLIENT_CONNECT c;
10564 Zero(&c, sizeof(c));
10565 UniStrCpy(c.AccountName, sizeof(c.AccountName), s);
10566 CtConnect(client, &c);
10567 Free(s);
10568 }
10569 ReleaseList(o);
10570 }
10571
10572 // Stop the operation of the client program
CtStopClient()10573 void CtStopClient()
10574 {
10575 UINT i, num;
10576 ACCOUNT **account_list;
10577 if (client == NULL)
10578 {
10579 // It is not running yet
10580 return;
10581 }
10582
10583 // Halting flag
10584 client->Halt = true;
10585
10586 // Disconnect all the RPC
10587 CiStopRpcServer(client);
10588
10589 // Exit the client notification service
10590 CncExit();
10591
10592 // Exit the Keep
10593 CiFreeKeep(client);
10594
10595 // Disconnect all accounts connected
10596 LockList(client->AccountList);
10597 {
10598 num = LIST_NUM(client->AccountList);
10599 account_list = ToArray(client->AccountList);
10600 }
10601 UnlockList(client->AccountList);
10602
10603 for (i = 0;i < num;i++)
10604 {
10605 ACCOUNT *a = account_list[i];
10606 SESSION *s = NULL;
10607
10608 Lock(a->lock);
10609 {
10610 if (a->ClientSession != NULL)
10611 {
10612 s = a->ClientSession;
10613 AddRef(s->ref);
10614 }
10615 }
10616 Unlock(a->lock);
10617
10618 if (s != NULL)
10619 {
10620 StopSession(s);
10621 ReleaseSession(s);
10622 Lock(a->lock);
10623 {
10624 if (a->ClientSession != NULL)
10625 {
10626 ReleaseSession(a->ClientSession);
10627 a->ClientSession = NULL;
10628 }
10629 }
10630 Unlock(a->lock);
10631 }
10632 }
10633
10634 Free(account_list);
10635
10636 // Stop the Saver
10637 CiFreeSaver(client);
10638
10639 // Release the client
10640 CtReleaseClient(client);
10641 client = NULL;
10642 }
10643
10644 // Client status indicator
CiClientStatusPrinter(SESSION * s,wchar_t * status)10645 void CiClientStatusPrinter(SESSION *s, wchar_t *status)
10646 {
10647 #ifdef OS_WIN32
10648 ACCOUNT *a;
10649 // Validate arguments
10650 if (s == NULL || status == NULL)
10651 {
10652 return;
10653 }
10654
10655 a = s->Account;
10656 if (a == NULL)
10657 {
10658 return;
10659 }
10660
10661 if (UniStrCmpi(status, L"init") == 0)
10662 {
10663 if (a->StatusWindow == NULL && s->Win32HideConnectWindow == false)
10664 {
10665 a->StatusWindow = CncStatusPrinterWindowStart(s);
10666 }
10667 }
10668 else if (UniStrCmpi(status, L"free") == 0)
10669 {
10670 if (a->StatusWindow != NULL)
10671 {
10672 CncStatusPrinterWindowStop(a->StatusWindow);
10673 a->StatusWindow = NULL;
10674 }
10675 }
10676 else
10677 {
10678 if (a->StatusWindow != NULL)
10679 {
10680 CncStatusPrinterWindowPrint(a->StatusWindow, status);
10681 }
10682 }
10683 #else // OS_WIN32
10684 UniPrint(L"Status: %s\n", status);
10685 #endif // OS_WIN32
10686 }
10687
10688
10689