allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (03/08/89)
Posting-number: Volume 6, Issue 59 Submitted-by: zeeff@b-tech.ann-arbor.mi.us (Jon Zeeff) Archive-name: crc-check [A set of crc programs. This came to me labeled as a "file system checker", but it's no fsck. ++bsa] This is a set of programs to check for unexpected file system corruption or security breaches. It's nice to be able to say that you know all your files are as they should be. #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: Makefile README crc.c crc_check.c find_crc # Wrapped by zeeff@b-tech on Sun Feb 26 12:10:25 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f Makefile -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"Makefile\" else echo shar: Extracting \"Makefile\" \(241 characters\) sed "s/^X//" >Makefile <<'END_OF_Makefile' X XCC=cc XCFLAGS = -O XLDFLAGS = X X XSRCS=crc.c crc_check.c XOBJS=crc.o crc_check.o X Xcrc: $(OBJS) X $(CC) -o crc crc.o $(CFLAGS) $(LDFLAGS) X $(CC) -o crc_check crc_check.o $(CFLAGS) $(LDFLAGS) X Xclean: X rm -f crc.tmp crc.files *.o crc crc_check X END_OF_Makefile if test 241 -ne `wc -c <Makefile`; then echo shar: \"Makefile\" unpacked with wrong size! fi # end of overwriting check fi if test -f README -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"README\" else echo shar: Extracting \"README\" \(1283 characters\) sed "s/^X//" >README <<'END_OF_README' X XThis is a set of programs to check for unexpected file system Xcorruption or security breaches. It's nice to be able to say that you Xknow all your files are as they should be. Mark Mendel wrote most of Xcrc.c and I wrote crc_check.c. It's written for Sys V, but BSD Xshouldn't be hard. X X XTo use it: X X1) you first create a crc list with the script find_crc. You can Xmodify it and add grep -v to the pipe to change the file systems that Xit checks. The end result is a file "crc.tmp". X X2) You can now use crc_check to compare this crc.tmp file to a crc list Xcreated earlier called crc.files. If everything is ok, you can mv Xcrc.tmp to crc.files. It is expected that you will want to use grep -v Xon the output of crc_check to cut down on the noise. X XNote that you can use a -i option when running crc to change the Xinitial crc value. If you don't tell anyone what this is, you can Xmake it nearly impossible for anyone to modify a file and then adjust Xthe crc value to the old one. To really do it right, you need to X X1) Run find_crc in single user mode (unless you modify the crc source). X2) Store all crc results offline. X3) Don't let anyone see your -i value or the crc results. X X XPlease send me any modifications you make. X XJon Zeeff Xzeeff@b-tech.ann-arbor.mi.us X X END_OF_README if test 1283 -ne `wc -c <README`; then echo shar: \"README\" unpacked with wrong size! fi # end of overwriting check fi if test -f crc.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"crc.c\" else echo shar: Extracting \"crc.c\" \(9918 characters\) sed "s/^X//" >crc.c <<'END_OF_crc.c' X/* updcrc(3), crc(1) - calculate crc polynomials X * X * Calculate, intelligently, the CRC of a dataset incrementally given a X * buffer full at a time. X * X * Usage: X * newcrc = updcrc( oldcrc, bufadr, buflen ) X * unsigned int oldcrc, buflen; X * char *bufadr; X * X * Compiling with -DTEST creates a program to print the CRC of stdin to stdout. X * Compile with -DMAKETAB to print values for crctab to stdout. If you change X * the CRC polynomial parameters, be sure to do this and change X * crctab's initial value. X * X * Notes: X * Regards the data stream as an integer whose MSB is the MSB of the first X * byte recieved. This number is 'divided' (using xor instead of subtraction) X * by the crc-polynomial P. X * XMODEM does things a little differently, essentially treating the LSB of X * the first data byte as the MSB of the integer. Define SWAPPED to make X * things behave in this manner. X * X * Author: Mark G. Mendel, 7/86 X * UUCP: ihnp4!umn-cs!hyper!mark, GEnie: mgm X */ X X#define TEST X X/* The CRC polynomial. X * These 4 values define the crc-polynomial. X * If you change them, you must change crctab[]'s initial value to what is X * printed by initcrctab() [see 'compile with -DMAKETAB' above]. X */ X X/* Value used by: CITT XMODEM ARC */ X#define P 0xA001 /* the poly: 0x1021 0x1021 A001 */ X#define INIT_CRC 0L /* init value: -1 0 0 */ X#define SWAPPED /* bit order: undef defined defined */ X#define W 16 /* bits in CRC:16 16 16 */ X X/* data type that holds a W-bit unsigned integer */ X#if W <= 16 X# define WTYPE unsigned short X#else X# define WTYPE unsigned long X#endif X X/* the number of bits per char: don't change it. */ X#define B 8 X Xstatic WTYPE crctab[1<<B] = /* as calculated by initcrctab() */ { X 0x0, 0xc0c1, 0xc181, 0x140, 0xc301, 0x3c0, 0x280, 0xc241, X 0xc601, 0x6c0, 0x780, 0xc741, 0x500, 0xc5c1, 0xc481, 0x440, X 0xcc01, 0xcc0, 0xd80, 0xcd41, 0xf00, 0xcfc1, 0xce81, 0xe40, X 0xa00, 0xcac1, 0xcb81, 0xb40, 0xc901, 0x9c0, 0x880, 0xc841, X 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, X 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, X 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, X 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, X 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, X 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, X 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, X 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, X 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, X 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, X 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, X 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, X 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, X 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, X 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, X 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, X 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, X 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, X 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, X 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, X 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, X 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, X 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, X 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, X 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, X 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, X 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, X 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040, X}; X X Xvoid perror(); Xchar *strcpy(); Xvoid exit(); X XWTYPE Xupdcrc( icrc, icp, icnt ) XWTYPE icrc; Xunsigned char *icp; Xint icnt; X{ X register WTYPE crc = icrc; X register unsigned char *cp = icp; X register int cnt = icnt; X X while ( cnt--) { X#ifndef SWAPPED X crc = (crc << B) ^ crctab[(crc>>(W-B)) ^ *cp++]; X#else X crc = (crc >> B) ^ crctab[(crc & ((1<<B)-1)) ^ *cp++]; X#endif X } X X return( crc ); X} X X X#ifdef MAKETAB X X#include <stdio.h> Xmain() X{ X initcrctab(); X} X X Xinitcrctab() X{ X register int b, i; X WTYPE v; X X X for ( b = 0; b <= (1 << B) - 1; ++b ) { X#ifndef SWAPPED X for ( v = b << (W - B), i = B; --i >= 0; ) X v = v & ((WTYPE)1 << (W - 1)) ? (v << 1) ^ P : v << 1; X#else X for ( v = b, i = B; --i >= 0; ) X v = v & 1 ? (v >> 1) ^ P : v >> 1; X#endif X crctab[b] = v; X X (void) printf( "0x%lx,", v & ((1L << W) - 1L)); X if ( (b & 7) == 7 ) X (void) printf("\n" ); X else X (void) printf(" "); X } X} X X X#endif X X#ifdef TEST X X#include <stdio.h> X#include <fcntl.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <pwd.h> X#include <grp.h> X#define MAXBUF 4096 X X#ifndef S_IRGRP X#define S_IRGRP (S_IREAD >> 3) X#define S_IWGRP (S_IWRITE >> 3) X#define S_IXGRP (S_IEXEC >> 3) X#define S_IROTH (S_IREAD >> 6) X#define S_IWOTH (S_IWRITE >> 6) X#define S_IXOTH (S_IEXEC >> 6) X#endif X Xstruct stat stat_buf; Xint initial_crc = INIT_CRC; X Xextern char *optarg; Xextern int optind; Xextern int opterr; X Xmain( argc, argv ) Xint argc; Xchar **argv; X{ X int stats_flag = 0; X X int c; X X if (argc == 1) { X print_crc((char *)0, 0); X return 0; X } X X /* process all arguments */ X X while ((c = getopt(argc, argv, "VvI:i:")) != EOF) { X X switch (c) { X X case 'V': X case 'v': X stats_flag = 1; X break; X X case 'I': X case 'i': X initial_crc = atoi(optarg); X break; X X default: X (void) fprintf(stderr, "crc: -v (verbose listing)\n"); X (void) fprintf(stderr, " -i value (initial crc value)\n"); X exit(1); X } X } X X for (; optind < argc ; optind++) X print_crc(argv[optind], stats_flag); X X return 0; X} X X Xprint_crc(name, stat_flag) Xchar *name; Xint stat_flag; X{ X int fd; X int nr; X unsigned char buf[MAXBUF]; X WTYPE crc; X#ifdef MAGICCHECK X WTYPE crc2; X#endif X X fd = 0; X X /* quietly ignore files we can't stat */ X X if (name != NULL && stat(name, &stat_buf) != 0) X return; X X /* don't do a crc on strange files */ X X crc = nr = 0; X X if (name == NULL || (stat_buf.st_mode & S_IFMT) == S_IFREG) { X X /* open the file and do a crc on it */ X X if (name != NULL && (fd = open( name, O_RDONLY )) < 0 ) { X perror( name ); X exit( -1 ); X } X#ifdef MAGICCHECK X crc2 = X#endif X crc = initial_crc; X X while ( (nr = read( fd, (char *)buf, MAXBUF )) > 0 ) { X crc = updcrc(crc, buf, nr ); X } X (void) close(fd); X X } X if ( nr != 0 ) { X perror( "read error" ); X } else { X (void) printf("%4.4x", (unsigned) crc ); X if (stat_flag) X stats(name); X else X (void) printf("\n"); X X } X X#ifdef MAGICCHECK X /* tack one's complement of crc onto data stream, and X continue crc calculation. Should get a constant (magic number) X dependent only on P, not the data. X */ X crc2 = crc ^ -1L; X for ( nr = W - B; nr >= 0; nr -= B ) { X buf[0] = (crc2 >> nr); X crc = updcrc(crc, buf, 1); X } X X /* crc should now equal magic */ X buf[0] = buf[1] = buf[2] = buf[3] = 0; X (void) printf( "magic test: %lx =?= %lx\n", crc, updcrc((WTYPE) - 1, buf, W / B)); X#endif X X X} X X Xstats(name) Xchar *name; X{ X X struct passwd *entry; X struct group *group_entry; X static char owner[20]; X static char group[20]; X char a_time[50]; X X struct passwd *getpwuid(); X struct group *getgrgid(); X char *ctime(); X X static int prev_uid = -9999; X static int prev_gid = -9999; X X if (stat_buf.st_uid != prev_uid) { X entry = getpwuid((int)stat_buf.st_uid); X if (entry) X (void) strcpy(owner, entry->pw_name); X else X (void) sprintf(owner, "%d", stat_buf.st_uid); X prev_uid = stat_buf.st_uid; X } X if (stat_buf.st_gid != prev_gid) { X group_entry = getgrgid((int)stat_buf.st_gid); X if (group_entry) X (void) strcpy(group, group_entry->gr_name); X else X (void) sprintf(group, "%d", stat_buf.st_gid); X prev_gid = stat_buf.st_gid; X } X X (void) strcpy(a_time, ctime(&stat_buf.st_mtime)); X a_time[24] = '\0'; X X print_perm(stat_buf.st_mode); X X (void) printf(" %s\t%s\t%s %s\n", owner, group, a_time + 4, name); X X} X X Xprint_perm(perm) Xunsigned int perm; X{ X X char string[20]; X (void) strcpy(string, "----------"); X X switch (perm & S_IFMT) { X X case S_IFDIR: X string[0] = 'd'; X break; X X case S_IFBLK: X string[0] = 'b'; X break; X X case S_IFCHR: X string[0] = 'c'; X break; X X case S_IFIFO: X string[0] = 'p'; X break; X } X if (perm & S_IREAD) X string[1] = 'r'; X if (perm & S_IWRITE) X string[2] = 'w'; X if (perm & S_ISUID && perm & S_IEXEC) X string[3] = 's'; X else if (perm & S_IEXEC) X string[3] = 'x'; X else if (perm & S_ISUID) X string[3] = 'S'; X X if (perm & S_IRGRP) X string[4] = 'r'; X if (perm & S_IWGRP) X string[5] = 'w'; X if (perm & S_ISUID && perm & S_IXGRP) X string[6] = 's'; X else if (perm & S_IXGRP) X string[6] = 'x'; X else if (perm & S_ISUID) X string[6] = 'l'; X X if (perm & S_IROTH) X string[7] = 'r'; X if (perm & S_IWOTH) X string[8] = 'w'; X if (perm & S_ISVTX && perm & S_IXOTH) X string[9] = 't'; X else if (perm & S_IXOTH) X string[9] = 'x'; X else if (perm & S_ISVTX) X string[9] = 'T'; X X (void) printf(" %s", string); X} X X#endif X END_OF_crc.c if test 9918 -ne `wc -c <crc.c`; then echo shar: \"crc.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f crc_check.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"crc_check.c\" else echo shar: Extracting \"crc_check.c\" \(4067 characters\) sed "s/^X//" >crc_check.c <<'END_OF_crc_check.c' X X/* X This progam will compare two crc lists and report the differences. X X By Jon Zeeff (zeeff@b-tech.ann-arbor.mi.us) X X Permission is granted to use this in any manner provided that X 1) the copyright notice is left intact, X 2) you don't hold me responsible for any bugs and X 3) you mail me any improvements that you make. X X X report: X corrupt - crc changed w/o date change X replaced - crc + date changed X perm - permissions changed X own/grp - owner or group changed X removed - X added - X XPrint the info for the new file except for deleted. X XUse: X Xfind / -print | sort | xargs crc -v > crc_file X Xto generate a crc list (crc.c should accompany this source). X XAssume that no files have tabs or spaces in the name. X X*/ X X/* max size of line */ X X#define BUF_SIZE 1124 X X#include <stdio.h> X Xchar *strrchr(); Xvoid exit(); X Xchar new_line[BUF_SIZE]; Xchar old_line[BUF_SIZE]; X XFILE *new_file; XFILE *old_file; X Xmain(argc, argv) Xint argc; Xchar **argv; X{ X /* X X If line =, read new line from each file X else X If date/perm/crc change, report and read new line from each file X else X If old_line < new_line, report file removed, read old line X else X report new line as added X read new_line X loop X*/ X X char *new_ptr; X char *old_ptr; X X if (argc != 3) { X (void) printf("wrong number of arguments\n"); X (void) printf("crc_check old_crc_file new_crc_file\n"); X exit(1); X } X new_file = fopen(argv[2], "r"); X old_file = fopen(argv[1], "r"); X X if (new_file == NULL || old_file == NULL) { X (void) printf("can't open input files\n"); X (void) printf("crc_check old_crc_file new_crc_file\n"); X exit(1); X } X X get_line(new_line); X get_line(old_line); X X for (; ; ) { X X check_eof(); X X /* If equal, print nothing and get new lines */ X X if (strcmp(old_line, new_line) == 0) { X get_line(new_line); X get_line(old_line); X continue; X } X X /* Compare just the file names */ X X new_ptr = strrchr(new_line, ' '); X old_ptr = strrchr(old_line, ' '); X X if (new_ptr == NULL || old_ptr == NULL) { X (void) printf("Error in input data\n"); X exit(1); X } X X if (strcmp(old_ptr, new_ptr) == 0) { X X new_ptr = strrchr(new_line, '\t'); X old_ptr = strrchr(old_line, '\t'); X X if (new_ptr == NULL || old_ptr == NULL) { X (void) printf("Error in input data\n"); X exit(1); X } X X /* check crc change */ X X if (strncmp(new_line, old_line, 4) != 0) X if (strcmp(new_ptr, old_ptr) == 0) X (void) printf("corrupt %s", new_line + 5); X else X (void) printf("replaced %s", new_line + 5); X X X /* check permission chenage */ X X if (strncmp(new_line + 5, old_line + 5, 11) != 0) X (void) printf("permiss %s", new_line + 5); X X /* check owner/group */ X X if (strncmp(new_line+16, old_line+16, new_ptr - new_line - 15) != 0) X (void) printf("own/grp %s", new_line + 5); X X get_line(new_line); X get_line(old_line); X continue; X } X X X if (strcmp(old_ptr, new_ptr) < 0) { X (void) printf("removed %s", old_line + 5); X get_line(old_line); X continue; X } X X (void) printf("added %s", new_line + 5); X get_line(new_line); X X } X X} X X Xget_line(string) Xchar *string; X{ X if (string == new_line) X (void) fgets(string, BUF_SIZE, new_file); X else X (void) fgets(string, BUF_SIZE, old_file); X X} X X Xcheck_eof() X{ X X if (feof(new_file)) { X X while (!feof(old_file)) { X (void) printf("removed %s", old_line + 5); X (void) fgets(old_line, BUF_SIZE, old_file); X } X exit(0); X } else if (feof(old_file)) { X while (!feof(new_file)) { X (void) printf("added %s", new_line + 5); X (void) fgets(new_line, BUF_SIZE, new_file); X } X exit(0); X } X X} X X END_OF_crc_check.c if test 4067 -ne `wc -c <crc_check.c`; then echo shar: \"crc_check.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f find_crc -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"find_crc\" else echo shar: Extracting \"find_crc\" \(58 characters\) sed "s/^X//" >find_crc <<'END_OF_find_crc' X Xfind / -mount -print | sort | xargs crc -v > crc.tmp X X END_OF_find_crc if test 58 -ne `wc -c <find_crc`; then echo shar: \"find_crc\" unpacked with wrong size! fi chmod +x find_crc # end of overwriting check fi echo shar: End of shell archive. exit 0 -- Jon Zeeff zeeff@b-tech.ann-arbor.mi.us Ann Arbor, MI mailrus!b-tech!zeeff