Admin interface for /sugg/ - Suggestions & Help

Admin password:
sttext a:hover { text-decoration: underline; } .deletebutton { display:none; }

Admin interface for

}; use constant THREAD_TEMPLATE => compile_template(ADMIN_HEAD_INCLUDE.q{
Edit:
Rebuild caches | Return to board | Log out

()

- delete - delete file - ban
}); use constant EDIT_TEMPLATE => compile_template(ADMIN_HEAD_INCLUDE.q{

This is the list of domain names Kareha considers to be spam.
You can find an up-to-date version here, or you can get the spam.txt file directly here.


}); use constant LIST_TEMPLATE => compile_template(ADMIN_HEAD_INCLUDE.q{
NumTitlePostsLast postFile size
: (closedpermasaged) kb permasage unpermasage close open
}); use constant LOGIN_TEMPLATE => compile_template(ADMIN_HEAD_INCLUDE.q{
Password incorrect
Admin password:
}); my @threads=get_threads(1); my %log=read_log(); my $query=new CGI; my $pass=$query->cookie("adminpass"); if($pass ne ENCODED_PASS) { my $password=$query->param("berra"); my $failed; if($password ne ADMIN_PASS) { print_http_header(); print LOGIN_TEMPLATE->( failed=>defined $password, ); exit; } else { make_cookies(adminpass=>ENCODED_PASS,-autopath=>"current"); } } my @shownthreads; my $showlist; my ($threadnum,$ranges,$list,$edit,$ban,$logout,$page)=$ENV{PATH_INFO}=~ m!/(?:([0-9]+)(?:/(.*)|)|(list)|(edit)|(ban)|(logout)|p([0-9]+))!i; if($threadnum) { show_threads(filter_post_ranges($threadnum,$ranges)); } elsif($list) { show_list(); } elsif($edit) { my $filename=$query->param("filename"); my $contents=$query->param("contents"); die "Not an editable file" unless grep { $_ eq $filename } (ADMIN_EDITABLE_FILES); if(defined $contents) { die unless $query->param('admin') eq ENCODED_PASS; do_save($filename,$contents); } else { show_edit($filename) } } elsif($ban) { my $id=$query->param("id"); my $reason=$query->param("reason"); die unless $query->param('admin') eq ENCODED_PASS; do_ban($id,$reason); } elsif($logout) { make_cookies(adminpass=>"",-autopath=>"current"); make_http_forward($ENV{SCRIPT_NAME},ALTERNATE_REDIRECT); } else { $page=0 unless $page; my $start=$page*THREADS_DISPLAYED; my $end=$start+THREADS_DISPLAYED-1; $end=$#threads if $end>$#threads; show_threads( map { filter_post_ranges($threads[$_],"l".ADMIN_SHOWN_POSTS,ADMIN_SHOWN_LINES) } ($start..$end) ); } sub show_threads(@) { my @shownthreads=@_; foreach my $thread (@shownthreads) { foreach my $post (@{$$thread{posts}}) { $$post{encrypted_password}=$log{$$thread{thread}}{$$post{num}}{password}; $$post{encrypted_ip}=$log{$$thread{thread}}{$$post{num}}{ip}; $$post{md5}=$log{$$thread{thread}}{$$post{num}}{md5}; $$post{filename}=$log{$$thread{thread}}{$$post{num}}{filename}; $$post{ip}=decrypt_ip($$post{encrypted_ip}); $$post{password}=decrypt_password($$post{encrypted_password}); $$post{masked_ip}=mask_ip($$post{ip},make_key("mask",SECRET,32)); } } print_http_header(); print THREAD_TEMPLATE->( threads=>\@threads, shownthreads=>\@shownthreads, currpage=>$page, adminpass=>ENCODED_PASS, editable=>[map +{ filename=>$_ },(ADMIN_EDITABLE_FILES)], ); } sub show_list() { print_http_header(); print LIST_TEMPLATE->( threads=>\@threads, adminpass=>ENCODED_PASS, ); } sub show_edit($) { my ($filename)=@_; my $contents=join "\n",read_array($filename); print_http_header(); print EDIT_TEMPLATE->( filename=>$filename, contents=>$contents, ); } sub do_save($$) { my ($filename,$contents)=@_; write_array($filename,$contents); make_http_forward($ENV{SCRIPT_NAME},ALTERNATE_REDIRECT); } sub do_ban($$) { my ($id,$reason)=@_; my $ip; if($id=~/^\d+\.\d+\.\d+\.\d+$/) { $ip=$id } elsif($id=~/^[0-9a-f]{8}$/i) { $ip=unmask_ip($id,make_key("mask",SECRET,32)) } else { die "Invalid address specified" } die "Banning is disabled" unless ADMIN_BAN_FILE; open BANFILE,">>",ADMIN_BAN_FILE or die "Could not open ban file \"".ADMIN_BAN_FILE."\" for writing"; print BANFILE compile_template(ADMIN_BAN_TEMPLATE,1)->( ip=>$ip, reason=>$reason, ); close BANFILE; make_http_forward($ENV{HTTP_REFERER},ALTERNATE_REDIRECT); } sub print_http_header() { print "Content-Type: ".get_xhtml_content_type(CHARSET,0)."\n"; print "Expires: Mon, 26 Jul 1997 05:00:00 GMT\n"; print "Cache-Control: max-age=0; must-revalidate; no-cache\n"; print "Pragma: no-cache\n"; print "\n"; } sub read_log() { my %posts; for(read_array(LOG_FILE)) { my ($thread,$num,%post); ($thread,$num,@post{"password","ip","key","md5","filename"})=split /\s*,\s*/; $posts{$thread}{$num}=\%post; } return %posts; } sub decrypt_ip($) { my ($str)=@_; my ($iv,$cipher); if(($iv,$cipher)=$str=~/^(.*?)!(.*)$/) { eval "use Digest::MD5 qw(md5)"; return rc4_old(decode_base64($cipher),md5(SECRET.$iv)); } elsif(($iv,$cipher)=$str=~/^(.*?):(.*)$/) { return rc4(decode_base64($cipher),"l".$iv.SECRET); } elsif(($iv,$cipher)=$str=~/^(.*?);(.*)$/) { return rc4(decode_base64($cipher),IP_PASSWD.$iv); } } sub decrypt_password($) { my ($str)=@_; my ($iv,$cipher); if(($iv,$cipher)=$str=~/^(.*?);(.*)$/) { return rc4(decode_base64($cipher),PASS_PASSWD.$iv); } else { return $str; } } sub rc4_old($$) { my ($message,$key)=@_; my @k=unpack 'C*',$key; my @s=0..255; my $y=0; for my $x (0..255) { $y=($k[$x%@k]+$s[$x]+$y)%256; @s[$x,$y]=@s[$y,$x]; } my $x,$y; my @message=unpack 'C*',$message; for(@message) { $x=($x+1)%256; $y=($y+$s[$x])%256; @s[$x,$y]=@s[$y,$x]; $_^=$s[($s[$x]+$s[$y])%256]; } return pack 'C*',@message; }