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.
This commit is contained in:
Yang Tse 2012-06-08 14:21:29 +02:00
parent 186b101deb
commit eeeba1496c
4 changed files with 178 additions and 206 deletions

View File

@ -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 */

View File

@ -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,151 +73,6 @@
return PARAM_NO_MEM; \
} WHILE_FALSE
#ifdef USE_GNUTLS_NETTLE
#include <nettle/md5.h>
#include <nettle/sha.h>
typedef struct md5_ctx MD5_CTX;
static void MD5_Init(MD5_CTX * ctx)
{
md5_init(ctx);
}
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)
{
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,
unsigned int inputLen)
{
sha1_update(ctx, inputLen, input);
}
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,
unsigned int inputLen)
{
sha256_update(ctx, inputLen, input);
}
static void SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
{
sha256_digest(ctx, 32, digest);
}
#else
#ifdef USE_GNUTLS
#include <gcrypt.h>
typedef gcry_md_hd_t MD5_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,
unsigned int inputLen)
{
gcry_md_write(*ctx, input, inputLen);
}
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)
{
gcry_md_open(ctx, GCRY_MD_SHA1, 0);
}
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)
{
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)
{
gcry_md_open(ctx, GCRY_MD_SHA256, 0);
}
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)
{
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,
@ -231,6 +103,145 @@ const digest_params SHA256_DIGEST_PARAMS[] = {
}
};
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}
};
#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,
unsigned int inputLen)
{
md5_update(ctx, inputLen, input);
}
static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
{
md5_digest(ctx, 16, digest);
}
static void SHA1_Init(SHA_CTX *ctx)
{
sha1_init(ctx);
}
static void SHA1_Update(SHA_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
{
sha1_update(ctx, inputLen, input);
}
static void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx)
{
sha1_digest(ctx, 20, digest);
}
static void SHA256_Init(SHA256_CTX *ctx)
{
sha256_init(ctx);
}
static void SHA256_Update(SHA256_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
{
sha256_update(ctx, inputLen, input);
}
static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
{
sha256_digest(ctx, 32, digest);
}
#elif defined(USE_GNUTLS)
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,
unsigned int inputLen)
{
gcry_md_write(*ctx, input, inputLen);
}
static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
{
memcpy(digest, gcry_md_read(*ctx, 0), 16);
gcry_md_close(*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)
{
gcry_md_write(*ctx, input, inputLen);
}
static void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx)
{
memcpy(digest, gcry_md_read(*ctx, 0), 20);
gcry_md_close(*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)
{
gcry_md_write(*ctx, input, inputLen);
}
static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
{
memcpy(digest, gcry_md_read(*ctx, 0), 32);
gcry_md_close(*ctx);
}
#endif /* CRYPTO LIBS */
digest_context *Curl_digest_init(const digest_params *dparams)
{
digest_context *ctxt;
@ -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.
*/

View File

@ -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 */

View File

@ -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 */