diff --git a/usr.sbin/mtree/Makefile b/usr.sbin/mtree/Makefile index 6376ea3af54e..2977c4722b57 100644 --- a/usr.sbin/mtree/Makefile +++ b/usr.sbin/mtree/Makefile @@ -10,7 +10,7 @@ SRCS+= specspec.c WARNS?= 4 -CFLAGS+= -DMD5 -DSHA1 -DRMD160 +CFLAGS+= -DMD5 -DSHA1 -DRMD160 -DSHA256 DPADD= ${LIBMD} LDADD= -lmd diff --git a/usr.sbin/mtree/compare.c b/usr.sbin/mtree/compare.c index bf4353c51855..44556d67a0ea 100644 --- a/usr.sbin/mtree/compare.c +++ b/usr.sbin/mtree/compare.c @@ -52,6 +52,9 @@ __FBSDID("$FreeBSD$"); #ifdef SHA1 #include #endif +#ifdef SHA256 +#include +#endif #include #include #include @@ -294,6 +297,24 @@ typeerr: LABEL; } } #endif /* RMD160 */ +#ifdef SHA256 + if (s->flags & F_SHA256) { + char *new_digest, buf[65]; + + new_digest = SHA256_File(p->fts_accpath, buf); + if (!new_digest) { + LABEL; + printf("%sSHA-256: %s: %s\n", tab, p->fts_accpath, + strerror(errno)); + tab = "\t"; + } else if (strcmp(new_digest, s->sha256digest)) { + LABEL; + printf("%sSHA-256 expected %s found %s\n", + tab, s->sha256digest, new_digest); + tab = "\t"; + } + } +#endif /* SHA256 */ if (s->flags & F_SLINK && strcmp(cp = rlink(p->fts_accpath), s->slink)) { diff --git a/usr.sbin/mtree/create.c b/usr.sbin/mtree/create.c index fa902e4649c2..f1b0313a746d 100644 --- a/usr.sbin/mtree/create.c +++ b/usr.sbin/mtree/create.c @@ -52,6 +52,9 @@ __FBSDID("$FreeBSD$"); #ifdef RMD160 #include #endif +#ifdef SHA256 +#include +#endif #include #include #include @@ -249,6 +252,16 @@ statf(int indent, FTSENT *p) output(indent, &offset, "ripemd160digest=%s", digest); } #endif /* RMD160 */ +#ifdef SHA256 + if (keys & F_SHA256 && S_ISREG(p->fts_statp->st_mode)) { + char *digest, buf[65]; + + digest = SHA256_File(p->fts_accpath, buf); + if (!digest) + err(1, "%s", p->fts_accpath); + output(indent, &offset, "sha256digest=%s", digest); + } +#endif /* SHA256 */ if (keys & F_SLINK && (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) output(indent, &offset, "link=%s", rlink(p->fts_accpath)); diff --git a/usr.sbin/mtree/misc.c b/usr.sbin/mtree/misc.c index cc211f025911..8f5344e68401 100644 --- a/usr.sbin/mtree/misc.c +++ b/usr.sbin/mtree/misc.c @@ -71,6 +71,9 @@ static KEY keylist[] = { #endif #ifdef SHA1 {"sha1digest", F_SHA1, NEEDVALUE}, +#endif +#ifdef SHA256 + {"sha256digest", F_SHA256, NEEDVALUE}, #endif {"size", F_SIZE, NEEDVALUE}, {"time", F_TIME, NEEDVALUE}, diff --git a/usr.sbin/mtree/mtree.8 b/usr.sbin/mtree/mtree.8 index 971474a1185b..0dad86d29d1f 100644 --- a/usr.sbin/mtree/mtree.8 +++ b/usr.sbin/mtree/mtree.8 @@ -204,6 +204,12 @@ The 160-1 .Pq Dq Tn SHA-1 message digest of the file. +.It Cm sha256digest +The +.Tn FIPS +180-2 +.Pq Dq Tn SHA-256 +message digest of the file. .It Cm ripemd160digest The .Tn RIPEMD160 @@ -317,21 +323,21 @@ To detect system binaries that have been ``trojan horsed'', it is recommended that .Nm .Fl K -.Cm sha1digest +.Cm sha256digest be run on the file systems, and a copy of the results stored on a different machine, or, at least, in encrypted form. The output file itself should be digested using the -.Xr md5 1 +.Xr sha256 1 utility. Then, periodically, .Nm and -.Xr md5 1 +.Xr sha256 1 should be run against the on-line specifications. While it is possible for the bad guys to change the on-line specifications to conform to their modified binaries, it is believed to be impractical for them to create a modified specification which has -the same MD5 digest as the original. +the same SHA-256 digest as the original. .Pp The .Fl d @@ -372,6 +378,10 @@ digests were added in .Fx 4.0 , as new attacks have demonstrated weaknesses in .Tn MD5 . +The +.Tn SHA-256 +digest was added in +.Fx 6.0 . Support for file flags was added in .Fx 4.0 , and mostly comes from diff --git a/usr.sbin/mtree/mtree.h b/usr.sbin/mtree/mtree.h index 7d899c6f6d03..b0d5415cdc4c 100644 --- a/usr.sbin/mtree/mtree.h +++ b/usr.sbin/mtree/mtree.h @@ -46,6 +46,7 @@ typedef struct _node { u_long cksum; /* check sum */ char *md5digest; /* MD5 digest */ char *sha1digest; /* SHA-1 digest */ + char *sha256digest; /* SHA-256 digest */ char *rmd160digest; /* RIPEMD160 digest */ char *slink; /* symbolic link reference */ uid_t st_uid; /* uid */ @@ -76,6 +77,7 @@ typedef struct _node { #define F_SHA1 0x20000 /* SHA-1 digest */ #define F_RMD160 0x40000 /* RIPEMD160 digest */ #define F_FLAGS 0x80000 /* file flags */ +#define F_SHA256 0x100000 /* SHA-256 digest */ u_int flags; /* items set */ #define F_BLOCK 0x001 /* block special */ diff --git a/usr.sbin/mtree/spec.c b/usr.sbin/mtree/spec.c index 0407f78cfa2d..ed9431692c73 100644 --- a/usr.sbin/mtree/spec.c +++ b/usr.sbin/mtree/spec.c @@ -194,6 +194,11 @@ set(char *t, NODE *ip) if(!ip->sha1digest) errx(1, "strdup"); break; + case F_SHA256: + ip->sha256digest = strdup(val); + if(!ip->sha256digest) + errx(1, "strdup"); + break; case F_RMD160: ip->rmd160digest = strdup(val); if(!ip->rmd160digest) diff --git a/usr.sbin/mtree/specspec.c b/usr.sbin/mtree/specspec.c index 59dd937bee74..f85882e0deef 100644 --- a/usr.sbin/mtree/specspec.c +++ b/usr.sbin/mtree/specspec.c @@ -82,6 +82,8 @@ shownode(NODE *n, int f, char const *path) printf(" sha1digest=%s", n->sha1digest); if (f & F_RMD160) printf(" rmd160digest=%s", n->rmd160digest); + if (f & F_SHA256) + printf(" sha256digest=%s", n->sha256digest); if (f & F_FLAGS) printf(" flags=%s", flags_to_string(n->st_flags)); printf("\n"); @@ -160,6 +162,8 @@ compare_nodes(NODE *n1, NODE *n2, char const *path) differs |= F_SHA1; if (FS(n1, n2, F_RMD160, rmd160digest)) differs |= F_RMD160; + if (FS(n1, n2, F_SHA256, sha256digest)) + differs |= F_SHA256; if (FF(n1, n2, F_FLAGS, st_flags)) differs |= F_FLAGS; if (differs) { @@ -213,19 +217,19 @@ walk_in_the_forest(NODE *t1, NODE *t2, char const *path) asprintf(&np, "%s%s/", path, c2->name); i = walk_in_the_forest(c1, c2, np); free(np); - i = compare_nodes(c1, c2, path); + i += compare_nodes(c1, c2, path); } else if (c2 == NULL && c1->type == F_DIR) { asprintf(&np, "%s%s/", path, c1->name); i = walk_in_the_forest(c1, c2, np); free(np); - i = compare_nodes(c1, c2, path); + i += compare_nodes(c1, c2, path); } else if (c1 == NULL || c2 == NULL) { i = compare_nodes(c1, c2, path); } else if (c1->type == F_DIR && c2->type == F_DIR) { asprintf(&np, "%s%s/", path, c1->name); i = walk_in_the_forest(c1, c2, np); free(np); - i = compare_nodes(c1, c2, path); + i += compare_nodes(c1, c2, path); } else { i = compare_nodes(c1, c2, path); } diff --git a/usr.sbin/mtree/test/test03.sh b/usr.sbin/mtree/test/test03.sh index e320c4f63ff5..bb3a5b5397e0 100644 --- a/usr.sbin/mtree/test/test03.sh +++ b/usr.sbin/mtree/test/test03.sh @@ -15,7 +15,7 @@ TMP=/tmp/mtree.$$ rm -rf ${TMP} mkdir -p ${TMP} -K=uid,uname,gid,gname,flags,md5digest,size,ripemd160digest,sha1digest,cksum +K=uid,uname,gid,gname,flags,md5digest,size,ripemd160digest,sha1digest,sha256digest,cksum rm -rf _FOO mkdir _FOO