Merge pull request #646 from PurpleI2P/openssl

recent changes
This commit is contained in:
orignal 2016-09-27 16:19:01 -04:00 committed by GitHub
commit 7c34c45983
15 changed files with 135 additions and 47 deletions

View File

@ -180,6 +180,18 @@ namespace http {
case eRouterStatusOK: s << "OK"; break; case eRouterStatusOK: s << "OK"; break;
case eRouterStatusTesting: s << "Testing"; break; case eRouterStatusTesting: s << "Testing"; break;
case eRouterStatusFirewalled: s << "Firewalled"; break; case eRouterStatusFirewalled: s << "Firewalled"; break;
case eRouterStatusError:
{
s << "Error";
switch (i2p::context.GetError ())
{
case eRouterErrorClockSkew:
s << "<br>Clock skew";
break;
default: ;
}
break;
}
default: s << "Unknown"; default: s << "Unknown";
} }
s << "<br>\r\n"; s << "<br>\r\n";
@ -344,50 +356,32 @@ namespace http {
void ShowLeasesSets(std::stringstream& s) void ShowLeasesSets(std::stringstream& s)
{ {
s << "<div id='leasesets'><b>LeaseSets:</b></div><br>"; s << "<div id='leasesets'><b>LeaseSets (click on to show info):</b></div><br>\r\n";
int counter = 1;
// for each lease set // for each lease set
i2p::data::netdb.VisitLeaseSets( i2p::data::netdb.VisitLeaseSets(
[&s](const i2p::data::IdentHash dest, std::shared_ptr<i2p::data::LeaseSet> leaseSet) [&s, &counter](const i2p::data::IdentHash dest, std::shared_ptr<i2p::data::LeaseSet> leaseSet)
{ {
// create copy of lease set so we extract leases // create copy of lease set so we extract leases
i2p::data::LeaseSet ls(leaseSet->GetBuffer(), leaseSet->GetBufferLen()); i2p::data::LeaseSet ls(leaseSet->GetBuffer(), leaseSet->GetBufferLen());
// begin lease set entry
s << "<div class='leaseset"; s << "<div class='leaseset";
if (ls.IsExpired()) if (ls.IsExpired())
s << " expired"; // additional css class for expired s << " expired"; // additional css class for expired
s << "'>"; s << "'>\r\n";
// invalid ?
if (!ls.IsValid()) if (!ls.IsValid())
s << "<div class='invalid'>!! Invalid !! </div>"; s << "<div class='invalid'>!! Invalid !! </div>\r\n";
// ident s << "<div class='slide'><label for='slide" << counter << "'>" << dest.ToBase32() << "</label>\r\n";
s << "<div class='ident'>" << dest.ToBase32() << "</div>"; s << "<input type='checkbox' id='slide" << (counter++) << "'/>\r\n<p class='content'>\r\n";
// LeaseSet time s << "<b>Expires:</b> " << ls.GetExpirationTime() << "<br>\r\n";
s << "<div class='expires'>expires: " << ls.GetExpirationTime() << "</div>";
// get non expired leases
auto leases = ls.GetNonExpiredLeases(); auto leases = ls.GetNonExpiredLeases();
// show non expired leases s << "<b>Non Expired Leases: " << leases.size() << "</b><br>\r\n";
s << "<div class='leasecount'>Non Expired Leases: " << leases.size() << "</div>";
// for each lease
s << "<div class='leases'>";
for ( auto & l : leases ) for ( auto & l : leases )
{ {
// begin lease s << "<b>Gateway:</b> " << l->tunnelGateway.ToBase64() << "<br>\r\n";
s << "<div class='lease'>"; s << "<b>TunnelID:</b> " << l->tunnelID << "<br>\r\n";
// gateway s << "<b>EndDate:</b> " << l->endDate << "<br>\r\n";
s << "<div class='gateway'>Gateway: " << l->tunnelGateway.ToBase64() << "</div>";
// tunnel id
s << "<div class='tunnelID'>TunnelID: " << l->tunnelID << "</div>";
// end date
s << "<div class='endDate'>EndDate: " << l->endDate << "</div>";
// end lease
s << "</div>";
} }
// end for each lease s << "</p>\r\n</div>\r\n</div>\r\n";
s << "</div>";
// end lease set entry
s << "</div>";
// linebreak
s << "<br>";
} }
); );
// end for each lease set // end for each lease set

View File

@ -109,7 +109,7 @@ namespace client
} }
else else
{ {
auto outboundTunnel = GetTunnelPool ()->GetNextOutboundTunnel (); outboundTunnel = GetTunnelPool ()->GetNextOutboundTunnel ();
auto leases = remote->GetNonExpiredLeases (); auto leases = remote->GetNonExpiredLeases ();
if (!leases.empty ()) if (!leases.empty ())
remoteLease = leases[rand () % leases.size ()]; remoteLease = leases[rand () % leases.size ()];

View File

@ -18,7 +18,7 @@ namespace i2p
RouterContext::RouterContext (): RouterContext::RouterContext ():
m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
m_StartupTime (0), m_Status (eRouterStatusOK ) m_StartupTime (0), m_Status (eRouterStatusOK), m_Error (eRouterErrorNone)
{ {
} }
@ -95,6 +95,7 @@ namespace i2p
if (status != m_Status) if (status != m_Status)
{ {
m_Status = status; m_Status = status;
m_Error = eRouterErrorNone;
switch (m_Status) switch (m_Status)
{ {
case eRouterStatusOK: case eRouterStatusOK:

View File

@ -20,9 +20,16 @@ namespace i2p
{ {
eRouterStatusOK = 0, eRouterStatusOK = 0,
eRouterStatusTesting = 1, eRouterStatusTesting = 1,
eRouterStatusFirewalled = 2 eRouterStatusFirewalled = 2,
eRouterStatusError = 3
}; };
enum RouterError
{
eRouterErrorNone = 0,
eRouterErrorClockSkew = 1
};
class RouterContext: public i2p::garlic::GarlicDestination class RouterContext: public i2p::garlic::GarlicDestination
{ {
public: public:
@ -49,7 +56,9 @@ namespace i2p
uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; }; uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; };
RouterStatus GetStatus () const { return m_Status; }; RouterStatus GetStatus () const { return m_Status; };
void SetStatus (RouterStatus status); void SetStatus (RouterStatus status);
RouterError GetError () const { return m_Error; };
void SetError (RouterError error) { m_Status = eRouterStatusError; m_Error = error; };
void UpdatePort (int port); // called from Daemon void UpdatePort (int port); // called from Daemon
void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer); bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer);
@ -107,6 +116,7 @@ namespace i2p
uint64_t m_StartupTime; // in seconds since epoch uint64_t m_StartupTime; // in seconds since epoch
uint32_t m_BandwidthLimit; // allowed bandwidth uint32_t m_BandwidthLimit; // allowed bandwidth
RouterStatus m_Status; RouterStatus m_Status;
RouterError m_Error;
std::mutex m_GarlicMutex; std::mutex m_GarlicMutex;
}; };

View File

@ -3,6 +3,10 @@
#include "I2PEndian.h" #include "I2PEndian.h"
#include <fstream> #include <fstream>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/make_shared.hpp>
#if (BOOST_VERSION >= 105300)
#include <boost/atomic.hpp>
#endif
#include "version.h" #include "version.h"
#include "Crypto.h" #include "Crypto.h"
#include "Base.h" #include "Base.h"
@ -17,14 +21,14 @@ namespace data
{ {
RouterInfo::RouterInfo (): m_Buffer (nullptr) RouterInfo::RouterInfo (): m_Buffer (nullptr)
{ {
m_Addresses = std::make_shared<Addresses>(); // create empty list m_Addresses = boost::make_shared<Addresses>(); // create empty list
} }
RouterInfo::RouterInfo (const std::string& fullPath): RouterInfo::RouterInfo (const std::string& fullPath):
m_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false), m_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false),
m_SupportedTransports (0), m_Caps (0) m_SupportedTransports (0), m_Caps (0)
{ {
m_Addresses = std::make_shared<Addresses>(); // create empty list m_Addresses = boost::make_shared<Addresses>(); // create empty list
m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
ReadFromFile (); ReadFromFile ();
} }
@ -32,7 +36,7 @@ namespace data
RouterInfo::RouterInfo (const uint8_t * buf, int len): RouterInfo::RouterInfo (const uint8_t * buf, int len):
m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0) m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0)
{ {
m_Addresses = std::make_shared<Addresses>(); // create empty list m_Addresses = boost::make_shared<Addresses>(); // create empty list
m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
memcpy (m_Buffer, buf, len); memcpy (m_Buffer, buf, len);
m_BufferLen = len; m_BufferLen = len;
@ -154,7 +158,7 @@ namespace data
s.read ((char *)&m_Timestamp, sizeof (m_Timestamp)); s.read ((char *)&m_Timestamp, sizeof (m_Timestamp));
m_Timestamp = be64toh (m_Timestamp); m_Timestamp = be64toh (m_Timestamp);
// read addresses // read addresses
auto addresses = std::make_shared<Addresses>(); auto addresses = boost::make_shared<Addresses>();
uint8_t numAddresses; uint8_t numAddresses;
s.read ((char *)&numAddresses, sizeof (numAddresses)); if (!s) return; s.read ((char *)&numAddresses, sizeof (numAddresses)); if (!s) return;
bool introducers = false; bool introducers = false;
@ -255,7 +259,11 @@ namespace data
m_SupportedTransports |= supportedTransports; m_SupportedTransports |= supportedTransports;
} }
} }
m_Addresses = addresses; #if (BOOST_VERSION >= 105300)
boost::atomic_store (&m_Addresses, addresses);
#else
m_Addresses = addresses; // race condition
#endif
// read peers // read peers
uint8_t numPeers; uint8_t numPeers;
s.read ((char *)&numPeers, sizeof (numPeers)); if (!s) return; s.read ((char *)&numPeers, sizeof (numPeers)); if (!s) return;

