[pan2] * make callback struct for ssl handshake dynamic * fix quark unref bug * handle password with gnome-



commit 1cf13977e3917b39df9361e2477962a053780f64
Author: Heinrich MÃller <henmull src gnome org>
Date:   Sun Apr 22 12:46:07 2012 +0200

    * make callback struct for ssl handshake dynamic
    * fix quark unref bug
    * handle password with gnome-keyring in secure memory as far as possible

 pan/data-impl/add-server.cc      |    2 +-
 pan/data-impl/data-impl.cc       |   10 ++---
 pan/data-impl/data-impl.h        |   10 ++---
 pan/data-impl/server.cc          |   65 ++++++++++++++++++++++---------------
 pan/data/data.h                  |   13 +++++---
 pan/data/server-info.h           |    6 ++--
 pan/gui/pan.cc                   |   14 ++++++++
 pan/gui/server-ui.cc             |    6 ++-
 pan/tasks/nntp-pool.cc           |    3 +-
 pan/tasks/socket-impl-main.cc    |    2 +-
 pan/tasks/socket-impl-openssl.cc |   16 +++++----
 11 files changed, 89 insertions(+), 58 deletions(-)
---
diff --git a/pan/data-impl/add-server.cc b/pan/data-impl/add-server.cc
index adb9b6f..38f973b 100644
--- a/pan/data-impl/add-server.cc
+++ b/pan/data-impl/add-server.cc
@@ -55,7 +55,7 @@ int main (int argc, char *argv[])
   if (have_password) password = argv[4];
   if (have_username || have_password) {
     std::cerr << "Username [" << username << "], password [" << password << "]\n";
-    data.set_server_auth (servername, username, password);
+    data.set_server_auth (servername, username, password.str);
   }
 
   // initialize the queue
diff --git a/pan/data-impl/data-impl.cc b/pan/data-impl/data-impl.cc
index 6f4d6ac..ca2fc1b 100644
--- a/pan/data-impl/data-impl.cc
+++ b/pan/data-impl/data-impl.cc
@@ -138,7 +138,7 @@ DataImpl :: password_encrypt (const PasswordData& pw)
       GNOME_KEYRING_NETWORK_PASSWORD,
       GNOME_KEYRING_DEFAULT,
       _("Pan Newsreader's server passwords"),
-      pw.pw.str,
+      pw.pw,
       "user", pw.user.str,
       "server", pw.server.c_str(),
       NULL)
@@ -152,7 +152,6 @@ DataImpl :: password_decrypt (PasswordData& pw) const
 {
 
   gchar* pwd = NULL;
-//  g_return_val_if_fail (pw, GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON);
 
   GnomeKeyringResult ret =
     gnome_keyring_find_password_sync (
@@ -162,14 +161,13 @@ DataImpl :: password_decrypt (PasswordData& pw) const
     "server", pw.server.c_str(),
     NULL);
 
-  std::string tmp;
   if (pwd)
-  { tmp = pwd;
+  {
+    pw.pw = gnome_keyring_memory_strdup(pwd);
     gnome_keyring_free_password(pwd);
   }
-  pw.pw = tmp;
 
-  return (pwd ? GNOME_KEYRING_RESULT_OK : GNOME_KEYRING_RESULT_DENIED) ;
+  return (pw.pw ? GNOME_KEYRING_RESULT_OK : GNOME_KEYRING_RESULT_DENIED) ;
 }
 #endif
 
diff --git a/pan/data-impl/data-impl.h b/pan/data-impl/data-impl.h
index 459eed4..6672fb7 100644
--- a/pan/data-impl/data-impl.h
+++ b/pan/data-impl/data-impl.h
@@ -112,18 +112,16 @@ namespace pan
 
       void load_server_properties (const DataIO&);
 
-      void save_server_properties (DataIO&) const;
+      void save_server_properties (DataIO&);
 
       typedef Loki::AssocVector<Quark,Server> servers_t;
 
       servers_t _servers;
 
-//      Server* find_server (const Quark& server);
-
     public:
       virtual const Server* find_server (const Quark& server) const;
       virtual Server* find_server (const Quark& server);
-      virtual bool find_server_by_hn (const Quark& server, Quark& setme) const;
+      virtual bool find_server_by_hn (const std::string& server, Quark& setme) const;
 
     public: // mutators
 
@@ -134,7 +132,7 @@ namespace pan
 
       virtual void set_server_auth (const Quark       & server,
                                     const StringView  & username,
-                                    const StringView  & password);
+                                    gchar             *&password);
 
       virtual void set_server_trust (const Quark      & servername,
                                      int                setme);
