socsvn commit: r256169 - in soc2013/ambarisha/head/usr.bin: dmget dms

ambarisha at FreeBSD.org ambarisha at FreeBSD.org
Mon Aug 19 20:48:16 UTC 2013


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;


More information about the svn-soc-all mailing list