diff --git a/.travis.yml b/.travis.yml index e11da2148..ea4fc567f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,7 +45,7 @@ before_script: script: - if [ $TRAVIS_OS_NAME == linux ] && [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make -j2; fi - - if [ $TRAVIS_OS_NAME == osx ] && [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make -j2; fi + - if [ $TRAVIS_OS_NAME == osx ] && [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then echo TEMPORARILY DISABLED make -j2; fi #after_success: diff --git a/libresapi/src/api/FileSearchHandler.cpp b/libresapi/src/api/FileSearchHandler.cpp index 73e7848f0..c768b1112 100644 --- a/libresapi/src/api/FileSearchHandler.cpp +++ b/libresapi/src/api/FileSearchHandler.cpp @@ -50,7 +50,7 @@ FileSearchHandler::~FileSearchHandler() mStateTokenServer->discardToken(mSearchesStateToken); } -void FileSearchHandler::notifyTurtleSearchResult(uint32_t search_id, const std::list& files) +void FileSearchHandler::notifyTurtleSearchResult(const RsPeerId& pid,uint32_t search_id, const std::list& files) { RS_STACK_MUTEX(mMtx); // ********** LOCKED ********** std::map::iterator mit = mSearches.find(search_id); diff --git a/libresapi/src/api/FileSearchHandler.h b/libresapi/src/api/FileSearchHandler.h index d4b3c31cf..66b79209c 100644 --- a/libresapi/src/api/FileSearchHandler.h +++ b/libresapi/src/api/FileSearchHandler.h @@ -37,7 +37,7 @@ public: virtual ~FileSearchHandler(); // from NotifyClient - virtual void notifyTurtleSearchResult(uint32_t search_id, const std::list& files); + virtual void notifyTurtleSearchResult(const RsPeerId &pid, uint32_t search_id, const std::list& files); private: void handleWildcard(Request& req, Response& resp); void handleCreateSearch(Request& req, Response& resp); diff --git a/libresapi/src/libresapi.pro b/libresapi/src/libresapi.pro index b07846411..ba728f9a5 100644 --- a/libresapi/src/libresapi.pro +++ b/libresapi/src/libresapi.pro @@ -110,7 +110,7 @@ libresapihttpserver { QMAKE_EXTRA_COMPILERS += create_webfiles_html create_webfiles_js create_webfiles_css } - win32 { + appveyor { DEFINES *= WINDOWS_SYS INCLUDEPATH += . $$INC_DIR @@ -126,6 +126,19 @@ libresapihttpserver { system($$MAKE_SRC\\init.bat .) } + win32 { + DEFINES *= WINDOWS_SYS + INCLUDEPATH += . $$INC_DIR + + PRO_PATH=$$shell_path($$_PRO_FILE_PWD_) + MAKE_SRC=$$shell_path($$PRO_PATH/webui-src/make-src) + + QMAKE_POST_LINK=$$MAKE_SRC/build.sh $$PRO_PATH + + # create dummy files + system($$MAKE_SRC/init.sh .) + } + linux { CONFIG += link_pkgconfig PKGCONFIG *= libmicrohttpd diff --git a/libretroshare/src/file_sharing/file_sharing_defaults.h b/libretroshare/src/file_sharing/file_sharing_defaults.h index 09bf937d5..6633e348f 100644 --- a/libretroshare/src/file_sharing/file_sharing_defaults.h +++ b/libretroshare/src/file_sharing/file_sharing_defaults.h @@ -21,24 +21,25 @@ ******************************************************************************/ #pragma once -static const uint32_t DELAY_BETWEEN_DIRECTORY_UPDATES = 600 ; // 10 minutes -static const uint32_t DELAY_BETWEEN_REMOTE_DIRECTORY_SYNC_REQ = 120 ; // 2 minutes -static const uint32_t DELAY_BETWEEN_LOCAL_DIRECTORIES_TS_UPDATE = 20 ; // 20 sec. But we only update for real if something has changed. -static const uint32_t DELAY_BETWEEN_REMOTE_DIRECTORIES_SWEEP = 60 ; // 60 sec. +static const uint32_t DELAY_BETWEEN_DIRECTORY_UPDATES = 600 ; // 10 minutes +static const uint32_t DELAY_BETWEEN_REMOTE_DIRECTORY_SYNC_REQ = 120 ; // 2 minutes +static const uint32_t DELAY_BETWEEN_LOCAL_DIRECTORIES_TS_UPDATE = 20 ; // 20 sec. But we only update for real if something has changed. +static const uint32_t DELAY_BETWEEN_REMOTE_DIRECTORIES_SWEEP = 60 ; // 60 sec. static const uint32_t DELAY_BEFORE_DELETE_NON_EMPTY_REMOTE_DIR = 60*24*86400 ; // delete non empty remoe directories after 60 days of inactivity static const uint32_t DELAY_BEFORE_DELETE_EMPTY_REMOTE_DIR = 5*24*86400 ; // delete empty remote directories after 5 days of inactivity -static const std::string HASH_CACHE_DURATION_SS = "HASH_CACHE_DURATION" ; // key string to store hash remembering time -static const std::string WATCH_FILE_DURATION_SS = "WATCH_FILES_DELAY" ; // key to store delay before re-checking for new files -static const std::string WATCH_FILE_ENABLED_SS = "WATCH_FILES_ENABLED"; // key to store ON/OFF flags for file whatch -static const std::string FOLLOW_SYMLINKS_SS = "FOLLOW_SYMLINKS"; // dereference symbolic links, or just ignore them. -static const std::string IGNORE_DUPLICATES = "IGNORE_DUPLICATES"; // do not index files that are referenced multiple times because of links -static const std::string WATCH_HASH_SALT_SS = "WATCH_HASH_SALT"; // Salt that is used to hash directory names -static const std::string IGNORED_PREFIXES_SS = "IGNORED_PREFIXES"; // ignore file prefixes -static const std::string IGNORED_SUFFIXES_SS = "IGNORED_SUFFIXES"; // ignore file suffixes -static const std::string IGNORE_LIST_FLAGS_SS = "IGNORED_FLAGS"; // ignore file flags -static const std::string MAX_SHARE_DEPTH = "MAX_SHARE_DEPTH"; // maximum depth of shared directories +static const std::string HASH_CACHE_DURATION_SS = "HASH_CACHE_DURATION" ; // key string to store hash remembering time +static const std::string WATCH_FILE_DURATION_SS = "WATCH_FILES_DELAY" ; // key to store delay before re-checking for new files +static const std::string WATCH_FILE_ENABLED_SS = "WATCH_FILES_ENABLED"; // key to store ON/OFF flags for file whatch +static const std::string TRUST_FRIEND_NODES_FOR_BANNED_FILES_SS = "TRUST_FRIEND_NODES_FOR_BANNED_FILES"; // should we trust friends for banned files or not +static const std::string FOLLOW_SYMLINKS_SS = "FOLLOW_SYMLINKS"; // dereference symbolic links, or just ignore them. +static const std::string IGNORE_DUPLICATES = "IGNORE_DUPLICATES"; // do not index files that are referenced multiple times because of links +static const std::string WATCH_HASH_SALT_SS = "WATCH_HASH_SALT"; // Salt that is used to hash directory names +static const std::string IGNORED_PREFIXES_SS = "IGNORED_PREFIXES"; // ignore file prefixes +static const std::string IGNORED_SUFFIXES_SS = "IGNORED_SUFFIXES"; // ignore file suffixes +static const std::string IGNORE_LIST_FLAGS_SS = "IGNORED_FLAGS"; // ignore file flags +static const std::string MAX_SHARE_DEPTH = "MAX_SHARE_DEPTH"; // maximum depth of shared directories static const std::string FILE_SHARING_DIR_NAME = "file_sharing" ; // hard-coded directory name to store friend file lists, hash cache, etc. static const std::string HASH_CACHE_FILE_NAME = "hash_cache.bin" ; // hard-coded directory name to store encrypted hash cache. @@ -61,6 +62,7 @@ static const uint64_t ENTRY_INDEX_BIT_MASK_64BITS = 0x0000000 static const uint32_t DELAY_BEFORE_DROP_REQUEST = 600; // every 10 min -static const bool FOLLOW_SYMLINKS_DEFAULT = true; +static const bool FOLLOW_SYMLINKS_DEFAULT = true; +static const bool TRUST_FRIEND_NODES_FOR_BANNED_FILES_DEFAULT = true; static const uint32_t FL_BASE_TMP_SECTION_SIZE = 4096 ; diff --git a/libretroshare/src/file_sharing/p3filelists.cc b/libretroshare/src/file_sharing/p3filelists.cc index 7448ffd0d..156490e18 100644 --- a/libretroshare/src/file_sharing/p3filelists.cc +++ b/libretroshare/src/file_sharing/p3filelists.cc @@ -37,6 +37,7 @@ #define P3FILELISTS_ERROR() std::cerr << "***ERROR***" << " : FILE_LISTS : " << __FUNCTION__ << " : " //#define DEBUG_P3FILELISTS 1 +#define DEBUG_CONTENT_FILTERING 1 static const uint32_t P3FILELISTS_UPDATE_FLAG_NOTHING_CHANGED = 0x0000 ; static const uint32_t P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED = 0x0001 ; @@ -72,6 +73,8 @@ p3FileDatabase::p3FileDatabase(p3ServiceControl *mpeers) mLastRemoteDirSweepTS = 0 ; mLastCleanupTime = 0 ; mLastDataRecvTS = 0 ; + mTrustFriendNodesForBannedFiles = TRUST_FRIEND_NODES_FOR_BANNED_FILES_DEFAULT; + mLastPrimaryBanListChangeTimeStamp = 0; // This is for the transmission of data @@ -182,15 +185,19 @@ int p3FileDatabase::tick() if(last_print_time + 20 < now) { - RS_STACK_MUTEX(mFLSMtx) ; + { + RS_STACK_MUTEX(mFLSMtx) ; #ifdef DEBUG_FILE_HIERARCHY - mLocalSharedDirs->print(); + mLocalSharedDirs->print(); #endif - last_print_time = now ; + last_print_time = now ; + } #warning mr-alice 2016-08-19: "This should be removed, but it's necessary atm for updating the GUI" RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0); + + checkSendBannedFilesInfo(); } if(mUpdateFlags) @@ -304,6 +311,15 @@ cleanup = true; } } + { + RS_STACK_MUTEX(mFLSMtx) ; + + RsFileListsBannedHashesConfigItem *item = new RsFileListsBannedHashesConfigItem ; + + item->primary_banned_files_list = mPrimaryBanList; + sList.push_back(item) ; + } + RsConfigKeyValueSet *rskv = new RsConfigKeyValueSet(); /* basic control parameters */ @@ -369,6 +385,14 @@ cleanup = true; { RsTlvKeyValue kv; + kv.key = TRUST_FRIEND_NODES_FOR_BANNED_FILES_SS; + kv.value = trustFriendNodesForBannedFiles()?"YES":"NO" ; + + rskv->tlvkvs.pairs.push_back(kv); + } + { + RsTlvKeyValue kv; + kv.key = WATCH_HASH_SALT_SS; kv.value = mLocalDirWatcher->hashSalt().toStdString(); @@ -462,6 +486,10 @@ bool p3FileDatabase::loadList(std::list& load) { setWatchEnabled(kit->value == "YES") ; } + else if(kit->key == TRUST_FRIEND_NODES_FOR_BANNED_FILES_SS) + { + setTrustFriendNodesForBannedFiles(kit->value == "YES") ; + } else if(kit->key == WATCH_HASH_SALT_SS) { std::cerr << "Initing directory watcher with saved secret salt..." << std::endl; @@ -533,6 +561,15 @@ bool p3FileDatabase::loadList(std::list& load) dirList.push_back(info) ; } + RsFileListsBannedHashesConfigItem *fb = dynamic_cast(*it) ; + + if(fb) + { + mPrimaryBanList = fb->primary_banned_files_list ; + mBannedFileListNeedsUpdate = true; + mLastPrimaryBanListChangeTimeStamp = time(NULL); + } + delete *it ; } @@ -1402,8 +1439,8 @@ void p3FileDatabase::tickRecv() { switch(item->PacketSubType()) { - case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: handleDirSyncRequest( dynamic_cast(item) ) ; - break ; + case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: handleDirSyncRequest( dynamic_cast(item) ) ; break ; + case RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_ITEM : handleBannedFilesInfo( dynamic_cast(item) ) ; break ; case RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM: { RsFileListsSyncResponseItem *sitem = dynamic_cast(item); @@ -1855,6 +1892,262 @@ bool p3FileDatabase::locked_generateAndSendSyncRequest(RemoteDirectoryStorage *r } +//=========================================================================================================================// +// Unwanted content filtering system // +//=========================================================================================================================// +bool p3FileDatabase::banFile(const RsFileHash& real_file_hash, const std::string& filename, uint64_t file_size) +{ +#ifdef DEBUG_CONTENT_FILTERING + P3FILELISTS_DEBUG() << " setting file \"" << filename << "\" size=" << file_size << " hash=" << real_file_hash << " as banned." << std::endl; +#endif + { + RS_STACK_MUTEX(mFLSMtx) ; + BannedFileEntry& entry(mPrimaryBanList[real_file_hash]) ; // primary list (user controlled) of files banned from FT search and forwarding. map + if(entry.ban_time_stamp == 0) + { + entry.filename = filename ; + entry.size = file_size ; + entry.ban_time_stamp = time(NULL); + + RsFileHash hash_of_hash ; + ftServer::encryptHash(real_file_hash,hash_of_hash) ; + + mBannedFileList.insert(real_file_hash) ; + mBannedFileList.insert(hash_of_hash) ; + + mLastPrimaryBanListChangeTimeStamp = time(NULL); + mBannedFileListNeedsUpdate = true ; + } + } + + IndicateConfigChanged(); + return true; +} +bool p3FileDatabase::unbanFile(const RsFileHash& real_file_hash) +{ +#ifdef DEBUG_CONTENT_FILTERING + P3FILELISTS_DEBUG() << " unbanning file with hash " << real_file_hash << std::endl; +#endif + { + RS_STACK_MUTEX(mFLSMtx) ; + mPrimaryBanList.erase(real_file_hash) ; + mLastPrimaryBanListChangeTimeStamp = time(NULL); + mBannedFileListNeedsUpdate = true ; + } + + IndicateConfigChanged(); + return true; +} + +bool p3FileDatabase::isFileBanned(const RsFileHash& hash) +{ + RS_STACK_MUTEX(mFLSMtx) ; + + if(mBannedFileList.empty()) // quick exit + return false ; + + RsFileHash hash_of_hash ; + ftServer::encryptHash(hash,hash_of_hash) ; + + bool res = mBannedFileList.find(hash) != mBannedFileList.end() || mBannedFileList.find(hash_of_hash) != mBannedFileList.end() ; + +#ifdef DEBUG_CONTENT_FILTERING + if(res) + P3FILELISTS_DEBUG() << " is file banned(" << hash << "): " << (res?"YES":"NO") << std::endl; +#endif + return res ; +} + +bool p3FileDatabase::getPrimaryBannedFilesList(std::map& banned_files) +{ + RS_STACK_MUTEX(mFLSMtx) ; + banned_files = mPrimaryBanList; + + return true ; +} + +bool p3FileDatabase::trustFriendNodesForBannedFiles() const +{ + RS_STACK_MUTEX(mFLSMtx) ; + return mTrustFriendNodesForBannedFiles; +} + +void p3FileDatabase::setTrustFriendNodesForBannedFiles(bool b) +{ + if(b != mTrustFriendNodesForBannedFiles) + { + IndicateConfigChanged(); + mBannedFileListNeedsUpdate = true; + } + + RS_STACK_MUTEX(mFLSMtx) ; + mTrustFriendNodesForBannedFiles = b; +} + +void p3FileDatabase::checkSendBannedFilesInfo() +{ + RS_STACK_MUTEX(mFLSMtx) ; + + // 1 - compare records to list of online friends, send own info of not already + +#ifdef DEBUG_CONTENT_FILTERING + P3FILELISTS_DEBUG() << " Checking banned files information: " << std::endl; +#endif + + time_t now = time(NULL); + std::list online_friends ; + rsPeers->getOnlineList(online_friends); + + std::set peers ; + for(auto it(online_friends.begin());it!=online_friends.end();++it) // convert to std::set for efficient search + peers.insert(*it) ; + + for(auto it(mPeerBannedFiles.begin());it!=mPeerBannedFiles.end();) + { + if(peers.find(it->first) == peers.end()) // friend not online, remove his record + { + it = mPeerBannedFiles.erase(it) ; +#ifdef DEBUG_CONTENT_FILTERING + P3FILELISTS_DEBUG() << " Peer " << it->first << " is offline: removign record." << std::endl; +#endif + continue; + } + + if(it->second.mLastSent < mLastPrimaryBanListChangeTimeStamp) // has ban info already been sent? If not do it. + { +#ifdef DEBUG_CONTENT_FILTERING + P3FILELISTS_DEBUG() << " Peer " << it->first << " is online and hasn't been sent since last change: sending..." << std::endl; +#endif + locked_sendBanInfo(it->first); + it->second.mLastSent = now; + } + + peers.erase(it->first); // friend has been handled -> remove from list + ++it; + } + + // 2 - add a new record for friends not already in the record map + + for(auto it(peers.begin());it!=peers.end();++it) + { + locked_sendBanInfo(*it); + mPeerBannedFiles[*it].mLastSent = now; +#ifdef DEBUG_CONTENT_FILTERING + P3FILELISTS_DEBUG() << " Peer " << *it << " is online and hasn't been sent info at all: sending..." << std::endl; +#endif + } + + // 3 - update list of banned hashes if it has changed somehow + + if(mBannedFileListNeedsUpdate) + { + mBannedFileList.clear(); + +#ifdef DEBUG_CONTENT_FILTERING + P3FILELISTS_DEBUG() << " Creating local banned file list: " << std::endl; +#endif + // Add all H(H(f)) from friends + + if(mTrustFriendNodesForBannedFiles) + for(auto it(mPeerBannedFiles.begin());it!=mPeerBannedFiles.end();++it) + for(auto it2(it->second.mBannedHashOfHash.begin());it2!=it->second.mBannedHashOfHash.end();++it2) + { + mBannedFileList.insert(*it2); + +#ifdef DEBUG_CONTENT_FILTERING + P3FILELISTS_DEBUG() << " from " << it->first << ": H(H(f)) = " << *it2 << std::endl; +#endif + } + + // Add H(f) and H(H(f)) from our primary list + + for(auto it(mPrimaryBanList.begin());it!=mPrimaryBanList.end();++it) + { + mBannedFileList.insert(it->first) ; + + RsFileHash hash_of_hash ; + ftServer::encryptHash(it->first,hash_of_hash) ; + + mBannedFileList.insert(hash_of_hash) ; + +#ifdef DEBUG_CONTENT_FILTERING + P3FILELISTS_DEBUG() << " primary: H(f) = " << it->first << ": H(H(f)) = " << hash_of_hash << std::endl; +#endif + } + + mBannedFileListNeedsUpdate = false ; + } + +#ifdef DEBUG_CONTENT_FILTERING + P3FILELISTS_DEBUG() << " Final list of locally banned hashes contains: " << mBannedFileList.size() << " elements." << std::endl; +#endif +} + +void p3FileDatabase::locked_sendBanInfo(const RsPeerId& peer) +{ + RsFileListsBannedHashesItem *item = new RsFileListsBannedHashesItem ; + uint32_t session_id = RSRandom::random_u32(); + + item->session_id = session_id ; + item->PeerId(peer); + + for(auto it(mPrimaryBanList.begin());it!=mPrimaryBanList.end();++it) + { + RsFileHash hash_of_hash ; + + ftServer::encryptHash(it->first,hash_of_hash) ; + + if(!item) + { + item = new RsFileListsBannedHashesItem ; + + item->PeerId(peer); + item->session_id = session_id ; + } + + item->encrypted_hashes.insert(hash_of_hash) ; + + if(item->encrypted_hashes.size() >= 200) + { + sendItem(item); + item = NULL ; + } + } + + if(item) + sendItem(item); +} + +void p3FileDatabase::handleBannedFilesInfo(RsFileListsBannedHashesItem *item) +{ + RS_STACK_MUTEX(mFLSMtx) ; + +#ifdef DEBUG_CONTENT_FILTERING + P3FILELISTS_DEBUG() << " received banned files info from peer " << item->PeerId() << ", session id = " << std::hex << item->session_id << std::dec << ": " << item->encrypted_hashes.size() << " files:" << std::endl; +#endif + // 1 - localize the friend in the banned file map + + PeerBannedFilesEntry& pbfe(mPeerBannedFiles[item->PeerId()]) ; + + if(pbfe.mSessionId != item->session_id) + pbfe.mBannedHashOfHash.clear(); + + pbfe.mSessionId = item->session_id ; + + // 2 - replace/update the list, depending on the session_id + + for(auto it(item->encrypted_hashes.begin());it!=item->encrypted_hashes.end();++it) + { + pbfe.mBannedHashOfHash.insert(*it); +#ifdef DEBUG_CONTENT_FILTERING + P3FILELISTS_DEBUG() << " added H(H(f)) = " << *it << std::endl; +#endif + } + + // 3 - tell the updater that the banned file list has changed + + mBannedFileListNeedsUpdate = true ; +} diff --git a/libretroshare/src/file_sharing/p3filelists.h b/libretroshare/src/file_sharing/p3filelists.h index 44e5ec4b4..a8ac377ea 100644 --- a/libretroshare/src/file_sharing/p3filelists.h +++ b/libretroshare/src/file_sharing/p3filelists.h @@ -62,9 +62,17 @@ class LocalDirectoryStorage ; class RsFileListsSyncRequestItem ; class RsFileListsSyncResponseItem ; +class RsFileListsBannedHashesItem ; class HashStorage ; +struct PeerBannedFilesEntry +{ + std::set mBannedHashOfHash; + uint32_t mSessionId ; // used for when a friend sends multiple packets in separate items. + time_t mLastSent; +}; + class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, public RsSharedFileService { public: @@ -132,6 +140,13 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub void setMaxShareDepth(int i) ; int maxShareDepth() const ; + bool banFile(const RsFileHash& real_file_hash, const std::string& filename, uint64_t file_size) ; + bool unbanFile(const RsFileHash& real_file_hash); + bool isFileBanned(const RsFileHash& hash) ; + bool getPrimaryBannedFilesList(std::map& banned_files) ; + bool trustFriendNodesForBannedFiles() const ; + void setTrustFriendNodesForBannedFiles(bool b) ; + // computes/gathers statistics about shared directories int getSharedDirStatistics(const RsPeerId& pid,SharedDirStats& stats); @@ -168,6 +183,8 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub void tickRecv(); void tickSend(); + void checkSendBannedFilesInfo(); + private: p3ServiceControl *mServCtrl ; RsPeerId mOwnId ; @@ -244,5 +261,18 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub std::string mFileSharingDir ; time_t mLastCleanupTime; time_t mLastDataRecvTS ; + + // File filtering. Not explicitly related to shared files, but has its place here + // + + std::map mPrimaryBanList ; // primary list (user controlled) of files banned from FT search and forwarding. map + std::map mPeerBannedFiles ; // records of which files other peers ban, stored as H(H(f)) + std::set mBannedFileList ; // list of banned hashes. This include original hashs and H(H(f)) when coming from friends. + bool mTrustFriendNodesForBannedFiles ; + bool mBannedFileListNeedsUpdate; + time_t mLastPrimaryBanListChangeTimeStamp; + + void locked_sendBanInfo(const RsPeerId& pid); + void handleBannedFilesInfo(RsFileListsBannedHashesItem *item); }; diff --git a/libretroshare/src/file_sharing/rsfilelistitems.cc b/libretroshare/src/file_sharing/rsfilelistitems.cc index 49aa4edff..c443d1f3a 100644 --- a/libretroshare/src/file_sharing/rsfilelistitems.cc +++ b/libretroshare/src/file_sharing/rsfilelistitems.cc @@ -34,14 +34,28 @@ void RsFileListsSyncRequestItem::serial_process(RsGenericSerializer::SerializeJo } void RsFileListsSyncResponseItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) { - RsTypeSerializer::serial_process (j,ctx,entry_hash,"entry_hash") ; - RsTypeSerializer::serial_process (j,ctx,checksum,"checksum") ; - RsTypeSerializer::serial_process (j,ctx,flags ,"flags") ; + RsTypeSerializer::serial_process (j,ctx,entry_hash, "entry_hash") ; + RsTypeSerializer::serial_process (j,ctx,checksum, "checksum") ; + RsTypeSerializer::serial_process (j,ctx,flags, "flags") ; RsTypeSerializer::serial_process (j,ctx,last_known_recurs_modf_TS,"last_known_recurs_modf_TS") ; - RsTypeSerializer::serial_process (j,ctx,request_id,"request_id") ; - RsTypeSerializer::serial_process(j,ctx,directory_content_data,"directory_content_data") ; + RsTypeSerializer::serial_process (j,ctx,request_id, "request_id") ; + RsTypeSerializer::serial_process(j,ctx,directory_content_data, "directory_content_data") ; +} +void RsFileListsBannedHashesItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) +{ + RsTypeSerializer::serial_process(j,ctx,session_id ,"session_id") ; + RsTypeSerializer::serial_process(j,ctx,encrypted_hashes,"encrypted_hashes") ; +} +void RsFileListsBannedHashesConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) +{ + RsTypeSerializer::serial_process(j,ctx,primary_banned_files_list,"primary_banned_files_list") ; +} +template<> void RsTypeSerializer::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx,BannedFileEntry& entry,const std::string& /*name*/) +{ + RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_NAME,entry.filename ,"entry.file_name") ; + RsTypeSerializer::serial_process(j,ctx, entry.size ,"entry.size") ; + RsTypeSerializer::serial_process (j,ctx, entry.ban_time_stamp,"entry.ban_time_stamp") ; } - RsItem *RsFileListsSerialiser::create_item(uint16_t service,uint8_t type) const { if(service != RS_SERVICE_TYPE_FILE_DATABASE) @@ -49,8 +63,10 @@ RsItem *RsFileListsSerialiser::create_item(uint16_t service,uint8_t type) const switch(type) { - case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: return new RsFileListsSyncRequestItem(); - case RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM: return new RsFileListsSyncResponseItem(); + case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: return new RsFileListsSyncRequestItem(); + case RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM: return new RsFileListsSyncResponseItem(); + case RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_ITEM: return new RsFileListsBannedHashesItem(); + case RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_CONFIG_ITEM: return new RsFileListsBannedHashesConfigItem(); default: return NULL ; } diff --git a/libretroshare/src/file_sharing/rsfilelistitems.h b/libretroshare/src/file_sharing/rsfilelistitems.h index 337bde15f..a8c84e18b 100644 --- a/libretroshare/src/file_sharing/rsfilelistitems.h +++ b/libretroshare/src/file_sharing/rsfilelistitems.h @@ -33,12 +33,13 @@ #include "gxs/rsgxsdata.h" #include "serialiser/rsserializer.h" +#include "retroshare/rsfiles.h" -// These items have "flag type" numbers, but this is not used. - -const uint8_t RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM = 0x01; -const uint8_t RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM = 0x02; -const uint8_t RS_PKT_SUBTYPE_FILELISTS_CONFIG_ITEM = 0x03; +const uint8_t RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM = 0x01; +const uint8_t RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM = 0x02; +const uint8_t RS_PKT_SUBTYPE_FILELISTS_CONFIG_ITEM = 0x03; +const uint8_t RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_ITEM = 0x04; +const uint8_t RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_CONFIG_ITEM = 0x05; /*! * Base class for filelist sync items @@ -103,6 +104,29 @@ public: RsTlvBinaryData directory_content_data ; // encoded binary data. This allows to vary the encoding format, in a way that is transparent to the serialiser. }; +class RsFileListsBannedHashesItem: public RsFileListsItem +{ +public: + RsFileListsBannedHashesItem() : RsFileListsItem(RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_ITEM){} + + virtual void clear() { encrypted_hashes.clear(); } + virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); + + uint32_t session_id ; // used to allow to send in multiple parts. + std::set encrypted_hashes ;// hash of hash for each banned file. +}; + +class RsFileListsBannedHashesConfigItem: public RsFileListsItem +{ +public: + RsFileListsBannedHashesConfigItem() : RsFileListsItem(RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_CONFIG_ITEM){} + + virtual void clear() { primary_banned_files_list.clear(); } + virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); + + std::map primary_banned_files_list ; +}; + class RsFileListsSerialiser : public RsServiceSerializer { public: diff --git a/libretroshare/src/ft/ftserver.cc b/libretroshare/src/ft/ftserver.cc index 49c476607..182964446 100644 --- a/libretroshare/src/ft/ftserver.cc +++ b/libretroshare/src/ft/ftserver.cc @@ -1837,8 +1837,7 @@ void ftServer::receiveSearchResult(RsTurtleFTSearchResultItem *item) } // end RS_STACK_MUTEX(mSearchCallbacksMapMutex); if(!hasCallback) - RsServer::notify()->notifyTurtleSearchResult( - item->request_id, item->result ); + RsServer::notify()->notifyTurtleSearchResult(item->PeerId(),item->request_id, item->result ); } /***************************** CONFIG ****************************/ @@ -1846,8 +1845,8 @@ void ftServer::receiveSearchResult(RsTurtleFTSearchResultItem *item) bool ftServer::addConfiguration(p3ConfigMgr *cfgmgr) { /* add all the subbits to config mgr */ - cfgmgr->addConfiguration("ft_database.cfg", mFileDatabase); - cfgmgr->addConfiguration("ft_extra.cfg", mFtExtra); + cfgmgr->addConfiguration("ft_database.cfg" , mFileDatabase); + cfgmgr->addConfiguration("ft_extra.cfg" , mFtExtra ); cfgmgr->addConfiguration("ft_transfers.cfg", mFtController); return true; @@ -1888,3 +1887,25 @@ void ftServer::cleanTimedOutSearches() cbpt = mSearchCallbacksMap.erase(cbpt); else ++cbpt; } + +// Offensive content file filtering + +int ftServer::banFile(const RsFileHash& real_file_hash, const std::string& filename, uint64_t file_size) +{ + return mFileDatabase->banFile(real_file_hash,filename,file_size) ; +} +int ftServer::unbanFile(const RsFileHash& real_file_hash) +{ + return mFileDatabase->unbanFile(real_file_hash) ; +} +bool ftServer::getPrimaryBannedFilesList(std::map& banned_files) +{ + return mFileDatabase->getPrimaryBannedFilesList(banned_files) ; +} + +bool ftServer::isHashBanned(const RsFileHash& hash) +{ + return mFileDatabase->isFileBanned(hash); +} + + diff --git a/libretroshare/src/ft/ftserver.h b/libretroshare/src/ft/ftserver.h index 5745d3d2b..c15c991fc 100644 --- a/libretroshare/src/ft/ftserver.h +++ b/libretroshare/src/ft/ftserver.h @@ -200,6 +200,11 @@ public: virtual int SearchBoolExp(RsRegularExpression::Expression * exp, std::list &results,FileSearchFlags flags,const RsPeerId& peer_id); virtual int getSharedDirStatistics(const RsPeerId& pid, SharedDirStats& stats) ; + virtual int banFile(const RsFileHash& real_file_hash, const std::string& filename, uint64_t file_size) ; + virtual int unbanFile(const RsFileHash& real_file_hash); + virtual bool getPrimaryBannedFilesList(std::map& banned_files) ; + virtual bool isHashBanned(const RsFileHash& hash); + /*** * Utility Functions ***/ @@ -245,6 +250,8 @@ public: virtual bool ignoreDuplicates() ; virtual void setIgnoreDuplicates(bool ignore) ; + static bool encryptHash(const RsFileHash& hash, RsFileHash& hash_of_hash); + /***************************************************************/ /*************** Data Transfer Interface ***********************/ /***************************************************************/ @@ -290,7 +297,6 @@ protected: // fnds out what is the real hash of encrypted hash hash bool findRealHash(const RsFileHash& hash, RsFileHash& real_hash); bool findEncryptedHash(const RsPeerId& virtual_peer_id, RsFileHash& encrypted_hash); - bool encryptHash(const RsFileHash& hash, RsFileHash& hash_of_hash); bool checkUploadLimit(const RsPeerId& pid,const RsFileHash& hash); private: diff --git a/libretroshare/src/gxs/rsgxsnettunnel.cc b/libretroshare/src/gxs/rsgxsnettunnel.cc index bbe10694b..026ba822b 100644 --- a/libretroshare/src/gxs/rsgxsnettunnel.cc +++ b/libretroshare/src/gxs/rsgxsnettunnel.cc @@ -30,7 +30,7 @@ #include "gxs/rsnxs.h" #include "rsgxsnettunnel.h" -#define DEBUG_RSGXSNETTUNNEL 1 +// #define DEBUG_RSGXSNETTUNNEL 1 #define GXS_NET_TUNNEL_NOT_IMPLEMENTED() { std::cerr << __PRETTY_FUNCTION__ << ": not yet implemented." << std::endl; } #define GXS_NET_TUNNEL_DEBUG() std::cerr << time(NULL) << " : GXS_NET_TUNNEL: " << __FUNCTION__ << " : " diff --git a/libretroshare/src/pqi/p3notify.cc b/libretroshare/src/pqi/p3notify.cc index 8616a0957..2ffd3c5cd 100644 --- a/libretroshare/src/pqi/p3notify.cc +++ b/libretroshare/src/pqi/p3notify.cc @@ -225,7 +225,7 @@ void p3Notify::notifyChatCleared (const ChatId& chat_id) void p3Notify::notifyChatLobbyTimeShift (int time_shift) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatLobbyTimeShift(time_shift) ; } void p3Notify::notifyCustomState (const std::string& peer_id , const std::string& status_string ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyCustomState (peer_id,status_string) ; } void p3Notify::notifyHashingInfo (uint32_t type , const std::string& fileinfo ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyHashingInfo (type,fileinfo) ; } -void p3Notify::notifyTurtleSearchResult (uint32_t search_id , const std::list& files ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyTurtleSearchResult(search_id,files) ; } +void p3Notify::notifyTurtleSearchResult (const RsPeerId& pid , uint32_t search_id , const std::list& files ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyTurtleSearchResult(pid,search_id,files) ; } #warning MISSING CODE HERE //void p3Notify::notifyTurtleSearchResult (uint32_t search_id , const std::list& groups ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyTurtleSearchResult(search_id,groups) ; } void p3Notify::notifyPeerHasNewAvatar (std::string peer_id ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerHasNewAvatar(peer_id) ; } diff --git a/libretroshare/src/pqi/p3notify.h b/libretroshare/src/pqi/p3notify.h index 7cc66d826..d288091c3 100644 --- a/libretroshare/src/pqi/p3notify.h +++ b/libretroshare/src/pqi/p3notify.h @@ -101,7 +101,7 @@ class p3Notify: public RsNotify void notifyChatLobbyTimeShift (int /* time_shift*/) ; void notifyCustomState (const std::string& /* peer_id */, const std::string& /* status_string */) ; void notifyHashingInfo (uint32_t /* type */, const std::string& /* fileinfo */) ; - void notifyTurtleSearchResult (uint32_t /* search_id */, const std::list& /* files */) ; + void notifyTurtleSearchResult (const RsPeerId &pid, uint32_t /* search_id */, const std::list& /* files */) ; #warning MISSING CODE HERE // void notifyTurtleSearchResult (uint32_t /* search_id */, const std::list& /* groups */) ; void notifyPeerHasNewAvatar (std::string /* peer_id */) ; diff --git a/libretroshare/src/retroshare/rsfiles.h b/libretroshare/src/retroshare/rsfiles.h index b7bbe728f..9a312683f 100644 --- a/libretroshare/src/retroshare/rsfiles.h +++ b/libretroshare/src/retroshare/rsfiles.h @@ -181,6 +181,15 @@ public: uint64_t mTotalSize ; }; +struct BannedFileEntry +{ + BannedFileEntry() : size(0),filename(""),ban_time_stamp(0) {} + + uint64_t size ; + std::string filename ; + time_t ban_time_stamp; +}; + class RsFiles { public: @@ -421,6 +430,11 @@ public: virtual int SearchBoolExp(RsRegularExpression::Expression * exp, std::list &results,FileSearchFlags flags,const RsPeerId& peer_id) = 0; virtual int getSharedDirStatistics(const RsPeerId& pid, SharedDirStats& stats) =0; + virtual int banFile(const RsFileHash& real_file_hash, const std::string& filename, uint64_t file_size) =0; + virtual int unbanFile(const RsFileHash& real_file_hash)=0; + virtual bool getPrimaryBannedFilesList(std::map& banned_files) =0; + virtual bool isHashBanned(const RsFileHash& hash) =0; + /*** * Utility Functions. ***/ diff --git a/libretroshare/src/retroshare/rsnotify.h b/libretroshare/src/retroshare/rsnotify.h index a418cb958..cf7777e9e 100644 --- a/libretroshare/src/retroshare/rsnotify.h +++ b/libretroshare/src/retroshare/rsnotify.h @@ -222,7 +222,7 @@ public: virtual void notifyChatLobbyTimeShift (int /* time_shift*/) {} 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 (uint32_t /* search_id */, const std::list& /* files */) {} + virtual void notifyTurtleSearchResult (const RsPeerId& /* pid */, uint32_t /* search_id */, const std::list& /* files */) {} #warning MISSING CODE HERE // virtual void notifyTurtleSearchResult (uint32_t /* search_id */, const std::list& /* groups */) {} virtual void notifyPeerHasNewAvatar (std::string /* peer_id */) {} diff --git a/libretroshare/src/turtle/p3turtle.cc b/libretroshare/src/turtle/p3turtle.cc index e165a6029..90274d02d 100644 --- a/libretroshare/src/turtle/p3turtle.cc +++ b/libretroshare/src/turtle/p3turtle.cc @@ -1108,6 +1108,27 @@ void p3turtle::performLocalSearch_files(RsTurtleFileSearchRequestItem *item,uint void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item) { + // Filter out banned hashes from the result. + + RsTurtleFTSearchResultItem *ftsr_tmp = dynamic_cast(item) ; + + if(ftsr_tmp != NULL) + { + for(auto it(ftsr_tmp->result.begin());it!=ftsr_tmp->result.end();) + if( rsFiles->isHashBanned((*it).hash) ) + { + std::cerr << "(II) filtering out banned hash " << (*it).hash << " from turtle result " << std::hex << item->request_id << std::dec << std::endl; + it = ftsr_tmp->result.erase(it); + } + else + ++it; + + if(ftsr_tmp->result.empty()) + return ; + } + + // Then handle the result + std::list > results_to_notify_off_mutex ; { @@ -1532,6 +1553,14 @@ void p3turtle::handleTunnelRequest(RsTurtleOpenTunnelItem *item) item->print(std::cerr,0) ; #endif + // check first if the hash is in the ban list. If so, drop the request. + + if(rsFiles->isHashBanned(item->file_hash)) + { + std::cerr << "(II) Rejecting tunnel request to ban hash " << item->file_hash << std::endl; + return ; + } + #ifdef TUNNEL_STATISTICS if(TS_request_bounces.find(item->request_id) != TS_request_bounces.end()) TS_request_bounces[item->request_id].push_back(time(NULL)) ; diff --git a/retroshare-gui/src/gui/FileTransfer/BannedFilesDialog.cpp b/retroshare-gui/src/gui/FileTransfer/BannedFilesDialog.cpp new file mode 100644 index 000000000..5be060b09 --- /dev/null +++ b/retroshare-gui/src/gui/FileTransfer/BannedFilesDialog.cpp @@ -0,0 +1,86 @@ +/******************************************************************************* + * retroshare-gui/src/gui/FileTransfer/BannedFilesDialog.cpp * + * * + * Copyright 2018 by Retroshare Team * + * * + * 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 . * + * * + *******************************************************************************/ + +#include +#include + +#include "retroshare/rsfiles.h" + +#include "BannedFilesDialog.h" + +#define COLUMN_FILE_NAME 0 +#define COLUMN_FILE_HASH 1 +#define COLUMN_FILE_SIZE 2 +#define COLUMN_FILE_TIME 3 + +BannedFilesDialog::BannedFilesDialog(QWidget *parent) + : QDialog(parent) +{ + ui.setupUi(this); + + fillFilesList() ; + + connect(ui.bannedFiles_TW, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(bannedFilesContextMenu(QPoint))); +} + +BannedFilesDialog::~BannedFilesDialog() {} + +void BannedFilesDialog::unbanFile() +{ + int row = ui.bannedFiles_TW->currentRow(); + + QTableWidgetItem *item = ui.bannedFiles_TW->item(row, COLUMN_FILE_HASH); + + RsFileHash hash(item->data(Qt::UserRole).toString().toStdString()) ; + rsFiles->unbanFile(hash) ; + + fillFilesList(); +} + +void BannedFilesDialog::bannedFilesContextMenu(QPoint) +{ + QMenu menu(this); + + menu.addAction(QIcon(":/images/FeedAdd.png"), tr("Remove"), this, SLOT(unbanFile())); + + menu.exec(QCursor::pos()); +} + +void BannedFilesDialog::fillFilesList() +{ + std::map banned_files ; + + rsFiles->getPrimaryBannedFilesList(banned_files); + int row=0; + + ui.bannedFiles_TW->setRowCount(banned_files.size()) ; + + for(auto it(banned_files.begin());it!=banned_files.end();++it) + { + ui.bannedFiles_TW->setItem(row, COLUMN_FILE_NAME, new QTableWidgetItem(QIcon(),QString::fromUtf8(it->second.filename.c_str()),0)); + ui.bannedFiles_TW->setItem(row, COLUMN_FILE_HASH, new QTableWidgetItem(QIcon(),QString::fromStdString(it->first.toStdString()),0)); + ui.bannedFiles_TW->setItem(row, COLUMN_FILE_SIZE, new QTableWidgetItem(QIcon(),QString::number(it->second.size),0)); + ui.bannedFiles_TW->setItem(row, COLUMN_FILE_TIME, new QTableWidgetItem(QIcon(),QDateTime::fromTime_t(it->second.ban_time_stamp).toString(),0)); + + ui.bannedFiles_TW->item(row, COLUMN_FILE_HASH)->setData(Qt::UserRole, QString::fromStdString(it->first.toStdString())); + + row++; + } +} diff --git a/retroshare-gui/src/gui/FileTransfer/BannedFilesDialog.h b/retroshare-gui/src/gui/FileTransfer/BannedFilesDialog.h new file mode 100644 index 000000000..cdcb4f6ee --- /dev/null +++ b/retroshare-gui/src/gui/FileTransfer/BannedFilesDialog.h @@ -0,0 +1,49 @@ +/******************************************************************************* + * retroshare-gui/src/gui/FileTransfer/BannedFilesDialog.h * + * * + * Copyright 2018 by Retroshare Team * + * * + * 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 . * + * * + *******************************************************************************/ + +#pragma once + +#include "RsAutoUpdatePage.h" +#include "ui_BannedFilesDialog.h" + +class BannedFilesDialog: public QDialog +{ + Q_OBJECT + +public: + /** Default Constructor */ + BannedFilesDialog(QWidget *parent = 0); + /** Default Destructor */ + ~BannedFilesDialog(); + +private slots: + void unbanFile(); + + /** management of the adv search dialog object when switching search modes */ + //void hideEvent(QHideEvent * event); + void bannedFilesContextMenu(QPoint); + +private: + void fillFilesList(); + + /** Qt Designer generated object */ + Ui::BannedFilesDialog ui; +}; + diff --git a/retroshare-gui/src/gui/FileTransfer/BannedFilesDialog.ui b/retroshare-gui/src/gui/FileTransfer/BannedFilesDialog.ui new file mode 100644 index 000000000..78d81df79 --- /dev/null +++ b/retroshare-gui/src/gui/FileTransfer/BannedFilesDialog.ui @@ -0,0 +1,67 @@ + + + BannedFilesDialog + + + + 0 + 0 + 923 + 810 + + + + + + + <html><head/><body><p><span style=" font-weight:600;">Collaborative file control</span>: the list below contains files you choose to ban from your <span style=" font-weight:600;">local</span> network: you will not forward search results nor data from these files to your friends. This list is securely shared with your friends, unless they uncheck option &quot;Trust my friends for banning unwanted content&quot;. This feature cannot globally hide a file unless a signficant proportion of users in the same network decide to ban it.</p></body></html> + + + Qt::AlignJustify|Qt::AlignVCenter + + + true + + + + + + + Qt::CustomContextMenu + + + true + + + true + + + false + + + + Filename + + + + + Hash + + + + + Size + + + + + Banned since... + + + + + + + + + diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp index be61a1dcc..20e5157da 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp @@ -26,6 +26,7 @@ #include "rshare.h" #include "SearchDialog.h" +#include "gui/FileTransfer/BannedFilesDialog.h" #include "gui/RSHumanReadableDelegate.h" #include "gui/RetroShareLink.h" #include "retroshare-gui/RsAutoUpdatePage.h" @@ -54,6 +55,7 @@ #define IMAGE_COLLVIEW ":/images/library_view.png" #define IMAGE_COLLOPEN ":/images/library.png" #define IMAGE_COPYLINK ":/images/copyrslink.png" +#define IMAGE_BANFILE ":/icons/biohazard_red.png" /* Key for UI Preferences */ #define UI_PREF_ADVANCED_SEARCH "UIOptions/AdvancedSearch" @@ -117,6 +119,7 @@ SearchDialog::SearchDialog(QWidget *parent) connect( ui.searchResultWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( searchResultWidgetCustomPopupMenu( QPoint ) ) ); connect( ui.searchSummaryWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( searchSummaryWidgetCustomPopupMenu( QPoint ) ) ); + connect( ui.showBannedFiles_TB, SIGNAL( clicked() ), this, SLOT( openBannedFiles() ) ); connect( ui.lineEdit, SIGNAL( returnPressed ( void ) ), this, SLOT( searchKeywords( void ) ) ); connect( ui.lineEdit, SIGNAL( textChanged ( const QString& ) ), this, SLOT( checkText( const QString& ) ) ); @@ -327,6 +330,7 @@ void SearchDialog::searchResultWidgetCustomPopupMenu( QPoint /*point*/ ) QMenu contextMnu(this) ; contextMnu.addAction(QIcon(IMAGE_START), tr("Download"), this, SLOT(download())) ; + contextMnu.addAction(QIcon(IMAGE_BANFILE), tr("Mark as bad"), this, SLOT(ban())) ; contextMnu.addSeparator();//-------------------------------------- contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyResultLink())) ; @@ -406,22 +410,53 @@ void SearchDialog::download() std::cout << "isuing file request from search dialog: -" << (item->text(SR_NAME_COL)).toStdString() << "-" << hash << "-" << (item->text(SR_SIZE_COL)).toULongLong() << "-ids=" ; - for(std::list::const_iterator it(srcIds.begin()); it!=srcIds.end(); ++it) { + for(std::list::const_iterator it(srcIds.begin()); it!=srcIds.end(); ++it) std::cout << *it << "-" << std::endl; - }//for(std::list::const_iterator - //QColor foreground = QColor(0, 128, 0); // green + QColor foreground = textColorDownloading(); QBrush brush(foreground); for (int i = 0; i < item->columnCount(); ++i) - { item->setForeground(i, brush); - } - }//if(!rsFiles -> FileRequest( - }//if (item->text(SR_HASH_COL).isEmpty()) - }//for (int i = 0 - if (attemptDownloadLocal) { + } + } + } + if (attemptDownloadLocal) QMessageBox::information(this, tr("Download Notice"), tr("Skipping Local Files")) ; - }//if (attemptDownloadLocal) +} + +void SearchDialog::ban() +{ + /* should also be able to handle multi-selection */ + + QList itemsForDownload = ui.searchResultWidget->selectedItems() ; + int numdls = itemsForDownload.size() ; + QTreeWidgetItem * item ; + + for (int i = 0; i < numdls; ++i) + { + item = itemsForDownload.at(i) ; + // call the download + // * + if(!item->text(SR_HASH_COL).isEmpty()) + { + std::cerr << "SearchDialog::download() Calling File Ban" << std::endl ; + + RsFileHash hash( item->text(SR_HASH_COL).toStdString()) ; + + rsFiles -> banFile( hash, (item->text(SR_NAME_COL)).toUtf8().constData() , (item->text(SR_SIZE_COL)).toULongLong()); + + while(item->parent() != NULL) + item = item->parent(); + + ui.searchResultWidget->takeTopLevelItem(ui.searchResultWidget->indexOfTopLevelItem(item)) ; + } + } +} + +void SearchDialog::openBannedFiles() +{ + BannedFilesDialog d ; + d.exec(); } void SearchDialog::collCreate() @@ -942,9 +977,7 @@ void SearchDialog::processResultQueue() while(!searchResultsQueue.empty() && nb_treated_elements++ < 250) { qulonglong search_id = searchResultsQueue.back().first ; - FileDetail file = searchResultsQueue.back().second ; - - searchResultsQueue.pop_back() ; + FileDetail& file = searchResultsQueue.back().second ; #ifdef DEBUG std::cout << "Updating file detail:" << std::endl ; @@ -954,6 +987,8 @@ void SearchDialog::processResultQueue() #endif insertFile(search_id,file); + + searchResultsQueue.pop_back() ; } ui.searchResultWidget->setSortingEnabled(true); if(!searchResultsQueue.empty()) @@ -1288,6 +1323,7 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s modifiedResult =QString::number(friendSource) + "/" + QString::number(anonymousSource); float fltRes = friendSource + (float)anonymousSource/1000; item->setText(SR_SOURCES_COL,modifiedResult); + item->setToolTip(SR_SOURCES_COL, tr("Obtained via ")+QString::fromStdString(rsPeers->getPeerName(file.id)) ); item->setData(SR_SOURCES_COL, ROLE_SORT, fltRes); item->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight ); item->setText(SR_SEARCH_ID_COL, sid_hexa); diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h index 57846692c..001ae3903 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h @@ -75,6 +75,7 @@ private slots: void searchSummaryWidgetCustomPopupMenu( QPoint point ); void download(); + void ban(); void collCreate(); void collModif(); @@ -86,6 +87,7 @@ private slots: void recommendtofriends(); void checkText(const QString&); + void openBannedFiles(); void copyResultLink(); void copySearchLink(); void openFolderSearch(); diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui b/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui index b3df60f05..47e221bf5 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui @@ -170,6 +170,23 @@ + + + + + 0 + 0 + + + + + + + + :/icons/biohazard_red.png:/icons/biohazard_red.png + + + @@ -450,6 +467,7 @@ + diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h index 51bc205d3..f98a96daa 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h @@ -55,7 +55,8 @@ public: /* Fixed numbers for load and save the last page */ SearchTab = 0, /** Network page. */ LocalSharedFilesTab = 1, /** Network new graph. */ - RemoteSharedFilesTab = 2 /** Old group chat page. */ + RemoteSharedFilesTab = 2, /** Old group chat page. */ + DownloadTab = 3 }; @@ -108,9 +109,6 @@ private slots: void expandAllUL(); void collapseAllUL(); -// void rootdecorated(); -// void rootisnotdecorated(); - void pauseFileTransfer(); void resumeFileTransfer(); void dlOpenFolder(); diff --git a/retroshare-gui/src/gui/notifyqt.cpp b/retroshare-gui/src/gui/notifyqt.cpp index da8dac48d..fa7bb4c82 100644 --- a/retroshare-gui/src/gui/notifyqt.cpp +++ b/retroshare-gui/src/gui/notifyqt.cpp @@ -568,7 +568,7 @@ void NotifyQt::notifyTurtleSearchResult(uint32_t search_id,const std::list& files) +void NotifyQt::notifyTurtleSearchResult(const RsPeerId& pid,uint32_t search_id,const std::list& files) { { QMutexLocker m(&_mutex) ; @@ -588,7 +588,7 @@ void NotifyQt::notifyTurtleSearchResult(uint32_t search_id,const std::list& found_files); + virtual void notifyTurtleSearchResult(const RsPeerId &pid, uint32_t search_id, const std::list& found_files); virtual void notifyTurtleSearchResult(uint32_t search_id,const std::list& found_groups); virtual void notifyPeerHasNewAvatar(std::string peer_id) ; virtual void notifyOwnAvatarChanged() ; diff --git a/retroshare-gui/src/gui/settings/TransferPage.ui b/retroshare-gui/src/gui/settings/TransferPage.ui index 529a6e260..2f6dd0dae 100644 --- a/retroshare-gui/src/gui/settings/TransferPage.ui +++ b/retroshare-gui/src/gui/settings/TransferPage.ui @@ -447,6 +447,13 @@ + + + + Trust friend nodes with banned files + + + diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index d973e5de8..b5b17d159 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -365,6 +365,7 @@ HEADERS += rshare.h \ gui/FileTransfer/DLListDelegate.h \ gui/FileTransfer/ULListDelegate.h \ gui/FileTransfer/TransfersDialog.h \ + gui/FileTransfer/BannedFilesDialog.h \ gui/statistics/TurtleRouterDialog.h \ gui/statistics/TurtleRouterStatistics.h \ gui/statistics/dhtgraph.h \ @@ -597,6 +598,7 @@ FORMS += gui/StartDialog.ui \ gui/FileTransfer/DetailsDialog.ui \ gui/FileTransfer/SearchDialog.ui \ gui/FileTransfer/SharedFilesDialog.ui \ + gui/FileTransfer/BannedFilesDialog.ui \ gui/MainWindow.ui \ gui/NetworkView.ui \ gui/MessengerWindow.ui \ @@ -743,6 +745,7 @@ SOURCES += main.cpp \ gui/FileTransfer/xprogressbar.cpp \ gui/FileTransfer/DetailsDialog.cpp \ gui/FileTransfer/TransferUserNotify.cpp \ + gui/FileTransfer/BannedFilesDialog.cpp \ gui/MainPage.cpp \ gui/HelpDialog.cpp \ gui/LogoBar.cpp \ diff --git a/retroshare-nogui/src/notifytxt.cc b/retroshare-nogui/src/notifytxt.cc index 18212b17e..d6d4741c4 100644 --- a/retroshare-nogui/src/notifytxt.cc +++ b/retroshare-nogui/src/notifytxt.cc @@ -219,7 +219,7 @@ void NotifyTxt::displayTransfers() /******************* Turtle Search Interface **********/ -void NotifyTxt::notifyTurtleSearchResult(uint32_t search_id,const std::list& found_files) +void NotifyTxt::notifyTurtleSearchResult(const RsPeerId &pid, uint32_t search_id, const std::list& found_files) { // std::cerr << "NotifyTxt::notifyTurtleSearchResult() " << found_files.size(); // std::cerr << " new results for Id: " << search_id; diff --git a/retroshare-nogui/src/notifytxt.h b/retroshare-nogui/src/notifytxt.h index 508bfd7fd..17dcbc409 100644 --- a/retroshare-nogui/src/notifytxt.h +++ b/retroshare-nogui/src/notifytxt.h @@ -44,7 +44,7 @@ class NotifyTxt: public NotifyClient virtual bool askForPassword(const std::string& title, const std::string& question, bool prev_is_bad, std::string& password,bool& cancel); virtual bool askForPluginConfirmation(const std::string& plugin_file, const std::string& plugin_hash,bool first_time); - virtual void notifyTurtleSearchResult(uint32_t search_id,const std::list& found_files); + virtual void notifyTurtleSearchResult(const RsPeerId& pid,uint32_t search_id,const std::list& found_files); /* interface for handling SearchResults */ void getSearchIds(std::list &searchIds);