@@ -168,7 +166,7 @@ namespace pan
 
       virtual bool get_server_auth (const Quark   & server,
                                     std::string   & setme_username,
-                                    std::string   & setme_password) const;
+                                    gchar         *&setme_password);
 
       virtual bool get_server_trust (const Quark  & servername, int&) const;
 
diff --git a/pan/data-impl/server.cc b/pan/data-impl/server.cc
index deb0b45..c9e3b4b 100644
--- a/pan/data-impl/server.cc
+++ b/pan/data-impl/server.cc
@@ -100,10 +100,10 @@ DataImpl :: find_server (const Quark& server) const
 }
 
 bool
-DataImpl :: find_server_by_hn (const Quark& server, Quark& setme) const
+DataImpl :: find_server_by_hn (const std::string& server, Quark& setme) const
 {
   foreach_const(servers_t, _servers, it)
-    if (it->second.host == server.c_str()) { setme = it->first; return true; }
+    if (it->second.host == server) { setme = it->first; return true; }
   return false;
 }
 
@@ -121,7 +121,7 @@ DataImpl :: set_server_article_expiration_age  (const Quark  & server,
 void
 DataImpl :: set_server_auth (const Quark       & server,
                              const StringView  & username,
-                             const StringView  & password)
+                             gchar             *&password)
 {
   Server * s (find_server (server));
   assert (s);
@@ -215,35 +215,43 @@ DataImpl :: save_server_info (const Quark& server)
 bool
 DataImpl :: get_server_auth (const Quark   & server,
                              std::string   & setme_username,
-                             std::string   & setme_password) const
+                             gchar         *&setme_password)
 {
-  const Server * s (find_server (server));
+  Server * s (find_server (server));
   bool found (s);
   if (found) {
     setme_username = s->username;
 #ifndef HAVE_GKR
     setme_password = s->password;
 #else
-    PasswordData pw;
-    pw.server = s->host;
-    pw.user = s->username;
-    GnomeKeyringResult res = password_decrypt(pw);
-    switch (res)
+    if (s->gkr_pw)
     {
-      case GNOME_KEYRING_RESULT_NO_MATCH:
-        Log::add_info_va(_("There seems to be no password set for server %s."), s->host.c_str());
-        break;
-
-      case GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON:
-        Log::add_urgent_va (_("GNOME Keyring denied access to the passwords."), s->host.c_str());
-        break;
-
-      case GNOME_KEYRING_RESULT_OK:
-        setme_password.assign(pw.pw.str, pw.pw.len);
-        break;
-
-      default:
-        break;
+      setme_password = s->gkr_pw;
+    }
+    else
+    {
+      PasswordData pw;
+      pw.server = s->host;
+      pw.user = s->username;
+      switch (password_decrypt(pw))
+      {
+        case GNOME_KEYRING_RESULT_NO_MATCH:
+          Log::add_info_va(_("There seems to be no password set for server %s."), s->host.c_str());
+          break;
+
+        case GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON:
+          Log::add_urgent_va (_("GNOME Keyring denied access to the passwords."), s->host.c_str());
+          break;
+
+        case GNOME_KEYRING_RESULT_OK:
+//          setme_password.assign(pw.pw.str, pw.pw.len);
+          setme_password = pw.pw;
+          s->gkr_pw = pw.pw;
+          break;
+
+        default:
+          break;
+      }
     }
 #endif
   }
@@ -483,7 +491,7 @@ namespace
 }
 
 void
