diff --git a/configure.in b/configure.in index 9a7f8d8e7..4c972dbd7 100644 --- a/configure.in +++ b/configure.in @@ -66,6 +66,7 @@ AC_ARG_WITH( m4_include(m4/macros/enable-disable.m4) ARG_ENABL_SET([curl], [enable CURL fetcher plugin to fetch files via libcurl. Requires libcurl.]) +ARG_ENABL_SET([soup], [enable soup fetcher plugin to fetch from HTTP via libsoup. Requires libsoup.]) ARG_ENABL_SET([ldap], [enable LDAP fetching plugin to fetch files via libldap. Requires openLDAP.]) ARG_DISBL_SET([aes], [disable AES software implementation plugin.]) ARG_DISBL_SET([des], [disable DES/3DES software implementation plugin.]) @@ -498,6 +499,12 @@ if test x$curl = xtrue; then AC_CHECK_HEADER([curl/curl.h],,[AC_MSG_ERROR([CURL header curl/curl.h not found!])]) fi +if test x$soup = xtrue; then + PKG_CHECK_MODULES(soup, [libsoup-2.4]) + AC_SUBST(soup_CFLAGS) + AC_SUBST(soup_LIBS) +fi + if test x$xml = xtrue; then PKG_CHECK_MODULES(xml, [libxml-2.0]) AC_SUBST(xml_CFLAGS) @@ -689,8 +696,9 @@ h_plugins= s_plugins= ADD_PLUGIN([test-vectors], [s libcharon pluto openac scepclient pki]) -ADD_PLUGIN([curl], [s libcharon pluto scepclient]) -ADD_PLUGIN([ldap], [s libcharon pluto scepclient]) +ADD_PLUGIN([curl], [s libcharon pluto scepclient scripts]) +ADD_PLUGIN([soup], [s libcharon pluto scripts]) +ADD_PLUGIN([ldap], [s libcharon pluto scepclient scripts]) ADD_PLUGIN([mysql], [s libcharon pluto pool manager medsrv]) ADD_PLUGIN([sqlite], [s libcharon pluto pool manager medsrv]) ADD_PLUGIN([aes], [s libcharon pluto openac scepclient pki scripts]) @@ -793,6 +801,7 @@ dnl libstrongswan plugins dnl ===================== AM_CONDITIONAL(USE_TEST_VECTORS, test x$test_vectors = xtrue) AM_CONDITIONAL(USE_CURL, test x$curl = xtrue) +AM_CONDITIONAL(USE_SOUP, test x$soup = xtrue) AM_CONDITIONAL(USE_LDAP, test x$ldap = xtrue) AM_CONDITIONAL(USE_AES, test x$aes = xtrue) AM_CONDITIONAL(USE_DES, test x$des = xtrue) @@ -960,6 +969,7 @@ AC_OUTPUT( src/libstrongswan/plugins/dnskey/Makefile src/libstrongswan/plugins/pem/Makefile src/libstrongswan/plugins/curl/Makefile + src/libstrongswan/plugins/soup/Makefile src/libstrongswan/plugins/ldap/Makefile src/libstrongswan/plugins/mysql/Makefile src/libstrongswan/plugins/sqlite/Makefile diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index debfaf7ae..6a29d8eea 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -282,6 +282,13 @@ if MONOLITHIC endif endif +if USE_SOUP + SUBDIRS += plugins/soup +if MONOLITHIC + libstrongswan_la_LIBADD += plugins/soup/libstrongswan-soup.la +endif +endif + if USE_LDAP SUBDIRS += plugins/ldap if MONOLITHIC diff --git a/src/libstrongswan/plugins/soup/Makefile.am b/src/libstrongswan/plugins/soup/Makefile.am new file mode 100644 index 000000000..9006f1b7c --- /dev/null +++ b/src/libstrongswan/plugins/soup/Makefile.am @@ -0,0 +1,16 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan ${soup_CFLAGS} + +AM_CFLAGS = -rdynamic + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-soup.la +else +plugin_LTLIBRARIES = libstrongswan-soup.la +endif + +libstrongswan_soup_la_SOURCES = \ + soup_plugin.h soup_plugin.c soup_fetcher.c soup_fetcher.h + +libstrongswan_soup_la_LDFLAGS = -module -avoid-version +libstrongswan_soup_la_LIBADD = ${soup_LIBS} diff --git a/src/libstrongswan/plugins/soup/soup_fetcher.c b/src/libstrongswan/plugins/soup/soup_fetcher.c new file mode 100644 index 000000000..fd97631bd --- /dev/null +++ b/src/libstrongswan/plugins/soup/soup_fetcher.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program 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 General Public License + * for more details. + */ + +#include "soup_fetcher.h" + +#include + +#include +#include + +#define DEFAULT_TIMEOUT 10 + +typedef struct private_soup_fetcher_t private_soup_fetcher_t; + +/** + * private data of a soup_fetcher_t object. + */ +struct private_soup_fetcher_t { + + /** + * Public data + */ + soup_fetcher_t public; + + /** + * HTTP request method + */ + const char *method; + + /** + * Request content type + */ + char *type; + + /** + * Request data + */ + chunk_t data; + + /** + * Request timeout + */ + u_int timeout; + + /** + * HTTP request version + */ + SoupHTTPVersion version; +}; + +METHOD(fetcher_t, fetch, status_t, + private_soup_fetcher_t *this, char *uri, chunk_t *result) +{ + SoupSession *session; + SoupMessage *message; + status_t status = FAILED; + + message = soup_message_new(this->method, uri); + if (!message) + { + return NOT_SUPPORTED; + } + if (this->type) + { + soup_message_set_request(message, this->type, SOUP_MEMORY_STATIC, + this->data.ptr, this->data.len); + } + soup_message_set_http_version(message, this->version); + session = soup_session_sync_new(); + g_object_set(G_OBJECT(session), + SOUP_SESSION_TIMEOUT, (guint)this->timeout, NULL); + + DBG2(DBG_LIB, "sending http request to '%s'...", uri); + soup_session_send_message(session, message); + if (SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) + { + *result = chunk_clone(chunk_create((u_char*)message->response_body->data, + message->response_body->length)); + status = SUCCESS; + } + else + { + DBG1(DBG_LIB, "HTTP request failed, code %d", message->status_code); + } + g_object_unref(G_OBJECT(message)); + g_object_unref(G_OBJECT(session)); + return status; +} + +METHOD(fetcher_t, set_option, bool, + private_soup_fetcher_t *this, fetcher_option_t option, ...) +{ + bool supported = TRUE; + va_list args; + + va_start(args, option); + switch (option) + { + case FETCH_REQUEST_DATA: + this->method = SOUP_METHOD_POST; + this->data = va_arg(args, chunk_t); + break; + case FETCH_REQUEST_TYPE: + this->type = va_arg(args, char*); + break; + case FETCH_HTTP_VERSION_1_0: + this->version = SOUP_HTTP_1_0; + break; + case FETCH_TIMEOUT: + this->timeout = va_arg(args, u_int); + break; + default: + supported = FALSE; + break; + } + va_end(args); + return supported; +} + +METHOD(fetcher_t, destroy, void, + private_soup_fetcher_t *this) +{ + free(this); +} + +/* + * Described in header. + */ +soup_fetcher_t *soup_fetcher_create() +{ + private_soup_fetcher_t *this; + + INIT(this, + .public = { + .interface = { + .fetch = _fetch, + .set_option = _set_option, + .destroy = _destroy, + }, + }, + .method = SOUP_METHOD_GET, + .version = SOUP_HTTP_1_1, + .timeout = DEFAULT_TIMEOUT, + ); + + return &this->public; +} diff --git a/src/libstrongswan/plugins/soup/soup_fetcher.h b/src/libstrongswan/plugins/soup/soup_fetcher.h new file mode 100644 index 000000000..9b2579515 --- /dev/null +++ b/src/libstrongswan/plugins/soup/soup_fetcher.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program 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 General Public License + * for more details. + */ + +/** + * @defgroup soup_fetcher soup_fetcher + * @{ @ingroup soup_p + */ + +#ifndef SOUP_FETCHER_H_ +#define SOUP_FETCHER_H_ + +#include + +typedef struct soup_fetcher_t soup_fetcher_t; + +/** + * Fetcher implementation for HTTP using libsoup. + */ +struct soup_fetcher_t { + + /** + * Implements fetcher interface. + */ + fetcher_t interface; +}; + +/** + * Create a soup_fetcher instance. + */ +soup_fetcher_t *soup_fetcher_create(); + +#endif /** SOUP_FETCHER_H_ @}*/ diff --git a/src/libstrongswan/plugins/soup/soup_plugin.c b/src/libstrongswan/plugins/soup/soup_plugin.c new file mode 100644 index 000000000..970e32472 --- /dev/null +++ b/src/libstrongswan/plugins/soup/soup_plugin.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program 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 General Public License + * for more details. + */ + +#include "soup_plugin.h" +#include "soup_fetcher.h" + +#include +#include + +#include + +typedef struct private_soup_plugin_t private_soup_plugin_t; + +/** + * private data of soup_plugin + */ +struct private_soup_plugin_t { + + /** + * public functions + */ + soup_plugin_t public; +}; + +METHOD(plugin_t, destroy, void, + private_soup_plugin_t *this) +{ + lib->fetcher->remove_fetcher(lib->fetcher, + (fetcher_constructor_t)soup_fetcher_create); + free(this); +} + +/* + * see header file + */ +plugin_t *soup_plugin_create() +{ + private_soup_plugin_t *this; + + g_type_init(); + if (!g_thread_get_initialized()) + { + g_thread_init(NULL); + } + + INIT(this, + .public = { + .plugin = { + .destroy = _destroy, + }, + }, + ); + + lib->fetcher->add_fetcher(lib->fetcher, + (fetcher_constructor_t)soup_fetcher_create, "http://"); + lib->fetcher->add_fetcher(lib->fetcher, + (fetcher_constructor_t)soup_fetcher_create, "https://"); + + return &this->public.plugin; +} diff --git a/src/libstrongswan/plugins/soup/soup_plugin.h b/src/libstrongswan/plugins/soup/soup_plugin.h new file mode 100644 index 000000000..2dfa1d243 --- /dev/null +++ b/src/libstrongswan/plugins/soup/soup_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program 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 General Public License + * for more details. + */ + +/** + * @defgroup soup_p soup + * @ingroup plugins + * + * @defgroup soup_plugin soup_plugin + * @{ @ingroup soup_p + */ + +#ifndef SOUP_PLUGIN_H_ +#define SOUP_PLUGIN_H_ + +#include + +typedef struct soup_plugin_t soup_plugin_t; + +/** + * Plugin implementing fetcher interface for HTTP using libsoup. + */ +struct soup_plugin_t { + + /** + * Implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** SOUP_PLUGIN_H_ @}*/