#! c:/perl/bin/perl # # crpedit.cgi # Edit a text or html on a browser and save with encription. # No one can read the text without the key to decript. # # 1.0 : 12/12/05 : Created # # $Id: crpedit.cgi,v 1.4 2005/12/12 07:03:45 Hideki Kanayama Exp $ use strict; use CGI qw(:cgi-lib); use CGI::Carp qw(fatalsToBrowser); use File::Basename; use Crypt::CBC; my $version = "1.0"; my $lastupdatedyear = "2005"; my $admindat = "adminpwd.dat"; my $setupfile = "crpedit_setup.pl"; my $script = basename($0); # English:1, Japanese:0 my $lang = 1; my $charset = ("Shift_JIS","ISO-8859-1")[$lang]; #######################3 # datadir our $datadir = "."; # datafile our $datafile = "$datadir/crpedit.dat"; # datafile our $basefile = "cryp.doc"; # lockfile our $lockfile = "lockfile.dat"; # Title our $pagetitle = ('クリプト編集','Crypt Edit')[$lang]; # Background our $bgimage_en = 0; our $bgimage_file = ''; our $bgcolor = "#ffffff"; # Back link our $backlink_en = 1; our $backlink = '..'; our $backlink_name = ('戻る','Back')[$lang]; # Body width our $body_width = '100'; # table layout our $number_en = 0; our $head_bgcolor = 'white'; our $title_head = 'Title'; our $title_width = 60; our $title_color = 'black'; our $date_head = 'Date'; our $date_width = 5; our $key_head = 'Key'; our $key_width = 5; our $option_width = 5; our $button_width = 5; our $button_name = 'Action'; # Admin link our $setup_en = 1; our $setup_name = ('管理用','Admin setup')[$lang]; # Admin only mode our $adminonly_en = 1; # body insertion our $body_insert1_en = 1; our $body_insert1 = "

Crypt Edit

"; our $body_insert2_en = 0; our $body_insert2 = ' '; our $body_insert3_en = 0; our $body_insert3 = ' '; # Style Sheet our $style_sheet_en = 0; our $style_sheet = ' '; # Head insert our $head_insert_en = 0; our $head_insert = ' '; # Time 1:localtime, 0:offset from GMT our $localtime_en = 1; our $offset_from_gmt = 9; #######################3 require "$setupfile" if (-e "$setupfile"); my $q = CGI->new; my $cgierror = $q->cgi_error; &error($cgierror) if ($cgierror); my %in = $q->Vars; if (! -e "$admindat"){ if ($in{mode} ne 'wradminpwd'){ &setadminpwd; } else { &wradminpwd($in{pwd}); } } if ($in{mode} eq 'crwrite'){ &crwrite; } elsif ($in{mode} eq 'action'){ &action; } elsif ($in{mode} eq 'deldoc2'){ &deldoc2; } elsif ($in{mode} eq 'setup'){ &setup; } elsif ($in{mode} eq 'wrsetup'){ &wrsetup; } else { &display; } sub display { &htmlhead($pagetitle); print "$body_insert1\n" if ($body_insert1_en); print "

"; print (('新規登録','New post')[$lang]); print "
\n"; print "$body_insert2\n" if ($body_insert2_en); print "
\n"; if ($backlink_en or $setup_en){ print "\n"; print "\n"; print "
\n"; print "$backlink_name\n" if ($backlink_en); print "\n"; print "$setup_name\n" if ($setup_en == 1); print "
\n"; } my $cols = 5 + $number_en; print ""; print "\n"; print "\n" if ($number_en); print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; if (open(DAT,"< $datafile")){ my $i=1; while(){ chomp; my ($num,$date,$title,$file,$type,$pwd)=split(/,/); my ($y,$m,$d,$h,$mm,$s) = split /-/, $date; my $dispdate; if ($lang) { $dispdate = sprintf("%2d/%2d/%4d",$m,$d,$y+1900); } else { $dispdate = sprintf("%4d年%2d月%2d日",$y+1900,$m,$d); } print ""; print "\n" if ($number_en); print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; $i++; } close(DAT); } print ""; print "\n"; print "
 "; print "$title_head"; print ""; print "$date_head"; print ""; print "$key_head"; print "  
 $i $title$dispdate"; print ""; print "\n"; print "\n"; print "
