"; /** * Function to modify the guestbook to approve the entry supplied. If no entry * is supplied then the function returns false. The function also returns false * if the guestbook cannot be written to. * * @param entry - String representing the guestbook entry to be modified * @return boolean - true if guestbook successfully modified else false */ function approveEntry( $entry ) { global $GUESTBOOK, $DELIMITER; if ( empty( $entry )) { return false; } $fields = explode( $DELIMITER, $entry ); $fields[6] = "1"; $approvedEntry = implode( $DELIMITER, $fields ); $guestbook = file_get_contents( $GUESTBOOK ); $updatedGuestbook = str_replace($entry, $approvedEntry, $guestbook); $file_handle = fopen( $GUESTBOOK, 'w+'); $bytesWritten = fwrite( $file_handle, $updatedGuestbook ); if ( $bytesWritten ) { fclose( $file_handle ); return true; } else { fclose( $file_handle ); return false; } } /** * Function to verify the guestbook entry to be approved and to modify the * guestbook for that entry. The function displays a user message to indicate * the modification of the guestbook * * @param void - no parameters are required * @return null - no values are returned */ function approveGuestEntry() { $session = getSessionID(); if ( empty( $session )) { displayGuestApproveFailure(); return; } $entry = getEntry( $session ); if ( approveEntry( $entry )) { displayGuestApproveSuccess(); return; } else { displayGuestApproveFailure(); return; } } /** * Function to modify the guestbook to confirm the entry supplied. If no entry * is supplied then the function returns false. The function also returns false * if the guestbook cannot be written to. * * @param entry - String representing the guestbook entry to be modified * @return boolean - true if guestbook successfully modified else false */ function confirmEntry( $entry ) { global $GUESTBOOK, $DELIMITER; if ( empty( $entry )) { return false; } $fields = explode( $DELIMITER, $entry ); $fields[8] = "1"; $confirmedEntry = implode( $DELIMITER, $fields ); $guestbook = file_get_contents( $GUESTBOOK ); $updatedGuestbook = str_replace($entry, $confirmedEntry, $guestbook); $file_handle = fopen( $GUESTBOOK, 'w+'); $bytesWritten = fwrite( $file_handle, $updatedGuestbook ); if ( $bytesWritten ) { fclose( $file_handle ); return true; } else { fclose( $file_handle ); return false; } } /** * Function to verify the guestbook entry to be confirmed and to modify the * guestbook for that entry. The function displays a user message to indicate * the modification of the guestbook * * @param void - no paramaters are required * @return null - no values are returned */ function confirmGuestEntry() { global $DELIMITER; $session = getSessionID(); if ( empty( $session )) { displayGuestConfirmFailure(); return false; } $entry = getEntry( $session ); if ( confirmEntry( $entry )) { $fields = explode( $DELIMITER, $entry ); emailAdminApproval( trim($fields[1]), trim($fields[2]), trim($fields[3]), trim($fields[4]), trim($fields[5])); displayGuestConfirmSuccess(); return true; } else { displayGuestConfirmFailure(); return false; } } /** * Function to display HTML message to user upon failure to confirm a guestbook * entry * * @param void - no paramaters are required * @return null - no values are returned */ function displayEmailConfirmationFailure() { print "The guestbook was unable to send a confirmation email to the address you provided.
\n"; print "This is a temporary failure. Please re-try again at a later time
\n"; print "
\n"; } /** * Generates the HTML code to display the guestbook entries. The entries are * parsed from the flatfile and encoded as HTML. The email addresses listed as * private are not displayed. Public email addresses are obfuscated to annoy * email harvesters. The background colors of each entry is alternated between * dark and light (specified in the CSS) to make the entries more readable * * @param void - no parameters are required * @return null - no values are returned */ function displayEntries() { global $NO_ENTRIES, $GUESTBOOK, $DELIMITER, $ENTRIES_DISPLAYED, $EMAIL_PRIVATE; if ( file_exists( $GUESTBOOK )) { $file_handle = file( $GUESTBOOK ); rsort( $file_handle ); $num_entries = count( $file_handle ); if ( $num_entries <= 0 ) { printf("\n

%s

