Browse Source

Merge remote-tracking branch 'purple/openssl'

pull/1169/head
Jeff Becker 6 years ago
parent
commit
fa154cc4d6
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05
  1. 74
      android/i2pd/Android.mk
  2. 42
      android/i2pd/Application.mk
  3. 2
      appveyor.yml
  4. 27
      build/CMakeLists.txt
  5. 2
      contrib/i2pd.service
  6. 13
      daemon/Daemon.h
  7. 3
      daemon/UnixDaemon.cpp
  8. 15
      libi2pd/Base.cpp
  9. 9
      libi2pd/Base.h
  10. 2
      libi2pd/Config.cpp
  11. 24
      libi2pd/CryptoKey.cpp
  12. 16
      libi2pd/CryptoKey.h
  13. 10
      libi2pd/Destination.cpp
  14. 2
      libi2pd/I2NPProtocol.cpp
  15. 2
      libi2pd/LeaseSet.cpp
  16. 33
      libi2pd/NTCPSession.cpp
  17. 6
      libi2pd/NTCPSession.h
  18. 11
      libi2pd/RouterContext.cpp
  19. 1
      libi2pd/RouterContext.h
  20. 2
      libi2pd/RouterInfo.cpp
  21. 82
      libi2pd/Streaming.cpp
  22. 36
      libi2pd/Streaming.h
  23. 5
      libi2pd/TunnelConfig.h
  24. 2
      libi2pd/version.h
  25. 14
      libi2pd_client/ClientContext.cpp
  26. 29
      libi2pd_client/HTTPProxy.cpp
  27. 2
      libi2pd_client/I2CP.cpp
  28. 2
      libi2pd_client/I2PTunnel.h
  29. 10
      qt/i2pd_qt/i2pd_qt.pro

74
android/i2pd/Android.mk