\n"; print "$body_insert3\n" if ($body_insert3_en); &htmltail; } sub getdata { my ($num,$date,$title,$file,$type,$pwd); my $act; if (open(LIST, "< $datadir/$datafile")) { while (){ chomp; ($num,$date,$title,$file,$type,$pwd)=split /,/; $act = 'action_' . $num; if ($in{$act} ne '') { last; } } close(LIST); } return ($num,$date,$title,$file,$type,$pwd); } sub action { my ($num,$date,$title,$file,$type,$pwd) = &getdata; if ($in{"option_$num"} eq 'edit' or $in{option} eq 'new'){ &crform($num); } elsif ($in{"option_$num"} eq 'delete'){ &deldoc; } elsif ($in{"option_$num"} eq 'browse'){ &showdoc; } else { &error(('サポートされていない選択がされました。','Wrong option is specified.')[$lang]); } } sub crform { my $number = shift; my $c; my $plaintext; my ($num,$date,$title,$file,$type,$pwd); my %type_select = (); my %char_select = (); my $opt; my $action; my $pagetitle = ('新規登録','New post')[$lang]; if ($in{"option_$number"} eq 'edit'){ $pagetitle = ('編集','Edit')[$lang]; &lockfile; open(LIST, "< $datadir/$datafile") or &error(("$datadir/$datafileが開けません。","Cannot open $datadir/$datafile")[$lang]); while (){ chomp; ($num,$date,$title,$file,$type,$pwd)=split /,/; $action = 'action_' . $num; if ($in{$action} ne ''){ $opt = 'option_' . $num; $type_select{$type} = 'checked'; last; } } close(LIST); &unlockfile; $plaintext = &get_plaintext($file,$in{"key_$num"}); } else { $opt = 'option'; $type_select{text} = 'checked'; $char_select{sjis} = 'checked'; } &htmlhead($pagetitle); print "
\n"; print (('タイトル','Title')[$lang]); print "\n
\n"; print "
\n"; print "\n"; print (('テキスト','Text')[$lang]); print "\n"; print 'HTML'; print "
"; print (('内容','Contents')[$lang]); print "

