Skip Menu |

This queue is for tickets about the Crypt-Pwsafe CPAN distribution.

Report information
The Basics
Id: 70302
Status: new
Priority: 0/
Queue: Crypt-Pwsafe

People
Owner: Nobody in particular
Requestors: sbeasley [...] acm.org
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: 1.2
Fixed in: (no value)



Subject: more flexible handling of password input
I have a script where I open two password files, use Crypt::Pwsafe to decrypt them, perform a "diff" on the two, then pipe the result to another program which colorizes diff-syntax output. Attached is a patch which adds the following features that I found necessary: - accepts a file handle or name (v1.2 only accepts a name) - accepts a custom user prompt as an argument to enter_combination - prints user prompt to STDERR rather than STDOUT - uses standard POSIX module rather than Term::ReadKey - restores terminal to normal state on SIGINT/__DIE__ (Ctrl-C) You might also want to remove Term::ReadKey from the prerequisites, although I didn't need to do that over here. :)
Subject: io.patch
diff '--exclude=CVS' -wur Crypt/Pwsafe.pm Crypt/Pwsafe.pm --- Crypt/Pwsafe.pm 2011-08-16 11:59:04.234375000 -0700 +++ Crypt/Pwsafe.pm 2011-03-06 20:16:41.893250000 -0800 @@ -11,8 +11,8 @@ use strict; use FileHandle; -use Term::ReadKey; # comment me out -#use autouse Term::ReadKey; +use POSIX qw(:termios_h); + my $SHA = "Digest::SHA"; eval "use $SHA"; if ($@) { $SHA .= "::PurePerl"; eval "use $SHA" } @@ -97,7 +97,7 @@ sub new { my ($class, $file, $pw) = @_; - my $fh = new FileHandle $file; + my $fh = ref( $file ) eq 'GLOB' ? $file : new FileHandle $file; die "Failed to open $file\n" unless defined $fh; $pw = enter_combination() unless defined $pw; my $header; @@ -243,13 +244,24 @@ } sub enter_combination { - print "Enter password safe combination: "; - local $SIG{__DIE__} = { ReadMode 0 }; - ReadMode 2; - my $pass = <STDIN>; - ReadMode 0; - chomp($pass); - print "\n"; + my ($prompt) = @_; + + my $termios = POSIX::Termios->new; + my $stdin = fileno STDIN; + $termios->getattr($stdin); + my $flag = $termios->getlflag; + my $reset = sub { + $termios->setlflag($flag); + $termios->setattr($stdin); + exit @_ if @_; + }; + print STDERR ($prompt or "Enter password safe combination: "); + local $SIG{'INT'} = local $SIG{__DIE__} = $reset; + $termios->setlflag($flag & ~(ECHO|ECHOK|ICANON)); + $termios->setattr($stdin); + chomp(my $pass = <STDIN>); + $reset->(); + print STDERR "\n"; return $pass; }
From: sbeasley [...] acm.org
On Tue Aug 16 15:28:49 2011, sbeasley wrote: Show quoted text
> - restores terminal to normal state on SIGINT/__DIE__ (Ctrl-C)
Attached slightly better patch: In both patches, it prints the prompt, reads input, then prints a newline. However, if you press Ctrl-C, the old patch doesn't print the newline, instead leaving the caret on the prompt line. The new patch prints the newline in any case, which I think is better.
Subject: io.patch
diff '--exclude=CVS' -L Crypt/Pwsafe.pm -L Crypt/Pwsafe.pm -wur Crypt/Pwsafe.pm Crypt/Pwsafe.pm --- Crypt/Pwsafe.pm +++ Crypt/Pwsafe.pm @@ -11,8 +11,8 @@ use strict; use FileHandle; -use Term::ReadKey; # comment me out -#use autouse Term::ReadKey; +use POSIX qw(:termios_h); + my $SHA = "Digest::SHA"; eval "use $SHA"; if ($@) { $SHA .= "::PurePerl"; eval "use $SHA" } @@ -97,7 +97,7 @@ sub new { my ($class, $file, $pw) = @_; - my $fh = new FileHandle $file; + my $fh = ref( $file ) eq 'GLOB' ? $file : new FileHandle $file; die "Failed to open $file\n" unless defined $fh; $pw = enter_combination() unless defined $pw; my $header; @@ -243,13 +244,24 @@ } sub enter_combination { - print "Enter password safe combination: "; - local $SIG{__DIE__} = { ReadMode 0 }; - ReadMode 2; - my $pass = <STDIN>; - ReadMode 0; - chomp($pass); - print "\n"; + my ($prompt) = @_; + + my $termios = POSIX::Termios->new; + my $stdin = fileno STDIN; + $termios->getattr($stdin); + my $flag = $termios->getlflag; + my $reset = sub { + print STDERR "\n"; + $termios->setlflag($flag); + $termios->setattr($stdin); + exit @_ if @_; + }; + print STDERR ($prompt or "Enter password safe combination: "); + local $SIG{'INT'} = local $SIG{__DIE__} = $reset; + $termios->setlflag($flag & ~(ECHO|ECHOK|ICANON)); + $termios->setattr($stdin); + chomp(my $pass = <STDIN>); + $reset->(); return $pass; }