diff --git a/libretroshare/src/crypto/chacha20.cpp b/libretroshare/src/crypto/chacha20.cpp index 26ee4a924..24e810283 100644 --- a/libretroshare/src/crypto/chacha20.cpp +++ b/libretroshare/src/crypto/chacha20.cpp @@ -33,6 +33,8 @@ #include #include +#include "crypto/chacha20.h" + #pragma once #define rotl(x,n) { x = (x << n) | (x >> (-n & 31)) ;} diff --git a/libretroshare/src/file_sharing/dir_hierarchy.cc b/libretroshare/src/file_sharing/dir_hierarchy.cc index a697fa120..f5c0dbeb4 100644 --- a/libretroshare/src/file_sharing/dir_hierarchy.cc +++ b/libretroshare/src/file_sharing/dir_hierarchy.cc @@ -661,18 +661,9 @@ DirectoryStorage::EntryIndex InternalFileHierarchyStorage::getSubDirIndex(Direct return static_cast(mNodes[parent_index])->subdirs[dir_tab_index]; } -bool InternalFileHierarchyStorage::searchHash(const RsFileHash& hash,std::list& results) +bool InternalFileHierarchyStorage::searchHash(const RsFileHash& hash,DirectoryStorage::EntryIndex& result) { - DirectoryStorage::EntryIndex indx ; - - if(getIndexFromFileHash(hash,indx)) - { - results.clear(); - results.push_back(indx) ; - return true ; - } - else - return false; + return getIndexFromFileHash(hash,result); } class DirectoryStorageExprFileEntry: public RsRegularExpression::ExpFileEntry diff --git a/libretroshare/src/file_sharing/dir_hierarchy.h b/libretroshare/src/file_sharing/dir_hierarchy.h index fe937fac9..dd1454b91 100644 --- a/libretroshare/src/file_sharing/dir_hierarchy.h +++ b/libretroshare/src/file_sharing/dir_hierarchy.h @@ -142,7 +142,7 @@ public: // search. SearchHash is logarithmic. The other two are linear. - bool searchHash(const RsFileHash& hash,std::list& results); + bool searchHash(const RsFileHash& hash, DirectoryStorage::EntryIndex &result); int searchBoolExp(RsRegularExpression::Expression * exp, std::list &results) const ; int searchTerms(const std::list& terms, std::list &results) const ; // does a logical OR between items of the list of terms diff --git a/libretroshare/src/file_sharing/directory_storage.cc b/libretroshare/src/file_sharing/directory_storage.cc index 02c406c5d..9ec32487f 100644 --- a/libretroshare/src/file_sharing/directory_storage.cc +++ b/libretroshare/src/file_sharing/directory_storage.cc @@ -168,10 +168,11 @@ bool DirectoryStorage::updateHash(const EntryIndex& index,const RsFileHash& hash return mFileHierarchy->updateHash(index,hash); } -int DirectoryStorage::searchHash(const RsFileHash& hash, std::list &results) const +int DirectoryStorage::searchHash(const RsFileHash& hash, const RsFileHash& real_hash, EntryIndex& result) const { RS_STACK_MUTEX(mDirStorageMtx) ; - return mFileHierarchy->searchHash(hash,results); +#warning code needed here + return mFileHierarchy->searchHash(hash,result); } void DirectoryStorage::load(const std::string& local_file_name) diff --git a/libretroshare/src/file_sharing/directory_storage.h b/libretroshare/src/file_sharing/directory_storage.h index 2d8119445..653b1286d 100644 --- a/libretroshare/src/file_sharing/directory_storage.h +++ b/libretroshare/src/file_sharing/directory_storage.h @@ -53,7 +53,7 @@ class DirectoryStorage virtual int searchTerms(const std::list& terms, std::list &results) const ; virtual int searchBoolExp(RsRegularExpression::Expression * exp, std::list &results) const ; - virtual int searchHash(const RsFileHash& hash, std::list &results) const ; + virtual int searchHash(const RsFileHash& hash, const RsFileHash &real_hash, EntryIndex &results) const ; // gets/sets the various time stamps: // diff --git a/libretroshare/src/file_sharing/p3filelists.cc b/libretroshare/src/file_sharing/p3filelists.cc index e53bc8e9a..199641298 100644 --- a/libretroshare/src/file_sharing/p3filelists.cc +++ b/libretroshare/src/file_sharing/p3filelists.cc @@ -979,16 +979,20 @@ bool p3FileDatabase::search(const RsFileHash &hash, FileSearchFlags hintflags, F if(hintflags & RS_FILE_HINTS_LOCAL) { - std::list res; - mLocalSharedDirs->searchHash(hash,res) ; + RsFileHash real_hash ; + EntryIndex indx; - if(res.empty()) + if(!mLocalSharedDirs->searchHash(hash,real_hash,indx)) return false; - EntryIndex indx = *res.begin() ; // no need to report duplicates - mLocalSharedDirs->getFileInfo(indx,info) ; + if(!real_hash.isNull()) + { + info.hash = real_hash ; + info.transfer_info_flags |= RS_FILE_REQ_ENCRYPTED ; + } + return true; } diff --git a/libretroshare/src/ft/ftserver.cc b/libretroshare/src/ft/ftserver.cc index b80aa51a2..e5476f725 100644 --- a/libretroshare/src/ft/ftserver.cc +++ b/libretroshare/src/ft/ftserver.cc @@ -730,6 +730,31 @@ bool ftServer::shareDownloadDirectory(bool share) /********************** Data Flow **********************/ /***************************************************************/ +bool ftServer::sendTurtleItem(const RsPeerId& peerId,const RsFileHash& hash,RsTurtleGenericTunnelItem *item) +{ + // first, we look for the encrypted hash map +#warning code needed here + if(true) + { + // we don't encrypt + mTurtleRouter->sendTurtleData(peerId,item) ; + } + else + { + // we encrypt the item + + RsTurtleGenericDataItem *encrypted_item ; + + if(!encryptItem(item, hash, encrypted_item)) + return false ; + + delete item ; + + mTurtleRouter->sendTurtleData(peerId,encrypted_item) ; + } + return true ; +} + /* Client Send */ bool ftServer::sendDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize) { @@ -743,7 +768,7 @@ bool ftServer::sendDataRequest(const RsPeerId& peerId, const RsFileHash& hash, u item->chunk_offset = offset ; item->chunk_size = chunksize ; - mTurtleRouter->sendTurtleData(peerId,item) ; + sendTurtleItem(peerId,hash,item) ; } else { @@ -776,8 +801,8 @@ bool ftServer::sendChunkMapRequest(const RsPeerId& peerId,const RsFileHash& hash if(mTurtleRouter->isTurtlePeer(peerId)) { RsTurtleFileMapRequestItem *item = new RsTurtleFileMapRequestItem ; - mTurtleRouter->sendTurtleData(peerId,item) ; - } + sendTurtleItem(peerId,hash,item) ; + } else { /* create a packet */ @@ -806,8 +831,8 @@ bool ftServer::sendChunkMap(const RsPeerId& peerId,const RsFileHash& hash,const { RsTurtleFileMapItem *item = new RsTurtleFileMapItem ; item->compressed_map = map ; - mTurtleRouter->sendTurtleData(peerId,item) ; - } + sendTurtleItem(peerId,hash,item) ; + } else { /* create a packet */ @@ -838,8 +863,8 @@ bool ftServer::sendSingleChunkCRCRequest(const RsPeerId& peerId,const RsFileHash RsTurtleChunkCrcRequestItem *item = new RsTurtleChunkCrcRequestItem; item->chunk_number = chunk_number ; - mTurtleRouter->sendTurtleData(peerId,item) ; - } + sendTurtleItem(peerId,hash,item) ; + } else { /* create a packet */ @@ -870,8 +895,8 @@ bool ftServer::sendSingleChunkCRC(const RsPeerId& peerId,const RsFileHash& hash, item->chunk_number = chunk_number ; item->check_sum = crc ; - mTurtleRouter->sendTurtleData(peerId,item) ; - } + sendTurtleItem(peerId,hash,item) ; + } else { /* create a packet */ @@ -941,8 +966,8 @@ bool ftServer::sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t } memcpy(item->chunk_data,&(((uint8_t *) data)[offset]),chunk) ; - mTurtleRouter->sendTurtleData(peerId,item) ; - } + sendTurtleItem(peerId,hash,item) ; + } else { RsFileTransferDataItem *rfd = new RsFileTransferDataItem(); @@ -1143,6 +1168,19 @@ bool ftServer::decryptItem(RsTurtleGenericDataItem *encrypted_item,const RsFileH return true ; } +bool ftServer::findRealHash(const RsFileHash& hash, RsFileHash& real_hash) +{ + std::map::const_iterator it = mEncryptedHashes.find(hash) ; + + if(it != mEncryptedHashes.end()) + { + real_hash = it->second ; + return true ; + } + else + return false ; +} + // Dont delete the item. The client (p3turtle) is doing it after calling this. // void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i, @@ -1150,6 +1188,31 @@ void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i, const RsPeerId& virtual_peer_id, RsTurtleGenericTunnelItem::Direction direction) { + if(i->PacketSubType() == RS_TURTLE_SUBTYPE_GENERIC_DATA) + { + std::cerr << "Received encrypted data item. Trying to decrypt" << std::endl; + + RsFileHash real_hash ; + + if(!findRealHash(hash,real_hash)) + { + std::cerr << "(EE) Cannot find real hash for encrypted data item with H(H(F))=" << hash << ". This is unexpected." << std::endl; + return ; + } + + RsTurtleGenericTunnelItem *decrypted_item ; + if(!decryptItem(dynamic_cast(i),real_hash,decrypted_item)) + { + std::cerr << "(EE) decryption error." << std::endl; + return ; + } + + receiveTurtleData(decrypted_item, real_hash, virtual_peer_id,direction) ; + + delete decrypted_item ; + return ; + } + switch(i->PacketSubType()) { case RS_TURTLE_SUBTYPE_FILE_REQUEST: diff --git a/libretroshare/src/ft/ftserver.h b/libretroshare/src/ft/ftserver.h index 4579c21ec..4f36aad91 100644 --- a/libretroshare/src/ft/ftserver.h +++ b/libretroshare/src/ft/ftserver.h @@ -242,6 +242,20 @@ protected: int handleIncoming() ; bool handleCacheData() ; + /*! + * \brief sendTurtleItem + * Sends the given item into a turtle tunnel, possibly encrypting it if the type of tunnel requires it, which is known from the hash itself. + * \param peerId Peer id to send to (this is a virtual peer id from turtle service) + * \param hash hash of the file. If the item needs to be encrypted + * \param item item to send. + * \return + * true if everything goes right + */ + bool sendTurtleItem(const RsPeerId& peerId,const RsFileHash& hash,RsTurtleGenericTunnelItem *item); + + // fnds out what is the real hash of encrypted hash hash + bool findRealHash(const RsFileHash& hash, RsFileHash& real_hash); + private: /**** INTERNAL FUNCTIONS ***/ @@ -266,6 +280,8 @@ private: std::string mConfigPath; std::string mDownloadPath; std::string mPartialsPath; + + std::map mEncryptedHashes ; // This map is such that sha1(it->second) = it->first }; diff --git a/libretroshare/src/retroshare/rsfiles.h b/libretroshare/src/retroshare/rsfiles.h index cd12396fb..b9f7a69be 100644 --- a/libretroshare/src/retroshare/rsfiles.h +++ b/libretroshare/src/retroshare/rsfiles.h @@ -63,26 +63,27 @@ const uint32_t RS_FILE_PEER_OFFLINE = 0x00002000; // Flags used when requesting info about transfers, mostly to filter out the result. // -const FileSearchFlags RS_FILE_HINTS_CACHE_deprecated ( 0x00000001 ); -const FileSearchFlags RS_FILE_HINTS_EXTRA ( 0x00000002 ); -const FileSearchFlags RS_FILE_HINTS_LOCAL ( 0x00000004 ); -const FileSearchFlags RS_FILE_HINTS_REMOTE ( 0x00000008 ); -const FileSearchFlags RS_FILE_HINTS_DOWNLOAD ( 0x00000010 ); -const FileSearchFlags RS_FILE_HINTS_UPLOAD ( 0x00000020 ); -const FileSearchFlags RS_FILE_HINTS_SPEC_ONLY ( 0x01000000 ); +const FileSearchFlags RS_FILE_HINTS_CACHE_deprecated ( 0x00000001 ); +const FileSearchFlags RS_FILE_HINTS_EXTRA ( 0x00000002 ); +const FileSearchFlags RS_FILE_HINTS_LOCAL ( 0x00000004 ); +const FileSearchFlags RS_FILE_HINTS_REMOTE ( 0x00000008 ); +const FileSearchFlags RS_FILE_HINTS_DOWNLOAD ( 0x00000010 ); +const FileSearchFlags RS_FILE_HINTS_UPLOAD ( 0x00000020 ); +const FileSearchFlags RS_FILE_HINTS_SPEC_ONLY ( 0x01000000 ); -const FileSearchFlags RS_FILE_HINTS_NETWORK_WIDE ( 0x00000080 );// anonymously shared over network -const FileSearchFlags RS_FILE_HINTS_BROWSABLE ( 0x00000100 );// browsable by friends -const FileSearchFlags RS_FILE_HINTS_PERMISSION_MASK ( 0x00000180 );// OR of the last two flags. Used to filter out. +const FileSearchFlags RS_FILE_HINTS_NETWORK_WIDE ( 0x00000080 );// anonymously shared over network +const FileSearchFlags RS_FILE_HINTS_BROWSABLE ( 0x00000100 );// browsable by friends +const FileSearchFlags RS_FILE_HINTS_PERMISSION_MASK ( 0x00000180 );// OR of the last two flags. Used to filter out. // Flags used when requesting a transfer // const TransferRequestFlags RS_FILE_REQ_ANONYMOUS_ROUTING ( 0x00000040 ); // Use to ask turtle router to download the file. +const TransferRequestFlags RS_FILE_REQ_ENCRYPTED ( 0x00000080 ); // Asks for end-to-end encryption of file at the level of ftServer const TransferRequestFlags RS_FILE_REQ_ASSUME_AVAILABILITY ( 0x00000200 ); // Assume full source availability. Used for cache files. -const TransferRequestFlags RS_FILE_REQ_CACHE_deprecated ( 0x00000400 ); // Assume full source availability. Used for cache files. +const TransferRequestFlags RS_FILE_REQ_CACHE_deprecated ( 0x00000400 ); // Old stuff used for cache files. Not used anymore. const TransferRequestFlags RS_FILE_REQ_EXTRA ( 0x00000800 ); -const TransferRequestFlags RS_FILE_REQ_MEDIA ( 0x00001000 ); -const TransferRequestFlags RS_FILE_REQ_BACKGROUND ( 0x00002000 ); // To download slowly. +const TransferRequestFlags RS_FILE_REQ_MEDIA ( 0x00001000 ); +const TransferRequestFlags RS_FILE_REQ_BACKGROUND ( 0x00002000 ); // To download slowly. const TransferRequestFlags RS_FILE_REQ_NO_SEARCH ( 0x02000000 ); // disable searching for potential direct sources. // const uint32_t RS_FILE_HINTS_SHARE_FLAGS_MASK = RS_FILE_HINTS_NETWORK_WIDE_OTHERS | RS_FILE_HINTS_BROWSABLE_OTHERS