package Password;
# $Id: Password.pm,v 1.2 2000/08/05 16:22:04 tom Exp $
################################################################

use strict;
use Exporter;
use vars qw(@ISA);

use ObjectTemplate;
use Input;
use Crypt;

@ISA = qw(ObjectTemplate);

attributes qw(filename
	      user_name
	      old_crypted_password new_crypted_password);

################################################################
sub initialize($)
{
    my $self = shift;

    unless ($self->user_name){
	# ユーザ名を取得
	#  getpwent() がサポートされていない場合は入力を求める
	my $name;
	eval('$name = (getpwent())[0];');
	if ($@){
	    $name = InputString("your name(with ascii char)", "");
	}
	$self->user_name($name);
    }
    $self->SUPER::initialize;
}

sub ChangePassword($)
{
    my $self = shift;

    $self->ReadOldPassword;
    $self->CheckOldPassword;
    $self->InputNewPassword;
    $self->WriteToFile;
}

sub ReadOldPassword ($)
{
    my $self = shift;
    
    # read old password file
    my $password_file = $self->filename;
    
    my $old_crypted_password;
    if (open(F, "$password_file")){
	$old_crypted_password = <F>;
	chomp $old_crypted_password;
    }
    $self->old_crypted_password($old_crypted_password);
}
sub CheckOldPassword ($)
{
    my $self = shift;
    
    # echo back off
    eval "system('stty -echo')";

    # 古いパスワードの確認
    if ($self->old_crypted_password){
	while (1){
    #	my $input_old_password = InputString("old password", "");
	    my $input_old_password = InputPassword("old password", "");	
	    if (IsLegalPassword($input_old_password, $self->old_crypted_password)){
		last;
	    } else {
		print "illegal password.\n";
	    }
	}
    }
}
sub InputNewPassword ($)
{
    my $self = shift;
    
    # 新しいパスワードの入力
    my $input_password = InputPassword("new password", "");

    while (1){
	my $retyped_password = InputString("retype password", "");
    #    my $retyped_password = InputPassword("retype password", "");    
	if ($input_password eq $retyped_password){
	    last;
	} else {
	    print "password mismatch.\n";
	}
    }
    # echo back on
    eval "system('stty echo')";

    # crypt チェック
    my $crypted_password = Encrypt($input_password, $self->user_name);
    $self->new_crypted_password($crypted_password);
    
    if ($input_password eq $crypted_password){
	my $password_file = $self->filename;
	print "** ATTENTION **
OS DO NOT support crypt(3), so password is not crypted.
be very careful at handling password file: $password_file
    ";
    }
}

sub WriteToFile ($)
{
    my $self = shift;
    
    # conf/.password に記録
    my $password_file = $self->filename;
    
    open(F, ">$password_file") || die $password_file;
    print F $self->new_crypted_password . "\n";
    close F;
    print "wrote to $password_file.\n";
}
sub IsSupportNoecho($)
{
    my $self = shift;

    eval "require 'Term::ReadKey'";
    if ($@){
	my $tmp_file = "check_noecho.tmp";
	eval qq(system("stty > $tmp_file"));
	if ($@){
	    return 0;
	} else {
	    return 1;
	}
	unlink($tmp_file);
    } else {
	return 1;
    }
}
1;
