Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/SoftEtherVPN/SoftEtherVPN_Stable.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/Cedar/Remote.c')
-rw-r--r--src/Cedar/Remote.c448
1 files changed, 448 insertions, 0 deletions
diff --git a/src/Cedar/Remote.c b/src/Cedar/Remote.c
new file mode 100644
index 00000000..b8ab70b8
--- /dev/null
+++ b/src/Cedar/Remote.c
@@ -0,0 +1,448 @@
+// SoftEther VPN Source Code
+// Cedar Communication Module
+//
+// SoftEther VPN Server, Client and Bridge are free software under GPLv2.
+//
+// Copyright (c) 2012-2014 Daiyuu Nobori.
+// Copyright (c) 2012-2014 SoftEther VPN Project, University of Tsukuba, Japan.
+// Copyright (c) 2012-2014 SoftEther Corporation.
+//
+// All Rights Reserved.
+//
+// http://www.softether.org/
+//
+// Author: Daiyuu Nobori
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+// Remote.c
+// Remote Procedure Call
+
+#include "CedarPch.h"
+
+// End of RPC
+void EndRpc(RPC *rpc)
+{
+ RpcFree(rpc);
+}
+
+// Release the RPC
+void RpcFree(RPC *rpc)
+{
+ // Validate arguments
+ if (rpc == NULL)
+ {
+ return;
+ }
+
+ Disconnect(rpc->Sock);
+ ReleaseSock(rpc->Sock);
+
+ DeleteLock(rpc->Lock);
+
+ Free(rpc);
+}
+
+// Get error
+UINT RpcGetError(PACK *p)
+{
+ // Validate arguments
+ if (p == NULL)
+ {
+ return ERR_DISCONNECTED;
+ }
+
+ return PackGetInt(p, "error_code");
+}
+
+// Error checking
+bool RpcIsOk(PACK *p)
+{
+ // Validate arguments
+ if (p == NULL)
+ {
+ return false;
+ }
+
+ if (PackGetInt(p, "error") == 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+// Error code setting
+void RpcError(PACK *p, UINT err)
+{
+ // Validate arguments
+ if (p == NULL)
+ {
+ return;
+ }
+
+ PackAddInt(p, "error", 1);
+ PackAddInt(p, "error_code", err);
+}
+
+// Start the RPC dispatcher
+PACK *CallRpcDispatcher(RPC *r, PACK *p)
+{
+ char func_name[MAX_SIZE];
+ // Validate arguments
+ if (r == NULL || p == NULL)
+ {
+ return NULL;
+ }
+
+ if (PackGetStr(p, "function_name", func_name, sizeof(func_name)) == false)
+ {
+ return NULL;
+ }
+
+ return r->Dispatch(r, func_name, p);
+}
+
+// Wait for the next RPC call
+bool RpcRecvNextCall(RPC *r)
+{
+ UINT size;
+ void *tmp;
+ SOCK *s;
+ BUF *b;
+ PACK *p;
+ PACK *ret;
+ // Validate arguments
+ if (r == NULL)
+ {
+ return false;
+ }
+
+ s = r->Sock;
+
+ if (RecvAll(s, &size, sizeof(UINT), s->SecureMode) == false)
+ {
+ return false;
+ }
+
+ size = Endian32(size);
+
+ if (size > MAX_PACK_SIZE)
+ {
+ return false;
+ }
+
+ tmp = MallocEx(size, true);
+
+ if (RecvAll(s, tmp, size, s->SecureMode) == false)
+ {
+ Free(tmp);
+ return false;
+ }
+
+ b = NewBuf();
+ WriteBuf(b, tmp, size);
+ SeekBuf(b, 0, 0);
+ Free(tmp);
+
+ p = BufToPack(b);
+ FreeBuf(b);
+
+ if (p == NULL)
+ {
+ return false;
+ }
+
+ ret = CallRpcDispatcher(r, p);
+ FreePack(p);
+
+ if (ret == NULL)
+ {
+ ret = PackError(ERR_NOT_SUPPORTED);
+ }
+
+ b = PackToBuf(ret);
+ FreePack(ret);
+
+ size = Endian32(b->Size);
+ SendAdd(s, &size, sizeof(UINT));
+ SendAdd(s, b->Buf, b->Size);
+
+ if (SendNow(s, s->SecureMode) == false)
+ {
+ FreeBuf(b);
+ return false;
+ }
+
+ FreeBuf(b);
+
+ return true;
+}
+
+// RPC server operation
+void RpcServer(RPC *r)
+{
+ SOCK *s;
+ // Validate arguments
+ if (r == NULL)
+ {
+ return;
+ }
+
+ s = r->Sock;
+
+ while (true)
+ {
+ // Wait for the next RPC call
+ if (RpcRecvNextCall(r) == false)
+ {
+ // Communication error
+ break;
+ }
+ }
+}
+
+// RPC call
+PACK *RpcCall(RPC *r, char *function_name, PACK *p)
+{
+ PACK *ret;
+ UINT num_retry = 0;
+ UINT err = 0;
+ // Validate arguments
+ if (r == NULL || function_name == NULL)
+ {
+ return NULL;
+ }
+
+// Debug("RpcCall: %s\n", function_name);
+
+ Lock(r->Lock);
+ {
+ if (p == NULL)
+ {
+ p = NewPack();
+ }
+
+ PackAddStr(p, "function_name", function_name);
+
+RETRY:
+ err = 0;
+ ret = RpcCallInternal(r, p);
+
+ if (ret == NULL)
+ {
+ if (r->IsVpnServer && r->Sock != NULL)
+ {
+ if (num_retry < 1)
+ {
+ num_retry++;
+
+ // Attempt to reconnect the RPC to the VPN Server
+ err = AdminReconnect(r);
+
+ if (err == ERR_NO_ERROR)
+ {
+ goto RETRY;
+ }
+ }
+ }
+ }
+
+ FreePack(p);
+
+ if (ret == NULL)
+ {
+ if (err == 0)
+ {
+ err = ERR_DISCONNECTED;
+ }
+
+ ret = PackError(err);
+ PackAddInt(ret, "error_code", err);
+ }
+ }
+ Unlock(r->Lock);
+
+ return ret;
+}
+
+// RPC internal call
+PACK *RpcCallInternal(RPC *r, PACK *p)
+{
+ BUF *b;
+ UINT size;
+ PACK *ret;
+ void *tmp;
+ // Validate arguments
+ if (r == NULL || p == NULL)
+ {
+ return NULL;
+ }
+
+ if (r->Sock == NULL)
+ {
+ return NULL;
+ }
+
+ b = PackToBuf(p);
+
+ size = Endian32(b->Size);
+ SendAdd(r->Sock, &size, sizeof(UINT));
+ SendAdd(r->Sock, b->Buf, b->Size);
+ FreeBuf(b);
+
+ if (SendNow(r->Sock, r->Sock->SecureMode) == false)
+ {
+ return NULL;
+ }
+
+ if (RecvAll(r->Sock, &size, sizeof(UINT), r->Sock->SecureMode) == false)
+ {
+ return NULL;
+ }
+
+ size = Endian32(size);
+ if (size > MAX_PACK_SIZE)
+ {
+ return NULL;
+ }
+
+ tmp = MallocEx(size, true);
+ if (RecvAll(r->Sock, tmp, size, r->Sock->SecureMode) == false)
+ {
+ Free(tmp);
+ return NULL;
+ }
+
+ b = NewBuf();
+ WriteBuf(b, tmp, size);
+ SeekBuf(b, 0, 0);
+ Free(tmp);
+
+ ret = BufToPack(b);
+ if (ret == NULL)
+ {
+ FreeBuf(b);
+ return NULL;
+ }
+
+ FreeBuf(b);
+
+ return ret;
+}
+
+// Start the RPC server
+RPC *StartRpcServer(SOCK *s, RPC_DISPATCHER *dispatch, void *param)
+{
+ RPC *r;
+ // Validate arguments
+ if (s == NULL)
+ {
+ return NULL;
+ }
+
+ r = ZeroMallocEx(sizeof(RPC), true);
+ r->Sock = s;
+ r->Param = param;
+ r->Lock = NewLock();
+ AddRef(s->ref);
+
+ r->ServerMode = true;
+ r->Dispatch = dispatch;
+
+ // Name generation
+ Format(r->Name, sizeof(r->Name), "RPC-%u", s->socket);
+
+ return r;
+}
+
+// Start the RPC client
+RPC *StartRpcClient(SOCK *s, void *param)
+{
+ RPC *r;
+ // Validate arguments
+ if (s == NULL)
+ {
+ return NULL;
+ }
+
+ r = ZeroMalloc(sizeof(RPC));
+ r->Sock = s;
+ r->Param = param;
+ r->Lock = NewLock();
+ AddRef(s->ref);
+
+ r->ServerMode = false;
+
+ return r;
+}
+
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/