|
Packit Service |
ca3877 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
|
Packit Service |
ca3877 |
/*
|
|
Packit Service |
ca3877 |
* Copyright (C) 2001-2003, Ximian, Inc.
|
|
Packit Service |
ca3877 |
* Copyright (C) 2013 Igalia, S.L.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#ifdef HAVE_CONFIG_H
|
|
Packit Service |
ca3877 |
#include <config.h>
|
|
Packit Service |
ca3877 |
#endif
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#include <stdio.h>
|
|
Packit Service |
ca3877 |
#include <stdlib.h>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#include <libsoup/soup.h>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static SoupSession *session;
|
|
Packit Service |
ca3877 |
static GMainLoop *loop;
|
|
Packit Service |
ca3877 |
static gboolean debug, head, quiet;
|
|
Packit Service |
ca3877 |
static const gchar *output_file_path = NULL;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
finished (SoupSession *session, SoupMessage *msg, gpointer loop)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
g_main_loop_quit (loop);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
get_url (const char *url)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
const char *name;
|
|
Packit Service |
ca3877 |
SoupMessage *msg;
|
|
Packit Service |
ca3877 |
const char *header;
|
|
Packit Service |
ca3877 |
FILE *output_file = NULL;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
msg = soup_message_new (head ? "HEAD" : "GET", url);
|
|
Packit Service |
ca3877 |
soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (loop) {
|
|
Packit Service |
ca3877 |
g_object_ref (msg);
|
|
Packit Service |
ca3877 |
soup_session_queue_message (session, msg, finished, loop);
|
|
Packit Service |
ca3877 |
g_main_loop_run (loop);
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
soup_session_send_message (session, msg);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
name = soup_message_get_uri (msg)->path;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!debug) {
|
|
Packit Service |
ca3877 |
if (msg->status_code == SOUP_STATUS_SSL_FAILED) {
|
|
Packit Service |
ca3877 |
GTlsCertificateFlags flags;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (soup_message_get_https_status (msg, NULL, &flags))
|
|
Packit Service |
ca3877 |
g_print ("%s: %d %s (0x%x)\n", name, msg->status_code, msg->reason_phrase, flags);
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
g_print ("%s: %d %s (no handshake status)\n", name, msg->status_code, msg->reason_phrase);
|
|
Packit Service |
ca3877 |
} else if (!quiet || SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code))
|
|
Packit Service |
ca3877 |
g_print ("%s: %d %s\n", name, msg->status_code, msg->reason_phrase);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) {
|
|
Packit Service |
ca3877 |
header = soup_message_headers_get_one (msg->response_headers,
|
|
Packit Service |
ca3877 |
"Location");
|
|
Packit Service |
ca3877 |
if (header) {
|
|
Packit Service |
ca3877 |
SoupURI *uri;
|
|
Packit Service |
ca3877 |
char *uri_string;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!debug && !quiet)
|
|
Packit Service |
ca3877 |
g_print (" -> %s\n", header);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
uri = soup_uri_new_with_base (soup_message_get_uri (msg), header);
|
|
Packit Service |
ca3877 |
uri_string = soup_uri_to_string (uri, FALSE);
|
|
Packit Service |
ca3877 |
get_url (uri_string);
|
|
Packit Service |
ca3877 |
g_free (uri_string);
|
|
Packit Service |
ca3877 |
soup_uri_free (uri);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
} else if (!head && SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
|
|
Packit Service |
ca3877 |
if (output_file_path) {
|
|
Packit Service |
ca3877 |
output_file = fopen (output_file_path, "w");
|
|
Packit Service |
ca3877 |
if (!output_file)
|
|
Packit Service |
ca3877 |
g_printerr ("Error trying to create file %s.\n", output_file_path);
|
|
Packit Service |
ca3877 |
} else if (!quiet)
|
|
Packit Service |
ca3877 |
output_file = stdout;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (output_file) {
|
|
Packit Service |
ca3877 |
fwrite (msg->response_body->data,
|
|
Packit Service |
ca3877 |
1,
|
|
Packit Service |
ca3877 |
msg->response_body->length,
|
|
Packit Service |
ca3877 |
output_file);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (output_file_path)
|
|
Packit Service |
ca3877 |
fclose (output_file);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
g_object_unref (msg);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* Inline class for providing a pre-configured client certificate */
|
|
Packit Service |
ca3877 |
typedef struct _GetTlsCertInteraction GetTlsCertInteraction;
|
|
Packit Service |
ca3877 |
typedef struct _GetTlsCertInteractionClass GetTlsCertInteractionClass;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static GType _get_tls_cert_interaction_get_type (void) G_GNUC_CONST;
|
|
Packit Service |
ca3877 |
static GetTlsCertInteraction * _get_tls_cert_interaction_new (GTlsCertificate *cert);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
struct _GetTlsCertInteraction
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GTlsInteraction parent_instance;
|
|
Packit Service |
ca3877 |
GTlsCertificate *cert;
|
|
Packit Service |
ca3877 |
};
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
struct _GetTlsCertInteractionClass
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GTlsInteractionClass parent_class;
|
|
Packit Service |
ca3877 |
};
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
G_DEFINE_TYPE (GetTlsCertInteraction, _get_tls_cert_interaction, G_TYPE_TLS_INTERACTION);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static GTlsInteractionResult
|
|
Packit Service |
ca3877 |
request_certificate (GTlsInteraction *interaction,
|
|
Packit Service |
ca3877 |
GTlsConnection *connection,
|
|
Packit Service |
ca3877 |
GTlsCertificateRequestFlags flags,
|
|
Packit Service |
ca3877 |
GCancellable *cancellable,
|
|
Packit Service |
ca3877 |
GError **error)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GetTlsCertInteraction *self = (GetTlsCertInteraction*)interaction;
|
|
Packit Service |
ca3877 |
g_tls_connection_set_certificate (connection, self->cert);
|
|
Packit Service |
ca3877 |
return G_TLS_INTERACTION_HANDLED;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
_get_tls_cert_interaction_init (GetTlsCertInteraction *interaction)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
_get_tls_cert_interaction_class_init (GetTlsCertInteractionClass *klass)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GTlsInteractionClass *interaction_class = G_TLS_INTERACTION_CLASS (klass);
|
|
Packit Service |
ca3877 |
interaction_class->request_certificate = request_certificate;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
GetTlsCertInteraction *
|
|
Packit Service |
ca3877 |
_get_tls_cert_interaction_new (GTlsCertificate *cert)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GetTlsCertInteraction *self = g_object_new (_get_tls_cert_interaction_get_type (), NULL);
|
|
Packit Service |
ca3877 |
self->cert = g_object_ref (cert);
|
|
Packit Service |
ca3877 |
return self;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static const char *ca_file, *proxy;
|
|
Packit Service |
ca3877 |
static char *client_cert_file, *client_key_file;
|
|
Packit Service |
ca3877 |
static gboolean synchronous, ntlm;
|
|
Packit Service |
ca3877 |
static gboolean negotiate;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static GOptionEntry entries[] = {
|
|
Packit Service |
ca3877 |
{ "ca-file", 'c', 0,
|
|
Packit Service |
ca3877 |
G_OPTION_ARG_STRING, &ca_file,
|
|
Packit Service |
ca3877 |
"Use FILE as the TLS CA file", "FILE" },
|
|
Packit Service |
ca3877 |
{ "cert", 0, 0,
|
|
Packit Service |
ca3877 |
G_OPTION_ARG_STRING, &client_cert_file,
|
|
Packit Service |
ca3877 |
"Use FILE as the TLS client certificate file", "FILE" },
|
|
Packit Service |
ca3877 |
{ "key", 0, 0,
|
|
Packit Service |
ca3877 |
G_OPTION_ARG_STRING, &client_key_file,
|
|
Packit Service |
ca3877 |
"Use FILE as the TLS client key file", "FILE" },
|
|
Packit Service |
ca3877 |
{ "debug", 'd', 0,
|
|
Packit Service |
ca3877 |
G_OPTION_ARG_NONE, &debug,
|
|
Packit Service |
ca3877 |
"Show HTTP headers", NULL },
|
|
Packit Service |
ca3877 |
{ "head", 'h', 0,
|
|
Packit Service |
ca3877 |
G_OPTION_ARG_NONE, &head,
|
|
Packit Service |
ca3877 |
"Do HEAD rather than GET", NULL },
|
|
Packit Service |
ca3877 |
{ "ntlm", 'n', 0,
|
|
Packit Service |
ca3877 |
G_OPTION_ARG_NONE, &ntlm,
|
|
Packit Service |
ca3877 |
"Use NTLM authentication", NULL },
|
|
Packit Service |
ca3877 |
{ "output", 'o', 0,
|
|
Packit Service |
ca3877 |
G_OPTION_ARG_STRING, &output_file_path,
|
|
Packit Service |
ca3877 |
"Write the received data to FILE instead of stdout", "FILE" },
|
|
Packit Service |
ca3877 |
{ "proxy", 'p', 0,
|
|
Packit Service |
ca3877 |
G_OPTION_ARG_STRING, &proxy,
|
|
Packit Service |
ca3877 |
"Use URL as an HTTP proxy", "URL" },
|
|
Packit Service |
ca3877 |
{ "quiet", 'q', 0,
|
|
Packit Service |
ca3877 |
G_OPTION_ARG_NONE, &quiet,
|
|
Packit Service |
ca3877 |
"Don't show HTTP status code", NULL },
|
|
Packit Service |
ca3877 |
{ "sync", 's', 0,
|
|
Packit Service |
ca3877 |
G_OPTION_ARG_NONE, &synchronous,
|
|
Packit Service |
ca3877 |
"Use SoupSessionSync rather than SoupSessionAsync", NULL },
|
|
Packit Service |
ca3877 |
{ NULL }
|
|
Packit Service |
ca3877 |
};
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static GOptionEntry negotiate_entries[] = {
|
|
Packit Service |
ca3877 |
{ "negotiate", 'N', 0,
|
|
Packit Service |
ca3877 |
G_OPTION_ARG_NONE, &negotiate,
|
|
Packit Service |
ca3877 |
"Use Negotiate authentication", NULL },
|
|
Packit Service |
ca3877 |
{ NULL }
|
|
Packit Service |
ca3877 |
};
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
int
|
|
Packit Service |
ca3877 |
main (int argc, char **argv)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GOptionContext *opts;
|
|
Packit Service |
ca3877 |
const char *url;
|
|
Packit Service |
ca3877 |
SoupURI *proxy_uri, *parsed;
|
|
Packit Service |
ca3877 |
GError *error = NULL;
|
|
Packit Service |
ca3877 |
SoupLogger *logger = NULL;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
opts = g_option_context_new (NULL);
|
|
Packit Service |
ca3877 |
g_option_context_add_main_entries (opts, entries, NULL);
|
|
Packit Service |
ca3877 |
if (soup_auth_negotiate_supported())
|
|
Packit Service |
ca3877 |
g_option_context_add_main_entries (opts, negotiate_entries, NULL);
|
|
Packit Service |
ca3877 |
if (!g_option_context_parse (opts, &argc, &argv, &error)) {
|
|
Packit Service |
ca3877 |
g_printerr ("Could not parse arguments: %s\n",
|
|
Packit Service |
ca3877 |
error->message);
|
|
Packit Service |
ca3877 |
g_printerr ("%s",
|
|
Packit Service |
ca3877 |
g_option_context_get_help (opts, TRUE, NULL));
|
|
Packit Service |
ca3877 |
exit (1);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (argc != 2) {
|
|
Packit Service |
ca3877 |
g_printerr ("%s",
|
|
Packit Service |
ca3877 |
g_option_context_get_help (opts, TRUE, NULL));
|
|
Packit Service |
ca3877 |
exit (1);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
g_option_context_free (opts);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
url = argv[1];
|
|
Packit Service |
ca3877 |
parsed = soup_uri_new (url);
|
|
Packit Service |
ca3877 |
if (!parsed) {
|
|
Packit Service |
ca3877 |
g_printerr ("Could not parse '%s' as a URL\n", url);
|
|
Packit Service |
ca3877 |
exit (1);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
soup_uri_free (parsed);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
session = g_object_new (SOUP_TYPE_SESSION,
|
|
Packit Service |
ca3877 |
SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_DECODER,
|
|
Packit Service |
ca3877 |
SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_COOKIE_JAR,
|
|
Packit Service |
ca3877 |
SOUP_SESSION_USER_AGENT, "get ",
|
|
Packit Service |
ca3877 |
SOUP_SESSION_ACCEPT_LANGUAGE_AUTO, TRUE,
|
|
Packit Service |
ca3877 |
NULL);
|
|
Packit Service |
ca3877 |
if (ntlm)
|
|
Packit Service |
ca3877 |
soup_session_add_feature_by_type (session, SOUP_TYPE_AUTH_NTLM);
|
|
Packit Service |
ca3877 |
if (ca_file)
|
|
Packit Service |
ca3877 |
g_object_set (session, "ssl-ca-file", ca_file, NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (client_cert_file) {
|
|
Packit Service |
ca3877 |
GTlsCertificate *client_cert;
|
|
Packit Service |
ca3877 |
GetTlsCertInteraction *interaction;
|
|
Packit Service |
ca3877 |
if (!client_key_file) {
|
|
Packit Service |
ca3877 |
g_printerr ("--key is required with --cert\n");
|
|
Packit Service |
ca3877 |
exit (1);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
client_cert = g_tls_certificate_new_from_files (client_cert_file, client_key_file, &error);
|
|
Packit Service |
ca3877 |
if (!client_cert) {
|
|
Packit Service |
ca3877 |
g_printerr ("%s\n", error->message);
|
|
Packit Service |
ca3877 |
exit (1);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
interaction = _get_tls_cert_interaction_new (client_cert);
|
|
Packit Service |
ca3877 |
g_object_set (session, SOUP_SESSION_TLS_INTERACTION, interaction, NULL);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (debug) {
|
|
Packit Service |
ca3877 |
logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, -1);
|
|
Packit Service |
ca3877 |
soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger));
|
|
Packit Service |
ca3877 |
g_object_unref (logger);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (proxy) {
|
|
Packit Service |
ca3877 |
proxy_uri = soup_uri_new (proxy);
|
|
Packit Service |
ca3877 |
if (!proxy_uri) {
|
|
Packit Service |
ca3877 |
g_printerr ("Could not parse '%s' as URI\n",
|
|
Packit Service |
ca3877 |
proxy);
|
|
Packit Service |
ca3877 |
exit (1);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_object_set (G_OBJECT (session),
|
|
Packit Service |
ca3877 |
SOUP_SESSION_PROXY_URI, proxy_uri,
|
|
Packit Service |
ca3877 |
NULL);
|
|
Packit Service |
ca3877 |
soup_uri_free (proxy_uri);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#ifdef LIBSOUP_HAVE_GSSAPI
|
|
Packit Service |
ca3877 |
if (negotiate) {
|
|
Packit Service |
ca3877 |
soup_session_add_feature_by_type (session,
|
|
Packit Service |
ca3877 |
SOUP_TYPE_AUTH_NEGOTIATE);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
#endif /* LIBSOUP_HAVE_GSSAPI */
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!synchronous)
|
|
Packit Service |
ca3877 |
loop = g_main_loop_new (NULL, TRUE);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
get_url (url);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!synchronous)
|
|
Packit Service |
ca3877 |
g_main_loop_unref (loop);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_object_unref (session);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return 0;
|
|
Packit Service |
ca3877 |
}
|