Merge pull request #557 from mr-alice/v0.6-FTEncryption

V0.6 ft encryption
This commit is contained in:
Cyril Soler 2016-11-04 20:02:14 +01:00 committed by GitHub
commit 8c1a6537b4
45 changed files with 2868 additions and 773 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,116 @@
/*
* RetroShare C++ File sharing default variables
*
* crypto/chacha20.h
*
* Copyright 2016 by Mr.Alice
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare.project@gmail.com".
*
*/
#include <stdint.h>
namespace librs
{
namespace crypto
{
/*!
* \brief chacha20_encrypt
* Performs in place encryption/decryption of the supplied data, using chacha20, using the supplied key and nonce.
*
* \param key secret encryption key. *Should never* be re-used.
* \param block_counter any integer. 0 is fine.
* \param nonce acts as an initialzation vector. /!\ it is extremely important to make sure that this nounce *is* everytime different. Using a purely random value is fine.
* \param data data that gets encrypted/decrypted in place
* \param size size of the data.
*/
void chacha20_encrypt(uint8_t key[32], uint32_t block_counter, uint8_t nonce[12], uint8_t *data, uint32_t size) ;
/*!
* \brief poly1305_tag
* Computes an authentication tag for the supplied data, using the given secret key.
* \param key secret key. *Should not* be used multiple times.
* \param message message to generate a tag for
* \param size size of the message
* \param tag place where the tag is stored.
*/
void poly1305_tag(uint8_t key[32],uint8_t *message,uint32_t size,uint8_t tag[16]);
/*!
* \brief AEAD_chacha20_poly1305
* Provides in-place authenticated encryption using the AEAD construction as described in RFC7539.
* The data is first encrypted in place then 16-padded and concatenated to its size, than concatenated to the
* 16-padded AAD (additional authenticated data) and its size, authenticated using poly1305.
*
* \param key key that is used to derive a one time secret key for poly1305 and that is also used to encrypt the data
* \param nonce nonce. *Should be unique* in order to make the chacha20 stream cipher unique.
* \param data data that is encrypted/decrypted in place.
* \param size size of the data
* \param aad additional authenticated data. Can be used to authenticate the nonce.
* \param aad_size
* \param tag generated poly1305 tag.
* \param encrypt true to encrypt, false to decrypt and check the tag.
* \return
* always true for encryption.
* authentication result for decryption. data is *always* xored to the cipher stream whatever the authentication result is.
*/
bool AEAD_chacha20_poly1305(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint32_t data_size,uint8_t *aad,uint32_t aad_size,uint8_t tag[16],bool encrypt_or_decrypt) ;
/*!
* \brief AEAD_chacha20_sha256
* Provides authenticated encryption using a simple construction that associates chacha20 encryption with HMAC authentication using
* the same 32 bytes key. The authenticated tag is the 16 first bytes of the sha256 HMAC.
*
* \param key encryption/authentication key
* \param nonce nonce. *Should be unique* in order to make chacha20 stream cipher unique.
* \param data data that is encrypted/decrypted in place
* \param data_size size of data to encrypt/authenticate
* \param aad additional authenticated data. Can be used to authenticate the nonce.
* \param aad_size
* \param tag 16 bytes authentication tag result
* \param encrypt true to encrypt, false to decrypt and check the tag.
* \return
* always true for encryption.
* authentication result for decryption. data is *always* xored to the cipher stream whatever the authentication result is.
*/
bool AEAD_chacha20_sha256(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint32_t data_size,uint8_t *aad,uint32_t aad_size,uint8_t tag[16],bool encrypt_or_decrypt) ;
/*!
* \brief constant_time_memcmp
* Provides a constant time comparison of two memory chunks. Calls CRYPTO_memcmp.
*
* \param m1 memory block 1
* \param m2 memory block 2
* \param size common size of m1 and m2
* \return
* false if the two chunks are different
* true if the two chunks are identical
*/
bool constant_time_memory_compare(const uint8_t *m1,const uint8_t *m2,uint32_t size) ;
/*!
* \brief perform_tests
* Tests all methods in this class, using the tests supplied in RFC7539
* \return
* true is all tests pass
*/
bool perform_tests() ;
}
}

View file

@ -677,18 +677,9 @@ DirectoryStorage::EntryIndex InternalFileHierarchyStorage::getSubDirIndex(Direct
return static_cast<DirEntry*>(mNodes[parent_index])->subdirs[dir_tab_index]; return static_cast<DirEntry*>(mNodes[parent_index])->subdirs[dir_tab_index];
} }
bool InternalFileHierarchyStorage::searchHash(const RsFileHash& hash,std::list<DirectoryStorage::EntryIndex>& results) bool InternalFileHierarchyStorage::searchHash(const RsFileHash& hash,DirectoryStorage::EntryIndex& result)
{ {
DirectoryStorage::EntryIndex indx ; return getIndexFromFileHash(hash,result);
if(getIndexFromFileHash(hash,indx))
{
results.clear();
results.push_back(indx) ;
return true ;
}
else
return false;
} }
class DirectoryStorageExprFileEntry: public RsRegularExpression::ExpFileEntry class DirectoryStorageExprFileEntry: public RsRegularExpression::ExpFileEntry

View file

@ -143,7 +143,7 @@ public:
// search. SearchHash is logarithmic. The other two are linear. // search. SearchHash is logarithmic. The other two are linear.
bool searchHash(const RsFileHash& hash,std::list<DirectoryStorage::EntryIndex>& results); bool searchHash(const RsFileHash& hash, DirectoryStorage::EntryIndex &result);
int searchBoolExp(RsRegularExpression::Expression * exp, std::list<DirectoryStorage::EntryIndex> &results) const ; int searchBoolExp(RsRegularExpression::Expression * exp, std::list<DirectoryStorage::EntryIndex> &results) const ;
int searchTerms(const std::list<std::string>& terms, std::list<DirectoryStorage::EntryIndex> &results) const ; // does a logical OR between items of the list of terms int searchTerms(const std::list<std::string>& terms, std::list<DirectoryStorage::EntryIndex> &results) const ; // does a logical OR between items of the list of terms

View file

