From eeeba1496cbcac7aaffdd9355270d61582e98d3a Mon Sep 17 00:00:00 2001
From: Yang Tse <yangsita@gmail.com>
Date: Fri, 8 Jun 2012 14:21:29 +0200
Subject: [PATCH] metalink: build fixes and adjustments II

Additionally, make hash checking ability mandatory in order to allow metalink
support in curl.

A command line option could be introduced to skip hash checking at runtime,
but the ability to check hashes should always be built-in when providing
metalink support.
---
 src/tool_getparam.c |   2 +-
 src/tool_metalink.c | 241 ++++++++++++++++++++------------------------
 src/tool_metalink.h |  22 ++--
 src/tool_operate.c  |   3 +-
 4 files changed, 120 insertions(+), 148 deletions(-)

diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index cc01efb18a..ab8ed1d5e7 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -39,11 +39,11 @@
 #include "tool_help.h"
 #include "tool_helpers.h"
 #include "tool_libinfo.h"
+#include "tool_metalink.h"
 #include "tool_msgs.h"
 #include "tool_paramhlp.h"
 #include "tool_parsecfg.h"
 #include "tool_version.h"
-#include "tool_metalink.h"
 
 #include "memdebug.h" /* keep this as LAST include */
 
diff --git a/src/tool_metalink.c b/src/tool_metalink.c
index 375cdd3b29..1dfe32783d 100644
--- a/src/tool_metalink.c
+++ b/src/tool_metalink.c
@@ -21,26 +21,43 @@
  ***************************************************************************/
 #include "tool_setup.h"
 
-#ifdef HAVE_UNISTD_H
-#  include <unistd.h>
-#endif
-
-#include <sys/stat.h>
-
-#ifdef HAVE_FCNTL_H
-#  include <fcntl.h>
-#endif
-
 #ifdef USE_METALINK
 
 #include <metalink/metalink_parser.h>
 
+#ifdef USE_SSLEAY
+#  ifdef USE_OPENSSL
+#    include <openssl/md5.h>
+#    include <openssl/sha.h>
+#  else
+#    include <md5.h>
+#    include <sha.h>
+#  endif
+#elif defined(USE_GNUTLS_NETTLE)
+#  include <nettle/md5.h>
+#  include <nettle/sha.h>
+#  define MD5_CTX    struct md5_ctx
+#  define SHA_CTX    struct sha1_ctx
+#  define SHA256_CTX struct sha256_ctx
+#elif defined(USE_GNUTLS)
+#  include <gcrypt.h>
+#  define MD5_CTX    gcry_md_hd_t
+#  define SHA_CTX    gcry_md_hd_t
+#  define SHA256_CTX gcry_md_hd_t
+#else
+#  error "Can't compile METALINK support without a crypto library."
+#endif
+
 #include "rawstr.h"
 
-#include "tool_metalink.h"
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
 #include "tool_getparam.h"
 #include "tool_paramhlp.h"
 #include "tool_cfgable.h"
+#include "tool_metalink.h"
 
 #include "memdebug.h" /* keep this as LAST include */
 
@@ -56,180 +73,174 @@
     return PARAM_NO_MEM; \
 } WHILE_FALSE
 
-#ifdef USE_GNUTLS_NETTLE
+const digest_params MD5_DIGEST_PARAMS[] = {
+  {
+    (Curl_digest_init_func) MD5_Init,
+    (Curl_digest_update_func) MD5_Update,
+    (Curl_digest_final_func) MD5_Final,
+    sizeof(MD5_CTX),
+    16
+  }
+};
+
+const digest_params SHA1_DIGEST_PARAMS[] = {
+  {
+    (Curl_digest_init_func) SHA1_Init,
+    (Curl_digest_update_func) SHA1_Update,
+    (Curl_digest_final_func) SHA1_Final,
+    sizeof(SHA_CTX),
+    20
+  }
+};
+
+const digest_params SHA256_DIGEST_PARAMS[] = {
+  {
+    (Curl_digest_init_func) SHA256_Init,
+    (Curl_digest_update_func) SHA256_Update,
+    (Curl_digest_final_func) SHA256_Final,
+    sizeof(SHA256_CTX),
+    32
+  }
+};
+
+static const metalink_digest_def SHA256_DIGEST_DEF[] = {
+  {"sha-256", SHA256_DIGEST_PARAMS}
+};
 
