summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2016-07-07 10:58:51 -0400
committerColin Walters <walters@verbum.org>2016-07-12 09:50:40 -0400
commit99d140332dec888814dc3ca0ff5d7bedb3c6a5f0 (patch)
tree6140bc9ff461c4d49f995a6971c04c7e68d8142a
parent5ec000ba17a1d5b808a71ef5909265713415bd45 (diff)
downloadlibsoup-99d140332dec888814dc3ca0ff5d7bedb3c6a5f0.tar.gz
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
-rw-r--r--examples/get.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/examples/get.c b/examples/get.c
index df052892..a760592c 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));