r10329 - in /branches/upstream/libterm-readpassword-perl: ./ current/ current/Changes current/MANIFEST current/META.yml current/Makefile.PL current/README current/ReadPassword.pm current/t/ current/t/1_basics.t current/t/2_interactive.t

vdanjean at users.alioth.debian.org vdanjean at users.alioth.debian.org
Sat Dec 1 12:16:26 UTC 2007


Author: vdanjean
Date: Sat Dec  1 12:16:26 2007
New Revision: 10329

URL: http://svn.debian.org/wsvn/?sc=1&rev=10329
Log:
[svn-inject] Installing original source of libterm-readpassword-perl

Added:
    branches/upstream/libterm-readpassword-perl/
    branches/upstream/libterm-readpassword-perl/current/
    branches/upstream/libterm-readpassword-perl/current/Changes
    branches/upstream/libterm-readpassword-perl/current/MANIFEST
    branches/upstream/libterm-readpassword-perl/current/META.yml
    branches/upstream/libterm-readpassword-perl/current/Makefile.PL
    branches/upstream/libterm-readpassword-perl/current/README
    branches/upstream/libterm-readpassword-perl/current/ReadPassword.pm
    branches/upstream/libterm-readpassword-perl/current/t/
    branches/upstream/libterm-readpassword-perl/current/t/1_basics.t
    branches/upstream/libterm-readpassword-perl/current/t/2_interactive.t

Added: branches/upstream/libterm-readpassword-perl/current/Changes
URL: http://svn.debian.org/wsvn/branches/upstream/libterm-readpassword-perl/current/Changes?rev=10329&op=file
==============================================================================
--- branches/upstream/libterm-readpassword-perl/current/Changes (added)
+++ branches/upstream/libterm-readpassword-perl/current/Changes Sat Dec  1 12:16:26 2007
@@ -1,0 +1,19 @@
+Revision history for Perl extension Term::ReadPassword.
+
+0.01  Wed Dec 13 07:57:34 2000
+	- original version; created by h2xs 1.18
+
+0.02  Wed Dec 8 2004
+	- added support for ctrl-U (James FitzGibbon
+	  <jfitzgibbon at primustel.ca>)
+
+0.03  Tue Mar 29 18:35:03 2005
+	- updated tests to (try to) pass automated tests
+
+0.04  Thu Mar 31 13:17:00 2005
+	- tweaked tests some more, trying to pass those automated tests
+	- still no new functionality
+
+0.05  Tue Jun 14 11:50:00 2005
+	- a space in place of the password now skips the interactive test
+	- save and restore the cc array, which seems to fix a bug

Added: branches/upstream/libterm-readpassword-perl/current/MANIFEST
URL: http://svn.debian.org/wsvn/branches/upstream/libterm-readpassword-perl/current/MANIFEST?rev=10329&op=file
==============================================================================
--- branches/upstream/libterm-readpassword-perl/current/MANIFEST (added)
+++ branches/upstream/libterm-readpassword-perl/current/MANIFEST Sat Dec  1 12:16:26 2007
@@ -1,0 +1,8 @@
+README
+Changes
+MANIFEST
+Makefile.PL
+ReadPassword.pm
+t/1_basics.t
+t/2_interactive.t
+META.yml

Added: branches/upstream/libterm-readpassword-perl/current/META.yml
URL: http://svn.debian.org/wsvn/branches/upstream/libterm-readpassword-perl/current/META.yml?rev=10329&op=file
==============================================================================
--- branches/upstream/libterm-readpassword-perl/current/META.yml (added)
+++ branches/upstream/libterm-readpassword-perl/current/META.yml Sat Dec  1 12:16:26 2007
@@ -1,0 +1,10 @@
+# http://module-build.sourceforge.net/META-spec.html
+#XXXXXXX This is a prototype!!!  It will change in the future!!! XXXXX#
+name:         Term-ReadPassword
+version:      0.05
+version_from: ReadPassword.pm
+installdirs:  site
+requires:
+
+distribution_type: module
+generated_by: ExtUtils::MakeMaker version 6.25

