Webインターフェースでパスワードを変更するスクリプト

  • 投稿日:
  • by
  • カテゴリ:

Webでパスワードを変更するスクリプトである。

まずはtelnetdをlocalhostのみに許可する段取りをする。

ssh2でnet::telnet のようなものを使用したが、戻り値が期待通りでなく、telnetd を敢えて動かしている次第。

次にnet::telnetが使えるように、以下をインストールする。

# apt-get install libnet-telnet-perl

次にchangepw.htmlとかいう名前のhtmlを書く。

危険なスクリプトなので、index.htmlなどからリンクされぬようご注意ください。

<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<title>password change</title>
</head>
<body bgcolor="#f0f080">
<h1>パスワード変更</h1>
<form action="/cgi-bin/chpw.pl" method="post">
<input name="hostname" value="localhost" type="hidden">
<table>
<tbody>
<tr>
<td>ログイン名</td>
<td><input name="username" type="text"></td>
</tr>
<tr>
</tr>
<tr>
<td>旧パスワード</td>
<td>
<input name="password" type="password"></td>
</tr>
<tr>
</tr>
<tr>
<td>新パスワード</td>
<td>
<input name="newpw1" type="password"></td>
</tr>
<tr>
</tr>
<tr>
<td><br>
</td>
<td>
<input name="newpw2" type="password">
確認のためにもう一度パスワードを入力してください
</td>
</tr>
<tr>
</tr>
</tbody>
</table>
<input value="変更" type="submit">
<input value="中止" type="reset">
</form>
</body>
</html>

次に/cgi-bin/以下にchpw.plなるperlスクリプトを置く。イントラ内でsambaを動かしているので、smbpasswd にも対応しているが、下記ではコメントアウトしてある。

#!/usr/bin/perl


$passwd_prompt1 = ':';
$passwd_prompt2 = ':';
$passwd_prompt3 = ':';
$passwd_prompt4 = ':';
$passwd_prompt5 = ':';
$passwd_prompt6 = ':';
$passwd_wrong = "passwd: sorry";

######################################################################
# subroutines
######################################################################

sub unexpected_error{
print "Unknown Error Occured \n";
&finalize;
}

sub bad_password{
print "パスワードとして使用できない文字を使用している可能性があります\n";
print "パスワードには(半角大小)アルファベットと数字を使うことができます\n";
print "新しいパスワードに別のパスワードを指定してください\n";
&finalize;
}

sub finalize {
$t->close;
print "Error </body></html>\n";
exit;
}

######################################################################
# main routine
######################################################################

$request_method = $ENV{'REQUEST_METHOD'};
if ($request_method eq "GET") {
@args = split(/&/,$ENV{'QUERY_STRING'});
} else {
read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
@args = split(/&/,$buffer);
}

foreach $arg (@args) {
($name, $value) = split(/=/,$arg);
$name =~ s/\n//g;
$form{$name} = $value;
}

$hostname = "127.0.0.1" ;
$portnum = "65531" ; #指定しなければデフォルトの23

$username = $form{'username'};
$password = $form{'password'};
$newpw1 = $form{'newpw1'};
$newpw2 = $form{'newpw2'};




print "Content-type: text/html\n\n";
print "<html><head><title>password change</title></head>\n";
print "<body>\n";




if ($newpw1 ne $newpw2) {
print "Confirm Error! \n";
print "</body>\n";
exit;
} else {
$newpassword = $newpw1;
}

if ($newpassword !~ /[a-zA-Z0-9_]+/) {
print "Bad charactor exists! \n";
print "</body>\n";
exit;
}

use Net::Telnet ();

$t = new Net::Telnet (Host => $hostname, Port => $portnum );
$t = new Net::Telnet (Host => $hostname, Errmode => "return");
$t->login($username,$password);

$t->print("passwd");

$t->waitfor(String => $passwd_prompt1);
if ($t->timed_out) {&unexpected_error;}
$t->print("$password");

$t->waitfor(String => $passwd_prompt2);
if ($t->timed_out) {&unexpected_error;}
$t->print("$newpassword");

$t->waitfor(String => $passwd_prompt3);
if ($t->timed_out) {&unexpected_error;}
$t->print("$newpassword");

$t->waitfor(String => $passwd_success);
if ($t->timed_out) {&unexpected_error;}

print "PW Succeeded <br> \n";

$t->print("smbpasswd");

$t->waitfor(String => $passwd_prompt4);
if ($t->timed_out) {&unexpected_error;}
$t->print("$password");

$t->waitfor(String => $passwd_prompt5);
if ($t->timed_out) {&unexpected_error;}
$t->print("$newpassword");

$t->waitfor(String => $passwd_prompt6);
if ($t->timed_out) {&unexpected_error;}
$t->print("$newpassword");

print "SMB-PW Succeeded \n";

$t->waitfor(String => $smbpasswd_success);
print "$smbpasswd_success <br>\n";
if ($t->timed_out) {&unexpected_error;}

$t->close;

if ( -e "logfile" ) {
print "logfile found ! \n" ;
system("date >> logfile") ;
} else {
print "logfile not found ..." ;
system(touch "logfile");
print "created ! \n";
}

open(LOGFILE, ">> logfile");
print LOGFILE " user= $username pass= $newpassword \n" ;
close(LOGFILE);

print "Succeeded \n";
print "</body></html>\n";

テストしてみる

おっとcgiとして認識されてない。

# diff mime.conf mime.conf.org
219c219
< AddHandler cgi-script .cgi .pl .sh
---
> #AddHandler cgi-script .cgi
#

さて再テスト

change-pw-1.JPGのサムネイル画像

HTMLが見えた! さて変更ボタンを押す。

change-pw-2.JPGのサムネイル画像

うん。うまく動いた!

-------

追記:21/02/03

何でtelnet使ったのかというと、lib-ssh2でexpectがどーにもうまく動かない。
それで仕方なくという経緯。
ところが、expectを使ったシェルスクリプトだと、ssh2をうまく動かせるらしい。
近々に書き換える。