-#include <nettle/md5.h>
-#include <nettle/sha.h>
+static const metalink_digest_def SHA1_DIGEST_DEF[] = {
+  {"sha-1", SHA1_DIGEST_PARAMS}
+};
 
-typedef struct md5_ctx MD5_CTX;
+static const metalink_digest_def MD5_DIGEST_DEF[] = {
+  {"md5", MD5_DIGEST_PARAMS}
+};
 
-static void MD5_Init(MD5_CTX * ctx)
+/*
+ * The alias of supported hash functions in the order by preference
+ * (basically stronger hash comes first). We included "sha-256" and
+ * "sha256". The former is the name defined in the IANA registry named
+ * "Hash Function Textual Names". The latter is widely (and
+ * historically) used in Metalink version 3.
+ */
+static const metalink_digest_alias digest_aliases[] = {
+  {"sha-256", SHA256_DIGEST_DEF},
+  {"sha256", SHA256_DIGEST_DEF},
+  {"sha-1", SHA1_DIGEST_DEF},
+  {"sha1", SHA1_DIGEST_DEF},
+  {"md5", MD5_DIGEST_DEF},
+  {NULL, NULL}
+};
+
+#ifdef USE_GNUTLS_NETTLE
+
+static void MD5_Init(MD5_CTX *ctx)
 {
   md5_init(ctx);
 }
 
-static void MD5_Update(MD5_CTX * ctx,
-                       const unsigned char * input,
+static void MD5_Update(MD5_CTX *ctx,
+                       const unsigned char *input,
                        unsigned int inputLen)
 {
   md5_update(ctx, inputLen, input);
 }
 
-static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
 {
   md5_digest(ctx, 16, digest);
 }
 
-typedef struct sha1_ctx SHA_CTX;
-
 static void SHA1_Init(SHA_CTX *ctx)
 {
   sha1_init(ctx);
 }
 
 static void SHA1_Update(SHA_CTX *ctx,
-                        const unsigned char * input,
+                        const unsigned char *input,
                         unsigned int inputLen)
 {
   sha1_update(ctx, inputLen, input);
 }
 
-static void SHA1_Final(unsigned char digest[20], SHA_CTX * ctx)
+static void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx)
 {
   sha1_digest(ctx, 20, digest);
 }
 
-typedef struct sha256_ctx SHA256_CTX;
-
 static void SHA256_Init(SHA256_CTX *ctx)
 {
   sha256_init(ctx);
 }
 
 static void SHA256_Update(SHA256_CTX *ctx,
-                          const unsigned char * input,
+                          const unsigned char *input,
                           unsigned int inputLen)
 {
   sha256_update(ctx, inputLen, input);
 }
 
-static void SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
+static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
 {
   sha256_digest(ctx, 32, digest);
 }
 
-#else
-
-#ifdef USE_GNUTLS
-
-#include <gcrypt.h>
+#elif defined(USE_GNUTLS)
 
-typedef gcry_md_hd_t MD5_CTX;
-
-static void MD5_Init(MD5_CTX * ctx)
+static void MD5_Init(MD5_CTX *ctx)
 {
   gcry_md_open(ctx, GCRY_MD_MD5, 0);
 }
 
