Merge branch 'csoler-v0.6-SecNotification'

This commit is contained in:
Gioacchino Mazzurco 2020-01-07 01:19:08 +01:00
commit b17738f668
No known key found for this signature in database
GPG key ID: A1FBCA3872E87051
80 changed files with 1585 additions and 2044 deletions

View file

@ -1186,11 +1186,13 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx)
RsErr() << __PRETTY_FUNCTION__ << " " << errMsg << std::endl;
if(rsEvents)
{
ev->mErrorMsg = errMsg;
rsEvents->postEvent(std::move(ev));
}
// if(rsEvents)
// {
// ev->mErrorMsg = errMsg;
// ev->mErrorCode = RsAuthSslConnectionAutenticationEvent::NO_CERTIFICATE_SUPPLIED;
//
// rsEvents->postEvent(std::move(ev));
// }
return verificationFailed;
}
@ -1217,8 +1219,11 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx)
if(rsEvents)
{
ev->mSslCn = sslCn;
ev->mSslId = sslId;
ev->mPgpId = pgpId;
ev->mErrorMsg = errMsg;
ev->mErrorCode = RsAuthSslError::MISSING_AUTHENTICATION_INFO;
rsEvents->postEvent(std::move(ev));
}
@ -1237,6 +1242,8 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx)
ev->mSslId = sslId;
ev->mSslCn = sslCn;
ev->mErrorMsg = errMsg;
ev->mErrorCode = RsAuthSslError::MISSING_AUTHENTICATION_INFO;
rsEvents->postEvent(std::move(ev));
}
@ -1266,6 +1273,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx)
ev->mSslCn = sslCn;
ev->mPgpId = pgpId;
ev->mErrorMsg = errorMsg;
ev->mErrorCode = RsAuthSslError::MISMATCHED_PGP_ID;
rsEvents->postEvent(std::move(ev));
}
@ -1290,12 +1298,29 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx)
ev->mSslId = sslId;
ev->mSslCn = sslCn;
ev->mPgpId = pgpId;
switch(auth_diagnostic)
{
case RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN:
ev->mErrorCode = RsAuthSslError::NOT_A_FRIEND;
break;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE:
ev->mErrorCode = RsAuthSslError::PGP_SIGNATURE_VALIDATION_FAILED;
break;
default:
ev->mErrorCode = RsAuthSslError::MISSING_AUTHENTICATION_INFO;
break;
}
ev->mErrorMsg = errMsg;
rsEvents->postEvent(std::move(ev));
}
return verificationFailed;
}
#ifdef AUTHSSL_DEBUG
std::cerr << "******* VerifyX509Callback cert: " << std::hex << ctx->cert <<std::dec << std::endl;
#endif
if ( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() && !AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) )
{
@ -1311,28 +1336,20 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx)
ev->mSslCn = sslCn;
ev->mPgpId = pgpId;
ev->mErrorMsg = errMsg;
ev->mErrorCode = RsAuthSslError::NOT_A_FRIEND;
rsEvents->postEvent(std::move(ev));
}
return verificationFailed;
}
setCurrentConnectionAttemptInfo(pgpId, sslId, sslCn);
//setCurrentConnectionAttemptInfo(pgpId, sslId, sslCn);
LocalStoreCert(x509Cert);
RsInfo() << __PRETTY_FUNCTION__ << " authentication successfull for "
<< "sslId: " << sslId << " isSslOnlyFriend: " << isSslOnlyFriend
<< std::endl;
if(rsEvents)
{
ev->mSuccess = true;
ev->mSslId = sslId;
ev->mSslCn = sslCn;
ev->mPgpId = pgpId;
rsEvents->postEvent(std::move(ev));
}
return verificationSuccess;
}
@ -1583,32 +1600,6 @@ bool AuthSSLimpl::decrypt(void *&out, int &outlen, const void *in, int inlen)
return true;
}
/********************************************************************************/
/********************************************************************************/
/********************* Cert Search / Add / Remove **************************/
/********************************************************************************/
/********************************************************************************/
void AuthSSLimpl::setCurrentConnectionAttemptInfo(const RsPgpId& gpg_id,const RsPeerId& ssl_id,const std::string& ssl_cn)
{
#ifdef AUTHSSL_DEBUG
std::cerr << "AuthSSL: registering connection 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(RsPgpId& gpg_id,RsPeerId& ssl_id,std::string& ssl_cn)
{
gpg_id = _last_gpgid_to_connect ;
ssl_id = _last_sslid_to_connect ;
ssl_cn = _last_sslcn_to_connect ;
}
/* Locked search -> internal help function */
bool AuthSSLimpl::locked_FindCert(const RsPeerId& id, X509** cert)
{
@ -1785,9 +1776,6 @@ bool AuthSSLimpl::loadList(std::list<RsItem*>& load)
return true;
}
RsAuthSslConnectionAutenticationEvent::RsAuthSslConnectionAutenticationEvent() :
RsEvent(RsEventType::AUTHSSL_CONNECTION_AUTENTICATION), mSuccess(false) {}
const EVP_PKEY*RsX509Cert::getPubKey(const X509& x509)
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)

