aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2015-03-17 02:52:33 +0100
committerGuilhem Moulin <guilhem@fripost.org>2015-03-17 02:52:33 +0100
commitc6030012937fedfb674796c89134b153955bdf17 (patch)
tree94fe996c6524571938b99af7f98dd544196e63b7
parent2982c60270152f229f2c414e30e6de510c8cfbe3 (diff)
edit command
-rwxr-xr-xicevault50
-rw-r--r--icevault.111
2 files changed, 61 insertions, 0 deletions
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;
diff --git a/icevault.1 b/icevault.1
index a58a1e1..f2b3b76 100644
--- a/icevault.1
+++ b/icevault.1
@@ -11,6 +11,8 @@ IceVault \- IceVault client user interface
.B icevault\fR [\fIOPTIONS\fR] \fBdump\fR \fIscheme\fR://\fIhostname\fR/\fIidentity\fR
.br
.B icevault\fR [\fIOPTIONS\fR] \fBclip\fR \fIscheme\fR://\fIhostname\fR/\fIidentity\fR
+.br
+.B icevault\fR [\fIOPTIONS\fR] \fBedit\fR \fIscheme\fR://\fIhostname\fR/\fIidentity\fR
.SH DESCRIPTION
@@ -77,11 +79,20 @@ Decrypt the \fIidentity\fR file and dump its content on the standard
output. Note that while the output is a valid YAML document, original
formatting may not be preserved; in particular, comments and empty lines
are stripped.
+
.TP
.B clip\fR \fIscheme\fR://\fIhostname\fR/\fIidentity\fR
Decrypt the \fIidentity\fR file and copy the first password to the
clipboard using \fIxclip\fR(1), with a maximum number of pastes of 1.
+.TP
+.B edit\fR \fIscheme\fR://\fIhostname\fR/\fIidentity\fR
+Decrypt the \fIidentity\fR file to a temporary file and opens it using
+the editor specified by the EDITOR environment variable. When the
+editor exits, the file is reencrypted if the SHA-256 digest of its
+content differs. Note that formatting and comments may not be preserved
+by subsequent updates of the \fIidentity\fR file.
+
.SH OPTIONS
.TP