[libsoup] examples/get: Add TLS client certificate support



commit 99d140332dec888814dc3ca0ff5d7bedb3c6a5f0
Author: Colin Walters <walters verbum org>
Date:   Thu Jul 7 10:58:51 2016 -0400

    examples/get: Add TLS client certificate support
    
    I'm trying to debug an ostree issue with client cert interaction with
    a specific server, and it's easier to drop ostree out of the picture
    and use this libsoup equivalent of `curl`.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=768524

 examples/get.c |   75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 75 insertions(+), 0 deletions(-)
---
diff --git a/examples/get.c b/examples/get.c
index df05289..a760592 100644
--- a/examples/get.c
+++ b/examples/get.c
@@ -92,7 +92,60 @@ get_url (const char *url)
        }
 }
 
+/* Inline class for providing a pre-configured client certificate */
+typedef struct _GetTlsCertInteraction        GetTlsCertInteraction;
+typedef struct _GetTlsCertInteractionClass   GetTlsCertInteractionClass;
+
+static GType                    _get_tls_cert_interaction_get_type    (void) G_GNUC_CONST;
+static GetTlsCertInteraction *  _get_tls_cert_interaction_new         (GTlsCertificate *cert);
+
+struct _GetTlsCertInteraction
+{
+       GTlsInteraction parent_instance;
+       GTlsCertificate *cert;
+};
+
+struct _GetTlsCertInteractionClass
+{
+       GTlsInteractionClass parent_class;
+};
+
+G_DEFINE_TYPE (GetTlsCertInteraction, _get_tls_cert_interaction, G_TYPE_TLS_INTERACTION);
+
+static GTlsInteractionResult
+request_certificate (GTlsInteraction              *interaction,
+                     GTlsConnection               *connection,
+                     GTlsCertificateRequestFlags   flags,
+                     GCancellable                 *cancellable,
+                     GError                      **error)
+{
+       GetTlsCertInteraction *self = (GetTlsCertInteraction*)interaction;
+       g_tls_connection_set_certificate (connection, self->cert);
+       return G_TLS_INTERACTION_HANDLED;
+}
+
+static void
+_get_tls_cert_interaction_init (GetTlsCertInteraction *interaction)
+{
+}
+
+static void
+_get_tls_cert_interaction_class_init (GetTlsCertInteractionClass *klass)
+{
+       GTlsInteractionClass *interaction_class = G_TLS_INTERACTION_CLASS (klass);
+       interaction_class->request_certificate = request_certificate;
+}
+
+GetTlsCertInteraction *
+_get_tls_cert_interaction_new (GTlsCertificate *cert)
+{
+       GetTlsCertInteraction *self = g_object_new (_get_tls_cert_interaction_get_type (), NULL);
+       self->cert = g_object_ref (cert);
+       return self;
+}
+
 static const char *ca_file, *proxy;
+static char *client_cert_file, *client_key_file;
 static gboolean synchronous, ntlm;
 static gboolean negotiate;
 
@@ -100,6 +153,12 @@ static GOptionEntry entries[] = {
        { "ca-file", 'c', 0,
          G_OPTION_ARG_STRING, &ca_file,
          "Use FILE as the TLS CA file", "FILE" },
+       { "cert", 0, 0,
+         G_OPTION_ARG_STRING, &client_cert_file,
+         "Use FILE as the TLS client certificate file", "FILE" },
+       { "key", 0, 0,
+         G_OPTION_ARG_STRING, &client_key_file,
+         "Use FILE as the TLS client key file", "FILE" },
        { "debug", 'd', 0,
          G_OPTION_ARG_NONE, &debug,
          "Show HTTP headers", NULL },
@@ -177,6 +236,22 @@ main (int argc, char **argv)
        if (ntlm)
                soup_session_add_feature_by_type (session, SOUP_TYPE_AUTH_NTLM);
 
+       if (client_cert_file) {
+               GTlsCertificate *client_cert;
+               GetTlsCertInteraction *interaction;
+               if (!client_key_file) {
+                       g_printerr ("--key is required with --cert\n");
+                       exit (1);
+               }
+               client_cert = g_tls_certificate_new_from_files (client_cert_file, client_key_file, &error);
+               if (!client_cert) {
+                       g_printerr ("%s\n", error->message);
+                       exit (1);
+               }
+               interaction = _get_tls_cert_interaction_new (client_cert);
+               g_object_set (session, SOUP_SESSION_TLS_INTERACTION, interaction, NULL);
+       }
+
        if (debug) {
                logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, -1);
                soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger));


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