#!/usr/local/bin/perl

## COSMO GATE v2.6 (00/07/04)
## Copyright(C) KENT WEB 1997-2000
## Mail: webmaster@kent-web.com
## Home: http://www.kent-web.com/

$ver = 'CosmoGate v2.6';

#---------------------------------------------------------------#
# ・このスクリプトはフリーソフトです。このスクリプトを使用した	#
#   いかなる損害も作者はその責を負いません。			#
# ・設置に関する質問は直接メールではお受けできませんので必ず	#
#   「サポート掲示板」へお願いいたします。			#
#---------------------------------------------------------------#

# ■設置例
#    /home/kent/
#           |
#           +-- private_html / secret.html [644] ... 隠しファイル
#           |
#           +-- public_html / index.htmlなど
#                 |
#                 +-- member / gate.cgi [755]
#                              log.dat  [666]

# ■アクセスログの閲覧の仕方 (gate.cgi?mode=admin)
#   http://〜〜/member/gate.cgi?mode=admin
#   ＊上記のように、?mode=admin という引数を付けてアクセスする。
#   ＊管理用パスワードの入力画面となりますので、下記設定の $pass で
#     指定するパスワードを入力して下さい。

#============#
#  設定項目  #
#============#

# 隠しファイルのフルパス
#  --> HTMLファイルの場合は、/ からのフルパスで記述
#  --> CGIファイルの場合は、http:// からのパスで記述
$goto = "http://cgi.kiwi.ne.jp/~gorogoro/mao_web/ac-1/replist.cgi";

# 隠しファイルの種類 (HTML=0 CGI=1 その他=2)
$kind = 1;

# bodyタグ
$body = '<body bgcolor="#F5F5F5" text="#000000">';

# スクリプトファイル名
$script = "./gate.cgi";

# method形式 (POST/GET)
$method = 'POST';

# アクセスログの記録 (0=no 1=yes)
$logkey = 1;

# 管理者用パスワード (英数字)
$pass = 'who-miru';

# 集計一覧からの戻り先
$home = 'http://factory-gorogoro.m78.com/mao_web/';

# アクセスログファイル
$logfile = './jonathan.dat';

# アクセスログ最大保持数
$max = 50;

# ユーザIDとパスワードを指定
#  --> 上下のID/PASS配列はコンマで区切っていくつでも指定可
#  --> 上下の配列は必ずペアで
@UserID = ('gorogoro');
@UserPW = ('jonathan');

# ホスト名取得方式
#  --> 0 : $ENV{'REMOTE_HOST'}
#  --> 1 : gethostbyaddr
$gethostbyaddr = 0;

#============#
#  設定完了  #
#============#


## COSMO GATEのメイン処理
&decode;
if ($buffer eq "") { &check; }
if ($mode eq "admin") { &admin; }

&pass_chk;
if ($kind == 0) { &html_view; }
elsif ($kind == 1) { &cgi_view; }
else {
	if ($logkey) { &axslog; }
	print "Location: $goto\n\n";
}
exit;


#-----------------------------#
#  パス一致の処理 (HTML出力） #
#-----------------------------#
sub html_view {
	# 対象ファイルを確認
	unless (-e "$goto") {
		&error("隠しファイルへの「パス」指定が不正です");
	}

	# HTMLを読み込み
	open(IN,"$goto") || &error("Open Error : $goto");
	@lines = <IN>;
	close(IN);

	# Macでバイナリー転送されたHTML対応
	if (@lines == 1 && $lines[0] =~ /\r/) {
		@lines = split(/\r/, $lines[0]);
	}

	# HTMLを表示
	print "Content-type: text/html\n\n";
	foreach (@lines) {
		print $_;
	}

	if ($logkey) { &axslog; }
}

#--------------------------------------#
#  パス一致の処理 (フレームでCGI出力)  #
#--------------------------------------#
sub cgi_view {
	print "Content-type: text/html\n\n";
	print "<html>\n";
	print "<head><title>SECRET FILE</title></head>\n";
	print "<frameset frameborder=no border=0 cols=\"100%\,*\">\n";
	print "<frame src=\"$goto\" name=\"main\">\n";
	print "</frameset>\n";
	print "</html>\n";

	if ($logkey) { &axslog; }
}

