According to tradition, the door of Plato's Academy in Athens bore the legend “Let no one ignorant of geometry enter”. Well, times change and intellectual standards erode—one of the biggest challenges in developing computer aided design software was finding competent programmers who knew anything at all about geometry. But even in this demotic age, is it too much to ask strangers who wish to comment on pages of a Web site primarily devoted to science and technology to be able to solve a linear equation?
FeedbackForm is a server-side CGI (Common Gateway Interface) program
written in the
Perl language
which permits you to add Feedback buttons to
pages on your Web site. When pressed, the user receives a feedback
form which permits entering an E-mail style message, which can be
either anonymous or include the submitter's name and E-mail address for
eventual replies. In order to submit the form, the user is asked to
solve a linear equation with integer coefficients and unknown. If the
correct solution is entered, the feedback message is forwarded to
an E-mail address defined in the CGI program on the server and hence
completely invisible to the submitter or to a junk mailer crawling the
site seeking E-mail addresses to abuse. The feedback E-mail includes the
URL on which the user pressed the feedback button, avoiding the mystery
when a user makes some generic comment about a page such as “The back
link is broken” and neglects to cite the URL in which they noted
the flaw.
The following button is “live”—it will launch the FeedbackForm application in “test mode”. You can play around with it, going as far as requesting feedback to be sent, but no feedback E-mail will actually be sent, so you needn't worry about cluttering up my mailbox. To actually send feedback, use the button at the bottom of this document.
Note: FeedbackForm is a Common Gateway Interface (CGI) program written in the Perl language. Installing a CGI program requires detailed knowledge of the Web server configuration of the system on which it is to be installed, and may require administrative (super-user) privilege to install. Programs and data directories must be installed with the correct ownership attributes and permissions, and program and library paths may need to be set to permit the CGI program to find the utilities it requires. Since Web server configurations differ widely from system to system, there's no cookbook approach to installing a program such as this—you need to understand what you're doing, and know how to track down and fix problems based on error messages in the HTTP server error log.To install FeedbackForm on your Web server, perform the following steps.
feedbackform-1.1.tar.gz
Directory/File | Variable | Example | Location on your system |
---|---|---|---|
CGI binaries | $CGI_Directory | /var/www/cgi-bin | |
Mailer protocol | $mailer | ||
Mailer | $mailerpath | /bin/mail | |
Logresolve | $logresolve | /usr/bin/logresolve | |
Spell checker | $spellCmd | /usr/bin/spell | |
Perl interpreter | #! | /usr/bin/perl |
Description | Variable | Your Setting |
---|---|---|
Feedback E-mail | ||
Master key | $masterKey | |
Working directory | $workingDirectory | |
Log file | $logFile |
./FeedbackForm.pl testIf you get a “bad interpreter” or “not executable” error, the location of Perl in the first line of the program is probably incorrect or the process of editing the program has caused it to lose execute permission (or Perl is missing or improperly installed on your system). If you get one or more missing directory or file messages or other misconfiguration errors, correct the configuration accordingly until you get the message “FeedbackForm configuration tests passed.”. Note that you must run this test on your Web server machine to verify that the programs and directories are properly configured there.
To add a feedback button to a page on your Web site, simply add the following HTML code where you wish the button to appear.
<form name="feedback" method="post" action="/cgi-bin/FeedbackForm.pl"> <input type="submit" value=" Feedback " /> </form>
If your server uses a different $CGI_Directory, adjust the “action” attribute in the form tag accordingly. You're free to change the label (“value”) on the button to whatever you wish, or use a graphical button instead of a text button. You can put as many feedback buttons on a given page as you like (for example, one at the top and bottom of a long document), and you can do so either by considering the entire document a single form with multiple submit buttons, or declaring each button within its own form (which allows you to include other forms between feedback buttons).
You can customise the behaviour of FeedbackForm by including the following hidden input fields within the form which invokes the script. These may be used in any combination, but only one field with a given name may appear in an individual form.
Whenever a feedback message is forwarded to the designated E-mail address, if the user specified an E-mail address, a URL is included which will add that E-mail address to the white list (if it is not on the list), or remove it (if it is).
Once an E-mail address is on the white list, a user who enters that address in a feedback form's E-mail field need not solve the problem in order to send feedback. Although the problem will be presented (since there's no way to know the requester's E-mail address when initially sending the form), a white listed user may simply leave the solution blank. The confirmation a white listed user receives when sending feedback contains a reminder that they're on the white list and need not solve future problems to send feedback.
You can customise the configuration of FeedbackForm in many ways by changing variable definitions at the start of the script. The following sections document each of these variables, grouped by function. The variables do not necessarily appear in the script in the same order they're listed here.
$CGI_Directory | Absolute path of the directory from which your Web server runs Common Gateway Interface (CGI) scripts. |
---|---|
$actionscript | URL with which the FeedbackForm.pl is invoked. This is usually “/cgi-bin/FeedbackForm.pl”, but you may change it as required if your server uses a different naming convention or you wish to invoke a different program while testing. |
$mailer | Name of program used to send feedback E-mail messages. This is just the program name, for example “mail”, and is used solely to identify how the message is passed to the mailer program. |
$mailerpath | Path name used to invoke the program used to send feedback E-mail. It's best to specify an absolute path name, but you can use a relative name as long as you're sure a CGI program invoked by your Web server will be able to find it. The program name needn't have anything to do with $mailer; it's fine, for example, to set $mailer to “mailx” and $mailerpath to, say, “/usr/ucb/mail”. |
Feedback will be sent to this E-mail address unless the $overrideEmail mechanism is enabled and an encrypted E-mail address is specified in the request form. If you filter your incoming mail, you may want to create an alias for messages sent by FeedbackForm, and/or use the little-known “+” gimmick (for example spam+feedback@uce.gov) with an existing address to identify feedback mail. | |
$logresolve | Absolute path name to execute the logresolve program, included with the Apache Web server, which looks up IP addresses (for example 192.168.10.12) and returns their fully qualified domain names (such as www.ratburger.org). If this program is not available on your server, set $logresolve to the null string; in this case domain lookups will not be performed and numeric IP addresses will be used in messages and log entries. |
$spellCmd | Absolute path name to execute the spelling checker program. This must be a program which reads the text to be checked from standard input and writes the possibly misspelled words to standard output. If you set $spellCmd to the null string, spelling checking will be disabled and no “Spell Check” button will appear in the feedback form. If you're worried about the burden spelling checking may impose on your server (or you don't have a suitable spelling checker program), set $spellCmd to the null string. This will remove the “Spell Check” button from the form and disable spelling checking. |
$workingDirectory | Directory in which FeedbackForm will keep its databases. This directory must be readable and writable by the user ID under which CGI programs run, and should not be accessible through your Web site. |
$wrapMax | If nonzero, the message input text box will be this number of characters in width and lines longer than this will be wrapped to be less than or equal to this length. If zero, the text input box will be 70 characters wide and lines longer than this will be left unchanged. |
---|---|
$headerText | The HTML text assigned to this variable replaces
the default heading on the feedback form. This can be any
HTML code. The value assigned to this string is evaluated at
run-time before being included in the document, and hence may
interpolate string variables such as $referer (the
URL of the referring page) and $pagetitle (the title
of the referring page). Because the string is evaluated, all
double quote marks must be preceded by a backslash. It is
usually most convenient to define $headerText as a
single-quoted “here” document. If $headerText is the
null string, the default heading is generated. Here is the
rather baroque $headerText declaration used by
the Fourmilab feedback page.
$headerText = << 'EOF'; <center> <table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"> <tr> <td width=\"160\" align=\"left\"> <a href=\"../\" target=\"_top\"> <img src=\"/images/logo/swlogo.png\" width=\"82\" height=\"74\" align=\"left\" border=\"0\" style=\"padding-left: 6px\" alt=\"Fourmilab home\" /> </a> </td> <td align=\"center\"> <font size=\"+2\"><em>Index Librorum Liberorum</em></font><br> <font size=\"+1\">Send feedback on page:<br><a href=\"$referer\">$qpagetitle</a></font><br> </td> <td width=\"160\" align=\"right\" style=\"padding-right: 6px\"> </td> </tr> </table> </center> <p /> <hr /> EOF |
$footerText | The HTML text assigned to this variable will be appended to the bottom of the feedback form. If set to the null string, nothing will be appended. As with $headerText, this string is evaluated at run-time, and double quote marks must be escaped with backslashes. |
$returnTime | After a user successfully submits feedback, they'll receive a confirmation page which, after $returnTime seconds, will return them automatically to the page on which they pressed the Feedback button. If you set $returnTime to 0, no automatic return will occur. The default is 10*$seconds. |
$sentience | If nonzero (the default), the user will be required to solve a problem before feedback will be forwarded. It set to zero, feedback will be sent immediately the user presses the “Send” button. |
$maxtries | Number of incorrect solutions a user may enter before being placed on the black list. The default is 3. |
Note: When setting the following parameters which govern generation of the equation the user is asked to solve, be careful that in the worst case (greatest order, coefficients, and answer), the right hand side of the equation does not exceed the maximum value of a 32 bit signed integer (±2,147,483,648). That'd be a bit much to ask of the Gentle User in any case. | |
$minorder | Minimum order (highest power of the unknown) of the equation sent to the user. The default value of 1 denotes a linear equation. |
$maxorder | Maximum order of the equation sent to the user. The default value of 1 denotes a linear equation. If you set $maxorder to a greater value (2 for quadratic, 3 for cubic, 4 for quartic, etc.), the order will be randomly chosen between $minorder and $maxorder inclusive. |
$mincoeff | Smallest coefficient of terms in the equation. The default value is 1. Note that you are free to set $mincoeff to a negative value; if you do, randomly chosen coefficients which come out zero are changed to 1. |
$maxcoeff | Largest coefficient on terms in the equation. This may be set to any value greater than $mincoeff; values are randomly selected within this inclusive range. |
$minanswer | Smallest value for the solution to the equation. The default value is 4. You may set this value negative. |
$maxanswer | Largest value for the solution to the equation, default 100. |
$leastanswer | If the range from $minanswer to $maxanswer includes zero, randomly chosen answers with absolute value less than $leastanswer will be set to $leastanswer, preserving the sign of the randomly generated value. |
$masterKey | Values sent to the user and returned when the form is submitted are
encrypted using the $masterKey, which should be 32 bytes
(64 digits) or more of hexadecimal data. You must generate
a unique master key when you install the program. You can create
a $masterKey declaration ready to paste into the program
by running:
./FeedbackForm.pl masterkey |
---|---|
$restrictReferer | If $restrictReferer is non-null, it is used as a regular expression to test the HTTP_REFERER field received from the Web server. This can (and should) be used to restrict access to pages originating at the site where it's hosted. If your site has several aliases (ratburger.org, ratburger.net, etc.) or permits access by IP address or IP address range, you'll have to craft a regular expression which matches everything you may see as a referer. Here, for example, is the declaration used for the Fourmilab server: |
$restrictReferer = qr{^http://(((www\.)?fourmilab\.(ch|com|net|org|to))|193\.8\.230\.\d+)/}; | |
$cribIP | If $cribIP is non-null, IP addresses which match its regular expression pattern will have the solution to the equation already filled into the text box in the feedback page. This is handy (only) for testing new versions of the program as you don't need to actually solve the equation every time in a long series of tests, and since you can still edit the value filled in the box, it permits testing both right and wrong answers, which white listing does not. The default is null. |
$overrideEmail | If set nonzero (the default is 0), $overrideEmail permits feedback request forms to specify the E-mail address to which feedback is sent, overriding the default address specified by $email. The E-mail address is specified by a hidden data field in the request form named “j” whose value is the E-mail address encrypted with the $masterKey you set for the program by invoking it with a command like: |
./FeedbackForm.pl mailcode spam@uce.gov | |
which will print the complete hidden field declaration to paste into the request form in your HTML document. Do not use this unless you absolutely must! Keeping the E-mail address hidden in the CGI program is immeasurably more secure than embedding it, however protected, in a document a user can examine. If you do permit E-mail addresses to be overridden, be sure to specify a $restrictEmail pattern so that, in the worst case, overrides are confined to your own site. | |
$restrictEmail | If you must set $overrideEmail to 1, you should restrict E-mail overrides to your own domain by forcing them to match the regular expression $restrictEmail. Otherwise, should your $masterKey be compromised or somebody figure out how to break the encryption in some other manner, your feedback page could be hijacked for use by other sites and, even worse, used to send junk mail to third parties. |
FeebackForm maintains several databases, all kept as Comma Separated Value (CSV) text files, to store permissions and the current state of transactions it's processing. All of these database files are kept within the $workingDirectory you define.
The White List is a list of E-mail addresses which are permitted to send feedback without entering a solution to the sentience test problem. Links included in feedback messages permit you to add and remove White List items.
$whiteList | White List database file name, “whitelist.csv” by default. |
---|---|
$restrictIP | If $restrictIP is non-null, it is used as a regular expression to test the IP address from which white list requests are sent. If the IP address does not match, the request will be rejected. Use this if you always manage your mail from a known IP address or range. If you process such requests from different IP addresses, leave this null (the default). |
The Black List keeps track of IP addresses from which more than the maximum permitted number of consecutive wrong answers have been received. Additional feedback requests from an IP address on the black list will receive an immediate message indicating they've already struck out. Black list entries expire after a specified time—this both gives the user another chance, and avoids permanently banning an IP address which may, in fact, be assigned to different users in succession as they connect to and disconnect from the Internet. A reasonable black list timeout interval is an hour or two.
$blackList | Black List database file name, “blacklist.csv” by default. |
---|---|
$blacklistTime | Interval, in seconds, between an IP address's being placed on the black list and when it expires and is removed. Constants are defined for $seconds, $minutes, $hours, $days to make this definition more readable. The default value is 2*$hours. If set to zero, the black list mechanism is entirely disabled. |
Problems sent to a user for solution are time stamped and normally must be solved with a given time interval. This prevents, for example, some cunning urchin's taking the problem to school the next day and inveigling teacher into solving it. Once a correct solution is entered, the time stamp of the last successfully solved problem is saved in the Green List. This defends against a “replay attack”, where the user saves a feedback page with the valid solution and then submits it over and over with additional messages. If FeedbackForm receives a purported solution which has either expired or has a time stamp equal to or earlier than the last problem solved, it chides the user and provides a fresh new problem. Problem expiration permits entries in the Green List to be removed after the expiration time is reached.
$greenList | Green List database file name, “greenlist.csv” by default. |
---|---|
$expirationTime | Interval, in seconds, between the time a problem is generated and sent to a user for solution and when it expires, after which a solution will no longer be accepted. This is also how long an entry for the time stamp of the last problem solved by a user remains in the green list. The default value is 1*$hours; if you set the value to 0, problems will never expire and no green list will be kept. |
$logFile | Log file name, “$workingDirectory/log.csv” by default. Note that while the default setting keeps the log file in the $workingDirectory, you're free to put it anywhere you like that CGI programs have write access. If you specify the null string, log file generation will be completely disabled. You can transfer logging to a new file at any time simply by renaming the existing log file to something else. |
---|
If you specify a non-null value for $logFile, FeedbackForm appends records to the specified file in Comma Separated Value (CSV) format for each transaction it processes. Each record begins with the fields:
Type,Date_time,IP_address
followed by field specific to the item Type. Fields which appear in log items have the following format and meaning. Fields which contain a comma or double quote are enclosed in double quotes; double quotes within a field are denoted by two consecutive double quotes. For example, the text:
Answer | Solution to equation entered by the user. |
---|---|
Date_time | Date and time the item was logged in the server's local time in the ISO-8601-like format: “YYYY-MM-DD:hh:mm:ss”. |
E-mail address entered in the feedback form or being added to or removed from the white list. | |
Equation | Equation the user was asked to solve. |
IP_address | The IP address in dotted quad notation (for example, 192.168.10.12) from which the logged transaction originated. |
Name | Name entered in the feedback form. |
Referer | URL of the page from which the feedback form was invoked. This is as given by the HTTP_REFERER passed by the Web server. |
Rhs | Right hand side value of equation sent to the user. |
Rhs_Wrong | Right hand side value with user's incorrect solution. |
Sent_to | E-mail address to which feedback was sent (or would have been sent were test mode not specified). |
Subject | Subject entered in the feedback form. |
Type | Text string identifying the event this item represents (and hence its format). |
The fields in each type of log item are listed below, along with a discussion of the event that item represents and the interpretation of type-specific fields.
This software is in the public domain. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, without any conditions or restrictions. This software is provided “as is” without express or implied warranty.