Added: branches/upstream/libterm-readpassword-perl/current/Makefile.PL
URL: http://svn.debian.org/wsvn/branches/upstream/libterm-readpassword-perl/current/Makefile.PL?rev=10329&op=file
==============================================================================
--- branches/upstream/libterm-readpassword-perl/current/Makefile.PL (added)
+++ branches/upstream/libterm-readpassword-perl/current/Makefile.PL Sat Dec  1 12:16:26 2007
@@ -1,0 +1,8 @@
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+    'NAME'	=> 'Term::ReadPassword',
+    'VERSION_FROM' => 'ReadPassword.pm', # finds $VERSION
+    'dist'	=> { 'COMPRESS' => 'gzip', 'SUFFIX' => 'gz' },
+);

Added: branches/upstream/libterm-readpassword-perl/current/README
URL: http://svn.debian.org/wsvn/branches/upstream/libterm-readpassword-perl/current/README?rev=10329&op=file
==============================================================================
--- branches/upstream/libterm-readpassword-perl/current/README (added)
+++ branches/upstream/libterm-readpassword-perl/current/README Sat Dec  1 12:16:26 2007
@@ -1,0 +1,122 @@
+This module is in alpha-testing. Build in the usual way; send bug reports
+and patches to me at the address below. From the documentation:
+
+NAME
+    Term::ReadPassword - Asking the user for a password
+
+SYNOPSIS
+      use Term::ReadPassword;
+      while (1) {
+        my $password = read_password('password: ');
+        redo unless defined $password;
+        if ($password eq 'flubber') {
+          print "Access granted.\n";
+          last;
+        } else {
+          print "Access denied.\n";
+          redo;
+        }
+      }
+
+DESCRIPTION
+    This module lets you ask the user for a password in the
+    traditional way, from the keyboard, without echoing.
+
+    This is not intended for use over the web; user authentication
+    over the web is another matter entirely. Also, this module
+    should generally be used in conjunction with Perl's crypt()
+    function, sold separately.
+
+    The read_password function prompts for input, reads a line of
+    text from the keyboard, then returns that line to the caller.
+    The line of text doesn't include the newline character, so
+    there's no need to use chomp.
+
+    While the user is entering the text, a few special characters
+    are processed. The character delete (or the character backspace)
+    will back up one character, removing the last character in the
+    input buffer (if any). The character CR (or the character LF)
+    will signal the end of input, causing the accumulated input
+    buffer to be returned. And, optionally, the character Control-C
+    may be used to terminate the input operation. (See details
+    below.) All other characters, even ones which would normally
+    have special purposes, will be added to the input buffer.
+
+    It is not recommended, though, that you use the as-yet-
+    unspecified control characters in your passwords, as those
+    characters may become meaningful in a future version of this
+    module. Applications which allow the user to set their own
+    passwords may wish to enforce this rule, perhaps with code
+    something like this:
+
+        {
+          # Naked block for scoping and redo
+          my $new_pw = read_password("Enter your new password: ");
+          if ($new_pw =~ /([^\x20-\x7E])/) {
+            my $bad = unpack "H*", $1;
+            print "Your password may not contain the ";
+            print "character with hex code $bad.\n";
+            redo;
+          } elsif (length($new_pw) < 5) {
+            print "Your password must be longer than that!\n";
+            redo;
+          } elsif ($new_pw ne read_password("Enter it again: ")) {
+            print "Passwords don't match.\n";
+            redo;
+          } else {
+            &change_password($new_pw);
+            print "Your password is now changed.\n";
+          }
+        }
+
+    The second parameter to read_password is the optional
+    `idle_timeout' value. If it is a non-zero number and there is no
+    keyboard input for that many seconds, the input operation will
+    terminate. Notice that this is not an overall time limit, as the
+    timer is restarted with each new character.
+
+    The third parameter will optionally allow the input operation to
+    be terminated by the user with Control-C. If this is not
+    supplied, or is false, a typed Control-C will be entered into
+    the input buffer just as any other character. In that case,
+    there is no way from the keyboard to terminate the program while
+    it is waiting for input. (That is to say, the normal ability to
+    generate signals from the keyboard is suspended during the call
+    to read_password.)
+
+    If the input operation terminates early (either because the
+    idle_timeout was exceeded, or because a Control-C was enabled
+    and typed), the return value will be `undef'. In either case,
+    there is no way provided to discover what (if anything) was
+    typed before the early termination, or why the input operation
+    was terminated.
+
+    So as to discourage users from typing their passwords anywhere
+    except at the prompt, any input which has been "typed ahead"
+    before the prompt appears will be discarded. And whether the
+    input operation terminates normally or not, a newline character
+    will be printed, so that the cursor will not remain on the line
+    after the prompt.
+
+SECURITY
+    You would think that a module dealing with passwords would be
+    full of security features. You'd think that, but you'd be wrong.
+    For example, perl provides no way to erase a piece of data from
+    memory. (It's easy to erase it so that it can't be accessed from
+    perl, but that's not the same thing as expunging it from the
+    actual memory.) If you've entered a password, even if the
+    variable that contained that password has been erased, it may be
+    possible for someone to find that password, in plaintext, in a
+    core dump. And that's just one potential security hole.
+
+    In short, if serious security is an issue, don't use this
+    module.
+
+AUTHOR
+    Tom Phoenix <rootbeer at redcat.com>
+
+SEE ALSO
+    Term::ReadLine, the "crypt" entry in the perlfunc manpage, and
+    your system's manpages for the low-level I/O operations used
+    here.
+

