Initial attempt at verifying hashes. - not working

This commit is contained in:
Ilim Ugur 2012-08-03 20:47:31 +03:00
parent 8cfac52713
commit 98db799759
8 changed files with 135 additions and 15 deletions

View File

@ -49,6 +49,7 @@ maintainer-makefile
mbtowc
mkdir
crypto/md5
crypto/sha1
pipe
quote
quotearg

View File

@ -193,7 +193,7 @@ static const struct {
#endif
{ "input", &opt.input_filename, cmd_file },
{ "iri", &opt.enable_iri, cmd_boolean },
#ifdef HAVE_SSL
#ifdef ENABLE_THREADS
{ "jobs", &opt.jobs, cmd_number },
#endif
{ "keepsessioncookies", &opt.keep_session_cookies, cmd_boolean },
@ -265,6 +265,9 @@ static const struct {
{ "useragent", NULL, cmd_spec_useragent },
{ "useservertimestamps", &opt.useservertimestamps, cmd_boolean },
{ "verbose", NULL, cmd_spec_verbose },
#ifdef ENABLE_METALINK
{ "verify", &opt.hashtype, cmd_string },
#endif
{ "wait", &opt.wait, cmd_time },
{ "waitretry", &opt.waitretry, cmd_time },
#ifdef USE_WATT32

View File

@ -287,6 +287,9 @@ static struct cmdline_option option_data[] =
{ "user-agent", 'U', OPT_VALUE, "useragent", -1 },
{ "verbose", 'v', OPT_BOOLEAN, "verbose", -1 },
{ "verbose", 0, OPT_BOOLEAN, "verbose", -1 },
#ifdef ENABLE_METALINK
{ "verify", 0, OPT_VALUE, "verify", -1 },
#endif
{ "version", 'V', OPT_FUNCALL, (void *) print_version, no_argument },
{ "wait", 'w', OPT_VALUE, "wait", -1 },
{ "waitretry", 0, OPT_VALUE, "waitretry", -1 },
@ -535,7 +538,10 @@ Download:\n"),
N_("\
--unlink remove file before clobber.\n"),
"\n",
#ifdef ENABLE_METALINK
N_("\
--verify specify hash type to verify the downloaded files. (Works only with metalink downloads for now)\n"),
#endif
N_("\
Directories:\n"),
N_("\

View File

@ -1,7 +1,26 @@
#include <stdlib.h>
#include <string.h>
#include <metalink/metalink_parser.h>
#include <metalink/metalink_types.h>
#include "wget.h"
#include "log.h"
#include "md5.h"
#include "sha1.h"
#include "metalink.h"
#define HASH_TYPES 2
#define MAX_DIGEST_VALUE 1024
static char supported_hashes[HASH_TYPES][5] = {"md5", "sha1"};
int digest_values[HASH_TYPES] = {MD5_DIGEST_SIZE, SHA1_DIGEST_SIZE};
int (*hash_function[HASH_TYPES]) (FILE *, void *);
/* Parses metalink into type metalink_t and returns a pointer to it.
Returns NULL if the parsing is failed. */
metalink_t*
metalink_context (const char *url)
{
@ -11,8 +30,81 @@ metalink_context (const char *url)
err = metalink_parse_file (url, &metalink);
if(err != 0)
{
return NULL;
}
return metalink;
}
/* Function checks the hashes of files based on the given values
in metalink file.
Its return values are;
-1 no comparisons could be made. Possible reasons include;
- Hash format entered to opt.hashtype is not supported.
- Metalink file does not contain the desired/supported hash type(s)
0 if at least 1 hash comparisons are made and all turned out to be equal.
1 if at least 1 hash comparison turned out to be different */
int
verify_hash(FILE *file, char *type, metalink_checksum_t **checksums)
{
int i, j, h, t=-2, res = 0, comparisons = 0;
unsigned char hash[MAX_DIGEST_VALUE];
hash_function[0] = md5_stream;
hash_function[1] = sha1_stream;
for(i = 0; i < HASH_TYPES; ++i)
if(!strcmp(type, supported_hashes[i]))
{
t=i;
break;
}
if (t < 0)
{
if(strcmp(type, "all"))
{
/* Entered hash type is not supported. Print out an error message and
exit appropriately. */
}
else
t = -1;
}
for (i = 0; checksums[i] != NULL; ++i)
{
/* Pick the hash function and digest value to use. */
if(t<0)
{
/* If any supported hash is asked to be inspected, then find if
type of checksums [i] is supported and in what index the relevant
function is. */
for(j = 0; j < HASH_TYPES; ++j)
if(!strcmp(checksums[i]->type, supported_hashes[j]))
{
h = j;
break;
}
/*checksums[i] has a hash type that is not supported. Skip it.*/
if(h < 0)
continue;
}
else if(strcmp(checksums[i]->type, type))
continue;
else
h = t;
(*hash_function[h]) (file, hash);
++comparisons;
if (memcmp(hash, checksums[i]->hash, digest_values[h]))
{
res = 1;
break;
}
else if(opt.verbose)
logprintf (LOG_NOTQUIET, _("%s checksum verified.\n"), checksums[i]->type);
}
if(comparisons)
return res;
else
return -1;
}

View File

@ -34,4 +34,6 @@ as that of the covered work. */
metalink_t *metalink_context (const char *);
int verify_hash(FILE *, char *, metalink_checksum_t **);
#endif /* MLINK_H */

View File

@ -58,19 +58,14 @@ struct s_thread_ctx
uerr_t status;
};
int
spawn_thread (struct s_thread_ctx*, char *, int, int);
int spawn_thread (struct s_thread_ctx*, char *, int, int);
int
collect_thread (sem_t *, struct s_thread_ctx *);
int collect_thread (sem_t *, struct s_thread_ctx *);
static void *
segmented_retrieve_url (void *);
static void * segmented_retrieve_url (void *);
void
merge_temp_files(const char *, int);
void merge_temp_files(const char *, int);
void
delete_temp_files(const char *, int);
void delete_temp_files(const char *, int);
#endif /* MULTI_H */

View File

@ -260,6 +260,9 @@ struct options
#ifdef ENABLE_THREADS
int jobs; /* How many threads use at the same time. */
#endif
#ifdef ENABLE_METALINK
char *hashtype;
#endif
};
extern struct options opt;

View File

@ -1177,8 +1177,26 @@ retrieve_from_file (const char *file, bool html, int *count)
}
else
{
++*count;
FILE *out;
int res;
merge_temp_files(file->name, N_THREADS);
if((out = fopen(file->name, "r")) == NULL)
{
/*FIXME: file could not be opened.*/
}
if(res = verify_hash(out, opt.hashtype, file->checksums))
++*count;
else if(res > 0)
{
/* File is corrupt. Print a message and go on. */
/* TODO: Improving the interoption dependencies to help retrying to
download a file, by just putting here a something similar to;
if(tries < N)
--i; */
}
fclose(out);
}
delete_temp_files(file->name, N_THREADS);