1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

[svn] Committed C. Frankel's SSL patch.

This commit is contained in:
hniksic 2000-12-05 15:09:41 -08:00
parent dc78acde56
commit 7828e81c79
19 changed files with 562 additions and 182 deletions

View File

@ -17,3 +17,5 @@ authentication.
Dan Harkless. Added --backup-converted, --follow-tags, --html-extension, Dan Harkless. Added --backup-converted, --follow-tags, --html-extension,
--ignore-tags, and --page-requisites; improved documentation; etc. --ignore-tags, and --page-requisites; improved documentation; etc.
Christian Fraenkel. Implemented SSL support.

View File

@ -1,3 +1,14 @@
2000-12-05 Hrvoje Niksic <hniksic@arsdigita.com>
* configure.in: Don't unconditionally define HAVE_SSL, even when
--with-ssl is given.
2000-12-03 Christian Fraenkel <christian.fraenkel@gmx.net>
* INSTALL: Added the --with-ssl switch
* configure.in: ditto
* TODO: Removed the corresponding entry
2000-11-23 Hrvoje Niksic <hniksic@arsdigita.com> 2000-11-23 Hrvoje Niksic <hniksic@arsdigita.com>
* configure.in: Build ALL_LINGUAS dynamically. * configure.in: Build ALL_LINGUAS dynamically.

View File

@ -29,6 +29,7 @@ scripts take. The most important ones are:
--enable and --with options recognized (mostly Wget-specific): --enable and --with options recognized (mostly Wget-specific):
--with-socks use the socks library --with-socks use the socks library
--with-ssl use the openssl library
--disable-opie disable support for opie or s/key FTP login --disable-opie disable support for opie or s/key FTP login
--disable-digest disable support for HTTP digest authorization --disable-digest disable support for HTTP digest authorization
--disable-debug disable support for debugging output --disable-debug disable support for debugging output

2
TODO
View File

@ -110,5 +110,3 @@ changes.
* Implement HTTP cookies. * Implement HTTP cookies.
* Implement more HTTP/1.1 bells and whistles (ETag, Content-MD5 etc.) * Implement more HTTP/1.1 bells and whistles (ETag, Content-MD5 etc.)
* Support SSL encryption through SSLeay or OpenSSL.

384
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -45,6 +45,9 @@ AC_ARG_WITH(socks,
[ --with-socks use the socks library], [ --with-socks use the socks library],
[AC_DEFINE(HAVE_SOCKS)]) [AC_DEFINE(HAVE_SOCKS)])
AC_ARG_WITH(ssl,
[ --with-ssl use the openssl library])
AC_ARG_ENABLE(opie, AC_ARG_ENABLE(opie,
[ --disable-opie disable support for opie or s/key FTP login], [ --disable-opie disable support for opie or s/key FTP login],
USE_OPIE=$enableval, USE_OPIE=yes) USE_OPIE=$enableval, USE_OPIE=yes)
@ -183,6 +186,20 @@ then
AC_CHECK_LIB(socks, Rconnect) AC_CHECK_LIB(socks, Rconnect)
fi fi
dnl check for ssl libraries
if test "x${with_ssl}" = xyes
then
ssl_lose=no
AC_CHECK_LIB(ssl,SSL_new,,ssl_lose=yes,-lcrypto)
AC_CHECK_LIB(crypto,main,,ssl_lose=yes)
if test "$ssl_lose" = no
then
AC_DEFINE(HAVE_SSL)
SSL_OBJ='gen_sslfunc$o'
AC_SUBST(SSL_OBJ)
fi
fi
dnl dnl
dnl Set of available languages. dnl Set of available languages.
dnl dnl

View File

@ -1,3 +1,20 @@
2000-12-03 Christian Fraenkel <christian.fraenkel@gmx.net>
* Makefile.in: added gen_sslfunc object
* config.h.in: added HAVE_SSL define
* connect.c: changed select_fd from static int to int
* connect.h: ditto
* gen_sslfunc.h: New file
* gen_sslfunc.c: ditto
* http.c: added HTTPS fuctionality
* retrc.c: ditto
* url.c: ditto
* init.c: added opt.httpsproxy
* options.h: ditto
* rbuf.h: added alternate rbuf struct
* wget.h: added CONSSLERR
* rbuf.c: ditto
2000-11-30 Jan Prikryl <prikryl@cg.tuwien.ac.at> 2000-11-30 Jan Prikryl <prikryl@cg.tuwien.ac.at>
* ftp-ls.c (ftp_parse_unix_ls): Added second parameter * ftp-ls.c (ftp_parse_unix_ls): Added second parameter

View File

