#!/usr/bin/perl
use strict;
# ソフトウェア情報
#
# BS Psssword Jump Ver2.2
# パスワードによって、ジャンプ先が変るCGIです。
#
# 著作権
# CGI-Store.JP
# http://cgi-store.jp/
#
# 公開日
# 2007/09/07
#
# 取扱説明書
# Cookieの使用の可否が設定できます。
# 使用する設定の時でも携帯端末と判断した場合、一部の端末では使用しません。
# (USER AGENTにDoCoMo・J-PHONE・UP.Browserが存在した場合、Cookie使用不可携帯端末と判断します。)
# Cookieにパスワードが保存されていない場合はフォームを表示します。
# Cookieを削除したい場合は、
# 「PssswordJump.cgi?act=clear」とアクセスすればCookieが削除されフォームが表示されます。
# エラー画面はSJISで出力されます。
# Locationヘッダが使用できないブラウザが携帯端末の一部にあるようです。
# その場合は正常に動作しません。ご了承ください。
# フォーム用HTMLファイル内にはフォームを記述する必要があります。
# 携帯端末はGETメソッドしか対応していない端末が数多くあります。
# 記述例:
#
# 標準ではフォーム用HTMLは、データディレクトリ内のformディレクトリにあるdefault.htmlが使用されます。
# 任意のフォームを複数用意する場合には、formディレクトリに違う名称の拡張子がhtmlを設置します。
# そして、任意のフォームを利用するには、「sample.html」を呼び出すには「PssswordJump.cgi?page=sample」へリンクします。
# 任意のHTMLを利用する時のCookie削除は「PssswordJump.cgi?act=clear&page=sample」です。
#
#
# 初期設定ここから
# データ用ディレクトリ
my $DataDir = './data';
# パスワード保存用ファイル
# 「パスワード文字列URL文字列」を各行毎に記述しておく。
my $PwdFile = $DataDir . '/password.txt';
# Cookieを使用するか。
# 1 -> 使用する。0 -> 使用しない。
my $UseCookie = 1;
# 初期設定ここまで
# フォームデコード
my($buffer, @pairs, $pair, $name, $value, %FORM);
%FORM = ();
if ($ENV{'REQUEST_METHOD'} eq "POST"){
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}
else{
$buffer = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/,$buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$name =~ tr/+/ /;
$name =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
$value =~ tr/+/ /;
$value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
$FORM{$name} = $value;
}
# USER AGENTのチェック
my($CType, %COOKIE);
%COOKIE = ();
if ($ENV{'HTTP_USER_AGENT'} =~ /DoCoMo/) {
$CType = 'imode';
}
elsif ($ENV{'HTTP_USER_AGENT'} =~ /J-PHONE/) {
$CType = 'jsky';
}
elsif ($ENV{'HTTP_USER_AGENT'} =~ /UP\.Browser/) {
$CType = 'ezweb';
}
else {
$CType = 'other';
if ($UseCookie == 1) {
&getCookie(\%COOKIE);
}
}
# フォーム用HTMLを決定する
my $FormFile = $DataDir . '/form/default.html';
if ($FORM{'page'} ne '') {
$FormFile = $DataDir . '/form/' . $FORM{'page'} . '.html';
}
unless (-e $FormFile) {
&error('Error', 'form file not found');
exit;
}
if ($FORM{'act'} eq '') {
if ($UseCookie == 0) {
&Form($FormFile);
}
elsif ($COOKIE{'PASSWORD'} eq '') {
&Form($FormFile);
}
else {
$FORM{'password'} = $COOKIE{'PASSWORD'};
&Jump;
}
}
elsif ($FORM{'act'} eq 'jump') {
&Jump;
}
elsif ($FORM{'act'} eq 'clear') {
if ($CType eq 'other') {
if ($UseCookie == 1) {
print &clearCookie('PASSWORD');
}
}
&Form($FormFile);
}
else {
&error('Error', 'End of Prpgram');
}
exit;
# form.cgiの出力
sub Form {
print "Content-type: text/html; charset=Shift_JIS\n\n";
open FILE, $_[0];
while () {
$_ =~ s/\x0D?\x0A?$//;
print $_ . "\n";
}
close FILE;
}
# リダイレクト処理
sub Jump {
my($seko, $data, $pwd, $url);
# パスワード照合
$seko = 0;
open FILE, $PwdFile;
while ($data = ) {
$data =~ s/\x0D?\x0A?$//;
($pwd, $url) = split(/\t/, $data, 2);
if ($FORM{'password'} eq $pwd) {
$seko = 1;
last;
}
}
close FILE;
# リダイレクト処理
if ($seko == 1) {
if ($CType eq 'other') {
if ($UseCookie == 1) {
print &setCookie('PASSWORD',$FORM{'password'});
}
}
print "Location: $url\n\n";
}
else {
&error('Error', 'Password Error');
}
}
# エラーメッセージ出力
sub error {
print "Content-type: text/html; charset=Shift_JIS\n\n";
print '' . "\n";
print '' . "\n";
print '' . $_[0] . '' . "\n";
print '' . "\n";
print '' . "\n";
print $_[0] . ':
' . "\n";
print $_[1] . "\n";
print '' . "\n";
print '' . "\n";
}
sub getCookie {
my($ref, $tmp, $name, $value);
$ref = $_[0];
for $tmp (split(/; */, $ENV{'HTTP_COOKIE'})) {
($name, $value) = split(/=/, $tmp);
$value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('C', hex($1))/eg;
$ref->{$name} = $value;
}
}
sub setCookie {
my $val = $_[1];
$val =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
my $tmp = 'Set-Cookie: ' . $_[0] . '=' . $val . '; ';
$tmp .= 'expires=Thu, 1-Jan-2030 00:00:00 GMT;' . "\n";
return $tmp;
}
sub clearCookie {
my $tmp = 'Set-Cookie: ' . $_[0] . '=xx; ';
$tmp .= 'expires=Thu, 1-Jan-1980 00:00:00 GMT;' . "\n";
return $tmp;
}