\n", $NO_ENTRIES); } else { $dark = 1; $displayed = 0; for($i = 0; $i < $num_entries; $i++) { if ( isset( $file_handle[$i] )) { $fields = explode( $DELIMITER, $file_handle[$i] ); $approved_entry = $fields[6]; if ( $approved_entry == 1 ) { $date = $fields[0]; $email = $fields[1]; $url = $fields[2]; $name = $fields[3]; $comments = $fields[4]; $private_email = $fields[5]; if ( $private_email == 1 ) { $email = $EMAIL_PRIVATE; } if ( $dark ) { printf("
\n"); $dark = 0; } else { printf("
\n"); $dark = 1; } $email = obsfuscateEmail($email); printf("\n

Name: %s on %s
\n", $name, $date); printf("Email: %s
\n", $email); printf("Website: %s
\n", $url); printf("Comments: %s

\n", $comments); printf("
\n"); $displayed++; } } } printf("\n

%d %s

\n", $displayed, $ENTRIES_DISPLAYED); } } else { printf("\n

%s

\n", $NO_ENTRIES); } } /** * Generates the HTML code to display the HTML form to accepting the guestbook * entry. The form is used to accept the user input and process it. If any error * messages are supplied then they are displayed at the bottom of the form as an * error. Any supplied values that are set as defaults for the appropriate fields, * else the application specific constants are used * * @param name - the text value for the name field (optional) * @param email - the text value for the email field (optional) * @param privateemail - the checkbox value for the privateemail checkbox (optional) * @param url - the text value for the website field (optional) * @param comments - the text value for the comments field (optional) * @param errors - the text value for any error messages to be displayed (optional) * @param session - the text value for the visitor session * @return null - no values are returned */ function displayForm( $name, $email, $privateemail, $url, $comments, $errors, $session ) { global $DEFAULT_NAME, $DEFAULT_EMAIL, $DEFAULT_EMAIL_PRIVACY, $DEFAULT_WEBSITE, $DEFAULT_COMMENTS; $name = empty( $name ) ? $DEFAULT_NAME : trim( $name ); $email = empty( $email ) ? $DEFAULT_EMAIL : trim( $email ); $privateemail = empty( $privateemail ) ? $DEFAULT_EMAIL_PRIVACY : trim( $privateemail ); $url = empty( $url ) ? $DEFAULT_WEBSITE : trim( $url ); $comments = empty( $comments ) ? $DEFAULT_COMMENTS : trim( $comments ); $errors = trim( $errors ); $session = empty( $session ) ? getSessionID() : trim( $session ); print "

* indicates a required field

Name: *
Email: *
Keep e-mail address private: *
Website:
Comments:

$errors