#------------------#
#  パスワード画面  #
#------------------#
sub check {
	# クッキーを取得
	&get_cookie;

	&header;
	print <<"EOM";
<br><br><br>
<center>
<h4>USER IDとPASSWORDを入力してください</h4>
<form action="$script" method="$method">
<table border=1>
<tr>
  <td><b>USER ID</b></td>
  <td><input type=text name=id size=10 value="$c_id"></td>
</tr>
<tr>
  <td><b>PASSWORD</b></td>
  <td><input type=password name=pw size=10 value="$c_pw"></td>
</tr>
<tr>
  <th colspan=2>
    <input type=submit value="認証する"><input type=reset value="リセット">
  </th>
</tr>
</table>
<input type=checkbox name=chk value="on" checked>認証情報を保存する
</form>
<center>
<br><br><br>
<small>
<!-- 著作権表\示 : 削除不可 ($ver) -->
- <a href="http://www.kent-web.com/" target="_top">Cosmo Gate</a> -
</small></center>
</body></html>
EOM
	exit;
}

#------------------------#
#  パスワードエラー処理  #
#------------------------#
sub pass_error {
	&header;
	print <<"EOM";
<br><br><br>
<center>
<hr width=300>
<h3>パスワードが不正です</h3>
<hr width=300>
<P>
<a href="javascript:history.back()">戻る</a>
</center>
</body></html>
EOM
	exit;
}

#-----------------------#
#  ID/PASSチェック処理  #
#-----------------------#
sub pass_chk {
	# 入力チェック
	if ($pw eq "") { &error("PASSWORDが入力されていません"); }

	# ID/PASSをマッチング
	local($flag) = 0;
	foreach (0 .. $#UserID) {
		if ($id eq "$UserID[$_]" && $pw eq "$UserPW[$_]") {
			$flag = 1;
			last;
		}
	}
	# 該当なしの場合はエラー処理
	if ($flag == 0) { &pass_error; }

	# ID/PASS情報をクッキー格納
	if ($in{'chk'} eq 'on') { &set_cookie('on'); }
	else { &set_cookie('off'); }
}

