diff --git a/ChangeLog b/ChangeLog index cda41480..17d3ce0f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2001-11-29 Hrvoje Niksic + + * configure.in: Use SSL's MD5 if we're compiling with SSL anyway. + 2001-11-27 Hrvoje Niksic * configure.in: Don't check for random. diff --git a/configure.in b/configure.in index 1cc995a2..0ed629bf 100644 --- a/configure.in +++ b/configure.in @@ -189,23 +189,6 @@ dnl dnl Checks for libraries. dnl -dnl -dnl Use the md5 lib if available (Solaris). -dnl - -if test x$wget_need_md5 = xyes -then - AC_DEFINE(HAVE_MD5) - AC_CHECK_LIB(md5, MD5Update, [ - AC_DEFINE(HAVE_SOLARIS_MD5) - LIBS="-lmd5 $LIBS" - ], [ - MD5_OBJ='gnu-md5$o' - AC_DEFINE(HAVE_BUILTIN_MD5) - ]) -fi -AC_SUBST(MD5_OBJ) - dnl On Solaris, -lnsl is needed to use gethostbyname. On "NCR MP-RAS dnl 3.0", however, gethostbyname is in libc, but -lnsl is still needed dnl to use -lsocket, as well as for functions such as inet_ntoa. We @@ -353,6 +336,47 @@ main(){return 0;} CC=$wget_save_CC fi +dnl +dnl Find an md5 implementation. +dnl + +dnl On Solaris, we use libmd5. If we're compiled with OpenSSL, use +dnl OpenSSL's md5 support. Otherwise, use our own md5. + +if test x$wget_need_md5 = xyes +then + MD5_OBJ='gen-md5$o' + + found_md5=no + + dnl First check for Solaris md5. + if test x$found_md5 = xno; then + AC_CHECK_LIB(md5, MD5Update, [ + AC_DEFINE(HAVE_SOLARIS_MD5) + LIBS="-lmd5 $LIBS" + found_md5=yes + ]) + fi + + dnl Then see if we're linking OpenSSL anyway; if yes, use its md5 + dnl implementation. + if test x$found_md5 = xno; then + if test x$ssl_linked = xyes; then + AC_DEFINE(HAVE_OPENSSL_MD5) + found_md5=yes + fi + fi + + dnl If none of the above worked, use the builtin one. + if test x$found_md5 = xno; then + AC_DEFINE(HAVE_BUILTIN_MD5) + found_md5=yes + MD5_OBJ="$MD5_OBJ gnu-md5\$o" + fi +fi +AC_DEFINE(HAVE_MD5) +AC_SUBST(MD5_OBJ) + dnl dnl Set of available languages. dnl diff --git a/src/config.h.in b/src/config.h.in index 1364d27f..c6413d60 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -219,6 +219,9 @@ char *alloca (); /* Define if we're using Solaris libmd5. */ #undef HAVE_SOLARIS_MD5 +/* Define if we're using OpenSSL md5. */ +#undef HAVE_OPENSSL_MD5 + /* Define if we're using builtin (GNU) md5.c. */ #undef HAVE_BUILTIN_MD5 diff --git a/src/ftp-opie.c b/src/ftp-opie.c index c9c7d2b9..39c90986 100644 --- a/src/ftp-opie.c +++ b/src/ftp-opie.c @@ -28,6 +28,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #endif #include "wget.h" +#include "gen-md5.h" /* Dictionary for integer-word translations. */ static char Wp[2048][4] = { @@ -2151,16 +2152,16 @@ calculate_skey_response (int sequence, const char *seed, const char *pass) char key[8]; static char buf[33]; - MD5_CONTEXT_TYPE ctx; + ALLOCA_MD5_CONTEXT (ctx); unsigned long results[4]; /* #### this looks 32-bit-minded */ char *feed = (char *) alloca (strlen (seed) + strlen (pass) + 1); strcpy (feed, seed); strcat (feed, pass); - MD5_INIT (&ctx); - MD5_UPDATE (feed, strlen (feed), &ctx); - MD5_FINISH (&ctx, results); + gen_md5_init (ctx); + gen_md5_update (feed, strlen (feed), ctx); + gen_md5_finish (ctx, (unsigned char *)results); results[0] ^= results[2]; results[1] ^= results[3]; @@ -2168,9 +2169,9 @@ calculate_skey_response (int sequence, const char *seed, const char *pass) while (0 < sequence--) { - MD5_INIT (&ctx); - MD5_UPDATE (key, 8, &ctx); - MD5_FINISH (&ctx, results); + gen_md5_init (ctx); + gen_md5_update (key, 8, ctx); + gen_md5_finish (ctx, (unsigned char *)results); results[0] ^= results[2]; results[1] ^= results[3]; memcpy (key, (char *) results, 8); diff --git a/src/gen-md5.c b/src/gen-md5.c new file mode 100644 index 00000000..02bd479f --- /dev/null +++ b/src/gen-md5.c @@ -0,0 +1,108 @@ +/* General MD5 support. + Copyright (C) 2001 Free Software Foundation, Inc. + +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 2 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, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include +#include "wget.h" + +#include "gen-md5.h" + +#ifdef HAVE_BUILTIN_MD5 +# include +typedef struct md5_ctx gen_md5_context_imp; +#endif + +#ifdef HAVE_SOLARIS_MD5 +# include +typedef MD5_CTX gen_md5_context_imp; +#endif + +#ifdef HAVE_OPENSSL_MD5 +# include +typedef MD5_CTX gen_md5_context_imp; +#endif + +struct gen_md5_context { + gen_md5_context_imp imp; +}; + +/* Originally I planned for these to be macros, but that's very hard + because some of these MD5 implementations use the same names for + their types. For example, it is impossible to include and + on Solaris, because the latter includes its own MD5 + implementation, which clashes with . */ + +int +gen_md5_context_size (void) +{ + return sizeof (struct gen_md5_context); +} + +void +gen_md5_init (gen_md5_context *ctx) +{ + gen_md5_context_imp *ctx_imp = &ctx->imp; + +#ifdef HAVE_BUILTIN_MD5 + md5_init_ctx (ctx_imp); +#endif + +#ifdef HAVE_SOLARIS_MD5 + MD5Init (ctx_imp); +#endif + +#ifdef HAVE_OPENSSL_MD5 + MD5_Init (ctx_imp); +#endif +} + +void +gen_md5_update (unsigned const char *buffer, int len, gen_md5_context *ctx) +{ + gen_md5_context_imp *ctx_imp = &ctx->imp; + +#ifdef HAVE_BUILTIN_MD5 + md5_process_bytes (buffer, len, ctx_imp); +#endif + +#ifdef HAVE_SOLARIS_MD5 + MD5Update (ctx_imp, buffer, len); +#endif + +#ifdef HAVE_OPENSSL_MD5 + MD5_Update (ctx_imp, buffer, len); +#endif +} + +void +gen_md5_finish (gen_md5_context *ctx, unsigned char *result) +{ + gen_md5_context_imp *ctx_imp = &ctx->imp; + +#ifdef HAVE_BUILTIN_MD5 + md5_finish_ctx (ctx_imp, result); +#endif + +#ifdef HAVE_SOLARIS_MD5 + MD5Final (result, ctx_imp); +#endif + +#ifdef HAVE_OPENSSL_MD5 + MD5_Final (result, ctx_imp); +#endif +} diff --git a/src/gen-md5.h b/src/gen-md5.h new file mode 100644 index 00000000..85714380 --- /dev/null +++ b/src/gen-md5.h @@ -0,0 +1,32 @@ +/* General MD5 header file. + Copyright (C) 2001 Free Software Foundation, Inc. + +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 2 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, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +typedef struct gen_md5_context gen_md5_context; + +/* Use a forward declaration so we don't have to include any of the + includes. */ +struct gen_md5_context; + +#define ALLOCA_MD5_CONTEXT(var_name) \ + gen_md5_context *var_name = alloca (gen_md5_context_size ()) + +int gen_md5_context_size PARAMS ((void)); +void gen_md5_init PARAMS ((gen_md5_context *)); +void gen_md5_update PARAMS ((const unsigned char *, int, gen_md5_context *)); +void gen_md5_finish PARAMS ((gen_md5_context *, unsigned char *)); diff --git a/src/http.c b/src/http.c index 3f9d8b0a..2eae2f19 100644 --- a/src/http.c +++ b/src/http.c @@ -64,6 +64,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ # include "gen_sslfunc.h" #endif /* HAVE_SSL */ #include "cookies.h" +#ifdef USE_DIGEST +# include "gen-md5.h" +#endif extern char *version_string; @@ -2233,37 +2236,37 @@ digest_authentication_encode (const char *au, const char *user, /* Calculate the digest value. */ { - MD5_CONTEXT_TYPE ctx; + ALLOCA_MD5_CONTEXT (ctx); unsigned char hash[MD5_HASHLEN]; unsigned char a1buf[MD5_HASHLEN * 2 + 1], a2buf[MD5_HASHLEN * 2 + 1]; unsigned char response_digest[MD5_HASHLEN * 2 + 1]; /* A1BUF = H(user ":" realm ":" password) */ - MD5_INIT (&ctx); - MD5_UPDATE (user, strlen (user), &ctx); - MD5_UPDATE (":", 1, &ctx); - MD5_UPDATE (realm, strlen (realm), &ctx); - MD5_UPDATE (":", 1, &ctx); - MD5_UPDATE (passwd, strlen (passwd), &ctx); - MD5_FINISH (&ctx, hash); + gen_md5_init (ctx); + gen_md5_update (user, strlen (user), ctx); + gen_md5_update (":", 1, ctx); + gen_md5_update (realm, strlen (realm), ctx); + gen_md5_update (":", 1, ctx); + gen_md5_update (passwd, strlen (passwd), ctx); + gen_md5_finish (ctx, hash); dump_hash (a1buf, hash); /* A2BUF = H(method ":" path) */ - MD5_INIT (&ctx); - MD5_UPDATE (method, strlen (method), &ctx); - MD5_UPDATE (":", 1, &ctx); - MD5_UPDATE (path, strlen (path), &ctx); - MD5_FINISH (&ctx, hash); + gen_md5_init (ctx); + gen_md5_update (method, strlen (method), ctx); + gen_md5_update (":", 1, ctx); + gen_md5_update (path, strlen (path), ctx); + gen_md5_finish (ctx, hash); dump_hash (a2buf, hash); /* RESPONSE_DIGEST = H(A1BUF ":" nonce ":" A2BUF) */ - MD5_INIT (&ctx); - MD5_UPDATE (a1buf, MD5_HASHLEN * 2, &ctx); - MD5_UPDATE (":", 1, &ctx); - MD5_UPDATE (nonce, strlen (nonce), &ctx); - MD5_UPDATE (":", 1, &ctx); - MD5_UPDATE (a2buf, MD5_HASHLEN * 2, &ctx); - MD5_FINISH (&ctx, hash); + gen_md5_init (ctx); + gen_md5_update (a1buf, MD5_HASHLEN * 2, ctx); + gen_md5_update (":", 1, ctx); + gen_md5_update (nonce, strlen (nonce), ctx); + gen_md5_update (":", 1, ctx); + gen_md5_update (a2buf, MD5_HASHLEN * 2, ctx); + gen_md5_finish (ctx, hash); dump_hash (response_digest, hash); res = (char*) xmalloc (strlen (user) diff --git a/src/sysdep.h b/src/sysdep.h index 1c5deb1b..7ac88bc5 100644 --- a/src/sysdep.h +++ b/src/sysdep.h @@ -198,25 +198,4 @@ void *memcpy (); # define MAP_FAILED ((void *) -1) #endif -/* Define wrapper macros for different MD5 routines. */ -#ifdef HAVE_MD5 - -#ifdef HAVE_BUILTIN_MD5 -# include -# define MD5_CONTEXT_TYPE struct md5_ctx -# define MD5_INIT(ctx) md5_init_ctx (ctx) -# define MD5_UPDATE(buffer, len, ctx) md5_process_bytes (buffer, len, ctx) -# define MD5_FINISH(ctx, result) md5_finish_ctx (ctx, result) -#endif - -#ifdef HAVE_SOLARIS_MD5 -# include -# define MD5_CONTEXT_TYPE MD5_CTX -# define MD5_INIT(ctx) MD5Init (ctx) -# define MD5_UPDATE(buffer, len, ctx) MD5Update (ctx, (unsigned char *)(buffer), len) -# define MD5_FINISH(ctx, result) MD5Final ((unsigned char *)(result), ctx) -#endif - -#endif /* HAVE_MD5 */ - #endif /* SYSDEP_H */ diff --git a/src/utils.c b/src/utils.c index 44b73d69..e93846cb 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1772,9 +1772,11 @@ determine_screen_width (void) #endif /* TIOCGWINSZ */ } -#if 0 +#if 1 /* A debugging function for checking whether an MD5 library works. */ +#include "gen-md5.h" + char * debug_test_md5 (char *buf) { @@ -1783,11 +1785,11 @@ debug_test_md5 (char *buf) unsigned char *p1; char *p2; int cnt; - MD5_CONTEXT_TYPE ctx; + ALLOCA_MD5_CONTEXT (ctx); - MD5_INIT (&ctx); - MD5_UPDATE (buf, strlen (buf), &ctx); - MD5_FINISH (&ctx, raw); + gen_md5_init (ctx); + gen_md5_update (buf, strlen (buf), ctx); + gen_md5_finish (ctx, raw); p1 = raw; p2 = res;