Completed Basic configuration storage:

* Added read/writetofile() fns to BinMemInterface
 * Added SignData() fns to AuthXPGP.
 * Added Certificate saving to AuthXPGP.
 * added Signatures to Configuration.
 * now discards messages if Hash is wrong (p3msgservice)



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@341 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2008-02-08 12:39:40 +00:00
parent 08d3634d28
commit 3e1b155f1a
12 changed files with 353 additions and 39 deletions

View File

@ -82,7 +82,7 @@ xpgpcert::xpgpcert(XPGP *xpgp, std::string pid)
AuthXPGP::AuthXPGP()
:init(0), sslctx(NULL), pkey(NULL)
:init(0), sslctx(NULL), pkey(NULL), mToSaveCerts(false), mConfigSaveActive(true)
{
}
@ -679,6 +679,9 @@ bool AuthXPGP::TrustCertificate(std::string id, bool totrust)
/* reevaluate the auth of the xpgp */
cert->trustLvl = XPGP_auth_certificate(pgp_keyring, cert->certificate);
valid = true;
/* resave if changed trust setting */
mToSaveCerts = true;
}
xpgpMtx.unlock(); /**** UNLOCK ****/
@ -755,9 +758,63 @@ bool AuthXPGP::AuthCertificate(std::string id)
}
/* Sign / Encrypt / Verify Data (TODO) */
bool AuthXPGP::SignData(std::string input, std::string &sign)
{
return SignData(input.c_str(), input.length(), sign);
}
bool AuthXPGP::SignData(const void *data, const uint32_t len, std::string &sign)
{
RsStackMutex stack(xpgpMtx); /***** STACK LOCK MUTEX *****/
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
unsigned int signlen = EVP_PKEY_size(pkey);
unsigned char signature[signlen];
if (0 == EVP_SignInit(mdctx, EVP_sha1()))
{
std::cerr << "EVP_SignInit Failure!" << std::endl;
EVP_MD_CTX_destroy(mdctx);
return false;
}
if (0 == EVP_SignUpdate(mdctx, data, len))
{
std::cerr << "EVP_SignUpdate Failure!" << std::endl;
EVP_MD_CTX_destroy(mdctx);
return false;
}
if (0 == EVP_SignFinal(mdctx, signature, &signlen, pkey))
{
std::cerr << "EVP_SignFinal Failure!" << std::endl;
EVP_MD_CTX_destroy(mdctx);
return false;
}
EVP_MD_CTX_destroy(mdctx);
sign.clear();
std::ostringstream out;
out << std::hex;
for(uint32_t i = 0; i < signlen; i++)
{
out << std::setw(2) << std::setfill('0');
out << (uint32_t) (signature[i]);
}
sign = out.str();
return true;
}
/**** NEW functions we've added ****/
@ -1119,6 +1176,8 @@ bool AuthXPGP::ProcessXPGP(XPGP *xpgp, std::string &id)
cert->signers = getXPGPsigners(xpgp);
/* resave if new certificate */
mToSaveCerts = true;
xpgpMtx.unlock(); /**** UNLOCK ****/
id = xpgpid;
@ -1592,6 +1651,33 @@ int printSSLError(SSL *ssl, int retval, int err, unsigned long err2,
*
*/
bool AuthXPGP::FinalSaveCertificates()
{
CheckSaveCertificates();
RsStackMutex stack(xpgpMtx); /***** LOCK *****/
mConfigSaveActive = false;
return true;
}
bool AuthXPGP::CheckSaveCertificates()
{
xpgpMtx.lock(); /***** LOCK *****/
if ((mConfigSaveActive) && (mToSaveCerts))
{
mToSaveCerts = false;
xpgpMtx.unlock(); /**** UNLOCK ****/
saveCertificates();
return true;
}
xpgpMtx.unlock(); /**** UNLOCK ****/
return false;
}
bool AuthXPGP::saveCertificates()
{
// construct file name.
@ -1605,6 +1691,12 @@ bool AuthXPGP::saveCertificates()
xpgpMtx.unlock(); /**** UNLOCK ****/
/* add on the slash */
if (neighdir != "")
{
neighdir += "/";
}
std::map<std::string, std::string>::iterator mit;
std::string conftxt;
@ -1989,6 +2081,7 @@ bool AuthXPGP::loadCertificates(bool &oldFormat, std::map<std::string, std::s
oldFormat = true;
}
mToSaveCerts = false;
return true;
}

View File

@ -103,6 +103,8 @@ virtual std::string getName(std::string id);
virtual bool getDetails(std::string id, pqiAuthDetails &details);
/* High Level Load/Save Configuration */
virtual bool FinalSaveCertificates();
virtual bool CheckSaveCertificates();
virtual bool saveCertificates();
virtual bool loadCertificates();
@ -123,7 +125,8 @@ virtual bool RevokeCertificate(std::string id);
virtual bool TrustCertificate(std::string id, bool trust);
/* Sign / Encrypt / Verify Data (TODO) */
virtual bool SignData(std::string input, std::string &sign);
virtual bool SignData(const void *data, const uint32_t len, std::string &sign);
/*********** Overloaded Functions from p3AuthMgr **********/
@ -169,6 +172,8 @@ bool locked_FindCert(std::string id, xpgpcert **cert);
xpgpcert *mOwnCert;
EVP_PKEY *pkey;
bool mToSaveCerts;
bool mConfigSaveActive;
std::map<std::string, xpgpcert *> mCerts;
};

