RetroShare/libretroshare/src/ft/ftdbase.cc
csoler b80aef1228 Suppressed the possibility for browsable only files to be searched by hash from turtle router.
This avoids that an attacker that captures a broadcast hash request can also ask for the file.

This needed to add back explicit sources in SearchDialog and private chat transfer. I dynamically search
for sources in file lists just before calling FileRequest.

When RS links anchorClick() will work properly with Qt, we can remove the search flag "EXTRA" from the
tunnel digging in p3turtle.cc, otherwise, people having this bug can't transfer files in private chat by
copy+paste of a RS link.
    
	Also:
	    - added missing mutexes in search requests into fimonitor.cc
		- suppressed some debug info in connect manager
		- added check for write fails when dumping config files



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3027 b45a01b8-16f6-495d-af2f-9b41ad6348cc
2010-05-29 13:17:09 +00:00

299 lines
6.4 KiB
C++

/*
* libretroshare/src/ft: ftdbase.cc
*
* File Transfer for RetroShare.
*
* Copyright 2008 by Robert Fernie.
*
* 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@lunamutt.com".
*
*/
#include "ft/ftdbase.h"
#include "util/rsdir.h"
#include "serialiser/rsconfigitems.h"
//#define DB_DEBUG 1
ftFiStore::ftFiStore(CacheStrapper *cs, CacheTransfer *cft, NotifyBase *cb_in,
RsPeerId ownid, std::string cachedir)
:FileIndexStore(cs, cft, cb_in, ownid, cachedir)
{
return;
}
bool ftFiStore::search(std::string hash, uint32_t hintflags, FileInfo &info) const
{
/* could use hintflags to specify which bits of fileinfo to use additionally.
eg. hintflags & FT_SEARCH_PEER_ID, then only return matching peers + hash.
eg. hintflags & FT_SEARCH_NAME, then only return matching name + hash.
*
* Still to see if concept is worthwhle
*/
#ifdef DB_DEBUG
std::cerr << "ftFiStore::search(" << hash << "," << hintflags;
std::cerr << ")";
std::cerr << std::endl;
#endif
std::list<FileDetail> results;
std::list<FileDetail>::iterator it;
if (SearchHash(hash, results))
{
bool first = true;
for(it = results.begin(); it != results.end(); it++)
{
#ifdef DB_DEBUG
std::cerr << "ftFiStore::search() found: ";
std::cerr << it->name << " (" << it->size;
std::cerr << ") @ " << it->id << " = " << hash;
std::cerr << std::endl;
#endif
bool fullmatch = true;
// if (it->size != size)
// fullmatch = false;
#if 0
if (hintflags & FT_SEARCH_PEER_ID)
{
pit = std::find(info.srcIds.begin(),
info.srcId.end(). it->id);
if (pit == info.srcIds.end())
{
fullmatch = false;
}
}
#endif
if (fullmatch)
{
if (first)
{
first = false;
info.fname = it->name;
info.size = it->size;
info.hash = it->hash;
}
TransferInfo ti;
ti.peerId = it->id;
ti.name = it->name;
ti.tfRate = 0;
info.peers.push_back(ti);
}
}
/**** DEPENDS ON SOURCES!
info.downloadStatus = FT_STATE_COMPLETE:
****/
/* if the first flag is cleared, we've definitely
* had a full match!.
*/
if (!first)
return true;
}
return false;
}
ftFiMonitor::ftFiMonitor(CacheStrapper *cs,NotifyBase *cb_in, std::string cachedir, std::string pid)
:FileIndexMonitor(cs,cb_in, cachedir, pid), p3Config(CONFIG_TYPE_FT_SHARED)
{
return;
}
bool ftFiMonitor::search(std::string hash, uint32_t hintflags, FileInfo &info) const
{
uint64_t fsize;
std::string path;
#ifdef DB_DEBUG
std::cerr << "ftFiMonitor::search(" << hash << "," << hintflags;
std::cerr << ")";
std::cerr << std::endl;
#endif
// Setup search flags according to hintflags. Originally flags was 0. I (cyril) don't know
// why we don't just pass hintflags there, so I tried to keep the idea.
//
uint32_t flags = hintflags & (RS_FILE_HINTS_BROWSABLE | RS_FILE_HINTS_NETWORK_WIDE);
if(findLocalFile(hash, flags, path, fsize))
{
/* fill in details */
#ifdef DB_DEBUG
std::cerr << "ftFiMonitor::search() found: ";
std::cerr << path;
std::cerr << " = " << hash << "," << fsize;
std::cerr << std::endl;
#endif
info.size = fsize;
info.fname = RsDirUtil::getTopDir(path);
info.path = path;
return true;
}
return false;
};
/******* LOAD / SAVE CONFIG List.
*
*
*
*
*/
RsSerialiser *ftFiMonitor::setupSerialiser()
{
RsSerialiser *rss = new RsSerialiser();
/* add in the types we need! */
rss->addSerialType(new RsFileConfigSerialiser());
return rss;
}
std::list<RsItem *> ftFiMonitor::saveList(bool &cleanup)
{
std::list<RsItem *> sList;
cleanup = true;
#ifdef DB_DEBUG
std::cerr << "ftFiMonitor::saveList()";
std::cerr << std::endl;
#endif
/* get list of directories */
std::list<SharedDirInfo> dirList;
std::list<SharedDirInfo>::iterator it;
getSharedDirectories(dirList);
for(it = dirList.begin(); it != dirList.end(); it++)
{
RsFileConfigItem *fi = new RsFileConfigItem();
fi->file.path = (*it).filename ;
fi->flags = (*it).shareflags ;
sList.push_back(fi);
}
return sList;
}
bool ftFiMonitor::loadList(std::list<RsItem *> load)
{
/* for each item, check it exists ....
* - remove any that are dead (or flag?)
*/
#ifdef DEBUG_ELIST
std::cerr << "ftFiMonitor::loadList()";
std::cerr << std::endl;
#endif
std::list<SharedDirInfo> dirList;
std::list<RsItem *>::iterator it;
for(it = load.begin(); it != load.end(); it++)
{
RsFileConfigItem *fi = dynamic_cast<RsFileConfigItem *>(*it);
if (!fi)
{
delete (*it);
continue;
}
/* ensure that it exists? */
SharedDirInfo info ;
info.filename = fi->file.path;
info.shareflags = fi->flags & (RS_FILE_HINTS_BROWSABLE | RS_FILE_HINTS_NETWORK_WIDE) ;
dirList.push_back(info) ;
}
/* set directories */
setSharedDirectories(dirList);
return true;
}
void ftFiMonitor::updateShareFlags(const SharedDirInfo& info)
{
FileIndexMonitor::updateShareFlags(info);
/* flag for config */
IndicateConfigChanged();
}
void ftFiMonitor::setSharedDirectories(std::list<SharedDirInfo> dirList)
{
FileIndexMonitor::setSharedDirectories(dirList);
/* flag for config */
IndicateConfigChanged();
}
ftCacheStrapper::ftCacheStrapper(p3ConnectMgr *cm)
:CacheStrapper(cm)
{
return;
}
/* overloaded search function */
bool ftCacheStrapper::search(std::string hash, uint32_t hintflags, FileInfo &info) const
{
#ifdef DB_DEBUG
std::cerr << "ftCacheStrapper::search(" << hash << "," << hintflags;
std::cerr << ")";
std::cerr << std::endl;
#endif
CacheData data;
if (findCache(hash, data))
{
#ifdef DB_DEBUG
std::cerr << "ftCacheStrapper::search() found: ";
std::cerr << data.path << "/" << data.name;
std::cerr << " = " << data.hash << "," << data.size;
std::cerr << std::endl;
#endif
/* ... */
info.size = data.size;
info.fname = data.name;
info.path = data.path + "/" + data.name;
return true;
}
return false;
}