@ -55,12 +55,13 @@ ETAGS = etags
ALLOCA = @ALLOCA@ ALLOCA = @ALLOCA@
MD5_OBJ = @MD5_OBJ@ MD5_OBJ = @MD5_OBJ@
OPIE_OBJ = @OPIE_OBJ@ OPIE_OBJ = @OPIE_OBJ@
SSL_OBJ = @SSL_OBJ@
OBJ = $(ALLOCA) cmpt$o connect$o fnmatch$o ftp$o ftp-basic$o \ OBJ = $(ALLOCA) cmpt$o connect$o fnmatch$o ftp$o ftp-basic$o \
ftp-ls$o $(OPIE_OBJ) ftpparse$o getopt$o hash$o \ ftp-ls$o $(OPIE_OBJ) ftpparse$o getopt$o hash$o \
headers$o host$o html-parse$o html-url$o http$o init$o \ headers$o host$o html-parse$o html-url$o http$o init$o \
log$o main$o $(MD5_OBJ) netrc$o rbuf$o recur$o retr$o \ log$o main$o $(MD5_OBJ) netrc$o rbuf$o recur$o retr$o \
snprintf$o url$o utils$o version$o snprintf$o $(SSL_OBJ) url$o utils$o version$o
.SUFFIXES: .SUFFIXES:
.SUFFIXES: .c .o ._c ._o .SUFFIXES: .c .o ._c ._o

View File

@ -218,4 +218,7 @@ char *alloca ();
# define _SVID_SOURCE # define _SVID_SOURCE
#endif #endif
/* Define if all libs needed for ssl support are existing */
#undef HAVE_SSL
#endif /* CONFIG_H */ #endif /* CONFIG_H */

View File

@ -201,7 +201,7 @@ bindport (unsigned short *port)
Returns 1 if FD is accessible, 0 for timeout and -1 for error in Returns 1 if FD is accessible, 0 for timeout and -1 for error in
select(). */ select(). */
static int int
select_fd (int fd, int maxtime, int writep) select_fd (int fd, int maxtime, int writep)
{ {
fd_set fds, exceptfds; fd_set fds, exceptfds;

View File

@ -490,37 +490,37 @@ ftp_parse_winnt_ls (const char *file)
tok = strtok(NULL, " "); tok = strtok(NULL, " ");
while (*tok == '\0') tok = strtok(NULL, " "); while (*tok == '\0') tok = strtok(NULL, " ");
if (*tok == '<') if (*tok == '<')
{ {
cur.type = FT_DIRECTORY; cur.type = FT_DIRECTORY;
cur.size = 0; cur.size = 0;
cur.perms = 493; /* my gcc does not like 0755 ?? */ cur.perms = 493; /* my gcc does not like 0755 ?? */
DEBUGP(("Directory\n")); DEBUGP(("Directory\n"));
} }
else else
{ {
cur.type = FT_PLAINFILE; cur.type = FT_PLAINFILE;
cur.size = atoi(tok); cur.size = atoi(tok);
cur.perms = 420; /* 0664 octal */ cur.perms = 420; /* 0664 octal */
DEBUGP(("File, size %ld bytes\n", cur.size)); DEBUGP(("File, size %ld bytes\n", cur.size));
} }
cur.linkto = NULL; cur.linkto = NULL;
/* And put everything into the linked list */ /* And put everything into the linked list */
if (!dir) if (!dir)
{ {
l = dir = (struct fileinfo *)xmalloc (sizeof (struct fileinfo)); l = dir = (struct fileinfo *)xmalloc (sizeof (struct fileinfo));
memcpy (l, &cur, sizeof (cur)); memcpy (l, &cur, sizeof (cur));
l->prev = l->next = NULL; l->prev = l->next = NULL;
} }
else else
{ {
cur.prev = l; cur.prev = l;
l->next = (struct fileinfo *)xmalloc (sizeof (struct fileinfo)); l->next = (struct fileinfo *)xmalloc (sizeof (struct fileinfo));
l = l->next; l = l->next;
memcpy (l, &cur, sizeof (cur)); memcpy (l, &cur, sizeof (cur));
l->next = NULL; l->next = NULL;
} }
xfree(line); xfree(line);
} }

View File