View file

@ -52,34 +52,6 @@ RsPeerId getCertSslId(const X509& x509);
const EVP_PKEY* getPubKey(const X509& x509);
};
/**
* Event triggered by AuthSSL when authentication of a connection attempt either
* fail or success
*/
struct RsAuthSslConnectionAutenticationEvent : RsEvent
{
RsAuthSslConnectionAutenticationEvent();
bool mSuccess;
RsPeerId mSslId;
std::string mSslCn;
RsPgpId mPgpId;
std::string mErrorMsg;
///* @see RsEvent @see RsSerializable
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override
{
RsEvent::serial_process(j, ctx);
RS_SERIAL_PROCESS(mSuccess);
RS_SERIAL_PROCESS(mSslId);
RS_SERIAL_PROCESS(mSslCn);
RS_SERIAL_PROCESS(mPgpId);
RS_SERIAL_PROCESS(mErrorMsg);
}
};
/**
* This is an implementation of SSL certificate authentication with PGP
* signatures, instead of centralized certification authority.
@ -165,13 +137,6 @@ public:
/// SSL specific functions used in pqissl/pqissllistener
virtual SSL_CTX* getCTX() = 0;
virtual void setCurrentConnectionAttemptInfo(
const RsPgpId& gpg_id, const RsPeerId& ssl_id,
const std::string& ssl_cn ) = 0;
virtual void getCurrentConnectionAttemptInfo(
RsPgpId& gpg_id, RsPeerId& ssl_id, std::string& ssl_cn ) = 0;
/**
* This function parse X509 certificate from the file and return some
* verified informations, like ID and signer
@ -258,14 +223,6 @@ public:
/* SSL specific functions used in pqissl/pqissllistener */
SSL_CTX* getCTX() override;
/* Restored these functions: */
void setCurrentConnectionAttemptInfo(
const RsPgpId& gpg_id, const RsPeerId& ssl_id,
const std::string& ssl_cn ) override;
void getCurrentConnectionAttemptInfo(
RsPgpId& gpg_id, RsPeerId& ssl_id, std::string& ssl_cn ) override;
private:
bool LocalStoreCert(X509* x509);

View file

@ -473,27 +473,20 @@ void p3LinkMgrIMPL::tickMonitors()
#endif
/* notify GUI */
if (peer.actions & RS_PEER_CONNECTED)
if (rsEvents && (peer.actions & RS_PEER_CONNECTED))
{
p3Notify *notify = RsServer::notify();
if (notify)
{
// normally these two below should disappear: there's no notion of popup in libretroshare.
// all GUI-type display features should be chosen in NotifyQt.
notify->AddPopupMessage(RS_POPUP_CONNECT, peer.id.toStdString(),"", "Online: ");
notify->AddFeedItem(RS_FEED_ITEM_PEER_CONNECT, peer.id.toStdString());
notify->notifyPeerConnected(peer.id.toStdString());
}
auto e = std::make_shared<RsConnectionEvent>();
e->mConnectionInfoCode = RsConnectionEventCode::PEER_CONNECTED;
e->mSslId = peer.id;
rsEvents->postEvent(e);
}
if (peer.actions & RS_PEER_DISCONNECTED)
if (rsEvents && (peer.actions & RS_PEER_DISCONNECTED))
{
p3Notify *notify = RsServer::notify();
if (notify)
notify->notifyPeerDisconnected(peer.id.toStdString());
}
auto e = std::make_shared<RsConnectionEvent>();
e->mConnectionInfoCode = RsConnectionEventCode::PEER_DISCONNECTED;
e->mSslId = peer.id;
rsEvents->postEvent(e);
}
}
}