View File

@ -8,6 +8,7 @@
#include <list> #include <list>
#include <iostream> #include <iostream>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include "Identity.h" #include "Identity.h"
#include "Profiling.h" #include "Profiling.h"
@ -201,7 +202,7 @@ namespace data
uint8_t * m_Buffer; uint8_t * m_Buffer;
size_t m_BufferLen; size_t m_BufferLen;
uint64_t m_Timestamp; uint64_t m_Timestamp;
std::shared_ptr<Addresses> m_Addresses; boost::shared_ptr<Addresses> m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9
std::map<std::string, std::string> m_Properties; std::map<std::string, std::string> m_Properties;
bool m_IsUpdated, m_IsUnreachable; bool m_IsUpdated, m_IsUnreachable;
uint8_t m_SupportedTransports, m_Caps; uint8_t m_SupportedTransports, m_Caps;

View File

@ -272,6 +272,16 @@ namespace transport
s.Insert (payload, 8); // relayTag and signed on time s.Insert (payload, 8); // relayTag and signed on time
m_RelayTag = bufbe32toh (payload); m_RelayTag = bufbe32toh (payload);
payload += 4; // relayTag payload += 4; // relayTag
if (i2p::context.GetStatus () == eRouterStatusTesting)
{
auto ts = i2p::util::GetSecondsSinceEpoch ();
uint32_t signedOnTime = bufbe32toh(payload);
if (signedOnTime < ts - SSU_CLOCK_SKEW || signedOnTime > ts + SSU_CLOCK_SKEW)
{
LogPrint (eLogError, "SSU: clock skew detected ", (int)ts - signedOnTime, ". Check your clock");
i2p::context.SetError (eRouterErrorClockSkew);
}
}
payload += 4; // signed on time payload += 4; // signed on time
// decrypt signature // decrypt signature
size_t signatureLen = m_RemoteIdentity->GetSignatureLen (); size_t signatureLen = m_RemoteIdentity->GetSignatureLen ();
@ -310,6 +320,14 @@ namespace transport
SetRemoteIdentity (std::make_shared<i2p::data::IdentityEx> (payload, identitySize)); SetRemoteIdentity (std::make_shared<i2p::data::IdentityEx> (payload, identitySize));
m_Data.UpdatePacketSize (m_RemoteIdentity->GetIdentHash ()); m_Data.UpdatePacketSize (m_RemoteIdentity->GetIdentHash ());
payload += identitySize; // identity payload += identitySize; // identity
auto ts = i2p::util::GetSecondsSinceEpoch ();
uint32_t signedOnTime = bufbe32toh(payload);
if (signedOnTime < ts - SSU_CLOCK_SKEW || signedOnTime > ts + SSU_CLOCK_SKEW)
{
LogPrint (eLogError, "SSU message 'confirmed' time difference ", (int)ts - signedOnTime, " exceeds clock skew");
Failed ();
return;
}
if (m_SignedData) if (m_SignedData)
m_SignedData->Insert (payload, 4); // insert Alice's signed on time m_SignedData->Insert (payload, 4); // insert Alice's signed on time
payload += 4; // signed-on time payload += 4; // signed-on time

