bash
ホストシステムでログインが成功したかどうかをテストするために必要なコマンドを呼び出すPython CGIスクリプトを作成しました。
これについてテストを書くにはどうすればよいですか?
たとえば、bash
ホストに登録されているユーザーに対して特定のユーザー名とパスワードの組み合わせをテストするスクリプトを作成できますか?
答え1
PAMを使用するのが最善の解決策です。小さなCコードを書くか、python-pamパッケージをインストールし、python-pamパッケージに付属のpythonスクリプトを使うことができます。バラより/usr/share/doc/python-pam/examples/pamtest.py
答え2
ユーザーがログインできるかどうかをテストする正しい方法は、実際にそのユーザーとしてログインすることです。
したがって、CGIスクリプトを使用することをお勧めします。expect
を実行するには、su
パスワードを渡して実行する必要があるコマンドを実行します。以下は、これを行うための予想されるスクリプトドラフトです(警告:確かにテストされておらず、期待の経験はあまりありません)。ユーザー名、パスワード、コマンドで置き換えます。 (私はbob
、swordfish
およびを書きましたsomecommand
。)正確に引用する必要があります。
spawn "/bin/su" "bob"
expect "Password:"
send "swordfish\r"
expect "^\\$"
send "somecommand"
expect -re "^\\$"
send "exit\r"
expect eof
コマンドを実行するためにレイヤーを通過したくない場合su
(たとえば、実行中の操作はCGIプロセス自体によって実行される必要があるため)、予想を使用してコマンドを実行し、戻りtrue
状態が0であることを確認してください。 。
別の方法はポリアクリルアミド以下を介してアプリケーションから直接Python用PAMバインディング。
答え3
これには、「C」、「Python」PAMソリューションが引用されています。 Perlソリューションも含めます:-)
#!/usr/bin/perl
use Authen::PAM;
use POSIX qw(ttyname);
$service = "login";
$username = "foo";
$password = "bar";
$tty_name = ttyname(fileno(STDIN));
sub my_conv_func {
my @res;
while ( @_ ) {
my $code = shift;
my $msg = shift;
my $ans = "";
$ans = $username if ($code == PAM_PROMPT_ECHO_ON() );
$ans = $password if ($code == PAM_PROMPT_ECHO_OFF() );
push @res, (PAM_SUCCESS(),$ans);
}
push @res, PAM_SUCCESS();
return @res;
}
ref($pamh = new Authen::PAM($service, $username, \&my_conv_func)) ||
die "Error code $pamh during PAM init!";
$res = $pamh->pam_set_item(PAM_TTY(), $tty_name);
$res = $pamh->pam_authenticate;
print $pamh->pam_strerror($res),"\n" unless $res == PAM_SUCCESS();
答え4
rootアクセス権があり、md5パスワードを使用していてパスワードのみを比較する必要がある場合は、perlを使用できます。暗号化::パスワードMD5基準寸法。 /etc/shadowからMD5ハッシュを取得して$1$を削除し、残りの$を分割します。フィールド1 =塩、フィールド2 =暗号化されたテキスト。 CGIに入力されたテキストは暗号化されたテキストと比較してハッシュされ、Bobはあなたのおじさんです。
#!/usr/bin/env perl
use Crypt::PasswdMD5;
my $user = $ARGV[0];
my $plain = $ARGV[1];
my $check = qx{ grep $user /etc/shadow | cut -d: -f2 };
chomp($check);
my($salt,$md5txt) = $check =~ m/\$1\$([^\$].+)\$(.*)$/;
my $pass = unix_md5_crypt($plain, $salt);
if ( "$check" eq "$pass" ) {
print "OK","\n";
} else {
print "ERR","\n";
}