[pan2/testing: 215/279] ssl fully working now todo: * win32 implementation if i have the time * configure script for openssl
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2/testing: 215/279] ssl fully working now todo: * win32 implementation if i have the time * configure script for openssl
- Date: Sat, 3 Dec 2011 22:39:39 +0000 (UTC)
commit 2c551658248d8d63a469159ed5544318e2639f0a
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date: Sat Oct 22 23:12:38 2011 +0200
ssl fully working now
todo:
* win32 implementation if i have the time
* configure script for openssl/crypto to be modular
pan.cbp | 2 +
pan/data-impl/add-server.cc | 17 ++--
pan/data-impl/data-impl.h | 7 +-
pan/data-impl/server.cc | 24 +++++-
pan/data/server-info.h | 5 +
pan/general/file-util.cc | 10 --
pan/general/file-util.h | 2 -
pan/gui/pan.cc | 3 +-
pan/gui/server-ui.cc | 52 ++++++++++-
pan/tasks/Makefile.am | 2 +
pan/tasks/nntp-pool.cc | 7 +-
pan/tasks/nntp-pool.h | 5 +-
pan/tasks/queue.cc | 2 +-
pan/tasks/queue.h | 5 +-
pan/tasks/socket-impl-gio.cc | 116 +---------------------
pan/tasks/socket-impl-gio.h | 11 --
pan/tasks/socket-impl-main.cc | 156 +++++++++++++++++++++++++++++
pan/tasks/socket-impl-main.h | 70 +++++++++++++
pan/tasks/socket-impl-openssl.cc | 204 ++++++++++++--------------------------
pan/tasks/socket-impl-openssl.h | 16 +---
pan/tasks/socket.h | 2 +-
21 files changed, 410 insertions(+), 308 deletions(-)
---
diff --git a/pan.cbp b/pan.cbp
index bb6cb1c..3d72e28 100644
--- a/pan.cbp
+++ b/pan.cbp
@@ -220,6 +220,8 @@
<Unit filename="pan/tasks/queue.h" />
<Unit filename="pan/tasks/socket-impl-gio.cc" />
<Unit filename="pan/tasks/socket-impl-gio.h" />
+ <Unit filename="pan/tasks/socket-impl-main.cc" />
+ <Unit filename="pan/tasks/socket-impl-main.h" />
<Unit filename="pan/tasks/socket-impl-openssl.cc" />
<Unit filename="pan/tasks/socket-impl-openssl.h" />
<Unit filename="pan/tasks/socket-impl-scripted.cc" />
diff --git a/pan/data-impl/add-server.cc b/pan/data-impl/add-server.cc
index b8e3514..3ae41b0 100644
--- a/pan/data-impl/add-server.cc
+++ b/pan/data-impl/add-server.cc
@@ -5,6 +5,7 @@
#include <pan/tasks/queue.h>
#include <pan/tasks/socket-impl-gio.h>
#include <pan/tasks/task-groups.h>
+#include <pan/tasks/socket-impl-main.h>
#include "data-impl.h"
using namespace pan;
@@ -57,13 +58,15 @@ int main (int argc, char *argv[])
// initialize the queue
TaskArchive null_task_archive;
WorkerPool pool;
- GIOChannelSocket::Creator _socket_creator;
- Queue queue (data, null_task_archive, &_socket_creator, pool, true, 10);
- queue.add_task (new TaskGroups (data, servername));
- // start the event loop...
- main_loop = g_main_loop_new (NULL, false);
- g_timeout_add (2*1000, check_for_tasks_done, &queue);
- g_main_loop_run (main_loop);
+ // FIXME : DBG!
+// SocketCreator _socket_creator;
+// Queue queue (data, null_task_archive, &_socket_creator, pool, true, 10);
+// queue.add_task (new TaskGroups (data, servername));
+//
+// // start the event loop...
+// main_loop = g_main_loop_new (NULL, false);
+// g_timeout_add (2*1000, check_for_tasks_done, &queue);
+// g_main_loop_run (main_loop);
return 0;
}
diff --git a/pan/data-impl/data-impl.h b/pan/data-impl/data-impl.h
index 5225b09..fb27ba0 100644
--- a/pan/data-impl/data-impl.h
+++ b/pan/data-impl/data-impl.h
@@ -107,10 +107,11 @@ namespace pan
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) {}
+ Server(): port(119), article_expiration_age(31), max_connections(2), rank(1), ssl_support(0) {}
};
typedef Loki::AssocVector<Quark,Server> servers_t;
@@ -140,6 +141,8 @@ namespace pan
virtual void set_server_rank (const Quark& server, int rank);
+ virtual void set_server_ssl_support (const Quark& server, int ssl);
+
virtual void set_server_article_expiration_age (const Quark & server,
int days);
@@ -164,6 +167,8 @@ namespace pan
virtual std::string get_server_address (const Quark& servername) const;
+ virtual bool get_server_ssl_support (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 2dd509c..f28baa7 100644
--- a/pan/data-impl/server.cc
+++ b/pan/data-impl/server.cc
@@ -158,6 +158,16 @@ DataImpl :: set_server_rank (const Quark & server,
}
void
+DataImpl :: set_server_ssl_support (const Quark & server,
+ int ssl)
+{
+ Server * s (find_server (server));
+ assert (s != 0);
+ s->ssl_support = ssl;
+
+}
+
+void
DataImpl :: save_server_info (const Quark& server)
{
Server * s (find_server (server));
@@ -206,6 +216,16 @@ DataImpl :: get_server_address (const Quark& server) const
return str;
}
+bool
+DataImpl :: get_server_ssl_support (const Quark & server) const
+{
+ bool retval (false);
+ const Server * s (find_server (server));
+ if (s != 0)
+ retval = (s->ssl_support != 0);
+ return retval;
+}
+
int
DataImpl :: get_server_limits (const Quark & server) const
{
@@ -330,6 +350,7 @@ 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);
s.newsrc_filename = kv["newsrc"];
if (s.newsrc_filename.empty()) { // set a default filename
std::ostringstream o;
@@ -382,7 +403,8 @@ DataImpl :: save_server_properties (DataIO& data_io) const
<< indent(depth) << "<expire-articles-n-days-old>" << s->article_expiration_age << "</expire-articles-n-days-old>\n"
<< 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) << "<rank>" << s->rank << "</rank>\n"
+ << indent(depth) << "<use-ssl>" << s->ssl_support << "</use-ssl>\n";
*out << indent(--depth) << "</server>\n";
}
diff --git a/pan/data/server-info.h b/pan/data/server-info.h
index 0bae055..9d20785 100644
--- a/pan/data/server-info.h
+++ b/pan/data/server-info.h
@@ -61,6 +61,9 @@ namespace pan
virtual void set_server_rank (const Quark& server,
int rank) = 0;
+ virtual void set_server_ssl_support (const Quark& server,
+ int ssl) = 0;
+
virtual void save_server_info (const Quark& server) = 0;
public: // accessors
@@ -76,6 +79,8 @@ namespace pan
// only used for debug and loging output
virtual std::string get_server_address (const Quark& servername) const = 0;
+ virtual bool get_server_ssl_support (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 7e8a770..2e08bc2 100644
--- a/pan/general/file-util.cc
+++ b/pan/general/file-util.cc
@@ -70,16 +70,6 @@ file :: get_pan_home ()
return pan_home;
}
-std::string
-file :: get_temp_attach_path()
-{
- char * pch (g_build_filename (file::get_pan_home().c_str(), "downloaded-attachments", NULL));
- file :: ensure_dir_exists (pch);
- std::string path (pch);
- g_free (pch);
- return path;
-}
-
const char*
file :: pan_strerror (int error_number)
{
diff --git a/pan/general/file-util.h b/pan/general/file-util.h
index fb9c77a..a81f751 100644
--- a/pan/general/file-util.h
+++ b/pan/general/file-util.h
@@ -58,8 +58,6 @@ namespace pan
*/
std::string get_pan_home ();
- std::string get_temp_attach_path ();
-
/**
* If the specified directory doesn't exist, Pan tries to create it.
* @param path
diff --git a/pan/gui/pan.cc b/pan/gui/pan.cc
index 619633a..42899f6 100644
--- a/pan/gui/pan.cc
+++ b/pan/gui/pan.cc
@@ -35,6 +35,7 @@ extern "C" {
#include <pan/general/worker-pool.h>
#include <pan/tasks/socket-impl-gio.h>
#include <pan/tasks/socket-impl-openssl.h>
+#include <pan/tasks/socket-impl-main.h>
#include <pan/tasks/task-groups.h>
#include <pan/tasks/task-xover.h>
#include <pan/tasks/nzb.h>
@@ -333,7 +334,7 @@ main (int argc, char *argv[])
WorkerPool worker_pool (4, true);
// GIOChannelSocket::Creator socket_creator;
- GIOChannelSocketSSL::Creator socket_creator;
+ SocketCreator socket_creator;
Queue queue (data, data, &socket_creator, worker_pool,
prefs.get_flag ("work-online", true),
diff --git a/pan/gui/server-ui.cc b/pan/gui/server-ui.cc
index a118661..d1664c2 100644
--- a/pan/gui/server-ui.cc
+++ b/pan/gui/server-ui.cc
@@ -55,6 +55,7 @@ namespace
GtkWidget * connection_limit_spin;
GtkWidget * expiration_age_combo;
GtkWidget * rank_combo;
+ GtkWidget * ssl_combo;
ServerEditDialog (Data& d, Queue& q): data(d), queue(q) {}
};
@@ -91,7 +92,7 @@ namespace
d->server = server;
- int port(119), max_conn(4), age(31*3), rank(1);
+ int port(119), max_conn(4), age(31*3), rank(1), ssl(0);
std::string addr, user, pass;
if (!server.empty()) {
d->data.get_server_addr (server, addr, port);
@@ -99,6 +100,7 @@ namespace
age = d->data.get_server_article_expiration_age (server);
rank = d->data.get_server_rank (server);
max_conn = d->data.get_server_limits (server);
+ ssl = d->data.get_server_ssl_support(server);
}
pan_entry_set_text (d->address_entry, addr);
@@ -131,6 +133,19 @@ namespace
break;
}
} while (gtk_tree_model_iter_next(model, &iter));
+
+ // set ssl combo
+ combo = GTK_COMBO_BOX (d->ssl_combo);
+ model = gtk_combo_box_get_model (combo);
+ if (gtk_tree_model_get_iter_first(model, &iter)) do {
+ int that;
+ gtk_tree_model_get (model, &iter, 1, &that, -1);
+ if (that == ssl) {
+ gtk_combo_box_set_active_iter (combo, &iter);
+ break;
+ }
+ } while (gtk_tree_model_iter_next(model, &iter));
+
}
void
@@ -159,6 +174,10 @@ namespace
combo = GTK_COMBO_BOX (d->rank_combo);
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);
+ combo = GTK_COMBO_BOX (d->ssl_combo);
+ if (gtk_combo_box_get_active_iter (combo, &iter))
+ gtk_tree_model_get (gtk_combo_box_get_model(combo), &iter, 1, &ssl, -1);
const char * err_msg (0);
if (addr.empty())
@@ -181,6 +200,7 @@ namespace
d->data.set_server_limits (d->server, max_conn);
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.save_server_info(d->server);
d->queue.upkeep ();
}
@@ -304,6 +324,36 @@ pan :: server_edit_dialog_new (Data& data, Queue& queue, GtkWindow * window, con
gtk_widget_set_tooltip_text( e, _("Fallback servers are used for articles that can't be found on the primaries. One common approach is to use free servers as primaries and subscription servers as fallbacks."));
HIG::workarea_add_row (t, &row, e, w);
+ // ssl 3.0 option
+ HIG::workarea_add_section_divider (t, &row);
+ HIG::workarea_add_section_title (t, &row, _("Security"));
+ HIG::workarea_add_section_spacer (t, row, 2);
+ struct { int o; const char * str; } ssl_items[] = {
+ { 0, N_("Use Plaintext (Unsecured) Connections") },
+ { 1, N_("Use Secure TLS (SSL) Connections") }
+ };
+ store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+ for (unsigned int i(0); i<G_N_ELEMENTS(ssl_items); ++i) {
+ GtkTreeIter iter;
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _(ssl_items[i].str), 1, ssl_items[i].o, -1);
+ }
+
+ d->ssl_combo = w = gtk_combo_box_new_with_model (GTK_TREE_MODEL(store));
+ g_object_unref (G_OBJECT(store));
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (w), renderer, true);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (w), renderer, "text", 0, NULL);
+ gtk_combo_box_set_active (GTK_COMBO_BOX(w), 0);
+ l = gtk_label_new (_("TLS (SSL) Options:"));
+ e = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER(e), l);
+ gtk_misc_set_alignment (GTK_MISC(l), 0.0f, 0.5f);
+ gtk_widget_set_tooltip_text( e, _("You can set the option for using/disabling secure SSL/TLS connections here. If you enable SSL/TLS, your data is encrypted and secure. "
+ "It is encouraged to use this option for privacy reasons."));
+ HIG::workarea_add_row (t, &row, e, w);
+
+
+
d->server = server;
edit_dialog_populate (data, server, d);
gtk_widget_show_all (d->dialog);
diff --git a/pan/tasks/Makefile.am b/pan/tasks/Makefile.am
index 32201a4..1a696bc 100644
--- a/pan/tasks/Makefile.am
+++ b/pan/tasks/Makefile.am
@@ -17,6 +17,7 @@ libtasks_a_SOURCES = \
queue.cc \
upload-queue.cc \
socket.cc \
+ socket-impl-main.cc \
socket-impl-openssl.cc \
socket-impl-gio.cc \
socket-impl-scripted.cc \
@@ -41,6 +42,7 @@ noinst_HEADERS = \
queue.h \
upload-queue.h \
socket.h \
+ socket-impl-main.h \
socket-impl-gio.h \
socket-impl-openssl.h \
socket-impl-scripted.h \
diff --git a/pan/tasks/nntp-pool.cc b/pan/tasks/nntp-pool.cc
index 2c9f061..12e4fc0 100644
--- a/pan/tasks/nntp-pool.cc
+++ b/pan/tasks/nntp-pool.cc
@@ -39,7 +39,7 @@ namespace
NNTP_Pool :: NNTP_Pool (const Quark & server,
ServerInfo & server_info,
- Socket::Creator * creator):
+ SocketCreator * creator):
_server_info (server_info),
_server (server),
_socket_creator (creator),
@@ -266,14 +266,13 @@ NNTP_Pool :: request_nntp (WorkerPool& threadpool)
if (!idle && ((pending+active)<max) && new_connections_are_allowed())
{
- debug ("trying to create a socket");
-
std::string address;
int port;
if (_server_info.get_server_addr (_server, address, port))
{
++_pending_connections;
- _socket_creator->create_socket (address, port, threadpool, this);
+ const bool ssl(_server_info.get_server_ssl_support(_server));
+ _socket_creator->create_socket (address, port, threadpool, this, ssl);
}
}
}
diff --git a/pan/tasks/nntp-pool.h b/pan/tasks/nntp-pool.h
index 9f5009f..4815e1b 100644
--- a/pan/tasks/nntp-pool.h
+++ b/pan/tasks/nntp-pool.h
@@ -26,6 +26,7 @@
#include <pan/data/server-info.h>
#include <pan/tasks/socket.h>
#include <pan/tasks/nntp.h>
+#include <pan/tasks/socket-impl-main.h>
namespace pan
{
@@ -45,7 +46,7 @@ namespace pan
NNTP_Pool (const Quark & server,
ServerInfo & server_info,
- Socket::Creator *);
+ SocketCreator *);
virtual ~NNTP_Pool ();
@@ -92,7 +93,7 @@ namespace pan
ServerInfo& _server_info;
const Quark _server;
- Socket::Creator * _socket_creator;
+ SocketCreator * _socket_creator;
int _pending_connections;
struct PoolItem {
diff --git a/pan/tasks/queue.cc b/pan/tasks/queue.cc
index 8d5aeae..3fbc306 100644
--- a/pan/tasks/queue.cc
+++ b/pan/tasks/queue.cc
@@ -33,7 +33,7 @@ using namespace pan;
Queue :: Queue (ServerInfo & server_info,
TaskArchive & archive,
- Socket::Creator * socket_creator,
+ SocketCreator * socket_creator,
WorkerPool & pool,
bool online,
int save_delay_secs):
diff --git a/pan/tasks/queue.h b/pan/tasks/queue.h
index b97d2c9..1257641 100644
--- a/pan/tasks/queue.h
+++ b/pan/tasks/queue.h
@@ -34,6 +34,7 @@
#include <pan/tasks/task.h>
#include <pan/tasks/encoder.h>
#include <pan/tasks/task-weak-ordering.h>
+#include <pan/tasks/socket-impl-main.h>
namespace pan
{
@@ -69,7 +70,7 @@ namespace pan
private AdaptableSet<Task*, TaskWeakOrdering>::Listener
{
public:
- Queue (ServerInfo&, TaskArchive&, Socket::Creator*, WorkerPool&,
+ Queue (ServerInfo&, TaskArchive&, SocketCreator*, WorkerPool&,
bool online, int save_delay_secs);
virtual ~Queue ();
@@ -201,7 +202,7 @@ namespace pan
std::set<TaskUpload*> _uploads;
std::set<Task*> _removing;
std::set<Task*> _stopped;
- Socket::Creator * _socket_creator;
+ SocketCreator * _socket_creator;
WorkerPool & _worker_pool;
Decoder _decoder;
Encoder _encoder;
diff --git a/pan/tasks/socket-impl-gio.cc b/pan/tasks/socket-impl-gio.cc
index a0e14eb..95f4993 100644
--- a/pan/tasks/socket-impl-gio.cc
+++ b/pan/tasks/socket-impl-gio.cc
@@ -89,71 +89,12 @@ extern "C" {
#include <pan/general/string-view.h>
#include <pan/usenet-utils/gnksa.h>
#include "socket-impl-gio.h"
+#include "socket-impl-main.h"
using namespace pan;
namespace
{
- typedef int (*t_getaddrinfo)(const char *,const char *, const struct addrinfo*, struct addrinfo **);
- t_getaddrinfo p_getaddrinfo (0);
-
- typedef void (*t_freeaddrinfo)(struct addrinfo*);
- t_freeaddrinfo p_freeaddrinfo (0);
-
- void ensure_module_inited (void)
- {
- static bool inited (false);
-
- if (!inited)
- {
- p_freeaddrinfo=NULL;
- p_getaddrinfo=NULL;
-
-#ifdef G_OS_WIN32
- WSADATA wsaData;
- WSAStartup(MAKEWORD(2,2), &wsaData);
-
- char sysdir[MAX_PATH], path[MAX_PATH+8];
-
- if(GetSystemDirectory(sysdir,MAX_PATH)!=0)
- {
- HMODULE lib=NULL;
- FARPROC pfunc=NULL;
- const char *libs[]={"ws2_32","wship6",NULL};
-
- for(const char **p=libs;*p!=NULL;++p)
- {
- g_snprintf(path,MAX_PATH+8,"%s\\%s",sysdir,*p);
- lib=LoadLibrary(path);
- if(!lib)
- continue;
- pfunc=GetProcAddress(lib,"getaddrinfo");
- if(!pfunc)
- {
- FreeLibrary(lib);
- lib=NULL;
- continue;
- }
- p_getaddrinfo=reinterpret_cast<t_getaddrinfo>(pfunc);
- pfunc=GetProcAddress(lib,"freeaddrinfo");
- if(!pfunc)
- {
- FreeLibrary(lib);
- lib=NULL;
- p_getaddrinfo=NULL;
- continue;
- }
- p_freeaddrinfo=reinterpret_cast<t_freeaddrinfo>(pfunc);
- break;
- }
- }
-#else
- p_freeaddrinfo=::freeaddrinfo;
- p_getaddrinfo=::getaddrinfo;
-#endif
- inited = true;
- }
- }
GIOChannel *
create_channel (const StringView& host_in, int port, std::string& setme_err)
@@ -170,7 +111,7 @@ namespace
char portbuf[32], hpbuf[255];
g_snprintf (portbuf, sizeof(portbuf), "%d", port);
g_snprintf (hpbuf,sizeof(hpbuf),"%s:%s",host_in.str,portbuf);
-
+
#ifdef G_OS_WIN32 // windows might not have getaddrinfo...
if (!p_getaddrinfo)
{
@@ -220,7 +161,7 @@ namespace
hints.ai_family = 0;
hints.ai_socktype = SOCK_STREAM;
struct addrinfo * ans;
- err = p_getaddrinfo (host.c_str(), portbuf, &hints, &ans);
+ err = ::getaddrinfo (host.c_str(), portbuf, &hints, &ans);
if (err != 0) {
char buf[512];
snprintf (buf, sizeof(buf), _("Error connecting to \"%s\""), hpbuf);
@@ -255,7 +196,7 @@ namespace
}
// cleanup
- p_freeaddrinfo (ans);
+ ::freeaddrinfo (ans);
}
// create the giochannel...
@@ -339,6 +280,7 @@ bool
GIOChannelSocket :: open (const StringView& address, int port, std::string& setme_err)
{
_host.assign (address.str, address.len);
+ std::cerr<<"open normal "<<address<<":"<<port<<std::endl;
_channel = create_channel (address, port, setme_err);
return _channel != 0;
}
@@ -553,51 +495,3 @@ GIOChannelSocket :: set_watch_mode (WatchMode mode)
debug ("set_watch_mode " << mode << ": _tag_watch is now " << _tag_watch);
}
-
-/***
-**** GIOChannel::SocketCreator -- create a socket in a worker thread
-***/
-
-namespace
-{
- struct ThreadWorker : public WorkerPool::Worker,
- public WorkerPool::Worker::Listener
- {
- std::string host;
- int port;
- Socket::Creator::Listener * listener;
-
- bool ok;
- Socket * socket;
- std::string err;
-
- ThreadWorker (const StringView& h, int p, Socket::Creator::Listener *l):
- host(h), port(p), listener(l), ok(false), socket(0) {}
-
- void do_work ()
- {
- socket = new GIOChannelSocket ();
- ok = socket->open (host, port, err);
- }
-
- /** called in main thread after do_work() is done */
- void on_worker_done (bool cancelled UNUSED)
- {
- // pass results to main thread...
- if (!err.empty()) Log :: add_err (err.c_str());
- listener->on_socket_created (host, port, ok, socket);
- }
- };
-}
-
-void
-GIOChannelSocket :: Creator :: create_socket (const StringView & host,
- int port,
- WorkerPool & threadpool,
- Listener * listener)
-{
- ensure_module_inited ();
-
- ThreadWorker * w = new ThreadWorker (host, port, listener);
- threadpool.push_work (w, w, true);
-}
diff --git a/pan/tasks/socket-impl-gio.h b/pan/tasks/socket-impl-gio.h
index da74acc..e38679e 100644
--- a/pan/tasks/socket-impl-gio.h
+++ b/pan/tasks/socket-impl-gio.h
@@ -61,17 +61,6 @@ namespace pan
enum DoResult { IO_ERR, IO_READ, IO_WRITE, IO_DONE };
DoResult do_read ();
DoResult do_write ();
-
- public:
-
- /**
- * Socket::Creator that instantiates GIOSocket objects.
- */
- class Creator: public Socket::Creator {
- public:
- virtual ~Creator () { }
- virtual void create_socket (const StringView& host, int port, WorkerPool&, Listener *l);
- };
};
}
diff --git a/pan/tasks/socket-impl-main.cc b/pan/tasks/socket-impl-main.cc
new file mode 100644
index 0000000..43b68b2
--- /dev/null
+++ b/pan/tasks/socket-impl-main.cc
@@ -0,0 +1,156 @@
+
+/* -*- 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
+ */
+
+
+/***
+**** GIOChannel::SocketCreator -- create a socket in a worker thread
+***/
+
+#include <string>
+#include <glib/giochannel.h>
+#include <glib/gstring.h>
+#include <pan/tasks/socket.h>
+
+#include <config.h>
+#include <iostream>
+#include <string>
+#include <cerrno>
+#include <cstring>
+
+#include <pan/general/log.h>
+#include <pan/general/macros.h>
+#include <pan/general/worker-pool.h>
+#include <pan/general/string-view.h>
+
+#include "socket-impl-main.h"
+
+using namespace pan;
+
+/* FIXME for win32!!!!!!!
+namespace
+{
+ void ensure_module_inited (void)
+ {
+ static bool inited (false);
+
+ if (!inited)
+ {
+ p_freeaddrinfo=NULL;
+ p_getaddrinfo=NULL;
+
+#ifdef G_OS_WIN32
+ WSADATA wsaData;
+ WSAStartup(MAKEWORD(2,2), &wsaData);
+
+ char sysdir[MAX_PATH], path[MAX_PATH+8];
+
+ if(GetSystemDirectory(sysdir,MAX_PATH)!=0)
+ {
+ HMODULE lib=NULL;
+ FARPROC pfunc=NULL;
+ const char *libs[]={"ws2_32","wship6",NULL};
+
+ for(const char **p=libs;*p!=NULL;++p)
+ {
+ g_snprintf(path,MAX_PATH+8,"%s\\%s",sysdir,*p);
+ lib=LoadLibrary(path);
+ if(!lib)
+ continue;
+ pfunc=GetProcAddress(lib,"getaddrinfo");
+ if(!pfunc)
+ {
+ FreeLibrary(lib);
+ lib=NULL;
+ continue;
+ }
+ p_getaddrinfo=reinterpret_cast<t_getaddrinfo>(pfunc);
+ pfunc=GetProcAddress(lib,"freeaddrinfo");
+ if(!pfunc)
+ {
+ FreeLibrary(lib);
+ lib=NULL;
+ p_getaddrinfo=NULL;
+ continue;
+ }
+ p_freeaddrinfo=reinterpret_cast<t_freeaddrinfo>(pfunc);
+ break;
+ }
+ }
+#else
+ p_freeaddrinfo=::freeaddrinfo;
+ p_getaddrinfo=::getaddrinfo;
+#endif
+ inited = true;
+ }
+ }
+}
+*/
+
+namespace pan
+{
+ struct ThreadWorker : public WorkerPool::Worker,
+ public WorkerPool::Worker::Listener
+ {
+ std::string host;
+ int port;
+ Socket::Creator::Listener * listener;
+
+ bool ok;
+ Socket * socket;
+ std::string err;
+ bool use_ssl;
+
+ ThreadWorker (const StringView& h, int p, Socket::Creator::Listener *l, bool ssl):
+ host(h), port(p), listener(l), ok(false), socket(0), use_ssl(ssl) {}
+
+ void do_work ()
+ {
+ if (use_ssl)
+ socket = new GIOChannelSocketSSL ();
+ else
+ socket = new GIOChannelSocket ();
+ ok = socket->open (host, port, err);
+ }
+
+ /** called in main thread after do_work() is done */
+ void on_worker_done (bool cancelled UNUSED)
+ {
+ // pass results to main thread...
+ if (!err.empty()) Log :: add_err (err.c_str());
+ listener->on_socket_created (host, port, ok, socket);
+ }
+ };
+}
+
+SocketCreator :: SocketCreator() {}
+SocketCreator :: ~SocketCreator() {}
+
+void
+SocketCreator :: create_socket (const StringView & host,
+ int port,
+ WorkerPool & threadpool,
+ Socket::Creator::Listener * listener,
+ bool use_ssl)
+{
+// ensure_module_inited ();
+
+ ThreadWorker * w = new ThreadWorker (host, port, listener, use_ssl);
+ threadpool.push_work (w, w, true);
+}
diff --git a/pan/tasks/socket-impl-main.h b/pan/tasks/socket-impl-main.h
new file mode 100644
index 0000000..c1b8787
--- /dev/null
+++ b/pan/tasks/socket-impl-main.h
@@ -0,0 +1,70 @@
+/* -*- 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
+ */
+
+
+#ifndef __SocketMAIN_h__
+#define __SocketMAIN_h__
+
+#ifdef G_OS_WIN32
+ #include <ws2tcpip.h>
+#else
+ #include <signal.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <netdb.h>
+ #include <arpa/inet.h>
+#endif
+
+#include <pan/general/string-view.h>
+#include <pan/general/worker-pool.h>
+#include "socket.h"
+#include "socket-impl-openssl.h"
+#include "socket-impl-gio.h"
+
+namespace pan
+{
+
+ typedef int (*t_getaddrinfo)(const char *,const char *, const struct addrinfo*, struct addrinfo **);
+ static t_getaddrinfo p_getaddrinfo (0);
+
+ typedef void (*t_freeaddrinfo)(struct addrinfo*);
+ static t_freeaddrinfo p_freeaddrinfo (0);
+
+}
+
+namespace pan
+{
+
+ class SocketCreator
+ {
+ public:
+ SocketCreator ();
+ virtual ~SocketCreator ();
+
+ virtual void create_socket (const StringView & host,
+ int port,
+ WorkerPool & threadpool,
+ Socket::Creator::Listener * listener,
+ bool use_ssl);
+ };
+
+}
+
+#endif
diff --git a/pan/tasks/socket-impl-openssl.cc b/pan/tasks/socket-impl-openssl.cc
index 66c0857..0c18bec 100644
--- a/pan/tasks/socket-impl-openssl.cc
+++ b/pan/tasks/socket-impl-openssl.cc
@@ -44,16 +44,16 @@ extern "C" {
#define _WIN32_WINNT 0x0501
#include <ws2tcpip.h>
#undef gai_strerror
- /*
+
#define gai_strerror(i) gai_strerror_does_not_link (i)
- const char*
- gai_strerror_does_not_link (int errval)
- {
- char buf[32];
- g_snprintf (buf, sizeof(buf), "Winsock error %d", errval);
- return buf;
- }
- */
+// const char*
+// gai_strerror_does_not_link (int errval)
+// {
+// char buf[32];
+// g_snprintf (buf, sizeof(buf), "Winsock error %d", errval);
+// return buf;
+// }
+
const char*
get_last_error (int err)
{
@@ -88,76 +88,11 @@ extern "C" {
#include <pan/general/log.h>
#include <pan/general/string-view.h>
#include <pan/usenet-utils/gnksa.h>
-#include "socket-impl-gio.h"
#include "socket-impl-openssl.h"
+#include "socket-impl-main.h"
using namespace pan;
-namespace
-{
- typedef int (*t_getaddrinfo)(const char *,const char *, const struct addrinfo*, struct addrinfo **);
- t_getaddrinfo p_getaddrinfo (0);
-
- typedef void (*t_freeaddrinfo)(struct addrinfo*);
- t_freeaddrinfo p_freeaddrinfo (0);
-
- void ensure_module_inited (void)
- {
- bool inited (false);
-
- if (!inited)
- {
- p_freeaddrinfo=0;
- p_getaddrinfo=0;
-
-#ifdef G_OS_WIN32
- WSADATA wsaData;
- WSAStartup(MAKEWORD(2,2), &wsaData);
-
- char sysdir[MAX_PATH], path[MAX_PATH+8];
-
- if(GetSystemDirectory(sysdir,MAX_PATH)!=0)
- {
- HMODULE lib=0;
- FARPROC pfunc=0;
- const char *libs[]={"ws2_32","wship6",0};
-
- for(const char **p=libs;*p!=0;++p)
- {
- g_snprintf(path,MAX_PATH+8,"%s\\%s",sysdir,*p);
- lib=LoadLibrary(path);
- if(!lib)
- continue;
- pfunc=GetProcAddress(lib,"getaddrinfo");
- if(!pfunc)
- {
- FreeLibrary(lib);
- lib=0;
- continue;
- }
- p_getaddrinfo=reinterpret_cast<t_getaddrinfo>(pfunc);
- pfunc=GetProcAddress(lib,"freeaddrinfo");
- if(!pfunc)
- {
- FreeLibrary(lib);
- lib=0;
- p_getaddrinfo=0;
- continue;
- }
- p_freeaddrinfo=reinterpret_cast<t_freeaddrinfo>(pfunc);
- break;
- }
- }
-#else
- p_freeaddrinfo=::freeaddrinfo;
- p_getaddrinfo=::getaddrinfo;
-#endif
- inited = true;
- }
- }
-
-}
-
/****
*****
*****
@@ -176,6 +111,7 @@ GIOChannelSocketSSL :: GIOChannelSocketSSL ():
debug ("GIOChannelSocketSSL ctor " << (void*)this);
}
+
GIOChannel *
GIOChannelSocketSSL :: create_channel (const StringView& host_in, int port, std::string& setme_err)
{
@@ -186,6 +122,8 @@ GIOChannelSocketSSL :: create_channel (const StringView& host_in, int port, std:
signal (SIGPIPE, SIG_IGN);
#endif
+ std::cerr<<"cc "<<host_in<<":"<<port<<"\n";
+
// get an addrinfo for the host
const std::string host (host_in.str, host_in.len);
char portbuf[32], hpbuf[255];
@@ -241,7 +179,7 @@ GIOChannelSocketSSL :: create_channel (const StringView& host_in, int port, std:
hints.ai_family = 0;
hints.ai_socktype = SOCK_STREAM;
struct addrinfo * ans;
- err = p_getaddrinfo (host.c_str(), portbuf, &hints, &ans);
+ err = ::getaddrinfo (host.c_str(), portbuf, &hints, &ans);
if (err != 0) {
char buf[512];
snprintf (buf, sizeof(buf), _("Error connecting to \"%s\""), hpbuf);
@@ -276,7 +214,7 @@ GIOChannelSocketSSL :: create_channel (const StringView& host_in, int port, std:
}
// cleanup
- p_freeaddrinfo (ans);
+ ::freeaddrinfo (ans);
}
// create the giochannel...
@@ -361,6 +299,46 @@ namespace
}
}
+ /* todo: real verify + UI ! */
+ gboolean ssl_verify(SSL *ssl, SSL_CTX *ctx, X509 *cert)
+ {
+// if (SSL_get_verify_result(ssl) != X509_V_OK) {
+ unsigned char md[EVP_MAX_MD_SIZE];
+ unsigned int n;
+ char *str;
+
+ if ((str = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0)) == NULL)
+ g_warning(" Could not get subject-name from peer certificate");
+ else {
+ g_warning(" Subject : %s", str);
+ free(str);
+ }
+ if ((str = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0)) == NULL)
+ g_warning(" Could not get issuer-name from peer certificate");
+ else {
+ g_warning(" Issuer : %s", str);
+ free(str);
+ }
+ if (! X509_digest(cert, EVP_md5(), md, &n))
+ g_warning(" Could not get fingerprint from peer certificate");
+ else {
+ char hex[] = "0123456789ABCDEF";
+ char fp[EVP_MAX_MD_SIZE*3];
+ if (n < sizeof(fp)) {
+ unsigned int i;
+ for (i = 0; i < n; i++) {
+ fp[i*3+0] = hex[(md[i] >> 4) & 0xF];
+ fp[i*3+1] = hex[(md[i] >> 0) & 0xF];
+ fp[i*3+2] = i == n - 1 ? '\0' : ':';
+ }
+ g_warning(" MD5 Fingerprint : %s", fp);
+ }
+ }
+// return FALSE;
+// }
+ return TRUE;
+ }
+
void ssl_free(GIOChannel *handle)
{
@@ -398,6 +376,7 @@ bool
GIOChannelSocketSSL :: open (const StringView& address, int port, std::string& setme_err)
{
_host.assign (address.str, address.len);
+ std::cerr<<"open ssl "<<address<<":"<<port<<std::endl;
_channel = create_channel (address, port, setme_err);
return _channel != 0;
}
@@ -452,34 +431,29 @@ namespace
return G_IO_STATUS_ERROR;
}
- int ssl_handshake(GIOChannel *handle)
+ bool ssl_handshake(GIOChannel *handle)
{
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
- int ret, err;
+ bool ret;
+ int err;
X509 *cert;
const char *errstr;
- if (!handle || !chan->ssl) return -1;
+ if (!handle || !chan->ssl || !chan->ctx) return -1;
ret = SSL_connect(chan->ssl);
if (ret <= 0) {
err = SSL_get_error(chan->ssl, ret);
- if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
- errstr = ERR_reason_error_string(ERR_get_error());
- g_warning("SSL handshake failed: %s", errstr != 0 ? errstr : "server closed connection");
+ if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
return -1;
- }
return err == SSL_ERROR_WANT_READ ? 1 : 3;
}
-
cert = SSL_get_peer_certificate(chan->ssl);
- if (cert == 0) {
- g_warning("SSL server supplied no certificate");
+ if (!cert && chan->ssl)
return -1;
- }
-// ret = chan->verify ? ssl_verify(chan->ssl, chan->ctx, handle->hostname.c_str(), cert) : true;
+ ret = chan->verify ? ssl_verify(chan->ssl, chan->ctx, cert) : true;
X509_free(cert);
return ret ? 0 : -1;
}
@@ -847,59 +821,9 @@ GIOChannelSocketSSL :: ssl_get_iochannel(GIOChannel *handle, gboolean verify)
gchan->read_buf = g_string_sized_new(4096*128);
/// FIXME : callback
- debug("before handshake");
- while (ssl_handshake(gchan) != 0) ;
- debug("after handshake");
+ if (ssl_handshake(gchan))
// std::cerr<<"handshake success!\n";
return gchan;
}
-
-/***
-**** GIOChannel::SocketCreator -- create a socket in a worker thread
-***/
-
-namespace
-{
- struct ThreadWorker : public WorkerPool::Worker,
- public WorkerPool::Worker::Listener
- {
- std::string host;
- int port;
- Socket::Creator::Listener * listener;
-
- bool ok;
- Socket * socket;
- std::string err;
-
- ThreadWorker (const StringView& h, int p, Socket::Creator::Listener *l):
- host(h), port(p), listener(l), ok(false), socket(0) {}
-
- void do_work ()
- {
- socket = new GIOChannelSocketSSL ();
- ok = socket->open (host, port, err);
- }
-
- /** called in main thread after do_work() is done */
- void on_worker_done (bool cancelled UNUSED)
- {
- // pass results to main thread...
- if (!err.empty()) Log :: add_err (err.c_str());
- listener->on_socket_created (host, port, ok, socket);
- }
- };
-}
-
-void
-GIOChannelSocketSSL :: Creator :: create_socket (const StringView & host,
- int port,
- WorkerPool & threadpool,
- Listener * listener)
-{
- ensure_module_inited ();
-
- ThreadWorker * w = new ThreadWorker (host, port, listener);
- threadpool.push_work (w, w, true);
-}
diff --git a/pan/tasks/socket-impl-openssl.h b/pan/tasks/socket-impl-openssl.h
index 323e76f..48d3017 100644
--- a/pan/tasks/socket-impl-openssl.h
+++ b/pan/tasks/socket-impl-openssl.h
@@ -32,6 +32,8 @@
#include <openssl/ssl.h>
#include <openssl/err.h>
+#include "socket-impl-gio.h"
+
namespace pan
{
/**
@@ -39,7 +41,7 @@ namespace pan
*
* @ingroup tasks
*/
- class GIOChannelSocketSSL: public Socket
+ class GIOChannelSocketSSL: public GIOChannelSocket
{
public:
GIOChannelSocketSSL ();
@@ -71,20 +73,8 @@ namespace pan
GIOChannel * create_channel (const StringView& host_in, int port, std::string& setme_err);
- //SSL functions
private:
GIOChannel* ssl_get_iochannel(GIOChannel *handle, gboolean verify=true);
-
- public:
-
- /**
- * Socket::Creator that instantiates GIOSocket objects.
- */
- class Creator: public Socket::Creator {
- public:
- virtual ~Creator () { }
- virtual void create_socket (const StringView& host, int port, WorkerPool&, Listener *l);
- };
};
}
diff --git a/pan/tasks/socket.h b/pan/tasks/socket.h
index db40ac2..a4cfa7e 100644
--- a/pan/tasks/socket.h
+++ b/pan/tasks/socket.h
@@ -86,7 +86,7 @@ namespace pan
};
virtual ~Creator () { }
- virtual void create_socket (const StringView& host, int port, WorkerPool&, Listener*) = 0;
+ virtual void create_socket (const StringView& host, int port, WorkerPool&, Listener*, bool) = 0;
};
};
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]