mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-23 22:49:37 -05:00
Major bugfixes to get PGP authentication finished.
* p3disc now exchanges "Issuer" (pgp) certificates as well. * additional types for rsdiscitems.h * Bug Fix for NULL packet in p3service.cc * allow unauthed SSL certificates to be added in AuthSSL - otherwise cant add new friends! * only save authed SSL certificates. * fixed ref/unref of PGP keys in AuthGPG * added Mutex protection to AuthGPG * added PGP reloading when key is imported, or signed. * Fixed PGP key signing. * added Additional field validLvl to RsPeerDetails. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1270 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
aeb07b4ce5
commit
d4b52a59e5
@ -49,6 +49,8 @@
|
||||
* AuthCertificate().
|
||||
* check isPGPAuthenticated().
|
||||
* if not - sign PGP certificate.
|
||||
*
|
||||
* access to local data is protected via pgpMtx.
|
||||
*/
|
||||
|
||||
#include "authgpg.h"
|
||||
@ -81,8 +83,19 @@ p3AuthMgr *getAuthMgr()
|
||||
return &instance_gpgroot;
|
||||
}
|
||||
|
||||
gpgcert::gpgcert()
|
||||
:key(NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
gpgcert::~gpgcert()
|
||||
{
|
||||
if (key)
|
||||
{
|
||||
gpgme_key_unref(key);
|
||||
}
|
||||
}
|
||||
|
||||
gpg_error_t pgp_pwd_callback(void *hook, const char *uid_hint, const char *passphrase_info, int prev_was_bad, int fd)
|
||||
{
|
||||
@ -101,7 +114,7 @@ gpg_error_t pgp_pwd_callback(void *hook, const char *uid_hint, const char *passp
|
||||
|
||||
static char *PgpPassword = NULL;
|
||||
|
||||
bool GPGAuthMgr::setPGPPassword(std::string pwd)
|
||||
bool GPGAuthMgr::setPGPPassword_locked(std::string pwd)
|
||||
{
|
||||
/* reset it while we change it */
|
||||
gpgme_set_passphrase_cb(CTX, NULL, NULL);
|
||||
@ -121,6 +134,7 @@ bool GPGAuthMgr::setPGPPassword(std::string pwd)
|
||||
GPGAuthMgr::GPGAuthMgr()
|
||||
:gpgmeInit(false)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
gpgme_check_version(NULL);
|
||||
@ -163,11 +177,9 @@ GPGAuthMgr::GPGAuthMgr()
|
||||
/* if we get to here -> we have inited okay */
|
||||
gpgmeInit = true;
|
||||
|
||||
storeAllKeys();
|
||||
printAllKeys();
|
||||
updateTrustAllKeys();
|
||||
|
||||
|
||||
storeAllKeys_locked();
|
||||
printAllKeys_locked();
|
||||
updateTrustAllKeys_locked();
|
||||
}
|
||||
|
||||
/* This function is called when retroshare is first started
|
||||
@ -180,6 +192,8 @@ GPGAuthMgr::GPGAuthMgr()
|
||||
|
||||
bool GPGAuthMgr::availablePGPCertificates(std::list<std::string> &ids)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
int i = 0;
|
||||
gpgme_key_t KEY = NULL;
|
||||
gpg_error_t ERR;
|
||||
@ -214,9 +228,6 @@ bool GPGAuthMgr::availablePGPCertificates(std::list<std::string> &ids)
|
||||
std::cerr << "GPGAuthMgr::availablePGPCertificates() Missing subkey"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
/* release key */
|
||||
gpgme_key_release (KEY);
|
||||
}
|
||||
|
||||
if (GPG_ERR_NO_ERROR != gpgme_op_keylist_end(CTX))
|
||||
@ -241,9 +252,8 @@ bool GPGAuthMgr::availablePGPCertificates(std::list<std::string> &ids)
|
||||
*/
|
||||
int GPGAuthMgr::GPGInit(std::string ownId, std::string name, std::string passphrase)
|
||||
{
|
||||
/* For now, I'll just load the key from the keyring and create the
|
||||
* self certificate. Passphrase verification needs to be done
|
||||
*/
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
gpgme_key_t newKey;
|
||||
gpg_error_t ERR;
|
||||
|
||||
@ -269,16 +279,20 @@ int GPGAuthMgr::GPGInit(std::string ownId, std::string name, std::string passphr
|
||||
mOwnGpgCert.user.id = ownId;
|
||||
mOwnGpgCert.key = newKey;
|
||||
this->passphrase = passphrase;
|
||||
setPGPPassword(passphrase);
|
||||
|
||||
mOwnId = ownId;
|
||||
gpgmeKeySelected = true;
|
||||
|
||||
setPGPPassword_locked(passphrase);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int GPGAuthMgr::GPGInit(std::string name, std::string comment,
|
||||
std::string email, std::string passphrase)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
gpgme_key_t newKey;
|
||||
gpgme_genkey_result_t result;
|
||||
gpg_error_t ERR;
|
||||
@ -309,7 +323,7 @@ int GPGAuthMgr::GPGInit(std::string name, std::string comment,
|
||||
mOwnGpgCert.key = newKey;
|
||||
|
||||
this->passphrase = passphrase;
|
||||
setPGPPassword(passphrase);
|
||||
setPGPPassword_locked(passphrase);
|
||||
|
||||
mOwnId = mOwnGpgCert.user.id;
|
||||
gpgmeKeySelected = true;
|
||||
@ -323,9 +337,9 @@ int GPGAuthMgr::GPGInit(std::string name, std::string comment,
|
||||
|
||||
|
||||
// store all keys in map mKeyList to avoid callin gpgme exe repeatedly
|
||||
bool GPGAuthMgr::storeAllKeys()
|
||||
bool GPGAuthMgr::storeAllKeys_locked()
|
||||
{
|
||||
std::cerr << "GPGAuthMgr::storeAllKeys()";
|
||||
std::cerr << "GPGAuthMgr::storeAllKeys_locked()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
gpg_error_t ERR;
|
||||
@ -335,6 +349,10 @@ bool GPGAuthMgr::storeAllKeys()
|
||||
std::cerr << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cerr << "GPGAuthMgr::storeAllKeys_locked() clearing existing ones";
|
||||
std::cerr << std::endl;
|
||||
mKeyList.clear();
|
||||
|
||||
/* enable SIG mode */
|
||||
gpgme_keylist_mode_t origmode = gpgme_get_keylist_mode(CTX);
|
||||
@ -453,14 +471,15 @@ bool GPGAuthMgr::storeAllKeys()
|
||||
|
||||
nu.user.trustLvl = KEY->owner_trust;
|
||||
nu.user.ownsign = KEY->can_sign;
|
||||
nu.user.validLvl = mainuid->validity;
|
||||
nu.user.trusted = (mainuid->validity > GPGME_VALIDITY_MARGINAL);
|
||||
|
||||
/* grab a reference, so the key remains */
|
||||
gpgme_key_ref(KEY);
|
||||
nu.key = KEY;
|
||||
|
||||
/* store in map */
|
||||
mKeyList[nu.user.id] = nu;
|
||||
|
||||
/* release key */
|
||||
//gpgme_key_release (KEY);
|
||||
}
|
||||
|
||||
if (GPG_ERR_NO_ERROR != gpgme_op_keylist_end(CTX))
|
||||
@ -477,7 +496,7 @@ bool GPGAuthMgr::storeAllKeys()
|
||||
}
|
||||
|
||||
// update trust on all available keys.
|
||||
bool GPGAuthMgr::updateTrustAllKeys()
|
||||
bool GPGAuthMgr::updateTrustAllKeys_locked()
|
||||
{
|
||||
gpg_error_t ERR;
|
||||
if (!gpgmeInit)
|
||||
@ -530,31 +549,6 @@ bool GPGAuthMgr::updateTrustAllKeys()
|
||||
std::cerr << " Name: " << ti->name;
|
||||
std::cerr << std::endl;
|
||||
|
||||
#if 0
|
||||
if (
|
||||
|
||||
|
||||
/* store in pqiAuthDetails */
|
||||
gpgcert nu;
|
||||
nu.user.id = (KEY->subkeys) ? KEY->subkeys->keyid : NULL;
|
||||
nu.user.fpr= (KEY->subkeys) ? KEY->subkeys->fpr : NULL;
|
||||
nu.user.name = (KEY->uids) ? KEY->uids->name : NULL;
|
||||
nu.user.email = (KEY->uids) ? KEY->uids->email : NULL;
|
||||
// nu.user.location = "here";
|
||||
// nu.user.org = "me.com";
|
||||
|
||||
nu.user.trustLvl = KEY->owner_trust;
|
||||
nu.user.ownsign = KEY->can_sign;
|
||||
nu.user.trusted = KEY->can_certify;
|
||||
|
||||
nu.key = KEY;
|
||||
/* store in map */
|
||||
mKeyList[nu.user.id] = nu;
|
||||
|
||||
/* release key */
|
||||
//gpgme_key_release (KEY);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
std::cerr << "End of TrustList Iteration.";
|
||||
@ -573,8 +567,9 @@ bool GPGAuthMgr::updateTrustAllKeys()
|
||||
return true;
|
||||
|
||||
}
|
||||
bool GPGAuthMgr::printAllKeys()
|
||||
bool GPGAuthMgr::printAllKeys_locked()
|
||||
{
|
||||
|
||||
certmap::const_iterator it;
|
||||
for(it = mKeyList.begin(); it != mKeyList.end(); it++)
|
||||
{
|
||||
@ -590,7 +585,7 @@ bool GPGAuthMgr::printAllKeys()
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "\townsign?: " << it->second.user.ownsign;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "\ttrusted?: " << it->second.user.trusted;
|
||||
std::cerr << "\ttrusted/valid: " << it->second.user.trusted;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "\tEmail: " << it->second.user.email;
|
||||
std::cerr << std::endl;
|
||||
@ -615,8 +610,9 @@ bool GPGAuthMgr::printAllKeys()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GPGAuthMgr::printOwnKeys()
|
||||
bool GPGAuthMgr::printOwnKeys_locked()
|
||||
{
|
||||
|
||||
certmap::iterator it;
|
||||
for(it = mKeyList.begin(); it != mKeyList.end(); it++)
|
||||
{
|
||||
@ -637,6 +633,8 @@ bool GPGAuthMgr::printOwnKeys()
|
||||
|
||||
X509 *GPGAuthMgr::SignX509Req(X509_REQ *req, long days, std::string gpg_passwd)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
/* Transform the X509_REQ into a suitable format to
|
||||
* generate DIGEST hash. (for SSL to do grunt work)
|
||||
*/
|
||||
@ -809,7 +807,7 @@ X509 *GPGAuthMgr::SignX509Req(X509_REQ *req, long days, std::string gpg_passwd)
|
||||
std::cerr << "Digest Applied: len: " << hashoutl << std::endl;
|
||||
|
||||
/* NOW Sign via GPG Functions */
|
||||
if (!DoOwnSignature(buf_hashout, hashoutl, buf_sigout, (unsigned int *) &sigoutl))
|
||||
if (!DoOwnSignature_locked(buf_hashout, hashoutl, buf_sigout, (unsigned int *) &sigoutl))
|
||||
{
|
||||
sigoutl = 0;
|
||||
goto err;
|
||||
@ -862,6 +860,8 @@ X509 *GPGAuthMgr::SignX509Req(X509_REQ *req, long days, std::string gpg_passwd)
|
||||
|
||||
bool GPGAuthMgr::AuthX509(X509 *x509)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
/* extract CN for peer Id */
|
||||
X509_NAME *issuer = X509_get_issuer_name(x509);
|
||||
std::string id = "";
|
||||
@ -931,7 +931,7 @@ bool GPGAuthMgr::AuthX509(X509 *x509)
|
||||
memmove(buf_sigout, signature->data, sigoutl);
|
||||
|
||||
/* NOW Sign via GPG Functions */
|
||||
if (!VerifySignature(id, buf_hashout, hashoutl, buf_sigout, (unsigned int) sigoutl))
|
||||
if (!VerifySignature_locked(id, buf_hashout, hashoutl, buf_sigout, (unsigned int) sigoutl))
|
||||
{
|
||||
sigoutl = 0;
|
||||
goto err;
|
||||
@ -981,7 +981,7 @@ void print_pgpme_verify_summary(unsigned int summary)
|
||||
}
|
||||
|
||||
|
||||
bool GPGAuthMgr::DoOwnSignature(void *data, unsigned int datalen, void *buf_sigout, unsigned int *outl)
|
||||
bool GPGAuthMgr::DoOwnSignature_locked(void *data, unsigned int datalen, void *buf_sigout, unsigned int *outl)
|
||||
{
|
||||
/* setup signers */
|
||||
gpgme_signers_clear(CTX);
|
||||
@ -1044,8 +1044,9 @@ bool GPGAuthMgr::DoOwnSignature(void *data, unsigned int datalen, void *buf_sigo
|
||||
|
||||
/* now extract the data from gpgmeSig */
|
||||
size_t len = 0;
|
||||
int len2 = len;
|
||||
char *export_sig = gpgme_data_release_and_get_mem(gpgmeSig, &len);
|
||||
fprintf(stderr, "GPGAuthMgr::Signature len: %ld \n", len);
|
||||
fprintf(stderr, "GPGAuthMgr::Signature len: %d \n", len2);
|
||||
if (len < *outl)
|
||||
{
|
||||
*outl = len;
|
||||
@ -1060,7 +1061,7 @@ bool GPGAuthMgr::DoOwnSignature(void *data, unsigned int datalen, void *buf_sigo
|
||||
|
||||
|
||||
/* import to GnuPG and other Certificates */
|
||||
bool GPGAuthMgr::VerifySignature(std::string id, void *data, int datalen,
|
||||
bool GPGAuthMgr::VerifySignature_locked(std::string id, void *data, int datalen,
|
||||
void *sig, unsigned int siglen)
|
||||
{
|
||||
gpgme_data_t gpgmeSig;
|
||||
@ -1139,6 +1140,8 @@ bool GPGAuthMgr::VerifySignature(std::string id, void *data, int datalen,
|
||||
|
||||
bool GPGAuthMgr::active()
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
return ((gpgmeInit) && (gpgmeKeySelected) && (gpgmeX509Selected));
|
||||
}
|
||||
|
||||
@ -1148,6 +1151,7 @@ int GPGAuthMgr::InitAuth(const char *srvr_cert, const char *priv_key,
|
||||
/* Initialise the SSL part */
|
||||
if (AuthSSL::InitAuth(srvr_cert, priv_key, passwd))
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
gpgmeX509Selected = true;
|
||||
return 1;
|
||||
}
|
||||
@ -1230,6 +1234,8 @@ std::string GPGAuthMgr::getName(std::string id)
|
||||
std::string name = AuthSSL::getName(id);
|
||||
if (name != "")
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
certmap::iterator it;
|
||||
if (mKeyList.end() != (it = mKeyList.find(id)))
|
||||
{
|
||||
@ -1248,6 +1254,8 @@ bool GPGAuthMgr::getDetails(std::string id, pqiAuthDetails &details)
|
||||
|
||||
if (AuthSSL::getDetails(id, details))
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
certmap::iterator it;
|
||||
if (mKeyList.end() != (it = mKeyList.find(details.issuer)))
|
||||
{
|
||||
@ -1263,6 +1271,8 @@ bool GPGAuthMgr::getDetails(std::string id, pqiAuthDetails &details)
|
||||
}
|
||||
else
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
/* if we cannot find a ssl cert - might be a pgp cert */
|
||||
certmap::iterator it;
|
||||
if (mKeyList.end() != (it = mKeyList.find(id)))
|
||||
@ -1280,11 +1290,15 @@ bool GPGAuthMgr::getDetails(std::string id, pqiAuthDetails &details)
|
||||
|
||||
std::string GPGAuthMgr::PGPOwnId()
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
return mOwnId;
|
||||
}
|
||||
|
||||
bool GPGAuthMgr::getPGPAllList(std::list<std::string> &ids)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
/* add an id for each pgp certificate */
|
||||
certmap::iterator it;
|
||||
for(it = mKeyList.begin(); it != mKeyList.end(); it++)
|
||||
@ -1296,10 +1310,12 @@ bool GPGAuthMgr::getPGPAllList(std::list<std::string> &ids)
|
||||
|
||||
bool GPGAuthMgr::getPGPAuthenticatedList(std::list<std::string> &ids)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
certmap::iterator it;
|
||||
for(it = mKeyList.begin(); it != mKeyList.end(); it++)
|
||||
{
|
||||
if (it->second.user.trustLvl > GPGME_VALIDITY_MARGINAL)
|
||||
if (it->second.user.trusted)
|
||||
{
|
||||
ids.push_back(it->first);
|
||||
}
|
||||
@ -1309,10 +1325,12 @@ bool GPGAuthMgr::getPGPAuthenticatedList(std::list<std::string> &ids)
|
||||
|
||||
bool GPGAuthMgr::getPGPUnknownList(std::list<std::string> &ids)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
certmap::iterator it;
|
||||
for(it = mKeyList.begin(); it != mKeyList.end(); it++)
|
||||
{
|
||||
if (it->second.user.trustLvl <= GPGME_VALIDITY_MARGINAL)
|
||||
if (!(it->second.user.trusted))
|
||||
{
|
||||
ids.push_back(it->first);
|
||||
}
|
||||
@ -1323,6 +1341,8 @@ bool GPGAuthMgr::getPGPUnknownList(std::list<std::string> &ids)
|
||||
|
||||
bool GPGAuthMgr::isPGPValid(std::string id)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
certmap::iterator it;
|
||||
return (mKeyList.end() != mKeyList.find(id));
|
||||
}
|
||||
@ -1330,10 +1350,16 @@ bool GPGAuthMgr::isPGPValid(std::string id)
|
||||
|
||||
bool GPGAuthMgr::isPGPAuthenticated(std::string id)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
certmap::iterator it;
|
||||
if (mKeyList.end() != (it = mKeyList.find(id)))
|
||||
{
|
||||
return (it->second.user.trustLvl > GPGME_VALIDITY_FULL);
|
||||
/* trustLvl... is just that ... we are interested in validity.
|
||||
* which is the 'trusted' flag.
|
||||
*/
|
||||
|
||||
return (it->second.user.trusted);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -1382,6 +1408,7 @@ bool GPGAuthMgr::loadCertificates()
|
||||
/* SKTAN : do not know how to use std::string id */
|
||||
std::string GPGAuthMgr::SaveCertificateToString(std::string id)
|
||||
{
|
||||
|
||||
if (!isPGPValid(id))
|
||||
{
|
||||
/* check if it is a SSL Certificate */
|
||||
@ -1394,6 +1421,8 @@ std::string GPGAuthMgr::SaveCertificateToString(std::string id)
|
||||
return emptystr;
|
||||
}
|
||||
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
std::string tmp;
|
||||
const char *pattern[] = { NULL, NULL };
|
||||
pattern[0] = id.c_str();
|
||||
@ -1429,6 +1458,7 @@ std::string GPGAuthMgr::SaveCertificateToString(std::string id)
|
||||
/* import to GnuPG and other Certificates */
|
||||
bool GPGAuthMgr::LoadCertificateFromString(std::string str, std::string &id)
|
||||
{
|
||||
|
||||
/* catch SSL Certs and pass to AuthSSL. */
|
||||
std::string sslmarker("-----BEGIN CERTIFICATE-----");
|
||||
size_t pos = str.find(sslmarker);
|
||||
@ -1438,6 +1468,7 @@ bool GPGAuthMgr::LoadCertificateFromString(std::string str, std::string &id)
|
||||
}
|
||||
|
||||
/* otherwise assume it is a PGP cert */
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
gpgme_data_t gpgmeData;
|
||||
if (GPG_ERR_NO_ERROR != gpgme_data_new_from_mem(&gpgmeData, str.c_str(), str.length(), 1))
|
||||
@ -1459,21 +1490,25 @@ bool GPGAuthMgr::LoadCertificateFromString(std::string str, std::string &id)
|
||||
|
||||
gpgme_import_result_t res = gpgme_op_import_result(CTX);
|
||||
|
||||
int imported = res->imported;
|
||||
|
||||
fprintf(stderr, "ImportCertificate(Considered: %d Imported: %d)\n",
|
||||
res->considered, res->imported);
|
||||
|
||||
fflush (NULL);
|
||||
fputs ("Begin Result:\n", stdout);
|
||||
showData (gpgmeData);
|
||||
fputs ("End Result.\n", stdout);
|
||||
|
||||
/* do we need to delete res??? */
|
||||
|
||||
gpgme_data_release (gpgmeData);
|
||||
|
||||
/* extract id(s)! */
|
||||
/* extract id(s)! (only if we actually imported one) */
|
||||
if (imported)
|
||||
{
|
||||
storeAllKeys_locked();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*** These are passed to SSL ****/
|
||||
bool GPGAuthMgr::LoadCertificateFromFile(std::string filename, std::string &id)
|
||||
{
|
||||
return false;
|
||||
@ -1483,14 +1518,15 @@ bool GPGAuthMgr::SaveCertificateToFile(std::string id, std::string filename)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GPGAuthMgr::LoadCertificateFromBinary(const uint8_t *ptr, uint32_t len, std::string &id)
|
||||
{
|
||||
return false;
|
||||
return AuthSSL::LoadCertificateFromBinary(ptr, len, id);
|
||||
}
|
||||
|
||||
bool GPGAuthMgr::SaveCertificateToBinary(std::string id, uint8_t **ptr, uint32_t *len)
|
||||
{
|
||||
return false;
|
||||
return AuthSSL::SaveCertificateToBinary(id, ptr, len);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
@ -1534,14 +1570,28 @@ bool GPGAuthMgr::AuthCertificate(std::string id)
|
||||
/* These take PGP Ids */
|
||||
bool GPGAuthMgr::SignCertificate(std::string id)
|
||||
{
|
||||
|
||||
std::cerr << "GPGAuthMgr::SignCertificate(" << id << ")";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return false;
|
||||
|
||||
if (1 != signCertificate(id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* reload stuff now ... */
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
storeAllKeys_locked();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GPGAuthMgr::RevokeCertificate(std::string id)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
std::cerr << "GPGAuthMgr::RevokeCertificate(" << id << ")";
|
||||
std::cerr << std::endl;
|
||||
|
||||
@ -1550,6 +1600,8 @@ bool GPGAuthMgr::RevokeCertificate(std::string id)
|
||||
|
||||
bool GPGAuthMgr::TrustCertificate(std::string id, bool trust)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
std::cerr << "GPGAuthMgr::TrustCertificate(" << id << "," << trust << ")";
|
||||
std::cerr << std::endl;
|
||||
|
||||
@ -1690,6 +1742,8 @@ int GPGAuthMgr::VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx)
|
||||
|
||||
int GPGAuthMgr::signCertificate(std::string id)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
/* The key should be in Others list and not in Peers list ??
|
||||
* Once the key is signed, it moves from Others to Peers list ???
|
||||
*/
|
||||
@ -1731,11 +1785,15 @@ int GPGAuthMgr::signCertificate(std::string id)
|
||||
/* revoke the signature on Certificate */
|
||||
int GPGAuthMgr::revokeCertificate(std::string id)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GPGAuthMgr::trustCertificate(std::string id, int trustlvl)
|
||||
{
|
||||
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
|
||||
|
||||
/* The certificate should be in Peers list ??? */
|
||||
|
||||
if(!isAuthenticated(id)) {
|
||||
@ -1891,14 +1949,27 @@ static gpgme_key_t getKey(gpgme_ctx_t CTX, std::string name, std::string comment
|
||||
|
||||
while(user != NULL) {
|
||||
if((name.size() && name == user->name) && (comment.size() && comment == user->comment) && \
|
||||
(email.size() && email == user->email)) {
|
||||
(email.size() && email == user->email))
|
||||
{
|
||||
/* grab a reference to the key */
|
||||
gpgme_op_keylist_end(CTX);
|
||||
if (GPG_ERR_NO_ERROR != gpgme_op_keylist_end(CTX))
|
||||
{
|
||||
std::cerr << "Error ending KeyList";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
gpgme_key_ref(key);
|
||||
return key;
|
||||
}
|
||||
user = user->next;
|
||||
}
|
||||
gpgme_key_release (key);
|
||||
}
|
||||
|
||||
|
||||
if (GPG_ERR_NO_ERROR != gpgme_op_keylist_end(CTX))
|
||||
{
|
||||
std::cerr << "Error ending KeyList";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1912,18 +1983,49 @@ static gpg_error_t keySignCallback(void *opaque, gpgme_status_code_t status, \
|
||||
class SignParams *sparams = (class SignParams *)params->oParams;
|
||||
const char *result = NULL;
|
||||
|
||||
fprintf(stderr,"keySignCallback status: %d args: %s, params->state: %d\n", status, args, params->state);
|
||||
|
||||
/* printf stuff out */
|
||||
if (status == GPGME_STATUS_EOF)
|
||||
fprintf(stderr,"keySignCallback GPGME_STATUS_EOF\n");
|
||||
if (status == GPGME_STATUS_GOT_IT)
|
||||
fprintf(stderr,"keySignCallback GPGME_STATUS_GOT_IT\n");
|
||||
if (status == GPGME_STATUS_USERID_HINT)
|
||||
fprintf(stderr,"keySignCallback GPGME_STATUS_USERID_HINT\n");
|
||||
if (status == GPGME_STATUS_NEED_PASSPHRASE)
|
||||
fprintf(stderr,"keySignCallback GPGME_STATUS_NEED_PASSPHRASE\n");
|
||||
if (status == GPGME_STATUS_GOOD_PASSPHRASE)
|
||||
fprintf(stderr,"keySignCallback GPGME_STATUS_GOOD_PASSPHRASE\n");
|
||||
if (status == GPGME_STATUS_BAD_PASSPHRASE)
|
||||
fprintf(stderr,"keySignCallback GPGME_STATUS_BAD_PASSPHRASE\n");
|
||||
|
||||
if (status == GPGME_STATUS_GET_LINE)
|
||||
fprintf(stderr,"keySignCallback GPGME_STATUS_GET_LINE\n");
|
||||
if (status == GPGME_STATUS_GET_BOOL)
|
||||
fprintf(stderr,"keySignCallback GPGME_STATUS_GET_BOOL\n");
|
||||
if (status == GPGME_STATUS_ALREADY_SIGNED)
|
||||
fprintf(stderr,"keySignCallback GPGME_STATUS_ALREADY_SIGNED\n");
|
||||
|
||||
|
||||
if(status == GPGME_STATUS_EOF ||
|
||||
status == GPGME_STATUS_GOT_IT ||
|
||||
status == GPGME_STATUS_USERID_HINT ||
|
||||
status == GPGME_STATUS_NEED_PASSPHRASE ||
|
||||
status == GPGME_STATUS_GOOD_PASSPHRASE ||
|
||||
// status == GPGME_STATUS_GOOD_PASSPHRASE ||
|
||||
status == GPGME_STATUS_BAD_PASSPHRASE) {
|
||||
|
||||
|
||||
fprintf(stderr,"keySignCallback Error status\n");
|
||||
ProcessPGPmeError(params->err);
|
||||
|
||||
return params->err;
|
||||
}
|
||||
|
||||
switch (params->state)
|
||||
{
|
||||
case SIGN_START:
|
||||
fprintf(stderr,"keySignCallback SIGN_START\n");
|
||||
|
||||
if (status == GPGME_STATUS_GET_LINE &&
|
||||
(!std::string("keyedit.prompt").compare(args)))
|
||||
{
|
||||
@ -1937,6 +2039,8 @@ static gpg_error_t keySignCallback(void *opaque, gpgme_status_code_t status, \
|
||||
}
|
||||
break;
|
||||
case SIGN_COMMAND:
|
||||
fprintf(stderr,"keySignCallback SIGN_COMMAND\n");
|
||||
|
||||
if (status == GPGME_STATUS_GET_BOOL &&
|
||||
(!std::string("keyedit.sign_all.okay").compare(args)))
|
||||
{
|
||||
@ -1981,6 +2085,8 @@ static gpg_error_t keySignCallback(void *opaque, gpgme_status_code_t status, \
|
||||
}
|
||||
break;
|
||||
case SIGN_UIDS:
|
||||
fprintf(stderr,"keySignCallback SIGN_UIDS\n");
|
||||
|
||||
if (status == GPGME_STATUS_GET_LINE &&
|
||||
(!std::string("sign_uid.expire").compare(args)))
|
||||
{
|
||||
@ -2013,6 +2119,8 @@ static gpg_error_t keySignCallback(void *opaque, gpgme_status_code_t status, \
|
||||
}
|
||||
break;
|
||||
case SIGN_SET_EXPIRE:
|
||||
fprintf(stderr,"keySignCallback SIGN_SET_EXPIRE\n");
|
||||
|
||||
if (status == GPGME_STATUS_GET_LINE &&
|
||||
(!std::string("sign_uid.class").compare(args)))
|
||||
{
|
||||
@ -2026,6 +2134,8 @@ static gpg_error_t keySignCallback(void *opaque, gpgme_status_code_t status, \
|
||||
}
|
||||
break;
|
||||
case SIGN_SET_CHECK_LEVEL:
|
||||
fprintf(stderr,"keySignCallback SIGN_SET_CHECK_LEVEL\n");
|
||||
|
||||
if (status == GPGME_STATUS_GET_BOOL &&
|
||||
(!std::string("sign_uid.okay").compare(args)))
|
||||
{
|
||||
@ -2039,12 +2149,20 @@ static gpg_error_t keySignCallback(void *opaque, gpgme_status_code_t status, \
|
||||
}
|
||||
break;
|
||||
case SIGN_ENTER_PASSPHRASE:
|
||||
fprintf(stderr,"keySignCallback SIGN_ENTER_PASSPHRASE\n");
|
||||
|
||||
if(status == GPGME_STATUS_GET_HIDDEN &&
|
||||
(!std::string("passphrase.enter").compare(args)))
|
||||
{
|
||||
params->state = SIGN_CONFIRM;
|
||||
result = sparams->passphrase.c_str();
|
||||
}
|
||||
// If using pgp_pwd_callback, then never have to enter passphrase this way.
|
||||
// must catch GOOD_PASSPHRASE to move on.
|
||||
else if (status == GPGME_STATUS_GOOD_PASSPHRASE)
|
||||
{
|
||||
params->state = SIGN_CONFIRM;
|
||||
}
|
||||
else
|
||||
{
|
||||
params->state = SIGN_ERROR;
|
||||
@ -2052,6 +2170,8 @@ static gpg_error_t keySignCallback(void *opaque, gpgme_status_code_t status, \
|
||||
}
|
||||
break;
|
||||
case SIGN_CONFIRM:
|
||||
fprintf(stderr,"keySignCallback SIGN_CONFIRM\n");
|
||||
|
||||
if (status == GPGME_STATUS_GET_LINE &&
|
||||
(!std::string("keyedit.prompt").compare(args)))
|
||||
{
|
||||
@ -2065,6 +2185,8 @@ static gpg_error_t keySignCallback(void *opaque, gpgme_status_code_t status, \
|
||||
}
|
||||
break;
|
||||
case SIGN_QUIT:
|
||||
fprintf(stderr,"keySignCallback SIGN_QUIT\n");
|
||||
|
||||
if (status == GPGME_STATUS_GET_BOOL &&
|
||||
(!std::string("keyedit.save.okay").compare(args)))
|
||||
{
|
||||
@ -2078,6 +2200,8 @@ static gpg_error_t keySignCallback(void *opaque, gpgme_status_code_t status, \
|
||||
}
|
||||
break;
|
||||
case SIGN_ERROR:
|
||||
fprintf(stderr,"keySignCallback SIGN_ERROR\n");
|
||||
|
||||
if (status == GPGME_STATUS_GET_LINE &&
|
||||
(!std::string("keyedit.prompt").compare(args)))
|
||||
{
|
||||
@ -2091,15 +2215,22 @@ static gpg_error_t keySignCallback(void *opaque, gpgme_status_code_t status, \
|
||||
params->err = gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"keySignCallback UNKNOWN state\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
fprintf(stderr,"keySignCallback result:%s\n", result);
|
||||
if (*result)
|
||||
write (fd, result, strlen (result));
|
||||
write (fd, "\n", 1);
|
||||
}
|
||||
|
||||
fprintf(stderr,"keySignCallback Error status\n");
|
||||
ProcessPGPmeError(params->err);
|
||||
|
||||
return params->err;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,9 @@
|
||||
class gpgcert
|
||||
{
|
||||
public:
|
||||
gpgcert();
|
||||
~gpgcert();
|
||||
|
||||
pqiAuthDetails user;
|
||||
gpgme_key_t key;
|
||||
};
|
||||
@ -52,19 +55,30 @@ typedef std::map<std::string, gpgcert> certmap;
|
||||
|
||||
class GPGAuthMgr: public AuthSSL
|
||||
{
|
||||
private:
|
||||
|
||||
/* Internal functions */
|
||||
bool setPGPPassword_locked(std::string pwd);
|
||||
bool DoOwnSignature_locked(void *, unsigned int, void *, unsigned int *);
|
||||
bool VerifySignature_locked(std::string id, void *data, int datalen,
|
||||
void *sig, unsigned int siglen);
|
||||
|
||||
// store all keys in map mKeyList to avoid calling gpgme exe repeatedly
|
||||
bool storeAllKeys_locked();
|
||||
bool updateTrustAllKeys_locked();
|
||||
|
||||
bool printAllKeys_locked();
|
||||
bool printOwnKeys_locked();
|
||||
|
||||
public:
|
||||
|
||||
GPGAuthMgr();
|
||||
~GPGAuthMgr();
|
||||
|
||||
bool setPGPPassword(std::string pwd);
|
||||
|
||||
X509* SignX509Req(X509_REQ *req, long days, std::string);
|
||||
bool AuthX509(X509 *x509);
|
||||
|
||||
bool DoOwnSignature(void *, unsigned int, void *, unsigned int *);
|
||||
bool VerifySignature(std::string id, void *data, int datalen,
|
||||
void *sig, unsigned int siglen);
|
||||
|
||||
bool availablePGPCertificates(std::list<std::string> &ids);
|
||||
|
||||
@ -106,13 +120,6 @@ class GPGAuthMgr: public AuthSSL
|
||||
bool CloseAuth();
|
||||
// int setConfigDirectories(std::string confFile, std::string neighDir);
|
||||
|
||||
// store all keys in map mKeyList to avoid calling gpgme exe repeatedly
|
||||
bool storeAllKeys();
|
||||
bool updateTrustAllKeys();
|
||||
|
||||
bool printAllKeys();
|
||||
bool printOwnKeys();
|
||||
|
||||
|
||||
|
||||
/*********************************************************************************/
|
||||
@ -272,7 +279,8 @@ bool checkSignature(std::string id, std::string hash, std::string signature);
|
||||
|
||||
private:
|
||||
|
||||
/* Example Storage - Change as needed */
|
||||
RsMutex pgpMtx;
|
||||
/* Below is protected via the mutex */
|
||||
|
||||
certmap mKeyList;
|
||||
|
||||
|
@ -1069,8 +1069,11 @@ bool AuthSSL::AuthCertificate(std::string id)
|
||||
|
||||
if (locked_FindCert(id, &cert))
|
||||
{
|
||||
/* ensuring this function can do nothing in PGP mode */
|
||||
#ifdef PQI_USE_SSLONLY
|
||||
cert->authed=true;
|
||||
mToSaveCerts = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
sslMtx.unlock(); /**** UNLOCK ****/
|
||||
@ -1553,18 +1556,20 @@ bool AuthSSL::ProcessX509(X509 *x509, std::string &id)
|
||||
/* extract id */
|
||||
std::string xid;
|
||||
|
||||
bool valid = ValidateCertificate(x509, xid);
|
||||
|
||||
|
||||
if (!ValidateCertificate(x509, xid))
|
||||
if (!valid)
|
||||
{
|
||||
#ifdef AUTHSSL_DEBUG
|
||||
std::cerr << "AuthSSL::ProcessX509() ValidateCertificate FAILED";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* bad certificate */
|
||||
#ifdef PQI_USE_SSLONLY
|
||||
/* bad ( or unknown pgp issuer ) certificate */
|
||||
X509_free(x509);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
sslcert *cert = NULL;
|
||||
@ -1603,6 +1608,7 @@ bool AuthSSL::ProcessX509(X509 *x509, std::string &id)
|
||||
/* check that they are exact */
|
||||
if (0 != X509_cmp(cert->certificate, x509))
|
||||
{
|
||||
|
||||
#ifdef AUTHSSL_DEBUG
|
||||
std::cerr << "AuthSSL::ProcessX509() Not the same: MAJOR ERROR";
|
||||
std::cerr << std::endl;
|
||||
@ -1632,6 +1638,7 @@ bool AuthSSL::ProcessX509(X509 *x509, std::string &id)
|
||||
|
||||
/* if we get here -> its a new certificate */
|
||||
cert = new sslcert(x509, xid);
|
||||
cert->authed = valid;
|
||||
|
||||
sslMtx.lock(); /***** LOCK *****/
|
||||
|
||||
@ -2231,9 +2238,10 @@ bool AuthSSL::saveCertificates()
|
||||
for(it = mCerts.begin(); it != mCerts.end(); it++)
|
||||
{
|
||||
// SAVE ALL CERTS
|
||||
#if 0
|
||||
if (it->second->authed)
|
||||
#if PQI_USE_PQISSL
|
||||
#endif
|
||||
// Save only Authed Certs;
|
||||
if (it->second->authed)
|
||||
{
|
||||
X509 *x509 = it->second->certificate;
|
||||
std::string hash;
|
||||
|
@ -95,8 +95,6 @@ virtual int InitAuth(const char *srvr_cert, const char *priv_key,
|
||||
virtual bool CloseAuth();
|
||||
virtual int setConfigDirectories(std::string confFile, std::string neighDir);
|
||||
|
||||
/* Extra Function SSL only */
|
||||
std::string getIssuerName(std::string id);
|
||||
|
||||
/*********** Overloaded Functions from p3AuthMgr **********/
|
||||
|
||||
@ -112,6 +110,7 @@ virtual bool getUnknownList(std::list<std::string> &ids);
|
||||
virtual bool isValid(std::string id);
|
||||
virtual bool isAuthenticated(std::string id);
|
||||
virtual std::string getName(std::string id);
|
||||
virtual std::string getIssuerName(std::string id);
|
||||
virtual bool getDetails(std::string id, pqiAuthDetails &details);
|
||||
|
||||
/* first party trust info (dummy) */
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "pqi/p3authmgr.h"
|
||||
|
||||
pqiAuthDetails::pqiAuthDetails()
|
||||
:trustLvl(0), ownsign(false), trusted(0)
|
||||
:trustLvl(0), validLvl(0), ownsign(false), trusted(false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -64,9 +64,10 @@ class pqiAuthDetails
|
||||
std::list<std::string> signers;
|
||||
|
||||
uint32_t trustLvl;
|
||||
uint32_t validLvl;
|
||||
|
||||
bool ownsign;
|
||||
bool trusted;
|
||||
bool trusted; // means valid in pgp world.
|
||||
};
|
||||
|
||||
|
||||
@ -95,6 +96,7 @@ virtual bool getUnknownList(std::list<std::string> &ids) = 0;
|
||||
virtual bool isValid(std::string id) = 0;
|
||||
virtual bool isAuthenticated(std::string id) = 0;
|
||||
virtual std::string getName(std::string id) = 0;
|
||||
virtual std::string getIssuerName(std::string id) { return getName(id); } // Default to same id.
|
||||
virtual bool getDetails(std::string id, pqiAuthDetails &details) = 0;
|
||||
|
||||
/* High Level Load/Save Configuration */
|
||||
|
@ -83,6 +83,7 @@ class RsPeerDetails
|
||||
std::list<std::string> signers;
|
||||
|
||||
uint32_t trustLvl;
|
||||
uint32_t validLvl;
|
||||
|
||||
bool ownsign; /* we have signed certificate */
|
||||
bool trusted; /* we trust their signature on others */
|
||||
|
@ -33,7 +33,9 @@
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <gpgme.h>
|
||||
#ifdef RS_USE_PGPSSL
|
||||
#include <gpgme.h>
|
||||
#endif
|
||||
|
||||
/**************** PQI_USE_XPGP ******************/
|
||||
#if defined(PQI_USE_XPGP)
|
||||
@ -306,8 +308,10 @@ bool p3Peers::getPeerDetails(std::string id, RsPeerDetails &d)
|
||||
|
||||
#ifdef RS_USE_PGPSSL
|
||||
d.trustLvl = authDetail.trustLvl;
|
||||
d.validLvl = authDetail.validLvl;
|
||||
#else
|
||||
d.trustLvl = RsPeerTranslateTrust(authDetail.trustLvl);
|
||||
d.validLvl = RsPeerTranslateTrust(authDetail.trustLvl);
|
||||
#endif
|
||||
|
||||
/* generate */
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "serialiser/rsbaseserial.h"
|
||||
#include "util/rsnet.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/* UInt16 get/set */
|
||||
|
||||
bool getRawUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t *out)
|
||||
@ -152,3 +154,55 @@ bool setRawUInt64(void *data, uint32_t size, uint32_t *offset, uint64_t in)
|
||||
|
||||
|
||||
|
||||
bool getRawString(void *data, uint32_t size, uint32_t *offset, std::string &outStr)
|
||||
{
|
||||
uint32_t len = 0;
|
||||
if (!getRawUInt32(data, size, offset, &len))
|
||||
{
|
||||
std::cerr << "getRawString() get size failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check there is space for string */
|
||||
if (size < *offset + len)
|
||||
{
|
||||
std::cerr << "getRawString() not enough size" << std::endl;
|
||||
return false;
|
||||
}
|
||||
uint8_t *buf = &(((uint8_t *) data)[*offset]);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
outStr += buf[i];
|
||||
}
|
||||
|
||||
(*offset) += len;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool setRawString(void *data, uint32_t size, uint32_t *offset, std::string &inStr)
|
||||
{
|
||||
uint32_t len = inStr.length();
|
||||
/* first check there is space */
|
||||
if (size < *offset + 4 + len)
|
||||
{
|
||||
//#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "setRawString() Not enough size" << std::endl;
|
||||
//#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!setRawUInt32(data, size, offset, len))
|
||||
{
|
||||
std::cerr << "setRawString() set size failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
void *buf = (void *) &(((uint8_t *) data)[*offset]);
|
||||
|
||||
/* pack it in */
|
||||
memcpy(buf, inStr.c_str(), len);
|
||||
|
||||
(*offset) += len;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -57,5 +57,8 @@ bool setRawUInt32(void *data, uint32_t size, uint32_t *offset, uint32_t in);
|
||||
bool getRawUInt64(void *data, uint32_t size, uint32_t *offset, uint64_t *out);
|
||||
bool setRawUInt64(void *data, uint32_t size, uint32_t *offset, uint64_t in);
|
||||
|
||||
bool getRawString(void *data, uint32_t size, uint32_t *offset, std::string &outStr);
|
||||
bool setRawString(void *data, uint32_t size, uint32_t *offset, std::string &inStr);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -37,6 +37,8 @@
|
||||
#define RSSERIAL_DEBUG 1
|
||||
***/
|
||||
|
||||
#define RSSERIAL_DEBUG 1
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/*************************************************************************/
|
||||
@ -45,12 +47,17 @@ uint32_t RsDiscSerialiser::size(RsItem *i)
|
||||
{
|
||||
RsDiscItem *rdi;
|
||||
RsDiscReply *rdr;
|
||||
RsDiscIssuer *rds;
|
||||
|
||||
/* do reply first - as it is derived from Item */
|
||||
if (NULL != (rdr = dynamic_cast<RsDiscReply *>(i)))
|
||||
{
|
||||
return sizeReply(rdr);
|
||||
}
|
||||
else if (NULL != (rds = dynamic_cast<RsDiscIssuer *>(i)))
|
||||
{
|
||||
return sizeIssuer(rds);
|
||||
}
|
||||
else if (NULL != (rdi = dynamic_cast<RsDiscItem *>(i)))
|
||||
{
|
||||
return sizeItem(rdi);
|
||||
@ -64,12 +71,17 @@ bool RsDiscSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
|
||||
{
|
||||
RsDiscItem *rdi;
|
||||
RsDiscReply *rdr;
|
||||
RsDiscIssuer *rds;
|
||||
|
||||
/* do reply first - as it is derived from Item */
|
||||
if (NULL != (rdr = dynamic_cast<RsDiscReply *>(i)))
|
||||
{
|
||||
return serialiseReply(rdr, data, pktsize);
|
||||
}
|
||||
else if (NULL != (rds = dynamic_cast<RsDiscIssuer *>(i)))
|
||||
{
|
||||
return serialiseIssuer(rds, data, pktsize);
|
||||
}
|
||||
else if (NULL != (rdi = dynamic_cast<RsDiscItem *>(i)))
|
||||
{
|
||||
return serialiseItem(rdi, data, pktsize);
|
||||
@ -98,6 +110,9 @@ RsItem *RsDiscSerialiser::deserialise(void *data, uint32_t *pktsize)
|
||||
case RS_PKT_SUBTYPE_DISC_ITEM:
|
||||
return deserialiseItem(data, pktsize);
|
||||
break;
|
||||
case RS_PKT_SUBTYPE_DISC_ISSUER:
|
||||
return deserialiseIssuer(data, pktsize);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
@ -448,4 +463,145 @@ RsDiscReply *RsDiscSerialiser::deserialiseReply(void *data, uint32_t *pktsize)
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
RsDiscIssuer::~RsDiscIssuer()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void RsDiscIssuer::clear()
|
||||
{
|
||||
issuerCert = "";
|
||||
}
|
||||
|
||||
std::ostream &RsDiscIssuer::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsDiscIssuer", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "Cert String: " << issuerCert << std::endl;
|
||||
|
||||
printRsItemEnd(out, "RsDiscIssuer", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
uint32_t RsDiscSerialiser::sizeIssuer(RsDiscIssuer *item)
|
||||
{
|
||||
uint32_t s = 8; /* header */
|
||||
s += 4; /* size in RawString() */
|
||||
s += item->issuerCert.length();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* serialise the data to the buffer */
|
||||
bool RsDiscSerialiser::serialiseIssuer(RsDiscIssuer *item, void *data, uint32_t *pktsize)
|
||||
{
|
||||
uint32_t tlvsize = sizeIssuer(item);
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (*pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
*pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
|
||||
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsDiscSerialiser::serialiseIssuer() Header: " << ok << std::endl;
|
||||
std::cerr << "RsDiscSerialiser::serialiseIssuer() Size: " << tlvsize << std::endl;
|
||||
#endif
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= setRawString(data, tlvsize, &offset, item->issuerCert);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsDiscSerialiser::serialiseIssuer() Size Error! " << std::endl;
|
||||
std::cerr << "Offset: " << offset << " tlvsize: " << tlvsize << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
RsDiscIssuer *RsDiscSerialiser::deserialiseIssuer(void *data, uint32_t *pktsize)
|
||||
{
|
||||
/* get the type and size */
|
||||
uint32_t rstype = getRsItemId(data);
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
||||
uint32_t offset = 0;
|
||||
|
||||
|
||||
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
|
||||
(RS_SERVICE_TYPE_DISC != getRsItemService(rstype)) ||
|
||||
(RS_PKT_SUBTYPE_DISC_ISSUER != getRsItemSubType(rstype)))
|
||||
{
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsDiscSerialiser::deserialiseIssuer() Wrong Type" << std::endl;
|
||||
#endif
|
||||
return NULL; /* wrong type */
|
||||
}
|
||||
|
||||
if (*pktsize < rssize) /* check size */
|
||||
{
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsDiscSerialiser::deserialiseIssuer() pktsize != rssize" << std::endl;
|
||||
std::cerr << "Pktsize: " << *pktsize << " Rssize: " << rssize << std::endl;
|
||||
#endif
|
||||
return NULL; /* not enough data */
|
||||
}
|
||||
|
||||
/* set the packet length */
|
||||
*pktsize = rssize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* ready to load */
|
||||
RsDiscIssuer *item = new RsDiscIssuer();
|
||||
item->clear();
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* get mandatory parts first */
|
||||
ok &= getRawString(data, rssize, &offset, item->issuerCert);
|
||||
|
||||
if (offset != rssize)
|
||||
{
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsDiscSerialiser::deserialiseIssuer() offset != rssize" << std::endl;
|
||||
std::cerr << "Offset: " << offset << " Rssize: " << rssize << std::endl;
|
||||
#endif
|
||||
/* error */
|
||||
delete item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsDiscSerialiser::deserialiseIssuer() ok = false" << std::endl;
|
||||
#endif
|
||||
delete item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
@ -33,8 +33,9 @@
|
||||
#include "serialiser/rstlvtypes.h"
|
||||
#include "serialiser/rsserviceids.h"
|
||||
|
||||
const uint8_t RS_PKT_SUBTYPE_DISC_ITEM = 0x01;
|
||||
const uint8_t RS_PKT_SUBTYPE_DISC_REPLY = 0x02;
|
||||
const uint8_t RS_PKT_SUBTYPE_DISC_ITEM = 0x01;
|
||||
const uint8_t RS_PKT_SUBTYPE_DISC_REPLY = 0x02;
|
||||
const uint8_t RS_PKT_SUBTYPE_DISC_ISSUER = 0x03;
|
||||
|
||||
class RsDiscItem: public RsItem
|
||||
{
|
||||
@ -83,6 +84,22 @@ virtual std::ostream &print(std::ostream &out, uint16_t indent = 0);
|
||||
RsTlvBinaryData certDER;
|
||||
};
|
||||
|
||||
class RsDiscIssuer: public RsDiscItem
|
||||
{
|
||||
public:
|
||||
|
||||
RsDiscIssuer()
|
||||
:RsDiscItem(RS_PKT_SUBTYPE_DISC_ISSUER)
|
||||
{ return; }
|
||||
|
||||
virtual ~RsDiscIssuer();
|
||||
|
||||
virtual void clear();
|
||||
virtual std::ostream &print(std::ostream &out, uint16_t indent = 0);
|
||||
|
||||
std::string issuerCert;
|
||||
};
|
||||
|
||||
class RsDiscSerialiser: public RsSerialType
|
||||
{
|
||||
public:
|
||||
@ -106,6 +123,10 @@ virtual uint32_t sizeReply(RsDiscReply *);
|
||||
virtual bool serialiseReply (RsDiscReply *item, void *data, uint32_t *size);
|
||||
virtual RsDiscReply *deserialiseReply(void *data, uint32_t *size);
|
||||
|
||||
virtual uint32_t sizeIssuer(RsDiscIssuer *);
|
||||
virtual bool serialiseIssuer (RsDiscIssuer *item, void *data, uint32_t *size);
|
||||
virtual RsDiscIssuer *deserialiseIssuer(void *data, uint32_t *size);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -65,6 +65,7 @@ const uint32_t P3DISC_FLAGS_PEER_TRUSTS_ME= 0x0040;
|
||||
/*****
|
||||
* #define P3DISC_DEBUG 1
|
||||
****/
|
||||
#define P3DISC_DEBUG 1
|
||||
|
||||
/*********** NOTE ***************
|
||||
*
|
||||
@ -146,6 +147,7 @@ int p3disc::handleIncoming()
|
||||
{
|
||||
RsDiscItem *di = NULL;
|
||||
RsDiscReply *dri = NULL;
|
||||
RsDiscIssuer *dii = NULL;
|
||||
|
||||
if (NULL == (di = dynamic_cast<RsDiscItem *> (item)))
|
||||
{
|
||||
@ -184,6 +186,11 @@ int p3disc::handleIncoming()
|
||||
|
||||
recvPeerFriendMsg(dri);
|
||||
}
|
||||
else if (NULL != (dii = dynamic_cast<RsDiscIssuer *> (di)))
|
||||
{
|
||||
|
||||
recvPeerIssuerMsg(dii);
|
||||
}
|
||||
else /* Ping */
|
||||
{
|
||||
recvPeerOwnMsg(di);
|
||||
@ -266,6 +273,11 @@ void p3disc::respondToPeer(std::string id)
|
||||
|
||||
if (!(detail.visState & RS_VIS_STATE_NODISC))
|
||||
{
|
||||
/* send issuer certs ... only do this for friends at initial connections,
|
||||
no need to do with onlineId list.
|
||||
*/
|
||||
|
||||
sendPeerIssuer(id, *it);
|
||||
sendPeerDetails(id, *it); /* (dest (to), source (cert)) */
|
||||
}
|
||||
}
|
||||
@ -485,6 +497,53 @@ void p3disc::sendPeerDetails(std::string to, std::string about)
|
||||
}
|
||||
|
||||
|
||||
/* (dest (to), source (cert)) */
|
||||
void p3disc::sendPeerIssuer(std::string to, std::string about)
|
||||
{
|
||||
/* this is just a straight certificate (normally pgp).
|
||||
* but can get quite big (>100K) so will use new packet type.
|
||||
*/
|
||||
|
||||
/* send it off */
|
||||
{
|
||||
#ifdef P3DISC_DEBUG
|
||||
std::ostringstream out;
|
||||
out << "p3disc::sendPeerIssuer()";
|
||||
out << " Sending details of: " << about;
|
||||
out << " to: " << to << std::endl;
|
||||
std::cerr << out.str() << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string aboutIssuerId = mAuthMgr->getIssuerName(about);
|
||||
if (aboutIssuerId == "")
|
||||
{
|
||||
/* major error! */
|
||||
return;
|
||||
}
|
||||
|
||||
// Construct a message
|
||||
RsDiscIssuer *di = new RsDiscIssuer();
|
||||
|
||||
// Fill the message
|
||||
// Set Target as input cert.
|
||||
di -> PeerId(to);
|
||||
|
||||
di -> issuerCert = mAuthMgr->SaveCertificateToString(aboutIssuerId);
|
||||
|
||||
#ifdef P3DISC_DEBUG
|
||||
std::cerr << "Saved certificate to string in RsDiscIssuer. " << std::endl ;
|
||||
#endif
|
||||
|
||||
// Send off message
|
||||
sendItem(di);
|
||||
|
||||
#ifdef P3DISC_DEBUG
|
||||
std::cerr << "Sent DI Message" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************************/
|
||||
/* Input Network Msgs */
|
||||
/*************************************************************************************/
|
||||
@ -607,6 +666,26 @@ void p3disc::recvPeerFriendMsg(RsDiscReply *item)
|
||||
}
|
||||
|
||||
|
||||
void p3disc::recvPeerIssuerMsg(RsDiscIssuer *item)
|
||||
{
|
||||
|
||||
#ifdef P3DISC_DEBUG
|
||||
std::cerr << "p3disc::recvPeerIssuerMsg() From: " << item->PeerId();
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* tells us their exact address (mConnectMgr can ignore if it looks wrong) */
|
||||
|
||||
/* load certificate */
|
||||
std::string peerId;
|
||||
bool loaded = mAuthMgr->LoadCertificateFromString(item->issuerCert, peerId);
|
||||
|
||||
/* cleanup (handled by caller) */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************************/
|
||||
/* Storing Network Graph */
|
||||
/*************************************************************************************/
|
||||
|
@ -99,11 +99,13 @@ void respondToPeer(std::string id);
|
||||
/* Network Output */
|
||||
void sendOwnDetails(std::string to);
|
||||
void sendPeerDetails(std::string to, std::string about);
|
||||
void sendPeerIssuer(std::string to, std::string about);
|
||||
|
||||
/* Network Input */
|
||||
int handleIncoming();
|
||||
void recvPeerOwnMsg(RsDiscItem *item);
|
||||
void recvPeerFriendMsg(RsDiscReply *item);
|
||||
void recvPeerIssuerMsg(RsDiscIssuer *item);
|
||||
|
||||
/* handle network shape */
|
||||
int addDiscoveryData(std::string fromId, std::string aboutId,
|
||||
|
@ -195,7 +195,10 @@ RsRawItem *p3Service::send()
|
||||
}
|
||||
|
||||
/* ensure PeerId is transferred */
|
||||
raw->PeerId(si->PeerId());
|
||||
if (raw)
|
||||
{
|
||||
raw->PeerId(si->PeerId());
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
delete si;
|
||||
|
Loading…
Reference in New Issue
Block a user