@ -44,6 +44,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
# endif # endif
#endif #endif
#ifdef HAVE_SSL
#include "gen_sslfunc.h"
#endif /* HAVE_SSL */
#ifdef WINDOWS #ifdef WINDOWS
# include <winsock.h> # include <winsock.h>
#endif #endif
@ -269,7 +273,6 @@ http_process_connection (const char *hdr, void *arg)
/* Whether a persistent connection is active. */ /* Whether a persistent connection is active. */
static int pc_active_p; static int pc_active_p;
/* Host and port of currently active persistent connection. */ /* Host and port of currently active persistent connection. */
static unsigned char pc_last_host[4]; static unsigned char pc_last_host[4];
static unsigned short pc_last_port; static unsigned short pc_last_port;
@ -277,6 +280,13 @@ static unsigned short pc_last_port;
/* File descriptor of the currently active persistent connection. */ /* File descriptor of the currently active persistent connection. */
static int pc_last_fd; static int pc_last_fd;
#ifdef HAVE_SSL
/* Whether a ssl handshake has occoured on this connection */
static int pc_active_ssl;
/* SSL connection of the currently active persistent connection. */
static SSL *pc_last_ssl;
#endif /* HAVE_SSL */
/* Mark the persistent connection as invalid. This is used by the /* Mark the persistent connection as invalid. This is used by the
CLOSE_* macros after they forcefully close a registered persistent CLOSE_* macros after they forcefully close a registered persistent
connection. This does not close the file descriptor -- it is left connection. This does not close the file descriptor -- it is left
@ -286,6 +296,9 @@ static void
invalidate_persistent (void) invalidate_persistent (void)
{ {
pc_active_p = 0; pc_active_p = 0;
#ifdef HAVE_SSL
pc_active_ssl = 0;
#endif /* HAVE_SSL */
DEBUGP (("Invalidating fd %d from further reuse.\n", pc_last_fd)); DEBUGP (("Invalidating fd %d from further reuse.\n", pc_last_fd));
} }
@ -298,7 +311,11 @@ invalidate_persistent (void)
If a previous connection was persistent, it is closed. */ If a previous connection was persistent, it is closed. */
static void static void
#ifndef HAVE_SSL
register_persistent (const char *host, unsigned short port, int fd) register_persistent (const char *host, unsigned short port, int fd)
#else
register_persistent (const char *host, unsigned short port, int fd, SSL* ssl)
#endif /* HAVE_SSL */
{ {
int success; int success;
@ -317,6 +334,10 @@ register_persistent (const char *host, unsigned short port, int fd)
persistent connection exists, but we then connect to a persistent connection exists, but we then connect to a
different host, and try to register a persistent different host, and try to register a persistent
connection to that one. */ connection to that one. */
#ifdef HAVE_SSL
/* the ssl disconnect has to take place before the closing of pc_last_fd */
if (pc_last_ssl) shutdown_ssl(pc_last_ssl);
#endif /* HAVE_SSL */
CLOSE (pc_last_fd); CLOSE (pc_last_fd);
invalidate_persistent (); invalidate_persistent ();
} }
@ -329,6 +350,10 @@ register_persistent (const char *host, unsigned short port, int fd)
pc_last_port = port; pc_last_port = port;
pc_last_fd = fd; pc_last_fd = fd;
pc_active_p = 1; pc_active_p = 1;
#ifdef HAVE_SSL
pc_last_ssl=ssl;
pc_active_ssl= ssl ? 1 : 0;
#endif /* HAVE_SSL */
DEBUGP (("Registered fd %d for persistent reuse.\n", fd)); DEBUGP (("Registered fd %d for persistent reuse.\n", fd));
} }
@ -336,7 +361,11 @@ register_persistent (const char *host, unsigned short port, int fd)
connecting to HOST:PORT. */ connecting to HOST:PORT. */
static int static int
#ifndef HAVE_SSL
persistent_available_p (const char *host, unsigned short port) persistent_available_p (const char *host, unsigned short port)
#else
persistent_available_p (const char *host, unsigned short port,int ssl)
#endif /* HAVE_SSL */
{ {
unsigned char this_host[4]; unsigned char this_host[4];
/* First, check whether a persistent connection is active at all. */ /* First, check whether a persistent connection is active at all. */
@ -365,6 +394,15 @@ persistent_available_p (const char *host, unsigned short port)
invalidate_persistent (); invalidate_persistent ();
return 0; return 0;
} }
#ifdef HAVE_SSL
/* Fourth: check if current connection is (not) ssl, too.
This test is unlikely to fail because HTTP and HTTPS
typicaly use different ports. Yet it is possible (or so
I have been told) to run HTTPS and HTTP simultaneus on
the same port. */
if (ssl!=pc_active_ssl)
return 0;
#endif /* HAVE_SSL */
return 1; return 1;
} }
@ -383,6 +421,7 @@ persistent_available_p (const char *host, unsigned short port)
`pc_active_p && (fd) == pc_last_fd' is "we're *now* using an `pc_active_p && (fd) == pc_last_fd' is "we're *now* using an
active, registered connection". */ active, registered connection". */
#ifndef HAVE_SSL
#define CLOSE_FINISH(fd) do { \ #define CLOSE_FINISH(fd) do { \
if (!keep_alive) \ if (!keep_alive) \
{ \ { \
@ -398,6 +437,25 @@ persistent_available_p (const char *host, unsigned short port)
invalidate_persistent (); \ invalidate_persistent (); \
} while (0) } while (0)
#else
#define CLOSE_FINISH(fd,ssl) do { \
if (!keep_alive) \
{ \
if (ssl) shutdown_ssl(ssl); \
CLOSE (fd); \
if (pc_active_p && (fd) == pc_last_fd) \
invalidate_persistent (); \
} \
} while (0)
#define CLOSE_INVALIDATE(fd,ssl) do { \
if (ssl) shutdown_ssl(ssl); \
CLOSE (fd); \
if (pc_active_p && (fd) == pc_last_fd) \
invalidate_persistent (); \
} while (0)
#endif /* HAVE_SSL */
struct http_stat struct http_stat
{ {
@ -466,6 +524,10 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt)
FILE *fp; FILE *fp;
int auth_tried_already; int auth_tried_already;
struct rbuf rbuf; struct rbuf rbuf;
#ifdef HAVE_SSL
static SSL_CTX *ssl_ctx=NULL;
SSL *ssl=NULL;
#endif /* HAVE_SSL */
/* Whether this connection will be kept alive after the HTTP request /* Whether this connection will be kept alive after the HTTP request
is done. */ is done. */
@ -478,6 +540,11 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt)
/* Whether keep-alive should be inhibited. */ /* Whether keep-alive should be inhibited. */
int inhibit_keep_alive; int inhibit_keep_alive;
#ifdef HAVE_SSL
/* initialize ssl_ctx on first run */
if (!ssl_ctx) init_ssl(&ssl_ctx);
#endif /* HAVE_SSL */
if (!(*dt & HEAD_ONLY)) if (!(*dt & HEAD_ONLY))
/* If we're doing a GET on the URL, as opposed to just a HEAD, we need to /* If we're doing a GET on the URL, as opposed to just a HEAD, we need to
know the local filename so we can save to it. */ know the local filename so we can save to it. */
@ -512,11 +579,15 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt)
/* First: establish the connection. */ /* First: establish the connection. */
if (inhibit_keep_alive if (inhibit_keep_alive
#ifndef HAVE_SSL
|| !persistent_available_p (u->host, u->port)) || !persistent_available_p (u->host, u->port))
#else
|| !persistent_available_p (u->host, u->port, (u->proto==URLHTTPS ? 1 : 0)))
#endif /* HAVE_SSL */
{ {
logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "), u->host, u->port); logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "), u->host, u->port);
err = make_connection (&sock, u->host, u->port); err = make_connection (&sock, u->host, u->port);
switch (err) switch (err)
{ {
case HOSTERR: case HOSTERR:
logputs (LOG_VERBOSE, "\n"); logputs (LOG_VERBOSE, "\n");
@ -548,6 +619,14 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt)
abort (); abort ();
break; break;
} }
#ifdef HAVE_SSL
if (u->proto==URLHTTPS) if (connect_ssl(&ssl,ssl_ctx,sock)!=0) {
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n"));
CLOSE (sock);
return CONSSLERR;
}
#endif /* HAVE_SSL */
} }
else else
{ {
@ -555,6 +634,9 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt)
/* #### pc_last_fd should be accessed through an accessor /* #### pc_last_fd should be accessed through an accessor
function. */ function. */
sock = pc_last_fd; sock = pc_last_fd;
#ifdef HAVE_SSL
ssl = pc_last_ssl;
#endif /* HAVE_SSL */
DEBUGP (("Reusing fd %d.\n", sock)); DEBUGP (("Reusing fd %d.\n", sock));
} }
@ -715,12 +797,24 @@ Accept: %s\r\n\
FREE_MAYBE (proxyauth); FREE_MAYBE (proxyauth);
/* Send the request to server. */ /* Send the request to server. */
#ifdef HAVE_SSL
if (u->proto==URLHTTPS) {
num_written = ssl_iwrite (ssl, request, strlen (request));
} else {
#endif /* HAVE_SSL */
num_written = iwrite (sock, request, strlen (request)); num_written = iwrite (sock, request, strlen (request));
#ifdef HAVE_SSL
}
#endif /* HAVE_SSL */
if (num_written < 0) if (num_written < 0)
{ {
logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"), logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"),
strerror (errno)); strerror (errno));
CLOSE_INVALIDATE (sock); #ifndef HAVE_SSL
CLOSE_INVALIDATE (sock);
#else
CLOSE_INVALIDATE (sock,ssl);
#endif /* HAVE_SSL */
return WRITEFAILED; return WRITEFAILED;
} }
logprintf (LOG_VERBOSE, _("%s request sent, awaiting response... "), logprintf (LOG_VERBOSE, _("%s request sent, awaiting response... "),
@ -732,7 +826,11 @@ Accept: %s\r\n\
/* Before reading anything, initialize the rbuf. */ /* Before reading anything, initialize the rbuf. */
rbuf_initialize (&rbuf, sock); rbuf_initialize (&rbuf, sock);
#ifdef HAVE_SSL
if (u->proto == URLHTTPS) {
rbuf.ssl=ssl;
} else { rbuf.ssl=NULL; }
#endif /* HAVE_SSL */
all_headers = NULL; all_headers = NULL;
all_length = 0; all_length = 0;
/* Header-fetching loop. */ /* Header-fetching loop. */
@ -767,7 +865,11 @@ Accept: %s\r\n\
FREE_MAYBE (type); FREE_MAYBE (type);
FREE_MAYBE (hs->newloc); FREE_MAYBE (hs->newloc);
FREE_MAYBE (all_headers); FREE_MAYBE (all_headers);
CLOSE_INVALIDATE (sock); #ifndef HAVE_SSL
CLOSE_INVALIDATE (sock);
#else
CLOSE_INVALIDATE (sock,ssl);
#endif /* HAVE_SSL */
return HEOF; return HEOF;
} }
else if (status == HG_ERROR) else if (status == HG_ERROR)
@ -779,7 +881,11 @@ Accept: %s\r\n\
FREE_MAYBE (type); FREE_MAYBE (type);
FREE_MAYBE (hs->newloc); FREE_MAYBE (hs->newloc);
FREE_MAYBE (all_headers); FREE_MAYBE (all_headers);
CLOSE_INVALIDATE (sock); #ifndef HAVE_SSL
CLOSE_INVALIDATE (sock);
#else
CLOSE_INVALIDATE (sock,ssl);
#endif /* HAVE_SSL */
return HERR; return HERR;
} }
@ -919,7 +1025,11 @@ Accept: %s\r\n\
if (keep_alive) if (keep_alive)
/* The server has promised that it will not close the connection /* The server has promised that it will not close the connection
when we're done. This means that we can register it. */ when we're done. This means that we can register it. */
#ifndef HAVE_SSL
register_persistent (u->host, u->port, sock); register_persistent (u->host, u->port, sock);
#else
register_persistent (u->host, u->port, sock, ssl);
#endif /* HAVE_SSL */
if ((statcode == HTTP_STATUS_UNAUTHORIZED) if ((statcode == HTTP_STATUS_UNAUTHORIZED)
&& authenticate_h) && authenticate_h)
@ -928,7 +1038,11 @@ Accept: %s\r\n\
FREE_MAYBE (type); FREE_MAYBE (type);
type = NULL; type = NULL;
FREEHSTAT (*hs); FREEHSTAT (*hs);
CLOSE_FINISH (sock); #ifndef HAVE_SSL
CLOSE_FINISH (sock);
#else
CLOSE_FINISH (sock,ssl);
#endif /* HAVE_SSL */
if (auth_tried_already) if (auth_tried_already)
{ {
/* If we have tried it already, then there is not point /* If we have tried it already, then there is not point
@ -1004,7 +1118,11 @@ Accept: %s\r\n\
FREE_MAYBE (type); FREE_MAYBE (type);
FREE_MAYBE (hs->newloc); FREE_MAYBE (hs->newloc);
FREE_MAYBE (all_headers); FREE_MAYBE (all_headers);
CLOSE_INVALIDATE (sock); #ifndef HAVE_SSL
CLOSE_INVALIDATE (sock);
#else
CLOSE_INVALIDATE (sock,ssl);
#endif /* HAVE_SSL */
return RANGEERR; return RANGEERR;
} }
@ -1034,7 +1152,11 @@ Accept: %s\r\n\
_("Location: %s%s\n"), _("Location: %s%s\n"),
hs->newloc ? hs->newloc : _("unspecified"), hs->newloc ? hs->newloc : _("unspecified"),
hs->newloc ? _(" [following]") : ""); hs->newloc ? _(" [following]") : "");
CLOSE_FINISH (sock); #ifndef HAVE_SSL
CLOSE_FINISH (sock);
#else
CLOSE_FINISH (sock,ssl);
#endif /* HAVE_SSL */
FREE_MAYBE (type); FREE_MAYBE (type);
FREE_MAYBE (all_headers); FREE_MAYBE (all_headers);
return NEWLOCATION; return NEWLOCATION;
@ -1075,7 +1197,11 @@ Accept: %s\r\n\
hs->res = 0; hs->res = 0;
FREE_MAYBE (type); FREE_MAYBE (type);
FREE_MAYBE (all_headers); FREE_MAYBE (all_headers);
CLOSE_FINISH (sock); #ifndef HAVE_SSL
CLOSE_FINISH (sock);
#else
CLOSE_FINISH (sock,ssl);
#endif /* HAVE_SSL */
return RETRFINISHED; return RETRFINISHED;
} }
@ -1089,7 +1215,11 @@ Accept: %s\r\n\
if (!fp) if (!fp)
{ {
logprintf (LOG_NOTQUIET, "%s: %s\n", u->local, strerror (errno)); logprintf (LOG_NOTQUIET, "%s: %s\n", u->local, strerror (errno));
CLOSE_FINISH (sock); #ifndef HAVE_SSL
CLOSE_FINISH (sock);
#else
CLOSE_FINISH (sock,ssl);
#endif /* HAVE_SSL */
FREE_MAYBE (all_headers); FREE_MAYBE (all_headers);
return FOPENERR; return FOPENERR;
} }
@ -1129,7 +1259,11 @@ Accept: %s\r\n\
hs->res = -2; hs->res = -2;
} }
FREE_MAYBE (all_headers); FREE_MAYBE (all_headers);
CLOSE_FINISH (sock); #ifndef HAVE_SSL
CLOSE_FINISH (sock);
#else
CLOSE_FINISH (sock,ssl);
#endif /* HAVE_SSL */
if (hs->res == -2) if (hs->res == -2)
return FWRITEERR; return FWRITEERR;
return RETRFINISHED; return RETRFINISHED;
@ -1350,6 +1484,13 @@ File `%s' already there, will not retrieve.\n"), u->local);
logprintf (LOG_NOTQUIET, _("Cannot write to `%s' (%s).\n"), logprintf (LOG_NOTQUIET, _("Cannot write to `%s' (%s).\n"),
u->local, strerror (errno)); u->local, strerror (errno));
FREEHSTAT (hstat); FREEHSTAT (hstat);
return err;
break;
case CONSSLERR:
/* Another fatal error. */
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n"));
FREEHSTAT (hstat);
xfree (filename_plus_orig_suffix); /* must precede every return! */ xfree (filename_plus_orig_suffix); /* must precede every return! */
return err; return err;
break; break;

