mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	verify jump link for valid characters
This commit is contained in:
		
							parent
							
								
									c8ae15041f
								
							
						
					
					
						commit
						3286bdb4a7
					
				
					 4 changed files with 60 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
*
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +28,11 @@ namespace data
 | 
			
		|||
		return T32;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool IsBase32 (char ch)
 | 
			
		||||
	{
 | 
			
		||||
		return (ch >= 'a' && ch <= 'z') || (ch >= '2' && ch <= '7');
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	static void iT64Build(void);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
| 
						 | 
				
			
			@ -55,6 +60,11 @@ namespace data
 | 
			
		|||
		return T64;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool IsBase64 (char ch)
 | 
			
		||||
	{
 | 
			
		||||
		return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '-' || ch == '~';
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	/*
 | 
			
		||||
	* 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
 | 
			
		||||
*
 | 
			
		||||
| 
						 | 
				
			
			@ -19,9 +19,11 @@ namespace data {
 | 
			
		|||
	size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len );
 | 
			
		||||
	const char * GetBase32SubstitutionTable ();
 | 
			
		||||
	const char * GetBase64SubstitutionTable ();
 | 
			
		||||
	bool IsBase64 (char ch);
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
	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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
*
 | 
			
		||||
| 
						 | 
				
			
			@ -403,9 +403,19 @@ namespace client
 | 
			
		|||
		if (!addr)
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		i2p::data::IdentityEx ident;
 | 
			
		||||
		if (ident.FromBase64 (jump) && ident.GetIdentHash () == addr->identHash)
 | 
			
		||||
			return true;
 | 
			
		||||
		auto pos = jump.find(".b32.i2p");
 | 
			
		||||
		if (pos != std::string::npos)
 | 
			
		||||
		{
 | 
			
		||||
			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;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,8 +75,9 @@ namespace proxy {
 | 
			
		|||
			void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered);
 | 
			
		||||
			void Terminate();
 | 
			
		||||
			void AsyncSockRead();
 | 
			
		||||
			bool ExtractAddressHelper(i2p::http::URL & url, std::string & b64, bool & confirm);
 | 
			
		||||
			void SanitizeHTTPRequest(i2p::http::HTTPReq & req);
 | 
			
		||||
			static bool ExtractAddressHelper(i2p::http::URL& url, std::string& jump, bool& confirm);
 | 
			
		||||
			static bool VerifyAddressHelper (const std::string& jump);
 | 
			
		||||
			static void SanitizeHTTPRequest(i2p::http::HTTPReq& req);
 | 
			
		||||
			void SentHTTPFailed(const boost::system::error_code & ecode);
 | 
			
		||||
			void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
 | 
			
		||||
			/* error helpers */
 | 
			
		||||
| 
						 | 
				
			
			@ -221,7 +222,7 @@ namespace proxy {
 | 
			
		|||
			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;
 | 
			
		||||
		const char *param = "i2paddresshelper=";
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +238,12 @@ namespace proxy {
 | 
			
		|||
 | 
			
		||||
		std::string value = params["i2paddresshelper"];
 | 
			
		||||
		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 (params["update"] == "true")
 | 
			
		||||
| 
						 | 
				
			
			@ -269,7 +275,26 @@ namespace proxy {
 | 
			
		|||
		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 */
 | 
			
		||||
		req.RemoveHeader("Via");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue