Browse Source

Merge remote-tracking branch 'upstream/openssl' into webroot

pull/1268/head
asokolov 6 years ago
parent
commit
a26ed6fe6c
  1. 15
      ChangeLog
  2. 3
      Win32/installer.iss
  3. 2
      android/AndroidManifest.xml
  4. 1
      android/assets/i2pd.conf
  5. 1
      android/assets/tunnels.d
  6. 2
      android/build.gradle
  7. 2
      appveyor.yml
  8. 10
      build/build_mingw.cmd
  9. 5
      contrib/i2pd.conf
  10. 6
      contrib/i2pd.service
  11. 9
      contrib/rpm/i2pd-git.spec
  12. 13
      contrib/rpm/i2pd.spec
  13. 7
      contrib/tunnels.d/IRC-Ilita.conf
  14. 7
      contrib/tunnels.d/IRC-Irc2P.conf
  15. 1
      contrib/tunnels.d/README
  16. 4
      debian/.gitignore
  17. 15
      debian/changelog
  18. 3
      debian/i2pd.1
  19. 1
      debian/i2pd.dirs
  20. 3
      debian/i2pd.init
  21. 1
      debian/i2pd.install
  22. 1
      debian/i2pd.links
  23. 3
      debian/i2pd.openrc
  24. 6
      debian/patches/02-fix-1210.patch
  25. 2
      debian/patches/series
  26. 19
      libi2pd/Config.cpp
  27. 10
      libi2pd/Crypto.cpp
  28. 15
      libi2pd/Crypto.h
  29. 119
      libi2pd/NTCP2.cpp
  30. 3
      libi2pd/NTCP2.h
  31. 8
      libi2pd/RouterContext.cpp
  32. 2
      libi2pd/version.h
  33. 41
      libi2pd_client/ClientContext.cpp
  34. 1
      libi2pd_client/ClientContext.h
  35. 2
      qt/i2pd_qt/android/AndroidManifest.xml
  36. BIN
      qt/i2pd_qt/data/icons/128x128/website.i2pd.i2pd.png
  37. BIN
      qt/i2pd_qt/data/icons/16x16/website.i2pd.i2pd.png
  38. BIN
      qt/i2pd_qt/data/icons/22x22/website.i2pd.i2pd.png
  39. BIN
      qt/i2pd_qt/data/icons/24x24/website.i2pd.i2pd.png
  40. BIN
      qt/i2pd_qt/data/icons/256x256/website.i2pd.i2pd.png
  41. BIN
      qt/i2pd_qt/data/icons/32x32/website.i2pd.i2pd.png
  42. BIN
      qt/i2pd_qt/data/icons/48x48/website.i2pd.i2pd.png
  43. BIN
      qt/i2pd_qt/data/icons/512x512/website.i2pd.i2pd.png
  44. BIN
      qt/i2pd_qt/data/icons/64x64/website.i2pd.i2pd.png
  45. 42
      qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml
  46. 11
      qt/i2pd_qt/data/website.i2pd.i2pd.desktop

15
ChangeLog

@ -1,6 +1,21 @@ @@ -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

3
Win32/installer.iss

@ -1,5 +1,5 @@ @@ -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 @@ -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

2
android/AndroidManifest.xml

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
package="org.purplei2p.i2pd"
android:installLocation="auto"
android:versionCode="1"
android:versionName="2.21.0">
android:versionName="2.22.0">
<uses-sdk
android:minSdkVersion="14"

1
android/assets/i2pd.conf

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
#logfile = /sdcard/i2pd/i2pd.log
loglevel = none
#tunnelsdir = /sdcard/i2pd/tunnels.d
# host = 1.2.3.4
# port = 4567

1
android/assets/tunnels.d

@ -0,0 +1 @@ @@ -0,0 +1 @@
../../contrib/tunnels.d

2
android/build.gradle

