diff -Nur --exclude-from /home/andi/freeciv-1.12.4/diff_ignore dillo-bak/configure.in dillo/configure.in --- dillo-bak/configure.in Mon Apr 14 19:03:59 2003 +++ dillo/configure.in Wed Apr 16 12:09:45 2003 @@ -90,6 +90,20 @@ AC_MSG_WARN(*** No libpng found. Disabling png images.***) fi +dnl Test for libssl + +if test "x$enable_ssl" = "xyes" ; then + AC_DEFINE(DILLO_SSL, 1, [Enable SSL Processing]) + if test -n "$LIBSSL_LIBDIR"; then + LIBS="$LIBS -L$LIBSSL_LIBDIR" + fi + AC_CHECK_LIB(ssl, SSL_connect) + AC_CHECK_LIB(crypto, BIO_ctrl) + if test -n "$LIBSSL_INCDIR"; then + CPPFLAGS="$CPPFLAGS -I$LIBSSL_INCDIR" + fi + AC_CHECK_HEADERS(openssl/ssl.h openssl/err.h) +fi dnl ---------------------- dnl Test for POSIX threads diff -Nur --exclude-from /home/andi/freeciv-1.12.4/diff_ignore dillo-bak/src/IO/DBIO.c dillo/src/IO/DBIO.c --- dillo-bak/src/IO/DBIO.c Thu Jan 1 01:00:00 1970 +++ dillo/src/IO/DBIO.c Wed Apr 16 12:09:45 2003 @@ -0,0 +1,285 @@ +/* + * File: DBIO.c + * + * Copyright (C) 2000, 2001 Jorge Arellano Cid + * Copyright (C) 2002 Jonathan P Springer + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, Jorge Arellano Cid and Jonathan + * Springer give permission to link the code of this program with the OpenSSL + * library (or modified versions of OpenSSL that use the same license as + * OpenSSL), and distribute linked combinations including the two. You must + * obey the GNU General Public License in all respects for all of the code + * used other than OpenSSL. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. + * If you do not wish to do so, delete this exception from your version. + * + */ + +/* + * Dillo's signal driven BIO engine + */ + +#include + +#ifdef DILLO_SSL + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../chain.h" +#include "DBIO.h" + +#include +#include + +//#define DEBUG_LEVEL 3 +#include "../debug.h" + + +/* + * Symbolic defines for shutdown() function + * (Not defined in the same header file, for all distros --Jcid) + */ +#define IO_StopRd 0 +#define IO_StopWr 1 +#define IO_StopRdWr 2 + + +/* + * IO-module data + */ + + +/* + * Return a newly created, and initialized, 'io' struct + */ +IOData_t *a_DBIO_new(BIO *bioin) +{ + IOData_t *io = g_new0(IOData_t, 1); + io->GioCh = NULL; + io->FD = -1; + io->Flags = 0; + io->bio = bioin; + return io; +} + +/* + * Free an 'io' struct + */ +void DBIO_free(IOData_t *io) +{ + if (io->Flags & IOFlag_FreeIOBuf) g_free(io->Buf); + g_free(io); +} + +/* + * Close an open BIO, and remove io controls. + * (This function can be used for Close and Abort operations) + */ +void DBIO_close_fd(IOData_t *io, gint CloseCode) +{ + if (io->bio) BIO_free_all(io->bio); + + IO_del(io); +} + +/* + * Abort an open FD. + * This function is called to abort a BIO connection due to an IO error + * or just because the connection is not required anymore. + */ +gboolean DBIO_abort(IOData_t *io) +{ + /* Close and finish this FD's activity */ + DBIO_close_fd(io, IO_StopRdWr); + + return FALSE; +} + +/* + * Read data from a BIO into a specific buffer + */ +gboolean DBIO_Callback_Read(gpointer data) +{ + ssize_t St; + gboolean ret; + IOData_t *io = (IOData_t *) data; + + DEBUG_MSG(3, " IO_read2\n"); + + /* Sometimes glib delivers events on already aborted FDs --Jcid */ + if ( IO_get(io->Key) == NULL ) return FALSE; + + St = BIO_read(io->bio, io->Buf, io->BufSize); + + if ( St < 0 ) { + if (BIO_should_retry(io->bio)) { + ret = TRUE; + } else { + io->Status = ERR_get_error(); + ret = FALSE; + } + } else if ( St == 0 ) { + if (BIO_should_retry(io->bio)) { + ret = TRUE; + } else { + a_DBIO_ccc(OpEnd, 2,0, io->Info, io, NULL); + ret = FALSE; + } + } else { + io->Status = St; /* Status is used for length */ + a_DBIO_ccc(OpSend, 2,0, io->Info, io, NULL); + ret = TRUE; + } + + return ret; +} + +/* + * Write data, from a specific buffer, into a file descriptor + * (** Write operations MUST NOT free the buffer because the buffer + * start is modified.) + * todo: Implement IOWrites, remove the constraint stated above. + */ +gboolean DBIO_Callback_Write(gpointer data) +{ + ssize_t St; + gboolean ret = FALSE; + IOData_t *io = (IOData_t *) data; + + DEBUG_MSG(3, " IO_write\n"); + + /* Sometimes glib delivers events on already aborted FDs --Jcid */ + if ( IO_get(io->Key) == NULL ) return FALSE; + + St = BIO_write(io->bio, io->Buf, io->BufSize); + io->Status = St; + + DEBUG_MSG(3, " IO_write: %s [errno %d] [St %d]\n", + g_strerror(errno), errno, St); + + if ( St <= 0 ) { + if (BIO_should_retry(io->bio)) { + ret = TRUE; + } else { + io->Status = ERR_get_error(); + ret = FALSE; + } + } else if ( St < io->BufSize ){ + // Not all data written + io->BufSize -= St; + io->Buf = ((gchar *)io->Buf) + St; + ret = TRUE; + } else { + // All data in buffer written + if ( io->Op == IOWrite ) { + /* Single write */ + a_DBIO_ccc(OpEnd, 1,0, io->Info, io, NULL); + ret = FALSE; + } else if ( io->Op == IOWrites ) { + /* todo: Writing in small chunks (not implemented) */ + } + } + + return ret; +} + +/* + * Receive an IO request (IORead | IOWrite | IOWrites), + */ +void DBIO_submit(IOData_t *r_io) +{ + if ( r_io->Op == IORead ) { + g_idle_add(DBIO_Callback_Read, (gpointer) r_io); + } else if (r_io->Op == IOWrite || r_io->Op == IOWrites ) { + g_idle_add(DBIO_Callback_Write, (gpointer) r_io); + } + + /* Add a reference pointer to this request */ + IO_ins(r_io); +} + +/* + * CCC function for the IO module + * ( Data = IOData_t* ; ExtraData = NULL ) + */ +void a_DBIO_ccc(int Op, int Branch,int Dir, ChainLink *Info, void *Data, void *ExtraData) +{ + IOData_t *io = Data; + + if ( Branch == 1 ) { + /* Send query */ + switch (Op) { + case OpStart: + io->Info = Info; + Info->LocalKey = io; + DBIO_submit(io); + break; + case OpEnd: + a_Chain_fcb(OpEnd, Info, io, NULL); + DBIO_free(io); + break; + case OpAbort: + a_Chain_fcb(OpAbort, Info, NULL, NULL); + DBIO_free(io); + break; + } + + } else if ( Branch == 2 ) { + /* Receive answer */ + switch (Op) { + case OpStart: + io->Info = Info; + Info->LocalKey = io; + a_Chain_link_new(Info, a_DBIO_ccc, FWD, a_Cache_ccc,2,2); + a_Chain_fcb(OpStart, Info, io, io->ExtData); + DBIO_submit(io); + break; + case OpSend: + a_Chain_fcb(OpSend, Info, io, NULL); + break; + case OpEnd: + a_Chain_fcb(OpEnd, Info, io, NULL); + DBIO_free(io); + break; + case OpAbort: + a_Chain_fcb(OpAbort, Info, io, NULL); + DBIO_free(io); + break; + } + + } else if ( Branch == -1 ) { + /* Backwards call */ + switch (Op) { + case OpAbort: + DEBUG_MSG(3, "IO : OpAbort [-1]\n"); + io = Info->LocalKey; + DBIO_abort(io); + DBIO_free(io); + g_free(Info); + break; + } + } +} + +#endif diff -Nur --exclude-from /home/andi/freeciv-1.12.4/diff_ignore dillo-bak/src/IO/DBIO.h dillo/src/IO/DBIO.h --- dillo-bak/src/IO/DBIO.h Thu Jan 1 01:00:00 1970 +++ dillo/src/IO/DBIO.h Wed Apr 16 12:09:45 2003 @@ -0,0 +1,21 @@ +#ifndef __DBIO_h +#define __DBIO_h + +#include + +#ifdef DILLO_SSL + +#include + +#include "IO.h" + +/* + * Exported functions + */ +IOData_t* a_DBIO_new(BIO *bio); +void a_DBIO_ccc(int Op, int Br,int Dir, ChainLink *Info, void *Data, void *ExtraData); + +#endif /* DILLO_SSL */ + +#endif /* __DBIO_h */ + diff -Nur --exclude-from /home/andi/freeciv-1.12.4/diff_ignore dillo-bak/src/IO/IO.c dillo/src/IO/IO.c --- dillo-bak/src/IO/IO.c Tue Apr 15 21:24:41 2003 +++ dillo/src/IO/IO.c Wed Apr 16 12:09:45 2003 @@ -62,6 +62,9 @@ io->GioCh = g_io_channel_unix_new(fd); io->Flags = 0; io->Key = 0; +#ifdef DILLO_SSL + io->bio = NULL; +#endif return io; } @@ -317,23 +320,23 @@ /* * Register an IO in ValidIOs */ -static void IO_ins(IOData_t *io) +void IO_ins(IOData_t *io) { - io->Key = a_Klist_insert(&ValidIOs, (gpointer)io); + io->Key = a_Klist_insert(&ValidIOs, (gpointer)io); } /* * Remove an IO from ValidIOs */ -static void IO_del(IOData_t *io) +void IO_del(IOData_t *io) { - a_Klist_remove(ValidIOs, io->Key); + a_Klist_remove(ValidIOs, io->Key); } /* * Return a io by its Key (NULL if not found) */ -static IOData_t *IO_get(gint Key) +IOData_t *IO_get(gint Key) { return a_Klist_get_data(ValidIOs, Key); } @@ -529,7 +532,7 @@ * Receive an IO request (IORead | IOWrite | IOWrites), * Set the GIOChannel and let it flow! */ -static void IO_submit(IOData_t *r_io) +void IO_submit(IOData_t *r_io) { /* Insert this IO in ValidIOs */ IO_ins(r_io); diff -Nur --exclude-from /home/andi/freeciv-1.12.4/diff_ignore dillo-bak/src/IO/IO.h dillo/src/IO/IO.h --- dillo-bak/src/IO/IO.h Tue Nov 5 16:30:43 2002 +++ dillo/src/IO/IO.h Wed Apr 16 12:09:45 2003 @@ -1,9 +1,15 @@ #ifndef __IO_H__ #define __IO_H__ +#include + #include #include +#ifdef DILLO_SSL +#include +#endif + #include "../chain.h" /* @@ -30,6 +36,7 @@ #define IOBufLen_File 4096 #define IOBufLen_Proto 4096 #define IOBufLen_About 4096 +#define IOBufLen_Matrix 4096 typedef struct { @@ -45,7 +52,11 @@ void *ExtData; /* External data reference (not used by IO.c) */ void *Info; /* CCC Info structure for this IO */ - GIOChannel *GioCh; /* IO channel */ +#ifdef DILLO_SSL + BIO *bio; +#endif + GIOChannel *GioCh; /* IO channel */ + } IOData_t; diff -Nur --exclude-from /home/andi/freeciv-1.12.4/diff_ignore dillo-bak/src/IO/Makefile.am dillo/src/IO/Makefile.am --- dillo-bak/src/IO/Makefile.am Tue Nov 5 16:30:43 2002 +++ dillo/src/IO/Makefile.am Wed Apr 16 12:10:53 2003 @@ -1,6 +1,9 @@ noinst_LIBRARIES = libDio.a libDio_a_SOURCES = \ + https.c \ + DBIO.h \ + DBIO.c \ mime.c \ mime.h \ about.c \ diff -Nur --exclude-from /home/andi/freeciv-1.12.4/diff_ignore dillo-bak/src/IO/Url.c dillo/src/IO/Url.c --- dillo-bak/src/IO/Url.c Tue Nov 5 16:30:43 2002 +++ dillo/src/IO/Url.c Wed Apr 16 12:09:45 2003 @@ -16,6 +16,7 @@ * This module selects the apropriate CCC-function for a given URL. */ +#include #include #include @@ -30,8 +31,8 @@ } UrlMethod_t; typedef struct { - const char *Name; /* Method name */ - ChainFunction_t cccFunction; /* Pointer to a CCC function */ + const char *Name; /* Method name */ + ChainFunction_t cccFunction; /* Pointer to a CCC function */ } UrlMethod2_t; @@ -78,6 +79,9 @@ ChainFunction_t a_Url_get_ccc_funct(const DilloUrl *Url) { static UrlMethod2_t cccList[] = { {"http" , a_Http_ccc}, +#ifdef DILLO_SSL + {"https", a_Https_ccc}, +#endif {"file" , a_File_ccc}, {"about", a_About_ccc}, {"dpi" , a_Dpi_ccc} }; diff -Nur --exclude-from /home/andi/freeciv-1.12.4/diff_ignore dillo-bak/src/IO/Url.h dillo/src/IO/Url.h --- dillo-bak/src/IO/Url.h Tue Nov 5 16:30:44 2002 +++ dillo/src/IO/Url.h Wed Apr 16 12:09:45 2003 @@ -45,6 +45,10 @@ void *Data1, void *Data2); void a_Dpi_ccc (int Op, int Branch, int Dir, ChainLink *Info, void *Data1, void *Data2); +#ifdef DILLO_SSL +void a_Https_ccc(int Op, int Br,int Dir, ChainLink *Info, void *Data, void *ExtraData); +void a_Https_freeall(void); +#endif #ifdef __cplusplus diff -Nur --exclude-from /home/andi/freeciv-1.12.4/diff_ignore dillo-bak/src/IO/http.c dillo/src/IO/http.c --- dillo-bak/src/IO/http.c Tue Apr 15 21:24:41 2003 +++ dillo/src/IO/http.c Wed Apr 16 12:09:45 2003 @@ -122,7 +122,7 @@ /* * Make the http query string */ -static char *Http_query(const DilloUrl *url, gboolean use_proxy) +char *Http_query(const DilloUrl *url, gboolean use_proxy) { gchar *str, *ptr, *cookies; GString *s_port = g_string_new(""), diff -Nur --exclude-from /home/andi/freeciv-1.12.4/diff_ignore dillo-bak/src/IO/https.c dillo/src/IO/https.c --- dillo-bak/src/IO/https.c Thu Jan 1 01:00:00 1970 +++ dillo/src/IO/https.c Wed Apr 16 12:09:45 2003 @@ -0,0 +1,442 @@ +/* + * File: https.c + * + * Copyright (C) 2000, 2001 Jorge Arellano Cid + * Copyright (C) 2002 Jonathan P Springer + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, Jorge Arellano Cid and Jonathan + * Springer give permission to link the code of this program with the OpenSSL + * library (or modified versions of OpenSSL that use the same license as + * OpenSSL), and distribute linked combinations including the two. You must + * obey the GNU General Public License in all respects for all of the code + * used other than OpenSSL. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. + * If you do not wish to do so, delete this exception from your version. + * + */ + +/* + * This program exploits code originally published under the OpenSSL demos/bio + * directory. I am uncertain as to the copyright status of this code, as no + * notice was included. If you own the copyright on this code and object to + * its use in this GPL program, please contact me. -- JPS + */ + +/* + * HTTPS connect functions + */ + +#include + +#ifdef DILLO_SSL + +#include +#include /* for errno */ +#include /* for strstr */ +#include +#include +#include +#include +#include /* for lots of socket stuff */ +#include /* for ntohl and stuff */ +#include +#include + +#include + +#include "Url.h" +#include "DBIO.h" +#include "../klist.h" +#include "../dns.h" +#include "../cache.h" +#include "../web.h" +#include "../interface.h" +extern char *a_Http_query(const DilloUrl *url, gboolean use_proxy); + + +/* Used to send a message to the bw's status bar */ +#define BW_MSG(web, root, fmt...) \ + (a_Web_valid(web) && (!(root) || (web)->flags & WEB_RootUrl)) ? \ + a_Interface_msg((web)->bw, fmt) : (root) + +#define DEBUG_LEVEL 5 +#include "../debug.h" + + +/* 'Url' and 'web' are just references (no need to deallocate them here). */ +typedef struct { + BIO* bio; + SSL* ssl; + const DilloUrl *Url; /* reference to original URL */ + DilloWeb *web; /* reference to client's web structure */ + guint32 ip_addr; /* Holds the DNS answer */ + gint Err; /* Holds the errno of the connect() call */ + ChainLink *Info; /* Used for CCC asynchronous operations */ +} SSLData_t; + + +/* + * Local data + */ +static Klist_t *ValidSSLs = NULL; /* Active sockets list. It holds pointers to + * SSLData_t structures. */ + +static gboolean Https_init = FALSE; + +static SSL_CTX* ssl_ctx; + +/* + * Forward declarations + */ +static void Https_send_query(ChainLink *Info, SSLData_t *S); +static void Https_expect_answer(SSLData_t *S); + +/* + * If it hasn't been initialized already, initialize + * the SSL-specific stuff. + */ +void Https_SSL_init(void) +{ + if (!Https_init) { + SSL_load_error_strings(); + OpenSSL_add_ssl_algorithms(); + ssl_ctx = SSL_CTX_new(SSLv23_client_method()); + Https_init = TRUE; + } +} + +/* + * Create and init a new SSLData_t struct, insert into ValidSSLs, + * and return a primary key for it. + */ +gint Https_SSL_new(void) +{ + SSLData_t *S = g_new0(SSLData_t, 1); + return a_Klist_insert(&ValidSSLs, (gpointer)S); +} + +/* + * Free SSLData_t struct + */ +void Https_SSL_free(gint SKey) +{ + SSLData_t *S; + + if ((S = a_Klist_get_data(ValidSSLs, SKey))) { + a_Klist_remove(ValidSSLs, SKey); + if (S->bio) BIO_free_all(S->bio); + g_free(S); + } +} + +/* + * This function is called after the socket has been successfuly connected, + * or upon an error condition on the connecting process. + * Task: use the socket to send the HTTP-query and expect its answer + */ +static gboolean Https_Callback_Use(gpointer data) +{ + ChainLink *Info; + SSLData_t *S; + gint SKey = (gint) data; + + DEBUG_MSG(3, "Https_Callback_Use\n"); + + /* This check is required because glib may asynchronously + * call this function with data that's no longer used --Jcid */ + if ( !(S = a_Klist_get_data(ValidSSLs, SKey)) ) return FALSE; + + Info = S->Info; + if ( S->Err ) { + DEBUG_MSG(3, "--Error detected\n"); + DEBUG_MSG(3, "%d:%s:%s:%s\n", S->Err, + ERR_lib_error_string(S->Err), + ERR_func_error_string(S->Err), + ERR_reason_error_string(S->Err)); + BW_MSG(S->web, 0, "ERROR: unable to connect to remote host"); + a_Chain_fcb(OpAbort, Info, NULL, NULL); + Https_SSL_free(SKey); + } else { + DEBUG_MSG(3, "--Connection established\n"); + Https_send_query(Info, S); + Https_expect_answer(S); + } + return FALSE; +} + +gboolean Https_Callback_Connect(gpointer data) { + + gint SKey = (gint) data; + SSLData_t *S; + + /* This check is required because glib may asynchronously + * call this function with data that's no longer used --Jcid */ + if ( !(S = a_Klist_get_data(ValidSSLs, SKey)) ) return FALSE; + + S->Err = 0; + if (BIO_do_connect(S->bio) != 1) { + if (BIO_should_retry(S->bio)) return TRUE; + S->Err = ERR_get_error(); + DEBUG_MSG(3, "%d:%s:%s:%s\n", S->Err, + ERR_lib_error_string(S->Err), + ERR_func_error_string(S->Err), + ERR_reason_error_string(S->Err)); + BW_MSG(S->web, 0, "ERROR: unable to connect to remote host"); + return FALSE; + } + g_idle_add(Https_Callback_Use, data); + return FALSE; +} + +/* + * This function gets called after the DNS succeeds solving a hostname. + * Task: Finish socket setup and start connecting the socket. + * Return value: 0 on success; -1 on error. +*/ +static int Https_connect_SSL(ChainLink *Info) +{ + SSLData_t *S = a_Klist_get_data(ValidSSLs, (gint)Info->LocalKey); + + BIO *ssl_bio; + union { + guint32 i; + guchar c[4]; + } U; + gchar *tmp_str; + int port = DILLO_URL_HTTPS_PORT; + + /* TODO - Better error checking */ + + /* Initialize some SSL stuff if this is our first connection */ + Https_SSL_init(); + + /* Create an SSL structure */ + S->ssl = SSL_new(ssl_ctx); + SSL_set_connect_state(S->ssl); + + /* Create a BIO structure */ + ssl_bio = BIO_new(BIO_f_ssl()); + BIO_set_ssl(ssl_bio, S->ssl, BIO_CLOSE); + + /* Create and configure the connection BIO */ + S->bio = BIO_new(BIO_s_connect()); + +#if 0 + U.i = htonl(S->ip_addr); +#else + U.i = S->ip_addr; /* should already be in the right order */ +#endif + tmp_str = g_strdup_printf("%u.%u.%u.%u", U.c[0], U.c[1], U.c[2], U.c[3]); + BIO_set_conn_hostname(S->bio, tmp_str); + g_free(tmp_str); + BIO_set_conn_int_port(S->bio, &port); + + BIO_set_nbio(S->bio, 1); /* non-blocking ON */ + + /* Chain the socket & SSL BIOs together */ + S->bio = BIO_push(ssl_bio, S->bio); /* chain this with the SSL BIO */ + + /* And set up a looping idle event to connect it... */ + g_idle_add(Https_Callback_Connect, (gpointer) Info->LocalKey); + + return 0; /* Success */ +} + +/* + * Create and submit the HTTP query to the IO engine + */ +static void Https_send_query(ChainLink *Info, SSLData_t *S) +{ + IOData_t *io; + gchar *query; + void *link; + + /* Create the query */ + query = Http_query(S->Url, FALSE); + + /* send query */ + BW_MSG(S->web, 1, "Sending query to %s...", URL_HOST(S->Url)); + io = a_DBIO_new(S->bio); + io->Op = IOWrite; + a_IO_set_buf(io, query, strlen(query)); + io->Flags |= IOFlag_FreeIOBuf; + io->ExtData = NULL; + link = a_Chain_link_new(Info, a_Https_ccc, BCK, a_DBIO_ccc,2,2); + a_DBIO_ccc(OpStart, 1,0, link, io, NULL); +} + +/* + * Expect the HTTP query's answer + */ +static void Https_expect_answer(SSLData_t *S) +{ + IOData_t *io2; + + /* receive answer */ + io2 = a_DBIO_new(S->bio); + io2->Op = IORead; + a_IO_set_buf(io2,g_malloc(IOBufLen_Http),IOBufLen_Http); + io2->Flags |= IOFlag_FreeIOBuf; + io2->ExtData = (void *) S->Url; + a_DBIO_ccc(OpStart, 2, 0,a_Chain_new(), io2, NULL); +} + +/* + * Asynchronously create a new http connection for 'Url' + * We'll set some socket parameters; the rest will be set later + * when the IP is known. + * ( Data = Requested Url; ExtraData = Web structure ) + * Return value: 0 on success, -1 otherwise + */ +gint Https_get(ChainLink *Info, void *Data, void *ExtraData) +{ + void *link; + const DilloUrl *Url = Data; + SSLData_t *S = a_Klist_get_data(ValidSSLs, (gint)Info->LocalKey); + gchar hostname[256], *Host = hostname; + + /* Reference Info data */ + S->Info = Info; + /* Reference Web data */ + S->web = ExtraData; + + Host = (gchar *)URL_HOST(Url); + + /* Set more socket parameters */ + S->Url = Url; + + /* Let the user know what we'll do */ + BW_MSG(S->web, 1, "DNS solving %s", URL_HOST(S->Url)); + + /* Let the DNS engine solve the hostname, and when done, + * we'll try to connect the socket */ + link = a_Chain_link_new(Info, a_Https_ccc, BCK, a_Dns_ccc, 1, 1); + a_Chain_bcb(OpStart,Info, Host,NULL); + + return 0; +} + +/* + * CCC function for the HTTP module + */ +void +a_Https_ccc(int Op, int Branch, int Dir, ChainLink *Info, void *Data, void *ExtraData) +{ + gint SKey = (gint)Info->LocalKey; + SSLData_t *S = a_Klist_get_data(ValidSSLs, SKey); + + if ( Branch == 1 ) { + /* DNS query branch */ + switch (Op) { + case OpStart: + Info->LocalKey = (void *) SKey = Https_SSL_new(); + if (Https_get(Info, Data, ExtraData) < 0) { + DEBUG_MSG(2, " HTTP: new abort handler! #2\n"); + S = a_Klist_get_data(ValidSSLs, SKey); + BW_MSG(S->web, 1, "ERROR: %s", g_strerror(S->Err)); + Https_SSL_free(SKey); + a_Chain_fcb(OpAbort, Info, NULL, NULL); + } + break; + case OpSend: + /* Successful DNS answer; save the IP */ + if (S) + { + DilloHost *dh=(DilloHost *)(((GSList *)Data)->data); + S->ip_addr = *(int *)dh->data; + } + break; + case OpEnd: + if (S) { + /* Unlink DNS_Info */ + a_Chain_del_link(Info, BCK); + /* start connecting the socket */ + if (Https_connect_SSL(Info) < 0) { + DEBUG_MSG(2, " HTTP: new abort handler! #1\n"); + BW_MSG(S->web, 1, "ERROR: %s", g_strerror(S->Err)); + Https_SSL_free(SKey); + a_Chain_fcb(OpAbort, Info, NULL, NULL); + } + } + break; + case OpAbort: + /* DNS wasn't able to resolve the hostname */ + if (S) { + /* Unlink DNS_Info */ + a_Chain_del_link(Info, BCK); + BW_MSG(S->web, 0, "ERROR: Dns can't solve %s", URL_HOST(S->Url)); + BIO_free_all(S->bio); + Https_SSL_free(SKey); + /* send abort message to higher-level functions */ + a_Chain_fcb(OpAbort, Info, NULL, NULL); + } + break; + + } + + } else if ( Branch == 2 ) { + /* IO send-query branch */ + switch (Op) { + case OpStart: + /* LocalKey was set by branch 1 */ + break; + case OpEnd: + /* finished sending the HTTP query */ + if (S) { + BW_MSG(S->web, 1, "Query sent, waiting for reply..."); + a_Chain_del_link(Info, BCK); + a_Chain_fcb(OpEnd, Info, NULL, NULL); + } + break; + case OpAbort: + /* something bad happened... */ + /* unlink IO_Info */ + if (S) { + a_Chain_del_link(Info, BCK); + a_Chain_fcb(OpAbort, Info, NULL, NULL); + Https_SSL_free(SKey); + } + break; + } + + } else if ( Branch == -1 ) { + /* Backwards abort */ + switch (Op) { + case OpAbort: + /* something bad happened... */ + DEBUG_MSG(2, "Http: OpAbort [-1]\n"); + Https_SSL_free(SKey); + a_Chain_bcb(OpAbort, Info, NULL, NULL); + g_free(Info); + break; + } + } +} + + + +/* + * Deallocate memory used by http module + * (Call this one at exit time) + */ +void a_Https_freeall(void) +{ + if (ssl_ctx) SSL_CTX_free(ssl_ctx); + a_Klist_free(&ValidSSLs); +} + +#endif Binary files dillo-bak/src/dillo and dillo/src/dillo differ diff -Nur --exclude-from /home/andi/freeciv-1.12.4/diff_ignore dillo-bak/src/dillo.c dillo/src/dillo.c --- dillo-bak/src/dillo.c Tue Apr 15 21:24:38 2003 +++ dillo/src/dillo.c Wed Apr 16 15:28:32 2003 @@ -19,6 +19,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include + #include #include @@ -297,6 +299,9 @@ a_Cache_freeall(); a_Dicache_freeall(); a_Http_freeall(); +#ifdef DILLO_SSL + a_Https_freeall(); +#endif a_Dns_freeall(); a_Prefs_freeall(); a_Dw_freeall();