From edcae8181571b57b058cb2249cb84b01df73d52a Mon Sep 17 00:00:00 2001 From: Michael Vrable Date: Mon, 20 Aug 2007 17:38:20 -0700 Subject: [PATCH] Implement --signature-filter for signing backup snapshots. If supplied, the argument to --signature-filter will be a program through which the text for the root snapshot descriptor is filtered. This filter should act much like "gpg --clearsign": produce a nearly-identical text file, with perhaps a few lines at the start or end containing the signature, but which can be treated as an ordinary segment descriptor by ignoring this leading and trailing data. --- NEWS | 4 ++++ scandir.cc | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index dcdd5e2..9b8ab0a 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,10 @@ 0.4? - Include an example filter script, lbs-filter-gpg, for encrypting segment data as it is written. + - Add support for signed snapshot descriptor files (via the + --signature-filter option). Due to the checksums contained in the + snapshot descriptor, the signature covers the entire contents of + the snapshot. 0.3 [2007-08-10] - LOCAL DATABASE CHANGE: A checksums file is now written out along diff --git a/scandir.cc b/scandir.cc index 44aedd2..588a907 100644 --- a/scandir.cc +++ b/scandir.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -572,6 +573,8 @@ void usage(const char *program) " --filter-extension=EXT\n" " string to append to segment files\n" " (defaults to \".bz2\")\n" + " --signature-filter=COMMAND\n" + " program though which to filter descriptor\n" " --scheme=NAME optional name for this snapshot\n", lbs_version, program ); @@ -582,6 +585,7 @@ int main(int argc, char *argv[]) string backup_dest = ""; string localdb_dir = ""; string backup_scheme = ""; + string signature_filter = ""; while (1) { static struct option long_options[] = { @@ -591,6 +595,7 @@ int main(int argc, char *argv[]) {"filter-extension", 1, 0, 0}, // 3 {"dest", 1, 0, 0}, // 4 {"scheme", 1, 0, 0}, // 5 + {"signature-filter", 1, 0, 0}, // 6 {NULL, 0, 0, 0}, }; @@ -623,6 +628,9 @@ int main(int argc, char *argv[]) case 5: // --scheme backup_scheme = optarg; break; + case 6: // --signature-filter + signature_filter = optarg; + break; default: fprintf(stderr, "Unhandled long option!\n"); return 1; @@ -762,12 +770,26 @@ int main(int argc, char *argv[]) /* Write a backup descriptor file, which says which segments are needed and * where to start to restore this snapshot. The filename is based on the - * current time. */ + * current time. If a signature filter program was specified, filter the + * data through that to give a chance to sign the descriptor contents. */ string desc_filename = backup_dest + "/snapshot-"; if (backup_scheme.size() > 0) desc_filename += backup_scheme + "-"; desc_filename = desc_filename + desc_buf + ".lbs"; - FILE *descriptor = fopen(desc_filename.c_str(), "w"); + + int descriptor_fd = open(desc_filename.c_str(), O_WRONLY | O_CREAT, 0666); + if (descriptor_fd < 0) { + fprintf(stderr, "Unable to open descriptor output file: %m\n"); + return 1; + } + pid_t signature_pid = 0; + if (signature_filter.size() > 0) { + int new_fd = spawn_filter(descriptor_fd, signature_filter.c_str(), + &signature_pid); + close(descriptor_fd); + descriptor_fd = new_fd; + } + FILE *descriptor = fdopen(descriptor_fd, "w"); fprintf(descriptor, "Format: LBS Snapshot v0.2\n"); fprintf(descriptor, "Producer: LBS %s\n", lbs_version); @@ -791,5 +813,14 @@ int main(int argc, char *argv[]) fclose(descriptor); + if (signature_pid) { + int status; + waitpid(signature_pid, &status, 0); + + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + throw IOException("Signature filter process error"); + } + } + return 0; } -- 2.20.1