Browse Source

gfsec-use: Add the restore/delete-cmd options.

These options allow the user to automatically call another
program when the secret has been reconstructed and when it
should be destroyed.

Incenp-bug-id: 8
master
Damien Goutte-Gattat 4 years ago
parent
commit
c2ef91c240
  1. 79
      src/gfsec-use.c

79
src/gfsec-use.c

@ -60,6 +60,14 @@ secret is destroyed when the command or the shell terminates.\n"));
-o, --output FILE Write reconstructed secret in the specified\n\
file (override configuration file).\n"));
puts(_("\
-r, --restore-cmd CMD Execute the specified command instead of\n\
writing the reconstructed secret to disk.\n\
The secret will be send to the standard\n\
input of the command.\n\
-d, --delete-cmd CMD Execute the specified command instead of\n\
deleting the reconstructed file.\n"));
printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
exit(status);
@ -150,34 +158,52 @@ get_share_data(gfsec_share_t *share)
return rc;
}
static void
delete_secret(const char *filename, const char *delete_cmd)
{
if ( delete_cmd ) {
int status;
status = system(delete_cmd);
if ( ! WIFEXITED(status) )
errx(EXIT_FAILURE, "Delete command terminated anormally");
}
else if ( unlink(filename) == -1 )
err(EXIT_FAILURE, "Cannot delete reconstructed file");
}
int
main(int argc, char **argv)
{
int c, keep;
const char *cfg_file, *output_file;
const char *cfg_file, *output_file, *restore_cmd, *delete_cmd;
char cfg_path[255];
gfsec_secret_t *cfg;
pid_t pid;
unsigned u;
struct option options[] = {
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'v' },
{ "config", 1, NULL, 'c' },
{ "keep", 0, NULL, 'k' },
{ "output", 1, NULL, 'o' },
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'v' },
{ "config", 1, NULL, 'c' },
{ "keep", 0, NULL, 'k' },
{ "output", 1, NULL, 'o' },
{ "restore-cmd", 1, NULL, 'r' },
{ "delete-cmd", 1, NULL, 'd' },
{ NULL, 0, NULL, 0 }
};
setprogname(argv[0]);
cfg_file = output_file = NULL;
restore_cmd = delete_cmd = NULL;
keep = 0;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
while ( (c = getopt_long(argc, argv, "hvc:ko:", options, NULL)) != -1 ) {
while ( (c = getopt_long(argc, argv, "hvc:ko:r:d:",
options, NULL)) != -1 ) {
switch ( c ) {
case 'h':
usage(EXIT_SUCCESS);
@ -202,6 +228,14 @@ main(int argc, char **argv)
case 'o':
output_file = optarg;
break;
case 'r':
restore_cmd = optarg;
break;
case 'd':
delete_cmd = optarg;
break;
}
}
@ -223,8 +257,11 @@ main(int argc, char **argv)
errx(EXIT_FAILURE, _("%s (line %u): %s"), cfg_path, u, gfsec_error_string(c));
}
if ( ! output_file && ! (output_file = cfg->filename) )
errx(EXIT_FAILURE, _("No output file specified"));
if ( ! output_file && ! restore_cmd && !(output_file = cfg->filename) )
errx(EXIT_FAILURE, _("No output file or restore command specified"));
if ( restore_cmd && ! delete_cmd )
keep = 1;
for ( u = 0; u < cfg->n_shares; u++ )
get_share_data(cfg->shares[u]);
@ -235,7 +272,18 @@ main(int argc, char **argv)
if ( (c = gfsec_secret_combine(cfg)) != 0 )
errx(EXIT_FAILURE, _("Error while reconstituting secret: %s"), gfsec_error_string(c));
if ( write_file(output_file, cfg->data, cfg->len) == -1 )
if ( restore_cmd ) {
FILE *out;
if ( ! (out = popen(restore_cmd, "w")) )
err(EXIT_FAILURE, _("Cannot execute command"));
if ( fwrite(cfg->data, 1, cfg->len, out) != cfg->len )
err(EXIT_FAILURE, _("Cannot send secret to command"));
pclose(out);
}
else if ( write_file(output_file, cfg->data, cfg->len) == -1 )
err(EXIT_FAILURE, _("Cannot write secret"));
if ( keep && argc >= optind ) {
@ -246,8 +294,9 @@ main(int argc, char **argv)
}
if ( (pid = fork()) == -1 ) {
unlink(cfg->filename);
err(EXIT_FAILURE, _("Cannot fork"));
warn(_("Cannot fork"));
delete_secret(output_file, delete_cmd);
exit(EXIT_FAILURE);
}
else if ( pid == 0 ) {
gfsec_secret_free(cfg);
@ -280,12 +329,10 @@ main(int argc, char **argv)
err(EXIT_FAILURE, _("Cannot wait for child process"));
if ( ! WIFEXITED(status) )
err(EXIT_FAILURE, _("Child process terminated anormally"));
errx(EXIT_FAILURE, _("Child process terminated anormally"));
printf(_("Removing secret.\n"));
if ( unlink(output_file) == -1 )
err(EXIT_FAILURE, _("Cannot delete reconstructed file"));
delete_secret(output_file, delete_cmd);
}
gfsec_secret_free(cfg);

Loading…
Cancel
Save