diff --git a/src/libostree/ostree-fetcher.c b/src/libostree/ostree-fetcher.c index cee33186cb..a178abfe75 100644 --- a/src/libostree/ostree-fetcher.c +++ b/src/libostree/ostree-fetcher.c @@ -52,6 +52,7 @@ typedef struct { SoupSession *session; /* not referenced */ GMainContext *main_context; volatile gint running; + GError *initialization_error; /* Any failure to load the db */ int tmpdir_dfd; char *tmpdir_name; @@ -357,12 +358,14 @@ static void session_thread_set_tls_interaction_cb (ThreadClosure *thread_closure, gpointer data) { - GTlsCertificate *cert = data; + const char *cert_and_key_path = data; /* str\0str\0 in one malloc buf */ + const char *cert_path = cert_and_key_path; + const char *key_path = cert_and_key_path + strlen (cert_and_key_path) + 1; glnx_unref_object OstreeTlsCertInteraction *interaction = NULL; /* The GTlsInteraction instance must be created in the * session thread so it uses the correct GMainContext. */ - interaction = _ostree_tls_cert_interaction_new (cert); + interaction = _ostree_tls_cert_interaction_new (cert_path, key_path); g_object_set (thread_closure->session, SOUP_SESSION_TLS_INTERACTION, @@ -374,13 +377,19 @@ static void session_thread_set_tls_database_cb (ThreadClosure *thread_closure, gpointer data) { - GTlsDatabase *database = data; + const char *db_path = data; - if (database != NULL) + if (db_path != NULL) { - g_object_set (thread_closure->session, - SOUP_SESSION_TLS_DATABASE, - database, NULL); + glnx_unref_object GTlsDatabase *tlsdb = NULL; + + g_clear_error (&thread_closure->initialization_error); + tlsdb = g_tls_file_database_new (db_path, &thread_closure->initialization_error); + + if (tlsdb) + g_object_set (thread_closure->session, + SOUP_SESSION_TLS_DATABASE, + tlsdb, NULL); } else { @@ -452,6 +461,13 @@ session_thread_request_uri (ThreadClosure *thread_closure, pending = g_task_get_task_data (task); cancellable = g_task_get_cancellable (task); + /* If we caught an error in init, re-throw it for every request */ + if (thread_closure->initialization_error) + { + g_task_return_error (task, g_error_copy (thread_closure->initialization_error)); + return; + } + create_pending_soup_request (pending, &local_error); if (local_error != NULL) { @@ -797,16 +813,24 @@ _ostree_fetcher_set_cookie_jar (OstreeFetcher *self, void _ostree_fetcher_set_client_cert (OstreeFetcher *self, - GTlsCertificate *cert) + const char *cert_path, + const char *key_path) { + g_autoptr(GString) buf = NULL; g_return_if_fail (OSTREE_IS_FETCHER (self)); - g_return_if_fail (G_IS_TLS_CERTIFICATE (cert)); + + if (cert_path) + { + buf = g_string_new (cert_path); + g_string_append_c (buf, '\0'); + g_string_append (buf, key_path); + } #ifdef HAVE_LIBSOUP_CLIENT_CERTS session_thread_idle_add (self->thread_closure, session_thread_set_tls_interaction_cb, - g_object_ref (cert), - (GDestroyNotify) g_object_unref); + g_string_free (g_steal_pointer (&buf), FALSE), + (GDestroyNotify) g_free); #else g_warning ("This version of OSTree is compiled without client side certificate support"); #endif @@ -814,24 +838,14 @@ _ostree_fetcher_set_client_cert (OstreeFetcher *self, void _ostree_fetcher_set_tls_database (OstreeFetcher *self, - GTlsDatabase *db) + const char *tlsdb_path) { g_return_if_fail (OSTREE_IS_FETCHER (self)); - g_return_if_fail (db == NULL || G_IS_TLS_DATABASE (db)); - if (db != NULL) - { - session_thread_idle_add (self->thread_closure, - session_thread_set_tls_database_cb, - g_object_ref (db), - (GDestroyNotify) g_object_unref); - } - else - { - session_thread_idle_add (self->thread_closure, - session_thread_set_tls_database_cb, - NULL, (GDestroyNotify) NULL); - } + session_thread_idle_add (self->thread_closure, + session_thread_set_tls_database_cb, + g_strdup (tlsdb_path), + (GDestroyNotify) g_free); } void diff --git a/src/libostree/ostree-fetcher.h b/src/libostree/ostree-fetcher.h index a57907e429..f19eb73b0d 100644 --- a/src/libostree/ostree-fetcher.h +++ b/src/libostree/ostree-fetcher.h @@ -93,10 +93,11 @@ void _ostree_fetcher_set_proxy (OstreeFetcher *fetcher, const char *proxy); void _ostree_fetcher_set_client_cert (OstreeFetcher *fetcher, - GTlsCertificate *cert); + const char *cert_path, + const char *key_path); void _ostree_fetcher_set_tls_database (OstreeFetcher *self, - GTlsDatabase *db); + const char *tlsdb_path); void _ostree_fetcher_set_extra_headers (OstreeFetcher *self, GVariant *extra_headers); diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 3dabb34633..45995a30d0 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -1951,17 +1951,7 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, } else if (tls_client_cert_path != NULL) { - g_autoptr(GTlsCertificate) client_cert = NULL; - - g_assert (tls_client_key_path != NULL); - - client_cert = g_tls_certificate_new_from_files (tls_client_cert_path, - tls_client_key_path, - error); - if (client_cert == NULL) - goto out; - - _ostree_fetcher_set_client_cert (fetcher, client_cert); + _ostree_fetcher_set_client_cert (fetcher, tls_client_cert_path, tls_client_key_path); } } @@ -1975,13 +1965,7 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, if (tls_ca_path != NULL) { - g_autoptr(GTlsDatabase) db = NULL; - - db = g_tls_file_database_new (tls_ca_path, error); - if (db == NULL) - goto out; - - _ostree_fetcher_set_tls_database (fetcher, db); + _ostree_fetcher_set_tls_database (fetcher, tls_ca_path); } } diff --git a/src/libostree/ostree-tls-cert-interaction.c b/src/libostree/ostree-tls-cert-interaction.c index 846d5725fc..7e60f9de4d 100644 --- a/src/libostree/ostree-tls-cert-interaction.c +++ b/src/libostree/ostree-tls-cert-interaction.c @@ -24,6 +24,8 @@ struct _OstreeTlsCertInteraction { GTlsInteraction parent_instance; + char *cert_path; + char *key_path; GTlsCertificate *cert; }; @@ -44,6 +46,14 @@ request_certificate (GTlsInteraction *interaction, GError **error) { OstreeTlsCertInteraction *self = (OstreeTlsCertInteraction*)interaction; + + if (!self->cert) + { + self->cert = g_tls_certificate_new_from_files (self->cert_path, self->key_path, error); + if (!self->cert) + return G_TLS_INTERACTION_FAILED; + } + g_tls_connection_set_certificate (connection, self->cert); return G_TLS_INTERACTION_HANDLED; } @@ -61,9 +71,11 @@ _ostree_tls_cert_interaction_class_init (OstreeTlsCertInteractionClass *klass) } OstreeTlsCertInteraction * -_ostree_tls_cert_interaction_new (GTlsCertificate *cert) +_ostree_tls_cert_interaction_new (const char *cert_path, + const char *key_path) { OstreeTlsCertInteraction *self = g_object_new (OSTREE_TYPE_TLS_CERT_INTERACTION, NULL); - self->cert = g_object_ref (cert); + self->cert_path = g_strdup (cert_path); + self->key_path = g_strdup (key_path); return self; } diff --git a/src/libostree/ostree-tls-cert-interaction.h b/src/libostree/ostree-tls-cert-interaction.h index c81097c5e3..ae4532f7ba 100644 --- a/src/libostree/ostree-tls-cert-interaction.h +++ b/src/libostree/ostree-tls-cert-interaction.h @@ -34,6 +34,7 @@ typedef struct _OstreeTlsCertInteractionClass OstreeTlsCertInteractionClass; GType _ostree_tls_cert_interaction_get_type (void) G_GNUC_CONST; -OstreeTlsCertInteraction * _ostree_tls_cert_interaction_new (GTlsCertificate *cert); +OstreeTlsCertInteraction * _ostree_tls_cert_interaction_new (const char *cert_path, + const char *key_path); G_END_DECLS