From 6bc94b09b219aee8ef81db78fe7f2b280cb40b6a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 23 Mar 2013 12:24:23 +0100 Subject: logsig: refactor 'dump' mode in rsgtutil The way tlvrecords are processed is changed in order to provide better extensibility for further work. --- tools/rsgtutil.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'tools/rsgtutil.c') diff --git a/tools/rsgtutil.c b/tools/rsgtutil.c index 9d9f3568..c5ac5066 100644 --- a/tools/rsgtutil.c +++ b/tools/rsgtutil.c @@ -44,8 +44,8 @@ dumpFile(char *name) { FILE *fp; uchar hdr[9]; - uint16_t tlvtype, tlvlen; void *obj; + tlvrecord_t rec; int r = -1; if(!strcmp(name, "-")) @@ -60,13 +60,14 @@ dumpFile(char *name) if((r = rsgt_tlvrdHeader(fp, hdr)) != 0) goto err; printf("File Header: '%s'\n", hdr); while(1) { /* we will err out on EOF */ - if((r = rsgt_tlvrd(fp, &tlvtype, &tlvlen, &obj)) != 0) { + if((r = rsgt_tlvrd(fp, &rec, &obj)) != 0) { if(feof(fp)) break; else goto err; } - rsgt_tlvprint(stdout, tlvtype, obj, verbose); + rsgt_tlvprint(stdout, rec.tlvtype, obj, verbose); + rsgt_objfree(rec.tlvtype, obj); } if(fp != stdin) -- cgit v1.2.3 From c77a77a6c7919d17936e6ba2f71b0903cac9c890 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 23 Mar 2013 13:07:12 +0100 Subject: rsgtutil: refactor 'verify' mode to use new tlv file read functions --- tools/rsgtutil.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools/rsgtutil.c') diff --git a/tools/rsgtutil.c b/tools/rsgtutil.c index c5ac5066..c78671c7 100644 --- a/tools/rsgtutil.c +++ b/tools/rsgtutil.c @@ -181,7 +181,7 @@ static void verify(char *name) { FILE *logfp = NULL, *sigfp = NULL; - block_sig_t *bs; + block_sig_t *bs = NULL; gtfile gf; uint8_t bHasRecHashes, bHasIntermedHashes; uint8_t bInBlock; @@ -225,6 +225,8 @@ verify(char *name) while(!feof(logfp)) { if(bInBlock == 0) { + if(bs != NULL) + rsgt_objfree(0x0902, bs); if((r = rsgt_getBlockParams(sigfp, 1, &bs, &bHasRecHashes, &bHasIntermedHashes)) != 0) goto err; -- cgit v1.2.3 From 0b77585a10062117d1904c8c08db1fc4520ab16d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 23 Mar 2013 14:59:50 +0100 Subject: rsgtutil: basic plumbing for extend mode does not contain actual implementation --- tools/rsgtutil.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'tools/rsgtutil.c') diff --git a/tools/rsgtutil.c b/tools/rsgtutil.c index c78671c7..f65c46fd 100644 --- a/tools/rsgtutil.c +++ b/tools/rsgtutil.c @@ -35,7 +35,7 @@ typedef unsigned char uchar; static enum { MD_DUMP, MD_DETECT_FILE_TYPE, MD_SHOW_SIGBLK_PARAMS, - MD_VERIFY + MD_VERIFY, MD_EXTEND } mode = MD_DUMP; static int verbose = 0; @@ -155,7 +155,12 @@ doVerifyRec(FILE *logfp, FILE *sigfp, block_sig_t *bs, gtfile gf, gterrctx_t *ec char rec[128*1024]; if(fgets(rec, sizeof(rec), logfp) == NULL) { - r = feof(logfp) ? RSGTE_EOF : RSGTE_IO; + if(feof(logfp)) { + r = RSGTE_EOF; + } else { + perror("log file input"); + r = RSGTE_IO; + } goto done; } lenRec = strlen(rec); @@ -176,21 +181,27 @@ done: return r; } -/* note: here we need to have the LOG file name, not signature! */ +/* We handle both verify and extend with the same function as they + * are very similiar. + * + * note: here we need to have the LOG file name, not signature! + */ static void verify(char *name) { - FILE *logfp = NULL, *sigfp = NULL; + FILE *logfp = NULL, *sigfp = NULL, *nsigfp = NULL; block_sig_t *bs = NULL; gtfile gf; uint8_t bHasRecHashes, bHasIntermedHashes; uint8_t bInBlock; int r = 0; char sigfname[4096]; + char nsigfname[4096]; gterrctx_t ectx; if(!strcmp(name, "-")) { - fprintf(stderr, "verify mode cannot work on stdin\n"); + fprintf(stderr, "%s mode cannot work on stdin\n", + mode == MD_VERIFY ? "verify" : "extend"); goto err; } else { snprintf(sigfname, sizeof(sigfname), "%s.gtsig", name); @@ -200,9 +211,17 @@ verify(char *name) goto err; } if((sigfp = fopen(sigfname, "r")) == NULL) { - perror(name); + perror(sigfname); goto err; } + if(mode == MD_EXTEND) { + snprintf(nsigfname, sizeof(nsigfname), "%s.gtsig.new", name); + nsigfname[sizeof(nsigfname)-1] = '\0'; + if((nsigfp = fopen(nsigfname, "w")) == NULL) { + perror(nsigfname); + goto err; + } + } } rsgtInit("rsyslog rsgtutil " VERSION); @@ -245,6 +264,7 @@ verify(char *name) fclose(logfp); fclose(sigfp); + fclose(nsigfp); rsgtExit(); rsgt_errctxExit(&ectx); return; @@ -253,6 +273,8 @@ err: fclose(logfp); if(sigfp != NULL) fclose(sigfp); + if(nsigfp != NULL) + fclose(nsigfp); if(r != RSGTE_EOF) fprintf(stderr, "error %d processing file %s\n", r, name); rsgtExit(); @@ -273,6 +295,7 @@ processFile(char *name) showSigblkParams(name); break; case MD_VERIFY: + case MD_EXTEND: verify(name); break; } @@ -287,6 +310,7 @@ static struct option long_options[] = {"detect-file-type", no_argument, NULL, 'T'}, {"show-sigblock-params", no_argument, NULL, 'B'}, {"verify", no_argument, NULL, 't'}, /* 't' as in "test signatures" */ + {"extend", no_argument, NULL, 'e'}, {"publications-server", optional_argument, NULL, 'P'}, {"show-verified", no_argument, NULL, 's'}, {NULL, 0, NULL, 0} @@ -327,6 +351,9 @@ main(int argc, char *argv[]) case 't': mode = MD_VERIFY; break; + case 'e': + mode = MD_EXTEND; + break; case '?': break; default:fprintf(stderr, "getopt_long() returns unknown value %d\n", opt); -- cgit v1.2.3 From 199630a5ef8f0c919fbbbd9e122415d1d72886a3 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 23 Mar 2013 18:39:03 +0100 Subject: rsgtutil/milestone: basic 'extend' mode implementation ... done up until the point where I need to wait for the timestamps to become extendible. So doing a milestone commit to make sure the work is inside the archive. Actual writing of the extended timestamp is missing. --- tools/rsgtutil.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'tools/rsgtutil.c') diff --git a/tools/rsgtutil.c b/tools/rsgtutil.c index f65c46fd..1f475527 100644 --- a/tools/rsgtutil.c +++ b/tools/rsgtutil.c @@ -148,13 +148,14 @@ err: fprintf(stderr, "error %d processing file %s\n", r, name); } static inline int -doVerifyRec(FILE *logfp, FILE *sigfp, block_sig_t *bs, gtfile gf, gterrctx_t *ectx, uint8_t bInBlock) +doVerifyRec(FILE *logfp, FILE *sigfp, FILE *nsigfp, + block_sig_t *bs, gtfile gf, gterrctx_t *ectx, uint8_t bInBlock) { int r; size_t lenRec; - char rec[128*1024]; + char line[128*1024]; - if(fgets(rec, sizeof(rec), logfp) == NULL) { + if(fgets(line, sizeof(line), logfp) == NULL) { if(feof(logfp)) { r = RSGTE_EOF; } else { @@ -163,20 +164,20 @@ doVerifyRec(FILE *logfp, FILE *sigfp, block_sig_t *bs, gtfile gf, gterrctx_t *ec } goto done; } - lenRec = strlen(rec); - if(rec[lenRec-1] == '\n') { - rec[lenRec-1] = '\0'; + lenRec = strlen(line); + if(line[lenRec-1] == '\n') { + line[lenRec-1] = '\0'; --lenRec; - rsgt_errctxSetErrRec(ectx, rec); + rsgt_errctxSetErrRec(ectx, line); } - /* we need to preserve the first record of each block for + /* we need to preserve the first line (record) of each block for * error-reporting purposes (bInBlock==0 meanst start of block) */ if(bInBlock == 0) - rsgt_errctxFrstRecInBlk(ectx, rec); + rsgt_errctxFrstRecInBlk(ectx, line); - r = rsgt_vrfy_nextRec(bs, gf, sigfp, (unsigned char*)rec, lenRec, ectx); + r = rsgt_vrfy_nextRec(bs, gf, sigfp, nsigfp, (unsigned char*)line, lenRec, ectx); done: return r; } @@ -231,7 +232,13 @@ verify(char *name) ectx.filename = strdup(sigfname); if((r = rsgt_chkFileHdr(sigfp, "LOGSIG10")) != 0) goto err; - + if(mode == MD_EXTEND) { + if(fwrite("LOGSIG10", 8, 1, nsigfp) != 1) { + perror(nsigfname); + r = RSGTE_IO; + goto err; + } + } gf = rsgt_vrfyConstruct_gf(); if(gf == NULL) { fprintf(stderr, "error initializing signature file structure\n"); @@ -254,10 +261,11 @@ verify(char *name) ++ectx.blkNum; } ++ectx.recNum, ++ectx.recNumInFile; - if((r = doVerifyRec(logfp, sigfp, bs, gf, &ectx, bInBlock)) != 0) + if((r = doVerifyRec(logfp, sigfp, nsigfp, bs, gf, &ectx, bInBlock)) != 0) goto err; if(ectx.recNum == bs->recCount) { - verifyBLOCK_SIG(bs, gf, sigfp, &ectx); + verifyBLOCK_SIG(bs, gf, sigfp, nsigfp, + (mode == MD_EXTEND) ? 1 : 0, &ectx); bInBlock = 0; } else bInBlock = 1; } -- cgit v1.2.3 From c896a6ba7498e15ddfe869823a64434a4180d57b Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 25 Mar 2013 15:56:33 +0100 Subject: rsgtsig: finish implementation of 'extend' mode This is tested as far as possible. However, the actual extend case can only be tested in about three weeks from now when the next publication is out. I have done module-testing with a mockup extend call, so chances are great the final test will be passed. --- tools/rsgtutil.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 13 deletions(-) (limited to 'tools/rsgtutil.c') diff --git a/tools/rsgtutil.c b/tools/rsgtutil.c index 1f475527..45106c00 100644 --- a/tools/rsgtutil.c +++ b/tools/rsgtutil.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -197,6 +198,7 @@ verify(char *name) uint8_t bInBlock; int r = 0; char sigfname[4096]; + char oldsigfname[4096]; char nsigfname[4096]; gterrctx_t ectx; @@ -222,6 +224,9 @@ verify(char *name) perror(nsigfname); goto err; } + snprintf(oldsigfname, sizeof(oldsigfname), + "%s.gtsig.old", name); + oldsigfname[sizeof(oldsigfname)-1] = '\0'; } } @@ -231,18 +236,18 @@ verify(char *name) ectx.fp = stderr; ectx.filename = strdup(sigfname); - if((r = rsgt_chkFileHdr(sigfp, "LOGSIG10")) != 0) goto err; + if((r = rsgt_chkFileHdr(sigfp, "LOGSIG10")) != 0) goto done; if(mode == MD_EXTEND) { if(fwrite("LOGSIG10", 8, 1, nsigfp) != 1) { perror(nsigfname); r = RSGTE_IO; - goto err; + goto done; } } gf = rsgt_vrfyConstruct_gf(); if(gf == NULL) { fprintf(stderr, "error initializing signature file structure\n"); - goto err; + goto done; } bInBlock = 0; @@ -255,36 +260,80 @@ verify(char *name) rsgt_objfree(0x0902, bs); if((r = rsgt_getBlockParams(sigfp, 1, &bs, &bHasRecHashes, &bHasIntermedHashes)) != 0) - goto err; + goto done; rsgt_vrfyBlkInit(gf, bs, bHasRecHashes, bHasIntermedHashes); ectx.recNum = 0; ++ectx.blkNum; } ++ectx.recNum, ++ectx.recNumInFile; if((r = doVerifyRec(logfp, sigfp, nsigfp, bs, gf, &ectx, bInBlock)) != 0) - goto err; + goto done; if(ectx.recNum == bs->recCount) { - verifyBLOCK_SIG(bs, gf, sigfp, nsigfp, - (mode == MD_EXTEND) ? 1 : 0, &ectx); + if((r = verifyBLOCK_SIG(bs, gf, sigfp, nsigfp, + (mode == MD_EXTEND) ? 1 : 0, &ectx)) != 0) + goto done; bInBlock = 0; } else bInBlock = 1; } - fclose(logfp); - fclose(sigfp); - fclose(nsigfp); +done: + if(r != RSGTE_EOF) + goto err; + + fclose(logfp); logfp = NULL; + fclose(sigfp); sigfp = NULL; + fclose(nsigfp); nsigfp = NULL; + + /* everything went fine, so we rename files if we updated them */ + if(mode == MD_EXTEND) { + if(unlink(oldsigfname) != 0) { + if(errno != ENOENT) { + perror("unlink oldsig"); + r = RSGTE_IO; + goto err; + } + } + if(link(sigfname, oldsigfname) != 0) { + perror("link oldsig"); + r = RSGTE_IO; + goto err; + } + if(unlink(sigfname) != 0) { + perror("unlink cursig"); + r = RSGTE_IO; + goto err; + } + if(link(nsigfname, sigfname) != 0) { + perror("link newsig"); + fprintf(stderr, "WARNING: current sig file has been " + "renamed to %s - you need to manually recover " + "it.\n", oldsigfname); + r = RSGTE_IO; + goto err; + } + if(unlink(nsigfname) != 0) { + perror("unlink newsig"); + fprintf(stderr, "WARNING: current sig file has been " + "renamed to %s - you need to manually recover " + "it.\n", oldsigfname); + r = RSGTE_IO; + goto err; + } + } rsgtExit(); rsgt_errctxExit(&ectx); return; + err: + fprintf(stderr, "error %d processing file %s\n", r, name); if(logfp != NULL) fclose(logfp); if(sigfp != NULL) fclose(sigfp); - if(nsigfp != NULL) + if(nsigfp != NULL) { fclose(nsigfp); - if(r != RSGTE_EOF) - fprintf(stderr, "error %d processing file %s\n", r, name); + unlink(nsigfname); + } rsgtExit(); rsgt_errctxExit(&ectx); } -- cgit v1.2.3