#!/usr/local/bin/perl # ############################################################# ### ### CGI掲示板(簡易版) SDnote-Jack Ver.1.0 ### ### (C) 2000 Sentora Dori ### http://www.lowpower.iis.u-tokyo.ac.jp/~hat ### ############################################################# # ##### 設定(ここから) ##### # パスワードファイルのあるディレクトリ $passfiledir = '../../cgidata/SD'; # パスワードファイル名 $passfile = 'SDpass.txt'; # post: postメソッド get: getメソッド $method = 'post'; ##### 設定(ここまで) 以下は変更必要なし ##### # このプログラムのタイトル $title = 'SD series password maker'; # パスワードファイルであることを示すサイン $signature = 'SDpassfile'; # このファイル名 $thisurl = 'makepass.cgi'; ### data format ### $passfile = "$passfiledir/$passfile"; &init_form(); $command = $form{'command'}; $inputpass = $form{'inputpass'}; $newmasterpass = $form{'newmasterpass'}; $newmasterpass2 = $form{'newmasterpass2'}; $programname = $form{'programname'}; $newpass = $form{'newpass'}; $newpass2 = $form{'newpass2'}; ##### branch ##### &print_error("[no password file]") if (!(-f "$passfile")); @file_info = stat($passfile); if ($file_info[7] == 0) { if ($command eq 'initmaster') { &do_initmaster; exit(0); } else { &show_initmaster; exit(0); } } close(TXT); if ($command eq 'makepass') { &do_checkmaster; &do_makepass; } elsif ($command eq 'checkmaster') { &do_checkmaster; &show_passfile; } elsif ($command eq 'changemaster') { &do_checkmaster; &do_changemaster; } elsif ($command eq 'showchangemaster') { &do_checkmaster; &show_changemaster; } else { &show_inputmaster; } exit(0); #----- パスワード作成 ----- sub do_makepass { if (!$programname) { print_error("プログラム名が入力されていません。"); } if ($newpass eq '') { &print_error("パスワードが入力されていません。"); } if ($newpass !~ /^\w+$/) { &print_error("パスワードに使用できる文字は英数字とアンダースコアのみです。"); } if ($newpass ne $newpass2) { &print_error("パスワードと確認用の入力が違います。"); } open(TXT, "+<$passfile") || die &print_error('[no password file]'); @txt = ; ($sign, $masterpass) = splice(@txt, 0, 2); chomp($sign); chomp($masterpass); if ($sign ne $signature) { &print_error("[not password file]"); } local($encpass) = &encode_pass($newpass); $findprogram = 0; for ($i = 0; $i < @txt; $i++) { ($name, $pass) = split(/,/, $txt[$i]); chomp($pass); if ($name eq $programname) { $txt[$i] = "$programname\,$encpass\n"; $findprogram = 1; last; } } if (!$findprogram) { $writeline = "$programname\,$encpass\n"; unshift(@txt, $writeline); } seek(TXT, 0, 0); print TXT "$signature\n"; print TXT "$masterpass\n"; print TXT @txt; close(TXT); &show_passfile; } #----- マスターパスワードチェック ----- sub do_checkmaster { open(TXT, "$passfile") || die &print_error('[no password file]'); @txt = ; close(TXT); ($sign, $masterpass) = splice(@txt, 0, 2); chomp($sign); chomp($masterpass); if ($sign ne $signature) { &print_error("[not password file]"); } if ($masterpass ne crypt($inputpass, $masterpass)) { &print_error("[password mismatch!]"); } return; } #----- マスターパスワード初期設定----- sub do_initmaster{ &verify_input; local($encpass) = &encode_pass($newmasterpass); local(@sign) = ("$signature\n", "$encpass\n"); open(TXT, "+<$passfile") || die &print_error('[no password file]'); seek(TXT, 0, 0); print TXT @sign; close(TXT); $inputpass = $newmasterpass; &show_passfile; } #----- マスターパスワード変更----- sub do_changemaster{ &verify_input; local($encpass) = &encode_pass($newmasterpass); local(@sign) = ("$signature\n", "$encpass\n"); open(TXT, "+<$passfile") || die &print_error('[no password file]'); @txt = ; ($sign, $masterpass) = splice(@txt, 0, 2); chomp($sign); chomp($masterpass); if ($sign ne $signature) { &print_error("[not password file]"); } seek(TXT, 0, 0); print TXT @sign; print TXT @txt; close(TXT); $inputpass = $newmasterpass; &show_passfile; } # 入力パスワードのチェック sub verify_input { if ($newmasterpass eq '') { &print_error("パスワードが入力されていません。"); } if ($newmasterpass !~ /^\w+$/) { &print_error("パスワードに使用できる文字は英数字とアンダースコアのみです。"); } if ($newmasterpass ne $newmasterpass2) { &print_error("マスターパスワードと確認用の入力が違います。"); } } #----- パスワードファイル表示 ----- sub show_passfile { local($name, $pass); open(TXT, "$passfile") || die &print_error('[no password file]'); @txt = ; close(TXT); ($sign, $masterpass) = splice(@txt, 0, 2); chomp($sign); chomp($masterpass); if ($sign ne $signature) { &print_error("[Not password file]"); } print "Content-type: text/plain\n\n"; print <<"END_SHOWPASSFILE_1"; $title
$title