@ -168,12 +168,6 @@ bool DirectoryStorage::updateHash(const EntryIndex& index,const RsFileHash& hash
return mFileHierarchy->updateHash(index,hash); return mFileHierarchy->updateHash(index,hash);
} }
int DirectoryStorage::searchHash(const RsFileHash& hash, std::list<EntryIndex> &results) const
{
RS_STACK_MUTEX(mDirStorageMtx) ;
return mFileHierarchy->searchHash(hash,results);
}
bool DirectoryStorage::load(const std::string& local_file_name) bool DirectoryStorage::load(const std::string& local_file_name)
{ {
RS_STACK_MUTEX(mDirStorageMtx) ; RS_STACK_MUTEX(mDirStorageMtx) ;
@ -295,6 +289,36 @@ bool DirectoryStorage::getIndexFromDirHash(const RsFileHash& hash,EntryIndex& in
/* Local Directory Storage */ /* Local Directory Storage */
/******************************************************************************************************************/ /******************************************************************************************************************/
RsFileHash LocalDirectoryStorage::makeEncryptedHash(const RsFileHash& hash)
{
return RsDirUtil::sha1sum(hash.toByteArray(),hash.SIZE_IN_BYTES);
}
bool LocalDirectoryStorage::locked_findRealHash(const RsFileHash& hash, RsFileHash& real_hash) const
{
std::map<RsFileHash,RsFileHash>::const_iterator it = mEncryptedHashes.find(hash) ;
if(it == mEncryptedHashes.end())
return false ;
real_hash = it->second ;
return true ;
}
int LocalDirectoryStorage::searchHash(const RsFileHash& hash, RsFileHash& real_hash, EntryIndex& result) const
{
RS_STACK_MUTEX(mDirStorageMtx) ;
if(locked_findRealHash(hash,real_hash) && mFileHierarchy->searchHash(real_hash,result))
return true ;
if(mFileHierarchy->searchHash(hash,result))
{
real_hash.clear();
return true ;
}
return false ;
}
void LocalDirectoryStorage::setSharedDirectoryList(const std::list<SharedDirInfo>& lst) void LocalDirectoryStorage::setSharedDirectoryList(const std::list<SharedDirInfo>& lst)
{ {
RS_STACK_MUTEX(mDirStorageMtx) ; RS_STACK_MUTEX(mDirStorageMtx) ;
@ -434,7 +458,15 @@ void LocalDirectoryStorage::updateTimeStamps()
#endif #endif
} }
} }
bool LocalDirectoryStorage::updateHash(const EntryIndex& index,const RsFileHash& hash)
{
{
RS_STACK_MUTEX(mDirStorageMtx) ;
mEncryptedHashes[makeEncryptedHash(hash)] = hash ;
}
return mFileHierarchy->updateHash(index,hash);
}
std::string LocalDirectoryStorage::locked_findRealRootFromVirtualFilename(const std::string& virtual_rootdir) const std::string LocalDirectoryStorage::locked_findRealRootFromVirtualFilename(const std::string& virtual_rootdir) const
{ {
/**** MUST ALREADY BE LOCKED ****/ /**** MUST ALREADY BE LOCKED ****/

View file

@ -53,7 +53,6 @@ class DirectoryStorage
virtual int searchTerms(const std::list<std::string>& terms, std::list<EntryIndex> &results) const ; virtual int searchTerms(const std::list<std::string>& terms, std::list<EntryIndex> &results) const ;
virtual int searchBoolExp(RsRegularExpression::Expression * exp, std::list<EntryIndex> &results) const ; virtual int searchBoolExp(RsRegularExpression::Expression * exp, std::list<EntryIndex> &results) const ;
virtual int searchHash(const RsFileHash& hash, std::list<EntryIndex> &results) const ;
// gets/sets the various time stamps: // gets/sets the various time stamps:
// //
@ -140,7 +139,9 @@ class DirectoryStorage
// Updates relevant information for the file at the given index. // Updates relevant information for the file at the given index.
bool updateFile(const EntryIndex& index,const RsFileHash& hash, const std::string& fname, uint64_t size, time_t modf_time) ; bool updateFile(const EntryIndex& index,const RsFileHash& hash, const std::string& fname, uint64_t size, time_t modf_time) ;
bool updateHash(const EntryIndex& index,const RsFileHash& hash);
// This is derived in LocalDirectoryStorage in order to also store H(H(F))
virtual bool updateHash(const EntryIndex& index,const RsFileHash& hash);
// Returns the hash of the directory at the given index and reverse. This hash is set as random the first time it is used (when updating directories). It will be // Returns the hash of the directory at the given index and reverse. This hash is set as random the first time it is used (when updating directories). It will be
// used by the sync system to designate the directory without referring to index (index could be used to figure out the existance of hidden directories) // used by the sync system to designate the directory without referring to index (index could be used to figure out the existance of hidden directories)
@ -216,6 +217,20 @@ public:
void updateShareFlags(const SharedDirInfo& info) ; void updateShareFlags(const SharedDirInfo& info) ;
bool convertSharedFilePath(const std::string& path_with_virtual_name,std::string& fullpath) ; bool convertSharedFilePath(const std::string& path_with_virtual_name,std::string& fullpath) ;
virtual bool updateHash(const EntryIndex& index,const RsFileHash& hash);
/*!
* \brief searchHash
* Looks into local database of shared files for the given hash. Also looks for files such that the hash of the hash
* matches the given hash, and returns the real hash.
* \param hash hash to look for
* \param real_hash hash such that H(real_hash) = hash, or null hash if not found.
* \param results Entry index of the file that is found
* \return
* true is a file is found
* false otherwise.
*/
virtual int searchHash(const RsFileHash& hash, RsFileHash &real_hash, EntryIndex &results) const ;
/*! /*!
* \brief updateTimeStamps * \brief updateTimeStamps
* Checks recursive TS and update the if needed. * Checks recursive TS and update the if needed.
@ -261,6 +276,8 @@ public:
bool serialiseDirEntry(const EntryIndex& indx, RsTlvBinaryData& bindata, const RsPeerId &client_id) ; bool serialiseDirEntry(const EntryIndex& indx, RsTlvBinaryData& bindata, const RsPeerId &client_id) ;
private: private:
static RsFileHash makeEncryptedHash(const RsFileHash& hash);
bool locked_findRealHash(const RsFileHash& hash, RsFileHash& real_hash) const;
std::string locked_getVirtualPath(EntryIndex indx) const ; std::string locked_getVirtualPath(EntryIndex indx) const ;
std::string locked_getVirtualDirName(EntryIndex indx) const ; std::string locked_getVirtualDirName(EntryIndex indx) const ;
@ -268,6 +285,7 @@ private:
std::string locked_findRealRootFromVirtualFilename(const std::string& virtual_rootdir) const; std::string locked_findRealRootFromVirtualFilename(const std::string& virtual_rootdir) const;
std::map<std::string,SharedDirInfo> mLocalDirs ; // map is better for search. it->first=it->second.filename std::map<std::string,SharedDirInfo> mLocalDirs ; // map is better for search. it->first=it->second.filename
std::map<RsFileHash,RsFileHash> mEncryptedHashes; // map such that hash(it->second) = it->first
std::string mFileName; std::string mFileName;
bool mTSChanged ; bool mTSChanged ;

View file

@ -345,7 +345,7 @@ bool p3FileDatabase::loadList(std::list<RsItem *>& load)
/* for each item, check it exists .... /* for each item, check it exists ....
* - remove any that are dead (or flag?) * - remove any that are dead (or flag?)
*/ */
static const FileStorageFlags PERMISSION_MASK = DIR_FLAGS_BROWSABLE_OTHERS | DIR_FLAGS_NETWORK_WIDE_OTHERS | DIR_FLAGS_BROWSABLE_GROUPS | DIR_FLAGS_NETWORK_WIDE_GROUPS ; static const FileStorageFlags PERMISSION_MASK = DIR_FLAGS_PERMISSIONS_MASK;
#ifdef DEBUG_FILE_HIERARCHY #ifdef DEBUG_FILE_HIERARCHY
P3FILELISTS_DEBUG() << "Load list" << std::endl; P3FILELISTS_DEBUG() << "Load list" << std::endl;
@ -400,7 +400,6 @@ bool p3FileDatabase::loadList(std::list<RsItem *>& load)
info.virtualname = fi->file.name; info.virtualname = fi->file.name;
info.shareflags = FileStorageFlags(fi->flags) ; info.shareflags = FileStorageFlags(fi->flags) ;
info.shareflags &= PERMISSION_MASK ; info.shareflags &= PERMISSION_MASK ;
info.shareflags &= ~DIR_FLAGS_NETWORK_WIDE_GROUPS ; // disabling this flag for know, for consistency reasons
for(std::set<RsNodeGroupId>::const_iterator itt(fi->parent_groups.ids.begin());itt!=fi->parent_groups.ids.end();++itt) for(std::set<RsNodeGroupId>::const_iterator itt(fi->parent_groups.ids.begin());itt!=fi->parent_groups.ids.end();++itt)
info.parent_groups.push_back(*itt) ; info.parent_groups.push_back(*itt) ;
@ -644,25 +643,24 @@ void p3FileDatabase::requestDirUpdate(void *ref)
bool p3FileDatabase::findChildPointer( void *ref, int row, void *& result, bool p3FileDatabase::findChildPointer( void *ref, int row, void *& result,
FileSearchFlags flags ) const FileSearchFlags flags ) const
{ {
RS_STACK_MUTEX(mFLSMtx);
result = NULL;
if (ref == NULL) if (ref == NULL)
{ {
if(flags & RS_FILE_HINTS_LOCAL) if(flags & RS_FILE_HINTS_LOCAL)
{ {
if(row != 0) return false; if(row != 0)
return false ;
convertEntryIndexToPointer(0,0,result); convertEntryIndexToPointer(0,0,result);
return true;
return true ;
} }
else if((uint32_t)row < mRemoteDirectories.size()) else if((uint32_t)row < mRemoteDirectories.size())
{ {
convertEntryIndexToPointer(mRemoteDirectories[row]->root(), row+1, result); convertEntryIndexToPointer(mRemoteDirectories[row]->root(),row+1,result);
return true; return true;
} }
else return false; else
return false;
} }
uint32_t fi; uint32_t fi;
@ -999,16 +997,20 @@ bool p3FileDatabase::search(const RsFileHash &hash, FileSearchFlags hintflags, F
if(hintflags & RS_FILE_HINTS_LOCAL) if(hintflags & RS_FILE_HINTS_LOCAL)
{ {
std::list<EntryIndex> res; RsFileHash real_hash ;
mLocalSharedDirs->searchHash(hash,res) ; EntryIndex indx;
if(res.empty()) if(!mLocalSharedDirs->searchHash(hash,real_hash,indx))
return false; return false;
EntryIndex indx = *res.begin() ; // no need to report duplicates
mLocalSharedDirs->getFileInfo(indx,info) ; mLocalSharedDirs->getFileInfo(indx,info) ;
if(!real_hash.isNull())
{
info.hash = real_hash ;
info.transfer_info_flags |= RS_FILE_REQ_ENCRYPTED ;
}
return true; return true;
} }

View file

@ -113,6 +113,7 @@ ftController::ftController(ftDataMultiplex *dm, p3ServiceControl *sc, uint32_t f
{ {
_max_active_downloads = 5 ; // default queue size _max_active_downloads = 5 ; // default queue size
_min_prioritized_transfers = 3 ; _min_prioritized_transfers = 3 ;
mDefaultEncryptionPolicy = RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE;
/* TODO */ /* TODO */
cnt = 0 ; cnt = 0 ;
} }
@ -580,7 +581,7 @@ void ftController::locked_checkQueueElement(uint32_t pos)
_queue[pos]->mState = ftFileControl::DOWNLOADING ; _queue[pos]->mState = ftFileControl::DOWNLOADING ;
if(_queue[pos]->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING) if(_queue[pos]->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING)
mTurtle->monitorTunnels(_queue[pos]->mHash,mFtServer,true) ; mFtServer->activateTunnels(_queue[pos]->mHash,mDefaultEncryptionPolicy,_queue[pos]->mFlags,true);
} }
if(pos >= _max_active_downloads && _queue[pos]->mState != ftFileControl::QUEUED && _queue[pos]->mState != ftFileControl::PAUSED) if(pos >= _max_active_downloads && _queue[pos]->mState != ftFileControl::QUEUED && _queue[pos]->mState != ftFileControl::PAUSED)
@ -589,7 +590,7 @@ void ftController::locked_checkQueueElement(uint32_t pos)
_queue[pos]->mCreator->closeFile() ; _queue[pos]->mCreator->closeFile() ;
if(_queue[pos]->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING) if(_queue[pos]->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING)
mTurtle->stopMonitoringTunnels(_queue[pos]->mHash) ; mFtServer->activateTunnels(_queue[pos]->mHash,mDefaultEncryptionPolicy,_queue[pos]->mFlags,false);
} }
} }
@ -833,7 +834,7 @@ bool ftController::completeFile(const RsFileHash& hash)
mDownloads.erase(it); mDownloads.erase(it);
if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING) if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING)
mTurtle->stopMonitoringTunnels(hash_to_suppress) ; mFtServer->activateTunnels(hash_to_suppress,mDefaultEncryptionPolicy,flags,false);
} // UNLOCK: RS_STACK_MUTEX(ctrlMutex); } // UNLOCK: RS_STACK_MUTEX(ctrlMutex);
@ -976,6 +977,21 @@ bool ftController::FileRequest(const std::string& fname, const RsFileHash& hash
if(alreadyHaveFile(hash, info)) if(alreadyHaveFile(hash, info))
return false ; return false ;
// the strategy for requesting encryption is the following:
//
// if policy is STRICT
// - disable clear, enforce encryption
// else
// - if not specified, use clear
//
if(mDefaultEncryptionPolicy == RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT)
{
flags |= RS_FILE_REQ_ENCRYPTED ;
flags &= ~RS_FILE_REQ_UNENCRYPTED ;
}
else if(!(flags & ( RS_FILE_REQ_ENCRYPTED | RS_FILE_REQ_UNENCRYPTED )))
flags |= RS_FILE_REQ_UNENCRYPTED ;
if(size == 0) // we treat this special case because if(size == 0) // we treat this special case because
{ {
/* if no destpath - send to download directory */ /* if no destpath - send to download directory */
@ -1172,7 +1188,7 @@ bool ftController::FileRequest(const std::string& fname, const RsFileHash& hash
// We check that flags are consistent. // We check that flags are consistent.
if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING) if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING)
mTurtle->monitorTunnels(hash,mFtServer,true) ; mFtServer->activateTunnels(hash,mDefaultEncryptionPolicy,flags,true);
bool assume_availability = false; bool assume_availability = false;
@ -1273,7 +1289,7 @@ bool ftController::setChunkStrategy(const RsFileHash& hash,FileChunksInfo::Chunk
bool ftController::FileCancel(const RsFileHash& hash) bool ftController::FileCancel(const RsFileHash& hash)
{ {
rsTurtle->stopMonitoringTunnels(hash) ; mFtServer->activateTunnels(hash,mDefaultEncryptionPolicy,TransferRequestFlags(0),false);
#ifdef CONTROL_DEBUG #ifdef CONTROL_DEBUG
std::cerr << "ftController::FileCancel" << std::endl; std::cerr << "ftController::FileCancel" << std::endl;
@ -1597,7 +1613,7 @@ bool ftController::FileDetails(const RsFileHash &hash, FileInfo &info)
info.queue_position = it->second->mQueuePosition ; info.queue_position = it->second->mQueuePosition ;
if(it->second->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING) if(it->second->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING)
info.storage_permission_flags |= DIR_FLAGS_NETWORK_WIDE_OTHERS ; // file being downloaded anonymously are always anonymously available. info.storage_permission_flags |= DIR_FLAGS_ANONYMOUS_DOWNLOAD ; // file being downloaded anonymously are always anonymously available.
/* get list of sources from transferModule */ /* get list of sources from transferModule */
std::list<RsPeerId> peerIds; std::list<RsPeerId> peerIds;
@ -1811,6 +1827,7 @@ const std::string download_dir_ss("DOWN_DIR");
const std::string partial_dir_ss("PART_DIR"); const std::string partial_dir_ss("PART_DIR");
const std::string default_chunk_strategy_ss("DEFAULT_CHUNK_STRATEGY"); const std::string default_chunk_strategy_ss("DEFAULT_CHUNK_STRATEGY");
const std::string free_space_limit_ss("FREE_SPACE_LIMIT"); const std::string free_space_limit_ss("FREE_SPACE_LIMIT");
const std::string default_encryption_policy_ss("DEFAULT_ENCRYPTION_POLICY");
/* p3Config Interface */ /* p3Config Interface */
@ -1858,6 +1875,8 @@ bool ftController::saveList(bool &cleanup, std::list<RsItem *>& saveData)
break ; break ;
} }
configMap[default_encryption_policy_ss] = (mDefaultEncryptionPolicy==RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE)?"PERMISSIVE":"STRICT" ;
rs_sprintf(s, "%lu", RsDiscSpace::freeSpaceLimit()); rs_sprintf(s, "%lu", RsDiscSpace::freeSpaceLimit());
configMap[free_space_limit_ss] = s ; configMap[free_space_limit_ss] = s ;
@ -2100,6 +2119,25 @@ bool ftController::loadConfigMap(std::map<std::string, std::string> &configMap)
setPartialsDirectory(mit->second); setPartialsDirectory(mit->second);
} }
if (configMap.end() != (mit = configMap.find(default_encryption_policy_ss)))
{
if(mit->second == "STRICT")
{
mDefaultEncryptionPolicy = RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT ;
std::cerr << "Note: loading default value for encryption policy: STRICT" << std::endl;
}
else if(mit->second == "PERMISSIVE")
{
mDefaultEncryptionPolicy = RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE ;
std::cerr << "Note: loading default value for encryption policy: PERMISSIVE" << std::endl;
}
else
{
std::cerr << "(EE) encryption policy not recognized: \"" << mit->second << "\"" << std::endl;
mDefaultEncryptionPolicy = RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE ;
}
}
if (configMap.end() != (mit = configMap.find(default_chunk_strategy_ss))) if (configMap.end() != (mit = configMap.find(default_chunk_strategy_ss)))
{ {
if(mit->second == "STREAMING") if(mit->second == "STREAMING")
@ -2133,6 +2171,17 @@ bool ftController::loadConfigMap(std::map<std::string, std::string> &configMap)
return true; return true;
} }
void ftController::setDefaultEncryptionPolicy(uint32_t p)
{
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
mDefaultEncryptionPolicy = p ;
IndicateConfigChanged();
}
uint32_t ftController::defaultEncryptionPolicy()
{
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
return mDefaultEncryptionPolicy ;
}
void ftController::setFreeDiskSpaceLimit(uint32_t size_in_mb) void ftController::setFreeDiskSpaceLimit(uint32_t size_in_mb)
{ {
RsDiscSpace::setFreeSpaceLimit(size_in_mb) ; RsDiscSpace::setFreeSpaceLimit(size_in_mb) ;

View file

@ -140,9 +140,11 @@ class ftController: public RsTickingThread, public pqiServiceMonitor, public p3C
bool setChunkStrategy(const RsFileHash& hash,FileChunksInfo::ChunkStrategy s); bool setChunkStrategy(const RsFileHash& hash,FileChunksInfo::ChunkStrategy s);
void setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy s); void setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy s);
void setDefaultEncryptionPolicy(uint32_t s);
FileChunksInfo::ChunkStrategy defaultChunkStrategy(); FileChunksInfo::ChunkStrategy defaultChunkStrategy();
uint32_t freeDiskSpaceLimit() const ; uint32_t freeDiskSpaceLimit() const ;
void setFreeDiskSpaceLimit(uint32_t size_in_mb) ; void setFreeDiskSpaceLimit(uint32_t size_in_mb) ;
uint32_t defaultEncryptionPolicy();
bool FileCancel(const RsFileHash& hash); bool FileCancel(const RsFileHash& hash);
bool FileControl(const RsFileHash& hash, uint32_t flags); bool FileControl(const RsFileHash& hash, uint32_t flags);
@ -237,6 +239,7 @@ class ftController: public RsTickingThread, public pqiServiceMonitor, public p3C
ftServer *mFtServer ; ftServer *mFtServer ;
p3ServiceControl *mServiceCtrl; p3ServiceControl *mServiceCtrl;
uint32_t mFtServiceId; uint32_t mFtServiceId;
uint32_t mDefaultEncryptionPolicy ;
uint32_t cnt ; uint32_t cnt ;
RsMutex ctrlMutex; RsMutex ctrlMutex;

View file

@ -350,9 +350,10 @@ bool ftExtraList::search(const RsFileHash &hash, FileSearchFlags /*hintflags*
// Now setup the file storage flags so that the client can know how to handle permissions // Now setup the file storage flags so that the client can know how to handle permissions
// //
info.storage_permission_flags = DIR_FLAGS_BROWSABLE_OTHERS ; #warning make sure this is right
info.storage_permission_flags = FileStorageFlags(0) ;//DIR_FLAGS_BROWSABLE_OTHERS ;
if(info.transfer_info_flags & RS_FILE_REQ_ANONYMOUS_ROUTING) info.storage_permission_flags |= DIR_FLAGS_NETWORK_WIDE_OTHERS ; if(info.transfer_info_flags & RS_FILE_REQ_ANONYMOUS_ROUTING) info.storage_permission_flags |= DIR_FLAGS_ANONYMOUS_DOWNLOAD ;
return true; return true;
} }

View file

@ -27,6 +27,8 @@
#include <time.h> #include <time.h>
#include "util/rsdebug.h" #include "util/rsdebug.h"
#include "util/rsdir.h" #include "util/rsdir.h"
#include "util/rsprint.h"
#include "crypto/chacha20.h"
#include "retroshare/rstypes.h" #include "retroshare/rstypes.h"
#include "retroshare/rspeers.h" #include "retroshare/rspeers.h"
const int ftserverzone = 29539; const int ftserverzone = 29539;
@ -55,9 +57,12 @@ const int ftserverzone = 29539;
* #define SERVER_DEBUG_CACHE 1 * #define SERVER_DEBUG_CACHE 1
***/ ***/
#define FTSERVER_DEBUG() std::cerr << time(NULL) << " : FILE_SERVER : " << __FUNCTION__ << " : "
#define FTSERVER_ERROR() std::cerr << "(EE) FILE_SERVER ERROR : "
static const time_t FILE_TRANSFER_LOW_PRIORITY_TASKS_PERIOD = 5 ; // low priority tasks handling every 5 seconds static const time_t FILE_TRANSFER_LOW_PRIORITY_TASKS_PERIOD = 5 ; // low priority tasks handling every 5 seconds
/* Setup */ /* Setup */
ftServer::ftServer(p3PeerMgr *pm, p3ServiceControl *sc) ftServer::ftServer(p3PeerMgr *pm, p3ServiceControl *sc)
: p3Service(), : p3Service(),
mPeerMgr(pm), mServiceCtrl(sc), mPeerMgr(pm), mServiceCtrl(sc),
@ -102,9 +107,9 @@ void ftServer::setConfigDirectory(std::string path)
RsDirUtil::checkCreateDirectory(remotecachedir) ; RsDirUtil::checkCreateDirectory(remotecachedir) ;
} }
/* Control Interface */ /* Control Interface */
/* add Config Items (Extra, Controller) */ /* add Config Items (Extra, Controller) */
void ftServer::addConfigComponents(p3ConfigMgr */*mgr*/) void ftServer::addConfigComponents(p3ConfigMgr */*mgr*/)
{ {
/* NOT SURE ABOUT THIS ONE */ /* NOT SURE ABOUT THIS ONE */
@ -120,7 +125,7 @@ const RsPeerId& ftServer::OwnId()
return null_id ; return null_id ;
} }
/* Final Setup (once everything is assigned) */ /* Final Setup (once everything is assigned) */
void ftServer::SetupFtServer() void ftServer::SetupFtServer()
{ {
@ -240,7 +245,9 @@ bool ftServer::alreadyHaveFile(const RsFileHash& hash, FileInfo &info)
bool ftServer::FileRequest(const std::string& fname, const RsFileHash& hash, uint64_t size, const std::string& dest, TransferRequestFlags flags, const std::list<RsPeerId>& srcIds) bool ftServer::FileRequest(const std::string& fname, const RsFileHash& hash, uint64_t size, const std::string& dest, TransferRequestFlags flags, const std::list<RsPeerId>& srcIds)
{ {
std::cerr << "Requesting " << fname << std::endl ; #ifdef SERVER_DEBUG
FTSERVER_DEBUG() << "Requesting " << fname << std::endl ;
#endif
if(!mFtController->FileRequest(fname, hash, size, dest, flags, srcIds)) if(!mFtController->FileRequest(fname, hash, size, dest, flags, srcIds))
return false ; return false ;
@ -248,6 +255,41 @@ bool ftServer::FileRequest(const std::string& fname, const RsFileHash& hash, uin
return true ; return true ;
} }
bool ftServer::activateTunnels(const RsFileHash& hash,uint32_t encryption_policy,TransferRequestFlags flags,bool onoff)
{
RsFileHash hash_of_hash ;
encryptHash(hash,hash_of_hash) ;
mEncryptedHashes.insert(std::make_pair(hash_of_hash,hash)) ;
if(onoff)
{
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << "Activating tunnels for hash " << hash << std::endl;
#endif
if(flags & RS_FILE_REQ_ENCRYPTED)
{
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << " flags require end-to-end encryption. Requesting hash of hash " << hash_of_hash << std::endl;
#endif
mTurtleRouter->monitorTunnels(hash_of_hash,this,true) ;
}
if((flags & RS_FILE_REQ_UNENCRYPTED) && (encryption_policy != RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT))
{
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << " flags require no end-to-end encryption. Requesting hash " << hash << std::endl;
#endif
mTurtleRouter->monitorTunnels(hash,this,true) ;
}
}
else
{
mTurtleRouter->stopMonitoringTunnels(hash_of_hash);
mTurtleRouter->stopMonitoringTunnels(hash);
}
return true ;
}
bool ftServer::setDestinationName(const RsFileHash& hash,const std::string& name) bool ftServer::setDestinationName(const RsFileHash& hash,const std::string& name)
{ {
return mFtController->setDestinationName(hash,name); return mFtController->setDestinationName(hash,name);
@ -272,6 +314,14 @@ void ftServer::setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy s)
{ {
mFtController->setDefaultChunkStrategy(s) ; mFtController->setDefaultChunkStrategy(s) ;
} }
uint32_t ftServer::defaultEncryptionPolicy()
{
return mFtController->defaultEncryptionPolicy() ;
}
void ftServer::setDefaultEncryptionPolicy(uint32_t s)
{
mFtController->setDefaultEncryptionPolicy(s) ;
}
FileChunksInfo::ChunkStrategy ftServer::defaultChunkStrategy() FileChunksInfo::ChunkStrategy ftServer::defaultChunkStrategy()
{ {
return mFtController->defaultChunkStrategy() ; return mFtController->defaultChunkStrategy() ;
@ -302,7 +352,7 @@ uint32_t ftServer::getQueueSize()
{ {
return mFtController->getQueueSize() ; return mFtController->getQueueSize() ;
} }
/* Control of Downloads Priority. */ /* Control of Downloads Priority. */
bool ftServer::changeQueuePosition(const RsFileHash& hash, QueueMove mv) bool ftServer::changeQueuePosition(const RsFileHash& hash, QueueMove mv)
{ {
mFtController->moveInQueue(hash,mv) ; mFtController->moveInQueue(hash,mv) ;
@ -337,7 +387,7 @@ void ftServer::requestDirUpdate(void *ref)
mFileDatabase->requestDirUpdate(ref) ; mFileDatabase->requestDirUpdate(ref) ;
} }
/* Directory Handling */ /* Directory Handling */
void ftServer::setDownloadDirectory(std::string path) void ftServer::setDownloadDirectory(std::string path)
{ {
mFtController->setDownloadDirectory(path); mFtController->setDownloadDirectory(path);
@ -414,11 +464,11 @@ RsTurtleGenericTunnelItem *ftServer::deserialiseItem(void *data,uint32_t size) c
uint32_t rstype = getRsItemId(data); uint32_t rstype = getRsItemId(data);
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "p3turtle: deserialising packet: " << std::endl ; FTSERVER_DEBUG() << "p3turtle: deserialising packet: " << std::endl ;
#endif #endif
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_TURTLE != getRsItemService(rstype))) if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_TURTLE != getRsItemService(rstype)))
{ {
std::cerr << " Wrong type !!" << std::endl ; FTSERVER_ERROR() << " Wrong type !!" << std::endl ;
return NULL; /* wrong type */ return NULL; /* wrong type */
} }
@ -439,28 +489,94 @@ RsTurtleGenericTunnelItem *ftServer::deserialiseItem(void *data,uint32_t size) c
} }
catch(std::exception& e) catch(std::exception& e)
{ {
std::cerr << "(EE) deserialisation error in " << __PRETTY_FUNCTION__ << ": " << e.what() << std::endl; FTSERVER_ERROR() << "(EE) deserialisation error in " << __PRETTY_FUNCTION__ << ": " << e.what() << std::endl;
return NULL ; return NULL ;
} }
} }
bool ftServer::isEncryptedSource(const RsPeerId& virtual_peer_id)
{
RS_STACK_MUTEX(srvMutex) ;
return mEncryptedPeerIds.find(virtual_peer_id) != mEncryptedPeerIds.end();
}
void ftServer::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir) void ftServer::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir)
{ {
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << "adding virtual peer. Direction=" << dir << ", hash=" << hash << ", vpid=" << virtual_peer_id << std::endl;
#endif
RsFileHash real_hash ;
{
if(findRealHash(hash,real_hash))
{
RS_STACK_MUTEX(srvMutex) ;
mEncryptedPeerIds[virtual_peer_id] = hash ;
}
else
real_hash = hash;
}
if(dir == RsTurtleGenericTunnelItem::DIRECTION_SERVER) if(dir == RsTurtleGenericTunnelItem::DIRECTION_SERVER)
mFtController->addFileSource(hash,virtual_peer_id) ; {
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << " direction is SERVER. Adding file source for end-to-end encrypted tunnel for real hash " << real_hash << ", virtual peer id = " << virtual_peer_id << std::endl;
#endif
mFtController->addFileSource(real_hash,virtual_peer_id) ;
}
} }
void ftServer::removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id) void ftServer::removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id)
{ {
RsFileHash real_hash ;
if(findRealHash(hash,real_hash))
mFtController->removeFileSource(real_hash,virtual_peer_id) ;
else
mFtController->removeFileSource(hash,virtual_peer_id) ; mFtController->removeFileSource(hash,virtual_peer_id) ;
RS_STACK_MUTEX(srvMutex) ;
mEncryptedPeerIds.erase(virtual_peer_id) ;
} }
bool ftServer::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& peer_id) bool ftServer::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& peer_id)
{ {
FileInfo info ; FileInfo info ;
bool res = FileDetails(hash, RS_FILE_HINTS_NETWORK_WIDE | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY, info); RsFileHash real_hash ;
bool found = false ;
if( (!res) && FileDetails(hash,RS_FILE_HINTS_DOWNLOAD,info)) if(FileDetails(hash, RS_FILE_HINTS_NETWORK_WIDE | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY, info))
{
if(info.transfer_info_flags & RS_FILE_REQ_ENCRYPTED)
{
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << "handleTunnelRequest: openning encrypted FT tunnel for H(H(F))=" << hash << " and H(F)=" << info.hash << std::endl;
#endif
RS_STACK_MUTEX(srvMutex) ;
mEncryptedHashes[hash] = info.hash;
real_hash = info.hash ;
}
else
real_hash = hash ;
found = true ;
}
else // try to see if we're already swarming the file
{
{
RS_STACK_MUTEX(srvMutex) ;
std::map<RsFileHash,RsFileHash>::const_iterator it = mEncryptedHashes.find(hash) ;
if(it != mEncryptedHashes.end())
real_hash = it->second ;
else
real_hash = hash ;
}
if(FileDetails(real_hash,RS_FILE_HINTS_DOWNLOAD,info))
{ {
// This file is currently being downloaded. Let's look if we already have a chunk or not. If not, no need to // This file is currently being downloaded. Let's look if we already have a chunk or not. If not, no need to
// share the file! // share the file!
@ -470,31 +586,47 @@ bool ftServer::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& peer_i
for(uint32_t i=0;i<info2.chunks.size();++i) for(uint32_t i=0;i<info2.chunks.size();++i)
if(info2.chunks[i] == FileChunksInfo::CHUNK_DONE) if(info2.chunks[i] == FileChunksInfo::CHUNK_DONE)
{ {
res = true ; found = true ;
if(info.transfer_info_flags & RS_FILE_REQ_ANONYMOUS_ROUTING)
info.storage_permission_flags = DIR_FLAGS_ANONYMOUS_DOWNLOAD ; // this is to allow swarming
break ; break ;
} }
} }
#ifdef SERVER_DEBUG }
std::cerr << "ftServer: performing local hash search for hash " << hash << std::endl;
if(res) if(found && mFtController->defaultEncryptionPolicy() == RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT && hash == real_hash)
{ {
std::cerr << "Found hash: " << std::endl; #ifdef SERVER_DEBUG
std::cerr << " hash = " << hash << std::endl; std::cerr << "(WW) rejecting file transfer for hash " << hash << " because the hash is not encrypted and encryption policy requires it." << std::endl;
std::cerr << " peer = " << peer_id << std::endl; #endif
std::cerr << " flags = " << info.storage_permission_flags << std::endl; return false ;
std::cerr << " local = " << rsFiles->FileDetails(hash, RS_FILE_HINTS_NETWORK_WIDE | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY | RS_FILE_HINTS_DOWNLOAD, info) << std::endl; }
std::cerr << " groups= " ; for(std::list<std::string>::const_iterator it(info.parent_groups.begin());it!=info.parent_groups.end();++it) std::cerr << (*it) << ", " ; std::cerr << std::endl;
std::cerr << " clear = " << rsPeers->computePeerPermissionFlags(peer_id,info.storage_permission_flags,info.parent_groups) << std::endl; #ifdef SERVER_DEBUG
FTSERVER_DEBUG() << "ftServer: performing local hash search for hash " << hash << std::endl;
if(found)
{
FTSERVER_DEBUG() << "Found hash: " << std::endl;
FTSERVER_DEBUG() << " hash = " << real_hash << std::endl;
FTSERVER_DEBUG() << " peer = " << peer_id << std::endl;
FTSERVER_DEBUG() << " flags = " << info.storage_permission_flags << std::endl;
FTSERVER_DEBUG() << " groups= " ;
for(std::list<RsNodeGroupId>::const_iterator it(info.parent_groups.begin());it!=info.parent_groups.end();++it)
FTSERVER_DEBUG() << (*it) << ", " ;
FTSERVER_DEBUG() << std::endl;
FTSERVER_DEBUG() << " clear = " << rsPeers->computePeerPermissionFlags(peer_id,info.storage_permission_flags,info.parent_groups) << std::endl;
} }
#endif #endif
// The call to computeHashPeerClearance() return a combination of RS_FILE_HINTS_NETWORK_WIDE and RS_FILE_HINTS_BROWSABLE // The call to computeHashPeerClearance() return a combination of RS_FILE_HINTS_NETWORK_WIDE and RS_FILE_HINTS_BROWSABLE
// This is an additional computation cost, but the way it's written here, it's only called when res is true. // This is an additional computation cost, but the way it's written here, it's only called when res is true.
// //
res = res && (RS_FILE_HINTS_NETWORK_WIDE & rsPeers->computePeerPermissionFlags(peer_id,info.storage_permission_flags,info.parent_groups)) ; found = found && (RS_FILE_HINTS_NETWORK_WIDE & rsPeers->computePeerPermissionFlags(peer_id,info.storage_permission_flags,info.parent_groups)) ;
return res ; return found ;
} }
/***************************************************************/ /***************************************************************/
@ -543,7 +675,7 @@ int ftServer::RequestDirDetails(void *ref, DirDetails &details, FileSearchFlags
{ {
return mFileDatabase->RequestDirDetails(ref,details,flags) ; return mFileDatabase->RequestDirDetails(ref,details,flags) ;
} }
uint32_t ftServer::getType(void *ref, FileSearchFlags /*flags*/) uint32_t ftServer::getType(void *ref, FileSearchFlags /* flags */)
{ {
return mFileDatabase->getType(ref) ; return mFileDatabase->getType(ref) ;
} }
@ -569,9 +701,9 @@ int ftServer::SearchBoolExp(RsRegularExpression::Expression * exp, std::list<Dir
return mFileDatabase->SearchBoolExp(exp,results,flags,peer_id) ; return mFileDatabase->SearchBoolExp(exp,results,flags,peer_id) ;
} }
/***************************************************************/ /***************************************************************/
/*************** Local Shared Dir Interface ********************/ /*************** Local Shared Dir Interface ********************/
/***************************************************************/ /***************************************************************/
bool ftServer::ConvertSharedFilePath(std::string path, std::string &fullpath) bool ftServer::ConvertSharedFilePath(std::string path, std::string &fullpath)
{ {
@ -599,7 +731,7 @@ bool ftServer::getSharedDirectories(std::list<SharedDirInfo> &dirs)
return true; return true;
} }
bool ftServer::setSharedDirectories(std::list<SharedDirInfo> &dirs) bool ftServer::setSharedDirectories(const std::list<SharedDirInfo>& dirs)
{ {
mFileDatabase->setSharedDirectories(dirs); mFileDatabase->setSharedDirectories(dirs);
return true; return true;
@ -640,34 +772,27 @@ bool ftServer::removeSharedDirectory(std::string dir)
std::list<SharedDirInfo>::iterator it; std::list<SharedDirInfo>::iterator it;
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::removeSharedDirectory(" << dir << ")"; FTSERVER_DEBUG() << "ftServer::removeSharedDirectory(" << dir << ")" << std::endl;
std::cerr << std::endl;
#endif #endif
mFileDatabase->getSharedDirectories(dirList); mFileDatabase->getSharedDirectories(dirList);
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
for(it = dirList.begin(); it != dirList.end(); ++it) for(it = dirList.begin(); it != dirList.end(); ++it)
{ FTSERVER_DEBUG() << " existing: " << (*it).filename << std::endl;
std::cerr << "ftServer::removeSharedDirectory()";
std::cerr << " existing: " << (*it).filename;
std::cerr << std::endl;
}
#endif #endif
for(it = dirList.begin();it!=dirList.end() && (*it).filename != dir;++it) ; for(it = dirList.begin();it!=dirList.end() && (*it).filename != dir;++it) ;
if(it == dirList.end()) if(it == dirList.end())
{ {
std::cerr << "(EE) ftServer::removeSharedDirectory(): Cannot Find Directory... Fail" << std::endl; FTSERVER_ERROR() << "(EE) ftServer::removeSharedDirectory(): Cannot Find Directory... Fail" << std::endl;
return false; return false;
} }
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::removeSharedDirectory()"; FTSERVER_DEBUG() << " Updating Directories" << std::endl;
std::cerr << " Updating Directories";
std::cerr << std::endl;
#endif #endif
dirList.erase(it); dirList.erase(it);
@ -703,7 +828,7 @@ bool ftServer::shareDownloadDirectory(bool share)
/* Share */ /* Share */
SharedDirInfo inf ; SharedDirInfo inf ;
inf.filename = mFtController->getDownloadDirectory(); inf.filename = mFtController->getDownloadDirectory();
inf.shareflags = DIR_FLAGS_NETWORK_WIDE_OTHERS ; inf.shareflags = DIR_FLAGS_ANONYMOUS_DOWNLOAD ;
return addSharedDirectory(inf); return addSharedDirectory(inf);
} }
@ -715,24 +840,59 @@ bool ftServer::shareDownloadDirectory(bool share)
} }
} }
/***************************************************************/ /***************************************************************/
/****************** End of RsFiles Interface *******************/ /****************** End of RsFiles Interface *******************/
/***************************************************************/ /***************************************************************/
//bool ftServer::loadConfigMap(std::map<std::string, std::string> &/*configMap*/) //bool ftServer::loadConfigMap(std::map<std::string, std::string> &/*configMap*/)
//{ //{
// return true; // return true;
//} //}
/***************************************************************/ /***************************************************************/
/********************** Data Flow **********************/ /********************** Data Flow **********************/
/***************************************************************/ /***************************************************************/
/* Client Send */ bool ftServer::sendTurtleItem(const RsPeerId& peerId,const RsFileHash& hash,RsTurtleGenericTunnelItem *item)
{
// we cannot look in the encrypted hash map, since the same hash--on this side of the FT--can be used with both
// encrypted and unencrypted peers ids. So the information comes from the virtual peer Id.
RsFileHash encrypted_hash;
if(findEncryptedHash(peerId,encrypted_hash))
{
// we encrypt the item
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << "Sending turtle item to peer ID " << peerId << " using encrypted tunnel." << std::endl;
#endif
RsTurtleGenericDataItem *encrypted_item ;
if(!encryptItem(item, hash, encrypted_item))
return false ;
delete item ;
mTurtleRouter->sendTurtleData(peerId,encrypted_item) ;
}
else
{
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << "Sending turtle item to peer ID " << peerId << " using non uncrypted tunnel." << std::endl;
#endif
mTurtleRouter->sendTurtleData(peerId,item) ;
}
return true ;
}
/* Client Send */
bool ftServer::sendDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize) bool ftServer::sendDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::sendDataRequest() to peer " << peerId << " for hash " << hash << ", offset=" << offset << ", chunk size="<< chunksize << std::endl; FTSERVER_DEBUG() << "ftServer::sendDataRequest() to peer " << peerId << " for hash " << hash << ", offset=" << offset << ", chunk size="<< chunksize << std::endl;
#endif #endif
if(mTurtleRouter->isTurtlePeer(peerId)) if(mTurtleRouter->isTurtlePeer(peerId))
{ {
@ -741,7 +901,7 @@ bool ftServer::sendDataRequest(const RsPeerId& peerId, const RsFileHash& hash, u
item->chunk_offset = offset ; item->chunk_offset = offset ;
item->chunk_size = chunksize ; item->chunk_size = chunksize ;
mTurtleRouter->sendTurtleData(peerId,item) ; sendTurtleItem(peerId,hash,item) ;
} }
else else
{ {
@ -769,12 +929,12 @@ bool ftServer::sendDataRequest(const RsPeerId& peerId, const RsFileHash& hash, u
bool ftServer::sendChunkMapRequest(const RsPeerId& peerId,const RsFileHash& hash,bool is_client) bool ftServer::sendChunkMapRequest(const RsPeerId& peerId,const RsFileHash& hash,bool is_client)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::sendChunkMapRequest() to peer " << peerId << " for hash " << hash << std::endl; FTSERVER_DEBUG() << "ftServer::sendChunkMapRequest() to peer " << peerId << " for hash " << hash << std::endl;
#endif #endif
if(mTurtleRouter->isTurtlePeer(peerId)) if(mTurtleRouter->isTurtlePeer(peerId))
{ {
RsTurtleFileMapRequestItem *item = new RsTurtleFileMapRequestItem ; RsTurtleFileMapRequestItem *item = new RsTurtleFileMapRequestItem ;
mTurtleRouter->sendTurtleData(peerId,item) ; sendTurtleItem(peerId,hash,item) ;
} }
else else
{ {
@ -798,13 +958,13 @@ bool ftServer::sendChunkMapRequest(const RsPeerId& peerId,const RsFileHash& hash
bool ftServer::sendChunkMap(const RsPeerId& peerId,const RsFileHash& hash,const CompressedChunkMap& map,bool is_client) bool ftServer::sendChunkMap(const RsPeerId& peerId,const RsFileHash& hash,const CompressedChunkMap& map,bool is_client)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::sendChunkMap() to peer " << peerId << " for hash " << hash << std::endl; FTSERVER_DEBUG() << "ftServer::sendChunkMap() to peer " << peerId << " for hash " << hash << std::endl;
#endif #endif
if(mTurtleRouter->isTurtlePeer(peerId)) if(mTurtleRouter->isTurtlePeer(peerId))
{ {
RsTurtleFileMapItem *item = new RsTurtleFileMapItem ; RsTurtleFileMapItem *item = new RsTurtleFileMapItem ;
item->compressed_map = map ; item->compressed_map = map ;
mTurtleRouter->sendTurtleData(peerId,item) ; sendTurtleItem(peerId,hash,item) ;
} }
else else
{ {
@ -829,14 +989,14 @@ bool ftServer::sendChunkMap(const RsPeerId& peerId,const RsFileHash& hash,const
bool ftServer::sendSingleChunkCRCRequest(const RsPeerId& peerId,const RsFileHash& hash,uint32_t chunk_number) bool ftServer::sendSingleChunkCRCRequest(const RsPeerId& peerId,const RsFileHash& hash,uint32_t chunk_number)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::sendSingleCRCRequest() to peer " << peerId << " for hash " << hash << ", chunk number=" << chunk_number << std::endl; FTSERVER_DEBUG() << "ftServer::sendSingleCRCRequest() to peer " << peerId << " for hash " << hash << ", chunk number=" << chunk_number << std::endl;
#endif #endif
if(mTurtleRouter->isTurtlePeer(peerId)) if(mTurtleRouter->isTurtlePeer(peerId))
{ {
RsTurtleChunkCrcRequestItem *item = new RsTurtleChunkCrcRequestItem; RsTurtleChunkCrcRequestItem *item = new RsTurtleChunkCrcRequestItem;
item->chunk_number = chunk_number ; item->chunk_number = chunk_number ;
mTurtleRouter->sendTurtleData(peerId,item) ; sendTurtleItem(peerId,hash,item) ;
} }
else else
{ {
@ -860,7 +1020,7 @@ bool ftServer::sendSingleChunkCRCRequest(const RsPeerId& peerId,const RsFileHash
bool ftServer::sendSingleChunkCRC(const RsPeerId& peerId,const RsFileHash& hash,uint32_t chunk_number,const Sha1CheckSum& crc) bool ftServer::sendSingleChunkCRC(const RsPeerId& peerId,const RsFileHash& hash,uint32_t chunk_number,const Sha1CheckSum& crc)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::sendSingleCRC() to peer " << peerId << " for hash " << hash << ", chunk number=" << chunk_number << std::endl; FTSERVER_DEBUG() << "ftServer::sendSingleCRC() to peer " << peerId << " for hash " << hash << ", chunk number=" << chunk_number << std::endl;
#endif #endif
if(mTurtleRouter->isTurtlePeer(peerId)) if(mTurtleRouter->isTurtlePeer(peerId))
{ {
@ -868,7 +1028,7 @@ bool ftServer::sendSingleChunkCRC(const RsPeerId& peerId,const RsFileHash& hash,
item->chunk_number = chunk_number ; item->chunk_number = chunk_number ;
item->check_sum = crc ; item->check_sum = crc ;
mTurtleRouter->sendTurtleData(peerId,item) ; sendTurtleItem(peerId,hash,item) ;
} }
else else
{ {
@ -890,7 +1050,7 @@ bool ftServer::sendSingleChunkCRC(const RsPeerId& peerId,const RsFileHash& hash,
return true ; return true ;
} }
/* Server Send */ /* Server Send */
bool ftServer::sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t baseoffset, uint32_t chunksize, void *data) bool ftServer::sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t baseoffset, uint32_t chunksize, void *data)
{ {
/* create a packet */ /* create a packet */
@ -900,12 +1060,7 @@ bool ftServer::sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t
uint32_t chunk; uint32_t chunk;
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::sendData() to " << peerId << std::endl; FTSERVER_DEBUG() << "ftServer::sendData() to " << peerId << ", hash: " << hash << " offset: " << baseoffset << " chunk: " << chunksize << " data: " << data << std::endl;
std::cerr << "hash: " << hash;
std::cerr << " offset: " << baseoffset;
std::cerr << " chunk: " << chunksize;
std::cerr << " data: " << data;
std::cerr << std::endl;
#endif #endif
while(tosend > 0) while(tosend > 0)
@ -939,7 +1094,7 @@ bool ftServer::sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t
} }
memcpy(item->chunk_data,&(((uint8_t *) data)[offset]),chunk) ; memcpy(item->chunk_data,&(((uint8_t *) data)[offset]),chunk) ;
mTurtleRouter->sendTurtleData(peerId,item) ; sendTurtleItem(peerId,hash,item) ;
} }
else else
{ {
@ -965,12 +1120,7 @@ bool ftServer::sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t
/* print the data pointer */ /* print the data pointer */
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::sendData() Packet: " << std::endl; FTSERVER_DEBUG() << "ftServer::sendData() Packet: " << " offset: " << rfd->fd.file_offset << " chunk: " << chunk << " len: " << rfd->fd.binData.bin_len << " data: " << rfd->fd.binData.bin_data << std::endl;
std::cerr << " offset: " << rfd->fd.file_offset;
std::cerr << " chunk: " << chunk;
std::cerr << " len: " << rfd->fd.binData.bin_len;
std::cerr << " data: " << rfd->fd.binData.bin_data;
std::cerr << std::endl;
#endif #endif
} }
@ -984,6 +1134,240 @@ bool ftServer::sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t
return true; return true;
} }
// Encrypts the given item using aead-chacha20-poly1305
//
// The format is the following
//
// [encryption format] [random initialization vector] [encrypted data size] [encrypted data] [authentication tag]
// 4 bytes 12 bytes 4 bytes variable 16 bytes
//
// +-------------------- authenticated data part ----------------------+
//
//
// Encryption format:
// ae ad 01 01 : encryption using AEAD, format 01 (authed with Poly1305 ), version 01
// ae ad 02 01 : encryption using AEAD, format 02 (authed with HMAC Sha256), version 01
//
//
void ftServer::deriveEncryptionKey(const RsFileHash& hash, uint8_t *key)
{
// The encryption key is simply the 256 hash of the
SHA256_CTX sha_ctx ;
if(SHA256_DIGEST_LENGTH != 32)
throw std::runtime_error("Warning: can't compute Sha1Sum with sum size != 32") ;
SHA256_Init(&sha_ctx);
SHA256_Update(&sha_ctx, hash.toByteArray(), hash.SIZE_IN_BYTES);
SHA256_Final (key, &sha_ctx);
}
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 ;
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 ;
bool ftServer::encryptItem(RsTurtleGenericTunnelItem *clear_item,const RsFileHash& hash,RsTurtleGenericDataItem *& encrypted_item)
{
uint8_t initialization_vector[ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE] ;
RSRandom::random_bytes(initialization_vector,ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) ;
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << "ftServer::Encrypting ft item." << std::endl;
FTSERVER_DEBUG() << " random nonce : " << RsUtil::BinToHex(initialization_vector,ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) << std::endl;
#endif
uint32_t total_data_size = ENCRYPTED_FT_HEADER_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_EDATA_SIZE + clear_item->serial_size() + ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE ;
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << " clear part size : " << clear_item->serial_size() << std::endl;
FTSERVER_DEBUG() << " total item size : " << total_data_size << std::endl;
#endif
encrypted_item = new RsTurtleGenericDataItem ;
encrypted_item->data_bytes = rs_malloc( total_data_size ) ;
encrypted_item->data_size = total_data_size ;
if(encrypted_item->data_bytes == NULL)
return false ;
uint8_t *edata = (uint8_t*)encrypted_item->data_bytes ;
uint32_t edata_size = clear_item->serial_size() ;
uint32_t offset = 0;
edata[0] = 0xae ;
edata[1] = 0xad ;
edata[2] = ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256 ; // means AEAD_chacha20_sha256
edata[3] = 0x01 ;
offset += ENCRYPTED_FT_HEADER_SIZE;
uint32_t aad_offset = offset ;
uint32_t aad_size = ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_EDATA_SIZE ;
memcpy(&edata[offset], initialization_vector, ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) ;
offset += ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ;
edata[offset+0] = (edata_size >> 0) & 0xff ;
edata[offset+1] = (edata_size >> 8) & 0xff ;
edata[offset+2] = (edata_size >> 16) & 0xff ;
edata[offset+3] = (edata_size >> 24) & 0xff ;
offset += ENCRYPTED_FT_EDATA_SIZE ;
uint32_t ser_size = (uint32_t)((int)total_data_size - (int)offset);
clear_item->serialize(&edata[offset], ser_size);
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << " clear item : " << RsUtil::BinToHex(&edata[offset],std::min(50,(int)total_data_size-(int)offset)) << "(...)" << std::endl;
#endif
uint32_t clear_item_offset = offset ;
offset += edata_size ;
uint32_t authentication_tag_offset = offset ;
assert(ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE + offset == total_data_size) ;
uint8_t encryption_key[32] ;
deriveEncryptionKey(hash,encryption_key) ;
if(edata[2] == ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305)
librs::crypto::AEAD_chacha20_poly1305(encryption_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],true) ;
else if(edata[2] == ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256)
librs::crypto::AEAD_chacha20_sha256 (encryption_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],true) ;
else
return false ;
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << " encryption key : " << RsUtil::BinToHex(encryption_key,32) << std::endl;
FTSERVER_DEBUG() << " authen. tag : " << RsUtil::BinToHex(&edata[authentication_tag_offset],ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE) << std::endl;
FTSERVER_DEBUG() << " final item : " << RsUtil::BinToHex(&edata[0],std::min(50u,total_data_size)) << "(...)" << std::endl;
#endif
return true ;
}
// Decrypts the given item using aead-chacha20-poly1305
bool ftServer::decryptItem(RsTurtleGenericDataItem *encrypted_item,const RsFileHash& hash,RsTurtleGenericTunnelItem *& decrypted_item)
{
uint8_t encryption_key[32] ;
deriveEncryptionKey(hash,encryption_key) ;
uint8_t *edata = (uint8_t*)encrypted_item->data_bytes ;
uint32_t offset = 0;
if(encrypted_item->data_size < ENCRYPTED_FT_HEADER_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_EDATA_SIZE) return false ;
if(edata[0] != 0xae) return false ;
if(edata[1] != 0xad) return false ;
if(edata[2] != ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305 && edata[2] != ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256) return false ;
if(edata[3] != 0x01) return false ;
offset += ENCRYPTED_FT_HEADER_SIZE ;
uint32_t aad_offset = offset ;
uint32_t aad_size = ENCRYPTED_FT_EDATA_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ;
uint8_t *initialization_vector = &edata[offset] ;
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << "ftServer::decrypting ft item." << std::endl;
FTSERVER_DEBUG() << " item data : " << RsUtil::BinToHex(edata,std::min(50u,encrypted_item->data_size)) << "(...)" << std::endl;
FTSERVER_DEBUG() << " hash : " << hash << std::endl;
FTSERVER_DEBUG() << " encryption key : " << RsUtil::BinToHex(encryption_key,32) << std::endl;
FTSERVER_DEBUG() << " random nonce : " << RsUtil::BinToHex(initialization_vector,ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) << std::endl;
#endif
offset += ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ;
uint32_t edata_size = 0 ;
edata_size += ((uint32_t)edata[offset+0]) << 0 ;
edata_size += ((uint32_t)edata[offset+1]) << 8 ;
edata_size += ((uint32_t)edata[offset+2]) << 16 ;
edata_size += ((uint32_t)edata[offset+3]) << 24 ;
if(edata_size + ENCRYPTED_FT_EDATA_SIZE + ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_HEADER_SIZE != encrypted_item->data_size)
{
FTSERVER_ERROR() << " ERROR: encrypted data size is " << edata_size << ", should be " << encrypted_item->data_size - (ENCRYPTED_FT_EDATA_SIZE + ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_HEADER_SIZE ) << std::endl;
return false ;
}
offset += ENCRYPTED_FT_EDATA_SIZE ;
uint32_t clear_item_offset = offset ;
uint32_t authentication_tag_offset = offset + edata_size ;
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << " authen. tag : " << RsUtil::BinToHex(&edata[authentication_tag_offset],ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE) << std::endl;
#endif
bool result ;
if(edata[2] == ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305)
result = librs::crypto::AEAD_chacha20_poly1305(encryption_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],false) ;
else if(edata[2] == ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256)
result = librs::crypto::AEAD_chacha20_sha256 (encryption_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],false) ;
else
return false ;
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << " authen. result : " << result << std::endl;
FTSERVER_DEBUG() << " decrypted daya : " << RsUtil::BinToHex(&edata[clear_item_offset],std::min(50u,edata_size)) << "(...)" << std::endl;
#endif
if(!result)
{
FTSERVER_ERROR() << "(EE) decryption/authentication went wrong." << std::endl;
return false ;
}
decrypted_item = deserialiseItem(&edata[clear_item_offset],edata_size) ;
if(decrypted_item == NULL)
return false ;
return true ;
}
bool ftServer::encryptHash(const RsFileHash& hash, RsFileHash& hash_of_hash)
{
hash_of_hash = RsDirUtil::sha1sum(hash.toByteArray(),hash.SIZE_IN_BYTES);
return true ;
}
bool ftServer::findEncryptedHash(const RsPeerId& virtual_peer_id, RsFileHash& encrypted_hash)
{
RS_STACK_MUTEX(srvMutex);
std::map<RsPeerId,RsFileHash>::const_iterator it = mEncryptedPeerIds.find(virtual_peer_id) ;
if(it != mEncryptedPeerIds.end())
{
encrypted_hash = it->second ;
return true ;
}
else
return false ;
}
bool ftServer::findRealHash(const RsFileHash& hash, RsFileHash& real_hash)
{
RS_STACK_MUTEX(srvMutex);
std::map<RsFileHash,RsFileHash>::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. // Dont delete the item. The client (p3turtle) is doing it after calling this.
// //
void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i, void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
@ -991,6 +1375,33 @@ void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
const RsPeerId& virtual_peer_id, const RsPeerId& virtual_peer_id,
RsTurtleGenericTunnelItem::Direction direction) RsTurtleGenericTunnelItem::Direction direction)
{ {
if(i->PacketSubType() == RS_TURTLE_SUBTYPE_GENERIC_DATA)
{
#ifdef SERVER_DEBUG
FTSERVER_DEBUG() << "Received encrypted data item. Trying to decrypt" << std::endl;
#endif
RsFileHash real_hash ;
if(!findRealHash(hash,real_hash))
{
FTSERVER_ERROR() << "(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<RsTurtleGenericDataItem *>(i),real_hash,decrypted_item))
{
FTSERVER_ERROR() << "(EE) decryption error." << std::endl;
return ;
}
receiveTurtleData(decrypted_item, real_hash, virtual_peer_id,direction) ;
delete decrypted_item ;
return ;
}
switch(i->PacketSubType()) switch(i->PacketSubType())
{ {
case RS_TURTLE_SUBTYPE_FILE_REQUEST: case RS_TURTLE_SUBTYPE_FILE_REQUEST:
@ -999,7 +1410,7 @@ void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
if (item) if (item)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::receiveTurtleData(): received file data request for " << hash << " from peer " << virtual_peer_id << std::endl; FTSERVER_DEBUG() << "ftServer::receiveTurtleData(): received file data request for " << hash << " from peer " << virtual_peer_id << std::endl;
#endif #endif
getMultiplexer()->recvDataRequest(virtual_peer_id,hash,0,item->chunk_offset,item->chunk_size) ; getMultiplexer()->recvDataRequest(virtual_peer_id,hash,0,item->chunk_offset,item->chunk_size) ;
} }
@ -1012,7 +1423,7 @@ void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
if (item) if (item)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::receiveTurtleData(): received file data for " << hash << " from peer " << virtual_peer_id << std::endl; FTSERVER_DEBUG() << "ftServer::receiveTurtleData(): received file data for " << hash << " from peer " << virtual_peer_id << std::endl;
#endif #endif
getMultiplexer()->recvData(virtual_peer_id,hash,0,item->chunk_offset,item->chunk_size,item->chunk_data) ; getMultiplexer()->recvData(virtual_peer_id,hash,0,item->chunk_offset,item->chunk_size,item->chunk_data) ;
@ -1028,7 +1439,7 @@ void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
if (item) if (item)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::receiveTurtleData(): received chunk map for hash " << hash << " from peer " << virtual_peer_id << std::endl; FTSERVER_DEBUG() << "ftServer::receiveTurtleData(): received chunk map for hash " << hash << " from peer " << virtual_peer_id << std::endl;
#endif #endif
getMultiplexer()->recvChunkMap(virtual_peer_id,hash,item->compressed_map,direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ; getMultiplexer()->recvChunkMap(virtual_peer_id,hash,item->compressed_map,direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ;
} }
@ -1039,7 +1450,7 @@ void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
{ {
//RsTurtleFileMapRequestItem *item = dynamic_cast<RsTurtleFileMapRequestItem *>(i) ; //RsTurtleFileMapRequestItem *item = dynamic_cast<RsTurtleFileMapRequestItem *>(i) ;
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::receiveTurtleData(): received chunkmap request for hash " << hash << " from peer " << virtual_peer_id << std::endl; FTSERVER_DEBUG() << "ftServer::receiveTurtleData(): received chunkmap request for hash " << hash << " from peer " << virtual_peer_id << std::endl;
#endif #endif
getMultiplexer()->recvChunkMapRequest(virtual_peer_id,hash,direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ; getMultiplexer()->recvChunkMapRequest(virtual_peer_id,hash,direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ;
} }
@ -1051,7 +1462,7 @@ void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
if (item) if (item)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::receiveTurtleData(): received single chunk CRC for hash " << hash << " from peer " << virtual_peer_id << std::endl; FTSERVER_DEBUG() << "ftServer::receiveTurtleData(): received single chunk CRC for hash " << hash << " from peer " << virtual_peer_id << std::endl;
#endif #endif
getMultiplexer()->recvSingleChunkCRC(virtual_peer_id,hash,item->chunk_number,item->check_sum) ; getMultiplexer()->recvSingleChunkCRC(virtual_peer_id,hash,item->chunk_number,item->check_sum) ;
} }
@ -1064,14 +1475,14 @@ void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
if (item) if (item)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::receiveTurtleData(): received single chunk CRC request for hash " << hash << " from peer " << virtual_peer_id << std::endl; FTSERVER_DEBUG() << "ftServer::receiveTurtleData(): received single chunk CRC request for hash " << hash << " from peer " << virtual_peer_id << std::endl;
#endif #endif
getMultiplexer()->recvSingleChunkCRCRequest(virtual_peer_id,hash,item->chunk_number) ; getMultiplexer()->recvSingleChunkCRCRequest(virtual_peer_id,hash,item->chunk_number) ;
} }
} }
break ; break ;
default: default:
std::cerr << "WARNING: Unknown packet type received: sub_id=" << reinterpret_cast<void*>(i->PacketSubType()) << ". Is somebody trying to poison you ?" << std::endl ; FTSERVER_ERROR() << "WARNING: Unknown packet type received: sub_id=" << reinterpret_cast<void*>(i->PacketSubType()) << ". Is somebody trying to poison you ?" << std::endl ;
} }
} }
@ -1107,9 +1518,6 @@ int ftServer::handleIncoming()
int nhandled = 0 ; int nhandled = 0 ;
RsItem *item = NULL ; RsItem *item = NULL ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::handleIncoming() " << std::endl;
#endif
while(NULL != (item = recvItem())) while(NULL != (item = recvItem()))
{ {
@ -1123,7 +1531,7 @@ int ftServer::handleIncoming()
if (f) if (f)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::handleIncoming: received data request for hash " << f->file.hash << ", offset=" << f->fileoffset << ", chunk size=" << f->chunksize << std::endl; FTSERVER_DEBUG() << "ftServer::handleIncoming: received data request for hash " << f->file.hash << ", offset=" << f->fileoffset << ", chunk size=" << f->chunksize << std::endl;
#endif #endif
mFtDataplex->recvDataRequest(f->PeerId(), f->file.hash, f->file.filesize, f->fileoffset, f->chunksize); mFtDataplex->recvDataRequest(f->PeerId(), f->file.hash, f->file.filesize, f->fileoffset, f->chunksize);
} }
@ -1136,7 +1544,7 @@ int ftServer::handleIncoming()
if (f) if (f)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::handleIncoming: received data for hash " << f->fd.file.hash << ", offset=" << f->fd.file_offset << ", chunk size=" << f->fd.binData.bin_len << std::endl; FTSERVER_DEBUG() << "ftServer::handleIncoming: received data for hash " << f->fd.file.hash << ", offset=" << f->fd.file_offset << ", chunk size=" << f->fd.binData.bin_len << std::endl;
#endif #endif
mFtDataplex->recvData(f->PeerId(), f->fd.file.hash, f->fd.file.filesize, f->fd.file_offset, f->fd.binData.bin_len, f->fd.binData.bin_data); mFtDataplex->recvData(f->PeerId(), f->fd.file.hash, f->fd.file.filesize, f->fd.file_offset, f->fd.binData.bin_len, f->fd.binData.bin_data);
@ -1153,7 +1561,7 @@ int ftServer::handleIncoming()
if (f) if (f)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::handleIncoming: received chunkmap request for hash " << f->hash << ", client=" << f->is_client << std::endl; FTSERVER_DEBUG() << "ftServer::handleIncoming: received chunkmap request for hash " << f->hash << ", client=" << f->is_client << std::endl;
#endif #endif
mFtDataplex->recvChunkMapRequest(f->PeerId(), f->hash,f->is_client) ; mFtDataplex->recvChunkMapRequest(f->PeerId(), f->hash,f->is_client) ;
} }
@ -1166,7 +1574,7 @@ int ftServer::handleIncoming()
if (f) if (f)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::handleIncoming: received chunkmap for hash " << f->hash << ", client=" << f->is_client << /*", map=" << f->compressed_map <<*/ std::endl; FTSERVER_DEBUG() << "ftServer::handleIncoming: received chunkmap for hash " << f->hash << ", client=" << f->is_client << /*", map=" << f->compressed_map <<*/ std::endl;
#endif #endif
mFtDataplex->recvChunkMap(f->PeerId(), f->hash,f->compressed_map,f->is_client) ; mFtDataplex->recvChunkMap(f->PeerId(), f->hash,f->compressed_map,f->is_client) ;
} }
@ -1179,7 +1587,7 @@ int ftServer::handleIncoming()
if (f) if (f)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::handleIncoming: received single chunk crc req for hash " << f->hash << ", chunk number=" << f->chunk_number << std::endl; FTSERVER_DEBUG() << "ftServer::handleIncoming: received single chunk crc req for hash " << f->hash << ", chunk number=" << f->chunk_number << std::endl;
#endif #endif
mFtDataplex->recvSingleChunkCRCRequest(f->PeerId(), f->hash,f->chunk_number) ; mFtDataplex->recvSingleChunkCRCRequest(f->PeerId(), f->hash,f->chunk_number) ;
} }
@ -1192,7 +1600,7 @@ int ftServer::handleIncoming()
if (f) if (f)
{ {
#ifdef SERVER_DEBUG #ifdef SERVER_DEBUG
std::cerr << "ftServer::handleIncoming: received single chunk crc req for hash " << f->hash << ", chunk number=" << f->chunk_number << ", checksum = " << f->check_sum << std::endl; FTSERVER_DEBUG() << "ftServer::handleIncoming: received single chunk crc req for hash " << f->hash << ", chunk number=" << f->chunk_number << ", checksum = " << f->check_sum << std::endl;
#endif #endif
mFtDataplex->recvSingleChunkCRC(f->PeerId(), f->hash,f->chunk_number,f->check_sum); mFtDataplex->recvSingleChunkCRC(f->PeerId(), f->hash,f->chunk_number,f->check_sum);
} }
@ -1211,7 +1619,7 @@ int ftServer::handleIncoming()
********************************** **********************************
*********************************/ *********************************/
/***************************** CONFIG ****************************/ /***************************** CONFIG ****************************/
bool ftServer::addConfiguration(p3ConfigMgr *cfgmgr) bool ftServer::addConfiguration(p3ConfigMgr *cfgmgr)
{ {

View file

@ -135,7 +135,8 @@ public:
virtual FileChunksInfo::ChunkStrategy defaultChunkStrategy() ; virtual FileChunksInfo::ChunkStrategy defaultChunkStrategy() ;
virtual uint32_t freeDiskSpaceLimit() const ; virtual uint32_t freeDiskSpaceLimit() const ;
virtual void setFreeDiskSpaceLimit(uint32_t size_in_mb) ; virtual void setFreeDiskSpaceLimit(uint32_t size_in_mb) ;
virtual void setDefaultEncryptionPolicy(uint32_t policy) ; // RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT/PERMISSIVE
virtual uint32_t defaultEncryptionPolicy() ;
/*** /***
* Control of Downloads Priority. * Control of Downloads Priority.
@ -156,6 +157,7 @@ public:
virtual bool FileDetails(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info); virtual bool FileDetails(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info);
virtual bool FileDownloadChunksDetails(const RsFileHash& hash,FileChunksInfo& info) ; virtual bool FileDownloadChunksDetails(const RsFileHash& hash,FileChunksInfo& info) ;
virtual bool FileUploadChunksDetails(const RsFileHash& hash,const RsPeerId& peer_id,CompressedChunkMap& map) ; virtual bool FileUploadChunksDetails(const RsFileHash& hash,const RsPeerId& peer_id,CompressedChunkMap& map) ;
virtual bool isEncryptedSource(const RsPeerId& virtual_peer_id) ;
/*** /***
@ -200,7 +202,7 @@ public:
virtual std::string getPartialsDirectory(); virtual std::string getPartialsDirectory();
virtual bool getSharedDirectories(std::list<SharedDirInfo> &dirs); virtual bool getSharedDirectories(std::list<SharedDirInfo> &dirs);
virtual bool setSharedDirectories(std::list<SharedDirInfo> &dirs); virtual bool setSharedDirectories(const std::list<SharedDirInfo> &dirs);
virtual bool addSharedDirectory(const SharedDirInfo& dir); virtual bool addSharedDirectory(const SharedDirInfo& dir);
virtual bool updateShareFlags(const SharedDirInfo& dir); // updates the flags. The directory should already exist ! virtual bool updateShareFlags(const SharedDirInfo& dir); // updates the flags. The directory should already exist !
virtual bool removeSharedDirectory(std::string dir); virtual bool removeSharedDirectory(std::string dir);
@ -217,6 +219,8 @@ public:
/*************** Data Transfer Interface ***********************/ /*************** Data Transfer Interface ***********************/
/***************************************************************/ /***************************************************************/
public: public:
virtual bool activateTunnels(const RsFileHash& hash,uint32_t default_encryption_policy,TransferRequestFlags flags,bool onoff);
virtual bool sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data); virtual bool sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data);
virtual bool sendDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize); virtual bool sendDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize);
virtual bool sendChunkMapRequest(const RsPeerId& peer_id,const RsFileHash& hash,bool is_client) ; virtual bool sendChunkMapRequest(const RsPeerId& peer_id,const RsFileHash& hash,bool is_client) ;
@ -224,6 +228,11 @@ public:
virtual bool sendSingleChunkCRCRequest(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_number) ; virtual bool sendSingleChunkCRCRequest(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_number) ;
virtual bool sendSingleChunkCRC(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_number,const Sha1CheckSum& crc) ; virtual bool sendSingleChunkCRC(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_number,const Sha1CheckSum& crc) ;
static void deriveEncryptionKey(const RsFileHash& hash, uint8_t *key);
bool encryptItem(RsTurtleGenericTunnelItem *clear_item,const RsFileHash& hash,RsTurtleGenericDataItem *& encrypted_item);
bool decryptItem(RsTurtleGenericDataItem *encrypted_item, const RsFileHash& hash, RsTurtleGenericTunnelItem *&decrypted_item);
/*************** Internal Transfer Fns *************************/ /*************** Internal Transfer Fns *************************/
virtual int tick(); virtual int tick();
@ -237,6 +246,22 @@ protected:
int handleIncoming() ; int handleIncoming() ;
bool handleCacheData() ; 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);
bool findEncryptedHash(const RsPeerId& virtual_peer_id, RsFileHash& encrypted_hash);
bool encryptHash(const RsFileHash& hash, RsFileHash& hash_of_hash);
private: private:
/**** INTERNAL FUNCTIONS ***/ /**** INTERNAL FUNCTIONS ***/
@ -261,6 +286,9 @@ private:
std::string mConfigPath; std::string mConfigPath;
std::string mDownloadPath; std::string mDownloadPath;
std::string mPartialsPath; std::string mPartialsPath;
std::map<RsFileHash,RsFileHash> mEncryptedHashes ; // This map is such that sha1(it->second) = it->first
std::map<RsPeerId,RsFileHash> mEncryptedPeerIds ; // This map holds the hash to be used with each peer id
}; };

