home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume08 / filescan < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  16.2 KB

  1. From decwrl!wuarchive!gem.mps.ohio-state.edu!ginosko!uunet!allbery Fri Sep 29 09:55:57 PDT 1989
  2. Article 1084 of comp.sources.misc:
  3. Path: decwrl!wuarchive!gem.mps.ohio-state.edu!ginosko!uunet!allbery
  4. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5. Newsgroups: comp.sources.misc
  6. Subject: v08i042: file integrity checker w/checksums
  7. Message-ID: <67570@uunet.UU.NET>
  8. Date: 14 Sep 89 23:00:18 GMT
  9. Sender: allbery@uunet.UU.NET
  10. Reply-To: mjr@welchlab.welch.jhu.edu (Marcus J. Ranum)
  11. Lines: 626
  12. Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  13.  
  14. Posting-number: Volume 8, Issue 42
  15. Submitted-by: mjr@welchlab.welch.jhu.edu (Marcus J. Ranum)
  16. Archive-name: filescan
  17.  
  18. #!/bin/sh
  19. #    This is a shell archive.
  20. #    Run the following text with /bin/sh to create:
  21. #    README
  22. #    Makefile
  23. #    filescan.c
  24. #    in_cksum.c
  25. #    filescan.8
  26. # This archive created: Wed Sep 13 16:06:18 1989
  27. echo shar: extracting README '(995 characters)'
  28. sed 's/^XX//' << \SHAR_EOF > README
  29. XX
  30. XX    This is a fairly simple little program I whipped up after I read
  31. XXthe CERT messages about versions of telnet(1) that snagged passwords. It
  32. XXreads a list of files and checks them against stored information to see
  33. XXif the files have been monkeyed with.
  34. XX
  35. XX    I don't think this software is a panacea for trojan horses and
  36. XXsuch forms of attack, but I *do* think it's a step, and I hope its flaws
  37. XXtrigger more in-depth approaches to these problems. Whether it becomes a
  38. XXuseful security tool, I've already realized it may save me a lot of work
  39. XXmaking sure that modified files are properly carried forward across
  40. XXoperating system revisions :-)
  41. XX
  42. XX    Currently the code is pretty UNIX specific, though any machine
  43. XXwith dbm or an equivalent, a stat(2) or equivalent system call, and a
  44. XXdirectory lister like find(1) could use it. There may be some berklisms
  45. XXin the code, but I assure you there are no NULL derefs or any of that
  46. XXcrap.
  47. XX
  48. XX    Anyhow, do with this what you will. Hopefully it may help
  49. XXsomeone.
  50. XX
  51. XX--mjr();
  52. SHAR_EOF
  53. if test 995 -ne "`wc -c README`"
  54. then
  55. echo shar: error transmitting README '(should have been 995 characters)'
  56. fi
  57. echo shar: extracting Makefile '(802 characters)'
  58. sed 's/^XX//' << \SHAR_EOF > Makefile
  59. XX#
  60. XX#    Makefile for filescan file summer and scanner.
  61. XX#    Copyright (C), Marcus J. Ranum, 1989. All rights reserved
  62. XX#    This code may be freely distributed as long as this header
  63. XX#    remains intact. No warranties are expressed or implied as
  64. XX#    to the suitability of this software for any purpose at all.
  65. XX#
  66. XX#    $Header: Makefile,v 1.1 89/09/13 14:21:31 mjr Rel $
  67. XX#
  68. XX
  69. XXINSDIR=/usr/etc
  70. XXMANDIR=/usr/man/man8
  71. XX
  72. XX#define DBM if you dont have NDBM.
  73. XXDBM= -DNDBM
  74. XX#DBM= -DDBM
  75. XX
  76. XXCFLAGS= -O $(DBM)
  77. XXLDFLAGS= -s
  78. XX
  79. XXLIBS= -ldbm
  80. XX
  81. XXfilescan:    filescan.o in_cksum.o
  82. XX    cc $(LDFLAGS) -o filescan filescan.o in_cksum.o $(LIBS)
  83. XX
  84. XXclean:
  85. XX    rm -f core *.o filescan
  86. XX
  87. XXlint:
  88. XX    lint $(DBM) filescan.c in_cksum.c
  89. XX
  90. XXinstall: filescan filescan.8
  91. XX    cp filescan $(INSDIR)
  92. XX    cp filescan.8 $(MANDIR)
  93. XX    chmod 644 $(MANDIR)/filescan.8
  94. XX
  95. XXfilescan.o:    Makefile filescan.c
  96. SHAR_EOF
  97. if test 802 -ne "`wc -c Makefile`"
  98. then
  99. echo shar: error transmitting Makefile '(should have been 802 characters)'
  100. fi
  101. echo shar: extracting filescan.c '(6800 characters)'
  102. sed 's/^XX//' << \SHAR_EOF > filescan.c
  103. XX#include <sys/types.h>
  104. XX#include <sys/stat.h>
  105. XX#include <sys/file.h>
  106. XX#ifdef    DBM
  107. XX#include <dbm.h>
  108. XX#endif
  109. XX#ifdef    NDBM
  110. XX#include <ndbm.h>
  111. XX#endif
  112. XX#include <stdio.h>
  113. XX
  114. XX/*
  115. XX    filescan file summer and scanner.
  116. XX    Copyright (C), Marcus J. Ranum, 1989. All rights reserved
  117. XX    This code may be freely distributed as long as this header
  118. XX    remains intact. No warranties are expressed or implied as
  119. XX    to the suitability of this software for any purpose at all.
  120. XX*/
  121. XX
  122. XX/*
  123. XX *    $Log:    filescan.c,v $
  124. XX * Revision 1.1  89/09/13  14:26:27  mjr
  125. XX * Initial revision
  126. XX * 
  127. XX * 
  128. XX*/
  129. XX
  130. XX#ifndef    lint
  131. XXstatic    char    *rcsid[] = "$Header: filescan.c,v 1.1 89/09/13 14:26:27 mjr Rel $";
  132. XX#endif
  133. XX
  134. XX
  135. XXextern    datum    fetch();
  136. XXextern    char    *rindex();
  137. XXextern    char    *getpass();
  138. XXextern    char    *sprintf();
  139. XX
  140. XXstatic    void        warn();
  141. XX
  142. XXint    docheckin = 0;
  143. XXFILE    *inf = { stdin };
  144. XXFILE    *outf = { stdout };
  145. XXint    updflg = 0;
  146. XXint    sumflg = 0;
  147. XX#ifdef    NDBM
  148. XXDBM    *dbf;                /* icky global, I know */
  149. XXextern    DBM    *dbm_open();
  150. XX#endif
  151. XX
  152. XXstruct    secrec    {
  153. XX    struct    stat    s;        /* stat info */
  154. XX    int        sum;        /* actual sum */
  155. XX    char        sumf;        /* checksum is present */
  156. XX};
  157. XX
  158. XX
  159. XXmain(ac,av)
  160. XXint    ac;
  161. XXchar    **av;
  162. XX{
  163. XX#ifdef    DBM
  164. XX    int    doinit = 0;
  165. XX#endif
  166. XX    char    buf[BUFSIZ];
  167. XX    char    *dbfile = NULL;
  168. XX    int    aflg = 0;
  169. XX    int    wflg = 0;
  170. XX    int    errcnt = 0;
  171. XX    int    warcnt = 0;
  172. XX
  173. XX    while(*++av) {
  174. XX        if(**av == '-') {
  175. XX            switch(*(*av + 1)) {
  176. XX            case 'a':    /* append to output */
  177. XX                aflg++;
  178. XX                break;
  179. XX
  180. XX            case 's':    /* perform checksum on store */
  181. XX                sumflg++;
  182. XX                break;
  183. XX
  184. XX            case 'u':    /* update changes in database */
  185. XX                updflg++;
  186. XX                break;
  187. XX
  188. XX            case 'w':    /* exit status is # of warnings */
  189. XX                wflg++;
  190. XX                break;
  191. XX
  192. XX            case 'c':    /* perform check in */
  193. XX                docheckin++;
  194. XX                break;
  195. XX    
  196. XX#ifdef    DBM
  197. XX            case 'C':    /* initialize and truncate database */
  198. XX                doinit++;
  199. XX                break;
  200. XX#endif
  201. XX
  202. XX            case 'o':    /* output from check */
  203. XX                if((outf = fopen(*++av,aflg?"a":"w")) == NULL) {
  204. XX                    perror(*av);
  205. XX                    exit(1);
  206. XX                }
  207. XX                break;
  208. XX
  209. XX            case 'i':    /* input to check or store */
  210. XX                if((inf = fopen(*++av,"r")) == NULL) {
  211. XX                    perror(*av);
  212. XX                    exit(1);
  213. XX                }
  214. XX                break;
  215. XX
  216. XX            case 'd':    /* database name */
  217. XX                dbfile = *++av;
  218. XX                break;
  219. XX
  220. XX            default:
  221. XX                 exit(usage());
  222. XX            }
  223. XX        }
  224. XX
  225. XX    }
  226. XX
  227. XX    if(dbfile == NULL) {
  228. XX        (void)fprintf(stderr,"can't initialize without datbase file name\n");
  229. XX        exit(usage());
  230. XX    }
  231. XX
  232. XX
  233. XX#ifdef    DBM
  234. XX    /* create new database files, since DBM is not smart enough to */
  235. XX    if(doinit) {
  236. XX        int    wfd;
  237. XX
  238. XX        (void)sprintf(buf,"%s.dir",dbfile);
  239. XX        if((wfd = open(buf,O_RDWR|O_TRUNC|O_CREAT,0600)) < 0) {
  240. XX            (void)fprintf(stderr,"cannot create ");
  241. XX            perror(buf);
  242. XX            exit(1);
  243. XX        }
  244. XX        (void)close(wfd);
  245. XX        (void)sprintf(buf,"%s.pag",dbfile);
  246. XX        if((wfd = open(buf,O_RDWR|O_TRUNC|O_CREAT,0600)) < 0) {
  247. XX            (void)fprintf(stderr,"cannot create ");
  248. XX            perror(buf);
  249. XX            exit(1);
  250. XX        }
  251. XX        (void)close(wfd);
  252. XX    }
  253. XX#endif
  254. XX
  255. XX
  256. XX#ifdef    DBM
  257. XX    /* open data files. DBM is global, so what the hey */
  258. XX    if (dbminit(dbfile) < 0) {
  259. XX        (void)fprintf(stderr,"cannot open database %s\n",dbfile);
  260. XX        exit(1);
  261. XX    }
  262. XX#endif
  263. XX
  264. XX#ifdef    NDBM
  265. XX    if((dbf = dbm_open(dbfile,O_RDWR|O_CREAT,0600)) == NULL) {
  266. XX        (void)fprintf(stderr,"cannot open database %s\n",dbfile);
  267. XX        exit(1);
  268. XX    }
  269. XX#endif
  270. XX
  271. XX
  272. XX    /* main loop. read input and either store it or check it */
  273. XX    while(fgets(buf,BUFSIZ,inf) != NULL) {
  274. XX        char    *p;
  275. XX
  276. XX        /* drop the newline */
  277. XX        if((p = rindex(buf,'\n')) != NULL)
  278. XX            *p = '\0';
  279. XX
  280. XX        if(docheckin)
  281. XX            errcnt += scan_store(buf,0);
  282. XX        else
  283. XX            errcnt += scan_check(buf,&warcnt);
  284. XX    }
  285. XX
  286. XX    /* exit with different values depending on request */
  287. XX#ifdef    DBM
  288. XX    (void)dbmclose();
  289. XX#endif
  290. XX#ifdef    NDBM
  291. XX    (void)dbm_close(dbf);
  292. XX#endif
  293. XX    exit(wflg ? warcnt : errcnt);
  294. XX}
  295. XX
  296. XXscan_store(fil,spec)
  297. XXchar    *fil;
  298. XXchar    spec;    /* override - make sure checksum is done for update */
  299. XX{
  300. XX    struct    secrec    sbuf;
  301. XX    datum    key;
  302. XX    datum    content;
  303. XX
  304. XX    if(stat(fil,&sbuf.s)) {
  305. XX        warn("cannot stat",fil);
  306. XX        return(1);
  307. XX    }
  308. XX
  309. XX    if(sumflg || spec) {
  310. XX        sbuf.sum = sumit(fil);
  311. XX        sbuf.sumf = 1;
  312. XX    } else
  313. XX        sbuf.sumf = 0;
  314. XX
  315. XX    key.dsize = strlen(fil);
  316. XX    key.dptr = fil;
  317. XX    content.dsize = sizeof(sbuf);
  318. XX    content.dptr = (char *)&sbuf;
  319. XX
  320. XX#ifdef    DBM
  321. XX    if(store(key, content)) {
  322. XX        warn("cannot store",fil);
  323. XX        return(1);
  324. XX    }
  325. XX#endif
  326. XX#ifdef    NDBM
  327. XX    if(dbm_store(dbf,key, content,DBM_REPLACE)) {
  328. XX        warn("cannot store",fil);
  329. XX        return(1);
  330. XX    }
  331. XX#endif
  332. XX    return(0);
  333. XX}
  334. XX
  335. XXscan_check(fil,warnings)
  336. XXchar    *fil;
  337. XXint    *warnings;
  338. XX{
  339. XX    struct    secrec    sptr;
  340. XX    struct    secrec    sbuf;
  341. XX    datum    key;
  342. XX    datum    content;
  343. XX    int    state = 0;
  344. XX
  345. XX    if(stat(fil,&sbuf.s)) {
  346. XX        warn("cannot stat",fil);
  347. XX        *warnings++;
  348. XX        return(1);
  349. XX    }
  350. XX
  351. XX    key.dptr = fil;
  352. XX    key.dsize = strlen(fil);
  353. XX
  354. XX#ifdef    DBM
  355. XX    content = fetch(key);
  356. XX#endif
  357. XX#ifdef    NDBM
  358. XX    content = dbm_fetch(dbf,key);
  359. XX#endif
  360. XX
  361. XX    /* i suppose that not being in the database is an error, */
  362. XX    /* not a security violation, in as many words */
  363. XX    if (content.dptr == 0) {
  364. XX        warn("no entry in database",fil);
  365. XX
  366. XX        /* update changes */
  367. XX        if(updflg) {
  368. XX            /* a checksum will be done only if sumflg is set */
  369. XX            (void)scan_store(fil,0);
  370. XX        }
  371. XX        return(1);
  372. XX    }
  373. XX
  374. XX    (void)bcopy(content.dptr,(char *)&sptr,sizeof(sptr));
  375. XX
  376. XX    /* check what we deem important */
  377. XX    if(sptr.sumf != 0) {
  378. XX        sbuf.sum = sumit(fil);
  379. XX        if(sptr.sum != sbuf.sum) {
  380. XX            warn("checksum does not match",fil);
  381. XX            state++;
  382. XX        }
  383. XX    }
  384. XX    if(sptr.s.st_size != sbuf.s.st_size) {
  385. XX        warn("file size has changed",fil);
  386. XX        state++;
  387. XX    }
  388. XX    if(sptr.s.st_uid != sbuf.s.st_uid) {
  389. XX        warn("owner uid has changed",fil);
  390. XX        state++;
  391. XX    }
  392. XX    if(sptr.s.st_uid != sbuf.s.st_uid) {
  393. XX        warn("owner gid has changed",fil);
  394. XX        state++;
  395. XX    }
  396. XX    if(sptr.s.st_mode != sbuf.s.st_mode) {
  397. XX        warn("permissions have changed",fil);
  398. XX        state++;
  399. XX    }
  400. XX    if(sptr.s.st_mtime != sbuf.s.st_mtime) {
  401. XX        warn("modification time has changed",fil);
  402. XX        state++;
  403. XX    }
  404. XX    if(sptr.s.st_ctime != sbuf.s.st_ctime) {
  405. XX        warn("creation time has changed",fil);
  406. XX        state++;
  407. XX    }
  408. XX
  409. XX    /* update changes */
  410. XX    if(updflg && state != 0)
  411. XX        /* checksum will be done if sumflg or the file flag is set */
  412. XX        (void)scan_store(fil,sptr.sumf);
  413. XX
  414. XX    return(state);
  415. XX}
  416. XX
  417. XXusage()
  418. XX{
  419. XX    (void)fprintf(stderr,"usage:\n");
  420. XX    (void)fprintf(stderr,"filescan -d database [-a (append to log)] [-s (perform checksums)]\n");
  421. XX#ifdef    NDBM
  422. XX    (void)fprintf(stderr,"\t[-w (exit with warnings)] [-c (load database)]\n");
  423. XX#endif
  424. XX#ifdef    DBM
  425. XX    (void)fprintf(stderr,"\t[-w (exit with warnings)] [-c (load database)] [-C (create database)]\n");
  426. XX#endif
  427. XX    (void)fprintf(stderr,"\t[-i filename (read list from file)] [-o filename (log file)]\n");
  428. XX    (void)fprintf(stderr,"\t[-u (update any changes found)]\n");
  429. XX    return(1);
  430. XX}
  431. XX
  432. XXstatic    void
  433. XXwarn(s1,s2)
  434. XXchar    *s1;
  435. XXchar    *s2;
  436. XX{
  437. XX    extern    int    errno;
  438. XX    extern    char    *sys_errlist[];
  439. XX
  440. XX    if(errno) 
  441. XX        (void)fprintf(outf,"%s:%s(%s)\n",s2,s1,sys_errlist[errno]);
  442. XX    else
  443. XX        (void)fprintf(outf,"%s:%s\n",s2,s1);
  444. XX}
  445. XX
  446. XX
  447. XXsumit(fil)
  448. XXchar    *fil;
  449. XX{
  450. XX    int    sum = 0;
  451. XX    int    fd;
  452. XX    int    cnt;
  453. XX    char    buf[BUFSIZ];
  454. XX
  455. XX    if((fd = open(fil,O_RDONLY)) < 0) {
  456. XX        warn("cannot read for sum",fil);
  457. XX    } else {
  458. XX        while((cnt = read(fd,buf,BUFSIZ)) > 0)
  459. XX            sum += in_cksum((u_short *)buf,cnt);
  460. XX        (void)close(fd);
  461. XX    }
  462. XX    return(sum);
  463. XX}
  464. SHAR_EOF
  465. if test 6800 -ne "`wc -c filescan.c`"
  466. then
  467. echo shar: error transmitting filescan.c '(should have been 6800 characters)'
  468. fi
  469. echo shar: extracting in_cksum.c '(830 characters)'
  470. sed 's/^XX//' << \SHAR_EOF > in_cksum.c
  471. XX#include <sys/types.h>
  472. XX
  473. XX/*
  474. XX * Internet Protocol checksum routine, stolen from ping.c
  475. XX */
  476. XX
  477. XXin_cksum(addr, len)
  478. XX    u_short    *addr;
  479. XX    int    len;
  480. XX{
  481. XX    register int nleft = len;
  482. XX    register u_short *w = addr;
  483. XX    register u_short answer;
  484. XX    register int sum = 0;
  485. XX
  486. XX    /*
  487. XX     *  Our algorithm is simple, using a 32 bit accumulator (sum),
  488. XX     *  we add sequential 16 bit words to it, and at the end, fold
  489. XX     *  back all the carry bits from the top 16 bits into the lower
  490. XX     *  16 bits.
  491. XX     */
  492. XX    while( nleft > 1 )  {
  493. XX        sum += *w++;
  494. XX        nleft -= 2;
  495. XX    }
  496. XX
  497. XX    /* mop up an odd byte, if necessary */
  498. XX    if( nleft == 1 )
  499. XX        sum += *(u_char *)w;
  500. XX
  501. XX    /*
  502. XX     * add back carry outs from top 16 bits to low 16 bits
  503. XX     */
  504. XX    sum = (sum >> 16) + (sum & 0xffff);    /* add hi 16 to low 16 */
  505. XX    sum += (sum >> 16);            /* add carry */
  506. XX    answer = ~sum;                /* truncate to 16 bits */
  507. XX    return (answer);
  508. XX}
  509. SHAR_EOF
  510. if test 830 -ne "`wc -c in_cksum.c`"
  511. then
  512. echo shar: error transmitting in_cksum.c '(should have been 830 characters)'
  513. fi
  514. echo shar: extracting filescan.8 '(3949 characters)'
  515. sed 's/^XX//' << \SHAR_EOF > filescan.8
  516. XX.\" $Header: filescan.8,v 1.1 89/09/13 15:48:34 mjr Exp $
  517. XX.TH FILESCAN 1 "13 September 1989"
  518. XX.SH NAME
  519. XXfilescan \- primitive trojan horse detector/permissions checker
  520. XX.SH SYNOPSIS
  521. XX.B filescan
  522. XX.RB " \-d database "
  523. XX.RB [ " \-a " ]
  524. XX.RB [ " \-C " ]
  525. XX.RB [ " \-c " ]
  526. XX.RB [ " \-s " ]
  527. XX.RB [ " \-u " ]
  528. XX.RB [ " \-w " ]
  529. XX.RB [ " \-i input" ]
  530. XX.RB [ " \-o output" ]
  531. XX.SH DESCRIPTION
  532. XX.LP
  533. XX.B filescan
  534. XXreads a list of file names from its standard input or file, and checks
  535. XXthe list for permissions changes, modification, change of size, etc. 
  536. XXThe intent is to make it \fIsomewhat\fR harder to insert a trojan horse into
  537. XXa system. Information about the files is stored in a
  538. XX.B dbm(3)
  539. XXhash table, for quick lookup. Warnings about interesting findings can
  540. XXbe either appended to a log file, mailed to systems administrators, and
  541. XXso on.
  542. XX.LP
  543. XX.B filescan
  544. XXis not going to make it impossible for someone to insert a trojan into
  545. XXa system, by any means. Running a complete checksum on all the files
  546. XXin the database can chew up a lot of CPU time, yet resorting to simply
  547. XXchecking file sizes, permissions and modification times is not 100%
  548. XXreliable, either. An additional weakness of such a system is the 
  549. XXdatabase itself. In this implementation, there is no protection for
  550. XXthe database, though encrypting the hash table's directory would
  551. XXmake it hard to modify. Obviously, a wrongdoer could flat-out remove
  552. XXthe database - but then they could reformat the disks, too.
  553. XX.B filescan
  554. XXshould be somewhat effective against basic mischef.
  555. XX.SH OPTIONS
  556. XX.TP
  557. XX.B \-C
  558. XXIf the database system is based on
  559. XX.B dbm(3)
  560. XXrather than
  561. XX.B ndbm(3)
  562. XXthis option will create the database files, or will truncate existing
  563. XXones.
  564. XX.TP
  565. XX.B \-c
  566. XXIndicates that the list being read should be 
  567. XXentered into the database. Presumably, this option will be run once,
  568. XXwhen the database is initialized.
  569. XX.TP
  570. XX.B \-s
  571. XXIndicates that a checksum should be performed on all files that are
  572. XXbeing stored or updated in the database. When a file is stored, a
  573. XXflag is stored with it, indicating that the file is to be summed,
  574. XXand it is automatically checked when the database is scanned.
  575. XX.TP
  576. XX.B \-u
  577. XXIndicates that the list being read should be checked for update against the
  578. XXcontents of the database. If any changes are detected, warnings are
  579. XXissued, and the changes are updated in the database. If this option is
  580. XXnot selected (the default is no update), the warning will be repeated
  581. XXevery time the file is checked.
  582. XX.TP
  583. XX.B \-w
  584. XXIndicates that the exit status of the program should be the total 
  585. XXnumber of warnings and errors. The default is the number of errors
  586. XX(a file not existing at all when it should is an error, rather than
  587. XXjust a warning).
  588. XX.TP
  589. XX.B "\-i filename"
  590. XXIndicates that 
  591. XX.B filescan
  592. XXshould read its file list from the named file. Only one file can be
  593. XXnamed in this manner.
  594. XX.TP
  595. XX.B "\-o filename"
  596. XXIndicates that 
  597. XX.B filescan
  598. XXshould send its warning messages to the named logfile. Only one file can be
  599. XXnamed in this manner.
  600. XX.TP
  601. XX.B \-a
  602. XXIndicates that the logfile should be opened for append mode, rather than
  603. XXtruncated.
  604. XX.SH EXAMPLE
  605. XX.LP
  606. XXInitializing a sample database:
  607. XX.br
  608. XXfind /usr/local/bin -type f -print | filescan -d sample -c -s
  609. XX.LP
  610. XXScanning and updating the database:
  611. XX.br
  612. XXfind /usr/local/bin -type f -print | filescan -d sample
  613. XX.fi
  614. XX.ad
  615. XX.SH "SEE ALSO"
  616. XX.BR sum (1)
  617. XX.BR find (1)
  618. XX.SH BUGS
  619. XX.LP
  620. XXThe limited options and failure to ensure security of the data base
  621. XXcould be considered a bug. Ideally, there should be an option whereby
  622. XXa different checksum could be used, or some kind of keying scheme
  623. XXshould be built into the checksum. (possibly, the program should
  624. XXread an optional checksum along with the file name?)
  625. XX.LP
  626. XXThis program should not give a false sense of security.
  627. XX.SH WARNING
  628. XXAvoid having /dev in the list of files, since the ttys change permission
  629. XXand ownership a lot. Also avoid having your database check on itself 
  630. XXin update mode, or you will always get warnings.
  631. XX.SH AUTHOR
  632. XXMarcus J. Ranum - mjr@welch.jhu.edu
  633. SHAR_EOF
  634. if test 3949 -ne "`wc -c filescan.8`"
  635. then
  636. echo shar: error transmitting filescan.8 '(should have been 3949 characters)'
  637. fi
  638. #    End of shell archive
  639. exit 0
  640.  
  641.  
  642.