From 51ea8498a9453bcaaf03f5077d8f0c11db88f8d6 Mon Sep 17 00:00:00 2001 From: John Shaver Date: Sun, 30 May 2010 19:39:27 -0600 Subject: [PATCH] This is the beginning. The first commit. Let's see what happens. --- config.php | 32 ++++++ docs/howto.rst | 48 ++++++++ form.html | 29 +++++ process.php | 80 ++++++++++++++ recaptchalib.php | 277 +++++++++++++++++++++++++++++++++++++++++++++++ template.txt | 2 + 6 files changed, 468 insertions(+) create mode 100644 config.php create mode 100644 docs/howto.rst create mode 100644 form.html create mode 100755 process.php create mode 100644 recaptchalib.php create mode 100644 template.txt diff --git a/config.php b/config.php new file mode 100644 index 0000000..377a21b --- /dev/null +++ b/config.php @@ -0,0 +1,32 @@ + diff --git a/docs/howto.rst b/docs/howto.rst new file mode 100644 index 0000000..e1f7b7c --- /dev/null +++ b/docs/howto.rst @@ -0,0 +1,48 @@ +Introduction +============ + +This script is designed to allow someone with little knowledge of scripting, +but some knowledge of html to create an email "contact" form. When designing +this script, I had 2 major goals. + +1. Little-to-no configuration. +------------------------------ + + The only necessary configuration in the script is to set your email + address you would like to receive the emails at. There are other + configuration options if you would like to have extra features (like a + redirect page or captcha spam protection) but you CAN just create an + email template and point a form action to the script and it will send + you emails. + +2. Compatability +---------------- + + I wanted this script to be compatible with as many servers as possible + with out having to make any server side settings. This is why I wrote + it in php, instead of python. With most hosts, you will already have + php and sendmail installed, configured and ready to go. + +The basic setup +=============== + +With the most basic setup, you get a script that accepts a form action by the +POST method and then send the information using a template you create to form +the email data how you would like it. + +Building the form html +---------------------- + +In order to have a form on your site, you must add the form to one of your html +pages. This can be done just by editing the html page with a text editor, or +by most webbuilding softwares by adding the form fields. If you use a site +building software, you may still need to edit the html code by hand, so I'll +breifly go over the html tags used to build the form and what they do. + +There are 2 basic html tags used when building a form. + +1.
tag +~~~~~~~~~~~~~~~~~~~~ + +All tags (we'll talk about those next) must go between the
and +
tags in your html code. The
tag also contains some info diff --git a/form.html b/form.html new file mode 100644 index 0000000..ada1fd4 --- /dev/null +++ b/form.html @@ -0,0 +1,29 @@ + + This is my title + + + This form is for testing out my templating for my mail script. It's an addlib of one of my sister's fan fics she wrote. Feel free to fill it out and it will send the addlib to me.
+
+ Please put everything in past tense unless otherwise stated.
+
+ + adjective
+ adjective
+ animal
+ verb
+ adjective
+ animal
+ + + + + + +
+ diff --git a/process.php b/process.php new file mode 100755 index 0000000..d78a5be --- /dev/null +++ b/process.php @@ -0,0 +1,80 @@ +is_valid) + { + die("Invalid CAPTCHA verification. Please go back and try again."); + } +} +if(isset($_POST["template"])) +{ + $template = file($_POST["template"]); +} +else +{ + $template = file($templateFile); +} + +$emailBody = ""; +$subject = ""; + +if(isset($_POST["email"])) +{ + $subject = "Contact form message from ".$_POST["email"]; +} +else +{ + $subject = "Contact form message."; +} + +$pattern = "/\{([a-zA-Z0-9_]+)\}/i"; + +foreach($template as $line) +{ + $emailBody .= preg_replace_callback( + $pattern, create_function( + '$matches', + '$temp = trim($matches[0], "{}");'. + 'if(isset($_POST[$temp])){'. + 'return $_POST[$temp];}'. + 'echo $_POST[$temp]; return "{NOT SPECIFIED}";'), + $line); +} + +if(isset($_POST["redirectURL"])) +{ + $redirectDestination = $_POST["redirectURL"]; +} + +if(@mail($sendToEmail, $subject, $emailBody, NULL, $sendmailParam)) +{ + if(isset($redirectDestination)) + { + header("Location: $redirectDestination"); + } + else + { + echo "Thank You for using John's form processing script. Your message has delivered successfuly."; + } +} +else +{ + echo "An error prevented your message from sending. Please try again later."; +} +?> diff --git a/recaptchalib.php b/recaptchalib.php new file mode 100644 index 0000000..897c509 --- /dev/null +++ b/recaptchalib.php @@ -0,0 +1,277 @@ + $value ) + $req .= $key . '=' . urlencode( stripslashes($value) ) . '&'; + + // Cut the last '&' + $req=substr($req,0,strlen($req)-1); + return $req; +} + + + +/** + * Submits an HTTP POST to a reCAPTCHA server + * @param string $host + * @param string $path + * @param array $data + * @param int port + * @return array response + */ +function _recaptcha_http_post($host, $path, $data, $port = 80) { + + $req = _recaptcha_qsencode ($data); + + $http_request = "POST $path HTTP/1.0\r\n"; + $http_request .= "Host: $host\r\n"; + $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; + $http_request .= "Content-Length: " . strlen($req) . "\r\n"; + $http_request .= "User-Agent: reCAPTCHA/PHP\r\n"; + $http_request .= "\r\n"; + $http_request .= $req; + + $response = ''; + if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) { + die ('Could not open socket'); + } + + fwrite($fs, $http_request); + + while ( !feof($fs) ) + $response .= fgets($fs, 1160); // One TCP-IP packet + fclose($fs); + $response = explode("\r\n\r\n", $response, 2); + + return $response; +} + + + +/** + * Gets the challenge HTML (javascript and non-javascript version). + * This is called from the browser, and the resulting reCAPTCHA HTML widget + * is embedded within the HTML form it was called from. + * @param string $pubkey A public key for reCAPTCHA + * @param string $error The error given by reCAPTCHA (optional, default is null) + * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false) + + * @return string - The HTML to be embedded in the user's form. + */ +function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) +{ + if ($pubkey == null || $pubkey == '') { + die ("To use reCAPTCHA you must get an API key from http://recaptcha.net/api/getkey"); + } + + if ($use_ssl) { + $server = RECAPTCHA_API_SECURE_SERVER; + } else { + $server = RECAPTCHA_API_SERVER; + } + + $errorpart = ""; + if ($error) { + $errorpart = "&error=" . $error; + } + return ' + + '; +} + + + + +/** + * A ReCaptchaResponse is returned from recaptcha_check_answer() + */ +class ReCaptchaResponse { + var $is_valid; + var $error; +} + + +/** + * Calls an HTTP POST function to verify if the user's guess was correct + * @param string $privkey + * @param string $remoteip + * @param string $challenge + * @param string $response + * @param array $extra_params an array of extra variables to post to the server + * @return ReCaptchaResponse + */ +function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array()) +{ + if ($privkey == null || $privkey == '') { + die ("To use reCAPTCHA you must get an API key from http://recaptcha.net/api/getkey"); + } + + if ($remoteip == null || $remoteip == '') { + die ("For security reasons, you must pass the remote ip to reCAPTCHA"); + } + + + + //discard spam submissions + if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) { + $recaptcha_response = new ReCaptchaResponse(); + $recaptcha_response->is_valid = false; + $recaptcha_response->error = 'incorrect-captcha-sol'; + return $recaptcha_response; + } + + $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/verify", + array ( + 'privatekey' => $privkey, + 'remoteip' => $remoteip, + 'challenge' => $challenge, + 'response' => $response + ) + $extra_params + ); + + $answers = explode ("\n", $response [1]); + $recaptcha_response = new ReCaptchaResponse(); + + if (trim ($answers [0]) == 'true') { + $recaptcha_response->is_valid = true; + } + else { + $recaptcha_response->is_valid = false; + $recaptcha_response->error = $answers [1]; + } + return $recaptcha_response; + +} + +/** + * gets a URL where the user can sign up for reCAPTCHA. If your application + * has a configuration page where you enter a key, you should provide a link + * using this function. + * @param string $domain The domain where the page is hosted + * @param string $appname The name of your application + */ +function recaptcha_get_signup_url ($domain = null, $appname = null) { + return "http://recaptcha.net/api/getkey?" . _recaptcha_qsencode (array ('domain' => $domain, 'app' => $appname)); +} + +function _recaptcha_aes_pad($val) { + $block_size = 16; + $numpad = $block_size - (strlen ($val) % $block_size); + return str_pad($val, strlen ($val) + $numpad, chr($numpad)); +} + +/* Mailhide related code */ + +function _recaptcha_aes_encrypt($val,$ky) { + if (! function_exists ("mcrypt_encrypt")) { + die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed."); + } + $mode=MCRYPT_MODE_CBC; + $enc=MCRYPT_RIJNDAEL_128; + $val=_recaptcha_aes_pad($val); + return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); +} + + +function _recaptcha_mailhide_urlbase64 ($x) { + return strtr(base64_encode ($x), '+/', '-_'); +} + +/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */ +function recaptcha_mailhide_url($pubkey, $privkey, $email) { + if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) { + die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . + "you can do so at http://mailhide.recaptcha.net/apikey"); + } + + + $ky = pack('H*', $privkey); + $cryptmail = _recaptcha_aes_encrypt ($email, $ky); + + return "http://mailhide.recaptcha.net/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail); +} + +/** + * gets the parts of the email to expose to the user. + * eg, given johndoe@example,com return ["john", "example.com"]. + * the email is then displayed as john...@example.com + */ +function _recaptcha_mailhide_email_parts ($email) { + $arr = preg_split("/@/", $email ); + + if (strlen ($arr[0]) <= 4) { + $arr[0] = substr ($arr[0], 0, 1); + } else if (strlen ($arr[0]) <= 6) { + $arr[0] = substr ($arr[0], 0, 3); + } else { + $arr[0] = substr ($arr[0], 0, 4); + } + return $arr; +} + +/** + * Gets html to display an email address given a public an private key. + * to get a key, go to: + * + * http://mailhide.recaptcha.net/apikey + */ +function recaptcha_mailhide_html($pubkey, $privkey, $email) { + $emailparts = _recaptcha_mailhide_email_parts ($email); + $url = recaptcha_mailhide_url ($pubkey, $privkey, $email); + + return htmlentities($emailparts[0]) . "...@" . htmlentities ($emailparts [1]); + +} + + +?> diff --git a/template.txt b/template.txt new file mode 100644 index 0000000..2b42b00 --- /dev/null +++ b/template.txt @@ -0,0 +1,2 @@ +The {adjective1} {adjective2} {animal1} {verb} over the {adjective3} {animal2}. +