\n"; print (('暗号化キー','Encryption key')[$lang]); print "\n
\n"; print (('パスワード','Password')[$lang]); print "\n
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
\n"; &htmltail; } sub get_plaintext { my $file = shift; my $key = shift; open(CRFILE, "< $datadir/$file") or &error(("$datadir/$fileが開けません。","Cannot open $datadir/$file.")[$lang]); my @tmp = ; close(CRFILE); my $c = &init_cipher($key); my $wholefile = join '', @tmp; return $c->decrypt("$wholefile"); } sub crwrite { if (!&checkadmin($in{pwd}) and $adminonly_en) { &error(('管理用パスワードが違います。','Wrong admin password.')[$lang]); } my ($num,$date,$title,$file,$type,$pwd); if (open(LIST, "< $datadir/$datafile")) { while (){ chomp; ($num,$date,$title,$file,$type,$pwd)=split /,/; if ($in{number} eq $num) { if (! &checkcrypt($in{pwd},"$pwd")){ &error(('パスワードが違います。','Wrong password.')[$lang]); } last; } } close(LIST); } else { $num = 0; } if ($in{contents} eq ''){ &error(('内容が書き込まれていません。','Contents must not be empty.')[$lang]); } if ($in{key} eq ''){ &error('クリプトキーが指定されていません。'); } if (! -e "$datadir/$file" and $in{option} eq 'edit'){ &error("$datafile/$fileが存在しません。"); } my $cipher = &init_cipher($in{key}); my $crypttext = $cipher->encrypt($in{contents}); $num++ if ($in{option} eq 'new'); $file = "$num-$basefile"; open(FILE,"> $datadir/$file"); binmode FILE; print FILE "$crypttext"; close(FILE); chmod(0666, "$datadir/$file"); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)= $localtime_en ? localtime(time) : gmtime(time + 3600 * $offset_from_gmt); $mon++; my $new_date = "$year-$mon-$mday-$hour-$min-$sec"; $in{title} =~ s//>/g; $in{title} =~ s/,/&\#44;/g; &lockfile; if ($in{option} eq 'edit'){ open(WRITEFILE,"> $datadir/tmp.$$"); open(READFILE,"< $datadir/$datafile"); while (){ chomp; ($num,$date,$title,$file,$type,$pwd) = split /,/; if ($in{number} == $num) { print WRITEFILE "$num,$new_date,$in{title},$file,$in{type}," . &makecrypt($in{pwd}) . "\n"; } else { print WRITEFILE "$_\n"; } } close WRITEFILE ; close READFILE; rename "$datadir/tmp.$$", "$datadir/$datafile"; } elsif ($in{option} eq 'new'){ open(WRITEFILE,">> $datadir/$datafile"); print WRITEFILE "$num,$new_date,$in{title},$file,$in{type}," . &makecrypt($in{pwd}) . "\n"; close(WRITEFILE); } chmod(0666, "$datadir/$datafile"); &unlockfile; print "Location: $script\n\n"; } sub showdoc { my ($num,$date,$title,$file,$type,$pwd) = &getdata; my $plaintext = &get_plaintext($file,$in{"key_$num"}); my $contenttype; if ($type eq 'text') { $contenttype = 'text/plain'; } elsif ($type eq 'html') { $contenttype = 'text/html'; } print $q->header(-type=>$contenttype, -charset=>$charset); print "$plaintext"; exit; } sub deldoc { my ($num,$date,$title,$file,$type,$pwd) = &getdata; &htmlhead(('削除','Delete')[$lang]); print "

\n"; if ($lang) { print "Deleting
$title.
Please enter password and click \"Delete\" button.

"; } else { print "$title
を削除します。
パスワードを入力して「削除」をクリックしてください。

"; } my $delbutton = ('削除','Delete')[$lang]; print "

