diff --git a/ChangeLog b/ChangeLog index ca30a1ac..9013ede8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,21 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.22.0] - 2018-11-09 +### Added +- Multiple tunnel config files from tunnels.d folder +### Changed +- Fetch own RouterInfo upon SessionRequest for NTCP2 +- Faster XOR between AES blocks for non AVX capable CPUs +### Fixed +- Fixed NTCP2 termination send + +## [2.21.1] - 2018-10-22 +### Changed +- cost=13 for unpublished NTCP2 address +### Fixed +- Handle I2NP messages longer than 32K + ## [2.21.0] - 2018-10-04 ### Added - EdDSA, x25519 and SipHash from openssl 1.1.1 diff --git a/Win32/installer.iss b/Win32/installer.iss index 8372a444..787eebeb 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.21.0" +#define I2Pd_ver "2.22.0" #define I2Pd_Publisher "PurpleI2P" [Setup] @@ -32,6 +32,7 @@ Source: ..\contrib\i2pd.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntex Source: ..\contrib\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist Source: ..\contrib\tunnels.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist Source: ..\contrib\certificates\*; DestDir: {userappdata}\i2pd\certificates; Flags: onlyifdoesntexist recursesubdirs createallsubdirs +Source: ..\contrib\tunnels.d\*; DestDir: {userappdata}\i2pd\tunnels.d; Flags: onlyifdoesntexist recursesubdirs createallsubdirs [Icons] Name: {group}\I2Pd; Filename: {app}\i2pd.exe diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index e5a711aa..5ad3834e 100755 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -3,7 +3,7 @@ package="org.purplei2p.i2pd" android:installLocation="auto" android:versionCode="1" - android:versionName="2.21.0"> + android:versionName="2.22.0"> > nul echo Building i2pd %tag% for win%bitness%: echo Build AVX+AESNI... -%xSH% "make DEBUG=no USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_avx_aesni.log 2>&1 +%xSH% "make DEBUG=no USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip %FILELIST% && make clean" > build/build_win%bitness%_avx_aesni_%tag%.log 2>&1 echo Build AVX... -%xSH% "make DEBUG=no USE_UPNP=yes USE_AVX=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_avx.log 2>&1 +%xSH% "make DEBUG=no USE_UPNP=yes USE_AVX=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx.zip %FILELIST% && make clean" > build/build_win%bitness%_avx_%tag%.log 2>&1 echo Build AESNI... -%xSH% "make DEBUG=no USE_UPNP=yes USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_aesni.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_aesni.log 2>&1 +%xSH% "make DEBUG=no USE_UPNP=yes USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_aesni.zip %FILELIST% && make clean" > build/build_win%bitness%_aesni_%tag%.log 2>&1 echo Build without extensions... -%xSH% "make DEBUG=no USE_UPNP=yes -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%.log 2>&1 +%xSH% "make DEBUG=no USE_UPNP=yes -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST% && make clean" > build/build_win%bitness%_%tag%.log 2>&1 :EOF \ No newline at end of file diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 92abf496..40949cc1 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -10,6 +10,11 @@ ## Default: ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf # tunconf = /var/lib/i2pd/tunnels.conf +## Tunnels config files path +## Use that path to store separated tunnels in different config files. +## Default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d +# tunnelsdir = /var/lib/i2pd/tunnels.conf.d + ## Where to write pidfile (don't write by default) # pidfile = /var/run/i2pd.pid diff --git a/contrib/i2pd.service b/contrib/i2pd.service index debd49b0..a8eeb8d3 100644 --- a/contrib/i2pd.service +++ b/contrib/i2pd.service @@ -11,7 +11,7 @@ RuntimeDirectoryMode=0700 LogsDirectory=i2pd LogsDirectoryMode=0700 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 +ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --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 ### Uncomment, if auto restart needed @@ -23,8 +23,10 @@ KillSignal=SIGQUIT #KillSignal=SIGINT #TimeoutStopSec=10m -# If you have problems with hanging i2pd, you can try enable this +# If you have problems with hanging i2pd, you can try increase this LimitNOFILE=4096 +# To enable write of coredump uncomment this +#LimitCORE=infinity PrivateDevices=yes [Install] diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 627b81ae..984ccffa 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.21.0 +Version: 2.22.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -60,11 +60,14 @@ install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf install -d -m 755 %{buildroot}%{_datadir}/i2pd +install -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d %{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates +%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/tunnels.d/ %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}%{_unitdir}/i2pd.service install -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd install -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates +ln -s %{_datadir}/i2pd/tunnels.conf.d %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d %pre @@ -91,6 +94,7 @@ getent passwd i2pd >/dev/null || \ %{_sbindir}/i2pd %{_datadir}/i2pd/certificates %config(noreplace) %{_sysconfdir}/i2pd/* +%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* /%{_unitdir}/i2pd.service %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd @@ -98,5 +102,8 @@ getent passwd i2pd >/dev/null || \ %changelog +* Fri Nov 09 2018 r4sas - 2.22.0 +- add support of tunnelsdir option + * Thu Feb 01 2018 r4sas - 2.18.0 - Initial i2pd-git based on i2pd 2.18.0-1 spec diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 2deeecab..5daeef2c 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.21.0 +Version: 2.22.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -58,11 +58,14 @@ install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf install -d -m 755 %{buildroot}%{_datadir}/i2pd +install -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d %{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates +%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/tunnels.d/ %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}%{_unitdir}/i2pd.service install -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd install -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates +ln -s %{_datadir}/i2pd/tunnels.conf.d %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d %pre @@ -89,6 +92,7 @@ getent passwd i2pd >/dev/null || \ %{_sbindir}/i2pd %{_datadir}/i2pd/certificates %config(noreplace) %{_sysconfdir}/i2pd/* +%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* /%{_unitdir}/i2pd.service %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd @@ -96,6 +100,13 @@ getent passwd i2pd >/dev/null || \ %changelog +* Fri Nov 09 2018 r4sas - 2.22.0 +- update to 2.22.0 +- add support of tunnelsdir option + +* Thu Oct 22 2018 orignal - 2.21.1 +- update to 2.21.1 + * Thu Oct 4 2018 orignal - 2.21.0 - update to 2.21.0 diff --git a/contrib/tunnels.d/IRC-Ilita.conf b/contrib/tunnels.d/IRC-Ilita.conf new file mode 100644 index 00000000..74d836aa --- /dev/null +++ b/contrib/tunnels.d/IRC-Ilita.conf @@ -0,0 +1,7 @@ +#[IRC-ILITA] +#type = client +#address = 127.0.0.1 +#port = 6669 +#destination = irc.ilita.i2p +#destinationport = 6667 +#keys = irc-keys.dat diff --git a/contrib/tunnels.d/IRC-Irc2P.conf b/contrib/tunnels.d/IRC-Irc2P.conf new file mode 100644 index 00000000..7255f9d5 --- /dev/null +++ b/contrib/tunnels.d/IRC-Irc2P.conf @@ -0,0 +1,7 @@ +#[IRC-IRC2P] +#type = client +#address = 127.0.0.1 +#port = 6668 +#destination = irc.postman.i2p +#destinationport = 6667 +#keys = irc-keys.dat \ No newline at end of file diff --git a/contrib/tunnels.d/README b/contrib/tunnels.d/README new file mode 100644 index 00000000..3ac3c1a3 --- /dev/null +++ b/contrib/tunnels.d/README @@ -0,0 +1 @@ +In that directory you can store separated config files for every tunnel. \ No newline at end of file diff --git a/debian/.gitignore b/debian/.gitignore index 6bc6bcf2..b03f9e24 100644 --- a/debian/.gitignore +++ b/debian/.gitignore @@ -1,9 +1,9 @@ +debhelper-build-stamp files i2pd-dbg.substvars -i2pd-dbg/ i2pd.postinst.debhelper i2pd.postrm.debhelper i2pd.prerm.debhelper i2pd.substvars i2pd/ - +i2pd-dbg/ diff --git a/debian/changelog b/debian/changelog index f16fb10d..eb48dbdf 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,18 @@ +i2pd (2.22.0-1) unstable; urgency=medium + + * updated to version 2.22.0/0.9.37 + * update manpage (1) + * update links, install files to support tunnelsdir option + * renamed and updated patch (#1210) + + -- r4sas Fri, 09 Nov 2018 02:00:00 +0000 + +i2pd (2.21.1-1) unstable; urgency=medium + + * updated to version 2.21.1 + + -- orignal Thu, 22 Oct 2018 16:00:00 +0000 + i2pd (2.21.0-1) unstable; urgency=medium * updated to version 2.21.0/0.9.37 diff --git a/debian/i2pd.1 b/debian/i2pd.1 index 9dd44093..5145321f 100644 --- a/debian/i2pd.1 +++ b/debian/i2pd.1 @@ -45,6 +45,9 @@ Log messages with full CLF-formatted date and time (\fIdisabled\fR by default) \fB\-\-datadir=\fR Path to storage of i2pd data (RI, keys, peer profiles, ...) .TP +\fB\-\-tunnelsdir=\fR +Path to tunnels configuration files (default: \fI~/.i2pd/tunnels.d\fR or \fI/var/lib/i2pd/tunnels.d\fR) +.TP \fB\-\-host=\fR The external IP address .TP diff --git a/debian/i2pd.dirs b/debian/i2pd.dirs index 3b643352..736e23bd 100644 --- a/debian/i2pd.dirs +++ b/debian/i2pd.dirs @@ -1,2 +1,3 @@ etc/i2pd +etc/i2pd/tunnels.conf.d var/lib/i2pd diff --git a/debian/i2pd.init b/debian/i2pd.init index e4ed01e1..33fd80a5 100644 --- a/debian/i2pd.init +++ b/debian/i2pd.init @@ -18,6 +18,7 @@ DAEMON_OPTS="" # Arguments to run the daemon with PIDFILE=/var/run/$NAME/$NAME.pid I2PCONF=/etc/$NAME/i2pd.conf TUNCONF=/etc/$NAME/tunnels.conf +TUNDIR=/etc/$NAME/tunnels.conf.d LOGFILE=/var/log/$NAME/$NAME.log USER="i2pd" @@ -53,7 +54,7 @@ do_start() || return 1 start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid "$USER" -- \ --service --daemon --log=file --logfile=$LOGFILE --conf=$I2PCONF --tunconf=$TUNCONF \ - --pidfile=$PIDFILE $DAEMON_OPTS > /dev/null 2>&1 \ + --tunnelsdir=$TUNDIR --pidfile=$PIDFILE $DAEMON_OPTS > /dev/null 2>&1 \ || return 2 return $? } diff --git a/debian/i2pd.install b/debian/i2pd.install index d81101fc..cae69c0e 100644 --- a/debian/i2pd.install +++ b/debian/i2pd.install @@ -3,4 +3,5 @@ contrib/i2pd.conf etc/i2pd/ contrib/tunnels.conf etc/i2pd/ contrib/subscriptions.txt etc/i2pd/ contrib/certificates/ usr/share/i2pd/ +contrib/tunnels.d/ etc/i2pd/tunnels.conf.d contrib/apparmor/usr.sbin.i2pd etc/apparmor.d diff --git a/debian/i2pd.links b/debian/i2pd.links index e8e2473b..083bc6ca 100644 --- a/debian/i2pd.links +++ b/debian/i2pd.links @@ -1,4 +1,5 @@ etc/i2pd/i2pd.conf var/lib/i2pd/i2pd.conf etc/i2pd/tunnels.conf var/lib/i2pd/tunnels.conf etc/i2pd/subscriptions.txt var/lib/i2pd/subscriptions.txt +etc/i2pd/tunnels.conf.d var/lib/i2pd/tunnels.conf.d usr/share/i2pd/certificates var/lib/i2pd/certificates diff --git a/debian/i2pd.openrc b/debian/i2pd.openrc index 2ad10bc5..deca4625 100644 --- a/debian/i2pd.openrc +++ b/debian/i2pd.openrc @@ -4,10 +4,11 @@ pidfile="/var/run/i2pd/i2pd.pid" logfile="/var/log/i2pd/i2pd.log" mainconf="/etc/i2pd/i2pd.conf" tunconf="/etc/i2pd/tunnels.conf" +tundir="/etc/i2pd/tunnels.conf.d" name="i2pd" command="/usr/sbin/i2pd" -command_args="--service --daemon --log=file --logfile=$logfile --conf=$mainconf --tunconf=$tunconf --pidfile=$pidfile" +command_args="--service --daemon --log=file --logfile=$logfile --conf=$mainconf --tunconf=$tunconf --tunnelsdir=$tundir --pidfile=$pidfile" description="i2p router written in C++" required_dirs="/var/lib/i2pd" required_files="$mainconf" diff --git a/debian/patches/fix-#1210 b/debian/patches/02-fix-1210.patch similarity index 75% rename from debian/patches/fix-#1210 rename to debian/patches/02-fix-1210.patch index 7e68135c..6a4caf94 100644 --- a/debian/patches/fix-#1210 +++ b/debian/patches/02-fix-1210.patch @@ -6,8 +6,8 @@ Bug: https://github.com/PurpleI2P/i2pd/issues/1210 Reviewed-By: r4sas Last-Update: 2018-08-25 ---- i2pd-2.20.0.orig/contrib/i2pd.service -+++ i2pd-2.20.0/contrib/i2pd.service +--- a/contrib/i2pd.service ++++ b/contrib/i2pd.service @@ -6,10 +6,10 @@ After=network.target [Service] User=i2pd @@ -21,5 +21,5 @@ Last-Update: 2018-08-25 +#LogsDirectory=i2pd +#LogsDirectoryMode=0700 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 + ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service ExecReload=/bin/kill -HUP $MAINPID diff --git a/debian/patches/series b/debian/patches/series index 5a9712bd..002802b5 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1,2 @@ 01-tune-build-opts.patch -fix-#1210 +02-fix-1210.patch diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index abeba94f..15777968 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -32,8 +32,10 @@ namespace config { options_description general("General options"); general.add_options() ("help", "Show this message") + ("version", "Show i2pd version") ("conf", value()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)") ("tunconf", value()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)") + ("tunnelsdir", value()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d") ("pidfile", value()->default_value(""), "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)") ("log", value()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)") ("logfile", value()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)") @@ -282,6 +284,23 @@ namespace config { { std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl; std::cout << m_OptionsDesc; + exit(EXIT_SUCCESS); + } + else if (m_Options.count("version")) + { + std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl; + std::cout << "Boost version " + << BOOST_VERSION / 100000 << "." // maj. version + << BOOST_VERSION / 100 % 1000 << "." // min. version + << BOOST_VERSION % 100 // patch version + << std::endl; +#if defined(OPENSSL_VERSION_TEXT) + std::cout << OPENSSL_VERSION_TEXT << std::endl; +#endif +#if defined(LIBRESSL_VERSION_TEXT) + std::cout << LIBRESSL_VERSION_TEXT << std::endl; +#endif + exit(EXIT_SUCCESS); } } diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 4393b2cc..ffd3c4ef 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -341,6 +341,16 @@ namespace crypto #endif } + void X25519Keys::GetPrivateKey (uint8_t * priv) const + { +#if OPENSSL_X25519 + size_t len = 32; + EVP_PKEY_get_raw_private_key (m_Pkey, priv, &len); +#else + memcpy (priv, m_PrivateKey, 32); +#endif + } + // ElGamal void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) { diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index c2da1f4d..5daf82b0 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -72,6 +72,7 @@ namespace crypto void GenerateKeys (); const uint8_t * GetPublicKey () const { return m_PublicKey; }; + void GetPrivateKey (uint8_t * priv) const; void Agree (const uint8_t * pub, uint8_t * shared); private: @@ -124,9 +125,17 @@ namespace crypto else #endif { - // TODO: implement it better - for (int i = 0; i < 16; i++) - buf[i] ^= other.buf[i]; + if (!(((size_t)buf | (size_t)other.buf) & 0x03)) // multiple of 4 ? + { + // we are good to cast to uint32_t * + for (int i = 0; i < 4; i++) + ((uint32_t *)buf)[i] ^= ((uint32_t *)other.buf)[i]; + } + else + { + for (int i = 0; i < 16; i++) + buf[i] ^= other.buf[i]; + } } } }; diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 1d60fef5..8caafd2f 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -40,7 +40,7 @@ namespace transport delete[] m_SessionConfirmedBuffer; } - void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived) + void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial) { // temp_key = HMAC-SHA256(ck, input_key_material) uint8_t tempKey[32]; unsigned int len; @@ -50,7 +50,16 @@ namespace transport HMAC(EVP_sha256(), tempKey, 32, one, 1, m_CK, &len); // derived = HMAC-SHA256(temp_key, ck || byte(0x02)) m_CK[32] = 2; - HMAC(EVP_sha256(), tempKey, 32, m_CK, 33, derived, &len); + HMAC(EVP_sha256(), tempKey, 32, m_CK, 33, m_K, &len); + } + + void NTCP2Establisher::MixHash (const uint8_t * buf, size_t len) + { + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, m_H, 32); + SHA256_Update (&ctx, buf, len); + SHA256_Final (m_H, &ctx); } void NTCP2Establisher::KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub) @@ -73,14 +82,11 @@ namespace transport SHA256_Update (&ctx, rs, 32); SHA256_Final (m_H, &ctx); // h = SHA256(h || epub) - SHA256_Init (&ctx); - SHA256_Update (&ctx, m_H, 32); - SHA256_Update (&ctx, epub, 32); - SHA256_Final (m_H, &ctx); + MixHash (epub, 32); // x25519 between pub and priv uint8_t inputKeyMaterial[32]; priv.Agree (pub, inputKeyMaterial); - MixKey (inputKeyMaterial, m_K); + MixKey (inputKeyMaterial); } void NTCP2Establisher::KDF1Alice () @@ -95,30 +101,18 @@ namespace transport void NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub) { - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, m_H, 32); - SHA256_Update (&ctx, sessionRequest + 32, 32); // encrypted payload - SHA256_Final (m_H, &ctx); + MixHash (sessionRequest + 32, 32); // encrypted payload int paddingLength = sessionRequestLen - 64; if (paddingLength > 0) - { - SHA256_Init (&ctx); - SHA256_Update (&ctx, m_H, 32); - SHA256_Update (&ctx, sessionRequest + 64, paddingLength); - SHA256_Final (m_H, &ctx); - } - SHA256_Init (&ctx); - SHA256_Update (&ctx, m_H, 32); - SHA256_Update (&ctx, epub, 32); - SHA256_Final (m_H, &ctx); + MixHash (sessionRequest + 64, paddingLength); + MixHash (epub, 32); // x25519 between remote pub and ephemaral priv uint8_t inputKeyMaterial[32]; m_EphemeralKeys.Agree (GetRemotePub (), inputKeyMaterial); - MixKey (inputKeyMaterial, m_K); + MixKey (inputKeyMaterial); } void NTCP2Establisher::KDF2Alice () @@ -135,14 +129,14 @@ namespace transport { uint8_t inputKeyMaterial[32]; i2p::context.GetStaticKeys ().Agree (GetRemotePub (), inputKeyMaterial); - MixKey (inputKeyMaterial, m_K); + MixKey (inputKeyMaterial); } void NTCP2Establisher::KDF3Bob () { uint8_t inputKeyMaterial[32]; m_EphemeralKeys.Agree (m_RemoteStaticKey, inputKeyMaterial); - MixKey (inputKeyMaterial, m_K); + MixKey (inputKeyMaterial); } void NTCP2Establisher::CreateEphemeralKey () @@ -170,8 +164,17 @@ namespace transport memset (options, 0, 16); options[1] = 2; // ver htobe16buf (options + 2, paddingLength); // padLen - m3p2Len = i2p::context.GetRouterInfo ().GetBufferLen () + 20; // (RI header + RI + MAC for now) TODO: implement options + // m3p2Len + auto bufLen = i2p::context.GetRouterInfo ().GetBufferLen (); + m3p2Len = bufLen + 4 + 16; // (RI header + RI + MAC for now) TODO: implement options htobe16buf (options + 4, m3p2Len); + // fill m3p2 payload (RouterInfo block) + m_SessionConfirmedBuffer = new uint8_t[m3p2Len + 48]; // m3p1 is 48 bytes + uint8_t * m3p2 = m_SessionConfirmedBuffer + 48; + m3p2[0] = eNTCP2BlkRouterInfo; // block + htobe16buf (m3p2 + 1, bufLen + 1); // flag + RI + m3p2[3] = 0; // flag + memcpy (m3p2 + 4, i2p::context.GetRouterInfo ().GetBuffer (), bufLen); // TODO: own RI should be protected by mutex // 2 bytes reserved htobe32buf (options + 8, i2p::util::GetSecondsSinceEpoch ()); // tsA // 4 bytes reserved @@ -208,23 +211,12 @@ namespace transport void NTCP2Establisher::CreateSessionConfirmedMessagePart1 (const uint8_t * nonce) { // update AD - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, m_H, 32); - SHA256_Update (&ctx, m_SessionCreatedBuffer + 32, 32); // encrypted payload - SHA256_Final (m_H, &ctx); - + MixHash (m_SessionCreatedBuffer + 32, 32); // encrypted payload int paddingLength = m_SessionCreatedBufferLen - 64; if (paddingLength > 0) - { - SHA256_CTX ctx1; - SHA256_Init (&ctx1); - SHA256_Update (&ctx1, m_H, 32); - SHA256_Update (&ctx1, m_SessionCreatedBuffer + 64, paddingLength); - SHA256_Final (m_H, &ctx1); - } - // part1 48 bytes - m_SessionConfirmedBuffer = new uint8_t[m3p2Len + 48]; + MixHash (m_SessionCreatedBuffer + 64, paddingLength); + + // part1 48 bytes i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetNTCP2StaticPublicKey (), 32, m_H, 32, m_K, nonce, m_SessionConfirmedBuffer, 48, true); // encrypt } @@ -232,24 +224,13 @@ namespace transport { // part 2 // update AD again - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, m_H, 32); - SHA256_Update (&ctx, m_SessionConfirmedBuffer, 48); - SHA256_Final (m_H, &ctx); - // fill and encrypt - uint8_t * buf = m_SessionConfirmedBuffer + 48; - buf[0] = eNTCP2BlkRouterInfo; // block - htobe16buf (buf + 1, i2p::context.GetRouterInfo ().GetBufferLen () + 1); // flag + RI - buf[3] = 0; // flag - memcpy (buf + 4, i2p::context.GetRouterInfo ().GetBuffer (), i2p::context.GetRouterInfo ().GetBufferLen ()); + MixHash (m_SessionConfirmedBuffer, 48); + // encrypt m3p2, it must be filled in SessionRequest KDF3Alice (); - i2p::crypto::AEADChaCha20Poly1305 (buf, m3p2Len - 16, m_H, 32, m_K, nonce, buf, m3p2Len, true); // encrypt + uint8_t * m3p2 = m_SessionConfirmedBuffer + 48; + i2p::crypto::AEADChaCha20Poly1305 (m3p2, m3p2Len - 16, m_H, 32, m_K, nonce, m3p2, m3p2Len, true); // encrypt // update h again - SHA256_Init (&ctx); - SHA256_Update (&ctx, m_H, 32); - SHA256_Update (&ctx, buf, m3p2Len); - SHA256_Final (m_H, &ctx); //h = SHA256(h || ciphertext) + MixHash (m3p2, m3p2Len); //h = SHA256(h || ciphertext) } bool NTCP2Establisher::ProcessSessionRequestMessage (uint16_t& paddingLen) @@ -339,21 +320,11 @@ namespace transport bool NTCP2Establisher::ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce) { // update AD - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, m_H, 32); - SHA256_Update (&ctx, m_SessionCreatedBuffer + 32, 32); // encrypted payload - SHA256_Final (m_H, &ctx); - + MixHash (m_SessionCreatedBuffer + 32, 32); // encrypted payload int paddingLength = m_SessionCreatedBufferLen - 64; if (paddingLength > 0) - { - SHA256_CTX ctx1; - SHA256_Init (&ctx1); - SHA256_Update (&ctx1, m_H, 32); - SHA256_Update (&ctx1, m_SessionCreatedBuffer + 64, paddingLength); - SHA256_Final (m_H, &ctx1); - } + MixHash (m_SessionCreatedBuffer + 64, paddingLength); + if (!i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer, 32, m_H, 32, m_K, nonce, m_RemoteStaticKey, 32, false)) // decrypt S { LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part1 AEAD verification failed "); @@ -365,11 +336,7 @@ namespace transport bool NTCP2Establisher::ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf) { // update AD again - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, m_H, 32); - SHA256_Update (&ctx, m_SessionConfirmedBuffer, 48); - SHA256_Final (m_H, &ctx); + MixHash (m_SessionConfirmedBuffer, 48); KDF3Bob (); if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer + 48, m3p2Len - 16, m_H, 32, m_K, nonce, m3p2Buf, m3p2Len - 16, false)) // decrypt @@ -1041,7 +1008,7 @@ namespace transport void NTCP2Session::SendTermination (NTCP2TerminationReason reason) { - if (!IsEstablished ()) return; + if (!m_SendKey || !m_SendSipKey) return; uint8_t payload[12] = { eNTCP2BlkTermination, 0, 9 }; htobe64buf (payload + 3, m_ReceiveSequenceNumber); payload[11] = (uint8_t)reason; diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 7db6e8bf..ec8ae527 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -95,7 +95,8 @@ namespace transport void KDF3Alice (); // for SessionConfirmed part 2 void KDF3Bob (); - void MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived); + void MixKey (const uint8_t * inputKeyMaterial); + void MixHash (const uint8_t * buf, size_t len); void KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub); // for SessionRequest, (pub, priv) for DH void KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub); // for SessionCreate void CreateEphemeralKey (); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 9c1acfcc..6b5053a8 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -116,12 +116,12 @@ namespace i2p void RouterContext::NewNTCP2Keys () { + m_StaticKeys.reset (new i2p::crypto::X25519Keys ()); + m_StaticKeys->GenerateKeys (); m_NTCP2Keys.reset (new NTCP2PrivateKeys ()); - RAND_bytes (m_NTCP2Keys->staticPrivateKey, 32); + m_StaticKeys->GetPrivateKey (m_NTCP2Keys->staticPrivateKey); + memcpy (m_NTCP2Keys->staticPublicKey, m_StaticKeys->GetPublicKey (), 32); RAND_bytes (m_NTCP2Keys->iv, 16); - BN_CTX * ctx = BN_CTX_new (); - i2p::crypto::GetEd25519 ()->ScalarMulB (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey, ctx); - BN_CTX_free (ctx); // save std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out); fk.write ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys)); diff --git a/libi2pd/version.h b/libi2pd/version.h index 3f09928c..22990219 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -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 21 +#define I2PD_VERSION_MINOR 22 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index b58677c8..257087ee 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -410,18 +410,44 @@ namespace client void ClientContext::ReadTunnels () { - boost::property_tree::ptree pt; + int numClientTunnels = 0, numServerTunnels = 0; std::string tunConf; i2p::config::GetOption("tunconf", tunConf); - if (tunConf == "") { + if (tunConf.empty ()) + { // TODO: cleanup this in 2.8.0 tunConf = i2p::fs::DataDirPath ("tunnels.cfg"); - if (i2p::fs::Exists(tunConf)) { - LogPrint(eLogWarning, "FS: please rename tunnels.cfg -> tunnels.conf here: ", tunConf); - } else { + if (i2p::fs::Exists(tunConf)) + LogPrint(eLogWarning, "Clients: please rename tunnels.cfg -> tunnels.conf here: ", tunConf); + else tunConf = i2p::fs::DataDirPath ("tunnels.conf"); + } + LogPrint(eLogDebug, "Clients: tunnels config file: ", tunConf); + ReadTunnels (tunConf, numClientTunnels, numServerTunnels); + + std::string tunDir; i2p::config::GetOption("tunnelsdir", tunDir); + if (tunDir.empty ()) + tunDir = i2p::fs::DataDirPath ("tunnels.d"); + if (i2p::fs::Exists (tunDir)) + { + std::vector files; + if (i2p::fs::ReadDir (tunDir, files)) + { + for (auto& it: files) + { + LogPrint(eLogDebug, "Clients: tunnels extra config file: ", it); + ReadTunnels (it, numClientTunnels, numServerTunnels); + } } } - LogPrint(eLogDebug, "FS: tunnels config file: ", tunConf); + + LogPrint (eLogInfo, "Clients: ", numClientTunnels, " I2P client tunnels created"); + LogPrint (eLogInfo, "Clients: ", numServerTunnels, " I2P server tunnels created"); + } + + + void ClientContext::ReadTunnels (const std::string& tunConf, int& numClientTunnels, int& numServerTunnels) + { + boost::property_tree::ptree pt; try { boost::property_tree::read_ini (tunConf, pt); @@ -432,7 +458,6 @@ namespace client return; } - int numClientTunnels = 0, numServerTunnels = 0; for (auto& section: pt) { std::string name = section.first; @@ -672,8 +697,6 @@ namespace client LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ()); } } - LogPrint (eLogInfo, "Clients: ", numClientTunnels, " I2P client tunnels created"); - LogPrint (eLogInfo, "Clients: ", numServerTunnels, " I2P server tunnels created"); } void ClientContext::ReadHttpProxy () diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 06aab3b1..a0c92045 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -87,6 +87,7 @@ namespace client private: void ReadTunnels (); + void ReadTunnels (const std::string& tunConf, int& numClientTunnels, int& numServerTunnels); void ReadHttpProxy (); void ReadSocksProxy (); template diff --git a/qt/i2pd_qt/android/AndroidManifest.xml b/qt/i2pd_qt/android/AndroidManifest.xml index ddb6aeb1..8eb723e7 100644 --- a/qt/i2pd_qt/android/AndroidManifest.xml +++ b/qt/i2pd_qt/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/qt/i2pd_qt/data/icons/128x128/website.i2pd.i2pd.png b/qt/i2pd_qt/data/icons/128x128/website.i2pd.i2pd.png new file mode 100644 index 00000000..ee5400c4 Binary files /dev/null and b/qt/i2pd_qt/data/icons/128x128/website.i2pd.i2pd.png differ diff --git a/qt/i2pd_qt/data/icons/16x16/website.i2pd.i2pd.png b/qt/i2pd_qt/data/icons/16x16/website.i2pd.i2pd.png new file mode 100644 index 00000000..bc020282 Binary files /dev/null and b/qt/i2pd_qt/data/icons/16x16/website.i2pd.i2pd.png differ diff --git a/qt/i2pd_qt/data/icons/22x22/website.i2pd.i2pd.png b/qt/i2pd_qt/data/icons/22x22/website.i2pd.i2pd.png new file mode 100644 index 00000000..5aed761e Binary files /dev/null and b/qt/i2pd_qt/data/icons/22x22/website.i2pd.i2pd.png differ diff --git a/qt/i2pd_qt/data/icons/24x24/website.i2pd.i2pd.png b/qt/i2pd_qt/data/icons/24x24/website.i2pd.i2pd.png new file mode 100644 index 00000000..996e1296 Binary files /dev/null and b/qt/i2pd_qt/data/icons/24x24/website.i2pd.i2pd.png differ diff --git a/qt/i2pd_qt/data/icons/256x256/website.i2pd.i2pd.png b/qt/i2pd_qt/data/icons/256x256/website.i2pd.i2pd.png new file mode 100644 index 00000000..3ed9b518 Binary files /dev/null and b/qt/i2pd_qt/data/icons/256x256/website.i2pd.i2pd.png differ diff --git a/qt/i2pd_qt/data/icons/32x32/website.i2pd.i2pd.png b/qt/i2pd_qt/data/icons/32x32/website.i2pd.i2pd.png new file mode 100644 index 00000000..922846c6 Binary files /dev/null and b/qt/i2pd_qt/data/icons/32x32/website.i2pd.i2pd.png differ diff --git a/qt/i2pd_qt/data/icons/48x48/website.i2pd.i2pd.png b/qt/i2pd_qt/data/icons/48x48/website.i2pd.i2pd.png new file mode 100644 index 00000000..4b7c81ea Binary files /dev/null and b/qt/i2pd_qt/data/icons/48x48/website.i2pd.i2pd.png differ diff --git a/qt/i2pd_qt/data/icons/512x512/website.i2pd.i2pd.png b/qt/i2pd_qt/data/icons/512x512/website.i2pd.i2pd.png new file mode 100644 index 00000000..6336627c Binary files /dev/null and b/qt/i2pd_qt/data/icons/512x512/website.i2pd.i2pd.png differ diff --git a/qt/i2pd_qt/data/icons/64x64/website.i2pd.i2pd.png b/qt/i2pd_qt/data/icons/64x64/website.i2pd.i2pd.png new file mode 100644 index 00000000..a291cab5 Binary files /dev/null and b/qt/i2pd_qt/data/icons/64x64/website.i2pd.i2pd.png differ diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml new file mode 100644 index 00000000..16ae602a --- /dev/null +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -0,0 +1,42 @@ + + + + website.i2pd.i2pd + website.i2pd.i2pd.desktop + CC0-1.0 + BSD-3-Clause + i2pd + Invisible Internet + +

i2pd (I2P Daemon) 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.

+

I2P allows people from all around the world to communicate and share information + without restrictions.

+

Features:

+
    +
  • Distributed anonymous networking framework
  • +
  • End-to-end encrypted communications
  • +
  • Small footprint, simple dependencies, fast performance
  • +
  • Rich set of APIs for developers of secure applications
  • +
+
+ + + https://i2pd.website/images/i2pd_qt.png + + + https://i2pd.website/ + https://github.com/PurpleI2P/i2pd/issues + https://i2pd.readthedocs.io/en/latest/ + supervillain@riseup.net + PurpleI2P Team + + + + + + + +
diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.desktop b/qt/i2pd_qt/data/website.i2pd.i2pd.desktop new file mode 100644 index 00000000..33cb3214 --- /dev/null +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Categories=Network;P2P;Qt; +Exec=i2pd_qt +GenericName=Invisible Internet +Comment=A universal anonymous network layer +Icon=website.i2pd.i2pd +Name=i2pd +Terminal=false +Type=Application +StartupNotify=false +Keywords=i2p;i2pd;vpn;p2p;