mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-08 22:57:52 +00:00
commit
46cb95f16c
14
ChangeLog
14
ChangeLog
@ -1,6 +1,20 @@
|
||||
# for this file format description,
|
||||
# see https://github.com/olivierlacan/keep-a-changelog
|
||||
|
||||
## [2.13.0] - 2017-04-06
|
||||
### Added
|
||||
- Persist local destination's tags
|
||||
- GOST signature types 9 and 10
|
||||
- Exploratory tunnels configuration
|
||||
### Changed
|
||||
- Reseed servers list
|
||||
- Inactive NTCP sockets get closed faster
|
||||
- Some EdDSA speed up
|
||||
### Fixed
|
||||
- Multiple acceptors for SAM
|
||||
- Follow on data after STREAM CREATE for SAM
|
||||
- Memory leaks
|
||||
|
||||
## [2.12.0] - 2017-02-14
|
||||
### Added
|
||||
- Additional HTTP and SOCKS proxy tunnels
|
||||
|
33
Crypto.h
33
Crypto.h
@ -289,13 +289,26 @@ namespace crypto
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER) // 1.1.0 or LibreSSL
|
||||
// define getters and setters introduced in 1.1.0
|
||||
inline int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
||||
{ d->p = p; d->q = q; d->g = g; return 1; }
|
||||
{
|
||||
if (d->p) BN_free (d->p);
|
||||
if (d->q) BN_free (d->q);
|
||||
if (d->g) BN_free (d->g);
|
||||
d->p = p; d->q = q; d->g = g; return 1;
|
||||
}
|
||||
inline int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
|
||||
{ d->pub_key = pub_key; d->priv_key = priv_key; return 1; }
|
||||
{
|
||||
if (d->pub_key) BN_free (d->pub_key);
|
||||
if (d->priv_key) BN_free (d->priv_key);
|
||||
d->pub_key = pub_key; d->priv_key = priv_key; return 1;
|
||||
}
|
||||
inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key)
|
||||
{ *pub_key = d->pub_key; *priv_key = d->priv_key; }
|
||||
inline int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
|
||||
{ sig->r = r; sig->s = s; return 1; }
|
||||
{
|
||||
if (sig->r) BN_free (sig->r);
|
||||
if (sig->s) BN_free (sig->s);
|
||||
sig->r = r; sig->s = s; return 1;
|
||||
}
|
||||
inline void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
|
||||
{ *pr = sig->r; *ps = sig->s; }
|
||||
|
||||
@ -309,12 +322,22 @@ inline void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM
|
||||
{ *pr = sig->r; *ps = sig->s; }
|
||||
|
||||
inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
|
||||
{ r->n = n; r->e = e; r->d = d; return 1; }
|
||||
{
|
||||
if (r->n) BN_free (r->n);
|
||||
if (r->e) BN_free (r->e);
|
||||
if (r->d) BN_free (r->d);
|
||||
r->n = n; r->e = e; r->d = d; return 1;
|
||||
}
|
||||
inline void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
|
||||
{ *n = r->n; *e = r->e; *d = r->d; }
|
||||
|
||||
inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
||||
{ dh->p = p; dh->q = q; dh->g = g; return 1; }
|
||||
{
|
||||
if (dh->p) BN_free (dh->p);
|
||||
if (dh->q) BN_free (dh->q);
|
||||
if (dh->g) BN_free (dh->g);
|
||||
dh->p = p; dh->q = q; dh->g = g; return 1;
|
||||
}
|
||||
inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
|
||||
{
|
||||
if (dh->pub_key) BN_free (dh->pub_key);
|
||||
|
@ -110,6 +110,7 @@ namespace client
|
||||
{
|
||||
if (!m_IsRunning)
|
||||
{
|
||||
LoadTags ();
|
||||
m_IsRunning = true;
|
||||
m_Pool->SetLocalDestination (shared_from_this ());
|
||||
m_Pool->SetActive (true);
|
||||
@ -145,6 +146,7 @@ namespace client
|
||||
delete m_Thread;
|
||||
m_Thread = 0;
|
||||
}
|
||||
SaveTags ();
|
||||
CleanUp (); // GarlicDestination
|
||||
return true;
|
||||
}
|
||||
|
14
FS.cpp
14
FS.cpp
@ -16,6 +16,7 @@
|
||||
#include "Base.h"
|
||||
#include "FS.h"
|
||||
#include "Log.h"
|
||||
#include "Garlic.h"
|
||||
|
||||
namespace i2p {
|
||||
namespace fs {
|
||||
@ -93,6 +94,11 @@ namespace fs {
|
||||
std::string destinations = DataDirPath("destinations");
|
||||
if (!boost::filesystem::exists(destinations))
|
||||
boost::filesystem::create_directory(destinations);
|
||||
std::string tags = DataDirPath("tags");
|
||||
if (!boost::filesystem::exists(tags))
|
||||
boost::filesystem::create_directory(tags);
|
||||
else
|
||||
i2p::garlic::CleanUpTagsFiles ();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -116,6 +122,14 @@ namespace fs {
|
||||
return boost::filesystem::exists(path);
|
||||
}
|
||||
|
||||
uint32_t GetLastUpdateTime (const std::string & path)
|
||||
{
|
||||
if (!boost::filesystem::exists(path)) return 0;
|
||||
boost::system::error_code ec;
|
||||
auto t = boost::filesystem::last_write_time (path, ec);
|
||||
return ec ? 0 : t;
|
||||
}
|
||||
|
||||
bool Remove(const std::string & path) {
|
||||
if (!boost::filesystem::exists(path))
|
||||
return false;
|
||||
|
4
FS.h
4
FS.h
@ -97,7 +97,7 @@ namespace fs {
|
||||
* @param files Vector to store found files
|
||||
* @return true on success and false if directory not exists
|
||||
*/
|
||||
bool ReadDir(const std::string & path, std::vector<std::string> & files);
|
||||
bool ReadDir(const std::string & path, std::vector<std::string> & files);
|
||||
|
||||
/**
|
||||
* @brief Remove file with given path
|
||||
@ -112,6 +112,8 @@ namespace fs {
|
||||
* @return true if file exists, false otherwise
|
||||
*/
|
||||
bool Exists(const std::string & path);
|
||||
|
||||
uint32_t GetLastUpdateTime (const std::string & path); // seconds since epoch
|
||||
|
||||
bool CreateDirectory (const std::string& path);
|
||||
|
||||
|
80
Garlic.cpp
80
Garlic.cpp
@ -10,6 +10,7 @@
|
||||
#include "Transports.h"
|
||||
#include "Timestamp.h"
|
||||
#include "Log.h"
|
||||
#include "FS.h"
|
||||
#include "Garlic.h"
|
||||
|
||||
namespace i2p
|
||||
@ -412,9 +413,7 @@ namespace garlic
|
||||
if (key)
|
||||
{
|
||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
auto decryption = std::make_shared<i2p::crypto::CBCDecryption>();
|
||||
decryption->SetKey (key);
|
||||
m_Tags[SessionTag(tag, ts)] = decryption;
|
||||
m_Tags[SessionTag(tag, ts)] = std::make_shared<AESDecryption>(key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -456,8 +455,7 @@ namespace garlic
|
||||
ElGamalBlock elGamal;
|
||||
if (length >= 514 && i2p::crypto::ElGamalDecrypt (GetEncryptionPrivateKey (), buf, (uint8_t *)&elGamal, m_Ctx, true))
|
||||
{
|
||||
auto decryption = std::make_shared<i2p::crypto::CBCDecryption>();
|
||||
decryption->SetKey (elGamal.sessionKey);
|
||||
auto decryption = std::make_shared<AESDecryption>(elGamal.sessionKey);
|
||||
uint8_t iv[32]; // IV is first 16 bytes
|
||||
SHA256(elGamal.preIV, 32, iv);
|
||||
decryption->SetIV (iv);
|
||||
@ -469,7 +467,7 @@ namespace garlic
|
||||
}
|
||||
}
|
||||
|
||||
void GarlicDestination::HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<i2p::crypto::CBCDecryption> decryption,
|
||||
void GarlicDestination::HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<AESDecryption> decryption,
|
||||
std::shared_ptr<i2p::tunnel::InboundTunnel> from)
|
||||
{
|
||||
uint16_t tagCount = bufbe16toh (buf);
|
||||
@ -714,5 +712,75 @@ namespace garlic
|
||||
HandleDeliveryStatusMessage (msg);
|
||||
}
|
||||
|
||||
void GarlicDestination::SaveTags ()
|
||||
{
|
||||
if (m_Tags.empty ()) return;
|
||||
std::string ident = GetIdentHash().ToBase32();
|
||||
std::string path = i2p::fs::DataDirPath("tags", (ident + ".tags"));
|
||||
std::ofstream f (path, std::ofstream::binary | std::ofstream::out | std::ofstream::trunc);
|
||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
// 4 bytes timestamp, 32 bytes tag, 32 bytes key
|
||||
for (auto it: m_Tags)
|
||||
{
|
||||
if (ts < it.first.creationTime + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||
{
|
||||
f.write ((char *)&it.first.creationTime, 4);
|
||||
f.write ((char *)it.first.data (), 32);
|
||||
f.write ((char *)it.second->GetKey ().data (), 32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GarlicDestination::LoadTags ()
|
||||
{
|
||||
std::string ident = GetIdentHash().ToBase32();
|
||||
std::string path = i2p::fs::DataDirPath("tags", (ident + ".tags"));
|
||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
if (ts < i2p::fs::GetLastUpdateTime (path) + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||
{
|
||||
// might contain non-expired tags
|
||||
std::ifstream f (path, std::ifstream::binary);
|
||||
if (f)
|
||||
{
|
||||
std::map<i2p::crypto::AESKey, std::shared_ptr<AESDecryption> > keys;
|
||||
// 4 bytes timestamp, 32 bytes tag, 32 bytes key
|
||||
while (!f.eof ())
|
||||
{
|
||||
uint32_t t;
|
||||
uint8_t tag[32], key[32];
|
||||
f.read ((char *)&t, 4); if (f.eof ()) break;
|
||||
if (ts < t + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||
{
|
||||
f.read ((char *)tag, 32);
|
||||
f.read ((char *)key, 32);
|
||||
}
|
||||
else
|
||||
f.seekg (64, std::ios::cur); // skip
|
||||
if (f.eof ()) break;
|
||||
|
||||
std::shared_ptr<AESDecryption> decryption;
|
||||
auto it = keys.find (key);
|
||||
if (it != keys.end ())
|
||||
decryption = it->second;
|
||||
else
|
||||
decryption = std::make_shared<AESDecryption>(key);
|
||||
m_Tags.insert (std::make_pair (SessionTag (tag, ts), decryption));
|
||||
}
|
||||
if (!m_Tags.empty ())
|
||||
LogPrint (eLogInfo, m_Tags.size (), " loaded for ", ident);
|
||||
}
|
||||
}
|
||||
i2p::fs::Remove (path);
|
||||
}
|
||||
|
||||
void CleanUpTagsFiles ()
|
||||
{
|
||||
std::vector<std::string> files;
|
||||
i2p::fs::ReadDir (i2p::fs::DataDirPath("tags"), files);
|
||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
for (auto it: files)
|
||||
if (ts >= i2p::fs::GetLastUpdateTime (it) + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||
i2p::fs::Remove (it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
32
Garlic.h
32
Garlic.h
@ -59,6 +59,22 @@ namespace garlic
|
||||
uint32_t creationTime; // seconds since epoch
|
||||
};
|
||||
|
||||
// AESDecryption is associated with session tags and store key
|
||||
class AESDecryption: public i2p::crypto::CBCDecryption
|
||||
{
|
||||
public:
|
||||
|
||||
AESDecryption (const uint8_t * key): m_Key (key)
|
||||
{
|
||||
SetKey (key);
|
||||
}
|
||||
const i2p::crypto::AESKey& GetKey () const { return m_Key; };
|
||||
|
||||
private:
|
||||
|
||||
i2p::crypto::AESKey m_Key;
|
||||
};
|
||||
|
||||
struct GarlicRoutingPath
|
||||
{
|
||||
std::shared_ptr<i2p::tunnel::OutboundTunnel> outboundTunnel;
|
||||
@ -67,7 +83,7 @@ namespace garlic
|
||||
uint32_t updateTime; // seconds since epoch
|
||||
int numTimesUsed;
|
||||
};
|
||||
|
||||
|
||||
class GarlicDestination;
|
||||
class GarlicRoutingSession: public std::enable_shared_from_this<GarlicRoutingSession>
|
||||
{
|
||||
@ -180,10 +196,13 @@ namespace garlic
|
||||
|
||||
void HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
||||
void HandleDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
||||
|
||||
|
||||
void SaveTags ();
|
||||
void LoadTags ();
|
||||
|
||||
private:
|
||||
|
||||
void HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<i2p::crypto::CBCDecryption> decryption,
|
||||
void HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<AESDecryption> decryption,
|
||||
std::shared_ptr<i2p::tunnel::InboundTunnel> from);
|
||||
void HandleGarlicPayload (uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from);
|
||||
|
||||
@ -195,7 +214,7 @@ namespace garlic
|
||||
std::mutex m_SessionsMutex;
|
||||
std::map<i2p::data::IdentHash, GarlicRoutingSessionPtr> m_Sessions;
|
||||
// incoming
|
||||
std::map<SessionTag, std::shared_ptr<i2p::crypto::CBCDecryption>> m_Tags;
|
||||
std::map<SessionTag, std::shared_ptr<AESDecryption> > m_Tags;
|
||||
// DeliveryStatus
|
||||
std::mutex m_DeliveryStatusSessionsMutex;
|
||||
std::map<uint32_t, GarlicRoutingSessionPtr> m_DeliveryStatusSessions; // msgID -> session
|
||||
@ -205,7 +224,10 @@ namespace garlic
|
||||
// for HTTP only
|
||||
size_t GetNumIncomingTags () const { return m_Tags.size (); }
|
||||
const decltype(m_Sessions)& GetSessions () const { return m_Sessions; };
|
||||
};
|
||||
};
|
||||
|
||||
void CleanUpTagsFiles ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#define I2Pd_AppName "i2pd"
|
||||
#define I2Pd_ver "2.12.0"
|
||||
#define I2Pd_ver "2.13.0"
|
||||
#define I2Pd_Publisher "PurpleI2P"
|
||||
|
||||
[Setup]
|
||||
|
@ -2,7 +2,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.purplei2p.i2pd"
|
||||
android:versionCode="1"
|
||||
android:versionName="2.12.0">
|
||||
android:versionName="2.13.0">
|
||||
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="24"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: 2.12.{build}
|
||||
version: 2.13.{build}
|
||||
pull_requests:
|
||||
do_not_increment_build_number: true
|
||||
branches:
|
||||
|
9
debian/changelog
vendored
9
debian/changelog
vendored
@ -1,3 +1,12 @@
|
||||
i2pd (2.13.0-1) unstable; urgency=low
|
||||
|
||||
* updated to version 2.13.0/0.9.29
|
||||
* updated debian/control
|
||||
* renamed logrotate to i2pd.logrotate
|
||||
* fixed init.d script
|
||||
|
||||
-- orignal <orignal@i2pmail.org> Tue, 6 Apr 2017 14:00:00 +0000
|
||||
|
||||
i2pd (2.12.0-1) unstable; urgency=low
|
||||
|
||||
* updated to version 2.12.0/0.9.28
|
||||
|
38
debian/control
vendored
38
debian/control
vendored
@ -1,17 +1,10 @@
|
||||
Source: i2pd
|
||||
Section: net
|
||||
Priority: extra
|
||||
Priority: optional
|
||||
Maintainer: R4SAS <r4sas@i2pmail.org>
|
||||
Build-Depends: debhelper (>= 9.0.0), dpkg-dev (>= 1.16.1~),
|
||||
gcc (>= 4.7) | clang (>= 3.3),
|
||||
libboost-system-dev (>= 1.46),
|
||||
libboost-date-time-dev,
|
||||
libboost-filesystem-dev,
|
||||
libboost-program-options-dev,
|
||||
libminiupnpc-dev,
|
||||
libssl-dev
|
||||
Standards-Version: 3.9.3
|
||||
Homepage: https://github.com/PurpleI2P/i2pd
|
||||
Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.16.1~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev, libboost-filesystem-dev, libboost-program-options-dev, libminiupnpc-dev, libssl-dev
|
||||
Standards-Version: 3.9.6
|
||||
Homepage: http://i2pd.website/
|
||||
Vcs-Git: git://github.com/PurpleI2P/i2pd.git
|
||||
Vcs-Browser: https://github.com/PurpleI2P/i2pd.git
|
||||
|
||||
@ -19,26 +12,23 @@ Package: i2pd
|
||||
Architecture: any
|
||||
Pre-Depends: adduser
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Recommends: privoxy
|
||||
Suggests: tor
|
||||
Description: load-balanced unspoofable packet switching network - C++ port
|
||||
I2P is an anonymizing network, offering a simple layer that identity-sensitive
|
||||
applications can use to securely communicate. All data is wrapped with several
|
||||
layers of encryption, and the network is both distributed and dynamic, with no
|
||||
trusted parties.
|
||||
Suggests: tor, privoxy
|
||||
Description: i2pd is a full-featured C++ implementation of I2P client.
|
||||
I2P (Invisible Internet Protocol) is a universal anonymous network layer. All
|
||||
communications over I2P are anonymous and end-to-end encrypted, participants
|
||||
don't reveal their real IP addresses.
|
||||
.
|
||||
This package contains the port of the I2P router to C++. Unless willing
|
||||
to test and report problems, you should install the 'i2p' package instead.
|
||||
This package contains the full-featured C++ implementation of I2P router.
|
||||
|
||||
Package: i2pd-dbg
|
||||
Architecture: any
|
||||
Priority: extra
|
||||
Section: debug
|
||||
Depends: i2pd (= ${binary:Version}), ${misc:Depends}
|
||||
Suggests: gdb
|
||||
Description: i2pd debugging symbols
|
||||
I2P is an anonymizing network, offering a simple layer that identity-sensitive
|
||||
applications can use to securely communicate. All data is wrapped with several
|
||||
layers of encryption, and the network is both distributed and dynamic, with no
|
||||
trusted parties.
|
||||
I2P (Invisible Internet Protocol) is a universal anonymous network layer. All
|
||||
communications over I2P are anonymous and end-to-end encrypted, participants
|
||||
don't reveal their real IP addresses.
|
||||
.
|
||||
This package contains symbols required for debugging.
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0"?>
|
||||
<manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.12.0" android:versionCode="2" android:installLocation="auto">
|
||||
<manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.13.0" android:versionCode="2" android:installLocation="auto">
|
||||
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23"/>
|
||||
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
|
||||
<!-- <application android:hardwareAccelerated="true" -->
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c)
|
||||
|
||||
#define I2PD_VERSION_MAJOR 2
|
||||
#define I2PD_VERSION_MINOR 12
|
||||
#define I2PD_VERSION_MINOR 13
|
||||
#define I2PD_VERSION_MICRO 0
|
||||
#define I2PD_VERSION_PATCH 0
|
||||
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
|
||||
|
Loading…
Reference in New Issue
Block a user