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