@ -0,0 +1,74 @@ @@ -0,0 +1,74 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := i2pd
LOCAL_CPP_FEATURES := rtti exceptions
LOCAL_C_INCLUDES += $(IFADDRS_PATH) $(LIB_SRC_PATH) $(LIB_CLIENT_SRC_PATH) $(DAEMON_SRC_PATH)
LOCAL_STATIC_LIBRARIES := \
boost_system \
boost_date_time \
boost_filesystem \
boost_program_options \
crypto ssl \
miniupnpc
LOCAL_LDLIBS := -lz
LOCAL_SRC_FILES := $(IFADDRS_PATH)/ifaddrs.c \
$(wildcard $(LIB_SRC_PATH)/*.cpp)\
$(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp)\
$(DAEMON_SRC_PATH)/UnixDaemon.cpp \
$(DAEMON_SRC_PATH)/Daemon.cpp \
$(DAEMON_SRC_PATH)/UPnP.cpp \
$(DAEMON_SRC_PATH)/HTTPServer.cpp \
$(DAEMON_SRC_PATH)/I2PControl.cpp \
$(DAEMON_SRC_PATH)/i2pd.cpp
include $(BUILD_EXECUTABLE)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_system
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_date_time
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_filesystem
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_program_options
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := crypto
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.0e/$(TARGET_ARCH_ABI)/lib/libcrypto.a
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.0e/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ssl
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.0e/$(TARGET_ARCH_ABI)/lib/libssl.a
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.0e/include
LOCAL_STATIC_LIBRARIES := crypto
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := miniupnpc
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnp-2.0/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnp-2.0/include
include $(PREBUILT_STATIC_LIBRARY)

42
android/i2pd/Application.mk

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
#APP_ABI := all
#APP_ABI := armeabi-v7a x86
#APP_ABI := x86
#APP_ABI := x86_64
APP_ABI := armeabi-v7a
#can be android-3 but will fail for x86 since arch-x86 is not present at ndkroot/platforms/android-3/ . libz is taken from there.
APP_PLATFORM := android-14
# http://stackoverflow.com/a/21386866/529442 http://stackoverflow.com/a/15616255/529442 to enable c++11 support in Eclipse
NDK_TOOLCHAIN_VERSION := 4.9
# APP_STL := stlport_shared --> does not seem to contain C++11 features
#APP_STL := gnustl_shared
APP_STL := gnustl_static
# Enable c++11 extensions in source code
APP_CPPFLAGS += -std=c++11 -fvisibility=default -fPIE
APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP
APP_LDFLAGS += -rdynamic -fPIE -pie
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
APP_CPPFLAGS += -DANDROID_ARM7A
endif
APP_OPTIM := debug
# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git
# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
# git clone https://github.com/PurpleI2P/android-ifaddrs.git
# change to your own
I2PD_LIBS_PATH = /home/u/build/i2p/daemon/static.libs
BOOST_PATH = $(I2PD_LIBS_PATH)/Boost-for-Android-Prebuilt
OPENSSL_PATH = $(I2PD_LIBS_PATH)/OpenSSL-for-Android-Prebuilt
MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt
IFADDRS_PATH = $(I2PD_LIBS_PATH)/android-ifaddrs
# don't change me
I2PD_SRC_PATH = $(PWD)/..
LIB_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd
LIB_CLIENT_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd_client
DAEMON_SRC_PATH = $(I2PD_SRC_PATH)/daemon

2
appveyor.yml

@ -17,7 +17,7 @@ environment: @@ -17,7 +17,7 @@ environment:
- MSYSTEM: MINGW32
install:
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc catgets"
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc"
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu "
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu"

27
build/CMakeLists.txt

@ -94,14 +94,17 @@ endif() @@ -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 @@ -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)

2
contrib/i2pd.service

@ -10,7 +10,7 @@ RuntimeDirectory=i2pd @@ -10,7 +10,7 @@ RuntimeDirectory=i2pd
RuntimeDirectoryMode=0700
LogsDirectory=i2pd
LogsDirectoryMode=0700
Type=simple
Type=forking
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
PIDFile=/var/run/i2pd/i2pd.pid

13
daemon/Daemon.h

@ -44,19 +44,6 @@ namespace util @@ -44,19 +44,6 @@ namespace util
}
};
#elif defined(ANDROID)
#define Daemon i2p::util::DaemonAndroid::Instance()
// dummy, invoked from android/jni/DaemonAndroid.*
class DaemonAndroid: public i2p::util::Daemon_Singleton
{
public:
static DaemonAndroid& Instance()
{
static DaemonAndroid instance;
return instance;
}
};
#elif defined(_WIN32)
#define Daemon i2p::util::DaemonWin32::Instance()
class DaemonWin32 : public Daemon_Singleton

3
daemon/UnixDaemon.cpp

@ -138,11 +138,14 @@ namespace i2p @@ -138,11 +138,14 @@ namespace i2p
LogPrint(eLogError, "Daemon: could not create pid file ", pidfile, ": ", strerror(errno));
return false;
}
#ifndef ANDROID
if (lockf(pidFH, F_TLOCK, 0) != 0)
{
LogPrint(eLogError, "Daemon: could not lock pid file ", pidfile, ": ", strerror(errno));
return false;
}
#endif
char pid[10];
sprintf(pid, "%d\n", getpid());
ftruncate(pidFH, 0);

15
libi2pd/Base.cpp

@ -210,6 +210,21 @@ namespace data @@ -210,6 +210,21 @@ namespace data
return 4*d.quot;
}
std::string ToBase64Standard (const std::string& in)
{
auto len = Base64EncodingBufferSize (in.length ());
char * str = new char[len+1];
auto l = ByteStreamToBase64 ((const uint8_t *)in.c_str (), in.length (), str, len);
str[l] = 0;
// replace '-' by '+' and '~' by '/'
for (size_t i = 0; i < l; i++)
if (str[i] == '-') str[i] = '+';
else if (str[i] == '~') str[i] = '/';
std::string s(str);
delete[] str;
return s;
}
/*
*
* iT64

9
libi2pd/Base.h

@ -15,10 +15,13 @@ namespace data { @@ -15,10 +15,13 @@ namespace data {
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);
/**
/**
Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
*/
size_t Base64EncodingBufferSize(const size_t input_size);
*/
size_t Base64EncodingBufferSize(const size_t input_size);
std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization
} // data
} // i2p