View file

@ -217,8 +217,6 @@ void p3Notify::notifyChatLobbyEvent(uint64_t lobby_id, uint32_t event_type,const
void p3Notify::notifyListPreChange(int list, int type) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyListPreChange(list,type) ; }
void p3Notify::notifyListChange (int list, int type) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyListChange (list,type) ; }
void p3Notify::notifyPeerConnected (const std::string& peer_id) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerConnected(peer_id); }
void p3Notify::notifyPeerDisconnected (const std::string& peer_id) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerDisconnected(peer_id); }
void p3Notify::notifyErrorMsg (int list, int sev, std::string msg) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyErrorMsg(list,sev,msg) ; }
void p3Notify::notifyChatMessage (const ChatMessage &msg) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatMessage(msg) ; }
void p3Notify::notifyChatStatus (const ChatId& chat_id, const std::string& status_string) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatStatus(chat_id,status_string) ; }
@ -235,8 +233,6 @@ void p3Notify::notifyOwnAvatarChanged ()
void p3Notify::notifyOwnStatusMessageChanged() { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyOwnStatusMessageChanged() ; }
void p3Notify::notifyDiskFull (uint32_t location , uint32_t size_limit_in_MB ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiskFull (location,size_limit_in_MB) ; }
void p3Notify::notifyPeerStatusChanged (const std::string& peer_id , uint32_t status ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChanged (peer_id,status) ; }
void p3Notify::notifyGxsChange (const RsGxsChanges& changes) {FOR_ALL_NOTIFY_CLIENTS (*it)->notifyGxsChange(changes) ;}
void p3Notify::notifyConnectionWithoutCert () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyConnectionWithoutCert(); }
void p3Notify::notifyPeerStatusChangedSummary () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChangedSummary() ; }
void p3Notify::notifyDiscInfoChanged () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiscInfoChanged () ; }

View file

@ -91,8 +91,6 @@ class p3Notify: public RsNotify
// Notifications of clients. Can be called from anywhere inside libretroshare.
//
void notifyPeerConnected (const std::string& /* peer_id */);
void notifyPeerDisconnected (const std::string& /* peer_id */);
void notifyListPreChange (int /* list */, int /* type */) ;
void notifyListChange (int /* list */, int /* type */) ;
void notifyErrorMsg (int /* list */, int /* sev */, std::string /* msg */) ;
@ -111,7 +109,6 @@ class p3Notify: public RsNotify
void notifyOwnStatusMessageChanged () ;
void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) ;
void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) ;
void notifyGxsChange (const RsGxsChanges& /* changes */);
void notifyConnectionWithoutCert ();
void notifyPeerStatusChangedSummary () ;

View file

@ -1804,12 +1804,24 @@ bool p3PeerMgrIMPL::addCandidateForOwnExternalAddress(const RsPeerId &from, cons
// Notify for every friend that has reported a wrong external address, except if that address is in the IP whitelist.
if((rsBanList!=NULL && !rsBanList->isAddressAccepted(addr_filtered,RSBANLIST_CHECKING_FLAGS_WHITELIST)) && (!sockaddr_storage_sameip(own_addr,addr_filtered)))
{
std::cerr << " Peer " << from << " reports a connection address (" << sockaddr_storage_iptostring(addr_filtered) <<") that is not your current external address (" << sockaddr_storage_iptostring(own_addr) << "). This is weird." << std::endl;
if((rsBanList && !rsBanList->isAddressAccepted(addr_filtered, RSBANLIST_CHECKING_FLAGS_WHITELIST))
&& !sockaddr_storage_sameip(own_addr, addr_filtered) )
{
RsInfo() << __PRETTY_FUNCTION__ << " Peer " << from
<< " reports a connection address (" << addr_filtered
<<") that is not your current external address ("
<< own_addr << "). This is weird." << std::endl;
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_IP_WRONG_EXTERNAL_IP_REPORTED, from.toStdString(), sockaddr_storage_iptostring(own_addr), sockaddr_storage_iptostring(addr));
}
if(rsEvents)
{
auto ev = std::make_shared<RsConnectionEvent>();
ev->mSslId = from;
ev->mOwnLocator = RsUrl(own_addr);
ev->mReportedLocator = RsUrl(addr);
ev->mConnectionInfoCode = RsConnectionEventCode::PEER_REPORTS_WRONG_IP;
rsEvents->postEvent(ev);
}
}
// we could also sweep over all connected friends and see if some report a different address.