"; } /** * Generated the HTML code to display message to indicate a guestbook entry was * not found, and the guestbook was not modified to approve the entry * * @param void - no parameters are required * @return null - no values are returned */ function displayGuestApproveFailure() { print "The guestbook entry was not found. This is a permanent error. Please contact the Guestbook administrator
\n"; print "
\n"; } /** * Generated the HTML code to display message to indicate a guestbook entry was * found and the guestbook was modified to approve the entry * * @param void - no parameters are required * @return null - no values are returned */ function displayGuestApproveSuccess() { print "Thank you for approving the entry. The guestbook entry will not be displayed as part of the guestbook.
\n"; print "
\n"; } /** * Generated the HTML code to display message to indicate a guestbook entry was * not found, and the guestbook was not modified to confirm the entry * * @param void - no parameters are required * @return null - no values are returned */ function displayGuestConfirmFailure() { print "The guestbook entry was not found. This is a permanent error. Please make another entry by
\n"; print "visiting the Guestbook. If problems persist, please contact the Guestbook administrator
\n"; print "
\n"; } /** * Generated the HTML code to display message to indicate a guestbook entry was * found and the guestbook was modified to confirm the entry * * @param void - no parameters are required * @return null - no values are returned */ function displayGuestConfirmSuccess() { print "Thank you for confirming your entry. An approval request email has been sent to the
\n"; print "Guestbook administrator. Once the administrator has approved the entry, it will be
\n"; print "displayed in the Guestbook.
\n"; print "
\n"; } /** * Generates the HTML code to acknowledge the signing of the guestbook * * @param void - no parameters are required * @return null - no values are returned */ function displaySignAcknowledge() { print "Thank you for signing the guestbook. Your entry will be displayed once it has been confirmed and approved.
\n"; print "
\n"; print "A confirmation email has been sent to the email address you submitted and requires your confirmation, once
\n"; print "it has been confirmed, the guestbook administrator's approval will be requested.
\n"; print "
\n"; print "Your requesting IP address has been logged for security reasons.
\n"; print "
\n"; } /** * Generates the HTML code to present the visitor the option to sign the guestbook. * * @param void - no parameters are required * @return null - no values are returned */ function displaySignOption() { print "Please feel free to sign the guestbook here
\n"; } /** * Generates the HTML code to present the visitor the option to view the guestbook. * * @param void - no parameters are required * @return null - no values are returned */ function displayViewOption() { print "Please feel free to view the guestbook here
\n"; } /** * Assembles the email headers and communicated with the MX server for the * domain to send the email based on the paramaters supplied. The function * complies witht he following RFC documents; * * http://www.ietf.org/rfc/rfc2821.txt * http://www.ietf.org/rfc/rfc2822.txt * * @param from - text representing the email sender address * @param namefrom - text representing the name of the sender * @param to - text representing the email receipient address * @param nameto - text representing the receipient name * @param subject - text representing the subject of the email * @param message - text representing the body of the email * @returns boolean - true of the email is sent successfully else false */ function email( $from, $namefrom, $to, $nameto, $subject, $message ) { global $SMTP_SERVER, $SMTP_PORT, $SMTP_USER, $SMTP_PASS, $SMTP_DOMAIN; // Declare local variables $timeout = 30; $readLength = 998; $mxServer = getMXserver( $to ); if ( empty ( $mxServer )) { return false; } // Prepare email headers - origination date field and the originator address // field(s) are mandatory. $headers = "Date:" . date( 'r' ) . "\r\n"; $headers .= "From:$namefrom <$from>\r\n"; $headers .= "Sender:$namefrom <$from>\r\n"; // transmitter (Sender) not required if same as author (From) $headers .= "Reply-To:$namefrom <$from>\r\n"; // Optional recommended headers $headers .= "To:$nameto <$to>\r\n"; $headers .= "Message-ID:". getSessionID() . "\r\n"; $headers .= "Subject:$subject\r\n"; // Connect to SMTP server on SMTP port $smtpServer = fsockopen( $mxServer, $SMTP_PORT, $errno, $errstr, $timeout); if ( !$smtpServer ) return false; $smtpReply = fgets( $smtpServer, $readLength ); // Client initiation fputs( $smtpServer, "EHLO $SMTP_DOMAIN\r\n" ); $smtpReply = fgets( $smtpServer, $readLength ); // Mail transactions fputs( $smtpServer, "MAIL FROM: <$from>\r\n" ); $smtpReply = fgets( $smtpServer, $readLength ); // Success = {250}, Failure ={550, 553} fputs( $smtpServer, "RCPT TO:<$to>\r\n" ); $smtpReply = fgets( $smtpServer, $readLength ); // Success = {250}, Failure ={550, 503} fputs( $smtpServer, "DATA \r\n" ); $smtpReply = fgets( $smtpServer, $readLength ); // Success = {354} fputs( $smtpServer, "$headers\n" ); $message = wordwrap( $message, 79 ); fputs( $smtpServer, "$message\r\n" ); fputs( $smtpServer, "\r\n.\r\n" ); $smtpReply = fgets( $smtpServer, $readLength ); // Success = {250}, Failure = {503, 554} // Terminate the connection fputs( $smtpServer, "QUIT\r\n" ); $smtpReply = fgets( $smtpServer, $readLength ); // Success = {221}, Failure = {421} return true; } /** * Sends an approval request email to the guestbook administrator * * @param email - the text value for the email field * @param url - the text value for the website field * @param name - the text value for the name field * @param comments - the text value for the comments field * @param privateemail - the checkbox value for the privateemail checkbox * @return boolean - true if email sent successfullyy else false */ function emailAdminApproval( $email, $url, $name, $comments, $privateemail ) { global $EMAILS_FROM, $EMAILS_FROM_NAME, $ADMIN_SUBJECT, $ADMIN_EMAIL_ADDRESS, $ADMIN_EMAIL_NAME, $ADMIN_APPROVE_LINK; $email_message = "\nDear $ADMIN_EMAIL_NAME,\n\nA guestbook entry has been made with the"; $email_message .= " following details:\n\nName:\t\t$name\n\nE-mail:\t$email\n\n"; $email_message .= "Website:\t$url\n\nComments:\n$comments\n\nIf you feel that the"; $email_message .= " entry is a legitimate one then please approve it by clicking the"; $email_message .= " link below.\n\n$ADMIN_APPROVE_LINK".getSessionID(); $email_message .= "\n\nSincerely\nThe Guestbook\n\n"; $email_message = wordwrap( $email_message ); return email( $EMAILS_FROM, $EMAILS_FROM_NAME, $ADMIN_EMAIL_ADDRESS, $ADMIN_EMAIL_NAME, $ADMIN_SUBJECT, $email_message ); } /** * Sends a confirmation request email to the submitted guest address * * @param email - the text value for the email field * @param url - the text value for the website field * @param name - the text value for the name field * @param comments - the text value for the comments field * @param privateemail - the checkbox value for the privateemail checkbox * @return boolean - true if email sent successfullyy else false */ function emailGuestConfirmation( $email, $url, $name, $comments, $privateemail ) { global $EMAILS_FROM, $EMAILS_FROM_NAME, $GUEST_SUBJECT, $GUEST_CONFIRM_LINK; $email_message = "\nDear $name,\n\nA guestbook entry has been made with the"; $email_message .= " following details:\n\nName:\t\t$name\n\nE-mail:\t$email\n\n"; $email_message .= "Website:\t$url\n\nComments:\n$comments\n\nIf you signed the"; $email_message .= " guestbook then please click on the link below to confirm the"; $email_message .= " entry, else please ignore this email\n\n$GUEST_CONFIRM_LINK"; $email_message .= getSessionID()."\n\nSincerely\nThe Guestbook\n\n"; $email_message = wordwrap( $email_message ); return email( $EMAILS_FROM, $EMAILS_FROM_NAME, $email, $name, $GUEST_SUBJECT, $email_message ); } /** * Generates the HTML code for the footer of the page. The main contents of the * page should have been dynamically generated already. * * @param void - no parameters are required * @return null - no values are returned */ function endPage() { print "
Copyright © Nishchal Kush, 2008. All Rights Reserved.
"; } /** * Checks if the supplied entry matches the session supplied. Returns true if the * supplied entry is for the supplied session, else returns false * * @param entry - text representing the guestbook entry to check * @param session - text representing the session ID to check against the * supplied entry * @returns boolean - true if the supplied guestbook entry is for the supplied * session, else false */ function entryForSession( $entry, $session ) { global $DELIMITER; $fields = explode( $DELIMITER, $entry ); if ( strcmp( $session, trim( $fields[9] )) == 0 ) { return true; } return false; } /** * Gets the MX record for the domain of the supplied email address. If a valid MX * record is not found then an empty string is returned * * @param email - text representing an email address * @returns string - text representing the MX record for the supplied email * address */ function getMXserver( $email ) { if ( empty( $email )) { return ""; } $addressParts = explode("@", $email); $domainName = $addressParts[1]; $winOS = strtoupper( substr( PHP_OS, 0, 3 )) === "WIN" ? true : false; if ( function_exists( "checkdnsrr" )) { if ( !checkdnsrr($domainName.".", "MX" )) { return ""; } else { $mxHosts = array(); if ( getmxrr( $domainName.".", $mxHosts )) { return $mxHosts[0]; } else { return ""; } } } else if ( $winOS ) { $nslookupResults = ""; $command = "nslookup -type=MX ".escapeshellcmd($domainName."."); exec($command, $nslookupResults); foreach ($nslookupResults as $nslookupLine ) { if( ereg( "^$domainName(.+)exchanger = (.+)$", $nslookupLine, $resultParts )) { return $resultParts[2]; } } return ""; } return ""; } /** * Retrieves the guestbook entry for the supplied session ID. Returns the * guestbook entry or an emty string if the entry for the supplied session * ID is not found * * @param session - text representing the session ID to search for * @returns string - text representing the guestbook entry or an empty string */ function getEntry( $session ) { global $GUESTBOOK; if ( empty( $session )) { return ""; } $entries = file( $GUESTBOOK ); foreach( $entries as $entry ) { if ( entryForSession( $entry, $session )) { return $entry; } } return ""; } /** * Returns the session ID for the guest, If not valid session ID are found then * a new session ID is generated and returned. The session ID is generated as an * MD5 hash based on the time, the client address and the client name * * @param void - no parameters are required * @return string - text representing the session ID for the guest */ function getSessionID() { if ( isset($_REQUEST['session']) ) { return trim($_REQUEST['session']); } if ( isset($_REQUEST['confirmID']) ) { return trim($_REQUEST['confirmID']); } if ( isset($_REQUEST['approveID']) ) { return trim($_REQUEST['approveID']); } return md5( uniqid( microtime()) . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']); } /** * Onsfuscates the email address supplied by replacing the '@' character with * ' (at) ' and the '.' symbol with ' (dot) '. It does not provide any real * obfuscation, but is intended only to make email address harvesting a little * annoying. * * @param email - text representing the email address to obfuscate * @returns string - text representing the obfuscated email address or an * empty string if a blank email address is supplied */ function obsfuscateEmail( $email ) { global $SYMBOL_AT, $SYMBOL_DOT; if ( empty( $email )) { return ""; } $email = str_replace('@', $SYMBOL_AT, $email); $email = str_replace('.', $SYMBOL_DOT, $email); return $email; } /** * Process the submitted HTML form. Parses the supplied form values and validates * some data and if valid then commits to the guestbook.A * * @param void - no parameters are required * @return null - no values are returned */ function processForm() { global $HTML_NEWLINE, $INVALID_EMAIL_ADDRESS, $TEXT_CARRIAGE_RETURN, $TEXT_NEWLINE; // Get form values $name = isset($_REQUEST['name']) ? trim($_REQUEST['name']) : ""; $email = isset($_REQUEST['email']) ? trim($_REQUEST['email']) : ""; $privateemail = isset($_REQUEST['privateemail']) ? trim($_REQUEST['privateemail']) : ""; $url = isset($_REQUEST['url']) ? trim($_REQUEST['url']) : ""; $comments = isset($_REQUEST['comments']) ? trim($_REQUEST['comments']) : ""; $session = getSessionID(); if ( $privateemail === "checked" ) { $privateemail_val = 1; } else { $privateemail_val = 0; $privateemail = "unchecked"; } // Format the text area value $comments = str_replace( $TEXT_CARRIAGE_RETURN, "", $comments ); $comments = str_replace( $TEXT_NEWLINE, $HTML_NEWLINE, $comments ); // Validate date and display page $errors = ""; if ( !validEmail($email)) { $errors .= $INVALID_EMAIL_ADDRESS . $HTML_NEWLINE; } startPage(); if ( $errors === "" ) { if ( emailGuestConfirmation( $email, $url, $name, $comments, $privateemail_val )) { writeGuestbook($email, $url, $name, $comments, $privateemail_val, $session ); displaySignAcknowledge(); } else { displayEmailConfirmationFailure(); } displayViewOption(); } else { displayViewOption(); displayForm( $name, $email, $privateemail, $url, $comments, $errors, $session ); } endPage(); } /** * Saves the guestbook entry to the guestbook flatfile by appending to the end of the file * * @param email - the text value for the email field * @param url - the text value for the website field * @param name - the text value for the name field * @param comments - the text value for the comments field * @param privateemail - the checkbox value for the privateemail checkbox * @param session - the text value for the visitor session * @return null - no values are returned */ function writeGuestbook( $email, $url, $name, $comments, $privateemail, $session ) { global $DELIMITER, $GUESTBOOK, $GUESTBOOK_NOT_WRITEABLE; $ip = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; $date = date("r"); $data = $date . $DELIMITER . $email . $DELIMITER . $url . $DELIMITER . $name . $DELIMITER . $comments . $DELIMITER; $data .= $privateemail . $DELIMITER . "0" . $DELIMITER . $ip . $DELIMITER . "0" . $DELIMITER . $session . "\n"; if (is_writable( $GUESTBOOK )) { $filehandle = fopen( $GUESTBOOK, 'a+' ); if (fwrite($filehandle, $data) === FALSE) { printf("

