mirror of
https://github.com/mirror/wget.git
synced 2025-03-14 20:00:15 +08:00
Merge remote-tracking branch 'origin' into parallel-wget
This commit is contained in:
commit
4445d48471
@ -6,6 +6,15 @@
|
||||
|
||||
* configure.ac: By default disable threads and metalink support.
|
||||
|
||||
2013-07-23 Tim Ruehsen <tim.ruehsen@gmx.de>
|
||||
|
||||
* configure.ac: Remove AM_CONDITIONAL HAVE_NETTLE.
|
||||
Reported by: Darshit Shah <darnir@gmail.com>.
|
||||
|
||||
2013-07-13 Tim Ruehsen <tim.ruehsen@gmx.de>
|
||||
|
||||
* configure.ac: check for libnettle when GNU TLS is used.
|
||||
|
||||
2013-05-17 Bykov Aleksey <gnfalex@rambler.ru>
|
||||
|
||||
* bootstrap: Add `mkostemp'
|
||||
|
23
configure.ac
23
configure.ac
@ -351,11 +351,26 @@ then
|
||||
AC_LIBOBJ([http-ntlm])
|
||||
fi
|
||||
else
|
||||
dnl If SSL is unavailable and the user explicitly requested NTLM,
|
||||
dnl abort.
|
||||
if test x"$ENABLE_NTLM" = xyes
|
||||
AC_CHECK_LIB(nettle, nettle_md4_init, [HAVE_NETTLE=yes], [HAVE_NETTLE=no; AC_MSG_WARN(*** libnettle was not found. You will not be able to use NTLM)])
|
||||
|
||||
if test x"$HAVE_NETTLE" = xyes
|
||||
then
|
||||
AC_MSG_ERROR([NTLM authorization requested and OpenSSL not found; aborting])
|
||||
AC_SUBST(NETTLE_LIBS, "-lnettle")
|
||||
AC_DEFINE([HAVE_NETTLE], [1], [Use libnettle])
|
||||
if test x"$ENABLE_NTLM" != xno
|
||||
then
|
||||
AC_DEFINE([ENABLE_NTLM], 1,
|
||||
[Define if you want the NTLM authorization support compiled in.])
|
||||
AC_LIBOBJ([http-ntlm])
|
||||
LIBS="$NETTLE_LIBS $LIBS"
|
||||
fi
|
||||
else
|
||||
dnl If SSL is unavailable and the user explicitly requested NTLM,
|
||||
dnl abort.
|
||||
if test x"$ENABLE_NTLM" = xyes
|
||||
then
|
||||
AC_MSG_ERROR([NTLM authorization requested and SSL not enabled; aborting])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2013-07-09 Giuseppe Scrivano <gscrivano@gnu.org>
|
||||
|
||||
* wget.texi (Download Options): Add documentation for --backups.
|
||||
(Wgetrc Commands): Add documentation for backups.
|
||||
Reported by: Tomas Hozza <thozza@redhat.com>.
|
||||
|
||||
2013-07-11 Tomas Hozza <thozza@redhat.com>
|
||||
|
||||
* wget.texi: Document --regex-type and --preserve-permissions.
|
||||
|
@ -651,6 +651,13 @@ Note that when @samp{-nc} is specified, files with the suffixes
|
||||
@samp{.html} or @samp{.htm} will be loaded from the local disk and
|
||||
parsed as if they had been retrieved from the Web.
|
||||
|
||||
@cindex backing up files
|
||||
@item --backups=@var{backups}
|
||||
Before (over)writing a file, back up an existing file by adding a
|
||||
@samp{.1} suffix (@samp{_1} on VMS) to the file name. Such backup
|
||||
files are rotated to @samp{.2}, @samp{.3}, and so on, up to
|
||||
@var{backups} (and lost beyond that).
|
||||
|
||||
@cindex continue retrieval
|
||||
@cindex incomplete downloads
|
||||
@cindex resume download
|
||||
@ -2911,9 +2918,11 @@ enables it).
|
||||
Enable/disable saving pre-converted files with the suffix
|
||||
@samp{.orig}---the same as @samp{-K} (which enables it).
|
||||
|
||||
@c @item backups = @var{number}
|
||||
@c #### Document me!
|
||||
@c
|
||||
@item backups = @var{number}
|
||||
Use up to @var{number} backups for a file. Backups are rotated by
|
||||
adding an incremental counter that starts at @samp{1}. The default is
|
||||
@samp{0}.
|
||||
|
||||
@item base = @var{string}
|
||||
Consider relative @sc{url}s in input files (specified via the
|
||||
@samp{input} command or the @samp{--input-file}/@samp{-i} option,
|
||||
|
@ -2,6 +2,64 @@
|
||||
|
||||
* utils.c (run_with_timeout): abort when there are more threads.
|
||||
|
||||
2013-07-16 Darshit Shah <darnir@gmail.com>
|
||||
|
||||
* wget.h (err_t): Added new errors, ATTRMISSING and UNKNOWNATTR to
|
||||
handle missing attributes and Unknown attribute values respectively in
|
||||
HTTP Headers.
|
||||
* exits.c (get_status_for_err): ATTRMISSING is a Protocol Error while
|
||||
UNKNOWNATTR is a general error, presumably because of a feature that
|
||||
is not yet implemented.
|
||||
* http.c (gethttp): Call create_authorization_line () separately. In
|
||||
case the auth_err flag has been set with an error, handle it and exit.
|
||||
* http.c (create_authorization_line): Pass a pointer, auth_err to set
|
||||
the flag for different kinds of errors encountered.
|
||||
* http.c (http_loop): Handle the errors raised by the authentication
|
||||
handlers.
|
||||
* http.c (digest_authentication_encode): Pass pointer auth_err to set
|
||||
the error flags.
|
||||
Set qop to NULL in case the value of the qop / algorithm attribute is
|
||||
unknown to Wget. Set an appropriate error too.
|
||||
|
||||
2013-07-13 Tim Ruehsen <tim.ruehsen@gmx.de>
|
||||
|
||||
* http.c (digest_authentication_encode): Fix a crash when the algorithm
|
||||
is not specified in the server response. Free dynamic memory used by
|
||||
the function when the function exits.
|
||||
* http-ntlm.c [HAVE_NETTLE]: Include <nettle/md4.h> and <nettle/des.h>.
|
||||
(setup_des_key) [HAVE_NETTLE]: New function to deal with
|
||||
libnettle.
|
||||
(calc_resp) [HAVE_NETTLE]: Add support for libnettle.
|
||||
(mkhash) [HAVE_NETTLE]: Likewise.
|
||||
Reported by: Tim Ruehsen <tim.ruehsen@gmx.de>.
|
||||
|
||||
2013-07-13 Steven M. Schweda <sms@antinode.info>
|
||||
|
||||
* warc.c (warc_tempfile): Fix a portability issue on VMS.
|
||||
|
||||
2013-07-10 Giuseppe Scrivano <gscrivano@gnu.org>
|
||||
|
||||
* http.c (read_response_body) [ALLOW_CLOBBER]: Move definition to..
|
||||
* options.h (struct options): Make `backups' an int.
|
||||
* url.h [ALLOW_CLOBBER]: .. Here. Do not clobber when backups are used.
|
||||
* url.c (url_file_name): Use the ALLOW_CLOBBER macro instead of
|
||||
repeating the code.
|
||||
|
||||
2013-07-08 Steven M. Schweda <sms@antinode.info>
|
||||
|
||||
* retr.c (rotate_backups): Support for VMS files.
|
||||
|
||||
2013-07-12 Giuseppe Scrivano <gscrivano@gnu.org>
|
||||
|
||||
* http.c (digest_authentication_encode): Set default value of
|
||||
`algorithm' to "MD5". Check if `qop' is not-NULL before access it.
|
||||
|
||||
2013-07-11 Karsten Hopp <karsten@redhat.com>
|
||||
|
||||
* openssl.c (struct openssl_read_args, struct scwt_context): New struct.
|
||||
(openssl_read, ssl_connect_with_timeout_callback): New function.
|
||||
(ssl_connect_wget): respect connect timeout.
|
||||
|
||||
2013-07-11 Tim Ruehsen <tim.ruehsen@gmx.de>
|
||||
|
||||
* gnutls.c (ssl_connect_wget): respect connect timeout.
|
||||
|
@ -68,7 +68,7 @@ get_status_for_err (uerr_t err)
|
||||
return WGET_EXIT_SSL_AUTH_FAIL;
|
||||
case FTPLOGINC: case FTPLOGREFUSED: case AUTHFAILED:
|
||||
return WGET_EXIT_SERVER_AUTH_FAIL;
|
||||
case HEOF: case HERR:
|
||||
case HEOF: case HERR: case ATTRMISSING:
|
||||
return WGET_EXIT_PROTOCOL_ERROR;
|
||||
case WRONGCODE: case FTPPORTERR: case FTPSYSERR:
|
||||
case FTPNSFOD: case FTPUNKNOWNTYPE: case FTPSRVERR:
|
||||
@ -76,7 +76,7 @@ get_status_for_err (uerr_t err)
|
||||
case CONTNOTSUPPORTED: case RANGEERR: case RETRBADPATTERN:
|
||||
case PROXERR:
|
||||
return WGET_EXIT_SERVER_ERROR;
|
||||
case URLERROR: case QUOTEXC: case SSLINITFAILED:
|
||||
case URLERROR: case QUOTEXC: case SSLINITFAILED: case UNKNOWNATTR:
|
||||
default:
|
||||
return WGET_EXIT_UNKNOWN;
|
||||
}
|
||||
|
@ -42,27 +42,33 @@ as that of the covered work. */
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openssl/des.h>
|
||||
#include <openssl/md4.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "http-ntlm.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907001L
|
||||
#define DES_key_schedule des_key_schedule
|
||||
#define DES_cblock des_cblock
|
||||
#define DES_set_odd_parity des_set_odd_parity
|
||||
#define DES_set_key des_set_key
|
||||
#define DES_ecb_encrypt des_ecb_encrypt
|
||||
#ifdef HAVE_NETTLE
|
||||
# include <nettle/md4.h>
|
||||
# include <nettle/des.h>
|
||||
#else
|
||||
# include <openssl/des.h>
|
||||
# include <openssl/md4.h>
|
||||
# include <openssl/opensslv.h>
|
||||
|
||||
# if OPENSSL_VERSION_NUMBER < 0x00907001L
|
||||
# define DES_key_schedule des_key_schedule
|
||||
# define DES_cblock des_cblock
|
||||
# define DES_set_odd_parity des_set_odd_parity
|
||||
# define DES_set_key des_set_key
|
||||
# define DES_ecb_encrypt des_ecb_encrypt
|
||||
|
||||
/* This is how things were done in the old days */
|
||||
#define DESKEY(x) x
|
||||
#define DESKEYARG(x) x
|
||||
#else
|
||||
# define DESKEY(x) x
|
||||
# define DESKEYARG(x) x
|
||||
# else
|
||||
/* Modern version */
|
||||
#define DESKEYARG(x) *x
|
||||
#define DESKEY(x) &x
|
||||
# define DESKEYARG(x) *x
|
||||
# define DESKEY(x) &x
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Define this to make the type-3 message include the NT response message */
|
||||
@ -176,6 +182,25 @@ ntlm_input (struct ntlmdata *ntlm, const char *header)
|
||||
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
|
||||
* key schedule ks is also set.
|
||||
*/
|
||||
#ifdef HAVE_NETTLE
|
||||
static void
|
||||
setup_des_key(unsigned char *key_56,
|
||||
struct des_ctx *des)
|
||||
{
|
||||
unsigned char key[8];
|
||||
|
||||
key[0] = key_56[0];
|
||||
key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
|
||||
key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
|
||||
key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
|
||||
key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
|
||||
key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
|
||||
key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
|
||||
key[7] = (key_56[6] << 1) & 0xFF;
|
||||
|
||||
nettle_des_set_key(des, key);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
setup_des_key(unsigned char *key_56,
|
||||
DES_key_schedule DESKEYARG(ks))
|
||||
@ -194,6 +219,7 @@ setup_des_key(unsigned char *key_56,
|
||||
DES_set_odd_parity(&key);
|
||||
DES_set_key(&key, ks);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* takes a 21 byte array and treats it as 3 56-bit DES keys. The
|
||||
@ -203,6 +229,18 @@ setup_des_key(unsigned char *key_56,
|
||||
static void
|
||||
calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
|
||||
{
|
||||
#ifdef HAVE_NETTLE
|
||||
struct des_ctx des;
|
||||
|
||||
setup_des_key(keys, &des);
|
||||
nettle_des_encrypt(&des, 8, results, plaintext);
|
||||
|
||||
setup_des_key(keys + 7, &des);
|
||||
nettle_des_encrypt(&des, 8, results + 8, plaintext);
|
||||
|
||||
setup_des_key(keys + 14, &des);
|
||||
nettle_des_encrypt(&des, 8, results + 16, plaintext);
|
||||
#else
|
||||
DES_key_schedule ks;
|
||||
|
||||
setup_des_key(keys, DESKEY(ks));
|
||||
@ -216,6 +254,7 @@ calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
|
||||
setup_des_key(keys+14, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -255,6 +294,15 @@ mkhash(const char *password,
|
||||
|
||||
{
|
||||
/* create LanManager hashed password */
|
||||
#ifdef HAVE_NETTLE
|
||||
struct des_ctx des;
|
||||
|
||||
setup_des_key(pw, &des);
|
||||
nettle_des_encrypt(&des, 8, lmbuffer, magic);
|
||||
|
||||
setup_des_key(pw + 7, &des);
|
||||
nettle_des_encrypt(&des, 8, lmbuffer + 8, magic);
|
||||
#else
|
||||
DES_key_schedule ks;
|
||||
|
||||
setup_des_key(pw, DESKEY(ks));
|
||||
@ -264,6 +312,7 @@ mkhash(const char *password,
|
||||
setup_des_key(pw+7, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
#endif
|
||||
|
||||
memset(lmbuffer+16, 0, 5);
|
||||
}
|
||||
@ -272,8 +321,11 @@ mkhash(const char *password,
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
{
|
||||
/* create NT hashed password */
|
||||
#ifdef HAVE_NETTLE
|
||||
struct md4_ctx MD4;
|
||||
#else
|
||||
MD4_CTX MD4;
|
||||
#endif
|
||||
|
||||
len = strlen(password);
|
||||
|
||||
@ -282,9 +334,16 @@ mkhash(const char *password,
|
||||
pw[2*i+1] = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_NETTLE
|
||||
nettle_md4_init(&MD4);
|
||||
nettle_md4_update(&MD4, 2*len, pw);
|
||||
nettle_md4_digest(&MD4, MD4_DIGEST_SIZE, ntbuffer);
|
||||
#else
|
||||
/* create NT hashed password */
|
||||
MD4_Init(&MD4);
|
||||
MD4_Update(&MD4, pw, 2*len);
|
||||
MD4_Final(ntbuffer, &MD4);
|
||||
#endif
|
||||
|
||||
memset(ntbuffer+16, 0, 5);
|
||||
}
|
||||
|
125
src/http.c
125
src/http.c
@ -78,7 +78,7 @@ extern char *version_string;
|
||||
struct http_stat;
|
||||
static char *create_authorization_line (const char *, const char *,
|
||||
const char *, const char *,
|
||||
const char *, bool *);
|
||||
const char *, bool *, uerr_t *);
|
||||
static char *basic_authentication_encode (const char *, const char *);
|
||||
static bool known_authentication_scheme_p (const char *, const char *);
|
||||
static void ensure_extension (struct http_stat *, const char *, int *);
|
||||
@ -1860,12 +1860,6 @@ read_response_body (struct http_stat *hs, int sock, FILE *fp, wgint contlen,
|
||||
} while (0)
|
||||
#endif /* def __VMS [else] */
|
||||
|
||||
/* The flags that allow clobbering the file (opening with "wb").
|
||||
Defined here to avoid repetition later. #### This will require
|
||||
rework. */
|
||||
#define ALLOW_CLOBBER (opt.noclobber || opt.always_rest || opt.timestamping \
|
||||
|| opt.dirstruct || opt.output_document)
|
||||
|
||||
/* Retrieve a document through HTTP protocol. It recognizes status
|
||||
code, and correctly handles redirections. It closes the network
|
||||
socket. If it receives an error from the functions below it, it
|
||||
@ -2625,6 +2619,7 @@ read_header:
|
||||
if (pconn)
|
||||
pconn->authorized = false;
|
||||
#endif
|
||||
uerr_t auth_err = RETROK;
|
||||
if (!auth_finished && (user && passwd))
|
||||
{
|
||||
/* IIS sends multiple copies of WWW-Authenticate, one with
|
||||
@ -2652,28 +2647,44 @@ read_header:
|
||||
else if (!basic_auth_finished
|
||||
|| !BEGINS_WITH (www_authenticate, "Basic"))
|
||||
{
|
||||
char *pth;
|
||||
pth = url_full_path (u);
|
||||
request_set_header (req, "Authorization",
|
||||
create_authorization_line (www_authenticate,
|
||||
user, passwd,
|
||||
request_method (req),
|
||||
pth,
|
||||
&auth_finished),
|
||||
rel_value);
|
||||
if (BEGINS_WITH (www_authenticate, "NTLM"))
|
||||
ntlm_seen = true;
|
||||
else if (!u->user && BEGINS_WITH (www_authenticate, "Basic"))
|
||||
char *pth = url_full_path (u);
|
||||
const char *value;
|
||||
uerr_t *auth_stat;
|
||||
auth_stat = xmalloc (sizeof (uerr_t));
|
||||
*auth_stat = RETROK;
|
||||
|
||||
value = create_authorization_line (www_authenticate,
|
||||
user, passwd,
|
||||
request_method (req),
|
||||
pth,
|
||||
&auth_finished,
|
||||
auth_stat);
|
||||
|
||||
auth_err = *auth_stat;
|
||||
if (auth_err == RETROK)
|
||||
{
|
||||
/* Need to register this host as using basic auth,
|
||||
* so we automatically send creds next time. */
|
||||
register_basic_auth_host (u->host);
|
||||
request_set_header (req, "Authorization", value, rel_value);
|
||||
|
||||
if (BEGINS_WITH (www_authenticate, "NTLM"))
|
||||
ntlm_seen = true;
|
||||
else if (!u->user && BEGINS_WITH (www_authenticate, "Basic"))
|
||||
{
|
||||
/* Need to register this host as using basic auth,
|
||||
* so we automatically send creds next time. */
|
||||
register_basic_auth_host (u->host);
|
||||
}
|
||||
|
||||
xfree (pth);
|
||||
xfree_null (message);
|
||||
resp_free (resp);
|
||||
xfree (head);
|
||||
xfree (auth_stat);
|
||||
goto retry_with_auth;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Creating the Authorization header went wrong */
|
||||
}
|
||||
xfree (pth);
|
||||
xfree_null (message);
|
||||
resp_free (resp);
|
||||
xfree (head);
|
||||
goto retry_with_auth;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2681,13 +2692,16 @@ read_header:
|
||||
* give up. */
|
||||
}
|
||||
}
|
||||
logputs (LOG_NOTQUIET, _("Authorization failed.\n"));
|
||||
request_free (req);
|
||||
xfree_null (message);
|
||||
resp_free (resp);
|
||||
xfree (head);
|
||||
REGISTER_PERSISTENT_CONNECTION ();
|
||||
return AUTHFAILED;
|
||||
|
||||
if (auth_err == RETROK)
|
||||
return AUTHFAILED;
|
||||
else
|
||||
return auth_err;
|
||||
}
|
||||
else /* statcode != HTTP_STATUS_UNAUTHORIZED */
|
||||
{
|
||||
@ -3439,12 +3453,23 @@ Spider mode enabled. Check if remote file exists.\n"));
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
logprintf (LOG_NOTQUIET, _("Cannot write to %s (%s).\n"),
|
||||
quote (hstat.local_file), strerror (errno));
|
||||
case HOSTERR: case CONIMPOSSIBLE: case PROXERR: case AUTHFAILED:
|
||||
case SSLINITFAILED: case CONTNOTSUPPORTED: case VERIFCERTERR:
|
||||
case FILEBADFILE:
|
||||
case HOSTERR: case CONIMPOSSIBLE: case PROXERR: case SSLINITFAILED:
|
||||
case CONTNOTSUPPORTED: case VERIFCERTERR: case FILEBADFILE:
|
||||
case UNKNOWNATTR:
|
||||
/* Fatal errors just return from the function. */
|
||||
ret = err;
|
||||
goto exit;
|
||||
case ATTRMISSING:
|
||||
/* A missing attribute in a Header is a fatal Protocol error. */
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
logprintf (LOG_NOTQUIET, _("Required attribute missing from Header received.\n"));
|
||||
ret = err;
|
||||
goto exit;
|
||||
case AUTHFAILED:
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
logprintf (LOG_NOTQUIET, _("Username/Password Authentication Failed.\n"));
|
||||
ret = err;
|
||||
goto exit;
|
||||
case WARC_ERR:
|
||||
/* A fatal WARC error. */
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
@ -3983,7 +4008,7 @@ dump_hash (char *buf, const unsigned char *hash)
|
||||
static char *
|
||||
digest_authentication_encode (const char *au, const char *user,
|
||||
const char *passwd, const char *method,
|
||||
const char *path)
|
||||
const char *path, uerr_t *auth_err)
|
||||
{
|
||||
static char *realm, *opaque, *nonce, *qop, *algorithm;
|
||||
static struct {
|
||||
@ -4003,7 +4028,7 @@ digest_authentication_encode (const char *au, const char *user,
|
||||
param_token name, value;
|
||||
|
||||
|
||||
realm = opaque = nonce = qop = algorithm = NULL;
|
||||
realm = opaque = nonce = algorithm = qop = NULL;
|
||||
|
||||
au += 6; /* skip over `Digest' */
|
||||
while (extract_param (&au, &name, &value, ','))
|
||||
@ -4023,22 +4048,27 @@ digest_authentication_encode (const char *au, const char *user,
|
||||
if (qop != NULL && strcmp(qop,"auth"))
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("Unsupported quality of protection '%s'.\n"), qop);
|
||||
user = NULL; /* force freeing mem and return */
|
||||
xfree_null (qop); /* force freeing mem and return */
|
||||
qop = NULL;
|
||||
}
|
||||
|
||||
if (algorithm != NULL && strcmp (algorithm,"MD5") && strcmp (algorithm,"MD5-sess"))
|
||||
else if (algorithm != NULL && strcmp (algorithm,"MD5") && strcmp (algorithm,"MD5-sess"))
|
||||
{
|
||||
logprintf (LOG_NOTQUIET, _("Unsupported algorithm '%s'.\n"), algorithm);
|
||||
user = NULL; /* force freeing mem and return */
|
||||
xfree_null (qop); /* force freeing mem and return */
|
||||
qop = NULL;
|
||||
}
|
||||
|
||||
if (!realm || !nonce || !user || !passwd || !path || !method)
|
||||
if (!realm || !nonce || !user || !passwd || !path || !method || !qop)
|
||||
{
|
||||
xfree_null (realm);
|
||||
xfree_null (opaque);
|
||||
xfree_null (nonce);
|
||||
xfree_null (qop);
|
||||
xfree_null (algorithm);
|
||||
if (!qop)
|
||||
*auth_err = UNKNOWNATTR;
|
||||
else
|
||||
*auth_err = ATTRMISSING;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -4060,7 +4090,7 @@ digest_authentication_encode (const char *au, const char *user,
|
||||
|
||||
dump_hash (a1buf, hash);
|
||||
|
||||
if (! strcmp (algorithm, "MD5-sess"))
|
||||
if (algorithm && !strcmp (algorithm, "MD5-sess"))
|
||||
{
|
||||
/* A1BUF = H( H(user ":" realm ":" password) ":" nonce ":" cnonce ) */
|
||||
snprintf (cnonce, sizeof (cnonce), "%08x", random_number(INT_MAX));
|
||||
@ -4085,7 +4115,7 @@ digest_authentication_encode (const char *au, const char *user,
|
||||
md5_finish_ctx (&ctx, hash);
|
||||
dump_hash (a2buf, hash);
|
||||
|
||||
if (!strcmp(qop, "auth") || !strcmp (qop, "auth-int"))
|
||||
if (qop && (!strcmp(qop, "auth") || !strcmp (qop, "auth-int")))
|
||||
{
|
||||
/* RFC 2617 Digest Access Authentication */
|
||||
/* generate random hex string */
|
||||
@ -4135,7 +4165,7 @@ digest_authentication_encode (const char *au, const char *user,
|
||||
|
||||
res = xmalloc (res_size);
|
||||
|
||||
if (!strcmp(qop,"auth"))
|
||||
if (qop && !strcmp (qop, "auth"))
|
||||
{
|
||||
res_len = snprintf (res, res_size, "Digest "\
|
||||
"username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\""\
|
||||
@ -4160,6 +4190,13 @@ digest_authentication_encode (const char *au, const char *user,
|
||||
snprintf(res + res_len, res_size - res_len, ", algorithm=\"%s\"", algorithm);
|
||||
}
|
||||
}
|
||||
|
||||
xfree_null (realm);
|
||||
xfree_null (opaque);
|
||||
xfree_null (nonce);
|
||||
xfree_null (qop);
|
||||
xfree_null (algorithm);
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif /* ENABLE_DIGEST */
|
||||
@ -4201,7 +4238,7 @@ known_authentication_scheme_p (const char *hdrbeg, const char *hdrend)
|
||||
static char *
|
||||
create_authorization_line (const char *au, const char *user,
|
||||
const char *passwd, const char *method,
|
||||
const char *path, bool *finished)
|
||||
const char *path, bool *finished, uerr_t *auth_err)
|
||||
{
|
||||
/* We are called only with known schemes, so we can dispatch on the
|
||||
first letter. */
|
||||
@ -4213,7 +4250,7 @@ create_authorization_line (const char *au, const char *user,
|
||||
#ifdef ENABLE_DIGEST
|
||||
case 'D': /* Digest */
|
||||
*finished = true;
|
||||
return digest_authentication_encode (au, user, passwd, method, path);
|
||||
return digest_authentication_encode (au, user, passwd, method, path, auth_err);
|
||||
#endif
|
||||
|
||||
#if defined ENABLE_NTLM && defined ENABLE_THREADS
|
||||
|
@ -735,6 +735,9 @@ Recursive download:\n"),
|
||||
N_("\
|
||||
-k, --convert-links make links in downloaded HTML or CSS point to\n\
|
||||
local files.\n"),
|
||||
N_("\
|
||||
--backups=N before writing file X, rotate up to N backup files.\n"),
|
||||
|
||||
#ifdef __VMS
|
||||
N_("\
|
||||
-K, --backup-converted before converting file X, back up as X_orig.\n"),
|
||||
|
@ -251,24 +251,50 @@ ssl_init (void)
|
||||
return false;
|
||||
}
|
||||
|
||||
struct openssl_transport_context {
|
||||
struct openssl_transport_context
|
||||
{
|
||||
SSL *conn; /* SSL connection handle */
|
||||
char *last_error; /* last error printed with openssl_errstr */
|
||||
};
|
||||
|
||||
struct openssl_read_args
|
||||
{
|
||||
int fd;
|
||||
struct openssl_transport_context *ctx;
|
||||
char *buf;
|
||||
int bufsize;
|
||||
int retval;
|
||||
};
|
||||
|
||||
static void openssl_read_callback(void *arg)
|
||||
{
|
||||
struct openssl_read_args *args = (struct openssl_read_args *) arg;
|
||||
struct openssl_transport_context *ctx = args->ctx;
|
||||
SSL *conn = ctx->conn;
|
||||
char *buf = args->buf;
|
||||
int bufsize = args->bufsize;
|
||||
int ret;
|
||||
|
||||
do
|
||||
ret = SSL_read (conn, buf, bufsize);
|
||||
while (ret == -1 && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
|
||||
&& errno == EINTR);
|
||||
args->retval = ret;
|
||||
}
|
||||
|
||||
static int
|
||||
openssl_read (int fd, char *buf, int bufsize, void *arg)
|
||||
{
|
||||
int ret;
|
||||
struct openssl_transport_context *ctx = arg;
|
||||
SSL *conn = ctx->conn;
|
||||
do
|
||||
ret = SSL_read (conn, buf, bufsize);
|
||||
while (ret == -1
|
||||
&& SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
|
||||
&& errno == EINTR);
|
||||
struct openssl_read_args args;
|
||||
args.fd = fd;
|
||||
args.buf = buf;
|
||||
args.bufsize = bufsize;
|
||||
args.ctx = (struct openssl_transport_context*) arg;
|
||||
|
||||
return ret;
|
||||
if (run_with_timeout(opt.read_timeout, openssl_read_callback, &args)) {
|
||||
return -1;
|
||||
}
|
||||
return args.retval;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -386,6 +412,19 @@ static struct transport_implementation openssl_transport = {
|
||||
openssl_peek, openssl_errstr, openssl_close
|
||||
};
|
||||
|
||||
struct scwt_context
|
||||
{
|
||||
SSL *ssl;
|
||||
int result;
|
||||
};
|
||||
|
||||
static void
|
||||
ssl_connect_with_timeout_callback(void *arg)
|
||||
{
|
||||
struct scwt_context *ctx = (struct scwt_context *)arg;
|
||||
ctx->result = SSL_connect(ctx->ssl);
|
||||
}
|
||||
|
||||
/* Perform the SSL handshake on file descriptor FD, which is assumed
|
||||
to be connected to an SSL server. The SSL handle provided by
|
||||
OpenSSL is registered with the file descriptor FD using
|
||||
@ -398,6 +437,7 @@ bool
|
||||
ssl_connect_wget (int fd, const char *hostname)
|
||||
{
|
||||
SSL *conn;
|
||||
struct scwt_context scwt_ctx;
|
||||
struct openssl_transport_context *ctx;
|
||||
|
||||
DEBUGP (("Initiating SSL handshake.\n"));
|
||||
@ -425,7 +465,14 @@ ssl_connect_wget (int fd, const char *hostname)
|
||||
if (!SSL_set_fd (conn, FD_TO_SOCKET (fd)))
|
||||
goto error;
|
||||
SSL_set_connect_state (conn);
|
||||
if (SSL_connect (conn) <= 0 || conn->state != SSL_ST_OK)
|
||||
|
||||
scwt_ctx.ssl = conn;
|
||||
if (run_with_timeout(opt.read_timeout, ssl_connect_with_timeout_callback,
|
||||
&scwt_ctx)) {
|
||||
DEBUGP (("SSL handshake timed out.\n"));
|
||||
goto timeout;
|
||||
}
|
||||
if (scwt_ctx.result <= 0 || conn->state != SSL_ST_OK)
|
||||
goto error;
|
||||
|
||||
ctx = xnew0 (struct openssl_transport_context);
|
||||
@ -441,6 +488,7 @@ ssl_connect_wget (int fd, const char *hostname)
|
||||
error:
|
||||
DEBUGP (("SSL handshake failed.\n"));
|
||||
print_errors ();
|
||||
timeout:
|
||||
if (conn)
|
||||
SSL_free (conn);
|
||||
return false;
|
||||
|
@ -171,7 +171,7 @@ struct options
|
||||
bool timestamping; /* Whether to use time-stamping. */
|
||||
|
||||
bool backup_converted; /* Do we save pre-converted files as *.orig? */
|
||||
bool backups; /* Are numeric backups made? */
|
||||
int backups; /* Are numeric backups made? */
|
||||
|
||||
char *useragent; /* User-Agent string, which can be set
|
||||
to something other than Wget. */
|
||||
|
32
src/retr.c
32
src/retr.c
@ -44,6 +44,9 @@ as that of the covered work. */
|
||||
#ifdef ENABLE_METALINK
|
||||
#include <metalink/metalink_parser.h>
|
||||
#include <metalink/metalink_types.h>
|
||||
#ifdef VMS
|
||||
# include <unixio.h> /* For delete(). */
|
||||
#endif
|
||||
|
||||
#include "metalink.h"
|
||||
#endif
|
||||
@ -1434,7 +1437,16 @@ free_urlpos (struct urlpos *l)
|
||||
void
|
||||
rotate_backups(const char *fname)
|
||||
{
|
||||
int maxlen = strlen (fname) + 1 + numdigit (opt.backups) + 1;
|
||||
#ifdef __VMS
|
||||
# define SEP "_"
|
||||
# define AVS ";*" /* All-version suffix. */
|
||||
# define AVSL (sizeof (AVS) - 1)
|
||||
#else
|
||||
# define SEP "."
|
||||
# define AVSL 0
|
||||
#endif
|
||||
|
||||
int maxlen = strlen (fname) + sizeof (SEP) + numdigit (opt.backups) + AVSL;
|
||||
char *from = (char *)alloca (maxlen);
|
||||
char *to = (char *)alloca (maxlen);
|
||||
struct_stat sb;
|
||||
@ -1446,12 +1458,24 @@ rotate_backups(const char *fname)
|
||||
|
||||
for (i = opt.backups; i > 1; i--)
|
||||
{
|
||||
sprintf (from, "%s.%d", fname, i - 1);
|
||||
sprintf (to, "%s.%d", fname, i);
|
||||
#ifdef VMS
|
||||
/* Delete (all versions of) any existing max-suffix file, to avoid
|
||||
* creating multiple versions of it. (On VMS, rename() will
|
||||
* create a new version of an existing destination file, not
|
||||
* destroy/overwrite it.)
|
||||
*/
|
||||
if (i == opt.backups)
|
||||
{
|
||||
sprintf (to, "%s%s%d%s", fname, SEP, i, AVS);
|
||||
delete (to);
|
||||
}
|
||||
#endif
|
||||
sprintf (to, "%s%s%d", fname, SEP, i);
|
||||
sprintf (from, "%s%s%d", fname, SEP, i - 1);
|
||||
rename (from, to);
|
||||
}
|
||||
|
||||
sprintf (to, "%s.%d", fname, 1);
|
||||
sprintf (to, "%s%s%d", fname, SEP, 1);
|
||||
rename(fname, to);
|
||||
}
|
||||
|
||||
|
@ -1670,11 +1670,12 @@ url_file_name (const struct url *u, char *replaced_filename)
|
||||
2) Retrieval with regetting.
|
||||
3) Timestamping is used.
|
||||
4) Hierarchy is built.
|
||||
5) Backups are specified.
|
||||
|
||||
The exception is the case when file does exist and is a
|
||||
directory (see `mkalldirs' for explanation). */
|
||||
|
||||
if ((opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct)
|
||||
if (ALLOW_CLOBBER
|
||||
&& !(file_exists_p (fname) && !file_non_directory_p (fname)))
|
||||
{
|
||||
unique = fname;
|
||||
|
@ -47,6 +47,12 @@ as that of the covered work. */
|
||||
* file descriptor. */
|
||||
#define CHOMP_BUFFER 19
|
||||
|
||||
/* The flags that allow clobbering the file (opening with "wb").
|
||||
Defined here to avoid repetition later. #### This will require
|
||||
rework. */
|
||||
#define ALLOW_CLOBBER (opt.noclobber || opt.always_rest || opt.timestamping \
|
||||
|| opt.dirstruct || opt.output_document || opt.backups > 0)
|
||||
|
||||
/* Specifies how, or whether, user auth information should be included
|
||||
* in URLs regenerated from URL parse structures. */
|
||||
enum url_auth_mode {
|
||||
|
25
src/warc.c
25
src/warc.c
@ -738,8 +738,14 @@ warc_start_new_file (bool meta)
|
||||
char *new_filename = malloc (base_filename_length + 1 + 5 + 8 + 1);
|
||||
warc_current_filename = new_filename;
|
||||
|
||||
#ifdef __VMS
|
||||
# define WARC_GZ "warc-gz"
|
||||
#else /* def __VMS */
|
||||
# define WARC_GZ "warc.gz"
|
||||
#endif /* def __VMS [else] */
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
const char *extension = (opt.warc_compression_enabled ? "warc.gz" : "warc");
|
||||
const char *extension = (opt.warc_compression_enabled ? WARC_GZ : "warc");
|
||||
#else
|
||||
const char *extension = "warc";
|
||||
#endif
|
||||
@ -1153,6 +1159,21 @@ warc_tempfile (void)
|
||||
if (path_search (filename, 100, opt.warc_tempdir, "wget", true) == -1)
|
||||
return NULL;
|
||||
|
||||
#ifdef __VMS
|
||||
/* 2013-07-12 SMS.
|
||||
* mkostemp()+unlink()+fdopen() scheme causes trouble on VMS, so use
|
||||
* mktemp() to uniquify the (VMS-style) name, and then use a normal
|
||||
* fopen() with a "create temp file marked for delete" option.
|
||||
*/
|
||||
{
|
||||
char *tfn;
|
||||
|
||||
tfn = mktemp (filename); /* Get unique name from template. */
|
||||
if (tfn == NULL)
|
||||
return NULL;
|
||||
return fopen (tfn, "w+", "fop=tmd"); /* Create auto-delete temp file. */
|
||||
}
|
||||
#else /* def __VMS */
|
||||
int fd = mkostemp (filename, O_TEMPORARY);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
@ -1162,8 +1183,8 @@ warc_tempfile (void)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
|
||||
return fdopen (fd, "wb+");
|
||||
#endif /* def __VMS [else] */
|
||||
}
|
||||
|
||||
|
||||
|
@ -357,10 +357,9 @@ typedef enum
|
||||
PROXERR,
|
||||
/* 50 */
|
||||
AUTHFAILED, QUOTEXC, WRITEFAILED, SSLINITFAILED, VERIFCERTERR,
|
||||
UNLINKERR, NEWLOCATION_KEEP_POST, CLOSEFAILED, WARC_ERR,
|
||||
WARC_TMP_FOPENERR,
|
||||
UNLINKERR, NEWLOCATION_KEEP_POST, CLOSEFAILED, ATTRMISSING, UNKNOWNATTR,
|
||||
/* 60 */
|
||||
WARC_TMP_FWRITEERR, THREADS_ERR, SEM_ERR
|
||||
WARC_ERR, WARC_TMP_FOPENERR, WARC_TMP_FWRITEERR, THREADS_ERR, SEM_ERR
|
||||
} uerr_t;
|
||||
|
||||
struct range {
|
||||
|
Loading…
Reference in New Issue
Block a user