View file

@ -30,7 +30,7 @@
#include <serialiser/itempriorities.h> #include <serialiser/itempriorities.h>
#include <ft/ftturtlefiletransferitem.h> #include <ft/ftturtlefiletransferitem.h>
uint32_t RsTurtleFileRequestItem::serial_size() uint32_t RsTurtleFileRequestItem::serial_size() const
{ {
uint32_t s = 0 ; uint32_t s = 0 ;
@ -42,7 +42,7 @@ uint32_t RsTurtleFileRequestItem::serial_size()
return s ; return s ;
} }
uint32_t RsTurtleFileDataItem::serial_size() uint32_t RsTurtleFileDataItem::serial_size() const
{ {
uint32_t s = 0 ; uint32_t s = 0 ;
@ -55,7 +55,7 @@ uint32_t RsTurtleFileDataItem::serial_size()
return s ; return s ;
} }
uint32_t RsTurtleFileMapRequestItem::serial_size() uint32_t RsTurtleFileMapRequestItem::serial_size() const
{ {
uint32_t s = 0 ; uint32_t s = 0 ;
@ -66,7 +66,7 @@ uint32_t RsTurtleFileMapRequestItem::serial_size()
return s ; return s ;
} }
uint32_t RsTurtleFileMapItem::serial_size() uint32_t RsTurtleFileMapItem::serial_size() const
{ {
uint32_t s = 0 ; uint32_t s = 0 ;
@ -80,7 +80,7 @@ uint32_t RsTurtleFileMapItem::serial_size()
return s ; return s ;
} }
uint32_t RsTurtleChunkCrcItem::serial_size() uint32_t RsTurtleChunkCrcItem::serial_size() const
{ {
uint32_t s = 0 ; uint32_t s = 0 ;
@ -91,7 +91,7 @@ uint32_t RsTurtleChunkCrcItem::serial_size()
return s ; return s ;
} }
uint32_t RsTurtleChunkCrcRequestItem::serial_size() uint32_t RsTurtleChunkCrcRequestItem::serial_size() const
{ {
uint32_t s = 0 ; uint32_t s = 0 ;
@ -101,7 +101,7 @@ uint32_t RsTurtleChunkCrcRequestItem::serial_size()
return s ; return s ;
} }
bool RsTurtleFileMapRequestItem::serialize(void *data,uint32_t& pktsize) bool RsTurtleFileMapRequestItem::serialize(void *data,uint32_t& pktsize) const
{ {
uint32_t tlvsize = serial_size(); uint32_t tlvsize = serial_size();
uint32_t offset = 0; uint32_t offset = 0;
@ -134,7 +134,7 @@ bool RsTurtleFileMapRequestItem::serialize(void *data,uint32_t& pktsize)
return ok; return ok;
} }
bool RsTurtleFileMapItem::serialize(void *data,uint32_t& pktsize) bool RsTurtleFileMapItem::serialize(void *data,uint32_t& pktsize) const
{ {
uint32_t tlvsize = serial_size(); uint32_t tlvsize = serial_size();
uint32_t offset = 0; uint32_t offset = 0;
@ -171,7 +171,7 @@ bool RsTurtleFileMapItem::serialize(void *data,uint32_t& pktsize)
return ok; return ok;
} }
bool RsTurtleChunkCrcRequestItem::serialize(void *data,uint32_t& pktsize) bool RsTurtleChunkCrcRequestItem::serialize(void *data,uint32_t& pktsize) const
{ {
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
std::cerr << "RsTurtleChunkCrcRequestItem::serialize(): serializing packet:" << std::endl ; std::cerr << "RsTurtleChunkCrcRequestItem::serialize(): serializing packet:" << std::endl ;
@ -206,7 +206,7 @@ bool RsTurtleChunkCrcRequestItem::serialize(void *data,uint32_t& pktsize)
return ok; return ok;
} }
bool RsTurtleChunkCrcItem::serialize(void *data,uint32_t& pktsize) bool RsTurtleChunkCrcItem::serialize(void *data,uint32_t& pktsize) const
{ {
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
std::cerr << "RsTurtleChunkCrcRequestItem::serialize(): serializing packet:" << std::endl ; std::cerr << "RsTurtleChunkCrcRequestItem::serialize(): serializing packet:" << std::endl ;
@ -345,7 +345,7 @@ RsTurtleChunkCrcRequestItem::RsTurtleChunkCrcRequestItem(void *data,uint32_t pkt
throw std::runtime_error("Unknown error while deserializing.") ; throw std::runtime_error("Unknown error while deserializing.") ;
#endif #endif
} }
bool RsTurtleFileRequestItem::serialize(void *data,uint32_t& pktsize) bool RsTurtleFileRequestItem::serialize(void *data,uint32_t& pktsize) const
{ {
uint32_t tlvsize = serial_size(); uint32_t tlvsize = serial_size();
uint32_t offset = 0; uint32_t offset = 0;
@ -459,7 +459,7 @@ RsTurtleFileDataItem::RsTurtleFileDataItem(void *data,uint32_t pktsize)
#endif #endif
} }
bool RsTurtleFileDataItem::serialize(void *data,uint32_t& pktsize) bool RsTurtleFileDataItem::serialize(void *data,uint32_t& pktsize) const
{ {
uint32_t tlvsize = serial_size(); uint32_t tlvsize = serial_size();
uint32_t offset = 0; uint32_t offset = 0;

View file

@ -44,8 +44,8 @@ class RsTurtleFileRequestItem: public RsTurtleGenericTunnelItem
virtual std::ostream& print(std::ostream& o, uint16_t) ; virtual std::ostream& print(std::ostream& o, uint16_t) ;
protected: protected:
virtual bool serialize(void *data,uint32_t& size) ; virtual bool serialize(void *data,uint32_t& size) const;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() const;
}; };
class RsTurtleFileDataItem: public RsTurtleGenericTunnelItem class RsTurtleFileDataItem: public RsTurtleGenericTunnelItem
@ -64,8 +64,8 @@ class RsTurtleFileDataItem: public RsTurtleGenericTunnelItem
virtual std::ostream& print(std::ostream& o, uint16_t) ; virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ; virtual bool serialize(void *data,uint32_t& size) const;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() const;
}; };
class RsTurtleFileMapRequestItem: public RsTurtleGenericTunnelItem class RsTurtleFileMapRequestItem: public RsTurtleGenericTunnelItem
@ -78,8 +78,8 @@ class RsTurtleFileMapRequestItem: public RsTurtleGenericTunnelItem
virtual std::ostream& print(std::ostream& o, uint16_t) ; virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ; virtual bool serialize(void *data,uint32_t& size) const;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() const;
}; };
class RsTurtleFileMapItem: public RsTurtleGenericTunnelItem class RsTurtleFileMapItem: public RsTurtleGenericTunnelItem
@ -96,8 +96,8 @@ class RsTurtleFileMapItem: public RsTurtleGenericTunnelItem
virtual std::ostream& print(std::ostream& o, uint16_t) ; virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ; virtual bool serialize(void *data,uint32_t& size) const;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() const;
}; };
class RsTurtleChunkCrcRequestItem: public RsTurtleGenericTunnelItem class RsTurtleChunkCrcRequestItem: public RsTurtleGenericTunnelItem
@ -113,8 +113,8 @@ class RsTurtleChunkCrcRequestItem: public RsTurtleGenericTunnelItem
virtual std::ostream& print(std::ostream& o, uint16_t) ; virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ; virtual bool serialize(void *data,uint32_t& size) const;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() const;
}; };
class RsTurtleChunkCrcItem: public RsTurtleGenericTunnelItem class RsTurtleChunkCrcItem: public RsTurtleGenericTunnelItem
@ -130,6 +130,6 @@ class RsTurtleChunkCrcItem: public RsTurtleGenericTunnelItem
Sha1CheckSum check_sum ; Sha1CheckSum check_sum ;
virtual std::ostream& print(std::ostream& o, uint16_t) ; virtual std::ostream& print(std::ostream& o, uint16_t) ;
virtual bool serialize(void *data,uint32_t& size) ; virtual bool serialize(void *data,uint32_t& size) const;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() const;
}; };

