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 // Remote.c
103 // Remote Procedure Call
104 
105 #include "CedarPch.h"
106 
107 // End of RPC
EndRpc(RPC * rpc)108 void EndRpc(RPC *rpc)
109 {
110 	RpcFree(rpc);
111 }
112 
113 // Release the RPC
RpcFree(RPC * rpc)114 void RpcFree(RPC *rpc)
115 {
116 	RpcFreeEx(rpc, false);
117 }
RpcFreeEx(RPC * rpc,bool no_disconnect)118 void RpcFreeEx(RPC *rpc, bool no_disconnect)
119 {
120 	// Validate arguments
121 	if (rpc == NULL)
122 	{
123 		return;
124 	}
125 
126 	if (no_disconnect == false)
127 	{
128 		Disconnect(rpc->Sock);
129 	}
130 
131 	ReleaseSock(rpc->Sock);
132 
133 	DeleteLock(rpc->Lock);
134 
135 	Free(rpc);
136 }
137 
138 // Get error
RpcGetError(PACK * p)139 UINT RpcGetError(PACK *p)
140 {
141 	// Validate arguments
142 	if (p == NULL)
143 	{
144 		return ERR_DISCONNECTED;
145 	}
146 
147 	return PackGetInt(p, "error_code");
148 }
149 
150 // Error checking
RpcIsOk(PACK * p)151 bool RpcIsOk(PACK *p)
152 {
153 	// Validate arguments
154 	if (p == NULL)
155 	{
156 		return false;
157 	}
158 
159 	if (PackGetInt(p, "error") == 0)
160 	{
161 		return true;
162 	}
163 	else
164 	{
165 		return false;
166 	}
167 }
168 
169 // Error code setting
RpcError(PACK * p,UINT err)170 void RpcError(PACK *p, UINT err)
171 {
172 	// Validate arguments
173 	if (p == NULL)
174 	{
175 		return;
176 	}
177 
178 	PackAddInt(p, "error", 1);
179 	PackAddInt(p, "error_code", err);
180 }
181 
182 // Start the RPC dispatcher
CallRpcDispatcher(RPC * r,PACK * p)183 PACK *CallRpcDispatcher(RPC *r, PACK *p)
184 {
185 	char func_name[MAX_SIZE];
186 	// Validate arguments
187 	if (r == NULL || p == NULL)
188 	{
189 		return NULL;
190 	}
191 
192 	if (PackGetStr(p, "function_name", func_name, sizeof(func_name)) == false)
193 	{
194 		return NULL;
195 	}
196 
197 	return r->Dispatch(r, func_name, p);
198 }
199 
200 // Wait for the next RPC call
RpcRecvNextCall(RPC * r)201 bool RpcRecvNextCall(RPC *r)
202 {
203 	UINT size;
204 	void *tmp;
205 	SOCK *s;
206 	BUF *b;
207 	PACK *p;
208 	PACK *ret;
209 	// Validate arguments
210 	if (r == NULL)
211 	{
212 		return false;
213 	}
214 
215 	s = r->Sock;
216 
217 	if (RecvAll(s, &size, sizeof(UINT), s->SecureMode) == false)
218 	{
219 		return false;
220 	}
221 
222 	size = Endian32(size);
223 
224 	if (size > MAX_PACK_SIZE)
225 	{
226 		return false;
227 	}
228 
229 	tmp = MallocEx(size, true);
230 
231 	if (RecvAll(s, tmp, size, s->SecureMode) == false)
232 	{
233 		Free(tmp);
234 		return false;
235 	}
236 
237 	b = NewBuf();
238 	WriteBuf(b, tmp, size);
239 	SeekBuf(b, 0, 0);
240 	Free(tmp);
241 
242 	p = BufToPack(b);
243 	FreeBuf(b);
244 
245 	if (p == NULL)
246 	{
247 		return false;
248 	}
249 
250 	ret = CallRpcDispatcher(r, p);
251 	FreePack(p);
252 
253 	if (ret == NULL)
254 	{
255 		ret = PackError(ERR_NOT_SUPPORTED);
256 	}
257 
258 	b = PackToBuf(ret);
259 	FreePack(ret);
260 
261 	size = Endian32(b->Size);
262 	SendAdd(s, &size, sizeof(UINT));
263 	SendAdd(s, b->Buf, b->Size);
264 
265 	if (SendNow(s, s->SecureMode) == false)
266 	{
267 		FreeBuf(b);
268 		return false;
269 	}
270 
271 	FreeBuf(b);
272 
273 	return true;
274 }
275 
276 // RPC server operation
RpcServer(RPC * r)277 void RpcServer(RPC *r)
278 {
279 	SOCK *s;
280 	// Validate arguments
281 	if (r == NULL)
282 	{
283 		return;
284 	}
285 
286 	s = r->Sock;
287 
288 	while (true)
289 	{
290 		// Wait for the next RPC call
291 		if (RpcRecvNextCall(r) == false)
292 		{
293 			// Communication error
294 			break;
295 		}
296 	}
297 }
298 
299 // RPC call
RpcCall(RPC * r,char * function_name,PACK * p)300 PACK *RpcCall(RPC *r, char *function_name, PACK *p)
301 {
302 	PACK *ret;
303 	UINT num_retry = 0;
304 	UINT err = 0;
305 	// Validate arguments
306 	if (r == NULL || function_name == NULL)
307 	{
308 		return NULL;
309 	}
310 
311 //	Debug("RpcCall: %s\n", function_name);
312 
313 	Lock(r->Lock);
314 	{
315 		if (p == NULL)
316 		{
317 			p = NewPack();
318 		}
319 
320 		PackAddStr(p, "function_name", function_name);
321 
322 RETRY:
323 		err = 0;
324 		ret = RpcCallInternal(r, p);
325 
326 		if (ret == NULL)
327 		{
328 			if (r->IsVpnServer && r->Sock != NULL)
329 			{
330 				if (num_retry < 1)
331 				{
332 					num_retry++;
333 
334 					// Attempt to reconnect the RPC to the VPN Server
335 					err = AdminReconnect(r);
336 
337 					if (err == ERR_NO_ERROR)
338 					{
339 						goto RETRY;
340 					}
341 				}
342 			}
343 		}
344 
345 		FreePack(p);
346 
347 		if (ret == NULL)
348 		{
349 			if (err == 0)
350 			{
351 				err = ERR_DISCONNECTED;
352 			}
353 
354 			ret = PackError(err);
355 			PackAddInt(ret, "error_code", err);
356 		}
357 	}
358 	Unlock(r->Lock);
359 
360 	return ret;
361 }
362 
363 // RPC internal call
RpcCallInternal(RPC * r,PACK * p)364 PACK *RpcCallInternal(RPC *r, PACK *p)
365 {
366 	BUF *b;
367 	UINT size;
368 	PACK *ret;
369 	void *tmp;
370 	// Validate arguments
371 	if (r == NULL || p == NULL)
372 	{
373 		return NULL;
374 	}
375 
376 	if (r->Sock == NULL)
377 	{
378 		return NULL;
379 	}
380 
381 	b = PackToBuf(p);
382 
383 	size = Endian32(b->Size);
384 	SendAdd(r->Sock, &size, sizeof(UINT));
385 	SendAdd(r->Sock, b->Buf, b->Size);
386 	FreeBuf(b);
387 
388 	if (SendNow(r->Sock, r->Sock->SecureMode) == false)
389 	{
390 		return NULL;
391 	}
392 
393 	if (RecvAll(r->Sock, &size, sizeof(UINT), r->Sock->SecureMode) == false)
394 	{
395 		return NULL;
396 	}
397 
398 	size = Endian32(size);
399 	if (size > MAX_PACK_SIZE)
400 	{
401 		return NULL;
402 	}
403 
404 	tmp = MallocEx(size, true);
405 	if (RecvAll(r->Sock, tmp, size, r->Sock->SecureMode) == false)
406 	{
407 		Free(tmp);
408 		return NULL;
409 	}
410 
411 	b = NewBuf();
412 	WriteBuf(b, tmp, size);
413 	SeekBuf(b, 0, 0);
414 	Free(tmp);
415 
416 	ret = BufToPack(b);
417 	if (ret == NULL)
418 	{
419 		FreeBuf(b);
420 		return NULL;
421 	}
422 
423 	FreeBuf(b);
424 
425 	return ret;
426 }
427 
428 // Start the RPC server
StartRpcServer(SOCK * s,RPC_DISPATCHER * dispatch,void * param)429 RPC *StartRpcServer(SOCK *s, RPC_DISPATCHER *dispatch, void *param)
430 {
431 	RPC *r;
432 	// Validate arguments
433 	if (s == NULL)
434 	{
435 		return NULL;
436 	}
437 
438 	r = ZeroMallocEx(sizeof(RPC), true);
439 	r->Sock = s;
440 	r->Param = param;
441 	r->Lock = NewLock();
442 	AddRef(s->ref);
443 
444 	r->ServerMode = true;
445 	r->Dispatch = dispatch;
446 
447 	// Name generation
448 	Format(r->Name, sizeof(r->Name), "RPC-%u", s->socket);
449 
450 	return r;
451 }
452 
453 // Start the RPC client
StartRpcClient(SOCK * s,void * param)454 RPC *StartRpcClient(SOCK *s, void *param)
455 {
456 	RPC *r;
457 	// Validate arguments
458 	if (s == NULL)
459 	{
460 		return NULL;
461 	}
462 
463 	r = ZeroMalloc(sizeof(RPC));
464 	r->Sock = s;
465 	r->Param = param;
466 	r->Lock = NewLock();
467 	AddRef(s->ref);
468 
469 	r->ServerMode = false;
470 
471 	return r;
472 }
473 
474