diff --git a/configure.ac b/configure.ac index 01ea237..1a08544 100644 --- a/configure.ac +++ b/configure.ac @@ -68,7 +68,7 @@ AC_ARG_WITH([libpsl], dnl SSL: Configure SSL backend to use AC_ARG_WITH([ssl], - [AS_HELP_STRING([--with-ssl={gnutls,openssl}], [specify SSL backend. GNU TLS is the default.])]) + [AS_HELP_STRING([--with-ssl={tlssep,gnutls,openssl}], [specify SSL backend. GNU TLS is the default.])]) dnl Zlib: Configure use iof zlib for compression @@ -404,8 +404,20 @@ AS_IF([test x"$with_ssl" = xopenssl], [ fi ]) fi +], [test x"$with_ssl" = xtlssep], [ + PKG_CHECK_MODULES([TLSSEP], libtlssep-0.1, [ + ssl_found=yes + AC_MSG_NOTICE([compiling in support for SSL via libtlssep]) + AC_LIBOBJ([tlssep]) + LIBS="$TLSSEP_LIBS $LIBS" + CFLAGS="$TLSSEP_CFLAGS $CFLAGS" + AC_DEFINE([HAVE_LIBTLSSEP], [1], [Define if libtlssep is available.]) + ssl_found=yes + ], [ + AC_MSG_ERROR([--with-ssl=tlssep was given, but SSL is not available.]) + ]) ], [ - # --with-ssl is not openssl: check if it's no + # --with-ssl is not openssl or tlssep: check if it's no AS_IF([test x"$with_ssl" != xno], [ dnl default is -lgnutls with_ssl=gnutls diff --git a/src/build_info.c.in b/src/build_info.c.in index ce1fe25..14ce517 100644 --- a/src/build_info.c.in +++ b/src/build_info.c.in @@ -12,3 +12,4 @@ psl defined HAVE_LIBPSL ssl choice: openssl defined HAVE_LIBSSL || defined HAVE_LIBSSL32 gnutls defined HAVE_LIBGNUTLS + grayline defined HAVE_LIBTLSSEP diff --git a/src/tlssep.c b/src/tlssep.c new file mode 100644 index 0000000..eb47481 --- /dev/null +++ b/src/tlssep.c @@ -0,0 +1,231 @@ +/* SSL support via libtlssep. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + 2009, 2010, 2011, 2012 Free Software Foundation, Inc. + Originally contributed by Christian Fraenkel. + +This file is part of GNU Wget. + +GNU Wget 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 3 of the License, or +(at your option) any later version. + +GNU Wget 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. + +You should have received a copy of the GNU General Public License +along with Wget. If not, see . + +Additional permission under GNU GPL version 3 section 7 + +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#include "wget.h" + +#include +#include +#include + +#include "utils.h" +#include "connect.h" +#include "url.h" +#include "ssl.h" + +typedef struct tlssep_desc_status_t { + tlssep_desc_t *desc; + tlssep_status_t status; +} tlssep_desc_status_t; + +/* Application-wide SSL context. This is common to all SSL + * connections. */ +static tlssep_context_t *context; + +static int +_tlssep_read(int fd, char *buf, int bufsize, void *arg) +{ + int readSize; + tlssep_desc_status_t *ds = arg; + + ds->status = tlssep_read(ds->desc, buf, bufsize, &readSize); + if (TLSSEP_STATUS_OK != ds->status) + { + readSize = -1; + goto done; + } + +done: + return readSize; +} + +static int +_tlssep_write(int fd _GL_UNUSED, char *buf, int bufsize, void *arg) +{ + int writeSize; + tlssep_desc_status_t *ds = arg; + + ds->status = tlssep_write(ds->desc, buf, bufsize, &writeSize); + if (TLSSEP_STATUS_OK != ds->status) + { + writeSize = -1; + goto done; + } + +done: + return writeSize; +} + +static int +_tlssep_poll(int fd, double timeout, int wait_for, void *arg) +{ + int retval = 0; + tlssep_desc_status_t *ds = arg; + bool has_pending = false; + + retval = tlssep_poll (ds->desc, timeout) == TLSSEP_STATUS_OK ? 1 : -1; + +done: + return retval; +} + +static int +_tlssep_peek(int fd, char *buf, int bufsize, void *arg) +{ + int readSize; + tlssep_desc_status_t *ds = arg; + + if (! _tlssep_poll(fd, 0.0, WAIT_FOR_READ, arg)) + { + readSize = 0; + goto done; + } + ds->status = tlssep_peek(ds->desc, buf, bufsize, &readSize); + if (TLSSEP_STATUS_OK != ds->status) + { + readSize = -1; + goto done; + } + +done: + return readSize; +} + +static const char * +_tlssep_errstr(int fd _GL_UNUSED, void *arg) +{ + tlssep_desc_status_t *ds = arg; + return tlssep_strerror(ds->status); +} + +static void +_tlssep_close(int fd, void *arg) +{ + tlssep_desc_status_t *ds = arg; + tlssep_close(ds->desc); + tlssep_terminate(context); + free(ds->desc); + free(ds); +} + +static struct transport_implementation tlssep_transport = { + _tlssep_read, _tlssep_write, _tlssep_poll, + _tlssep_peek, _tlssep_errstr, _tlssep_close +}; + +bool +ssl_init (void) +{ + bool retval = true; + + if (NULL != context) + { + goto done; + } + + tlssep_desc_status_t *ds = calloc(sizeof(tlssep_desc_status_t), 1); + if (NULL == ds) + { + retval = false; + goto done; + } + + context = calloc(sizeof(tlssep_context_t), 1); + if (NULL == context) + { + retval = false; + goto done; + } + + ds->status = tlssep_init(context); + if (TLSSEP_STATUS_OK != ds->status) + { + retval = false; + goto done; + } + +done: + if (false == retval) + { + tlssep_terminate(context); + } + + return retval; +} + +bool +ssl_connect_wget (int fd, const char *hostname) +{ + bool retval = true; + + tlssep_desc_status_t *ds = calloc(sizeof(tlssep_desc_status_t), 1); + if (NULL == ds) + { + retval = false; + goto done; + } + + ds->desc = calloc(sizeof(tlssep_desc_t), 1); + if (NULL == ds->desc) + { + retval = false; + goto done; + } + + ds->status = tlssep_connect(context, fd, hostname, NULL, ds->desc); + if (TLSSEP_STATUS_OK != ds->status) + { + retval = false; + goto done; + } + + fd_register_transport (fd, &tlssep_transport, ds); + +done: + if (TLSSEP_STATUS_OK != ds->status) { + if (NULL != ds->desc) + { + free(ds->desc); + } + if (NULL != ds) + { + free(ds); + } + } + + return retval; +} + +bool +ssl_check_certificate (int fd, const char *host) +{ + /* Covered by tlssep_connect. */ + return true; +} diff --git a/src/wget.h b/src/wget.h index cdc4c4b..cc570da 100644 --- a/src/wget.h +++ b/src/wget.h @@ -52,7 +52,7 @@ as that of the covered work. */ #endif /* Is OpenSSL or GNUTLS available? */ -#if defined HAVE_LIBSSL || defined HAVE_LIBSSL32 || defined HAVE_LIBGNUTLS +#if defined HAVE_LIBSSL || defined HAVE_LIBSSL32 || defined HAVE_LIBTLSSEP || defined HAVE_LIBGNUTLS # define HAVE_SSL #endif