-DataImpl :: save_server_properties (DataIO& data_io) const
+DataImpl :: save_server_properties (DataIO& data_io)
 {
   int depth (0);
   std::ostream * out = data_io.write_server_properties ();
@@ -500,13 +508,18 @@ DataImpl :: save_server_properties (DataIO& data_io) const
   *out << indent(depth++) << "<server-properties>\n";
   foreach_const (alpha_quarks_t, servers, it) {
     const Server* s (find_server (*it));
-    std::string user, pass;
+    std::string user;
+    gchar* pass(NULL);
     get_server_auth(*it, user, pass);
     *out << indent(depth++) << "<server id=\"" << escaped(it->to_string()) << "\">\n";
     *out << indent(depth) << "<host>" << escaped(s->host) << "</host>\n"
          << indent(depth) << "<port>" << s->port << "</port>\n"
          << indent(depth) << "<username>" << escaped(user) << "</username>\n"
+#ifdef HAVE_GKR
+         << indent(depth) << "<password>" << "HANDLED_BY_GNOME_KEYRING" << "</password>\n"
+#else
          << indent(depth) << "<password>" << escaped(pass) << "</password>\n"
+#endif
          << 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"
diff --git a/pan/data/data.h b/pan/data/data.h
index 64015f8..c7d40fd 100644
--- a/pan/data/data.h
+++ b/pan/data/data.h
@@ -178,7 +178,8 @@ namespace pan
       {
         Quark server;
         StringView user;
-        StringView pw;
+//        StringView pw;
+        gchar* pw;
       };
 
     public:
@@ -197,8 +198,10 @@ namespace pan
          int trust;
          typedef sorted_vector<Quark,true,AlphabeticalQuarkOrdering> groups_t;
          groups_t groups;
+         gchar* gkr_pw;
 
-         Server(): port(STD_NNTP_PORT), article_expiration_age(31), max_connections(2), rank(1), ssl_support(0), trust(0) {}
+         Server(): port(STD_NNTP_PORT), article_expiration_age(31), max_connections(2),
+                    rank(1), ssl_support(0), trust(0), gkr_pw(NULL) {}
       };
 
     protected:
@@ -227,7 +230,7 @@ namespace pan
       virtual GnomeKeyringResult password_decrypt (PasswordData&) const = 0;
 #endif
       /** Gets a quark to the provided hostname */
-      virtual bool find_server_by_hn (const Quark& server, Quark& setme) const = 0;
+      virtual bool find_server_by_hn (const std::string& server, Quark& setme) const = 0;
 
       virtual const Server* find_server (const Quark& server) const = 0;
 
@@ -241,7 +244,7 @@ namespace pan
 
       virtual void set_server_auth (const Quark       & server,
                                     const StringView  & username,
-                                    const StringView  & password) = 0;
+                                    gchar             *&password) = 0;
 
       virtual void set_server_trust (const Quark      & servername,
                                      const int          setme) = 0;
@@ -259,7 +262,7 @@ namespace pan
 
       virtual bool get_server_auth (const Quark   & server,
                                     std::string   & setme_username,
-                                    std::string   & setme_password) const = 0;
+                                    gchar         *& setme_password) = 0;
 
       virtual bool get_server_trust (const Quark  & servername, int&) const = 0;
 
diff --git a/pan/data/server-info.h b/pan/data/server-info.h
index 6ac87e5..9930d4a 100644
--- a/pan/data/server-info.h
+++ b/pan/data/server-info.h
@@ -46,7 +46,7 @@ namespace pan
 
       virtual void set_server_auth (const Quark       & servername,
                                     const StringView  & username,
-                                    const StringView  & password) = 0;
+                                    gchar             *&password) = 0;
 
       virtual void set_server_trust (const Quark       & servername,
                                      const int           setme) = 0;
@@ -75,7 +75,7 @@ namespace pan
 
       virtual bool get_server_auth (const Quark   & servername,
                                     std::string   & setme_username,
-                                    std::string   & setme_password) const=0;
+                                    gchar         *&setme_password) = 0;
 
       virtual bool get_server_trust (const Quark  & servername, int&) const = 0;
 
@@ -95,7 +95,7 @@ namespace pan
 
       virtual int get_server_article_expiration_age  (const Quark  & server) const = 0;
 
-      virtual bool find_server_by_hn (const Quark& server, Quark& setme) const = 0;
+      virtual bool find_server_by_hn (const std::string& server, Quark& setme) const = 0;
   };
 }
 
diff --git a/pan/gui/pan.cc b/pan/gui/pan.cc
index 72ab44d..1169b1b 100644
--- a/pan/gui/pan.cc
+++ b/pan/gui/pan.cc
@@ -1047,11 +1047,25 @@ main (int argc, char *argv[])
     }
 
     delete queue_and_gui;
+
+  // free dbus pan struct and handle
 #ifdef HAVE_DBUS
   #ifndef DEBUG_PARALLEL
     pan_dbus_deinit(&pan);
   #endif
 #endif
+
+#ifdef HAVE_GKR
+    // free secure passwords
+    foreach(quarks_t, data.get_servers(), it)
+    {
+      Data::Server* s(data.find_server(*it));
+      if (s && s->gkr_pw)
+      {
+        gnome_keyring_memory_free(s->gkr_pw);
+      }
+    }
+#endif
   }
 
   g_mime_shutdown ();
