[pan2/testing: 239/279] moved blacklist for server connections from nntp-pool to certstore (servers are blacklisted on faile
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2/testing: 239/279] moved blacklist for server connections from nntp-pool to certstore (servers are blacklisted on faile
- Date: Sat, 3 Dec 2011 22:41:40 +0000 (UTC)
commit 2ad72e3180cf9d887eefbf6e7d66bca70eea3b25
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date: Wed Nov 9 21:49:03 2011 +0100
moved blacklist for server connections from nntp-pool to certstore
(servers are blacklisted on failed connection attempts and whitelisted
on succesful addition of a valid SSL certificate)
pan/gui/gui.cc | 5 +-
pan/tasks/cert-store.cc | 183 +++++++++++++++++++++++++++++++++-----
pan/tasks/cert-store.h | 16 +++-
pan/tasks/nntp-pool.cc | 14 ++--
pan/tasks/socket-impl-openssl.cc | 21 ++++-
pan/tasks/socket-impl-openssl.h | 4 +
6 files changed, 210 insertions(+), 33 deletions(-)
---
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index 1749ac7..1838ee3 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -1307,6 +1307,7 @@ bool GUI::deletion_confirmation_dialog()
bool GUI :: confirm_accept_new_cert_dialog(GtkWindow * parent, X509* cert, const Quark& server)
{
bool ret(false);
+
char buf[4096];
CertStore::pretty_print_x509(buf,sizeof(buf), server, cert);
gdk_threads_enter();
@@ -2103,7 +2104,7 @@ GUI :: on_verify_cert_failed(X509* cert, std::string server, int nr)
void
GUI :: on_valid_cert_added (X509* cert, std::string server)
-{
+{}
+
-}
#endif
diff --git a/pan/tasks/cert-store.cc b/pan/tasks/cert-store.cc
index dbb33aa..d911a7c 100644
--- a/pan/tasks/cert-store.cc
+++ b/pan/tasks/cert-store.cc
@@ -60,14 +60,11 @@ namespace pan
int
verify_callback(int ok, X509_STORE_CTX *store)
-// verify_callback(X509_STORE_CTX *store, void* args)
{
SSL * ssl = (SSL*)X509_STORE_CTX_get_ex_data(store, SSL_get_ex_data_X509_STORE_CTX_idx());
mydata_t* mydata = (mydata_t*)SSL_get_ex_data(ssl, SSL_get_fd(ssl));
-// CertStore * me = (CertStore*)args;
-
if (!ok)
{
if (mydata->ignore_all==1) return 1;
@@ -76,20 +73,16 @@ namespace pan
int depth = X509_STORE_CTX_get_error_depth(store);
int err = X509_STORE_CTX_get_error(store);
- if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN)
+ /* accept user-override on self-signed certificates */
+ if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
+ err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
mydata->cs->verify_failed(cert, mydata->server, err);
}
return ok;
-// SSL_CTX_set_verify(me->get_ctx(), SSL_VERIFY_PEER, store->verify_cb);
-//
-// int ok =
-//
-// }
-
}
-void
+int
CertStore :: get_all_certs_from_disk(std::set<X509*>& setme)
{
char filename[PATH_MAX];
@@ -122,7 +115,7 @@ CertStore :: get_all_certs_from_disk(std::set<X509*>& setme)
}
g_dir_close (dir);
- if (cnt != 0) Log::add_info_va(_("Succesfully added %d SSL PEM certificate(s) to Certificate Store."), cnt);
+ return cnt;
}
void
@@ -133,11 +126,12 @@ CertStore :: init_me()
_store = SSL_CTX_get_cert_store(_ctx);
std::set<X509*> certs;
+ int r(0);
get_all_certs_from_disk (certs);
foreach_const (std::set<X509*>, certs, it)
- X509_STORE_add_cert(_store, *it);
-// SSL_CTX_set_cert_verify_callback(_ctx, verify_callback, (void*)this);
- SSL_CTX_set_verify(_ctx, SSL_VERIFY_PEER, verify_callback);
+ if (X509_STORE_add_cert(_store, *it) != 0) ++r;
+ if (r != 0) Log::add_info_va(_("Succesfully added %d SSL PEM certificate(s) to Certificate Store."), r);
+ SSL_CTX_set_verify(_ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback);
}
@@ -229,7 +223,7 @@ namespace
unsigned int n;
if (! X509_digest(cert, EVP_md5(), md, &n))
- res += _("Not available.");
+ res = _("Not available.");
else {
char hex[] = "0123456789ABCDEF";
char fp[EVP_MAX_MD_SIZE*3];
@@ -240,26 +234,173 @@ namespace
fp[i*3+1] = hex[(md[i] >> 0) & 0xF];
fp[i*3+2] = i == n - 1 ? '\0' : ':';
}
- res += fp;
+ res = fp;
}
}
return res;
}
+ std::string
+ get_x509_enddate(X509* cert)
+ {
+ std::string res;
+
+ return res;
+ }
+
+}
+
+time_t
+getTimeFromASN1(const ASN1_TIME * aTime)
+{
+ time_t lResult = 0;
+
+
+ char lBuffer[24];
+ char * pBuffer = lBuffer;
+
+
+ size_t lTimeLength = aTime->length;
+ char * pString = (char *)aTime->data;
+
+
+ if (aTime->type == V_ASN1_UTCTIME)
+ {
+ if ((lTimeLength < 11) || (lTimeLength > 17))
+ {
+ return 0;
+ }
+
+
+ memcpy(pBuffer, pString, 10);
+ pBuffer += 10;
+ pString += 10;
+ }
+ else
+ {
+ if (lTimeLength < 13)
+ {
+ return 0;
+ }
+
+
+ memcpy(pBuffer, pString, 12);
+ pBuffer += 12;
+ pString += 12;
+ }
+
+
+ if ((*pString == 'Z') || (*pString == '-') || (*pString == '+'))
+ {
+ *(pBuffer++) = '0';
+ *(pBuffer++) = '0';
+ }
+ else
+ {
+ *(pBuffer++) = *(pString++);
+ *(pBuffer++) = *(pString++);
+ // Skip any fractional seconds...
+ if (*pString == '.')
+ {
+ pString++;
+ while ((*pString >= '0') && (*pString <= '9'))
+ {
+ pString++;
+ }
+ }
+ }
+
+
+ *(pBuffer++) = 'Z';
+ *(pBuffer++) = '\0';
+
+
+ time_t lSecondsFromUCT;
+ if (*pString == 'Z')
+ {
+ lSecondsFromUCT = 0;
+ }
+ else
+ {
+ if ((*pString != '+') && (pString[5] != '-'))
+ {
+ return 0;
+ }
+
+
+ lSecondsFromUCT = ((pString[1]-'0') * 10 + (pString[2]-'0')) * 60;
+ lSecondsFromUCT += (pString[3]-'0') * 10 + (pString[4]-'0');
+ if (*pString == '-')
+ {
+ lSecondsFromUCT = -lSecondsFromUCT;
+ }
+ }
+
+
+ tm lTime;
+ lTime.tm_sec = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
+ lTime.tm_min = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
+ lTime.tm_hour = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
+ lTime.tm_mday = ((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0');
+ lTime.tm_mon = (((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0')) - 1;
+ lTime.tm_year = ((lBuffer[0] - '0') * 10) + (lBuffer[1] - '0');
+ if (lTime.tm_year < 50)
+ {
+ lTime.tm_year += 100; // RFC 2459
+ }
+ lTime.tm_wday = 0;
+ lTime.tm_yday = 0;
+ lTime.tm_isdst = 0; // No DST adjustment requested
+
+ lResult = mktime(&lTime);
+
+ if ((time_t)-1 != lResult)
+ {
+ if (0 != lTime.tm_isdst)
+ lResult -= 3600; // mktime may adjust for DST (OS dependent)
+ lResult += lSecondsFromUCT;
+ }
+ else
+ lResult = 0;
+
+ return lResult;
}
void
CertStore :: pretty_print_x509 (char* buf, size_t size, const Quark& server, X509* cert)
{
if (!cert) return;
+// char buffer[4096];
+// int len;
+// int i = X509_get_ext_by_NID(cert, NID_invalidity_date, -1);
+// BIO *bio = BIO_new(BIO_s_mem());
+// X509_EXTENSION * ex = X509_get_ext( cert,i);
+// std::cerr<<"pretty "<<i<<" "<<ex<<" "<<bio<<std::endl;
+// if(!X509V3_EXT_print(bio, ex, 0, 0))
+// M_ASN1_OCTET_STRING_print(bio,ex->value);
+// len = BIO_read(bio, buffer, 4096);
+// buffer[len] = '\0';
+// BIO_free(bio);
+
+ time_t t = getTimeFromASN1(cert->cert_info->validity->notAfter);
+ time_t t2 = getTimeFromASN1(cert->cert_info->validity->notBefore);
+ EvolutionDateMaker date_maker;
+ char * until = date_maker.get_date_string (t);
+ char * before = date_maker.get_date_string (t2);
+
g_snprintf(buf,size, _("The current server <b>'%s'</b> sent this security certificate :\n\n"
- "<b>Issuer :</b> \n%s\n\n"
+ "<b>Issuer :</b>\n%s\n\n"
"<b>Subject : </b>\n%s\n\n"
- "<b>Fingerprint : </b>\n%s\n\n"),
+ "<b>Valid until : </b>%s\n\n"
+ "<b>Not valid before : </b>%s\n\n"
+ "<b>Fingerprint (MD5) : </b>\n%s\n\n"),
server.c_str(),
- X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0),
- X509_NAME_oneline(X509_get_subject_name(cert), 0, 0),
+ X509_NAME_oneline(cert->cert_info->issuer, 0, 0),
+ X509_NAME_oneline(cert->cert_info->subject, 0, 0),
+ until,
+ before,
get_x509_fingerpint_md5(cert).c_str());
+
}
diff --git a/pan/tasks/cert-store.h b/pan/tasks/cert-store.h
index 9105b8e..3794acd 100644
--- a/pan/tasks/cert-store.h
+++ b/pan/tasks/cert-store.h
@@ -58,11 +58,12 @@ namespace pan
X509_STORE* _store;
std::string _path;
std::vector<SSL_SESSION*> _sessions;
+ certs_t _blacklist;
public:
SSL_CTX* get_ctx() { return _ctx; }
X509_STORE* get_store() const { return _store; }
- void get_all_certs_from_disk(std::set<X509*>& setme);
+ int get_all_certs_from_disk(std::set<X509*>& setme);
const X509* get_cert_to_server(const Quark& server) const;
static void pretty_print_x509 (char* buf, size_t size, const Quark& server, X509* cert);
SSL_SESSION* get_session()
@@ -81,6 +82,19 @@ namespace pan
_sessions.push_back(s);
}
+ bool in_blacklist (const Quark& s)
+ {
+ return _blacklist.count(s) != 0;
+ }
+ void blacklist (const Quark& s)
+ {
+ _blacklist.insert(s);
+ }
+ void whitelist (const Quark& s)
+ {
+ _blacklist.erase(s);
+ }
+
private:
void remove_hard(const Quark&);
diff --git a/pan/tasks/nntp-pool.cc b/pan/tasks/nntp-pool.cc
index 7b03538..89aed74 100644
--- a/pan/tasks/nntp-pool.cc
+++ b/pan/tasks/nntp-pool.cc
@@ -275,14 +275,13 @@ NNTP_Pool :: request_nntp (WorkerPool& threadpool)
std::string address;
int port;
if (_server_info.get_server_addr (_server, address, port))
- {
- if (_blacklist.count(address) == 0)
+ if (!_certstore.in_blacklist(address))
+// if (_blacklist.count(address) == 0)
{
++_pending_connections;
const bool ssl(_server_info.get_server_ssl_support(_server));
_socket_creator->create_socket (address, port, threadpool, this, ssl);
}
- }
}
}
@@ -348,13 +347,16 @@ NNTP_Pool :: idle_upkeep ()
void
NNTP_Pool :: on_verify_cert_failed (X509* cert, std::string server, int nr)
{
- _blacklist.insert(server);
- abort_tasks();
+// _blacklist.erase(server);
+ _certstore.blacklist(server);
+ std::cerr<<"adding "<<server<<" to blacklist ("<<cert<<", "<<nr<<")"<<std::endl;
}
void
NNTP_Pool :: on_valid_cert_added (X509* cert, std::string server)
{
- _blacklist.erase(server);
+// _blacklist.insert(server);
+ _certstore.whitelist(server);
+ std::cerr<<"removing "<<server<<" from blacklist ("<<cert<<")"<<std::endl;
}
#endif
diff --git a/pan/tasks/socket-impl-openssl.cc b/pan/tasks/socket-impl-openssl.cc
index aea118e..054650d 100644
--- a/pan/tasks/socket-impl-openssl.cc
+++ b/pan/tasks/socket-impl-openssl.cc
@@ -121,7 +121,8 @@ GIOChannelSocketSSL :: GIOChannelSocketSSL (SSL_CTX* ctx, CertStore& cs):
_in_buf (g_string_new (0)),
_io_performed (false),
_ctx(ctx),
- _certstore(cs)
+ _certstore(cs),
+ _rehandshake(false)
{
// std::cerr<<"GIOChannelSocketSSL ctor " << (void*)this<<std::endl;
cs.add_listener(this);
@@ -373,7 +374,7 @@ namespace
}
- int ssl_handshake(GIOChannel *handle, CertStore::Listener* listener, CertStore* cs, std::string host, SSL_SESSION* session)
+ int ssl_handshake(GIOChannel *handle, CertStore::Listener* listener, CertStore* cs, std::string host, SSL_SESSION* session, bool rehandshake)
{
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
@@ -392,6 +393,20 @@ namespace
SSL_set_ex_data(chan->ssl, SSL_get_fd(chan->ssl), &mydata);
if (session) ret = SSL_set_session(chan->ssl, session);
+// if (rehandshake)
+// {
+//// SSL_set_verify(ssl,SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
+//
+// /* Stop the client from just resuming the un-authenticated session */
+// SSL_set_session_id_context(chan->ssl, (void *)&s_server_auth_session_id_context, sizeof(s_server_auth_session_id_context));
+//
+// if(SSL_renegotiate(ssl)<=0)
+// return 1;
+// if(SSL_do_handshake(ssl)<=0)
+// ssl->state=SSL_ST_ACCEPT;
+// if(SSL_do_handshake(ssl)<=0)
+// return 1;
+// }
ret = SSL_connect(chan->ssl);
if (ret <= 0) {
@@ -786,7 +801,7 @@ GIOChannelSocketSSL :: ssl_get_iochannel(GIOChannel *handle, gboolean verify)
gchan->read_buf = g_string_sized_new(4096*128);
int ret;
- if ((ret = ssl_handshake(gchan, this, &_certstore, _host, _session)) == 0)
+ if ((ret = ssl_handshake(gchan, this, &_certstore, _host, _session, _rehandshake)) == 0)
{
g_io_channel_set_flags (handle, G_IO_FLAG_NONBLOCK, 0);
return gchan;
diff --git a/pan/tasks/socket-impl-openssl.h b/pan/tasks/socket-impl-openssl.h
index 20eef27..ac71638 100644
--- a/pan/tasks/socket-impl-openssl.h
+++ b/pan/tasks/socket-impl-openssl.h
@@ -71,6 +71,10 @@ namespace pan
SSL_CTX * _ctx;
CertStore& _certstore;
SSL_SESSION* _session;
+ bool _rehandshake;
+
+ public:
+ void set_rehandshake (bool setme) { _rehandshake = setme; }
private:
enum WatchMode { READ_NOW, WRITE_NOW, IGNORE_NOW };
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]