\n"; print qq(\n); print qq(\n); print qq(\n); print "\n"; &htmltail; } sub deldoc2 { if (!&checkadmin($in{pwd}) and $adminonly_en) { &error(('管理用パスワードが違います。','Wrong admin password.')[$lang]); } my ($num,$date,$title,$file,$type,$pwd) = &getdata; my $delnumber = $num; if (!&checkcrypt($in{pwd},$pwd)) { &error(('パスワードが違います。','Wrong password.')[$lang]); } &lockfile; open(WRITEFILE,"> $datadir/tmp.$$"); open(READFILE,"< $datadir/$datafile"); while (){ chomp; ($num,$date,$title,$file,$type,$pwd) = split /,/; if ($delnumber == $num) { unlink "$datadir/$file"; } else { print WRITEFILE "$_\n"; } } close WRITEFILE; close READFILE; rename "$datadir/tmp.$$", "$datadir/$datafile"; chmod(0666, "$datadir/$datafile"); &unlockfile; print "Location: $script\n\n"; } sub setup { &setadminpwd if ($in{pwd} eq ''); &error(('管理用パスワードが違います。','Wrong admin password')[$lang]) unless &checkadmin($in{pwd}); &htmlhead(('管理用セットアップ','Admin setup')[$lang]); print "\n"; print "\n"; print "\n"; print "\n"; my @setup_check; my @localtime_check; my @adminonly_check; $setup_check[$setup_en] = "checked"; $localtime_check[$localtime_en] = "checked"; $adminonly_check[$adminonly_en] = "checked"; my %check; $check{number}[$number_en] = "checked"; $check{bgimage}[$bgimage_en] = "checked"; $check{backlink}[$backlink_en] = "checked"; $check{style_sheet}[$style_sheet_en] = "checked"; $check{head_insert}[$head_insert_en] = "checked"; $check{body_insert1}[$body_insert1_en] = "checked"; $check{body_insert2}[$body_insert2_en] = "checked"; $check{body_insert3}[$body_insert3_en] = "checked"; my $message = ("
  • 管理人パスワードを変更するには、$admindatを削除して、$scriptを実行しなおしてパスワードを再入力してください。
  • これらの設定は$setupfileに保存されます。また、$setupfileをエディタ等で変更してもこの設定ページに反映されます。
  • $scriptがバージョンアップされた場合、単純に$scriptだけを置き換えるだけで設定はそのまま使えます。
  • $admindatと$setupfileのファイル名はこの設定ページでは変更できません。変更したい場合は$scriptの中で変更してください。
  • 管理用リンクを非表\示にしている場合にこのページにアクセスするには、$script?mode=setupを実行するとアクセスできます。
  • 数字やカラー指定は必ず半角で指定してください。全角やブランクだとCGIが起動しなくなります。万一間違って全角で書いてしまった場合は、$setupfileをエディタで開きその場所を半角に正しく修正してください。それで直ります。
  • ", "
  • If you want to change your admin password, delete $admindat and open $script on your browser. Then set a new password.
  • The setup in this page is saved in $setupfile. If you modify $setupfile by an editor, it also reflicted to this page.
  • If you upgreaded $script, please simply replace $script. These setup will be inheritated.
  • The file names of $admindat and $setupfile can not be modified in this page. If you want to change them, please do it in this script.
  • If you want to access this page when you disable \"admin link\" display, please open $script?mode=setup.
  • ")[$lang]; print " "; print qq(\n\n); print qq(\n); print qq(\n); print qq(\n\n); print qq(\n); print qq(\n); print qq(\n\n); print qq(\n); print qq(\n); print qq(\n\n); print qq(\n); print qq(\n); print qq(\n\n); print qq(\n); print qq(\n); print qq(\n\n\n\n); print qq(\n\n\n\n); print qq(\n\n\n); print qq(\n\n\n\n); print qq(\n\n\n\n); print qq(\n\n\n\n); print qq(\n\n\n\n); my $valid = (('有効','valid')[$lang]); my $invalid = (('無効','invalid')[$lang]); print qq(\n\n\n); print qq(\n\n\n\n); print qq(\n\n\n\n); print qq(\n\n\n\n); print qq(
      $message
    \n); print (('データディレクトリ','Data directory')[$lang]); print qq(
    \n); print (('データファイル','Data file')[$lang]); print qq(
    \n); print (('データファイルの基の名前','Data file base name')[$lang]); print qq(
    \n); print (('暗号化されたファイルがnumber-basenameのファイル名でdatadirに保存されます。','An encrypted file will be saved as number-basename in datadir.')[$lang]); print qq(\n
    \n); print (('ロックファイル','lock file')[$lang]); print qq(
    \n); print (('タイトル','Title')[$lang]); print qq(
    \n); print (('ブラウザのタイトルバーに表示されるタイトルです。ページのタイトルは「body内挿入部」で自由にタイトル表示させることができます。','This is displayed in the title bar of the browser. The page title can be set in the "body insert" in this page.')[$lang]); print qq(
    \n); print (('バックグラウンド','Background')[$lang]); print qq(\n); print qq(); print (('画像を使う','Use image')[$lang]); print "\n"; print qq(); print (('カラー設定にする
    ','Use color
    ')[$lang]); print "\n"; print qq(); print (('画像を使う場合の画像ファイル
    ','Image file when to use an image
    ')[$lang]); print "\n"; print qq(); print (('カラー設定の場合のカラー番号(白:\#ffffff 又は white)','')[$lang]); print qq(
    \n); print (('トップへのリンク','Link to top')[$lang]); print qq(\n); print qq(); print (('表示','Display')[$lang]); print "\n"; print qq(); print (('非表示
    ','Not display
    ')[$lang]); print "\n"; print qq(); print (('リンク名
    ','Link name
    ')[$lang]); print qq(); print (('URL
    ','URL
    ')[$lang]); print qq(
    \n); print (('表示幅','Display widthb')[$lang]); print qq(); print (('ブラウザ全体の','Pacentage out of browser width')[$lang]); print qq(%\n); print qq(
    \n); print (('テーブルレイアウト','Table layout')[$lang]); print qq(\n); print (('ヘッダーの背景色','Background color of the header')[$lang]); print qq(
    \n); print (('タイトル名','Title name')[$lang]); print qq(
    \n); print (('タイトルの幅','Title width')[$lang]); print qq(%
    \n); print (('タイトルの色','Title font color')[$lang]); print qq(
    \n); print (('日付名','Date name')[$lang]); print qq(
    \n); print (('日付の幅','Date width')[$lang]); print qq(%
    \n); print (('キー名','Key name')[$lang]); print qq(
    \n); print (('キー欄の幅','Key cell width')[$lang]); print qq(%
    \n); print (('オプション欄の幅','Option cell width')[$lang]); print qq(%
    \n); print (('ボタン欄の幅','Button cell width')[$lang]); print qq(%
    \n); print (('ボタン名','Button name')[$lang]); print qq(%
    \n); print qq(
    \n); print (('番号','Number')[$lang]); print qq(\n); print qq(); print (('表示','Display')[$lang]); print "\n"; print qq(); print (('非表示
    ','Not display
    ')[$lang]); print "\n"; print qq(
    \n); print (('管理用リンク表示','Amin link display')[$lang]); print qq(\n); print qq(); print (('表示','On')[$lang]); print qq(); print (('非表示
    ','Off
    ')[$lang]); print (('リンク名','Link name')[$lang]); print qq(\n); print qq(
    \n); print (('管理人オンリーモード','Admin only mode')[$lang]); print qq(\n); print qq(); print (('管理人オンリーモード','Admin only mode')[$lang]); print qq(); print (('ユーザーモード
    ','User mode
    ')[$lang]); print qq(
    \n); print (('<body>内挿入文','sentense in <body>')[$lang]); print "\n"; print (('上部に表示される文をHTMLで記述。ここにイベントの予定や詳細等を記述することができます。その他リンク、画像なんでもHTMLで記述できます。タイトルを非表示にして凝ったタイトルをここに記述することもできます。
    ページ上部','HTML format. You can discrive event detail here.
    Top of the page')[$lang]); print qq($valid); print qq($invalid
    \n); print qq(
    \n); print (('テーブルの上','above the title')[$lang]); print qq($valid); print qq($invalid
    \n); print qq(
    \n); print (('ページの一番下','bottom of the page')[$lang]); print qq($valid); print qq($invalid
    \n); print qq(
    \n); print qq(
    \n); print (('<head>内挿入文','sentense in <head>')[$lang]); print qq(\n); print qq($valid\n); print qq($invalid
    \n); print (('HTML書式
    ポップアップ広告やJavascript、<META>を挿入したい場合にここに記述する。
    以下の記述が<head>〜</head>内に挿入される。
    ','HTML format. Javascript, popup ads, <META> and so on can be inserted in here.')[$lang]); print qq(
    \n); print qq(
    \n); print (('スタイルシート','Style Sheet')[$lang]); print qq(\n); print qq($valid\n); print qq($invalid
    \n); print qq(
    \n); print qq(
    \n); print (('時間設定','Time')[$lang]); print qq(\n); print qq(); print (('GMTからのオフセット','Offset from GMT')[$lang]); print qq(\n); print (('ローカルタイム
    ','Localtime
    ')[$lang]); print (('GMTからのオフセットに設定した場合、GMTより','When set to GMT, an offset from GMT')[$lang]); print qq(\n); print (('時間(日本:+9時間)','hours (Japan : +9)')[$lang]); print qq(
    \n); print qq(

    \n); print "

    \n"; &htmltail; } ###################### セットアップ作成 ############################ sub wrsetup { &error(('パスワードが違います。','Wrong admin password')[$lang]) unless (&checkadmin($in{pwd})); open(SETUP,"> $setupfile") || &error(('セットアップファイルが作成できません。
    CGIを置いてあるディレクトリが書き込み可能か確認してください。',"Cannot create $setupfile.")[$lang]); foreach (keys(%in)){ $in{$_} =~ s/
    /\n/g; $in{$_} =~ s/,/,/g; $in{$_} =~ s/<//g; $in{$_} =~ s/\s*$//; } print SETUP <header(-charset=>$charset); print "\n"; print "\n"; print "\n"; print "$title\n"; if ($head_insert_en == 1){ print "$head_insert\n"; } if ($style_sheet_en == 1){ print "\n"; } print "\n"; print "\n"; print "
    \n"; } sub copyright { my $mysite = ('http://www.hidekik.com/','http://www.hidekik.com/en/')[$lang]; print "

    "; print "$script Ver. $version
    \n"; print "Copyright(C) $lastupdatedyear,
    hidekik.com\n"; print "
    "; } sub htmltail { ©right; print "
    \n\n"; exit; } sub error { my ($msg) = shift; &unlockfile; &htmlhead($msg); print "
    $msg
    \n"; &htmltail; exit; } sub makecrypt { my $plain = shift; my $salt = join "", ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]; my $result = crypt($plain,$salt) or crypt($plain,'$1$'.$salt.'$'); return $result; } sub setadminpwd { my $subname = 'setadminpwd'; &htmlhead(('管理者用パスワードを入力してください','Please set an admin password')[$lang]); print "
    \n"; if ($in{mode} eq 'setup'){ if ($lang){ print "
    Please enter an admin password
    \n"; } else { print "
    管理者用パスワードを入力してください。
    \n"; } print "\n"; my $but = ('入力','Enter')[$lang]; print "\n"; print "\n"; } else { if ($lang){ print "
    Please set an admin password
    \n"; } else { print "
    管理者用パスワードを設定してください。
    \n"; } print "\n"; my $but = ('設定','Enter')[$lang]; print "\n"; print "\n"; } &htmltail; } sub wradminpwd { my $plain = shift; my $passwd = &makecrypt($plain); if (open(FILE,"> $admindat")){ print FILE "$passwd"; close(FILE); } else { &error('パスワードファイル作成に失敗しました'); } print "Location: $script\n\n"; } sub checkadmin { my $pwd = shift; if (open(ADMINFILE,"< $admindat")){ my $filepwd = ; close(ADMINFILE); my $inpwd = crypt($pwd,$filepwd); return ("$inpwd" eq "$filepwd"); } else { &error('パスワードファイルが存在しません'); } } sub lockfile { while(-e "$lockfile"){ sleep(1); } open(LOCK,"> $lockfile"); close(LOCK); } sub unlockfile { unlink("tmp.$$") if (-e "tmp.$$"); unlink("$lockfile") if (-e $lockfile); } sub init_cipher { my $inkey = shift; my $localkey; my $cipher; my $cipher_set = ''; my $keylength = length($inkey); if ($keylength < 8){ my $addcount = 8 - $keylength; my $padding = 'a' x $addcount; $localkey = $inkey . $padding; } else { $localkey = $inkey; } my %cipher_options = ( key => "$localkey", cipher => 'Blowfish', salt => 1, regenerate_key => 1, padding => 'standard', ); $cipher = new Crypt::CBC (\%cipher_options); return($cipher); }