View File

@ -27,6 +27,7 @@ namespace transport
const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds
const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes
const int SSU_CLOCK_SKEW = 60; // in seconds
// payload types (4 bits) // payload types (4 bits)
const uint8_t PAYLOAD_TYPE_SESSION_REQUEST = 0; const uint8_t PAYLOAD_TYPE_SESSION_REQUEST = 0;

50
Timestamp.cpp Normal file
View File

@ -0,0 +1,50 @@
#include <inttypes.h>
#include <string.h>
#include <boost/asio.hpp>
#include "I2PEndian.h"
#include "Timestamp.h"
namespace i2p
{
namespace util
{
std::chrono::system_clock::duration g_TimeOffset = std::chrono::system_clock::duration::zero ();
void SyncTimeWithNTP (const std::string& address)
{
boost::asio::io_service service;
boost::asio::ip::udp::resolver::query query (boost::asio::ip::udp::v4 (), address, "ntp");
boost::system::error_code ec;
auto it = boost::asio::ip::udp::resolver (service).resolve (query, ec);
if (!ec && it != boost::asio::ip::udp::resolver::iterator())
{
auto ep = (*it).endpoint (); // take first one
boost::asio::ip::udp::socket socket (service);
socket.open (boost::asio::ip::udp::v4 (), ec);
if (!ec)
{
uint8_t request[48];// 48 bytes NTP request
memset (request, 0, 48);
request[0] = 0x80; // client mode, version 0
uint8_t * response = new uint8_t[1500]; // MTU
size_t len = 0;
try
{
socket.send_to (boost::asio::buffer (request, 48), ep);
len = socket.receive_from (boost::asio::buffer (response, 1500), ep);
}
catch (std::exception& e)
{
}
if (len >= 8)
{
uint32_t ts = bufbe32toh (response + 4);
if (ts > 2208988800U) ts -= 2208988800U; // 1/1/1970 from 1/1/1900
}
delete[] response;
}
}
}
}
}