View file

@ -1096,8 +1096,7 @@ int pqissl::SSL_Connection_Complete()
if (err != 1)
{
int serr = SSL_get_error(ssl_connection, err);
if ((serr == SSL_ERROR_WANT_READ)
|| (serr == SSL_ERROR_WANT_WRITE))
if ((serr == SSL_ERROR_WANT_READ) || (serr == SSL_ERROR_WANT_WRITE))
{
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
@ -1108,6 +1107,14 @@ int pqissl::SSL_Connection_Complete()
return 0;
}
if(rsEvents)
{
X509 *x509 = SSL_get_peer_certificate(ssl_connection);
auto ev = std::make_shared<RsAuthSslConnectionAutenticationEvent>();
ev->mSslId = RsX509Cert::getCertSslId(*x509);
ev->mErrorCode = RsAuthSslError::PEER_REFUSED_CONNECTION;
rsEvents->postEvent(ev);
}
std::string out;
rs_sprintf(out, "pqissl::SSL_Connection_Complete()\nIssues with SSL Connect(%d)!\n", err);
@ -1253,10 +1260,12 @@ int pqissl::accept_locked( SSL *ssl, int fd,
if (rsPeers->servicePermissionFlags(PeerId()) & RS_NODE_PERM_REQUIRE_WL)
checking_flags |= RSBANLIST_CHECKING_FLAGS_WHITELIST;
if(rsBanList && !rsBanList->isAddressAccepted(
foreign_addr, checking_flags, check_result ))
if( RsX509Cert::getCertSslId(*SSL_get_peer_certificate(ssl)) != PeerId())
std::cerr << "(EE) pqissl::accept_locked(): PeerId() is " << PeerId() << " but certificate ID is " << RsX509Cert::getCertSslId(*SSL_get_peer_certificate(ssl)) << std::endl;
if(rsBanList && !rsBanList->isAddressAccepted( foreign_addr, checking_flags, check_result ))
{
RsErr() << __PRETTY_FUNCTION__
RsInfo() << __PRETTY_FUNCTION__
<< " Refusing incoming SSL connection from blacklisted "
<< "foreign address " << foreign_addr
<< ". Reason: " << check_result << ". This should never happen "
@ -1264,11 +1273,16 @@ int pqissl::accept_locked( SSL *ssl, int fd,
<< std::endl;
print_stacktrace();
RsServer::notify()->AddFeedItem(
RS_FEED_ITEM_SEC_IP_BLACKLISTED,
PeerId().toStdString(),
sockaddr_storage_iptostring(foreign_addr), "", "",
check_result);
if(rsEvents)
{
X509 *x509 = SSL_get_peer_certificate(ssl);
auto ev = std::make_shared<RsAuthSslConnectionAutenticationEvent>();
ev->mSslId = RsX509Cert::getCertSslId(*x509);
ev->mLocator = RsUrl(foreign_addr);
ev->mErrorCode = RsAuthSslError::IP_IS_BLACKLISTED;
rsEvents->postEvent(ev);
}
reset_locked();
return failure;
}
@ -1324,7 +1338,7 @@ int pqissl::accept_locked( SSL *ssl, int fd,
/* shutdown existing - in all cases use the new one */
if ((ssl_connection) && (ssl_connection != ssl))
{
std::cerr << __PRETTY_FUNCTION__
RsInfo() << __PRETTY_FUNCTION__
<< " closing Previous/Existing ssl_connection" << std::endl;
SSL_shutdown(ssl_connection);
SSL_free (ssl_connection);
@ -1332,7 +1346,7 @@ int pqissl::accept_locked( SSL *ssl, int fd,
if ((sockfd > -1) && (sockfd != fd))
{
std::cerr << __PRETTY_FUNCTION__ << " closing Previous/Existing sockfd"
RsInfo() << __PRETTY_FUNCTION__ << " closing Previous/Existing sockfd"
<< std::endl;
net_internal_close(sockfd);
}
@ -1348,7 +1362,7 @@ int pqissl::accept_locked( SSL *ssl, int fd,
*/
sockaddr_storage_copy(foreign_addr, remote_addr);
std::cerr << __PRETTY_FUNCTION__ << " SUCCESSFUL connection to: "
RsInfo() << __PRETTY_FUNCTION__ << " SUCCESSFUL connection to: "
<< PeerId().toStdString() << " remoteaddr: "
<< sockaddr_storage_iptostring(remote_addr) << std::endl;

View file

@ -424,23 +424,8 @@ int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool
{
// attempt the accept again.
int fd = SSL_get_fd(incoming_connexion_info.ssl);
AuthSSL::getAuthSSL()->setCurrentConnectionAttemptInfo(RsPgpId(),RsPeerId(),std::string()) ;
int err = SSL_accept(incoming_connexion_info.ssl);
// Now grab the connection info that was filled in by the callback.
// In the case the callback did not succeed the SSL certificate will not be accessible
// from SSL_get_peer_certificate, so we need to get it from the callback system.
//
AuthSSL::getAuthSSL()->getCurrentConnectionAttemptInfo(incoming_connexion_info.gpgid,incoming_connexion_info.sslid,incoming_connexion_info.sslcn) ;
#ifdef DEBUG_LISTENNER
std::cerr << "Info from callback: " << std::endl;
std::cerr << " Got PGP Id = " << incoming_connexion_info.gpgid << std::endl;
std::cerr << " Got SSL Id = " << incoming_connexion_info.sslid << std::endl;
std::cerr << " Got SSL CN = " << incoming_connexion_info.sslcn << std::endl;
#endif
if (err <= 0)
{
int ssl_err = SSL_get_error(incoming_connexion_info.ssl, err);
@ -486,10 +471,22 @@ int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool
break;
}
closeConnection(fd, incoming_connexion_info.ssl) ;
pqioutput(PQL_WARNING, pqissllistenzone, "Read Error on the SSL Socket\nShutting it down!");
// We use SSL_get_verify_result() in order to differentiate two cases:
// case 1: the incoming connection is closed because the peer is not a friend. This is already handled in authssl.
// case 2: the incoming connection is closed because no authentication info is available, in which case it returns X509_V_OK
auto vres = SSL_get_verify_result(incoming_connexion_info.ssl);
if(vres == X509_V_OK && nullptr != rsEvents)
{
auto ev = std::make_shared<RsAuthSslConnectionAutenticationEvent>();
ev->mLocator = RsUrl(incoming_connexion_info.addr);
ev->mErrorCode = RsAuthSslError::MISSING_AUTHENTICATION_INFO;
rsEvents->postEvent(ev);
}
closeConnection(fd, incoming_connexion_info.ssl);
// failure -1, pending 0, sucess 1.
return -1;
}
@ -505,23 +502,22 @@ int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool
incoming_connexion_info.sslcn = RsX509Cert::getCertName(*x509);
incoming_connexion_info.sslid = RsX509Cert::getCertSslId(*x509);
#ifdef DEBUG_LISTENNER
#ifndef DEBUG_LISTENNER
std::cerr << "ContinueSSL:" << std::endl;
std::cerr << " Got PGP Id = " << incoming_connexion_info.gpgid << std::endl;
std::cerr << " Got SSL Id = " << incoming_connexion_info.sslid << std::endl;
std::cerr << " Got SSL CN = " << incoming_connexion_info.sslcn << std::endl;
#endif
}
#ifdef DEBUG_LISTENNER
else
std::cerr << " no info." << std::endl;
#endif
// if it succeeds
if (0 < completeConnection(fd, incoming_connexion_info))
{
return 1;
}
/* else we shut it down! */
pqioutput(PQL_WARNING, pqissllistenzone,