From 7b00d828b2b26862920542f7dd428793869931ce Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 1 Jan 2018 08:28:42 -0500 Subject: [PATCH 01/29] fix lambda capture, don't capture copy --- libi2pd/Streaming.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 93cf2a9f..6c933752 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -334,7 +334,7 @@ namespace stream void Stream::AsyncReceive (const Buffer& buffer, ReceiveHandler handler, int timeout) { auto s = shared_from_this(); - m_Service.post ([=](void) + m_Service.post ([s, buffer, handler, timeout](void) { if (!s->m_ReceiveQueue.empty () || s->m_Status == eStreamStatusReset) s->HandleReceiveTimer (boost::asio::error::make_error_code (boost::asio::error::operation_aborted), buffer, handler, 0); From 938d5d901ace83d785cd546d74c068aa6a3f002b Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 2 Jan 2018 11:34:58 -0500 Subject: [PATCH 02/29] implement i2cp session reconfigure --- libi2pd/Destination.cpp | 40 ++++++++++++++++++++++++++++++ libi2pd/Destination.h | 4 +++ libi2pd/TunnelPool.cpp | 12 +++++++++ libi2pd/TunnelPool.h | 5 ++++ libi2pd_client/I2CP.cpp | 55 +++++++++++++++++++++++++++++++++++++++-- 5 files changed, 114 insertions(+), 2 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index cb42e480..160b95e6 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -169,6 +169,46 @@ namespace client return false; } + bool LeaseSetDestination::Reconfigure(std::map params) + { + + auto itr = params.find("i2cp.dontPublishLeaseSet"); + if (itr != params.end()) + { + m_IsPublic = itr->second != "true"; + } + + int inLen, outLen, inQuant, outQuant, numTags, minLatency, maxLatency; + std::map intOpts = { + {I2CP_PARAM_INBOUND_TUNNEL_LENGTH, inLen}, + {I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, outLen}, + {I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, inQuant}, + {I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, outQuant}, + {I2CP_PARAM_TAGS_TO_SEND, numTags}, + {I2CP_PARAM_MIN_TUNNEL_LATENCY, minLatency}, + {I2CP_PARAM_MAX_TUNNEL_LATENCY, maxLatency} + }; + + auto pool = GetTunnelPool(); + inLen = pool->GetNumInboundHops(); + outLen = pool->GetNumOutboundHops(); + inQuant = pool->GetNumInboundTunnels(); + outQuant = pool->GetNumOutboundTunnels(); + minLatency = 0; + maxLatency = 0; + + for (auto opt : intOpts) + { + itr = params.find(opt.first); + if(itr != params.end()) + { + opt.second = std::stoi(itr->second); + } + } + pool->RequireLatency(minLatency, maxLatency); + return pool->Reconfigure(inLen, outLen, inQuant, outQuant); + } + std::shared_ptr LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident) { std::shared_ptr remoteLS; diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 17daecb5..f93577e6 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -96,6 +96,10 @@ namespace client virtual bool Start (); virtual bool Stop (); + + /** i2cp reconfigure */ + virtual bool Reconfigure(std::map i2cpOpts); + bool IsRunning () const { return m_IsRunning; }; boost::asio::io_service& GetService () { return m_Service; }; std::shared_ptr GetTunnelPool () { return m_Pool; }; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index a3592708..dd163993 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -69,6 +69,18 @@ namespace tunnel m_Tests.clear (); } + bool TunnelPool::Reconfigure(int inHops, int outHops, int inQuant, int outQuant) { + if( inHops >= 0 && outHops >= 0 && inQuant > 0 && outQuant > 0) + { + m_NumInboundHops = inHops; + m_NumOutboundHops = outHops; + m_NumInboundTunnels = inQuant; + m_NumOutboundTunnels = outQuant; + return true; + } + return false; + } + void TunnelPool::TunnelCreated (std::shared_ptr createdTunnel) { if (!m_IsActive) return; diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 07c3024e..fc46930c 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -78,7 +78,12 @@ namespace tunnel int GetNumInboundTunnels () const { return m_NumInboundTunnels; }; int GetNumOutboundTunnels () const { return m_NumOutboundTunnels; }; + int GetNumInboundHops() const { return m_NumInboundHops; }; + int GetNumOutboundHops() const { return m_NumOutboundHops; }; + /** i2cp reconfigure */ + bool Reconfigure(int inboundHops, int outboundHops, int inboundQuant, int outboundQuant); + void SetCustomPeerSelector(ITunnelPeerSelector * selector); void UnsetCustomPeerSelector(); bool HasCustomPeerSelector(); diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index f98b1af3..293f4067 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -416,8 +416,59 @@ namespace client void I2CPSession::ReconfigureSessionMessageHandler (const uint8_t * buf, size_t len) { - // TODO: implement actual reconfiguration - SendSessionStatusMessage (2); // updated + uint8_t status = 3; // rejected + if(len > sizeof(uint16_t)) + { + uint16_t sessionID = bufbe16toh(buf); + if(sessionID == m_SessionID) + { + buf += sizeof(uint16_t); + const uint8_t * body = buf; + i2p::data::IdentityEx ident; + if(ident.FromBuffer(buf, len - sizeof(uint16_t))) + { + if (ident == *m_Destination->GetIdentity()) + { + size_t identsz = ident.GetFullLen(); + buf += identsz; + uint16_t optssize = bufbe16toh(buf); + if (optssize <= len - sizeof(uint16_t) - sizeof(uint64_t) - identsz - ident.GetSignatureLen() - sizeof(uint16_t)) + { + buf += sizeof(uint16_t); + std::map opts; + ExtractMapping(buf, optssize, opts); + buf += optssize; + //uint64_t date = bufbe64toh(buf); + buf += sizeof(uint64_t); + const uint8_t * sig = buf; + if(ident.Verify(body, len - sizeof(uint16_t), sig)) + { + if(m_Destination->Reconfigure(opts)) + { + LogPrint(eLogInfo, "I2CP: reconfigured destination"); + status = 2; // updated + } + else + LogPrint(eLogWarning, "I2CP: failed to reconfigure destination"); + } + else + LogPrint(eLogError, "I2CP: invalid reconfigure message signature"); + } + else + LogPrint(eLogError, "I2CP: mapping size missmatch"); + } + else + LogPrint(eLogError, "I2CP: destination missmatch"); + } + else + LogPrint(eLogError, "I2CP: malfromed destination"); + } + else + LogPrint(eLogError, "I2CP: session missmatch"); + } + else + LogPrint(eLogError, "I2CP: short message"); + SendSessionStatusMessage (status); } void I2CPSession::SendSessionStatusMessage (uint8_t status) From 254bf313a2e5cbc6fbcff656ea6c4da2c0eea24a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 2 Jan 2018 11:48:38 -0500 Subject: [PATCH 03/29] fix previous commit --- libi2pd_client/I2CP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 293f4067..5717ab50 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -441,7 +441,7 @@ namespace client //uint64_t date = bufbe64toh(buf); buf += sizeof(uint64_t); const uint8_t * sig = buf; - if(ident.Verify(body, len - sizeof(uint16_t), sig)) + if(ident.Verify(body, len - sizeof(uint16_t) - ident.GetSignatureLen(), sig)) { if(m_Destination->Reconfigure(opts)) { From ab80def94b3c5c53e3a250135922589dbda90d1f Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 2 Jan 2018 12:06:10 -0500 Subject: [PATCH 04/29] use reference instead of copy --- libi2pd/Destination.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 160b95e6..642be1f9 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -197,7 +197,7 @@ namespace client minLatency = 0; maxLatency = 0; - for (auto opt : intOpts) + for (auto & opt : intOpts) { itr = params.find(opt.first); if(itr != params.end()) From 1967dee50c48b474979aa6e532f5677182c86d0d Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 2 Jan 2018 12:59:16 -0500 Subject: [PATCH 05/29] don't recreate tunnels of different size --- libi2pd/Tunnel.cpp | 11 ++++++++--- libi2pd/TunnelPool.cpp | 28 ++++++++++++++++++---------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 6ae1e119..e39c4fd4 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -670,10 +670,12 @@ namespace tunnel { if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) { - tunnel->SetIsRecreated (); auto pool = tunnel->GetTunnelPool (); - if (pool) + if (pool && tunnel->GetPeers().size() == pool->GetNumOutboundHops()) + { + tunnel->SetIsRecreated (); pool->RecreateOutboundTunnel (tunnel); + } } if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) tunnel->SetState (eTunnelStateExpiring); @@ -723,8 +725,11 @@ namespace tunnel { tunnel->SetIsRecreated (); auto pool = tunnel->GetTunnelPool (); - if (pool) + if (pool && tunnel->GetPeers().size() == pool->GetNumInboundHops()) + { + tunnel->SetIsRecreated (); pool->RecreateInboundTunnel (tunnel); + } } if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index dd163993..7fc2592c 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -491,11 +491,14 @@ namespace tunnel outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel..."); std::shared_ptr config; - if (m_NumInboundHops > 0) config = std::make_shared(tunnel->GetPeers ()); - auto newTunnel = tunnels.CreateInboundTunnel (config, outboundTunnel); - newTunnel->SetTunnelPool (shared_from_this()); - if (newTunnel->IsEstablished ()) // zero hops - TunnelCreated (newTunnel); + if (m_NumInboundHops > 0 && tunnel->GetPeers().size() > 0) config = std::make_shared(tunnel->GetPeers ()); + if (m_NumInboundHops == 0 || config) + { + auto newTunnel = tunnels.CreateInboundTunnel (config, outboundTunnel); + newTunnel->SetTunnelPool (shared_from_this()); + if (newTunnel->IsEstablished ()) // zero hops + TunnelCreated (newTunnel); + } } void TunnelPool::CreateOutboundTunnel () @@ -533,12 +536,17 @@ namespace tunnel { LogPrint (eLogDebug, "Tunnels: Re-creating destination outbound tunnel..."); std::shared_ptr config; - if (m_NumOutboundHops > 0) + if (tunnel->GetPeers().size() > 0 && m_NumOutboundHops > 0) + { config = std::make_shared(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()); - auto newTunnel = tunnels.CreateOutboundTunnel (config); - newTunnel->SetTunnelPool (shared_from_this ()); - if (newTunnel->IsEstablished ()) // zero hops - TunnelCreated (newTunnel); + } + if(m_NumOutboundHops == 0 || config) + { + auto newTunnel = tunnels.CreateOutboundTunnel (config); + newTunnel->SetTunnelPool (shared_from_this ()); + if (newTunnel->IsEstablished ()) // zero hops + TunnelCreated (newTunnel); + } } else LogPrint (eLogDebug, "Tunnels: Can't re-create outbound tunnel, no inbound tunnels found"); From 80149342f252c1cb96c50c7835a53da12c9c2adb Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 3 Jan 2018 10:02:11 -0500 Subject: [PATCH 06/29] proper bounds check --- libi2pd/Garlic.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 3212da01..f9c297f6 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -538,7 +538,7 @@ namespace garlic { case eGarlicDeliveryTypeLocal: LogPrint (eLogDebug, "Garlic: type local"); - if (offset > (int)len) + if (offset > (int)len || offset <= 0) { LogPrint (eLogError, "Garlic: message is too short"); break; @@ -549,7 +549,7 @@ namespace garlic LogPrint (eLogDebug, "Garlic: type destination"); buf += 32; // destination. check it later or for multiple destinations offset = buf1 - buf; - if (offset > (int)len) + if (offset > (int)len || offset <= 0) { LogPrint (eLogError, "Garlic: message is too short"); break; @@ -563,7 +563,7 @@ namespace garlic uint8_t * gwHash = buf; buf += 32; offset = buf1 - buf; - if (offset + 4 > (int)len) + if (offset + 4 > (int)len || offset <= 0) { LogPrint (eLogError, "Garlic: message is too short"); break; @@ -594,7 +594,7 @@ namespace garlic offset = buf1 - buf; if (!from) // received directly { - if (offset > (int)len) + if (offset > (int)len || offset <= 0) { LogPrint (eLogError, "Garlic: message is too short"); break; @@ -609,7 +609,7 @@ namespace garlic default: LogPrint (eLogWarning, "Garlic: unknown delivery type ", (int)deliveryType); } - if (offset > (int)len) + if (offset > (int)len || offset <= 0) { LogPrint (eLogError, "Garlic: message is too short"); break; @@ -619,7 +619,7 @@ namespace garlic buf += 8; // Date buf += 3; // Certificate offset = buf1 - buf; - if (offset > (int)len) + if (offset > (int)len || offset <= 0) { LogPrint (eLogError, "Garlic: clove is too long"); break; From 29e861d1e6cb962ab35f255d61c27368894f6c1e Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 22 Feb 2018 06:54:33 -0500 Subject: [PATCH 07/29] fix issue #1124 --- libi2pd_client/I2PService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 21e1fdfa..0ba9d696 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -87,7 +87,7 @@ namespace client auto itr = m_ReadyCallbacks.begin(); while(itr != m_ReadyCallbacks.end()) { - if(itr->second >= now) + if(itr->second <= now) { itr->first(boost::asio::error::timed_out); itr = m_ReadyCallbacks.erase(itr); From ce9c9411b149d6defb9698a6038df3da68659b04 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 25 Feb 2018 08:47:39 -0500 Subject: [PATCH 08/29] fix issue #1126 --- libi2pd_client/SAM.cpp | 47 +++++++++++++++++++++++++++++++++++------- libi2pd_client/SAM.h | 1 + 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index f4736922..8865db85 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -107,6 +107,21 @@ namespace client std::placeholders::_1, std::placeholders::_2)); } + static bool SAMVersionAccceptable(const std::string & ver) + { + return ver == "3.0" || ver == "3.1"; + } + + static bool SAMVersionTooLow(const std::string & ver) + { + return ver.size() && ver[0] < '3'; + } + + static bool SAMVersionTooHigh(const std:::string & ver) + { + return ver.size() && ver > "3.1"; + } + void SAMSocket::HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) { if (ecode) @@ -132,19 +147,37 @@ namespace client if (!strcmp (m_Buffer, SAM_HANDSHAKE)) { - std::string version("3.0"); + std::string maxver("3.1"); + std::string minver("3.0"); // try to find MIN and MAX, 3.0 if not found if (separator) { separator++; std::map params; ExtractParams (separator, params); - //auto it = params.find (SAM_PARAM_MAX); - // TODO: check MIN as well - //if (it != params.end ()) - // version = it->second; + auto it = params.find (SAM_PARAM_MAX); + if (it != params.end ()) + maxver = it->second; + it = params.find(SAM_PARAM_MIN); + if (it != params.end ()) + minver = it->second; + } + // version negotiation + std::string version; + if (SAMVersionAcceptable(maxver)) + { + version = maxver; + } + else if (SAMVersionAcceptable(minver)) + { + version = minver; + } + else if (SAMVersionTooLow(minver) && SAMVersionIsTooHigh(maxver)) + { + version = "3.0"; } - if (version[0] == '3') // we support v3 (3.0 and 3.1) only + + if (SAMVersionAcceptable(version)) { #ifdef _MSC_VER size_t l = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ()); @@ -156,7 +189,7 @@ namespace client std::placeholders::_1, std::placeholders::_2)); } else - SendMessageReply (SAM_HANDSHAKE_I2P_ERROR, strlen (SAM_HANDSHAKE_I2P_ERROR), true); + SendMessageReply (SAM_HANDSHAKE_NOVERSION, strlen (SAM_HANDSHAKE_NOVERSION), true); } else { diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 931d0f2b..767be16d 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -23,6 +23,7 @@ namespace client const int SAM_SESSION_READINESS_CHECK_INTERVAL = 20; // in seconds const char SAM_HANDSHAKE[] = "HELLO VERSION"; const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=%s\n"; + const char SAM_HANDSHAKE_NOVERSION[] = "HELLO REPLY RESULT=NOVERSION\n"; const char SAM_HANDSHAKE_I2P_ERROR[] = "HELLO REPLY RESULT=I2P_ERROR\n"; const char SAM_SESSION_CREATE[] = "SESSION CREATE"; const char SAM_SESSION_CREATE_REPLY_OK[] = "SESSION STATUS RESULT=OK DESTINATION=%s\n"; From ce30f89c60094b0eb807db45bf417938bf08d6f3 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 25 Feb 2018 08:49:39 -0500 Subject: [PATCH 09/29] make it compile :D --- libi2pd_client/SAM.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 8865db85..5f668e39 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -107,7 +107,7 @@ namespace client std::placeholders::_1, std::placeholders::_2)); } - static bool SAMVersionAccceptable(const std::string & ver) + static bool SAMVersionAcceptable(const std::string & ver) { return ver == "3.0" || ver == "3.1"; } @@ -117,7 +117,7 @@ namespace client return ver.size() && ver[0] < '3'; } - static bool SAMVersionTooHigh(const std:::string & ver) + static bool SAMVersionTooHigh(const std::string & ver) { return ver.size() && ver > "3.1"; } @@ -172,7 +172,7 @@ namespace client { version = minver; } - else if (SAMVersionTooLow(minver) && SAMVersionIsTooHigh(maxver)) + else if (SAMVersionTooLow(minver) && SAMVersionTooHigh(maxver)) { version = "3.0"; } From 157411dcc6ff326647817c1d56d8b9b5c11ae9d5 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 25 Feb 2018 08:51:07 -0500 Subject: [PATCH 10/29] Revert "fix issue #1124" This reverts commit 29e861d1e6cb962ab35f255d61c27368894f6c1e. --- libi2pd_client/I2PService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 0ba9d696..21e1fdfa 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -87,7 +87,7 @@ namespace client auto itr = m_ReadyCallbacks.begin(); while(itr != m_ReadyCallbacks.end()) { - if(itr->second <= now) + if(itr->second >= now) { itr->first(boost::asio::error::timed_out); itr = m_ReadyCallbacks.erase(itr); From 0f77b4810ded4941f523b58c789738ece0e1a169 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 26 Feb 2018 08:00:07 -0500 Subject: [PATCH 11/29] revert --- libi2pd_client/I2CP.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 1a1026b4..361d9f94 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -434,14 +434,14 @@ namespace client uint16_t optssize = bufbe16toh(buf); if (optssize <= len - sizeof(uint16_t) - sizeof(uint64_t) - identsz - ident.GetSignatureLen() - sizeof(uint16_t)) { - buf += 2 + buf += sizeof(uint16_t); std::map opts; ExtractMapping(buf, optssize, opts); buf += optssize; //uint64_t date = bufbe64toh(buf); - buf += 8; + buf += sizeof(uint64_t); const uint8_t * sig = buf; - if(ident.Verify(body, len - 2 - ident.GetSignatureLen(), sig)) + if(ident.Verify(body, len - sizeof(uint16_t) - ident.GetSignatureLen(), sig)) { if(m_Destination->Reconfigure(opts)) { From 82a4630061ab6250dbcb9c5d6d482bb2d4c8a56c Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 26 Feb 2018 08:09:26 -0500 Subject: [PATCH 12/29] use correct function --- libi2pd/Tunnel.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 33a0bffe..73abc1a7 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -671,7 +671,8 @@ namespace tunnel if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) { auto pool = tunnel->GetTunnelPool (); - if (pool && tunnel->GetPeers().size() == pool->GetNumOutboundHops()) + // let it die if the tunnel pool has been reconfigured and this is old + if (pool && tunnel->GetTunnelConfig()->GetNumHops() == pool->GetNumOutboundHops()) { tunnel->SetIsRecreated (); pool->RecreateOutboundTunnel (tunnel); @@ -723,9 +724,9 @@ namespace tunnel { if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) { - tunnel->SetIsRecreated (); auto pool = tunnel->GetTunnelPool (); - if (pool && tunnel->GetPeers().size() == pool->GetNumInboundHops()) + // let it die if the tunnel pool was reconfigured and has different number of hops + if (pool && tunnel->GetTunnelConfig()->GetNumHops() == pool->GetNumInboundHops()) { tunnel->SetIsRecreated (); pool->RecreateInboundTunnel (tunnel); From 008a0647640acc64a29209b5abb7adad4cdef768 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 26 Feb 2018 08:12:15 -0500 Subject: [PATCH 13/29] revert --- libi2pd/Garlic.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index f3e946b6..59089072 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -538,7 +538,7 @@ namespace garlic { case eGarlicDeliveryTypeLocal: LogPrint (eLogDebug, "Garlic: type local"); - if (offset > (int)len || offset <= 0) + if (offset > (int)len) { LogPrint (eLogError, "Garlic: message is too short"); break; @@ -594,7 +594,7 @@ namespace garlic offset = buf - buf1; if (!from) // received directly { - if (offset > (int)len || offset <= 0) + if (offset > (int)len) { LogPrint (eLogError, "Garlic: message is too short"); break; @@ -609,7 +609,7 @@ namespace garlic default: LogPrint (eLogWarning, "Garlic: unknown delivery type ", (int)deliveryType); } - if (offset > (int)len || offset <= 0) + if (offset > (int)len) { LogPrint (eLogError, "Garlic: message is too short"); break; From 7b4fc19fca254e16047a1297fa3f8088e0ccc5b8 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 26 Feb 2018 08:18:01 -0500 Subject: [PATCH 14/29] be concise --- libi2pd/TunnelPool.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 197d1ebd..4f740a09 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -491,7 +491,10 @@ namespace tunnel outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel..."); std::shared_ptr config; - if (m_NumInboundHops > 0 && tunnel->GetPeers().size() > 0) config = std::make_shared(tunnel->GetPeers ()); + if (m_NumInboundHops > 0 && tunnel->GetPeers().size()) + { + config = std::make_shared(tunnel->GetPeers ()); + } if (m_NumInboundHops == 0 || config) { auto newTunnel = tunnels.CreateInboundTunnel (config, outboundTunnel); @@ -536,7 +539,7 @@ namespace tunnel { LogPrint (eLogDebug, "Tunnels: Re-creating destination outbound tunnel..."); std::shared_ptr config; - if (tunnel->GetPeers().size() > 0 && m_NumOutboundHops > 0) + if (m_NumOutboundHops > 0 && tunnel->GetPeers().size()) { config = std::make_shared(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()); } From 5a2b795440ecc90a806ea326ccfb7224f4f6bafe Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 26 Feb 2018 19:41:24 -0500 Subject: [PATCH 15/29] fixed crash --- libi2pd/Tunnel.cpp | 4 ++-- libi2pd/Tunnel.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 73abc1a7..c7e1b1b4 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -672,7 +672,7 @@ namespace tunnel { auto pool = tunnel->GetTunnelPool (); // let it die if the tunnel pool has been reconfigured and this is old - if (pool && tunnel->GetTunnelConfig()->GetNumHops() == pool->GetNumOutboundHops()) + if (pool && tunnel->GetNumHops() == pool->GetNumOutboundHops()) { tunnel->SetIsRecreated (); pool->RecreateOutboundTunnel (tunnel); @@ -726,7 +726,7 @@ namespace tunnel { auto pool = tunnel->GetTunnelPool (); // let it die if the tunnel pool was reconfigured and has different number of hops - if (pool && tunnel->GetTunnelConfig()->GetNumHops() == pool->GetNumInboundHops()) + if (pool && tunnel->GetNumHops() == pool->GetNumInboundHops()) { tunnel->SetIsRecreated (); pool->RecreateInboundTunnel (tunnel); diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 38beccaa..3244faad 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -105,6 +105,7 @@ namespace tunnel bool IsFailed () const { return m_State == eTunnelStateFailed; }; bool IsRecreated () const { return m_IsRecreated; }; void SetIsRecreated () { m_IsRecreated = true; }; + int GetNumHops () const { return m_Hops.size (); }; virtual bool IsInbound() const = 0; std::shared_ptr GetTunnelPool () const { return m_Pool; }; From 21545ab7da765f3d769a64ac53eb82bf0b712007 Mon Sep 17 00:00:00 2001 From: l-n-s Date: Sat, 3 Mar 2018 05:52:11 -0500 Subject: [PATCH 16/29] I2PControl: add new method ClientServicesInfo --- daemon/I2PControl.cpp | 190 ++++++++++++++++++++++++++++++++++++++++++ daemon/I2PControl.h | 12 +++ 2 files changed, 202 insertions(+) diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 494ea026..78121691 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -65,6 +65,7 @@ namespace client m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler; m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler; m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler; + m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler; // I2PControl m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler; @@ -92,6 +93,14 @@ namespace client // NetworkSetting m_NetworkSettingHandlers["i2p.router.net.bw.in"] = &I2PControlService::InboundBandwidthLimit; m_NetworkSettingHandlers["i2p.router.net.bw.out"] = &I2PControlService::OutboundBandwidthLimit; + + // ClientServicesInfo + m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler; + m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler; + m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler; + m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler; + m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler; + m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler; } I2PControlService::~I2PControlService () @@ -289,6 +298,13 @@ namespace client ss << "\"" << name << "\":" << std::fixed << std::setprecision(2) << value; } + void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, const boost::property_tree::ptree& value) const + { + std::ostringstream buf; + boost::property_tree::write_json (buf, value, false); + ss << "\"" << name << "\":" << buf.str(); + } + void I2PControlService::SendResponse (std::shared_ptr socket, std::shared_ptr buf, std::ostringstream& response, bool isHtml) { @@ -457,6 +473,7 @@ namespace client InsertParam (results, "i2p.router.net.total.sent.bytes", (double)i2p::transport::transports.GetTotalSentBytes ()); } + // RouterManager void I2PControlService::RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results) @@ -586,5 +603,178 @@ namespace client } EVP_PKEY_free (pkey); } + +// ClientServicesInfo + + void I2PControlService::ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results) + { + for (auto it = params.begin (); it != params.end (); it++) + { + LogPrint (eLogDebug, "I2PControl: ClientServicesInfo request: ", it->first); + auto it1 = m_ClientServicesInfoHandlers.find (it->first); + if (it1 != m_ClientServicesInfoHandlers.end ()) + { + if (it != params.begin ()) results << ","; + (this->*(it1->second))(results); + } + else + LogPrint (eLogError, "I2PControl: ClientServicesInfo unknown request ", it->first); + } + } + + void I2PControlService::I2PTunnelInfoHandler (std::ostringstream& results) + { + boost::property_tree::ptree pt; + boost::property_tree::ptree client_tunnels, server_tunnels; + + for (auto& it: i2p::client::context.GetClientTunnels ()) + { + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); + boost::property_tree::ptree ct; + ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + client_tunnels.add_child(it.second->GetName (), ct); + } + + auto& serverTunnels = i2p::client::context.GetServerTunnels (); + if (!serverTunnels.empty ()) { + for (auto& it: serverTunnels) + { + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); + boost::property_tree::ptree st; + st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + st.put("port", it.second->GetLocalPort ()); + server_tunnels.add_child(it.second->GetName (), st); + } + } + + auto& clientForwards = i2p::client::context.GetClientForwards (); + if (!clientForwards.empty ()) + { + for (auto& it: clientForwards) + { + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); + boost::property_tree::ptree ct; + ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + client_tunnels.add_child(it.second->GetName (), ct); + } + } + + auto& serverForwards = i2p::client::context.GetServerForwards (); + if (!serverForwards.empty ()) + { + for (auto& it: serverForwards) + { + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); + boost::property_tree::ptree st; + st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + server_tunnels.add_child(it.second->GetName (), st); + } + } + + pt.add_child("client", client_tunnels); + pt.add_child("server", server_tunnels); + + InsertParam (results, "I2PTunnel", pt); + } + + void I2PControlService::HTTPProxyInfoHandler (std::ostringstream& results) + { + boost::property_tree::ptree pt; + + auto httpProxy = i2p::client::context.GetHttpProxy (); + if (httpProxy) + { + auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash(); + pt.put("enabled", true); + pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + } + else + pt.put("enabled", false); + + InsertParam (results, "HTTPProxy", pt); + } + + void I2PControlService::SOCKSInfoHandler (std::ostringstream& results) + { + boost::property_tree::ptree pt; + + auto socksProxy = i2p::client::context.GetSocksProxy (); + if (socksProxy) + { + auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash(); + pt.put("enabled", true); + pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + } + else + pt.put("enabled", false); + + InsertParam (results, "SOCKS", pt); + } + + void I2PControlService::SAMInfoHandler (std::ostringstream& results) + { + boost::property_tree::ptree pt; + auto sam = i2p::client::context.GetSAMBridge (); + if (sam) + { + pt.put("enabled", true); + boost::property_tree::ptree sam_sessions; + for (auto& it: sam->GetSessions ()) + { + boost::property_tree::ptree sam_session, sam_session_sockets; + auto& name = it.second->localDestination->GetNickname (); + auto& ident = it.second->localDestination->GetIdentHash(); + sam_session.put("name", name); + sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + + for (const auto& socket: it.second->ListSockets()) + { + boost::property_tree::ptree stream; + stream.put("type", socket->GetSocketType ()); + stream.put("remote_endpoint", socket->GetSocket ().remote_endpoint()); + + sam_session_sockets.push_back(std::make_pair("", stream)); + } + sam_session.add_child("sockets", sam_session_sockets); + sam_sessions.add_child(it.first, sam_session); + } + + pt.add_child("sessions", sam_sessions); + } + else + pt.put("enabled", false); + + InsertParam (results, "SAM", pt); + } + + void I2PControlService::BOBInfoHandler (std::ostringstream& results) + { + boost::property_tree::ptree pt; + auto bob = i2p::client::context.GetBOBCommandChannel (); + if (bob) + { + /* TODO more info */ + pt.put("enabled", true); + } + else + pt.put("enabled", false); + + InsertParam (results, "BOB", pt); + } + + void I2PControlService::I2CPInfoHandler (std::ostringstream& results) + { + boost::property_tree::ptree pt; + auto i2cp = i2p::client::context.GetI2CPServer (); + if (i2cp) + { + /* TODO more info */ + pt.put("enabled", true); + } + else + pt.put("enabled", false); + + InsertParam (results, "I2CP", pt); + } } } diff --git a/daemon/I2PControl.h b/daemon/I2PControl.h index a7ed1eab..3233ad12 100644 --- a/daemon/I2PControl.h +++ b/daemon/I2PControl.h @@ -57,6 +57,7 @@ namespace client void InsertParam (std::ostringstream& ss, const std::string& name, int value) const; void InsertParam (std::ostringstream& ss, const std::string& name, double value) const; void InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value) const; + void InsertParam (std::ostringstream& ss, const std::string& name, const boost::property_tree::ptree& value) const; // methods typedef void (I2PControlService::*MethodHandler)(const boost::property_tree::ptree& params, std::ostringstream& results); @@ -67,6 +68,7 @@ namespace client void RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results); void RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results); void NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results); + void ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results); // I2PControl typedef void (I2PControlService::*I2PControlRequestHandler)(const std::string& value); @@ -98,6 +100,15 @@ namespace client void InboundBandwidthLimit (const std::string& value, std::ostringstream& results); void OutboundBandwidthLimit (const std::string& value, std::ostringstream& results); + // ClientServicesInfo + typedef void (I2PControlService::*ClientServicesInfoRequestHandler)(std::ostringstream& results); + void I2PTunnelInfoHandler (std::ostringstream& results); + void HTTPProxyInfoHandler (std::ostringstream& results); + void SOCKSInfoHandler (std::ostringstream& results); + void SAMInfoHandler (std::ostringstream& results); + void BOBInfoHandler (std::ostringstream& results); + void I2CPInfoHandler (std::ostringstream& results); + private: std::string m_Password; @@ -115,6 +126,7 @@ namespace client std::map m_RouterInfoHandlers; std::map m_RouterManagerHandlers; std::map m_NetworkSettingHandlers; + std::map m_ClientServicesInfoHandlers; }; } } From 12292afdec5e7636e1662a3535e7bbeed3b56738 Mon Sep 17 00:00:00 2001 From: l-n-s Date: Sun, 4 Mar 2018 11:28:09 -0500 Subject: [PATCH 17/29] I2PControl: s/remote_endpoint/peer --- daemon/I2PControl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 78121691..39c2d3d2 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -731,7 +731,7 @@ namespace client { boost::property_tree::ptree stream; stream.put("type", socket->GetSocketType ()); - stream.put("remote_endpoint", socket->GetSocket ().remote_endpoint()); + stream.put("peer", socket->GetSocket ().remote_endpoint()); sam_session_sockets.push_back(std::make_pair("", stream)); } From 18d3c81018788adbbe566ebaff7861c63bb9b9be Mon Sep 17 00:00:00 2001 From: yangfl Date: Mon, 5 Mar 2018 00:51:53 +0800 Subject: [PATCH 18/29] Makefile: add detection for GNU userspace --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 460b16e4..6d56ec7d 100644 --- a/Makefile +++ b/Makefile @@ -30,12 +30,12 @@ ifneq (, $(findstring darwin, $(SYS))) else include Makefile.osx endif +else ifneq (, $(findstring linux, $(SYS))$(findstring gnu, $(SYS))) + DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp + include Makefile.linux else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS))) DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp include Makefile.bsd -else ifneq (, $(findstring linux, $(SYS))) - DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp - include Makefile.linux else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS))) DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp include Makefile.mingw From 6d15be9a32989b0d00312a5b2589e36ba0ea7836 Mon Sep 17 00:00:00 2001 From: Fabrice Fontaine Date: Sun, 4 Mar 2018 18:29:13 +0100 Subject: [PATCH 19/29] Fix cmake error when -DBUILD_SHARED_LIBS=ON Fixes "CMake Error: TARGETS given no LIBRARY DESTINATION for shared library target" by adding LIBRARY parameter to INSTALL call Signed-off-by: Fabrice Fontaine --- build/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 4f875b33..a1c8957b 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -97,6 +97,7 @@ set_target_properties(libi2pd PROPERTIES PREFIX "") install(TARGETS libi2pd EXPORT libi2pd ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib COMPONENT Libraries) # TODO Make libi2pd available to 3rd party projects via CMake as imported target # FIXME This pulls stdafx From 1d934bd543360bfdd40e1501d16d8beb2016ccd8 Mon Sep 17 00:00:00 2001 From: Fabrice Fontaine Date: Mon, 5 Mar 2018 14:55:54 +0100 Subject: [PATCH 20/29] Install libi2pdclient When building with -DBUILD_SHARED_LIBS=ON, libi2pdclient is not installed on target so install it by calling install. Moreover, rename i2pdclient to libi2pdclient so library is installed with correct name. Signed-off-by: Fabrice Fontaine --- build/CMakeLists.txt | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index a1c8957b..364c3304 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -120,7 +120,13 @@ set (CLIENT_SRC if(WITH_WEBSOCKETS) list (APPEND CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/Websocket.cpp") endif () -add_library(i2pdclient ${CLIENT_SRC}) +add_library(libi2pdclient ${CLIENT_SRC}) +set_target_properties(libi2pdclient PROPERTIES PREFIX "") +install(TARGETS libi2pdclient + EXPORT libi2pdclient + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + COMPONENT Libraries) set(DAEMON_SRC_DIR ../daemon) @@ -304,7 +310,7 @@ if (WITH_PCH) WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) target_compile_options(libi2pd PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$/stdafx.pch") - target_compile_options(i2pdclient PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$/stdafx.pch") + target_compile_options(libi2pdclient PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$/stdafx.pch") else() string(TOUPPER ${CMAKE_BUILD_TYPE} BTU) get_directory_property(DEFS DEFINITIONS) @@ -313,12 +319,12 @@ if (WITH_PCH) COMMAND ${CMAKE_CXX_COMPILER} ${FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/../libi2pd/stdafx.h -o ${CMAKE_BINARY_DIR}/stdafx.h.gch ) target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h) - target_compile_options(i2pdclient PRIVATE -include libi2pd/stdafx.h) + target_compile_options(libi2pdclient PRIVATE -include libi2pd/stdafx.h) endif() target_link_libraries(libi2pd stdafx) endif() -target_link_libraries(i2pdclient libi2pd) +target_link_libraries(libi2pdclient libi2pd) find_package ( Boost COMPONENTS system filesystem program_options date_time REQUIRED ) if(NOT DEFINED Boost_INCLUDE_DIRS) @@ -451,7 +457,7 @@ if (WITH_BINARY) if (WITH_STATIC) set(DL_LIB ${CMAKE_DL_LIBS}) endif() - target_link_libraries( "${PROJECT_NAME}" libi2pd i2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) + target_link_libraries( "${PROJECT_NAME}" libi2pd libi2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) set (APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") From 2661db23f61f52d4d3bb7024b82dfa34b4de2b93 Mon Sep 17 00:00:00 2001 From: l-n-s Date: Mon, 5 Mar 2018 12:34:41 -0500 Subject: [PATCH 21/29] I2PControl: fix indentation --- daemon/I2PControl.cpp | 270 +++++++++++++++++++++--------------------- 1 file changed, 135 insertions(+), 135 deletions(-) diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 39c2d3d2..fcff78cd 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -299,11 +299,11 @@ namespace client } void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, const boost::property_tree::ptree& value) const - { - std::ostringstream buf; - boost::property_tree::write_json (buf, value, false); - ss << "\"" << name << "\":" << buf.str(); - } + { + std::ostringstream buf; + boost::property_tree::write_json (buf, value, false); + ss << "\"" << name << "\":" << buf.str(); + } void I2PControlService::SendResponse (std::shared_ptr socket, std::shared_ptr buf, std::ostringstream& response, bool isHtml) @@ -624,157 +624,157 @@ namespace client void I2PControlService::I2PTunnelInfoHandler (std::ostringstream& results) { - boost::property_tree::ptree pt; - boost::property_tree::ptree client_tunnels, server_tunnels; - - for (auto& it: i2p::client::context.GetClientTunnels ()) - { - auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - boost::property_tree::ptree ct; - ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); - client_tunnels.add_child(it.second->GetName (), ct); - } - - auto& serverTunnels = i2p::client::context.GetServerTunnels (); - if (!serverTunnels.empty ()) { - for (auto& it: serverTunnels) - { - auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - boost::property_tree::ptree st; - st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); - st.put("port", it.second->GetLocalPort ()); - server_tunnels.add_child(it.second->GetName (), st); - } - } - - auto& clientForwards = i2p::client::context.GetClientForwards (); - if (!clientForwards.empty ()) - { - for (auto& it: clientForwards) - { - auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - boost::property_tree::ptree ct; - ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); - client_tunnels.add_child(it.second->GetName (), ct); - } - } - - auto& serverForwards = i2p::client::context.GetServerForwards (); - if (!serverForwards.empty ()) - { - for (auto& it: serverForwards) - { - auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - boost::property_tree::ptree st; - st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); - server_tunnels.add_child(it.second->GetName (), st); - } - } - - pt.add_child("client", client_tunnels); - pt.add_child("server", server_tunnels); - - InsertParam (results, "I2PTunnel", pt); + boost::property_tree::ptree pt; + boost::property_tree::ptree client_tunnels, server_tunnels; + + for (auto& it: i2p::client::context.GetClientTunnels ()) + { + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); + boost::property_tree::ptree ct; + ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + client_tunnels.add_child(it.second->GetName (), ct); + } + + auto& serverTunnels = i2p::client::context.GetServerTunnels (); + if (!serverTunnels.empty ()) { + for (auto& it: serverTunnels) + { + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); + boost::property_tree::ptree st; + st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + st.put("port", it.second->GetLocalPort ()); + server_tunnels.add_child(it.second->GetName (), st); + } + } + + auto& clientForwards = i2p::client::context.GetClientForwards (); + if (!clientForwards.empty ()) + { + for (auto& it: clientForwards) + { + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); + boost::property_tree::ptree ct; + ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + client_tunnels.add_child(it.second->GetName (), ct); + } + } + + auto& serverForwards = i2p::client::context.GetServerForwards (); + if (!serverForwards.empty ()) + { + for (auto& it: serverForwards) + { + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); + boost::property_tree::ptree st; + st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + server_tunnels.add_child(it.second->GetName (), st); + } + } + + pt.add_child("client", client_tunnels); + pt.add_child("server", server_tunnels); + + InsertParam (results, "I2PTunnel", pt); } void I2PControlService::HTTPProxyInfoHandler (std::ostringstream& results) { - boost::property_tree::ptree pt; + boost::property_tree::ptree pt; - auto httpProxy = i2p::client::context.GetHttpProxy (); - if (httpProxy) - { - auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash(); - pt.put("enabled", true); - pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); - } - else - pt.put("enabled", false); + auto httpProxy = i2p::client::context.GetHttpProxy (); + if (httpProxy) + { + auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash(); + pt.put("enabled", true); + pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + } + else + pt.put("enabled", false); - InsertParam (results, "HTTPProxy", pt); - } + InsertParam (results, "HTTPProxy", pt); + } void I2PControlService::SOCKSInfoHandler (std::ostringstream& results) { - boost::property_tree::ptree pt; + boost::property_tree::ptree pt; - auto socksProxy = i2p::client::context.GetSocksProxy (); - if (socksProxy) - { - auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash(); - pt.put("enabled", true); - pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); - } - else - pt.put("enabled", false); + auto socksProxy = i2p::client::context.GetSocksProxy (); + if (socksProxy) + { + auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash(); + pt.put("enabled", true); + pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + } + else + pt.put("enabled", false); - InsertParam (results, "SOCKS", pt); - } + InsertParam (results, "SOCKS", pt); + } void I2PControlService::SAMInfoHandler (std::ostringstream& results) { - boost::property_tree::ptree pt; - auto sam = i2p::client::context.GetSAMBridge (); - if (sam) - { - pt.put("enabled", true); - boost::property_tree::ptree sam_sessions; - for (auto& it: sam->GetSessions ()) + boost::property_tree::ptree pt; + auto sam = i2p::client::context.GetSAMBridge (); + if (sam) { - boost::property_tree::ptree sam_session, sam_session_sockets; - auto& name = it.second->localDestination->GetNickname (); - auto& ident = it.second->localDestination->GetIdentHash(); - sam_session.put("name", name); - sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); - - for (const auto& socket: it.second->ListSockets()) - { - boost::property_tree::ptree stream; - stream.put("type", socket->GetSocketType ()); - stream.put("peer", socket->GetSocket ().remote_endpoint()); - - sam_session_sockets.push_back(std::make_pair("", stream)); - } - sam_session.add_child("sockets", sam_session_sockets); - sam_sessions.add_child(it.first, sam_session); - } - - pt.add_child("sessions", sam_sessions); - } - else - pt.put("enabled", false); - - InsertParam (results, "SAM", pt); - } + pt.put("enabled", true); + boost::property_tree::ptree sam_sessions; + for (auto& it: sam->GetSessions ()) + { + boost::property_tree::ptree sam_session, sam_session_sockets; + auto& name = it.second->localDestination->GetNickname (); + auto& ident = it.second->localDestination->GetIdentHash(); + sam_session.put("name", name); + sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); + + for (const auto& socket: it.second->ListSockets()) + { + boost::property_tree::ptree stream; + stream.put("type", socket->GetSocketType ()); + stream.put("peer", socket->GetSocket ().remote_endpoint()); + + sam_session_sockets.push_back(std::make_pair("", stream)); + } + sam_session.add_child("sockets", sam_session_sockets); + sam_sessions.add_child(it.first, sam_session); + } + + pt.add_child("sessions", sam_sessions); + } + else + pt.put("enabled", false); + + InsertParam (results, "SAM", pt); + } void I2PControlService::BOBInfoHandler (std::ostringstream& results) { - boost::property_tree::ptree pt; - auto bob = i2p::client::context.GetBOBCommandChannel (); - if (bob) - { - /* TODO more info */ - pt.put("enabled", true); - } - else - pt.put("enabled", false); + boost::property_tree::ptree pt; + auto bob = i2p::client::context.GetBOBCommandChannel (); + if (bob) + { + /* TODO more info */ + pt.put("enabled", true); + } + else + pt.put("enabled", false); - InsertParam (results, "BOB", pt); - } + InsertParam (results, "BOB", pt); + } void I2PControlService::I2CPInfoHandler (std::ostringstream& results) { - boost::property_tree::ptree pt; - auto i2cp = i2p::client::context.GetI2CPServer (); - if (i2cp) - { - /* TODO more info */ - pt.put("enabled", true); - } - else - pt.put("enabled", false); - - InsertParam (results, "I2CP", pt); - } + boost::property_tree::ptree pt; + auto i2cp = i2p::client::context.GetI2CPServer (); + if (i2cp) + { + /* TODO more info */ + pt.put("enabled", true); + } + else + pt.put("enabled", false); + + InsertParam (results, "I2CP", pt); + } } } From b0781668e2e51ba4820bff5e0f0bcc5eaa4be441 Mon Sep 17 00:00:00 2001 From: Fabrice Fontaine Date: Mon, 5 Mar 2018 18:30:02 +0100 Subject: [PATCH 22/29] Create LogsDirectory in i2pd.service Create /var/log/i2pd through LogsDirectory parameter of systemd and set its permission to 0700 through LogsDirectoryMode. Indeed, this directory must be created with the correct permission as it is used in ExecStart command Signed-off-by: Fabrice Fontaine --- contrib/i2pd.service | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/i2pd.service b/contrib/i2pd.service index 5ed31d41..9af96c37 100644 --- a/contrib/i2pd.service +++ b/contrib/i2pd.service @@ -8,6 +8,8 @@ User=i2pd Group=i2pd RuntimeDirectory=i2pd RuntimeDirectoryMode=0700 +LogsDirectory=i2pd +LogsDirectoryMode=0700 Type=simple ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service ExecReload=/bin/kill -HUP $MAINPID From e58aaa3f32cb80bfbcd7eba0cd1f5a10c017e8ae Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Mar 2018 12:36:38 -0500 Subject: [PATCH 23/29] make sure tunnelID is non-zero --- libi2pd/TunnelConfig.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 7267fc30..9707fa17 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -35,6 +35,7 @@ namespace tunnel RAND_bytes (replyKey, 32); RAND_bytes (replyIV, 16); RAND_bytes ((uint8_t *)&tunnelID, 4); + if (!tunnelID) tunnelID = 1; // tunnelID can't be zero isGateway = true; isEndpoint = true; ident = r; @@ -50,6 +51,7 @@ namespace tunnel nextIdent = ident; isEndpoint = false; RAND_bytes ((uint8_t *)&nextTunnelID, 4); + if (!nextTunnelID) nextTunnelID = 1; // tunnelID can't be zero } void SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent) From 066f8863fddb5135d9ccce2ccb56016bb583f861 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Mar 2018 16:08:44 -0500 Subject: [PATCH 24/29] pass zero padding parameter to ECEIS encryption --- libi2pd/Crypto.cpp | 47 +++++++++++++++++++++++++++++++++---------- libi2pd/Crypto.h | 4 ++-- libi2pd/CryptoKey.cpp | 8 ++++---- 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index d7d5adf6..5ba3334d 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -373,7 +373,7 @@ namespace crypto } // ECIES - void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) + void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) { BN_CTX_start (ctx); BIGNUM * q = BN_CTX_get (ctx); @@ -386,10 +386,19 @@ namespace crypto EC_POINT_mul (curve, p, k, nullptr, nullptr, ctx); BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx); EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr); - encrypted[0] = 0; - bn2buf (x, encrypted + 1, len); - bn2buf (y, encrypted + 1 + len, len); - RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len); + if (zeroPadding) + { + encrypted[0] = 0; + bn2buf (x, encrypted + 1, len); + bn2buf (y, encrypted + 1 + len, len); + RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len); + } + else + { + bn2buf (x, encrypted, len); + bn2buf (y, encrypted + len, len); + RAND_bytes (encrypted + 2*len, 256 - 2*len); + } // ecryption key and iv EC_POINT_mul (curve, p, nullptr, key, k, ctx); EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr); @@ -403,16 +412,21 @@ namespace crypto memcpy (m+33, data, 222); SHA256 (m+33, 222, m+1); // encrypt - encrypted[257] = 0; CBCEncryption encryption; encryption.SetKey (shared); encryption.SetIV (iv); - encryption.Encrypt (m, 256, encrypted + 258); + if (zeroPadding) + { + encrypted[257] = 0; + encryption.Encrypt (m, 256, encrypted + 258); + } + else + encryption.Encrypt (m, 256, encrypted + 256); EC_POINT_free (p); BN_CTX_end (ctx); } - bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) { bool ret = true; BN_CTX_start (ctx); @@ -421,8 +435,16 @@ namespace crypto int len = BN_num_bytes (q); // point for shared secret BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx); - BN_bin2bn (encrypted + 1, len, x); - BN_bin2bn (encrypted + 1 + len, len, y); + if (zeroPadding) + { + BN_bin2bn (encrypted + 1, len, x); + BN_bin2bn (encrypted + 1 + len, len, y); + } + else + { + BN_bin2bn (encrypted, len, x); + BN_bin2bn (encrypted + len, len, y); + } auto p = EC_POINT_new (curve); if (EC_POINT_set_affine_coordinates_GFp (curve, p, x, y, nullptr)) { @@ -439,7 +461,10 @@ namespace crypto CBCDecryption decryption; decryption.SetKey (shared); decryption.SetIV (iv); - decryption.Decrypt (encrypted + 258, 256, m); + if (zeroPadding) + decryption.Decrypt (encrypted + 258, 256, m); + else + decryption.Decrypt (encrypted + 256, 256, m); // verify and copy uint8_t hash[32]; SHA256 (m + 33, 222, hash); diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index b833ff19..6e4ddb3d 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -54,8 +54,8 @@ namespace crypto void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub); // ECIES - void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); // 222 bytes data, 514 bytes encrypted - bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); + void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without + bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false); void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub); // HMAC diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 4be230f7..cd6952a0 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -47,7 +47,7 @@ namespace crypto void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) { if (m_Curve && m_PublicKey) - ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, ctx); + ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, ctx, true); } ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv) @@ -65,7 +65,7 @@ namespace crypto bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) { if (m_Curve && m_PrivateKey) - return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx); + return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx, true); return false; } @@ -107,7 +107,7 @@ namespace crypto void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) { if (m_PublicKey) - ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, ctx); + ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, ctx, true); } ECIESGOSTR3410Decryptor::ECIESGOSTR3410Decryptor (const uint8_t * priv) @@ -123,7 +123,7 @@ namespace crypto bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) { if (m_PrivateKey) - return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx); + return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx, true); return false; } From 182ffe44954e76fe443e30b5d45509d9864a1192 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 9 Mar 2018 14:56:06 -0500 Subject: [PATCH 25/29] use croorect encryption type for tunnel build --- libi2pd/CryptoKey.cpp | 24 ++++++++++++------------ libi2pd/CryptoKey.h | 16 ++++++++-------- libi2pd/Destination.cpp | 2 +- libi2pd/I2NPProtocol.cpp | 2 +- libi2pd/LeaseSet.cpp | 2 +- libi2pd/RouterContext.cpp | 7 ++++++- libi2pd/RouterContext.h | 1 + libi2pd/RouterInfo.cpp | 2 +- libi2pd/TunnelConfig.h | 5 +++-- libi2pd_client/I2CP.cpp | 2 +- 10 files changed, 35 insertions(+), 28 deletions(-) diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index cd6952a0..711d4ce6 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -12,9 +12,9 @@ namespace crypto memcpy (m_PublicKey, pub, 256); } - void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) + void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) { - ElGamalEncrypt (m_PublicKey, data, encrypted, ctx, true); + ElGamalEncrypt (m_PublicKey, data, encrypted, ctx, zeroPadding); } ElGamalDecryptor::ElGamalDecryptor (const uint8_t * priv) @@ -22,9 +22,9 @@ namespace crypto memcpy (m_PrivateKey, priv, 256); } - bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) { - return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx, true); + return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx, zeroPadding); } ECIESP256Encryptor::ECIESP256Encryptor (const uint8_t * pub) @@ -44,10 +44,10 @@ namespace crypto if (m_PublicKey) EC_POINT_free (m_PublicKey); } - void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) + void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) { if (m_Curve && m_PublicKey) - ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, ctx, true); + ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, ctx, zeroPadding); } ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv) @@ -62,10 +62,10 @@ namespace crypto if (m_PrivateKey) BN_free (m_PrivateKey); } - bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) { if (m_Curve && m_PrivateKey) - return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx, true); + return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx, zeroPadding); return false; } @@ -104,10 +104,10 @@ namespace crypto if (m_PublicKey) EC_POINT_free (m_PublicKey); } - void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) + void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) { if (m_PublicKey) - ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, ctx, true); + ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, ctx, zeroPadding); } ECIESGOSTR3410Decryptor::ECIESGOSTR3410Decryptor (const uint8_t * priv) @@ -120,10 +120,10 @@ namespace crypto if (m_PrivateKey) BN_free (m_PrivateKey); } - bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) { if (m_PrivateKey) - return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx, true); + return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx, zeroPadding); return false; } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index ece86eb0..0dff7584 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -13,7 +13,7 @@ namespace crypto public: virtual ~CryptoKeyEncryptor () {}; - virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) = 0; // 222 bytes data, 512 bytes encrypted + virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) = 0; // 222 bytes data, 512/514 bytes encrypted }; class CryptoKeyDecryptor @@ -21,7 +21,7 @@ namespace crypto public: virtual ~CryptoKeyDecryptor () {}; - virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) = 0; // 512 bytes encrypted, 222 bytes data + virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) = 0; // 512/514 bytes encrypted, 222 bytes data }; // ElGamal @@ -30,7 +30,7 @@ namespace crypto public: ElGamalEncryptor (const uint8_t * pub); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); + void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding); private: @@ -42,7 +42,7 @@ namespace crypto public: ElGamalDecryptor (const uint8_t * priv); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); private: @@ -57,7 +57,7 @@ namespace crypto ECIESP256Encryptor (const uint8_t * pub); ~ECIESP256Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); + void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding); private: @@ -72,7 +72,7 @@ namespace crypto ECIESP256Decryptor (const uint8_t * priv); ~ECIESP256Decryptor (); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); private: @@ -90,7 +90,7 @@ namespace crypto ECIESGOSTR3410Encryptor (const uint8_t * pub); ~ECIESGOSTR3410Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); + void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding); private: @@ -104,7 +104,7 @@ namespace crypto ECIESGOSTR3410Decryptor (const uint8_t * priv); ~ECIESGOSTR3410Decryptor (); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); private: diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index b191cbf1..bafd49da 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1024,7 +1024,7 @@ namespace client bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const { if (m_Decryptor) - return m_Decryptor->Decrypt (encrypted, data, ctx); + return m_Decryptor->Decrypt (encrypted, data, ctx, true); else LogPrint (eLogError, "Destinations: decryptor is not set"); return false; diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 9bb7dfd1..c91bfdb3 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -327,7 +327,7 @@ namespace i2p { LogPrint (eLogDebug, "I2NP: Build request record ", i, " is ours"); BN_CTX * ctx = BN_CTX_new (); - i2p::crypto::ElGamalDecrypt (i2p::context.GetPrivateKeys ().GetPrivateKey () , record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText, ctx); + i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText, ctx); BN_CTX_free (ctx); // replace record to reply if (i2p::context.AcceptsTunnels () && diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index f2355930..8b6063fc 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -212,7 +212,7 @@ namespace data { auto encryptor = m_Identity->CreateEncryptor (m_EncryptionKey); if (encryptor) - encryptor->Encrypt (data, encrypted, ctx); + encryptor->Encrypt (data, encrypted, ctx, true); } LocalLeaseSet::LocalLeaseSet (std::shared_ptr identity, const uint8_t * encryptionPublicKey, std::vector > tunnels): diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 38fe3224..99f79df6 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -482,6 +482,11 @@ namespace i2p bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const { - return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx) : false; + return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, true) : false; + } + + bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const + { + return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, false) : false; } } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index ef23af25..4bd324f5 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -61,6 +61,7 @@ namespace i2p void SetError (RouterError error) { m_Status = eRouterStatusError; m_Error = error; }; int GetNetID () const { return m_NetID; }; void SetNetID (int netID) { m_NetID = netID; }; + bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const; void UpdatePort (int port); // called from Daemon void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index e9c2a384..e3f4d2d4 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -840,7 +840,7 @@ namespace data { auto encryptor = m_RouterIdentity->CreateEncryptor (nullptr); if (encryptor) - encryptor->Encrypt (data, encrypted, ctx); + encryptor->Encrypt (data, encrypted, ctx, true); } } } diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 9707fa17..48e66f2e 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -5,7 +5,6 @@ #include #include #include -#include "Crypto.h" #include "Identity.h" #include "RouterContext.h" #include "Timestamp.h" @@ -103,7 +102,9 @@ namespace tunnel htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ()); htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); - i2p::crypto::ElGamalEncrypt (ident->GetEncryptionPublicKey (), clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); + auto encryptor = ident->CreateEncryptor (nullptr); + if (encryptor) + encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } }; diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 361d9f94..b08fded1 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -37,7 +37,7 @@ namespace client bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const { if (m_Decryptor) - return m_Decryptor->Decrypt (encrypted, data, ctx); + return m_Decryptor->Decrypt (encrypted, data, ctx, true); else LogPrint (eLogError, "I2CP: decryptor is not set"); return false; From ce8d701ecb92be1563681ec9ce98a9e4d02041fd Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 11 Mar 2018 19:20:47 +0300 Subject: [PATCH 26/29] WITH_LIBRARY usage closes #1146. Need to be checked before. --- build/CMakeLists.txt | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 364c3304..fc9ca417 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -94,14 +94,17 @@ endif() add_library(libi2pd ${LIBI2PD_SRC}) set_target_properties(libi2pd PROPERTIES PREFIX "") -install(TARGETS libi2pd - EXPORT libi2pd - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - COMPONENT Libraries) + +if (WITH_LIBRARY) + install(TARGETS libi2pd + EXPORT libi2pd + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + COMPONENT Libraries) # TODO Make libi2pd available to 3rd party projects via CMake as imported target # FIXME This pulls stdafx # install(EXPORT libi2pd DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() set (CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/AddressBook.cpp" @@ -120,13 +123,17 @@ set (CLIENT_SRC if(WITH_WEBSOCKETS) list (APPEND CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/Websocket.cpp") endif () + add_library(libi2pdclient ${CLIENT_SRC}) set_target_properties(libi2pdclient PROPERTIES PREFIX "") -install(TARGETS libi2pdclient - EXPORT libi2pdclient - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - COMPONENT Libraries) + +if (WITH_LIBRARY) + install(TARGETS libi2pdclient + EXPORT libi2pdclient + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + COMPONENT Libraries) +endif() set(DAEMON_SRC_DIR ../daemon) From b1a6c5ddf7787b4275ec77730f59fa1324159d6c Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 16 Mar 2018 11:12:18 -0400 Subject: [PATCH 27/29] fixed build for gcc 4.7 --- libi2pd/NTCPSession.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index e3d6c004..e0bd1135 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -178,7 +178,8 @@ namespace transport } // TODO: check for number of pending keys auto s = shared_from_this (); - m_Server.Work(s, [s]() -> std::function { + // TODO: we need to pass this for gcc 4.7, should be removed later on + m_Server.Work(s, [s, this]() -> std::function { if (!s->m_DHKeysPair) s->m_DHKeysPair = transports.GetNextDHKeysPair (); s->CreateAESKey (s->m_Establisher->phase1.pubKey); @@ -242,7 +243,8 @@ namespace transport else { auto s = shared_from_this (); - m_Server.Work(s, [s]() -> std::function { + // TODO: we need to pass this for gcc 4.7, should be removed later on + m_Server.Work(s, [s, this]() -> std::function { s->CreateAESKey (s->m_Establisher->phase2.pubKey); return std::bind(&NTCPSession::HandlePhase2, s); }); From b7c350202d63e7413bc4b21d61426fe6d5229340 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Mar 2018 20:43:47 -0400 Subject: [PATCH 28/29] always create EdDSA RouterInfo --- libi2pd/RouterContext.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 99f79df6..a82ace85 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -34,11 +34,7 @@ namespace i2p void RouterContext::CreateNewRouter () { -#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER) m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); -#else - m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_DSA_SHA1); -#endif SaveKeys (); NewRouterInfo (); } From b041bcdc655c45fa106392cd272f8eddcb867326 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 23 Mar 2018 11:41:36 -0400 Subject: [PATCH 29/29] publish updated LeaseSet in destination's thread --- libi2pd/Destination.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index bafd49da..b7c2ee32 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -281,8 +281,12 @@ namespace client i2p::garlic::GarlicDestination::SetLeaseSetUpdated (); if (m_IsPublic) { - m_PublishVerificationTimer.cancel (); - Publish (); + auto s = shared_from_this (); + m_Service.post ([s](void) + { + s->m_PublishVerificationTimer.cancel (); + s->Publish (); + }); } }