%s

\n", $GUESTBOOK_WRITE_FAILED); } else { printf("

%s

\n", $GUESTBOOK_ENTRY_CONFIRMED); } fclose($filehandle); } else { printf("

%s

\n", $GUESTBOOK_NOT_WRITEABLE); } } /** * Generates the HTML code for the header of the page. The main contents of the * page can be generated dynamically one this is done. * * @param void - no parameters are required * @return null - no values are returned */ function startPage() { print " www.kush.com.fj - the indian IT guy
 
 
 
 
 

guests

guestbook

"; } /** * Performs email address validation. Checks the format of the email address * and attempts to connect to the POP (port 25) of the MX server specified * for the domain supplied. If successful then performs and RBL list check * for the MX server. * * @param email - text representing the email address * @returns boolean - true if a vlid email address else false */ function validEmail( $email ) { return validEmailFormat( $email ) && validEmailServer( $email ); } /** * Checks the format of the email address supplied. The check is performed somewhat un-pragmaticaly again * RFC 2822 (http://tools.ietf.org/html/rfc2822) and RFC 2821 (http://tools.ietf.org/html/rfc2822). * * @param email - text representing the email address * @returns boolean - true if a valid email address format else false */ function validEmailFormat( $email ) { if ( empty( $email )) { return false; } if ( !ereg( "^[^@]{1,64}@[^@]{1,255}$", $email)) { return false; } else { $addressParts = explode("@", $email); $usernameParts = explode(".", $addressParts[0]); for ( $i = 0; $i < sizeof( $usernameParts ); $i++ ) { if ( !ereg( "^([A-Za-z0-9!#$%&'*+/=?^_`{|}~-]{1,64})$", $usernameParts[$i] )) { return false; } } $domainParts = explode( ".", $addressParts[1]); if ( sizeof( $domainParts ) < 2) { return false; } else { for ( $i = 0; $i < sizeof( $domainParts ); $i++ ) { if ( !ereg( "^([A-Za-z0-9!#$%&'*+/=?^_`{|}~-]{1,255})$", $domainParts[$i] )) { return false; } } return true; } } return false; } /** * Checks the MX record for the email address and attempts connection on port * 25. If successful then checks the MX server against RBL listings * * @param email - text representing the email address * @returns boolean - true if a valid email address server host else false */ function validEmailServer( $email ) { if ( empty( $email )) { return false; } $mxServer = getMXserver( $email ); if ( empty( $mxServer )) { return false; } else { if ( fsockopen( $mxServer, 25, $errno, $errstr, 30 )) { return validEmailServerRBL( $email ); } else { return false; } } return false; } /** * Checks the RBL lists for the MX server of the email address supplied. * * @param email - text representing the email address * @returns boolean - true if a email address server host not in RBL host * else false */ function validEmailServerRBL( $email ) { if ( empty( $email )) { return false; } $mxServer = getMXserver( $email ); if ( empty( $mxServer )) { return false; } else { $mxIP = gethostbyname( $mxServer ); $revMXip = array_reverse( explode('.', $mxIP )); foreach( $BLACKLISTS as $blacklist ) { $lookupMXip = implode( '.', $revMXip ).'.'.$blacklist; if ( $lookupMXip != gethostbyname( $lookupMXip )) { return false; } } } return true; } /** * Main script entry point */ $guestbook_action = isset($_REQUEST['do']) ? trim($_REQUEST['do']) : ""; switch ( $guestbook_action ) { case "approve": startPage(); approveGuestEntry(); displayViewOption(); endPage(); break; case "confirm": startPage(); confirmGuestEntry(); displayViewOption(); endPage(); break; case "view": startPage(); displaySignOption(); displayEntries(); endPage(); break; case "sign": startPage(); displayViewOption(); displayForm(); endPage(); break; case "Submit": processForm(); break; case "": default: startPage(); displayViewOption(); displaySignOption(); endPage(); break; } ?>