View File

@ -126,6 +126,7 @@ static struct {
{ "httppasswd", &opt.http_passwd, cmd_string }, { "httppasswd", &opt.http_passwd, cmd_string },
{ "httpproxy", &opt.http_proxy, cmd_string }, { "httpproxy", &opt.http_proxy, cmd_string },
{ "httpuser", &opt.http_user, cmd_string }, { "httpuser", &opt.http_user, cmd_string },
{ "httpsproxy", &opt.https_proxy, cmd_string },
{ "ignorelength", &opt.ignore_length, cmd_boolean }, { "ignorelength", &opt.ignore_length, cmd_boolean },
{ "ignoretags", &opt.ignore_tags, cmd_vector }, { "ignoretags", &opt.ignore_tags, cmd_vector },
{ "includedirectories", &opt.includes, cmd_directory_vector }, { "includedirectories", &opt.includes, cmd_directory_vector },
@ -1012,6 +1013,7 @@ cleanup (void)
xfree (opt.ftp_acc); xfree (opt.ftp_acc);
FREE_MAYBE (opt.ftp_pass); FREE_MAYBE (opt.ftp_pass);
FREE_MAYBE (opt.ftp_proxy); FREE_MAYBE (opt.ftp_proxy);
FREE_MAYBE (opt.https_proxy);
FREE_MAYBE (opt.http_proxy); FREE_MAYBE (opt.http_proxy);
free_vec (opt.no_proxy); free_vec (opt.no_proxy);
FREE_MAYBE (opt.useragent); FREE_MAYBE (opt.useragent);

View File

@ -90,7 +90,7 @@ struct options
int use_proxy; /* Do we use proxy? */ int use_proxy; /* Do we use proxy? */
int proxy_cache; /* Do we load from proxy cache? */ int proxy_cache; /* Do we load from proxy cache? */
char *http_proxy, *ftp_proxy; char *http_proxy, *ftp_proxy, *https_proxy;
char **no_proxy; char **no_proxy;
char *base_href; char *base_href;
char *proxy_user; /*oli*/ char *proxy_user; /*oli*/

View File

@ -25,10 +25,23 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "rbuf.h" #include "rbuf.h"
#include "connect.h" #include "connect.h"
#ifdef HAVE_SSL
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#endif /* HAVE_SSL */
void void
rbuf_initialize (struct rbuf *rbuf, int fd) rbuf_initialize (struct rbuf *rbuf, int fd)
{ {
rbuf->fd = fd; rbuf->fd = fd;
#ifdef HAVE_SSL
/* pointing ssl to NULL results in an unchanged behaviour */
rbuf->ssl = NULL;
#endif /* HAVE_SSL */
rbuf->buffer_pos = rbuf->buffer; rbuf->buffer_pos = rbuf->buffer;
rbuf->buffer_left = 0; rbuf->buffer_left = 0;
} }
@ -64,7 +77,15 @@ rbuf_peek (struct rbuf *rbuf, char *store)
int res; int res;
rbuf->buffer_pos = rbuf->buffer; rbuf->buffer_pos = rbuf->buffer;
rbuf->buffer_left = 0; rbuf->buffer_left = 0;
res = iread (rbuf->fd, rbuf->buffer, sizeof (rbuf->buffer)); #ifdef HAVE_SSL
if (rbuf->ssl != NULL) {
res = ssl_iread (rbuf->ssl, rbuf->buffer, sizeof (rbuf->buffer));
} else {
#endif /* HAVE_SSL */
res = iread (rbuf->fd, rbuf->buffer, sizeof (rbuf->buffer));
#ifdef HAVE_SSL
}
#endif /* HAVE_SSL */
if (res <= 0) if (res <= 0)
return res; return res;
rbuf->buffer_left = res; rbuf->buffer_left = res;

View File

@ -20,10 +20,17 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef RBUF_H #ifndef RBUF_H
#define RBUF_H #define RBUF_H
#ifdef HAVE_SSL
# include <openssl/ssl.h>
#endif
/* Retrieval stream */ /* Retrieval stream */
struct rbuf struct rbuf
{ {
int fd; int fd;
#ifdef HAVE_SSL
SSL *ssl; /* the ssl structure -- replaces fd for ssl connections */
#endif /* HAVE_SSL */
char buffer[4096]; /* the input buffer */ char buffer[4096]; /* the input buffer */
char *buffer_pos; /* current position in the buffer */ char *buffer_pos; /* current position in the buffer */
size_t buffer_left; /* number of bytes left in the buffer: size_t buffer_left; /* number of bytes left in the buffer:
@ -42,6 +49,23 @@ struct rbuf
result of historical implementation of header code. The macro result of historical implementation of header code. The macro
should return the character or EOF, and in case of error store it should return the character or EOF, and in case of error store it
to rbuf->err or something. */ to rbuf->err or something. */
#ifdef HAVE_SSL
/* SSL version of rbuf. If rbuf.ssl isn't NULL use ssl_iread instead
of iread */
#define RBUF_READCHAR(rbuf, store) \
((rbuf)->buffer_left \
? (--(rbuf)->buffer_left, \
*((char *) (store)) = *(rbuf)->buffer_pos++, 1) \
: ((rbuf)->buffer_pos = (rbuf)->buffer, \
((((rbuf)->internal_dont_touch_this \
= (rbuf->ssl == NULL) ? (iread ((rbuf)->fd, (rbuf)->buffer, \
sizeof ((rbuf)->buffer))) : (ssl_iread ((rbuf)->ssl, (rbuf)->buffer, \
sizeof ((rbuf)->buffer))) ) <= 0) \
? (rbuf)->internal_dont_touch_this \
: ((rbuf)->buffer_left = (rbuf)->internal_dont_touch_this - 1, \
*((char *) (store)) = *(rbuf)->buffer_pos++, \
1))))
#else
#define RBUF_READCHAR(rbuf, store) \ #define RBUF_READCHAR(rbuf, store) \
((rbuf)->buffer_left \ ((rbuf)->buffer_left \
? (--(rbuf)->buffer_left, \ ? (--(rbuf)->buffer_left, \
@ -55,9 +79,15 @@ struct rbuf
*((char *) (store)) = *(rbuf)->buffer_pos++, \ *((char *) (store)) = *(rbuf)->buffer_pos++, \
1)))) 1))))
#endif /* HAVE_SSL */
/* Return the file descriptor of RBUF. */ /* Return the file descriptor of RBUF. */
#define RBUF_FD(rbuf) ((rbuf)->fd) #define RBUF_FD(rbuf) ((rbuf)->fd)
/* Return the file descriptor of RBUF. */
#define RBUF_SSL(rbuf) ((rbuf)->ssl)
/* Function declarations */ /* Function declarations */
void rbuf_initialize PARAMS ((struct rbuf *, int)); void rbuf_initialize PARAMS ((struct rbuf *, int));
int rbuf_initialized_p PARAMS ((struct rbuf *)); int rbuf_initialized_p PARAMS ((struct rbuf *));