View file

@ -381,6 +381,8 @@ HEADERS += ft/ftchunkmap.h \
ft/fttransfermodule.h \ ft/fttransfermodule.h \
ft/ftturtlefiletransferitem.h ft/ftturtlefiletransferitem.h
HEADERS += crypto/chacha20.h
HEADERS += directory_updater.h \ HEADERS += directory_updater.h \
directory_list.h \ directory_list.h \
p3filelists.h p3filelists.h
@ -539,6 +541,8 @@ SOURCES += ft/ftchunkmap.cc \
ft/fttransfermodule.cc \ ft/fttransfermodule.cc \
ft/ftturtlefiletransferitem.cc ft/ftturtlefiletransferitem.cc
SOURCES += crypto/chacha20.cpp
SOURCES += chat/distantchat.cc \ SOURCES += chat/distantchat.cc \
chat/p3chatservice.cc \ chat/p3chatservice.cc \
chat/distributedchat.cc \ chat/distributedchat.cc \

View file

@ -43,6 +43,9 @@ const uint32_t RS_FILE_CTRL_PAUSE = 0x00000100;
const uint32_t RS_FILE_CTRL_START = 0x00000200; const uint32_t RS_FILE_CTRL_START = 0x00000200;
const uint32_t RS_FILE_CTRL_FORCE_CHECK = 0x00000400; const uint32_t RS_FILE_CTRL_FORCE_CHECK = 0x00000400;
const uint32_t RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT = 0x00000001 ;
const uint32_t RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE = 0x00000002 ;
const uint32_t RS_FILE_RATE_TRICKLE = 0x00000001; const uint32_t RS_FILE_RATE_TRICKLE = 0x00000001;
const uint32_t RS_FILE_RATE_SLOW = 0x00000002; const uint32_t RS_FILE_RATE_SLOW = 0x00000002;
const uint32_t RS_FILE_RATE_STANDARD = 0x00000003; const uint32_t RS_FILE_RATE_STANDARD = 0x00000003;
@ -73,13 +76,16 @@ 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_NETWORK_WIDE ( 0x00000080 );// anonymously shared over network
const FileSearchFlags RS_FILE_HINTS_BROWSABLE ( 0x00000100 );// browsable by friends 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_SEARCHABLE ( 0x00000200 );// browsable by friends
const FileSearchFlags RS_FILE_HINTS_PERMISSION_MASK ( 0x00000380 );// OR of the last tree flags. Used to filter out.
// Flags used when requesting a transfer // 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_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_UNENCRYPTED ( 0x00000100 ); // Asks for no 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_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_EXTRA ( 0x00000800 );
const TransferRequestFlags RS_FILE_REQ_MEDIA ( 0x00001000 ); const TransferRequestFlags RS_FILE_REQ_MEDIA ( 0x00001000 );
const TransferRequestFlags RS_FILE_REQ_BACKGROUND ( 0x00002000 ); // To download slowly. const TransferRequestFlags RS_FILE_REQ_BACKGROUND ( 0x00002000 ); // To download slowly.
@ -96,7 +102,7 @@ struct SharedDirInfo
{ {
std::string filename ; std::string filename ;
std::string virtualname ; std::string virtualname ;
FileStorageFlags shareflags ; // DIR_FLAGS_NETWORK_WIDE_OTHERS | DIR_FLAGS_BROWSABLE_GROUPS | ... FileStorageFlags shareflags ; // combnation of DIR_FLAGS_ANONYMOUS_DOWNLOAD | DIR_FLAGS_BROWSABLE | ...
std::list<RsNodeGroupId> parent_groups ; std::list<RsNodeGroupId> parent_groups ;
}; };
@ -141,6 +147,8 @@ class RsFiles
virtual void setFreeDiskSpaceLimit(uint32_t size_in_mb) =0; virtual void setFreeDiskSpaceLimit(uint32_t size_in_mb) =0;
virtual bool FileControl(const RsFileHash& hash, uint32_t flags) = 0; virtual bool FileControl(const RsFileHash& hash, uint32_t flags) = 0;
virtual bool FileClearCompleted() = 0; virtual bool FileClearCompleted() = 0;
virtual void setDefaultEncryptionPolicy(uint32_t policy)=0 ; // RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT/PERMISSIVE
virtual uint32_t defaultEncryptionPolicy()=0 ;
/*** /***
* Control of Downloads Priority. * Control of Downloads Priority.
@ -159,6 +167,7 @@ class RsFiles
virtual void FileDownloads(std::list<RsFileHash> &hashs) = 0; virtual void FileDownloads(std::list<RsFileHash> &hashs) = 0;
virtual bool FileUploads(std::list<RsFileHash> &hashs) = 0; virtual bool FileUploads(std::list<RsFileHash> &hashs) = 0;
virtual bool FileDetails(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) = 0; virtual bool FileDetails(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) = 0;
virtual bool isEncryptedSource(const RsPeerId& virtual_peer_id) =0;
/// Gives chunk details about the downloaded file with given hash. /// Gives chunk details about the downloaded file with given hash.
virtual bool FileDownloadChunksDetails(const RsFileHash& hash,FileChunksInfo& info) = 0 ; virtual bool FileDownloadChunksDetails(const RsFileHash& hash,FileChunksInfo& info) = 0 ;
@ -209,7 +218,8 @@ class RsFiles
virtual std::string getDownloadDirectory() = 0; virtual std::string getDownloadDirectory() = 0;
virtual std::string getPartialsDirectory() = 0; virtual std::string getPartialsDirectory() = 0;
virtual bool getSharedDirectories(std::list<SharedDirInfo> &dirs) = 0; virtual bool getSharedDirectories(std::list<SharedDirInfo>& dirs) = 0;
virtual bool setSharedDirectories(const std::list<SharedDirInfo>& dirs) = 0;
virtual bool addSharedDirectory(const SharedDirInfo& dir) = 0; virtual bool addSharedDirectory(const SharedDirInfo& dir) = 0;
virtual bool updateShareFlags(const SharedDirInfo& dir) = 0; // updates the flags. The directory should already exist ! virtual bool updateShareFlags(const SharedDirInfo& dir) = 0; // updates the flags. The directory should already exist !
virtual bool removeSharedDirectory(std::string dir) = 0; virtual bool removeSharedDirectory(std::string dir) = 0;

View file

@ -155,12 +155,13 @@ const FileStorageFlags DIR_FLAGS_PARENT ( 0x0001 );
const FileStorageFlags DIR_FLAGS_DETAILS ( 0x0002 ); // apparently unused const FileStorageFlags DIR_FLAGS_DETAILS ( 0x0002 ); // apparently unused
const FileStorageFlags DIR_FLAGS_CHILDREN ( 0x0004 ); // apparently unused const FileStorageFlags DIR_FLAGS_CHILDREN ( 0x0004 ); // apparently unused
const FileStorageFlags DIR_FLAGS_NETWORK_WIDE_OTHERS ( 0x0080 ); // Flags for directory sharing permissions. The last const FileStorageFlags DIR_FLAGS_ANONYMOUS_DOWNLOAD ( 0x0080 ); // Flags for directory sharing permissions. The last
const FileStorageFlags DIR_FLAGS_BROWSABLE_OTHERS ( 0x0100 ); // one should be the OR of the all four flags. //const FileStorageFlags DIR_FLAGS_BROWSABLE_OTHERS ( 0x0100 ); // one should be the OR of the all four flags.
const FileStorageFlags DIR_FLAGS_NETWORK_WIDE_GROUPS ( 0x0200 ); //const FileStorageFlags DIR_FLAGS_NETWORK_WIDE_GROUPS ( 0x0200 );
const FileStorageFlags DIR_FLAGS_BROWSABLE_GROUPS ( 0x0400 ); const FileStorageFlags DIR_FLAGS_BROWSABLE ( 0x0400 );
const FileStorageFlags DIR_FLAGS_PERMISSIONS_MASK ( DIR_FLAGS_NETWORK_WIDE_OTHERS | DIR_FLAGS_BROWSABLE_OTHERS const FileStorageFlags DIR_FLAGS_ANONYMOUS_SEARCH ( 0x0800 );
| DIR_FLAGS_NETWORK_WIDE_GROUPS | DIR_FLAGS_BROWSABLE_GROUPS ); const FileStorageFlags DIR_FLAGS_PERMISSIONS_MASK ( DIR_FLAGS_ANONYMOUS_DOWNLOAD | /*DIR_FLAGS_BROWSABLE_OTHERS
DIR_FLAGS_NETWORK_WIDE_GROUPS*/ DIR_FLAGS_BROWSABLE | DIR_FLAGS_ANONYMOUS_SEARCH);
const FileStorageFlags DIR_FLAGS_LOCAL ( 0x1000 ); const FileStorageFlags DIR_FLAGS_LOCAL ( 0x1000 );
const FileStorageFlags DIR_FLAGS_REMOTE ( 0x2000 ); const FileStorageFlags DIR_FLAGS_REMOTE ( 0x2000 );

