From b18a186c5fd7bdfd5d5b98ba07fb3514f25ac346 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 6 May 2017 18:20:48 +0200 Subject: [PATCH] fixed ftExtraList to accept e2e encrypted transfers in addition to direct transfers. This fixed the drag+drop of shared files in a distant chat --- libretroshare/src/ft/ftextralist.cc | 90 ++++++++++++++++++++--------- libretroshare/src/ft/ftextralist.h | 69 +++++++++++----------- 2 files changed, 100 insertions(+), 59 deletions(-) diff --git a/libretroshare/src/ft/ftextralist.cc b/libretroshare/src/ft/ftextralist.cc index 7548d421c..cd52f5ce5 100644 --- a/libretroshare/src/ft/ftextralist.cc +++ b/libretroshare/src/ft/ftextralist.cc @@ -53,11 +53,6 @@ void ftExtraList::data_tick() bool todo = false; time_t now = time(NULL); -#ifdef DEBUG_ELIST - //std::cerr << "ftExtraList::run() Iteration"; - //std::cerr << std::endl; -#endif - { RsStackMutex stack(extMutex); @@ -131,6 +126,7 @@ void ftExtraList::hashAFile() /* stick it in the available queue */ mFiles[details.info.hash] = details; + mHashOfHash[makeEncryptedHash(details.info.hash)] = details.info.hash ; /* add to the path->hash map */ mHashedList[details.info.path] = details.info.hash; @@ -169,6 +165,7 @@ bool ftExtraList::addExtraFile(std::string path, const RsFileHash& hash, /* stick it in the available queue */ mFiles[details.info.hash] = details; + mHashOfHash[makeEncryptedHash(details.info.hash)] = details.info.hash ; IndicateConfigChanged(); @@ -190,6 +187,8 @@ bool ftExtraList::removeExtraFile(const RsFileHash& hash, TransferRequestFlags f RsStackMutex stack(extMutex); + mHashOfHash.erase(makeEncryptedHash(hash)) ; + std::map::iterator it; it = mFiles.find(hash); if (it == mFiles.end()) @@ -242,29 +241,26 @@ bool ftExtraList::cleanupOldFiles() time_t now = time(NULL); std::list toRemove; - std::list::iterator rit; - std::map::iterator it; - for(it = mFiles.begin(); it != mFiles.end(); ++it) - { - /* check timestamps */ + for( std::map::iterator it = mFiles.begin(); it != mFiles.end(); ++it) /* check timestamps */ if ((time_t)it->second.info.age < now) - { toRemove.push_back(it->first); - } - } if (toRemove.size() > 0) { + std::map::iterator it; + /* remove items */ - for(rit = toRemove.begin(); rit != toRemove.end(); ++rit) - { + for(std::list::iterator rit = toRemove.begin(); rit != toRemove.end(); ++rit) + { if (mFiles.end() != (it = mFiles.find(*rit))) { cleanupEntry(it->second.info.path, it->second.info.transfer_info_flags); mFiles.erase(it); } - } + mHashOfHash.erase(makeEncryptedHash(*rit)) ; + } + IndicateConfigChanged(); } return true; @@ -333,31 +329,71 @@ bool ftExtraList::hashExtraFileDone(std::string path, FileInfo &info) **/ bool ftExtraList::search(const RsFileHash &hash, FileSearchFlags /*hintflags*/, FileInfo &info) const { - #ifdef DEBUG_ELIST - std::cerr << "ftExtraList::search()"; - std::cerr << std::endl; + std::cerr << "ftExtraList::search() hash=" << hash ; #endif /* find hash */ std::map::const_iterator fit; if (mFiles.end() == (fit = mFiles.find(hash))) { - return false; +#ifdef DEBUG_ELIST + std::cerr << " not found in mFiles. Trying encrypted... " ; +#endif + // File not found. We try to look for encrypted hash. + + std::map::const_iterator hit = mHashOfHash.find(hash) ; + + if(hit == mHashOfHash.end()) + { +#ifdef DEBUG_ELIST + std::cerr << " not found." << std::endl; +#endif + return false; + } +#ifdef DEBUG_ELIST + std::cerr << " found! Reaching data..." ; +#endif + + fit = mFiles.find(hit->second) ; + + if(fit == mFiles.end()) // not found. This is an error. + { +#ifdef DEBUG_ELIST + std::cerr << " no data. Returning false." << std::endl; +#endif + return false ; + } + +#ifdef DEBUG_ELIST + std::cerr << " ok! Accepting encrypted transfer." << std::endl; +#endif + info = fit->second.info; + info.storage_permission_flags = FileStorageFlags(DIR_FLAGS_ANONYMOUS_DOWNLOAD) ; + info.transfer_info_flags |= RS_FILE_REQ_ENCRYPTED ; } + else + { +#ifdef DEBUG_ELIST + std::cerr << " found! Accepting direct transfer" << std::endl; +#endif + info = fit->second.info; - info = fit->second.info; - - // Now setup the file storage flags so that the client can know how to handle permissions - // -#warning mr-alice: make sure this is right - info.storage_permission_flags = FileStorageFlags(0) ;//DIR_FLAGS_BROWSABLE_OTHERS ; + // Unencrypted file transfer: We only allow direct transfers. This is not exactly secure since another friend can + // swarm the file. But the hash being kept secret, there's no risk here. + // + info.storage_permission_flags = FileStorageFlags(DIR_FLAGS_BROWSABLE) ; + } if(info.transfer_info_flags & RS_FILE_REQ_ANONYMOUS_ROUTING) info.storage_permission_flags |= DIR_FLAGS_ANONYMOUS_DOWNLOAD ; return true; } +RsFileHash ftExtraList::makeEncryptedHash(const RsFileHash& hash) +{ + return RsDirUtil::sha1sum(hash.toByteArray(),hash.SIZE_IN_BYTES); +} /*** * Configuration - store extra files. @@ -472,6 +508,8 @@ bool ftExtraList::loadList(std::list& load) /* stick it in the available queue */ mFiles[details.info.hash] = details; + mHashOfHash[makeEncryptedHash(details.info.hash)] = details.info.hash ; + delete (*it); /* short sleep */ diff --git a/libretroshare/src/ft/ftextralist.h b/libretroshare/src/ft/ftextralist.h index 19f1be302..211e66dc6 100644 --- a/libretroshare/src/ft/ftextralist.h +++ b/libretroshare/src/ft/ftextralist.h @@ -109,66 +109,69 @@ const uint32_t CLEANUP_PERIOD = 600; /* 10 minutes */ class ftExtraList: public RsTickingThread, public p3Config, public ftSearch { - public: +public: - ftExtraList(); + ftExtraList(); - /*** + /*** * If the File is alreay Hashed, then just add it in. **/ -bool addExtraFile(std::string path, const RsFileHash &hash, - uint64_t size, uint32_t period, TransferRequestFlags flags); + bool addExtraFile(std::string path, const RsFileHash &hash, + uint64_t size, uint32_t period, TransferRequestFlags flags); -bool removeExtraFile(const RsFileHash& hash, TransferRequestFlags flags); -bool moveExtraFile(std::string fname, const RsFileHash& hash, uint64_t size, - std::string destpath); + bool removeExtraFile(const RsFileHash& hash, TransferRequestFlags flags); + bool moveExtraFile(std::string fname, const RsFileHash& hash, uint64_t size, + std::string destpath); - /*** - * Hash file, and add to the files, + /*** + * Hash file, and add to the files, * file is removed after period. **/ -bool hashExtraFile(std::string path, uint32_t period, TransferRequestFlags flags); -bool hashExtraFileDone(std::string path, FileInfo &info); + bool hashExtraFile(std::string path, uint32_t period, TransferRequestFlags flags); + bool hashExtraFileDone(std::string path, FileInfo &info); - /*** - * Search Function - used by File Transfer + /*** + * Search Function - used by File Transfer * implementation of ftSearch. * **/ -virtual bool search(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) const; + virtual bool search(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) const; - /*** - * Thread Main Loop + /*** + * Thread Main Loop **/ -virtual void data_tick(); + virtual void data_tick(); - /*** + /*** * Configuration - store extra files. * **/ - protected: -virtual RsSerialiser *setupSerialiser(); -virtual bool saveList(bool &cleanup, std::list&); -virtual bool loadList(std::list& load); +protected: + virtual RsSerialiser *setupSerialiser(); + virtual bool saveList(bool &cleanup, std::list&); + virtual bool loadList(std::list& load); - private: + static RsFileHash makeEncryptedHash(const RsFileHash& hash); - /* Worker Functions */ -void hashAFile(); -bool cleanupOldFiles(); -bool cleanupEntry(std::string path, TransferRequestFlags flags); +private: - mutable RsMutex extMutex; + /* Worker Functions */ + void hashAFile(); + bool cleanupOldFiles(); + bool cleanupEntry(std::string path, TransferRequestFlags flags); - std::list mToHash; + mutable RsMutex extMutex; - std::map mHashedList; /* path -> hash ( not saved ) */ - std::map mFiles; + std::list mToHash; - time_t cleanup ; + std::map mHashedList; /* path -> hash ( not saved ) */ + std::map mFiles; + std::map mHashOfHash; /* sha1(hash) map so as to answer requests to encrypted transfers */ + + time_t cleanup ; };