1 // SoftEther VPN Source Code - Stable Edition Repository
2 // Cedar Communication Module
3 //
4 // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
5 //
6 // Copyright (c) Daiyuu Nobori.
7 // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
8 // Copyright (c) SoftEther Corporation.
9 // Copyright (c) all contributors on SoftEther VPN project in GitHub.
10 //
11 // All Rights Reserved.
12 //
13 // http://www.softether.org/
14 //
15 // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
16 // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
17 //
18 // License: The Apache License, Version 2.0
19 // https://www.apache.org/licenses/LICENSE-2.0
20 //
21 // DISCLAIMER
22 // ==========
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 // SOFTWARE.
31 //
32 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
33 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
34 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
35 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
36 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
37 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
38 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
39 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
40 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
41 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
42 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
43 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
44 // LAW OR COURT RULE.
45 //
46 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
47 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
48 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
49 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
50 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
51 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
52 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
53 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
54 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
55 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
56 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
57 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
58 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
59 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
60 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
61 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
62 // STATEMENT FOR WARNING AND DISCLAIMER.
63 //
64 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
65 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
66 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
67 //
68 //
69 // SOURCE CODE CONTRIBUTION
70 // ------------------------
71 //
72 // Your contribution to SoftEther VPN Project is much appreciated.
73 // Please send patches to us through GitHub.
74 // Read the SoftEther VPN Patch Acceptance Policy in advance:
75 // http://www.softether.org/5-download/src/9.patch
76 //
77 //
78 // DEAR SECURITY EXPERTS
79 // ---------------------
80 //
81 // If you find a bug or a security vulnerability please kindly inform us
82 // about the problem immediately so that we can fix the security problem
83 // to protect a lot of users around the world as soon as possible.
84 //
85 // Our e-mail address for security reports is:
86 // softether-vpn-security [at] softether.org
87 //
88 // Please note that the above e-mail address is not a technical support
89 // inquiry address. If you need technical assistance, please visit
90 // http://www.softether.org/ and ask your question on the users forum.
91 //
92 // Thank you for your cooperation.
93 //
94 //
95 // NO MEMORY OR RESOURCE LEAKS
96 // ---------------------------
97 //
98 // The memory-leaks and resource-leaks verification under the stress
99 // test has been passed before release this source code.
100 
101 
102 // EtherLog.c
103 // EtherLogger program
104 
105 #include "CedarPch.h"
106 
107 static LOCK *el_lock = NULL;
108 static EL *el = NULL;
109 
110 // RPC functional related macro
111 #define	DECLARE_RPC_EX(rpc_name, data_type, function, in_rpc, out_rpc, free_rpc)		\
112 	else if (StrCmpi(name, rpc_name) == 0)								\
113 	{																	\
114 		data_type t;													\
115 		Zero(&t, sizeof(t));											\
116 		in_rpc(&t, p);													\
117 		err = function(e, &t);											\
118 		if (err == ERR_NO_ERROR)										\
119 		{																\
120 			out_rpc(ret, &t);											\
121 		}																\
122 		free_rpc(&t);													\
123 		ok = true;														\
124 	}
125 #define	DECLARE_RPC(rpc_name, data_type, function, in_rpc, out_rpc)		\
126 	else if (StrCmpi(name, rpc_name) == 0)								\
127 	{																	\
128 		data_type t;													\
129 		Zero(&t, sizeof(t));											\
130 		in_rpc(&t, p);													\
131 		err = function(e, &t);											\
132 		if (err == ERR_NO_ERROR)										\
133 		{																\
134 			out_rpc(ret, &t);											\
135 		}																\
136 		ok = true;														\
137 	}
138 #define	DECLARE_SC_EX(rpc_name, data_type, function, in_rpc, out_rpc, free_rpc)	\
139 	UINT function(RPC *r, data_type *t)									\
140 	{																	\
141 		PACK *p, *ret;													\
142 		UINT err;														\
143 		if (r == NULL || t == NULL)										\
144 		{																\
145 			return ERR_INTERNAL_ERROR;									\
146 		}																\
147 		p = NewPack();													\
148 		out_rpc(p, t);													\
149 		free_rpc(t);													\
150 		Zero(t, sizeof(data_type));										\
151 		ret = AdminCall(r, rpc_name, p);								\
152 		err = GetErrorFromPack(ret);									\
153 		if (err == ERR_NO_ERROR)										\
154 		{																\
155 			in_rpc(t, ret);												\
156 		}																\
157 		FreePack(ret);													\
158 		return err;														\
159 	}
160 #define	DECLARE_SC(rpc_name, data_type, function, in_rpc, out_rpc)		\
161 	UINT function(RPC *r, data_type *t)									\
162 	{																	\
163 		PACK *p, *ret;													\
164 		UINT err;														\
165 		if (r == NULL || t == NULL)										\
166 		{																\
167 			return ERR_INTERNAL_ERROR;									\
168 		}																\
169 		p = NewPack();													\
170 		out_rpc(p, t);													\
171 		ret = AdminCall(r, rpc_name, p);								\
172 		err = GetErrorFromPack(ret);									\
173 		if (err == ERR_NO_ERROR)										\
174 		{																\
175 			in_rpc(t, ret);												\
176 		}																\
177 		FreePack(ret);													\
178 		return err;														\
179 	}
180 
181 // RPC client disconnect
EcDisconnect(RPC * rpc)182 void EcDisconnect(RPC *rpc)
183 {
184 	// Validate arguments
185 	if (rpc == NULL)
186 	{
187 		return;
188 	}
189 
190 	RpcFree(rpc);
191 }
192 
193 // RPC client connect
EcConnect(char * host,UINT port,char * password,RPC ** rpc)194 UINT EcConnect(char *host, UINT port, char *password, RPC **rpc)
195 {
196 	SOCK *s;
197 	UCHAR password_hash[SHA1_SIZE];
198 	UCHAR rand[SHA1_SIZE];
199 	UCHAR response[SHA1_SIZE];
200 	bool retcode;
201 	// Validate arguments
202 	if (host == NULL)
203 	{
204 		host = "localhost";
205 	}
206 	if (port == 0)
207 	{
208 		port = EL_ADMIN_PORT;
209 	}
210 	if (password == NULL)
211 	{
212 		password = "";
213 	}
214 	if (rpc == NULL)
215 	{
216 		return ERR_INTERNAL_ERROR;
217 	}
218 
219 	// Connect to the server
220 	s = Connect(host, port);
221 	if (s == NULL)
222 	{
223 		// Connection failure
224 		return ERR_CONNECT_FAILED;
225 	}
226 
227 	SetTimeout(s, 5000);
228 
229 	// Hash the password
230 	Hash(password_hash, password, StrLen(password), true);
231 
232 	// Receive the random number
233 	Zero(rand, sizeof(rand));
234 	RecvAll(s, rand, sizeof(rand), false);
235 	SecurePassword(response, password_hash, rand);
236 
237 	// Send a response
238 	SendAll(s, response, sizeof(response), false);
239 
240 	// Receive results
241 	retcode = false;
242 	if (RecvAll(s, &retcode, sizeof(retcode), false) == false)
243 	{
244 		// Disconnect
245 		ReleaseSock(s);
246 		return ERR_PROTOCOL_ERROR;
247 	}
248 	retcode = Endian32(retcode);
249 
250 	if (retcode == false)
251 	{
252 		// Password incorrect
253 		ReleaseSock(s);
254 		return ERR_AUTH_FAILED;
255 	}
256 
257 	// Successful connection
258 	SetTimeout(s, INFINITE);
259 
260 	*rpc = StartRpcClient(s, NULL);
261 
262 	ReleaseSock(s);
263 
264 	return ERR_NO_ERROR;
265 }
266 
267 // RPC server function
ElRpcServer(RPC * r,char * name,PACK * p)268 PACK *ElRpcServer(RPC *r, char *name, PACK *p)
269 {
270 	EL *e;
271 	PACK *ret;
272 	UINT err;
273 	bool ok;
274 	// Validate arguments
275 	if (r == NULL || name == NULL || p == NULL || r->Param == NULL)
276 	{
277 		return NULL;
278 	}
279 
280 	e = (EL *)r->Param;
281 
282 	ret = NewPack();
283 	err = ERR_NO_ERROR;
284 	ok = false;
285 
286 	if (0) {}
287 
288 	DECLARE_RPC("AddDevice", RPC_ADD_DEVICE, EtAddDevice, InRpcAddDevice, OutRpcAddDevice)
289 	DECLARE_RPC("DelDevice", RPC_DELETE_DEVICE, EtDelDevice, InRpcDeleteDevice, OutRpcDeleteDevice)
290 	DECLARE_RPC("SetDevice", RPC_ADD_DEVICE, EtSetDevice, InRpcAddDevice, OutRpcAddDevice)
291 	DECLARE_RPC("GetDevice", RPC_ADD_DEVICE, EtGetDevice, InRpcAddDevice, OutRpcAddDevice)
292 	DECLARE_RPC_EX("EnumDevice", RPC_ENUM_DEVICE, EtEnumDevice, InRpcEnumDevice, OutRpcEnumDevice, FreeRpcEnumDevice)
293 	DECLARE_RPC("SetPassword", RPC_SET_PASSWORD, EtSetPassword, InRpcSetPassword, OutRpcSetPassword)
294 	DECLARE_RPC_EX("EnumAllDevice", RPC_ENUM_DEVICE, EtEnumAllDevice, InRpcEnumDevice, OutRpcEnumDevice, FreeRpcEnumDevice)
295 	DECLARE_RPC("AddLicenseKey", RPC_TEST, EtAddLicenseKey, InRpcTest, OutRpcTest)
296 	DECLARE_RPC("DelLicenseKey", RPC_TEST, EtDelLicenseKey, InRpcTest, OutRpcTest)
297 	DECLARE_RPC_EX("EnumLicenseKey", RPC_ENUM_LICENSE_KEY, EtEnumLicenseKey, InRpcEnumLicenseKey, OutRpcEnumLicenseKey, FreeRpcEnumLicenseKey)
298 	DECLARE_RPC("GetLicenseStatus", RPC_EL_LICENSE_STATUS, EtGetLicenseStatus, InRpcElLicenseStatus, OutRpcElLicenseStatus)
299 	DECLARE_RPC("GetBridgeSupport", RPC_BRIDGE_SUPPORT, EtGetBridgeSupport, InRpcBridgeSupport, OutRpcBridgeSupport)
300 	DECLARE_RPC("RebootServer", RPC_TEST, EtRebootServer, InRpcTest, OutRpcTest)
301 
302 	if (ok == false)
303 	{
304 		err = ERR_NOT_SUPPORTED;
305 	}
306 
307 	PackAddInt(ret, "error", err);
308 
309 	return ret;
310 }
311 
312 DECLARE_SC("AddDevice", RPC_ADD_DEVICE, EcAddDevice, InRpcAddDevice, OutRpcAddDevice)
313 DECLARE_SC("DelDevice", RPC_DELETE_DEVICE, EcDelDevice, InRpcDeleteDevice, OutRpcDeleteDevice)
314 DECLARE_SC("SetDevice", RPC_ADD_DEVICE, EcSetDevice, InRpcAddDevice, OutRpcAddDevice)
315 DECLARE_SC("GetDevice", RPC_ADD_DEVICE, EcGetDevice, InRpcAddDevice, OutRpcAddDevice)
316 DECLARE_SC_EX("EnumDevice", RPC_ENUM_DEVICE, EcEnumDevice, InRpcEnumDevice, OutRpcEnumDevice, FreeRpcEnumDevice)
317 DECLARE_SC("SetPassword", RPC_SET_PASSWORD, EcSetPassword, InRpcSetPassword, OutRpcSetPassword)
318 DECLARE_SC_EX("EnumAllDevice", RPC_ENUM_DEVICE, EcEnumAllDevice, InRpcEnumDevice, OutRpcEnumDevice, FreeRpcEnumDevice)
319 DECLARE_SC("AddLicenseKey", RPC_TEST, EcAddLicenseKey, InRpcTest, OutRpcTest)
320 DECLARE_SC("DelLicenseKey", RPC_TEST, EcDelLicenseKey, InRpcTest, OutRpcTest)
321 DECLARE_SC_EX("EnumLicenseKey", RPC_ENUM_LICENSE_KEY, EcEnumLicenseKey, InRpcEnumLicenseKey, OutRpcEnumLicenseKey, FreeRpcEnumLicenseKey)
322 DECLARE_SC("GetLicenseStatus", RPC_EL_LICENSE_STATUS, EcGetLicenseStatus, InRpcElLicenseStatus, OutRpcElLicenseStatus)
323 DECLARE_SC("GetBridgeSupport", RPC_BRIDGE_SUPPORT, EcGetBridgeSupport, InRpcBridgeSupport, OutRpcBridgeSupport)
324 DECLARE_SC("RebootServer", RPC_TEST, EcRebootServer, InRpcTest, OutRpcTest)
325 
326 // Thread to restart the server
EiRebootServerThread(THREAD * thread,void * param)327 void EiRebootServerThread(THREAD *thread, void *param)
328 {
329 	// Validate arguments
330 	if (thread == NULL)
331 	{
332 		return;
333 	}
334 
335 	if (el == NULL)
336 	{
337 		return;
338 	}
339 
340 	// Stopping the server
341 	ElStop();
342 
343 	// Starting the server
344 	ElStart();
345 }
346 
347 // Restarting the server
EiRebootServer()348 void EiRebootServer()
349 {
350 	THREAD *t;
351 
352 	t = NewThread(EiRebootServerThread, NULL);
353 	ReleaseThread(t);
354 }
355 
356 // RPC to restart server
EtRebootServer(EL * a,RPC_TEST * t)357 UINT EtRebootServer(EL *a, RPC_TEST *t)
358 {
359 
360 	EiRebootServer();
361 
362 	return ERR_NO_ERROR;
363 }
364 
365 // Get support information for the local bridge
EtGetBridgeSupport(EL * a,RPC_BRIDGE_SUPPORT * t)366 UINT EtGetBridgeSupport(EL *a, RPC_BRIDGE_SUPPORT *t)
367 {
368 	Zero(t, sizeof(RPC_BRIDGE_SUPPORT));
369 
370 	t->IsBridgeSupportedOs = IsBridgeSupported();
371 	t->IsWinPcapNeeded = IsNeedWinPcap();
372 
373 	return ERR_NO_ERROR;
374 }
375 
376 // Update the status by checking the all licenses
ElCheckLicense(EL_LICENSE_STATUS * st,LICENSE * e)377 void ElCheckLicense(EL_LICENSE_STATUS *st, LICENSE *e)
378 {
379 }
380 
381 // Save by analyzing the status of the current license
ElParseCurrentLicenseStatus(LICENSE_SYSTEM * s,EL_LICENSE_STATUS * st)382 void ElParseCurrentLicenseStatus(LICENSE_SYSTEM *s, EL_LICENSE_STATUS *st)
383 {
384 }
385 
386 // Get a license status
EtGetLicenseStatus(EL * e,RPC_EL_LICENSE_STATUS * t)387 UINT EtGetLicenseStatus(EL *e, RPC_EL_LICENSE_STATUS *t)
388 {
389 	UINT ret = ERR_NO_ERROR;
390 	LICENSE_SYSTEM *ls = e->LicenseSystem;
391 
392 	if (ls == NULL)
393 	{
394 		return ERR_NOT_SUPPORTED;
395 	}
396 
397 	Zero(t, sizeof(RPC_EL_LICENSE_STATUS));
398 
399 	// Get the current license status
400 	ElParseCurrentLicenseStatus(ls, e->LicenseStatus);
401 
402 	t->Valid = e->LicenseStatus->Valid;
403 	t->SystemId = e->LicenseStatus->SystemId;
404 	t->SystemExpires = e->LicenseStatus->Expires;
405 
406 	return ret;
407 }
408 
409 // Enumerate the license keys
EtEnumLicenseKey(EL * el,RPC_ENUM_LICENSE_KEY * t)410 UINT EtEnumLicenseKey(EL *el, RPC_ENUM_LICENSE_KEY *t)
411 {
412 	return ERR_NOT_SUPPORTED;
413 }
414 
415 // Add a license key
EtAddLicenseKey(EL * e,RPC_TEST * t)416 UINT EtAddLicenseKey(EL *e, RPC_TEST *t)
417 {
418 	return ERR_NOT_SUPPORTED;
419 }
420 
421 // Delete the license key
EtDelLicenseKey(EL * e,RPC_TEST * t)422 UINT EtDelLicenseKey(EL *e, RPC_TEST *t)
423 {
424 	return ERR_NOT_SUPPORTED;
425 }
426 
427 // Password setting
EtSetPassword(EL * e,RPC_SET_PASSWORD * t)428 UINT EtSetPassword(EL *e, RPC_SET_PASSWORD *t)
429 {
430 	Copy(e->HashedPassword, t->HashedPassword, SHA1_SIZE);
431 
432 	ElSaveConfig(e);
433 
434 	return ERR_NO_ERROR;
435 }
436 
437 // Add a device
EtAddDevice(EL * e,RPC_ADD_DEVICE * t)438 UINT EtAddDevice(EL *e, RPC_ADD_DEVICE *t)
439 {
440 	if (ElAddCaptureDevice(e, t->DeviceName, &t->LogSetting, t->NoPromiscus) == false)
441 	{
442 		return ERR_CAPTURE_DEVICE_ADD_ERROR;
443 	}
444 
445 	ElSaveConfig(e);
446 
447 	return ERR_NO_ERROR;
448 }
449 
450 // Remove the device
EtDelDevice(EL * e,RPC_DELETE_DEVICE * t)451 UINT EtDelDevice(EL *e, RPC_DELETE_DEVICE *t)
452 {
453 	if (ElDeleteCaptureDevice(e, t->DeviceName) == false)
454 	{
455 		return ERR_CAPTURE_NOT_FOUND;
456 	}
457 
458 	ElSaveConfig(e);
459 
460 	return ERR_NO_ERROR;
461 }
462 
463 // Get the device
EtGetDevice(EL * e,RPC_ADD_DEVICE * t)464 UINT EtGetDevice(EL *e, RPC_ADD_DEVICE *t)
465 {
466 	UINT ret = ERR_CAPTURE_NOT_FOUND;
467 
468 	LockList(e->DeviceList);
469 	{
470 		EL_DEVICE *d, a;
471 		Zero(&a, sizeof(a));
472 		StrCpy(a.DeviceName, sizeof(a.DeviceName), t->DeviceName);
473 
474 		d = Search(e->DeviceList, &a);
475 
476 		if (d != NULL)
477 		{
478 			ret = ERR_NO_ERROR;
479 
480 			Copy(&t->LogSetting, &d->LogSetting, sizeof(HUB_LOG));
481 			t->NoPromiscus = d->NoPromiscus;
482 		}
483 	}
484 	UnlockList(e->DeviceList);
485 
486 	return ret;
487 }
488 
489 // Device Setting
EtSetDevice(EL * e,RPC_ADD_DEVICE * t)490 UINT EtSetDevice(EL *e, RPC_ADD_DEVICE *t)
491 {
492 	if (ElSetCaptureDeviceLogSetting(e, t->DeviceName, &t->LogSetting) == false)
493 	{
494 		return ERR_CAPTURE_NOT_FOUND;
495 	}
496 
497 	ElSaveConfig(e);
498 
499 	return ERR_NO_ERROR;
500 }
501 
502 // Enumerate all devices
EtEnumAllDevice(EL * e,RPC_ENUM_DEVICE * t)503 UINT EtEnumAllDevice(EL *e, RPC_ENUM_DEVICE *t)
504 {
505 	TOKEN_LIST *eth;
506 	UINT i;
507 	if (IsEthSupported() == false)
508 	{
509 		return ERR_NOT_SUPPORTED;
510 	}
511 
512 	FreeRpcEnumDevice(t);
513 	Zero(t, sizeof(RPC_ENUM_DEVICE));
514 
515 	eth = GetEthList();
516 
517 	t->NumItem = eth->NumTokens;
518 	t->Items = ZeroMalloc(sizeof(RPC_ENUM_DEVICE_ITEM) * t->NumItem);
519 
520 	for (i = 0;i < eth->NumTokens;i++)
521 	{
522 		char *name = eth->Token[i];
523 		RPC_ENUM_DEVICE_ITEM *item = &t->Items[i];
524 
525 		StrCpy(item->DeviceName, sizeof(item->DeviceName), name);
526 	}
527 
528 	FreeToken(eth);
529 
530 	return ERR_NO_ERROR;
531 }
532 
533 // Device enumeration
EtEnumDevice(EL * e,RPC_ENUM_DEVICE * t)534 UINT EtEnumDevice(EL *e, RPC_ENUM_DEVICE *t)
535 {
536 	bool is_beta_expired = ElIsBetaExpired();
537 
538 	if (is_beta_expired)
539 	{
540 		// The beta version has expired
541 		return ERR_BETA_EXPIRES;
542 	}
543 
544 	FreeRpcEnumDevice(t);
545 	Zero(t, sizeof(RPC_ENUM_DEVICE));
546 
547 	LockList(e->DeviceList);
548 	{
549 		UINT i;
550 
551 		t->NumItem = LIST_NUM(e->DeviceList);
552 		t->Items = ZeroMalloc(sizeof(RPC_ENUM_DEVICE_ITEM) * t->NumItem);
553 
554 		for (i = 0;i < t->NumItem;i++)
555 		{
556 			RPC_ENUM_DEVICE_ITEM *d = &t->Items[i];
557 			EL_DEVICE *eld = LIST_DATA(e->DeviceList, i);
558 
559 			StrCpy(d->DeviceName, sizeof(d->DeviceName), eld->DeviceName);
560 			d->Active = eld->Active && ((ELOG_IS_BETA || e->LicenseStatus->Valid) ? true : false);
561 		}
562 	}
563 	UnlockList(e->DeviceList);
564 
565 	return ERR_NO_ERROR;
566 }
567 
InRpcAddDevice(RPC_ADD_DEVICE * t,PACK * p)568 void InRpcAddDevice(RPC_ADD_DEVICE *t, PACK *p)
569 {
570 	UINT i;
571 	// Validate arguments
572 	if (t == NULL || p == NULL)
573 	{
574 		return;
575 	}
576 
577 	Zero(t, sizeof(RPC_ADD_DEVICE));
578 	PackGetStr(p, "DeviceName", t->DeviceName, sizeof(t->DeviceName));
579 	t->NoPromiscus = PackGetInt(p, "NoPromiscus");
580 	t->LogSetting.PacketLogSwitchType = PackGetInt(p, "PacketLogSwitchType");
581 
582 	for (i = 0;i < NUM_PACKET_LOG;i++)
583 	{
584 		t->LogSetting.PacketLogConfig[i] = PackGetIntEx(p, "PacketLogConfig", i);
585 	}
586 }
587 
OutRpcAddDevice(PACK * p,RPC_ADD_DEVICE * t)588 void OutRpcAddDevice(PACK *p, RPC_ADD_DEVICE *t)
589 {
590 	UINT i;
591 	// Validate arguments
592 	if (t == NULL || p == NULL)
593 	{
594 		return;
595 	}
596 
597 	PackAddStr(p, "DeviceName", t->DeviceName);
598 	PackAddInt(p, "NoPromiscus", t->NoPromiscus);
599 	PackAddInt(p, "PacketLogSwitchType", t->LogSetting.PacketLogSwitchType);
600 
601 	for (i = 0;i < NUM_PACKET_LOG;i++)
602 	{
603 		PackAddIntEx(p, "PacketLogConfig", t->LogSetting.PacketLogConfig[i], i, NUM_PACKET_LOG);
604 	}
605 }
606 
InRpcDeleteDevice(RPC_DELETE_DEVICE * t,PACK * p)607 void InRpcDeleteDevice(RPC_DELETE_DEVICE *t, PACK *p)
608 {
609 	// Validate arguments
610 	if (t == NULL || p == NULL)
611 	{
612 		return;
613 	}
614 
615 	Zero(t, sizeof(RPC_DELETE_DEVICE));
616 	PackGetStr(p, "DeviceName", t->DeviceName, sizeof(t->DeviceName));
617 }
618 
OutRpcDeleteDevice(PACK * p,RPC_DELETE_DEVICE * t)619 void OutRpcDeleteDevice(PACK *p, RPC_DELETE_DEVICE *t)
620 {
621 	// Validate arguments
622 	if (p == NULL || t == NULL)
623 	{
624 		return;
625 	}
626 
627 	PackAddStr(p, "DeviceName", t->DeviceName);
628 }
629 
InRpcEnumDevice(RPC_ENUM_DEVICE * t,PACK * p)630 void InRpcEnumDevice(RPC_ENUM_DEVICE *t, PACK *p)
631 {
632 	UINT i;
633 	// Validate arguments
634 	if (t == NULL || p == NULL)
635 	{
636 		return;
637 	}
638 
639 	Zero(t, sizeof(RPC_ENUM_DEVICE));
640 	t->NumItem = PackGetInt(p, "NumItem");
641 	t->Items = ZeroMalloc(sizeof(RPC_ENUM_DEVICE_ITEM) * t->NumItem);
642 
643 	for (i = 0;i < t->NumItem;i++)
644 	{
645 		RPC_ENUM_DEVICE_ITEM *d = &t->Items[i];
646 
647 		PackGetStrEx(p, "DeviceName", d->DeviceName, sizeof(d->DeviceName), i);
648 		d->Active = PackGetBoolEx(p, "Active", i);
649 	}
650 
651 	t->IsLicenseSupported = PackGetBool(p, "IsLicenseSupported");
652 }
653 
OutRpcEnumDevice(PACK * p,RPC_ENUM_DEVICE * t)654 void OutRpcEnumDevice(PACK *p, RPC_ENUM_DEVICE *t)
655 {
656 	UINT i;
657 	// Validate arguments
658 	if (t == NULL || p == NULL)
659 	{
660 		return;
661 	}
662 
663 	PackAddInt(p, "NumItem", t->NumItem);
664 
665 	PackSetCurrentJsonGroupName(p, "DeviceList");
666 	for (i = 0;i < t->NumItem;i++)
667 	{
668 		RPC_ENUM_DEVICE_ITEM *d = &t->Items[i];
669 
670 		PackAddStrEx(p, "DeviceName", d->DeviceName, i, t->NumItem);
671 		PackAddBoolEx(p, "Active", d->Active, i, t->NumItem);
672 	}
673 	PackSetCurrentJsonGroupName(p, NULL);
674 
675 	PackAddBool(p, "IsLicenseSupported", t->IsLicenseSupported);
676 }
677 
FreeRpcEnumDevice(RPC_ENUM_DEVICE * t)678 void FreeRpcEnumDevice(RPC_ENUM_DEVICE *t)
679 {
680 	// Validate arguments
681 	if (t == NULL)
682 	{
683 		return;
684 	}
685 
686 	Free(t->Items);
687 }
688 
689 // RPC_LICENSE_STATUS
InRpcElLicenseStatus(RPC_EL_LICENSE_STATUS * t,PACK * p)690 void InRpcElLicenseStatus(RPC_EL_LICENSE_STATUS *t, PACK *p)
691 {
692 	// Validate arguments
693 	if (t == NULL || p == NULL)
694 	{
695 		return;
696 	}
697 
698 	Zero(t, sizeof(RPC_EL_LICENSE_STATUS));
699 
700 	t->Valid = PackGetBool(p, "Valid");
701 	t->SystemId = PackGetInt64(p, "SystemId");
702 	t->SystemExpires = PackGetInt64(p, "SystemExpires");
703 }
OutRpcElLicenseStatus(PACK * p,RPC_EL_LICENSE_STATUS * t)704 void OutRpcElLicenseStatus(PACK *p, RPC_EL_LICENSE_STATUS *t)
705 {
706 	// Validate arguments
707 	if (t == NULL || p == NULL)
708 	{
709 		return;
710 	}
711 
712 	PackAddBool(p, "Valid", t->Valid);
713 	PackAddInt64(p, "SystemId", t->SystemId);
714 	PackAddTime64(p, "SystemExpires", t->SystemExpires);
715 }
716 
717 // Listener thread
ElListenerProc(THREAD * thread,void * param)718 void ElListenerProc(THREAD *thread, void *param)
719 {
720 	TCP_ACCEPTED_PARAM *data = (TCP_ACCEPTED_PARAM *)param;
721 	EL *e;
722 	SOCK *s;
723 	UCHAR rand[SHA1_SIZE];
724 	UCHAR pass1[SHA1_SIZE], pass2[SHA1_SIZE];
725 	// Validate arguments
726 	if (data == NULL || thread == NULL)
727 	{
728 		return;
729 	}
730 
731 	e = (EL *)data->r->ThreadParam;
732 	s = data->s;
733 	AddRef(s->ref);
734 	SetTimeout(s, 5000);
735 	LockList(e->AdminThreadList);
736 	{
737 		AddRef(thread->ref);
738 		AddRef(s->ref);
739 		Insert(e->AdminThreadList, thread);
740 		Insert(e->AdminSockList, s);
741 	}
742 	UnlockList(e->AdminThreadList);
743 	NoticeThreadInit(thread);
744 
745 	// Submit a challenge
746 	Rand(rand, sizeof(rand));
747 	SendAll(s, rand, sizeof(rand), false);
748 
749 	// Receive a response
750 	SecurePassword(pass1, e->HashedPassword, rand);
751 	Zero(pass2, sizeof(pass2));
752 	RecvAll(s, pass2, sizeof(pass2), false);
753 
754 	if (Cmp(pass1, pass2, SHA1_SIZE) != 0)
755 	{
756 		// Password incorrect
757 		bool code = false;
758 		code = Endian32(code);
759 		SendAll(s, &code, sizeof(code), false);
760 	}
761 	else
762 	{
763 		// Password match
764 		bool code = true;
765 		RPC *r;
766 
767 		code = Endian32(code);
768 		SendAll(s, &code, sizeof(code), false);
769 
770 		SetTimeout(s, INFINITE);
771 
772 		// Start operation as a RPC server
773 		r = StartRpcServer(s, ElRpcServer, e);
774 		RpcServer(r);
775 		RpcFree(r);
776 	}
777 
778 	Disconnect(s);
779 	ReleaseSock(s);
780 
781 	LockList(e->AdminThreadList);
782 	{
783 		if (Delete(e->AdminThreadList, thread))
784 		{
785 			ReleaseThread(thread);
786 		}
787 		if (Delete(e->AdminSockList, s))
788 		{
789 			ReleaseSock(s);
790 		}
791 	}
792 	UnlockList(e->AdminThreadList);
793 }
794 
795 // Listener start
ElStartListener(EL * e)796 void ElStartListener(EL *e)
797 {
798 	// Validate arguments
799 	if (e == NULL)
800 	{
801 		return;
802 	}
803 
804 	e->AdminThreadList = NewList(NULL);
805 	e->AdminSockList = NewList(NULL);
806 
807 	e->Listener = NewListenerEx(e->Cedar, LISTENER_TCP, e->Port == 0 ? EL_ADMIN_PORT : e->Port,
808 		ElListenerProc, e);
809 }
810 
811 // Listener stop
ElStopListener(EL * e)812 void ElStopListener(EL *e)
813 {
814 	UINT i;
815 	THREAD **threads;
816 	SOCK **socks;
817 	UINT num_threads, num_socks;
818 	// Validate arguments
819 	if (e == NULL)
820 	{
821 		return;
822 	}
823 
824 	StopAllListener(e->Cedar);
825 
826 	LockList(e->AdminThreadList);
827 	{
828 		threads = ToArray(e->AdminThreadList);
829 		num_threads = LIST_NUM(e->AdminThreadList);
830 		DeleteAll(e->AdminThreadList);
831 
832 		socks = ToArray(e->AdminSockList);
833 		num_socks = LIST_NUM(e->AdminSockList);
834 		DeleteAll(e->AdminSockList);
835 	}
836 	UnlockList(e->AdminThreadList);
837 
838 	for (i = 0;i < num_socks;i++)
839 	{
840 		Disconnect(socks[i]);
841 		ReleaseSock(socks[i]);
842 	}
843 
844 	for (i = 0;i < num_threads;i++)
845 	{
846 		WaitThread(threads[i], INFINITE);
847 		ReleaseThread(threads[i]);
848 	}
849 
850 	Free(threads);
851 	Free(socks);
852 
853 	ReleaseList(e->AdminSockList);
854 	ReleaseList(e->AdminThreadList);
855 
856 	ReleaseListener(e->Listener);
857 }
858 
859 // Update the log configuration of the capture device
ElSetCaptureDeviceLogSetting(EL * e,char * name,HUB_LOG * log)860 bool ElSetCaptureDeviceLogSetting(EL *e, char *name, HUB_LOG *log)
861 {
862 	EL_DEVICE *d;
863 	bool ret = false;
864 	// Validate arguments
865 	if (e == NULL || log == NULL || name == NULL)
866 	{
867 		return false;
868 	}
869 
870 	LockList(e->DeviceList);
871 	{
872 		EL_DEVICE t;
873 
874 		Zero(&t, sizeof(t));
875 		StrCpy(t.DeviceName, sizeof(t.DeviceName), name);
876 
877 		d = Search(e->DeviceList, &t);
878 
879 		if (d != NULL)
880 		{
881 			Copy(&d->LogSetting, log, sizeof(HUB_LOG));
882 
883 			SetLogSwitchType(d->Logger, log->PacketLogSwitchType);
884 
885 			ret = true;
886 		}
887 	}
888 	UnlockList(e->DeviceList);
889 
890 	return ret;
891 }
892 
893 // Confirm whether the beta version has expired
ElIsBetaExpired()894 bool ElIsBetaExpired()
895 {
896 	SYSTEMTIME st;
897 	UINT64 expires64;
898 	UINT64 now64;
899 	if (ELOG_IS_BETA == false)
900 	{
901 		return false;
902 	}
903 
904 	Zero(&st, sizeof(st));
905 
906 	st.wYear = ELOG_BETA_EXPIRES_YEAR;
907 	st.wMonth = ELOG_BETA_EXPIRES_MONTH;
908 	st.wDay = ELOG_BETA_EXPIRES_DAY;
909 
910 	expires64 = SystemToUINT64(&st);
911 	now64 = LocalTime64();
912 
913 	if (now64 >= expires64)
914 	{
915 		return true;
916 	}
917 
918 	return false;
919 }
920 
921 // Capture thread
ElCaptureThread(THREAD * thread,void * param)922 void ElCaptureThread(THREAD *thread, void *param)
923 {
924 }
925 
926 // Delete the capture device
ElDeleteCaptureDevice(EL * e,char * name)927 bool ElDeleteCaptureDevice(EL *e, char *name)
928 {
929 	bool ret = false;
930 	EL_DEVICE *d, t;
931 	// Validate arguments
932 	if (e == NULL || name == NULL)
933 	{
934 		return false;
935 	}
936 
937 	LockList(e->DeviceList);
938 	{
939 		Zero(&t, sizeof(t));
940 		StrCpy(t.DeviceName, sizeof(t.DeviceName), name);
941 
942 		d = Search(e->DeviceList, &t);
943 
944 		if (d != NULL)
945 		{
946 			// Stop capture
947 			d->Halt = true;
948 			Cancel(d->Cancel1);
949 
950 			// Wait for thread stop
951 			WaitThread(d->Thread, INFINITE);
952 			ReleaseThread(d->Thread);
953 
954 			// Release the memory
955 			Delete(e->DeviceList, d);
956 			Free(d);
957 
958 			ret = true;
959 		}
960 	}
961 	UnlockList(e->DeviceList);
962 
963 	return ret;
964 }
965 
966 // Add a capture device
ElAddCaptureDevice(EL * e,char * name,HUB_LOG * log,bool no_promiscus)967 bool ElAddCaptureDevice(EL *e, char *name, HUB_LOG *log, bool no_promiscus)
968 {
969 	EL_DEVICE *d, t;
970 	// Validate arguments
971 	if (e == NULL || name == NULL || log == NULL)
972 	{
973 		return false;
974 	}
975 
976 	Zero(&t, sizeof(t));
977 	StrCpy(t.DeviceName, sizeof(t.DeviceName), name);
978 
979 	LockList(e->DeviceList);
980 	{
981 		d = Search(e->DeviceList, &t);
982 		if (d != NULL)
983 		{
984 			// Capture settings with the same name already exists
985 			UnlockList(e->DeviceList);
986 			return false;
987 		}
988 
989 		// Add a device
990 		d = ZeroMalloc(sizeof(EL_DEVICE));
991 		StrCpy(d->DeviceName, sizeof(d->DeviceName), name);
992 		Copy(&d->LogSetting, log, sizeof(HUB_LOG));
993 		d->NoPromiscus = no_promiscus;
994 		d->el = e;
995 		Insert(e->DeviceList, d);
996 
997 		// Start the thread
998 		d->Thread = NewThread(ElCaptureThread, d);
999 		WaitThreadInit(d->Thread);
1000 	}
1001 	UnlockList(e->DeviceList);
1002 
1003 	ElSaveConfig(e);
1004 
1005 	return true;
1006 }
1007 
1008 // Write the license List
EiWriteLicenseManager(FOLDER * f,EL * s)1009 void EiWriteLicenseManager(FOLDER *f, EL *s)
1010 {
1011 }
1012 
1013 // Read the license list
EiLoadLicenseManager(EL * s,FOLDER * f)1014 void EiLoadLicenseManager(EL *s, FOLDER *f)
1015 {
1016 }
1017 
1018 // Configuration initialization
ElInitConfig(EL * e)1019 void ElInitConfig(EL *e)
1020 {
1021 	// Validate arguments
1022 	if (e == NULL)
1023 	{
1024 		return;
1025 	}
1026 
1027 	// Device list initialization
1028 	e->DeviceList = NewList(ElCompareDevice);
1029 
1030 	// Read configuration file
1031 	ElLoadConfig(e);
1032 
1033 	// Write configuration file
1034 	ElSaveConfig(e);
1035 }
1036 
1037 // Write the configuration
ElSaveConfig(EL * e)1038 void ElSaveConfig(EL *e)
1039 {
1040 	FOLDER *root;
1041 	// Validate arguments
1042 	if (e == NULL)
1043 	{
1044 		return;
1045 	}
1046 
1047 	root = CfgCreateFolder(NULL, TAG_ROOT);
1048 
1049 	ElSaveConfigToFolder(e, root);
1050 
1051 	SaveCfgRw(e->CfgRw, root);
1052 
1053 	CfgDeleteFolder(root);
1054 }
1055 
1056 // Write the configuration to the folder
ElSaveConfigToFolder(EL * e,FOLDER * root)1057 void ElSaveConfigToFolder(EL *e, FOLDER *root)
1058 {
1059 	UINT i;
1060 	FOLDER *devices;
1061 	// Validate arguments
1062 	if (e == NULL || root == NULL)
1063 	{
1064 		return;
1065 	}
1066 
1067 	CfgAddInt64(root, "AutoDeleteCheckDiskFreeSpaceMin", e->AutoDeleteCheckDiskFreeSpaceMin);
1068 
1069 	CfgAddInt(root, "AdminPort", e->Port);
1070 
1071 	CfgAddByte(root, "AdminPassword", e->HashedPassword, sizeof(e->HashedPassword));
1072 
1073 	if (ELOG_IS_BETA == false)
1074 	{
1075 		EiWriteLicenseManager(CfgCreateFolder(root, "LicenseManager"), e);
1076 	}
1077 
1078 	devices = CfgCreateFolder(root,"Devices");
1079 
1080 	LockList(e->DeviceList);
1081 	{
1082 		for (i = 0;i < LIST_NUM(e->DeviceList);i++)
1083 		{
1084 			FOLDER *f;
1085 			EL_DEVICE *d = LIST_DATA(e->DeviceList, i);
1086 
1087 			f = CfgCreateFolder(devices, d->DeviceName);
1088 			SiWriteHubLogCfgEx(f, &d->LogSetting, true);
1089 			CfgAddBool(f, "NoPromiscusMode", d->NoPromiscus);
1090 		}
1091 	}
1092 	UnlockList(e->DeviceList);
1093 }
1094 
1095 // Read the configuration from the folder
ElLoadConfigFromFolder(EL * e,FOLDER * root)1096 void ElLoadConfigFromFolder(EL *e, FOLDER *root)
1097 {
1098 	UINT i;
1099 	TOKEN_LIST *t;
1100 	FOLDER *devices;
1101 
1102 	// Validate arguments
1103 	if (e == NULL || root == NULL)
1104 	{
1105 		return;
1106 	}
1107 
1108 	i = CfgGetInt(root, "AdminPort");
1109 	if (i >= 1 && i <= 65535)
1110 	{
1111 		e->Port = i;
1112 	}
1113 
1114 	e->AutoDeleteCheckDiskFreeSpaceMin = CfgGetInt64(root, "AutoDeleteCheckDiskFreeSpaceMin");
1115 	if (CfgIsItem(root, "AutoDeleteCheckDiskFreeSpaceMin") == false && e->AutoDeleteCheckDiskFreeSpaceMin == 0)
1116 	{
1117 		e->AutoDeleteCheckDiskFreeSpaceMin = DISK_FREE_SPACE_DEFAULT;
1118 	}
1119 
1120 	if (e->AutoDeleteCheckDiskFreeSpaceMin != 0)
1121 	{
1122 		if (e->AutoDeleteCheckDiskFreeSpaceMin < DISK_FREE_SPACE_MIN)
1123 		{
1124 			e->AutoDeleteCheckDiskFreeSpaceMin = DISK_FREE_SPACE_MIN;
1125 		}
1126 	}
1127 
1128 	if (CfgGetByte(root, "AdminPassword", e->HashedPassword, sizeof(e->HashedPassword)) != sizeof(e->HashedPassword))
1129 	{
1130 		Hash(e->HashedPassword, "", 0, true);
1131 	}
1132 
1133 	if (ELOG_IS_BETA == false)
1134 	{
1135 		EiLoadLicenseManager(e,	CfgGetFolder(root, "LicenseManager"));
1136 	}
1137 
1138 	devices = CfgGetFolder(root, "Devices");
1139 	if(devices != NULL)
1140 	{
1141 		LockList(e->DeviceList);
1142 		{
1143 			t = CfgEnumFolderToTokenList(devices);
1144 			for (i = 0;i < t->NumTokens;i++)
1145 			{
1146 				char *name = t->Token[i];
1147 				FOLDER *f = CfgGetFolder(devices, name);
1148 
1149 				if (f != NULL)
1150 				{
1151 					HUB_LOG g;
1152 
1153 					Zero(&g, sizeof(g));
1154 					SiLoadHubLogCfg(&g, f);
1155 					ElAddCaptureDevice(e, name, &g, CfgGetBool(f, "NoPromiscusMode"));
1156 				}
1157 			}
1158 			FreeToken(t);
1159 		}
1160 		UnlockList(e->DeviceList);
1161 	}
1162 }
1163 
1164 // Reading configuration
ElLoadConfig(EL * e)1165 bool ElLoadConfig(EL *e)
1166 {
1167 	FOLDER *root;
1168 	bool ret = false;
1169 	// Validate arguments
1170 	if (e == NULL)
1171 	{
1172 		return false;
1173 	}
1174 
1175 	e->Port = EL_ADMIN_PORT;
1176 
1177 	e->CfgRw = NewCfgRw(&root, EL_CONFIG_FILENAME);
1178 
1179 	if (root != NULL)
1180 	{
1181 		ElLoadConfigFromFolder(e, root);
1182 
1183 		CfgDeleteFolder(root);
1184 	}
1185 	else
1186 	{
1187 		char *pass = "";
1188 		Hash(e->HashedPassword, pass, StrLen(pass), true);
1189 		e->AutoDeleteCheckDiskFreeSpaceMin = DISK_FREE_SPACE_DEFAULT;
1190 	}
1191 
1192 	return ret;
1193 }
1194 
1195 // Configuration release
ElFreeConfig(EL * e)1196 void ElFreeConfig(EL *e)
1197 {
1198 	UINT i;
1199 	LIST *o;
1200 	// Validate arguments
1201 	if (e == NULL)
1202 	{
1203 		return;
1204 	}
1205 
1206 	// Write the configuration file
1207 	ElSaveConfig(e);
1208 	FreeCfgRw(e->CfgRw);
1209 
1210 	// Stop all capture
1211 	o = NewList(NULL);
1212 	LockList(e->DeviceList);
1213 	{
1214 		for (i = 0;i < LIST_NUM(e->DeviceList);i++)
1215 		{
1216 			EL_DEVICE *d = LIST_DATA(e->DeviceList, i);
1217 			Insert(o, CopyStr(d->DeviceName));
1218 		}
1219 		for (i = 0;i < LIST_NUM(o);i++)
1220 		{
1221 			char *name = LIST_DATA(o, i);
1222 			ElDeleteCaptureDevice(e, name);
1223 			Free(name);
1224 		}
1225 		ReleaseList(o);
1226 	}
1227 	UnlockList(e->DeviceList);
1228 
1229 	ReleaseList(e->DeviceList);
1230 }
1231 
1232 // Comparison function of the device
ElCompareDevice(void * p1,void * p2)1233 int ElCompareDevice(void *p1, void *p2)
1234 {
1235 	EL_DEVICE *d1, *d2;
1236 	// Validate arguments
1237 	if (p1 == NULL || p2 == NULL)
1238 	{
1239 		return 0;
1240 	}
1241 	d1 = *(EL_DEVICE **)p1;
1242 	d2 = *(EL_DEVICE **)p2;
1243 	if (d1 == NULL || d2 == NULL)
1244 	{
1245 		return 0;
1246 	}
1247 
1248 	return StrCmpi(d1->DeviceName, d2->DeviceName);
1249 }
1250 
1251 // Clean-up the EL
CleanupEl(EL * e)1252 void CleanupEl(EL *e)
1253 {
1254 	// Validate arguments
1255 	if (e == NULL)
1256 	{
1257 		return;
1258 	}
1259 
1260 	// Stop Eraser
1261 	FreeEraser(e->Eraser);
1262 
1263 	// Stop Listener
1264 	ElStopListener(e);
1265 
1266 	// Setting release
1267 	ElFreeConfig(e);
1268 
1269 	// Free the license system
1270 	if(e->LicenseSystem != NULL)
1271 	{
1272 	}
1273 
1274 	// Free the license status
1275 	if(e->LicenseStatus != NULL)
1276 	{
1277 		Free(e->LicenseStatus);
1278 	}
1279 
1280 	// Ethernet release
1281 	FreeEth();
1282 
1283 	ReleaseCedar(e->Cedar);
1284 
1285 	DeleteLock(e->lock);
1286 
1287 	Free(e);
1288 }
1289 
1290 // Release the EL
ReleaseEl(EL * e)1291 void ReleaseEl(EL *e)
1292 {
1293 	// Validate arguments
1294 	if (e == NULL)
1295 	{
1296 		return;
1297 	}
1298 
1299 	if (Release(e->ref) == 0)
1300 	{
1301 		CleanupEl(e);
1302 	}
1303 }
1304 
1305 // Create the EL
NewEl()1306 EL *NewEl()
1307 {
1308 	EL *e;
1309 
1310 #ifdef OS_WIN32
1311 	RegistWindowsFirewallAll();
1312 #endif
1313 
1314 	e = ZeroMalloc(sizeof(EL));
1315 	e->lock = NewLock();
1316 	e->ref = NewRef();
1317 
1318 	e->Cedar = NewCedar(NULL, NULL);
1319 
1320 
1321 	// Ethernet initialization
1322 	InitEth();
1323 
1324 	// Setting initialization
1325 	ElInitConfig(e);
1326 
1327 	// Listener start
1328 	ElStartListener(e);
1329 
1330 	// Initialize the license status
1331 	ElParseCurrentLicenseStatus(e->LicenseSystem, e->LicenseStatus);
1332 
1333 	// Eraser start
1334 	e->Eraser = NewEraser(NULL, e->AutoDeleteCheckDiskFreeSpaceMin);
1335 
1336 	return e;
1337 }
1338 
1339 // EL start
ElStart()1340 void ElStart()
1341 {
1342 	// Raise the priority
1343 	OSSetHighPriority();
1344 
1345 	Lock(el_lock);
1346 	{
1347 		el = NewEl();
1348 	}
1349 	Unlock(el_lock);
1350 }
1351 
1352 // EL stop
ElStop()1353 void ElStop()
1354 {
1355 	Lock(el_lock);
1356 	{
1357 		ReleaseEl(el);
1358 		el = NULL;
1359 	}
1360 	Unlock(el_lock);
1361 }
1362 
1363 // EL initialization
ElInit()1364 void ElInit()
1365 {
1366 	// Lock initialization
1367 	el_lock = NewLock();
1368 }
1369 
1370 // EL release
ElFree()1371 void ElFree()
1372 {
1373 	// Lock release
1374 	DeleteLock(el_lock);
1375 	el_lock = NULL;
1376 }
1377 
1378