2
libi2pd/Config.cpp

@ -191,7 +191,7 @@ namespace config { @@ -191,7 +191,7 @@ namespace config {
// "https://uk.reseed.i2p2.no:444/," // mamoth's shit
"https://i2p-0.manas.ca:8443/,"
"https://download.xxlspeed.com/,"
"https://reseed-ru.lngserv.ru/,"
"https://reseed-fr.i2pd.xyz/,"
"https://reseed.atomike.ninja/,"
"https://reseed.memcpy.io/,"
"https://reseed.onion.im/,"

24
libi2pd/CryptoKey.cpp

@ -12,9 +12,9 @@ namespace crypto @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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;
}

16
libi2pd/CryptoKey.h

@ -13,7 +13,7 @@ namespace crypto @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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:

10
libi2pd/Destination.cpp

@ -281,8 +281,12 @@ namespace client @@ -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 ();
});
}
}
@ -1024,7 +1028,7 @@ namespace client @@ -1024,7 +1028,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;

2
libi2pd/I2NPProtocol.cpp

@ -327,7 +327,7 @@ namespace i2p @@ -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 () &&

2
libi2pd/LeaseSet.cpp

@ -212,7 +212,7 @@ namespace data @@ -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<const IdentityEx> identity, const uint8_t * encryptionPublicKey, std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels):

33
libi2pd/NTCPSession.cpp

@ -24,6 +24,12 @@ namespace i2p @@ -24,6 +24,12 @@ namespace i2p
{
namespace transport
{
struct NTCPWork
{
std::shared_ptr<NTCPSession> session;
};
NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter):
TransportSession (in_RemoteRouter, NTCP_ESTABLISH_TIMEOUT),
m_Server (server), m_Socket (m_Server.GetService ()),
@ -177,18 +183,20 @@ namespace transport @@ -177,18 +183,20 @@ namespace transport
}
}
// TODO: check for number of pending keys
auto s = shared_from_this ();
m_Server.Work(s, [s]() -> std::function<void(void)> {
if (!s->m_DHKeysPair)
s->m_DHKeysPair = transports.GetNextDHKeysPair ();
s->CreateAESKey (s->m_Establisher->phase1.pubKey);
return std::bind(&NTCPSession::SendPhase2, s);
auto work = new NTCPWork{shared_from_this()};
m_Server.Work(work->session, [work, this]() -> std::function<void(void)> {
if (!work->session->m_DHKeysPair)
work->session->m_DHKeysPair = transports.GetNextDHKeysPair ();
work->session->CreateAESKey (work->session->m_Establisher->phase1.pubKey);
return std::bind(&NTCPSession::SendPhase2, work->session, work);
});
}
}
void NTCPSession::SendPhase2 ()
void NTCPSession::SendPhase2 (NTCPWork * work)
{
if(work)
delete work;
const uint8_t * y = m_DHKeysPair->GetPublicKey ();
memcpy (m_Establisher->phase2.pubKey, y, 256);
uint8_t xy[512];
@ -241,16 +249,17 @@ namespace transport @@ -241,16 +249,17 @@ namespace transport
}
else
{
auto s = shared_from_this ();
m_Server.Work(s, [s]() -> std::function<void(void)> {
s->CreateAESKey (s->m_Establisher->phase2.pubKey);
return std::bind(&NTCPSession::HandlePhase2, s);
auto work = new NTCPWork{shared_from_this()};
m_Server.Work(work->session, [work, this]() -> std::function<void(void)> {
work->session->CreateAESKey (work->session->m_Establisher->phase2.pubKey);
return std::bind(&NTCPSession::HandlePhase2, work->session, work);
});
}
}
void NTCPSession::HandlePhase2 ()
void NTCPSession::HandlePhase2 (NTCPWork * work)
{
if(work) delete work;
m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240);
m_Encryption.SetIV (m_Establisher->phase1.HXxorHI + 16);

6
libi2pd/NTCPSession.h

@ -35,6 +35,8 @@ namespace transport @@ -35,6 +35,8 @@ namespace transport
} encrypted;
};
struct NTCPWork;
const size_t NTCP_MAX_MESSAGE_SIZE = 16384;
const size_t NTCP_BUFFER_SIZE = 1028; // fits 1 tunnel data message
const int NTCP_CONNECT_TIMEOUT = 5; // 5 seconds
@ -77,12 +79,12 @@ namespace transport @@ -77,12 +79,12 @@ namespace transport
void SendPhase3 ();
void HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandlePhase2 ();
void HandlePhase2 (NTCPWork * work=nullptr);
void HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA);
void HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA);
//server
void SendPhase2 ();
void SendPhase2 (NTCPWork * work=nullptr);
void SendPhase4 (uint32_t tsA, uint32_t tsB);
void HandlePhase1Received (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandlePhase2Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB);