各プログラムのパスワードを作成します。
(プログラム名:default はすべてのプログラムの標準パスワードとして使用できます。)

プログラム名:CGIの各プログラムを参照
パスワードは確認のために2箇所に入力してください。 (カット&ペーストは避けてください。)
英数字とアンダースコアのみ使用できます。
パスワードは各プログラムの管理に必要となります。忘れたら変更してください。
プログラム名
新規・変更パスワード
確認用の再入力

現在、設定されているパスワード END_SHOWPASSFILE_1 print "
"; print ""; for ($i = 0; $i < @txt; $i++) { ($name, $pass) = split(/,/, $txt[$i]); print <<"END_SHOWPASSFILE_2"; END_SHOWPASSFILE_2 } print "
プログラム名パスワード(暗号形式)
$name$pass
"; } #----- マスターパスワード入力画面表示 ----- sub show_inputmaster { print "Content-type: text/plain\n\n"; print <<"END_SHOW_INPUTMASTER"; $title
$title
マスターパスワード入力


マスターパスワード
END_SHOW_INPUTMASTER } #----- マスターパスワード初期化用フォーム表示 ----- sub show_initmaster { print "Content-type: text/html\n\n"; print <<"END_SHOW_INITMASTER"; $contenttype $title
$title
マスターパスワード初期設定


SD series pass maker のマスターパスワードを設定してください。
確認のために2箇所に入力してください。(カット&ペーストは避けてください。)
英数字とアンダースコアのみ使用できます。
SD series のプログラムのパスワード管理に必要となりますので、忘れないようにしてください。
マスターパスワード
確認用の再入力

END_SHOW_INITMASTER } #----- マスターパスワード変更用フォームを表示する ----- sub show_changemaster { print "Content-type: text/html\n\n"; print <<"END_SHOW_CHANGEMASTER"; $title
$title
マスターパスワード変更


現在のパスワードを入力し、 新しいパスワードは確認のために2箇所に入力してください。
(カット&ペーストは避けてください。)
現在のマスターパスワード
新しいマスターパスワード
確認用の再入力
END_SHOW_CHANGEMASTER } #----- ブラウザへの入力データの取得 ----- sub init_form { local($query, @dataarray, $method, $property, $value); $method = $ENV{'REQUEST_METHOD'}; $method =~ tr/A-Z/a-z/; if ($method eq 'post') { read(STDIN, $query, $ENV{'CONTENT_LENGTH'}); } else { $query = $ENV{'QUERY_STRING'}; } @dataarray = split(/&/, $query); foreach $data (@dataarray) { ($property, $value) = split(/=/, $data); $form{$property} = $value; } } #----- パスワード暗号化 ----- sub encode_pass { local($sec, $min, $hour, $day, $mon, $year, $weekday) = localtime(time); local(@token) = ('0'..'9', 'A'..'Z', 'a'..'z'); local($pass) = @_; local($encpass, $salt1, $salt2); $salt1 = $token[(time | $$) % scalar(@token)]; $salt2 = $token[($sec + $min*60 + $hour*3600) % scalar(@token)]; $encpass = crypt($pass, "$salt1$salt2"); return $encpass; } ##### エラー処理 ##### #----- エラー文を出力し終了 ----- sub print_error { local($msg) = @_; print "Content-type: text/plain\n\n"; print $msg; exit(0); }