-static void MD5_Update(MD5_CTX * ctx,
-                       const unsigned char * input,
+static void MD5_Update(MD5_CTX *ctx,
+                       const unsigned char *input,
                        unsigned int inputLen)
 {
   gcry_md_write(*ctx, input, inputLen);
 }
 
-static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
 {
   memcpy(digest, gcry_md_read(*ctx, 0), 16);
   gcry_md_close(*ctx);
 }
 
-typedef gcry_md_hd_t SHA_CTX;
-
-static void SHA1_Init(SHA_CTX * ctx)
+static void SHA1_Init(SHA_CTX *ctx)
 {
   gcry_md_open(ctx, GCRY_MD_SHA1, 0);
 }
 
-static void SHA1_Update(SHA_CTX * ctx,
-                       const unsigned char * input,
-                       unsigned int inputLen)
+static void SHA1_Update(SHA_CTX *ctx,
+                        const unsigned char *input,
+                        unsigned int inputLen)
 {
   gcry_md_write(*ctx, input, inputLen);
 }
 
-static void SHA1_Final(unsigned char digest[20], SHA_CTX * ctx)
+static void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx)
 {
   memcpy(digest, gcry_md_read(*ctx, 0), 20);
   gcry_md_close(*ctx);
 }
 
-typedef gcry_md_hd_t SHA256_CTX;
-
-static void SHA256_Init(SHA256_CTX * ctx)
+static void SHA256_Init(SHA256_CTX *ctx)
 {
   gcry_md_open(ctx, GCRY_MD_SHA256, 0);
 }
 
-static void SHA256_Update(SHA256_CTX * ctx,
-                       const unsigned char * input,
-                       unsigned int inputLen)
+static void SHA256_Update(SHA256_CTX *ctx,
+                          const unsigned char *input,
+                          unsigned int inputLen)
 {
   gcry_md_write(*ctx, input, inputLen);
 }
 
-static void SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
+static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
 {
   memcpy(digest, gcry_md_read(*ctx, 0), 32);
   gcry_md_close(*ctx);
 }
 
-#else
-
-#ifdef USE_OPENSSL
-#  include <openssl/md5.h>
-#  include <openssl/sha.h>
-#else /* USE_OPENSSL */
-
-/* TODO hash functions for other libraries here */
-
-#endif /* USE_OPENSSL */
-
-#endif /* USE_GNUTLS */
-
-#endif /* USE_GNUTLS_NETTLE */
-
-#ifdef METALINK_HASH_CHECK
-
-const digest_params MD5_DIGEST_PARAMS[] = {
-  {
-    (Curl_digest_init_func) MD5_Init,
-    (Curl_digest_update_func) MD5_Update,
-    (Curl_digest_final_func) MD5_Final,
-    sizeof(MD5_CTX),
-    16
-  }
-};
-
-const digest_params SHA1_DIGEST_PARAMS[] = {
-  {
-    (Curl_digest_init_func) SHA1_Init,
-    (Curl_digest_update_func) SHA1_Update,
-    (Curl_digest_final_func) SHA1_Final,
-    sizeof(SHA_CTX),
-    20
-  }
-};
-
-const digest_params SHA256_DIGEST_PARAMS[] = {
-  {
-    (Curl_digest_init_func) SHA256_Init,
-    (Curl_digest_update_func) SHA256_Update,
-    (Curl_digest_final_func) SHA256_Final,
-    sizeof(SHA256_CTX),
-    32
-  }
-};
+#endif /* CRYPTO LIBS */
 
 digest_context *Curl_digest_init(const digest_params *dparams)
 {
@@ -274,34 +285,6 @@ int Curl_digest_final(digest_context *context, unsigned char *result)
   return 0;
 }
 