View File

@ -8,6 +8,8 @@ namespace i2p
{ {
namespace util namespace util
{ {
extern std::chrono::system_clock::duration g_TimeOffset;
inline uint64_t GetMillisecondsSinceEpoch () inline uint64_t GetMillisecondsSinceEpoch ()
{ {
return std::chrono::duration_cast<std::chrono::milliseconds>( return std::chrono::duration_cast<std::chrono::milliseconds>(

View File

@ -57,6 +57,7 @@ LOCAL_SRC_FILES := DaemonAndroid.cpp i2pd_android.cpp \
../../TunnelEndpoint.cpp \ ../../TunnelEndpoint.cpp \
../../TunnelGateway.cpp \ ../../TunnelGateway.cpp \
../../TunnelPool.cpp \ ../../TunnelPool.cpp \
../../Timestamp.cpp \
../../util.cpp \ ../../util.cpp \
../../i2pd.cpp ../../UPnP.cpp ../../i2pd.cpp ../../UPnP.cpp

View File

@ -55,6 +55,7 @@ set (LIBI2PD_SRC
"${CMAKE_SOURCE_DIR}/Datagram.cpp" "${CMAKE_SOURCE_DIR}/Datagram.cpp"
"${CMAKE_SOURCE_DIR}/Family.cpp" "${CMAKE_SOURCE_DIR}/Family.cpp"
"${CMAKE_SOURCE_DIR}/Signature.cpp" "${CMAKE_SOURCE_DIR}/Signature.cpp"
"${CMAKE_SOURCE_DIR}/Timestamp.cpp"
"${CMAKE_SOURCE_DIR}/api.cpp" "${CMAKE_SOURCE_DIR}/api.cpp"
) )

View File

@ -27,7 +27,7 @@ msys2
### x86 (32-bit architecture) ### x86 (32-bit architecture)
Get install file msys2-i686-20150916.exe from https://msys2.github.io. Get install file msys2-i686-*.exe from https://msys2.github.io.
open MSYS2 Shell (from Start menu). open MSYS2 Shell (from Start menu).
Install all prerequisites and download i2pd source: Install all prerequisites and download i2pd source:
@ -44,7 +44,7 @@ make
### x64 (64-bit architecture) ### x64 (64-bit architecture)
Get install file msys2-x86_64-20150916.exe from https://msys2.github.io. Get install file msys2-x86_64-*.exe from https://msys2.github.io.
open MSYS2 Shell (from Start menu). open MSYS2 Shell (from Start menu).
Install all prerequisites and download i2pd source: Install all prerequisites and download i2pd source:
@ -97,9 +97,9 @@ Requirements for building:
* [CMake](https://cmake.org/) (tested with 3.1.3) * [CMake](https://cmake.org/) (tested with 3.1.3)
* [Visual Studio Community Edition](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx) (tested with VS2013 Update 4) * [Visual Studio Community Edition](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx) (tested with VS2013 Update 4)
* [Boost](http://www.boost.org/) (tested with 1.59) * [Boost](http://www.boost.org/) (tested with 1.59)
* Optionally [MiniUPnP](http://miniupnp.free.f) (tested with 1.9), we need only few client headers * Optionally [MiniUPnP](http://miniupnp.free.fr) (tested with 1.9), we need only few client headers
* OpenSSL (tested with 1.0.1p and 1.0.2e), if building from sources (recommended), you'll need as well * OpenSSL (tested with 1.0.1p and 1.0.2e), if building from sources (recommended), you'll need as well
* [Netwide assembler](www.nasm.us) * [Netwide assembler](http://www.nasm.us/)
* Strawberry Perl or ActiveState Perl, do NOT try msys2 perl, it won't work * Strawberry Perl or ActiveState Perl, do NOT try msys2 perl, it won't work

View File

@ -5,7 +5,7 @@ LIB_SRC = \
SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \ SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \
Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \ Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \
Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \ Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \
Config.cpp HTTP.cpp util.cpp api.cpp Config.cpp HTTP.cpp Timestamp.cpp util.cpp api.cpp
LIB_CLIENT_SRC = \ LIB_CLIENT_SRC = \
AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp \ AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp \

View File

@ -35,7 +35,8 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \
../../RouterInfo.cpp ../../SAM.cpp ../../Signature.cpp ../../SOCKS.cpp ../../SSU.cpp \ ../../RouterInfo.cpp ../../SAM.cpp ../../Signature.cpp ../../SOCKS.cpp ../../SSU.cpp \
../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \ ../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \
../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \ ../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \
../../TunnelPool.cpp ../../UPnP.cpp ../../util.cpp ../../Gzip.cpp ../../i2pd.cpp ../../TunnelPool.cpp ../../UPnP.cpp ../../Gzip.cpp ../../Timestamp.cpp ../../util.cpp \
../../i2pd.cpp
HEADERS += DaemonQT.h mainwindow.h \ HEADERS += DaemonQT.h mainwindow.h \
../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \ ../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \