diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index b66e7c541..079a2db83 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -978,7 +978,7 @@ static int verify_x509_callback(int preverify_ok, X509_STORE_CTX *ctx) std::string sslid ; getX509id(x509,sslid); - AuthSSL::getAuthSSL()->registerConnexionAttempt_ids(gpgid,sslid,sslcn) ; + AuthSSL::getAuthSSL()->setCurrentConnectionAttemptInfo(gpgid,sslid,sslcn) ; } return verify; @@ -1289,100 +1289,61 @@ bool AuthSSLimpl::decrypt(void *&out, int &outlen, const void *in, int inlen) /********************************************************************************/ /********************************************************************************/ -void AuthSSLimpl::registerConnexionAttempt_ids(const std::string& gpg_id,const std::string& ssl_id,const std::string& ssl_cn) +void AuthSSLimpl::setCurrentConnectionAttemptInfo(const std::string& gpg_id,const std::string& ssl_id,const std::string& ssl_cn) { +#ifdef AUTHSSL_DEBUG std::cerr << "AuthSSL: registering connexion attempt from:" << std::endl; std::cerr << " GPG id: " << gpg_id << std::endl; std::cerr << " SSL id: " << ssl_id << std::endl; std::cerr << " SSL cn: " << ssl_cn << std::endl; +#endif _last_gpgid_to_connect = gpg_id ; _last_sslid_to_connect = ssl_id ; _last_sslcn_to_connect = ssl_cn ; } +void AuthSSLimpl::getCurrentConnectionAttemptInfo(std::string& gpg_id,std::string& ssl_id,std::string& ssl_cn) +{ + gpg_id = _last_gpgid_to_connect ; + ssl_id = _last_sslid_to_connect ; + ssl_cn = _last_sslcn_to_connect ; +} /* store for discovery */ -bool AuthSSLimpl::FailedCertificate(X509 *x509, const struct sockaddr_in& addr, bool incoming) +bool AuthSSLimpl::FailedCertificate(X509 *x509, const std::string& gpgid, + const std::string& sslid, + const std::string& sslcn, + const struct sockaddr_in& addr, + bool incoming) { - std::string gpgid = "Unknown GPG Id" ; - std::string sslcn = "Unknown SSL location" ; - std::string sslid = "Unknown SSL Id" ; + std::string ip_address ; + rs_sprintf_append(ip_address, "%s:%u", rs_inet_ntoa(addr.sin_addr).c_str(), ntohs(addr.sin_port)); - if(x509 != NULL) - { - if(!getX509id(x509, sslid)) - { - std::cerr << "AuthSSLimpl::FailedCertificate() ERROR cannot extract X509id from certificate"; - std::cerr << std::endl; - } + bool authed = (x509 != NULL && AuthX509WithGPG(x509)) ; - gpgid = getX509CNString(x509->cert_info->issuer); - sslcn = getX509CNString(x509->cert_info->subject); - } - else if(incoming) - { - gpgid = _last_gpgid_to_connect ; - sslcn = _last_sslcn_to_connect ; - sslid = _last_sslid_to_connect ; - } + if(authed) + LocalStoreCert(x509); std::cerr << "AuthSSLimpl::FailedCertificate() "; if (incoming) { + getPqiNotify()->AddPopupMessage(RS_POPUP_CONNECT_ATTEMPT, gpgid, sslcn, sslid); + getPqiNotify()->AddFeedItem(RS_FEED_ITEM_SEC_CONNECT_ATTEMPT, gpgid, sslid, sslcn, ip_address); + std::cerr << " Incoming from: "; } - else + else { + if(authed) + getPqiNotify()->AddFeedItem(RS_FEED_ITEM_SEC_AUTH_DENIED, gpgid, sslid, sslcn, ip_address); + else + getPqiNotify()->AddFeedItem(RS_FEED_ITEM_SEC_UNKNOWN_OUT, gpgid, sslid, sslcn, ip_address); + std::cerr << " Outgoing to: "; } - - // Hacky - adding IpAddress to SSLId. - std::string ip_address ; - rs_sprintf_append(ip_address, "%s:%u", rs_inet_ntoa(addr.sin_addr).c_str(), ntohs(addr.sin_port)); - std::cerr << "GpgId: " << gpgid << " SSLcn: " << sslcn << " peerId: " << sslid << ", ip address: " << ip_address; std::cerr << std::endl; - uint32_t notifyType = 0; - - /* if auths -> store */ - if(x509 != NULL && AuthX509WithGPG(x509)) - { - std::cerr << "AuthSSLimpl::FailedCertificate() Cert Checked Out, so passing to Notify"; - std::cerr << std::endl; - - if (incoming) - { - notifyType = RS_FEED_ITEM_SEC_CONNECT_ATTEMPT; - getPqiNotify()->AddPopupMessage(RS_POPUP_CONNECT_ATTEMPT, gpgid, sslcn, sslid); - } - else - { - notifyType = RS_FEED_ITEM_SEC_AUTH_DENIED; - } - - getPqiNotify()->AddFeedItem(notifyType, gpgid, sslid, sslcn, ip_address); - - LocalStoreCert(x509); - return true; - } - else - { - /* unknown peer! */ - if (incoming) - { - notifyType = RS_FEED_ITEM_SEC_CONNECT_ATTEMPT; - getPqiNotify()->AddPopupMessage(RS_POPUP_CONNECT_ATTEMPT, gpgid, sslcn, sslid); - } - else - { - notifyType = RS_FEED_ITEM_SEC_UNKNOWN_OUT; - } - - getPqiNotify()->AddFeedItem(notifyType, gpgid, sslid, sslcn, ip_address); - - } - return false; } diff --git a/libretroshare/src/pqi/authssl.h b/libretroshare/src/pqi/authssl.h index 1ee1b1b5f..bc3e0919f 100644 --- a/libretroshare/src/pqi/authssl.h +++ b/libretroshare/src/pqi/authssl.h @@ -152,8 +152,10 @@ virtual bool ValidateCertificate(X509 *x509, std::string &peerId) = 0; /* valid virtual SSL_CTX *getCTX() = 0; /* Restored these functions: */ -virtual void registerConnexionAttempt_ids(const std::string& gpg_id,const std::string& ssl_id,const std::string& ssl_cn) = 0 ; -virtual bool FailedCertificate(X509 *x509, const struct sockaddr_in &addr, bool incoming) = 0; /* store for discovery */ +virtual void setCurrentConnectionAttemptInfo(const std::string& gpg_id,const std::string& ssl_id,const std::string& ssl_cn) = 0 ; +virtual void getCurrentConnectionAttemptInfo( std::string& gpg_id, std::string& ssl_id, std::string& ssl_cn) = 0 ; + +virtual bool FailedCertificate(X509 *x509, const std::string& gpgid,const std::string& sslid,const std::string& sslcn,const struct sockaddr_in &addr, bool incoming) = 0; /* store for discovery */ virtual bool CheckCertificate(std::string peerId, X509 *x509) = 0; /* check that they are exact match */ }; @@ -227,8 +229,9 @@ virtual bool ValidateCertificate(X509 *x509, std::string &peerId); /* validate virtual SSL_CTX *getCTX(); /* Restored these functions: */ -virtual void registerConnexionAttempt_ids(const std::string& gpg_id,const std::string& ssl_id,const std::string& ssl_cn) ; -virtual bool FailedCertificate(X509 *x509, const struct sockaddr_in &addr, bool incoming); /* store for discovery */ +virtual void setCurrentConnectionAttemptInfo(const std::string& gpg_id,const std::string& ssl_id,const std::string& ssl_cn) ; +virtual void getCurrentConnectionAttemptInfo( std::string& gpg_id, std::string& ssl_id, std::string& ssl_cn) ; +virtual bool FailedCertificate(X509 *x509, const std::string& gpgid,const std::string& sslid,const std::string& sslcn,const struct sockaddr_in &addr, bool incoming); /* store for discovery */ virtual bool CheckCertificate(std::string peerId, X509 *x509); /* check that they are exact match */ diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index f533083e4..a2890c3d6 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1143,7 +1143,14 @@ int pqissl::Extract_Failed_SSL_Certificate() // we actually connected to remote_addr, // which could be // (pqissl's case) sslcert->serveraddr or sslcert->localaddr. - AuthSSL::getAuthSSL()->FailedCertificate(peercert, remote_addr, false); + + std::string sslid ; + getX509id(peercert, sslid) ; + + std::string gpgid = getX509CNString(peercert->cert_info->issuer); + std::string sslcn = getX509CNString(peercert->cert_info->subject); + + AuthSSL::getAuthSSL()->FailedCertificate(peercert, gpgid,sslid,sslcn,remote_addr, false); return 1; } diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index 597716eb0..b38ae5176 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -363,26 +363,43 @@ int pqissllistenbase::acceptconnection() // Negotiate certificates. SSL stylee. // Allow negotiations for secure transaction. - SSL *ssl = SSL_new(AuthSSL::getAuthSSL() -> getCTX()); - SSL_set_fd(ssl, fd); + IncomingSSLInfo incoming_connexion_info ; - return continueSSL(ssl, remote_addr, true); // continue and save if incomplete. + incoming_connexion_info.ssl = SSL_new(AuthSSL::getAuthSSL() -> getCTX()); + incoming_connexion_info.addr = remote_addr ; + incoming_connexion_info.gpgid = "" ; + incoming_connexion_info.sslid = "" ; + incoming_connexion_info.sslcn = "" ; + + SSL_set_fd(incoming_connexion_info.ssl, fd); + + return continueSSL(incoming_connexion_info, true); // continue and save if incomplete. } -int pqissllistenbase::continueSSL(SSL *ssl, struct sockaddr_in remote_addr, bool addin) +int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool addin) { // attempt the accept again. - int fd = SSL_get_fd(ssl); - int err = SSL_accept(ssl); + int fd = SSL_get_fd(incoming_connexion_info.ssl); + + // clear the connexion info that will be filled in by the callback. + // + AuthSSL::getAuthSSL()->setCurrentConnectionAttemptInfo(std::string(),std::string(),std::string()) ; + + int err = SSL_accept(incoming_connexion_info.ssl); + + // No grab the connexion info that was filled in by the callback. + // + AuthSSL::getAuthSSL()->getCurrentConnectionAttemptInfo(incoming_connexion_info.gpgid,incoming_connexion_info.sslid,incoming_connexion_info.sslcn) ; + if (err <= 0) { - int ssl_err = SSL_get_error(ssl, err); + int ssl_err = SSL_get_error(incoming_connexion_info.ssl, err); int err_err = ERR_get_error(); { std::string out; rs_sprintf(out, "pqissllistenbase::continueSSL() Issues with SSL Accept(%d)!\n", err); - printSSLError(ssl, err, ssl_err, err_err, out); + printSSLError(incoming_connexion_info.ssl, err, ssl_err, err_err, out); pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out); } @@ -396,7 +413,7 @@ int pqissllistenbase::continueSSL(SSL *ssl, struct sockaddr_in remote_addr, bool out += "pqissllistenbase::continueSSL() Adding SSL to incoming!"; // add to incomingqueue. - incoming_ssl[ssl] = remote_addr; + incoming_ssl.push_back(incoming_connexion_info) ; } pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out); @@ -406,9 +423,9 @@ int pqissllistenbase::continueSSL(SSL *ssl, struct sockaddr_in remote_addr, bool } /* we have failed -> get certificate if possible */ - Extract_Failed_SSL_Certificate(ssl, &remote_addr); + Extract_Failed_SSL_Certificate(incoming_connexion_info); - closeConnection(fd, ssl); + closeConnection(fd, incoming_connexion_info.ssl) ; pqioutput(PQL_WARNING, pqissllistenzone, "Read Error on the SSL Socket\nShutting it down!"); @@ -417,7 +434,7 @@ int pqissllistenbase::continueSSL(SSL *ssl, struct sockaddr_in remote_addr, bool } // if it succeeds - if (0 < completeConnection(fd, ssl, remote_addr)) + if (0 < completeConnection(fd, incoming_connexion_info)) { return 1; } @@ -426,7 +443,7 @@ int pqissllistenbase::continueSSL(SSL *ssl, struct sockaddr_in remote_addr, bool pqioutput(PQL_WARNING, pqissllistenzone, "pqissllistenbase::completeConnection() Failed!"); - closeConnection(fd, ssl); + closeConnection(fd, incoming_connexion_info.ssl) ; pqioutput(PQL_WARNING, pqissllistenzone, "Shutting it down!"); @@ -461,23 +478,29 @@ int pqissllistenbase::closeConnection(int fd, SSL *ssl) -int pqissllistenbase::Extract_Failed_SSL_Certificate(SSL *ssl, struct sockaddr_in *addr) +int pqissllistenbase::Extract_Failed_SSL_Certificate(const IncomingSSLInfo& info) { - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, - "pqissllistenbase::Extract_Failed_SSL_Certificate()"); + pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, "pqissllistenbase::Extract_Failed_SSL_Certificate()"); std::cerr << "pqissllistenbase::Extract_Failed_SSL_Certificate() FAILED CONNECTION due to security!"; std::cerr << std::endl; // Get the Peer Certificate.... - X509 *peercert = SSL_get_peer_certificate(ssl); + X509 *peercert = SSL_get_peer_certificate(info.ssl); + + std::cerr << "Extract_Failed_SSL_Certificate: " << std::endl; + std::cerr << " SSL = " << (void*)info.ssl << std::endl; + std::cerr << " GPG id = " << info.gpgid << std::endl; + std::cerr << " SSL id = " << info.sslid << std::endl; + std::cerr << " SSL cn = " << info.sslcn << std::endl; + std::cerr << " addr+p = " << rs_inet_ntoa(info.addr.sin_addr) << ":" << ntohs(info.addr.sin_port) << std::endl; if (peercert == NULL) { std::string out; - rs_sprintf(out, "pqissllistenbase::Extract_Failed_SSL_Certificate() from: %s:%u ERROR Peer didn't give Cert!", rs_inet_ntoa(addr->sin_addr).c_str(), ntohs(addr->sin_port)); + rs_sprintf(out, "pqissllistenbase::Extract_Failed_SSL_Certificate() from: %s:%u ERROR Peer didn't give Cert!", rs_inet_ntoa(info.addr.sin_addr).c_str(), ntohs(info.addr.sin_port)); std::cerr << out << std::endl; - AuthSSL::getAuthSSL()->FailedCertificate(peercert, *addr, true); + AuthSSL::getAuthSSL()->FailedCertificate(peercert, info.gpgid,info.sslid,info.sslcn,info.addr, true); pqioutput(PQL_WARNING, pqissllistenzone, out); return -1; @@ -488,7 +511,7 @@ int pqissllistenbase::Extract_Failed_SSL_Certificate(SSL *ssl, struct sockaddr_ { std::string out; - rs_sprintf(out, "pqissllistenbase::Extract_Failed_SSL_Certificate() from: %s:%u Passing Cert to AuthSSL() for analysis", rs_inet_ntoa(addr->sin_addr).c_str(), ntohs(addr->sin_port)); + rs_sprintf(out, "pqissllistenbase::Extract_Failed_SSL_Certificate() from: %s:%u Passing Cert to AuthSSL() for analysis", rs_inet_ntoa(info.addr.sin_addr).c_str(), ntohs(info.addr.sin_port)); std::cerr << out << std::endl; pqioutput(PQL_WARNING, pqissllistenzone, out); @@ -497,7 +520,7 @@ int pqissllistenbase::Extract_Failed_SSL_Certificate(SSL *ssl, struct sockaddr_ // save certificate... (and ip locations) // false for outgoing.... - AuthSSL::getAuthSSL()->FailedCertificate(peercert, *addr, true); + AuthSSL::getAuthSSL()->FailedCertificate(peercert, info.gpgid,info.sslid,info.sslcn,info.addr, true); return 1; } @@ -507,25 +530,22 @@ int pqissllistenbase::continueaccepts() { // for each of the incoming sockets.... call continue. - std::map::iterator it, itd; - for(it = incoming_ssl.begin(); it != incoming_ssl.end();) + for(std::list::iterator it = incoming_ssl.begin(); it != incoming_ssl.end();) { - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, - "pqissllistenbase::continueaccepts() Continuing SSL"); - if (0 != continueSSL(it->first, it->second, false)) + pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, "pqissllistenbase::continueaccepts() Continuing SSL"); + + if (0 != continueSSL( *it, false)) { - pqioutput(PQL_DEBUG_ALERT, pqissllistenzone, - "pqissllistenbase::continueaccepts() SSL Complete/Dead!"); + pqioutput(PQL_DEBUG_ALERT, pqissllistenzone, + "pqissllistenbase::continueaccepts() SSL Complete/Dead!"); /* save and increment -> so we can delete */ - itd = it++; + std::list::iterator itd = it++; incoming_ssl.erase(itd); } else - { it++; - } } return 1; } @@ -720,11 +740,11 @@ int pqissllistener::status() return 1; } -int pqissllistener::completeConnection(int fd, SSL *ssl, struct sockaddr_in &remote_addr) +int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info) { // Get the Peer Certificate.... - X509 *peercert = SSL_get_peer_certificate(ssl); + X509 *peercert = SSL_get_peer_certificate(info.ssl); if (peercert == NULL) { @@ -786,7 +806,7 @@ int pqissllistener::completeConnection(int fd, SSL *ssl, struct sockaddr_in &rem if (found == false) { - std::string out = "No Matching Certificate for Connection:" + rs_inet_ntoa(remote_addr.sin_addr) +"\npqissllistenbase: Will shut it down!"; + std::string out = "No Matching Certificate for Connection:" + rs_inet_ntoa(info.addr.sin_addr) +"\npqissllistenbase: Will shut it down!"; pqioutput(PQL_WARNING, pqissllistenzone, out); // but as it passed the authentication step, @@ -808,15 +828,15 @@ int pqissllistener::completeConnection(int fd, SSL *ssl, struct sockaddr_in &rem // Pushback into Accepted List. AcceptedSSL as; as.mFd = fd; - as.mSSL = ssl; + as.mSSL = info.ssl; as.mPeerId = newPeerId; - as.mAddr = remote_addr; + as.mAddr = info.addr; as.mAcceptTS = time(NULL); accepted_ssl.push_back(as); std::string out = "pqissllistener::completeConnection() Successful Connection with: " + newPeerId; - out += " for Connection:" + rs_inet_ntoa(remote_addr.sin_addr) + " Adding to WAIT-ACCEPT Queue"; + out += " for Connection:" + rs_inet_ntoa(info.addr.sin_addr) + " Adding to WAIT-ACCEPT Queue"; pqioutput(PQL_WARNING, pqissllistenzone, out); return 1; diff --git a/libretroshare/src/pqi/pqissllistener.h b/libretroshare/src/pqi/pqissllistener.h index 577c7a674..85f6df5af 100644 --- a/libretroshare/src/pqi/pqissllistener.h +++ b/libretroshare/src/pqi/pqissllistener.h @@ -85,11 +85,21 @@ int acceptconnection(); int continueaccepts(); int finaliseAccepts(); -int continueSSL(SSL *ssl, struct sockaddr_in remote_addr, bool); + struct IncomingSSLInfo + { + SSL *ssl ; + sockaddr_in addr ; + std::string gpgid ; + std::string sslid ; + std::string sslcn ; + }; + + // fn to get cert, anyway +int continueSSL(IncomingSSLInfo&, bool); int closeConnection(int fd, SSL *ssl); int isSSLActive(int fd, SSL *ssl); -virtual int completeConnection(int sockfd, SSL *in_connection, struct sockaddr_in &raddr) = 0; +virtual int completeConnection(int sockfd, IncomingSSLInfo&) = 0; virtual int finaliseConnection(int fd, SSL *ssl, std::string peerId, struct sockaddr_in &raddr) = 0; protected: @@ -98,13 +108,12 @@ virtual int finaliseConnection(int fd, SSL *ssl, std::string peerId, struct sock private: - // fn to get cert, anyway -int Extract_Failed_SSL_Certificate(SSL *ssl, struct sockaddr_in *inaddr); + int Extract_Failed_SSL_Certificate(const IncomingSSLInfo&); bool active; int lsock; - std::map incoming_ssl; + std::list incoming_ssl ; protected: @@ -126,7 +135,7 @@ int removeListenPort(std::string id); //virtual int tick(); virtual int status(); -virtual int completeConnection(int sockfd, SSL *in_connection, struct sockaddr_in &raddr); +virtual int completeConnection(int sockfd, IncomingSSLInfo&); virtual int finaliseConnection(int fd, SSL *ssl, std::string peerId, struct sockaddr_in &raddr); private: