[ostree] pull: Add tls-client-cert-{path, key} (if we have new enough libsoup)
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree] pull: Add tls-client-cert-{path, key} (if we have new enough libsoup)
- Date: Thu, 1 May 2014 21:14:13 +0000 (UTC)
commit 25ad4a9f65a5dae9348fd38c7f4b8b0df1f9773a
Author: Colin Walters <walters verbum org>
Date: Thu May 1 12:55:13 2014 -0400
pull: Add tls-client-cert-{path,key} (if we have new enough libsoup)
This is an actually working version of client-side certificates.
Depends on:
See: https://bugzilla.gnome.org/show_bug.cgi?id=334021
We detect whether libsoup is new enough for this.
https://bugzilla.gnome.org/show_bug.cgi?id=729356
Makefile-libostree.am | 8 +++-
configure.ac | 9 ++++
doc/ostree.repo-config.xml | 20 +++++++-
src/libostree/ostree-fetcher.c | 28 +++++++++++
src/libostree/ostree-fetcher.h | 3 +
src/libostree/ostree-repo-pull.c | 35 ++++++++++++++
src/libostree/ostree-tls-cert-interaction.c | 69 +++++++++++++++++++++++++++
src/libostree/ostree-tls-cert-interaction.h | 39 +++++++++++++++
8 files changed, 209 insertions(+), 2 deletions(-)
---
diff --git a/Makefile-libostree.am b/Makefile-libostree.am
index 5fd6000..d2c039c 100644
--- a/Makefile-libostree.am
+++ b/Makefile-libostree.am
@@ -1,6 +1,6 @@
# Makefile for C source code
#
-# Copyright (C) 2011 Colin Walters <walters verbum org>
+# Copyright (C) 2011,2014 Colin Walters <walters verbum org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -88,6 +88,12 @@ libostree_1_la_SOURCES += src/libostree/ostree-libarchive-input-stream.h \
src/libostree/ostree-libarchive-input-stream.c \
$(NULL)
endif
+if HAVE_LIBSOUP_CLIENT_CERTS
+libostree_1_la_SOURCES += \
+ src/libostree/ostree-tls-cert-interaction.c \
+ src/libostree/ostree-tls-cert-interaction.h \
+ $(NULL)
+endif
libostree_1_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree
-DLOCALEDIR=\"$(datadir)/locale\" -DGPGVPATH=\"$(GPGVPATH)\" $(OT_INTERNAL_GIO_UNIX_CFLAGS)
$(OT_DEP_LZMA_CFLAGS)
libostree_1_la_LDFLAGS = -version-number 1:0:0 -Bsymbolic-functions -export-symbols-regex '^ostree_'
diff --git a/configure.ac b/configure.ac
index 9089ddc..74094c9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -63,12 +63,21 @@ AS_IF([test x$with_soup != xno ], [
PKG_CHECK_MODULES(OT_DEP_SOUP, $SOUP_DEPENDENCY)
AC_DEFINE(HAVE_LIBSOUP, 1, [Define if we have libsoup.pc])
with_soup=yes
+ save_CFLAGS=$CFLAGS
+ CFLAGS=$OT_DEP_SOUP_CFLAGS
+ have_libsoup_client_certs=no
+ AC_CHECK_DECL([SOUP_SESSION_TLS_INTERACTION], [
+ AC_DEFINE(HAVE_LIBSOUP_CLIENT_CERTS, 1, [Define if we have libsoup client certs])
+ have_libsoup_client_certs=yes
+ ], [], [#include <libsoup/soup.h>])
+ CFLAGS=$save_CFLAGS
], [
with_soup=no
])
], [ with_soup=no ])
if test x$with_soup != xno; then OSTREE_FEATURES="$OSTREE_FEATURES +libsoup"; fi
AM_CONDITIONAL(USE_LIBSOUP, test x$with_soup != xno)
+AM_CONDITIONAL(HAVE_LIBSOUP_CLIENT_CERTS, test x$have_libsoup_client_certs = xyes)
m4_ifdef([GOBJECT_INTROSPECTION_CHECK], [
GOBJECT_INTROSPECTION_CHECK([1.34.0])
diff --git a/doc/ostree.repo-config.xml b/doc/ostree.repo-config.xml
index 07244d0..4240814 100644
--- a/doc/ostree.repo-config.xml
+++ b/doc/ostree.repo-config.xml
@@ -104,12 +104,30 @@ Boston, MA 02111-1307, USA.
<varlistentry>
<term><varname>gpg-verify</varname></term>
- <listitem><para>A boolean value, defaults to <tt>true</tt>.
+ <listitem><para>A boolean value, defaults to true.
Controls whether or not OSTree will require commits to be
signed by a known GPG key. For more information, see the
<citerefentry><refentrytitle>ostree</refentrytitle><manvolnum>1</manvolnum></citerefentry>
manual under GPG.</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>tls-permissive</varname></term>
+ <listitem><para>A boolean value, defaults to false. By
+ default, server TLS certificates will be checked against the
+ system certificate store. If this variable is set, any
+ certificate will be accepted.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>tls-client-cert-path</varname></term>
+ <listitem><para>Path to file for client-side certificate, to present when making requests to this
repository.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>tls-client-key-path</varname></term>
+ <listitem><para>Path to file containing client-side certificate key, to present when making requests
to this repository.</para></listitem>
+ </varlistentry>
</variablelist>
</refsect1>
diff --git a/src/libostree/ostree-fetcher.c b/src/libostree/ostree-fetcher.c
index c8db3a0..06023c6 100644
--- a/src/libostree/ostree-fetcher.c
+++ b/src/libostree/ostree-fetcher.c
@@ -25,6 +25,9 @@
#include <gio/gfiledescriptorbased.h>
#include "ostree-fetcher.h"
+#ifdef HAVE_LIBSOUP_CLIENT_CERTS
+#include "ostree-tls-cert-interaction.h"
+#endif
#include "ostree.h"
#include "otutil.h"
#include "libgsystem.h"
@@ -79,6 +82,8 @@ struct OstreeFetcher
GFile *tmpdir;
+ GTlsCertificate *client_cert;
+
SoupSession *session;
SoupRequester *requester;
@@ -107,6 +112,7 @@ ostree_fetcher_finalize (GObject *object)
g_clear_object (&self->session);
g_clear_object (&self->tmpdir);
+ g_clear_object (&self->client_cert);
g_hash_table_destroy (self->sending_messages);
g_hash_table_destroy (self->message_to_request);
@@ -175,6 +181,9 @@ ostree_fetcher_init (OstreeFetcher *self)
}
}
+ if (g_getenv ("OSTREE_DEBUG_HTTP"))
+ soup_session_add_feature (self->session, (SoupSessionFeature*)soup_logger_new (SOUP_LOGGER_LOG_BODY,
500));
+
self->requester = (SoupRequester *)soup_session_get_feature (self->session, SOUP_TYPE_REQUESTER);
g_object_get (self->session, "max-conns-per-host", &max_conns, NULL);
self->max_outstanding = 3 * max_conns;
@@ -204,6 +213,24 @@ ostree_fetcher_new (GFile *tmpdir,
return self;
}
+void
+ostree_fetcher_set_client_cert (OstreeFetcher *fetcher,
+ GTlsCertificate *cert)
+{
+ g_clear_object (&fetcher->client_cert);
+ fetcher->client_cert = g_object_ref (cert);
+ if (fetcher->client_cert)
+ {
+#ifdef HAVE_LIBSOUP_CLIENT_CERTS
+ gs_unref_object GTlsInteraction *interaction =
+ (GTlsInteraction*)ostree_tls_cert_interaction_new (fetcher->client_cert);
+ g_object_set (fetcher->session, "tls-interaction", interaction, NULL);
+#else
+ g_warning ("This version of OSTree is compiled without client side certificate support");
+#endif
+ }
+}
+
static void
on_request_sent (GObject *object, GAsyncResult *result, gpointer user_data);
@@ -215,6 +242,7 @@ ostree_fetcher_process_pending_queue (OstreeFetcher *self)
self->outstanding < self->max_outstanding)
{
OstreeFetcherPendingURI *next = g_queue_pop_head (&self->pending_queue);
+
self->outstanding++;
soup_request_send_async (next->request, next->cancellable,
on_request_sent, next);
diff --git a/src/libostree/ostree-fetcher.h b/src/libostree/ostree-fetcher.h
index 220bd93..928d2a3 100644
--- a/src/libostree/ostree-fetcher.h
+++ b/src/libostree/ostree-fetcher.h
@@ -54,6 +54,9 @@ GType ostree_fetcher_get_type (void) G_GNUC_CONST;
OstreeFetcher *ostree_fetcher_new (GFile *tmpdir,
OstreeFetcherConfigFlags flags);
+void ostree_fetcher_set_client_cert (OstreeFetcher *fetcher,
+ GTlsCertificate *cert);
+
char * ostree_fetcher_query_state_text (OstreeFetcher *self);
guint64 ostree_fetcher_bytes_transferred (OstreeFetcher *self);
diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c
index 427bd92..e3e5a77 100644
--- a/src/libostree/ostree-repo-pull.c
+++ b/src/libostree/ostree-repo-pull.c
@@ -1086,6 +1086,41 @@ ostree_repo_pull (OstreeRepo *self,
pull_data->fetcher = ostree_fetcher_new (pull_data->repo->tmp_dir,
fetcher_flags);
+ {
+ gs_free char *tls_client_cert_path = NULL;
+ gs_free char *tls_client_key_path = NULL;
+
+ if (!ot_keyfile_get_value_with_default (config, remote_key,
+ "tls-client-cert-path",
+ NULL, &tls_client_cert_path, error))
+ goto out;
+ if (!ot_keyfile_get_value_with_default (config, remote_key,
+ "tls-client-key-path",
+ NULL, &tls_client_key_path, error))
+ goto out;
+
+ if ((tls_client_cert_path != NULL) != (tls_client_key_path != NULL))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "\"%s\" must specify both \"tls-client-cert-path\" and \"tls-client-key-path\"",
remote_key);
+ goto out;
+ }
+ else if (tls_client_cert_path)
+ {
+ gs_unref_object GTlsCertificate *client_cert = NULL;
+
+ g_assert (tls_client_key_path);
+
+ client_cert = g_tls_certificate_new_from_files (tls_client_cert_path,
+ tls_client_key_path,
+ error);
+ if (!client_cert)
+ goto out;
+
+ ostree_fetcher_set_client_cert (pull_data->fetcher, client_cert);
+ }
+ }
+
if (!pull_data->base_uri)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
diff --git a/src/libostree/ostree-tls-cert-interaction.c b/src/libostree/ostree-tls-cert-interaction.c
new file mode 100644
index 0000000..63de917
--- /dev/null
+++ b/src/libostree/ostree-tls-cert-interaction.c
@@ -0,0 +1,69 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2014 Colin Walters <walters verbum org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "ostree-tls-cert-interaction.h"
+
+struct _OstreeTlsCertInteraction
+{
+ GTlsInteraction parent_instance;
+
+ GTlsCertificate *cert;
+};
+
+struct _OstreeTlsCertInteractionClass
+{
+ GTlsInteractionClass parent_class;
+};
+
+#include <string.h>
+
+G_DEFINE_TYPE (OstreeTlsCertInteraction, ostree_tls_cert_interaction, G_TYPE_TLS_INTERACTION);
+
+static GTlsInteractionResult
+request_certificate (GTlsInteraction *interaction,
+ GTlsConnection *connection,
+ GTlsCertificateRequestFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ OstreeTlsCertInteraction *self = (OstreeTlsCertInteraction*)interaction;
+ g_tls_connection_set_certificate (connection, self->cert);
+ return G_TLS_INTERACTION_HANDLED;
+}
+
+static void
+ostree_tls_cert_interaction_init (OstreeTlsCertInteraction *interaction)
+{
+}
+
+static void
+ostree_tls_cert_interaction_class_init (OstreeTlsCertInteractionClass *klass)
+{
+ GTlsInteractionClass *interaction_class = G_TLS_INTERACTION_CLASS (klass);
+ interaction_class->request_certificate = request_certificate;
+}
+
+OstreeTlsCertInteraction *
+ostree_tls_cert_interaction_new (GTlsCertificate *cert)
+{
+ OstreeTlsCertInteraction *self = g_object_new (OSTREE_TYPE_TLS_CERT_INTERACTION, NULL);
+ self->cert = g_object_ref (cert);
+ return self;
+}
diff --git a/src/libostree/ostree-tls-cert-interaction.h b/src/libostree/ostree-tls-cert-interaction.h
new file mode 100644
index 0000000..ca9cd32
--- /dev/null
+++ b/src/libostree/ostree-tls-cert-interaction.h
@@ -0,0 +1,39 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2013 Colin Walters <walters verbum org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define OSTREE_TYPE_TLS_CERT_INTERACTION (ostree_tls_cert_interaction_get_type ())
+#define OSTREE_TLS_CERT_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o),
OSTREE_TYPE_TLS_CERT_INTERACTION, OstreeTlsCertInteraction))
+#define OSTREE_TLS_CERT_INTERACTION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k),
OSTREE_TYPE_TLS_CERT_INTERACTION, OstreeTlsCertInteractionClass))
+#define OSTREE_IS_TLS_CERT_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o),
OSTREE_TYPE_TLS_CERT_INTERACTION))
+#define OSTREE_IS_TLS_CERT_INTERACTION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k),
OSTREE_TYPE_TLS_CERT_INTERACTION))
+#define OSTREE_TLS_CERT_INTERACTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),
OSTREE_TYPE_TLS_CERT_INTERACTION, OstreeTlsCertInteractionClass))
+
+typedef struct _OstreeTlsCertInteraction OstreeTlsCertInteraction;
+typedef struct _OstreeTlsCertInteractionClass OstreeTlsCertInteractionClass;
+
+GType ostree_tls_cert_interaction_get_type (void) G_GNUC_CONST;
+
+OstreeTlsCertInteraction * ostree_tls_cert_interaction_new (GTlsCertificate *cert);
+
+G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]