From c6030012937fedfb674796c89134b153955bdf17 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Tue, 17 Mar 2015 02:52:33 +0100 Subject: edit command --- icevault | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'icevault') diff --git a/icevault b/icevault index 1c0ba1b..4690842 100755 --- a/icevault +++ b/icevault @@ -82,6 +82,7 @@ sub usage($) { ." or: $0 [OPTIONS] insert [identity]\n" ." or: $0 [OPTIONS] dump scheme://hostname/identity\n" ." or: $0 [OPTIONS] clip scheme://hostname/identity\n" + ." or: $0 [OPTIONS] edit scheme://hostname/identity\n" . "Consult the manual page for more information.\n"; exit $rv; } @@ -717,6 +718,55 @@ elsif ($command eq 'dump') { print STDOUT (defined $LOCALE ? $LOCALE->encode(YAML::Tiny::Dump $form) : YAML::Tiny::Dump $form); } +elsif ($command eq 'edit') { + usage(1) unless $#ARGV == 0; + my $id = shift; + my $file = getIdentityFile $id; + error "No such identity C<%s>", $id unless -f $file; + + error "C<%s> is not set", '$EDITOR' unless defined $ENV{EDITOR}; + $ENV{EDITOR} =~ /\A(\p{Print}+)\z/ or error "Insecure C<%s>", "\$EDITOR"; + my $EDITOR = $1; # untaint $EDITOR + + my $fh = File::Temp::->new(SUFFIX => '.yaml', UNLINK => 0, TMPDIR => 1); + END { unlink $fh->filename if defined $fh; } # never leave cleartext lying around + myprintf \*STDERR, "Decrypting identity file C<%s>", $file if $CONFIG{debug}; + + # XXX use loadIdentityFile + open my $NULL, '<', '/dev/null'; + my $pid = open2(">&".$fh->fileno, "<&".fileno($NULL), $CONFIG{gpg}, qw/-o - --decrypt --/, $file) + or error "Can't fork: %s", $!; + waitpid $pid, 0; + error "C<%s> exited with value %d", $CONFIG{gpg}, ($? >> 8) if $? and $? != -1; + $fh->close; + + my $h = sha256_file $fh->filename; + system $EDITOR, $fh->filename; + error "C<%s> exited with value %d", $EDITOR, ($? >> 8) if $? and $? != -1; + + if ($h eq sha256_file $fh->filename) { + print "No modification made\n"; + } + else { + # XXX use saveIdentityFile + # don't encrypt directly into the destination $file so we don't + # end up with a messed up $file if something goes wrong + myprintf "Saving user changes for identity C<%s>", $id; + my $outfh = File::Temp::->new(SUFFIX => '.gpg', UNLINK => 0, TMPDIR => 1); + my $pid = open2(">&".$outfh->fileno, "<&".fileno($NULL), + $CONFIG{gpg}, qw/-o - --no-encrypt-to --recipient/, $CONFIG{keyid}, + '--encrypt', '--', $fh->filename) + or error "Can't fork: %s", $!; + waitpid $pid, 0; + error "C<%s> exited with value %d", $CONFIG{gpg}, ($? >> 8) if $? and $? != -1; + $outfh->close; + + move $outfh->filename, $file or error "Can't move C<%s>: %s", $outfh->filename, $!; + } + + close $NULL; +} + elsif ($command eq 'clip') { usage(1) unless $#ARGV == 0; my $id = shift; -- cgit v1.2.3