From d4b52a59e5dad80518d1fae6aa7031b90ce7d87c Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 25 May 2009 11:38:47 +0000 Subject: [PATCH] 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 --- libretroshare/src/pqi/authgpg.cc | 271 ++++++++++++++----- libretroshare/src/pqi/authgpg.h | 32 ++- libretroshare/src/pqi/authssl.cc | 18 +- libretroshare/src/pqi/authssl.h | 3 +- libretroshare/src/pqi/p3authmgr.cc | 2 +- libretroshare/src/pqi/p3authmgr.h | 4 +- libretroshare/src/rsiface/rspeers.h | 1 + libretroshare/src/rsserver/p3peers.cc | 6 +- libretroshare/src/serialiser/rsbaseserial.cc | 54 ++++ libretroshare/src/serialiser/rsbaseserial.h | 3 + libretroshare/src/serialiser/rsdiscitems.cc | 156 +++++++++++ libretroshare/src/serialiser/rsdiscitems.h | 25 +- libretroshare/src/services/p3disc.cc | 79 ++++++ libretroshare/src/services/p3disc.h | 2 + libretroshare/src/services/p3service.cc | 5 +- 15 files changed, 566 insertions(+), 95 deletions(-) diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index beb03a80d..189b8ddc7 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -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 &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 &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 &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 &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 &ids) bool GPGAuthMgr::getPGPAuthenticatedList(std::list &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 &ids) bool GPGAuthMgr::getPGPUnknownList(std::list &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 &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; } diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index a832eba5f..0eef90d40 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -41,6 +41,9 @@ class gpgcert { public: + gpgcert(); + ~gpgcert(); + pqiAuthDetails user; gpgme_key_t key; }; @@ -52,19 +55,30 @@ typedef std::map 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 &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; diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index 9c798215b..221fea559 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -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; diff --git a/libretroshare/src/pqi/authssl.h b/libretroshare/src/pqi/authssl.h index 745ebabb6..993b1fcc1 100644 --- a/libretroshare/src/pqi/authssl.h +++ b/libretroshare/src/pqi/authssl.h @@ -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 &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) */ diff --git a/libretroshare/src/pqi/p3authmgr.cc b/libretroshare/src/pqi/p3authmgr.cc index bbee994b8..db2664e97 100644 --- a/libretroshare/src/pqi/p3authmgr.cc +++ b/libretroshare/src/pqi/p3authmgr.cc @@ -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; } diff --git a/libretroshare/src/pqi/p3authmgr.h b/libretroshare/src/pqi/p3authmgr.h index 12ceba3e8..b41c95ae2 100644 --- a/libretroshare/src/pqi/p3authmgr.h +++ b/libretroshare/src/pqi/p3authmgr.h @@ -64,9 +64,10 @@ class pqiAuthDetails std::list 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 &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 */ diff --git a/libretroshare/src/rsiface/rspeers.h b/libretroshare/src/rsiface/rspeers.h index ae3976d5c..d8a9dd58c 100644 --- a/libretroshare/src/rsiface/rspeers.h +++ b/libretroshare/src/rsiface/rspeers.h @@ -83,6 +83,7 @@ class RsPeerDetails std::list signers; uint32_t trustLvl; + uint32_t validLvl; bool ownsign; /* we have signed certificate */ bool trusted; /* we trust their signature on others */ diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 3b0c592dc..42fb693e8 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -33,7 +33,9 @@ #include #include -#include +#ifdef RS_USE_PGPSSL + #include +#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 */ diff --git a/libretroshare/src/serialiser/rsbaseserial.cc b/libretroshare/src/serialiser/rsbaseserial.cc index 48d0e8e3c..1d6ebd149 100644 --- a/libretroshare/src/serialiser/rsbaseserial.cc +++ b/libretroshare/src/serialiser/rsbaseserial.cc @@ -30,6 +30,8 @@ #include "serialiser/rsbaseserial.h" #include "util/rsnet.h" +#include + /* 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; +} + diff --git a/libretroshare/src/serialiser/rsbaseserial.h b/libretroshare/src/serialiser/rsbaseserial.h index 47f15c2c8..9c2e5ac7b 100644 --- a/libretroshare/src/serialiser/rsbaseserial.h +++ b/libretroshare/src/serialiser/rsbaseserial.h @@ -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 diff --git a/libretroshare/src/serialiser/rsdiscitems.cc b/libretroshare/src/serialiser/rsdiscitems.cc index d4e393a5a..cbec5dce4 100644 --- a/libretroshare/src/serialiser/rsdiscitems.cc +++ b/libretroshare/src/serialiser/rsdiscitems.cc @@ -37,6 +37,8 @@ #define RSSERIAL_DEBUG 1 ***/ +#define RSSERIAL_DEBUG 1 + #include /*************************************************************************/ @@ -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(i))) { return sizeReply(rdr); } + else if (NULL != (rds = dynamic_cast(i))) + { + return sizeIssuer(rds); + } else if (NULL != (rdi = dynamic_cast(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(i))) { return serialiseReply(rdr, data, pktsize); } + else if (NULL != (rds = dynamic_cast(i))) + { + return serialiseIssuer(rds, data, pktsize); + } else if (NULL != (rdi = dynamic_cast(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; +} + + + /*************************************************************************/ diff --git a/libretroshare/src/serialiser/rsdiscitems.h b/libretroshare/src/serialiser/rsdiscitems.h index a5f19137b..19ba3bed8 100644 --- a/libretroshare/src/serialiser/rsdiscitems.h +++ b/libretroshare/src/serialiser/rsdiscitems.h @@ -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); + }; diff --git a/libretroshare/src/services/p3disc.cc b/libretroshare/src/services/p3disc.cc index 00c63783f..3f8e55f81 100644 --- a/libretroshare/src/services/p3disc.cc +++ b/libretroshare/src/services/p3disc.cc @@ -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 (item))) { @@ -184,6 +186,11 @@ int p3disc::handleIncoming() recvPeerFriendMsg(dri); } + else if (NULL != (dii = dynamic_cast (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 */ /*************************************************************************************/ diff --git a/libretroshare/src/services/p3disc.h b/libretroshare/src/services/p3disc.h index 23614f4e2..0e30f0e3f 100644 --- a/libretroshare/src/services/p3disc.h +++ b/libretroshare/src/services/p3disc.h @@ -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, diff --git a/libretroshare/src/services/p3service.cc b/libretroshare/src/services/p3service.cc index b05b1c4da..9d4186816 100644 --- a/libretroshare/src/services/p3service.cc +++ b/libretroshare/src/services/p3service.cc @@ -195,7 +195,10 @@ RsRawItem *p3Service::send() } /* ensure PeerId is transferred */ - raw->PeerId(si->PeerId()); + if (raw) + { + raw->PeerId(si->PeerId()); + } /* cleanup */ delete si;