View file

@ -1359,7 +1359,7 @@ FileSearchFlags p3Peers::computePeerPermissionFlags(const RsPeerId& peer_ssl_id,
// very simple algorithm. // very simple algorithm.
// //
bool found = false ; bool found = directory_parent_groups.empty() ; // by default, empty list means browsable by everyone.
RsPgpId pgp_id = getGPGId(peer_ssl_id) ; RsPgpId pgp_id = getGPGId(peer_ssl_id) ;
for(std::list<RsNodeGroupId>::const_iterator it(directory_parent_groups.begin());it!=directory_parent_groups.end() && !found;++it) for(std::list<RsNodeGroupId>::const_iterator it(directory_parent_groups.begin());it!=directory_parent_groups.end() && !found;++it)
@ -1378,13 +1378,15 @@ FileSearchFlags p3Peers::computePeerPermissionFlags(const RsPeerId& peer_ssl_id,
// found = true ; // found = true ;
} }
bool network_wide = (share_flags & DIR_FLAGS_NETWORK_WIDE_OTHERS) ;//|| ( (share_flags & DIR_FLAGS_NETWORK_WIDE_GROUPS) && found) ; bool network_wide = (share_flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD) ;//|| ( (share_flags & DIR_FLAGS_NETWORK_WIDE_GROUPS) && found) ;
bool browsable = (share_flags & DIR_FLAGS_BROWSABLE_OTHERS) || ( (share_flags & DIR_FLAGS_BROWSABLE_GROUPS) && found) ; bool browsable = (share_flags & DIR_FLAGS_BROWSABLE) && found ;
bool searchable = (share_flags & DIR_FLAGS_ANONYMOUS_SEARCH) ;
FileSearchFlags final_flags ; FileSearchFlags final_flags ;
if(network_wide) final_flags |= RS_FILE_HINTS_NETWORK_WIDE ; if(network_wide) final_flags |= RS_FILE_HINTS_NETWORK_WIDE ;
if(browsable ) final_flags |= RS_FILE_HINTS_BROWSABLE ; if(browsable ) final_flags |= RS_FILE_HINTS_BROWSABLE ;
if(searchable ) final_flags |= RS_FILE_HINTS_SEARCHABLE ;
return final_flags ; return final_flags ;
} }

View file

@ -1729,7 +1729,7 @@ void RsTurtleStringSearchRequestItem::performLocalSearch(std::list<TurtleFileInf
std::cerr << "Performing rsFiles->search()" << std::endl ; std::cerr << "Performing rsFiles->search()" << std::endl ;
#endif #endif
// now, search! // now, search!
rsFiles->SearchKeywords(words, initialResults,RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_NETWORK_WIDE,PeerId()); rsFiles->SearchKeywords(words, initialResults,RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_SEARCHABLE,PeerId());
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
std::cerr << initialResults.size() << " matches found." << std::endl ; std::cerr << initialResults.size() << " matches found." << std::endl ;
@ -1767,7 +1767,7 @@ void RsTurtleRegExpSearchRequestItem::performLocalSearch(std::list<TurtleFileInf
return ; return ;
// now, search! // now, search!
rsFiles->SearchBoolExp(exp,initialResults,RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_NETWORK_WIDE,PeerId()); rsFiles->SearchBoolExp(exp,initialResults,RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_SEARCHABLE,PeerId());
result.clear() ; result.clear() ;

View file

@ -16,7 +16,7 @@
// ---------------------------------- Packet sizes -----------------------------------// // ---------------------------------- Packet sizes -----------------------------------//
// //
uint32_t RsTurtleStringSearchRequestItem::serial_size() uint32_t RsTurtleStringSearchRequestItem::serial_size() const
{ {
uint32_t s = 0 ; uint32_t s = 0 ;
@ -27,7 +27,7 @@ uint32_t RsTurtleStringSearchRequestItem::serial_size()
return s ; return s ;
} }
uint32_t RsTurtleRegExpSearchRequestItem::serial_size() uint32_t RsTurtleRegExpSearchRequestItem::serial_size() const
{ {
uint32_t s = 0 ; uint32_t s = 0 ;
@ -48,7 +48,7 @@ uint32_t RsTurtleRegExpSearchRequestItem::serial_size()
return s ; return s ;
} }
uint32_t RsTurtleSearchResultItem::serial_size() uint32_t RsTurtleSearchResultItem::serial_size()const
{ {
uint32_t s = 0 ; uint32_t s = 0 ;
@ -67,7 +67,7 @@ uint32_t RsTurtleSearchResultItem::serial_size()
return s ; return s ;
} }
uint32_t RsTurtleOpenTunnelItem::serial_size() uint32_t RsTurtleOpenTunnelItem::serial_size()const
{ {
uint32_t s = 0 ; uint32_t s = 0 ;
@ -80,7 +80,7 @@ uint32_t RsTurtleOpenTunnelItem::serial_size()
return s ; return s ;
} }
uint32_t RsTurtleTunnelOkItem::serial_size() uint32_t RsTurtleTunnelOkItem::serial_size() const
{ {
uint32_t s = 0 ; uint32_t s = 0 ;
@ -91,7 +91,7 @@ uint32_t RsTurtleTunnelOkItem::serial_size()
return s ; return s ;
} }
uint32_t RsTurtleGenericDataItem::serial_size() uint32_t RsTurtleGenericDataItem::serial_size() const
{ {
uint32_t s = 0 ; uint32_t s = 0 ;
@ -159,7 +159,7 @@ RsItem *RsTurtleSerialiser::deserialise(void *data, uint32_t *size)
} }
bool RsTurtleStringSearchRequestItem::serialize(void *data,uint32_t& pktsize) bool RsTurtleStringSearchRequestItem::serialize(void *data,uint32_t& pktsize) const
{ {
uint32_t tlvsize = serial_size(); uint32_t tlvsize = serial_size();
uint32_t offset = 0; uint32_t offset = 0;
@ -193,7 +193,7 @@ bool RsTurtleStringSearchRequestItem::serialize(void *data,uint32_t& pktsize)
return ok; return ok;
} }
bool RsTurtleRegExpSearchRequestItem::serialize(void *data,uint32_t& pktsize) bool RsTurtleRegExpSearchRequestItem::serialize(void *data,uint32_t& pktsize) const
{ {
uint32_t tlvsize = serial_size(); uint32_t tlvsize = serial_size();
uint32_t offset = 0; uint32_t offset = 0;
@ -313,7 +313,7 @@ RsTurtleRegExpSearchRequestItem::RsTurtleRegExpSearchRequestItem(void *data,uint
#endif #endif
} }
bool RsTurtleSearchResultItem::serialize(void *data,uint32_t& pktsize) bool RsTurtleSearchResultItem::serialize(void *data,uint32_t& pktsize) const
{ {
uint32_t tlvsize = serial_size(); uint32_t tlvsize = serial_size();
uint32_t offset = 0; uint32_t offset = 0;
@ -398,7 +398,7 @@ RsTurtleSearchResultItem::RsTurtleSearchResultItem(void *data,uint32_t pktsize)
#endif #endif
} }
bool RsTurtleOpenTunnelItem::serialize(void *data,uint32_t& pktsize) bool RsTurtleOpenTunnelItem::serialize(void *data,uint32_t& pktsize) const
{ {
uint32_t tlvsize = serial_size(); uint32_t tlvsize = serial_size();
uint32_t offset = 0; uint32_t offset = 0;
@ -464,7 +464,7 @@ RsTurtleOpenTunnelItem::RsTurtleOpenTunnelItem(void *data,uint32_t pktsize)
#endif #endif
} }
bool RsTurtleTunnelOkItem::serialize(void *data,uint32_t& pktsize) bool RsTurtleTunnelOkItem::serialize(void *data,uint32_t& pktsize) const
{ {
uint32_t tlvsize = serial_size(); uint32_t tlvsize = serial_size();
uint32_t offset = 0; uint32_t offset = 0;
@ -572,7 +572,7 @@ RsTurtleGenericDataItem::RsTurtleGenericDataItem(void *data,uint32_t pktsize)
#endif #endif
} }
bool RsTurtleGenericDataItem::serialize(void *data,uint32_t& pktsize) bool RsTurtleGenericDataItem::serialize(void *data,uint32_t& pktsize) const
{ {
uint32_t tlvsize = serial_size(); uint32_t tlvsize = serial_size();
uint32_t offset = 0; uint32_t offset = 0;

View file

@ -35,8 +35,8 @@ class RsTurtleItem: public RsItem
public: public:
RsTurtleItem(uint8_t turtle_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_TURTLE,turtle_subtype) {} RsTurtleItem(uint8_t turtle_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_TURTLE,turtle_subtype) {}
virtual bool serialize(void *data,uint32_t& size) = 0 ; // Isn't it better that items can serialize themselves ? virtual bool serialize(void *data,uint32_t& size) const = 0 ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() = 0 ; // deserialise is handled using a constructor virtual uint32_t serial_size() const = 0 ; // deserialise is handled using a constructor
virtual void clear() {} virtual void clear() {}
}; };
@ -63,8 +63,8 @@ class RsTurtleSearchResultItem: public RsTurtleItem
virtual std::ostream& print(std::ostream& o, uint16_t) ; virtual std::ostream& print(std::ostream& o, uint16_t) ;
protected: protected:
virtual bool serialize(void *data,uint32_t& size) ; virtual bool serialize(void *data,uint32_t& size) const ;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() const ;
}; };
class RsTurtleSearchRequestItem: public RsTurtleItem class RsTurtleSearchRequestItem: public RsTurtleItem
@ -92,8 +92,8 @@ class RsTurtleStringSearchRequestItem: public RsTurtleSearchRequestItem
virtual std::ostream& print(std::ostream& o, uint16_t) ; virtual std::ostream& print(std::ostream& o, uint16_t) ;
protected: protected:
virtual bool serialize(void *data,uint32_t& size) ; virtual bool serialize(void *data,uint32_t& size) const ;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() const ;
}; };
class RsTurtleRegExpSearchRequestItem: public RsTurtleSearchRequestItem class RsTurtleRegExpSearchRequestItem: public RsTurtleSearchRequestItem
@ -109,8 +109,8 @@ class RsTurtleRegExpSearchRequestItem: public RsTurtleSearchRequestItem
virtual std::ostream& print(std::ostream& o, uint16_t) ; virtual std::ostream& print(std::ostream& o, uint16_t) ;
protected: protected:
virtual bool serialize(void *data,uint32_t& size) ; virtual bool serialize(void *data,uint32_t& size) const ;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() const ;
}; };
/***********************************************************************************/ /***********************************************************************************/
@ -131,8 +131,8 @@ class RsTurtleOpenTunnelItem: public RsTurtleItem
virtual std::ostream& print(std::ostream& o, uint16_t) ; virtual std::ostream& print(std::ostream& o, uint16_t) ;
protected: protected:
virtual bool serialize(void *data,uint32_t& size) ; virtual bool serialize(void *data,uint32_t& size) const ;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() const ;
}; };
class RsTurtleTunnelOkItem: public RsTurtleItem class RsTurtleTunnelOkItem: public RsTurtleItem
@ -147,8 +147,8 @@ class RsTurtleTunnelOkItem: public RsTurtleItem
virtual std::ostream& print(std::ostream& o, uint16_t) ; virtual std::ostream& print(std::ostream& o, uint16_t) ;
protected: protected:
virtual bool serialize(void *data,uint32_t& size) ; virtual bool serialize(void *data,uint32_t& size) const ;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() const ;
}; };
/***********************************************************************************/ /***********************************************************************************/
@ -208,8 +208,8 @@ class RsTurtleGenericDataItem: public RsTurtleGenericTunnelItem
virtual std::ostream& print(std::ostream& o, uint16_t) ; virtual std::ostream& print(std::ostream& o, uint16_t) ;
protected: protected:
virtual bool serialize(void *data,uint32_t& size) ; virtual bool serialize(void *data,uint32_t& size) const ;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() const ;
}; };
/***********************************************************************************/ /***********************************************************************************/

