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