Merge pull request #10 from RetroShare/master

update master
This commit is contained in:
defnax 2019-09-25 16:25:59 +02:00 committed by GitHub
commit 8fe63273fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
317 changed files with 15771 additions and 9363 deletions

4
.gitmodules vendored
View File

@ -7,3 +7,7 @@
[submodule "build_scripts/OBS"]
path = build_scripts/OBS
url = https://github.com/RetroShare/OBS.git
[submodule "supportlibs/udp-discovery-cpp"]
path = supportlibs/udp-discovery-cpp
url = https://github.com/truvorskameikin/udp-discovery-cpp.git
branch = develop

View File

@ -22,7 +22,7 @@ before_install:
- if [ $TRAVIS_OS_NAME == osx ]; then brew install ccach; export PATH="/usr/local/opt/ccache/libexec:$PATH" ; fi
- if [ $TRAVIS_OS_NAME == osx ]; then brew install qt5; fi
- if [ $TRAVIS_OS_NAME == osx ]; then brew link --force qt5 ; fi
- if [ $TRAVIS_OS_NAME == osx ]; then brew install openssl miniupnpc libmicrohttpd sqlcipher xapian; fi
- if [ $TRAVIS_OS_NAME == osx ]; then brew install openssl miniupnpc libmicrohttpd sqlcipher xapian cmark; fi
- if [ $TRAVIS_OS_NAME == osx ]; then brew install p7zip; fi
- if [ $TRAVIS_OS_NAME == osx ]; then npm install -g appdmg; fi
@ -47,8 +47,9 @@ addons:
branch_pattern: coverity_scan
before_script:
- if [ $TRAVIS_OS_NAME == linux ]; then qmake QMAKE_CC=$CC QMAKE_CXX=$CXX; fi
- if [ $TRAVIS_OS_NAME == osx ]; then qmake QMAKE_CC=$CC QMAKE_CXX=$CXX CONFIG+=rs_macos10.14 CONFIG+=no_retroshare_plugins INCLUDEPATH+=/usr/local/opt/openssl/include/ INCLUDEPATH+=/usr/local/Cellar/sqlcipher/4.0.1/include INCLUDEPATH+=/usr/local/Cellar/libmicrohttpd/0.9.62_1/include QMAKE_LIBDIR+=/usr/local/opt/openssl/lib/ QMAKE_LIBDIR+=/usr/local/Cellar/libmicrohttpd/0.9.62_1/lib QMAKE_LIBDIR+=/usr/local/Cellar/sqlcipher/4.0.1/lib; fi
- env
- if [ $TRAVIS_OS_NAME == linux ]; then qmake; fi
- if [ $TRAVIS_OS_NAME == osx ]; then qmake CONFIG+=rs_macos10.14 INCLUDEPATH+=/usr/local/opt/openssl/include/ INCLUDEPATH+=$(find /usr/local/Cellar/sqlcipher/*/include | headn -n 1) INCLUDEPATH+=$(find /usr/local/Cellar/libmicrohttpd/*/include | head -n 1) QMAKE_LIBDIR+=/usr/local/opt/openssl/lib/ QMAKE_LIBDIR+=$(find /usr/local/Cellar/libmicrohttpd/*/lib | head -n 1) QMAKE_LIBDIR+=$(find /usr/local/Cellar/sqlcipher/*/lib | head -n 1); fi
script:
- if [ $TRAVIS_OS_NAME == osx ] && [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make -j4; fi

View File

@ -46,6 +46,7 @@ Install all needed dependencies:
pacman -S mingw-w64-i686-xapian-core
pacman -S mingw-w64-i686-sqlcipher
pacman -S mingw-w64-i686-qt5
pacman -S mingw32/mingw-w64-i686-cmake
We're done installing MSYS2, close the shell terminal.

View File

@ -90,7 +90,7 @@ install:
# Configuring MSys2
- set PATH=C:\msys64\usr\bin;%PATH%
- set PATH=C:\msys64\mingw32\bin;%PATH%
- pacman --noconfirm -S mingw-w64-i686-qt5 mingw-w64-i686-miniupnpc mingw-w64-i686-sqlcipher mingw-w64-i686-libmicrohttpd mingw-w64-i686-xapian-core
- pacman --noconfirm -S mingw-w64-i686-qt5 mingw-w64-i686-miniupnpc mingw-w64-i686-sqlcipher mingw-w64-i686-libmicrohttpd mingw-w64-i686-xapian-core mingw-w64-i686-cmark
#- pacman --noconfirm -S mingw-w64-i686-qt5-static mingw-w64-i686-miniupnpc mingw-w64-i686-sqlcipher mingw-w64-i686-libmicrohttpd
#- set PATH=C:\msys64\mingw32\qt5-static\bin\;%PATH%
@ -105,6 +105,15 @@ install:
- copy C:\msys64\mingw64\x86_64-w64-mingw32\bin\ranlib.exe C:\msys64\mingw64\bin\x86_64-w64-mingw32-ranlib.exe
- copy C:\msys64\mingw64\bin\windres.exe C:\msys64\mingw64\bin\x86_64-w64-mingw32-windres.exe
# Work-around linker looking for Qt dll in wrong place
- copy C:\msys64\mingw32\bin\Qt5PrintSupport.dll C:\msys64\mingw32\lib\Qt5PrintSupport.dll
- copy C:\msys64\mingw32\bin\Qt5Widgets.dll C:\msys64\mingw32\lib\Qt5Widgets.dll
- copy C:\msys64\mingw32\bin\Qt5Multimedia.dll C:\msys64\mingw32\lib\Qt5Multimedia.dll
- copy C:\msys64\mingw32\bin\Qt5Gui.dll C:\msys64\mingw32\lib\Qt5Gui.dll
- copy C:\msys64\mingw32\bin\Qt5Network.dll C:\msys64\mingw32\lib\Qt5Network.dll
- copy C:\msys64\mingw32\bin\Qt5Xml.dll C:\msys64\mingw32\lib\Qt5Xml.dll
- copy C:\msys64\mingw32\bin\Qt5Core.dll C:\msys64\mingw32\lib\Qt5Core.dll
#---------------------------------#
# build configuration #
@ -136,13 +145,15 @@ before_package:
# to run your custom scripts instead of automatic MSBuild
build_script:
- env
- git submodule update --init
- qmake -Wall -spec win32-g++ "CONFIG=debug"
- mingw32-make -j3
# scripts to run after build
after_build:
- mkdir %RS_DEPLOY%
- copy retroshare-nogui\src\retroshare-nogui.exe %RS_DEPLOY%\
- copy retroshare-service\src\retroshare-service.exe %RS_DEPLOY%\
- copy retroshare-gui\src\retroshare.exe %RS_DEPLOY%\
## In Debug build winedeplyqt forget the non debug Qt libs
@ -235,6 +246,10 @@ after_build:
- copy C:\msys64\mingw32\bin\libunistring*.dll %RS_DEPLOY%\
- copy C:\msys64\mingw32\bin\libffi*.dll %RS_DEPLOY%\
## Needed for cmark
- copy C:\msys64\mingw32\bin\libcmark*.dll %RS_DEPLOY%\
- copy C:\msys64\mingw32\bin\libdouble-conversion*.dll %RS_DEPLOY%\
- find C:\projects\RetroShare >> filelist.txt
# to disable automatic builds
@ -244,10 +259,11 @@ after_build:
# artifacts configuration #
#---------------------------------#
artifacts:
- path: $(RS_DEPLOY)
- path: '**\*.exe'
- path: filelist.txt
#artifacts:
# - path: '**\*.exe'
# - path: filelist.txt
# - path: $(RS_DEPLOY)
#
# # pushing a single file
# - path: test.zip

View File

@ -21,24 +21,27 @@ define_default_value HOST_NUM_CPU $(nproc)
define_default_value BZIP2_SOURCE_VERSION "1.0.6"
define_default_value BZIP2_SOURCE_SHA256 a2848f34fcd5d6cf47def00461fcb528a0484d8edef8208d6d2e2909dc61d9cd
define_default_value OPENSSL_SOURCE_VERSION "1.1.1"
define_default_value OPENSSL_SOURCE_SHA256 2836875a0f89c03d0fdf483941512613a50cfb421d6fd94b9f41d7279d586a3d
define_default_value OPENSSL_SOURCE_VERSION "1.1.1c"
define_default_value OPENSSL_SOURCE_SHA256 f6fb3079ad15076154eda9413fed42877d668e7069d9b87396d0804fdb3f4c90
define_default_value SQLITE_SOURCE_YEAR "2018"
define_default_value SQLITE_SOURCE_VERSION "3250200"
define_default_value SQLITE_SOURCE_SHA256 da9a1484423d524d3ac793af518cdf870c8255d209e369bd6a193e9f9d0e3181
define_default_value SQLCIPHER_SOURCE_VERSION "3.4.2"
define_default_value SQLCIPHER_SOURCE_SHA256 69897a5167f34e8a84c7069f1b283aba88cdfa8ec183165c4a5da2c816cfaadb
define_default_value SQLCIPHER_SOURCE_VERSION "4.2.0"
define_default_value SQLCIPHER_SOURCE_SHA256 105c1b813f848da038c03647a8bfc9d42fb46865e6aaf4edfd46ff3b18cdccfc
define_default_value LIBUPNP_SOURCE_VERSION "1.6.25"
define_default_value LIBUPNP_SOURCE_SHA256 c5a300b86775435c076d58a79cc0d5a977d76027d2a7d721590729b7f369fa43
define_default_value LIBUPNP_SOURCE_VERSION "1.8.4"
define_default_value LIBUPNP_SOURCE_SHA256 976c3e4555604cdd8391ed2f359c08c9dead3b6bf131c24ce78e64d6669af2ed
define_default_value INSTALL_QT_ANDROID "false"
define_default_value QT_VERSION "5.12.0"
define_default_value QT_ANDROID_INSTALLER_SHA256 a214084e2295c9a9f8727e8a0131c37255bf724bfc69e80f7012ba3abeb1f763
define_default_value RESTBED_SOURCE_VERSION "4.6"
define_default_value RESTBED_SOURCE_VERSION f74f9329dac82e662c1d570b7cd72c192b729eb4
define_default_value UDP_DISCOVERY_CPP_SOURCE "https://github.com/truvorskameikin/udp-discovery-cpp.git"
define_default_value UDP_DISCOVERY_CPP_VERSION "develop"
define_default_value XAPIAN_SOURCE_VERSION "1.4.7"
define_default_value XAPIAN_SOURCE_SHA256 13f08a0b649c7afa804fa0e85678d693fd6069dd394c9b9e7d41973d74a3b5d3
@ -78,15 +81,24 @@ function verified_download()
}
}
cArch=""
eABI=""
if [ "${ANDROID_NDK_ARCH}" == "x86" ]; then
cArch="i686"
eABI=""
else
case "${ANDROID_NDK_ARCH}" in
"arm")
cArch="${ANDROID_NDK_ARCH}"
eABI="eabi"
fi
;;
"arm64")
cArch="aarch64"
eABI=""
;;
"x86")
cArch="i686"
eABI=""
;;
esac
export SYSROOT="${NATIVE_LIBS_TOOLCHAIN_PATH}/sysroot/"
export PREFIX="${SYSROOT}/usr/"
export CC="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-clang"
@ -98,6 +110,12 @@ export RANLIB="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-r
## More information available at https://android.googlesource.com/platform/ndk/+/ics-mr0/docs/STANDALONE-TOOLCHAIN.html
build_toolchain()
{
echo "build_toolchain()
################################################################################
################################################################################
################################################################################
"
rm -rf ${NATIVE_LIBS_TOOLCHAIN_PATH}
${ANDROID_NDK_PATH}/build/tools/make_standalone_toolchain.py --verbose \
--arch ${ANDROID_NDK_ARCH} --install-dir ${NATIVE_LIBS_TOOLCHAIN_PATH} \
@ -108,6 +126,11 @@ build_toolchain()
## This avoid <cmath> include errors due to -isystem and -I ordering issue
delete_copied_includes()
{
echo "delete_copied_includes()
################################################################################
################################################################################
################################################################################
"
cat "${NATIVE_LIBS_TOOLCHAIN_PATH}/deletefiles" | while read delFile ; do
rm "$delFile"
done
@ -116,6 +139,12 @@ delete_copied_includes()
## More information available at https://gitlab.com/relan/provisioners/merge_requests/1 and http://stackoverflow.com/a/34032216
install_qt_android()
{
echo "install_qt_android()
################################################################################
################################################################################
################################################################################
"
QT_VERSION_CODE=$(echo $QT_VERSION | tr -d .)
QT_INSTALL_PATH=${NATIVE_LIBS_TOOLCHAIN_PATH}/Qt
QT_INSTALLER="qt-unified-linux-x64-3.0.2-online.run"
@ -199,11 +228,17 @@ QT_QPA_PLATFORM=minimal ./${QT_INSTALLER} --script ${QT_INSTALLER_SCRIPT}
## More information available at retroshare://file?name=Android%20Native%20Development%20Kit%20Cookbook.pdf&size=29214468&hash=0123361c1b14366ce36118e82b90faf7c7b1b136
build_bzlib()
{
echo "build_bzlib()
################################################################################
################################################################################
################################################################################
"
B_dir="bzip2-${BZIP2_SOURCE_VERSION}"
rm -rf $B_dir
verified_download $B_dir.tar.gz $BZIP2_SOURCE_SHA256 \
http://trumpetti.atm.tut.fi/gentoo/distfiles/bzip2-${BZIP2_SOURCE_VERSION}.tar.gz
http://distfiles.gentoo.org/distfiles/bzip2-${BZIP2_SOURCE_VERSION}.tar.gz
tar -xf $B_dir.tar.gz
cd $B_dir
@ -223,6 +258,12 @@ build_bzlib()
## More information available at http://doc.qt.io/qt-5/opensslsupport.html
build_openssl()
{
echo "build_openssl()
################################################################################
################################################################################
################################################################################
"
B_dir="openssl-${OPENSSL_SOURCE_VERSION}"
rm -rf $B_dir
@ -240,7 +281,7 @@ build_openssl()
[[ ${ANDROID_NDK_ARCH} =~ .*64.* ]] && oBits=64
ANDROID_NDK="${ANDROID_NDK_PATH}" PATH="${SYSROOT}/bin/:${PATH}" \
./Configure linux-generic${oBits} --prefix="${PREFIX}" \
./Configure linux-generic${oBits} -fPIC --prefix="${PREFIX}" \
--openssldir="${SYSROOT}/etc/ssl"
# sed -i 's/LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \\/LIBNAME=$$i \\/g' Makefile
# sed -i '/LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \\/d' Makefile
@ -253,14 +294,21 @@ build_openssl()
build_sqlite()
{
echo "build_sqlite()
################################################################################
################################################################################
################################################################################
"
B_dir="sqlite-autoconf-${SQLITE_SOURCE_VERSION}"
rm -rf $B_dir
verified_download $B_dir.tar.gz $SQLITE_SOURCE_SHA256 \
https://www.sqlite.org/${SQLITE_SOURCE_YEAR}/$B_dir.tar.gz
tar -xf $B_dir.tar.gz
cd $B_dir
./configure --prefix="${PREFIX}" --host=${ANDROID_NDK_ARCH}-linux
./configure --with-pic --prefix="${PREFIX}" --host=${cArch}-linux
make -j${HOST_NUM_CPU}
make install
rm -f ${PREFIX}/lib/libsqlite3.so*
@ -271,6 +319,12 @@ build_sqlite()
build_sqlcipher()
{
echo "build_sqlcipher()
################################################################################
################################################################################
################################################################################
"
B_dir="sqlcipher-${SQLCIPHER_SOURCE_VERSION}"
rm -rf $B_dir
@ -281,8 +335,16 @@ build_sqlcipher()
tar -xf $T_file
cd $B_dir
./configure --build=$(sh ./config.guess) \
--host=${ANDROID_NDK_ARCH}-linux \
case "${ANDROID_NDK_ARCH}" in
"arm64")
# SQLCipher config.sub is outdated and doesn't recognize newer architectures
rm config.sub
autoreconf --verbose --install --force
automake --add-missing --copy --force-missing
;;
esac
./configure --with-pic --build=$(sh ./config.guess) \
--host=${cArch}-linux \
--prefix="${PREFIX}" --with-sysroot="${SYSROOT}" \
--enable-tempstore=yes \
--disable-tcl --disable-shared \
@ -294,20 +356,30 @@ build_sqlcipher()
build_libupnp()
{
B_dir="libupnp-${LIBUPNP_SOURCE_VERSION}"
echo "build_libupnp()
################################################################################
################################################################################
################################################################################
"
B_dir="pupnp-release-${LIBUPNP_SOURCE_VERSION}"
B_ext=".tar.gz"
B_file="${B_dir}${B_ext}"
rm -rf $B_dir
verified_download $B_dir.tar.bz2 $LIBUPNP_SOURCE_SHA256 \
https://sourceforge.net/projects/pupnp/files/pupnp/libUPnP%20${LIBUPNP_SOURCE_VERSION}/$B_dir.tar.bz2
verified_download $B_file $LIBUPNP_SOURCE_SHA256 \
https://github.com/mrjimenez/pupnp/archive/release-${LIBUPNP_SOURCE_VERSION}${B_ext}
tar -xf $B_dir.tar.bz2
tar -xf $B_file
cd $B_dir
./bootstrap
## liupnp must be configured as static library because if not the linker will
## look for libthreadutils.so.6 at runtime that cannot be packaged on android
## as it supports only libname.so format for libraries, thus resulting in a
## crash at startup.
./configure --enable-static --disable-shared --disable-samples \
--prefix="${PREFIX}" --host=${ANDROID_NDK_ARCH}-linux
./configure --with-pic --enable-static --disable-shared --disable-samples \
--disable-largefile \
--prefix="${PREFIX}" --host=${cArch}-linux
make -j${HOST_NUM_CPU}
make install
cd ..
@ -315,6 +387,12 @@ build_libupnp()
build_rapidjson()
{
echo "build_rapidjson()
################################################################################
################################################################################
################################################################################
"
B_dir="rapidjson-${RAPIDJSON_SOURCE_VERSION}"
D_file="${B_dir}.tar.gz"
verified_download $D_file $RAPIDJSON_SOURCE_SHA256 \
@ -325,25 +403,65 @@ build_rapidjson()
build_restbed()
{
echo "build_restbed()
################################################################################
################################################################################
################################################################################
"
[ -d restbed ] || git clone --depth=2000 https://github.com/Corvusoft/restbed.git
cd restbed
git fetch --tags
git checkout tags/${RESTBED_SOURCE_VERSION}
# git fetch --tags
# git checkout tags/${RESTBED_SOURCE_VERSION}
git checkout ${RESTBED_SOURCE_VERSION}
git submodule update --init dependency/asio
git submodule update --init dependency/catch
git submodule update --init dependency/kashmir
cd ..
rm -rf restbed-build; mkdir restbed-build ; cd restbed-build
cmake -DBUILD_SSL=OFF -DCMAKE_INSTALL_PREFIX="${PREFIX}" -B. -H../restbed
cmake \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DBUILD_SSL=OFF -DCMAKE_INSTALL_PREFIX="${PREFIX}" -B. -H../restbed
make -j${HOST_NUM_CPU}
make install
cp "${PREFIX}/library/librestbed.a" "${PREFIX}/lib/"
cd ..
}
build_udp-discovery-cpp()
{
echo "build_udp-discovery-cpp()
################################################################################
################################################################################
################################################################################
"
S_dir="udp-discovery-cpp"
[ -d $S_dir ] || git clone $UDP_DISCOVERY_CPP_SOURCE $S_dir
cd $S_dir
git checkout $UDP_DISCOVERY_CPP_VERSION
cd ..
B_dir="udp-discovery-cpp-build"
rm -rf ${B_dir}; mkdir ${B_dir}; cd ${B_dir}
cmake \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_INSTALL_PREFIX="${PREFIX}" -B. -H../udp-discovery-cpp
make -j${HOST_NUM_CPU}
cp libudp-discovery.a "${PREFIX}/lib/"
cp ../$S_dir/*.hpp "${PREFIX}/include/"
cd ..
}
build_xapian()
{
echo "build_xapian()
################################################################################
################################################################################
################################################################################
"
B_dir="xapian-core-${XAPIAN_SOURCE_VERSION}"
D_file="$B_dir.tar.xz"
verified_download $D_file $XAPIAN_SOURCE_SHA256 \
@ -355,9 +473,10 @@ build_xapian()
B_large_file=""
[ "${ANDROID_PLATFORM_VER}" -lt "24" ] && B_large_file="--disable-largefile"
./configure ${B_endiannes_detection_failure_workaround} ${B_large_file} \
--with-pic \
--disable-backend-inmemory --disable-backend-remote \
--disable--backend-chert --enable-backend-glass \
--host=${ANDROID_NDK_ARCH}-linux --enable-static --disable-shared \
--host=${cArch}-linux --enable-static --disable-shared \
--prefix="${PREFIX}" --with-sysroot="${SYSROOT}"
make -j${HOST_NUM_CPU}
make install
@ -372,6 +491,7 @@ build_sqlcipher
build_libupnp
build_rapidjson
build_restbed
build_udp-discovery-cpp
build_xapian
delete_copied_includes

View File

@ -7,6 +7,10 @@ Files: openpgpsdk/*
Copyright: 2005-2008 Ben Laurie, Rachel Willmer, Retroshare Team <retroshare.team@gmail.com>
License: Apache-2.0
Files: jsonapi-generator/* libretroshare/src/jsonapi/*
Copyright: 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org>
License: AGPL-3+
Files: libretroshare/*
Copyright: 2007-2018, Retroshare Team <retroshare.team@gmail.com>
License: LGPL-3+

@ -1 +1 @@
Subproject commit aafa7aef112f5701c039a13864e1d446d2fbfe46
Subproject commit a8c1d3bca9de4c93d0212ed9dcda22fe06c833ec

View File

@ -1,23 +1,25 @@
/*
* RetroShare JSON API
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*******************************************************************************
* RetroShare JSON API *
* *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
registerHandler("$%apiPath%$",
[$%captureVars%$](const std::shared_ptr<rb::Session> session)
registerHandler( "$%apiPath%$",
[this](const std::shared_ptr<rb::Session> session)
{
const std::multimap<std::string, std::string> headers
{
@ -27,7 +29,7 @@ registerHandler("$%apiPath%$",
session->yield(rb::OK, headers);
size_t reqSize = session->get_request()->get_header("Content-Length", 0);
session->fetch( reqSize, [$%captureVars%$](
session->fetch( reqSize, [this](
const std::shared_ptr<rb::Session> session,
const rb::Bytes& body )
{
@ -41,14 +43,25 @@ $%paramsDeclaration%$
$%inputParamsDeserialization%$
$%callbackName%$ = [session]($%callbackParams%$)
const std::weak_ptr<rb::Session> weakSession(session);
$%callbackName%$ = [this, weakSession]($%callbackParams%$)
{
auto session = weakSession.lock();
if(!session || session->is_closed()) return;
$%callbackParamsSerialization%$
std::stringstream message;
message << "data: " << compactJSON << ctx.mJson << "\n\n";
session->yield(message.str());
$%sessionEarlyClose%$
std::stringstream sStream;
sStream << "data: " << compactJSON << ctx.mJson << "\n\n";
const std::string message = sStream.str();
mService.schedule( [weakSession, message]()
{
auto session = weakSession.lock();
if(!session || session->is_closed()) return;
session->yield(message);
$%sessionEarlyClose%$
} );
};
$%functionCall%$
@ -61,5 +74,4 @@ $%outputParamsSerialization%$
session->yield(message.str());
$%sessionDelayedClose%$
} );
}, $%requiresAuth%$);
}, $%requiresAuth%$ );

View File

@ -1,20 +1,22 @@
/*
* RetroShare JSON API
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*******************************************************************************
* RetroShare JSON API *
* *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
@ -90,7 +92,7 @@ int main(int argc, char *argv[])
{
QDomDocument hDoc;
QString hFilePath(it.next());
QString parseError; int line, column;
QString parseError; int line = -1, column = -1;
QFile hFile(hFilePath);
if (!hFile.open(QIODevice::ReadOnly) ||
!hDoc.setContent(&hFile, &parseError, &line, &column))
@ -318,18 +320,13 @@ int main(int argc, char *argv[])
"\t\t\tRS_SERIAL_PROCESS(retval);\n";
if(hasOutput) outputParamsSerialization += "\t\t}\n";
QString captureVars;
QString sessionEarlyClose;
if(hasSingleCallback)
sessionEarlyClose = "session->close();";
QString sessionDelayedClose;
if(hasMultiCallback)
{
sessionDelayedClose = "mService.schedule( [session](){session->close();}, std::chrono::seconds(maxWait+120) );";
captureVars = "this";
}
sessionDelayedClose = "RsThread::async( [=](){ std::this_thread::sleep_for(std::chrono::seconds(maxWait+120)); mService.schedule( [=](){ auto session = weakSession.lock(); if(session && session->is_open()) session->close(); } ); } );";
QString callbackParamsSerialization;
@ -379,7 +376,6 @@ int main(int argc, char *argv[])
substitutionsMap.insert("apiPath", apiPath);
substitutionsMap.insert("sessionEarlyClose", sessionEarlyClose);
substitutionsMap.insert("sessionDelayedClose", sessionDelayedClose);
substitutionsMap.insert("captureVars", captureVars);
substitutionsMap.insert("callbackName", callbackName);
substitutionsMap.insert("callbackParams", callbackParams);
substitutionsMap.insert("callbackParamsSerialization", callbackParamsSerialization);

View File

@ -1,23 +1,25 @@
/*
* RetroShare JSON API
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*******************************************************************************
* RetroShare JSON API *
* *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
registerHandler("$%apiPath%$",
[$%captureVars%$](const std::shared_ptr<rb::Session> session)
registerHandler( "$%apiPath%$",
[](const std::shared_ptr<rb::Session> session)
{
size_t reqSize = session->get_request()->get_header("Content-Length", 0);
session->fetch( reqSize, [](
@ -44,5 +46,5 @@ $%outputParamsSerialization%$
// return them to the API caller
DEFAULT_API_CALL_JSON_RETURN(rb::OK);
} );
}, $%requiresAuth%$);
}, $%requiresAuth%$ );

View File

@ -827,9 +827,10 @@ int decodeCompactPeerId(struct sockaddr_in *addr, char *enc, int len)
memset(addr, 0, sizeof(struct sockaddr_in));
uint32_t *ip = (uint32_t *) (enc);
//uint32_t *ip = (uint32_t *) (enc);
uint16_t *port = (uint16_t *) (&enc[4]);
addr->sin_addr.s_addr = (*ip);
memcpy(& addr->sin_addr.s_addr, enc, sizeof(in_addr_t)); // aligned version of "addr->sin_addr.s_addr = (*ip); "
addr->sin_port = (*port);
addr->sin_family = AF_INET;

View File

@ -32,8 +32,8 @@
namespace resource_api
{
FileSearchHandler::FileSearchHandler(StateTokenServer *sts, RsNotify *notify, RsTurtle *turtle, RsFiles *files):
mStateTokenServer(sts), mNotify(notify), mTurtle(turtle), mRsFiles(files),
FileSearchHandler::FileSearchHandler(StateTokenServer *sts, RsNotify *notify, RsTurtle */*turtle*/, RsFiles *files):
mStateTokenServer(sts), mNotify(notify)/*, mTurtle(turtle)*/, mRsFiles(files),
mMtx("FileSearchHandler")
{
mNotify->registerNotifyClient(this);
@ -50,7 +50,7 @@ FileSearchHandler::~FileSearchHandler()
mStateTokenServer->discardToken(mSearchesStateToken);
}
void FileSearchHandler::notifyTurtleSearchResult(const RsPeerId& pid,uint32_t search_id, const std::list<TurtleFileInfo>& files)
void FileSearchHandler::notifyTurtleSearchResult(const RsPeerId& /*pid*/,uint32_t search_id, const std::list<TurtleFileInfo>& files)
{
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
std::map<uint32_t, Search>::iterator mit = mSearches.find(search_id);

View File

@ -45,7 +45,7 @@ private:
StateTokenServer* mStateTokenServer;
RsNotify* mNotify;
RsTurtle* mTurtle;
//RsTurtle* mTurtle;
RsFiles* mRsFiles;
class Search{

View File

@ -145,7 +145,8 @@ void RsControlModule::run()
#endif
RsInit::InitRsConfig();
int initResult = RsInit::InitRetroShare(argc, argv, true);
RsConfigOptions opt;
int initResult = RsInit::InitRetroShare(opt);
if (initResult < 0) {
std::cerr << "RsControlModule: FATAL ERROR, initialising libretroshare FAILED." << std::endl;

View File

@ -614,4 +614,4 @@ namespace json
}
}
#endif //__SUPER_EASY_JSON_H__
#endif //__SUPER_EASY_JSON_H__

View File

@ -67,13 +67,10 @@ uint32_t msecs_of_day()
static const uint32_t DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID = 0xa0001 ;
typedef RsGxsTunnelService::RsGxsTunnelId RsGxsTunnelId;
DistantChatService::DistantChatService() : mDistantChatMtx("distant chat")
{
mGxsTunnels = NULL ;
mDistantChatPermissions = RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NONE ; // default: accept everyone
}
DistantChatService::DistantChatService() :
// default: accept everyone
mDistantChatPermissions(RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NONE),
mGxsTunnels(nullptr), mDistantChatMtx("distant chat") {}
void DistantChatService::connectToGxsTunnelService(RsGxsTunnelService *tr)
{
@ -181,7 +178,8 @@ bool DistantChatService::acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTun
return res ;
}
void DistantChatService::notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId &tunnel_id, uint32_t tunnel_status)
void DistantChatService::notifyTunnelStatus(
const RsGxsTunnelId& tunnel_id, uint32_t tunnel_status )
{
#ifdef DEBUG_DISTANT_CHAT
DISTANT_CHAT_DEBUG() << "DistantChatService::notifyTunnelStatus(): got notification " << std::hex << tunnel_status << std::dec << " for tunnel " << tunnel_id << std::endl;
@ -207,7 +205,8 @@ void DistantChatService::notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunne
}
}
void DistantChatService::receiveData(const RsGxsTunnelService::RsGxsTunnelId &tunnel_id, unsigned char *data, uint32_t data_size)
void DistantChatService::receiveData(
const RsGxsTunnelId& tunnel_id, unsigned char* data, uint32_t data_size)
{
#ifdef DEBUG_DISTANT_CHAT
DISTANT_CHAT_DEBUG() << "DistantChatService::receiveData(): got data of size " << std::dec << data_size << " for tunnel " << tunnel_id << std::endl;
@ -249,7 +248,8 @@ void DistantChatService::receiveData(const RsGxsTunnelService::RsGxsTunnelId &tu
void DistantChatService::markDistantChatAsClosed(const DistantChatPeerId& dcpid)
{
mGxsTunnels->closeExistingTunnel(RsGxsTunnelService::RsGxsTunnelId(dcpid),DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID) ;
mGxsTunnels->closeExistingTunnel(
RsGxsTunnelId(dcpid), DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID );
RS_STACK_MUTEX(mDistantChatMtx) ;

View File

@ -30,12 +30,13 @@ class RsGixs ;
static const uint32_t DISTANT_CHAT_AES_KEY_SIZE = 16 ;
/**
* Public interface only uses DistandChatPeerId, but internally, this is
* converted into a RsGxsTunnelId
*/
class DistantChatService: public RsGxsTunnelService::RsGxsTunnelClientService
{
public:
// So, public interface only uses DistandChatPeerId, but internally, this is converted into a RsGxsTunnelService::RsGxsTunnelId
DistantChatService() ;
virtual void triggerConfigSave()=0 ;
@ -91,9 +92,13 @@ public:
virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) ;
private:
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id, const RsGxsTunnelService::RsGxsTunnelId& tunnel_id, bool am_I_client_side) ;
virtual void notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId& tunnel_id,uint32_t tunnel_status) ;
virtual void receiveData(const RsGxsTunnelService::RsGxsTunnelId& id,unsigned char *data,uint32_t data_size) ;
virtual bool acceptDataFromPeer(
const RsGxsId& gxs_id, const RsGxsTunnelId& tunnel_id,
bool am_I_client_side);
virtual void notifyTunnelStatus(
const RsGxsTunnelId& tunnel_id, uint32_t tunnel_status);
virtual void receiveData(
const RsGxsTunnelId& id, unsigned char* data, uint32_t data_size );
// Utility functions.

View File

@ -39,12 +39,12 @@
//#define DEBUG_CHAT_LOBBIES 1
static const int CONNECTION_CHALLENGE_MAX_COUNT = 20 ; // sends a connection challenge every 20 messages
static const rstime_t CONNECTION_CHALLENGE_MAX_MSG_AGE = 30 ; // maximum age of a message to be used in a connection challenge
static const int CONNECTION_CHALLENGE_MIN_DELAY = 15 ; // sends a connection at most every 15 seconds
static const int LOBBY_CACHE_CLEANING_PERIOD = 10 ; // clean lobby caches every 10 secs (remove old messages)
static const int CONNECTION_CHALLENGE_MAX_COUNT = 20 ; // sends a connection challenge every 20 messages
static const rstime_t CONNECTION_CHALLENGE_MAX_MSG_AGE = 30 ; // maximum age of a message to be used in a connection challenge
static const int CONNECTION_CHALLENGE_MIN_DELAY = 15 ; // sends a connection at most every 15 seconds
static const int LOBBY_CACHE_CLEANING_PERIOD = 10 ; // clean lobby caches every 10 secs (remove old messages)
static const rstime_t MAX_KEEP_MSG_RECORD = 1200 ; // keep msg record for 1200 secs max.
static const rstime_t MAX_KEEP_MSG_RECORD = 1200 ; // keep msg record for 1200 secs max.
static const rstime_t MAX_KEEP_INACTIVE_NICKNAME = 180 ; // keep inactive nicknames for 3 mn max.
static const rstime_t MAX_DELAY_BETWEEN_LOBBY_KEEP_ALIVE = 120 ; // send keep alive packet every 2 minutes.
static const rstime_t MAX_KEEP_PUBLIC_LOBBY_RECORD = 60 ; // keep inactive lobbies records for 60 secs max.
@ -52,7 +52,7 @@ static const rstime_t MIN_DELAY_BETWEEN_PUBLIC_LOBBY_REQ = 20 ; // don't ask
static const rstime_t LOBBY_LIST_AUTO_UPDATE_TIME = 121 ; // regularly ask for available lobbies every 5 minutes, to allow auto-subscribe to work
static const uint32_t MAX_ALLOWED_LOBBIES_IN_LIST_WARNING = 50 ;
//static const uint32_t MAX_MESSAGES_PER_SECONDS_NUMBER = 5 ; // max number of messages from a given peer in a window for duration below
//static const uint32_t MAX_MESSAGES_PER_SECONDS_NUMBER = 5 ; // max number of messages from a given peer in a window for duration below
static const uint32_t MAX_MESSAGES_PER_SECONDS_PERIOD = 10 ; // duration window for max number of messages before messages get dropped.
#define IS_PUBLIC_LOBBY(flags) (flags & RS_CHAT_LOBBY_FLAGS_PUBLIC )
@ -933,7 +933,7 @@ void DistributedChatService::sendLobbyStatusPeerChangedNickname(const ChatLobbyI
}
void DistributedChatService::sendLobbyStatusPeerLiving(const ChatLobbyId& lobby_id)
void DistributedChatService::sendLobbyStatusPeerLeaving(const ChatLobbyId& lobby_id)
{
sendLobbyStatusItem(lobby_id,RS_CHAT_LOBBY_EVENT_PEER_LEFT,std::string()) ;
}
@ -990,7 +990,7 @@ bool DistributedChatService::locked_initLobbyBouncableObject(const ChatLobbyId&
while( lobby.msg_cache.find(item.msg_id) != lobby.msg_cache.end() ) ;
RsIdentityDetails details ;
if(!rsIdentity->getIdDetails(lobby.gxs_id,details))
if(!rsIdentity || !rsIdentity->getIdDetails(lobby.gxs_id,details))
{
std::cerr << "(EE) Cannot send chat lobby object. Signign identity " << lobby.gxs_id << " is unknown." << std::endl;
return false ;
@ -1580,6 +1580,9 @@ bool DistributedChatService::joinVisibleChatLobby(const ChatLobbyId& lobby_id,co
}
_chat_lobbys[lobby_id] = entry ;
}
setLobbyAutoSubscribe(lobby_id,true);
triggerConfigSave(); // so that we save the subscribed lobbies
for(std::list<RsPeerId>::const_iterator it(invited_friends.begin());it!=invited_friends.end();++it)
invitePeerToLobby(lobby_id,*it) ;
@ -1629,6 +1632,8 @@ ChatLobbyId DistributedChatService::createChatLobby(const std::string& lobby_nam
RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ;
triggerConfigSave();
return lobby_id ;
}
@ -1666,10 +1671,11 @@ void DistributedChatService::handleFriendUnsubscribeLobby(RsChatLobbyUnsubscribe
void DistributedChatService::unsubscribeChatLobby(const ChatLobbyId& id)
{
// send AKN item
sendLobbyStatusPeerLiving(id) ;
sendLobbyStatusPeerLeaving(id) ;
setLobbyAutoSubscribe(id, false);
{
RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mDistributedChatMtx);
std::map<ChatLobbyId,ChatLobbyEntry>::iterator it = _chat_lobbys.find(id) ;
@ -1704,6 +1710,7 @@ void DistributedChatService::unsubscribeChatLobby(const ChatLobbyId& id)
_chat_lobbys.erase(it) ;
}
triggerConfigSave(); // so that we save the subscribed lobbies
RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_DEL) ;
// done!
@ -1826,15 +1833,27 @@ bool DistributedChatService::setIdentityForChatLobby(const ChatLobbyId& lobby_id
void DistributedChatService::setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe)
{
if(autoSubscribe){
_known_lobbies_flags[lobby_id] |= RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE;
RsGxsId gxsId;
if (getIdentityForChatLobby(lobby_id, gxsId))
_lobby_default_identity[lobby_id] = gxsId;
} else {
_known_lobbies_flags[lobby_id] &= ~RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE ;
_lobby_default_identity.erase(lobby_id);
}
if(autoSubscribe)
{
{
RS_STACK_MUTEX(mDistributedChatMtx);
_known_lobbies_flags[lobby_id] |= RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE;
}
RsGxsId gxsId;
if (getIdentityForChatLobby(lobby_id, gxsId))
{
RS_STACK_MUTEX(mDistributedChatMtx);
_lobby_default_identity[lobby_id] = gxsId;
}
}
else
{
RS_STACK_MUTEX(mDistributedChatMtx);
_known_lobbies_flags[lobby_id] &= ~RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE ;
_lobby_default_identity.erase(lobby_id);
}
RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ;
triggerConfigSave();
@ -1966,6 +1985,15 @@ void DistributedChatService::addToSaveList(std::list<RsItem*>& list) const
list.push_back(clci) ;
}
for(auto it(_chat_lobbys.begin());it!=_chat_lobbys.end();++it)
{
RsSubscribedChatLobbyConfigItem *scli = new RsSubscribedChatLobbyConfigItem;
scli->info = it->second; // copies the ChatLobbyInfo part only
list.push_back(scli);
}
/* Save Default Nick Name */
{
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ;
@ -2061,6 +2089,59 @@ bool DistributedChatService::processLoadListItem(const RsItem *item)
if(!own_ids.empty())
_default_identity = own_ids.front() ;
}
const RsSubscribedChatLobbyConfigItem *scli = dynamic_cast<const RsSubscribedChatLobbyConfigItem*>(item);
if(scli != NULL)
{
if(_chat_lobbys.find(scli->info.lobby_id) != _chat_lobbys.end()) // do nothing if the lobby is already subscribed
return true;
std::cerr << "Re-subscribing to chat lobby " << (void*)scli->info.lobby_id << ", flags = " << scli->info.lobby_flags << std::endl;
rstime_t now = time(NULL);
// Add the chat room into visible chat rooms
{
RS_STACK_MUTEX(mDistributedChatMtx); /********** STACK LOCKED MTX ******/
VisibleChatLobbyRecord& rec(_visible_lobbies[scli->info.lobby_id]) ;
rec.lobby_id = scli->info.lobby_id ;
rec.lobby_name = scli->info.lobby_name ;
rec.lobby_topic = scli->info.lobby_topic ;
rec.participating_friends = scli->info.participating_friends;
rec.total_number_of_peers = 0;
rec.last_report_time = now ;
rec.lobby_flags = EXTRACT_PRIVACY_FLAGS(scli->info.lobby_flags) ;
_known_lobbies_flags[scli->info.lobby_id] |= RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE;
}
// Add the chat room into subscribed chat rooms
ChatLobbyEntry entry ;
(ChatLobbyInfo&)entry = scli->info;
entry.virtual_peer_id = makeVirtualPeerId(entry.lobby_id) ; // not random, so we keep the same id at restart
entry.connexion_challenge_count = 0 ;
entry.last_activity = now ;
entry.last_connexion_challenge_time = now ;
entry.last_keep_alive_packet_time = now ;
{
RS_STACK_MUTEX(mDistributedChatMtx); /********** STACK LOCKED MTX ******/
_chat_lobbys[entry.lobby_id] = entry ;
}
// make the UI aware of the existing chat room
RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ;
return true;
}
return false ;
}

View File

@ -72,6 +72,7 @@ class DistributedChatService
void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe);
bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id);
void sendLobbyStatusString(const ChatLobbyId& id,const std::string& status_string) ;
void sendLobbyStatusPeerLeaving(const ChatLobbyId& lobby_id) ;
ChatLobbyId createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic, const std::set<RsPeerId>& invited_friends,ChatLobbyFlags flags) ;
@ -93,7 +94,7 @@ class DistributedChatService
bool sendLobbyChat(const ChatLobbyId &lobby_id, const std::string&) ;
bool handleRecvChatLobbyMsgItem(RsChatMsgItem *item) ;
bool checkSignature(RsChatLobbyBouncingObject *obj,const RsPeerId& peer_id) ;
bool checkSignature(RsChatLobbyBouncingObject *obj,const RsPeerId& peer_id) ;
private:
/// make some statistics about time shifts, to prevent various issues.
@ -119,7 +120,6 @@ class DistributedChatService
bool bounceLobbyObject(RsChatLobbyBouncingObject *obj, const RsPeerId& peer_id) ;
void sendLobbyStatusItem(const ChatLobbyId&, int type, const std::string& status_string) ;
void sendLobbyStatusPeerLiving(const ChatLobbyId& lobby_id) ;
void sendLobbyStatusPeerChangedNickname(const ChatLobbyId& lobby_id, const std::string& newnick) ;
void sendLobbyStatusNewPeer(const ChatLobbyId& lobby_id) ;

View File

@ -21,6 +21,7 @@
*******************************************************************************/
#include <stdexcept>
#include "retroshare/rsmsgs.h"
#include "util/rstime.h"
#include "serialiser/rsbaseserial.h"
#include "serialiser/rstlvbase.h"
@ -52,6 +53,7 @@ RsItem *RsChatSerialiser::create_item(uint16_t service_id,uint8_t item_sub_id) c
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST: return new RsChatLobbyListRequestItem();
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST: return new RsChatLobbyListItem();
case RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG: return new RsChatLobbyConfigItem();
case RS_PKT_SUBTYPE_SUBSCRIBED_CHAT_LOBBY_CONFIG: return new RsSubscribedChatLobbyConfigItem();
case RS_PKT_SUBTYPE_OUTGOING_MAP: return new PrivateOugoingMapItem();
default:
std::cerr << "Unknown packet type in chat!" << std::endl;
@ -172,6 +174,11 @@ void RsChatAvatarItem::serial_process(RsGenericSerializer::SerializeJob j,RsGene
RsTypeSerializer::serial_process(j,ctx,b,"image data") ;
}
void RsSubscribedChatLobbyConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
info.serial_process(j,ctx);
}
void RsChatLobbyConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process<uint64_t>(j,ctx,lobby_Id,"lobby_Id") ;

View File

@ -34,6 +34,7 @@
#include "serialiser/rstlvidset.h"
#include "serialiser/rstlvfileitem.h"
#include "retroshare/rsmsgs.h"
/* chat Flags */
const uint32_t RS_CHAT_FLAG_PRIVATE = 0x0001;
@ -82,6 +83,8 @@ const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_DEPRECATED = 0x1A ; // to be remo
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE = 0x1B ;
const uint8_t RS_PKT_SUBTYPE_OUTGOING_MAP = 0x1C ;
const uint8_t RS_PKT_SUBTYPE_SUBSCRIBED_CHAT_LOBBY_CONFIG = 0x1D ;
typedef uint64_t ChatLobbyId ;
typedef uint64_t ChatLobbyMsgId ;
typedef std::string ChatLobbyNickName ;
@ -298,6 +301,19 @@ struct RsPrivateChatMsgConfigItem : RsChatItem
uint32_t recvTime;
};
class RsSubscribedChatLobbyConfigItem: public RsChatItem
{
public:
RsSubscribedChatLobbyConfigItem() :RsChatItem(RS_PKT_SUBTYPE_SUBSCRIBED_CHAT_LOBBY_CONFIG) {}
virtual ~RsSubscribedChatLobbyConfigItem() {}
virtual void clear() { RsChatItem::clear(); info.clear(); }
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
ChatLobbyInfo info;
};
class RsChatLobbyConfigItem: public RsChatItem
{
public:

View File

@ -47,10 +47,10 @@ namespace librs
template<class T> friend HashStream& operator<<(HashStream& u, const T&) ;
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
friend HashStream& operator<<(HashStream& u,const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& r)
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
friend HashStream& operator<<(HashStream& u, const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& r)
{
EVP_DigestUpdate(u.mdctx,r.toByteArray(),ID_SIZE_IN_BYTES);
EVP_DigestUpdate(u.mdctx, r.toByteArray(), ID_SIZE_IN_BYTES);
return u;
}
private:

View File

@ -85,7 +85,10 @@ virtual int dhtInfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::
return 0;
// now check the filter
if(rsBanList->isAddressAccepted(*(const sockaddr_storage*)addr, RSBANLIST_CHECKING_FLAGS_BLACKLIST, NULL)) {
if(rsBanList->isAddressAccepted(
*reinterpret_cast<const sockaddr_storage*>(addr),
RSBANLIST_CHECKING_FLAGS_BLACKLIST ))
{
*isBanned = false;
} else {
#ifdef DEBUG_BITDHT

View File

@ -65,6 +65,7 @@ p3FileDatabase::p3FileDatabase(p3ServiceControl *mpeers)
mRemoteDirectories.clear() ; // we should load them!
mOwnId = mpeers->getOwnId() ;
mBannedFileListNeedsUpdate = false;
mLocalSharedDirs = new LocalDirectoryStorage(mFileSharingDir + "/" + LOCAL_SHARED_DIRS_FILE_NAME,mOwnId);
mHashCache = new HashStorage(mFileSharingDir + "/" + HASH_CACHE_FILE_NAME) ;
@ -968,16 +969,18 @@ int p3FileDatabase::getSharedDirStatistics(const RsPeerId& pid,SharedDirStats& s
}
}
void p3FileDatabase::removeExtraFile(const RsFileHash& hash)
bool p3FileDatabase::removeExtraFile(const RsFileHash& hash)
{
bool ret = false;
{
RS_STACK_MUTEX(mFLSMtx) ;
mExtraFiles->removeExtraFile(hash);
ret = mExtraFiles->removeExtraFile(hash);
mLastExtraFilesCacheUpdate = 0 ; // forced cache reload
}
RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0);
return ret;
}
void p3FileDatabase::getExtraFilesDirDetails(void *ref,DirectoryStorage::EntryIndex e,DirDetails& d) const
@ -1945,7 +1948,10 @@ p3FileDatabase::DirSyncRequestId p3FileDatabase::makeDirSyncReqId(const RsPeerId
// This is kind of arbitrary. The important thing is that the same ID needs to be generated every time for a given (peer_id,entry index) pair, in a way
// that cannot be brute-forced or reverse-engineered, which explains the random bias and the usage of the hash, that is itself random.
uint64_t r = random_bias ^ *((uint64_t*)tmp.toByteArray()) ;
uint64_t tmp2 ;
memcpy(&tmp2,tmp.toByteArray(),sizeof(uint64_t));
uint64_t r = random_bias ^ tmp2;
#ifdef DEBUG_P3FILELISTS
std::cerr << "Creating ID " << std::hex << r << std::dec << " from peer id " << peer_id << " and hash " << hash << std::endl;

View File

@ -109,8 +109,8 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
virtual int SearchKeywords(const std::list<std::string>& keywords, std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) ;
virtual int SearchBoolExp(RsRegularExpression::Expression *exp, std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) const ;
// Extra file list
virtual void removeExtraFile(const RsFileHash& hash);
// Extra file list
virtual bool removeExtraFile(const RsFileHash& hash);
// Interface for browsing dir hierarchy
//

View File

@ -3,7 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2008 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2008 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -272,7 +273,8 @@ bool ftExtraList::cleanupEntry(std::string /*path*/, TransferRequestFlags /*flag
* file is removed after period.
**/
bool ftExtraList::hashExtraFile(std::string path, uint32_t period, TransferRequestFlags flags)
bool ftExtraList::hashExtraFile(
std::string path, uint32_t period, TransferRequestFlags flags )
{
#ifdef DEBUG_ELIST
std::cerr << "ftExtraList::hashExtraFile() path: " << path;
@ -282,12 +284,25 @@ bool ftExtraList::hashExtraFile(std::string path, uint32_t period, TransferRequ
std::cerr << std::endl;
#endif
/* add into queue */
RS_STACK_MUTEX(extMutex);
auto failure = [](std::string errMsg)
{
RsErr() << __PRETTY_FUNCTION__ << " " << errMsg << std::endl;
return false;
};
if(!RsDirUtil::fileExists(path))
return failure("file: " + path + "not found");
if(RsDirUtil::checkDirectory(path))
return failure("Cannot add a directory: " + path + "as extra file");
FileDetails details(path, period, flags);
details.info.age = time(NULL) + period;
mToHash.push_back(details);
details.info.age = static_cast<int>(time(nullptr) + period);
{
RS_STACK_MUTEX(extMutex);
mToHash.push_back(details); /* add into queue */
}
return true;
}

View File

@ -678,14 +678,13 @@ bool ftServer::ExtraFileAdd(std::string fname, const RsFileHash& hash, uint64_t
}
bool ftServer::ExtraFileRemove(const RsFileHash& hash)
{
mFileDatabase->removeExtraFile(hash);
return true;
}
{ return mFileDatabase->removeExtraFile(hash); }
bool ftServer::ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags)
bool ftServer::ExtraFileHash(
std::string localpath, rstime_t period, TransferRequestFlags flags )
{
return mFtExtra->hashExtraFile(localpath, period, flags);
return mFtExtra->hashExtraFile(
localpath, static_cast<uint32_t>(period), flags );
}
bool ftServer::ExtraFileStatus(std::string localpath, FileInfo &info)
@ -1227,6 +1226,7 @@ void ftServer::deriveEncryptionKey(const RsFileHash& hash, uint8_t *key)
SHA256_Final (key, &sha_ctx);
}
#ifdef USE_NEW_METHOD
static const uint32_t ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE = 12 ;
static const uint32_t ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE = 16 ;
static const uint32_t ENCRYPTED_FT_HEADER_SIZE = 4 ;
@ -1234,7 +1234,7 @@ static const uint32_t ENCRYPTED_FT_EDATA_SIZE = 4 ;
static const uint8_t ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305 = 0x01 ;
static const uint8_t ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256 = 0x02 ;
#endif //USE_NEW_METHOD
bool ftServer::encryptItem(RsTurtleGenericTunnelItem *clear_item,const RsFileHash& hash,RsTurtleGenericDataItem *& encrypted_item)
{

View File

@ -181,7 +181,7 @@ public:
***/
virtual bool ExtraFileAdd(std::string fname, const RsFileHash& hash, uint64_t size, uint32_t period, TransferRequestFlags flags);
virtual bool ExtraFileRemove(const RsFileHash& hash);
virtual bool ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags);
virtual bool ExtraFileHash(std::string localpath, rstime_t period, TransferRequestFlags flags);
virtual bool ExtraFileStatus(std::string localpath, FileInfo &info);
virtual bool ExtraFileMove(std::string fname, const RsFileHash& hash, uint64_t size, std::string destpath);

View File

@ -1,9 +1,10 @@
/*******************************************************************************
* libretroshare/src/rsitems: rsdiscitems.cc *
* Gossip discovery service items *
* *
* libretroshare: retroshare core library *
* *
* Copyright 2007-2008 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2007-2008 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -19,73 +20,62 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include "rsitems/rsdiscovery2items.h"
#include "gossipdiscovery/gossipdiscoveryitems.h"
#include "serialiser/rsbaseserial.h"
#include "serialiser/rstypeserializer.h"
#if 0
#include "rsitems/rsserviceids.h"
#include "serialiser/rstlvbase.h"
#include "serialiser/rstlvtypes.h"
#endif
/***
* #define RSSERIAL_DEBUG 1
* #define RSSERIAL_ERROR_DEBUG 1
***/
#define RSSERIAL_ERROR_DEBUG 1
#include "serialiser/rsserializable.h"
#include <iostream>
RsItem *RsDiscSerialiser::create_item(uint16_t service,uint8_t item_subtype) const
RsItem *RsDiscSerialiser::create_item(
uint16_t service, uint8_t item_subtype ) const
{
if(service != RS_SERVICE_TYPE_DISC)
return NULL ;
if(service != RS_SERVICE_TYPE_DISC) return nullptr;
switch(item_subtype)
{
case RS_PKT_SUBTYPE_DISC_PGP_LIST : return new RsDiscPgpListItem() ; //= 0x01;
case RS_PKT_SUBTYPE_DISC_PGP_CERT : return new RsDiscPgpCertItem() ; //= 0x02;
case RS_PKT_SUBTYPE_DISC_CONTACT_deprecated : return NULL ; //= 0x03;
#if 0
case RS_PKT_SUBTYPE_DISC_SERVICES : return new RsDiscServicesItem(); //= 0x04;
#endif
case RS_PKT_SUBTYPE_DISC_CONTACT : return new RsDiscContactItem(); //= 0x05;
case RS_PKT_SUBTYPE_DISC_IDENTITY_LIST : return new RsDiscIdentityListItem(); //= 0x06;
switch(static_cast<RsGossipDiscoveryItemType>(item_subtype))
{
case RsGossipDiscoveryItemType::PGP_LIST: return new RsDiscPgpListItem();
case RsGossipDiscoveryItemType::PGP_CERT_BINARY: return new RsDiscPgpKeyItem();
case RsGossipDiscoveryItemType::CONTACT: return new RsDiscContactItem();
case RsGossipDiscoveryItemType::IDENTITY_LIST: return new RsDiscIdentityListItem();
default:
return NULL ;
}
return nullptr;
}
return nullptr;
}
/*************************************************************************/
void RsDiscPgpListItem::clear()
void RsDiscPgpListItem::clear()
{
mode = DISC_PGP_LIST_MODE_NONE;
mode = RsGossipDiscoveryPgpListMode::NONE;
pgpIdSet.TlvClear();
}
void RsDiscPgpListItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
void RsDiscPgpListItem::serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RsTypeSerializer::serial_process<uint32_t>(j,ctx,mode,"mode") ;
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,pgpIdSet,"pgpIdSet") ;
RS_SERIAL_PROCESS(mode);
RS_SERIAL_PROCESS(pgpIdSet);
}
void RsDiscPgpCertItem::clear()
void RsDiscPgpKeyItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
pgpId.clear();
pgpCert.clear();
RsTypeSerializer::serial_process(j,ctx,pgpKeyId,"pgpKeyId") ;
RsTypeSerializer::TlvMemBlock_proxy prox(bin_data,bin_len) ;
RsTypeSerializer::serial_process(j,ctx,prox,"keyData") ;
}
void RsDiscPgpCertItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
void RsDiscPgpKeyItem::clear()
{
RsTypeSerializer::serial_process(j,ctx,pgpId,"pgpId") ;
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_PGPCERT,pgpCert,"pgpCert") ;
pgpKeyId.clear();
free(bin_data);
bin_data = nullptr;
bin_len=0;
}
void RsDiscContactItem::clear()
@ -156,3 +146,9 @@ void RsDiscIdentityListItem::serial_process(RsGenericSerializer::SerializeJob j,
RS_SERIAL_PROCESS(ownIdentityList);
}
RsDiscItem::RsDiscItem(RsGossipDiscoveryItemType subtype)
: RsItem( RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DISC, static_cast<uint8_t>(subtype) )
{
}
RsDiscItem::~RsDiscItem() {}

View File

@ -1,9 +1,10 @@
/*******************************************************************************
* libretroshare/src/rsitems: rsdiscitems.h *
* Gossip discovery service items *
* *
* libretroshare: retroshare core library *
* *
* Copyright 2004-2008 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2004-2008 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -19,91 +20,94 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef RS_DISC_ITEMS_H
#define RS_DISC_ITEMS_H
#pragma once
#include "serialiser/rsserial.h"
#include "serialiser/rstlvidset.h"
#include "serialiser/rstlvaddrs.h"
#include "serialiser/rstlvbinary.h"
#include "rsitems/rsserviceids.h"
#include "rsitems/rsitem.h"
#include "rsitems/itempriorities.h"
#include "serialiser/rsserializer.h"
const uint8_t RS_PKT_SUBTYPE_DISC_PGP_LIST = 0x01;
const uint8_t RS_PKT_SUBTYPE_DISC_PGP_CERT = 0x02;
const uint8_t RS_PKT_SUBTYPE_DISC_CONTACT_deprecated = 0x03;
const uint8_t RS_PKT_SUBTYPE_DISC_SERVICES = 0x04;
const uint8_t RS_PKT_SUBTYPE_DISC_CONTACT = 0x05;
const uint8_t RS_PKT_SUBTYPE_DISC_IDENTITY_LIST = 0x06;
enum class RsGossipDiscoveryItemType : uint8_t
{
PGP_LIST = 0x1,
PGP_CERT = 0x2, // deprecated
CONTACT = 0x5,
IDENTITY_LIST = 0x6,
PGP_CERT_BINARY = 0x9,
};
class RsDiscItem: public RsItem
{
protected:
RsDiscItem(uint8_t subtype) :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DISC, subtype) {}
protected:
RsDiscItem(RsGossipDiscoveryItemType subtype);
public:
RsDiscItem() = delete;
virtual ~RsDiscItem();
};
#define DISC_PGP_LIST_MODE_NONE 0x00
#define DISC_PGP_LIST_MODE_FRIENDS 0x01
#define DISC_PGP_LIST_MODE_GETCERT 0x02
/**
* This enum is underlined by uint32_t for historical reasons.
* We are conscious that uint32_t is an overkill for so few possible values but,
* changing here it at this point would break binary serialized item
* retro-compatibility.
*/
enum class RsGossipDiscoveryPgpListMode : uint32_t
{
NONE = 0x0,
FRIENDS = 0x1,
GETCERT = 0x2
};
class RsDiscPgpListItem: public RsDiscItem
{
public:
RsDiscPgpListItem()
:RsDiscItem(RS_PKT_SUBTYPE_DISC_PGP_LIST)
{
setPriorityLevel(QOS_PRIORITY_RS_DISC_PGP_LIST);
}
RsDiscPgpListItem() : RsDiscItem(RsGossipDiscoveryItemType::PGP_LIST)
{ setPriorityLevel(QOS_PRIORITY_RS_DISC_PGP_LIST); }
virtual ~RsDiscPgpListItem(){}
void clear() override;
void serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override;
virtual void clear();
virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */);
uint32_t mode;
RsGossipDiscoveryPgpListMode mode;
RsTlvPgpIdSet pgpIdSet;
};
class RsDiscPgpCertItem: public RsDiscItem
class RsDiscPgpKeyItem: public RsDiscItem
{
public:
RsDiscPgpCertItem()
:RsDiscItem(RS_PKT_SUBTYPE_DISC_PGP_CERT)
{
setPriorityLevel(QOS_PRIORITY_RS_DISC_PGP_CERT);
}
RsDiscPgpKeyItem() : RsDiscItem(RsGossipDiscoveryItemType::PGP_CERT_BINARY)
{ setPriorityLevel(QOS_PRIORITY_RS_DISC_PGP_CERT); }
virtual ~RsDiscPgpCertItem(){}
virtual ~RsDiscPgpKeyItem() { delete[](bin_data);bin_data=nullptr;bin_len=0;}
virtual void clear();
virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */);
void clear() override;
void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx) override;
RsPgpId pgpId;
std::string pgpCert;
RsPgpId pgpKeyId; // duplicate information for practical reasons
unsigned char *bin_data; // binry key data allocated with new unsigned char[]
uint32_t bin_len;
};
class RsDiscContactItem: public RsDiscItem
{
public:
RsDiscContactItem()
:RsDiscItem(RS_PKT_SUBTYPE_DISC_CONTACT)
{
setPriorityLevel(QOS_PRIORITY_RS_DISC_CONTACT);
}
RsDiscContactItem() : RsDiscItem(RsGossipDiscoveryItemType::CONTACT)
{ setPriorityLevel(QOS_PRIORITY_RS_DISC_CONTACT); }
virtual ~RsDiscContactItem() {}
virtual void clear();
virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */);
void clear() override;
void serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override;
RsPgpId pgpId;
RsPeerId sslId;
@ -143,53 +147,23 @@ class RsDiscIdentityListItem: public RsDiscItem
{
public:
RsDiscIdentityListItem()
:RsDiscItem(RS_PKT_SUBTYPE_DISC_IDENTITY_LIST)
{
setPriorityLevel(QOS_PRIORITY_RS_DISC_CONTACT);
}
RsDiscIdentityListItem() :
RsDiscItem(RsGossipDiscoveryItemType::IDENTITY_LIST)
{ setPriorityLevel(QOS_PRIORITY_RS_DISC_CONTACT); }
virtual ~RsDiscIdentityListItem() {}
void clear() override { ownIdentityList.clear(); }
void serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override;
virtual void clear() { ownIdentityList.clear() ; }
virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
std::list<RsGxsId> ownIdentityList ;
std::list<RsGxsId> ownIdentityList;
};
#if 0
class RsDiscServicesItem: public RsDiscItem
{
public:
RsDiscServicesItem()
:RsDiscItem(RS_PKT_SUBTYPE_DISC_SERVICES)
{
setPriorityLevel(QOS_PRIORITY_RS_DISC_SERVICES);
}
virtual ~RsDiscServicesItem();
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent = 0);
std::string version;
RsTlvServiceIdMap mServiceIdMap;
};
#endif
class RsDiscSerialiser: public RsServiceSerializer
{
public:
RsDiscSerialiser() :RsServiceSerializer(RS_SERVICE_TYPE_DISC) {}
public:
RsDiscSerialiser() :RsServiceSerializer(RS_SERVICE_TYPE_DISC) {}
virtual ~RsDiscSerialiser() {}
virtual ~RsDiscSerialiser() {}
RsItem *create_item(uint16_t service,uint8_t item_subtype) const ;
RsItem* create_item(uint16_t service, uint8_t item_subtype) const;
};
#endif // RS_DISC_ITEMS_H

View File

@ -0,0 +1,222 @@
/*******************************************************************************
* RetroShare gossip discovery service implementation *
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2004-2013 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
//
// p3GossipDiscovery is reponsible for facilitating the circulation of public keys between friend nodes.
//
// The service locally holds a cache that stores:
// * the list of friend profiles, in each of which the list of locations with their own discovery flag (which means whether they allow discovery or not)
// * the list of friend nodes, with their version number
//
// Data flow
// =========
//
// statusChange(std::list<pqiServicePeer>&) // called by pqiMonitor when peers are added,removed, or recently connected
// |
// +---- sendOwnContactInfo(RsPeerId) // [On connection] sends own PgpId, discovery flag, list of own signed GxsIds
// | |
// | +---->[to friend]
// |
// +---- locally add/remove cache info // [New/Removed friend] updates the list of friends, along with their own discovery flag
//
// tick()
// |
// +------ handleIncoming()
// |
// +-- recvOwnContactInfo(RsPeerId) // update location, IP addresses of a peer.
// | |
// | +------(if the peer has short_invite flag)
// | | |
// | | +---------requestPGPKey()->[to friend] // requests the full PGP public key, so as to be
// | | // able to validate connections.
// | |
// | +------(if disc != RS_VS_DISC_OFF)
// | |
// | +---------sendPgpList()->[to friend] // sends own list of friend profiles for which at least one location
// | // accepts discovery
// +-- processContactInfo(item->PeerId(), contact);
// | |
// | +------ addFriend() // called on nodes signed by the PGP key mentionned in the disc info
// | |
// | +------ update local discovery info
// |
// +-- recvIdentityList(Gxs Identity List)
// | |
// | +------ mGixs->requestKey(*it,peers,use_info) ; // requestKey() takes care of requesting the GxsIds that are missing
// |
// +-- recvPGPCertificate(item->PeerId(), pgpkey);
// | |
// | +------(if peer has short invite flag)
// | |
// | +--------- add key to keyring, accept connections and notify peerMgr
// |
// +-- processPGPList(pgplist->PeerId(), pgplist); // list of PGP keys of a friend, received from himself
// | |
// | +------ requestPgpCertificate() // request missing keys only
// | |
// | +------ updatePeers_locked(fromId)
// | |
// | +--------- sendContactInfo_locked(from,to) // sends IP information about mutual friends to the origin of the info
// | |
// | +--------- sendContactInfo_locked(to,from) // sends IP information origin to online mutual friends
// |
// +-- recvPGPCertificateRequest(pgplist->PeerId(), pgplist);
// |
// +------ sendPGPCertificate() // only sends the ones we are friend with, and only send own cert
// // if discovery is off
//
// Notes:
// * Tor nodes never send their own IP, and normal nodes never send their IP to Tor nodes either.
// A Tor node may accidentally know the IP of a normal node when it adds its certificate. However, the IP is dropped and not saved in this case.
// Generally speaking, no IP information should leave or transit through a Tor node.
//
// * the decision to call recvOwnContactInfo() or processContactInfo() depends on whether the item's peer id is the one the info is about. This is
// a bit unsafe. We should probably have to different items here especially if the information is not exactly the same.
//
#include <memory>
#include "retroshare/rsgossipdiscovery.h"
#include "pqi/p3peermgr.h"
#include "pqi/p3linkmgr.h"
#include "pqi/p3netmgr.h"
#include "pqi/pqiservicemonitor.h"
#include "gossipdiscovery/gossipdiscoveryitems.h"
#include "services/p3service.h"
#include "pqi/authgpg.h"
#include "gxs/rsgixs.h"
class p3ServiceControl;
struct DiscSslInfo
{
DiscSslInfo() : mDiscStatus(RS_VS_DISC_OFF) {} // default is to not allow discovery, until the peer tells about it
uint16_t mDiscStatus;
};
struct DiscPeerInfo
{
DiscPeerInfo() {}
std::string mVersion;
};
struct DiscPgpInfo
{
DiscPgpInfo() {}
void mergeFriendList(const std::set<RsPgpId> &friends);
std::set<RsPgpId> mFriendSet;
std::map<RsPeerId, DiscSslInfo> mSslIds;
};
class p3discovery2 :
public RsGossipDiscovery, public p3Service, public pqiServiceMonitor
//public AuthGPGService
{
public:
p3discovery2( p3PeerMgr* peerMgr, p3LinkMgr* linkMgr, p3NetMgr* netMgr,
p3ServiceControl* sc, RsGixs* gixs );
virtual ~p3discovery2();
virtual RsServiceInfo getServiceInfo();
/************* from pqiServiceMonitor *******************/
virtual void statusChange(const std::list<pqiServicePeer> &plist);
/************* from pqiServiceMonitor *******************/
int tick();
/* external interface */
bool getDiscFriends(const RsPeerId &id, std::list<RsPeerId> &friends);
bool getDiscPgpFriends(const RsPgpId &pgpid, std::list<RsPgpId> &gpg_friends);
bool getPeerVersion(const RsPeerId &id, std::string &version);
bool getWaitingDiscCount(size_t &sendCount, size_t &recvCount);
/************* from AuthGPService ****************/
// virtual AuthGPGOperation *getGPGOperation();
// virtual void setGPGOperation(AuthGPGOperation *operation);
private:
RsPgpId getPGPId(const RsPeerId &id);
int handleIncoming();
void updatePgpFriendList();
void addFriend(const RsPeerId &sslId);
void removeFriend(const RsPeerId &sslId);
void updatePeerAddresses(const RsDiscContactItem *item);
void updatePeerAddressList(const RsDiscContactItem *item);
void sendOwnContactInfo(const RsPeerId &sslid);
void recvOwnContactInfo(const RsPeerId &fromId, const RsDiscContactItem *item);
void sendPGPList(const RsPeerId &toId);
void processPGPList(const RsPeerId &fromId, const RsDiscPgpListItem *item);
void processContactInfo(const RsPeerId &fromId, const RsDiscContactItem *info);
// send/recv information
void requestPGPCertificate(const RsPgpId &aboutId, const RsPeerId &toId);
void recvPGPCertificateRequest(const RsPeerId& fromId, const RsDiscPgpListItem* item );
void sendPGPCertificate(const RsPgpId &aboutId, const RsPeerId &toId);
void recvPGPCertificate(const RsPeerId &fromId, RsDiscPgpKeyItem *item);
void recvIdentityList(const RsPeerId& pid,const std::list<RsGxsId>& ids);
bool setPeerVersion(const RsPeerId &peerId, const std::string &version);
void rsEventsHandler(const RsEvent& event);
RsEventsHandlerId_t mRsEventsHandle;
p3PeerMgr *mPeerMgr;
p3LinkMgr *mLinkMgr;
p3NetMgr *mNetMgr;
p3ServiceControl *mServiceCtrl;
RsGixs* mGixs;
/* data */
RsMutex mDiscMtx;
void updatePeers_locked(const RsPeerId &aboutId);
void sendContactInfo_locked(const RsPgpId &aboutId, const RsPeerId &toId);
rstime_t mLastPgpUpdate;
std::map<RsPgpId, DiscPgpInfo> mFriendList;
std::map<RsPeerId, DiscPeerInfo> mLocationMap;
// This was used to async the receiving of PGP keys, mainly because PGPHandler cross-checks all signatures, so receiving these keys in large loads can be costly
// Because discovery is not running in the main thread, there's no reason to re-async this into another process (e.g. AuthGPG)
//
// std::list<RsDiscPgpCertItem *> mPendingDiscPgpCertInList;
protected:
RS_SET_CONTEXT_DEBUG_LEVEL(1)
};

View File

@ -3,7 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2012-2012 by Robert Fernie, Evi-Parker Christopher *
* Copyright (C) 2012 Christopher Evi-Parker *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -36,6 +37,7 @@
#include "rsgixs.h"
#include "rsgxsutil.h"
#include "rsserver/p3face.h"
#include "retroshare/rsevents.h"
#include <algorithm>
@ -64,10 +66,11 @@ static const uint32_t INDEX_AUTHEN_ADMIN = 0x00000040; // admin key
static const uint32_t MSG_CLEANUP_PERIOD = 60*59; // 59 minutes
static const uint32_t INTEGRITY_CHECK_PERIOD = 60*31; // 31 minutes
RsGenExchange::RsGenExchange(RsGeneralDataService *gds, RsNetworkExchangeService *ns,
RsSerialType *serviceSerialiser, uint16_t servType, RsGixs* gixs,
uint32_t authenPolicy)
: mGenMtx("GenExchange"),
RsGenExchange::RsGenExchange(
RsGeneralDataService* gds, RsNetworkExchangeService* ns,
RsSerialType* serviceSerialiser, uint16_t servType, RsGixs* gixs,
uint32_t authenPolicy ) :
mGenMtx("GenExchange"),
mDataStore(gds),
mNetService(ns),
mSerialiser(serviceSerialiser),
@ -1097,7 +1100,10 @@ void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::receiveChanges()" << std::endl;
#endif
RsGxsChanges out;
std::unique_ptr<RsGxsChanges> evt(new RsGxsChanges);
evt->mServiceType = static_cast<RsServiceType>(mServType);
RsGxsChanges& out = *evt;
out.mService = getTokenService();
// collect all changes in one GxsChanges object
@ -1109,7 +1115,7 @@ void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
RsGxsMsgChange* mc;
RsGxsDistantSearchResultChange *gt;
if((mc = dynamic_cast<RsGxsMsgChange*>(n)) != NULL)
if((mc = dynamic_cast<RsGxsMsgChange*>(n)) != nullptr)
{
if (mc->metaChange())
{
@ -1120,7 +1126,7 @@ void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
addMessageChanged(out.mMsgs, mc->msgChangeMap);
}
}
else if((gc = dynamic_cast<RsGxsGroupChange*>(n)) != NULL)
else if((gc = dynamic_cast<RsGxsGroupChange*>(n)) != nullptr)
{
if(gc->metaChange())
{
@ -1131,18 +1137,20 @@ void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
out.mGrps.splice(out.mGrps.end(), gc->mGrpIdList);
}
}
else if((gt = dynamic_cast<RsGxsDistantSearchResultChange*>(n)) != NULL)
else if(( gt =
dynamic_cast<RsGxsDistantSearchResultChange*>(n) ) != nullptr)
{
out.mDistantSearchReqs.push_back(gt->mRequestId);
}
else
std::cerr << "(EE) Unknown changes type!!" << std::endl;
RsErr() << __PRETTY_FUNCTION__ << " Unknown changes type!"
<< std::endl;
delete n;
}
changes.clear() ;
RsServer::notify()->notifyGxsChange(out);
RsServer::notify()->notifyGxsChange(out);
if(rsEvents) rsEvents->postEvent(std::move(evt));
}
bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe)
@ -1154,8 +1162,7 @@ bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId,
setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED,
(GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED | GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED));
if(mNetService != NULL)
mNetService->subscribeStatusChanged(grpId,subscribe) ;
if(mNetService) mNetService->subscribeStatusChanged(grpId,subscribe);
#ifdef GEN_EXCH_DEBUG
else
std::cerr << "(EE) No mNetService in RsGenExchange for service 0x" << std::hex << mServType << std::dec << std::endl;
@ -3437,3 +3444,7 @@ bool RsGenExchange::localSearch( const std::string& matchString,
{
return mNetService->search(matchString, results);
}
RsGxsChanges::RsGxsChanges() :
RsEvent(RsEventType::GXS_CHANGES), mServiceType(RsServiceType::NONE),
mService(nullptr) {}

View File

@ -113,7 +113,10 @@ public:
* @param gixs This is used for verification of msgs and groups received by Gen Exchange using identities.
* @param authenPolicy This determines the authentication used for verfying authorship of msgs and groups
*/
RsGenExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, uint16_t mServType, RsGixs* gixs, uint32_t authenPolicy);
RsGenExchange(
RsGeneralDataService* gds, RsNetworkExchangeService* ns,
RsSerialType* serviceSerialiser, uint16_t mServType, RsGixs* gixs,
uint32_t authenPolicy );
virtual ~RsGenExchange();

View File

@ -92,8 +92,6 @@
* as these will be used very frequently.
*****/
typedef PGPIdType RsPgpId;
/* Identity Interface for GXS Message Verification.
*/
class RsGixs

View File

@ -217,7 +217,9 @@ bool GrpCircleVetting::expired()
{
return time(NULL) > (mTimeStamp + EXPIRY_PERIOD_OFFSET);
}
bool GrpCircleVetting::canSend(const SSLIdType& peerId, const RsGxsCircleId& circleId,bool& should_encrypt)
bool GrpCircleVetting::canSend(
const RsPeerId& peerId, const RsGxsCircleId& circleId,
bool& should_encrypt )
{
if(mCircles->isLoaded(circleId))
{

View File

@ -146,9 +146,16 @@ bool RsGxsMessageCleanUp::clean()
}
RsGxsIntegrityCheck::RsGxsIntegrityCheck(
RsGeneralDataService* const dataService, RsGenExchange* genex,
RsSerialType& serializer, RsGixs* gixs ) :
mDs(dataService), mGenExchangeClient(genex), mSerializer(serializer),
RsGeneralDataService* const dataService, RsGenExchange* genex,
RsSerialType&
#ifdef RS_DEEP_SEARCH
serializer
#endif
, RsGixs* gixs )
: mDs(dataService), mGenExchangeClient(genex),
#ifdef RS_DEEP_SEARCH
mSerializer(serializer),
#endif
mDone(false), mIntegrityMutex("integrity"), mGixs(gixs) {}
void RsGxsIntegrityCheck::run()

View File

@ -21,8 +21,7 @@
* *
*******************************************************************************/
#ifndef GXSUTIL_H_
#define GXSUTIL_H_
#pragma once
#include <vector>
#include "rsitems/rsnxsitems.h"
@ -214,8 +213,9 @@ private:
RsGeneralDataService* const mDs;
RsGenExchange *mGenExchangeClient;
#ifdef RS_DEEP_SEARCH
RsSerialType& mSerializer;
#endif
bool mDone;
RsMutex mIntegrityMutex;
std::list<RsGxsGroupId> mDeletedGrps;
@ -262,5 +262,3 @@ public:
GxsMsgReq mMsgs ;
uint32_t mToken;
};
#endif /* GXSUTIL_H_ */

View File

@ -3,7 +3,7 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2016-2017 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2016-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -22,12 +22,13 @@
#include "util/rsdir.h"
#include "gxstrans/p3gxstrans.h"
#include "util/stacktrace.h"
#include "util/rsdebug.h"
//#define DEBUG_GXSTRANS 1
typedef unsigned int uint;
RsGxsTrans *rsGxsTrans = NULL ;
/*extern*/ RsGxsTrans* rsGxsTrans = nullptr;
const uint32_t p3GxsTrans::MAX_DELAY_BETWEEN_CLEANUPS = 900; // every 15 mins. Could be less.
@ -240,10 +241,7 @@ void p3GxsTrans::handleResponse(uint32_t token, uint32_t req_type)
if(!have_preferred_group)
{
/* This is true only at first run when we haven't received mail
* distribuition groups from friends
* TODO: We should check if we have some connected friend too, to
* avoid to create yet another never used mail distribution group.
*/
* distribuition groups from friends */
#ifdef DEBUG_GXSTRANS
std::cerr << "p3GxsTrans::handleResponse(...) preferredGroupId.isNu"
@ -533,6 +531,14 @@ void p3GxsTrans::service_tick()
for(std::map<RsGxsId,MsgSizeCount>::const_iterator it(per_user_statistics.begin());it!=per_user_statistics.end();++it)
std::cerr << " " << it->first << ": " << it->second.count << " " << it->second.size << std::endl;
#endif
// Waiting here is very important because the thread may still be updating its semaphores after setting isDone() to true
// If we delete it during this operation it will corrupt the stack and cause unpredictable errors.
while(mCleanupThread->isRunning())
{
std::cerr << "Waiting for mCleanupThread to terminate..." << std::endl;
rstime::rs_usleep(500*1000);
}
delete mCleanupThread;
mCleanupThread=NULL ;
@ -613,9 +619,10 @@ void p3GxsTrans::service_tick()
}
else
{
/* TODO: It is a receipt for a message sent by someone else
/* It is a receipt for a message sent by someone else
* we can delete original mail from our GXS DB without
* waiting for GXS_STORAGE_PERIOD */
* waiting for GXS_STORAGE_PERIOD, this has been implemented
* already by Cyril into GxsTransIntegrityCleanupThread */
}
break;
}
@ -956,9 +963,9 @@ void p3GxsTrans::locked_processOutgoingRecord(OutgoingRecord& pr)
{
case RsGxsTransEncryptionMode::CLEAR_TEXT:
{
std::cerr << "p3GxsTrans::sendMail(...) you are sending a mail "
<< "without encryption, everyone can read it!"
<< std::endl;
RsWarn() << __PRETTY_FUNCTION__ << " you are sending a mail "
<< "without encryption, everyone can read it!"
<< std::endl;
break;
}
case RsGxsTransEncryptionMode::RSA:
@ -978,15 +985,15 @@ void p3GxsTrans::locked_processOutgoingRecord(OutgoingRecord& pr)
}
else
{
std::cerr << "p3GxsTrans::sendMail(...) RSA encryption failed! "
<< "error_status: " << encryptError << std::endl;
RsErr() << __PRETTY_FUNCTION__ << " RSA encryption failed! "
<< "error_status: " << encryptError << std::endl;
pr.status = GxsTransSendStatus::FAILED_ENCRYPTION;
goto processingFailed;
}
}
case RsGxsTransEncryptionMode::UNDEFINED_ENCRYPTION:
default:
std::cerr << "p3GxsTrans::sendMail(...) attempt to send mail with "
RsErr() << __PRETTY_FUNCTION__ << " attempt to send mail with "
<< "wrong EncryptionMode: "
<< static_cast<uint>(pr.mailItem.cryptoType)
<< " dropping mail!" << std::endl;
@ -1032,7 +1039,8 @@ void p3GxsTrans::locked_processOutgoingRecord(OutgoingRecord& pr)
{
RS_STACK_MUTEX(mIngoingMutex);
auto range = mIncomingQueue.equal_range(pr.mailItem.mailId);
bool changed = false ;
bool changed = false;
bool received = false;
for( auto it = range.first; it != range.second; ++it)
{
@ -1043,14 +1051,21 @@ void p3GxsTrans::locked_processOutgoingRecord(OutgoingRecord& pr)
mIncomingQueue.erase(it); delete rt;
pr.status = GxsTransSendStatus::RECEIPT_RECEIVED;
changed = true ;
changed = true;
received = true;
break;
}
}
if(!received && time(nullptr) - pr.sent_ts > GXS_STORAGE_PERIOD)
{
changed = true;
pr.status = GxsTransSendStatus::FAILED_TIMED_OUT;
}
if(changed)
IndicateConfigChanged();
// TODO: Resend message if older then treshold
break;
}
case GxsTransSendStatus::RECEIPT_RECEIVED:
@ -1059,14 +1074,13 @@ void p3GxsTrans::locked_processOutgoingRecord(OutgoingRecord& pr)
processingFailed:
case GxsTransSendStatus::FAILED_RECEIPT_SIGNATURE:
case GxsTransSendStatus::FAILED_ENCRYPTION:
case GxsTransSendStatus::FAILED_TIMED_OUT:
default:
{
std::cout << "p3GxsTrans::processRecord(" << pr.mailItem.mailId
<< ") failed with: " << static_cast<uint>(pr.status)
RsErr() << __PRETTY_FUNCTION__ << " processing:" << pr.mailItem.mailId
<< " failed with: " << static_cast<uint>(pr.status)
<< std::endl;
break;
}
}
}
void p3GxsTrans::notifyClientService(const OutgoingRecord& pr)

View File

@ -3,7 +3,7 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2016-2017 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2016-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -21,7 +21,7 @@
*******************************************************************************/
#pragma once
#include <stdint.h>
#include <cstdint>
#include <unordered_map>
#include <map>
@ -70,7 +70,7 @@ struct MsgSizeCount
};
/**
* @brief p3GxsTrans is a mail delivery service based on GXS.
* @brief p3GxsTrans asyncronous redundant small mail trasport on top of GXS.
* p3GxsTrans is capable of asynchronous mail delivery and acknowledgement.
* p3GxsTrans is meant to be capable of multiple encryption options,
* @see RsGxsTransEncryptionMode at moment messages are encrypted using RSA

View File

@ -1062,7 +1062,7 @@ void p3GxsTunnelService::handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item)
// Note: for some obscure reason, the typedef does not work here. Looks like a compiler error. So I use the primary type.
/*static*/ GXSTunnelId p3GxsTunnelService::makeGxsTunnelId(
/*static*/ RsGxsTunnelId p3GxsTunnelService::makeGxsTunnelId(
const RsGxsId &own_id, const RsGxsId &distant_id )
{
unsigned char mem[RsGxsId::SIZE_IN_BYTES * 2] ;

View File

@ -1,20 +1,19 @@
/*******************************************************************************
* libretroshare/src/gxs: jsonapi.cpp *
* *
* RetroShare JSON API *
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
@ -38,6 +37,7 @@
#include "retroshare/rsinit.h"
#include "util/rsurl.h"
#include "util/rstime.h"
#include "retroshare/rsevents.h"
// Generated at compile time
#include "jsonapi-includes.inl"
@ -96,7 +96,7 @@ JsonApiServer::corsOptionsHeaders =
/*static*/ bool JsonApiServer::checkRsServicePtrReady(
void* serviceInstance, const std::string& serviceName,
const void* serviceInstance, const std::string& serviceName,
RsGenericSerializer::SerializeContext& ctx,
const std::shared_ptr<restbed::Session> session)
{
@ -279,6 +279,69 @@ JsonApiServer::JsonApiServer(uint16_t port, const std::string& bindAddress,
} );
}, true);
registerHandler("/rsEvents/registerEventsHandler",
[this](const std::shared_ptr<rb::Session> session)
{
const std::multimap<std::string, std::string> headers
{
{ "Connection", "keep-alive" },
{ "Content-Type", "text/event-stream" }
};
session->yield(rb::OK, headers);
size_t reqSize = static_cast<size_t>(
session->get_request()->get_header("Content-Length", 0) );
session->fetch( reqSize, [this](
const std::shared_ptr<rb::Session> session,
const rb::Bytes& body )
{
INITIALIZE_API_CALL_JSON_CONTEXT;
if( !checkRsServicePtrReady(
rsEvents, "rsEvents", cAns, session ) )
return;
const std::weak_ptr<rb::Session> weakSession(session);
RsEventsHandlerId_t hId = rsEvents->generateUniqueHandlerId();
std::function<void(std::shared_ptr<const RsEvent>)> multiCallback =
[this, weakSession, hId](std::shared_ptr<const RsEvent> event)
{
mService.schedule( [weakSession, hId, event]()
{
auto session = weakSession.lock();
if(!session || session->is_closed())
{
if(rsEvents) rsEvents->unregisterEventsHandler(hId);
return;
}
RsGenericSerializer::SerializeContext ctx;
RsTypeSerializer::serial_process(
RsGenericSerializer::TO_JSON, ctx,
*const_cast<RsEvent*>(event.get()), "event" );
std::stringstream message;
message << "data: " << compactJSON << ctx.mJson << "\n\n";
session->yield(message.str());
} );
};
bool retval = rsEvents->registerEventsHandler(multiCallback, hId);
{
RsGenericSerializer::SerializeContext& ctx(cAns);
RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON);
RS_SERIAL_PROCESS(retval);
}
// return them to the API caller
std::stringstream message;
message << "data: " << compactJSON << cAns.mJson << "\n\n";
session->yield(message.str());
} );
}, true);
// Generated at compile time
#include "jsonapi-wrappers.inl"
}

View File

@ -1,24 +1,22 @@
/*******************************************************************************
* libretroshare/src/gxs: jsonapi.h *
* *
* RetroShare JSON API *
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include <string>
@ -54,6 +52,8 @@ extern JsonApiServer* jsonApiServer;
*/
struct JsonApiServer : RsSingleJobThread, p3Config
{
static const uint16_t DEFAULT_PORT = 9092 ;
/**
* @brief construct a JsonApiServer instance with given parameters
* @param[in] port listening port fpt the JSON API socket
@ -64,7 +64,7 @@ struct JsonApiServer : RsSingleJobThread, p3Config
* false otherwise, this usually requires user interacion to confirm access
*/
JsonApiServer(
uint16_t port = 9092,
uint16_t port = DEFAULT_PORT,
const std::string& bindAddress = "127.0.0.1",
const std::function<bool(const std::string&)> newAccessRequestCallback = [](const std::string&){return false;} );
@ -199,8 +199,18 @@ private:
static void handleCorsOptions(const std::shared_ptr<rb::Session> session);
static bool checkRsServicePtrReady(
void* serviceInstance, const std::string& serviceName,
const void* serviceInstance, const std::string& serviceName,
RsGenericSerializer::SerializeContext& ctx,
const std::shared_ptr<restbed::Session> session );
static inline bool checkRsServicePtrReady(
const std::shared_ptr<const void> serviceInstance,
const std::string& serviceName,
RsGenericSerializer::SerializeContext& ctx,
const std::shared_ptr<restbed::Session> session )
{
return checkRsServicePtrReady(
serviceInstance.get(), serviceName, ctx, session );
}
};

View File

@ -1,24 +1,22 @@
/*******************************************************************************
* libretroshare/src/gxs: jsonapiitems.h *
* *
* RetroShare JSON API *
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include <string>

View File

@ -108,7 +108,7 @@ SOURCES += tcponudp/udppeer.cc \
tcponudp/tcppacket.cc \
tcponudp/tcpstream.cc \
tcponudp/tou.cc \
tcponudp/bss_tou.c \
tcponudp/bss_tou.cc \
tcponudp/udprelay.cc \
pqi/pqissludp.cc \
@ -134,6 +134,8 @@ SOURCES += tcponudp/udppeer.cc \
PUBLIC_HEADERS = retroshare/rsdisc.h \
retroshare/rsgossipdiscovery \
retroshare/rsevents.h \
retroshare/rsexpr.h \
retroshare/rsfiles.h \
retroshare/rshistory.h \
@ -193,13 +195,13 @@ linux-* {
}
}
# Check if the systems libupnp has been Debian-patched
system(grep -E 'char[[:space:]]+PublisherUrl' /usr/include/upnp/upnp.h >/dev/null 2>&1) {
# Normal libupnp
} else {
# Patched libupnp or new unreleased version
DEFINES *= PATCHED_LIBUPNP
}
contains(RS_UPNP_LIB, threadutil) { # ensure we don't break libpnp-1.8.x
# Check if the systems libupnp-1.6.x has been Debian-patched
!system(grep -E 'char[[:space:]]+PublisherUrl' /usr/include/upnp/upnp.h >/dev/null 2>&1) {
# Patched libupnp or new unreleased version
DEFINES *= PATCHED_LIBUPNP
}
}
PKGCONFIG *= libssl
equals(RS_UPNP_LIB, "upnp ixml threadutil"):PKGCONFIG *= libupnp
@ -451,7 +453,7 @@ HEADERS += rsitems/rsitem.h \
serialiser/rstlvbanlist.h \
rsitems/rsbanlistitems.h \
rsitems/rsbwctrlitems.h \
rsitems/rsdiscovery2items.h \
gossipdiscovery/gossipdiscoveryitems.h \
rsitems/rsheartbeatitems.h \
rsitems/rsrttitems.h \
rsitems/rsgxsrecognitems.h \
@ -459,13 +461,14 @@ HEADERS += rsitems/rsitem.h \
rsitems/rsserviceinfoitems.h \
HEADERS += services/autoproxy/p3i2pbob.h \
services/rseventsservice.h \
services/autoproxy/rsautoproxymonitor.h \
services/p3msgservice.h \
services/p3service.h \
services/p3statusservice.h \
services/p3banlist.h \
services/p3bwctrl.h \
services/p3discovery2.h \
services/p3bwctrl.h \
gossipdiscovery/p3gossipdiscovery.h \
services/p3heartbeat.h \
services/p3rtt.h \
services/p3serviceinfo.h \
@ -477,6 +480,7 @@ HEADERS += turtle/p3turtle.h \
HEADERS += util/folderiterator.h \
util/rsdebug.h \
util/rskbdinput.h \
util/rsmemory.h \
util/smallobject.h \
util/rsdir.h \
@ -557,9 +561,7 @@ SOURCES += pqi/authgpg.cc \
pqi/pqiqosstreamer.cc \
pqi/sslfns.cc \
pqi/pqinetstatebox.cc \
pqi/p3servicecontrol.cc \
# pqi/p3dhtmgr.cc \
pqi/p3servicecontrol.cc
SOURCES += rsserver/p3face-config.cc \
rsserver/p3face-server.cc \
@ -571,7 +573,6 @@ SOURCES += rsserver/p3face-config.cc \
rsserver/rsinit.cc \
rsserver/rsaccounts.cc \
rsserver/rsloginhandler.cc \
rsserver/rstypes.cc \
rsserver/p3serverconfig.cc
SOURCES += grouter/p3grouter.cc \
@ -601,7 +602,7 @@ SOURCES += serialiser/rsbaseserial.cc \
serialiser/rstlvbanlist.cc \
rsitems/rsbanlistitems.cc \
rsitems/rsbwctrlitems.cc \
rsitems/rsdiscovery2items.cc \
gossipdiscovery/gossipdiscoveryitems.cc \
rsitems/rsrttitems.cc \
rsitems/rsgxsrecognitems.cc \
rsitems/rsgxsupdateitems.cc \
@ -609,26 +610,24 @@ SOURCES += serialiser/rsbaseserial.cc \
SOURCES += services/autoproxy/rsautoproxymonitor.cc \
services/rseventsservice.cc \
services/autoproxy/p3i2pbob.cc \
services/p3msgservice.cc \
services/p3service.cc \
services/p3statusservice.cc \
services/p3banlist.cc \
services/p3bwctrl.cc \
services/p3discovery2.cc \
gossipdiscovery/p3gossipdiscovery.cc \
services/p3heartbeat.cc \
services/p3rtt.cc \
services/p3serviceinfo.cc \
SOURCES += turtle/p3turtle.cc \
turtle/rsturtleitem.cc
# turtle/turtlerouting.cc \
# turtle/turtlesearch.cc \
# turtle/turtletunnels.cc
turtle/rsturtleitem.cc
SOURCES += util/folderiterator.cc \
util/rsdebug.cc \
util/rskbdinput.cc \
util/rsexpr.cc \
util/smallobject.cc \
util/rsdir.cc \
@ -648,37 +647,14 @@ SOURCES += util/folderiterator.cc \
util/rsurl.cc
equals(RS_UPNP_LIB, miniupnpc) {
HEADERS += upnp/upnputil.h upnp/upnphandler_miniupnp.h
SOURCES += upnp/upnputil.c upnp/upnphandler_miniupnp.cc
} else {
HEADERS += upnp/UPnPBase.h upnp/upnphandler_linux.h
SOURCES += upnp/UPnPBase.cpp upnp/upnphandler_linux.cc
DEFINES *= RS_USE_LIBUPNP
HEADERS += rs_upnp/upnputil.h rs_upnp/upnphandler_miniupnp.h
SOURCES += rs_upnp/upnputil.c rs_upnp/upnphandler_miniupnp.cc
}
zeroconf {
HEADERS += zeroconf/p3zeroconf.h \
SOURCES += zeroconf/p3zeroconf.cc \
# Disable Zeroconf (we still need the code for zcnatassist
# DEFINES *= RS_ENABLE_ZEROCONF
}
# This is seperated from the above for windows/linux platforms.
# It is acceptable to build in zeroconf and have it not work,
# but unacceptable to rely on Apple's libraries for Upnp when we have alternatives. '
zcnatassist {
HEADERS += zeroconf/p3zcnatassist.h \
SOURCES += zeroconf/p3zcnatassist.cc \
DEFINES *= RS_ENABLE_ZCNATASSIST
contains(RS_UPNP_LIB, upnp) {
HEADERS += rs_upnp/upnp18_retrocompat.h
HEADERS += rs_upnp/UPnPBase.h rs_upnp/upnphandler_linux.h
SOURCES += rs_upnp/UPnPBase.cpp rs_upnp/upnphandler_linux.cc
}
# new gxs cache system
@ -865,22 +841,26 @@ rs_jsonapi {
DUMMYRESTBEDINPUT = FORCE
CMAKE_GENERATOR_OVERRIDE=""
win32-g++:CMAKE_GENERATOR_OVERRIDE="-G \"MSYS Makefiles\""
genrestbedlib.name = Generating libresbed.
genrestbedlib.name = Generating librestbed.
genrestbedlib.input = DUMMYRESTBEDINPUT
genrestbedlib.output = $$clean_path($${RESTBED_BUILD_PATH}/librestbed.a)
genrestbedlib.CONFIG += target_predeps combine
genrestbedlib.variable_out = PRE_TARGETDEPS
genrestbedlib.commands = \
cd $${RS_SRC_PATH} && \
git submodule update --init --recommend-shallow supportlibs/restbed && \
cd $${RESTBED_SRC_PATH} && \
git submodule update --init --recommend-shallow dependency/asio && \
git submodule update --init --recommend-shallow dependency/catch && \
git submodule update --init --recommend-shallow dependency/kashmir && \
mkdir -p $${RESTBED_BUILD_PATH}; cd $${RESTBED_BUILD_PATH} && \
cmake -DCMAKE_CXX_COMPILER=$$QMAKE_CXX $${CMAKE_GENERATOR_OVERRIDE} -DBUILD_SSL=OFF \
-DCMAKE_INSTALL_PREFIX=. -B. -H$$shell_path($${RESTBED_SRC_PATH}) && \
make
cd $${RS_SRC_PATH} && ( \
git submodule update --init supportlibs/restbed ; \
cd $${RESTBED_SRC_PATH} ; \
git submodule update --init dependency/asio ; \
git submodule update --init dependency/catch ; \
git submodule update --init dependency/kashmir ; \
true ) && \
mkdir -p $${RESTBED_BUILD_PATH} && cd $${RESTBED_BUILD_PATH} && \
cmake \
-DCMAKE_CXX_COMPILER=$$QMAKE_CXX \
$${CMAKE_GENERATOR_OVERRIDE} -DBUILD_SSL=OFF \
-DCMAKE_INSTALL_PREFIX=. -B. \
-H$$shell_path($${RESTBED_SRC_PATH}) && \
$(MAKE)
QMAKE_EXTRA_COMPILERS += genrestbedlib
RESTBED_HEADER_FILE=$$clean_path($${RESTBED_BUILD_PATH}/include/restbed)
@ -889,7 +869,7 @@ rs_jsonapi {
genrestbedheader.output = $${RESTBED_HEADER_FILE}
genrestbedheader.CONFIG += target_predeps combine no_link
genrestbedheader.variable_out = HEADERS
genrestbedheader.commands = cd $${RESTBED_BUILD_PATH} && make install
genrestbedheader.commands = cd $${RESTBED_BUILD_PATH} && $(MAKE) install
QMAKE_EXTRA_COMPILERS += genrestbedheader
}
@ -925,6 +905,37 @@ rs_deep_search {
HEADERS += deep_search/deep_search.h
}
rs_broadcast_discovery {
HEADERS += retroshare/rsbroadcastdiscovery.h \
services/broadcastdiscoveryservice.h
SOURCES += services/broadcastdiscoveryservice.cc
no_rs_cross_compiling {
DUMMYQMAKECOMPILERINPUT = FORCE
CMAKE_GENERATOR_OVERRIDE=""
win32-g++:CMAKE_GENERATOR_OVERRIDE="-G \"MSYS Makefiles\""
udpdiscoverycpplib.name = Generating libudp-discovery.a.
udpdiscoverycpplib.input = DUMMYQMAKECOMPILERINPUT
udpdiscoverycpplib.output = $$clean_path($${UDP_DISCOVERY_BUILD_PATH}/libudp-discovery.a)
udpdiscoverycpplib.CONFIG += target_predeps combine
udpdiscoverycpplib.variable_out = PRE_TARGETDEPS
udpdiscoverycpplib.commands = \
cd $${RS_SRC_PATH} && ( \
git submodule update --init supportlibs/udp-discovery-cpp || \
true ) && \
mkdir -p $${UDP_DISCOVERY_BUILD_PATH} && \
cd $${UDP_DISCOVERY_BUILD_PATH} && \
cmake -DCMAKE_C_COMPILER=$$fixQmakeCC($$QMAKE_CC) \
-DCMAKE_CXX_COMPILER=$$QMAKE_CXX \
$${CMAKE_GENERATOR_OVERRIDE} \
-DBUILD_EXAMPLE=OFF -DBUILD_TOOL=OFF \
-DCMAKE_INSTALL_PREFIX=. -B. \
-H$$shell_path($${UDP_DISCOVERY_SRC_PATH}) && \
$(MAKE)
QMAKE_EXTRA_COMPILERS += udpdiscoverycpplib
}
}
###########################################################################################################
# OLD CONFIG OPTIONS.
# Not used much - but might be useful one day.

View File

@ -23,6 +23,7 @@
#include "retroshare/rsids.h"
#include "retroshare/rstypes.h"
#include "util/rsdeprecate.h"
/* This is a small collection of PGP functions that are widely used in libretroshare.
* This interface class allows these functions to be easily mocked for testing.
@ -40,6 +41,9 @@ class PgpAuxUtils
virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const =0;
virtual bool VerifySignBin(const void *data, uint32_t len, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint) = 0;
/** @deprecated this method depends on retroshare-gui to work */
RS_DEPRECATED_FOR("AuthGPG::SignDataBin")
virtual bool askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result, std::string reason) = 0;
};

View File

@ -908,12 +908,14 @@ bool PGPHandler::checkAndImportKeyPair(ops_keyring_t *tmp_keyring, RsPgpId &impo
return false ;
}
if(pubkey == NULL || seckey == NULL || pubkey == seckey)
if(pubkey == nullptr || seckey == nullptr || pubkey == seckey)
{
import_error = "File does not contain a public and a private key. Sorry." ;
return false ;
}
if(memcmp(pubkey->fingerprint.fingerprint,seckey->fingerprint.fingerprint,PGP_KEY_FINGERPRINT_SIZE) != 0)
if(memcmp( pubkey->fingerprint.fingerprint,
seckey->fingerprint.fingerprint,
RsPgpFingerprint::SIZE_IN_BYTES ) != 0)
{
import_error = "Public and private keys do nt have the same fingerprint. Sorry!" ;
return false ;
@ -940,7 +942,10 @@ bool PGPHandler::checkAndImportKeyPair(ops_keyring_t *tmp_keyring, RsPgpId &impo
bool found = false ;
for(uint32_t i=0;i<result->valid_count;++i)
if(!memcmp((unsigned char*)result->valid_sigs[i].signer_id,pubkey->key_id,PGP_KEY_ID_SIZE))
if(!memcmp(
static_cast<uint8_t*>(result->valid_sigs[i].signer_id),
pubkey->key_id,
RsPgpId::SIZE_IN_BYTES ))
{
found = true ;
break ;
@ -1032,7 +1037,17 @@ void PGPHandler::addNewKeyToOPSKeyring(ops_keyring_t *kr,const ops_keydata_t& ke
kr->nkeys++ ;
}
bool PGPHandler::LoadCertificateFromBinaryData(const unsigned char *data,uint32_t data_len,RsPgpId& id,std::string& error_string)
{
return LoadCertificate(data,data_len,ops_false,id,error_string);
}
bool PGPHandler::LoadCertificateFromString(const std::string& pgp_cert,RsPgpId& id,std::string& error_string)
{
return LoadCertificate((unsigned char*)(pgp_cert.c_str()),pgp_cert.length(),ops_true,id,error_string);
}
bool PGPHandler::LoadCertificate(const unsigned char *data,uint32_t data_len,bool armoured,RsPgpId& id,std::string& error_string)
{
RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures.
#ifdef DEBUG_PGPHANDLER
@ -1041,9 +1056,9 @@ bool PGPHandler::LoadCertificateFromString(const std::string& pgp_cert,RsPgpId&
ops_keyring_t *tmp_keyring = allocateOPSKeyring();
ops_memory_t *mem = ops_memory_new() ;
ops_memory_add(mem,(unsigned char *)pgp_cert.c_str(),pgp_cert.length()) ;
ops_memory_add(mem,data,data_len) ;
if(!ops_keyring_read_from_mem(tmp_keyring,ops_true,mem))
if(!ops_keyring_read_from_mem(tmp_keyring,armoured,mem))
{
ops_keyring_free(tmp_keyring) ;
free(tmp_keyring) ;
@ -1087,7 +1102,10 @@ bool PGPHandler::LoadCertificateFromString(const std::string& pgp_cert,RsPgpId&
bool found = false ;
for(uint32_t i=0;i<result->valid_count;++i)
if(!memcmp((unsigned char*)result->valid_sigs[i].signer_id,keydata->key_id,PGP_KEY_ID_SIZE))
if(!memcmp(
static_cast<uint8_t*>(result->valid_sigs[i].signer_id),
keydata->key_id,
RsPgpId::SIZE_IN_BYTES ))
{
found = true ;
break ;
@ -1164,7 +1182,9 @@ bool PGPHandler::locked_addOrMergeKey(ops_keyring_t *keyring,std::map<RsPgpId,PG
}
else
{
if(memcmp(existing_key->fingerprint.fingerprint, keydata->fingerprint.fingerprint,PGP_KEY_FINGERPRINT_SIZE))
if(memcmp( existing_key->fingerprint.fingerprint,
keydata->fingerprint.fingerprint,
RsPgpFingerprint::SIZE_IN_BYTES ))
{
std::cerr << "(EE) attempt to merge key with identical id, but different fingerprint!" << std::endl;
return false ;
@ -1187,37 +1207,7 @@ bool PGPHandler::locked_addOrMergeKey(ops_keyring_t *keyring,std::map<RsPgpId,PG
return ret ;
}
// bool PGPHandler::encryptTextToString(const RsPgpId& key_id,const std::string& text,std::string& outstring)
// {
// RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures.
//
// const ops_keydata_t *public_key = getPublicKey(key_id) ;
//
// if(public_key == NULL)
// {
// std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl;
// return false ;
// }
//
// if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY)
// {
// std::cerr << "PGPHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl;
// return false ;
// }
//
// ops_create_info_t *info;
// ops_memory_t *buf = NULL ;
// ops_setup_memory_write(&info, &buf, 0);
//
// ops_encrypt_stream(info, public_key, NULL, ops_false, ops_true);
// ops_write(text.c_str(), text.length(), info);
// ops_writer_close(info);
//
// outstring = std::string((char *)ops_memory_get_data(buf),ops_memory_get_length(buf)) ;
// ops_create_info_delete(info);
//
// return true ;
// }
bool PGPHandler::encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile)
{
RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures.
@ -1591,6 +1581,11 @@ void PGPHandler::locked_updateOwnSignatureFlag(PGPCertificateInfo& cert,const Rs
cert._flags &= ~PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_SIGNED_ME ;
}
RsPgpId PGPHandler::pgpIdFromFingerprint(const PGPFingerprintType& f)
{
return RsPgpId(f.toByteArray() + _RsIdSize::PGP_FINGERPRINT - _RsIdSize::PGP_ID);
}
bool PGPHandler::getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const
{
RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures.
@ -1792,7 +1787,8 @@ bool PGPHandler::privateTrustCertificate(const RsPgpId& id,int trustlvl)
struct PrivateTrustPacket
{
unsigned char user_id[PGP_KEY_ID_SIZE] ; // pgp id in unsigned char format.
/// pgp id in unsigned char format.
unsigned char user_id[RsPgpId::SIZE_IN_BYTES];
uint8_t trust_level ; // trust level. From 0 to 6.
uint32_t time_stamp ; // last time the cert was ever used, in seconds since the epoch. 0 means not initialized.
};
@ -1854,9 +1850,12 @@ bool PGPHandler::locked_writePrivateTrustDatabase()
}
PrivateTrustPacket trustpacket ;
for(std::map<RsPgpId,PGPCertificateInfo>::iterator it = _public_keyring_map.begin();it!=_public_keyring_map.end() ;++it)
for( std::map<RsPgpId,PGPCertificateInfo>::iterator it =
_public_keyring_map.begin(); it!=_public_keyring_map.end(); ++it )
{
memcpy(trustpacket.user_id,RsPgpId(it->first).toByteArray(),PGP_KEY_ID_SIZE) ;
memcpy( trustpacket.user_id,
it->first.toByteArray(),
RsPgpId::SIZE_IN_BYTES );
trustpacket.trust_level = it->second._trustLvl ;
trustpacket.time_stamp = it->second._time_stamp ;
@ -2115,4 +2114,3 @@ bool PGPHandler::removeKeysFromPGPKeyring(const std::set<RsPgpId>& keys_to_remov
return true ;
}

View File

@ -21,10 +21,6 @@
*******************************************************************************/
#pragma once
#pragma once
// This class implements an abstract pgp handler to be used in RetroShare.
//
#include <stdint.h>
#include <string>
#include <list>
@ -80,6 +76,7 @@ class PGPCertificateInfo
static const uint8_t PGP_CERTIFICATE_TYPE_RSA = 0x02 ;
};
/// This class offer an abstract pgp handler to be used in RetroShare.
class PGPHandler
{
public:
@ -107,6 +104,7 @@ class PGPHandler
bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) ;
bool LoadCertificateFromString(const std::string& pem, RsPgpId& gpg_id, std::string& error_string);
bool LoadCertificateFromBinaryData(const unsigned char *bin_data,uint32_t bin_data_len, RsPgpId& gpg_id, std::string& error_string);
std::string SaveCertificateToString(const RsPgpId& id,bool include_signatures) const ;
bool exportPublicKey(const RsPgpId& id,unsigned char *& mem,size_t& mem_size,bool armoured,bool include_signatures) const ;
@ -125,8 +123,6 @@ class PGPHandler
bool encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile) ;
bool decryptTextFromFile(const RsPgpId& key_id,std::string& text,const std::string& encrypted_inputfile) ;
//bool encryptTextToString(const RsPgpId& key_id,const std::string& text,std::string& outstring) ;
//bool decryptTextFromString(const RsPgpId& key_id,const std::string& encrypted_text,std::string& outstring) ;
bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const ;
void setAcceptConnexion(const RsPgpId&,bool) ;
@ -158,6 +154,7 @@ class PGPHandler
static void setPassphraseCallback(PassphraseCallback cb) ;
static PassphraseCallback passphraseCallback() { return _passphrase_callback ; }
static RsPgpId pgpIdFromFingerprint(const PGPFingerprintType& f) ;
// Gets info about the key. Who are the signers, what's the owner's name, etc.
//
@ -176,6 +173,7 @@ class PGPHandler
bool syncDatabase() ;
private:
bool LoadCertificate(const unsigned char *bin_data,uint32_t bin_data_len, bool armoured, RsPgpId& gpg_id, std::string& error_string);
void initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t i) ;
// Returns true if the signatures have been updated
@ -232,4 +230,3 @@ class PGPHandler
static PassphraseCallback _passphrase_callback ;
static bool mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src) ; // returns true if signature lists are different
};

View File

@ -3,8 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2016 Cyril Soler <csoler@users.sourceforge.net> *
* Copyright 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2016 Cyril Soler <csoler@users.sourceforge.net> *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -31,6 +31,7 @@
#include "rscertificate.h"
#include "util/rsstring.h"
#include "util/stacktrace.h"
#include "util/rsdebug.h"
//#define DEBUG_RSCERTIFICATE
@ -55,6 +56,7 @@ static bool is_acceptable_radix64Char(char c)
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '+' || c == '/' || c == '=' ;
}
RsCertificate::~RsCertificate()
{
delete[] binary_pgp_key ;
@ -166,28 +168,16 @@ std::string RsCertificate::toStdString() const
return out2 ;
}
RsCertificate::RsCertificate(const std::string& str) :
location_name(""), pgp_version("Version: OpenPGP:SDK v0.9"),
dns_name(""), only_pgp(true)
{
uint32_t err_code;
binary_pgp_key = nullptr;
if(!initializeFromString(str, err_code))
{
std::cerr << __PRETTY_FUNCTION__ << " is deprecated because it can "
<< "miserably fail like this! str: " << str
<< " err_code: " << err_code << std::endl;
print_stacktrace();
throw err_code;
}
}
RsCertificate::RsCertificate(const RsPeerDetails& Detail, const unsigned char *binary_pgp_block,size_t binary_pgp_block_size)
:pgp_version("Version: OpenPGP:SDK v0.9")
{
if(binary_pgp_block_size == 0 || binary_pgp_block == NULL)
throw std::runtime_error("Cannot init a certificate with a void key block.") ;
if(binary_pgp_block_size == 0 || binary_pgp_block == nullptr)
{
RsErr() << __PRETTY_FUNCTION__ << " is deprecated because it can "
<< "miserably fail like this! " << std::endl;
print_stacktrace();
throw std::runtime_error("Cannot init a certificate with a void key block.");
}
binary_pgp_key = new unsigned char[binary_pgp_block_size] ;
memcpy(binary_pgp_key,binary_pgp_block,binary_pgp_block_size) ;
@ -256,6 +246,91 @@ RsCertificate::RsCertificate(const RsPeerDetails& Detail, const unsigned char *b
}
}
/*static*/ std::unique_ptr<RsCertificate> RsCertificate::fromMemoryBlock(
const RsPeerDetails& details, const uint8_t* binary_pgp_block,
size_t binary_pgp_block_size )
{
if(binary_pgp_block_size == 0 || binary_pgp_block == nullptr)
{
RsErr() << __PRETTY_FUNCTION__ << " invalid parameters! " << std::endl;
print_stacktrace();
return nullptr;
}
std::unique_ptr<RsCertificate> crt(new RsCertificate);
crt->binary_pgp_key = new uint8_t[binary_pgp_block_size];
memcpy(crt->binary_pgp_key, binary_pgp_block, binary_pgp_block_size);
crt->binary_pgp_key_size = binary_pgp_block_size;
if(!details.isOnlyGPGdetail)
{
crt->only_pgp = false;
crt->location_id = RsPeerId(details.id);
crt->location_name = details.location;
if (details.isHiddenNode)
{
crt->hidden_node = true;
crt->hidden_node_address = details.hiddenNodeAddress;
rs_sprintf_append(
crt->hidden_node_address, ":%u", details.hiddenNodePort);
memset(crt->ipv4_internal_ip_and_port, 0, 6);
memset(crt->ipv4_external_ip_and_port, 0, 6);
crt->dns_name = "";
}
else
{
crt->hidden_node = false;
crt->hidden_node_address = "";
try
{
scan_ip( details.localAddr, details.localPort,
crt->ipv4_internal_ip_and_port );
}
catch(...)
{
RsErr() << __PRETTY_FUNCTION__ << " Invalid LocalAddress: "
<< details.localAddr << std::endl;
memset(crt->ipv4_internal_ip_and_port, 0, 6);
}
try
{
scan_ip( details.extAddr, details.extPort,
crt->ipv4_external_ip_and_port );
}
catch(...)
{
RsErr() << __PRETTY_FUNCTION__ << " Invalid ExternalAddress: "
<< details.extAddr << std::endl;
memset(crt->ipv4_external_ip_and_port, 0, 6);
}
crt->dns_name = details.dyndns;
for(auto&& ipr : details.ipAddressList)
crt->mLocators.insert(RsUrl(ipr.substr(0, ipr.find(' '))));
}
}
else
{
crt->only_pgp = true;
crt->hidden_node = false;
crt->hidden_node_address = "";
crt->location_id = RsPeerId();
crt->location_name = "";
memset(crt->ipv4_internal_ip_and_port, 0, 6);
memset(crt->ipv4_external_ip_and_port, 0, 6);
crt->dns_name = "";
}
return crt; // Implicit move semantic
}
void RsCertificate::scan_ip(const std::string& ip_string, unsigned short port,unsigned char *ip_and_port)
{
int d0,d1,d2,d3 ;
@ -272,165 +347,174 @@ void RsCertificate::scan_ip(const std::string& ip_string, unsigned short port,un
ip_and_port[5] = port & 0xff ;
}
bool RsCertificate::initializeFromString(const std::string& instr,uint32_t& err_code)
/*static*/ std::unique_ptr<RsCertificate> RsCertificate::fromString(
const std::string& instr, uint32_t& err_code )
{
try
Dbg3() << __PRETTY_FUNCTION__ << std::endl;
std::unique_ptr<RsCertificate> crt(new RsCertificate);
std::string str;
err_code = CERTIFICATE_PARSING_ERROR_NO_ERROR;
// 0 - clean the string and check that it is pure radix64
for(uint32_t i=0;i<instr.length();++i)
{
std::string str ;
err_code = CERTIFICATE_PARSING_ERROR_NO_ERROR ;
if(instr[i] == ' ' || instr[i] == '\t' || instr[i] == '\n')
continue;
// 0 - clean the string and check that it is pure radix64
//
for(uint32_t i=0;i<instr.length();++i)
{
if(instr[i] == ' ' || instr[i] == '\t' || instr[i] == '\n')
continue ;
if(! is_acceptable_radix64Char(instr[i]))
return nullptr;
if(! is_acceptable_radix64Char(instr[i]))
return false ;
str += instr[i] ;
}
#ifdef DEBUG_RSCERTIFICATE
std::cerr << "Decoding from:" << str << std::endl;
#endif
// 1 - decode the string.
//
std::vector<uint8_t> bf = Radix64::decode(str) ;
size_t size = bf.size();
bool checksum_check_passed = false;
unsigned char *buf = bf.data();
size_t total_s = 0;
only_pgp = true;
uint8_t certificate_version = 0x00;
while(total_s < size)
{
uint8_t ptag = buf[0];
buf = &buf[1];
unsigned char *buf2 = buf;
uint32_t s = PGPKeyParser::read_125Size(buf);
total_s += 1 + ((size_t)buf-(size_t)buf2) ;
if(total_s > size)
{
err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR ;
return false ;
}
#ifdef DEBUG_RSCERTIFICATE
std::cerr << "Packet parse: read ptag " << (int)ptag << ", size " << s << ", total_s = " << total_s << ", expected total = " << size << std::endl;
#endif
switch(ptag)
{
case CERTIFICATE_PTAG_VERSION_SECTION:
certificate_version = buf[0];
break;
case CERTIFICATE_PTAG_PGP_SECTION:
binary_pgp_key = new unsigned char[s];
memcpy(binary_pgp_key,buf,s);
binary_pgp_key_size = s;
break;
case CERTIFICATE_PTAG_NAME_SECTION:
location_name = std::string((char *)buf,s);
break;
case CERTIFICATE_PTAG_SSLID_SECTION:
if(s != location_id.SIZE_IN_BYTES)
{
err_code = CERTIFICATE_PARSING_ERROR_INVALID_LOCATION_ID;
return false;
}
location_id = RsPeerId(buf);
only_pgp = false;
break;
case CERTIFICATE_PTAG_DNS_SECTION:
dns_name = std::string((char *)buf,s);
break;
case CERTIFICATE_PTAG_HIDDENNODE_SECTION:
hidden_node_address = std::string((char *)buf,s);
hidden_node = true;
break;
case CERTIFICATE_PTAG_LOCIPANDPORT_SECTION:
if(s != 6)
{
err_code = CERTIFICATE_PARSING_ERROR_INVALID_LOCAL_IP;
return false;
}
memcpy(ipv4_internal_ip_and_port,buf,s);
break;
case CERTIFICATE_PTAG_EXTIPANDPORT_SECTION:
if(s != 6)
{
err_code = CERTIFICATE_PARSING_ERROR_INVALID_EXTERNAL_IP;
return false;
}
memcpy(ipv4_external_ip_and_port,buf,s);
break;
case CERTIFICATE_PTAG_CHECKSUM_SECTION:
{
if(s != 3 || total_s+3 != size)
{
err_code =
CERTIFICATE_PARSING_ERROR_INVALID_CHECKSUM_SECTION;
return false;
}
uint32_t computed_crc =
PGPKeyManagement::compute24bitsCRC(bf.data(),size-5);
uint32_t certificate_crc =
buf[0] + (buf[1] << 8) + (buf[2] << 16);
if(computed_crc != certificate_crc)
{
err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR;
return false;
}
else checksum_check_passed = true;
break;
}
case CERTIFICATE_PTAG_EXTRA_LOCATOR:
mLocators.insert(RsUrl(std::string((char *)buf, s)));
break;
default:
std::cerr << "(WW) unknwown PTAG 0x" << std::hex << ptag
<< std::dec << " in certificate! Ignoring it."
<< std::endl;
break;
}
buf = &buf[s];
total_s += s ;
}
if(!checksum_check_passed)
{
err_code = CERTIFICATE_PARSING_ERROR_MISSING_CHECKSUM ;
return false ;
}
if(certificate_version != CERTIFICATE_VERSION_06)
{
err_code = CERTIFICATE_PARSING_ERROR_WRONG_VERSION ;
return false ;
}
#ifdef DEBUG_RSCERTIFICATE
std::cerr << "Certificate is version " << (int)certificate_version << std::endl;
#endif
if(total_s != size)
std::cerr << "(EE) Certificate contains trailing characters. Weird." << std::endl;
return true ;
str += instr[i];
}
catch(std::exception& e)
Dbg4() << __PRETTY_FUNCTION__ << " Decoding from: " << str << std::endl;
// 1 - decode the string.
std::vector<uint8_t> bf = Radix64::decode(str);
size_t size = bf.size();
bool checksum_check_passed = false;
unsigned char* buf = bf.data();
size_t total_s = 0;
crt->only_pgp = true;
uint8_t certificate_version = 0x00;
while(total_s < size)
{
if(binary_pgp_key != NULL)
delete[] binary_pgp_key ;
uint8_t ptag = buf[0];
buf = &buf[1];
err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR ;
return false ;
unsigned char *buf2 = buf;
uint32_t s = 0;
try { s = PGPKeyParser::read_125Size(buf); }
catch (...)
{
err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR;
return nullptr;
}
total_s += 1 + (
reinterpret_cast<size_t>(buf) -
reinterpret_cast<size_t>(buf2) );
if(total_s > size)
{
err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR;
return nullptr;
}
Dbg3() << __PRETTY_FUNCTION__ << " Read ptag: "
<< static_cast<uint32_t>(ptag)
<< ", size " << s << ", total_s = " << total_s
<< ", expected total = " << size << std::endl;
switch(ptag)
{
case CERTIFICATE_PTAG_VERSION_SECTION:
certificate_version = buf[0];
break;
case CERTIFICATE_PTAG_PGP_SECTION:
crt->binary_pgp_key = new unsigned char[s];
memcpy(crt->binary_pgp_key, buf, s);
crt->binary_pgp_key_size = s;
break;
case CERTIFICATE_PTAG_NAME_SECTION:
crt->location_name =
std::string(reinterpret_cast<char*>(buf), s);
break;
case CERTIFICATE_PTAG_SSLID_SECTION:
if(s != crt->location_id.SIZE_IN_BYTES)
{
err_code = CERTIFICATE_PARSING_ERROR_INVALID_LOCATION_ID;
return nullptr;
}
// We just checked buffer size so next line is not unsafe
crt->location_id = RsPeerId::fromBufferUnsafe(buf);
crt->only_pgp = false;
break;
case CERTIFICATE_PTAG_DNS_SECTION:
crt->dns_name = std::string(reinterpret_cast<char*>(buf), s);
break;
case CERTIFICATE_PTAG_HIDDENNODE_SECTION:
crt->hidden_node_address =
std::string(reinterpret_cast<char*>(buf),s);
crt->hidden_node = true;
break;
case CERTIFICATE_PTAG_LOCIPANDPORT_SECTION:
if(s != 6)
{
err_code = CERTIFICATE_PARSING_ERROR_INVALID_LOCAL_IP;
return nullptr;
}
memcpy(crt->ipv4_internal_ip_and_port, buf, s);
break;
case CERTIFICATE_PTAG_EXTIPANDPORT_SECTION:
if(s != 6)
{
err_code = CERTIFICATE_PARSING_ERROR_INVALID_EXTERNAL_IP;
return nullptr;
}
memcpy(crt->ipv4_external_ip_and_port, buf, s);
break;
case CERTIFICATE_PTAG_CHECKSUM_SECTION:
{
if(s != 3 || total_s+3 != size)
{
err_code =
CERTIFICATE_PARSING_ERROR_INVALID_CHECKSUM_SECTION;
return nullptr;
}
uint32_t computed_crc =
PGPKeyManagement::compute24bitsCRC(bf.data(),size-5);
uint32_t certificate_crc = static_cast<uint32_t>(
buf[0] + (buf[1] << 8) + (buf[2] << 16) );
if(computed_crc != certificate_crc)
{
err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR;
return nullptr;
}
else checksum_check_passed = true;
break;
}
case CERTIFICATE_PTAG_EXTRA_LOCATOR:
crt->mLocators.insert(
RsUrl(std::string(reinterpret_cast<char*>(buf), s)));
break;
default:
RsWarn() << __PRETTY_FUNCTION__ << " unknwown ptag: "
<< static_cast<uint32_t>(ptag)
<< " in certificate! Ignoring it." << std::endl;
break;
}
buf = &buf[s];
total_s += s;
}
if(!checksum_check_passed)
{
err_code = CERTIFICATE_PARSING_ERROR_MISSING_CHECKSUM;
return nullptr;
}
if(certificate_version != CERTIFICATE_VERSION_06)
{
err_code = CERTIFICATE_PARSING_ERROR_WRONG_VERSION;
return nullptr;
}
Dbg3() << __PRETTY_FUNCTION__ << " Certificate version: "
<< static_cast<uint32_t>(certificate_version) << std::endl;
if(total_s != size)
RsWarn() << __PRETTY_FUNCTION__ << " Certificate contains trailing "
<< "characters. Weird." << std::endl;
return crt; // Implicit move semantic
}
std::string RsCertificate::hidden_node_string() const
@ -450,6 +534,7 @@ std::string RsCertificate::ext_ip_string() const
os << (int)ipv4_external_ip_and_port[0] << "." << (int)ipv4_external_ip_and_port[1] << "." << (int)ipv4_external_ip_and_port[2] << "." << (int)ipv4_external_ip_and_port[3] ;
return os.str() ;
}
std::string RsCertificate::loc_ip_string() const
{
std::ostringstream os ;
@ -467,28 +552,29 @@ unsigned short RsCertificate::loc_port_us() const
return (int)ipv4_internal_ip_and_port[4]*256 + (int)ipv4_internal_ip_and_port[5] ;
}
bool RsCertificate::cleanCertificate(const std::string& input,std::string& output,Format& format,int& error_code,bool check_content)
bool RsCertificate::cleanCertificate( const std::string& input, std::string& output, Format& format, uint32_t& error_code, bool check_content )
{
if(cleanCertificate(input,output,error_code))
if(cleanRadix64(input,output,error_code))
{
format = RS_CERTIFICATE_RADIX ;
RsPeerDetails details;
if(!check_content)
return true ;
if(rsPeers->parseShortInvite(output,details,error_code))
{
format = RS_CERTIFICATE_SHORT_RADIX;
return true;
}
try
{
RsCertificate c(input) ;
return true ;
}
catch(uint32_t err_code)
{
error_code = err_code ;
return false;
}
format = RS_CERTIFICATE_RADIX;
if(!check_content) return true;
uint32_t errCode;
auto crt = RsCertificate::fromString(input, errCode);
error_code = static_cast<int>(errCode);
return crt != nullptr;
}
return false ;
return false;
}
std::string RsCertificate::armouredPGPKey() const
@ -498,7 +584,7 @@ std::string RsCertificate::armouredPGPKey() const
// Yeah, this is simple, and that is what's good about the radix format. Can't be broken ;-)
//
bool RsCertificate::cleanCertificate(const std::string& instr,std::string& str,int& error_code)
bool RsCertificate::cleanRadix64(const std::string& instr,std::string& str,uint32_t& error_code)
{
error_code = RS_PEER_CERT_CLEANING_CODE_NO_ERROR ;

View File

@ -3,7 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2016 Cyril Soler <csoler@users.sourceforge.net> *
* Copyright (C) 2016 Cyril Soler <csoler@users.sourceforge.net> *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -23,42 +24,45 @@
#include "retroshare/rstypes.h"
#include "util/rsurl.h"
#include "util/rsmemory.h"
#include "util/rsdebug.h"
#include <set>
#include <string>
#include <memory>
struct RsPeerDetails;
class RsCertificate
{
public:
typedef enum { RS_CERTIFICATE_OLD_FORMAT, RS_CERTIFICATE_RADIX } Format;
typedef enum { RS_CERTIFICATE_OLD_FORMAT, RS_CERTIFICATE_RADIX, RS_CERTIFICATE_SHORT_RADIX } Format;
/**
* @brief Costruct an empty certificate, use toghether with
* if(initializeFromString) for safe certificate radix string parsing
* @brief Create certificate object from certificate string
* @param[in] str radix format certificate string
* @param[out] errorCode Optional storage for eventual error code,
* meaningful only on failure
* @return nullptr on failure, pointer to the generated certificate
* otherwise
*/
RsCertificate() :
ipv4_external_ip_and_port{0,0,0,0,0,0},
ipv4_internal_ip_and_port{0,0,0,0,0,0},
binary_pgp_key(nullptr), binary_pgp_key_size(0),
pgp_version("Version: OpenPGP:SDK v0.9"), only_pgp(true),
hidden_node(false) {}
static std::unique_ptr<RsCertificate> fromString(
const std::string& str,
uint32_t& errorCode = RS_DEFAULT_STORAGE_PARAM(uint32_t) );
/**
* @brief Initialize from certificate string
* @param[in] str radix format string
* @param[out] errCode storage for eventual error code
* @return false on failure, true otherwise
* @brief Create certificate object from peer details and PGP memory block
* @param[in] details peer details
* @param[in] binary_pgp_block pointer to PGP memory block
* @param[in] binary_pgp_block_size size of PGP memory block
* @return nullptr on failure, pointer to the generated certificate
* otherwise
*/
bool initializeFromString(const std::string& str, uint32_t& errCode);
static std::unique_ptr<RsCertificate> fromMemoryBlock(
const RsPeerDetails& details, const uint8_t* binary_pgp_block,
size_t binary_pgp_block_size );
/// Constructs from binary gpg key, and RsPeerDetails.
RsCertificate( const RsPeerDetails& details,
const unsigned char *gpg_mem_block,
size_t gpg_mem_block_size );
virtual ~RsCertificate();
~RsCertificate();
/// Convert to certificate radix string
std::string toStdString() const;
@ -80,21 +84,22 @@ public:
static bool cleanCertificate(
const std::string& input, std::string& output,
RsCertificate::Format& format, int& error_code, bool check_content);
RsCertificate::Format& format, uint32_t& error_code, bool check_content);
const std::set<RsUrl>& locators() const { return mLocators; }
/**
* @deprecated using this costructor may raise exception that cause
* crash if not handled, use empty constructor + if(initFromString) for a
* safer behaviour.
* crash if not handled.
*/
RS_DEPRECATED explicit RsCertificate(const std::string& input_string);
RS_DEPRECATED_FOR("RsCertificate::fromMemoryBlock(...)")
RsCertificate( const RsPeerDetails& details,
const unsigned char *gpg_mem_block,
size_t gpg_mem_block_size );
private:
// new radix format
static bool cleanCertificate( const std::string& input,
std::string& output, int&);
static bool cleanRadix64(const std::string& input, std::string& output, uint32_t &);
static void scan_ip( const std::string& ip_string, unsigned short port,
unsigned char *destination_memory );
@ -105,6 +110,14 @@ private:
RsCertificate(const RsCertificate&) {} /// non copy-able
const RsCertificate& operator=(const RsCertificate&); /// non copy-able
/// @brief Costruct an empty certificate
RsCertificate() :
ipv4_external_ip_and_port{0,0,0,0,0,0},
ipv4_internal_ip_and_port{0,0,0,0,0,0},
binary_pgp_key(nullptr), binary_pgp_key_size(0),
pgp_version("Version: OpenPGP:SDK v0.9"), only_pgp(true),
hidden_node(false) {}
unsigned char ipv4_external_ip_and_port[6];
unsigned char ipv4_internal_ip_and_port[6];
@ -120,5 +133,7 @@ private:
bool only_pgp ; /// does the cert contain only pgp info?
bool hidden_node; /// IP or hidden Node Address.
RS_SET_CONTEXT_DEBUG_LEVEL(1)
};

View File

@ -534,6 +534,19 @@ bool AuthGPG::getGPGSignedList(std::list<RsPgpId> &ids)
return PGPHandler::SaveCertificateToString(id,include_signatures) ;
}
/* import to GnuPG and other Certificates */
bool AuthGPG::LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string)
{
RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/
if(PGPHandler::LoadCertificateFromBinaryData(data,data_len,gpg_id,error_string))
{
updateOwnSignatureFlag(gpg_id,mOwnGpgId) ;
return true ;
}
return false ;
}
/* import to GnuPG and other Certificates */
bool AuthGPG::LoadCertificateFromString(const std::string &str, RsPgpId& gpg_id,std::string& error_string)

View File

@ -172,6 +172,7 @@ public:
*
****/
virtual bool LoadCertificateFromString(const std::string &pem, RsPgpId& gpg_id,std::string& error_string);
virtual bool LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string);
virtual std::string SaveCertificateToString(const RsPgpId &id,bool include_signatures) ;
// Cached certificates.

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2004-2008 by Robert Fernie, Retroshare Team. *
* Copyright (C) 2004-2008 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -19,21 +20,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef MRK_AUTH_SSL_HEADER
#define MRK_AUTH_SSL_HEADER
#pragma once
/*
* This is an implementation of SSL certificate authentication, which is
* overloaded with pgp style signatures, and web-of-trust authentication.
*
* only the owner ssl cert is store, the rest is jeus callback verification
*
* To use as an SSL authentication system, you must use a common CA certificate.
* * The pqissl stuff doesn't need to differentiate between SSL, SSL + PGP,
* as its X509 certs.
* * The rsserver stuff has to distinguish between all three types ;(
*
*/
#include <openssl/evp.h>
#include <openssl/x509.h>
@ -42,197 +30,273 @@
#include <map>
#include "util/rsthreads.h"
#include "pqi/pqi_base.h"
#include "pqi/pqinetwork.h"
#include "pqi/p3cfgmgr.h"
#include "util/rsmemory.h"
#include "retroshare/rsevents.h"
/* This #define removes Connection Manager references in AuthSSL.
* They should not be here. What about Objects and orthogonality?
* This code is also stopping immediate reconnections from working.
/**
* Functions to interact elegantly with X509 certificates, using this functions
* you can avoid annoying #ifdef *SSL_VERSION_NUMBER all around the code.
* Function names should be self descriptive.
*/
class AuthSSL;
class sslcert
namespace RsX509Cert
{
public:
sslcert(X509* x509, const RsPeerId& id);
sslcert();
/* certificate parameters */
RsPeerId id;
std::string name;
std::string location;
std::string org;
std::string email;
RsPgpId issuer;
PGPFingerprintType fpr;
/* Auth settings */
bool authed;
/* INTERNAL Parameters */
X509* certificate;
std::string getCertName(const X509& x509);
std::string getCertLocation(const X509& x509);
std::string getCertOrg(const X509& x509);
RsPgpId getCertIssuer(const X509& x509);
std::string getCertIssuerString(const X509& x509);
RsPeerId getCertSslId(const X509& x509);
const EVP_PKEY* getPubKey(const X509& x509);
};
/* required to install instance */
/**
* Event triggered by AuthSSL when authentication of a connection attempt either
* fail or success
*/
struct RsAuthSslConnectionAutenticationEvent : RsEvent
{
RsAuthSslConnectionAutenticationEvent();
bool mSuccess;
RsPeerId mSslId;
std::string mSslCn;
RsPgpId mPgpId;
std::string mErrorMsg;
///* @see RsEvent @see RsSerializable
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override
{
RsEvent::serial_process(j, ctx);
RS_SERIAL_PROCESS(mSuccess);
RS_SERIAL_PROCESS(mSslId);
RS_SERIAL_PROCESS(mSslCn);
RS_SERIAL_PROCESS(mPgpId);
RS_SERIAL_PROCESS(mErrorMsg);
}
};
/**
* This is an implementation of SSL certificate authentication with PGP
* signatures, instead of centralized certification authority.
*/
class AuthSSL
{
public:
AuthSSL();
public:
static AuthSSL& instance();
static AuthSSL *getAuthSSL();
static void AuthSSLInit();
RS_DEPRECATED_FOR(AuthSSL::instance())
static AuthSSL* getAuthSSL();
/* Initialisation Functions (Unique) */
virtual bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey) = 0;
/* Initialisation Functions (Unique) */
virtual bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey) = 0;
virtual bool active() = 0;
virtual int InitAuth(const char *srvr_cert, const char *priv_key,
const char *passwd, std::string alternative_location_name) = 0;
virtual bool CloseAuth() = 0;
virtual bool active() = 0;
virtual int InitAuth(
const char* srvr_cert, const char* priv_key, const char* passwd,
std::string locationName ) = 0;
virtual bool CloseAuth() = 0;
/*********** Overloaded Functions from p3AuthMgr **********/
/* get Certificate Id */
virtual const RsPeerId& OwnId() = 0;
virtual std::string getOwnLocation() = 0;
/* get Certificate Id */
virtual const RsPeerId& OwnId() = 0;
virtual std::string getOwnLocation() = 0;
/* Load/Save certificates */
virtual std::string SaveOwnCertificateToString() = 0;
virtual std::string SaveOwnCertificateToString() = 0;
/* Sign / Encrypt / Verify Data */
virtual bool SignData(std::string input, std::string &sign) = 0;
virtual bool SignData(const void *data, const uint32_t len, std::string &sign) = 0;
virtual bool SignData(std::string input, std::string &sign) = 0;
virtual bool SignData(
const void* data, const uint32_t len, std::string& sign ) = 0;
virtual bool SignDataBin(std::string, unsigned char*, unsigned int*) = 0;
virtual bool SignDataBin(const void*, uint32_t, unsigned char*, unsigned int*) = 0;
virtual bool VerifyOwnSignBin(const void*, uint32_t, unsigned char*, unsigned int) = 0;
virtual bool VerifySignBin(const void *data, const uint32_t len,
unsigned char *sign, unsigned int signlen, const RsPeerId& sslId) = 0;
virtual bool SignDataBin(std::string, unsigned char*, unsigned int*) = 0;
virtual bool SignDataBin(
const void*, uint32_t, unsigned char*, unsigned int* ) = 0;
virtual bool VerifyOwnSignBin(
const void*, uint32_t, unsigned char*, unsigned int ) = 0;
virtual bool VerifySignBin(
const void* data, const uint32_t len, unsigned char* sign,
unsigned int signlen, const RsPeerId& sslId ) = 0;
// return : false if encrypt failed
virtual bool encrypt(void *&out, int &outlen, const void *in, int inlen, const RsPeerId& peerId) = 0;
// return : false if decrypt fails
virtual bool decrypt(void *&out, int &outlen, const void *in, int inlen) = 0;
/// return false if failed
virtual bool encrypt(
void*& out, int& outlen, const void* in, int inlen,
const RsPeerId& peerId ) = 0;
/// return false if failed
virtual bool decrypt(void*& out, int& outlen, const void* in, int inlen) = 0;
virtual X509* SignX509ReqWithGPG(X509_REQ* req, long days) = 0;
/**
* @brief Verify PGP signature correcteness on given X509 certificate
* Beware this doesn't check if the PGP signer is friend or not, just if the
* signature is valid!
* @param[in] x509 pointer ti the X509 certificate to check
* @param[out] diagnostic one of RS_SSL_HANDSHAKE_DIAGNOSTIC_* diagnostic
* codes
* @param[in] verbose if true, prints the authentication result to screen.
* @return true if correctly signed, false otherwise
*/
virtual bool AuthX509WithGPG(
X509* x509,
bool verbose,
uint32_t& diagnostic = RS_DEFAULT_STORAGE_PARAM(uint32_t)
) = 0;
/**
* @brief Callback provided to OpenSSL to authenticate connections
* This is the ultimate place where connection attempts get accepted
* if authenticated or refused if not authenticated.
* Emits @see RsAuthSslConnectionAutenticationEvent.
* @param preverify_ok passed by OpenSSL ignored as this call is the first
* in the authentication callback chain
* @param ctx OpenSSL connection context
* @return 0 if authentication failed, 1 if success see OpenSSL
* documentation
*/
virtual int VerifyX509Callback(int preverify_ok, X509_STORE_CTX* ctx) = 0;
/// SSL specific functions used in pqissl/pqissllistener
virtual SSL_CTX* getCTX() = 0;
virtual void setCurrentConnectionAttemptInfo(
const RsPgpId& gpg_id, const RsPeerId& ssl_id,
const std::string& ssl_cn ) = 0;
virtual void getCurrentConnectionAttemptInfo(
RsPgpId& gpg_id, RsPeerId& ssl_id, std::string& ssl_cn ) = 0;
virtual X509* SignX509ReqWithGPG(X509_REQ *req, long days) = 0;
virtual bool AuthX509WithGPG(X509 *x509,uint32_t& auth_diagnostic)=0;
/**
* This function parse X509 certificate from the file and return some
* verified informations, like ID and signer
* @return false on error, true otherwise
*/
virtual bool parseX509DetailsFromFile(
const std::string& certFilePath, RsPeerId& certId, RsPgpId& issuer,
std::string& location ) = 0;
virtual ~AuthSSL();
virtual int VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx) = 0;
virtual bool ValidateCertificate(X509 *x509, RsPeerId& peerId) = 0; /* validate + get id */
protected:
AuthSSL() {}
public: /* SSL specific functions used in pqissl/pqissllistener */
virtual SSL_CTX *getCTX() = 0;
/* Restored these functions: */
virtual void setCurrentConnectionAttemptInfo(const RsPgpId& gpg_id,const RsPeerId& ssl_id,const std::string& ssl_cn) = 0 ;
virtual void getCurrentConnectionAttemptInfo( RsPgpId& gpg_id, RsPeerId& ssl_id, std::string& ssl_cn) = 0 ;
virtual bool FailedCertificate(X509 *x509, const RsPgpId& gpgid,const RsPeerId& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming) = 0; /* store for discovery */
virtual bool CheckCertificate(const RsPeerId& peerId, X509 *x509) = 0; /* check that they are exact match */
static void setAuthSSL_debug(AuthSSL*) ; // used for debug only. The real function is InitSSL()
static AuthSSL *instance_ssl ;
RS_SET_CONTEXT_DEBUG_LEVEL(2)
};
class AuthSSLimpl : public AuthSSL, public p3Config
{
public:
public:
/* Initialisation Functions (Unique) */
/** Initialisation Functions (Unique) */
AuthSSLimpl();
bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey);
bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey) override;
virtual bool active();
virtual int InitAuth(const char *srvr_cert, const char *priv_key,
const char *passwd, std::string alternative_location_name);
virtual bool CloseAuth();
bool active() override;
int InitAuth( const char *srvr_cert, const char *priv_key,
const char *passwd, std::string locationName )
override;
bool CloseAuth() override;
/*********** Overloaded Functions from p3AuthMgr **********/
/* get Certificate Id */
virtual const RsPeerId& OwnId();
virtual std::string getOwnLocation();
const RsPeerId& OwnId() override;
virtual std::string getOwnLocation() override;
/* Load/Save certificates */
virtual std::string SaveOwnCertificateToString();
virtual std::string SaveOwnCertificateToString() override;
/* Sign / Encrypt / Verify Data */
virtual bool SignData(std::string input, std::string &sign);
virtual bool SignData(const void *data, const uint32_t len, std::string &sign);
bool SignData(std::string input, std::string &sign) override;
bool SignData(
const void *data, const uint32_t len, std::string &sign) override;
virtual bool SignDataBin(std::string, unsigned char*, unsigned int*);
virtual bool SignDataBin(const void*, uint32_t, unsigned char*, unsigned int*);
virtual bool VerifyOwnSignBin(const void*, uint32_t, unsigned char*, unsigned int);
virtual bool VerifySignBin(const void *data, const uint32_t len,
unsigned char *sign, unsigned int signlen, const RsPeerId& sslId);
bool SignDataBin(std::string, unsigned char*, unsigned int*) override;
virtual bool SignDataBin(
const void*, uint32_t, unsigned char*, unsigned int*) override;
bool VerifyOwnSignBin(
const void*, uint32_t, unsigned char*, unsigned int) override;
virtual bool VerifySignBin(
const void *data, const uint32_t len, unsigned char *sign,
unsigned int signlen, const RsPeerId& sslId) override;
// return : false if encrypt failed
virtual bool encrypt(void *&out, int &outlen, const void *in, int inlen, const RsPeerId& peerId);
// return : false if decrypt fails
virtual bool decrypt(void *&out, int &outlen, const void *in, int inlen);
bool encrypt(
void*& out, int& outlen, const void* in, int inlen,
const RsPeerId& peerId ) override;
bool decrypt(void *&out, int &outlen, const void *in, int inlen) override;
virtual X509* SignX509ReqWithGPG(X509_REQ *req, long days) override;
virtual X509* SignX509ReqWithGPG(X509_REQ *req, long days);
virtual bool AuthX509WithGPG(X509 *x509,uint32_t& auth_diagnostic);
/// @see AuthSSL
bool AuthX509WithGPG(X509 *x509, bool verbose, uint32_t& auth_diagnostic) override;
/// @see AuthSSL
int VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx) override;
virtual int VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx);
virtual bool ValidateCertificate(X509 *x509, RsPeerId& peerId); /* validate + get id */
/// @see AuthSSL
bool parseX509DetailsFromFile(
const std::string& certFilePath, RsPeerId& certId,
RsPgpId& issuer, std::string& location ) override;
/*****************************************************************/
/*********************** p3config ******************************/
/* Key Functions to be overloaded for Full Configuration */
virtual RsSerialiser *setupSerialiser();
virtual bool saveList(bool &cleanup, std::list<RsItem *>& );
virtual bool loadList(std::list<RsItem *>& load);
/* Key Functions to be overloaded for Full Configuration */
RsSerialiser* setupSerialiser() override;
bool saveList(bool &cleanup, std::list<RsItem *>& ) override;
bool loadList(std::list<RsItem *>& load) override;
/*****************************************************************/
public: /* SSL specific functions used in pqissl/pqissllistener */
virtual SSL_CTX *getCTX();
public:
/* SSL specific functions used in pqissl/pqissllistener */
SSL_CTX* getCTX() override;
/* Restored these functions: */
virtual void setCurrentConnectionAttemptInfo(const RsPgpId& gpg_id,const RsPeerId& ssl_id,const std::string& ssl_cn) ;
virtual void getCurrentConnectionAttemptInfo( RsPgpId& gpg_id, RsPeerId& ssl_id, std::string& ssl_cn) ;
virtual bool FailedCertificate(X509 *x509, const RsPgpId& gpgid,const RsPeerId& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming); /* store for discovery */
virtual bool CheckCertificate(const RsPeerId& peerId, X509 *x509); /* check that they are exact match */
/* Restored these functions: */
void setCurrentConnectionAttemptInfo(
const RsPgpId& gpg_id, const RsPeerId& ssl_id,
const std::string& ssl_cn ) override;
void getCurrentConnectionAttemptInfo(
RsPgpId& gpg_id, RsPeerId& ssl_id, std::string& ssl_cn ) override;
private:
private:
bool LocalStoreCert(X509* x509);
bool RemoveX509(const RsPeerId id);
bool LocalStoreCert(X509* x509);
bool RemoveX509(const RsPeerId id);
/*********** LOCKED Functions ******/
bool locked_FindCert(const RsPeerId& id, sslcert **cert);
bool locked_FindCert(const RsPeerId& id, X509** cert);
/* Data */
/* these variables are constants -> don't need to protect */
SSL_CTX *sslctx;
RsPeerId mOwnId;
sslcert *mOwnCert;
X509* mOwnCert;
RsMutex sslMtx; /* protects all below */
/**
* If the location name is included in SSL certificate it becomes a public
* information, because anyone able to open an SSL connection to the host is
* able to read it. To avoid that location name is now stored separately and
* and not included in the SSL certificate.
*/
std::string mOwnLocationName;
RsMutex sslMtx; /* protects all below */
EVP_PKEY *mOwnPrivateKey;
EVP_PKEY *mOwnPublicKey;
EVP_PKEY* mOwnPrivateKey;
EVP_PKEY* mOwnPublicKey;
int init;
std::map<RsPeerId, X509*> mCerts;
std::map<RsPeerId, sslcert *> mCerts;
RsPgpId _last_gpgid_to_connect ;
std::string _last_sslcn_to_connect ;
RsPeerId _last_sslid_to_connect ;
RsPgpId _last_gpgid_to_connect;
std::string _last_sslcn_to_connect;
RsPeerId _last_sslid_to_connect;
};
#endif // MRK_AUTH_SSL_HEADER

View File

@ -101,14 +101,20 @@ peerAddrInfo::peerAddrInfo()
}
peerConnectState::peerConnectState()
: connecttype(0),
lastavailable(0),
lastattempt(0),
name(""),
state(0), actions(0),
source(0),
inConnAttempt(0),
wasDeniedConnection(false), deniedTS(false), deniedInConnAttempt(false)
: dhtVisible(false),
connecttype(0),
actAsServer(false),
lastavailable(0),
lastattempt(0),
name(""),
state(0),
actions(0),
linkType(0),
source(0),
inConnAttempt(false),
wasDeniedConnection(false),
deniedTS(0),
deniedInConnAttempt(false)
{
}
@ -471,12 +477,24 @@ void p3LinkMgrIMPL::tickMonitors()
if (peer.actions & RS_PEER_CONNECTED)
{
p3Notify *notify = RsServer::notify();
if (notify)
{
// normally these two below should disappear: there's no notion of popup in libretroshare.
// all GUI-type display features should be chosen in NotifyQt.
notify->AddPopupMessage(RS_POPUP_CONNECT, peer.id.toStdString(),"", "Online: ");
notify->AddFeedItem(RS_FEED_ITEM_PEER_CONNECT, peer.id.toStdString());
notify->notifyPeerConnected(peer.id.toStdString());
}
}
if (peer.actions & RS_PEER_DISCONNECTED)
{
p3Notify *notify = RsServer::notify();
if (notify)
notify->notifyPeerDisconnected(peer.id.toStdString());
}
}
}
@ -1032,47 +1050,6 @@ bool p3LinkMgrIMPL::connectResult(const RsPeerId &id, bool success, bool isIncom
* From various sources
*/
// from pqissl, when a connection failed due to security
void p3LinkMgrIMPL::notifyDeniedConnection(const RsPgpId& gpgid,const RsPeerId& sslid,const std::string& sslcn,const struct sockaddr_storage &/*addr*/, bool incoming)
{
std::cerr << "p3LinkMgrIMPL::notifyDeniedConnection()";
std::cerr << " pgpid: " << gpgid;
std::cerr << " sslid: " << sslid;
std::cerr << " sslcn: " << sslcn;
std::cerr << std::endl;
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
std::map<RsPeerId, peerConnectState>::iterator it;
it = mFriendList.find(sslid);
if (it == mFriendList.end())
{
std::cerr << "p3LinkMgrIMPL::notifyDeniedConnection() of NON-FRIEND: " << sslid;
std::cerr << std::endl;
return;
}
it->second.wasDeniedConnection = true;
it->second.deniedTS = time(NULL);
if ((!incoming) && it->second.inConnAttempt)
{
it->second.deniedInConnAttempt = true;
it->second.deniedConnectionAttempt = it->second.currentConnAddrAttempt;
std::cerr << "p3LinkMgrIMPL::notifyDeniedConnection() Denied In Connection Attempt";
std::cerr << std::endl;
}
else
{
it->second.deniedInConnAttempt = false;
std::cerr << "p3LinkMgrIMPL::notifyDeniedConnection() Denied NOT In Connection Attempt";
std::cerr << std::endl;
}
return;
}
void p3LinkMgrIMPL::peerStatus(const RsPeerId& id, const pqiIpAddrSet &addrs,
uint32_t type, uint32_t flags, uint32_t source)
{
@ -1656,30 +1633,8 @@ bool p3LinkMgrIMPL::retryConnectTCP(const RsPeerId &id)
return false;
}
#define MAX_TCP_ADDR_AGE (3600 * 24 * 14) // two weeks in seconds.
bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const struct sockaddr_storage &addr, rstime_t age)
bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const sockaddr_storage& addr)
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr(";
std::cerr << sockaddr_storage_tostring(addr);
std::cerr << ", " << age << ")";
std::cerr << std::endl;
#endif
/*
* if it is old - quick rejection
*/
if (age > MAX_TCP_ADDR_AGE)
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() REJECTING - TOO OLD";
std::cerr << std::endl;
#endif
return false;
}
/* if invalid - quick rejection */
if ( ! sockaddr_storage_isValidNet(addr) )
{
@ -1726,7 +1681,7 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_SpecificAddress(peerConnectState *pee
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_SpecificAddresses()";
std::cerr << std::endl;
#endif
if (locked_CheckPotentialAddr(remoteAddr, 0))
if(locked_CheckPotentialAddr(remoteAddr))
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_SpecificAddresses() ";
@ -1757,7 +1712,7 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses(peerConnectState *pe
#endif
// Just push all the addresses onto the stack.
/* try "current addresses" first */
if (locked_CheckPotentialAddr(localAddr, 0))
if (locked_CheckPotentialAddr(localAddr))
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses() ";
@ -1778,7 +1733,7 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses(peerConnectState *pe
addAddressIfUnique(peer->connAddrs, pca, false);
}
if (locked_CheckPotentialAddr(serverAddr, 0))
if (locked_CheckPotentialAddr(serverAddr))
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses() ";
@ -1806,7 +1761,6 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses(peerConnectState
/* now try historical addresses */
/* try local addresses first */
std::list<pqiIpAddress>::const_iterator ait;
rstime_t now = time(NULL);
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses()";
@ -1814,7 +1768,7 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses(peerConnectState
#endif
for(ait = ipAddrs.mLocal.mAddrs.begin(); ait != ipAddrs.mLocal.mAddrs.end(); ++ait)
{
if (locked_CheckPotentialAddr(ait->mAddr, now - ait->mSeenTime))
if (locked_CheckPotentialAddr(ait->mAddr))
{
#ifdef LINKMGR_DEBUG
@ -1841,7 +1795,7 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses(peerConnectState
for(ait = ipAddrs.mExt.mAddrs.begin();
ait != ipAddrs.mExt.mAddrs.end(); ++ait)
{
if (locked_CheckPotentialAddr(ait->mAddr, now - ait->mSeenTime))
if (locked_CheckPotentialAddr(ait->mAddr))
{
#ifdef LINKMGR_DEBUG
@ -1898,7 +1852,7 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_AddDynDNS(peerConnectState *peer, std
pca.bandwidth = 0;
/* check address validity */
if (locked_CheckPotentialAddr(pca.addr, 0))
if (locked_CheckPotentialAddr(pca.addr))
{
addAddressIfUnique(peer->connAddrs, pca, true);
}
@ -1959,7 +1913,7 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_ProxyAddress(peerConnectState *peer,
pca.domain_port = domain_port;
/* check address validity */
if (locked_CheckPotentialAddr(pca.addr, 0))
if (locked_CheckPotentialAddr(pca.addr))
{
addAddressIfUnique(peer->connAddrs, pca, true);
}
@ -2207,11 +2161,10 @@ void p3LinkMgrIMPL::printPeerLists(std::ostream &out)
return;
}
bool p3LinkMgrIMPL::checkPotentialAddr(const sockaddr_storage &addr, rstime_t age)
bool p3LinkMgrIMPL::checkPotentialAddr(const sockaddr_storage& addr)
{
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
return locked_CheckPotentialAddr(addr,age) ;
RS_STACK_MUTEX(mLinkMtx);
return locked_CheckPotentialAddr(addr);
}

View File

@ -171,8 +171,6 @@ virtual bool connectAttempt(const RsPeerId &id, struct sockaddr_storage &raddr,
virtual bool connectResult(const RsPeerId &id, bool success, bool isIncomingConnection, uint32_t flags, const struct sockaddr_storage &remote_peer_address) = 0;
virtual bool retryConnect(const RsPeerId &id) = 0;
virtual void notifyDeniedConnection(const RsPgpId& gpgid,const RsPeerId& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming) = 0;
/* Network Addresses */
virtual bool setLocalAddress(const struct sockaddr_storage &addr) = 0;
virtual bool getLocalAddress(struct sockaddr_storage &addr) = 0;
@ -182,7 +180,7 @@ virtual bool getLocalAddress(struct sockaddr_storage &addr) = 0;
virtual void getFriendList(std::list<RsPeerId> &ssl_peers) = 0; // ONLY used by p3peers.cc USE p3PeerMgr instead.
virtual bool getFriendNetStatus(const RsPeerId &id, peerConnectState &state) = 0; // ONLY used by p3peers.cc
virtual bool checkPotentialAddr(const struct sockaddr_storage &addr, rstime_t age)=0;
virtual bool checkPotentialAddr(const sockaddr_storage& addr) = 0;
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
virtual int addFriend(const RsPeerId &ssl_id, bool isVisible) = 0;
@ -230,8 +228,6 @@ virtual bool connectAttempt(const RsPeerId &id, struct sockaddr_storage &raddr,
virtual bool connectResult(const RsPeerId &id, bool success, bool isIncomingConnection, uint32_t flags, const struct sockaddr_storage &remote_peer_address);
virtual bool retryConnect(const RsPeerId &id);
virtual void notifyDeniedConnection(const RsPgpId& gpgid,const RsPeerId& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming);
/* Network Addresses */
virtual bool setLocalAddress(const struct sockaddr_storage &addr);
virtual bool getLocalAddress(struct sockaddr_storage &addr);
@ -269,7 +265,8 @@ int removeFriend(const RsPeerId &ssl_id);
void printPeerLists(std::ostream &out);
virtual bool checkPotentialAddr(const struct sockaddr_storage &addr, rstime_t age);
virtual bool checkPotentialAddr(const sockaddr_storage& addr);
protected:
/* THESE CAN PROBABLY BE REMOVED */
//bool shutdown(); /* blocking shutdown call */
@ -302,7 +299,8 @@ void locked_ConnectAttempt_ProxyAddress(peerConnectState *peer, const uint32_t
bool locked_ConnectAttempt_Complete(peerConnectState *peer);
bool locked_CheckPotentialAddr(const struct sockaddr_storage &addr, rstime_t age);
bool locked_CheckPotentialAddr(const sockaddr_storage& addr);
bool addAddressIfUnique(std::list<peerConnectAddress> &addrList, peerConnectAddress &pca, bool pushFront);

View File

@ -217,6 +217,8 @@ void p3Notify::notifyChatLobbyEvent(uint64_t lobby_id, uint32_t event_type,const
void p3Notify::notifyListPreChange(int list, int type) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyListPreChange(list,type) ; }
void p3Notify::notifyListChange (int list, int type) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyListChange (list,type) ; }
void p3Notify::notifyPeerConnected (const std::string& peer_id) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerConnected(peer_id); }
void p3Notify::notifyPeerDisconnected (const std::string& peer_id) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerDisconnected(peer_id); }
void p3Notify::notifyErrorMsg (int list, int sev, std::string msg) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyErrorMsg(list,sev,msg) ; }
void p3Notify::notifyChatMessage (const ChatMessage &msg) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatMessage(msg) ; }
void p3Notify::notifyChatStatus (const ChatId& chat_id, const std::string& status_string) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatStatus(chat_id,status_string) ; }

View File

@ -91,6 +91,8 @@ class p3Notify: public RsNotify
// Notifications of clients. Can be called from anywhere inside libretroshare.
//
void notifyPeerConnected (const std::string& /* peer_id */);
void notifyPeerDisconnected (const std::string& /* peer_id */);
void notifyListPreChange (int /* list */, int /* type */) ;
void notifyListChange (int /* list */, int /* type */) ;
void notifyErrorMsg (int /* list */, int /* sev */, std::string /* msg */) ;

View File

@ -89,7 +89,7 @@ static const std::string kConfigKeyProxyServerPortI2P = "PROXY_SERVER_PORT_I2P";
void printConnectState(std::ostream &out, peerState &peer);
peerState::peerState()
:netMode(RS_NET_MODE_UNKNOWN), vs_disc(RS_VS_DISC_FULL), vs_dht(RS_VS_DHT_FULL), lastcontact(0),
:skip_pgp_signature_validation(false),netMode(RS_NET_MODE_UNKNOWN), vs_disc(RS_VS_DISC_FULL), vs_dht(RS_VS_DHT_FULL), lastcontact(0),
hiddenNode(false), hiddenPort(0), hiddenType(RS_HIDDEN_TYPE_NONE)
{
sockaddr_storage_clear(localaddr);
@ -338,17 +338,31 @@ bool p3PeerMgrIMPL::isFriend(const RsPeerId& id)
#ifdef PEER_DEBUG_COMMON
std::cerr << "p3PeerMgrIMPL::isFriend(" << id << ") called" << std::endl;
#endif
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
RS_STACK_MUTEX(mPeerMtx);
bool ret = (mFriendList.end() != mFriendList.find(id));
#ifdef PEER_DEBUG_COMMON
std::cerr << "p3PeerMgrIMPL::isFriend(" << id << ") returning : " << ret << std::endl;
#endif
return ret;
}
bool p3PeerMgrIMPL::isSslOnlyFriend(const RsPeerId& id)
{
#ifdef PEER_DEBUG_COMMON
std::cerr << "p3PeerMgrIMPL::isFriend(" << id << ") called" << std::endl;
#endif
RS_STACK_MUTEX(mPeerMtx);
auto it = mFriendList.find(id);
bool ret = it != mFriendList.end() && it->second.skip_pgp_signature_validation ;
#ifdef PEER_DEBUG_COMMON
std::cerr << "p3PeerMgrIMPL::isFriend(" << id << ") returning : " << ret << std::endl;
#endif
return ret;
}
bool p3PeerMgrIMPL::getPeerName(const RsPeerId &ssl_id, std::string &name)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
RS_STACK_MUTEX(mPeerMtx);
/* check for existing */
std::map<RsPeerId, peerState>::iterator it;
@ -826,19 +840,6 @@ bool p3PeerMgrIMPL::getFriendNetStatus(const RsPeerId &id, peerState &state)
}
bool p3PeerMgrIMPL::getOthersNetStatus(const RsPeerId &id, peerState &state)
{
RS_STACK_MUTEX(mPeerMtx);
/* check for existing */
std::map<RsPeerId, peerState>::iterator it;
it = mOthersList.find(id);
if (it == mOthersList.end()) return false;
state = it->second;
return true;
}
int p3PeerMgrIMPL::getConnectAddresses(
const RsPeerId &id, sockaddr_storage &lAddr, sockaddr_storage &eAddr,
pqiIpAddrSet &histAddrs, std::string &dyndns )
@ -872,8 +873,7 @@ bool p3PeerMgrIMPL::haveOnceConnected()
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
/* check for existing */
std::map<RsPeerId, peerState>::iterator it;
for(it = mFriendList.begin(); it != mFriendList.end(); ++it)
for(auto it = mFriendList.begin(); it != mFriendList.end(); ++it)
{
if (it->second.lastcontact > 0)
{
@ -896,6 +896,28 @@ bool p3PeerMgrIMPL::haveOnceConnected()
}
bool p3PeerMgrIMPL::notifyPgpKeyReceived(const RsPgpId& pgp_id)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
bool changed = false;
for(auto it(mFriendList.begin());it!=mFriendList.end();++it)
{
if(it->second.gpg_id == pgp_id)
{
std::cerr << "(WW) notification that full key " << pgp_id << " is available. Reseting short invite flag for peer " << it->first << std::endl;
it->second.skip_pgp_signature_validation = false;
changed = true;
}
}
if(changed)
IndicateConfigChanged();
return true;
}
/*******************************************************************/
/*******************************************************************/
@ -915,9 +937,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg
if (id == AuthSSL::getAuthSSL()->OwnId())
{
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::addFriend() cannot add own id as a friend." << std::endl;
#endif
RsErr() << "p3PeerMgrIMPL::addFriend() cannot add own id as a friend. That's a bug!" << std::endl;
/* (1) already exists */
return false;
}
@ -932,15 +952,27 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg
#endif
std::map<RsPeerId, peerState>::iterator it;
if (mFriendList.end() != mFriendList.find(id))
if (mFriendList.end() != (it=mFriendList.find(id)))
{
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::addFriend() Already Exists" << std::endl;
#endif
/* (1) already exists */
return true;
// The friend may already be here, including with a short invite (meaning the PGP key is unknown).
if(it->second.gpg_id != input_gpg_id)// already exists as a friend with a different PGP id!!
{
RsErr() << "Trying to add SSL id (" << id << ") that is already a friend with existing PGP key (" << it->second.gpg_id << ") but using a different PGP key (" << input_gpg_id << "). This is a bug!" << std::endl;
return false;
}
else
return true; /* (1) already exists */
}
// check that the PGP key is known
if(!AuthGPG::getAuthGPG()->isGPGId(gpg_id))
{
RsErr() << "Trying to add SSL id (" << id << ") to be validated with unknown PGP key (" << gpg_id << ". This is a bug!" << std::endl;
return false;
}
//Authentication is now tested at connection time, we don't store the ssl cert anymore
//
if (!AuthGPG::getAuthGPG()->isGPGAccepted(gpg_id) && gpg_id != AuthGPG::getAuthGPG()->getGPGOwnId())
@ -952,61 +984,70 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg
return false;
}
// after that, we know that we have the key, because AuthGPG wouldn't answer yes for a key it doesn't know.
/* check if it is in others */
if (mOthersList.end() != (it = mOthersList.find(id)))
{
/* (2) in mOthersList -> move over */
// if (mOthersList.end() != (it = mOthersList.find(id)))
// {
// /* (2) in mOthersList -> move over */
//#ifdef PEER_DEBUG
// std::cerr << "p3PeerMgrIMPL::addFriend() Move from Others" << std::endl;
//#endif
// if(!it->second.gpg_id.isNull() && it->second.gpg_id != input_gpg_id)// already exists as a friend with a different PGP id!!
// RsErr() << "Trying to add SSL id (" << id << ") that is already known (but not friend) with existing PGP key (" << it->second.gpg_id
// << ") but using a different PGP key (" << input_gpg_id << "). This looks like a bug! The friend will be added again with the new PGP key ID." << std::endl;
//
// mFriendList[id] = it->second;
// mOthersList.erase(it);
//
// it = mFriendList.find(id);
//
// /* setup connectivity parameters */
// it->second.vs_disc = vs_disc;
// it->second.vs_dht = vs_dht;
//
// it->second.netMode = netMode;
// it->second.lastcontact = lastContact;
//
// it->second.gpg_id = input_gpg_id;
// it->second.skip_pgp_signature_validation = false;
//
// mStatusChanged = true;
//
// notifyLinkMgr = true;
//
// IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
// }
// else
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::addFriend() Move from Others" << std::endl;
std::cerr << "p3PeerMgrIMPL::addFriend() Creating New Entry" << std::endl;
#endif
mFriendList[id] = it->second;
mOthersList.erase(it);
/* create a new entry */
peerState pstate;
it = mFriendList.find(id);
pstate.id = id;
pstate.gpg_id = gpg_id;
pstate.name = AuthGPG::getAuthGPG()->getGPGName(gpg_id);
/* setup connectivity parameters */
it->second.vs_disc = vs_disc;
it->second.vs_dht = vs_dht;
pstate.vs_disc = vs_disc;
pstate.vs_dht = vs_dht;
pstate.netMode = netMode;
pstate.lastcontact = lastContact;
it->second.netMode = netMode;
it->second.lastcontact = lastContact;
pstate.gpg_id = input_gpg_id;
pstate.skip_pgp_signature_validation = false;
mStatusChanged = true;
/* addr & timestamps -> auto cleared */
notifyLinkMgr = true;
mFriendList[id] = pstate;
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
else
{
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::addFriend() Creating New Entry" << std::endl;
#endif
mStatusChanged = true;
/* create a new entry */
peerState pstate;
notifyLinkMgr = true;
pstate.id = id;
pstate.gpg_id = gpg_id;
pstate.name = AuthGPG::getAuthGPG()->getGPGName(gpg_id);
pstate.vs_disc = vs_disc;
pstate.vs_dht = vs_dht;
pstate.netMode = netMode;
pstate.lastcontact = lastContact;
/* addr & timestamps -> auto cleared */
mFriendList[id] = pstate;
mStatusChanged = true;
notifyLinkMgr = true;
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
if (notifyLinkMgr)
@ -1029,6 +1070,93 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg
return true;
}
bool p3PeerMgrIMPL::addSslOnlyFriend( const RsPeerId& sslId, const RsPgpId& pgp_id,const RsPeerDetails& dt )
{
if(sslId.isNull() || sslId == getOwnId())
{
RsErr() <<"Attempt to add yourself or a null ID as SSL-only friend (id=" << sslId << ")" << std::endl;
return false;
}
peerState pstate;
// {
// RS_STACK_MUTEX(mPeerMtx);
//
// /* If in mOthersList -> move over */
// auto it = mOthersList.find(sslId);
// if (it != mOthersList.end())
// {
// pstate = it->second;
// mOthersList.erase(it);
// }
//
//
// } // RS_STACK_MUTEX(mPeerMtx);
if(!pstate.gpg_id.isNull() && AuthGPG::getAuthGPG()->isGPGAccepted(pstate.gpg_id))
{
RsErr() << "Trying to add as SSL-only friend a peer which PGP id is already a friend. This means the code is inconsistent. Not doing this!" << std::endl;
return false;
}
if(pgp_id.isNull())
{
RsErr() << "Null pgp id for friend added with skip_pgp_signature_validaiton flag. This is not allowed." << std::endl;
return false;
}
pstate.gpg_id = pgp_id;
pstate.id = sslId;
if(!dt.name.empty()) pstate.name = dt.name;
if(!dt.dyndns.empty()) pstate.dyndns = dt.dyndns;
pstate.hiddenNode = dt.isHiddenNode;
if(!dt.hiddenNodeAddress.empty())
pstate.hiddenDomain = dt.hiddenNodeAddress;
if(dt.hiddenNodePort) pstate.hiddenPort = dt.hiddenNodePort;
if(dt.hiddenType) pstate.hiddenType = dt.hiddenType;
if(!dt.location.empty()) pstate.location = dt.location;
pstate.skip_pgp_signature_validation = true;
{ RS_STACK_MUTEX(mPeerMtx);
mFriendList[sslId] = pstate;
mStatusChanged = true;
} // RS_STACK_MUTEX(mPeerMtx);
IndicateConfigChanged();
mLinkMgr->addFriend(sslId, dt.vs_dht != RS_VS_DHT_OFF);
// To update IP addresses is much more confortable to use locators
if(!dt.isHiddenNode)
{
for(const std::string& locator : dt.ipAddressList)
addPeerLocator(sslId, locator);
if(dt.extPort && !dt.extAddr.empty())
{
RsUrl locator;
locator.setScheme("ipv4").setHost(dt.extAddr)
.setPort(dt.extPort);
addPeerLocator(sslId, locator);
}
if(dt.localPort && !dt.localAddr.empty())
{
RsUrl locator;
locator.setScheme("ipv4").setHost(dt.localAddr)
.setPort(dt.localPort);
addPeerLocator(sslId, locator);
}
}
return true;
}
bool p3PeerMgrIMPL::removeFriend(const RsPgpId &id)
{
#ifdef PEER_DEBUG
@ -1059,7 +1187,7 @@ bool p3PeerMgrIMPL::removeFriend(const RsPgpId &id)
sslid_toRemove.push_back(it->second.id);
mOthersList[it->second.id] = peer;
//mOthersList[it->second.id] = peer;
mStatusChanged = true;
//success = true;
@ -1134,7 +1262,7 @@ bool p3PeerMgrIMPL::removeFriend(const RsPeerId &id, bool removePgpId)
if(removePgpId)
pgpid_toRemove.push_back(it->second.gpg_id);
mOthersList[id] = peer;
//mOthersList[id] = peer;
mStatusChanged = true;
//success = true;
@ -1194,14 +1322,14 @@ void p3PeerMgrIMPL::printPeerLists(std::ostream &out)
out << std::endl;
}
out << "p3PeerMgrIMPL::printPeerLists() Others List";
out << std::endl;
for(it = mOthersList.begin(); it != mOthersList.end(); ++it)
{
out << "\t SSL ID: " << it->second.id;
out << "\t GPG ID: " << it->second.gpg_id;
out << std::endl;
}
// out << "p3PeerMgrIMPL::printPeerLists() Others List";
// out << std::endl;
// for(it = mOthersList.begin(); it != mOthersList.end(); ++it)
// {
// out << "\t SSL ID: " << it->second.id;
// out << "\t GPG ID: " << it->second.gpg_id;
// out << std::endl;
// }
}
return;
@ -1383,16 +1511,10 @@ bool p3PeerMgrIMPL::addPeerLocator(const RsPeerId &sslId, const RsUrl& locator)
auto it = mFriendList.find(sslId);
if (it == mFriendList.end())
{
it = mOthersList.find(sslId);
if (it == mOthersList.end())
{
#ifdef PEER_DEBUG
std::cerr << __PRETTY_FUNCTION__ << "cannot add address "
<< "info, peer id: " << sslId << " not found in list"
<< std::endl;
std::cerr << __PRETTY_FUNCTION__ << "cannot add address " << "info, peer id: " << sslId << " not found in list" << std::endl;
#endif
return false;
}
}
changed = it->second.ipAddrs.updateLocalAddrs(ip);
@ -1440,15 +1562,10 @@ bool p3PeerMgrIMPL::setLocalAddress( const RsPeerId &id,
std::map<RsPeerId, peerState>::iterator it;
if (mFriendList.end() == (it = mFriendList.find(id)))
{
if (mOthersList.end() == (it = mOthersList.find(id)))
{
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::setLocalAddress() cannot add addres "
<< "info : peer id not found in friend list id: "
<< id << std::endl;
std::cerr << "p3PeerMgrIMPL::setLocalAddress() cannot add addres " << "info : peer id not found in friend list id: " << id << std::endl;
#endif
return false;
}
}
/* "it" points to peer */
@ -1476,12 +1593,12 @@ bool p3PeerMgrIMPL::setExtAddress( const RsPeerId &id,
bool changed = false;
uint32_t check_res = 0;
if( rsBanList!=NULL && !rsBanList->isAddressAccepted(
addr, RSBANLIST_CHECKING_FLAGS_BLACKLIST, &check_res) )
if(rsBanList && !rsBanList->isAddressAccepted(
addr, RSBANLIST_CHECKING_FLAGS_BLACKLIST, check_res ))
{
std::cerr << "(SS) trying to set external contact address for peer "
<< id << " to a banned address "
<< sockaddr_storage_iptostring(addr) << std::endl;
RsErr() << __PRETTY_FUNCTION__ << " trying to set external contact "
<< "address for peer: " << id << " to a banned address " << addr
<< std::endl;
return false;
}
@ -1506,15 +1623,10 @@ bool p3PeerMgrIMPL::setExtAddress( const RsPeerId &id,
std::map<RsPeerId, peerState>::iterator it;
if (mFriendList.end() == (it = mFriendList.find(id)))
{
if (mOthersList.end() == (it = mOthersList.find(id)))
{
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::setLocalAddress() cannot add addres "
<< "info : peer id not found in friend list id: " << id
<< std::endl;
std::cerr << "p3PeerMgrIMPL::setLocalAddress() cannot add addres " << "info : peer id not found in friend list id: " << id << std::endl;
#endif
return false;
}
}
/* "it" points to peer */
@ -1561,13 +1673,10 @@ bool p3PeerMgrIMPL::setDynDNS(const RsPeerId &id, const std::string &dyndns)
std::map<RsPeerId, peerState>::iterator it;
if (mFriendList.end() == (it = mFriendList.find(id)))
{
if (mOthersList.end() == (it = mOthersList.find(id)))
{
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::setDynDNS() cannot add dyn dns info : peer id not found in friend list id: " << id << std::endl;
std::cerr << "p3PeerMgrIMPL::setDynDNS() cannot add dyn dns info : peer id not found in friend list id: " << id << std::endl;
#endif
return false;
}
return false;
}
/* "it" points to peer */
@ -1602,7 +1711,7 @@ bool p3PeerMgrIMPL::addCandidateForOwnExternalAddress(const RsPeerId &from, cons
sockaddr_storage_clear(addr_filtered) ;
sockaddr_storage_copyip(addr_filtered,addr) ;
#ifdef PEER_DEBUG
#ifndef PEER_DEBUG
std::cerr << "Own external address is " << sockaddr_storage_iptostring(addr_filtered) << ", as reported by friend " << from << std::endl;
#endif
@ -1705,7 +1814,7 @@ bool p3PeerMgrIMPL::getExtAddressReportedByFriends(sockaddr_storage &addr, uint8
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
uint32_t count ;
uint32_t count =0;
locked_computeCurrentBestOwnExtAddressCandidate(addr,count) ;
@ -1729,7 +1838,7 @@ static bool cleanIpList(std::list<pqiIpAddress>& lst,const RsPeerId& pid,p3LinkM
/* remove unused parameter warnings */
(void) pid;
#endif
if(!link_mgr->checkPotentialAddr( (*it2).mAddr,now - (*it2).mSeenTime))
if(!link_mgr->checkPotentialAddr((*it2).mAddr))
{
#ifdef PEER_DEBUG
std::cerr << " (SS) Removing Banned/old IP address " << sockaddr_storage_iptostring( (*it2).mAddr) << " from peer " << pid << ", age = " << now - (*it2).mSeenTime << std::endl;
@ -1776,13 +1885,10 @@ bool p3PeerMgrIMPL::updateAddressList(const RsPeerId& id, const pqiIpAddrSet
std::map<RsPeerId, peerState>::iterator it;
if (mFriendList.end() == (it = mFriendList.find(id)))
{
if (mOthersList.end() == (it = mOthersList.find(id)))
{
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::setLocalAddress() cannot add addres info : peer id not found in friend list. id: " << id << std::endl;
std::cerr << "p3PeerMgrIMPL::setLocalAddress() cannot add addres info : peer id not found in friend list. id: " << id << std::endl;
#endif
return false;
}
return false;
}
/* "it" points to peer */
@ -1821,11 +1927,8 @@ bool p3PeerMgrIMPL::updateCurrentAddress(const RsPeerId& id, const pqiIpAddre
std::map<RsPeerId, peerState>::iterator it;
if (mFriendList.end() == (it = mFriendList.find(id)))
{
if (mOthersList.end() == (it = mOthersList.find(id)))
{
std::cerr << "p3PeerMgrIMPL::updateCurrentAddress() ERROR peer id not found: " << id << std::endl;
return false;
}
}
if (sockaddr_storage_isPrivateNet(addr.mAddr))
@ -1868,11 +1971,8 @@ bool p3PeerMgrIMPL::updateLastContact(const RsPeerId& id)
std::map<RsPeerId, peerState>::iterator it;
if (mFriendList.end() == (it = mFriendList.find(id)))
{
if (mOthersList.end() == (it = mOthersList.find(id)))
{
std::cerr << "p3PeerMgrIMPL::updateLastContact() ERROR peer id not found: " << id << std::endl;
return false;
}
}
it->second.lastcontact = time(NULL);
@ -1894,10 +1994,7 @@ bool p3PeerMgrIMPL::setNetworkMode(const RsPeerId &id, uint32_t netMode)
std::map<RsPeerId, peerState>::iterator it;
if (mFriendList.end() == (it = mFriendList.find(id)))
{
if (mOthersList.end() == (it = mOthersList.find(id)))
{
return false;
}
}
bool changed = false;
@ -1964,10 +2061,7 @@ bool p3PeerMgrIMPL::setVisState(const RsPeerId &id, uint16_t vs_disc, uint16_
std::map<RsPeerId, peerState>::iterator it;
if (mFriendList.end() == (it = mFriendList.find(id)))
{
if (mOthersList.end() == (it = mOthersList.find(id)))
{
return false;
}
}
else
{
@ -2344,7 +2438,20 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
#endif
/* ************* */
// permission flags is used as a mask for the existing perms, so we set it to 0xffff
addFriend(peer_id, peer_pgp_id, pitem->netMode, pitem->vs_disc, pitem->vs_dht, pitem->lastContact, RS_NODE_PERM_ALL);
RsPeerDetails det ;
if(!rsPeers->getGPGDetails(peer_pgp_id,det))
{
// would be better to add flags into RsPeerNetItem so that we already have this information. However, it's possible that the PGP key
// has been added in the meantime, so the peer would be loaded with the right pGP key attached.
RsInfo() << __PRETTY_FUNCTION__ << " loading SSL-only " << "friend: " << peer_id << " " << pitem->location << std::endl;
addSslOnlyFriend(peer_id,peer_pgp_id);
}
else if(!addFriend( peer_id, peer_pgp_id, pitem->netMode, pitem->vs_disc, pitem->vs_dht, pitem->lastContact, RS_NODE_PERM_ALL ))
{
RsInfo() << __PRETTY_FUNCTION__ << " cannot add friend friend: " << peer_id << " " << pitem->location << ". Somthing's wrong." << std::endl;
}
setLocation(pitem->nodePeerId, pitem->location);
}

View File

@ -76,6 +76,13 @@ class peerState
RsPeerId id;
RsPgpId gpg_id;
// This flag is used when adding a single SSL cert as friend without adding its PGP key in the friend list. This allows to
// have short invites. However, because this represent a significant security risk, we perform multiple consistency checks
// whenever we use this flag, in particular:
// flat is true <==> friend SSL cert is in the friend list, but PGP id is not in the friend list
bool skip_pgp_signature_validation;
uint32_t netMode; /* EXT / UPNP / UDP / HIDDEN / INVALID */
/* visState */
uint16_t vs_disc;
@ -127,8 +134,17 @@ public:
rstime_t lastContact = 0,
ServicePermissionFlags = ServicePermissionFlags(RS_NODE_PERM_DEFAULT) ) = 0;
virtual bool addSslOnlyFriend(
const RsPeerId& sslId,
const RsPgpId& pgpId,
const RsPeerDetails& details = RsPeerDetails() ) = 0;
// Calling this removed the skip_pgp_signature_validation flag on all peers which PGP key is the one supplied.
virtual bool notifyPgpKeyReceived(const RsPgpId& pgp_key_id) = 0;
virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId) = 0;
virtual bool isFriend(const RsPeerId& ssl_id) = 0;
virtual bool isSslOnlyFriend(const RsPeerId &ssl_id)=0;
virtual bool getAssociatedPeers(const RsPgpId &gpg_id, std::list<RsPeerId> &ids) = 0;
virtual bool removeAllFriendLocations(const RsPgpId &gpgid) = 0;
@ -192,7 +208,6 @@ virtual bool UpdateOwnAddress(const struct sockaddr_storage &local_addr, cons
virtual bool getOwnNetStatus(peerState &state) = 0;
virtual bool getFriendNetStatus(const RsPeerId &id, peerState &state) = 0;
virtual bool getOthersNetStatus(const RsPeerId &id, peerState &state) = 0;
virtual bool getPeerName(const RsPeerId &ssl_id, std::string &name) = 0;
virtual bool getGpgId(const RsPeerId &sslId, RsPgpId &gpgId) = 0;
@ -242,10 +257,16 @@ public:
virtual bool addFriend(const RsPeerId&ssl_id, const RsPgpId&gpg_id, uint32_t netMode = RS_NET_MODE_UDP,
uint16_t vsDisc = RS_VS_DISC_FULL, uint16_t vsDht = RS_VS_DHT_FULL,
rstime_t lastContact = 0,ServicePermissionFlags = ServicePermissionFlags(RS_NODE_PERM_DEFAULT));
bool addSslOnlyFriend(const RsPeerId& sslId, const RsPgpId &pgp_id, const RsPeerDetails& details = RsPeerDetails() ) override;
virtual bool notifyPgpKeyReceived(const RsPgpId& pgp_key_id) override;
virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId);
virtual bool removeFriend(const RsPgpId &pgp_id);
virtual bool isFriend(const RsPeerId &ssl_id);
virtual bool isSslOnlyFriend(const RsPeerId &ssl_id);
virtual bool getAssociatedPeers(const RsPgpId &gpg_id, std::list<RsPeerId> &ids);
virtual bool removeAllFriendLocations(const RsPgpId &gpgid);
@ -307,7 +328,6 @@ public:
virtual bool getOwnNetStatus(peerState &state);
virtual bool getFriendNetStatus(const RsPeerId &id, peerState &state);
virtual bool getOthersNetStatus(const RsPeerId &id, peerState &state);
virtual bool getPeerName(const RsPeerId& ssl_id, std::string& name);
virtual bool getGpgId(const RsPeerId& sslId, RsPgpId& gpgId);
@ -395,7 +415,6 @@ private:
peerState mOwnState;
std::map<RsPeerId, peerState> mFriendList; // <SSLid , peerState>
std::map<RsPeerId, peerState> mOthersList;
std::map<RsPeerId,sockaddr_storage> mReportedOwnAddresses ;

View File

@ -28,6 +28,8 @@
#include "rsitems/rsnxsitems.h"
#include "pqi/p3cfgmgr.h"
#include "pqi/pqiservice.h"
#include "retroshare/rspeers.h"
#include "retroshare/rsevents.h"
/*******************************/
// #define SERVICECONTROL_DEBUG 1
@ -756,6 +758,11 @@ bool p3ServiceControl::updateFilterByPeer_locked(const RsPeerId &peerId)
mPeerFilterMap[peerId] = peerFilter;
}
recordFilterChanges_locked(peerId, originalFilter, peerFilter);
using Evt_t = RsPeerStateChangedEvent;
if(rsEvents)
rsEvents->postEvent(std::unique_ptr<Evt_t>(new Evt_t(peerId)));
return true;
}
@ -1392,29 +1399,6 @@ RsServiceInfo::RsServiceInfo()
return;
}
std::ostream &operator<<(std::ostream &out, const RsPeerServiceInfo &info)
{
out << "RsPeerServiceInfo(" << info.mPeerId << ")";
out << std::endl;
std::map<uint32_t, RsServiceInfo>::const_iterator it;
for(it = info.mServiceList.begin(); it != info.mServiceList.end(); ++it)
{
out << "\t Service:" << it->first << " : ";
out << it->second;
out << std::endl;
}
return out;
}
std::ostream &operator<<(std::ostream &out, const RsServiceInfo &info)
{
out << "RsServiceInfo(" << info.mServiceType << "): " << info.mServiceName;
out << " Version(" << info.mVersionMajor << "," << info.mVersionMinor << ")";
out << " MinVersion(" << info.mMinVersionMajor << "," << info.mMinVersionMinor << ")";
return out;
}
std::ostream &operator<<(std::ostream &out, const ServicePeerFilter &filter)
{
out << "ServicePeerFilter DenyAll: " << filter.mDenyAll;

View File

@ -35,7 +35,7 @@
#include "pqi/pqissllistener.h"
#include "pqi/p3linkmgr.h"
#include <retroshare/rspeers.h>
#include "retroshare/rspeers.h"
#include <retroshare/rsdht.h>
#include <retroshare/rsbanlist.h>
@ -1115,9 +1115,6 @@ int pqissl::SSL_Connection_Complete()
rslog(RSL_WARNING, pqisslzone, out);
// attempt real error.
Extract_Failed_SSL_Certificate();
rslog(RSL_ALERT, pqisslzone, "pqissl::SSL_Connection_Complete() -> calling reset()");
reset_locked();
waiting = WAITING_FAIL_INTERFACE;
@ -1132,159 +1129,95 @@ int pqissl::SSL_Connection_Complete()
return 1;
}
int pqissl::Extract_Failed_SSL_Certificate()
{
std::cerr << "pqissl::Extract_Failed_SSL_Certificate() FAILED Connection due to Security Issues";
std::cerr << std::endl;
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Extract_Failed_SSL_Certificate()");
#endif
// Get the Peer Certificate....
X509 *peercert = SSL_get_peer_certificate(ssl_connection);
if (peercert == NULL)
{
rslog(RSL_WARNING, pqisslzone,
"pqissl::Extract_Failed_SSL_Certificate() Peer Didnt Give Cert");
std::cerr << "pqissl::Extract_Failed_SSL_Certificate() ERROR Peer Didn't Give Us Certificate";
std::cerr << std::endl;
return -1;
}
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Extract_Failed_SSL_Certificate() Have Peer Cert - Registering");
#endif
std::cerr << "pqissl::Extract_Failed_SSL_Certificate() Passing FAILED Cert to AuthSSL for analysis";
std::cerr << std::endl;
// save certificate... (and ip locations)
// false for outgoing....
// we actually connected to remote_addr,
// which could be
// (pqissl's case) sslcert->serveraddr or sslcert->localaddr.
RsPeerId sslid ;
getX509id(peercert, sslid) ;
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
RsPgpId gpgid(getX509CNString(peercert->cert_info->issuer));
std::string sslcn = getX509CNString(peercert->cert_info->subject);
#else
RsPgpId gpgid(getX509CNString(X509_get_issuer_name(peercert)));
std::string sslcn = getX509CNString(X509_get_subject_name(peercert));
#endif
AuthSSL::getAuthSSL()->FailedCertificate(peercert, gpgid,sslid,sslcn,remote_addr, false);
mLinkMgr->notifyDeniedConnection(gpgid, sslid, sslcn, remote_addr, false);
return 1;
}
int pqissl::Authorise_SSL_Connection()
{
#ifdef PQISSL_DEBUG
std::cerr << __PRETTY_FUNCTION__ << std::endl;
#endif
Dbg3() << __PRETTY_FUNCTION__ << std::endl;
if (time(NULL) > ssl_connect_timeout)
constexpr int failure = -1;
if (time(nullptr) > ssl_connect_timeout)
{
std::cerr << __PRETTY_FUNCTION__ << " Connection timed out reset!"
<< std::endl;
RsInfo() << __PRETTY_FUNCTION__ << " Connection timed out reset!"
<< std::endl;
reset_locked();
}
int err;
if (0 >= (err = SSL_Connection_Complete())) return err;
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Authorise_SSL_Connection() SSL_Connection_Complete");
#endif
Dbg3() << __PRETTY_FUNCTION__ << "SSL_Connection_Complete success."
<< std::endl;
// reset switch.
waiting = WAITING_NOT;
X509 *peercert = SSL_get_peer_certificate(ssl_connection);
if (peercert == NULL)
#ifdef RS_PQISSL_AUTH_DOUBLE_CHECK
X509* peercert = SSL_get_peer_certificate(ssl_connection);
if (!peercert)
{
rslog(RSL_WARNING, pqisslzone,
"pqissl::Authorise_SSL_Connection() Peer Didnt Give Cert");
rslog(RSL_ALERT, pqisslzone, "pqissl::Authorise_Connection_Complete() -> calling reset()");
// Failed completely
reset_locked();
return -1;
RsFatal() << __PRETTY_FUNCTION__ << " failed to retrieve peer "
<< "certificate at this point this should never happen!"
<< std::endl;
print_stacktrace();
exit(failure);
}
RsPeerId certPeerId;
getX509id(peercert, certPeerId);
if (RsPeerId(certPeerId) != PeerId()) {
rslog(RSL_WARNING, pqisslzone,
"pqissl::Authorise_SSL_Connection() the cert Id doesn't match the Peer id we're trying to connect to.");
rslog(RSL_ALERT, pqisslzone, "pqissl::Authorise_Connection_Complete() -> calling reset()");
// Failed completely
reset_locked();
return -1;
}
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Authorise_SSL_Connection() Have Peer Cert");
#endif
// save certificate... (and ip locations)
// false for outgoing....
// we actually connected to remote_addr,
// which could be
// (pqissl's case) sslcert->serveraddr or sslcert->localaddr.
AuthSSL::getAuthSSL()->CheckCertificate(PeerId(), peercert);
bool certCorrect = true; /* WE know it okay already! */
uint32_t check_result ;
uint32_t checking_flags = RSBANLIST_CHECKING_FLAGS_BLACKLIST;
if (rsPeers->servicePermissionFlags(PeerId()) & RS_NODE_PERM_REQUIRE_WL)
checking_flags |= RSBANLIST_CHECKING_FLAGS_WHITELIST;
if(rsBanList!=NULL && !rsBanList->isAddressAccepted(remote_addr,checking_flags,&check_result))
{
std::cerr << "(SS) refusing connection attempt from IP address " << sockaddr_storage_iptostring(remote_addr) << ". Reason: " <<
((check_result == RSBANLIST_CHECK_RESULT_NOT_WHITELISTED)?"not whitelisted (peer requires whitelist)":"blacklisted") << std::endl;
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_IP_BLACKLISTED, PeerId().toStdString(), sockaddr_storage_iptostring(remote_addr), "", "", check_result);
reset_locked();
return 0 ;
}
// check it's the right one.
if (certCorrect)
RsPeerId certPeerId = RsX509Cert::getCertSslId(*peercert);
if (RsPeerId(certPeerId) != PeerId())
{
// then okay...
rslog(RSL_WARNING, pqisslzone, "pqissl::Authorise_SSL_Connection() Accepting Conn. Peer: " + PeerId().toStdString());
RsErr() << __PRETTY_FUNCTION__ << " the cert Id doesn't match the peer "
<< "id we're trying to connect to." << std::endl;
//std::cerr << "pqissl::Authorise_SSL_Connection(): accepting connection from " << sockaddr_storage_iptostring(remote_addr) << std::endl;
accept_locked(ssl_connection, sockfd, remote_addr);
return 1;
/* TODO: Considering how difficult is managing to get a connection to a
* friend nowadays on the Internet because of evil NAT everywhere.
* If the cert is from a friend anyway we should find a way to make good
* use of this connection instead of throwing it away... */
X509_free(peercert);
reset_locked();
return failure;
}
rslog(RSL_WARNING, pqisslzone, "pqissl::Authorise_SSL_Connection() Something Wrong ... Shutdown. Peer: " + PeerId().toStdString());
/* At this point the actual connection authentication has already been
* performed in AuthSSL::VerifyX509Callback, any furter authentication check
* like the followings are redundant. */
// else shutdown ssl connection.
rslog(RSL_ALERT, pqisslzone, "pqissl::Authorise_Connection_Complete() -> calling reset()");
bool isSslOnlyFriend = rsPeers->isSslOnlyFriend(certPeerId);
reset_locked();
return 0;
uint32_t authErrCode = 0;
if( !isSslOnlyFriend && !AuthSSL::instance().AuthX509WithGPG(peercert,false, authErrCode) )
{
RsFatal() << __PRETTY_FUNCTION__ << " failure verifying peer "
<< "certificate signature. This should never happen at this "
<< "point!" << std::endl;
print_stacktrace();
X509_free(peercert); // not needed but just in case we change to return
exit(failure);
}
RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert);
if( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
!AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
{
RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId
<< " is not friend. It is very unlikely to happen at this "
<< "point! Either the user must have been so fast to deny "
<< "friendship just after VerifyX509Callback have returned "
<< "success and just before this code being executed, or "
<< "something really fishy is happening! Share the full log "
<< "with developers." << std::endl;
print_stacktrace();
X509_free(peercert); // not needed but just in case we change to return
exit(failure);
}
#endif // def RS_PQISSL_AUTH_REDUNDANT_CHECK
Dbg2() << __PRETTY_FUNCTION__ << " Accepting connection to peer: "
<< PeerId() << " with address: " << remote_addr << std::endl;
return accept_locked(ssl_connection, sockfd, remote_addr);
}
@ -1300,28 +1233,36 @@ int pqissl::accept( SSL *ssl, int fd,
return accept_locked(ssl, fd, foreign_addr);
}
int pqissl::accept_locked( SSL *ssl, int fd,
int pqissl::accept_locked( SSL *ssl, int fd,
const sockaddr_storage &foreign_addr )
{
#ifdef PQISSL_DEBUG
std::cerr << __PRETTY_FUNCTION__ << std::endl;
#endif
Dbg3() << __PRETTY_FUNCTION__ << std::endl;
constexpr int failure = -1;
constexpr int success = 1;
#ifdef RS_PQISSL_BANLIST_DOUBLE_CHECK
/* At this point, as we are actively attempting the connection, we decide
* the address to which to connect to, banned addresses should never get
* here as the filtering for banned addresses happens much before, this
* check is therefore redundant, and if it trigger something really fishy
* must be happening (a bug somewhere else in the code). */
uint32_t check_result;
uint32_t checking_flags = RSBANLIST_CHECKING_FLAGS_BLACKLIST;
if (rsPeers->servicePermissionFlags(PeerId()) & RS_NODE_PERM_REQUIRE_WL)
checking_flags |= RSBANLIST_CHECKING_FLAGS_WHITELIST;
if( rsBanList && !rsBanList->isAddressAccepted( foreign_addr,
checking_flags,
&check_result ) )
if(rsBanList && !rsBanList->isAddressAccepted(
foreign_addr, checking_flags, check_result ))
{
std::cerr << __PRETTY_FUNCTION__
<< " (SS) refusing incoming SSL connection from blacklisted "
<< "foreign address "
<< sockaddr_storage_iptostring(foreign_addr)
<< ". Reason: " << check_result << "." << std::endl;
RsErr() << __PRETTY_FUNCTION__
<< " Refusing incoming SSL connection from blacklisted "
<< "foreign address " << foreign_addr
<< ". Reason: " << check_result << ". This should never happen "
<< "at this point! Please report full log to developers!"
<< std::endl;
print_stacktrace();
RsServer::notify()->AddFeedItem(
RS_FEED_ITEM_SEC_IP_BLACKLISTED,
@ -1329,14 +1270,15 @@ int pqissl::accept_locked( SSL *ssl, int fd,
sockaddr_storage_iptostring(foreign_addr), "", "",
check_result);
reset_locked();
return -1;
return failure;
}
#endif //def RS_BANLIST_REDUNDANT_CHECK
if (waiting != WAITING_NOT)
{
std::cerr << __PRETTY_FUNCTION__ << " Peer: " << PeerId().toStdString()
<< " - Two connections in progress - Shut 1 down!"
<< std::endl;
RsInfo() << __PRETTY_FUNCTION__ << " Peer: " << PeerId()
<< " - Two connections in progress - Shut 1 down!"
<< std::endl;
// outgoing connection in progress.
// shut this baby down.
@ -1431,7 +1373,7 @@ int pqissl::accept_locked( SSL *ssl, int fd,
waiting = WAITING_FAIL_INTERFACE; // failed completely.
reset_locked();
return -1;
return failure;
}
#ifdef PQISSL_DEBUG
else std::cerr << __PRETTY_FUNCTION__ << " Socket made non-nlocking!"
@ -1456,7 +1398,7 @@ int pqissl::accept_locked( SSL *ssl, int fd,
sockaddr_storage addr; sockaddr_storage_copy(remote_addr, addr);
parent()->notifyEvent(this, NET_CONNECT_SUCCESS, addr);
}
return 1;
return success;
}
/********** Implementation of BinInterface **************************

View File

@ -3,8 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2004-2006 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2004-2006 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2015-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -20,8 +20,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef MRK_PQI_SSL_HEADER
#define MRK_PQI_SSL_HEADER
#pragma once
// operating system specific network header.
#include "pqi/pqinetwork.h"
@ -32,6 +31,11 @@
#include "pqi/pqi_base.h"
#include "pqi/authssl.h"
#define RS_PQISSL_AUTH_DOUBLE_CHECK 1
#define RS_PQISSL_BANLIST_DOUBLE_CHECK 1
#define WAITING_NOT 0
#define WAITING_DELAY 1
#define WAITING_SOCK_CONNECT 2
@ -159,8 +163,6 @@ int Initiate_SSL_Connection();
int SSL_Connection_Complete();
int Authorise_SSL_Connection();
int Extract_Failed_SSL_Certificate(); // try to get cert anyway.
// check connection timeout.
bool CheckConnectionTimeout();
@ -207,9 +209,6 @@ bool CheckConnectionTimeout();
private:
// ssl only fns.
int connectInterface(const struct sockaddr_storage &addr);
RS_SET_CONTEXT_DEBUG_LEVEL(1)
};
#endif // MRK_PQI_SSL_HEADER

View File

@ -20,20 +20,20 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include "pqi/pqissl.h"
#include "pqi/pqissllistener.h"
#include "pqi/pqinetwork.h"
#include "pqi/sslfns.h"
#include "pqi/p3peermgr.h"
#include <errno.h>
#include <openssl/err.h>
#include "util/rsdebug.h"
#include "util/rsstring.h"
#include "retroshare/rsbanlist.h"
#include "pqi/authgpg.h"
#include <unistd.h>
#include <errno.h>
#include <openssl/err.h>
static struct RsLog::logInfo pqissllistenzoneInfo = {RsLog::Default, "p3peermgr"};
#define pqissllistenzone &pqissllistenzoneInfo
@ -486,9 +486,6 @@ int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool
break;
}
/* we have failed -> get certificate if possible */
Extract_Failed_SSL_Certificate(incoming_connexion_info);
closeConnection(fd, incoming_connexion_info.ssl) ;
pqioutput(PQL_WARNING, pqissllistenzone, "Read Error on the SSL Socket\nShutting it down!");
@ -502,20 +499,11 @@ int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool
//
X509 *x509 = SSL_get_peer_certificate(incoming_connexion_info.ssl) ;
#ifdef DEBUG_LISTENNER
std::cerr << "Info from certificate: " << std::endl;
#endif
if(x509 != NULL)
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
incoming_connexion_info.gpgid = RsPgpId(std::string(getX509CNString(x509->cert_info->issuer)));
incoming_connexion_info.sslcn = getX509CNString(x509->cert_info->subject);
#else
incoming_connexion_info.gpgid = RsPgpId(std::string(getX509CNString(X509_get_issuer_name(x509))));
incoming_connexion_info.sslcn = getX509CNString(X509_get_subject_name(x509));
#endif
getX509id(x509,incoming_connexion_info.sslid);
if(x509)
{
incoming_connexion_info.gpgid = RsX509Cert::getCertIssuer(*x509);
incoming_connexion_info.sslcn = RsX509Cert::getCertName(*x509);
incoming_connexion_info.sslid = RsX509Cert::getCertSslId(*x509);
#ifdef DEBUG_LISTENNER
std::cerr << " Got PGP Id = " << incoming_connexion_info.gpgid << std::endl;
@ -571,61 +559,6 @@ int pqissllistenbase::closeConnection(int fd, SSL *ssl)
return 1;
}
int pqissllistenbase::Extract_Failed_SSL_Certificate(const IncomingSSLInfo& info)
{
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, "pqissllistenbase::Extract_Failed_SSL_Certificate()");
std::cerr << "pqissllistenbase::Extract_Failed_SSL_Certificate() FAILED CONNECTION due to security!";
std::cerr << std::endl;
// Get the Peer Certificate....
X509 *peercert = SSL_get_peer_certificate(info.ssl);
std::cerr << "Extract_Failed_SSL_Certificate: " << std::endl;
std::cerr << " SSL = " << (void*)info.ssl << std::endl;
std::cerr << " GPG id = " << info.gpgid << std::endl;
std::cerr << " SSL id = " << info.sslid << std::endl;
std::cerr << " SSL cn = " << info.sslcn << std::endl;
std::cerr << " addr+p = " << sockaddr_storage_tostring(info.addr) << std::endl;
if (peercert == NULL)
{
std::string out;
out += "pqissllistenbase::Extract_Failed_SSL_Certificate() from: ";
out += sockaddr_storage_tostring(info.addr);
out += " ERROR Peer didn't give Cert!";
std::cerr << out << std::endl;
AuthSSL::getAuthSSL()->FailedCertificate(peercert, info.gpgid,info.sslid,info.sslcn,info.addr, true);
pqioutput(PQL_WARNING, pqissllistenzone, out);
return -1;
}
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
"pqissllistenbase::Extract_Failed_SSL_Certificate() Have Peer Cert - Registering");
{
std::string out;
out += "pqissllistenbase::Extract_Failed_SSL_Certificate() from: ";
out += sockaddr_storage_tostring(info.addr);
out += " Passing Cert to AuthSSL() for analysis";
std::cerr << out << std::endl;
pqioutput(PQL_WARNING, pqissllistenzone, out);
std::cerr << out << std::endl;
}
// save certificate... (and ip locations)
// false for outgoing....
AuthSSL::getAuthSSL()->FailedCertificate(peercert, info.gpgid,info.sslid,info.sslcn,info.addr, true);
return 1;
}
int pqissllistenbase::continueaccepts()
{
@ -830,91 +763,76 @@ int pqissllistener::status()
}
int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
{
{
constexpr int failure = -1;
constexpr int success = 1;
// Get the Peer Certificate....
X509 *peercert = SSL_get_peer_certificate(info.ssl);
if (peercert == NULL)
X509* peercert = SSL_get_peer_certificate(info.ssl);
if(!peercert)
{
pqioutput(PQL_WARNING, pqissllistenzone,
"pqissllistener::completeConnection() Peer Did Not Provide Cert!");
// failure -1, pending 0, sucess 1.
// pqissllistenbase will shutdown!
return -1;
RsFatal() << __PRETTY_FUNCTION__ << " failed to retrieve peer "
<< "certificate at this point this should never happen!"
<< std::endl;
print_stacktrace();
exit(failure);
}
// Check cert.
RsPeerId newPeerId;
RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert);
RsPeerId newPeerId = RsX509Cert::getCertSslId(*peercert);
#ifdef RS_PQISSL_AUTH_DOUBLE_CHECK
/* At this point the actual connection authentication has already been
* performed in AuthSSL::VerifyX509Callback, any furter authentication check
* like the followings are redundant. */
/****
* As the validation is actually done before this...
* we should only need to call CheckCertificate here!
****/
bool isSslOnlyFriend = rsPeers->isSslOnlyFriend(newPeerId);
bool certOk = AuthSSL::getAuthSSL()->ValidateCertificate(peercert, newPeerId);
uint32_t authErrCode = 0;
if( !isSslOnlyFriend &&
!AuthSSL::instance().AuthX509WithGPG(peercert,false, authErrCode) )
{
RsFatal() << __PRETTY_FUNCTION__ << " failure verifying peer "
<< "certificate signature. This should never happen at this "
<< "point!" << std::endl;
print_stacktrace();
X509_free(peercert); // not needed but just in case we change to return
exit(failure);
}
if( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() &&
!AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
{
RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId
<< " is not friend. It is very unlikely to happen at this "
<< "point! Either the user must have been so fast to deny "
<< "friendship just after VerifyX509Callback have returned "
<< "success and just before this code being executed, or "
<< "something really fishy is happening! Share the full log "
<< "with developers." << std::endl;
print_stacktrace();
X509_free(peercert); // not needed but just in case we change to return
exit(failure);
}
#endif //def RS_PQISSL_AUTH_REDUNDANT_CHECK
bool found = false;
std::map<RsPeerId, pqissl *>::iterator it;
// Let connected one through as well! if ((npc == NULL) || (npc -> Connected()))
if (!certOk)
for(auto it = listenaddr.begin(); !found && it != listenaddr.end(); )
{
pqioutput(PQL_WARNING, pqissllistenzone,
"pqissllistener::completeConnection() registerCertificate Failed!");
// bad - shutdown.
// pqissllistenbase will shutdown!
X509_free(peercert);
return -1;
if (it -> first == newPeerId) found = true;
else ++it;
}
else
if (!found)
{
std::string out = "pqissllistener::continueSSL()\nchecking: " + newPeerId.toStdString() + "\n";
// check if cert is in our list.....
for(it = listenaddr.begin();(found!=true) && (it!=listenaddr.end());)
{
out + "\tagainst: " + it->first.toStdString() + "\n";
if (it -> first == newPeerId)
{
// accept even if already connected.
out += "\t\tMatch!";
found = true;
}
else
{
++it;
}
}
Dbg1() << __PRETTY_FUNCTION__ << " got secure connection from address: "
<< info.addr << " with previously unknown SSL certificate: "
<< newPeerId << " signed by PGP friend: " << pgpId
<< ". Adding the new location as SSL friend." << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out);
}
if (found == false)
{
std::string out = "No Matching Certificate for Connection:";
out += sockaddr_storage_tostring(info.addr);
out += "\npqissllistenbase: Will shut it down!";
pqioutput(PQL_WARNING, pqissllistenzone, out);
// but as it passed the authentication step,
// we can add it into the AuthSSL, and mConnMgr.
AuthSSL::getAuthSSL()->CheckCertificate(newPeerId, peercert);
/* now need to get GPG id too */
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
RsPgpId pgpid(std::string(getX509CNString(peercert->cert_info->issuer)));
#else
RsPgpId pgpid(std::string(getX509CNString(X509_get_issuer_name(peercert))));
#endif
mPeerMgr->addFriend(newPeerId, pgpid);
X509_free(peercert);
return -1;
mPeerMgr->addFriend(newPeerId, pgpId);
}
// Cleanup cert.
@ -926,17 +844,14 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
as.mSSL = info.ssl;
as.mPeerId = newPeerId;
as.mAddr = info.addr;
as.mAcceptTS = time(NULL);
as.mAcceptTS = time(nullptr);
accepted_ssl.push_back(as);
std::string out = "pqissllistener::completeConnection() Successful Connection with: " + newPeerId.toStdString();
out += " for Connection:";
out += sockaddr_storage_tostring(info.addr);
out += " Adding to WAIT-ACCEPT Queue";
pqioutput(PQL_WARNING, pqissllistenzone, out);
Dbg1() << __PRETTY_FUNCTION__ << "Successful Connection with: "
<< newPeerId << " with address: " << info.addr << std::endl;
return 1;
return success;
}
int pqissllistener::finaliseConnection(int fd, SSL *ssl, const RsPeerId& peerId, const struct sockaddr_storage &remote_addr)

View File

@ -19,21 +19,20 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef MRK_PQI_SSL_LISTEN_HEADER
#define MRK_PQI_SSL_LISTEN_HEADER
#pragma once
#include <openssl/ssl.h>
// operating system specific network header.
#include "pqi/pqinetwork.h"
#include <string>
#include <map>
#include "pqi/pqi_base.h"
#include "pqi/pqilistener.h"
#include "pqi/authssl.h"
#include "util/rsdebug.h"
#include "pqi/pqinetwork.h"
#define RS_PQISSL_AUTH_DOUBLE_CHECK 1
/***************************** pqi Net SSL Interface *********************************
*/
@ -98,7 +97,7 @@ protected:
p3PeerMgr *mPeerMgr;
private:
int Extract_Failed_SSL_Certificate(const IncomingSSLInfo&);
bool active;
int lsock;
std::list<IncomingSSLInfo> incoming_ssl ;
@ -122,7 +121,6 @@ public:
private:
std::map<RsPeerId, pqissl*> listenaddr;
RS_SET_CONTEXT_DEBUG_LEVEL(2)
};
#endif // MRK_PQI_SSL_LISTEN_HEADER

View File

@ -31,6 +31,7 @@
#include "pqi/pqi_base.h"
#include "util/rsdir.h"
#include "util/rsstring.h"
#include "pqi/authssl.h"
#include <openssl/ssl.h>
#include <openssl/err.h>
@ -675,13 +676,6 @@ int pem_passwd_cb(char *buf, int size, int rwflag, void *password)
return(strlen(buf));
}
/* XXX FIX */
bool CheckX509Certificate(X509 */*x509*/)
{
return true;
}
uint64_t getX509SerialNumber(X509 *cert)
{
ASN1_INTEGER *serial = X509_get_serialNumber(cert);
@ -711,69 +705,6 @@ uint32_t getX509RetroshareCertificateVersion(X509 *cert)
}
}
// Not dependent on sslroot. load, and detroys the X509 memory.
int LoadCheckX509(const char *cert_file, RsPgpId& issuerName, std::string &location, RsPeerId &userId)
{
/* This function loads the X509 certificate from the file,
* and checks the certificate
*/
FILE *tmpfp = RsDirUtil::rs_fopen(cert_file, "r");
if (tmpfp == NULL)
{
#ifdef AUTHSSL_DEBUG
std::cerr << "sslroot::LoadCheckAndGetX509Name()";
std::cerr << " Failed to open Certificate File:" << cert_file;
std::cerr << std::endl;
#endif
return 0;
}
// get xPGP certificate.
X509 *x509 = PEM_read_X509(tmpfp, NULL, NULL, NULL);
fclose(tmpfp);
// check the certificate.
bool valid = false;
if (x509)
{
valid = CheckX509Certificate(x509);
if (valid)
{
valid = getX509id(x509, userId);
}
}
if (valid)
{
// extract the name.
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
issuerName = RsPgpId(std::string(getX509CNString(x509->cert_info->issuer)));
location = getX509LocString(x509->cert_info->subject);
#else
issuerName = RsPgpId(std::string(getX509CNString(X509_get_issuer_name(x509))));
location = getX509LocString(X509_get_subject_name(x509));
#endif
}
#ifdef AUTHSSL_DEBUG
std::cout << getX509Info(x509) << std::endl ;
#endif
// clean up.
X509_free(x509);
if (valid)
{
// happy!
return 1;
}
else
{
// something went wrong!
return 0;
}
}
std::string getX509NameString(X509_NAME *name)
{
std::string namestr;
@ -896,10 +827,9 @@ std::string getX509Info(X509 *cert)
/********** SSL ERROR STUFF ******************************************/
int printSSLError(SSL *ssl, int retval, int err, unsigned long err2, std::string &out)
int printSSLError(
SSL*, int retval, int err, unsigned long err2, std::string& out )
{
(void) ssl; /* remove unused parameter warnings */
std::string reason;
std::string mainreason = std::string("UNKNOWN ERROR CODE");
@ -939,7 +869,18 @@ int printSSLError(SSL *ssl, int retval, int err, unsigned long err2, std::string
{
mainreason = std::string("SSL_ERROR_SSL");
}
rs_sprintf_append(out, "RetVal(%d) -> SSL Error: %s\n\t + ERR Error: %s\n", retval, mainreason.c_str(), ERR_error_string(err2, NULL));
rs_sprintf_append( out,
"RetVal(%d) -> SSL Error: %s\n\t + ERR Error: %s\n",
retval, mainreason.c_str(),
ERR_error_string(err2, nullptr) );
return 1;
}
std::string sslErrorToString(int retval, int err, unsigned long err2)
{
std::string ret;
// When printSSLError will be removed it's code will be moved here
printSSLError(nullptr, retval, err, err2, ret);
return ret;
}

View File

@ -1,4 +1,4 @@
/*******************************************************************************
/*******************************************************************************
* libretroshare/src/pqi: sslfns.h *
* *
* libretroshare: retroshare core library *
@ -19,8 +19,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef RS_PQI_SSL_HELPER_H
#define RS_PQI_SSL_HELPER_H
#pragma once
/* Functions in this file are SSL only,
* and have no dependence on SSLRoot() etc.
@ -32,9 +31,12 @@
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <inttypes.h>
#include <retroshare/rstypes.h>
#include <string>
#include <inttypes.h>
#include "util/rsdeprecate.h"
#include "retroshare/rstypes.h"
/****
* #define AUTHSSL_DEBUG 1
@ -113,11 +115,6 @@ bool getX509id(X509 *x509, RsPeerId &xid);
int pem_passwd_cb(char *buf, int size, int rwflag, void *password);
bool CheckX509Certificate(X509 *x509);
// Not dependent on sslroot. load, and detroys the X509 memory.
int LoadCheckX509(const char *cert_file, RsPgpId& issuer, std::string &location, RsPeerId& userId);
std::string getX509NameString(X509_NAME *name);
std::string getX509CNString(X509_NAME *name);
std::string getX509TypeString(X509_NAME *name, const char *type, int len);
@ -131,7 +128,8 @@ uint32_t getX509RetroshareCertificateVersion(X509 *cert) ;
/********** SSL ERROR STUFF ******************************************/
int printSSLError(SSL *ssl, int retval, int err, unsigned long err2, std::string &out);
#endif /* RS_PQI_SSL_HELPER_H */
RS_DEPRECATED_FOR(sslErrorToString)
int printSSLError(
SSL* unused, int retval, int err, unsigned long err2, std::string& out);
std::string sslErrorToString(int retval, int err, unsigned long err2);

View File

@ -1,9 +1,9 @@
/*******************************************************************************
* libretroshare/src/retroshare: rsbanlist.h *
* IPv4 address filtering interface *
* *
* libretroshare: retroshare core library *
* *
* Copyright 2011-2011 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2015 Cyril Soler <retroshare.team@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -21,12 +21,21 @@
*******************************************************************************/
#pragma once
#include <list>
#include "util/rsnet.h"
#include "util/rstime.h"
#include "util/rsmemory.h"
class RsBanList;
extern RsBanList *rsBanList ;
/**
* Pointer to global instance of RsBanList service implementation
* @jsonapi{development}
*/
extern RsBanList* rsBanList;
// TODO: use enum class instead of defines
#define RSBANLIST_ORIGIN_UNKNOWN 0
#define RSBANLIST_ORIGIN_SELF 1
#define RSBANLIST_ORIGIN_FRIEND 2
@ -55,7 +64,7 @@ extern RsBanList *rsBanList ;
#define RSBANLIST_TYPE_BLACKLIST 2
#define RSBANLIST_TYPE_WHITELIST 3
class RsTlvBanListEntry ;
class RsTlvBanListEntry;
class BanListPeer
{
@ -78,42 +87,71 @@ public:
class RsBanList
{
public:
virtual void enableIPFiltering(bool b) =0;
virtual bool ipFilteringEnabled() =0;
/**
* @brief Enable or disable IP filtering service
* @jsonapi{development}
* @param[in] enable pass true to enable, false to disable
*/
virtual void enableIPFiltering(bool enable) = 0;
// addIpRange()/removeIpRange()
// addr: full IPv4 address. Port is ignored.
// masked_bytes: 0=full IP, 1="/24", 2="/16"
// list_type: RSBANLIST_TYPE_WHITELIST or RSBANLIST_TYPE_BLACKLIST
// comment: anything, user-based.
/**
* @brief Get ip filtering service status
* @jsonapi{development}
* @return true if enabled, false if disabled
*/
virtual bool ipFilteringEnabled() = 0;
virtual bool addIpRange(const struct sockaddr_storage& addr,int masked_bytes,uint32_t list_type,const std::string& comment) =0;
virtual bool removeIpRange(const struct sockaddr_storage& addr,int masked_bytes,uint32_t list_type) =0;
/**
* @brief addIpRange
* @param addr full IPv4 address. Port is ignored.
* @param masked_bytes 0=full IP, 1="/24", 2="/16"
* @param list_type RSBANLIST_TYPE_WHITELIST or RSBANLIST_TYPE_BLACKLIST
* @param comment anything, user-based
* @return
*/
virtual bool addIpRange(
const sockaddr_storage& addr, int masked_bytes, uint32_t list_type,
const std::string& comment ) = 0;
// isAddressAccepted()
// addr: full IPv4 address. Port is ignored.
// checking flags: any combination of RSBANLIST_CHECKING_FLAGS_BLACKLIST and RSBANLIST_CHECKING_FLAGS_WHITELIST
// check_result: returned result of the check in RSBANLIST_CHECK_RESULT_*
// returned value: true=address is accepted, false=address is rejected.
/**
* @brief removeIpRange
* @param addr full IPv4 address. Port is ignored.
* @param masked_bytes 0=full IP, 1="/24", 2="/16"
* @param list_type RSBANLIST_TYPE_WHITELIST or RSBANLIST_TYPE_BLACKLIST
* @return
*/
virtual bool removeIpRange(
const sockaddr_storage& addr, int masked_bytes, uint32_t list_type
) = 0;
virtual bool isAddressAccepted(const struct sockaddr_storage& addr,uint32_t checking_flags,uint32_t *check_result=NULL) =0;
/**
* @brief isAddressAccepted
* @param addr full IPv4 address. Port is ignored.
* @param checking_flags any combination of
* RSBANLIST_CHECKING_FLAGS_BLACKLIST and
* RSBANLIST_CHECKING_FLAGS_WHITELIST
* @param check_result returned result of the check in
* RSBANLIST_CHECK_RESULT_*
* @return true if address is accepted, false false if address is rejected.
*/
virtual bool isAddressAccepted(
const sockaddr_storage& addr, uint32_t checking_flags,
uint32_t& check_result = RS_DEFAULT_STORAGE_PARAM(uint32_t) ) = 0;
virtual void getBannedIps(std::list<BanListPeer>& list) =0;
virtual void getWhiteListedIps(std::list<BanListPeer>& list) =0;
virtual void getBannedIps(std::list<BanListPeer>& list) = 0;
virtual void getWhiteListedIps(std::list<BanListPeer>& list) = 0;
virtual bool autoRangeEnabled() =0;
virtual void enableAutoRange(bool b) =0 ;
virtual bool autoRangeEnabled() = 0;
virtual void enableAutoRange(bool b) = 0;
virtual int autoRangeLimit() =0;
virtual void setAutoRangeLimit(int n)=0;
virtual int autoRangeLimit() = 0;
virtual void setAutoRangeLimit(int n) = 0;
virtual void enableIPsFromFriends(bool b) =0;
virtual bool IPsFromFriendsEnabled() =0;
virtual void enableIPsFromFriends(bool b) = 0;
virtual bool IPsFromFriendsEnabled() = 0;
virtual void enableIPsFromDHT(bool b) =0;
virtual bool iPsFromDHTEnabled() =0;
virtual void enableIPsFromDHT(bool b) = 0;
virtual bool iPsFromDHTEnabled() = 0;
virtual ~RsBanList();
};

View File

@ -0,0 +1,109 @@
/*******************************************************************************
* RetroShare Broadcast Domain Discovery *
* *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@altermundi.net> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include <functional>
#include <memory>
#include <vector>
#include <string>
#include "retroshare/rsids.h"
#include "retroshare/rstypes.h"
#include "serialiser/rsserializable.h"
#include "util/rstime.h"
#include "util/rsurl.h"
#include "util/rsmemory.h"
#include "retroshare/rsevents.h"
class RsBroadcastDiscovery;
/**
* Pointer to global instance of RsBroadcastDiscovery service implementation
* @jsonapi{development}
*
* TODO: this should become std::weak_ptr once we have a reasonable services
* management.
*/
extern std::shared_ptr<RsBroadcastDiscovery> rsBroadcastDiscovery;
struct RsBroadcastDiscoveryResult : RsSerializable
{
RsPeerId mSslId;
std::string mProfileName;
RsUrl mLocator;
/// @see RsSerializable
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override
{
RS_SERIAL_PROCESS(mSslId);
RS_SERIAL_PROCESS(mProfileName);
RS_SERIAL_PROCESS(mLocator);
}
RsBroadcastDiscoveryResult() = default;
RsBroadcastDiscoveryResult (const RsBroadcastDiscoveryResult&) = default;
~RsBroadcastDiscoveryResult() override;
};
/**
* @brief Event emitted when a non friend new peer is found in the local network
* @see RsEvents
*/
struct RsBroadcastDiscoveryPeerFoundEvent : RsEvent
{
RsBroadcastDiscoveryPeerFoundEvent(
const RsBroadcastDiscoveryResult& eventData ) :
RsEvent(RsEventType::BROADCAST_DISCOVERY_PEER_FOUND), mData(eventData) {}
RsBroadcastDiscoveryResult mData;
/// @see RsSerializable
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override
{
RsEvent::serial_process(j, ctx);
RS_SERIAL_PROCESS(mData);
}
~RsBroadcastDiscoveryPeerFoundEvent() override;
};
/**
* Announce own RetroShare instace and look friends and peers in own broadcast
* domain (aka LAN).
* Emit event @see RsBroadcastDiscoveryPeerFoundEvent when a new peer (not
* friend yet) is found.
*/
class RsBroadcastDiscovery
{
public:
/**
* @brief Get potential peers that have been discovered up until now
* @jsonapi{development}
* @return vector containing discovered peers, may be empty.
*/
virtual std::vector<RsBroadcastDiscoveryResult> getDiscoveredPeers() = 0;
virtual ~RsBroadcastDiscovery();
};

View File

@ -1,9 +1,9 @@
/*******************************************************************************
* libretroshare/src/retroshare: rsdht.h *
* RetroShare gossip discovery - discovery2 retro-compatibility include *
* *
* libretroshare: retroshare core library *
* *
* Copyright 2008-2008 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -19,66 +19,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef RETROSHARE_DISC_GUI_INTERFACE_H
#define RETROSHARE_DISC_GUI_INTERFACE_H
#pragma once
#include <inttypes.h>
#include <string>
#include <list>
#include <map>
#include <retroshare/rstypes.h>
#include "retroshare/rsgossipdiscovery.h"
#include "util/rsdeprecate.h"
/* The Main Interface Class - for information about your Peers */
class RsDisc;
#warning "Including retroshare/rsdisc.h is deprecated, \
use retroshare/rsgossipdiscovery.h instead"
/**
* Pointer to global instance of RsDisc service implementation
* @jsonapi{development}
*/
extern RsDisc *rsDisc;
using RsDisc RS_DEPRECATED_FOR("RsGossipDiscovery") = RsGossipDiscovery;
class RsDisc
{
public:
RsDisc() {}
virtual ~RsDisc() {}
/**
* @brief getDiscFriends get a list with all friends (ssl id) to a given friend (ssl id)
* @jsonapi{development}
* @param[in] id peer to get the friends of
* @param[out] friends list of friends (ssl id)
* @return true on success false otherwise
*/
virtual bool getDiscFriends(const RsPeerId &id, std::list<RsPeerId>& friends) = 0;
/**
* @brief getDiscPgpFriends get a list with all friends (pgp id) to a given friend (pgp id)
* @jsonapi{development}
* @param[in] pgpid peer to get the friends of
* @param[out] gpg_friends list of friends (gpg id)
* @return true on success false otherwise
*/
virtual bool getDiscPgpFriends(const RsPgpId &pgpid, std::list<RsPgpId>& gpg_friends) = 0;
/**
* @brief getPeerVersion get the version string of a peer.
* @jsonapi{development}
* @param[in] id peer to get the version string of
* @param[out] versions version string sent by the peer
* @return true on success false otherwise
*/
virtual bool getPeerVersion(const RsPeerId &id, std::string &versions) = 0;
/**
* @brief getWaitingDiscCount get the number of queued discovery packets.
* @jsonapi{development}
* @param[out] sendCount number of queued outgoing packets
* @param[out] recvCount number of queued incoming packets
* @return true on success false otherwise
*/
virtual bool getWaitingDiscCount(size_t &sendCount, size_t &recvCount) = 0;
};
#endif
#define rsDisc rsGossipDiscovery.get()

View File

@ -0,0 +1,169 @@
/*******************************************************************************
* Retroshare events service *
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include <memory>
#include <cstdint>
#include "util/rsmemory.h"
#include "serialiser/rsserializable.h"
#include "serialiser/rstypeserializer.h"
class RsEvents;
/**
* Pointer to global instance of RsEvents service implementation
* @jsonapi{development}
*
* TODO: this should become std::weak_ptr once we have a reasonable services
* management.
*/
extern RsEvents* rsEvents;
/**
* @brief Events types.
* When creating a new type of event, add a new type here and use that to
* initialize mType in the constructor of your derivative of @see RsEvent
*/
enum class RsEventType : uint32_t
{
NONE = 0, /// Used to detect uninitialized event
/// @see RsBroadcastDiscovery
BROADCAST_DISCOVERY_PEER_FOUND = 1,
/// @see RsDiscPendingPgpReceivedEvent
GOSSIP_DISCOVERY_INVITE_RECEIVED = 2,
/// @see AuthSSL
AUTHSSL_CONNECTION_AUTENTICATION = 3,
/// @see pqissl
REMOTE_PEER_REFUSED_CONNECTION = 4,
/// @see RsGxsChanges
GXS_CHANGES = 5,
/// Emitted when a peer state changes, @see RsPeers
PEER_STATE_CHANGED = 6,
MAX /// Used to detect invalid event type passed
};
/**
* This struct is not meant to be used directly, you should create events type
* deriving from it.
*/
struct RsEvent : RsSerializable
{
protected:
RsEvent(RsEventType type) :
mType(type), mTimePoint(std::chrono::system_clock::now()) {}
RsEvent() = delete;
public:
RsEventType mType;
std::chrono::system_clock::time_point mTimePoint;
/**
* Derived types must call this method at beginning of their implementation
* of serial_process
* @see RsSerializable
*/
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override
{
RS_SERIAL_PROCESS(mType);
rstime_t mTime = std::chrono::system_clock::to_time_t(mTimePoint);
RS_SERIAL_PROCESS(mTime);
mTimePoint = std::chrono::system_clock::from_time_t(mTime);
}
~RsEvent() override;
};
typedef uint32_t RsEventsHandlerId_t;
class RsEvents
{
public:
/**
* @brief Post event to the event queue.
* @param[in] event
* @param[out] errorMessage Optional storage for error messsage, meaningful
* only on failure.
* @return False on error, true otherwise.
*/
virtual bool postEvent(
std::shared_ptr<const RsEvent> event,
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
) = 0;
/**
* @brief Send event directly to handlers. Blocking API
* The handlers get exectuded on the caller thread.
* @param[in] event
* @param[out] errorMessage Optional storage for error messsage, meaningful
* only on failure.
* @return False on error, true otherwise.
*/
virtual bool sendEvent(
std::shared_ptr<const RsEvent> event,
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
) = 0;
/**
* @brief Generate unique handler identifier
* @return generate Id
*/
virtual RsEventsHandlerId_t generateUniqueHandlerId() = 0;
/**
* @brief Register events handler
* Every time an event is dispatced the registered events handlers will get
* their method handleEvent called with the event passed as paramether.
* @jsonapi{development,manualwrapper}
* @param multiCallback Function that will be called each time an event
* is dispatched.
* @param[inout] hId Optional storage for handler id, useful to
* eventually unregister the handler later. The
* value may be provided to the function call but
* must habe been generated with
* @see generateUniqueHandlerId()
* @return False on error, true otherwise.
*/
virtual bool registerEventsHandler(
std::function<void(std::shared_ptr<const RsEvent>)> multiCallback,
RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0)
) = 0;
/**
* @brief Unregister event handler
* @param[in] hId Id of the event handler to unregister
* @return True if the handler id has been found, false otherwise.
*/
virtual bool unregisterEventsHandler(RsEventsHandlerId_t hId) = 0;
virtual ~RsEvents();
};

View File

@ -3,7 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2008-2008 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2008 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -208,7 +209,7 @@ public:
virtual ~RsFiles() {}
/**
* Provides file data for the gui, media streaming or rpc clients.
* @brief Provides file data for the gui, media streaming or rpc clients.
* It may return unverified chunks. This allows streaming without having to
* wait for hashes or completion of the file.
* This function returns an unspecified amount of bytes. Either as much data
@ -224,7 +225,7 @@ public:
* @param[in] offset where the desired block starts
* @param[inout] requested_size size of pre-allocated data. Will be updated
* by the function.
* @param data pre-allocated memory chunk of size 'requested_size' by the
* @param[out] data pre-allocated memory chunk of size 'requested_size' by the
* client
* @return Returns false in case
* - the files is not available on the local node
@ -422,22 +423,47 @@ public:
* @brief Get details about the upload with given hash
* @jsonapi{development}
* @param[in] hash file identifier
* @param[in] peer_id peer identifier
* @param[in] peerId peer identifier
* @param[out] map storage for chunk info
* @return true if file found, false otherwise
*/
virtual bool FileUploadChunksDetails(
const RsFileHash& hash, const RsPeerId& peer_id,
const RsFileHash& hash, const RsPeerId& peerId,
CompressedChunkMap& map ) = 0;
/***
* Extra List Access
***/
//virtual bool ExtraFileAdd(std::string fname, std::string hash, uint64_t size, uint32_t period, TransferRequestFlags flags) = 0;
virtual bool ExtraFileRemove(const RsFileHash& hash) = 0;
virtual bool ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags) = 0;
virtual bool ExtraFileStatus(std::string localpath, FileInfo &info) = 0;
virtual bool ExtraFileMove(std::string fname, const RsFileHash& hash, uint64_t size, std::string destpath) = 0;
/**
* @brief Remove file from extra fila shared list
* @jsonapi{development}
* @param[in] hash hash of the file to remove
* @return return false on error, true otherwise
*/
virtual bool ExtraFileRemove(const RsFileHash& hash) = 0;
/**
* @brief Add file to extra shared file list
* @jsonapi{development}
* @param[in] localpath path of the file
* @param[in] period how much time the file will be kept in extra list in
* seconds
* @param[in] flags sharing policy flags ex: RS_FILE_REQ_ANONYMOUS_ROUTING
* @return false on error, true otherwise
*/
virtual bool ExtraFileHash(
std::string localpath, rstime_t period, TransferRequestFlags flags
) = 0;
/**
* @brief Get extra file information
* @jsonapi{development}
* @param[in] localpath path of the file
* @param[out] info storage for the file information
* @return false on error, true otherwise
*/
virtual bool ExtraFileStatus(std::string localpath, FileInfo &info) = 0;
virtual bool ExtraFileMove(
std::string fname, const RsFileHash& hash, uint64_t size,
std::string destpath ) = 0;
/**
* @brief Request directory details, subsequent multiple call may be used to

View File

@ -1,6 +1,37 @@
/*******************************************************************************
* libretroshare/src/retroshare: rsflags.h *
* *
* libretroshare: retroshare core library *
* *
* Copyright 2012-2019 by Retroshare Team <contact@retroshare.cc> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include <stdint.h>
#include <cstdint>
/* G10h4ck: TODO we should redefine flags in a way that the flag declaration and
* the flags values (bit fields) would be strongly logically linked.
* A possible way is to take an enum class containing the names of each
* bitfield and corresponding value as template parameter, this way would also
* avoid the need of dumb template parameter that is used only to make the
* types incompatible but that doesn't help finding what are the possible values
* for a kind of flag. Another appealing approach seems the first one described
* here https://softwareengineering.stackexchange.com/questions/194412/using-scoped-enums-for-bit-flags-in-c
* a few simple macros could be used instead of the template class */
// This class provides a representation for flags that can be combined with bitwise
// operations. However, because the class is templated with an id, it's not possible to

View File

@ -0,0 +1,106 @@
/*******************************************************************************
* RetroShare remote peers gossip discovery *
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2008 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include <cstdint>
#include <string>
#include <list>
#include <map>
#include "retroshare/rstypes.h"
#include "retroshare/rsevents.h"
#include "util/rsmemory.h"
class RsGossipDiscovery;
/**
* Pointer to global instance of RsGossipDiscovery service implementation
* @jsonapi{development}
*
* TODO: this should become std::weak_ptr once we have a reasonable services
* management.
*/
extern std::shared_ptr<RsGossipDiscovery> rsGossipDiscovery;
/**
* @brief Emitted when a pending PGP certificate is received
*/
struct RsGossipDiscoveryFriendInviteReceivedEvent : RsEvent
{
RsGossipDiscoveryFriendInviteReceivedEvent(
const std::string& invite );
std::string mInvite;
/// @see RsSerializable
virtual void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RsEvent::serial_process(j,ctx);
RS_SERIAL_PROCESS(mInvite);
}
};
class RsGossipDiscovery
{
public:
virtual ~RsGossipDiscovery() = default;
/**
* @brief getDiscFriends get a list of all friends of a given friend
* @jsonapi{development}
* @param[in] id peer to get the friends of
* @param[out] friends list of friends (ssl id)
* @return true on success false otherwise
*/
virtual bool getDiscFriends( const RsPeerId& id,
std::list<RsPeerId>& friends ) = 0;
/**
* @brief getDiscPgpFriends get a list of all friends of a given friend
* @jsonapi{development}
* @param[in] pgpid peer to get the friends of
* @param[out] gpg_friends list of friends (gpg id)
* @return true on success false otherwise
*/
virtual bool getDiscPgpFriends(
const RsPgpId& pgpid, std::list<RsPgpId>& gpg_friends ) = 0;
/**
* @brief getPeerVersion get the version string of a peer.
* @jsonapi{development}
* @param[in] id peer to get the version string of
* @param[out] version version string sent by the peer
* @return true on success false otherwise
*/
virtual bool getPeerVersion(const RsPeerId& id, std::string& version) = 0;
/**
* @brief getWaitingDiscCount get the number of queued discovery packets.
* @jsonapi{development}
* @param[out] sendCount number of queued outgoing packets
* @param[out] recvCount number of queued incoming packets
* @return true on success false otherwise
*/
virtual bool getWaitingDiscCount(size_t& sendCount, size_t& recvCount) = 0;
};

View File

@ -47,6 +47,8 @@ extern RsGxsChannels* rsGxsChannels;
struct RsGxsChannelGroup : RsSerializable
{
RsGxsChannelGroup() : mAutoDownload(false) {}
RsGroupMetaData mMeta;
std::string mDescription;
RsGxsImage mImage;
@ -140,10 +142,13 @@ public:
* posted
* @param[in] threadId Id of the post (that is a thread) in the channel
* where the comment is placed
* @param[in] comment UTF-8 string containing the comment itself
* @param[in] authorId Id of the author of the comment
* @param[in] parentId Id of the parent of the comment that is either a
* channel post Id or the Id of another comment.
* @param[in] authorId Id of the author of the comment
* @param[in] comment UTF-8 string containing the comment itself
* @param[in] origCommentId If this is supposed to replace an already
* existent comment, the id of the old post.
* If left blank a new post will be created.
* @param[out] commentMessageId Optional storage for the id of the comment
* that was created, meaningful only on success.
* @param[out] errorMessage Optional storage for error message, meaningful
@ -153,9 +158,10 @@ public:
virtual bool createCommentV2(
const RsGxsGroupId& channelId,
const RsGxsMessageId& threadId,
const RsGxsMessageId& parentId,
const RsGxsId& authorId,
const std::string& comment,
const RsGxsId& authorId,
const RsGxsMessageId& parentId = RsGxsMessageId(),
const RsGxsMessageId& origCommentId = RsGxsMessageId(),
RsGxsMessageId& commentMessageId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
) = 0;

View File

@ -3,8 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2012 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2012-2014 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -32,6 +32,7 @@
#include "retroshare/rsgxsifacehelper.h"
#include "retroshare/rsidentity.h"
#include "serialiser/rsserializable.h"
#include "util/rsmemory.h"
class RsGxsCircles;
@ -74,8 +75,6 @@ static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_ALLOWED = 0x0007 ;// user
struct RsGxsCircleGroup : RsSerializable
{
virtual ~RsGxsCircleGroup() {}
RsGroupMetaData mMeta;
std::set<RsPgpId> mLocalFriends;
@ -95,17 +94,17 @@ struct RsGxsCircleGroup : RsSerializable
RS_SERIAL_PROCESS(mInvitedMembers);
RS_SERIAL_PROCESS(mSubCircles);
}
~RsGxsCircleGroup() override;
};
struct RsGxsCircleMsg : RsSerializable
{
virtual ~RsGxsCircleMsg() {}
RsMsgMetaData mMeta;
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_UNNAMED
/* This is horrible and should be changed into yet to be defined something
* reasonable in next non retrocompatible version */
* reasonable in next non-retrocompatible version */
std::string stuff;
#endif
@ -116,6 +115,8 @@ struct RsGxsCircleMsg : RsSerializable
RS_SERIAL_PROCESS(mMeta);
RS_SERIAL_PROCESS(stuff);
}
~RsGxsCircleMsg() override;
};
struct RsGxsCircleDetails : RsSerializable
@ -123,7 +124,7 @@ struct RsGxsCircleDetails : RsSerializable
RsGxsCircleDetails() :
mCircleType(static_cast<uint32_t>(RsGxsCircleType::EXTERNAL)),
mAmIAllowed(false) {}
~RsGxsCircleDetails() override {}
~RsGxsCircleDetails() override;
RsGxsCircleId mCircleId;
std::string mCircleName;
@ -162,16 +163,29 @@ class RsGxsCircles: public RsGxsIfaceHelper
public:
RsGxsCircles(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {}
virtual ~RsGxsCircles() {}
virtual ~RsGxsCircles();
/**
* @brief Create new circle
* @jsonapi{development}
* @param[inout] cData input name and flags of the circle, storage for
* generated circle data id etc.
* @param[in] circleName String containing cirlce name
* @param[in] circleType Circle type
* @param[out] circleId Optional storage to output created circle id
* @param[in] restrictedId Optional id of a pre-existent circle that see the
* created circle. Meaningful only if circleType == EXTERNAL, must be null
* in all other cases.
* @param[in] authorId Optional author of the circle.
* @param[in] gxsIdMembers GXS ids of the members of the circle.
* @param[in] localMembers PGP ids of the members if the circle.
* @return false if something failed, true otherwhise
*/
virtual bool createCircle(RsGxsCircleGroup& cData) = 0;
virtual bool createCircle(
const std::string& circleName, RsGxsCircleType circleType,
RsGxsCircleId& circleId = RS_DEFAULT_STORAGE_PARAM(RsGxsCircleId),
const RsGxsCircleId& restrictedId = RsGxsCircleId(),
const RsGxsId& authorId = RsGxsId(),
const std::set<RsGxsId>& gxsIdMembers = std::set<RsGxsId>(),
const std::set<RsPgpId>& localMembers = std::set<RsPgpId>() ) = 0;
/**
* @brief Edit own existing circle

View File

@ -142,19 +142,6 @@ struct RsGxsComment : RsSerializable
RS_SERIAL_PROCESS(mOwnVote);
RS_SERIAL_PROCESS(mVotes);
}
const std::ostream &print(std::ostream &out, std::string indent = "", std::string varName = "") const {
out << indent << varName << " of RsGxsComment Values ###################" << std::endl;
mMeta.print(out, indent + " ", "mMeta");
out << indent << " mComment: " << mComment << std::endl;
out << indent << " mUpVotes: " << mUpVotes << std::endl;
out << indent << " mDownVotes: " << mDownVotes << std::endl;
out << indent << " mScore: " << mScore << std::endl;
out << indent << " mOwnVote: " << mOwnVote << std::endl;
out << indent << " mVotes.size(): " << mVotes.size() << std::endl;
out << indent << "######################################################" << std::endl;
return out;
}
};

View File

@ -52,12 +52,11 @@ namespace GXS_SERV {
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_MASK = 0x0000ff00;
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_NONE = 0x00000000;
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_GPG = 0x00000100; // Anti-spam feature. Allows to ask higher reputation to anonymous IDs
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_REQUIRED = 0x00000200; // unused
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_REQUIRED = 0x00000200;
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN = 0x00000400; // ???
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES = 0x00000800; // not used anymore
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN = 0x00001000; // Anti-spam feature. Allows to ask higher reputation to unknown IDs and anonymous IDs
// These are *not used*
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_MASK = 0x000000ff;
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED = 0x00000001;
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED = 0x00000002; // unused

View File

@ -3,8 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2012 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2012-2014 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -30,9 +30,9 @@
#include "retroshare/rsgxsifacehelper.h"
#include "serialiser/rstlvidset.h"
#include "serialiser/rsserializable.h"
#include "retroshare/rsgxscircles.h"
/* The Main Interface Class - for information about your Peers */
class RsGxsForums;
/**
@ -43,8 +43,10 @@ extern RsGxsForums* rsGxsForums;
/** Forum Service message flags, to be used in RsMsgMetaData::mMsgFlags
* Gxs imposes to use the first two bytes (lower bytes) of mMsgFlags for
* Gxs imposes to use the first two bytes (lower bytes) of mMsgFlags for
* private forum flags, the upper bytes being used for internal GXS stuff.
* @todo mixing service level flags and GXS level flag into the same member is
* prone to confusion, use separated members for those things
*/
static const uint32_t RS_GXS_FORUM_MSG_FLAGS_MASK = 0x0000000f;
static const uint32_t RS_GXS_FORUM_MSG_FLAGS_MODERATED = 0x00000001;
@ -54,46 +56,52 @@ static const uint32_t RS_GXS_FORUM_MSG_FLAGS_MODERATED = 0x00000001;
struct RsGxsForumGroup : RsSerializable
{
virtual ~RsGxsForumGroup() {}
/** Forum GXS metadata */
RsGroupMetaData mMeta;
/** @brief Forum desciption */
std::string mDescription;
/* What's below is optional, and handled by the serialiser
* TODO: run away from TLV old serializables as those types are opaque to
* JSON API! */
/** @brief List of forum moderators ids
* @todo run away from TLV old serializables as those types are opaque to
* JSON API! */
RsTlvGxsIdSet mAdminList;
/** @brief List of forum pinned posts, those are usually displayed on top
* @todo run away from TLV old serializables as those types are opaque to
* JSON API! */
RsTlvGxsMsgIdSet mPinnedPosts;
/// @see RsSerializable
virtual void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(mMeta);
RS_SERIAL_PROCESS(mDescription);
RS_SERIAL_PROCESS(mAdminList);
RS_SERIAL_PROCESS(mPinnedPosts);
}
virtual void serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override;
// utility functions
~RsGxsForumGroup() override;
bool canEditPosts(const RsGxsId& id) const { return mAdminList.ids.find(id) != mAdminList.ids.end() || id == mMeta.mAuthorId; }
/* G10h4ck: We should avoid actual methods in this contexts as they are
* invisible to JSON API */
bool canEditPosts(const RsGxsId& id) const;
};
struct RsGxsForumMsg : RsSerializable
{
virtual ~RsGxsForumMsg() {}
/** @brief Forum post GXS metadata */
RsMsgMetaData mMeta;
/** @brief Forum post content */
std::string mMsg;
/// @see RsSerializable
virtual void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
virtual void serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override
{
RS_SERIAL_PROCESS(mMeta);
RS_SERIAL_PROCESS(mMsg);
}
~RsGxsForumMsg() override;
};
@ -101,23 +109,67 @@ class RsGxsForums: public RsGxsIfaceHelper
{
public:
explicit RsGxsForums(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {}
virtual ~RsGxsForums() {}
virtual ~RsGxsForums();
/**
* @brief Create forum. Blocking API.
* @brief Create forum.
* @jsonapi{development}
* @param[inout] forum Forum data (name, description...)
* @return false on error, true otherwise
* @param[in] name Name of the forum
* @param[in] description Optional description of the forum
* @param[in] authorId Optional id of the froum owner author
* @param[in] moderatorsIds Optional list of forum moderators
* @param[in] circleType Optional visibility rule, default public.
* @param[in] circleId If the forum is not public specify the id of
* the circle who can see the forum. Depending on
* the value you pass for circleType this should
* be a circle if EXTERNAL is passed, a local
* friends group id if NODES_GROUP is passed,
* empty otherwise.
* @param[out] forumId Optional storage for the id of the created
* forum, meaningful only if creations succeeds.
* @param[out] errorMessage Optional storage for error messsage, meaningful
* only if creation fail.
* @return False on error, true otherwise.
*/
virtual bool createForum(RsGxsForumGroup& forum) = 0;
virtual bool createForumV2(
const std::string& name, const std::string& description,
const RsGxsId& authorId = RsGxsId(),
const std::set<RsGxsId>& moderatorsIds = std::set<RsGxsId>(),
RsGxsCircleType circleType = RsGxsCircleType::PUBLIC,
const RsGxsCircleId& circleId = RsGxsCircleId(),
RsGxsGroupId& forumId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId),
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
) = 0;
/**
* @brief Create forum message. Blocking API.
* @brief Create a post on the given forum.
* @jsonapi{development}
* @param[inout] message
* @param[in] forumId Id of the forum in which the post is to be
* submitted
* @param[in] title UTF-8 string containing the title of the post
* @param[in] mBody UTF-8 string containing the text of the post
* @param[in] authorId Id of the author of the comment
* @param[in] parentId Optional Id of the parent post if this post is a
* reply to another post, empty otherwise.
* @param[in] origPostId If this is supposed to replace an already
* existent post, the id of the old post.
* If left blank a new post will be created.
* @param[out] postMsgId Optional storage for the id of the created,
* meaningful only on success.
* @param[out] errorMessage Optional storage for error message, meaningful
* only on failure.
* @return false on error, true otherwise
*/
virtual bool createMessage(RsGxsForumMsg& message) = 0;
virtual bool createPost(
const RsGxsGroupId& forumId,
const std::string& title,
const std::string& mBody,
const RsGxsId& authorId,
const RsGxsMessageId& parentId = RsGxsMessageId(),
const RsGxsMessageId& origPostId = RsGxsMessageId(),
RsGxsMessageId& postMsgId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
) = 0;
/**
* @brief Edit forum details.
@ -167,7 +219,7 @@ public:
*/
virtual bool getForumContent(
const RsGxsGroupId& forumId,
std::set<RsGxsMessageId>& msgsIds,
const std::set<RsGxsMessageId>& msgsIds,
std::vector<RsGxsForumMsg>& msgs) = 0;
/**
@ -189,6 +241,26 @@ public:
virtual bool subscribeToForum( const RsGxsGroupId& forumId,
bool subscribe ) = 0;
/**
* @brief Create forum. Blocking API.
* @jsonapi{development}
* @param[inout] forum Forum data (name, description...)
* @return false on error, true otherwise
* @deprecated @see createForumV2
*/
RS_DEPRECATED_FOR(createForumV2)
virtual bool createForum(RsGxsForumGroup& forum) = 0;
/**
* @brief Create forum message. Blocking API.
* @jsonapi{development}
* @param[inout] message
* @return false on error, true otherwise
* @deprecated @see createPost
*/
RS_DEPRECATED_FOR(createPost)
virtual bool createMessage(RsGxsForumMsg& message) = 0;
/* Specific Service Data */
RS_DEPRECATED_FOR("getForumsSummaries, getForumsInfo")
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups) = 0;
@ -203,4 +275,3 @@ public:
RS_DEPRECATED_FOR(editForum)
virtual bool updateGroup(uint32_t &token, RsGxsForumGroup &group) = 0;
};

View File

@ -3,7 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2012 by Christopher Evi-Parker *
* Copyright (C) 2012 Christopher Evi-Parker *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -19,9 +20,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef RSGXSIFACE_H_
#define RSGXSIFACE_H_
#pragma once
#include "retroshare/rsreputations.h"
#include "retroshare/rsgxsservice.h"
@ -29,6 +28,8 @@
#include "retroshare/rsgxsifacetypes.h"
#include "util/rsdeprecate.h"
#include "serialiser/rsserializable.h"
#include "rsitems/rsserviceids.h"
#include "retroshare/rsevents.h"
/*!
* This structure is used to transport group summary information when a GXS
@ -71,17 +72,35 @@ struct RsGxsGroupSummary : RsSerializable
/*!
* Stores ids of changed gxs groups and messages. It is used to notify the GUI about changes.
* Stores ids of changed gxs groups and messages.
* It is used to notify about GXS changes.
*/
struct RsGxsChanges
struct RsGxsChanges : RsEvent
{
RsGxsChanges(): mService(0){}
RsTokenService *mService;
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > mMsgs;
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > mMsgsMeta;
std::list<RsGxsGroupId> mGrps;
std::list<RsGxsGroupId> mGrpsMeta;
std::list<TurtleRequestId> mDistantSearchReqs;
RsGxsChanges();
/// Type of the service
RsServiceType mServiceType;
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > mMsgs;
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > mMsgsMeta;
std::list<RsGxsGroupId> mGrps;
std::list<RsGxsGroupId> mGrpsMeta;
std::list<TurtleRequestId> mDistantSearchReqs;
/// @see RsSerializable
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override
{
RsEvent::serial_process(j,ctx);
RS_SERIAL_PROCESS(mServiceType);
RS_SERIAL_PROCESS(mMsgs);
RS_SERIAL_PROCESS(mMsgsMeta);
RS_SERIAL_PROCESS(mGrps);
RS_SERIAL_PROCESS(mGrpsMeta);
RS_SERIAL_PROCESS(mDistantSearchReqs);
}
RsTokenService* mService; /// Weak pointer, not serialized
};
/*!
@ -220,7 +239,3 @@ struct RsGxsIface
virtual RsReputationLevel minReputationForForwardingMessages(
uint32_t group_sign_flags,uint32_t identity_flags ) = 0;
};
#endif /* RSGXSIFACE_H_ */

View File

@ -34,10 +34,7 @@
#include "serialiser/rstypeserializer.h"
#include "util/rstime.h"
typedef GXSGroupId RsGxsGroupId;
typedef Sha1CheckSum RsGxsMessageId;
typedef GXSId RsGxsId;
typedef GXSCircleId RsGxsCircleId;
typedef std::map<RsGxsGroupId, std::set<RsGxsMessageId> > GxsMsgIdResult;
typedef std::pair<RsGxsGroupId, RsGxsMessageId> RsGxsGrpMsgIdPair;
@ -143,14 +140,20 @@ struct RsMsgMetaData : RsSerializable
std::string mMsgName;
rstime_t mPublishTs;
/// the lower 16 bits for service, upper 16 bits for GXS
uint32_t mMsgFlags;
/** the lower 16 bits for service, upper 16 bits for GXS
* @todo mixing service level flags and GXS level flag into the same member
* is prone to confusion, use separated members for those things, this could
* be done without breaking network retro-compatibility */
uint32_t mMsgFlags;
// BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG.
// normally READ / UNREAD flags. LOCAL Data.
/// the first 16 bits for service, last 16 for GXS
uint32_t mMsgStatus;
/** the first 16 bits for service, last 16 for GXS
* @todo mixing service level flags and GXS level flag into the same member
* is prone to confusion, use separated members for those things, this could
* be done without breaking network retro-compatibility */
uint32_t mMsgStatus;
rstime_t mChildTs;
std::string mServiceString; // Service Specific Free-Form extra storage.
@ -172,25 +175,6 @@ struct RsMsgMetaData : RsSerializable
RS_SERIAL_PROCESS(mChildTs);
RS_SERIAL_PROCESS(mServiceString);
}
const std::ostream &print(std::ostream &out, std::string indent = "", std::string varName = "") const {
out
<< indent << varName << " of RsMsgMetaData Values ###################" << std::endl
<< indent << " mGroupId: " << mGroupId.toStdString() << std::endl
<< indent << " mMsgId: " << mMsgId.toStdString() << std::endl
<< indent << " mThreadId: " << mThreadId.toStdString() << std::endl
<< indent << " mParentId: " << mParentId.toStdString() << std::endl
<< indent << " mOrigMsgId: " << mOrigMsgId.toStdString() << std::endl
<< indent << " mAuthorId: " << mAuthorId.toStdString() << std::endl
<< indent << " mMsgName: " << mMsgName << std::endl
<< indent << " mPublishTs: " << mPublishTs << std::endl
<< indent << " mMsgFlags: " << std::hex << mMsgFlags << std::dec << std::endl
<< indent << " mMsgStatus: " << std::hex << mMsgStatus << std::dec << std::endl
<< indent << " mChildTs: " << mChildTs << std::endl
<< indent << " mServiceString: " << mServiceString << std::endl
<< indent << "######################################################" << std::endl;
return out;
}
};
class GxsGroupStatistic

View File

@ -1,3 +1,23 @@
/*******************************************************************************
* libretroshare/src/retroshare: rsgxstrans.h *
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2016-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version 3 as *
* published by the Free Software Foundation. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include "retroshare/rstokenservice.h"
@ -41,7 +61,8 @@ enum class GxsTransSendStatus : uint8_t
/// Records with status >= RECEIPT_RECEIVED get deleted
RECEIPT_RECEIVED = 0x0a,
FAILED_RECEIPT_SIGNATURE = 0xf0,
FAILED_ENCRYPTION = 0xf1
FAILED_ENCRYPTION = 0xf1,
FAILED_TIMED_OUT = 0xf2
};
typedef uint64_t RsGxsTransId;
@ -79,6 +100,7 @@ struct RsGxsTransOutgoingRecord
RsGxsGroupId group_id ;
};
/// RetroShare GxsTrans asyncronous redundant small mail trasport on top of GXS
class RsGxsTrans: public RsGxsIfaceHelper
{
public:

View File

@ -29,8 +29,6 @@
class RsGxsTunnelService
{
public:
typedef GXSTunnelId RsGxsTunnelId ;
enum {
RS_GXS_TUNNEL_ERROR_NO_ERROR = 0x0000,
RS_GXS_TUNNEL_ERROR_UNKNOWN_GXS_ID = 0x0001

View File

@ -151,11 +151,9 @@ struct RsGxsIdGroup : RsSerializable
RsGenericSerializer::SerializeContext& ctx ) override;
};
std::ostream &operator<<(std::ostream &out, const RsGxsIdGroup &group);
// DATA TYPE FOR EXTERNAL INTERFACE.
struct RsRecognTag
struct RS_DEPRECATED RsRecognTag
{
RsRecognTag(uint16_t tc, uint16_t tt, bool v) :
tag_class(tc), tag_type(tt), valid(v) {}
@ -166,7 +164,7 @@ struct RsRecognTag
};
struct RsRecognTagDetails
struct RS_DEPRECATED RsRecognTagDetails
{
RsRecognTagDetails() :
valid_from(0), valid_to(0), tag_class(0), tag_type(0), is_valid(false),
@ -246,14 +244,22 @@ struct RsIdentityUsage : RsSerializable
CIRCLE_MEMBERSHIP_CHECK = 0x13
} ;
RS_DEPRECATED
RsIdentityUsage( uint16_t service, const RsIdentityUsage::UsageCode& code,
const RsGxsGroupId& gid = RsGxsGroupId(),
const RsGxsMessageId& mid = RsGxsMessageId(),
uint64_t additional_id=0,
const std::string& comment = std::string() );
RsIdentityUsage( RsServiceType service,
RsIdentityUsage::UsageCode code,
const RsGxsGroupId& gid = RsGxsGroupId(),
const RsGxsMessageId& mid = RsGxsMessageId(),
uint64_t additional_id=0,
const std::string& comment = std::string() );
/// Id of the service using that identity, as understood by rsServiceControl
uint16_t mServiceId;
RsServiceType mServiceId;
/** Specific code to use. Will allow forming the correct translated message
* in the GUI if necessary. */
@ -382,6 +388,7 @@ struct RsIdentity : RsGxsIfaceHelper
/**
* @brief Get identity details, from the cache
* @jsonapi{development}
* @param[in] id Id of the identity
* @param[out] details Storage for the identity details
* @return false on error, true otherwise
@ -402,7 +409,7 @@ struct RsIdentity : RsGxsIfaceHelper
* @param[out] ids storage for the ids
* @return false on error, true otherwise
*/
virtual bool getOwnSignedIds(std::vector<RsGxsId> ids) = 0;
virtual bool getOwnSignedIds(std::vector<RsGxsId>& ids) = 0;
/**
* @brief Get own pseudonimous (unsigned) ids
@ -410,7 +417,7 @@ struct RsIdentity : RsGxsIfaceHelper
* @param[out] ids storage for the ids
* @return false on error, true otherwise
*/
virtual bool getOwnPseudonimousIds(std::vector<RsGxsId> ids) = 0;
virtual bool getOwnPseudonimousIds(std::vector<RsGxsId>& ids) = 0;
/**
* @brief Check if an id is own
@ -470,6 +477,7 @@ struct RsIdentity : RsGxsIfaceHelper
/**
* @brief Set/unset identity as contact
* @jsonapi{development}
* @param[in] id Id of the identity
* @param[in] isContact true to set, false to unset
* @return false on error, true otherwise
@ -505,6 +513,14 @@ struct RsIdentity : RsGxsIfaceHelper
*/
virtual void setDeleteBannedNodesThreshold(uint32_t days) = 0;
/**
* @brief request details of a not yet known identity to the network
* @jsonapi{development}
* @param[in] id id of the identity to request
* @return false on error, true otherwise
*/
virtual bool requestIdentity(const RsGxsId& id) = 0;
RS_DEPRECATED
virtual bool getGroupSerializedData(

View File

@ -3,7 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2013 by Cyril Soler <csoler@users.sourceforge.net> *
* Copyright (C) 2013 Cyril Soler <csoler@users.sourceforge.net> *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -19,35 +20,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
// This class aims at defining a generic ID type that is a list of bytes. It
// can be converted into a hexadecial string for printing, mainly) or for
// compatibility with old methods.
//
// To use this class, derive your own ID type from it. Examples include:
//
// class RsPgpId: public t_RsGenericIdType<8>
// {
// [..]
// };
//
// class PGPFingerprintType: public t_RsGenericIdType<20>
// {
// [..]
// };
//
// With this, there is no implicit conversion between subtypes, and therefore ID mixup
// is impossible.
//
// A simpler way to make ID types is to
// typedef t_RsGenericIdType<MySize> MyType ;
//
// ID Types with different lengths will be incompatible on compilation.
//
// Warning: never store references to a t_RsGenericIdType accross threads, since the
// cached string convertion is not thread safe.
//
#pragma once
#include <stdexcept>
@ -55,125 +27,213 @@
#include <iostream>
#include <ostream>
#include <string.h>
#include <stdint.h>
#include <util/rsrandom.h>
#include <cstdint>
#include <vector>
#include <list>
#include <set>
#include <memory>
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> class t_RsGenericIdType
#include "util/rsdebug.h"
#include "util/rsrandom.h"
#include "util/stacktrace.h"
/**
* RsGenericIdType values might be random, but must be different, in order to
* make the various IDs incompatible with each other.
*/
enum class RsGenericIdType
{
public:
typedef std::list<t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> > std_list;
typedef std::vector<t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> > std_vector;
typedef std::set<t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> > std_set;
t_RsGenericIdType()
{
memset(bytes,0,ID_SIZE_IN_BYTES) ; // by default, ids are set to null()
}
virtual ~t_RsGenericIdType() {}
// Explicit constructor from a hexadecimal string
//
explicit t_RsGenericIdType(const std::string& hex_string) ;
// Explicit constructor from a byte array. The array should have size at least ID_SIZE_IN_BYTES
//
explicit t_RsGenericIdType(const unsigned char bytes[]) ;
// Explicit constructor from a different type, checking that the sizes are compatible.
// This is used for conversions such as
//
// GroupId -> CircleId
// GroupId -> GxsId
//
template<bool UPPER_CASE2,uint32_t UNIQUE_IDENTIFIER2>
explicit t_RsGenericIdType(const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE2,UNIQUE_IDENTIFIER2>& id)
{
memcpy(bytes,id.toByteArray(),ID_SIZE_IN_BYTES) ;
}
// Random initialization. Can be useful for testing and to generate new ids.
//
static t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> random()
{
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> id ;
RSRandom::random_bytes(id.bytes,ID_SIZE_IN_BYTES) ;
return id ;
}
inline void clear() { memset(bytes,0,SIZE_IN_BYTES) ; }
// Converts to a std::string using cached value.
//
const unsigned char *toByteArray() const { return &bytes[0] ; }
static const uint32_t SIZE_IN_BYTES = ID_SIZE_IN_BYTES ;
inline bool operator==(const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& fp) const { return !memcmp(bytes,fp.bytes,ID_SIZE_IN_BYTES) ; }
inline bool operator!=(const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& fp) const { return !!memcmp(bytes,fp.bytes,ID_SIZE_IN_BYTES); }
inline bool operator< (const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& fp) const { return (memcmp(bytes,fp.bytes,ID_SIZE_IN_BYTES) < 0) ; }
inline t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>
operator~ () const
{
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> ret;
for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i)
ret.bytes[i] = ~bytes[i];
return ret;
}
inline t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>
operator| (const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& fp) const
{
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> ret;
for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i)
ret.bytes[i] = bytes[i] | fp.bytes[i];
return ret;
}
inline bool isNull() const
{
for(uint32_t i=0;i<SIZE_IN_BYTES;++i)
if(bytes[i] != 0)
return false ;
return true ;
}
friend std::ostream& operator<<(std::ostream& out,const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& id)
{
return out << id.toStdString(UPPER_CASE) ;
}
inline std::string toStdString() const { return toStdString(UPPER_CASE) ; }
inline static uint32_t serial_size() { return SIZE_IN_BYTES ; }
bool serialise(void *data,uint32_t pktsize,uint32_t& offset) const
{
if(offset + SIZE_IN_BYTES > pktsize)
return false ;
memcpy(&((uint8_t*)data)[offset],bytes,SIZE_IN_BYTES) ;
offset += SIZE_IN_BYTES ;
return true ;
}
bool deserialise(const void *data,uint32_t pktsize,uint32_t& offset)
{
if(offset + SIZE_IN_BYTES > pktsize)
return false ;
memcpy(bytes,&((uint8_t*)data)[offset],SIZE_IN_BYTES) ;
offset += SIZE_IN_BYTES ;
return true ;
}
private:
std::string toStdString(bool upper_case) const ;
unsigned char bytes[ID_SIZE_IN_BYTES] ;
SSL,
PGP_ID,
SHA1,
PGP_FINGERPRINT,
GXS_GROUP,
GXS_ID,
GXS_MSG,
GXS_CIRCLE,
GROUTER,
GXS_TUNNEL,
DISTANT_CHAT,
NODE_GROUP,
SHA256,
BIAS_20_BYTES
};
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> std::string t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>::toStdString(bool upper_case) const
/**
* This class aims at defining a generic ID type that is a list of bytes. It
* can be converted into a hexadecial string for printing, mainly) or for
* compatibility with old methods.
*
* To use this class, derive your own ID type from it.
* @see RsPpgFingerprint as an example.
*
* Take care to define and use a different @see RsGenericIdType for each ne type
* of ID you create, to avoid implicit conversion between subtypes, and
* therefore accidental ID mixup is impossible.
*
* ID Types with different lengths are not convertible even using explicit
* constructor and compilation would fail if that is attempted.
*
* Warning: never store references to a t_RsGenericIdType accross threads, since
* the cached string convertion is not thread safe.
*/
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
struct t_RsGenericIdType
{
using Id_t = t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>;
using std_list = std::list<Id_t>;
using std_vector = std::vector<Id_t>;
using std_set = std::set<Id_t>;
/// by default, ids are set to null()
t_RsGenericIdType() { memset(bytes, 0, ID_SIZE_IN_BYTES); }
/// Explicit constructor from a hexadecimal string
explicit t_RsGenericIdType(const std::string& hex_string);
/**
* @brief Construct from a buffer of at least the size of SIZE_IN_BYTES
* This is dangerous if used without being absolutely sure of buffer size,
* nothing prevent a buffer of wrong size being passed at runtime!
* @param[in] buff pointer to the buffer
* @return empty id on failure, an id initialized from the bytes in the
* buffer
*/
static Id_t fromBufferUnsafe(const uint8_t* buff)
{
Id_t ret;
if(!buff)
{
RsErr() << __PRETTY_FUNCTION__ << " invalid paramethers buff: "
<< buff << std::endl;
print_stacktrace();
return ret;
}
memmove(ret.bytes, buff, SIZE_IN_BYTES);
return ret;
}
/**
* Explicit constructor from a different type but with same size.
*
* This is used for conversions such as
* GroupId -> CircleId
* GroupId -> GxsId
*/
template<bool UPPER_CASE2, RsGenericIdType UNIQUE_IDENTIFIER2>
explicit t_RsGenericIdType(
const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE2, UNIQUE_IDENTIFIER2>&
id )
{ memmove(bytes, id.toByteArray(), ID_SIZE_IN_BYTES); }
/// Random initialization. Can be useful for testing and to generate new ids.
static Id_t random()
{
Id_t id;
RsRandom::random_bytes(id.bytes, ID_SIZE_IN_BYTES);
return id;
}
inline void clear() { memset(bytes, 0, SIZE_IN_BYTES); }
/// Converts to a std::string using cached value.
const uint8_t* toByteArray() const { return &bytes[0]; }
static constexpr uint32_t SIZE_IN_BYTES = ID_SIZE_IN_BYTES;
inline bool operator==(const Id_t& fp) const
{ return !memcmp(bytes, fp.bytes, ID_SIZE_IN_BYTES); }
inline bool operator!=(const Id_t& fp) const
{ return !!memcmp(bytes, fp.bytes, ID_SIZE_IN_BYTES); }
inline bool operator< (const Id_t& fp) const
{ return (memcmp(bytes, fp.bytes, ID_SIZE_IN_BYTES) < 0); }
inline Id_t operator~ () const
{
Id_t ret;
for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i)
ret.bytes[i] = ~bytes[i];
return ret;
}
inline Id_t operator| (const Id_t& fp) const
{
Id_t ret;
for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i)
ret.bytes[i] = bytes[i] | fp.bytes[i];
return ret;
}
inline bool isNull() const
{
for(uint32_t i=0; i < SIZE_IN_BYTES; ++i)
if(bytes[i] != 0) return false;
return true;
}
friend std::ostream& operator<<(std::ostream& out, const Id_t& id)
{
switch (UNIQUE_IDENTIFIER)
{
case RsGenericIdType::PGP_FINGERPRINT:
{
uint8_t index = 0;
for(char c : id.toStdString())
{
out << c;
if(++index % 4 == 0 && index < id.SIZE_IN_BYTES*2) out << ' ';
}
}
break;
default: out << id.toStdString(UPPER_CASE); break;
}
return out;
}
inline std::string toStdString() const { return toStdString(UPPER_CASE); }
inline static uint32_t serial_size() { return SIZE_IN_BYTES; }
bool serialise(void* data,uint32_t pktsize,uint32_t& offset) const
{
if(offset + SIZE_IN_BYTES > pktsize) return false;
memmove( &(reinterpret_cast<uint8_t*>(data))[offset],
bytes, SIZE_IN_BYTES );
offset += SIZE_IN_BYTES;
return true;
}
bool deserialise(const void* data, uint32_t pktsize, uint32_t& offset)
{
if(offset + SIZE_IN_BYTES > pktsize) return false;
memmove( bytes,
&(reinterpret_cast<const uint8_t*>(data))[offset],
SIZE_IN_BYTES );
offset += SIZE_IN_BYTES;
return true;
}
/** Explicit constructor from a byte array. The array must have size at
* least ID_SIZE_IN_BYTES
* @deprecated This is too dangerous!
* Nothing prevent a buffer of wrong size being passed at runtime!
*/
RS_DEPRECATED_FOR("fromBufferUnsafe(const uint8_t* buff)")
explicit t_RsGenericIdType(const uint8_t bytes[]);
private:
std::string toStdString(bool upper_case) const;
uint8_t bytes[ID_SIZE_IN_BYTES];
};
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
std::string t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>
::toStdString(bool upper_case) const
{
static const char outh[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ;
static const char outl[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' } ;
@ -195,14 +255,20 @@ template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> s
return res ;
}
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>::t_RsGenericIdType(const std::string& s)
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>
::t_RsGenericIdType(const std::string& s)
{
int n=0;
std::string::size_type n = 0;
if(s.length() != ID_SIZE_IN_BYTES*2)
{
if(!s.empty())
std::cerr << "t_RsGenericIdType<>::t_RsGenericIdType(std::string&): supplied string in constructor has wrong size. Expected ID size=" << ID_SIZE_IN_BYTES*2 << " String=\"" << s << "\" = " << s.length() << std::endl;
{
RsErr() << __PRETTY_FUNCTION__ << " supplied string in constructor "
<< "has wrong size. Expected ID size=" << ID_SIZE_IN_BYTES*2
<< " String=\"" << s << "\" = " << s.length() << std::endl;
print_stacktrace();
}
clear();
return;
}
@ -221,58 +287,52 @@ template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> t
bytes[i] += (b-'a'+10) << 4*(1-k) ;
else if(b >= '0' && b <= '9')
bytes[i] += (b-'0') << 4*(1-k) ;
else {
std::cerr << "t_RsGenericIdType<>::t_RsGenericIdType(std::string&): supplied string is not purely hexadecimal: s=\"" << s << "\"" << std::endl;
clear();
else
{
RsErr() << __PRETTY_FUNCTION__ << "supplied string is not "
<< "purely hexadecimal: s=\"" << s << "\"" << std::endl;
clear();
return;
}
}
}
}
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>::t_RsGenericIdType(const unsigned char *mem)
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
RS_DEPRECATED_FOR("t_RsGenericIdType::fromBuffer(...)")
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>::
t_RsGenericIdType(const uint8_t mem[]) /// @deprecated Too dangerous!
{
if(mem == NULL)
memset(bytes,0,ID_SIZE_IN_BYTES) ;
else
memcpy(bytes,mem,ID_SIZE_IN_BYTES) ;
if(mem == nullptr) memset(bytes, 0, ID_SIZE_IN_BYTES);
else memcpy(bytes, mem, ID_SIZE_IN_BYTES);
}
static const int SSL_ID_SIZE = 16 ; // = CERTSIGNLEN
static const int CERT_SIGN_LEN = 16 ; // = CERTSIGNLEN
static const int PGP_KEY_ID_SIZE = 8 ;
static const int PGP_KEY_FINGERPRINT_SIZE = 20 ;
static const int SHA1_SIZE = 20 ;
static const int SHA256_SIZE = 32 ;
/**
* This constants are meant to be used only inside this file.
* Use @see t_RsGenericIdType::SIZE_IN_BYTES in other places.
*/
namespace _RsIdSize
{
constexpr uint32_t SSL_ID = 16; // = CERT_SIGN
constexpr uint32_t CERT_SIGN = 16; // = SSL_ID
constexpr uint32_t PGP_ID = 8;
constexpr uint32_t PGP_FINGERPRINT = 20;
constexpr uint32_t SHA1 = 20;
constexpr uint32_t SHA256 = 32;
}
// These constants are random, but should be different, in order to make the various IDs incompatible with each other.
//
static const uint32_t RS_GENERIC_ID_SSL_ID_TYPE = 0x0001 ;
static const uint32_t RS_GENERIC_ID_PGP_ID_TYPE = 0x0002 ;
static const uint32_t RS_GENERIC_ID_SHA1_ID_TYPE = 0x0003 ;
static const uint32_t RS_GENERIC_ID_PGP_FINGERPRINT_TYPE = 0x0004 ;
static const uint32_t RS_GENERIC_ID_GXS_GROUP_ID_TYPE = 0x0005 ;
static const uint32_t RS_GENERIC_ID_GXS_ID_TYPE = 0x0006 ;
static const uint32_t RS_GENERIC_ID_GXS_MSG_ID_TYPE = 0x0007 ;
static const uint32_t RS_GENERIC_ID_GXS_CIRCLE_ID_TYPE = 0x0008 ;
static const uint32_t RS_GENERIC_ID_GROUTER_ID_TYPE = 0x0009 ;
static const uint32_t RS_GENERIC_ID_GXS_TUNNEL_ID_TYPE = 0x0010 ;
static const uint32_t RS_GENERIC_ID_GXS_DISTANT_CHAT_ID_TYPE = 0x0011 ;
static const uint32_t RS_GENERIC_ID_NODE_GROUP_ID_TYPE = 0x0012 ;
static const uint32_t RS_GENERIC_ID_SHA256_ID_TYPE = 0x0013 ;
static const uint32_t RS_GENERIC_ID_20_BYTES_UNTYPED = 0x0014 ;
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_SSL_ID_TYPE> SSLIdType ;
typedef t_RsGenericIdType< PGP_KEY_ID_SIZE , true, RS_GENERIC_ID_PGP_ID_TYPE> PGPIdType ;
typedef t_RsGenericIdType< SHA1_SIZE , false, RS_GENERIC_ID_SHA1_ID_TYPE> Sha1CheckSum ;
typedef t_RsGenericIdType< SHA256_SIZE , false, RS_GENERIC_ID_SHA256_ID_TYPE> Sha256CheckSum ;
typedef t_RsGenericIdType< PGP_KEY_FINGERPRINT_SIZE, true, RS_GENERIC_ID_PGP_FINGERPRINT_TYPE> PGPFingerprintType ;
typedef t_RsGenericIdType< SHA1_SIZE , true, RS_GENERIC_ID_20_BYTES_UNTYPED> Bias20Bytes ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_GROUP_ID_TYPE > GXSGroupId ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_ID_TYPE > GXSId ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_CIRCLE_ID_TYPE > GXSCircleId ;
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_GXS_TUNNEL_ID_TYPE > GXSTunnelId ;
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_GXS_DISTANT_CHAT_ID_TYPE > DistantChatPeerId ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_NODE_GROUP_ID_TYPE > RsNodeGroupId ;
using RsPeerId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::SSL >;
using RsPgpId = t_RsGenericIdType<_RsIdSize::PGP_ID , true, RsGenericIdType::PGP_ID >;
using Sha1CheckSum = t_RsGenericIdType<_RsIdSize::SHA1 , false, RsGenericIdType::SHA1 >;
using Sha256CheckSum = t_RsGenericIdType<_RsIdSize::SHA256 , false, RsGenericIdType::SHA256 >;
using RsPgpFingerprint = t_RsGenericIdType<_RsIdSize::PGP_FINGERPRINT, true, RsGenericIdType::PGP_FINGERPRINT>;
using Bias20Bytes = t_RsGenericIdType<_RsIdSize::SHA1 , true, RsGenericIdType::BIAS_20_BYTES >;
using RsGxsGroupId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_GROUP >;
using RsGxsId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_ID >;
using RsGxsCircleId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_CIRCLE >;
using RsGxsTunnelId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::GXS_TUNNEL >;
using DistantChatPeerId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::DISTANT_CHAT >;
using RsNodeGroupId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::NODE_GROUP >;
/// @deprecated Ugly name kept temporarly only because it is used in many places
using PGPFingerprintType RS_DEPRECATED_FOR(RsPpgFingerprint) = RsPgpFingerprint;

View File

@ -1,9 +1,8 @@
/*******************************************************************************
* libretroshare/src/retroshare: rsinit.h *
* *
* libretroshare: retroshare core library *
* *
* Copyright 2004-2006 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2004-2014 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2016-2019 Gioacchino Mazzurco <gio@altermundi.net> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -19,8 +18,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef RETROSHARE_INIT_INTERFACE_H
#define RETROSHARE_INIT_INTERFACE_H
#pragma once
/// RetroShare initialization and login API
// Initialize ok, result >= 0
#define RS_INIT_OK 0 // Initialize ok
@ -29,13 +30,7 @@
#define RS_INIT_AUTH_FAILED -1 // AuthGPG::InitAuth failed
#define RS_INIT_BASE_DIR_ERROR -2 // AuthGPG::InitAuth failed
#define RS_INIT_NO_KEYRING -3 // Keyring is empty. Need to import it.
/****
* #define RS_USE_PGPSSL 1
***/
#define RS_USE_PGPSSL 1
#define RS_INIT_NO_EXECUTABLE -4 // executable path hasn't been set in config options
#include <stdint.h>
#include <list>
@ -43,7 +38,7 @@
#include <vector>
#include <retroshare/rstypes.h>
struct RsLoginHelper;
class RsLoginHelper;
/**
* Pointer to global instance of RsLoginHelper
@ -51,6 +46,38 @@ struct RsLoginHelper;
*/
extern RsLoginHelper* rsLoginHelper;
/**
* @brief The RsInitConfig struct
* This class contains common configuration options, that executables using libretroshare may want to
* set using e.g. commandline options. To be passed to RsInit::InitRetroShare().
*/
struct RsConfigOptions
{
RsConfigOptions();
// required
std::string main_executable_path;/* this should be set to argv[0] */
// Optional. Only change if needed.
bool autoLogin; /* try auto-login */
bool udpListenerOnly; /* only listen to udp */
std::string forcedInetAddress; /* inet address to use.*/
uint16_t forcedPort; /* port to listen to */
bool outStderr;
int debugLevel;
std::string logfname; /* output filename for log */
std::string opModeStr; /* operating mode. Acceptable values: "Full", "NoTurtle", "Gaming", "Minimal" */
std::string optBaseDir; /* base directory where to find profiles, etc */
uint16_t jsonApiPort; /* port to use fo Json API */
std::string jsonApiBindAddress; /* bind address for Json API */
};
/*!
* Initialisation Class (not publicly disclosed to RsIFace)
@ -63,7 +90,7 @@ public:
OK, /// Everything go as expected, no error occurred
ERR_ALREADY_RUNNING, /// Another istance is running already
ERR_CANT_ACQUIRE_LOCK, /// Another istance is already running?
ERR_UNKOWN /// Unkown error, maybe password is wrong?
ERR_UNKNOWN /// Unkown error, maybe password is wrong?
};
/* reorganised RsInit system */
@ -83,12 +110,19 @@ public:
* invalid argument passed and vice versa
* @return RS_INIT_...
*/
static int InitRetroShare(int argc, char **argv, bool strictCheck=true);
static int InitRetroShare(const RsConfigOptions&);
static bool isPortable();
static bool isWindowsXP();
static bool collectEntropy(uint32_t bytes) ;
/*!
* \brief lockFilePath
* \return
* full path for the lock file. Can be used to warn the user about a non deleted lock that would prevent to start.
*/
static std::string lockFilePath();
/*
* Setup Hidden Location;
*/
@ -276,8 +310,10 @@ extern RsAccounts* rsAccounts;
* This helper class have been implemented because there was not reasonable way
* to login in the API that could be exposed via JSON API
*/
struct RsLoginHelper
class RsLoginHelper
{
public:
RsLoginHelper() {}
/**
* @brief Normal way to attempt login
* @jsonapi{development,manualwrapper}
@ -301,7 +337,7 @@ struct RsLoginHelper
RsPeerId mLocationId;
RsPgpId mPgpId;
std::string mLocationName;
std::string mPpgName;
std::string mPgpName;
/// @see RsSerializable::serial_process
void serial_process( RsGenericSerializer::SerializeJob j,
@ -340,5 +376,3 @@ struct RsLoginHelper
*/
bool isLoggedIn();
};
#endif

View File

@ -470,6 +470,8 @@ public:
std::map<RsGxsId, rstime_t> gxs_ids ; // list of non direct friend who participate. Used to display only.
rstime_t last_activity ; // last recorded activity. Useful for removing dead lobbies.
virtual void clear() { gxs_ids.clear(); lobby_id = 0; lobby_name.clear(); lobby_topic.clear(); participating_friends.clear(); }
// RsSerializable interface
public:
void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) {
@ -485,14 +487,13 @@ public:
}
};
std::ostream &operator<<(std::ostream &out, const Rs::Msgs::MessageInfo &info);
class RsMsgs;
/**
* @brief Pointer to retroshare's message service
* @jsonapi{development}
*/
extern RsMsgs *rsMsgs;
extern RsMsgs* rsMsgs;
class RsMsgs
{
@ -521,6 +522,7 @@ public:
* @return true on success
*/
virtual bool getMessage(const std::string &msgId, Rs::Msgs::MessageInfo &msg) = 0;
/**
* @brief getMessageCount
* @jsonapi{development}
@ -832,6 +834,13 @@ virtual void getOwnAvatarData(unsigned char *& data,int& size) = 0 ;
*/
virtual void unsubscribeChatLobby(const ChatLobbyId &lobby_id) = 0;
/**
* @brief sendLobbyStatusPeerLeaving notify friend nodes that we're leaving a subscribed lobby
* @jsonapi{development}
* @param[in] lobby_id lobby to leave
*/
virtual void sendLobbyStatusPeerLeaving(const ChatLobbyId& lobby_id) = 0;
/**
* @brief setIdentityForChatLobby set the chat identit
* @jsonapi{development}

View File

@ -19,8 +19,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef RS_NOTIFY_GUI_INTERFACE_H
#define RS_NOTIFY_GUI_INTERFACE_H
#pragma once
#include <map>
#include <list>
@ -30,6 +29,7 @@
#include "rsturtle.h"
#include "rsgxsifacetypes.h"
#include "util/rsdeprecate.h"
class ChatId;
class ChatMessage;
@ -148,7 +148,7 @@ const uint32_t NOTIFY_HASHTYPE_FINISH = 2; /* Finish */
const uint32_t NOTIFY_HASHTYPE_HASH_FILE = 3; /* Hashing file */
const uint32_t NOTIFY_HASHTYPE_SAVE_FILE_INDEX = 4; /* Hashing file */
class RsFeedItem
class RS_DEPRECATED RsFeedItem
{
public:
RsFeedItem(uint32_t type, const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4, uint32_t result1)
@ -181,9 +181,9 @@ class RsFeedItem
// This mechanism can be used in plugins, new services, etc.
//
class NotifyClient;
class RS_DEPRECATED NotifyClient;
class RsNotify
class RS_DEPRECATED_FOR(RsEvents) RsNotify
{
public:
/* registration of notifies clients */
@ -206,12 +206,14 @@ class RsNotify
virtual bool setDisableAskPassword (const bool /*bValue*/) { return false ; }
};
class NotifyClient
class RS_DEPRECATED NotifyClient
{
public:
NotifyClient() {}
virtual ~NotifyClient() {}
virtual void notifyPeerConnected (const std::string& /* peer_id */) {}
virtual void notifyPeerDisconnected (const std::string& /* peer_id */) {}
virtual void notifyListPreChange (int /* list */, int /* type */) {}
virtual void notifyListChange (int /* list */, int /* type */) {}
virtual void notifyErrorMsg (int /* list */, int /* sev */, std::string /* msg */) {}
@ -223,8 +225,6 @@ public:
virtual void notifyCustomState (const std::string& /* peer_id */, const std::string& /* status_string */) {}
virtual void notifyHashingInfo (uint32_t /* type */, const std::string& /* fileinfo */) {}
virtual void notifyTurtleSearchResult (const RsPeerId& /* pid */, uint32_t /* search_id */, const std::list<TurtleFileInfo>& /* files */) {}
#warning MISSING CODE HERE
// virtual void notifyTurtleSearchResult (uint32_t /* search_id */, const std::list<TurtleGxsInfo >& /* groups */) {}
virtual void notifyPeerHasNewAvatar (std::string /* peer_id */) {}
virtual void notifyOwnAvatarChanged () {}
virtual void notifyOwnStatusMessageChanged () {}
@ -245,4 +245,3 @@ public:
virtual bool askForPassword (const std::string& /* title */, const std::string& /* key_details */, bool /* prev_is_bad */, std::string& /* password */,bool& /* cancelled */ ) { return false ;}
virtual bool askForPluginConfirmation (const std::string& /* plugin_filename */, const std::string& /* plugin_file_hash */,bool /* first_time */) { return false ;}
};
#endif

View File

@ -31,6 +31,7 @@
#include "util/rsurl.h"
#include "util/rsdeprecate.h"
#include "util/rstime.h"
#include "retroshare/rsevents.h"
class RsPeers;
@ -73,7 +74,7 @@ const uint32_t RS_HIDDEN_TYPE_I2P = 0x0004;
/* mask to match all valid hidden types */
const uint32_t RS_HIDDEN_TYPE_MASK = RS_HIDDEN_TYPE_I2P | RS_HIDDEN_TYPE_TOR;
/* Visibility */
/* Visibility parameter for discovery */
const uint32_t RS_VS_DISC_OFF = 0x0000;
const uint32_t RS_VS_DISC_MINIMAL = 0x0001;
const uint32_t RS_VS_DISC_FULL = 0x0002;
@ -129,6 +130,8 @@ const uint32_t CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR = 0x16 ;
const uint32_t CERTIFICATE_PARSING_ERROR_UNKNOWN_SECTION_PTAG = 0x17 ;
const uint32_t CERTIFICATE_PARSING_ERROR_MISSING_CHECKSUM = 0x18 ;
const uint32_t CERTIFICATE_PARSING_ERROR_WRONG_VERSION = 0x19 ;
const uint32_t CERTIFICATE_PARSING_ERROR_MISSING_PGP_FINGERPRINT = 0x1a ;
const uint32_t CERTIFICATE_PARSING_ERROR_MISSING_LOCATION_ID = 0x1b ;
const uint32_t PGP_KEYRING_REMOVAL_ERROR_NO_ERROR = 0x20 ;
const uint32_t PGP_KEYRING_REMOVAL_ERROR_CANT_REMOVE_SECRET_KEYS = 0x21 ;
@ -139,40 +142,40 @@ const uint32_t PGP_KEYRING_REMOVAL_ERROR_DATA_INCONSISTENCY = 0x24 ;
/* LinkType Flags */
// CONNECTION
const uint32_t RS_NET_CONN_TRANS_MASK = 0x0000ffff;
const uint32_t RS_NET_CONN_TRANS_TCP_MASK = 0x0000000f;
const uint32_t RS_NET_CONN_TRANS_TCP_UNKNOWN = 0x00000001;
const uint32_t RS_NET_CONN_TRANS_TCP_LOCAL = 0x00000002;
const uint32_t RS_NET_CONN_TRANS_TCP_EXTERNAL = 0x00000004;
const uint32_t RS_NET_CONN_TRANS_MASK = 0x0000ffff;
const uint32_t RS_NET_CONN_TRANS_TCP_MASK = 0x0000000f;
const uint32_t RS_NET_CONN_TRANS_TCP_UNKNOWN = 0x00000001;
const uint32_t RS_NET_CONN_TRANS_TCP_LOCAL = 0x00000002;
const uint32_t RS_NET_CONN_TRANS_TCP_EXTERNAL = 0x00000004;
const uint32_t RS_NET_CONN_TRANS_UDP_MASK = 0x000000f0;
const uint32_t RS_NET_CONN_TRANS_UDP_UNKNOWN = 0x00000010;
const uint32_t RS_NET_CONN_TRANS_UDP_DIRECT = 0x00000020;
const uint32_t RS_NET_CONN_TRANS_UDP_PROXY = 0x00000040;
const uint32_t RS_NET_CONN_TRANS_UDP_RELAY = 0x00000080;
const uint32_t RS_NET_CONN_TRANS_UDP_MASK = 0x000000f0;
const uint32_t RS_NET_CONN_TRANS_UDP_UNKNOWN = 0x00000010;
const uint32_t RS_NET_CONN_TRANS_UDP_DIRECT = 0x00000020;
const uint32_t RS_NET_CONN_TRANS_UDP_PROXY = 0x00000040;
const uint32_t RS_NET_CONN_TRANS_UDP_RELAY = 0x00000080;
const uint32_t RS_NET_CONN_TRANS_OTHER_MASK = 0x00000f00;
const uint32_t RS_NET_CONN_TRANS_OTHER_MASK = 0x00000f00;
const uint32_t RS_NET_CONN_TRANS_UNKNOWN = 0x00001000;
const uint32_t RS_NET_CONN_TRANS_UNKNOWN = 0x00001000;
const uint32_t RS_NET_CONN_SPEED_MASK = 0x000f0000;
const uint32_t RS_NET_CONN_SPEED_UNKNOWN = 0x00000000;
const uint32_t RS_NET_CONN_SPEED_TRICKLE = 0x00010000;
const uint32_t RS_NET_CONN_SPEED_LOW = 0x00020000;
const uint32_t RS_NET_CONN_SPEED_NORMAL = 0x00040000;
const uint32_t RS_NET_CONN_SPEED_HIGH = 0x00080000;
const uint32_t RS_NET_CONN_SPEED_MASK = 0x000f0000;
const uint32_t RS_NET_CONN_SPEED_UNKNOWN = 0x00000000;
const uint32_t RS_NET_CONN_SPEED_TRICKLE = 0x00010000;
const uint32_t RS_NET_CONN_SPEED_LOW = 0x00020000;
const uint32_t RS_NET_CONN_SPEED_NORMAL = 0x00040000;
const uint32_t RS_NET_CONN_SPEED_HIGH = 0x00080000;
const uint32_t RS_NET_CONN_QUALITY_MASK = 0x00f00000;
const uint32_t RS_NET_CONN_QUALITY_UNKNOWN = 0x00000000;
const uint32_t RS_NET_CONN_QUALITY_MASK = 0x00f00000;
const uint32_t RS_NET_CONN_QUALITY_UNKNOWN = 0x00000000;
// THIS INFO MUST BE SUPPLIED BY PEERMGR....
const uint32_t RS_NET_CONN_TYPE_MASK = 0x0f000000;
const uint32_t RS_NET_CONN_TYPE_UNKNOWN = 0x00000000;
const uint32_t RS_NET_CONN_TYPE_ACQUAINTANCE = 0x01000000;
const uint32_t RS_NET_CONN_TYPE_FRIEND = 0x02000000;
const uint32_t RS_NET_CONN_TYPE_SERVER = 0x04000000;
const uint32_t RS_NET_CONN_TYPE_CLIENT = 0x08000000;
const uint32_t RS_NET_CONN_TYPE_MASK = 0x0f000000;
const uint32_t RS_NET_CONN_TYPE_UNKNOWN = 0x00000000;
const uint32_t RS_NET_CONN_TYPE_ACQUAINTANCE = 0x01000000;
const uint32_t RS_NET_CONN_TYPE_FRIEND = 0x02000000;
const uint32_t RS_NET_CONN_TYPE_SERVER = 0x04000000;
const uint32_t RS_NET_CONN_TYPE_CLIENT = 0x08000000;
// working state of proxy
@ -204,6 +207,14 @@ std::string RsPeerNetModeString(uint32_t netModel);
std::string RsPeerLastConnectString(uint32_t lastConnect);
/* We should definitely split this into 2 sub-structures:
* PGP info (or profile info) with all info related to PGP keys
* peer info: all network related information
*
* Plus top level information:
* isOnlyPgpDetail (this could be obsolete if the methods to query about PGP info is a different function)
* peer Id
*/
struct RsPeerDetails : RsSerializable
{
RsPeerDetails();
@ -220,13 +231,14 @@ struct RsPeerDetails : RsSerializable
RsPgpId issuer;
PGPFingerprintType fpr; /* pgp fingerprint */
RsPgpFingerprint fpr; /* pgp fingerprint */
std::string authcode; // TODO: 2015/12/31 (cyril) what is this used for ?????
std::list<RsPgpId> gpgSigners;
uint32_t trustLvl;
uint32_t validLvl;
bool skip_pgp_signature_validation;
bool ownsign; /* we have signed the remote peer GPG key */
bool hasSignedMe; /* the remote peer has signed my GPG key */
@ -358,7 +370,22 @@ struct RsGroupInfo : RsSerializable
}
};
std::ostream &operator<<(std::ostream &out, const RsPeerDetails &detail);
/** Event emitted when a peer change state */
struct RsPeerStateChangedEvent : RsEvent
{
/// @param[in] sslId is of the peer which changed state
RsPeerStateChangedEvent(RsPeerId sslId);
/// Storage fot the id of the peer that changed state
RsPeerId mSslId;
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override
{
RsEvent::serial_process(j, ctx);
RS_SERIAL_PROCESS(mSslId);
}
};
/** The Main Interface Class - for information about your Peers
* A peer is another RS instance, means associated with an SSL certificate
@ -436,6 +463,16 @@ public:
*/
virtual bool isPgpFriend(const RsPgpId& pgpId) = 0;
/**
* @brief Check if given peer is a trusted SSL node pending PGP approval
* Peers added through short invite remain in this state as long as their
* PGP key is not received and verified/approved by the user.
* @jsonapi{development}
* @param[in] sslId id of the peer to check
* @return true if the node is trusted, false otherwise
*/
virtual bool isSslOnlyFriend(const RsPeerId& sslId) = 0;
virtual std::string getPeerName(const RsPeerId &ssl_id) = 0;
virtual std::string getGPGName(const RsPgpId& gpg_id) = 0;
@ -462,12 +499,17 @@ public:
virtual RsPgpId getGPGId(const RsPeerId& sslId) = 0;
virtual bool isKeySupported(const RsPgpId& gpg_ids) = 0;
virtual bool getGPGAcceptedList(std::list<RsPgpId> &gpg_ids) = 0;
virtual bool getGPGSignedList(std::list<RsPgpId> &gpg_ids) = 0;//friends that we accpet to connect with but we don't want to sign their gpg key
virtual bool getGPGValidList(std::list<RsPgpId> &gpg_ids) = 0;
virtual bool getGPGAllList(std::list<RsPgpId> &gpg_ids) = 0;
virtual bool getGPGSignedList(std::list<RsPgpId> &gpg_ids) = 0;// keys signed by our own PGP key.
virtual bool getGPGValidList(std::list<RsPgpId> &gpg_ids) = 0;// all PGP keys without filtering
virtual bool getGPGAllList(std::list<RsPgpId> &gpg_ids) = 0;// all PGP keys as well
virtual bool getAssociatedSSLIds(const RsPgpId& gpg_id, std::list<RsPeerId>& ids) = 0;
virtual bool gpgSignData(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason = "") = 0;
virtual RsPgpId pgpIdFromFingerprint(const RsPgpFingerprint& fpr) = 0;
// Note: the two methods below could be unified. The fact that one of them can take an optional RsPeerDetails struct as parameter
// seems quite inconsistent.
/**
* @brief Add trusted node
* @jsonapi{development}
@ -476,8 +518,26 @@ public:
* @param[in] flags service permissions flag
* @return false if error occurred, true otherwise
*/
virtual bool addFriend( const RsPeerId &sslId, const RsPgpId& gpgId,
ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT ) = 0;
virtual bool addFriend(
const RsPeerId& sslId, const RsPgpId& gpgId,
ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT ) = 0;
/**
* @brief Add SSL-only trusted node
* When adding an SSL-only node, it is authorized to connect. Every time a
* connection is established the user is notified about the need to verify
* the PGP fingerprint, until she does, at that point the node become a full
* SSL+PGP friend.
* @jsonapi{development}
* @param[in] sslId SSL id of the node to add
* @param[in] pgpId PGP id of the node to add. Will be used for validation when the key is available.
* @param[in] details Optional extra details known about the node to add
* @return false if error occurred, true otherwise
*/
virtual bool addSslOnlyFriend(
const RsPeerId& sslId,
const RsPgpId& pgpId,
const RsPeerDetails& details = RsPeerDetails() ) = 0;
/**
* @brief Revoke connection trust from to node
@ -599,6 +659,38 @@ public:
bool includeSignatures = false,
bool includeExtraLocators = true ) = 0;
/**
* @brief Get RetroShare short invite of the given peer
* @jsonapi{development}
* @param[out] invite storage for the generated invite
* @param[in] sslId Id of the peer of which we want to generate an invite,
* a null id (all 0) is passed, an invite for own node is returned.
* @param[in] formatRadix true to get in base64 format false to get URL.
* @param[in] bareBones true to get smallest invite, which miss also
* the information necessary to attempt an outgoing connection, but still
* enough to accept an incoming one.
* @param[in] baseUrl URL into which to sneak in the RetroShare invite
* radix, this is primarly useful to trick other applications into making
* the invite clickable, or to disguise the RetroShare invite into a
* "normal" looking web link. Used only if formatRadix is false.
* @return false if error occurred, true otherwise
*/
virtual bool getShortInvite(
std::string& invite, const RsPeerId& sslId = RsPeerId(),
bool formatRadix = false, bool bareBones = false,
const std::string& baseUrl = "https://retroshare.me/" ) = 0;
/**
* @brief Parse the give short invite to extract contained information
* @jsonapi{development}
* @param[in] invite string containing the short invite to parse
* @param[out] details storage for the extracted information, consider it
* @param[out] err_code storage for the error code
* @return false if error occurred, true otherwise
*/
virtual bool parseShortInvite(
const std::string& invite, RsPeerDetails& details,uint32_t& err_code ) = 0;
/**
* @brief Add trusted node from invite
* @jsonapi{development}
@ -642,8 +734,13 @@ public:
const std::string& cert, RsPeerDetails& certDetails,
uint32_t& errorCode ) = 0;
virtual bool loadPgpKeyFromBinaryData( const unsigned char *bin_key_data,
uint32_t bin_key_len,
RsPgpId& gpg_id,
std::string& error_string )=0;
// Certificate utils
virtual bool cleanCertificate(const std::string &certstr, std::string &cleanCert,int& error_code) = 0;
virtual bool cleanCertificate(const std::string &certstr, std::string &cleanCert,bool& is_short_format,uint32_t& error_code) = 0;
virtual bool saveCertificateToFile(const RsPeerId& id, const std::string &fname) = 0;
virtual std::string saveCertificateToString(const RsPeerId &id) = 0;
@ -751,6 +848,3 @@ public:
RS_DEPRECATED_FOR(isPgpFriend)
virtual bool isGPGAccepted(const RsPgpId &gpg_id_is_friend) = 0;
};

View File

@ -30,6 +30,7 @@
#include "retroshare/rsfiles.h"
#include "retroshare/rsversion.h"
#include "util/rsinitedptr.h"
#include "retroshare/rsdisc.h"
class RsPluginHandler ;
extern RsPluginHandler *rsPlugins ;
@ -40,7 +41,6 @@ class RsReputations ;
class RsTurtle ;
class RsGxsTunnelService ;
class RsDht ;
class RsDisc ;
class RsMsgs ;
class RsGxsForums;
class RsGxsChannels;

View File

@ -88,10 +88,6 @@ struct RsPeerServiceInfo : RsSerializable
}
};
std::ostream &operator<<(std::ostream &out, const RsPeerServiceInfo &info);
std::ostream &operator<<(std::ostream &out, const RsServiceInfo &info);
struct RsServicePermissions : RsSerializable
{
RsServicePermissions();

View File

@ -107,9 +107,6 @@ struct RsTokReqOptions
rstime_t mAfter;
};
std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta);
std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta);
/*!
* A proxy class for requesting generic service data for GXS
* This seperates the request mechanism from the actual retrieval of data

View File

@ -37,15 +37,6 @@
#define USE_NEW_CHUNK_CHECKING_CODE
// This adds a level of indirection to types, so we can easily change them if needed
//
//typedef std::string RsCertId; // unused
//typedef std::string RsChanId;
//typedef std::string RsMsgId;
//typedef std::string RsAuthId;
typedef SSLIdType RsPeerId ;
typedef PGPIdType RsPgpId ;
typedef Sha1CheckSum RsFileHash ;
typedef Sha1CheckSum RsMessageId ;
@ -257,8 +248,6 @@ struct FileInfo : RsSerializable
}
};
std::ostream &operator<<(std::ostream &out, const FileInfo& info);
/**
* Pointers in this class have no real meaning as pointers, they are used as
* indexes, internally by retroshare.
@ -379,8 +368,6 @@ struct DirDetails : RsSerializable
}
};
std::ostream &operator<<(std::ostream &out, const DirDetails& details);
class FileDetail
{
public:

View File

@ -6,6 +6,7 @@
* Copyright (c) 2004-2009 Marcelo Roberto Jimenez ( phoenix@amule.org ) *
* Copyright (c) 2006-2009 aMule Team ( admin@amule.org / http://www.amule.org)*
* Copyright (c) 2009-2010 Retroshare Team *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -25,12 +26,14 @@
#define UPNP_C
#include "UPnPBase.h"
#include <stdio.h>
#include <string.h>
#include <sstream> // for std::istringstream
#include <algorithm> // For transform()
#include "util/rsstring.h"
#include "rs_upnp/upnp18_retrocompat.h"
#ifdef __GNUC__
#if __GNUC__ >= 4
@ -115,7 +118,7 @@ std::string CUPnPLib::processUPnPErrorMessage(
const std::string &message,
int errorCode,
const DOMString errorString,
IXML_Document *doc) const
const IXML_Document* doc) const
{
/* remove unused parameter warnings */
(void) message;
@ -159,7 +162,7 @@ std::string CUPnPLib::processUPnPErrorMessage(
void CUPnPLib::ProcessActionResponse(
IXML_Document *RespDoc,
const IXML_Document* RespDoc,
const std::string &actionName) const
{
/* remove unused parameter warnings */
@ -196,11 +199,11 @@ void CUPnPLib::ProcessActionResponse(
* \brief Returns the root node of a given document.
*/
IXML_Element *CUPnPLib::Element_GetRootElement(
IXML_Document *doc) const
const IXML_Document* doc) const
{
IXML_Element *root = REINTERPRET_CAST(IXML_Element *)(
IXML_Element* root = REINTERPRET_CAST(IXML_Element *)(
ixmlNode_getFirstChild(
REINTERPRET_CAST(IXML_Node *)(doc)));
REINTERPRET_CAST(IXML_Node *)(const_cast<IXML_Document*>(doc))));
return root;
}
@ -344,12 +347,12 @@ const std::string CUPnPLib::Element_GetAttributeByTag(
CUPnPError::CUPnPError(
const CUPnPLib &upnpLib,
IXML_Document *errorDoc)
:
m_root (upnpLib.Element_GetRootElement(errorDoc)),
m_ErrorCode (upnpLib.Element_GetChildValueByTag(m_root, "errorCode")),
m_ErrorDescription(upnpLib.Element_GetChildValueByTag(m_root, "errorDescription"))
const CUPnPLib &upnpLib,
const IXML_Document *errorDoc)
:
m_root (upnpLib.Element_GetRootElement(errorDoc)),
m_ErrorCode (upnpLib.Element_GetChildValueByTag(m_root, "errorCode")),
m_ErrorDescription(upnpLib.Element_GetChildValueByTag(m_root, "errorDescription"))
{
}
@ -485,7 +488,8 @@ m_timeout(1801),
m_SCPD(NULL)
{
int errcode;
m_SID[0]=0;
std::vector<char> vscpdURL(URLBase.length() + m_SCPDURL.length() + 1);
char *scpdURL = &vscpdURL[0];
errcode = UpnpResolveURL(
@ -748,7 +752,7 @@ bool CUPnPService::Execute(
GetAbsControlURL().c_str(),
GetServiceType().c_str(),
NULL, ActionDoc,
static_cast<Upnp_FunPtr>(&CUPnPControlPoint::Callback),
reinterpret_cast<Upnp_FunPtr>(&CUPnPControlPoint::Callback),
NULL);
return true;
}
@ -948,7 +952,7 @@ m_WanService(NULL)
#endif
ret = UpnpRegisterClient(
static_cast<Upnp_FunPtr>(&CUPnPControlPoint::Callback),
reinterpret_cast<Upnp_FunPtr>(&CUPnPControlPoint::Callback),
&m_UPnPClientHandle,
&m_UPnPClientHandle);
if (ret != UPNP_E_SUCCESS) {
@ -1295,185 +1299,149 @@ bool CUPnPControlPoint::PrivateGetExternalIpAdress()
// This function is static
int CUPnPControlPoint::Callback(Upnp_EventType EventType, void *Event, void * /*Cookie*/)
int CUPnPControlPoint::Callback(
Upnp_EventType EventType, const void* Event, void * /*Cookie*/ )
{
if(!Event) return 0;
std::string msg;
std::string msg2;
// Somehow, this is unreliable. UPNP_DISCOVERY_ADVERTISEMENT_ALIVE events
// happen with a wrong cookie and... boom!
// CUPnPControlPoint *upnpCP = static_cast<CUPnPControlPoint *>(Cookie);
CUPnPControlPoint *upnpCP = CUPnPControlPoint::s_CtrlPoint ;
if (upnpCP == NULL)
return 0;
//fprintf(stderr, "Callback: %d, Cookie: %p\n", EventType, Cookie);
switch (EventType) {
case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
#ifdef UPNP_DEBUG
std::cerr << "CUPnPControlPoint::Callback() UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: ";
#endif
goto upnpDiscovery;
case UPNP_DISCOVERY_SEARCH_RESULT: {
#ifdef UPNP_DEBUG
std::cerr << "UPNP_DISCOVERY_SEARCH_RESULT: ";
#endif
// UPnP Discovery
upnpDiscovery:
struct Upnp_Discovery *d_event = (struct Upnp_Discovery *)Event;
IXML_Document *doc = NULL;
int ret;
if (d_event->ErrCode != UPNP_E_SUCCESS) {
#ifdef UPNP_DEBUG
std::cerr << upnpCP->m_upnpLib.GetUPnPErrorMessage(d_event->ErrCode) << "." << std::endl;
#endif
}
#ifdef UPNP_DEBUG
std::cerr << "CUPnPControlPoint::Callback() URetrieving device description from " <<
d_event->Location << "." << std::endl;
#endif
CUPnPControlPoint* upnpCP = CUPnPControlPoint::s_CtrlPoint;
if (!upnpCP) return 0;
switch (EventType)
{
case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: /*fallthrough*/
case UPNP_DISCOVERY_SEARCH_RESULT:
{
const UpnpDiscovery* d_event = static_cast<const UpnpDiscovery*>(Event);
// Get the XML tree device description in doc
ret = UpnpDownloadXmlDoc(d_event->Location, &doc);
if (ret != UPNP_E_SUCCESS) {
IXML_Document* doc = nullptr;
UpnpDownloadXmlDoc(UpnpDiscovery_get_Location_cstr(d_event), &doc);
if (!doc) break;
IXML_Element* root = upnpCP->m_upnpLib.Element_GetRootElement(doc);
// Extract the URLBase
const std::string urlBase = upnpCP->m_upnpLib.
Element_GetChildValueByTag(root, "URLBase");
// Get the root device
IXML_Element *rootDevice = upnpCP->m_upnpLib.
Element_GetFirstChildByTag(root, "device");
// Extract the deviceType
std::string devType(upnpCP->m_upnpLib.
Element_GetChildValueByTag(rootDevice, "deviceType"));
#ifdef UPNP_DEBUG
std::cerr << "CUPnPControlPoint::Callback() UError retrieving device description from " <<
d_event->Location << ": " <<
upnpCP->m_upnpLib.GetUPnPErrorMessage(ret) << ".";
std::cerr << "CUPnPControlPoint::Callback() EventType==UPNP_DISCOVERY_SEARCH_RESULT" << std::endl
<< "urlBase:" << urlBase << std::endl
<< "devType:" << devType << std::endl;
#endif
} else {
#ifdef UPNP_DEBUG
std::cerr << "CUPnPControlPoint::Callback() URetrieving device description from " <<
d_event->Location << "." << std::endl;
// Only add device if it is an InternetGatewayDevice
if (stdStringIsEqualCI(devType, upnpCP->m_upnpLib.UPNP_DEVICE_IGW))
{
// This condition can be used to auto-detect
// the UPnP device we are interested in.
// Obs.: Don't block the entry here on this
// condition! There may be more than one device,
// and the first that enters may not be the one
// we are interested in!
upnpCP->SetIGWDeviceDetected(true);
// Log it if not UPNP_DISCOVERY_ADVERTISEMENT_ALIVE,
// we don't want to spam our logs.
//if (EventType != UPNP_DISCOVERY_ADVERTISEMENT_ALIVE) {
// Add the root device to our list
upnpCP->AddRootDevice(
rootDevice, urlBase,
UpnpDiscovery_get_Location_cstr(d_event),
UpnpDiscovery_get_Expires(d_event) );
#if (UPNP_VERSION > 10624) && (UPNP_VERSION < 10800)
upnpCP->m_WaitForSearchTimeoutMutex.unlock();
#endif
}
if (doc) {
// Get the root node
IXML_Element *root =
upnpCP->m_upnpLib.Element_GetRootElement(doc);
// Extract the URLBase
const std::string urlBase = upnpCP->m_upnpLib.
Element_GetChildValueByTag(root, "URLBase");
// Get the root device
IXML_Element *rootDevice = upnpCP->m_upnpLib.
Element_GetFirstChildByTag(root, "device");
// Extract the deviceType
std::string devType(upnpCP->m_upnpLib.
Element_GetChildValueByTag(rootDevice, "deviceType"));
// Only add device if it is an InternetGatewayDevice
if (stdStringIsEqualCI(devType, upnpCP->m_upnpLib.UPNP_DEVICE_IGW)) {
// This condition can be used to auto-detect
// the UPnP device we are interested in.
// Obs.: Don't block the entry here on this
// condition! There may be more than one device,
// and the first that enters may not be the one
// we are interested in!
upnpCP->SetIGWDeviceDetected(true);
// Log it if not UPNP_DISCOVERY_ADVERTISEMENT_ALIVE,
// we don't want to spam our logs.
//if (EventType != UPNP_DISCOVERY_ADVERTISEMENT_ALIVE) {
#ifdef UPNP_DEBUG
std::cerr << "Internet Gateway Device Detected." << std::endl;
#endif
//}
#ifdef UPNP_DEBUG
std::cerr << "CUPnPControlPoint::Callback() UGetting root device desc." << std::endl;
#endif
// Add the root device to our list
upnpCP->AddRootDevice(rootDevice, urlBase,
d_event->Location, d_event->Expires);
#ifdef UPNP_DEBUG
std::cerr << "CUPnPControlPoint::Callback() UFinishing getting root device desc." << std::endl;
#endif
}
// Free the XML doc tree
ixmlDocument_free(doc);
}
// Free the XML doc tree
ixmlDocument_free(doc);
break;
}
case UPNP_DISCOVERY_SEARCH_TIMEOUT: {
//fprintf(stderr, "Callback: UPNP_DISCOVERY_SEARCH_TIMEOUT\n");
// Search timeout
#ifdef UPNP_DEBUG
std::cerr << "CUPnPControlPoint::Callback() UUPNP_DISCOVERY_SEARCH_TIMEOUT : unlocking mutex." << std::endl;
case UPNP_DISCOVERY_SEARCH_TIMEOUT:
{
#if (UPNP_VERSION > 10624) && (UPNP_VERSION < 10800)
std::cerr << "********************************************************************************" << std::endl
<< "*** THIS SHOULD NOT HAPPEN !!! TELL IT TO DEVS ***" << std::endl
<< "*** UPnPBase.cpp CUPnPControlPoint::Callback() UPNP_DISCOVERY_SEARCH_TIMEOUT ***" << std::endl
<< "********************************************************************************" << std::endl;
#endif
// Unlock the search timeout mutex
upnpCP->m_WaitForSearchTimeoutMutex.unlock();
break;
}
case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: {
//fprintf(stderr, "Callback: UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE\n");
// UPnP Device Removed
struct Upnp_Discovery *dab_event = (struct Upnp_Discovery *)Event;
if (dab_event->ErrCode != UPNP_E_SUCCESS) {
#ifdef UPNP_DEBUG
std::cerr << "CUPnPControlPoint::Callback() Uerror(UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE): " <<
upnpCP->m_upnpLib.GetUPnPErrorMessage(dab_event->ErrCode) <<
"." << std::endl;
#endif
}
std::string devType = dab_event->DeviceType;
case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: // UPnP Device Removed
{
const UpnpDiscovery* dab_event = static_cast<const UpnpDiscovery*>(Event);
if(!dab_event) break;
std::string devType = UpnpDiscovery_get_DeviceType_cstr(dab_event);
// Check for an InternetGatewayDevice and removes it from the list
std::transform(devType.begin(), devType.end(), devType.begin(), tolower);
if (stdStringIsEqualCI(devType, upnpCP->m_upnpLib.UPNP_DEVICE_IGW)) {
upnpCP->RemoveRootDevice(dab_event->DeviceId);
}
if (stdStringIsEqualCI(devType, upnpCP->m_upnpLib.UPNP_DEVICE_IGW))
upnpCP->RemoveRootDevice(
UpnpDiscovery_get_DeviceID_cstr(dab_event) );
break;
}
case UPNP_EVENT_RECEIVED: {
#ifdef UPNP_DEBUG
fprintf(stderr, "Callback: UPNP_EVENT_RECEIVED\n");
#endif
case UPNP_EVENT_RECEIVED:
{
// Event reveived
struct Upnp_Event *e_event = (struct Upnp_Event *)Event;
const std::string Sid = e_event->Sid;
const UpnpEvent* e_event = static_cast<const UpnpEvent*>(Event);
const std::string Sid = UpnpEvent_get_SID_cstr(e_event);
// Parses the event
upnpCP->OnEventReceived(Sid, e_event->EventKey, e_event->ChangedVariables);
upnpCP->OnEventReceived( Sid,
UpnpEvent_get_EventKey(e_event),
UpnpEvent_get_ChangedVariables(e_event) );
break;
}
case UPNP_EVENT_SUBSCRIBE_COMPLETE:
//fprintf(stderr, "Callback: UPNP_EVENT_SUBSCRIBE_COMPLETE\n");
msg += "error(UPNP_EVENT_SUBSCRIBE_COMPLETE): ";
goto upnpEventRenewalComplete;
case UPNP_EVENT_UNSUBSCRIBE_COMPLETE:
//fprintf(stderr, "Callback: UPNP_EVENT_UNSUBSCRIBE_COMPLETE\n");
msg += "error(UPNP_EVENT_UNSUBSCRIBE_COMPLETE): ";
goto upnpEventRenewalComplete;
case UPNP_EVENT_RENEWAL_COMPLETE: {
//fprintf(stderr, "Callback: UPNP_EVENT_RENEWAL_COMPLETE\n");
case UPNP_EVENT_RENEWAL_COMPLETE:
{
msg += "error(UPNP_EVENT_RENEWAL_COMPLETE): ";
upnpEventRenewalComplete:
struct Upnp_Event_Subscribe *es_event =
(struct Upnp_Event_Subscribe *)Event;
if (es_event->ErrCode != UPNP_E_SUCCESS) {
const UpnpEventSubscribe* es_event =
static_cast<const UpnpEventSubscribe*>(Event);
if (UpnpEventSubscribe_get_ErrCode(es_event) != UPNP_E_SUCCESS)
{
msg += "Error in Event Subscribe Callback";
upnpCP->m_upnpLib.processUPnPErrorMessage(
msg, es_event->ErrCode, NULL, NULL);
} else {
#if 0
TvCtrlPointHandleSubscribeUpdate(
es_event->PublisherUrl,
es_event->Sid,
es_event->TimeOut );
#endif
msg, UpnpEventSubscribe_get_ErrCode(es_event),
nullptr, nullptr );
}
break;
}
case UPNP_EVENT_AUTORENEWAL_FAILED:
//fprintf(stderr, "Callback: UPNP_EVENT_AUTORENEWAL_FAILED\n");
msg += "CUPnPControlPoint::Callback() error(UPNP_EVENT_AUTORENEWAL_FAILED): ";
msg2 += "UPNP_EVENT_AUTORENEWAL_FAILED: ";
goto upnpEventSubscriptionExpired;
case UPNP_EVENT_SUBSCRIPTION_EXPIRED: {
//fprintf(stderr, "Callback: UPNP_EVENT_SUBSCRIPTION_EXPIRED\n");
msg += "CUPnPControlPoint::Callback() error(UPNP_EVENT_SUBSCRIPTION_EXPIRED): ";
msg2 += "UPNP_EVENT_SUBSCRIPTION_EXPIRED: ";
upnpEventSubscriptionExpired:
struct Upnp_Event_Subscribe *es_event =
(struct Upnp_Event_Subscribe *)Event;
const UpnpEventSubscribe* es_event =
static_cast<const UpnpEventSubscribe*>(Event);
Upnp_SID newSID;
int TimeOut = 1801;
int ret = UpnpSubscribe(
@ -1481,20 +1449,25 @@ upnpEventSubscriptionExpired:
#ifdef PATCHED_LIBUPNP
UpnpString_get_String(es_event->PublisherUrl),
#else
es_event->PublisherUrl,
UpnpEventSubscribe_get_PublisherUrl_cstr(es_event),
#endif
&TimeOut,
newSID);
if (ret != UPNP_E_SUCCESS) {
if (ret != UPNP_E_SUCCESS)
{
msg += "Error Subscribing to EventURL";
upnpCP->m_upnpLib.processUPnPErrorMessage(
msg, es_event->ErrCode, NULL, NULL);
} else {
msg, UpnpEventSubscribe_get_ErrCode(es_event),
nullptr, nullptr );
}
else
{
ServiceMap::iterator it =
#ifdef PATCHED_LIBUPNP
upnpCP->m_ServiceMap.find(UpnpString_get_String(es_event->PublisherUrl));
#else
upnpCP->m_ServiceMap.find(es_event->PublisherUrl);
upnpCP->m_ServiceMap.find(
UpnpEventSubscribe_get_PublisherUrl_cstr(es_event) );
#endif
if (it != upnpCP->m_ServiceMap.end()) {
CUPnPService &service = *(it->second);
@ -1504,7 +1477,7 @@ upnpEventSubscriptionExpired:
#ifdef PATCHED_LIBUPNP
UpnpString_get_String(es_event->PublisherUrl) <<
#else
es_event->PublisherUrl <<
UpnpEventSubscribe_get_PublisherUrl_cstr(es_event) <<
#endif
"' with SID == '" <<
newSID << "'." << std::endl;
@ -1512,7 +1485,9 @@ upnpEventSubscriptionExpired:
// service is the same. But here we only have one
// service, so...
upnpCP->RefreshPortMappings();
} else {
}
else
{
#ifdef UPNP_DEBUG
std::cerr << "CUPnPControlPoint::Callback() Error: did not find service " <<
newSID << " in the service map." << std::endl;
@ -1521,41 +1496,49 @@ upnpEventSubscriptionExpired:
}
break;
}
case UPNP_CONTROL_ACTION_COMPLETE: {
//fprintf(stderr, "Callback: UPNP_CONTROL_ACTION_COMPLETE\n");
case UPNP_CONTROL_ACTION_COMPLETE:
{
// This is here if we choose to do this asynchronously
struct Upnp_Action_Complete *a_event =
(struct Upnp_Action_Complete *)Event;
if (a_event->ErrCode != UPNP_E_SUCCESS) {
const UpnpActionComplete* a_event =
static_cast<const UpnpActionComplete*>(Event);
if(UpnpActionComplete_get_ErrCode(a_event) != UPNP_E_SUCCESS)
{
upnpCP->m_upnpLib.processUPnPErrorMessage(
"UpnpSendActionAsync",
a_event->ErrCode, NULL,
a_event->ActionResult);
} else {
"UpnpSendActionAsync",
UpnpActionComplete_get_ErrCode(a_event), nullptr,
UpnpActionComplete_get_ActionResult(a_event) );
}
else
{
// Check the response document
upnpCP->m_upnpLib.ProcessActionResponse(
a_event->ActionResult,
"<UpnpSendActionAsync>");
UpnpActionComplete_get_ActionResult(a_event),
"<UpnpSendActionAsync>" );
}
/* No need for any processing here, just print out results.
* Service state table updates are handled by events.
*/
break;
}
case UPNP_CONTROL_GET_VAR_COMPLETE: {
#ifdef UPNP_DEBUG
fprintf(stderr, "CUPnPControlPoint::Callback() Callback: UPNP_CONTROL_GET_VAR_COMPLETE\n");
#endif
case UPNP_CONTROL_GET_VAR_COMPLETE:
{
msg += "CUPnPControlPoint::Callback() error(UPNP_CONTROL_GET_VAR_COMPLETE): ";
struct Upnp_State_Var_Complete *sv_event =
(struct Upnp_State_Var_Complete *)Event;
if (sv_event->ErrCode != UPNP_E_SUCCESS) {
const UpnpStateVarComplete* sv_event =
static_cast<const UpnpStateVarComplete*>(Event);
if (UpnpStateVarComplete_get_ErrCode(sv_event) != UPNP_E_SUCCESS)
{
msg += "m_UpnpGetServiceVarStatusAsync";
upnpCP->m_upnpLib.processUPnPErrorMessage(
msg, sv_event->ErrCode, NULL, NULL);
} else {
//add the variable to the wanservice property map
(upnpCP->m_WanService->propertyMap)[std::string(sv_event->StateVarName)] = std::string(sv_event->CurrentVal);
msg, UpnpStateVarComplete_get_ErrCode(sv_event),
nullptr, nullptr );
}
else
{
//add the variable to the wanservice property map
(upnpCP->m_WanService->propertyMap)[
std::string(
UpnpStateVarComplete_get_StateVarName_cstr(sv_event) ) ]
= std::string(UpnpStateVarComplete_get_CurrentVal_cstr(sv_event));
}
break;
}
@ -1603,7 +1586,7 @@ eventSubscriptionRequest:
void CUPnPControlPoint::OnEventReceived(
const std::string &Sid,
int EventKey,
IXML_Document *ChangedVariablesDoc)
const IXML_Document* ChangedVariablesDoc)
{
/* remove unused parameter warnings */
(void) EventKey;

View File

@ -43,6 +43,7 @@
extern std::string stdEmptyString;
#endif // UPNP_C
//#define UPNP_DEBUG 1
/**
* Case insensitive std::string comparison
@ -113,20 +114,18 @@ public:
// Convenience function to avoid repetitive processing of error
// messages
std::string processUPnPErrorMessage(
const std::string &messsage,
int code,
const DOMString errorString,
IXML_Document *doc) const;
std::string processUPnPErrorMessage(const std::string &messsage,
int code,
const DOMString errorString,
const IXML_Document* doc) const;
// Processing response to actions
void ProcessActionResponse(
IXML_Document *RespDoc,
const std::string &actionName) const;
const IXML_Document* RespDoc,
const std::string& actionName ) const;
// IXML_Element
IXML_Element *Element_GetRootElement(
IXML_Document *doc) const;
IXML_Element* Element_GetRootElement(const IXML_Document* doc) const;
IXML_Element *Element_GetFirstChild(
IXML_Element *parent) const;
IXML_Element *Element_GetNextSibling(
@ -257,7 +256,7 @@ private:
public:
CUPnPError(
const CUPnPLib &upnpLib,
IXML_Document *errorDoc);
const IXML_Document *errorDoc);
~CUPnPError() {}
const std::string &getErrorCode() const
{ return m_ErrorCode; }
@ -597,13 +596,10 @@ public:
// Callback function
static int Callback(
Upnp_EventType EventType,
void* Event,
void* Cookie);
void OnEventReceived(
const std::string &Sid,
int EventKey,
IXML_Document *ChangedVariables);
Upnp_EventType EventType, const void* Event, void* Cookie );
void OnEventReceived(const std::string &Sid,
int EventKey,
const IXML_Document* ChangedVariables);
private:
void AddRootDevice(

View File

@ -0,0 +1,82 @@
/*******************************************************************************
* libupnp-1.8.x -> libupnp-1.6.x retrocompatibility header *
* *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include <upnp/upnp.h>
#if UPNP_VERSION < 10800
using UpnpDiscovery = Upnp_Discovery;
using UpnpEvent = Upnp_Event;
using UpnpEventSubscribe = Upnp_Event_Subscribe;
using UpnpActionComplete = Upnp_Action_Complete;
using UpnpStateVarComplete = Upnp_State_Var_Complete;
static inline const char* UpnpStateVarComplete_get_CurrentVal_cstr(
const UpnpStateVarComplete* esvc) noexcept { return esvc->CurrentVal; }
#endif // UPNP_VERSION < 10800
#if UPNP_VERSION < 10624
static inline int UpnpDiscovery_get_Expires(const Upnp_Discovery* disc) noexcept
{ return disc->Expires; }
static inline const char* UpnpDiscovery_get_DeviceID_cstr(
const Upnp_Discovery* disc ) noexcept
{ return disc->DeviceId; }
static inline const char* UpnpDiscovery_get_DeviceType_cstr(
const Upnp_Discovery* disc ) noexcept
{ return disc->DeviceType; }
static inline const char* UpnpDiscovery_get_Location_cstr(
const Upnp_Discovery* disc ) noexcept
{ return disc->Location; }
static inline const char* UpnpEvent_get_SID_cstr(const UpnpEvent* ev) noexcept
{ return ev->Sid; }
static inline int UpnpEvent_get_EventKey(const UpnpEvent* ev) noexcept
{ return ev->EventKey; }
static inline const IXML_Document* UpnpEvent_get_ChangedVariables(
const UpnpEvent* ev) noexcept { return ev->ChangedVariables; }
static inline int UpnpEventSubscribe_get_ErrCode(const UpnpEventSubscribe* evs)
noexcept { return evs->ErrCode; }
static inline const char* UpnpEventSubscribe_get_PublisherUrl_cstr(
const UpnpEventSubscribe* evs ) noexcept { return evs->PublisherUrl; }
static inline int UpnpActionComplete_get_ErrCode(const UpnpActionComplete* evc)
noexcept { return evc->ErrCode; }
static inline const IXML_Document* UpnpActionComplete_get_ActionResult(
const UpnpActionComplete* evc ) noexcept { return evc->ActionResult; }
static inline int UpnpStateVarComplete_get_ErrCode(
const UpnpStateVarComplete* esvc) noexcept { return esvc->ErrCode; }
static inline const char* UpnpStateVarComplete_get_StateVarName_cstr(
const UpnpStateVarComplete* esvc) noexcept { return esvc->StateVarName; }
#endif // UPNP_VERSION < 10624

View File

@ -28,7 +28,7 @@ extern "C" {
#endif
/* This stuff is actually C */
#include "upnp/upnphandler_linux.h"
#include "rs_upnp/upnphandler_linux.h"
#include "util/rsnet.h"

View File

@ -31,7 +31,7 @@
#include "util/rsthreads.h"
#include <upnp/upnp.h>
#include "upnp/UPnPBase.h"
#include "rs_upnp/UPnPBase.h"
#define RS_UPNP_S_UNINITIALISED 0
#define RS_UPNP_S_UNAVAILABLE 1

View File

@ -31,8 +31,8 @@ extern "C" {
#endif
/* This stuff is actually C */
#include "upnp/upnphandler_miniupnp.h"
#include "upnp/upnputil.h"
#include "rs_upnp/upnphandler_miniupnp.h"
#include "rs_upnp/upnputil.h"
class uPnPConfigData
{

Some files were not shown because too many files have changed in this diff Show More