mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-18 12:40:00 +00:00
verify jump link for valid characters
This commit is contained in:
parent
c8ae15041f
commit
3286bdb4a7
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2023, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@ -28,6 +28,11 @@ namespace data
|
|||||||
return T32;
|
return T32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsBase32 (char ch)
|
||||||
|
{
|
||||||
|
return (ch >= 'a' && ch <= 'z') || (ch >= '2' && ch <= '7');
|
||||||
|
}
|
||||||
|
|
||||||
static void iT64Build(void);
|
static void iT64Build(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -55,6 +60,11 @@ namespace data
|
|||||||
return T64;
|
return T64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsBase64 (char ch)
|
||||||
|
{
|
||||||
|
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '-' || ch == '~';
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reverse Substitution Table (built in run time)
|
* Reverse Substitution Table (built in run time)
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
|
* Copyright (c) 2013-2023, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@ -19,9 +19,11 @@ namespace data {
|
|||||||
size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len );
|
size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len );
|
||||||
const char * GetBase32SubstitutionTable ();
|
const char * GetBase32SubstitutionTable ();
|
||||||
const char * GetBase64SubstitutionTable ();
|
const char * GetBase64SubstitutionTable ();
|
||||||
|
bool IsBase64 (char ch);
|
||||||
|
|
||||||
size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen);
|
size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen);
|
||||||
size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen);
|
size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen);
|
||||||
|
bool IsBase32 (char ch);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
|
* Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2022, The PurpleI2P Project
|
* Copyright (c) 2013-2023, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@ -403,10 +403,20 @@ namespace client
|
|||||||
if (!addr)
|
if (!addr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
i2p::data::IdentityEx ident;
|
auto pos = jump.find(".b32.i2p");
|
||||||
if (ident.FromBase64 (jump) && ident.GetIdentHash () == addr->identHash)
|
if (pos != std::string::npos)
|
||||||
return true;
|
{
|
||||||
|
i2p::data::IdentHash identHash;
|
||||||
|
if (identHash.FromBase32(jump.substr (0, pos)) && identHash == addr->identHash)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i2p::data::IdentityEx ident;
|
||||||
|
if (ident.FromBase64 (jump) && ident.GetIdentHash () == addr->identHash)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +75,9 @@ namespace proxy {
|
|||||||
void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered);
|
void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered);
|
||||||
void Terminate();
|
void Terminate();
|
||||||
void AsyncSockRead();
|
void AsyncSockRead();
|
||||||
bool ExtractAddressHelper(i2p::http::URL & url, std::string & b64, bool & confirm);
|
static bool ExtractAddressHelper(i2p::http::URL& url, std::string& jump, bool& confirm);
|
||||||
void SanitizeHTTPRequest(i2p::http::HTTPReq & req);
|
static bool VerifyAddressHelper (const std::string& jump);
|
||||||
|
static void SanitizeHTTPRequest(i2p::http::HTTPReq& req);
|
||||||
void SentHTTPFailed(const boost::system::error_code & ecode);
|
void SentHTTPFailed(const boost::system::error_code & ecode);
|
||||||
void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
|
void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
|
||||||
/* error helpers */
|
/* error helpers */
|
||||||
@ -221,7 +222,7 @@ namespace proxy {
|
|||||||
std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
|
std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HTTPReqHandler::ExtractAddressHelper(i2p::http::URL & url, std::string & b64, bool & confirm)
|
bool HTTPReqHandler::ExtractAddressHelper(i2p::http::URL& url, std::string& jump, bool& confirm)
|
||||||
{
|
{
|
||||||
confirm = false;
|
confirm = false;
|
||||||
const char *param = "i2paddresshelper=";
|
const char *param = "i2paddresshelper=";
|
||||||
@ -237,8 +238,13 @@ namespace proxy {
|
|||||||
|
|
||||||
std::string value = params["i2paddresshelper"];
|
std::string value = params["i2paddresshelper"];
|
||||||
len += value.length();
|
len += value.length();
|
||||||
b64 = i2p::http::UrlDecode(value);
|
jump = i2p::http::UrlDecode(value);
|
||||||
|
if (!VerifyAddressHelper (jump))
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "HTTPProxy: Malformed jump link ", jump);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// if we need update exists, request formed with update param
|
// if we need update exists, request formed with update param
|
||||||
if (params["update"] == "true")
|
if (params["update"] == "true")
|
||||||
{
|
{
|
||||||
@ -269,7 +275,26 @@ namespace proxy {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPReqHandler::SanitizeHTTPRequest(i2p::http::HTTPReq & req)
|
bool HTTPReqHandler::VerifyAddressHelper (const std::string& jump)
|
||||||
|
{
|
||||||
|
auto pos = jump.find(".b32.i2p");
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
auto b32 = jump.substr (0, pos);
|
||||||
|
for (auto& ch: b32)
|
||||||
|
if (!i2p::data::IsBase32(ch)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto& ch: jump)
|
||||||
|
if (!i2p::data::IsBase64(ch)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HTTPReqHandler::SanitizeHTTPRequest(i2p::http::HTTPReq& req)
|
||||||
{
|
{
|
||||||
/* drop common headers */
|
/* drop common headers */
|
||||||
req.RemoveHeader("Via");
|
req.RemoveHeader("Via");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user