@ -29,7 +29,7 @@ android { @@ -29,7 +29,7 @@ android {
targetSdkVersion 28
minSdkVersion 14
versionCode 1
versionName "2.21.0"
versionName "2.22.0"
ndk {
abiFilters 'armeabi-v7a'
abiFilters 'x86'

2
appveyor.yml

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
version: 2.21.{build}
version: 2.22.0.{build}
pull_requests:
do_not_increment_build_number: true
branches:

10
build/build_mingw.cmd

@ -21,6 +21,8 @@ set MSYSTEM=MINGW32 @@ -21,6 +21,8 @@ set MSYSTEM=MINGW32
set "xSH=%WD%bash -lc"
set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d"
REM detecting number of processors and subtract 1.
set /a threads=%NUMBER_OF_PROCESSORS%-1
@ -62,12 +64,12 @@ exit /b 0 @@ -62,12 +64,12 @@ exit /b 0
%xSH% "make clean" >> 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

5
contrib/i2pd.conf

@ -10,6 +10,11 @@ @@ -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

6
contrib/i2pd.service

@ -11,7 +11,7 @@ RuntimeDirectoryMode=0700 @@ -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 @@ -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]

9
contrib/rpm/i2pd-git.spec

@ -1,7 +1,7 @@ @@ -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 @@ -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 || \ @@ -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 || \ @@ -98,5 +102,8 @@ getent passwd i2pd >/dev/null || \
%changelog
* Fri Nov 09 2018 r4sas <r4sas@i2pmail.org> - 2.22.0
- add support of tunnelsdir option
* Thu Feb 01 2018 r4sas <r4sas@i2pmail.org> - 2.18.0
- Initial i2pd-git based on i2pd 2.18.0-1 spec

13
contrib/rpm/i2pd.spec

@ -1,5 +1,5 @@ @@ -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 @@ -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 || \ @@ -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 || \ @@ -96,6 +100,13 @@ getent passwd i2pd >/dev/null || \
%changelog
* Fri Nov 09 2018 r4sas <r4sas@i2pmail.org> - 2.22.0
- update to 2.22.0
- add support of tunnelsdir option
* Thu Oct 22 2018 orignal <i2porignal@yandex.ru> - 2.21.1
- update to 2.21.1
* Thu Oct 4 2018 orignal <i2porignal@yandex.ru> - 2.21.0
- update to 2.21.0

7
contrib/tunnels.d/IRC-Ilita.conf

@ -0,0 +1,7 @@ @@ -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

7
contrib/tunnels.d/IRC-Irc2P.conf

@ -0,0 +1,7 @@ @@ -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

1
contrib/tunnels.d/README

@ -0,0 +1 @@ @@ -0,0 +1 @@
In that directory you can store separated config files for every tunnel.

4
debian/.gitignore vendored

@ -1,9 +1,9 @@ @@ -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/

15
debian/changelog vendored

@ -1,3 +1,18 @@ @@ -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 <r4sas@i2pmail.org> Fri, 09 Nov 2018 02:00:00 +0000
i2pd (2.21.1-1) unstable; urgency=medium
* updated to version 2.21.1
-- orignal <orignal@i2pmail.org> 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

3
debian/i2pd.1 vendored

@ -45,6 +45,9 @@ Log messages with full CLF-formatted date and time (\fIdisabled\fR by default) @@ -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

1
debian/i2pd.dirs vendored

@ -1,2 +1,3 @@ @@ -1,2 +1,3 @@
etc/i2pd
etc/i2pd/tunnels.conf.d
var/lib/i2pd

3
debian/i2pd.init vendored

@ -18,6 +18,7 @@ DAEMON_OPTS="" # Arguments to run the daemon with @@ -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() @@ -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 $?
}

1
debian/i2pd.install vendored

@ -3,4 +3,5 @@ contrib/i2pd.conf etc/i2pd/ @@ -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

1
debian/i2pd.links vendored

@ -1,4 +1,5 @@ @@ -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

3
debian/i2pd.openrc vendored

@ -4,10 +4,11 @@ pidfile="/var/run/i2pd/i2pd.pid" @@ -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"

6
debian/patches/fix-#1210 → debian/patches/02-fix-1210.patch vendored

@ -6,8 +6,8 @@ Bug: https://github.com/PurpleI2P/i2pd/issues/1210 @@ -6,8 +6,8 @@ Bug: https://github.com/PurpleI2P/i2pd/issues/1210
Reviewed-By: r4sas <r4sas@i2pmail.org>
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 @@ -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

2
debian/patches/series vendored

@ -1,2 +1,2 @@ @@ -1,2 +1,2 @@
01-tune-build-opts.patch
fix-#1210
02-fix-1210.patch

19
libi2pd/Config.cpp

@ -32,8 +32,10 @@ namespace config { @@ -32,8 +32,10 @@ namespace config {
options_description general("General options");
general.add_options()
("help", "Show this message")
("version", "Show i2pd version")
("conf", value<std::string>()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)")
("tunconf", value<std::string>()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)")
("tunnelsdir", value<std::string>()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d")
("pidfile", value<std::string>()->default_value(""), "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)")
("log", value<std::string>()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)")
("logfile", value<std::string>()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)")
@ -282,6 +284,23 @@ namespace config { @@ -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);
}
}

10
libi2pd/Crypto.cpp

@ -341,6 +341,16 @@ namespace crypto @@ -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)
{

15
libi2pd/Crypto.h

@ -72,6 +72,7 @@ namespace crypto @@ -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 @@ -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];
}
}
}
};