11
libi2pd/RouterContext.cpp

@ -34,11 +34,7 @@ namespace i2p @@ -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 ();
}
@ -482,6 +478,11 @@ namespace i2p @@ -482,6 +478,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;
}
}

1
libi2pd/RouterContext.h

@ -61,6 +61,7 @@ namespace i2p @@ -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

2
libi2pd/RouterInfo.cpp

@ -840,7 +840,7 @@ namespace data @@ -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);
}
}
}

82
libi2pd/Streaming.cpp

@ -903,11 +903,7 @@ namespace stream @@ -903,11 +903,7 @@ namespace stream
StreamingDestination::StreamingDestination (std::shared_ptr<i2p::client::ClientDestination> owner, uint16_t localPort, bool gzip):
m_Owner (owner), m_LocalPort (localPort), m_Gzip (gzip),
m_LastIncomingReceiveStreamID (0),
m_PendingIncomingTimer (m_Owner->GetService ()),
m_ConnTrackTimer(m_Owner->GetService()),
m_ConnsPerMinute(DEFAULT_MAX_CONNS_PER_MIN),
m_LastBanClear(i2p::util::GetMillisecondsSinceEpoch()),
m_EnableDrop(false)
m_PendingIncomingTimer (m_Owner->GetService ())
{
}
@ -923,7 +919,6 @@ namespace stream @@ -923,7 +919,6 @@ namespace stream
void StreamingDestination::Start ()
{
ScheduleConnTrack();
}
void StreamingDestination::Stop ()
@ -931,15 +926,10 @@ namespace stream @@ -931,15 +926,10 @@ namespace stream
ResetAcceptor ();
m_PendingIncomingTimer.cancel ();
m_PendingIncomingStreams.clear ();
m_ConnTrackTimer.cancel();
{
std::unique_lock<std::mutex> l(m_StreamsMutex);
m_Streams.clear ();
}
{
std::unique_lock<std::mutex> l(m_ConnsMutex);
m_Conns.clear ();
}
}
void StreamingDestination::HandleNextPacket (Packet * packet)
@ -971,17 +961,7 @@ namespace stream @@ -971,17 +961,7 @@ namespace stream
auto incomingStream = CreateNewIncomingStream ();
incomingStream->HandleNextPacket (packet); // SYN
auto ident = incomingStream->GetRemoteIdentity();
if(ident && m_EnableDrop)
{
auto ih = ident->GetIdentHash();
if(DropNewStream(ih))
{
// drop
LogPrint(eLogWarning, "Streaming: Dropping connection, too many inbound streams from ", ih.ToBase32());
incomingStream->Terminate();
return;
}
}
m_LastIncomingReceiveStreamID = receiveStreamID;
// handle saved packets if any
@ -1176,63 +1156,5 @@ namespace stream @@ -1176,63 +1156,5 @@ namespace stream
return msg;
}
void StreamingDestination::SetMaxConnsPerMinute(const uint32_t conns)
{
m_EnableDrop = conns > 0;
m_ConnsPerMinute = conns;
LogPrint(eLogDebug, "Streaming: Set max conns per minute per destination to ", conns);
}
bool StreamingDestination::DropNewStream(const i2p::data::IdentHash & ih)
{
std::lock_guard<std::mutex> lock(m_ConnsMutex);
if (m_Banned.size() > MAX_BANNED_CONNS) return true; // overload
auto end = std::end(m_Banned);
if ( std::find(std::begin(m_Banned), end, ih) != end) return true; // already banned
auto itr = m_Conns.find(ih);
if (itr == m_Conns.end())
m_Conns[ih] = 0;
m_Conns[ih] += 1;
bool ban = m_Conns[ih] >= m_ConnsPerMinute;
if (ban)
{
m_Banned.push_back(ih);
m_Conns.erase(ih);
LogPrint(eLogWarning, "Streaming: ban ", ih.ToBase32());
}
return ban;
}
void StreamingDestination::HandleConnTrack(const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
{ // acquire lock
std::lock_guard<std::mutex> lock(m_ConnsMutex);
// clear conn tracking
m_Conns.clear();
// check for ban clear
auto ts = i2p::util::GetMillisecondsSinceEpoch();
if (ts - m_LastBanClear >= DEFAULT_BAN_INTERVAL)
{
// clear bans
m_Banned.clear();
m_LastBanClear = ts;
}
}
// reschedule timer
ScheduleConnTrack();
}
}
void StreamingDestination::ScheduleConnTrack()
{
m_ConnTrackTimer.expires_from_now (boost::posix_time::seconds(60));
m_ConnTrackTimer.async_wait (
std::bind (&StreamingDestination::HandleConnTrack,
shared_from_this (), std::placeholders::_1));
}
}
}

