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