View file

@ -1387,7 +1387,12 @@ QString TransfersDialog::getPeerName(const RsPeerId& id) const
// connect mgr). In such a case their id can suitably hold for a name. // connect mgr). In such a case their id can suitably hold for a name.
// //
if(res == "") if(res == "")
{
if(rsFiles->isEncryptedSource(id))
return tr("Anonymous end-to-end encrypted tunnel 0x")+QString::fromStdString(id.toStdString()).left(8) ;
else
return tr("Anonymous tunnel 0x")+QString::fromStdString(id.toStdString()).left(8) ; return tr("Anonymous tunnel 0x")+QString::fromStdString(id.toStdString()).left(8) ;
}
else else
return res ; return res ;
} }

View file

@ -235,7 +235,7 @@ void QuickStartWizard::on_pushButtonSharesAdd_clicked()
{ {
SharedDirInfo sdi ; SharedDirInfo sdi ;
sdi.filename = dir ; sdi.filename = dir ;
sdi.shareflags = DIR_FLAGS_BROWSABLE_OTHERS | DIR_FLAGS_NETWORK_WIDE_OTHERS ; sdi.shareflags = DIR_FLAGS_BROWSABLE | DIR_FLAGS_ANONYMOUS_DOWNLOAD ;
rsFiles->addSharedDirectory(sdi); rsFiles->addSharedDirectory(sdi);
@ -331,8 +331,8 @@ void QuickStartWizard::loadShare()
QCheckBox *cb1 = new QCheckBox ; QCheckBox *cb1 = new QCheckBox ;
QCheckBox *cb2 = new QCheckBox ; QCheckBox *cb2 = new QCheckBox ;
cb1->setChecked( (*it).shareflags & DIR_FLAGS_NETWORK_WIDE_OTHERS ) ; cb1->setChecked( (*it).shareflags & DIR_FLAGS_ANONYMOUS_DOWNLOAD ) ;
cb2->setChecked( (*it).shareflags & DIR_FLAGS_BROWSABLE_OTHERS ) ; cb2->setChecked( (*it).shareflags & DIR_FLAGS_BROWSABLE ) ;
cb1->setToolTip(tr("If checked, the share is anonymously shared to anybody.")) ; cb1->setToolTip(tr("If checked, the share is anonymously shared to anybody.")) ;
cb2->setToolTip(tr("If checked, the share is browsable by your friends.")) ; cb2->setToolTip(tr("If checked, the share is browsable by your friends.")) ;
@ -364,8 +364,8 @@ void QuickStartWizard::updateFlags(bool b)
{ {
std::cerr << "Looking for row=" << row << ", file=" << (*it).filename << ", flags=" << (*it).shareflags << std::endl ; std::cerr << "Looking for row=" << row << ", file=" << (*it).filename << ", flags=" << (*it).shareflags << std::endl ;
FileStorageFlags current_flags(0u) ; FileStorageFlags current_flags(0u) ;
current_flags |= (dynamic_cast<QCheckBox*>(ui.shareddirList->cellWidget(row,1)))->isChecked()? DIR_FLAGS_NETWORK_WIDE_OTHERS:(FileStorageFlags)0u ; current_flags |= (dynamic_cast<QCheckBox*>(ui.shareddirList->cellWidget(row,1)))->isChecked()? DIR_FLAGS_ANONYMOUS_DOWNLOAD:(FileStorageFlags)0u ;
current_flags |= (dynamic_cast<QCheckBox*>(ui.shareddirList->cellWidget(row,2)))->isChecked()? DIR_FLAGS_BROWSABLE_OTHERS :(FileStorageFlags)0u ; current_flags |= (dynamic_cast<QCheckBox*>(ui.shareddirList->cellWidget(row,2)))->isChecked()? DIR_FLAGS_BROWSABLE :(FileStorageFlags)0u ;
if( ((*it).shareflags ^ current_flags).toUInt32() ) if( ((*it).shareflags ^ current_flags).toUInt32() )
{ {

View file

@ -30,6 +30,7 @@
#include <gui/common/RsUrlHandler.h> #include <gui/common/RsUrlHandler.h>
#include <gui/common/FilesDefs.h> #include <gui/common/FilesDefs.h>
#include <gui/common/GroupDefs.h> #include <gui/common/GroupDefs.h>
#include <gui/gxs/GxsIdDetails.h>
#include "RemoteDirModel.h" #include "RemoteDirModel.h"
#include <retroshare/rsfiles.h> #include <retroshare/rsfiles.h>
#include <retroshare/rstypes.h> #include <retroshare/rstypes.h>
@ -216,16 +217,21 @@ QString RetroshareDirModel::getFlagsString(FileStorageFlags flags)
{ {
char str[11] = "- - -" ; char str[11] = "- - -" ;
if(flags & DIR_FLAGS_BROWSABLE_GROUPS) str[0] = 'B' ; if(flags & DIR_FLAGS_BROWSABLE) str[0] = 'B' ;
//if(flags & DIR_FLAGS_NETWORK_WIDE_GROUPS) str[3] = 'N' ; if(flags & DIR_FLAGS_ANONYMOUS_SEARCH) str[3] = 'S' ;
if(flags & DIR_FLAGS_BROWSABLE_OTHERS) str[3] = 'B' ; if(flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD) str[6] = 'N' ;
if(flags & DIR_FLAGS_NETWORK_WIDE_OTHERS) str[6] = 'N' ;
return QString(str) ; return QString(str) ;
} }
QString RetroshareDirModel::getGroupsString(const std::list<RsNodeGroupId>& group_ids) QString RetroshareDirModel::getGroupsString(FileStorageFlags flags,const std::list<RsNodeGroupId>& group_ids)
{ {
QString groups_str ; if(!(flags & DIR_FLAGS_BROWSABLE))
return QString();
if(group_ids.empty())
return tr("[All friend nodes]") ;
QString groups_str = tr("Only ");
RsGroupInfo group_info ; RsGroupInfo group_info ;
for(std::list<RsNodeGroupId>::const_iterator it(group_ids.begin());it!=group_ids.end();) for(std::list<RsNodeGroupId>::const_iterator it(group_ids.begin());it!=group_ids.end();)
@ -271,8 +277,55 @@ QString RetroshareDirModel::getAgeIndicatorString(const DirDetails &details) con
return ret; return ret;
} }
const QIcon& RetroshareDirModel::getFlagsIcon(FileStorageFlags flags)
{
static QIcon *static_icons[8] = {NULL};
int n=0;
if(flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD) n += 1 ;
if(flags & DIR_FLAGS_ANONYMOUS_SEARCH ) n += 2 ;
if(flags & DIR_FLAGS_BROWSABLE ) n += 4 ;
n-= 1;
if(static_icons[n] == NULL)
{
QList<QIcon> icons ;
if(flags & DIR_FLAGS_ANONYMOUS_SEARCH)
icons.push_back(QIcon(":icons/search_red_128.png")) ;
else
icons.push_back(QIcon(":icons/void_128.png")) ;
if(flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD)
icons.push_back(QIcon(":icons/anonymous_blue_128.png")) ;
else
icons.push_back(QIcon(":icons/void_128.png")) ;
if(flags & DIR_FLAGS_BROWSABLE)
icons.push_back(QIcon(":icons/browsable_green_128.png")) ;
else
icons.push_back(QIcon(":icons/void_128.png")) ;
QPixmap pix ;
GxsIdDetails::GenerateCombinedPixmap(pix, icons, 128);
static_icons[n] = new QIcon(pix);
std::cerr << "Generated icon for flags " << std::hex << flags << std::endl;
}
return *static_icons[n] ;
}
QVariant RetroshareDirModel::decorationRole(const DirDetails& details,int coln) const QVariant RetroshareDirModel::decorationRole(const DirDetails& details,int coln) const
{ {
if(coln == 3)
{
if(details.type == DIR_TYPE_PERSON) return QVariant() ;
return getFlagsIcon(details.flags) ;
}
if(coln > 0) if(coln > 0)
return QVariant() ; return QVariant() ;
@ -352,16 +405,9 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const
case 2: case 2:
return misc::userFriendlyDuration(details.min_age); return misc::userFriendlyDuration(details.min_age);
case 3: case 3:
return getFlagsString(details.flags); return QVariant();
// case 4:
// {
// QString ind("");
// if (ageIndicator != IND_ALWAYS)
// ind = getAgeIndicatorString(details);
// return ind;
// }
case 4: case 4:
return getGroupsString(details.parent_groups) ; return getGroupsString(details.flags,details.parent_groups) ;
default: default:
return tr("FILE"); return tr("FILE");
@ -383,9 +429,9 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const
case 2: case 2:
return misc::userFriendlyDuration(details.min_age); return misc::userFriendlyDuration(details.min_age);
case 3: case 3:
return getFlagsString(details.flags); return QVariant();
case 4: case 4:
return getGroupsString(details.parent_groups) ; return getGroupsString(details.flags,details.parent_groups) ;
default: default:
return tr("DIR"); return tr("DIR");
@ -663,12 +709,12 @@ QVariant TreeStyle_RDM::headerData(int section, Qt::Orientation orientation, int
if (RemoteMode) if (RemoteMode)
return tr("Friend"); return tr("Friend");
else else
return tr("Share Flags"); return tr("Access");
case 4: case 4:
if (RemoteMode) if (RemoteMode)
return tr("What's new"); return tr("What's new");
else else
return tr("Groups"); return tr("Visibility");
} }
return QString("Column %1").arg(section); return QString("Column %1").arg(section);
} }

View file

@ -94,9 +94,10 @@ class RetroshareDirModel : public QAbstractItemModel
void treeStyle(); void treeStyle();
void downloadDirectory(const DirDetails & details, int prefixLen); void downloadDirectory(const DirDetails & details, int prefixLen);
static QString getFlagsString(FileStorageFlags f) ; static QString getFlagsString(FileStorageFlags f) ;
static QString getGroupsString(const std::list<RsNodeGroupId> &) ; static QString getGroupsString(FileStorageFlags flags, const std::list<RsNodeGroupId> &) ;
QString getAgeIndicatorString(const DirDetails &) const; QString getAgeIndicatorString(const DirDetails &) const;
// void getAgeIndicatorRec(const DirDetails &details, QString &ret) const; // void getAgeIndicatorRec(const DirDetails &details, QString &ret) const;
static const QIcon& getFlagsIcon(FileStorageFlags flags) ;
virtual QVariant displayRole(const DirDetails&,int) const = 0 ; virtual QVariant displayRole(const DirDetails&,int) const = 0 ;
virtual QVariant sortRole(const QModelIndex&,const DirDetails&,int) const =0; virtual QVariant sortRole(const QModelIndex&,const DirDetails&,int) const =0;

View file

@ -57,7 +57,7 @@ ShareDialog::ShareDialog(std::string filename, QWidget *parent)
hb2->addWidget(new QLabel(tr("Share flags and groups:")+" ")) ; hb2->addWidget(new QLabel(tr("Share flags and groups:")+" ")) ;
groupflagsbox = new GroupFlagsWidget(ui.shareflags_GB) ; groupflagsbox = new GroupFlagsWidget(ui.shareflags_GB) ;
groupflagsbox->setFlags(DIR_FLAGS_NETWORK_WIDE_OTHERS) ; // default value groupflagsbox->setFlags(DIR_FLAGS_ANONYMOUS_DOWNLOAD) ; // default value
messageBox = new QTextEdit(ui.shareflags_GB) ; messageBox = new QTextEdit(ui.shareflags_GB) ;
messageBox->setReadOnly(true) ; messageBox->setReadOnly(true) ;

View file

@ -34,7 +34,8 @@
#include "ShareManager.h" #include "ShareManager.h"
#include "ShareDialog.h" #include "ShareDialog.h"
#include "settings/rsharesettings.h" #include "settings/rsharesettings.h"
#include <gui/common/GroupFlagsWidget.h> #include "gui/common/GroupFlagsWidget.h"
#include "gui/common/GroupSelectionBox.h"
#include "gui/common/GroupDefs.h" #include "gui/common/GroupDefs.h"
#include "gui/notifyqt.h" #include "gui/notifyqt.h"
#include "util/QtVersion.h" #include "util/QtVersion.h"
@ -61,33 +62,83 @@ ShareManager::ShareManager()
ui.headerFrame->setHeaderText(tr("Share Manager")); ui.headerFrame->setHeaderText(tr("Share Manager"));
isLoading = false; isLoading = false;
load();
Settings->loadWidgetInformation(this); Settings->loadWidgetInformation(this);
connect(ui.addButton, SIGNAL(clicked( bool ) ), this , SLOT( showShareDialog() ) ); connect(ui.addButton, SIGNAL(clicked( bool ) ), this , SLOT( addShare() ) );
connect(ui.editButton, SIGNAL(clicked( bool ) ), this , SLOT( editShareDirectory() ) );
connect(ui.removeButton, SIGNAL(clicked( bool ) ), this , SLOT( removeShareDirectory() ) );
connect(ui.closeButton, SIGNAL(clicked()), this, SLOT(applyAndClose())); connect(ui.closeButton, SIGNAL(clicked()), this, SLOT(applyAndClose()));
connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(cancel()));
connect(ui.shareddirList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(shareddirListCostumPopupMenu(QPoint))); connect(ui.shareddirList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(shareddirListCustomPopupMenu(QPoint)));
connect(ui.shareddirList, SIGNAL(currentCellChanged(int,int,int,int)), this, SLOT(shareddirListCurrentCellChanged(int,int,int,int))); connect(ui.shareddirList, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(doubleClickedCell(int,int)));
connect(ui.shareddirList, SIGNAL(cellChanged(int,int)), this, SLOT(handleCellChange(int,int)));
connect(NotifyQt::getInstance(), SIGNAL(groupsChanged(int)), this, SLOT(updateGroups())); connect(NotifyQt::getInstance(), SIGNAL(groupsChanged(int)), this, SLOT(reload()));
ui.editButton->setEnabled(false);
ui.removeButton->setEnabled(false);
QHeaderView* header = ui.shareddirList->horizontalHeader(); QHeaderView* header = ui.shareddirList->horizontalHeader();
QHeaderView_setSectionResizeModeColumn(header, COLUMN_PATH, QHeaderView::Stretch); QHeaderView_setSectionResizeModeColumn(header, COLUMN_PATH, QHeaderView::Stretch);
//header->setResizeMode(COLUMN_NETWORKWIDE, QHeaderView::Fixed);
//header->setResizeMode(COLUMN_BROWSABLE, QHeaderView::Fixed);
header->setHighlightSections(false); header->setHighlightSections(false);
setAcceptDrops(true); setAcceptDrops(true);
setAttribute(Qt::WA_DeleteOnClose, true); setAttribute(Qt::WA_DeleteOnClose, true);
reload();
}
void ShareManager::handleCellChange(int row,int column)
{
if(isLoading)
return ;
if(column == COLUMN_VIRTUALNAME)
{
// check if the thing already exists
for(uint32_t i=0;i<mDirInfos.size();++i)
if(i != (uint32_t)row && (mDirInfos[row].virtualname == std::string(ui.shareddirList->item(i,COLUMN_VIRTUALNAME)->text().toUtf8())))
{
ui.shareddirList->item(row,COLUMN_VIRTUALNAME)->setText(QString::fromUtf8(mDirInfos[row].virtualname.c_str())) ;
return ;
}
mDirInfos[row].virtualname = std::string(ui.shareddirList->item(row,COLUMN_VIRTUALNAME)->text().toUtf8()) ;
}
}
void ShareManager::editShareDirectory()
{
QTableWidget *listWidget = ui.shareddirList;
int row = listWidget -> currentRow();
doubleClickedCell(row,COLUMN_PATH) ;
}
void ShareManager::doubleClickedCell(int row,int column)
{
if(column == COLUMN_PATH)
{
QString dirname = QFileDialog::getExistingDirectory(NULL,tr("Choose directory"),QString(),QFileDialog::DontUseNativeDialog | QFileDialog::ShowDirsOnly);
if(!dirname.isNull())
{
std::string new_name( dirname.toUtf8() );
for(uint32_t i=0;i<mDirInfos.size();++i)
if(mDirInfos[row].filename == new_name)
return ;
mDirInfos[row].filename = new_name ;
load();
}
}
else if(column == COLUMN_GROUPS)
{
std::list<RsNodeGroupId> selected_groups = GroupSelectionDialog::selectGroups(mDirInfos[row].parent_groups) ;
mDirInfos[row].parent_groups = selected_groups ;
load();
}
} }
ShareManager::~ShareManager() ShareManager::~ShareManager()
@ -97,15 +148,25 @@ ShareManager::~ShareManager()
Settings->saveWidgetInformation(this); Settings->saveWidgetInformation(this);
} }
void ShareManager::cancel()
{
close();
}
void ShareManager::applyAndClose() void ShareManager::applyAndClose()
{ {
// std::cerr << "ShareManager:::close(): updating!" << std::endl; // This is the only place where we change things.
std::list<SharedDirInfo> infos ;
for(uint32_t i=0;i<mDirInfos.size();++i)
infos.push_back(mDirInfos[i]) ;
rsFiles->setSharedDirectories(infos) ;
updateFlags() ;
close() ; close() ;
} }
void ShareManager::shareddirListCostumPopupMenu( QPoint /*point*/ ) void ShareManager::shareddirListCustomPopupMenu( QPoint /*point*/ )
{ {
QMenu contextMnu( this ); QMenu contextMnu( this );
@ -121,6 +182,19 @@ void ShareManager::shareddirListCostumPopupMenu( QPoint /*point*/ )
contextMnu.exec(QCursor::pos()); contextMnu.exec(QCursor::pos());
} }
void ShareManager::reload()
{
std::list<SharedDirInfo> dirs ;
rsFiles->getSharedDirectories(dirs) ;
mDirInfos.clear();
for(std::list<SharedDirInfo>::const_iterator it(dirs.begin());it!=dirs.end();++it)
mDirInfos.push_back(*it) ;
load();
}
/** Loads the settings for this page */ /** Loads the settings for this page */
void ShareManager::load() void ShareManager::load()
{ {
@ -128,25 +202,19 @@ void ShareManager::load()
return ; return ;
isLoading = true; isLoading = true;
// std::cerr << "ShareManager:: In load !!!!!" << std::endl ;
std::list<SharedDirInfo>::const_iterator it;
std::list<SharedDirInfo> dirs;
rsFiles->getSharedDirectories(dirs);
/* get a link to the table */ /* get a link to the table */
QTableWidget *listWidget = ui.shareddirList; QTableWidget *listWidget = ui.shareddirList;
/* set new row count */ /* set new row count */
listWidget->setRowCount(dirs.size()); listWidget->setRowCount(mDirInfos.size());
int row=0 ; for(uint32_t row=0;row<mDirInfos.size();++row)
for(it = dirs.begin(); it != dirs.end(); ++it,++row)
{ {
listWidget->setItem(row, COLUMN_PATH, new QTableWidgetItem(QString::fromUtf8((*it).filename.c_str()))); listWidget->setItem(row, COLUMN_PATH, new QTableWidgetItem(QString::fromUtf8(mDirInfos[row].filename.c_str())));
listWidget->setItem(row, COLUMN_VIRTUALNAME, new QTableWidgetItem(QString::fromUtf8((*it).virtualname.c_str()))); listWidget->setItem(row, COLUMN_VIRTUALNAME, new QTableWidgetItem(QString::fromUtf8(mDirInfos[row].virtualname.c_str())));
GroupFlagsWidget *widget = new GroupFlagsWidget(NULL,(*it).shareflags); GroupFlagsWidget *widget = new GroupFlagsWidget(NULL,mDirInfos[row].shareflags);
listWidget->setRowHeight(row, 32 * QFontMetricsF(font()).height()/14.0); listWidget->setRowHeight(row, 32 * QFontMetricsF(font()).height()/14.0);
listWidget->setCellWidget(row, COLUMN_SHARE_FLAGS, widget); listWidget->setCellWidget(row, COLUMN_SHARE_FLAGS, widget);
@ -154,18 +222,26 @@ void ShareManager::load()
listWidget->setItem(row, COLUMN_GROUPS, new QTableWidgetItem()) ; listWidget->setItem(row, COLUMN_GROUPS, new QTableWidgetItem()) ;
listWidget->item(row,COLUMN_GROUPS)->setBackgroundColor(QColor(183,236,181)) ; listWidget->item(row,COLUMN_GROUPS)->setBackgroundColor(QColor(183,236,181)) ;
//connect(widget,SIGNAL(flagsChanged(FileStorageFlags)),this,SLOT(updateFlags())) ; connect(widget,SIGNAL(flagsChanged(FileStorageFlags)),this,SLOT(updateFlags())) ;
listWidget->item(row,COLUMN_PATH)->setToolTip(tr("Double click to change shared directory path")) ;
listWidget->item(row,COLUMN_GROUPS)->setToolTip(tr("Double click to select which groups of friends can see the files")) ;
listWidget->item(row,COLUMN_VIRTUALNAME)->setToolTip(tr("Double click to change the name that friends will see")) ;
listWidget->item(row,COLUMN_GROUPS)->setText(getGroupString(mDirInfos[row].parent_groups));
QFont font = listWidget->item(row,COLUMN_GROUPS)->font();
font.setBold(mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE) ;
listWidget->item(row,COLUMN_GROUPS)->setTextColor( (mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE)? (Qt::black):(Qt::lightGray)) ;
listWidget->item(row,COLUMN_GROUPS)->setFont(font);
} }
listWidget->setColumnWidth(COLUMN_SHARE_FLAGS,132 * QFontMetricsF(font()).height()/14.0) ; listWidget->setColumnWidth(COLUMN_SHARE_FLAGS,132 * QFontMetricsF(font()).height()/14.0) ;
//ui.incomingDir->setText(QString::fromStdString(rsFiles->getDownloadDirectory()));
listWidget->update(); /* update display */ listWidget->update(); /* update display */
update(); update();
isLoading = false ; isLoading = false ;
updateGroups();
} }
void ShareManager::showYourself() void ShareManager::showYourself()
@ -173,6 +249,7 @@ void ShareManager::showYourself()
if(_instance == NULL) if(_instance == NULL)
_instance = new ShareManager() ; _instance = new ShareManager() ;
_instance->reload() ;
_instance->show() ; _instance->show() ;
_instance->activateWindow(); _instance->activateWindow();
} }
@ -184,109 +261,39 @@ void ShareManager::showYourself()
} }
if (update_local) { if (update_local) {
_instance->load(); _instance->reload();
} }
} }
void ShareManager::updateFlags() void ShareManager::updateFlags()
{ {
if(isLoading)
return ;
isLoading = true ; // stops GUI update. Otherwise each call to rsFiles->updateShareFlags() modifies the GUI that we count on to check
// what has changed => fail!
// std::cerr << "Updating flags" << std::endl;
std::list<SharedDirInfo>::iterator it;
std::list<SharedDirInfo> dirs;
rsFiles->getSharedDirectories(dirs);
std::map<QString, FileStorageFlags> mapped_flags ;
for(int row=0;row<ui.shareddirList->rowCount();++row) for(int row=0;row<ui.shareddirList->rowCount();++row)
{ {
QString dirpath = ui.shareddirList->item(row,COLUMN_PATH)->text() ;
FileStorageFlags flags = (dynamic_cast<GroupFlagsWidget*>(ui.shareddirList->cellWidget(row,COLUMN_SHARE_FLAGS)))->flags() ; FileStorageFlags flags = (dynamic_cast<GroupFlagsWidget*>(ui.shareddirList->cellWidget(row,COLUMN_SHARE_FLAGS)))->flags() ;
mDirInfos[row].shareflags = flags ;
mapped_flags[dirpath] = flags ;
// std::cerr << "Getting new flags " << flags << " for path " << dirpath.toStdString() << std::endl;
} }
for(std::list<SharedDirInfo>::iterator it(dirs.begin());it!=dirs.end();++it)
{
FileStorageFlags newf = mapped_flags[QString::fromUtf8((*it).filename.c_str())] ;
if( (*it).shareflags != newf )
{
(*it).shareflags = newf ;
rsFiles->updateShareFlags(*it) ; // modifies the flags
// std::cerr << "Updating flags to " << newf << " for dir " << (*it).filename << std::endl ;
}
}
isLoading = false ; // re-enable GUI load
load() ; // update the GUI. load() ; // update the GUI.
} }
void ShareManager::updateGroups() QString ShareManager::getGroupString(const std::list<RsNodeGroupId>& groups)
{ {
if(isLoading) if(groups.empty())
return ; return tr("[All friend nodes]") ;
// std::cerr << "Updating groups" << std::endl;
std::list<SharedDirInfo>::iterator it;
std::list<SharedDirInfo> dirs;
rsFiles->getSharedDirectories(dirs);
int row=0 ;
for(it = dirs.begin(); it != dirs.end(); ++it,++row)
{
QTableWidgetItem *item = ui.shareddirList->item(row, COLUMN_GROUPS);
QString group_string;
int n = 0; int n = 0;
for (std::list<RsNodeGroupId>::const_iterator it2((*it).parent_groups.begin());it2!=(*it).parent_groups.end();++it2,++n) QString group_string ;
for (std::list<RsNodeGroupId>::const_iterator it(groups.begin());it!=groups.end();++it,++n)
{ {
if (n>0) if (n>0)
group_string += ", " ; group_string += ", " ;
RsGroupInfo groupInfo; RsGroupInfo groupInfo;
rsPeers->getGroupInfo(*it2, groupInfo); rsPeers->getGroupInfo(*it, groupInfo);
group_string += GroupDefs::name(groupInfo); group_string += GroupDefs::name(groupInfo);
} }
item->setText(group_string); return group_string ;
}
}
void ShareManager::editShareDirectory()
{
/* id current dir */
int row = ui.shareddirList->currentRow();
QTableWidgetItem *item = ui.shareddirList->item(row, COLUMN_PATH);
if (item) {
std::string filename = item->text().toUtf8().constData();
std::list<SharedDirInfo> dirs;
rsFiles->getSharedDirectories(dirs);
std::list<SharedDirInfo>::const_iterator it;
for (it = dirs.begin(); it != dirs.end(); ++it) {
if (it->filename == filename) {
/* file name found, show dialog */
ShareDialog sharedlg (it->filename, this);
sharedlg.setWindowTitle(tr("Edit Shared Folder"));
sharedlg.exec();
load();
break;
}
}
}
} }
void ShareManager::removeShareDirectory() void ShareManager::removeShareDirectory()
@ -301,7 +308,10 @@ void ShareManager::removeShareDirectory()
{ {
if ((QMessageBox::question(this, tr("Warning!"),tr("Do you really want to stop sharing this directory ?"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes) if ((QMessageBox::question(this, tr("Warning!"),tr("Do you really want to stop sharing this directory ?"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes)
{ {
rsFiles->removeSharedDirectory( qdir->text().toUtf8().constData()); for(uint32_t i=row;i+1<mDirInfos.size();++i)
mDirInfos[i] = mDirInfos[i+1] ;
mDirInfos.pop_back() ;
load(); load();
} }
} }
@ -315,6 +325,30 @@ void ShareManager::showEvent(QShowEvent *event)
} }
} }
void ShareManager::addShare()
{
QString fname = QFileDialog::getExistingDirectory(NULL,tr("Choose a directory to share"),QString(),QFileDialog::DontUseNativeDialog | QFileDialog::ShowDirsOnly);
if(fname.isNull())
return;
std::string dir_name ( fname.toUtf8() );
// check that the directory does not already exist
for(uint32_t i=0;i<mDirInfos.size();++i)
if(mDirInfos[i].filename == dir_name)
return ;
mDirInfos.push_back(SharedDirInfo());
mDirInfos.back().filename = dir_name ;
mDirInfos.back().virtualname = std::string();
mDirInfos.back().shareflags = DIR_FLAGS_ANONYMOUS_DOWNLOAD | DIR_FLAGS_ANONYMOUS_SEARCH;
mDirInfos.back().parent_groups.clear();
load();
}
void ShareManager::showShareDialog() void ShareManager::showShareDialog()
{ {
ShareDialog sharedlg ("", this); ShareDialog sharedlg ("", this);
@ -327,14 +361,6 @@ void ShareManager::shareddirListCurrentCellChanged(int currentRow, int currentCo
Q_UNUSED(currentColumn); Q_UNUSED(currentColumn);
Q_UNUSED(previousRow); Q_UNUSED(previousRow);
Q_UNUSED(previousColumn); Q_UNUSED(previousColumn);
if (currentRow >= 0) {
ui.editButton->setEnabled(true);
ui.removeButton->setEnabled(true);
} else {
ui.editButton->setEnabled(false);
ui.removeButton->setEnabled(false);
}
} }
void ShareManager::dragEnterEvent(QDragEnterEvent *event) void ShareManager::dragEnterEvent(QDragEnterEvent *event)

View file

@ -26,6 +26,7 @@
#include <QDialog> #include <QDialog>
#include <QFileDialog> #include <QFileDialog>
#include <retroshare/rsfiles.h>
#include "ui_ShareManager.h" #include "ui_ShareManager.h"
class ShareManager : public QDialog class ShareManager : public QDialog
@ -54,15 +55,20 @@ protected:
private slots: private slots:
/** Create the context popup menu and it's submenus */ /** Create the context popup menu and it's submenus */
void shareddirListCurrentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn); void shareddirListCurrentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn);
void shareddirListCostumPopupMenu( QPoint point ); void shareddirListCustomPopupMenu( QPoint point );
void addShare();
void doubleClickedCell(int,int);
void handleCellChange(int row,int column);
void editShareDirectory();
void showShareDialog(); void showShareDialog();
void editShareDirectory();
void removeShareDirectory(); void removeShareDirectory();
void updateFlags(); void updateFlags();
void updateGroups();
void applyAndClose() ; void applyAndClose() ;
void cancel() ;
void reload() ;
static QString getGroupString(const std::list<RsNodeGroupId>& groups);
private: private:
static ShareManager *_instance; static ShareManager *_instance;
bool isLoading; bool isLoading;
@ -72,6 +78,8 @@ private:
/** Qt Designer generated object */ /** Qt Designer generated object */
Ui::ShareManager ui; Ui::ShareManager ui;
std::vector<SharedDirInfo> mDirInfos ;
}; };
#endif #endif