36
libi2pd/Streaming.h

@ -53,22 +53,6 @@ namespace stream @@ -53,22 +53,6 @@ namespace stream
const int PENDING_INCOMING_TIMEOUT = 10; // in seconds
const int MAX_RECEIVE_TIMEOUT = 30; // in seconds
/** i2cp option for limiting inbound stremaing connections */
const char I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN[] = "maxconns";
/** default maximum connections attempts per minute per destination */
const uint32_t DEFAULT_MAX_CONNS_PER_MIN = 600;
/**
* max banned destinations per local destination
* TODO: make configurable
*/
const uint16_t MAX_BANNED_CONNS = 9999;
/**
* length of a ban in ms
* TODO: make configurable
*/
const uint64_t DEFAULT_BAN_INTERVAL = 60 * 60 * 1000;
struct Packet
{
size_t len, offset;
@ -273,9 +257,6 @@ namespace stream @@ -273,9 +257,6 @@ namespace stream
void HandleDataMessagePayload (const uint8_t * buf, size_t len);
std::shared_ptr<I2NPMessage> CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort);
/** set max connections per minute per destination */
void SetMaxConnsPerMinute(const uint32_t conns);
Packet * NewPacket () { return m_PacketsPool.Acquire(); }
void DeletePacket (Packet * p) { return m_PacketsPool.Release(p); }
@ -286,13 +267,6 @@ namespace stream @@ -286,13 +267,6 @@ namespace stream
std::shared_ptr<Stream> CreateNewIncomingStream ();
void HandlePendingIncomingTimer (const boost::system::error_code& ecode);
/** handle cleaning up connection tracking for ratelimits */
void HandleConnTrack(const boost::system::error_code& ecode);
bool DropNewStream(const i2p::data::IdentHash & ident);
void ScheduleConnTrack();
private:
std::shared_ptr<i2p::client::ClientDestination> m_Owner;
@ -306,17 +280,7 @@ namespace stream @@ -306,17 +280,7 @@ namespace stream
boost::asio::deadline_timer m_PendingIncomingTimer;
std::map<uint32_t, std::list<Packet *> > m_SavedPackets; // receiveStreamID->packets, arrived before SYN
std::mutex m_ConnsMutex;
/** how many connections per minute did each identity have */
std::map<i2p::data::IdentHash, uint32_t> m_Conns;
boost::asio::deadline_timer m_ConnTrackTimer;
uint32_t m_ConnsPerMinute;
/** banned identities */
std::vector<i2p::data::IdentHash> m_Banned;
uint64_t m_LastBanClear;
i2p::util::MemoryPool<Packet> m_PacketsPool;
bool m_EnableDrop;
public:

