[pan2: 198/268] Changes to the certificate mechanisms: * load/save from/to servers.xml tag * certstore loads certs a
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2: 198/268] Changes to the certificate mechanisms: * load/save from/to servers.xml tag * certstore loads certs a
- Date: Mon, 2 Jan 2012 15:54:39 +0000 (UTC)
commit 44229f2defd6421d9241dd7e8f0be66bb9c30f4d
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date: Fri Nov 18 13:40:34 2011 +0100
Changes to the certificate mechanisms:
* load/save from/to servers.xml tag
* certstore loads certs at startup from this file
* user-modifiable
pan.cbp | 2 +
pan/data-impl/Makefile.am | 6 +-
pan/data-impl/cert-store.cc | 234 ----------------------------------
pan/data-impl/data-impl.cc | 1 +
pan/data-impl/data-impl.h | 28 ++---
pan/data-impl/server.cc | 43 ++++++-
pan/data/Makefile.am | 22 ++--
pan/data/cert-store.cc | 229 +++++++++++++++++++++++++++++++++
pan/{data-impl => data}/cert-store.h | 23 +++-
pan/data/data.h | 28 ++++-
pan/data/encode-cache.h | 9 +-
pan/data/server-info.h | 4 +
pan/general/file-util.cc | 10 +-
pan/general/file-util.h | 2 +
pan/gui/gui.cc | 23 +++-
pan/gui/gui.h | 4 +-
pan/gui/pan.cc | 2 +-
pan/gui/server-ui.cc | 20 ++-
pan/tasks/nntp-pool.cc | 2 +-
pan/tasks/nntp-pool.h | 4 +-
pan/tasks/queue.h | 2 +-
pan/tasks/socket-impl-main.cc | 2 +-
pan/tasks/socket-impl-main.h | 4 +-
pan/tasks/socket-impl-openssl.cc | 11 +-
pan/tasks/socket-impl-openssl.h | 4 +-
pan/tasks/task-groups.h | 2 +-
pan/tasks/task-upload.h | 1 +
27 files changed, 400 insertions(+), 322 deletions(-)
---
diff --git a/pan.cbp b/pan.cbp
index cd009b6..382480f 100644
--- a/pan.cbp
+++ b/pan.cbp
@@ -70,6 +70,8 @@
<Unit filename="pan/data/article-test.cc" />
<Unit filename="pan/data/article.cc" />
<Unit filename="pan/data/article.h" />
+ <Unit filename="pan/data/cert-store.cc" />
+ <Unit filename="pan/data/cert-store.h" />
<Unit filename="pan/data/data.cc" />
<Unit filename="pan/data/data.h" />
<Unit filename="pan/data/defgroup.h" />
diff --git a/pan/data-impl/Makefile.am b/pan/data-impl/Makefile.am
index 4b817b9..695c050 100644
--- a/pan/data-impl/Makefile.am
+++ b/pan/data-impl/Makefile.am
@@ -13,8 +13,7 @@ libpandata_a_SOURCES = \
server.cc \
my-tree.cc \
task-archive.cc \
- xover.cc \
- cert-store.cc
+ xover.cc
noinst_HEADERS = \
article-filter.h \
@@ -23,8 +22,7 @@ noinst_HEADERS = \
data-io.h \
defgroup.h \
profiles.h \
- memchunk.h \
- cert-store.h
+ memchunk.h
noinst_PROGRAMS = \
add-server \
diff --git a/pan/data-impl/data-impl.cc b/pan/data-impl/data-impl.cc
index 13b353f..531da3a 100644
--- a/pan/data-impl/data-impl.cc
+++ b/pan/data-impl/data-impl.cc
@@ -65,6 +65,7 @@ DataImpl :: DataImpl (bool unit_test, int cache_megs, DataIO * io):
ProfilesImpl (*io),
_cache (get_cache_path(), cache_megs),
_encode_cache (get_encode_cache_path(), cache_megs),
+ _certstore(*this),
_unit_test (unit_test),
_data_io (io),
_descriptions_loaded (false),
diff --git a/pan/data-impl/data-impl.h b/pan/data-impl/data-impl.h
index 012e890..fc96789 100644
--- a/pan/data-impl/data-impl.h
+++ b/pan/data-impl/data-impl.h
@@ -45,7 +45,7 @@
#include <pan/data-impl/memchunk.h>
#ifdef HAVE_OPENSSL
- #include <pan/data-impl/cert-store.h>
+ #include <pan/data/cert-store.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
@@ -111,29 +111,15 @@ namespace pan
void save_server_properties (DataIO&) const;
- struct Server
- {
- std::string username;
- std::string password;
- std::string host;
- std::string newsrc_filename;
- int port;
- int article_expiration_age;
- int max_connections;
- int rank;
- int ssl_support;
- typedef sorted_vector<Quark,true,AlphabeticalQuarkOrdering> groups_t;
- groups_t groups;
-
- Server(): port(119), article_expiration_age(31), max_connections(2), rank(1), ssl_support(0) {}
- };
-
typedef Loki::AssocVector<Quark,Server> servers_t;
servers_t _servers;
Server* find_server (const Quark& server);
- const Server* find_server (const Quark& server) const;
+
+ public:
+ virtual const Server* find_server (const Quark& server) const;
+ virtual bool find_server_by_hn (const Quark& server, Quark& setme) const;
public: // mutators
@@ -157,6 +143,8 @@ namespace pan
virtual void set_server_ssl_support (const Quark& server, int ssl);
+ virtual void set_server_cert (const Quark & server, const StringView & cert);
+
virtual void set_server_article_expiration_age (const Quark & server,
int days);
@@ -183,6 +171,8 @@ namespace pan
virtual bool get_server_ssl_support (const Quark & server) const;
+ virtual std::string get_server_cert (const Quark & server) const;
+
virtual int get_server_rank (const Quark& server) const;
virtual int get_server_limits (const Quark & server) const;
diff --git a/pan/data-impl/server.cc b/pan/data-impl/server.cc
index f28baa7..10af926 100644
--- a/pan/data-impl/server.cc
+++ b/pan/data-impl/server.cc
@@ -78,26 +78,36 @@ DataImpl :: add_new_server ()
return new_server;
}
-DataImpl :: Server*
+Data :: Server*
DataImpl :: find_server (const Quark& server)
{
Server * retval (0);
+
servers_t::iterator it (_servers.find (server));
if (it != _servers.end())
retval = &it->second;
return retval;
}
-const DataImpl :: Server*
+const Data :: Server*
DataImpl :: find_server (const Quark& server) const
{
const Server * retval (0);
+
servers_t::const_iterator it (_servers.find (server));
if (it != _servers.end())
retval = &it->second;
return retval;
}
+bool
+DataImpl :: find_server_by_hn (const Quark& server, Quark& setme) const
+{
+ foreach_const(servers_t, _servers, it)
+ if (it->second.host == server.c_str()) { setme = it->first; return true; }
+ return false;
+}
+
void
DataImpl :: set_server_article_expiration_age (const Quark & server,
int days)
@@ -168,6 +178,16 @@ DataImpl :: set_server_ssl_support (const Quark & server,
}
void
+DataImpl :: set_server_cert (const Quark & server,
+ const StringView & cert)
+{
+ Server * s (find_server (server));
+ assert (s != 0);
+ s->cert = cert;
+
+}
+
+void
DataImpl :: save_server_info (const Quark& server)
{
Server * s (find_server (server));
@@ -226,6 +246,17 @@ DataImpl :: get_server_ssl_support (const Quark & server) const
return retval;
}
+std::string
+DataImpl :: get_server_cert (const Quark & server) const
+{
+ std::string str;
+ const Server * s (find_server (server));
+ if (s) {
+ str = s->cert;
+ }
+ return str;
+}
+
int
DataImpl :: get_server_limits (const Quark & server) const
{
@@ -350,7 +381,9 @@ DataImpl :: load_server_properties (const DataIO& source)
s.max_connections = to_int (kv["connection-limit"], 2);
s.article_expiration_age = to_int(kv["expire-articles-n-days-old"], 31);
s.rank = to_int(kv["rank"], 1);
- s.ssl_support = to_int(kv["use-ssl"], 0);
+ int ssl(to_int(kv["use-ssl"], 0));
+ s.ssl_support = ssl;
+ if (ssl == 1) s.cert = kv["cert"];
s.newsrc_filename = kv["newsrc"];
if (s.newsrc_filename.empty()) { // set a default filename
std::ostringstream o;
@@ -359,7 +392,6 @@ DataImpl :: load_server_properties (const DataIO& source)
}
}
-// save_server_properties (*const_cast<DataIO*>(&source));
}
namespace
@@ -404,7 +436,8 @@ DataImpl :: save_server_properties (DataIO& data_io) const
<< indent(depth) << "<connection-limit>" << s->max_connections << "</connection-limit>\n"
<< indent(depth) << "<newsrc>" << s->newsrc_filename << "</newsrc>\n"
<< indent(depth) << "<rank>" << s->rank << "</rank>\n"
- << indent(depth) << "<use-ssl>" << s->ssl_support << "</use-ssl>\n";
+ << indent(depth) << "<use-ssl>" << s->ssl_support << "</use-ssl>\n"
+ << indent(depth) << "<cert>" << s->cert << "</cert>\n";
*out << indent(--depth) << "</server>\n";
}
diff --git a/pan/data/Makefile.am b/pan/data/Makefile.am
index b979ea9..3e4e34b 100644
--- a/pan/data/Makefile.am
+++ b/pan/data/Makefile.am
@@ -1,7 +1,7 @@
AM_CPPFLAGS = -I top_srcdir@ @GMIME_CFLAGS@ @GLIB_CFLAGS@ @GTK_CFLAGS@
LDADD = @GTK_LIBS@
-SUBDIRS = decode-test-cache
+#SUBDIRS = decode-test-cache
noinst_LIBRARIES = libdata.a
@@ -9,6 +9,7 @@ libdata_a_SOURCES = \
article.cc \
article-cache.cc \
encode-cache.cc \
+ cert-store.cc \
data.cc \
parts.cc \
xref.cc
@@ -17,23 +18,24 @@ noinst_HEADERS = \
article.h \
article-cache.h \
encode-cache.h \
+ cert-store.h \
data.h \
defgroup.h \
parts.h \
server-info.h \
xref.h
-noinst_PROGRAMS = \
- article-test \
- xref-test
+#noinst_PROGRAMS = \
+# article-test \
+# xref-test
#dnl decode-test
#dnl decode_test_SOURCES = decode-test.cc
#dnl decode_test_LDADD = $(TEST_LDADD)
-TESTS = $(noinst_PROGRAMS)
-TEST_LDADD = ./libdata.a ../usenet-utils/libusenetutils.a ../general/libgeneralutils.a @GMIME_LIBS@ @GLIB_LIBS@
-xref_test_SOURCES = xref-test.cc
-xref_test_LDADD = $(TEST_LDADD)
-article_test_SOURCES = article-test.cc
-article_test_LDADD = $(TEST_LDADD)
+#TESTS = $(noinst_PROGRAMS)
+#TEST_LDADD = ./libdata.a ../usenet-utils/libusenetutils.a ../general/libgeneralutils.a @GMIME_LIBS@ @GLIB_LIBS@
+#xref_test_SOURCES = xref-test.cc
+#xref_test_LDADD = $(TEST_LDADD)
+#article_test_SOURCES = article-test.cc
+#article_test_LDADD = $(TEST_LDADD)
diff --git a/pan/data/cert-store.cc b/pan/data/cert-store.cc
new file mode 100644
index 0000000..60715fe
--- /dev/null
+++ b/pan/data/cert-store.cc
@@ -0,0 +1,229 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2006 Charles Kerr <charles rebelbase com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <string>
+#include <glib/giochannel.h>
+#include <glib/gstring.h>
+#include <pan/tasks/socket.h>
+#include <config.h>
+#include <map>
+#include <string>
+#include <sstream>
+#include <fstream>
+#include <iostream>
+#include <string>
+
+extern "C" {
+ #include <glib/gi18n.h>
+}
+
+#include <pan/general/debug.h>
+#include <pan/general/e-util.h>
+#include <pan/general/macros.h>
+#include <pan/usenet-utils/ssl-utils.h>
+#include <pan/general/file-util.h>
+#include <pan/general/messages.h>
+#include <pan/general/log.h>
+#include <pan/general/string-view.h>
+#include <pan/usenet-utils/mime-utils.h>
+
+#include "cert-store.h"
+
+using namespace pan;
+
+#ifdef HAVE_OPENSSL
+namespace pan
+{
+
+ int
+ verify_callback(int ok, X509_STORE_CTX *store)
+ {
+
+ 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));
+
+ if (!ok)
+ {
+ if (mydata->ignore_all==1) { return 1; }
+
+ X509 *cert = X509_STORE_CTX_get_current_cert(store);
+ int depth = X509_STORE_CTX_get_error_depth(store);
+ int err = X509_STORE_CTX_get_error(store);
+
+ /* 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 ||
+ err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
+ err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
+ mydata->cs->verify_failed(cert, mydata->server, mydata->cert_name, err);
+ else
+ g_warning("[[DEBUG:]] unknown error condition, please report me: %s", ssl_err_to_string(err).c_str());
+ }
+
+ return ok;
+ }
+
+ int
+ CertStore :: get_all_certs_from_disk(std::set<X509*>& setme)
+ {
+
+ int cnt(0);
+ quarks_t servers(_data.get_servers());
+ foreach_const(quarks_t, servers, it)
+ {
+ const Data::Server* s(_data.find_server(*it));
+ if (!s) continue;
+ const char* filename(s->cert.c_str());
+ if (!filename) continue;
+ FILE *fp = fopen(filename,"r");
+ if (!fp) continue;
+ X509 *x = X509_new();
+ if (!x) { fclose(fp); continue; }
+ PEM_read_X509(fp,&x, 0, 0);
+ fclose(fp);
+ setme.insert(x);
+ _certs.insert(s->host);
+ _cert_to_server[s->host] = x;
+ ++cnt;
+ }
+
+ return cnt;
+ }
+
+ void
+ CertStore :: init_me()
+ {
+ assert (_ctx);
+
+ _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)
+ 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);
+
+ }
+
+ void
+ CertStore :: remove_hard(const Quark& server)
+ {
+ char buf[2048];
+ g_snprintf (buf, sizeof(buf), "%s%c%s.pem", _path.c_str(), G_DIR_SEPARATOR, server.c_str());
+ unlink(buf);
+ }
+
+ void
+ CertStore :: remove (const Quark& server)
+ {
+ if (_cert_to_server.count(server) > 0)
+ {
+ _cert_to_server.erase(server);
+ _certs.erase(server);
+ remove_hard(server);
+// SSL_CTX_set_cert_store(_ctx, X509_STORE_new());
+ Quark setme;
+ _data.find_server_by_hn(server, setme);
+ _data.set_server_cert(setme, "");
+ _data.save_server_info(setme);
+ init_me();
+ }
+
+ }
+
+ CertStore :: CertStore (Data& data): _data(data)
+ {
+ char buf[2048];
+ g_snprintf(buf,sizeof(buf),"%s%cssl_certs",file::get_pan_home().c_str(), G_DIR_SEPARATOR);
+ _path = buf;
+ if (!file::ensure_dir_exists (buf))
+ {
+ std::cerr<<"Error initializing certstore. Check your permissions for the directory \"ssl-certs\" and main subfolder in your home directory! Fatal, exiting.";
+ file::print_file_info(std::cerr, buf);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ CertStore :: ~CertStore ()
+ {}
+
+
+
+ bool
+ CertStore :: add(X509* cert, const Quark& server)
+ {
+ if (!cert || server.empty()) return false;
+ X509_STORE_add_cert(get_store(),cert);
+
+ std::string addr; int port;
+ _data.get_server_addr(server, addr, port);
+ _certs.insert(addr);
+ _cert_to_server[addr] = cert;
+
+ const char* buf(build_cert_name(addr.c_str()).c_str());
+
+ _data.set_server_cert(server, buf);
+ _data.save_server_info(server);
+
+ FILE * fp = fopen(buf, "wb");
+ if (!fp) return false;
+ if (PEM_write_X509(fp, cert) != 1) { fclose(fp); return false; }
+ fclose(fp);
+ chmod (buf, 0600);
+
+ valid_cert_added(cert, server.c_str());
+ return true;
+ }
+
+
+ X509*
+ CertStore :: get_cert_to_server(const Quark& server) const
+ {
+ X509* ret(0);
+ Quark serv;
+
+ /* strip port from server if existing */
+ std::string s(server);
+ std::string::size_type idx = s.rfind(":");
+ if(idx != std::string::npos)
+ serv = s.substr(0,idx);
+ else
+ serv = server;
+
+ if (_cert_to_server.count(serv) > 0)
+ ret = _cert_to_server.find(serv)->second;
+ return ret;
+ }
+
+ std::string
+ CertStore :: build_cert_name(std::string host)
+ {
+ char buf[2048];
+ g_snprintf(buf,sizeof(buf),"%s%cssl_certs%c%s.pem",file::get_pan_home().c_str(),
+ G_DIR_SEPARATOR,G_DIR_SEPARATOR, host.c_str());
+ return buf;
+ }
+
+
+} // namespace pan
+
+
+#endif
diff --git a/pan/data-impl/cert-store.h b/pan/data/cert-store.h
similarity index 88%
rename from pan/data-impl/cert-store.h
rename to pan/data/cert-store.h
index 311c16a..7fe1a80 100644
--- a/pan/data-impl/cert-store.h
+++ b/pan/data/cert-store.h
@@ -28,6 +28,9 @@
#include <openssl/rand.h>
#include <openssl/x509.h>
#endif
+
+#include <pan/data/data.h>
+
#include <pan/tasks/socket.h>
#include <pan/general/quark.h>
#include <pan/general/macros.h>
@@ -39,11 +42,13 @@
namespace pan
{
+ class Data;
+
class CertStore
{
#ifdef HAVE_OPENSSL
public:
- CertStore () ;
+ CertStore (Data& data) ;
virtual ~CertStore () ;
private:
@@ -57,12 +62,13 @@ namespace pan
std::string _path;
std::vector<SSL_SESSION*> _sessions;
certs_t _blacklist;
+ Data& _data;
public:
SSL_CTX* get_ctx() { return _ctx; }
X509_STORE* get_store() const { return _store; }
int get_all_certs_from_disk(std::set<X509*>& setme);
- const X509* get_cert_to_server(const Quark& server) const;
+ X509* get_cert_to_server(const Quark& server) const;
SSL_SESSION* get_session()
{
SSL_SESSION* ret(0);
@@ -103,15 +109,18 @@ namespace pan
void remove_hard(const Quark&);
public:
+
bool add(X509*, const Quark&) ;
void remove (const Quark&);
bool exist (const Quark& q) { return (_certs.count(q) > 0); }
+ static std::string build_cert_name(std::string host);
+
struct Listener
{
virtual ~Listener() {}
/* functions that other listeners listen on */
- virtual void on_verify_cert_failed (X509* cert UNUSED, std::string server UNUSED, int nr UNUSED) = 0;
+ virtual void on_verify_cert_failed (X509* cert UNUSED, std::string server UNUSED, std::string cert_name UNUSED, int nr UNUSED) = 0;
virtual void on_valid_cert_added (X509* cert UNUSED, std::string server UNUSED) = 0;
};
@@ -122,10 +131,11 @@ namespace pan
void remove_listener (Listener * l) { _listeners.erase(l); }
/* notify functions for listener list */
- void verify_failed (X509* c, std::string server, int nr)
+ void verify_failed (X509* c, std::string server, std::string cn, int nr)
{
+ std::cerr<<"verify failed "<<server<<" "<<cn<<"\n";
for (listeners_t::iterator it(_listeners.begin()), end(_listeners.end()); it!=end; ++it)
- (*it)->on_verify_cert_failed (c, server, nr);
+ (*it)->on_verify_cert_failed (c, server, cn, nr);
}
void valid_cert_added (X509* c, std::string server)
@@ -148,12 +158,13 @@ namespace pan
int ignore_all;
CertStore* cs;
std::string server;
+ std::string cert_name;
CertStore::Listener* l;
#else
public:
- CertStore () {};
+ CertStore (Data&) {};
virtual ~CertStore () {};
void add_listener (void * l) {}
diff --git a/pan/data/data.h b/pan/data/data.h
index eb75cbd..fda34ed 100644
--- a/pan/data/data.h
+++ b/pan/data/data.h
@@ -32,14 +32,15 @@
#include <pan/data/article.h>
#include <pan/data/article-cache.h>
#include <pan/data/encode-cache.h>
+#include <pan/data/cert-store.h>
#include <pan/data/server-info.h>
-#include <pan/data-impl/cert-store.h>
namespace pan
{
class FilterInfo;
class RulesInfo;
class Queue;
+ class CertStore;
/**
* Data Interface class for seeing the mapping between groups and servers.
@@ -162,6 +163,26 @@ namespace pan
public virtual Profiles,
public virtual ArticleReferences
{
+
+ public:
+ struct Server
+ {
+ std::string username;
+ std::string password;
+ std::string host;
+ std::string newsrc_filename;
+ std::string cert;
+ int port;
+ int article_expiration_age;
+ int max_connections;
+ int rank;
+ int ssl_support;
+ typedef sorted_vector<Quark,true,AlphabeticalQuarkOrdering> groups_t;
+ groups_t groups;
+
+ Server(): port(119), article_expiration_age(31), max_connections(2), rank(1), ssl_support(0) {}
+ };
+
protected:
Data () {}
@@ -184,6 +205,11 @@ namespace pan
public:
+ /** Gets a quark to the provided hostname */
+ virtual bool find_server_by_hn (const Quark& server, Quark& setme) const = 0;
+
+ virtual const Server* find_server (const Quark& server) const = 0;
+
virtual quarks_t get_servers () const = 0;
virtual void delete_server (const Quark& server) = 0;
diff --git a/pan/data/encode-cache.h b/pan/data/encode-cache.h
index 34091ef..b805825 100644
--- a/pan/data/encode-cache.h
+++ b/pan/data/encode-cache.h
@@ -34,14 +34,11 @@ namespace pan
class StringView;
/**
- * A disk cache for binary attachments.
+ * A disk cache for binary attachments to be yenc-encoded
*
- * This allows a cache to be set to a certain maximum size, where
- * the oldest articles will be aged out when the cache is full.
- *
- * It also has a lock/unlock mechanism to allow the cache to grow
+ * It has a lock/unlock mechanism to allow the cache to grow
* past its limit briefly to allow large multipart articles' pieces
- * to all be held at once (for decoding).
+ * to all be held at once (for encoding).
*
* FIXME: This should probably be an interface class implemented in
* data-impl in the same way profiles was.
diff --git a/pan/data/server-info.h b/pan/data/server-info.h
index 9d20785..cdcf73e 100644
--- a/pan/data/server-info.h
+++ b/pan/data/server-info.h
@@ -64,6 +64,8 @@ namespace pan
virtual void set_server_ssl_support (const Quark& server,
int ssl) = 0;
+ virtual void set_server_cert (const Quark & server, const StringView & cert) = 0;
+
virtual void save_server_info (const Quark& server) = 0;
public: // accessors
@@ -81,6 +83,8 @@ namespace pan
virtual bool get_server_ssl_support (const Quark & server) const = 0;
+ virtual std::string get_server_cert (const Quark & server) const = 0;
+
/** If set_server_limits() has never been called, 2 is returned. */
virtual int get_server_limits (const Quark & server) const = 0;
diff --git a/pan/general/file-util.cc b/pan/general/file-util.cc
index 8b97daa..f4ec2bc 100644
--- a/pan/general/file-util.cc
+++ b/pan/general/file-util.cc
@@ -145,7 +145,8 @@ file :: ensure_dir_exists (const StringView& dirname_sv)
if (cmd == EX_BIT)
if (chmod(dirname.c_str(), 0740))
{
- Log::add_urgent_va("Error setting executable bit for directory '%s' : Please check your permissions.", dirname.c_str());
+ Log::add_urgent_va("Error setting executable bit for directory '%s' : "
+ "Please check your permissions.", dirname.c_str());
print_file_info(std::cerr,dirname.c_str());
}
}
@@ -158,12 +159,7 @@ file :: file_exists (const char * filename)
return filename && *filename && g_file_test (filename, G_FILE_TEST_EXISTS);
}
-/**
-*** Attempt to make a filename safe for use.
-*** This is done by replacing illegal characters with '_'.
-*** This function assumes the input is UTF8 since gmime uses UTF8 interface.
-*** return value must be g_free'd.
-**/
+
std::string
file :: sanitize (const StringView& fname)
{
diff --git a/pan/general/file-util.h b/pan/general/file-util.h
index 4f49d1b..1ef563a 100644
--- a/pan/general/file-util.h
+++ b/pan/general/file-util.h
@@ -79,6 +79,8 @@ namespace pan
* <ol>
* <li>Replacing illegal characters with '_'.
* <li>Ensure the resulting string is UTF8-safe
+ * <li>This function assumes the input is UTF8 since gmime uses UTF8 interface.
+ * <li>Return value must be g_free'd.
* </ol>
*/
std::string sanitize (const StringView& filename);
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index 8597758..fede36f 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -2096,20 +2096,33 @@ GUI :: on_prefs_string_changed (const StringView& key, const StringView& value)
#ifdef HAVE_OPENSSL
void
-GUI :: on_verify_cert_failed(X509* cert, std::string server, int nr)
+GUI :: on_verify_cert_failed(X509* cert, std::string server, std::string cert_name, int nr)
{
- if (!cert) return;
+ std::cerr<<"on verify failed gui ("<<server<<") ("<<cert_name<<")\n";
+ if (!cert || cert_name.empty() || server.empty()) return;
+
+ Quark setme;
+ bool found(_data.find_server_by_hn(server, setme));
+
if (GUI::confirm_accept_new_cert_dialog(get_window(_root),cert,server))
- if (!_certstore.add(cert, server))
+ if (!_certstore.add(cert, setme))
Log::add_urgent_va("Error adding certificate of server '%s' to Certificate Store",server.c_str());
+ else
+ {
+ std::cerr<<"added cert "<<cert<<" to server "<<server<<std::endl;
+ if (found)
+ {
+ std::cerr<<"on verify failed gui ("<<server<<") ("<<cert_name<<")\n";
+ _data.set_server_cert(setme, cert_name);
+ _data.save_server_info(setme);
+ }
+ }
}
void
GUI :: on_valid_cert_added (X509* cert, std::string server)
{
- std::cerr<<"whitelist "<<server<<std::endl;
-
/* whitelist to make avaible for nntp-pool */
_certstore.whitelist(server);
diff --git a/pan/gui/gui.h b/pan/gui/gui.h
index 7617890..3dec2fd 100644
--- a/pan/gui/gui.h
+++ b/pan/gui/gui.h
@@ -25,7 +25,7 @@
#include <pan/data/article-cache.h>
#include <pan/data/encode-cache.h>
#include <pan/tasks/queue.h>
-#include <pan/data-impl/cert-store.h>
+#include <pan/data/cert-store.h>
#include <pan/gui/action-manager.h>
#include <pan/gui/pan-ui.h>
#include <pan/gui/prefs.h>
@@ -183,7 +183,7 @@ namespace pan
virtual void on_queue_error (Queue&, const StringView& message);
#ifdef HAVE_OPENSSL
private: // CertStore::Listener
- virtual void on_verify_cert_failed(X509*, std::string, int);
+ virtual void on_verify_cert_failed(X509*, std::string, std::string, int);
virtual void on_valid_cert_added (X509*, std::string);
#endif
private: // Log::Listener
diff --git a/pan/gui/pan.cc b/pan/gui/pan.cc
index 679e387..3d3f5c8 100644
--- a/pan/gui/pan.cc
+++ b/pan/gui/pan.cc
@@ -42,7 +42,7 @@ extern "C" {
#include <pan/tasks/socket-impl-openssl.h>
#endif
-#include <pan/data-impl/cert-store.h>
+#include <pan/data/cert-store.h>
#include <pan/tasks/socket-impl-gio.h>
#include <pan/tasks/socket-impl-main.h>
#include <pan/tasks/task-groups.h>
diff --git a/pan/gui/server-ui.cc b/pan/gui/server-ui.cc
index 4403fad..48e81d9 100644
--- a/pan/gui/server-ui.cc
+++ b/pan/gui/server-ui.cc
@@ -40,7 +40,7 @@ extern "C" {
#ifdef HAVE_OPENSSL
- #include <pan/data-impl/cert-store.h>
+ #include <pan/data/cert-store.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
@@ -62,6 +62,7 @@ namespace
Data& data;
Queue& queue;
Quark server;
+ StringView cert;
GtkWidget * dialog;
GtkWidget * address_entry;
GtkWidget * port_spin;
@@ -108,7 +109,7 @@ namespace
d->server = server;
int port(119), max_conn(4), age(31*3), rank(1), ssl(0);
- std::string addr, user, pass;
+ std::string addr, user, pass, cert;
if (!server.empty()) {
d->data.get_server_addr (server, addr, port);
d->data.get_server_auth (server, user, pass);
@@ -116,6 +117,7 @@ namespace
rank = d->data.get_server_rank (server);
max_conn = d->data.get_server_limits (server);
ssl = d->data.get_server_ssl_support(server);
+ cert = d->data.get_server_cert(server);
}
pan_entry_set_text (d->address_entry, addr);
@@ -192,6 +194,7 @@ namespace
if (gtk_combo_box_get_active_iter (combo, &iter))
gtk_tree_model_get (gtk_combo_box_get_model(combo), &iter, 1, &rank, -1);
int ssl(0);
+ StringView cert(d->cert);
#ifdef HAVE_OPENSSL
combo = GTK_COMBO_BOX (d->ssl_combo);
if (gtk_combo_box_get_active_iter (combo, &iter))
@@ -220,6 +223,7 @@ namespace
d->data.set_server_article_expiration_age (d->server, age);
d->data.set_server_rank (d->server, rank);
d->data.set_server_ssl_support(d->server, ssl);
+ d->data.set_server_cert(d->server,cert);
d->data.save_server_info(d->server);
d->queue.upkeep ();
}
@@ -371,6 +375,7 @@ pan :: server_edit_dialog_new (Data& data, Queue& queue, GtkWindow * window, con
// ssl 3.0 option
#ifdef HAVE_OPENSSL
+ // select ssl/plaintext
HIG::workarea_add_section_divider (t, &row);
HIG::workarea_add_section_title (t, &row, _("Security"));
HIG::workarea_add_section_spacer (t, row, 2);
@@ -656,7 +661,7 @@ namespace
char buf[4096] ;
if (!selected_server.empty()) {
- X509* cert = (X509*)store.get_cert_to_server(addr);
+ X509* cert (store.get_cert_to_server(addr));
if (cert)
{
pretty_print_x509(buf,sizeof(buf),addr, cert,false);
@@ -666,9 +671,8 @@ namespace
GTK_DIALOG_MODAL,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE, buf);
-// g_snprintf(buf,sizeof(buf), _("Server Certificate for <b>'%s'</b>"), addr.c_str());
-// gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(w), "%s", buf);
-// gtk_window_set_title(GTK_WINDOW(w), buf);
+ g_snprintf(buf,sizeof(buf), _("Server Certificate for <b>'%s'</b>"), addr.c_str());
+ gtk_window_set_title(GTK_WINDOW(w), buf);
gtk_widget_show_all (w);
g_signal_connect_swapped (w, "response", G_CALLBACK (gtk_widget_destroy), w);
}
@@ -721,7 +725,7 @@ namespace
}
- /* add a cert from disk, overwriting the current certificate for the selected server */
+ /* add a cert from disk, overwriting the current setting for the selected server */
void
cert_add_button_clicked_cb (GtkButton *, gpointer user_data)
{
@@ -743,7 +747,7 @@ namespace
PEM_read_X509(fp,&x, 0, 0);
fclose(fp);
d->data.get_server_addr(selected_server, addr, port);
- if (!store.add(x,addr))
+ if (!store.add(x,selected_server))
{
_err:
Log::add_err_va("Error adding certificate of server '%s' to CertStore. Check the console output!", addr.c_str());
diff --git a/pan/tasks/nntp-pool.cc b/pan/tasks/nntp-pool.cc
index 9cdfc22..ff0abde 100644
--- a/pan/tasks/nntp-pool.cc
+++ b/pan/tasks/nntp-pool.cc
@@ -350,7 +350,7 @@ NNTP_Pool :: idle_upkeep ()
#ifdef HAVE_OPENSSL
void
-NNTP_Pool:: on_verify_cert_failed(X509* cert, std::string server, int nr)
+NNTP_Pool:: on_verify_cert_failed(X509* cert, std::string server, std::string cert_name, int nr)
{
// abort_tasks();
}
diff --git a/pan/tasks/nntp-pool.h b/pan/tasks/nntp-pool.h
index 0a256b1..f173863 100644
--- a/pan/tasks/nntp-pool.h
+++ b/pan/tasks/nntp-pool.h
@@ -29,7 +29,7 @@
#include <pan/tasks/socket-impl-main.h>
#ifdef HAVE_OPENSSL
- #include <pan/data-impl/cert-store.h>
+ #include <pan/data/cert-store.h>
#endif
namespace pan
@@ -89,7 +89,7 @@ namespace pan
#ifdef HAVE_OPENSSL
private:
// CertStore::Listener
- virtual void on_verify_cert_failed (X509*, std::string, int) ;
+ virtual void on_verify_cert_failed (X509*, std::string, std::string, int) ;
virtual void on_valid_cert_added (X509*, std::string );
#endif
private:
diff --git a/pan/tasks/queue.h b/pan/tasks/queue.h
index 0aba713..75fcbc1 100644
--- a/pan/tasks/queue.h
+++ b/pan/tasks/queue.h
@@ -37,7 +37,7 @@
#include <pan/tasks/socket-impl-main.h>
#ifdef HAVE_OPENSSL
- #include <pan/data-impl/cert-store.h>
+ #include <pan/data/cert-store.h>
#endif
namespace pan
diff --git a/pan/tasks/socket-impl-main.cc b/pan/tasks/socket-impl-main.cc
index b41ea99..2889bc7 100644
--- a/pan/tasks/socket-impl-main.cc
+++ b/pan/tasks/socket-impl-main.cc
@@ -175,7 +175,7 @@ SocketCreator :: create_socket (const StringView & host,
#ifdef HAVE_OPENSSL
void
-SocketCreator :: on_verify_cert_failed(X509* cert, std::string server, int nr)
+SocketCreator :: on_verify_cert_failed(X509* cert, std::string server, std::string cert_name, int nr)
{
// delete_all_socks(socket_map, server);
}
diff --git a/pan/tasks/socket-impl-main.h b/pan/tasks/socket-impl-main.h
index 16cd43c..a8ff82b 100644
--- a/pan/tasks/socket-impl-main.h
+++ b/pan/tasks/socket-impl-main.h
@@ -42,7 +42,7 @@
#include "socket-impl-openssl.h"
#endif
-#include <pan/data-impl/cert-store.h>
+#include <pan/data/cert-store.h>
#include "socket-impl-gio.h"
namespace
@@ -140,7 +140,7 @@ namespace pan
std::multimap<std::string, Socket*> socket_map;
// CertStore::Listener
- virtual void on_verify_cert_failed(X509*, std::string, int);
+ virtual void on_verify_cert_failed(X509*, std::string, std::string, int);
virtual void on_valid_cert_added (X509*, std::string );
#endif
CertStore & store;
diff --git a/pan/tasks/socket-impl-openssl.cc b/pan/tasks/socket-impl-openssl.cc
index 9dccaaf..d550c99 100644
--- a/pan/tasks/socket-impl-openssl.cc
+++ b/pan/tasks/socket-impl-openssl.cc
@@ -95,7 +95,7 @@ extern "C" {
#include <pan/usenet-utils/gnksa.h>
#include "socket-impl-openssl.h"
#include "socket-impl-main.h"
-#include <pan/data-impl/cert-store.h>
+#include <pan/data/cert-store.h>
using namespace pan;
@@ -372,7 +372,8 @@ namespace
}
- int ssl_handshake(GIOChannel *handle, CertStore::Listener* listener, CertStore* cs, std::string host, SSL_SESSION* session, bool rehandshake)
+ int ssl_handshake(GIOChannel *handle, CertStore::Listener* listener,
+ CertStore* cs, std::string host, SSL_SESSION* session, bool rehandshake)
{
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
@@ -382,11 +383,13 @@ namespace
const char *errstr;
/* init custom data for callback */
- mydata_t mydata;// = new mydata_t();
+ mydata_t mydata;
mydata.ctx = chan->ctx;
mydata.cs = cs;
mydata.ignore_all = 0;
mydata.l = listener;
+ /* build cert name from scratch or from Server* */
+ mydata.cert_name = CertStore::build_cert_name(host);
mydata.server = host;
SSL_set_ex_data(chan->ssl, SSL_get_fd(chan->ssl), &mydata);
@@ -808,7 +811,7 @@ GIOChannelSocketSSL :: ssl_get_iochannel(GIOChannel *handle, gboolean verify)
}
void
-GIOChannelSocketSSL :: on_verify_cert_failed (X509* cert, std::string server, int nr)
+GIOChannelSocketSSL :: on_verify_cert_failed (X509* cert, std::string server, std::string cert_name, int nr)
{
if (!_certstore.in_blacklist(server)) _certstore.blacklist(server);
}
diff --git a/pan/tasks/socket-impl-openssl.h b/pan/tasks/socket-impl-openssl.h
index 85a3b8e..38ef501 100644
--- a/pan/tasks/socket-impl-openssl.h
+++ b/pan/tasks/socket-impl-openssl.h
@@ -28,7 +28,7 @@
#include <pan/tasks/socket-impl-gio.h>
#ifdef HAVE_OPENSSL
- #include <pan/data-impl/cert-store.h>
+ #include <pan/data/cert-store.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
@@ -87,7 +87,7 @@ namespace pan
DoResult do_write ();
// CertStore::Listener
- virtual void on_verify_cert_failed (X509*, std::string, int) ;
+ virtual void on_verify_cert_failed (X509*, std::string, std::string, int) ;
virtual void on_valid_cert_added (X509*, std::string );
GIOChannel * create_channel (const StringView& host_in, int port, std::string& setme_err);
diff --git a/pan/tasks/task-groups.h b/pan/tasks/task-groups.h
index 860aa5e..d520e1a 100644
--- a/pan/tasks/task-groups.h
+++ b/pan/tasks/task-groups.h
@@ -23,7 +23,7 @@
#include <pan/general/quark.h>
#include <pan/data/data.h>
#include <pan/tasks/task.h>
-#include <pan/data-impl/cert-store.h>
+#include <pan/data/cert-store.h>
#include <pan/tasks/nntp.h>
namespace pan
diff --git a/pan/tasks/task-upload.h b/pan/tasks/task-upload.h
index 2be4800..9048c71 100644
--- a/pan/tasks/task-upload.h
+++ b/pan/tasks/task-upload.h
@@ -46,6 +46,7 @@ extern "C" {
namespace pan
{
struct Encoder;
+ class Data;
/**
* Task for uploading binary data to usenet
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]