119
libi2pd/NTCP2.cpp

@ -40,7 +40,7 @@ namespace transport @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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;

3
libi2pd/NTCP2.h

@ -95,7 +95,8 @@ namespace transport @@ -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 ();

8
libi2pd/RouterContext.cpp

@ -116,12 +116,12 @@ namespace i2p @@ -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));

2
libi2pd/version.h

@ -7,7 +7,7 @@ @@ -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)

41
libi2pd_client/ClientContext.cpp

@ -410,18 +410,44 @@ namespace client @@ -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<std::string> 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 @@ -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 @@ -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 ()

1
libi2pd_client/ClientContext.h

@ -87,6 +87,7 @@ namespace client @@ -87,6 +87,7 @@ namespace client
private:
void ReadTunnels ();
void ReadTunnels (const std::string& tunConf, int& numClientTunnels, int& numServerTunnels);
void ReadHttpProxy ();
void ReadSocksProxy ();
template<typename Section, typename Type>

2
qt/i2pd_qt/android/AndroidManifest.xml

@ -1,5 +1,5 @@ @@ -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.21.0" android:versionCode="1" android:installLocation="auto">
<manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.22.0" android:versionCode="1" 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" -->

BIN
qt/i2pd_qt/data/icons/128x128/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
qt/i2pd_qt/data/icons/16x16/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
qt/i2pd_qt/data/icons/22x22/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
qt/i2pd_qt/data/icons/24x24/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
qt/i2pd_qt/data/icons/256x256/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
qt/i2pd_qt/data/icons/32x32/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
qt/i2pd_qt/data/icons/48x48/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
qt/i2pd_qt/data/icons/512x512/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

BIN
qt/i2pd_qt/data/icons/64x64/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

42
qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2018 Viktor Villainov <supervillain@riseup.net> -->
<component type="desktop">
<id>website.i2pd.i2pd</id>
<launchable type="desktop-id">website.i2pd.i2pd.desktop</launchable>
<metadata_license>CC0-1.0</metadata_license>
<project_license>BSD-3-Clause</project_license>
<name>i2pd</name>
<summary>Invisible Internet</summary>
<description>
<p>i2pd (I2P Daemon) is a full-featured C++ implementation of I2P client.</p>
<p>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. </p>
<p>I2P allows people from all around the world to communicate and share information
without restrictions.</p>
<p>Features:</p>
<ul>
<li>Distributed anonymous networking framework</li>
<li>End-to-end encrypted communications</li>
<li>Small footprint, simple dependencies, fast performance</li>
<li>Rich set of APIs for developers of secure applications</li>
</ul>
</description>
<screenshots>
<screenshot type="default">
<image height="590" width="923">https://i2pd.website/images/i2pd_qt.png</image>
</screenshot>
</screenshots>
<url type="homepage">https://i2pd.website/</url>
<url type="bugtracker">https://github.com/PurpleI2P/i2pd/issues</url>
<url type="help">https://i2pd.readthedocs.io/en/latest/</url>
<update_contact>supervillain@riseup.net</update_contact>
<developer_name>PurpleI2P Team</developer_name>
<translation type="qt" />
<releases>
<release version="2.21.1" date="2018-10-22" />
<release version="2.21.0" date="2018-10-04" />
</releases>
<content_rating type="oars-1.1" />
</component>

11
qt/i2pd_qt/data/website.i2pd.i2pd.desktop

@ -0,0 +1,11 @@ @@ -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;
Loading…
Cancel
Save