View file

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>741</width> <width>1210</width>
<height>334</height> <height>334</height>
</rect> </rect>
</property> </property>
@ -18,7 +18,16 @@
<normaloff>:/images/logo/logo_16.png</normaloff>:/images/logo/logo_16.png</iconset> <normaloff>:/images/logo/logo_16.png</normaloff>:/images/logo/logo_16.png</iconset>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout_3">
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<property name="spacing"> <property name="spacing">
@ -49,7 +58,7 @@
<property name="topMargin"> <property name="topMargin">
<number>6</number> <number>6</number>
</property> </property>
<item row="1" column="0" colspan="6"> <item row="1" column="0" colspan="4">
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="groupBox">
<property name="title"> <property name="title">
<string>Shared Folder Manager</string> <string>Shared Folder Manager</string>
@ -64,7 +73,7 @@
<enum>Qt::CustomContextMenu</enum> <enum>Qt::CustomContextMenu</enum>
</property> </property>
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::DoubleClicked</set>
</property> </property>
<property name="alternatingRowColors"> <property name="alternatingRowColors">
<bool>true</bool> <bool>true</bool>
@ -92,17 +101,17 @@
</attribute> </attribute>
<column> <column>
<property name="text"> <property name="text">
<string>Directory</string> <string>Shared directory</string>
</property> </property>
</column> </column>
<column> <column>
<property name="text"> <property name="text">
<string>Virtual Folder</string> <string>Visible name</string>
</property> </property>
</column> </column>
<column> <column>
<property name="text"> <property name="text">
<string>Share flags</string> <string>Access</string>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string comment="If activated, the share is anonymously accessible to anybody"/> <string comment="If activated, the share is anonymously accessible to anybody"/>
@ -110,7 +119,7 @@
</column> </column>
<column> <column>
<property name="text"> <property name="text">
<string>Groups</string> <string>Visibility</string>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string comment="If checked, the share is browsable by your friends"/> <string comment="If checked, the share is browsable by your friends"/>
@ -139,7 +148,7 @@
<string>Add a Share Directory</string> <string>Add a Share Directory</string>
</property> </property>
<property name="text"> <property name="text">
<string>Add</string> <string>Add new</string>
</property> </property>
<property name="iconSize"> <property name="iconSize">
<size> <size>
@ -149,35 +158,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="2"> <item row="2" column="1">
<widget class="QPushButton" name="removeButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
<property name="toolTip">
<string>Stop sharing selected Directory</string>
</property>
<property name="text">
<string>Remove</string>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
<item row="2" column="3">
<spacer> <spacer>
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -190,24 +171,14 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="2" column="4"> <item row="2" column="2">
<widget class="QPushButton" name="closeButton"> <widget class="QPushButton" name="closeButton">
<property name="text"> <property name="text">
<string>Apply and close</string> <string>Apply and close</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="0" column="0" colspan="3">
<widget class="QPushButton" name="editButton">
<property name="toolTip">
<string>Edit selected Shared Directory</string>
</property>
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="5">
<widget class="StyledLabel" name="labelInstructions"> <widget class="StyledLabel" name="labelInstructions">
<property name="palette"> <property name="palette">
<palette> <palette>
@ -290,6 +261,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="3">
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View file

@ -25,8 +25,10 @@
#include <QTreeView> #include <QTreeView>
#include <QClipboard> #include <QClipboard>
#include <QMenu> #include <QMenu>
#include <QPainter>
#include <QProcess> #include <QProcess>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QStyledItemDelegate>
#include "SharedFilesDialog.h" #include "SharedFilesDialog.h"
#include "settings/AddFileAssociationDialog.h" #include "settings/AddFileAssociationDialog.h"
@ -114,6 +116,36 @@ private:
RetroshareDirModel *m_dirModel; RetroshareDirModel *m_dirModel;
}; };
// This class allows to draw the item in the share flags column using an appropriate size
class ShareFlagsItemDelegate: public QStyledItemDelegate
{
public:
ShareFlagsItemDelegate() {}
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_ASSERT(index.isValid());
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
// disable default icon
opt.icon = QIcon();
// draw default item
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0);
const QRect r = option.rect;
// get pixmap
QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
QPixmap pix = icon.pixmap(r.size());
// draw pixmap at center of item
const QPoint p = QPoint((r.width() - pix.width())/2, (r.height() - pix.height())/2);
painter->drawPixmap(r.topLeft() + p, pix);
}
};
/** Constructor */ /** Constructor */
SharedFilesDialog::SharedFilesDialog(RetroshareDirModel *_tree_model,RetroshareDirModel *_flat_model,QWidget *parent) SharedFilesDialog::SharedFilesDialog(RetroshareDirModel *_tree_model,RetroshareDirModel *_flat_model,QWidget *parent)
: RsAutoUpdatePage(1000,parent),model(NULL) : RsAutoUpdatePage(1000,parent),model(NULL)
@ -221,6 +253,8 @@ LocalSharedFilesDialog::LocalSharedFilesDialog(QWidget *parent)
connect(editshareAct, SIGNAL(triggered()), this, SLOT(editSharePermissions())) ; connect(editshareAct, SIGNAL(triggered()), this, SLOT(editSharePermissions())) ;
ui.titleBarPixmap->setPixmap(QPixmap(IMAGE_MYFILES)) ; ui.titleBarPixmap->setPixmap(QPixmap(IMAGE_MYFILES)) ;
ui.dirTreeView->setItemDelegateForColumn(COLUMN_FRIEND,new ShareFlagsItemDelegate()) ;
} }
RemoteSharedFilesDialog::RemoteSharedFilesDialog(QWidget *parent) RemoteSharedFilesDialog::RemoteSharedFilesDialog(QWidget *parent)

View file

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>737</width> <width>1156</width>
<height>402</height> <height>402</height>
</rect> </rect>
</property> </property>
@ -86,7 +86,7 @@
<item> <item>
<widget class="QPushButton" name="addShares_PB"> <widget class="QPushButton" name="addShares_PB">
<property name="text"> <property name="text">
<string>Add Share</string> <string>Configure shared directories</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="images.qrc"> <iconset resource="images.qrc">

View file