diff --git a/pan/gui/server-ui.cc b/pan/gui/server-ui.cc
index 83cf3e3..07b0c03 100644
--- a/pan/gui/server-ui.cc
+++ b/pan/gui/server-ui.cc
@@ -116,7 +116,8 @@ namespace
     d->server = server;
 
     int port(STD_NNTP_PORT), max_conn(4), age(31*3), rank(1), ssl(0), trust(0);
-    std::string addr, user, pass, cert;
+    std::string addr, user, cert;
+    gchar* pass(NULL);
     if (!server.empty()) {
       d->data.get_server_addr (server, addr, port);
       d->data.get_server_auth (server, user, pass);
@@ -193,7 +194,7 @@ namespace
       const int port (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(d->port_spin)));
       const int max_conn (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(d->connection_limit_spin)));
       StringView user (pan_entry_get_text (d->auth_username_entry));
-      StringView pass = pan_entry_get_text (d->auth_password_entry);
+      gchar* pass = gnome_keyring_memory_strdup(gtk_entry_get_text(GTK_ENTRY(d->auth_password_entry)));
 
       int age (31);
       GtkTreeIter iter;
@@ -247,6 +248,7 @@ namespace
 
     if (destroy)
       gtk_widget_destroy (GTK_WIDGET(w));
+
   }
 
   void delete_server_edit_dialog (gpointer p)
diff --git a/pan/tasks/nntp-pool.cc b/pan/tasks/nntp-pool.cc
index 1475e6c..1de2594 100644
--- a/pan/tasks/nntp-pool.cc
+++ b/pan/tasks/nntp-pool.cc
@@ -170,7 +170,8 @@ NNTP_Pool :: on_socket_created (const StringView  & host,
                                 bool                ok,
                                 Socket            * socket)
 {
-  std::string user, pass;
+  std::string user;
+  gchar* pass(NULL);
   ok = ok && _server_info.get_server_auth (_server, user, pass);
   debug("on socket created "<<host<<" "<<ok<<" "<<socket);
   if (!ok)
diff --git a/pan/tasks/socket-impl-main.cc b/pan/tasks/socket-impl-main.cc
index 3ec7bcd..01f5993 100644
--- a/pan/tasks/socket-impl-main.cc
+++ b/pan/tasks/socket-impl-main.cc
@@ -143,7 +143,7 @@ SocketCreator :: create_socket (ServerInfo& info,
                                 bool               use_ssl)
 {
     Quark server;
-    data.find_server_by_hn(host, server);
+    data.find_server_by_hn(host.to_string(), server);
     ensure_module_init ();
     if (store.in_blacklist(server)) return;
 #ifdef HAVE_GNUTLS
diff --git a/pan/tasks/socket-impl-openssl.cc b/pan/tasks/socket-impl-openssl.cc
index 01d8220..6862240 100644
--- a/pan/tasks/socket-impl-openssl.cc
+++ b/pan/tasks/socket-impl-openssl.cc
@@ -308,6 +308,8 @@ namespace
     gnutls_deinit (chan->session);
     g_free(chan->host);
     g_free(chan);
+    // free callback struct
+    delete (mydata_t*)gnutls_session_get_ptr (chan->session);
   }
 }
 
@@ -569,17 +571,17 @@ GIOChannelSocketGnuTLS :: _gnutls_handshake (GIOChannel *channel)
   g_return_val_if_fail (chan->session, G_IO_STATUS_ERROR);
 
   /* init custom data for callback */
-  mydata_t mydata;
+  mydata_t* mydata = new mydata_t();
 
-  mydata.cs = &_certstore;
+  mydata->cs = &_certstore;
   Quark setme;
-  _data.find_server_by_hn(_host.c_str(), setme);
-  mydata.host = setme;
-  mydata.hostname_full = _host;
+  _data.find_server_by_hn(_host, setme);
+  mydata->host = setme;
+  mydata->hostname_full = _host;
   int res(0); // always trust server cert
   _data.get_server_trust (setme, res);
-  mydata.always_trust = res;
-  gnutls_session_set_ptr (chan->session, (void *) &mydata);
+  mydata->always_trust = res;
+  gnutls_session_set_ptr (chan->session, (void *) mydata);
 
   int status = gnutls_handshake (chan->session);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]