aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xcli/icevault58
1 files changed, 37 insertions, 21 deletions
diff --git a/cli/icevault b/cli/icevault
index 73136d1..992ee6a 100755
--- a/cli/icevault
+++ b/cli/icevault
@@ -80,6 +80,11 @@ sub usage($) {
exit $rv;
}
+sub mysystem(@) {
+ system {$_[0]} @_;
+ error "C<%s> exited with value %d", $_[0], ($? >> 8) if $? and $? != -1;
+}
+
# grepIdx BLOCK LIST
# Evaluates the BLOCK for each element of LIST (locally setting $_ to
# each element) and returns the list value consisting of the index of
@@ -134,7 +139,7 @@ sub loadConfig($) {
chomp;
s/#.*//; # ignore comments
next if /^\s*$/; # ignore empty and blank lines
- /^([-\@\w.]+)(?:\s*=\s*)(\p{print}+)/ or error "Can't parse config line: C<%s>", $_;
+ /^([-\@a-zA-Z0-9.]+)(?:\s*=\s*)(\p{Print}+)/ or error "Can't parse config line: C<%s>", $_;
$CONFIG{$1} //= $2;
}
close $CONFIG;
@@ -162,10 +167,11 @@ sub connect($) {
}
closedir $dh;
error "No Firefox profile found under C<%s>", $ffdir unless defined $profile;
- "$ffdir/$profile" =~ /\A(\p{Print}+)\z/ or error "Insecure C<%s>", "$ffdir/$profile"; # untaint $ffdir/$profile
- $sockname = "$1/$sockname";
- myprintf \*STDERR, "Using socket C<%s>", $sockname if $CONFIG{debug};
+ $sockname = "$$ffdir/$profile/$sockname";
}
+ myprintf \*STDERR, "Using socket C<%s>", $sockname if $CONFIG{debug};
+ $sockname =~ /\A(\/\p{Print}+)\z/ or error "Insecure C<%s>", $sockname; # untaint $sockname
+ $sockname = $1;
require 'IO/Socket/UNIX.pm';
$SOCKET = IO::Socket::UNIX->new( Type => IO::Socket::UNIX::SOCK_STREAM(), Peer => $sockname )
@@ -224,13 +230,31 @@ sub sendCommand(@) {
getResponse();
}
+
+# Glob over all form templates. Note that the output needs to be
+# $LOCALE-decode'ed.
+sub myglob(;$$$) {
+ my ($s, $h, $i) = @_;
+ my $glob = $LOCALE->encode($CONFIG{store});
+ require 'File/Glob.pm';
+
+ $glob =~ s/([\\\[\]\{\}\*\?\~])/\\$1/g;
+ $glob =~ s{\%(.)}{ $1 eq '%' ? '%' :
+ $1 eq 's' ? $s // '*' :
+ $1 eq 'h' ? $h // '*' :
+ $1 eq 'i' ? $i // '*' :
+ die "Invalid placeholder %$1" }ge;
+
+ myprintf \*STDERR, "Using glob pattern C<%s>", $glob if $CONFIG{debug};
+ return File::Glob::bsd_glob($glob);
+}
+
# Get all identities with the given $prefix. If there are multiple
# matches and $all is false, limit the output to one depth more than the
# longuest common prefix.
sub complete($;$) {
my $prefix = shift // '';
my $all = shift;
- require 'File/Glob.pm';
my $pat = $CONFIG{store};
my ($s, $h, $i); # extract URI components from the prefix
@@ -253,14 +277,6 @@ sub complete($;$) {
$gh .= '*' if defined $gh and !defined $gi;
$gi .= '*' if defined $gi;
- my $glob = $pat;
- $glob =~ s/([\\\[\]\{\}\*\?\~])/\\$1/g;
- $glob =~ s{\%(.)}{ $1 eq '%' ? '%' :
- $1 eq 's' ? $gs // '*' :
- $1 eq 'h' ? $gh // '*' :
- $1 eq 'i' ? $gi // '*' :
- die "Invalid placeholder %$1" }ge;
-
# construct regexp to extract the URI compontents of the matching URIs
my ($ps, $ph, $pi) = ($s, $h, $i);
$ps = defined $h ? qr/(?<s>\Q$s\E)/ : (defined $s and $s ne '') ? qr/(?<s>\Q$s\E[A-Za-z0-9-]*)/ : qr/(?<s>[A-Za-z0-9-]+)/;
@@ -275,11 +291,11 @@ sub complete($;$) {
die "Invalid placeholder %$1"}ge;
$pat = qr/\A$pat\z/;
- myprintf \*STDERR, "Using glob pattern C<%s>", $glob if $CONFIG{debug};
- myprintf \*STDERR, "Using regexp C<%s>", "$pat" if $CONFIG{debug};
+ myprintf \*STDERR, "Using regexp C<%s>", "$pat" if $CONFIG{debug};
my @matches;
- foreach my $filename (File::Glob::bsd_glob($glob)) {
+ foreach my $filename (myglob($gs, $gh, $gi)) {
+ next unless -f $filename;
$LOCALE->decode($filename) =~ $pat or die "$filename doesn't match $pat";
push @matches, "$+{s}://$+{h}/$+{i}";
}
@@ -339,8 +355,7 @@ sub getIdentityFile($) {
$1 eq 'h' ? $h :
$1 eq 'i' ? $i :
die "Invalid placeholder %$1" }ge;
- $filename =~ /\A(\p{Print}+)\z/ or error "Insecure C<%s>", $filename; # untaint $filename
- return $1;
+ return $filename;
}
# Decrypt the given identity file. In scalar context, return the
@@ -846,8 +861,9 @@ elsif ($command eq 'edit') {
require 'File/Temp.pm';
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 $EDITOR = $ENV{EDITOR} // 'editor';
+ $EDITOR =~ /\A(\p{Print}+)\z/ or error "Insecure C<%s>", "\$EDITOR";
+ $EDITOR = $1; # untaint $EDITOR
my $fh = File::Temp->new(SUFFIX => '.yaml', UNLINK => 0, TMPDIR => 1) or die;
END { unlink $fh->filename if defined $fh; } # never leave cleartext lying around
@@ -855,7 +871,7 @@ elsif ($command eq 'edit') {
my $h = sha256_file $fh->filename;
while (1) {
- system $EDITOR, $fh->filename;
+ mysystem $EDITOR, $fh->filename;
error "C<%s> exited with value %d", $EDITOR, ($? >> 8) if $? and $? != -1;
my $h2 = sha256_file $fh->filename;