View File

@ -118,7 +118,15 @@ get_contents (int fd, FILE *fp, long *len, long restval, long expected,
int amount_to_read = (use_expected int amount_to_read = (use_expected
? MIN (expected - *len, sizeof (c)) ? MIN (expected - *len, sizeof (c))
: sizeof (c)); : sizeof (c));
res = iread (fd, c, amount_to_read); #ifdef HAVE_SSL
if (rbuf->ssl!=NULL) {
res = ssl_iread (rbuf->ssl, c, amount_to_read);
} else {
#endif /* HAVE_SSL */
res = iread (fd, c, amount_to_read);
#ifdef HAVE_SSL
}
#endif /* HAVE_SSL */
if (res > 0) if (res > 0)
{ {
if (fwrite (c, sizeof (char), res, fp) < res) if (fwrite (c, sizeof (char), res, fp) < res)
@ -322,7 +330,7 @@ rate (long bytes, long msecs)
&& no_proxy_match((u)->host, \ && no_proxy_match((u)->host, \
(const char **)opt.no_proxy)) (const char **)opt.no_proxy))
/* Retrieve the given URL. Decides which loop to call -- HTTP, FTP, /* Retrieve the given URL. Decides which loop to call -- HTTP(S), FTP,
or simply copy it with file:// (#### the latter not yet or simply copy it with file:// (#### the latter not yet
implemented!). */ implemented!). */
uerr_t uerr_t
@ -415,7 +423,11 @@ retrieve_url (const char *origurl, char **file, char **newloc,
assert (u->proto != URLFILE); /* #### Implement me! */ assert (u->proto != URLFILE); /* #### Implement me! */
mynewloc = NULL; mynewloc = NULL;
#ifdef HAVE_SSL
if (u->proto == URLHTTP || u->proto == URLHTTPS )
#else
if (u->proto == URLHTTP) if (u->proto == URLHTTP)
#endif /* HAVE_SSL */
result = http_loop (u, &mynewloc, dt); result = http_loop (u, &mynewloc, dt);
else if (u->proto == URLFTP) else if (u->proto == URLFTP)
{ {

View File

@ -46,6 +46,7 @@ extern int errno;
/* Default port definitions */ /* Default port definitions */
#define DEFAULT_HTTP_PORT 80 #define DEFAULT_HTTP_PORT 80
#define DEFAULT_FTP_PORT 21 #define DEFAULT_FTP_PORT 21
#define DEFAULT_HTTPS_PORT 443
/* Table of Unsafe chars. This is intialized in /* Table of Unsafe chars. This is intialized in
init_unsafe_char_table. */ init_unsafe_char_table. */
@ -77,8 +78,8 @@ static void path_simplify_with_kludge PARAMS ((char *));
static int urlpath_length PARAMS ((const char *)); static int urlpath_length PARAMS ((const char *));
/* NULL-terminated list of strings to be recognized as prototypes (URL /* NULL-terminated list of strings to be recognized as prototypes (URL
schemes). Note that recognized doesn't mean supported -- only HTTP schemes). Note that recognized doesn't mean supported -- only HTTP,
and FTP are currently supported. HTTPS and FTP are currently supported .
However, a string that does not match anything in the list will be However, a string that does not match anything in the list will be
considered a relative URL. Thus it's important that this list has considered a relative URL. Thus it's important that this list has
@ -133,6 +134,9 @@ struct proto
static struct proto sup_protos[] = static struct proto sup_protos[] =
{ {
{ "http://", URLHTTP, DEFAULT_HTTP_PORT }, { "http://", URLHTTP, DEFAULT_HTTP_PORT },
#ifdef HAVE_SSL
{ "https://",URLHTTPS, DEFAULT_HTTPS_PORT},
#endif
{ "ftp://", URLFTP, DEFAULT_FTP_PORT }, { "ftp://", URLFTP, DEFAULT_FTP_PORT },
/*{ "file://", URLFILE, DEFAULT_FTP_PORT },*/ /*{ "file://", URLFILE, DEFAULT_FTP_PORT },*/
}; };
@ -1288,6 +1292,10 @@ getproxy (uerr_t proto)
return opt.http_proxy ? opt.http_proxy : getenv ("http_proxy"); return opt.http_proxy ? opt.http_proxy : getenv ("http_proxy");
else if (proto == URLFTP) else if (proto == URLFTP)
return opt.ftp_proxy ? opt.ftp_proxy : getenv ("ftp_proxy"); return opt.ftp_proxy ? opt.ftp_proxy : getenv ("ftp_proxy");
#ifdef HAVE_SSL
else if (proto == URLHTTPS)
return opt.https_proxy ? opt.https_proxy : getenv ("https_proxy");
#endif /* HAVE_SSL */
else else
return NULL; return NULL;
} }