View File

@ -187,6 +187,16 @@ bool p3DummyAuthMgr::getDetails(std::string id, pqiAuthDetails &details)
return false;
}
bool p3DummyAuthMgr::FinalSaveCertificates()
{
return false;
}
bool p3DummyAuthMgr::CheckSaveCertificates()
{
return false;
}
bool p3DummyAuthMgr::saveCertificates()
{
return false;
@ -248,3 +258,14 @@ bool p3DummyAuthMgr::TrustCertificate(std::string id, bool trust)
return false;
}
bool p3DummyAuthMgr::SignData(std::string input, std::string &sign)
{
return false;
}
bool p3DummyAuthMgr::SignData(const void *data, const uint32_t len, std::string &sign)
{
return false;
}

View File

@ -96,6 +96,8 @@ virtual std::string getName(std::string id) = 0;
virtual bool getDetails(std::string id, pqiAuthDetails &details) = 0;
/* High Level Load/Save Configuration */
virtual bool FinalSaveCertificates() = 0;
virtual bool CheckSaveCertificates() = 0;
virtual bool saveCertificates() = 0;
virtual bool loadCertificates() = 0;
@ -119,10 +121,11 @@ virtual bool RevokeCertificate(std::string id) = 0;
virtual bool TrustCertificate(std::string id, bool trust) = 0;
/* Sign / Encrypt / Verify Data (TODO) */
virtual bool SignData(std::string input, std::string &sign) = 0;
virtual bool SignData(const void *data, const uint32_t len, std::string &sign) = 0;
//virtual bool encryptData(std::string recipientId, std::string plaindata, std::string &result);
};
@ -155,6 +158,8 @@ virtual std::string getName(std::string id);
virtual bool getDetails(std::string id, pqiAuthDetails &details);
/* High Level Load/Save Configuration */
virtual bool FinalSaveCertificates();
virtual bool CheckSaveCertificates();
virtual bool saveCertificates();
virtual bool loadCertificates();
@ -173,6 +178,8 @@ virtual bool SignCertificate(std::string id);
virtual bool RevokeCertificate(std::string id);
virtual bool TrustCertificate(std::string id, bool trust);
virtual bool SignData(std::string input, std::string &sign);
virtual bool SignData(const void *data, const uint32_t len, std::string &sign);
std::string mOwnId;
std::map<std::string, pqiAuthDetails> mPeerList;

View File

