Date: Mon, 19 Aug 2013 20:48:15 GMT From: ambarisha@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r256169 - in soc2013/ambarisha/head/usr.bin: dmget dms Message-ID: <201308192048.r7JKmFw2031887@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ambarisha Date: Mon Aug 19 20:48:15 2013 New Revision: 256169 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=256169 Log: Added SHA1 and MD5 checksum verification The checksum file has to be passed using the -C switch for dmget Modified: soc2013/ambarisha/head/usr.bin/dmget/dm.h soc2013/ambarisha/head/usr.bin/dmget/dmget.c soc2013/ambarisha/head/usr.bin/dmget/fetch.c soc2013/ambarisha/head/usr.bin/dms/dm.h soc2013/ambarisha/head/usr.bin/dms/dms.c soc2013/ambarisha/head/usr.bin/dms/worker.c Modified: soc2013/ambarisha/head/usr.bin/dmget/dm.h ============================================================================== --- soc2013/ambarisha/head/usr.bin/dmget/dm.h Mon Aug 19 20:46:32 2013 (r256168) +++ soc2013/ambarisha/head/usr.bin/dmget/dm.h Mon Aug 19 20:48:15 2013 (r256169) @@ -6,10 +6,18 @@ #include <stdio.h> #include <fetch.h> +#include <openssl/sha.h> +#include <openssl/md5.h> /* TODO : Fix the path, make sure the perms on it are good */ #define DMS_UDS_PATH "/tmp/dms.uds" +#define NO_CHKSUM 0 +#define SHA1_CHKSUM 1 +#define MD5_CHKSUM 2 + +#define MAX_CHKSUM_LEN SHA_DIGEST_LENGTH /* TODO: Any better alternative? */ + struct dmres { int status; int errcode; @@ -24,8 +32,16 @@ off_t B_size; off_t S_size; long T_secs; - long flags; + int sha1; + char sha1sum[SHA_DIGEST_LENGTH]; + int chksum_type; + union { + char sha1sum[SHA_DIGEST_LENGTH]; + char md5sum[MD5_DIGEST_LENGTH]; + } chksum; + + long flags; #define A_FLAG (1 << 0) #define F_FLAG (1 << 1) #define O_STDOUT (1 << 2) Modified: soc2013/ambarisha/head/usr.bin/dmget/dmget.c ============================================================================== --- soc2013/ambarisha/head/usr.bin/dmget/dmget.c Mon Aug 19 20:46:32 2013 (r256168) +++ soc2013/ambarisha/head/usr.bin/dmget/dmget.c Mon Aug 19 20:48:15 2013 (r256169) @@ -96,11 +96,24 @@ static int mk_reqbuf(struct dmreq dmreq, char **reqbuf, char op) { - int bufsize = 0, i = 0; + int bufsize = 0, i = 0, csumlen = 0; + + switch(dmreq.chksum_type) { + case SHA1_CHKSUM: + csumlen = SHA_DIGEST_LENGTH; + break; + case MD5_CHKSUM: + csumlen = MD5_DIGEST_LENGTH; + break; + default: + break; + } bufsize += sizeof(bufsize); // Buffer size bufsize += 1; // Opcode - bufsize += sizeof(struct dmreq) - (3 * sizeof(char*)); // fix sizeof(dmreq) + bufsize += sizeof(struct dmreq); + bufsize -= (3 * sizeof(char*)) + sizeof(dmreq.chksum); // fix sizeof(dmreq) + bufsize += csumlen; bufsize += strlen(dmreq.i_filename) + 1; // bufsize += strlen(dmreq.URL) + 1; bufsize += strlen(dmreq.path) + 1; @@ -138,6 +151,22 @@ memcpy(*reqbuf + i, &(dmreq.T_secs), sizeof(dmreq.T_secs)); i += sizeof(dmreq.T_secs); + + memcpy(*reqbuf + i, &(dmreq.chksum_type), sizeof(dmreq.chksum_type)); + i += sizeof(dmreq.chksum_type); + + switch(dmreq.chksum_type) { + case SHA1_CHKSUM: + memcpy(*reqbuf + i, &(dmreq.chksum.sha1sum), SHA_DIGEST_LENGTH); + i += SHA_DIGEST_LENGTH; + break; + case MD5_CHKSUM: + memcpy(*reqbuf + i, &(dmreq.chksum.md5sum), MD5_DIGEST_LENGTH); + i += MD5_DIGEST_LENGTH; + break; + default: + break; + } memcpy(*reqbuf + i, &(dmreq.flags), sizeof(dmreq.flags)); i += sizeof(dmreq.flags); Modified: soc2013/ambarisha/head/usr.bin/dmget/fetch.c ============================================================================== --- soc2013/ambarisha/head/usr.bin/dmget/fetch.c Mon Aug 19 20:46:32 2013 (r256168) +++ soc2013/ambarisha/head/usr.bin/dmget/fetch.c Mon Aug 19 20:48:15 2013 (r256169) @@ -88,6 +88,9 @@ static long w_secs; /* -w: retry delay */ static int family = PF_UNSPEC; /* -[46]: address family to use */ +static int chksum_type = NO_CHKSUM; /* (SHA1/MD5/NO)_CHKSUM */ +static char chksum[MAX_CHKSUM_LEN]; + static int sigint; /* SIGINT received */ static long ftp_timeout = TIMEOUT; /* default timeout for FTP transfers */ @@ -264,6 +267,19 @@ if (i_flag) dmreq.i_filename = i_filename; else dmreq.i_filename = ""; + dmreq.chksum_type = chksum_type; + switch(chksum_type) { + case SHA1_CHKSUM: + memcpy(dmreq.chksum.sha1sum, chksum, SHA_DIGEST_LENGTH); + break; + case MD5_CHKSUM: + memcpy(dmreq.chksum.md5sum, chksum, MD5_DIGEST_LENGTH); + break; + default: + dmreq.chksum_type = NO_CHKSUM; + break; + } + dmreq.flags = 0; if (A_flag) dmreq.flags |= A_FLAG; if (F_flag) dmreq.flags |= F_FLAG; @@ -285,6 +301,37 @@ } static void +checksum(char *fn) +{ + FILE *f; + int ret, clen, i; + char csumstr[MAX_CHKSUM_LEN * 2]; + + f = fopen(fn, "r"); + ret = fread(csumstr, MAX_CHKSUM_LEN, 1, f); + if (ret == SHA_DIGEST_LENGTH * 2) { + chksum_type = SHA1_CHKSUM; + clen = SHA_DIGEST_LENGTH; + } else if (ret == MD5_DIGEST_LENGTH * 2) { + chksum_type = MD5_CHKSUM; + clen = MD5_DIGEST_LENGTH; + } else { + goto error; + } + + for (i = 0; i < clen; i++) { + if (sscanf(csumstr + (2 * i), "%2X", chksum + i) != 1) + goto error; + } + + return; + +error: + chksum_type = NO_CHKSUM; + return; +} + +static void usage(void) { fprintf(stderr, "%s\n%s\n%s\n%s\n", @@ -294,7 +341,6 @@ " [-T seconds] [-w seconds] [-i file] -h host -f file [-c dir]"); } - /* * Entry point */ @@ -308,7 +354,7 @@ int c, e, r; while ((c = getopt(argc, argv, - "146AaB:bc:dFf:Hh:i:lMmN:nPpo:qRrS:sT:tUvw:")) != -1) + "146AaB:bc:C:dFf:Hh:i:lMmN:nPpo:qRrS:sT:tUvw:")) != -1) switch (c) { case '1': once_flag = 1; @@ -337,6 +383,9 @@ case 'c': c_dirname = optarg; break; + case 'C': + checksum(optarg); + break; case 'd': d_flag = 1; break; Modified: soc2013/ambarisha/head/usr.bin/dms/dm.h ============================================================================== --- soc2013/ambarisha/head/usr.bin/dms/dm.h Mon Aug 19 20:46:32 2013 (r256168) +++ soc2013/ambarisha/head/usr.bin/dms/dm.h Mon Aug 19 20:48:15 2013 (r256169) @@ -6,10 +6,18 @@ #include <stdio.h> #include <fetch.h> +#include <openssl/sha.h> +#include <openssl/md5.h> /* TODO : Fix the path, make sure the perms on it are good */ #define DMS_UDS_PATH "/tmp/dms.uds" +#define NO_CHKSUM 0 +#define SHA1_CHKSUM 1 +#define MD5_CHKSUM 2 + +#define MAX_CHKSUM_LEN SHA_DIGEST_LENGTH /* TODO: Any better alternative? */ + struct dmres { int status; int errcode; @@ -24,8 +32,16 @@ off_t B_size; off_t S_size; long T_secs; - long flags; + int sha1; + char sha1sum[SHA_DIGEST_LENGTH]; + int chksum_type; + union { + char sha1sum[SHA_DIGEST_LENGTH]; + char md5sum[MD5_DIGEST_LENGTH]; + } chksum; + + long flags; #define A_FLAG (1 << 0) #define F_FLAG (1 << 1) #define O_STDOUT (1 << 2) Modified: soc2013/ambarisha/head/usr.bin/dms/dms.c ============================================================================== --- soc2013/ambarisha/head/usr.bin/dms/dms.c Mon Aug 19 20:46:32 2013 (r256168) +++ soc2013/ambarisha/head/usr.bin/dms/dms.c Mon Aug 19 20:48:15 2013 (r256169) @@ -170,7 +170,23 @@ memcpy(&(dmreq->T_secs), rcvbuf + i, sizeof(dmreq->T_secs)); i += sizeof(dmreq->T_secs); - + + memcpy(&(dmreq->chksum_type), rcvbuf + i, sizeof(dmreq->chksum_type)); + i += sizeof(dmreq->chksum_type); + + switch(dmreq->chksum_type) { + case SHA1_CHKSUM: + memcpy(dmreq->chksum.sha1sum, rcvbuf + i, SHA_DIGEST_LENGTH); + i += SHA_DIGEST_LENGTH; + break; + case MD5_CHKSUM: + memcpy(dmreq->chksum.md5sum, rcvbuf + i, MD5_DIGEST_LENGTH); + i += MD5_DIGEST_LENGTH; + break; + case NO_CHKSUM: + break; + } + memcpy(&(dmreq->flags), rcvbuf + i, sizeof(dmreq->flags)); i += sizeof(dmreq->flags); Modified: soc2013/ambarisha/head/usr.bin/dms/worker.c ============================================================================== --- soc2013/ambarisha/head/usr.bin/dms/worker.c Mon Aug 19 20:46:32 2013 (r256168) +++ soc2013/ambarisha/head/usr.bin/dms/worker.c Mon Aug 19 20:48:15 2013 (r256169) @@ -666,7 +666,7 @@ return (r); } -FILE * +static FILE * dmXGet(struct dmjob *dmjob, struct url_stat *us) { char flags[8]; @@ -676,12 +676,7 @@ struct dmreq *dmreq = dmjob->request; /* populate tmpjob */ - - /* TODO : Modify stat_* to udpate jobs of progress, - * right now we just put the msgs on stderr - * */ tmpjob.client = STDERR_FILENO; - tmpjob.request = &tmpreq; tmpreq.v_level = dmreq->v_level; tmpreq.ftp_timeout = dmjob->request->ftp_timeout; @@ -765,6 +760,52 @@ return f; } +static int +validate_and_copy(struct dmjob *dmjob, FILE *f, struct url_stat us) +{ + int ret, ret2; + SHA_CTX sha_ctx; + MD5_CTX md5_ctx; + char buf[1024], chksum[SHA_DIGEST_LENGTH]; /* TODO: MAX DIGEST LENGTH */ + + switch(dmjob->request->chksum_type) { + case SHA1_CHKSUM: + SHA1_Init(&sha_ctx); + + fseek(f, 0, SEEK_SET); + while ((ret = fread(buf, 1, 1024, f)) != 0) + SHA1_Update(&sha_ctx, buf, ret); + SHA1_Final(chksum, &sha_ctx); + + if (memcmp(chksum, dmjob->request->chksum.sha1sum, + SHA_DIGEST_LENGTH) != 0) { + fprintf(stderr, "dms: checksum missmatch\n"); + /* Notify the client of the same */ + return -1; + } + break; + case MD5_CHKSUM: + MD5_Init(&md5_ctx); + + fseek(f, 0, SEEK_SET); + while ((ret = fread(buf, 1, 1024, f)) != 0) + MD5_Update(&md5_ctx, buf, ret); + MD5_Final(chksum, &md5_ctx); + + if (memcmp(chksum, dmjob->request->chksum.md5sum, + MD5_DIGEST_LENGTH) != 0) { + fprintf(stderr, "dms: checksum mismatch\n"); + return -1; + } + break; + default: + break; + } + + fseek(f, 0, SEEK_SET); + return fetch(dmjob, f, us); +} + /* TODO: This handler isn't registered as SIGUSR1 interrupts the download * Figure out a proper way to handle this * */ @@ -892,8 +933,7 @@ if (f == NULL) { ret = -1; } else { - fseek(f, 0, SEEK_SET); - ret = fetch(dmjob, f, us); + ret = validate_and_copy(dmjob, f, us); } report.status = ret;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201308192048.r7JKmFw2031887>