View File

@ -246,12 +246,12 @@ enum
This is, of course, utter crock. */ This is, of course, utter crock. */
typedef enum typedef enum
{ {
NOCONERROR, HOSTERR, CONSOCKERR, CONERROR, NOCONERROR, HOSTERR, CONSOCKERR, CONERROR, CONSSLERR,
CONREFUSED, NEWLOCATION, NOTENOUGHMEM, CONPORTERR, CONREFUSED, NEWLOCATION, NOTENOUGHMEM, CONPORTERR,
BINDERR, BINDOK, LISTENERR, ACCEPTERR, ACCEPTOK, BINDERR, BINDOK, LISTENERR, ACCEPTERR, ACCEPTOK,
CONCLOSED, FTPOK, FTPLOGINC, FTPLOGREFUSED, FTPPORTERR, CONCLOSED, FTPOK, FTPLOGINC, FTPLOGREFUSED, FTPPORTERR,
FTPNSFOD, FTPRETROK, FTPUNKNOWNTYPE, FTPRERR, FTPNSFOD, FTPRETROK, FTPUNKNOWNTYPE, FTPRERR,
FTPREXC, FTPSRVERR, FTPRETRINT, FTPRESTFAIL, FTPREXC, FTPSRVERR, FTPRETRINT, FTPRESTFAIL, URLHTTPS,
URLOK, URLHTTP, URLFTP, URLFILE, URLUNKNOWN, URLBADPORT, URLOK, URLHTTP, URLFTP, URLFILE, URLUNKNOWN, URLBADPORT,
URLBADHOST, FOPENERR, FWRITEERR, HOK, HLEXC, HEOF, URLBADHOST, FOPENERR, FWRITEERR, HOK, HLEXC, HEOF,
HERR, RETROK, RECLEVELEXC, FTPACCDENIED, WRONGCODE, HERR, RETROK, RECLEVELEXC, FTPACCDENIED, WRONGCODE,