-static const metalink_digest_def SHA256_DIGEST_DEF[] = {
-  {"sha-256", SHA256_DIGEST_PARAMS}
-};
-
-static const metalink_digest_def SHA1_DIGEST_DEF[] = {
-  {"sha-1", SHA1_DIGEST_PARAMS}
-};
-
-static const metalink_digest_def MD5_DIGEST_DEF[] = {
-  {"md5", MD5_DIGEST_PARAMS}
-};
-
-/*
- * The alias of supported hash functions in the order by preference
- * (basically stronger hash comes first). We included "sha-256" and
- * "sha256". The former is the name defined in the IANA registry named
- * "Hash Function Textual Names". The latter is widely (and
- * historically) used in Metalink version 3.
- */
-static const metalink_digest_alias digest_aliases[] = {
-  {"sha-256", SHA256_DIGEST_DEF},
-  {"sha256", SHA256_DIGEST_DEF},
-  {"sha-1", SHA1_DIGEST_DEF},
-  {"sha1", SHA1_DIGEST_DEF},
-  {"md5", MD5_DIGEST_DEF},
-  {NULL, NULL}
-};
-
 static unsigned char hex_to_uint(const char *s)
 {
   int v[2];
@@ -414,10 +397,6 @@ int metalink_check_hash(struct Configurable *config,
   return rv;
 }
 
-#endif /* METALINK_HASH_CHECK */
-
-#ifdef USE_METALINK
-
 static metalink_checksum *new_metalink_checksum(const char *hash_name,
                                                 const char *hash_value)
 {
@@ -538,8 +517,6 @@ int parse_metalink(struct Configurable *config, const char *infile)
   return 0;
 }
 
-#endif /* USE_METALINK */
-
 /*
  * Returns nonzero if content_type includes mediatype.
  */
diff --git a/src/tool_metalink.h b/src/tool_metalink.h
index c38240241d..3ce1fe2f99 100644
--- a/src/tool_metalink.h
+++ b/src/tool_metalink.h
@@ -23,13 +23,6 @@
  ***************************************************************************/
 #include "tool_setup.h"
 
-struct Configurable;
-
-#if defined(USE_OPENSSL) || defined(USE_GNUTLS)
-/* Define 1 if hash check is enabled in Metalink transfer */
-#  define METALINK_HASH_CHECK 1
-#endif
-
 typedef struct metalink_checksum {
   struct metalink_checksum *next;
   char *hash_name;
@@ -49,17 +42,13 @@ typedef struct metalinkfile {
   metalink_resource *resource;
 } metalinkfile;
 
+#ifdef USE_METALINK
+
 /*
  * Counts the resource in the metalinkfile.
  */
-#ifdef USE_METALINK
 int count_next_metalink_resource(metalinkfile *mlfile);
 void clean_metalink(struct Configurable *config);
-#else
-#define count_next_metalink_resource(x) 0
-#define clean_metalink(x)
-#endif
-
 
 int parse_metalink(struct Configurable *config, const char *infile);
 
@@ -126,4 +115,11 @@ int metalink_check_hash(struct Configurable *config,
                         metalinkfile *mlfile,
                         const char *filename);
 
+#else /* USE_METALINK */
+
+#define count_next_metalink_resource(x)  0
+#define clean_metalink(x)  Curl_nop_stmt
+
+#endif /* USE_METALINK */
+
 #endif /* HEADER_CURL_TOOL_METALINK_H */
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 2da92ca440..d01e383269 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -65,6 +65,7 @@
 #include "tool_homedir.h"
 #include "tool_libinfo.h"
 #include "tool_main.h"
+#include "tool_metalink.h"
 #include "tool_msgs.h"
 #include "tool_operate.h"
 #include "tool_operhlp.h"
@@ -1577,14 +1578,12 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
               fprintf(config->errors, "Could not parse Metalink file.\n");
           }
         }
-#  ifdef METALINK_HASH_CHECK
         else if(metalink && res == CURLE_OK && !metalink_next_res) {
           int rv = metalink_check_hash(config, mlfile, outs.filename);
           if(rv == 0) {
             metalink_next_res = 1;
           }
         }
-#  endif /* METALINK_HASH_CHECK */
 #endif /* USE_METALINK */
 
         /* No more business with this output struct */
-- 
GitLab