@ -25,6 +25,7 @@
#include "pqi/p3cfgmgr.h"
#include "pqi/p3authmgr.h"
#include "pqi/pqibin.h"
#include "pqi/pqistreamer.h"
@ -32,8 +33,8 @@
#define CONFIG_DEBUG 1
p3ConfigMgr::p3ConfigMgr(std::string dir, std::string fname, std::string signame)
:basedir(dir), metafname(fname), metasigfname(signame),
p3ConfigMgr::p3ConfigMgr(p3AuthMgr *am, std::string dir, std::string fname, std::string signame)
:mAuthMgr(am), basedir(dir), metafname(fname), metasigfname(signame),
mConfigSaveActive(true)
{
@ -108,6 +109,12 @@ void p3ConfigMgr::saveConfiguration()
std::cerr << it->first << " Hash: " << it->second->Hash();
std::cerr << std::endl;
#endif
if (it->second->Hash() == "")
{
/* skip if no hash */
continue;
}
RsTlvKeyValue kv;
{
std::ostringstream out;
@ -126,23 +133,47 @@ void p3ConfigMgr::saveConfiguration()
#endif
/* Write the data to a stream */
uint32_t bioflags = BIN_FLAGS_HASH_DATA | BIN_FLAGS_WRITEABLE;
BinInterface *bio = new BinFileInterface(metafname.c_str(), bioflags);
uint32_t bioflags = BIN_FLAGS_WRITEABLE;
BinMemInterface *membio = new BinMemInterface(1000, bioflags);
RsSerialiser *rss = new RsSerialiser();
rss->addSerialType(new RsGeneralConfigSerialiser());
pqistreamer stream(rss, "CONFIG", bio, 0);
pqistreamer stream(rss, "CONFIG", membio, 0);
stream.SendItem(item);
stream.tick();
stream.tick();
/* get hash */
std::string totalhash = bio->gethash();
/* sign data */
std::string signature;
mAuthMgr->SignData(membio->memptr(), membio->memsize(), signature);
/* sign the hash of the data */
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::saveConfiguration() MetaFile Signature:";
std::cerr << std::endl;
std::cerr << signature;
std::cerr << std::endl;
#endif
if (!membio->writetofile(metafname.c_str()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::saveConfiguration() Failed to Write MetaFile";
std::cerr << std::endl;
#endif
}
/* write signature to configuration */
BinMemInterface *signbio = new BinMemInterface(signature.c_str(),
signature.length(), BIN_FLAGS_READABLE);
if (!signbio->writetofile(metasigfname.c_str()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::saveConfiguration() Failed to Write MetaSignFile";
std::cerr << std::endl;
#endif
}
}
@ -156,13 +187,63 @@ void p3ConfigMgr::loadConfiguration()
std::cerr << std::endl;
#endif
/* Write the data to a stream */
uint32_t bioflags = BIN_FLAGS_HASH_DATA | BIN_FLAGS_READABLE;
BinInterface *bio = new BinFileInterface(metafname.c_str(), bioflags);
/* write signature to configuration */
BinMemInterface *signbio = new BinMemInterface(1000, BIN_FLAGS_READABLE);
if (!signbio->readfromfile(metasigfname.c_str()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() Failed to Load MetaSignFile";
std::cerr << std::endl;
#endif
}
std::string oldsignature((char *) signbio->memptr(), signbio->memsize());
delete signbio;
BinMemInterface *membio = new BinMemInterface(1000, BIN_FLAGS_READABLE);
if (!membio->readfromfile(metafname.c_str()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() Failed to Load MetaFile";
std::cerr << std::endl;
#endif
delete membio;
}
/* get signature */
std::string signature;
mAuthMgr->SignData(membio->memptr(), membio->memsize(), signature);
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() New MetaFile Signature:";
std::cerr << std::endl;
std::cerr << signature;
std::cerr << std::endl;
#endif
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() Orig MetaFile Signature:";
std::cerr << std::endl;
std::cerr << oldsignature;
std::cerr << std::endl;
#endif
if (signature != oldsignature)
{
/* Failed */
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() Signature Check Failed";
std::cerr << std::endl;
#endif
return;
}
membio->fseek(0); /* go to start */
RsSerialiser *rss = new RsSerialiser();
rss->addSerialType(new RsGeneralConfigSerialiser());
pqistreamer stream(rss, "CONFIG", bio, 0);
pqistreamer stream(rss, "CONFIG", membio, 0);
stream.tick();
stream.tick();
@ -182,12 +263,6 @@ void p3ConfigMgr::loadConfiguration()
#endif
std::string totalhash = bio->gethash();
/* check it TODO */
/* sign the hash of the data */
/* check signature with configuration */
/* extract info from KeyValueSet */
std::list<RsTlvKeyValue>::iterator it;
for(it = item->tlvkvs.pairs.begin(); it != item->tlvkvs.pairs.end(); it++)
@ -300,6 +375,8 @@ bool p3Config::loadConfiguration(std::string &loadHash)
{
delete (*it);
}
setHash("");
return false;
}

View File

@ -64,6 +64,7 @@ const uint32_t CONFIG_TYPE_FSERVER = 0x0003;
const uint32_t CONFIG_TYPE_MSGS = 0x0004;
class p3ConfigMgr;
class p3AuthMgr;
class pqiConfig
{
@ -111,7 +112,7 @@ bool HasConfigChanged(uint16_t idx);
class p3ConfigMgr
{
public:
p3ConfigMgr(std::string bdir, std::string fname, std::string signame);
p3ConfigMgr(p3AuthMgr *am, std::string bdir, std::string fname, std::string signame);
void tick();
void saveConfiguration();
@ -127,6 +128,8 @@ void completeConfiguration();
/* these are constants - so shouldn't need mutex */
p3AuthMgr *mAuthMgr;
const std::string basedir;
const std::string metafname;
const std::string metasigfname;

View File

@ -35,23 +35,23 @@ BinFileInterface::BinFileInterface(const char *fname, int flags)
if ((bin_flags & BIN_FLAGS_READABLE) &&
(bin_flags & BIN_FLAGS_WRITEABLE))
{
buf = fopen(fname, "r+");
buf = fopen(fname, "rb+");
/* if the file don't exist */
if (!buf)
{
buf = fopen(fname, "w+");
buf = fopen(fname, "wb+");
}
}
else if (bin_flags & BIN_FLAGS_READABLE)
{
buf = fopen(fname, "r");
buf = fopen(fname, "rb");
}
else if (bin_flags & BIN_FLAGS_WRITEABLE)
{
// This is enough to remove old file in Linux...
// but not in windows.... (what to do)
buf = fopen(fname, "w");
buf = fopen(fname, "wb");
fflush(buf); /* this might help windows! */
}
else
@ -155,6 +155,23 @@ BinMemInterface::BinMemInterface(int defsize, int flags)
}
}
BinMemInterface::BinMemInterface(const void *data, const int defsize, int flags)
:bin_flags(flags), buf(NULL), size(defsize),
recvsize(0), readloc(0), hash(NULL), bcount(0)
{
buf = malloc(defsize);
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash = new pqihash();
}
/* just remove the const
* *BAD* but senddata don't change it anyway
*/
senddata((void *) data, defsize);
}
BinMemInterface::~BinMemInterface()
{
if (buf)
@ -174,7 +191,7 @@ int BinMemInterface::fseek(int loc)
}
int BinMemInterface::senddata(void *data, int len)
int BinMemInterface::senddata(void *data, const int len)
{
if(recvsize + len > size)
{
@ -231,6 +248,64 @@ uint64_t BinMemInterface::bytecount()
return 0;
}
bool BinMemInterface::writetofile(const char *fname)
{
FILE *fd = fopen(fname, "wb");
if (!fd)
{
return false;
}
if (1 != fwrite(buf, recvsize, 1, fd))
{
fclose(fd);
return false;
}
fclose(fd);
return true;
}
bool BinMemInterface::readfromfile(const char *fname)
{
FILE *fd = fopen(fname, "rb");
if (!fd)
{
return false;
}
/* get size */
::fseek(fd, 0L, SEEK_END);
int fsize = ftell(fd);
if (fsize > size)
{
/* not enough room */
std::cerr << "BinMemInterface::readfromfile() not enough room";
std::cerr << std::endl;
fclose(fd);
return false;
}
::fseek(fd, 0L, SEEK_SET);
if (1 != fread(buf, fsize, 1, fd))
{
/* not enough room */
std::cerr << "BinMemInterface::readfromfile() failed fread";
std::cerr << std::endl;
fclose(fd);
return false;
}
recvsize = fsize;
readloc = 0;
fclose(fd);
return true;
}
/**************************************************************************/
@ -448,4 +523,3 @@ std::string NetBinDummy::gethash()
return std::string("");
}

View File

@ -76,12 +76,18 @@ class BinMemInterface: public BinInterface
{
public:
BinMemInterface(int defsize, int flags);
BinMemInterface(const void *data, const int size, int flags);
virtual ~BinMemInterface();
/* Extra Interfaces */
int fseek(int loc);
int memsize() { return recvsize; }
void *memptr() { return buf; }
/* file interface */
bool writetofile(const char *fname);
bool readfromfile(const char *fname);
virtual int tick() { return 1; }
virtual int senddata(void *data, int len);

View File

@ -335,6 +335,8 @@ void RsServer::ConfigFinalSave()
{
/* force saving of transfers */
server->saveFileTransferStatus();
mAuthMgr->FinalSaveCertificates();
mConfigMgr->completeConfiguration();
}

View File

@ -243,6 +243,9 @@ void RsServer::run()
/* force saving FileTransferStatus */
server->saveFileTransferStatus();
/* see if we need to resave certs */
mAuthMgr->CheckSaveCertificates();
/* hour loop */
if (++min >= 60)
{

View File

@ -498,7 +498,7 @@ int RsServer::StartupRetroShare(RsInit *config)
server->setSaveDir(config->homePath.c_str()); /* Default Save Dir - config will overwrite */
server->setSearchInterface(pqih, mAuthMgr, mConnMgr);
mConfigMgr = new p3ConfigMgr(config->basedir, "rs-v0.4.cfg", "rs-v0.4.sgn");
mConfigMgr = new p3ConfigMgr(mAuthMgr, config->basedir, "rs-v0.4.cfg", "rs-v0.4.sgn");
mGeneralConfig = new p3GeneralConfig();
@ -551,6 +551,8 @@ int RsServer::StartupRetroShare(RsInit *config)
if (oldFormat)
{
std::cerr << "Startup() Loaded Old Certificate Format" << std::endl;
/* transfer all authenticated peers to friend list */
std::list<std::string> authIds;
mAuthMgr->getAuthenticatedList(authIds);

View File

@ -328,20 +328,41 @@ bool p3MsgService::loadConfiguration(std::string &loadHash)
std::string hashin = in->gethash();
delete pa_in;
if (hashin != loadHash)
{
/* big error message! */
std::cerr << "p3MsgService::loadConfiguration() FAILED!" << std::endl;
std::cerr << "p3MsgService::loadConfiguration() FAILED!" << std::endl;
std::cerr << "p3MsgService::loadConfiguration() FAILED!" << std::endl;
std::cerr << "p3MsgService::loadConfiguration() FAILED!" << std::endl;
std::cerr << "p3MsgService::loadConfiguration() FAILED!" << std::endl;
std::cerr << "p3MsgService::loadConfiguration() FAILED! Msgs Tampered" << std::endl;
std::string msgfileold = msgfile + ".failed";
rename(msgfile.c_str(), msgfileold.c_str());
std::cerr << "Moving Old file to: " << msgfileold << std::endl;
std::cerr << "removing dodgey msgs" << std::endl;
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
std::map<uint32_t, RsMsgItem *>::iterator mit;
for(mit = imsg.begin(); mit != imsg.end(); mit++)
{
delete (mit->second);
}
imsg.clear();
for(mit = msgOutgoing.begin(); mit != msgOutgoing.end(); mit++)
{
delete (mit->second);
}
msgOutgoing.clear();
setHash("");
return false;
}
setHash(hashin);
delete pa_in;
return true;
}