@ -3,31 +3,26 @@
#include "GroupFlagsWidget.h" #include "GroupFlagsWidget.h"
#include <retroshare/rsfiles.h> #include <retroshare/rsfiles.h>
#define FLAGS_GROUP_NETWORK_WIDE_ICON ":images/anonymous_128_green.png" #define FLAGS_ANONYMOUS_SEARCH_ON ":icons/search_red_128.png"
#define FLAGS_GROUP_BROWSABLE_ICON ":images/browsable_128_green.png" #define FLAGS_ANONYMOUS_SEARCH_OFF ":icons/blank_red_128.png"
#define FLAGS_GROUP_UNCHECKED ":images/blank_128_green.png" #define FLAGS_BROWSABLE_ON ":icons/browsable_green_128.png"
#define FLAGS_OTHER_NETWORK_WIDE_ICON ":images/anonymous_128_blue.png" #define FLAGS_BROWSABLE_OFF ":icons/blank_green_128.png"
#define FLAGS_OTHER_BROWSABLE_ICON ":images/browsable_128_blue.png" #define FLAGS_ANONYMOUS_DL_ON ":icons/anonymous_blue_128.png"
#define FLAGS_OTHER_UNCHECKED ":images/blank_128_blue.png" #define FLAGS_ANONYMOUS_DL_OFF ":icons/blank_blue_128.png"
#define INDEX_GROUP_BROWSABLE 0 #define INDEX_ANON_SEARCH 0
#define INDEX_GROUP_NETWORK_W 1 #define INDEX_ANON_DL 1
#define INDEX_OTHER_BROWSABLE 2 #define INDEX_BROWSABLE 2
#define INDEX_OTHER_NETWORK_W 3
#define INDEX_GROUP_UNCHECKED 4
#define INDEX_OTHER_UNCHECKED 5
/*QString GroupFlagsWidget::_tooltips_on[4] = { /*QString GroupFlagsWidget::_tooltips_on[4] = {
QObject::tr("Directory is browsable for friends from groups"), QObject::tr("Directory is visible to friends"),
QObject::tr("Directory is accessible by anonymous tunnels from friends from groups"), QObject::tr("Directory can be search anonymously"),
QObject::tr("Directory is browsable for any friend"), QObject::tr("Directory is accessible by anonymous tunnels")
QObject::tr("Directory is accessible by anonymous tunnels from any friend")
}; };
QString GroupFlagsWidget::_tooltips_off[4] = { QString GroupFlagsWidget::_tooltips_off[4] = {
QObject::tr("Directory is NOT browsable for friends from groups"), QObject::tr("Directory is not visible to friends"),
QObject::tr("Directory is NOT accessible by anonymous tunnels from friends from groups"), QObject::tr("Directory cannot be searched anonymously"),
QObject::tr("Directory is NOT browsable for any friend"), QObject::tr("Directory is NOT accessible by anonymous tunnels")
QObject::tr("Directory is NOT accessible by anonymous tunnels from any friend")
}; };
*/ */
GroupFlagsWidget::GroupFlagsWidget(QWidget *parent,FileStorageFlags flags) GroupFlagsWidget::GroupFlagsWidget(QWidget *parent,FileStorageFlags flags)
@ -39,35 +34,33 @@ GroupFlagsWidget::GroupFlagsWidget(QWidget *parent,FileStorageFlags flags)
setMaximumSize(128 * QFontMetricsF(font()).height()/14.0,32 * QFontMetricsF(font()).height()/14.0) ; setMaximumSize(128 * QFontMetricsF(font()).height()/14.0,32 * QFontMetricsF(font()).height()/14.0) ;
setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
_icons[INDEX_GROUP_BROWSABLE] = new QIcon(FLAGS_GROUP_BROWSABLE_ICON) ; _icons[2*INDEX_BROWSABLE+0] = new QIcon(FLAGS_BROWSABLE_OFF) ;
_icons[INDEX_GROUP_NETWORK_W] = new QIcon(FLAGS_GROUP_NETWORK_WIDE_ICON) ; _icons[2*INDEX_BROWSABLE+1] = new QIcon(FLAGS_BROWSABLE_ON) ;
_icons[INDEX_OTHER_BROWSABLE] = new QIcon(FLAGS_OTHER_BROWSABLE_ICON) ; _icons[2*INDEX_ANON_SEARCH+0] = new QIcon(FLAGS_ANONYMOUS_SEARCH_OFF) ;
_icons[INDEX_OTHER_NETWORK_W] = new QIcon(FLAGS_OTHER_NETWORK_WIDE_ICON) ; _icons[2*INDEX_ANON_SEARCH+1] = new QIcon(FLAGS_ANONYMOUS_SEARCH_ON) ;
_icons[INDEX_GROUP_UNCHECKED] = new QIcon(FLAGS_GROUP_UNCHECKED) ; _icons[2*INDEX_ANON_DL+0] = new QIcon(FLAGS_ANONYMOUS_DL_OFF) ;
_icons[INDEX_OTHER_UNCHECKED] = new QIcon(FLAGS_OTHER_UNCHECKED) ; _icons[2*INDEX_ANON_DL+1] = new QIcon(FLAGS_ANONYMOUS_DL_ON) ;
setLayout(_layout) ; setLayout(_layout) ;
_flags[0] = DIR_FLAGS_BROWSABLE_GROUPS ; _flags[INDEX_BROWSABLE ] = DIR_FLAGS_BROWSABLE ;
_flags[1] = DIR_FLAGS_NETWORK_WIDE_GROUPS ; _flags[INDEX_ANON_SEARCH] = DIR_FLAGS_ANONYMOUS_SEARCH ;
_flags[2] = DIR_FLAGS_BROWSABLE_OTHERS ; _flags[INDEX_ANON_DL ] = DIR_FLAGS_ANONYMOUS_DOWNLOAD ;
_flags[3] = DIR_FLAGS_NETWORK_WIDE_OTHERS ;
for(int i=0;i<4;++i) for(int i=0;i<3;++i)
{ {
_buttons[i] = new QPushButton(this) ; _buttons[i] = new QPushButton(this) ;
_buttons[i]->setCheckable(true) ; _buttons[i]->setCheckable(true) ;
_buttons[i]->setChecked(flags & _flags[i]) ; _buttons[i]->setChecked(flags & _flags[i]) ;
_buttons[i]->setIconSize(QSize(32 * QFontMetricsF(font()).height()/14.0,32 * QFontMetricsF(font()).height()/14.0)); _buttons[i]->setIconSize(QSize(32 * QFontMetricsF(font()).height()/14.0,32 * QFontMetricsF(font()).height()/14.0));
update_button_state(_buttons[i]->isChecked(),i) ; update_button_state(_buttons[i]->isChecked(),i) ;
_layout->addWidget(_buttons[i]) ; _layout->addWidget(_buttons[i]) ;
} }
_buttons[INDEX_GROUP_NETWORK_W]->setHidden(true);
connect(_buttons[INDEX_GROUP_NETWORK_W],SIGNAL(toggled(bool)),this,SLOT(update_GN_button(bool))) ; connect(_buttons[INDEX_ANON_DL ],SIGNAL(toggled(bool)),this,SLOT(update_DL_button(bool))) ;
connect(_buttons[INDEX_OTHER_NETWORK_W],SIGNAL(toggled(bool)),this,SLOT(update_ON_button(bool))) ; connect(_buttons[INDEX_ANON_SEARCH],SIGNAL(toggled(bool)),this,SLOT(update_SR_button(bool))) ;
connect(_buttons[INDEX_GROUP_BROWSABLE],SIGNAL(toggled(bool)),this,SLOT(update_GB_button(bool))) ; connect(_buttons[INDEX_BROWSABLE ],SIGNAL(toggled(bool)),this,SLOT(update_BR_button(bool))) ;
connect(_buttons[INDEX_OTHER_BROWSABLE],SIGNAL(toggled(bool)),this,SLOT(update_OB_button(bool))) ;
_layout->setSpacing(0); _layout->setSpacing(0);
_layout->setContentsMargins(0, 0, 0, 0); _layout->setContentsMargins(0, 0, 0, 0);
@ -84,16 +77,15 @@ FileStorageFlags GroupFlagsWidget::flags() const
{ {
FileStorageFlags flags ; FileStorageFlags flags ;
for(int i=0;i<4;++i) for(int i=0;i<3;++i)
if(_buttons[i]->isChecked()) flags |= _flags[i] ; if(_buttons[i]->isChecked()) flags |= _flags[i] ;
flags &= ~DIR_FLAGS_NETWORK_WIDE_GROUPS ;
return flags ; return flags ;
} }
void GroupFlagsWidget::setFlags(FileStorageFlags flags) void GroupFlagsWidget::setFlags(FileStorageFlags flags)
{ {
for(int i=0;i<4;++i) for(int i=0;i<3;++i)
{ {
_buttons[i]->setChecked(flags & _flags[i]) ; _buttons[i]->setChecked(flags & _flags[i]) ;
update_button_state(_buttons[i]->isChecked(),i) ; update_button_state(_buttons[i]->isChecked(),i) ;
@ -104,41 +96,28 @@ void GroupFlagsWidget::update_button_state(bool b,int button_id)
{ {
QString tip_on, tip_off; QString tip_on, tip_off;
switch (button_id) { switch (button_id) {
case 0: case INDEX_BROWSABLE:
tip_on = tr("Directory is browsable for friends from groups"); tip_on = tr("Directory content is visible to friend nodes (see list at right)");
tip_off = tr("Directory is NOT browsable for friends from groups"); tip_off = tr("Directory content is NOT visible to friend nodes");
break; break;
case 1: case INDEX_ANON_SEARCH:
tip_on = tr("Directory is accessible by anonymous tunnels from friends from groups"); tip_on = tr("Directory can be searched anonymously");
tip_off = tr("Directory is NOT accessible by anonymous tunnels from friends from groups"); tip_off = tr("Directory cannot be searched anonymously");
break; break;
case 2: case INDEX_ANON_DL:
tip_on = tr("Directory is browsable for any friend"); if(_buttons[INDEX_ANON_SEARCH]->isChecked())
tip_off = tr("Directory is NOT browsable for any friend"); tip_on = tr("Files can be accessed using anonymous tunnels");
break; else
case 3: tip_on = tr("Files can be accessed using anonymous & end-to-end encrypted tunnels");
tip_on = tr("Directory is accessible by anonymous tunnels from any friend");
tip_off = tr("Directory is NOT accessible by anonymous tunnels from any friend"); tip_off = tr("Files cannot be downloaded anonymously");
break; break;
default: default:
tip_on = ""; tip_on = "";
tip_off = ""; tip_off = "";
} }
if(b) _buttons[button_id]->setIcon(*_icons[2*button_id+(int)b]) ;
{ _buttons[button_id]->setToolTip(b?tip_on:tip_off) ;
_buttons[button_id]->setIcon(*_icons[button_id]) ;
_buttons[button_id]->setToolTip(tip_on) ;
}
else if(button_id == INDEX_GROUP_NETWORK_W || button_id == INDEX_GROUP_BROWSABLE)
{
_buttons[button_id]->setIcon(*_icons[INDEX_GROUP_UNCHECKED]) ;
_buttons[button_id]->setToolTip(tip_off) ;
}
else
{
_buttons[button_id]->setIcon(*_icons[INDEX_OTHER_UNCHECKED]) ;
_buttons[button_id]->setToolTip(tip_off) ;
}
} }
QString GroupFlagsWidget::groupInfoString(FileStorageFlags flags, const QList<QString>& groupNames) QString GroupFlagsWidget::groupInfoString(FileStorageFlags flags, const QList<QString>& groupNames)
@ -155,42 +134,39 @@ QString GroupFlagsWidget::groupInfoString(FileStorageFlags flags, const QList<QS
groups_string += *it ; groups_string += *it ;
} }
if(flags & DIR_FLAGS_BROWSABLE_OTHERS) if(flags & DIR_FLAGS_BROWSABLE)
res += tr("All friend nodes can browse this directory") + "\n" ; {
else if(flags & DIR_FLAGS_BROWSABLE_GROUPS) if(groupNames.empty())
if(!groupNames.empty()) res += tr("All friend nodes can see this directory") + "\n" ;
res += tr("Only friend nodes in groups %1 can browse this directory").arg(groups_string) + "\n" ;
else else
res += tr("No one can browse this directory") + "\n" ; res += tr("Only visible to friend nodes in groups: %1").arg(groups_string) + "\n" ;
}
else else
res += tr("No one can browse this directory") + "\n" ; res += tr("Not visible to friend nodes") + "\n" ;
if(flags & DIR_FLAGS_NETWORK_WIDE_OTHERS) if((flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD) && !(flags & DIR_FLAGS_ANONYMOUS_SEARCH))
res += tr("All friend nodes can relay anonymous tunnels to this directory") ; res += tr("Files can be downloaded (but not searched) anonymously") ;
else if(flags & DIR_FLAGS_NETWORK_WIDE_GROUPS) else if((flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD) && (flags & DIR_FLAGS_ANONYMOUS_SEARCH))
res += tr("Only friend nodes in groups")+" " + groups_string +" "+ tr("can relay anonymous tunnels to this directory") ; res += tr("Files can be downloaded and searched anonymously") ;
else if(!(flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD) && (flags & DIR_FLAGS_ANONYMOUS_SEARCH))
res += tr("Files can be searched (but not downloaded) anonymously") ;
else else
res += tr("No one can anonymously access this directory.") ; res += tr("No one can anonymously access/search these files.") ;
//if(flags.toUInt32() == 0)
// res += tr("No friends can access nor see this directory.") ;
return res ; return res ;
} }
void GroupFlagsWidget::update_GN_button(bool b) { update_button_state(b,INDEX_GROUP_NETWORK_W) ; updated() ; } void GroupFlagsWidget::update_DL_button(bool b) { update_button_state(b,INDEX_ANON_DL ) ; updated() ; }
void GroupFlagsWidget::update_GB_button(bool b) { update_button_state(b,INDEX_GROUP_BROWSABLE) ; updated() ; } void GroupFlagsWidget::update_SR_button(bool b) { update_button_state(b,INDEX_ANON_SEARCH) ; updated() ; }
void GroupFlagsWidget::update_ON_button(bool b) { update_button_state(b,INDEX_OTHER_NETWORK_W) ; updated() ; } void GroupFlagsWidget::update_BR_button(bool b) { update_button_state(b,INDEX_BROWSABLE ) ; updated() ; }
void GroupFlagsWidget::update_OB_button(bool b) { update_button_state(b,INDEX_OTHER_BROWSABLE) ; updated() ; }
GroupFlagsWidget::~GroupFlagsWidget() GroupFlagsWidget::~GroupFlagsWidget()
{ {
for(int i=0;i<4;++i) for(int i=0;i<3;++i)
{ {
delete _buttons[i] ; delete _buttons[i] ;
delete _icons[i] ; delete _icons[2*i+0] ;
delete _icons[2*i+1] ;
} }
delete _icons[INDEX_GROUP_UNCHECKED] ;
delete _icons[INDEX_OTHER_UNCHECKED] ;
} }

View file

@ -22,10 +22,9 @@ class GroupFlagsWidget: public QWidget
void updated() ; void updated() ;
protected slots: protected slots:
void update_GN_button(bool) ; void update_DL_button(bool) ;
void update_GB_button(bool) ; void update_SR_button(bool) ;
void update_ON_button(bool) ; void update_BR_button(bool) ;
void update_OB_button(bool) ;
signals: signals:
void flagsChanged(FileStorageFlags) const ; void flagsChanged(FileStorageFlags) const ;

View file

@ -1,3 +1,5 @@
#include <QLayout>
#include <QDialogButtonBox>
#include <retroshare/rspeers.h> #include <retroshare/rspeers.h>
#include "GroupSelectionBox.h" #include "GroupSelectionBox.h"
#include "GroupDefs.h" #include "GroupDefs.h"
@ -17,7 +19,6 @@ GroupSelectionBox::GroupSelectionBox(QWidget *parent)
// Fill with available groups // Fill with available groups
fillGroups(); fillGroups();
} }
void GroupSelectionBox::fillGroups() void GroupSelectionBox::fillGroups()
{ {
std::list<RsNodeGroupId> selectedIds; std::list<RsNodeGroupId> selectedIds;
@ -78,3 +79,39 @@ void GroupSelectionBox::selectedGroupNames(QList<QString> &groupNames) const
} }
} }
} }
std::list<RsNodeGroupId> GroupSelectionDialog::selectGroups(const std::list<RsNodeGroupId>& default_groups)
{
GroupSelectionDialog gsd(NULL) ;
gsd.mBox->setSelectedGroupIds(default_groups) ;
gsd.exec();
std::list<RsNodeGroupId> selected_groups ;
gsd.mBox->selectedGroupIds(selected_groups);
return selected_groups ;
}
GroupSelectionDialog::~GroupSelectionDialog()
{
delete mBox ;
}
GroupSelectionDialog::GroupSelectionDialog(QWidget *parent)
{
mBox = new GroupSelectionBox(this) ;
QLayout *l = new QVBoxLayout ;
setLayout(l) ;
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
l->addWidget(mBox) ;
l->addWidget(buttonBox) ;
l->update() ;
}

View file

@ -1,4 +1,5 @@
#include <QListWidget> #include <QListWidget>
#include <QDialog>
#include <retroshare/rsids.h> #include <retroshare/rsids.h>
class GroupSelectionBox: public QListWidget class GroupSelectionBox: public QListWidget
@ -8,6 +9,8 @@ class GroupSelectionBox: public QListWidget
public: public:
GroupSelectionBox(QWidget *parent); GroupSelectionBox(QWidget *parent);
static void selectGroups(const std::list<RsNodeGroupId>& default_groups) ;
void selectedGroupIds(std::list<RsNodeGroupId> &groupIds) const; void selectedGroupIds(std::list<RsNodeGroupId> &groupIds) const;
void selectedGroupNames(QList<QString> &groupNames) const; void selectedGroupNames(QList<QString> &groupNames) const;
@ -16,3 +19,17 @@ public:
private slots: private slots:
void fillGroups(); void fillGroups();
}; };
class GroupSelectionDialog: public QDialog
{
Q_OBJECT
public:
GroupSelectionDialog(QWidget *parent) ;
virtual ~GroupSelectionDialog() ;
static std::list<RsNodeGroupId> selectGroups(const std::list<RsNodeGroupId>& default_groups) ;
private:
GroupSelectionBox *mBox ;
};

View file

@ -25,15 +25,16 @@
<file>icons/settings/sound.svg</file> <file>icons/settings/sound.svg</file>
<file>icons/settings/webinterface.svg</file> <file>icons/settings/webinterface.svg</file>
<file>icons/add_user_256.png</file> <file>icons/add_user_256.png</file>
<file>icons/anonymous_blue_128.png</file>
<file>icons/anonymous_green_128.png</file>
<file>icons/aol.png</file> <file>icons/aol.png</file>
<file>icons/avatar_128.png</file> <file>icons/avatar_128.png</file>
<file>icons/avatar_grey_128.png</file> <file>icons/avatar_grey_128.png</file>
<file>icons/blank_blue_128.png</file> <file>icons/blank_red_128.png</file>
<file>icons/void_128.png</file>
<file>icons/blank_green_128.png</file> <file>icons/blank_green_128.png</file>
<file>icons/browsable_blue_128.png</file> <file>icons/blank_blue_128.png</file>
<file>icons/browsable_green_128.png</file> <file>icons/browsable_green_128.png</file>
<file>icons/search_red_128.png</file>
<file>icons/anonymous_blue_128.png</file>
<file>icons/bullet_blue_128.png</file> <file>icons/bullet_blue_128.png</file>
<file>icons/bullet_green_128.png</file> <file>icons/bullet_green_128.png</file>
<file>icons/bullet_grey_128.png</file> <file>icons/bullet_grey_128.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View file

@ -3,7 +3,7 @@
echo '<RCC>' echo '<RCC>'
echo '\t<qresource prefix="/">' echo '\t<qresource prefix="/">'
for i in `ls *.png`; do for i in `ls *.png */*png */*svg`; do
echo '\t\t<file>icons/'$i'</file>' echo '\t\t<file>icons/'$i'</file>'
done done

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

@ -44,10 +44,17 @@ TransferPage::TransferPage(QWidget * parent, Qt::WindowFlags flags)
case FileChunksInfo::CHUNK_STRATEGY_RANDOM: ui._defaultStrategy_CB->setCurrentIndex(2) ; break ; case FileChunksInfo::CHUNK_STRATEGY_RANDOM: ui._defaultStrategy_CB->setCurrentIndex(2) ; break ;
} }
switch(rsFiles->defaultEncryptionPolicy())
{
case RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE: ui._e2e_encryption_CB->setCurrentIndex(0) ; break ;
case RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT : ui._e2e_encryption_CB->setCurrentIndex(1) ; break ;
}
ui._diskSpaceLimit_SB->setValue(rsFiles->freeDiskSpaceLimit()) ; ui._diskSpaceLimit_SB->setValue(rsFiles->freeDiskSpaceLimit()) ;
QObject::connect(ui._queueSize_SB,SIGNAL(valueChanged(int)),this,SLOT(updateQueueSize(int))) ; QObject::connect(ui._queueSize_SB,SIGNAL(valueChanged(int)),this,SLOT(updateQueueSize(int))) ;
QObject::connect(ui._defaultStrategy_CB,SIGNAL(activated(int)),this,SLOT(updateDefaultStrategy(int))) ; QObject::connect(ui._defaultStrategy_CB,SIGNAL(activated(int)),this,SLOT(updateDefaultStrategy(int))) ;
QObject::connect(ui._e2e_encryption_CB,SIGNAL(activated(int)),this,SLOT(updateEncryptionPolicy(int))) ;
QObject::connect(ui._diskSpaceLimit_SB,SIGNAL(valueChanged(int)),this,SLOT(updateDiskSizeLimit(int))) ; QObject::connect(ui._diskSpaceLimit_SB,SIGNAL(valueChanged(int)),this,SLOT(updateDiskSizeLimit(int))) ;
QObject::connect(ui._max_tr_up_per_sec_SB, SIGNAL( valueChanged( int ) ), this, SLOT( updateMaxTRUpRate(int) ) ); QObject::connect(ui._max_tr_up_per_sec_SB, SIGNAL( valueChanged( int ) ), this, SLOT( updateMaxTRUpRate(int) ) );
@ -57,6 +64,19 @@ void TransferPage::updateMaxTRUpRate(int b)
{ {
rsTurtle->setMaxTRForwardRate(b) ; rsTurtle->setMaxTRForwardRate(b) ;
} }
void TransferPage::updateEncryptionPolicy(int b)
{
switch(b)
{
case 1: rsFiles->setDefaultEncryptionPolicy(RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT) ;
break ;
default:
case 0: rsFiles->setDefaultEncryptionPolicy(RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE) ;
break ;
}
}
void TransferPage::updateDefaultStrategy(int i) void TransferPage::updateDefaultStrategy(int i)
{ {
switch(i) switch(i)

View file

@ -49,6 +49,7 @@ class TransferPage: public ConfigPage
void updateDefaultStrategy(int) ; void updateDefaultStrategy(int) ;
void updateDiskSizeLimit(int) ; void updateDiskSizeLimit(int) ;
void updateMaxTRUpRate(int); void updateMaxTRUpRate(int);
void updateEncryptionPolicy(int);
private: private:

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>700</width> <width>741</width>
<height>356</height> <height>372</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
@ -49,6 +49,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>End-to-end encryption:</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
@ -135,6 +142,23 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QComboBox" name="_e2e_encryption_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Anonymous tunnels can be end-o-end encrypted. In order to maintain backward compatibility, this can be made optional (choosing &amp;quot;Accepted&amp;quot;), but in the end, all Retroshare nodes will be switched to &amp;quot;Enforced&amp;quot;, meaning that all anonymous transfers will be end-to-end encrypted.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<item>
<property name="text">
<string>Accepted</string>
</property>
</item>
<item>
<property name="text">
<string>Enforced</string>
</property>
</item>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>

View file

@ -0,0 +1,12 @@
#include <gtest/gtest.h>
// from libretroshare
#include "crypto/chacha20.h"
TEST(libretroshare_crypto, ChaCha20)
{
std::cerr << "Testing Chacha20" << std::endl;
EXPECT_TRUE(librs::crypto::perform_tests()) ;
}

View file

@ -272,6 +272,10 @@ INCLUDEPATH += ../librssimulator/
SOURCES += unittests.cc \ SOURCES += unittests.cc \
################################## Crypto ##################################
SOURCES += libretroshare/crypto/chacha20_test.cc
################################ Serialiser ################################ ################################ Serialiser ################################
HEADERS += libretroshare/serialiser/support.h \ HEADERS += libretroshare/serialiser/support.h \
libretroshare/serialiser/rstlvutil.h \ libretroshare/serialiser/rstlvutil.h \