[glib-networking] gnutls: Initialize the gnutls_session in initable_init



commit d393aab1a9d5f89436e67d9c53f4344267fc9cbc
Author: Olivier CrĂȘte <olivier crete collabora com>
Date:   Tue Mar 5 20:24:32 2013 -0500

    gnutls: Initialize the gnutls_session in initable_init
    
    This way, we are sure that all of the properties have been set by that point.
    And the GIOStream needs to be set before creating the GnuTLS session to know
    if it's a datagram session or not.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=697908

 tls/gnutls/gtlsclientconnection-gnutls.c |   47 ++++++++++++++++++++++++++++-
 tls/gnutls/gtlsconnection-gnutls.c       |   19 ++----------
 tls/gnutls/gtlsserverconnection-gnutls.c |   13 ++++----
 3 files changed, 55 insertions(+), 24 deletions(-)
---
diff --git a/tls/gnutls/gtlsclientconnection-gnutls.c b/tls/gnutls/gtlsclientconnection-gnutls.c
index cc64f9e..d5d63fa 100644
--- a/tls/gnutls/gtlsclientconnection-gnutls.c
+++ b/tls/gnutls/gtlsclientconnection-gnutls.c
@@ -42,6 +42,8 @@ enum
   PROP_ACCEPTED_CAS
 };
 
+static void     g_tls_client_connection_gnutls_initable_interface_init (GInitableIface  *iface);
+
 static void g_tls_client_connection_gnutls_client_connection_interface_init (GTlsClientConnectionInterface 
*iface);
 
 static int g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t             session,
@@ -51,7 +53,11 @@ static int g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t
                                                             int                          pk_algos_length,
                                                             gnutls_retr2_st             *st);
 
+static GInitableIface *g_tls_client_connection_gnutls_parent_initable_iface;
+
 G_DEFINE_TYPE_WITH_CODE (GTlsClientConnectionGnutls, g_tls_client_connection_gnutls, 
G_TYPE_TLS_CONNECTION_GNUTLS,
+                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+                                               g_tls_client_connection_gnutls_initable_interface_init)
                         G_IMPLEMENT_INTERFACE (G_TYPE_TLS_CLIENT_CONNECTION,
                                                
g_tls_client_connection_gnutls_client_connection_interface_init));
 
@@ -152,6 +158,30 @@ g_tls_client_connection_gnutls_finalize (GObject *object)
   G_OBJECT_CLASS (g_tls_client_connection_gnutls_parent_class)->finalize (object);
 }
 