#----------------------#
#  アクセスログを取得  #
#----------------------#
sub axslog {
	# 時間を取得
	$ENV{'TZ'} = "JST-9";
	($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

	# 日時のフォーマット
	$date = sprintf("%04d\/%02d\/%02d\-%02d\:%02d\:%02d",
			$year+1900,$mon+1,$mday,$hour,$min,$sec);

	# ログファイルの読み込み
	open(IN,"$logfile") || &error("Open Error : $logfile");
	@data = <IN>;
	close(IN);

	# 最大ログ数の調整
	while ($max <= @data) { pop(@data); }

	# ホスト名を取得
	&get_host;

	# ログをフォーマット
	unshift(@data,"$id<>$date<>$host<>$ENV{'HTTP_USER_AGENT'}<>\n");

	# ログを更新
	open(OUT,">$logfile") || &error("Write Error : $logfile");
	print OUT @data;
	close(OUT);
}

#--------------#
#  管理モード  #
#--------------#
sub admin {
	# 入室処理
	if ($in{'pass'} ne "$pass") {
		&header;
		print "<center><h4>パスワードを入力して下さい</h4>\n";
		print "<P><form action=\"$script\" method=\"$method\">\n";
		print "<input type=hidden name=mode value=\"admin\">\n";
		print "<input type=password name=pass size=8>";
		print "<input type=submit value=\" 認証 \">\n";
		print "</body></html>\n";
		exit;
	}

	# ログファイルの読み込み
	open(IN,"$logfile") || &error("Open Error : $logfile");
	@log = <IN>;
	close(IN);

	&header;
	print <<"EOM";
<center>
<hr width="400">
<h2>アクセスログ一覧集計</h2>
<hr width="400">
<P>
<table cellpadding=0 cellspacing=0 border=1>
<tr>
  <td>
    <form action="$home" target="_top">
    <input type=submit value="トップページ">
  </td></form>
  <td>
    <form action="$script" method="$method">
    <input type=hidden name=mode value="admin">
    <input type=hidden name=pass value="$in{'pass'}">
    <input type=hidden name=shukei value="off">
    <input type=submit value="ログ一覧">
  </td></form>
  <td>
    <form action="$script" method="$method">
    <input type=hidden name=mode value="admin">
    <input type=hidden name=pass value="$in{'pass'}">
    <input type=hidden name=shukei value="on">
    <input type=submit value="ログ集計">
  </td></form>
</tr>
</table>
<P>
EOM

	# ログ一覧の場合
	if ($in{'shukei'} ne "on") {
		print "<table border=1 cellspacing=0>\n";
		print "<tr><th>No</th><th>日時</th><th>USER ID</th><th>ホスト名</th><th>ブラウザ</th></tr>\n";

		$i = 0;
		foreach (@log) {
			($uid,$date,$host,$bruz) = split(/<>/, $_);
			$i++;
			print "<tr><td align=center>$i</td><td>$date</td>";
			print "<th>$uid</th><td>$host</td><td>$bruz</td></tr>\n";
		}
		print "</table>\n";
	}
	# ログ集計の場合
	else {
		print "<table border=1 cellspacing=0>\n";
		print "<tr><th>USER ID</th><th>アクセス数</th></tr>\n";
		foreach (@UserID) {
			$i=0;
			foreach $x (@log) {
				($uid,$date,$host,$bruz) = split(/<>/, $x);
				if ($_ eq "$uid") { $i++; }
			}
			# セル集計表示
			print "<tr><th>$_</th><th>$i</th></tr>\n";
		}
		print "</table>\n";
	}
	print "</center>\n";
	print "</body></html>\n";
	exit;
}

#------------------#
#  エラー表示処理  #
#------------------#
sub error {
	&header;
	print "<center><hr width='75%'><P><h3>ERROR !</h3>\n";
	print "<P><font color='red'><b>$_[0]</b></font>\n";
	print "<P><hr width='75%'></center>\n";
	print "</body></html>\n";
	exit;
}

#------------------#
#  HTMLのヘッダー  #
#------------------#
sub header {
	print "Content-type: text/html\n\n";
	print <<"EOM";
<html>
<head>
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=Shift_JIS">
<title>COSMO GATE</title></head>
$body
EOM
}

#----------------#
#  デコード処理  #
#----------------#
sub decode {
	if ($ENV{'REQUEST_METHOD'} eq "POST") {
		read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
	} else { $buffer = $ENV{'QUERY_STRING'}; }

	@pairs = split(/&/, $buffer);
	foreach (@pairs) {
		($name,$value) = split(/=/, $_);
		$value =~ tr/+/ /;
		$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

		$in{$name} = $value;
	}
	$mode = $in{'mode'};
	$id   = $in{'id'};
	$pw   = $in{'pw'};
}

#------------------#
#  クッキーの発行  #
#------------------#
sub set_cookie {
	($secg,$ming,$hourg,$mdayg,$mong,$yearg,$wdayg) = gmtime(time + 60*24*60*60);
	$yearg += 1900;
	if ($secg  < 10)  { $secg  = "0$secg";  }
	if ($ming  < 10)  { $ming  = "0$ming";  }
	if ($hourg < 10)  { $hourg = "0$hourg"; }
	if ($mdayg < 10)  { $mdayg = "0$mdayg"; }
	$month = ('Jan','Feb','Mar','Apr','May','Jun',
			'Jul','Aug','Sep','Oct','Nov','Dec')[$mong];
	$youbi = ('Sunday','Monday','Tuesday','Wednesday',
			'Thursday','Friday','Saturday')[$wdayg];
	$date_gmt = "$youbi, $mdayg\-$month\-$yearg $hourg:$ming:$secg GMT";

	if ($_[0] eq "on") { $cook = "id\:$id\,pw\:$pw"; }
	else { $cook = "id:,pw:"; }
	print "Set-Cookie: GATE=$cook; expires=$date_gmt\n";
}

#------------------#
#  クッキーを取得  #
#------------------#
sub get_cookie {
	$cookies = $ENV{'HTTP_COOKIE'};
	@pairs = split(/;/, $cookies);
	foreach (@pairs) {
		local($name,$value) = split(/=/, $_);
		$name =~ s/ //g;
		$DUMMY{$name} = $value;
	}
	@pairs = split(/,/, $DUMMY{'GATE'});
	foreach (@pairs) {
		local($name,$value) = split(/:/, $_);
		$COOKIE{$name} = $value;
	}
	$c_id = $COOKIE{'id'};
	$c_pw = $COOKIE{'pw'};
}

#----------------#
#  ホスト名取得  #
#----------------#
sub get_host {
	$host = $ENV{'REMOTE_HOST'};
	$addr = $ENV{'REMOTE_ADDR'};

	if ($gethostbyaddr) {
		if ($host eq "" || $host eq "$addr") {
			$host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2);
		}
	}
	if ($host eq "") { $host = $addr; }
}
