diff options
author | Mike Fulbright <msf@redhat.com> | 2003-03-20 22:43:10 +0000 |
---|---|---|
committer | Mike Fulbright <msf@redhat.com> | 2003-03-20 22:43:10 +0000 |
commit | 720f69db5a6df4a3d6afe90ea228b5a90fe41333 (patch) | |
tree | 45e350ddecfcfd5fd9aec0ba89c46a2e84c2b8d9 /isomd5sum | |
parent | 67b207a86792001ee078517cdca387ef3cdde3ac (diff) | |
download | anaconda-720f69db5a6df4a3d6afe90ea228b5a90fe41333.tar.gz anaconda-720f69db5a6df4a3d6afe90ea228b5a90fe41333.tar.xz anaconda-720f69db5a6df4a3d6afe90ea228b5a90fe41333.zip |
splitting up implant stuff so I can make a python binding for tim
Diffstat (limited to 'isomd5sum')
-rw-r--r-- | isomd5sum/Makefile | 6 | ||||
-rw-r--r-- | isomd5sum/checkisomd5.c | 303 | ||||
-rw-r--r-- | isomd5sum/implantisomd5.c | 197 | ||||
-rw-r--r-- | isomd5sum/libcheckisomd5.c | 307 | ||||
-rw-r--r-- | isomd5sum/libcheckisomd5.h | 6 | ||||
-rw-r--r-- | isomd5sum/libimplantisomd5.c | 204 | ||||
-rw-r--r-- | isomd5sum/libimplantisomd5.h | 5 | ||||
-rw-r--r-- | isomd5sum/md5.c | 2 |
8 files changed, 536 insertions, 494 deletions
diff --git a/isomd5sum/Makefile b/isomd5sum/Makefile index 1a3995508..3166c654e 100644 --- a/isomd5sum/Makefile +++ b/isomd5sum/Makefile @@ -2,8 +2,10 @@ include ../Makefile.inc all: gcc -c -O -g -D_FILE_OFFSET_BITS=64 md5.c - gcc -O -g -D_FILE_OFFSET_BITS=64 -o implantisomd5 implantisomd5.c md5.o -lm -lpopt - gcc -O -g -D_FILE_OFFSET_BITS=64 -o checkisomd5 checkisomd5.c md5.o -lm + gcc -c -O -g -D_FILE_OFFSET_BITS=64 libimplantisomd5.c + gcc -O -g -D_FILE_OFFSET_BITS=64 -o implantisomd5 implantisomd5.c libimplantisomd5.o md5.o -lm -lpopt + gcc -c -O -g -D_FILE_OFFSET_BITS=64 libcheckisomd5.c + gcc -O -g -D_FILE_OFFSET_BITS=64 -o checkisomd5 checkisomd5.c libcheckisomd5.o md5.o -lm install: install -m 755 implantisomd5 $(DESTDIR)/$(RUNTIMEDIR) diff --git a/isomd5sum/checkisomd5.c b/isomd5sum/checkisomd5.c index 5ef184a86..177d10ef4 100644 --- a/isomd5sum/checkisomd5.c +++ b/isomd5sum/checkisomd5.c @@ -3,310 +3,9 @@ /* Michael Fulbright msf@redhat.com */ #include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> #include "md5.h" - -#define APPDATA_OFFSET 883 -#define SIZE_OFFSET 84 - -#define MAX(x, y) ((x > y) ? x : y) -#define MIN(x, y) ((x < y) ? x : y) - -/* finds primary volume descriptor and returns info from it */ -/* mediasum must be a preallocated buffer at least 33 bytes long */ -int parsepvd(int isofd, char *mediasum, int *skipsectors, long long *isosize, int *supported) { - unsigned char buf[2048]; - unsigned char buf2[512]; - unsigned char tmpbuf[512]; - int skipfnd, md5fnd, supportedfnd; - unsigned int loc; - long long offset; - unsigned char *p; - - *supported = 0; - - if (lseek(isofd, (off_t)(16L * 2048L), SEEK_SET) == -1) - return ((long long)-1); - - offset = (16L * 2048L); - for (;1;) { - if (read(isofd, buf, 2048) <=0) - return ((long long)-1); - - if (buf[0] == 1) - /* found primary volume descriptor */ - break; - else if (buf[0] == 255) - /* hit end and didn't find primary volume descriptor */ - return ((long long)-1); - offset += 2048L; - } - - /* read out md5sum */ - memcpy(buf2, buf + APPDATA_OFFSET, 512); - buf2[511] = '\0'; - - md5fnd = 0; - skipfnd = 0; - supportedfnd = 0; - loc = 0; - while (loc < 512) { - if (!strncmp(buf2 + loc, "ISO MD5SUM = ", 13)) { - - /* make sure we dont walk off end */ - if ((loc + 32) > 511) - return -1; - - memcpy(mediasum, buf2 + loc + 13, 32); - mediasum[32] = '\0'; - md5fnd = 1; - loc += 45; - for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++); - } else if (!strncmp(buf2 + loc, "SKIPSECTORS = ", 14)) { - char *errptr; - - /* make sure we dont walk off end */ - if ((loc + 14) > 511) - return -1; - - loc = loc + 14; - for (p=tmpbuf; buf2[loc] != ';' && loc < 512; p++, loc++) - *p = buf2[loc]; - - *p = '\0'; - - *skipsectors = strtol(tmpbuf, &errptr, 10); - if (errptr && *errptr) { - return -1; - } else { - skipfnd = 1; - } - - for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++); - } else if (!strncmp(buf2 + loc, "RHLISOSTATUS=1", 14)) { - *supported = 1; - supportedfnd = 1; - } else if (!strncmp(buf2 + loc, "RHLISOSTATUS=0", 14)) { - *supported = 0; - supportedfnd = 1; - } else { - loc++; - } - - if ((skipfnd & md5fnd) & supportedfnd) - break; - } - - - if (!(skipfnd & md5fnd)) - return -1; - - /* get isosize */ - *isosize = (buf[SIZE_OFFSET]*0x1000000+buf[SIZE_OFFSET+1]*0x10000 + - buf[SIZE_OFFSET+2]*0x100 + buf[SIZE_OFFSET+3]) * 2048LL; - - return offset; -} - -/* returns -1 if no checksum encoded in media, 0 if no match, 1 if match */ -/* mediasum is the sum encoded in media, computedsum is one we compute */ -/* both strings must be pre-allocated at least 33 chars in length */ -int checkmd5sum(int isofd, char *mediasum, char *computedsum) { - int nread; - int i; - int appdata_start_offset, appdata_end_offset; - int nattempt; - int skipsectors; - int supported; - unsigned int bufsize = 32768; - unsigned char md5sum[16]; - unsigned int len; - unsigned char *buf; - long long isosize, offset, pvd_offset, apoff; - MD5_CTX md5ctx; - - if ((pvd_offset = parsepvd(isofd, mediasum, &skipsectors, &isosize, &supported)) < 0) - return -1; - - /* printf("Mediasum = %s\n",mediasum); */ - - /* rewind, compute md5sum */ - lseek(isofd, 0L, SEEK_SET); - - MD5_Init(&md5ctx); - - offset = 0; - apoff = pvd_offset + APPDATA_OFFSET; - - buf = malloc(bufsize * sizeof(unsigned char)); - printf("Percent complete: %05.1f%%", (100.0*offset)/(isosize-skipsectors*2048.0)); - fflush(stdout); - while (offset < isosize - skipsectors*2048) { - nattempt = MIN(isosize - skipsectors*2048 - offset, bufsize); - - /* printf("%lld %lld %lld %d\n", offset, isosize, isosize-SKIPSECTORS*2048, nattempt); */ - - nread = read(isofd, buf, nattempt); - if (nread <= 0) - break; - - /* overwrite md5sum we implanted with original data */ - if (offset < apoff && offset+nread >= apoff) { - appdata_start_offset = apoff - offset; - appdata_end_offset = MIN(appdata_start_offset+MIN(nread, 512), - offset + nread - apoff); - len = appdata_end_offset - appdata_start_offset; - memset(buf+appdata_start_offset, ' ', len); - } else if (offset >= apoff && offset+nread < apoff + 512) { - appdata_start_offset = 0; - appdata_end_offset = nread; - len = appdata_end_offset - appdata_start_offset; - memset(buf+appdata_start_offset, ' ', len); - } else if (offset < apoff + 512 && offset+nread >= apoff + 512) { - appdata_start_offset = 0; - appdata_end_offset = apoff + 512 - offset; - len = appdata_end_offset - appdata_start_offset; - memset(buf+appdata_start_offset, ' ', len); - } - - MD5_Update(&md5ctx, buf, nread); - offset = offset + nread; - - printf("\b\b\b\b\b\b%05.1f%%", (100.0*offset)/(isosize-skipsectors*2048.0)); - fflush(stdout); - } - - printf("\b\b\b\b\b\b\n\n", (100.0*offset)/(isosize-skipsectors*2048.0)); - - sleep(1); - - free(buf); - - MD5_Final(md5sum, &md5ctx); - - *computedsum = '\0'; - for (i=0; i<16; i++) { - char tmpstr[4]; - snprintf (tmpstr, 4, "%02x", md5sum[i]); - strcat(computedsum, tmpstr); - } - - /* printf("mediasum, computedsum = %s %s\n", mediasum, computedsum); */ - - if (strcmp(mediasum, computedsum)) - return 0; - else - return 1; - } - - -#if 0 -static void readCB(void *co, long long pos) { - struct progressCBdata *data = co; - static int tick = 0; - char tickmark[2] = "-"; - char * ticks = "-\\|/"; - - newtScaleSet(data->scale, pos); - tick++; - if (tick > 399) tick = 0; - *tickmark = ticks[tick / 100]; - - newtLabelSetText(data->label, tickmark); - newtRefresh(); -} -#endif - -int doMediaCheck(int isofd, char *mediasum, char *computedsum, long long *isosize, int *supported) { - int rc; - int llen; - int skipsectors; - - if (parsepvd(isofd, mediasum, &skipsectors, isosize, supported) < 0) { - fprintf(stderr, "Unable to read the disc checksum from the " - "primary volume descriptor. This probably " - "means the disc was created without adding the " - "checksum."); - return -1; - } - - rc = checkmd5sum(isofd, mediasum, computedsum); - - return rc; -} - -int mediaCheckFile(char *file) { - int isofd; - int rc; - char *result; - unsigned char mediasum[33], computedsum[33]; - char tmpstr[256]; - long long isosize; - int supported; - - isofd = open(file, O_RDONLY); - - if (isofd < 0) { - fprintf(stderr, "Unable to find install image %s\n", file); - return -1; - } - - rc = doMediaCheck(isofd, mediasum, computedsum, &isosize, &supported); - - close(isofd); - - /* printf("isosize = %lld\n", isosize); - printf("%s\n%s\n", mediasum, computedsum);*/ - - fprintf(stderr, "The supported flag value is %d\n", supported); - - if ( rc == 0) - result = "FAIL.\n\nIt is not recommended to use this media."; - else if (rc > 0) - result = "PASS.\n\nIt is OK to install from this media."; - else - result = "NA.\n\nNo checksum information available, unable to verify media."; - - fprintf(stderr, "The media check is complete, the " - "result is: %s\n", result); - - return rc; -} - -int printMD5SUM(char *file) { - int isofd; - char mediasum[64]; - char computedsum; - long long isosize; - int supported; - int rc; - int llen; - int skipsectors; - - isofd = open(file, O_RDONLY); - - if (isofd < 0) { - fprintf(stderr, "%s: Unable to find install image.\n", file); - exit(1); - } - - if (parsepvd(isofd, mediasum, &skipsectors, &isosize, &supported) < 0) { - fprintf(stderr, "%s: Could not get pvd data", file); - exit(1); - } - - close(isofd); - - printf("%s: %s\n", file, mediasum); -} - - +#include "libcheckisomd5.h" int main(int argc, char **argv) { int rc; diff --git a/isomd5sum/implantisomd5.c b/isomd5sum/implantisomd5.c index 2e127b769..589fb8e49 100644 --- a/isomd5sum/implantisomd5.c +++ b/isomd5sum/implantisomd5.c @@ -4,79 +4,10 @@ /* Michael Fulbright msf@redhat.com */ #include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> #include <popt.h> #include "md5.h" - -#define APPDATA_OFFSET 883 -#define SIZE_OFFSET 84 - -/* number of sectors to ignore at end of iso when computing sum */ -#define SKIPSECTORS 15 - -#define MAX(x, y) ((x > y) ? x : y) -#define MIN(x, y) ((x < y) ? x : y) - -/* finds primary volume descriptor and returns info from it */ -/* mediasum must be a preallocated buffer at least 33 bytes long */ -int parsepvd(int isofd, char *mediasum, long long *isosize) { - unsigned char buf[2048]; - long long offset; - unsigned char *p; - - if (lseek(isofd, (off_t)(16L * 2048L), SEEK_SET) == -1) - return ((long long)-1); - - offset = (16L * 2048L); - for (;1;) { - if (read(isofd, buf, 2048) <= 0) - return ((long long)-1); - - if (buf[0] == 1) - /* found primary volume descriptor */ - break; - else if (buf[0] == 255) - /* hit end and didn't find primary volume descriptor */ - return ((long long)-1); - offset += 2048L; - } - - /* read out md5sum */ -#if 0 - memcpy(mediasum, buf + APPDATA_OFFSET + 13, 32); - mediasum[32] = '\0'; - - for (p=mediasum; *p; p++) - if (*p != ' ') - break; - - /* if the md5sum was all spaces, we didn't find md5sum */ - if (!*p) - return -1; -#endif - - /* get isosize */ - *isosize = (buf[SIZE_OFFSET]*0x1000000+buf[SIZE_OFFSET+1]*0x10000 + - buf[SIZE_OFFSET+2]*0x100 + buf[SIZE_OFFSET+3]) * 2048LL; - - return offset; -} - - -unsigned int writeAppData(unsigned char *appdata, char *valstr, unsigned int loc) { - if (loc + strlen(valstr) > 511) { - printf("Attempted to write too much appdata, exiting...\n"); - exit(-1); - } - - memcpy(appdata + loc, valstr, strlen(valstr)); - - return loc+strlen(valstr); -} +#include "libimplantisomd5.h" static void usage(void) { @@ -86,26 +17,13 @@ static void usage(void) { int main(int argc, char **argv) { - int i; int rc; - int isofd; - int nread; - int dirty; - int pvd_offset; + char *errstr; + const char **args; + int forceit=0; int supported=0; int help=0; - long long isosize, total; - const char **args; - unsigned char md5sum[16]; - unsigned int loc; - unsigned char *fname; - unsigned char buf[2048]; - unsigned char orig_appdata[512]; - unsigned char new_appdata[512]; - unsigned char mediasum[33], computedsum[33]; - char md5str[40]; - MD5_CTX md5ctx; poptContext optCon; struct poptOption options[] = { @@ -132,108 +50,7 @@ int main(int argc, char **argv) { if (!args || !args[0] || !args[0][0]) usage(); - fname = args[0]; - - isofd = open(fname, O_RDWR); - - if (isofd < 0) { - fprintf(stderr, "Error - Unable to open file %s\n\n", fname); - exit(1); - } - - pvd_offset = parsepvd(isofd, mediasum, &isosize); - if (pvd_offset < 0) { - fprintf(stderr, "Could not find primary volumne!\n\n"); - exit(1); - } - - lseek(isofd, pvd_offset + APPDATA_OFFSET, SEEK_SET); - nread = read(isofd, orig_appdata, 512); - - if (!forceit) { - dirty = 0; - for (i=0; i < 512; i++) - if (orig_appdata[i] != ' ') - dirty = 1; - - if (dirty) { - fprintf(stderr, "Application data has been used - not implanting md5sum!\n"); - exit(1); - } - } else { - /* write out blanks to erase old app data */ - lseek(isofd, pvd_offset + APPDATA_OFFSET, SEEK_SET); - memset(new_appdata, ' ', 512); - i = write(isofd, new_appdata, 512); - if (i<0) { - printf("write failed %d\n", i); - perror(""); - } - } - - /* now do md5sum */ - lseek(isofd, 0L, SEEK_SET); - - MD5_Init(&md5ctx); - - total = 0; - /* read up to 15 sectors from end, due to problems reading last few */ - /* sectors on burned CDs */ - while (total < isosize - SKIPSECTORS*2048) { - nread = read(isofd, buf, 2048); - if (nread <= 0) - break; - - MD5_Update(&md5ctx, buf, nread); - total = total + nread; - } - - MD5_Final(md5sum, &md5ctx); - - *md5str = '\0'; - for (i=0; i<16; i++) { - char tmpstr[4]; - snprintf (tmpstr, 4, "%02x", md5sum[i]); - strcat(md5str, tmpstr); - } - - printf("Inserting md5sum into iso image...\n"); - printf("md5 = %s\n", md5str); - /* memcpy(new_appdata, orig_appdata, 512); */ - memset(new_appdata, ' ', 512); - - loc = 0; - loc = writeAppData(new_appdata, "ISO MD5SUM = ", loc); - loc = writeAppData(new_appdata, md5str, loc); - loc = writeAppData(new_appdata, ";", loc); - snprintf(buf, sizeof(buf), "SKIPSECTORS = %d", SKIPSECTORS); - loc = writeAppData(new_appdata, buf, loc); - loc = writeAppData(new_appdata, ";", loc); - - if (supported) { - printf("Setting supported flag to 1\n"); - loc = writeAppData(new_appdata, "RHLISOSTATUS=1", loc); - } else { - printf("Setting supported flag to 0\n"); - loc = writeAppData(new_appdata, "RHLISOSTATUS=0", loc); - } - - loc = writeAppData(new_appdata, ";", loc); - - loc = writeAppData(new_appdata, "THIS IS NOT THE SAME AS RUNNING MD5SUM ON THIS ISO!!", loc); - - i = lseek(isofd, pvd_offset + APPDATA_OFFSET, SEEK_SET); - if (i<0) - printf("seek failed\n"); - - i = write(isofd, new_appdata, 512); - if (i<0) { - printf("write failed %d\n", i); - perror(""); - } - - close(isofd); - - printf("Done!\n"); - exit(0); + rc = implantISOFile((char *)args[0], supported, forceit, errstr); + if (rc) + fprintf(stderr, errstr); } diff --git a/isomd5sum/libcheckisomd5.c b/isomd5sum/libcheckisomd5.c new file mode 100644 index 000000000..a13dc13a4 --- /dev/null +++ b/isomd5sum/libcheckisomd5.c @@ -0,0 +1,307 @@ +/* Copyright 2001 Red Hat, Inc. */ +/* Michael Fulbright msf@redhat.com */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> + +#include "md5.h" +#include "libcheckisomd5.h" + +#define APPDATA_OFFSET 883 +#define SIZE_OFFSET 84 + +#define MAX(x, y) ((x > y) ? x : y) +#define MIN(x, y) ((x < y) ? x : y) + +/* finds primary volume descriptor and returns info from it */ +/* mediasum must be a preallocated buffer at least 33 bytes long */ +int parsepvd(int isofd, char *mediasum, int *skipsectors, long long *isosize, int *supported) { + unsigned char buf[2048]; + unsigned char buf2[512]; + unsigned char tmpbuf[512]; + int skipfnd, md5fnd, supportedfnd; + unsigned int loc; + long long offset; + unsigned char *p; + + *supported = 0; + + if (lseek(isofd, (off_t)(16L * 2048L), SEEK_SET) == -1) + return ((long long)-1); + + offset = (16L * 2048L); + for (;1;) { + if (read(isofd, buf, 2048) <=0) + return ((long long)-1); + + if (buf[0] == 1) + /* found primary volume descriptor */ + break; + else if (buf[0] == 255) + /* hit end and didn't find primary volume descriptor */ + return ((long long)-1); + offset += 2048L; + } + + /* read out md5sum */ + memcpy(buf2, buf + APPDATA_OFFSET, 512); + buf2[511] = '\0'; + + md5fnd = 0; + skipfnd = 0; + supportedfnd = 0; + loc = 0; + while (loc < 512) { + if (!strncmp(buf2 + loc, "ISO MD5SUM = ", 13)) { + + /* make sure we dont walk off end */ + if ((loc + 32) > 511) + return -1; + + memcpy(mediasum, buf2 + loc + 13, 32); + mediasum[32] = '\0'; + md5fnd = 1; + loc += 45; + for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++); + } else if (!strncmp(buf2 + loc, "SKIPSECTORS = ", 14)) { + char *errptr; + + /* make sure we dont walk off end */ + if ((loc + 14) > 511) + return -1; + + loc = loc + 14; + for (p=tmpbuf; buf2[loc] != ';' && loc < 512; p++, loc++) + *p = buf2[loc]; + + *p = '\0'; + + *skipsectors = strtol(tmpbuf, &errptr, 10); + if (errptr && *errptr) { + return -1; + } else { + skipfnd = 1; + } + + for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++); + } else if (!strncmp(buf2 + loc, "RHLISOSTATUS=1", 14)) { + *supported = 1; + supportedfnd = 1; + } else if (!strncmp(buf2 + loc, "RHLISOSTATUS=0", 14)) { + *supported = 0; + supportedfnd = 1; + } else { + loc++; + } + + if ((skipfnd & md5fnd) & supportedfnd) + break; + } + + + if (!(skipfnd & md5fnd)) + return -1; + + /* get isosize */ + *isosize = (buf[SIZE_OFFSET]*0x1000000+buf[SIZE_OFFSET+1]*0x10000 + + buf[SIZE_OFFSET+2]*0x100 + buf[SIZE_OFFSET+3]) * 2048LL; + + return offset; +} + +/* returns -1 if no checksum encoded in media, 0 if no match, 1 if match */ +/* mediasum is the sum encoded in media, computedsum is one we compute */ +/* both strings must be pre-allocated at least 33 chars in length */ +int checkmd5sum(int isofd, char *mediasum, char *computedsum) { + int nread; + int i; + int appdata_start_offset, appdata_end_offset; + int nattempt; + int skipsectors; + int supported; + unsigned int bufsize = 32768; + unsigned char md5sum[16]; + unsigned int len; + unsigned char *buf; + long long isosize, offset, pvd_offset, apoff; + MD5_CTX md5ctx; + + if ((pvd_offset = parsepvd(isofd, mediasum, &skipsectors, &isosize, &supported)) < 0) + return -1; + + /* printf("Mediasum = %s\n",mediasum); */ + + /* rewind, compute md5sum */ + lseek(isofd, 0L, SEEK_SET); + + MD5_Init(&md5ctx); + + offset = 0; + apoff = pvd_offset + APPDATA_OFFSET; + + buf = malloc(bufsize * sizeof(unsigned char)); + printf("Percent complete: %05.1f%%", (100.0*offset)/(isosize-skipsectors*2048.0)); + fflush(stdout); + while (offset < isosize - skipsectors*2048) { + nattempt = MIN(isosize - skipsectors*2048 - offset, bufsize); + + /* printf("%lld %lld %lld %d\n", offset, isosize, isosize-SKIPSECTORS*2048, nattempt); */ + + nread = read(isofd, buf, nattempt); + if (nread <= 0) + break; + + /* overwrite md5sum we implanted with original data */ + if (offset < apoff && offset+nread >= apoff) { + appdata_start_offset = apoff - offset; + appdata_end_offset = MIN(appdata_start_offset+MIN(nread, 512), + offset + nread - apoff); + len = appdata_end_offset - appdata_start_offset; + memset(buf+appdata_start_offset, ' ', len); + } else if (offset >= apoff && offset+nread < apoff + 512) { + appdata_start_offset = 0; + appdata_end_offset = nread; + len = appdata_end_offset - appdata_start_offset; + memset(buf+appdata_start_offset, ' ', len); + } else if (offset < apoff + 512 && offset+nread >= apoff + 512) { + appdata_start_offset = 0; + appdata_end_offset = apoff + 512 - offset; + len = appdata_end_offset - appdata_start_offset; + memset(buf+appdata_start_offset, ' ', len); + } + + MD5_Update(&md5ctx, buf, nread); + offset = offset + nread; + + printf("\b\b\b\b\b\b%05.1f%%", (100.0*offset)/(isosize-skipsectors*2048.0)); + fflush(stdout); + } + + printf("\b\b\b\b\b\b\n\n", (100.0*offset)/(isosize-skipsectors*2048.0)); + + sleep(1); + + free(buf); + + MD5_Final(md5sum, &md5ctx); + + *computedsum = '\0'; + for (i=0; i<16; i++) { + char tmpstr[4]; + snprintf (tmpstr, 4, "%02x", md5sum[i]); + strcat(computedsum, tmpstr); + } + + /* printf("mediasum, computedsum = %s %s\n", mediasum, computedsum); */ + + if (strcmp(mediasum, computedsum)) + return 0; + else + return 1; + } + + +#if 0 +static void readCB(void *co, long long pos) { + struct progressCBdata *data = co; + static int tick = 0; + char tickmark[2] = "-"; + char * ticks = "-\\|/"; + + newtScaleSet(data->scale, pos); + tick++; + if (tick > 399) tick = 0; + *tickmark = ticks[tick / 100]; + + newtLabelSetText(data->label, tickmark); + newtRefresh(); +} +#endif + +int doMediaCheck(int isofd, char *mediasum, char *computedsum, long long *isosize, int *supported) { + int rc; + int llen; + int skipsectors; + + if (parsepvd(isofd, mediasum, &skipsectors, isosize, supported) < 0) { + fprintf(stderr, "Unable to read the disc checksum from the " + "primary volume descriptor. This probably " + "means the disc was created without adding the " + "checksum."); + return -1; + } + + rc = checkmd5sum(isofd, mediasum, computedsum); + + return rc; +} + +int mediaCheckFile(char *file) { + int isofd; + int rc; + char *result; + unsigned char mediasum[33], computedsum[33]; + char tmpstr[256]; + long long isosize; + int supported; + + isofd = open(file, O_RDONLY); + + if (isofd < 0) { + fprintf(stderr, "Unable to find install image %s\n", file); + return -1; + } + + rc = doMediaCheck(isofd, mediasum, computedsum, &isosize, &supported); + + close(isofd); + + /* printf("isosize = %lld\n", isosize); + printf("%s\n%s\n", mediasum, computedsum);*/ + + fprintf(stderr, "The supported flag value is %d\n", supported); + + if ( rc == 0) + result = "FAIL.\n\nIt is not recommended to use this media."; + else if (rc > 0) + result = "PASS.\n\nIt is OK to install from this media."; + else + result = "NA.\n\nNo checksum information available, unable to verify media."; + + fprintf(stderr, "The media check is complete, the " + "result is: %s\n", result); + + return rc; +} + +int printMD5SUM(char *file) { + int isofd; + char mediasum[64]; + char computedsum; + long long isosize; + int supported; + int rc; + int llen; + int skipsectors; + + isofd = open(file, O_RDONLY); + + if (isofd < 0) { + fprintf(stderr, "%s: Unable to find install image.\n", file); + exit(1); + } + + if (parsepvd(isofd, mediasum, &skipsectors, &isosize, &supported) < 0) { + fprintf(stderr, "%s: Could not get pvd data", file); + exit(1); + } + + close(isofd); + + printf("%s: %s\n", file, mediasum); +} diff --git a/isomd5sum/libcheckisomd5.h b/isomd5sum/libcheckisomd5.h new file mode 100644 index 000000000..0ce7f0bd5 --- /dev/null +++ b/isomd5sum/libcheckisomd5.h @@ -0,0 +1,6 @@ +#ifndef __LIBCHECKISOMD5_H__ +#define __LIBCHECKISOMD5_H__ + +int mediaCheckFile(char *iso); + +#endif diff --git a/isomd5sum/libimplantisomd5.c b/isomd5sum/libimplantisomd5.c new file mode 100644 index 000000000..55bb73f2d --- /dev/null +++ b/isomd5sum/libimplantisomd5.c @@ -0,0 +1,204 @@ +/* Copyright 2001 Red Hat, Inc. */ +/* Michael Fulbright msf@redhat.com */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include "md5.h" +#include "libimplantisomd5.h" + +#define APPDATA_OFFSET 883 +#define SIZE_OFFSET 84 + +/* number of sectors to ignore at end of iso when computing sum */ +#define SKIPSECTORS 15 + +#define MAX(x, y) ((x > y) ? x : y) +#define MIN(x, y) ((x < y) ? x : y) + +/* finds primary volume descriptor and returns info from it */ +/* mediasum must be a preallocated buffer at least 33 bytes long */ +int parsepvd(int isofd, char *mediasum, long long *isosize) { + unsigned char buf[2048]; + long long offset; + unsigned char *p; + + if (lseek(isofd, (off_t)(16L * 2048L), SEEK_SET) == -1) + return ((long long)-1); + + offset = (16L * 2048L); + for (;1;) { + if (read(isofd, buf, 2048) <= 0) + return ((long long)-1); + + if (buf[0] == 1) + /* found primary volume descriptor */ + break; + else if (buf[0] == 255) + /* hit end and didn't find primary volume descriptor */ + return ((long long)-1); + offset += 2048L; + } + + /* read out md5sum */ +#if 0 + memcpy(mediasum, buf + APPDATA_OFFSET + 13, 32); + mediasum[32] = '\0'; + + for (p=mediasum; *p; p++) + if (*p != ' ') + break; + + /* if the md5sum was all spaces, we didn't find md5sum */ + if (!*p) + return -1; +#endif + + /* get isosize */ + *isosize = (buf[SIZE_OFFSET]*0x1000000+buf[SIZE_OFFSET+1]*0x10000 + + buf[SIZE_OFFSET+2]*0x100 + buf[SIZE_OFFSET+3]) * 2048LL; + + return offset; +} + + +unsigned int writeAppData(unsigned char *appdata, char *valstr, unsigned int loc) { + if (loc + strlen(valstr) > 511) { + printf("Attempted to write too much appdata, exiting...\n"); + exit(-1); + } + + memcpy(appdata + loc, valstr, strlen(valstr)); + + return loc+strlen(valstr); +} + + +static void usage(void) { + fprintf(stderr, "implantisomd5: implantisomd5 [--force] [--supported] <isofilename>\n"); + exit(1); +} + + +int implantISOFile(char *fname, int supported, int forceit, char *errstr) { + int i; + int rc; + int isofd; + int nread; + int dirty; + int pvd_offset; + long long isosize, total; + unsigned char md5sum[16]; + unsigned int loc; + unsigned char buf[2048]; + unsigned char orig_appdata[512]; + unsigned char new_appdata[512]; + unsigned char mediasum[33], computedsum[33]; + char md5str[40]; + MD5_CTX md5ctx; + + isofd = open(fname, O_RDWR); + + if (isofd < 0) { + errstr = "Error - Unable to open file %s\n\n"; + return -1; + } + + pvd_offset = parsepvd(isofd, mediasum, &isosize); + if (pvd_offset < 0) { + errstr = "Could not find primary volumne!\n\n"; + return -1; + } + + lseek(isofd, pvd_offset + APPDATA_OFFSET, SEEK_SET); + nread = read(isofd, orig_appdata, 512); + + if (!forceit) { + dirty = 0; + for (i=0; i < 512; i++) + if (orig_appdata[i] != ' ') + dirty = 1; + + if (dirty) { + errstr = "Application data has been used - not implanting md5sum!\n"; + return -1; + } + } else { + /* write out blanks to erase old app data */ + lseek(isofd, pvd_offset + APPDATA_OFFSET, SEEK_SET); + memset(new_appdata, ' ', 512); + i = write(isofd, new_appdata, 512); + if (i<0) { + printf("write failed %d\n", i); + perror(""); + } + } + + /* now do md5sum */ + lseek(isofd, 0L, SEEK_SET); + + MD5_Init(&md5ctx); + + total = 0; + /* read up to 15 sectors from end, due to problems reading last few */ + /* sectors on burned CDs */ + while (total < isosize - SKIPSECTORS*2048) { + nread = read(isofd, buf, 2048); + if (nread <= 0) + break; + + MD5_Update(&md5ctx, buf, nread); + total = total + nread; + } + + MD5_Final(md5sum, &md5ctx); + + *md5str = '\0'; + for (i=0; i<16; i++) { + char tmpstr[4]; + snprintf (tmpstr, 4, "%02x", md5sum[i]); + strcat(md5str, tmpstr); + } + + printf("Inserting md5sum into iso image...\n"); + printf("md5 = %s\n", md5str); + /* memcpy(new_appdata, orig_appdata, 512); */ + memset(new_appdata, ' ', 512); + + loc = 0; + loc = writeAppData(new_appdata, "ISO MD5SUM = ", loc); + loc = writeAppData(new_appdata, md5str, loc); + loc = writeAppData(new_appdata, ";", loc); + snprintf(buf, sizeof(buf), "SKIPSECTORS = %d", SKIPSECTORS); + loc = writeAppData(new_appdata, buf, loc); + loc = writeAppData(new_appdata, ";", loc); + + if (supported) { + printf("Setting supported flag to 1\n"); + loc = writeAppData(new_appdata, "RHLISOSTATUS=1", loc); + } else { + printf("Setting supported flag to 0\n"); + loc = writeAppData(new_appdata, "RHLISOSTATUS=0", loc); + } + + loc = writeAppData(new_appdata, ";", loc); + + loc = writeAppData(new_appdata, "THIS IS NOT THE SAME AS RUNNING MD5SUM ON THIS ISO!!", loc); + + i = lseek(isofd, pvd_offset + APPDATA_OFFSET, SEEK_SET); + if (i<0) + printf("seek failed\n"); + + i = write(isofd, new_appdata, 512); + if (i<0) { + printf("write failed %d\n", i); + perror(""); + } + + close(isofd); + + return 0; +} diff --git a/isomd5sum/libimplantisomd5.h b/isomd5sum/libimplantisomd5.h new file mode 100644 index 000000000..f5a983297 --- /dev/null +++ b/isomd5sum/libimplantisomd5.h @@ -0,0 +1,5 @@ +#ifndef __LIBIMPLANTISOMD5_H__ +#define __LIBIMPLANTISOMD5_H__ +int implantISOFile(char *iso, int supported, int forceit, char *errstr); +#endif + diff --git a/isomd5sum/md5.c b/isomd5sum/md5.c index fe032ebba..6f0e4ff6f 100644 --- a/isomd5sum/md5.c +++ b/isomd5sum/md5.c @@ -21,6 +21,8 @@ #include <string.h> #include "md5.h" +void MD5_Transform(uint32 *buf, uint32 const *in); + #ifndef HIGHFIRST #define byteReverse(buf, len) /* Nothing */ #else |