+static gboolean
+g_tls_client_connection_gnutls_initable_init (GInitable       *initable,
+                                             GCancellable    *cancellable,
+                                             GError         **error)
+{
+  GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (initable);
+  gnutls_session_t session;
+  const gchar *hostname;
+
+  if (!g_tls_client_connection_gnutls_parent_initable_iface->
+      init (initable, cancellable, error))
+    return FALSE;
+
+  session = g_tls_connection_gnutls_get_session (gnutls);
+  hostname = get_server_identity (G_TLS_CLIENT_CONNECTION_GNUTLS (gnutls));
+  if (hostname)
+    {
+      gnutls_server_name_set (session, GNUTLS_NAME_DNS,
+                              hostname, strlen (hostname));
+    }
+
+  return TRUE;
+}
+
 static void
 g_tls_client_connection_gnutls_get_property (GObject    *object,
                                             guint       prop_id,
@@ -220,8 +250,13 @@ g_tls_client_connection_gnutls_set_property (GObject      *object,
        {
          gnutls_session_t session = g_tls_connection_gnutls_get_session (G_TLS_CONNECTION_GNUTLS (gnutls));
 
-         gnutls_server_name_set (session, GNUTLS_NAME_DNS,
-                                 hostname, strlen (hostname));
+         /* This will only be triggered if the identity is set after
+          * initialization */
+         if (session)
+            {
+              gnutls_server_name_set (session, GNUTLS_NAME_DNS,
+                                      hostname, strlen (hostname));
+            }
        }
       break;
 
@@ -417,3 +452,11 @@ g_tls_client_connection_gnutls_client_connection_interface_init (GTlsClientConne
 {
   iface->copy_session_state = g_tls_client_connection_gnutls_copy_session_state;
 }
+
+static void
+g_tls_client_connection_gnutls_initable_interface_init (GInitableIface  *iface)
+{
+  g_tls_client_connection_gnutls_parent_initable_iface = g_type_interface_peek_parent (iface);
+
+  iface->init = g_tls_client_connection_gnutls_initable_init;
+}
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index 5326c86..94d96a7 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -292,15 +292,14 @@ g_tls_connection_gnutls_initable_init (GInitable     *initable,
                                       GError       **error)
 {
   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (initable);
+  gboolean client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
+  guint flags = client ? GNUTLS_CLIENT : GNUTLS_SERVER;
   int status;
 
   g_return_val_if_fail (gnutls->priv->base_istream != NULL &&
                        gnutls->priv->base_ostream != NULL, FALSE);
 
-  /* Make sure gnutls->priv->session has been initialized (it may have
-   * already been initialized by a construct-time property setter).
-   */
-  g_tls_connection_gnutls_get_session (gnutls);
+  gnutls_init (&gnutls->priv->session, flags);
 
   status = gnutls_credentials_set (gnutls->priv->session,
                                   GNUTLS_CRD_CERTIFICATE,
@@ -521,18 +520,6 @@ g_tls_connection_gnutls_get_credentials (GTlsConnectionGnutls *gnutls)
 gnutls_session_t
 g_tls_connection_gnutls_get_session (GTlsConnectionGnutls *gnutls)
 {
-  /* Ideally we would initialize gnutls->priv->session from
-   * g_tls_connection_gnutls_init(), but we can't tell if it's a
-   * client or server connection at that point... And
-   * g_tls_connection_gnutls_initiable_init() is too late, because
-   * construct-time property setters may need to modify it.
-   */
-  if (!gnutls->priv->session)
-    {
-      gboolean client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
-      gnutls_init (&gnutls->priv->session, client ? GNUTLS_CLIENT : GNUTLS_SERVER);
-    }
-
   return gnutls->priv->session;
 }
 
diff --git a/tls/gnutls/gtlsserverconnection-gnutls.c b/tls/gnutls/gtlsserverconnection-gnutls.c
index 01def4c..aea76fb 100644
--- a/tls/gnutls/gtlsserverconnection-gnutls.c
+++ b/tls/gnutls/gtlsserverconnection-gnutls.c
@@ -75,17 +75,11 @@ static void
 g_tls_server_connection_gnutls_init (GTlsServerConnectionGnutls *gnutls)
 {
   gnutls_certificate_credentials_t creds;
-  gnutls_session_t session;
 
   gnutls->priv = G_TYPE_INSTANCE_GET_PRIVATE (gnutls, G_TYPE_TLS_SERVER_CONNECTION_GNUTLS, 
GTlsServerConnectionGnutlsPrivate);
 
   creds = g_tls_connection_gnutls_get_credentials (G_TLS_CONNECTION_GNUTLS (gnutls));
   gnutls_certificate_set_retrieve_function (creds, g_tls_server_connection_gnutls_retrieve_function);
-
-  session = g_tls_connection_gnutls_get_session (G_TLS_CONNECTION_GNUTLS (gnutls));
-  gnutls_db_set_retrieve_function (session, g_tls_server_connection_gnutls_db_retrieve);
-  gnutls_db_set_store_function (session, g_tls_server_connection_gnutls_db_store);
-  gnutls_db_set_remove_function (session, g_tls_server_connection_gnutls_db_remove);
 }
 
 static gboolean
@@ -93,12 +87,19 @@ g_tls_server_connection_gnutls_initable_init (GInitable       *initable,
                                              GCancellable    *cancellable,
                                              GError         **error)
 {
+  GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (initable);
   GTlsCertificate *cert;
+  gnutls_session_t session;
 
   if (!g_tls_server_connection_gnutls_parent_initable_iface->
       init (initable, cancellable, error))
     return FALSE;
 
+  session = g_tls_connection_gnutls_get_session (G_TLS_CONNECTION_GNUTLS (gnutls));
+  gnutls_db_set_retrieve_function (session, g_tls_server_connection_gnutls_db_retrieve);
+  gnutls_db_set_store_function (session, g_tls_server_connection_gnutls_db_store);
+  gnutls_db_set_remove_function (session, g_tls_server_connection_gnutls_db_remove);
+
   cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (initable));
   if (cert && !g_tls_certificate_gnutls_has_key (G_TLS_CERTIFICATE_GNUTLS (cert)))
     {


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