Added: branches/upstream/libterm-readpassword-perl/current/ReadPassword.pm
URL: http://svn.debian.org/wsvn/branches/upstream/libterm-readpassword-perl/current/ReadPassword.pm?rev=10329&op=file
==============================================================================
--- branches/upstream/libterm-readpassword-perl/current/ReadPassword.pm (added)
+++ branches/upstream/libterm-readpassword-perl/current/ReadPassword.pm Sat Dec  1 12:16:26 2007
@@ -1,0 +1,285 @@
+package Term::ReadPassword;
+
+use strict;
+use Term::ReadLine;
+use POSIX qw(:termios_h);
+    use constant CC_FIELDS =>
+	(VEOF VEOL VERASE VINTR VKILL VQUIT
+	VSUSP VSTART VSTOP VMIN VTIME NCCS);
+
+use vars qw(
+    $VERSION @ISA @EXPORT @EXPORT_OK
+    $ALLOW_STDIN %SPECIAL $SUPPRESS_NEWLINE $INPUT_LIMIT
+);
+
+require Exporter;
+
+ at ISA = qw(Exporter);
+ at EXPORT = qw(
+	read_password 
+);
+$VERSION = '0.05';
+
+# The special characters in the input stream
+%SPECIAL = (
+    "\x03"	=> 'INT',	# Control-C, Interrupt
+    "\x15"	=> 'NAK',	# Control-U, NAK (clear buffer)
+    "\x08"	=> 'DEL',	# Backspace
+    "\x7f"	=> 'DEL',	# Delete
+    "\x0d"	=> 'ENT',	# CR, Enter
+    "\x0a"	=> 'ENT',	# LF, Enter
+);
+
+# The maximum amount of data for the input buffer to hold
+$INPUT_LIMIT = 1000;
+
+sub read_password {
+    my($prompt, $idle_limit, $interruptable) = @_;
+    $prompt = '' unless defined $prompt;
+    $idle_limit = 0 unless defined $idle_limit;
+    $interruptable = 0 unless defined $interruptable;
+
+    # Let's open the TTY (rather than STDIN) if we can
+    local(*TTY, *TTYOUT);
+    my($in, $out) = Term::ReadLine->findConsole;
+    die "No console available" unless $in;
+    if (open TTY, "+<$in") {
+        # Cool
+    } elsif ($ALLOW_STDIN) {
+        open TTY, "<&STDIN"
+	    or die "Can't re-open STDIN: $!";
+    } else {
+        die "Can't open '$in' read/write: $!";
+    }
+
+    # And let's send the output to the TTY as well
+    if (open TTYOUT, ">>$out") {
+	# Cool
+    } elsif ($ALLOW_STDIN) {
+	# Well, let's allow STDOUT as well
+	open TTYOUT, ">>&STDOUT"
+	    or die "Can't re-open STDOUT: $!";
+    } else {
+	die "Can't open '$out' for output: $!";
+    }
+
+    # Don't buffer it!
+    select( (select(TTYOUT), $|=1)[0] );
+    print TTYOUT $prompt;
+
+    # Okay, now remember where everything was, so we can put it back when
+    # we're done 
+    my $fd_tty = fileno(TTY);
+    my $term = POSIX::Termios->new();
+    $term->getattr($fd_tty);
+    my $original_flags = $term->getlflag();
+    my %original_cc = map +($_, $term->getcc($_)), CC_FIELDS;
+
+    # What makes this setup different from the ordinary?
+    # No keyboard-generated signals, no echoing, no canonical input
+    # processing (like backspace handling)
+    my $flags = $original_flags & ~(ISIG | ECHO | ICANON);
+    $term->setlflag($flags);
+    if ($idle_limit) {
+	# $idle_limit is in seconds, so multiply by ten
+	$term->setcc(VTIME, 10 * $idle_limit);
+	# Continue running the program after that time, even if there
+	# weren't any characters typed
+	$term->setcc(VMIN, 0);
+    } else {
+	# No time limit, but...
+	$term->setcc(VTIME, 0);
+	# Continue as soon as one character has been struck
+	$term->setcc(VMIN, 1);
+    }
+
+    # If there's anything already buffered, we should throw it out. This
+    # is to discourage users from typing their password before they see
+    # the prompt, since their keystrokes may be echoing on the screen. 
+    #
+    # So this statement supposedly makes sure the prompt goes out, the
+    # unread input buffer is discarded, and _then_ the changes take
+    # effect. Thus, everything they typed ahead is (probably) echoed.
+    $term->setattr($fd_tty, TCSAFLUSH);
+
+    my $input = '';
+    my $return_value;
+KEYSTROKE:
+    while (1) {
+        my $new_keys = '';
+	my $count = sysread(TTY, $new_keys, 99);
+	# We're here, so either the idle_limit expired, or the user typed
+	# something.
+	if ($count) {
+	    for my $new_key (split //, $new_keys) {
+	        if (my $meaning = $SPECIAL{$new_key}) {
+		    if ($meaning eq 'ENT') {
+		        # Enter/return key
+			# Return what we have so far
+			$return_value = $input;
+			last KEYSTROKE;
+		    } elsif ($meaning eq 'DEL') {
+		        # Delete/backspace key
+			# Take back one char, if possible
+			chop $input;
+		    } elsif ($meaning eq 'NAK') {
+		        # Control-U (NAK)
+		        # Clear what we have read so far
+		        $input = '';
+		    } elsif ($interruptable and $meaning eq 'INT') {
+			# Breaking out of the program
+			# Return early
+			last KEYSTROKE;
+		    } else {
+		        # Just an ordinary keystroke
+			$input .= $new_key;
+		    }
+		} else {
+		    # Not special
+		    $input .= $new_key;
+		}
+ 	    }
+	    # Just in case someone sends a lot of data
+	    $input = substr($input, 0, $INPUT_LIMIT)
+	        if length($input) > $INPUT_LIMIT;
+	} else {
+	    # No count, so something went wrong. Assume timeout.
+	    # Return early
+	    last KEYSTROKE;
+	}
+    }
+
+    # Done with waiting for input. Let's not leave the cursor sitting
+    # there, after the prompt.
+    print TTY "\n" unless $SUPPRESS_NEWLINE;
+
+    # Let's put everything back where we found it.
+    $term->setlflag($original_flags);
+    while (my($field, $value) = each %original_cc) {
+        $term->setcc($field, $value);
+    }
+    $term->setattr($fd_tty, TCSAFLUSH);
+    close(TTY);
+    close(TTYOUT);
+    $return_value;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Term::ReadPassword - Asking the user for a password
+
+=head1 SYNOPSIS
+
+  use Term::ReadPassword;
+  while (1) {
+    my $password = read_password('password: ');
+    redo unless defined $password;
+    if ($password eq 'flubber') {
+      print "Access granted.\n";
+      last;
+    } else {
+      print "Access denied.\n";
+      redo;
+    }
+  }
+
+=head1 DESCRIPTION
+
+This module lets you ask the user for a password in the traditional way,
+from the keyboard, without echoing.
+
+This is not intended for use over the web; user authentication over the
+web is another matter entirely. Also, this module should generally be used
+in conjunction with Perl's B<crypt()> function, sold separately.
+
+The B<read_password> function prompts for input, reads a line of text from
+the keyboard, then returns that line to the caller. The line of text
+doesn't include the newline character, so there's no need to use B<chomp>.
+
+While the user is entering the text, a few special characters are processed.
+The character delete (or the character backspace) will back up one
+character, removing the last character in the input buffer (if any). The
+character CR (or the character LF) will signal the end of input, causing the
+accumulated input buffer to be returned. Control-U will empty the input
+buffer. And, optionally, the character Control-C may be used to terminate
+the input operation. (See details below.) All other characters, even ones
+which would normally have special purposes, will be added to the input
+buffer.
+
+It is not recommended, though, that you use the as-yet-unspecified control
+characters in your passwords, as those characters may become meaningful in
+a future version of this module. Applications which allow the user to set
+their own passwords may wish to enforce this rule, perhaps with code
+something like this:
+
+    {
+      # Naked block for scoping and redo
+      my $new_pw = read_password("Enter your new password: ");
+      if ($new_pw =~ /([^\x20-\x7E])/) {
+        my $bad = unpack "H*", $1;
+	print "Your password may not contain the ";
+	print "character with hex code $bad.\n";
+	redo;
+      } elsif (length($new_pw) < 5) {
+        print "Your password must be longer than that!\n";
+	redo;
+      } elsif ($new_pw ne read_password("Enter it again: ")) {
+	print "Passwords don't match.\n";
+	redo;
+      } else {
+        &change_password($new_pw);
+	print "Your password is now changed.\n";
+      }
+    }
+
+The second parameter to B<read_password> is the optional C<idle_timeout>
+value. If it is a non-zero number and there is no keyboard input for that
+many seconds, the input operation will terminate. Notice that this is not
+an overall time limit, as the timer is restarted with each new character.
+
+The third parameter will optionally allow the input operation to be
+terminated by the user with Control-C. If this is not supplied, or is
+false, a typed Control-C will be entered into the input buffer just as any
+other character. In that case, there is no way from the keyboard to
+terminate the program while it is waiting for input. (That is to say, the
+normal ability to generate signals from the keyboard is suspended during
+the call to B<read_password>.)
+
+If the input operation terminates early (either because the idle_timeout
+was exceeded, or because a Control-C was enabled and typed), the return
+value will be C<undef>. In either case, there is no way provided to
+discover what (if anything) was typed before the early termination, or why
+the input operation was terminated.
+
+So as to discourage users from typing their passwords anywhere except at
+the prompt, any input which has been "typed ahead" before the prompt
+appears will be discarded. And whether the input operation terminates
+normally or not, a newline character will be printed, so that the cursor
+will not remain on the line after the prompt. 
+
+=head1 SECURITY
+
+You would think that a module dealing with passwords would be full of
+security features. You'd think that, but you'd be wrong. For example, perl
+provides no way to erase a piece of data from memory. (It's easy to erase
+it so that it can't be accessed from perl, but that's not the same thing
+as expunging it from the actual memory.) If you've entered a password,
+even if the variable that contained that password has been erased, it may
+be possible for someone to find that password, in plaintext, in a core
+dump. And that's just one potential security hole.
+
+In short, if serious security is an issue, don't use this module.
+
+=head1 AUTHOR
+
+Tom Phoenix <rootbeer at redcat.com>
+
+=head1 SEE ALSO
+
+Term::ReadLine, L<perlfunc/crypt>, and your system's manpages for the
+low-level I/O operations used here.
+
+=cut

Added: branches/upstream/libterm-readpassword-perl/current/t/1_basics.t
URL: http://svn.debian.org/wsvn/branches/upstream/libterm-readpassword-perl/current/t/1_basics.t?rev=10329&op=file
==============================================================================
--- branches/upstream/libterm-readpassword-perl/current/t/1_basics.t (added)
+++ branches/upstream/libterm-readpassword-perl/current/t/1_basics.t Sat Dec  1 12:16:26 2007
@@ -1,0 +1,7 @@
+#!perl
+
+BEGIN { $| = 1; print "1..1\n"; }
+END {print "not ok 1\n" unless $loaded;}
+use Term::ReadPassword;
+$loaded = 1;
+print "ok 1\n";

Added: branches/upstream/libterm-readpassword-perl/current/t/2_interactive.t
URL: http://svn.debian.org/wsvn/branches/upstream/libterm-readpassword-perl/current/t/2_interactive.t?rev=10329&op=file
==============================================================================
--- branches/upstream/libterm-readpassword-perl/current/t/2_interactive.t (added)
+++ branches/upstream/libterm-readpassword-perl/current/t/2_interactive.t Sat Dec  1 12:16:26 2007
@@ -1,0 +1,80 @@
+#!perl
+
+use Term::ReadPassword;
+
+if ($ENV{AUTOMATED_TESTING}) {
+    print "1..0 # Skip: Automated testing detected (AUTOMATED_TESTING) \n";
+    exit;
+}
+
+print "1..1\n";
+
+# Let's open the TTY (rather than STDOUT) if we can
+# local(*TTY, *TTYOUT);
+my($in, $out) = Term::ReadLine->findConsole;
+die "No console available" unless $out;
+
+if (open TTYOUT, ">>$out") {
+    # Cool
+} else {
+    # Well, let's allow STDOUT instead
+    open TTYOUT, ">>&STDOUT"
+	or die "Can't re-open STDOUT: $!";
+}
+
+# Don't buffer it!
+select( (select(TTYOUT), $|=1)[0] );
+
+# Well, this would be hard to test unless I set up a ptty and sockets and
+# my head hurts....
+INTERACTIVE: {
+  my $secret = '';
+  { 
+    # Naked block for scoping and redo
+    print TTYOUT "\n\n# (Don't worry - you're not changing any real password!)\n";
+    my $new_pw = read_password("Enter your (fake) new password: ", 20);
+    if (not defined $new_pw) {
+      print TTYOUT "# Time's up!\n";
+      print TTYOUT "# Were you scared, or are you merely an automated test?\n";
+      print "ok 1\n";
+      last INTERACTIVE;
+    } elsif ($new_pw eq '') {
+      print TTYOUT "# No empty passwords allowed.\n";
+      print TTYOUT "# (Use the password ' ' (a space character) to skip this test.)\n";
+      redo;
+    } elsif ($new_pw =~ /^ +$/) {
+      print TTYOUT "# Skipping the test!\n";
+      print "ok 1\n";
+      last INTERACTIVE;
+    } elsif ($new_pw =~ /([^\x20-\x7E])/) {
+      my $bad = unpack "H*", $1;
+      print TTYOUT "# Your (fake) password may not contain the ";
+      print TTYOUT "evil character with hex code $bad.\n";
+      redo;
+    } elsif (length($new_pw) < 3) {
+      print TTYOUT "# Your (fake) password must be longer than that!\n";
+      redo;
+    } elsif ($new_pw ne read_password("Enter it again: ")) {
+      print TTYOUT "# Passwords don't match.\n";
+      redo;
+    } else {
+      $secret = $new_pw;
+      print TTYOUT "# Your (fake) password is now changed.\n";
+    }
+  }
+
+  print TTYOUT "# \n# Time passes... you come back the next day... and you see...\n";
+  while (1) {
+    my $password = read_password('password: ');
+    redo unless defined $password;
+    if ($password eq $secret) {
+      print TTYOUT "# Access granted.\n";
+      print "ok 1\n";
+      last;
+    } else {
+      print TTYOUT "# Access denied.\n";
+      print TTYOUT "# (But I'll tell you: The password is '$secret'.)\n";
+      redo;
+    }
+  }
+}




More information about the Pkg-perl-cvs-commits mailing list