Beispiel #1
0
PACK *WpcCallEx(char *url, INTERNET_SETTING *setting, UINT timeout_connect, UINT timeout_comm,
				char *function_name, PACK *pack, X *cert, K *key, void *sha1_cert_hash, bool *cancel, UINT max_recv_size,
				char *additional_header_name, char *additional_header_value)
{
	URL_DATA data;
	BUF *b, *recv;
	UINT error;
	WPC_PACKET packet;
	// Validate arguments
	if (function_name == NULL || pack == NULL)
	{
		return PackError(ERR_INTERNAL_ERROR);
	}

	if (ParseUrl(&data, url, true, NULL) == false)
	{
		return PackError(ERR_INTERNAL_ERROR);
	}

	PackAddStr(pack, "function", function_name);

	b = WpcGeneratePacket(pack, cert, key);
	if (b == NULL)
	{
		return PackError(ERR_INTERNAL_ERROR);
	}

	SeekBuf(b, b->Size, 0);
	WriteBufInt(b, 0);
	SeekBuf(b, 0, 0);

	if (IsEmptyStr(additional_header_name) == false && IsEmptyStr(additional_header_value) == false)
	{
		StrCpy(data.AdditionalHeaderName, sizeof(data.AdditionalHeaderName), additional_header_name);
		StrCpy(data.AdditionalHeaderValue, sizeof(data.AdditionalHeaderValue), additional_header_value);
	}

	recv = HttpRequestEx(&data, setting, timeout_connect, timeout_comm, &error,
		false, b->Buf, NULL, NULL, sha1_cert_hash, cancel, max_recv_size);

	FreeBuf(b);

	if (recv == NULL)
	{
		return PackError(error);
	}

	if (WpcParsePacket(&packet, recv) == false)
	{
		FreeBuf(recv);
		return PackError(ERR_PROTOCOL_ERROR);
	}

	FreeBuf(recv);

	FreeX(packet.Cert);

	return packet.Pack;
}
const PackReader::File & PackReader::getFile(const std::string & path){
    if (files.find(lowercase(path)) != files.end()){
        return files.find(lowercase(path))->second;
    }
    ostringstream out;
    out << "No such pak file '" << path << "'";
    throw PackError(__FILE__, __LINE__, out.str());
}
PackReader::PackReader(const Filesystem::AbsolutePath & filename):
filename(filename){
    ifstream stream;
    Global::debug(0) << "Reading pak file " << filename.path() << endl;
    stream.open(filename.path().c_str(), std::ios::in | std::ios::binary);
    Storage::LittleEndianReader reader(stream);
    uint32_t magic = reader.readByte4();
    if (magic != MAGIC){
        ostringstream error;
        error << filename.path() << " is not a packfile! " << std::hex << magic;
        throw PackError(__FILE__, __LINE__, error.str());
    } else {
        // cout << "Ok got a packfile" << endl;
    }
    uint32_t version = reader.readByte4();
    /* just assume we can read all versions for now */

    // cout << "Version is " << version << endl;
    reader.seekEnd(-4);
    uint32_t headerPosition = reader.readByte4();
    reader.seek(headerPosition);

    // cout << "Header at 0x" << std::hex << headerPosition << std::dec << endl;

    bool done = false;
    try{
        while (!done){
            uint32_t current = reader.position();
            uint32_t length = reader.readByte4();
            uint32_t start = reader.readByte4();
            uint32_t size = reader.readByte4();
            /* will read upto 80 bytes, but potentially fewer if a null byte
             * is reached.
             */
            string name = reader.readStringX(80);
            if (name.size() != 0){
                files[sanitizePath(name)] = File(start, size);
            }
            done = name.size() == 0;
            // cout << name << " at " << start << " size " << size << " length " << length << endl;
            // cout << " seek to " << (current + length) << endl;
            // reader.seek(current + length);
            done |= stream.eof();
        }
    } catch (const Storage::Eof & eof){
    }
    stream.close();

    handle.open(filename.path().c_str(), std::ios::in | std::ios::binary);
    Util::Thread::initializeLock(&readLock);
}
Beispiel #4
0
// Management thread
void NiAdminThread(THREAD *thread, void *param)
{
	NAT_ADMIN *a = (NAT_ADMIN *)param;
	NAT *n;
	SOCK *s;
	UCHAR random[SHA1_SIZE];
	UINT err;
	// Validate arguments
	if (thread == NULL || param == NULL)
	{
		return;
	}

	// Random number generation
	Rand(random, sizeof(random));

	a->Thread = thread;
	AddRef(a->Thread->ref);
	s = a->Sock;
	AddRef(s->ref);

	n = a->Nat;

	LockList(n->AdminList);
	{
		Add(n->AdminList, a);
	}
	UnlockList(n->AdminList);

	NoticeThreadInit(thread);

	err = ERR_AUTH_FAILED;

	if (StartSSL(s, n->AdminX, n->AdminK))
	{
		PACK *p;

		// Send the random number
		p = NewPack();
		PackAddData(p, "auth_random", random, sizeof(random));

		if (HttpServerSend(s, p))
		{
			PACK *p;
			// Receive a password
			p = HttpServerRecv(s);
			if (p != NULL)
			{
				UCHAR secure_password[SHA1_SIZE];
				UCHAR secure_check[SHA1_SIZE];

				if (PackGetData2(p, "secure_password", secure_password, sizeof(secure_password)))
				{
					SecurePassword(secure_check, n->HashedPassword, random);

					if (Cmp(secure_check, secure_password, SHA1_SIZE) == 0)
					{
						UCHAR test[SHA1_SIZE];
						// Password match
						Hash(test, "", 0, true);
						SecurePassword(test, test, random);

#if	0
						if (Cmp(test, secure_check, SHA1_SIZE) == 0 && s->RemoteIP.addr[0] != 127)
						{
							// A client can not connect from the outside with blank password
							err = ERR_NULL_PASSWORD_LOCAL_ONLY;
						}
						else
#endif

						{
							// Successful connection
							err = ERR_NO_ERROR;
							NiAdminMain(n, s);
						}
					}
				}

				FreePack(p);
			}
		}

		FreePack(p);

		if (err != ERR_NO_ERROR)
		{
			p = PackError(err);
			HttpServerSend(s, p);
			FreePack(p);
		}
	}

	Disconnect(s);
	ReleaseSock(s);
}
Beispiel #5
0
// 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;
}
Beispiel #6
0
// 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;
}
Beispiel #7
0
// 管理スレッド
void NiAdminThread(THREAD *thread, void *param)
{
	NAT_ADMIN *a = (NAT_ADMIN *)param;
	NAT *n;
	SOCK *s;
	UCHAR random[SHA1_SIZE];
	UINT err;
	// 引数チェック
	if (thread == NULL || param == NULL)
	{
		return;
	}

	// 乱数生成
	Rand(random, sizeof(random));

	a->Thread = thread;
	AddRef(a->Thread->ref);
	s = a->Sock;
	AddRef(s->ref);

	n = a->Nat;

	LockList(n->AdminList);
	{
		Add(n->AdminList, a);
	}
	UnlockList(n->AdminList);

	NoticeThreadInit(thread);

	err = ERR_AUTH_FAILED;

	if (StartSSL(s, n->AdminX, n->AdminK))
	{
		PACK *p;

		// 乱数を送信する
		p = NewPack();
		PackAddData(p, "auth_random", random, sizeof(random));

		if (HttpServerSend(s, p))
		{
			PACK *p;
			// パスワードを受け取る
			p = HttpServerRecv(s);
			if (p != NULL)
			{
				UCHAR secure_password[SHA1_SIZE];
				UCHAR secure_check[SHA1_SIZE];

				if (PackGetData2(p, "secure_password", secure_password, sizeof(secure_password)))
				{
					SecurePassword(secure_check, n->HashedPassword, random);

					if (Cmp(secure_check, secure_password, SHA1_SIZE) == 0)
					{
						UCHAR test[SHA1_SIZE];
						// パスワード一致
						Hash(test, "", 0, true);
						SecurePassword(test, test, random);

#if	0
						if (Cmp(test, secure_check, SHA1_SIZE) == 0 && s->RemoteIP.addr[0] != 127)
						{
							// 空白パスワードは外部から接続できない
							err = ERR_NULL_PASSWORD_LOCAL_ONLY;
						}
						else
#endif

						{
							// 接続成功
							err = ERR_NO_ERROR;
							NiAdminMain(n, s);
						}
					}
				}

				FreePack(p);
			}
		}

		FreePack(p);

		if (err != ERR_NO_ERROR)
		{
			p = PackError(err);
			HttpServerSend(s, p);
			FreePack(p);
		}
	}

	Disconnect(s);
	ReleaseSock(s);
}