5
libi2pd/TunnelConfig.h

@ -5,7 +5,6 @@ @@ -5,7 +5,6 @@
#include <sstream>
#include <vector>
#include <memory>
#include "Crypto.h"
#include "Identity.h"
#include "RouterContext.h"
#include "Timestamp.h"
@ -103,7 +102,9 @@ namespace tunnel @@ -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);
}
};

2
libi2pd/version.h

@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
#define I2P_VERSION_MAJOR 0
#define I2P_VERSION_MINOR 9
#define I2P_VERSION_MICRO 33
#define I2P_VERSION_MICRO 34
#define I2P_VERSION_PATCH 0
#define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)

14
libi2pd_client/ClientContext.cpp

@ -531,6 +531,7 @@ namespace client @@ -531,6 +531,7 @@ namespace client
LogPrint(eLogInfo, "Clients: I2P Client tunnel connect timeout set to ", timeout);
}
auto clientTunnelDest = clientTunnel->GetLocalDestination (); // make copy of destination for possible update
auto ins = m_ClientTunnels.insert (std::make_pair (clientEndpoint, std::unique_ptr<I2PService>(clientTunnel)));
if (ins.second)
{
@ -540,10 +541,10 @@ namespace client @@ -540,10 +541,10 @@ namespace client
else
{
// TODO: update
if (ins.first->second->GetLocalDestination () != clientTunnel->GetLocalDestination ())
if (ins.first->second->GetLocalDestination () != clientTunnelDest)
{
LogPrint (eLogInfo, "Clients: I2P client tunnel destination updated");
ins.first->second->SetLocalDestination (clientTunnel->GetLocalDestination ());
ins.first->second->SetLocalDestination (clientTunnelDest);
}
ins.first->second->isUpdated = true;
LogPrint (eLogInfo, "Clients: I2P client tunnel for endpoint ", clientEndpoint, " already exists");
@ -567,7 +568,7 @@ namespace client @@ -567,7 +568,7 @@ namespace client
bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true);
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
i2p::data::CryptoKeyType cryptoType = section.second.get (I2P_CLIENT_TUNNEL_CRYPTO_TYPE, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL);
uint32_t maxConns = section.second.get(i2p::stream::I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN, i2p::stream::DEFAULT_MAX_CONNS_PER_MIN);
std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
@ -618,8 +619,6 @@ namespace client @@ -618,8 +619,6 @@ namespace client
else // regular server tunnel by default
serverTunnel = new I2PServerTunnel (name, host, port, localDestination, inPort, gzip);
LogPrint(eLogInfo, "Clients: Set Max Conns To ", maxConns);
serverTunnel->SetMaxConnsPerMinute(maxConns);
if(!isUniqueLocal)
{
LogPrint(eLogInfo, "Clients: disabling loopback address mapping");
@ -641,6 +640,7 @@ namespace client @@ -641,6 +640,7 @@ namespace client
while (comma != std::string::npos);
serverTunnel->SetAccessList (idents);
}
auto serverTunnelDest = serverTunnel->GetLocalDestination ();
auto ins = m_ServerTunnels.insert (std::make_pair (
std::make_pair (localDestination->GetIdentHash (), inPort),
std::unique_ptr<I2PServerTunnel>(serverTunnel)));
@ -652,10 +652,10 @@ namespace client @@ -652,10 +652,10 @@ namespace client
else
{
// TODO: update
if (ins.first->second->GetLocalDestination () != serverTunnel->GetLocalDestination ())
if (ins.first->second->GetLocalDestination () != serverTunnelDest)
{
LogPrint (eLogInfo, "Clients: I2P server tunnel destination updated");
ins.first->second->SetLocalDestination (serverTunnel->GetLocalDestination ());
ins.first->second->SetLocalDestination (serverTunnelDest);
}
ins.first->second->isUpdated = true;
LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists");

29
libi2pd_client/HTTPProxy.cpp

@ -219,7 +219,7 @@ namespace proxy { @@ -219,7 +219,7 @@ namespace proxy {
/* replace headers */
req.UpdateHeader("User-Agent", "MYOB/6.66 (AN/ON)");
/* add headers */
req.AddHeader("Connection", "close"); /* keep-alive conns not supported yet */
req.UpdateHeader("Connection", "close"); /* keep-alive conns not supported yet */
}
/**
@ -387,18 +387,31 @@ namespace proxy { @@ -387,18 +387,31 @@ namespace proxy {
LogPrint(eLogDebug, "HTTPProxy: ", m_ClientRequestURL.host);
m_ClientRequestURL.schema = "";
m_ClientRequestURL.host = "";
std::string origURI = m_ClientRequest.uri; // TODO: what do we need to chage uri for?
m_ClientRequest.uri = m_ClientRequestURL.to_string();
m_ClientRequest.write(m_ClientRequestBuffer);
m_ClientRequestBuffer << m_recv_buf.substr(m_req_len);
// assume http if empty schema
if (m_ProxyURL.schema == "" || m_ProxyURL.schema == "http") {
if (m_ProxyURL.schema == "" || m_ProxyURL.schema == "http")
{
// handle upstream http proxy
if (!m_ProxyURL.port) m_ProxyURL.port = 80;
if (m_ProxyURL.is_i2p())
{
m_send_buf = m_recv_buf;
m_ClientRequest.uri = origURI;
if (!m_ProxyURL.user.empty () || !m_ProxyURL.pass.empty ())
{
// remove existing authorization if any
m_ClientRequest.RemoveHeader("Proxy-");
// add own http proxy authorization
std::string s = "Basic " + i2p::data::ToBase64Standard (m_ProxyURL.user + ":" + m_ProxyURL.pass);
m_ClientRequest.AddHeader("Proxy-Authorization", s);
}
m_send_buf = m_ClientRequest.to_string();
m_recv_buf.erase(0, m_req_len);
m_send_buf.append(m_recv_buf);
GetOwner()->CreateStream (std::bind (&HTTPReqHandler::HandleStreamRequestComplete,
shared_from_this(), std::placeholders::_1), m_ProxyURL.host, m_ProxyURL.port);
}
@ -409,14 +422,18 @@ namespace proxy { @@ -409,14 +422,18 @@ namespace proxy {
m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamHTTPProxyConnect, this, std::placeholders::_1));
}));
}
} else if (m_ProxyURL.schema == "socks") {
}
else if (m_ProxyURL.schema == "socks")
{
// handle upstream socks proxy
if (!m_ProxyURL.port) m_ProxyURL.port = 9050; // default to tor default if not specified
boost::asio::ip::tcp::resolver::query q(m_ProxyURL.host, std::to_string(m_ProxyURL.port));
m_proxy_resolver.async_resolve(q, std::bind(&HTTPReqHandler::HandleUpstreamProxyResolved, this, std::placeholders::_1, std::placeholders::_2, [&](boost::asio::ip::tcp::endpoint ep) {
m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamSocksProxyConnect, this, std::placeholders::_1));
}));
} else {
}
else
{
// unknown type, complain
GenericProxyError("unknown outproxy url", m_ProxyURL.to_string().c_str());
}

2
libi2pd_client/I2CP.cpp

@ -37,7 +37,7 @@ namespace client @@ -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;

2
libi2pd_client/I2PTunnel.h

@ -280,8 +280,6 @@ namespace client @@ -280,8 +280,6 @@ namespace client
const char* GetName() { return m_Name.c_str (); }
void SetMaxConnsPerMinute(const uint32_t conns) { m_PortDestination->SetMaxConnsPerMinute(conns); }
private:
void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it,
std::shared_ptr<boost::asio::ip::tcp::resolver> resolver);

10
qt/i2pd_qt/i2pd_qt.pro

@ -268,8 +268,14 @@ android { @@ -268,8 +268,14 @@ android {
}
linux:!android {
message("Using Linux settings")
LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc
message("Using Linux settings")
LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc
}
windows:!android {
message("Using Windows settings")
DEFINES += BOOST_USE_WINDOWS_H WINDOWS
LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc
}
!android:!symbian:!maemo5:!simulator {

Loading…
Cancel
Save