diff --git a/en/cgi/Makefile b/en/cgi/Makefile index 06a07d2fcb..bde0a27bb9 100644 --- a/en/cgi/Makefile +++ b/en/cgi/Makefile @@ -1,4 +1,4 @@ -# $FreeBSD: www/en/cgi/Makefile,v 1.25 2005/10/06 15:44:08 remko Exp $ +# $FreeBSD: www/en/cgi/Makefile,v 1.26 2005/11/06 20:28:56 ceri Exp $ .if exists(../Makefile.conf) .include "../Makefile.conf" @@ -34,6 +34,7 @@ CGI+= pds.cgi CGI+= ports.cgi CGI+= query-pr.cgi CGI+= query-pr-summary.cgi +CGI+= querypr-code.cgi CGI+= search.cgi CGI+= sendpr-code.cgi CGI+= url.cgi diff --git a/en/cgi/query-pr.cgi b/en/cgi/query-pr.cgi index 07b948f928..2ff101cf59 100755 --- a/en/cgi/query-pr.cgi +++ b/en/cgi/query-pr.cgi @@ -3,12 +3,22 @@ $ENV{'PATH'} = "/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/bin"; +use DB_File; +use Fcntl qw(:DEFAULT :flock); + require "./cgi-lib.pl"; require "./cgi-style.pl"; require "getopts.pl"; require "./Gnats.pm"; import Gnats; -&Getopts('p:'); +my $expiretime = 2700; +$dbpath = "/tmp/querypr-code.db"; + +&Getopts('cp:'); + +if ($opt_c) { + $codeentered = $opt_c; +} if ($opt_p) { @@ -22,8 +32,15 @@ if ($opt_p) { ($scriptname = $ENV{'SCRIPT_NAME'}) =~ s|^/?|/|; $scriptname =~ s|/$||; ($summary = $scriptname) =~ s/query-pr/query-pr-summary/; - print "
\n"; print "See also the PR summary
\n"; print &html_footer; @@ -36,6 +53,56 @@ if (!($pr = $input{'pr'}) && &MethGet) { $pr = $ENV{'QUERY_STRING'}; } +# Get the confirmation code if it exists +# (and wasn't specified with -c). +$codeentered ||= $input{'code-confirm'}; + +# Verify the data ... + +$db_obj = tie(%db_hash, 'DB_File', $dbpath, O_CREAT|O_RDWR, 0644) + or die "dbcreate $dbpath $!"; +$fd = $db_obj->fd; +open(DB_FH, "+<&=$fd") or die "fdopen $!"; + +unless (flock (DB_FH, LOCK_EX | LOCK_NB)) { + unless (flock (DB_FH, LOCK_EX)) { die "flock: $!" } +} + +# Sweep for and remove expired codes. +foreach $randomcode (keys %db_hash) { + if ( ($currenttime - $expiretime) >= $db_hash{$randomcode}) { + delete $db_hash{"$randomcode"}; + } +} + +$currenttime = time(); +if (defined($codeentered) && $codeentered && $db_hash{$codeentered} && + (($currenttime - $expiretime) <= $db_hash{$codeentered})) { + # This code is good. Set the flag and remove the code. + $codeok++; + delete $db_hash{"$codeentered"}; +} else { + # Fail silently. + if ($db_hash{$codeentered}) { + print "code was in db\n"; + print "time in db is $db_hash{$codeentered}\n"; + } else { + print "code not in db\n"; + } + print "code entered was $codeentered\n"; + print "current time is $currenttime\n"; + print "expire time is $expiretime\n"; + + die ("shit: $@"); + undef; +} + +$db_obj->sync(); # to flush +flock(DB_FH, LOCK_UN); +undef $db_obj; # removing the last reference to the DB + # closes it. Closing DB_FH is implicit. +untie %db_hash; + # be tolerant to) { $origsyn = $syn; $syn = &fixline($syn); print &html_header("Problem Report $cat/$number : $syn"); + if (! $codeok ) { + print "View PR with email + addresses
\n"; + } print "$syn
\n\n"; } else { next if $inhdr; @@ -154,7 +225,7 @@ while(
) { } else { $trailer .= $2; } - if ($1 eq "Originator" && $from ne "") { # add email address + if ($1 eq "Originator" && $from ne "" && $codeok) { # add email address $trailer .= " <" . &fixline($from) . ">"; } $trailer .= ''; @@ -182,6 +253,22 @@ $email =~ s/[^a-zA-Z+.@-]/"%" . sprintf("%02X", unpack("C", $&))/eg; print qq`Submit Followup | Raw PR | Find Another PR\n`; +if (! $codeok ) { + print ""; + print "To see this PR with email addresses "; + print " displayed, enter the code from the image and submit: \n"; + print "
\n"; +} + print &html_footer; # Sleep 0.35 seconds to avoid DoS attacks from broken robots diff --git a/en/cgi/querypr-code.cgi b/en/cgi/querypr-code.cgi new file mode 100755 index 0000000000..671183b172 --- /dev/null +++ b/en/cgi/querypr-code.cgi @@ -0,0 +1,84 @@ +#!/usr/bin/perl -T +# +# $FreeBSD$ +# +# Cribbed from sendpr-code.cgi, which is: +# Copyright (c) 2003 Eric Anderson + +use DB_File; +use Fcntl qw(:DEFAULT :flock); +use strict; + +$ENV{"PATH"} = "/bin:/usr/bin"; +$ENV{"TMPDIR"} = "/tmp"; + +my($fd, $db_obj, %db_hash, $currenttime, $randomcode, $pngbindata, $randompick, $pnmlist, $i); +my($expiretime, $pnmcat, $pnmtopng, $pnmdatadir, $dbpath); + +############################################ +# generate 8 character code from A-Z0-9 (no I,O,0,1 for clarity) +my @availchars = qw(A B C D E F G H J K L M N P Q R S T U V W X Y Z + 2 3 4 5 6 7 8 9); + +$pnmcat = "/usr/local/bin/pnmcat"; +$pnmtopng = "/usr/local/bin/pnmtopng"; +$pnmdatadir = "../gifs/"; +$dbpath = "/tmp/querypr-code.db"; +$expiretime = 2700; # seconds until code expires +############################################ + +$currenttime = time(); + +# DB stuff here +$db_obj = tie(%db_hash, 'DB_File', $dbpath, O_CREAT|O_RDWR, 0644) + or die "dbcreate $dbpath $!"; +$fd = $db_obj->fd; +open(DB_FH, "+<&=$fd") or die "fdopen $!"; + +unless (flock (DB_FH, LOCK_EX | LOCK_NB)) { + unless (flock (DB_FH, LOCK_EX)) { die "flock: $!" } +} + +&gencode; + +while ($db_hash{$randomcode}) { + # it already exists so: + # we check age (over x seconds old?) + # if it is, override with new date + # if not, generate a new code + if ( ($currenttime - $expiretime) <= $db_hash{$randomcode}) { + &gencode; + } else { + delete $db_hash{"$randomcode"}; + } +} + +$db_hash{$randomcode} = $currenttime; + +$db_obj->sync(); # to flush +flock(DB_FH, LOCK_UN); +undef $db_obj; # removing the last reference to the DB + # closes it. Closing DB_FH is implicit. +untie %db_hash; + +$/ = ""; + +open(BUILDPNG, "$pnmcat -lr $pnmlist | $pnmtopng 2>/dev/null |"); +$pngbindata =; +print "Pragma: no-cache\n"; +print "Content-type: image/png\n\n"; +print "$pngbindata"; +close(BUILDPNG); + +############################################ +sub gencode { + srand( time() ^ ($$ + ($$ << 15)) ); + + for ($i = 0; $i < 8; $i++) { + $randompick = $availchars[int(rand(@availchars))]; + $randomcode .= "$randompick"; + $pnmlist .= "$pnmdatadir$randompick\.pnm "; + } +} + +