squirrelmail/0000755000175000017500000000000011737431050012614 5ustar thijsthijssquirrelmail/plugins/0000755000175000017500000000000011737431042014276 5ustar thijsthijssquirrelmail/plugins/info/0000755000175000017500000000000011737431041015230 5ustar thijsthijssquirrelmail/plugins/info/setup.php0000644000175000017500000000166711700173711017110 0ustar thijsthijs _("IMAP server information"), 'url' => '../plugins/info/options.php', 'desc' => _("Run some test IMAP commands, displaying both the command and the result. These tests use the SquirrelMail IMAP commands and your current SquirrelMail configuration. Custom command strings can be used."), 'js' => false ); } ?>squirrelmail/plugins/info/index.php0000644000175000017500000000075711700173711017056 0ustar thijsthijssquirrelmail/plugins/info/README0000644000175000017500000000314010645123115016103 0ustar thijsthijsREADME for the info plugin for SquirrelMail This plugin is designed to aid a system admin or SquirrelMail developer troubleshoot IMAP commands and responses. IMPORTANT NOTE: ***************************************************** * THIS PLUGIN IS NOT MEANT FOR END USERS. IT ALLOWS * * UNVALIDATED DATA TO BE PASSED TO THE IMAP SERVER. * * IT IS BY NO MEANS SECURE AND SHOULD ONLY BE USED * * FOR TESTING, TROUBLESHOOTING AND DEVELOPMENT. * ***************************************************** You have been warned :) Ok, now to the good stuff. Enable this plugin as you would any other. Its called 'info'. You will then have an "IMAP server information" section on your options page. This will take you to an IMAP command workshop where you can select pre-made commands, send them to the IMAP server and see the response. All selected commands will be run one at a time starting with the first selected command and working down. Commands can be modified however you like, but remember, you are performing these commands on the account you are logged into, so any command that changes the contents of your mailbox will ..er.. change the contents of your mailbox :) Changes and custom commands are maintained as long as you are on the IMAP server options page (even after submitting tests). Once you leave this page and return then the commmands are reset to the defaults. You can manually reset the commands using the 'default' button, or clear the contents of all the commands with the 'clear' button. This plugin has been originally developed by Jason Munro and is now maintained by the SquirrelMail Project Team. squirrelmail/plugins/info/functions.php0000644000175000017500000000345011700173711017750 0ustar thijsthijs".htmlspecialchars($query).""; fputs ($imap_stream, $query); $response = sqimap_read_data_list($imap_stream, $sid, false, $responses, $message); array_push($response, $message); return $response; } function print_response($response) { foreach($response as $index=>$value) { if (is_array($value)) { print_response($value); } else { print htmlspecialchars($value)."
\n"; } } } /** * Check if plugin is enabled * @param string $plugin_name plugin name * @return boolean */ function info_is_plugin_enabled($plugin_name) { global $plugins; if (empty($plugins) || ! is_array($plugins)) return false; if ( in_array($plugin_name,$plugins) ) { return true; } else { return false; } } squirrelmail/plugins/info/options.php0000644000175000017500000001352311700173711017435 0ustar thijsthijs'. _("Plugin is disabled."). '

'; exit; } /* GLOBALS */ sqgetGlobalVar('username', $username, SQ_SESSION); sqgetGlobalVar('key', $key, SQ_COOKIE); sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION); sqgetGlobalVar('submit', $submit, SQ_POST); for($i = 0; $i <= 9; $i++){ $varc = 'CHECK_TEST_'.$i; sqgetGlobalVar($varc, $$varc, SQ_POST); $vart = 'TEST_'.$i; sqgetGlobalVar($vart, $$vart, SQ_POST); } /* END GLOBALS */ $imap_stream = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0); $caps_array = get_caps($imap_stream); $list = array ( 'TEST_0', 'TEST_1', 'TEST_2', 'TEST_3', 'TEST_4', 'TEST_5', 'TEST_6', 'TEST_7', 'TEST_8', 'TEST_9'); print "
IMAP server information

\n"; print "

\n"; print "
\n"; print "
Server Capability response:
\n"; foreach($caps_array[0] as $value) { print htmlspecialchars($value); } print "
\n"; if (!isset($submit) || $submit == 'default') { print "
Select the IMAP commands you would like to run. Most commands require a selected mailbox so the SELECT-command is already setup. You can clear all the commands and test your own IMAP command strings. The commands are executed in order. The default values are simple IMAP commands using your default_charset and folder_prefix from SquirrelMail when needed.

NOTE: These commands are live, any changes made will effect your current email account.

\n"; if (!isset($submit)) { $submit = ''; } } else { print 'folder_prefix = ' . htmlspecialchars($folder_prefix) . "
\n". 'default_charset = ' . htmlspecialchars($default_charset) . "\n"; } print "

\n"; if ($submit == 'submit') { $type = array(); for ($i=0;$i "SELECT $mailbox", 'TEST_1' => "STATUS $mailbox (MESSAGES RECENT)", 'TEST_2' => "EXAMINE $mailbox", 'TEST_3' => "SEARCH CHARSET \"$default_charset\" ALL *", 'TEST_4' => "THREAD REFERENCES $default_charset ALL", 'TEST_5' => "SORT (DATE) $default_charset ALL", 'TEST_6' => "FETCH 1:* (FLAGS BODY[HEADER.FIELDS (FROM DATE TO)])", 'TEST_7' => "LSUB \"$folder_prefix\" \"*%\"", 'TEST_8' => "LIST \"$folder_prefix*\" \"*\"", 'TEST_9' => ""); } print "
\n"; print "
\n"; print "\n"; print "
SelectTest NameIMAP command string
\n"; foreach($type as $index=>$value) { print "
$index\n"; print addInput($index, $value, 60); } print "

\n"; print "
". addSubmit('submit','submit'). addSubmit('clear','submit'). addSubmit('default','submit'). "

\n"; $tests = array(); if ($submit == 'submit') { foreach ($type as $index=>$value) { $check = "CHECK_".$index; if (isset($$check)) { $type[$index] = $$index; array_push($tests, $index); } } for ($i=0;$i\n"; print ""; print "\n"; $response = imap_test($imap_stream, $type[$tests[$i]]); print "\n"; print "
".$tests[$i]."
". "Request:
". "Response:
"; print_response($response); print "

\n"; } } print "
"; sqimap_logout($imap_stream); do_hook('info_bottom'); ?> squirrelmail/plugins/README.plugins0000644000175000017500000000222011041300312016611 0ustar thijsthijsPlugins ======= To understand more about plugins, read: http://squirrelmail.org/docs/admin/admin-7.html#ss7.1 http://squirrelmail.org/docs/devel/devel-4.html For the impatient, here is an extremely brief overview of how to install plugins. 1. Change to the plugins directory. $ cd plugins/ 2. Unarchive the plugin. $ tar -zxvf /home/me/myplugin.tar.gz 3. Note the directory that the plugin was created into. For this example, we will assume it was put in the directory: myplugin/. 4. Read the README, INSTALL or other documentation in your new plugin. Follow any important configuration instructions inside (about half the time there are none, sometimes they are extensive). $ cd myplugin/ $ more README 5. Go to the config directory and run conf.pl $ cd ../../config/ $ ./conf.pl 6. Choose option 8 and proceed to add the new plugin following the instructions there (move the desired plugin from the "Available Plugins" category to the "Installed Plugins" category by entering its number). Save and exit, and your plugin should be in place. squirrelmail/plugins/mail_fetch/0000755000175000017500000000000011737431041016370 5ustar thijsthijssquirrelmail/plugins/mail_fetch/setup.php0000644000175000017500000002514111700173711020241 0ustar thijsthijs '' && // Empty passwords no allowed ( ( $mailfetch_login_[$i_loop] == 'on' && $mailfetch_newlog == 'on' ) || $mailfetch_fref_[$i_loop] == 'on' ) ) { $mailfetch_server_[$i_loop] = getPref($data_dir, $username, "mailfetch_server_$i_loop"); $mailfetch_port_[$i_loop] = getPref($data_dir, $username , "mailfetch_port_$i_loop"); $mailfetch_alias_[$i_loop] = getPref($data_dir, $username, "mailfetch_alias_$i_loop"); $mailfetch_user_[$i_loop] = getPref($data_dir, $username, "mailfetch_user_$i_loop"); $mailfetch_lmos_[$i_loop] = getPref($data_dir, $username, "mailfetch_lmos_$i_loop"); $mailfetch_uidl_[$i_loop] = getPref($data_dir, $username, "mailfetch_uidl_$i_loop"); $mailfetch_subfolder_[$i_loop] = getPref($data_dir, $username, "mailfetch_subfolder_$i_loop"); $mailfetch_server=$mailfetch_server_[$i_loop]; $mailfetch_port=$mailfetch_port_[$i_loop]; $mailfetch_user=$mailfetch_user_[$i_loop]; $mailfetch_alias=$mailfetch_alias_[$i_loop]; $mailfetch_pass=$mailfetch_pass_[$i_loop]; $mailfetch_lmos=$mailfetch_lmos_[$i_loop]; $mailfetch_login=$mailfetch_login_[$i_loop]; $mailfetch_uidl=$mailfetch_uidl_[$i_loop]; $mailfetch_subfolder=$mailfetch_subfolder_[$i_loop]; // $outMsg .= "$mailfetch_alias checked
"; // $outMsg .= "$mailfetch_alias_[$i_loop]
"; $pop3 = new POP3($mailfetch_server, 60); if (!$pop3->connect($mailfetch_server,$mailfetch_port)) { $outMsg .= _("Warning, ") . $pop3->ERROR; continue; } $imap_stream = sqimap_login($username, $key, $imapServerAddress, $imapPort, 10); $Count = $pop3->login($mailfetch_user, $mailfetch_pass); if (($Count == false || $Count == -1) && $pop3->ERROR != '') { $outMsg .= _("Login Failed:") . $pop3->ERROR; continue; } // register_shutdown_function($pop3->quit()); $msglist = $pop3->uidl(); $i = 1; for ($j = 1; $j < sizeof($msglist); $j++) { if ($msglist["$j"] == $mailfetch_uidl) { $i = $j+1; break; } } if ($Count < $i) { $pop3->quit(); continue; } if ($Count == 0) { $pop3->quit(); continue; } else { $newmsgcount = $Count - $i + 1; } // Faster to get them all at once $mailfetch_uidl = $pop3->uidl(); if (! is_array($mailfetch_uidl) && $mailfetch_lmos == 'on') $outMsg .= _("Server does not support UIDL."); for (; $i <= $Count; $i++) { if (!ini_get('safe_mode')) set_time_limit(20); // 20 seconds per message max $Message = ""; $MessArray = $pop3->get($i); if ( (!$MessArray) or (gettype($MessArray) != "array")) { $outMsg .= _("Warning, ") . $pop3->ERROR; continue 2; } while (list($lineNum, $line) = each ($MessArray)) { $Message .= $line; } /** * check if mail folder is not null and subscribed * Function can check if mail folder is only unsubscribed * and use unsubscribed mail folder. */ if ($mailfetch_subfolder=='' || ! mail_fetch_check_folder($imap_stream,$mailfetch_subfolder)) { fputs($imap_stream, "A3$i APPEND INBOX {" . strlen($Message) . "}\r\n"); } else { fputs($imap_stream, "A3$i APPEND $mailfetch_subfolder {" . strlen($Message) . "}\r\n"); } $Line = fgets($imap_stream, 1024); if (substr($Line, 0, 1) == '+') { fputs($imap_stream, $Message); fputs($imap_stream, "\r\n"); sqimap_read_data($imap_stream, "A3$i", false, $response, $message); if ($mailfetch_lmos != 'on') { $pop3->delete($i); } } else { echo "$Line"; $outMsg .= _("Error Appending Message!"); } } $pop3->quit(); sqimap_logout($imap_stream); if (is_array($mailfetch_uidl)) { setPref($data_dir,$username,"mailfetch_uidl_$i_loop", array_pop($mailfetch_uidl)); } } } if( trim( $outMsg ) <> '' ) { echo '
' . _("Mail Fetch Result:") . "
$outMsg
"; } if( $mailfetch_newlog == 'on' ) { setPref($data_dir, $username, 'mailfetch_newlog', 'off'); } } function mail_fetch_setnew() { global $data_dir; require_once(SM_PATH . 'functions/prefs.php'); sqgetGlobalVar('username', $username, SQ_SESSION); setPref( $data_dir, $username, 'mailfetch_newlog', 'on' ); } function mailfetch_optpage_register_block() { global $optpage_blocks; $optpage_blocks[] = array( 'name' => _("POP3 Fetch Mail"), 'url' => '../plugins/mail_fetch/options.php', 'desc' => _("This configures settings for downloading email from a POP3 mailbox to your account on this server."), 'js' => false ); } function mail_fetch_folderact($args) { global $username, $data_dir; if (empty($args) || !is_array($args)) { return; } /* Should be 3 ars, 1: old folder, 2: action, 3: new folder */ if (count($args) != 3) { return; } list($old_folder, $action, $new_folder) = $args; $mailfetch_server_number = getPref($data_dir, $username, 'mailfetch_server_number'); for ($i = 0; $i < $mailfetch_server_number; $i++) { $mailfetch_subfolder = getPref($data_dir, $username, 'mailfetch_subfolder_' . $i); if ($mailfetch_subfolder != $old_folder) { continue; } if ($action == 'delete') { setPref($data_dir, $username, 'mailfetch_subfolder_' . $i, 'INBOX'); } elseif ($action == 'rename') { setPref($data_dir, $username, 'mailfetch_subfolder_' . $i, $new_folder); } } } squirrelmail/plugins/mail_fetch/index.php0000644000175000017500000000076211700173711020212 0ustar thijsthijs
'; echo html_tag( 'table', html_tag( 'tr', html_tag( 'td', '' . _("Remote POP server Fetching Mail") . '', 'center', $color[0] ) ) , 'center', '', 'width="95%" cols="1"' ); // get $server_to_fetch from globals, if not set display a choice to the user if (! sqgetGlobalVar('server_to_fetch', $server_to_fetch, SQ_POST) ) { echo '
' . "
" . html_tag( 'table', '', 'center', '', 'width="70%" cols="2"' ) . html_tag( 'tr' ) . html_tag( 'td', _("Select Server:") . '    ', 'right' ) . html_tag( 'td', '', 'left' ) . '' . '' . ''; //if password not set, ask for it for ($i=0;$i<$mailfetch_server_number;$i++) { if ($mailfetch_pass_[$i]=='') { echo html_tag( 'tr', html_tag( 'td', _("Password for") . ' ' . htmlspecialchars((($mailfetch_alias_[$i]=='')?$mailfetch_server_[$i]:$mailfetch_alias_[$i])) . ':     ', 'right' ) . html_tag( 'td', '', 'left' ) ); } } echo html_tag( 'tr', html_tag( 'td', ' ' ) . html_tag( 'td', '', 'left' ) ) . '
'; exit(); } if ( $server_to_fetch == 'all' ) { $i_start = 0; $i_stop = $mailfetch_server_number; } else { $i_start = $server_to_fetch; $i_stop = $i_start+1; } for ($i_loop=$i_start;$i_loop<$i_stop;$i_loop++) { $mailfetch_server=$mailfetch_server_[$i_loop]; $mailfetch_port=$mailfetch_port_[$i_loop]; $mailfetch_user=$mailfetch_user_[$i_loop]; if ($mailfetch_pass_[$i_loop] == '') { sqgetGlobalVar("pass_$i_loop", $mailfetch_pass, SQ_POST); } else { $mailfetch_pass = $mailfetch_pass_[$i_loop]; } $mailfetch_lmos=$mailfetch_lmos_[$i_loop]; $mailfetch_login=$mailfetch_login_[$i_loop]; $mailfetch_uidl=$mailfetch_uidl_[$i_loop]; $mailfetch_subfolder=$mailfetch_subfolder_[$i_loop]; $pop3 = new POP3($mailfetch_server, 60); echo '
' . html_tag( 'table', html_tag( 'tr', html_tag( 'td', '' . _("Fetching from ") . htmlspecialchars((($mailfetch_alias_[$i_loop] == '')?$mailfetch_server:$mailfetch_alias_[$i_loop])) . '', 'center' ) , '', $color[9] ) , '', '', 'width="90%"' ); flush(); if (!$pop3->connect($mailfetch_server,$mailfetch_port)) { Mail_Fetch_Status(_("Oops, ") . $pop3->ERROR ); continue; } Mail_Fetch_Status(_("Opening IMAP server")); $imap_stream = sqimap_login($username, $key, $imapServerAddress, $imapPort, 10); // check if destination folder is not set, is not subscribed and is not \noselect folder if($mailfetch_subfolder == '' || ! mail_fetch_check_folder($imap_stream,$mailfetch_subfolder)) { $mailfetch_subfolder = 'INBOX'; } Mail_Fetch_Status(_("Opening POP server")); $Count = $pop3->login($mailfetch_user, $mailfetch_pass); if (($Count == false || $Count == -1) && $pop3->ERROR != '') { Mail_Fetch_Status(_("Login Failed:") . ' ' . $pop3->ERROR ); continue; } // register_shutdown_function($pop3->quit()); $msglist = $pop3->uidl(); $i = 1; for ($j = 1; $j < sizeof($msglist); $j++) { if ($msglist["$j"] == $mailfetch_uidl) { $i = $j+1; break; } } if ($Count < $i) { Mail_Fetch_Status(_("Login OK: No new messages")); $pop3->quit(); continue; } if ($Count == 0) { Mail_Fetch_Status(_("Login OK: Inbox EMPTY")); $pop3->quit(); continue; } else { $newmsgcount = $Count - $i + 1; Mail_Fetch_Status(sprintf(_("Login OK: Inbox contains %s messages"), $newmsgcount)); } Mail_Fetch_Status(_("Fetching UIDL...")); // Faster to get them all at once $mailfetch_uidl = $pop3->uidl(); if (! is_array($mailfetch_uidl) && $mailfetch_lmos == 'on') Mail_Fetch_Status(_("Server does not support UIDL.")); if ($mailfetch_lmos == 'on') { Mail_Fetch_Status(_("Leaving messages on server...")); } else { Mail_Fetch_Status(_("Deleting messages from server...")); } for (; $i <= $Count; $i++) { Mail_Fetch_Status(_("Fetching message ") . "$i" ); if (!ini_get('safe_mode')) set_time_limit(20); // 20 seconds per message max $Message = ""; $MessArray = $pop3->get($i); while ( (!$MessArray) or (gettype($MessArray) != "array")) { Mail_Fetch_Status(_("Oops, ") . $pop3->ERROR); // re-connect pop3 Mail_Fetch_Status(_("Server error. Disconnect")); $pop3->quit(); Mail_Fetch_Status(_("Reconnect from dead connection")); if (!$pop3->connect($mailfetch_server)) { Mail_Fetch_Status(_("Oops, ") . $pop3->ERROR ); Mail_Fetch_Status(_("Saving UIDL")); setPref($data_dir,$username,"mailfetch_uidl_$i_loop", $mailfetch_uidl[$i-1]); continue; } $Count = $pop3->login($mailfetch_user, $mailfetch_pass); if (($Count == false || $Count == -1) && $pop3->ERROR != '') { Mail_Fetch_Status(_("Login Failed:") . ' ' . htmlspecialchars($pop3->ERROR) ); Mail_Fetch_Status(_("Saving UIDL")); setPref($data_dir,$username,"mailfetch_uidl_$i_loop", $mailfetch_uidl[$i-1]); continue; } Mail_Fetch_Status(_("Refetching message ") . "$i" ); $MessArray = $pop3->get($i); } // end while while (list($lineNum, $line) = each ($MessArray)) { $Message .= $line; } fputs($imap_stream, "A3$i APPEND \"$mailfetch_subfolder\" {" . strlen($Message) . "}\r\n"); $Line = fgets($imap_stream, 1024); if (substr($Line, 0, 1) == '+') { fputs($imap_stream, $Message); fputs($imap_stream, "\r\n"); sqimap_read_data($imap_stream, "A3$i", false, $response, $message); if ( $response <> 'OK' ) { Mail_Fetch_Status(_("Error Appending Message!")." ".$message ); Mail_Fetch_Status(_("Closing POP")); $pop3->quit(); Mail_Fetch_Status(_("Logging out from IMAP")); sqimap_logout($imap_stream); Mail_Fetch_Status(_("Saving UIDL")); setPref($data_dir,$username,"mailfetch_uidl_$i_loop", $mailfetch_uidl[$i-1]); exit; } else { Mail_Fetch_Status(_("Message appended to mailbox")); } if ($mailfetch_lmos != 'on') { if( $pop3->delete($i) ) { Mail_Fetch_Status(sprintf(_("Message %d deleted from remote server!"), $i)); } else { Mail_Fetch_Status(_("Delete failed:") . htmlspecialchars($pop3->ERROR) ); } } } else { echo "$Line"; Mail_Fetch_Status(_("Error Appending Message!")); Mail_Fetch_Status(_("Closing POP")); $pop3->quit(); Mail_Fetch_Status(_("Logging out from IMAP")); sqimap_logout($imap_stream); // not gurantee corect! Mail_Fetch_Status(_("Saving UIDL")); setPref($data_dir,$username,"mailfetch_uidl_$i_loop", $mailfetch_uidl[$i-1]); exit; } } Mail_Fetch_Status(_("Closing POP")); $pop3->quit(); Mail_Fetch_Status(_("Logging out from IMAP")); sqimap_logout($imap_stream); if (is_array($mailfetch_uidl)) { Mail_Fetch_Status(_("Saving UIDL")); setPref($data_dir,$username,"mailfetch_uidl_$i_loop", array_pop($mailfetch_uidl)); } Mail_Fetch_Status(_("Done")); } ?>
squirrelmail/plugins/mail_fetch/README0000644000175000017500000001225511407611203017247 0ustar thijsthijsMail Fetch Downloads mail from a pop3 server to your SquirrelMail account. Features ======== * Copies messages from remote server * Saves server, alias, username, and password in prefs file... * Remembers where to resume downloading messages if your pop server supports UIDL. * Optionally deletes mail from the remote server. * Allow an infinite amount of remote servers * Optional to not save password - prompt on check * Save messages into a local IMAP folder instead of INBOX * Check mail during login (Needs SM 1.1.3 or older). * Check mail during folder refreshes. * Allows gettext translations. Description =========== Feel like grabbing your messages from a different mail server into SquirrelMail? This might be able to help. Configuration ============= Under the options you can add, delete or modify server list where fetching mail. For each server you can set also username and password; if you leave password blank, the password whore required when you fetch mail. Make sure "Leave Mail On Server" is checked if you do not want Mail_Fetch to delete it from the remote server. Once configured, click 'Fetch' in the SquirrelMail menu to get your mail; you can fetch mail from all server instead or from only one by selecting the options dispayed. If you want to check mail periodicaly choose "Check mail during login" or "Check mail during folder refresh". Of course passwords have to be entered in order for this to work. In order to secure a little bit the system, pop3 passwords can be encrypted. The encryption key may be defined in to places. The first, and more secure, is in the httpd configuration as an enviromental variable called MF_TIT only accesible from the SquirrelMail directory. the way you can do this from apache is adding the following directives to httpd.conf (supposing that SquirrelMail is located at /usr/local) or an included configuration file: SetEnv MF_TIT "MailFetch Secure for SquirrelMail 1.x" Of course, you should replace the text inside double quotes with the key you want to (some kind of secret text). A please remember that the file where you decided to place this must be root only readable. The second way is to edit functions.php and look for: if( !isset( $MF_TIT ) ) { $MF_TIT = "MailFetch Secure for SquirrelMail 1.x"; } Once again change the text "MailFetch Secure for SquirrelMail 1.x" with a secret text. Please note that you must redefine passwords each time you change the key. To maintain compatibilty with older systems, mail_fetch can work with old pref files, with no encrypted passwords. If this occurs, you'll see that the "Encrypt Password" checkbox in the option page is not checked. If you reenter account's passwords the system will switch to encrypted mode. Security ======== By default, the user is not allowed to enter a non-standard POP3 port number when configuring an external server with this plugin. This prevents the use of this plugin as a port scanner against other servers. However, if you need to allow users to access a POP3 service running on a non- standard port, you may create a "config.php" file by copying "config_example.php" and editing the list of allowable port numbers therein. If "ALL" is added to the list of allowable port numbers, then there will be no restriction on port numbers whatsoever. Be aware that although this may not represent any security threat to servers elsewhere on the Internet that does not already exist (other port scanners are freely available), if your server resides on a network behind a firewall, this could allow a malicious user to scan the servers and services behind your firewall that they'd normally not have access to. The user will also not be allowed to enter server addresses starting with "10.", "192.", "127." and "localhost" by default. This prevents users from being able to scan an internal network for the presence of other servers they are not allowed to access. If other server addresses should be banned, or this list is too restrictive, you may create a "config.php" file by copying "config_example.php" and then edit the list of blocked server addresses therein. Future Work =========== * Add IMAP server stealing * Limit number of pop accounts Installation ============ Go back to the main directory, run configure and add the plugin. Some plugin settings can be adjusted in config/mail_fetch_config.php or plugins/mail_fetch/config.php files. See plugins/mail_fetch/config_sample.php Note for mod_gzip users ======================= As fetching module shows information while fetching is taking place, it is a good idea to disable compression for that operation. The way to do this with mod_gzip is: mod_gzip_item_exclude file fetch.php Note for Newmail Plugin users ============================= In order to Newmail plugin detect new mails during folder refreshes make sure that Mail_Fetch is listed first that Newmail in the SM configuration. To do so you only have to remove Newmail plugin and then add it again. Credits ======= This plugin has been originally created by Tyler Akins, with contributions from Philippe Mingo, Tomaso Minelli and Joshua Pollak. It's now maintained by the SquirrelMail Project Team. squirrelmail/plugins/mail_fetch/functions.php0000644000175000017500000001324111714462746021125 0ustar thijsthijs * and josh@superfork.com (extracted from PHP manual) * Adapted for MailFetch by Philippe Mingo * * @copyright 1999-2012 The SquirrelMail Project Team * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @version $Id: functions.php 14276 2012-02-08 12:09:10Z kink $ * @package plugins * @subpackage mail_fetch */ /** declare plugin globals */ global $mail_fetch_allow_unsubscribed; /** * Controls use of unsubscribed folders in plugin * @global boolean $mail_fetch_allow_unsubscribed * @since 1.5.1 and 1.4.5 */ $mail_fetch_allow_unsubscribed = false; /** * Validate a requested POP3 port number * * Allowable port numbers are configured in config.php * (see config_example.php for an example and more * rules about how the list of allowable port numbers * can be specified) * * @param int $requested_port The port number given by the user * * @return string An error string is returned if the port * number is not allowable, otherwise an * empty string is returned. * */ function validate_mail_fetch_port_number($requested_port) { global $mail_fetch_allowable_ports; @include_once(SM_PATH . 'plugins/mail_fetch/config.php'); if (empty($mail_fetch_allowable_ports)) $mail_fetch_allowable_ports = array(110, 995); if (in_array('ALL', $mail_fetch_allowable_ports)) return ''; if (!in_array($requested_port, $mail_fetch_allowable_ports)) { sq_change_text_domain('mail_fetch'); $error = _("Sorry, that port number is not allowed"); sq_change_text_domain('squirrelmail'); return $error; } return ''; } /** * Validate a requested POP3 server address * * Blocked server addresses are configured in config.php * (see config_example.php for more details) * * @param int $requested_address The server address given by the user * * @return string An error string is returned if the server * address is not allowable, otherwise an * empty string is returned. * */ function validate_mail_fetch_server_address($requested_address) { global $mail_fetch_block_server_pattern; @include_once(SM_PATH . 'plugins/mail_fetch/config.php'); if (empty($mail_fetch_block_server_pattern)) $mail_fetch_block_server_pattern = '/(^10\.)|(^192\.)|(^127\.)|(^localhost)/'; if ($mail_fetch_block_server_pattern == 'UNRESTRICTED') return ''; if (preg_match($mail_fetch_block_server_pattern, $requested_address)) { sq_change_text_domain('mail_fetch'); $error = _("Sorry, that server address is not allowed"); sq_change_text_domain('squirrelmail'); return $error; } return ''; } /** * hex2bin() only exists since PHP 5.4 */ if ( ! function_exists('hex2bin') ) { function hex2bin( $data ) { /* Original code by josh@superfork.com */ $len = strlen($data); $newdata = ''; for( $i=0; $i < $len; $i += 2 ) { $newdata .= pack( "C", hexdec( substr( $data, $i, 2) ) ); } return $newdata; } } function mf_keyED( $txt ) { global $MF_TIT; if( !isset( $MF_TIT ) ) { $MF_TIT = "MailFetch Secure for SquirrelMail 1.x"; } $encrypt_key = md5( $MF_TIT ); $ctr = 0; $tmp = ""; for( $i = 0; $i < strlen( $txt ); $i++ ) { if( $ctr == strlen( $encrypt_key ) ) $ctr=0; $tmp.= substr( $txt, $i, 1 ) ^ substr( $encrypt_key, $ctr, 1 ); $ctr++; } return $tmp; } function encrypt( $txt ) { srand( (double) microtime() * 1000000 ); $encrypt_key = md5( rand( 0, 32000 ) ); $ctr = 0; $tmp = ""; for( $i = 0; $i < strlen( $txt ); $i++ ) { if ($ctr==strlen($encrypt_key)) $ctr=0; $tmp.= substr($encrypt_key,$ctr,1) . (substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1)); $ctr++; } return bin2hex( mf_keyED( $tmp ) ); } function decrypt( $txt ) { $txt = mf_keyED( hex2bin( $txt ) ); $tmp = ''; for ( $i=0; $i < strlen( $txt ); $i++ ) { $md5 = substr( $txt, $i, 1 ); $i++; $tmp.= ( substr( $txt, $i, 1 ) ^ $md5 ); } return $tmp; } /** * check mail folder * @param stream $imap_stream imap connection resource * @param string $imap_folder imap folder name * @return boolean true, when folder can be used to store messages. * @since 1.5.1 and 1.4.5 */ function mail_fetch_check_folder($imap_stream,$imap_folder) { global $mail_fetch_allow_unsubscribed; // check if folder is subscribed or only exists. if (sqimap_mailbox_is_subscribed($imap_stream,$imap_folder)) { $ret = true; } elseif ($mail_fetch_allow_unsubscribed && sqimap_mailbox_exists($imap_stream,$imap_folder)) { $ret = true; } else { $ret = false; } // make sure that folder can store messages if ($ret && mail_fetch_check_noselect($imap_stream,$imap_folder)) { $ret = false; } return $ret; } /** * Checks if folder is noselect (can't store messages) * * Function does not check if folder subscribed. * @param stream $imap_stream imap connection resource * @param string $imap_folder imap folder name * @return boolean true, when folder has noselect flag. false in any other case. * @since 1.5.1 and 1.4.5 */ function mail_fetch_check_noselect($imap_stream,$imap_folder) { $boxes=sqimap_mailbox_list($imap_stream); foreach($boxes as $box) { if ($box['unformatted']==$imap_folder) { return (bool) check_is_noselect($box['raw']); } } return false; } squirrelmail/plugins/mail_fetch/options.php0000644000175000017500000005175311700173711020604 0ustar thijsthijs
' . html_tag( 'table', html_tag( 'tr', html_tag( 'td', '' . _("Remote POP server settings") . '', 'center', $color[0] ) ), 'center', '', 'width="95%"' ) . html_tag( 'table', html_tag( 'tr', html_tag( 'td', _("You should be aware that the encryption used to store your password is not perfectly secure. However, if you are using pop, there is inherently no encryption anyway. Additionally, the encryption that we do to save it on the server can be undone by a hacker reading the source to this file." ) , 'left' ) ) . html_tag( 'tr', html_tag( 'td', _("If you leave password empty, it will be asked when you fetch mail.") , 'left' ) ) . html_tag( 'tr', html_tag( 'td', '':'>') . _("Encrypt passwords (informative only)") , 'right' ) ) , 'center', '', 'width="95%"' ); // display error or other messages if necessary // if (!empty($message)) { echo html_tag( 'table', '', 'center', '', 'width="70%" cellpadding="5" cellspacing="1"' ) . html_tag( 'tr', html_tag( 'td', '' . $message . '', 'center', $color[2] )); } switch( $mf_action ) { case 'config': echo html_tag( 'table', '', 'center', '', 'width="70%" cellpadding="5" cellspacing="1"' ) . html_tag( 'tr', html_tag( 'td', '' . _("Add Server") . '', 'center', $color[9] ) ) . html_tag( 'tr' ) . html_tag( 'td', '', 'center', $color[0] ) . "" . '' . html_tag( 'table' ) . html_tag( 'tr', html_tag( 'th', _("Server:"), 'right' ) . html_tag( 'td', '', 'left' ) ) . html_tag( 'tr', html_tag( 'th', _("Port:"), 'right') . html_tag( 'td', '', 'left') ) . html_tag( 'tr', html_tag( 'th', _("Alias:"), 'right' ) . html_tag( 'td', '', 'left' ) ) . html_tag( 'tr', html_tag( 'th', _("Username:"), 'right' ) . html_tag( 'td', '', 'left' ) ) . html_tag( 'tr', html_tag( 'th', _("Password:"), 'right' ) . html_tag( 'td', '', 'left' ) ) . html_tag( 'tr' ) . html_tag( 'th', _("Store in Folder:"), 'right' ) . html_tag( 'td', '', 'left' ); $imapConnection = sqimap_login ($username, $key, $imapServerAddress, $imapPort, 0); $boxes = sqimap_mailbox_list($imapConnection); echo '' . html_tag( 'tr', html_tag( 'th', ' ', 'right' ) . html_tag( 'td', '' . _("Leave mail on server"), 'left' ) ) . html_tag( 'tr', html_tag( 'th', ' ', 'right' ) . html_tag( 'td', '' . _("Check mail at login"), 'left' ) ) . html_tag( 'tr', html_tag( 'th', ' ', 'right' ) . html_tag( 'td', '' . _("Check mail at folder refresh"), 'left' ) ) . html_tag( 'tr', html_tag( 'td', '', 'center', '', 'colspan="2"' ) ) . '
'; // Modify Server echo '
' . html_tag( 'table', '', 'center', '', 'width="70%" cellpadding="5" cellspacing="1"' ) . html_tag( 'tr', html_tag( 'td', '' . _("Modify Server") . '', 'center', $color[9] ) ) . html_tag( 'tr' ) . html_tag( 'td', '', 'center', $color[0] ); if ($mailfetch_server_number>0) { echo "
"; echo '' . _("Server Name:") . ' '. '  '. '  '. '
'; } else { echo _("No servers known."); } echo ''; break; case 'Delete': //erase confirmation about a server echo html_tag( 'table', html_tag( 'tr', html_tag( 'td', '' . _("Fetching Servers") . '', 'center', $color[0] ) ) , 'center', '', 'width="95%" cellpadding="5" cellspacing="1"' ) . '
' . html_tag( 'table', html_tag( 'tr', html_tag( 'td', '' . _("Confirm Deletion of a Server") . '', 'center', $color[9] ) ) . html_tag( 'tr', html_tag( 'td', "" . '' . '
' . _("Selected Server:") . " " . htmlspecialchars($mailfetch_server_[$mf_sn]) . "
" . _("Confirm delete of selected server?") . '

' . '' . '
' , 'center', $color[9] ) ) , 'center', '', 'width="70%" cellpadding="5" cellspacing="1"' ); break; //modify a server case 'Modify': echo html_tag( 'table', html_tag( 'tr', html_tag( 'td', '' . _("Fetching Servers") . '', 'center', $color[0] ) ) , 'center', '', 'width="95%" cellpadding="5" cellspacing="1"' ) . '
' . html_tag( 'table', '', 'center', '', 'width="70%" cellpadding="5" cellspacing="1"' ) . html_tag( 'tr', html_tag( 'td', '' . _("Modify Server") . '', 'center', $color[9] ) ) . html_tag( 'tr' ) . html_tag( 'td', '', 'center', $color[0] ) . "" . '' . html_tag( 'table' ) . html_tag( 'tr', html_tag( 'th', _("Server:"), 'right' ) . html_tag( 'td', '', 'left' ) ) . html_tag( 'tr', html_tag( 'th', _("Port:"), 'right' ) . html_tag( 'td', '', 'left' ) ) . html_tag( 'tr', html_tag( 'th', _("Alias:"), 'right' ) . html_tag( 'td', '', 'left' ) ) . html_tag( 'tr', html_tag( 'th', _("Username:"), 'right' ) . html_tag( 'td', '', 'left' ) ) . html_tag( 'tr', html_tag( 'th', _("Password:"), 'right' ) . html_tag( 'td', '', 'left' ) ) . html_tag( 'tr' ) . html_tag( 'th', _("Store in Folder:"), 'right' ) . html_tag( 'td', '', 'left' ); $imapConnection = sqimap_login ($username, $key, $imapServerAddress, $imapPort, 0); $boxes = sqimap_mailbox_list($imapConnection); echo '' . html_tag( 'tr', html_tag( 'th', ' ', 'right' ) . html_tag( 'td', '' . _("Leave Mail on Server") , 'left' ) ) . html_tag( 'tr', html_tag( 'th', ' ', 'right' ) . html_tag( 'td', '' . _("Check mail at login"), 'left' ) ) . html_tag( 'tr', html_tag( 'th', ' ', 'right' ) . html_tag( 'td', '' . _("Check mail at folder refresh") , 'left' ) ) . html_tag( 'tr', html_tag( 'td', '', 'center', '', 'colspan="2"' ) ) . ''; break; default: //unsupported action echo '' . html_tag( 'table', html_tag( 'tr', html_tag( 'td', '' . _("Fetching Servers") . '', 'center', $color[0] ) ) , 'center', '', 'width="95%"' ) . '
' . html_tag( 'table', html_tag( 'tr', html_tag( 'td', '' . _("Undefined Function") . '', 'center', $color[9] ) . html_tag( 'td', '' . _("The function you requested is unknown.") . '', 'center', $color[0] ) ) , 'center', '', 'width="70%"' ); } ?> squirrelmail/plugins/mail_fetch/class.POP3.php0000644000175000017500000005052511700173711020732 0ustar thijsthijsBUFFER,"integer"); if( !empty($server) ) { // Do not allow programs to alter MAILSERVER // if it is already specified. They can get around // this if they -really- want to, so don't count on it. if(empty($this->MAILSERVER)) $this->MAILSERVER = $server; } if(!empty($timeout)) { settype($timeout,"integer"); $this->TIMEOUT = $timeout; if (!ini_get('safe_mode')) set_time_limit($timeout); } return true; } function update_timer () { if (!ini_get('safe_mode')) set_time_limit($this->TIMEOUT); return true; } function connect ($server, $port = 110) { // Opens a socket to the specified server. Unless overridden, // port defaults to 110. Returns true on success, false on fail // If MAILSERVER is set, override $server with it's value if (!isset($port) || !$port) {$port = 110;} if(!empty($this->MAILSERVER)) $server = $this->MAILSERVER; if(empty($server)){ $this->ERROR = "POP3 connect: " . _("No server specified"); unset($this->FP); return false; } $fp = @fsockopen("$server", $port, $errno, $errstr); if(!$fp) { $this->ERROR = "POP3 connect: " . _("Error ") . "[$errno] [$errstr]"; unset($this->FP); return false; } socket_set_blocking($fp,-1); $this->update_timer(); $reply = fgets($fp,$this->BUFFER); $reply = $this->strip_clf($reply); if($this->DEBUG) error_log("POP3 SEND [connect: $server] GOT [$reply]",0); if(!$this->is_ok($reply)) { $this->ERROR = "POP3 connect: " . _("Error ") . "[$reply]"; unset($this->FP); return false; } $this->FP = $fp; $this->BANNER = $this->parse_banner($reply); return true; } function user ($user = "") { // Sends the USER command, returns true or false if( empty($user) ) { $this->ERROR = "POP3 user: " . _("no login ID submitted"); return false; } elseif(!isset($this->FP)) { $this->ERROR = "POP3 user: " . _("connection not established"); return false; } else { $reply = $this->send_cmd("USER $user"); if(!$this->is_ok($reply)) { $this->ERROR = "POP3 user: " . _("Error ") . "[$reply]"; return false; } else return true; } } function pass ($pass = "") { // Sends the PASS command, returns # of msgs in mailbox, // returns false (undef) on Auth failure if(empty($pass)) { $this->ERROR = "POP3 pass: " . _("No password submitted"); return false; } elseif(!isset($this->FP)) { $this->ERROR = "POP3 pass: " . _("connection not established"); return false; } else { $reply = $this->send_cmd("PASS $pass"); if(!$this->is_ok($reply)) { $this->ERROR = "POP3 pass: " . _("Authentication failed") . " [$reply]"; $this->quit(); return false; } else { // Auth successful. $count = $this->last("count"); $this->COUNT = $count; return $count; } } } function apop ($login,$pass) { // Attempts an APOP login. If this fails, it'll // try a standard login. YOUR SERVER MUST SUPPORT // THE USE OF THE APOP COMMAND! // (apop is optional per rfc1939) if(!isset($this->FP)) { $this->ERROR = "POP3 apop: " . _("No connection to server"); return false; } elseif(!$this->ALLOWAPOP) { $retVal = $this->login($login,$pass); return $retVal; } elseif(empty($login)) { $this->ERROR = "POP3 apop: " . _("No login ID submitted"); return false; } elseif(empty($pass)) { $this->ERROR = "POP3 apop: " . _("No password submitted"); return false; } else { $banner = $this->BANNER; if( (!$banner) or (empty($banner)) ) { $this->ERROR = "POP3 apop: " . _("No server banner") . ' - ' . _("abort"); $retVal = $this->login($login,$pass); return $retVal; } else { $AuthString = $banner; $AuthString .= $pass; $APOPString = md5($AuthString); $cmd = "APOP $login $APOPString"; $reply = $this->send_cmd($cmd); if(!$this->is_ok($reply)) { $this->ERROR = "POP3 apop: " . _("apop authentication failed") . ' - ' . _("abort"); $retVal = $this->login($login,$pass); return $retVal; } else { // Auth successful. $count = $this->last("count"); $this->COUNT = $count; return $count; } } } } function login ($login = "", $pass = "") { // Sends both user and pass. Returns # of msgs in mailbox or // false on failure (or -1, if the error occurs while getting // the number of messages.) if( !isset($this->FP) ) { $this->ERROR = "POP3 login: " . _("No connection to server"); return false; } else { $fp = $this->FP; if( !$this->user( $login ) ) { // Preserve the error generated by user() return false; } else { $count = $this->pass($pass); if( (!$count) || ($count == -1) ) { // Preserve the error generated by last() and pass() return false; } else return $count; } } } function top ($msgNum, $numLines = "0") { // Gets the header and first $numLines of the msg body // returns data in an array with each returned line being // an array element. If $numLines is empty, returns // only the header information, and none of the body. if(!isset($this->FP)) { $this->ERROR = "POP3 top: " . _("No connection to server"); return false; } $this->update_timer(); $fp = $this->FP; $buffer = $this->BUFFER; $cmd = "TOP $msgNum $numLines"; fwrite($fp, "TOP $msgNum $numLines\r\n"); $reply = fgets($fp, $buffer); $reply = $this->strip_clf($reply); if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); } if(!$this->is_ok($reply)) { $this->ERROR = "POP3 top: " . _("Error ") . "[$reply]"; return false; } $count = 0; $MsgArray = array(); $line = fgets($fp,$buffer); while ( !preg_match('/^\.\r\n/',$line)) { $MsgArray[$count] = $line; $count++; $line = fgets($fp,$buffer); if(empty($line)) { break; } } return $MsgArray; } function pop_list ($msgNum = "") { // If called with an argument, returns that msgs' size in octets // No argument returns an associative array of undeleted // msg numbers and their sizes in octets if(!isset($this->FP)) { $this->ERROR = "POP3 pop_list: " . _("No connection to server"); return false; } $fp = $this->FP; $Total = $this->COUNT; if( (!$Total) or ($Total == -1) ) { return false; } if($Total == 0) { return array("0","0"); // return -1; // mailbox empty } $this->update_timer(); if(!empty($msgNum)) { $cmd = "LIST $msgNum"; fwrite($fp,"$cmd\r\n"); $reply = fgets($fp,$this->BUFFER); $reply = $this->strip_clf($reply); if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); } if(!$this->is_ok($reply)) { $this->ERROR = "POP3 pop_list: " . _("Error ") . "[$reply]"; return false; } list($junk,$num,$size) = preg_split('/\s+/',$reply); return $size; } $cmd = "LIST"; $reply = $this->send_cmd($cmd); if(!$this->is_ok($reply)) { $reply = $this->strip_clf($reply); $this->ERROR = "POP3 pop_list: " . _("Error ") . "[$reply]"; return false; } $MsgArray = array(); $MsgArray[0] = $Total; for($msgC=1;$msgC <= $Total; $msgC++) { if($msgC > $Total) { break; } $line = fgets($fp,$this->BUFFER); $line = $this->strip_clf($line); if(strpos($line, '.') === 0) { $this->ERROR = "POP3 pop_list: " . _("Premature end of list"); return false; } list($thisMsg,$msgSize) = preg_split('/\s+/',$line); settype($thisMsg,"integer"); if($thisMsg != $msgC) { $MsgArray[$msgC] = "deleted"; } else { $MsgArray[$msgC] = $msgSize; } } return $MsgArray; } function get ($msgNum) { // Retrieve the specified msg number. Returns an array // where each line of the msg is an array element. if(!isset($this->FP)) { $this->ERROR = "POP3 get: " . _("No connection to server"); return false; } $this->update_timer(); $fp = $this->FP; $buffer = $this->BUFFER; $cmd = "RETR $msgNum"; $reply = $this->send_cmd($cmd); if(!$this->is_ok($reply)) { $this->ERROR = "POP3 get: " . _("Error ") . "[$reply]"; return false; } $count = 0; $MsgArray = array(); $line = fgets($fp,$buffer); while ( !preg_match('/^\.\r\n/',$line)) { if ( $line{0} == '.' ) { $line = substr($line,1); } $MsgArray[$count] = $line; $count++; $line = fgets($fp,$buffer); if(empty($line)) { break; } } return $MsgArray; } function last ( $type = "count" ) { // Returns the highest msg number in the mailbox. // returns -1 on error, 0+ on success, if type != count // results in a popstat() call (2 element array returned) $last = -1; if(!isset($this->FP)) { $this->ERROR = "POP3 last: " . _("No connection to server"); return $last; } $reply = $this->send_cmd("STAT"); if(!$this->is_ok($reply)) { $this->ERROR = "POP3 last: " . _("Error ") . "[$reply]"; return $last; } $Vars = preg_split('/\s+/',$reply); $count = $Vars[1]; $size = $Vars[2]; settype($count,"integer"); settype($size,"integer"); if($type != "count") { return array($count,$size); } return $count; } function reset () { // Resets the status of the remote server. This includes // resetting the status of ALL msgs to not be deleted. // This method automatically closes the connection to the server. if(!isset($this->FP)) { $this->ERROR = "POP3 reset: " . _("No connection to server"); return false; } $reply = $this->send_cmd("RSET"); if(!$this->is_ok($reply)) { // The POP3 RSET command -never- gives a -ERR // response - if it ever does, something truely // wild is going on. $this->ERROR = "POP3 reset: " . _("Error ") . "[$reply]"; @error_log("POP3 reset: ERROR [$reply]",0); } $this->quit(); return true; } function send_cmd ( $cmd = "" ) { // Sends a user defined command string to the // POP server and returns the results. Useful for // non-compliant or custom POP servers. // Do NOT includ the \r\n as part of your command // string - it will be appended automatically. // The return value is a standard fgets() call, which // will read up to $this->BUFFER bytes of data, until it // encounters a new line, or EOF, whichever happens first. // This method works best if $cmd responds with only // one line of data. if(!isset($this->FP)) { $this->ERROR = "POP3 send_cmd: " . _("No connection to server"); return false; } if(empty($cmd)) { $this->ERROR = "POP3 send_cmd: " . _("Empty command string"); return ""; } $fp = $this->FP; $buffer = $this->BUFFER; $this->update_timer(); fwrite($fp,"$cmd\r\n"); $reply = fgets($fp,$buffer); $reply = $this->strip_clf($reply); if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); } return $reply; } function quit() { // Closes the connection to the POP3 server, deleting // any msgs marked as deleted. if(!isset($this->FP)) { $this->ERROR = "POP3 quit: " . _("connection does not exist"); return false; } $fp = $this->FP; $cmd = "QUIT"; fwrite($fp,"$cmd\r\n"); $reply = fgets($fp,$this->BUFFER); $reply = $this->strip_clf($reply); if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); } fclose($fp); unset($this->FP); return true; } function popstat () { // Returns an array of 2 elements. The number of undeleted // msgs in the mailbox, and the size of the mbox in octets. $PopArray = $this->last("array"); if($PopArray == -1) { return false; } if( (!$PopArray) or (empty($PopArray)) ) { return false; } return $PopArray; } function uidl ($msgNum = "") { // Returns the UIDL of the msg specified. If called with // no arguments, returns an associative array where each // undeleted msg num is a key, and the msg's uidl is the element // Array element 0 will contain the total number of msgs if(!isset($this->FP)) { $this->ERROR = "POP3 uidl: " . _("No connection to server"); return false; } $fp = $this->FP; $buffer = $this->BUFFER; if(!empty($msgNum)) { $cmd = "UIDL $msgNum"; $reply = $this->send_cmd($cmd); if(!$this->is_ok($reply)) { $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]"; return false; } list ($ok,$num,$myUidl) = preg_split('/\s+/',$reply); return $myUidl; } else { $this->update_timer(); $UIDLArray = array(); $Total = $this->COUNT; $UIDLArray[0] = $Total; if ($Total < 1) { return $UIDLArray; } $cmd = "UIDL"; fwrite($fp, "UIDL\r\n"); $reply = fgets($fp, $buffer); $reply = $this->strip_clf($reply); if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); } if(!$this->is_ok($reply)) { $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]"; return false; } $line = ""; $count = 1; $line = fgets($fp,$buffer); while ( !preg_match('/^\.\r\n/',$line)) { list ($msg,$msgUidl) = preg_split('/\s+/',$line); $msgUidl = $this->strip_clf($msgUidl); if($count == $msg) { $UIDLArray[$msg] = $msgUidl; } else { $UIDLArray[$count] = 'deleted'; } $count++; $line = fgets($fp,$buffer); } } return $UIDLArray; } function delete ($msgNum = "") { // Flags a specified msg as deleted. The msg will not // be deleted until a quit() method is called. if(!isset($this->FP)) { $this->ERROR = "POP3 delete: " . _("No connection to server"); return false; } if(empty($msgNum)) { $this->ERROR = "POP3 delete: " . _("No msg number submitted"); return false; } $reply = $this->send_cmd("DELE $msgNum"); if(!$this->is_ok($reply)) { $this->ERROR = "POP3 delete: " . _("Command failed ") . "[$reply]"; return false; } return true; } // ********************************************************* // The following methods are internal to the class. function is_ok ($cmd = "") { // Return true or false on +OK or -ERR if( empty($cmd) ) return false; else return( stripos($cmd, '+OK') !== false ); } function strip_clf ($text = "") { // Strips \r\n from server responses if(empty($text)) return $text; else { $stripped = str_replace(array("\r","\n"),'',$text); return $stripped; } } function parse_banner ( $server_text ) { $outside = true; $banner = ""; $length = strlen($server_text); for($count =0; $count < $length; $count++) { $digit = substr($server_text,$count,1); if(!empty($digit)) { if( (!$outside) && ($digit != '<') && ($digit != '>') ) { $banner .= $digit; } if ($digit == '<') { $outside = false; } if($digit == '>') { $outside = true; } } } $banner = $this->strip_clf($banner); // Just in case return "<$banner>"; } } // End class // For php4 compatibility if (!function_exists("stripos")) { function stripos($haystack, $needle){ return strpos($haystack, stristr( $haystack, $needle )); } } squirrelmail/plugins/message_details/0000755000175000017500000000000011737431041017426 5ustar thijsthijssquirrelmail/plugins/message_details/message_details_top.php0000644000175000017500000000374711700173711024162 0ustar thijsthijs\n". "\n". "\n", FALSE ); sqgetGlobalVar('passed_id', $passed_id, SQ_GET); if (!sqgetGlobalVar('passed_ent_id', $passed_ent_id, SQ_GET)) $passed_ent_id = 0; sqgetGlobalVar('mailbox', $mailbox, SQ_GET); echo "\n" . '
' . '
' . '  '. '  '. ' '. '' . '' . '' . '' . '
'. '
'. ''. "\n"; ?> squirrelmail/plugins/message_details/setup.php0000644000175000017500000000341711700173711021301 0ustar thijsthijs' . "\n" . '\n" . "\n" . " | $print_text\n"; } echo $result; } squirrelmail/plugins/message_details/index.php0000644000175000017500000000077211700173711021251 0ustar thijsthijssquirrelmail/plugins/message_details/message_details_main.php0000644000175000017500000000256711700173711024303 0ustar thijsthijs\n"; echo ''; echo ''; echo ''."\n"."\n"; ?> squirrelmail/plugins/message_details/message_details_bottom.php0000644000175000017500000002216511700173711024657 0ustar thijsthijs'; $end = ''; $entStr = ''; $bla =''; $content = array (); $content_indx = -1; $contentset = false; $count=count($body); $body[$count-1] = substr($body[$count-1], -1); for ($i=1; $i < $count; $i++) { $line = trim($body[$i]); if ($line == '') { $pre = ''; $end = ''; if ($bnd_end) { $header = true; $mimepart = false; } else if ($messageheader) { if ($header) { $header=false; $end = "\n \n".''."\n \n".'
'."\n \n"; } $mimepart = -$header; $bnd_end = false; if ($messageheaderstart) { $messageheaderstart=false; } } else if ($messageheaderstart) { $messageheader= false; } else { if ($header) { $pre = ''; $end = "\n \n".'
'."\n \n".'
'."\n \n"; } $header = false; $mimepart=true; } $contentset = false; $nameset = false; } else { if (!$header && $messageheader) { $messageheaderstart=true; if ($pre != '') { $pre = ''; } } if (!$messageheader && !$header ) { $mimepart=true; } else { $mimepart=false; } $pre = ''; $end = ''; } if ( ( $header || $messageheader) && (preg_match("/^.*boundary=\"?(.+(?=\")|.+).*/i",$line,$reg)) ) { $bnd = $reg[1]; $bndreg = $bnd; $bndreg = str_replace("\\","\\\\",$bndreg); $bndreg = str_replace("?","\\?",$bndreg); $bndreg = str_replace("+","\\+",$bndreg); $bndreg = str_replace(".","\\.",$bndreg); $bndreg = str_replace("/","\\/",$bndreg); $bndreg = str_replace("-","\\-",$bndreg); $bndreg = str_replace("(","\\(",$bndreg); $bndreg = str_replace(")","\\)",$bndreg); $boundaries[] = array( 'bnd' => $bnd, 'bndreg' => $bndreg); $messageheader = false; $messageheaderstart=false; $mimepart=false; if ($entStr=='') { $entStr='0'; } else { $entStr = CalcEntity("$entStr",1); } } if (($line != '' && $line{0} == '-' || $header) && isset($boundaries[0])) { $cnt=count($boundaries)-1; $bnd = $boundaries[$cnt]['bnd']; $bndreg = $boundaries[$cnt]['bndreg']; $regstr = '/^--'."($bndreg)".".*".'/'; if (preg_match($regstr,$line,$reg) ) { $bndlen = strlen($reg[1]); $bndend = false; if (strlen($line) > ($bndlen + 3)) { if ($line{$bndlen+2} == '-' && $line{$bndlen+3} == '-') $bndend = true; } if ($bndend) { $entStr = CalcEntity("$entStr",-1); array_pop($boundaries); $pre .= ''; $header = true; $mimepart = false; $bnd_end = true; $encoding = ''; } else { $header = true; $bnd_end = false; $entStr = CalcEntity("$entStr",0); $content_indx++; $content[$content_indx]=array(); $content[$content_indx]['ent'] = '$entStr".''; $pre .= "\n \n".'
'."\n \n".'
'."\n"; $header = true; $mimepart = false; $encoding = ''; } } else { if ($header) { if (!$contentset && preg_match("/^.*(content-type:)\s*(\w+)\/(\w+).*/i",$line,$reg)) { if (strtolower($reg[2]) == 'message' && strtolower($reg[3]) == 'rfc822') { $messageheader = true; } $content[$content_indx]['type'] = "$reg[2]/$reg[3]"; $contentset = true; if ($reg[2] == 'image') { $entities["$entStr"] = array(); $entities["$entStr"]['entity'] = $entStr; $entities["$entStr"]['contenttype']=$reg[2].'/'.$reg[3]; } } else if (!$nameset && preg_match("/^.*(name=\s*)\"(.*)\".*/i",$line,$reg)) { $name = htmlspecialchars($reg[2]); $content[$content_indx]['name'] = decodeHeader($name); $nameset = true; if (isset($entities["$entStr"])) { $entities["$entStr"]['name'] = urlEncode($reg[2]); } } else if (preg_match("/^.*(content-transfer-encoding:)\s*(\w+-?(\w+)?).*/i",$line,$reg) ) { $encoding = $reg[2]; if (isset($entities["$entStr"])) { $entities["$entStr"]['encoding']=$reg[2]; } $content[$content_indx]['encoding'] = $encoding; $mimeentity = ''; } $pre .= ''; //$mimepart=false; } } } /* if ($mimepart) { if (isset($entities["$entStr"])) { if (isset($encoding) && $encoding == 'base64') { if (!isset( $entities["$entStr"]['content'])) $entities[$entStr]['content'] = ''; $entities["$entStr"]['content'] .= $line; } } } */ $line = htmlspecialchars($line); $message_body .= "$pre"."$line"."$end".'
'."\r\n"; } $xtra = << ECHO; displayHtmlHeader( _("Message Details"), $xtra, FALSE ); /* body */ echo "\n"; echo ''."\n"; echo ''."\n"; echo '
'."\n"; if (count($content) > 0) { echo '

' . _("Bodystructure") . "

\n\n"; echo ''. ''. ''. ''. ''. ''. ''. ''; for ($i = 0; $i < count($content);$i++) { echo ''."\n"; } echo '
' . _("Entity") . '' . _("Content-Type") . '' . _("Name") . '' . _("Encoding") . '
'; echo $content[$i]['ent'].''; if (isset($content[$i]['type'])) { echo $content[$i]['type']; } else echo 'TEXT/PLAIN'; echo ''; if (isset($content[$i]['name'])) { echo $content[$i]['name']; } else echo ' '; echo ''; if (isset($content[$i]['encoding'])) { echo $content[$i]['encoding']; } else echo ' '; echo '

'."\n"; } echo '

' . _("RFC822 Message body") . "

\n\n"; echo '
'."\n\n"; echo $message_body; echo '
'; ?> squirrelmail/plugins/squirrelspell/0000755000175000017500000000000011737431041017203 5ustar thijsthijssquirrelmail/plugins/squirrelspell/setup.php0000644000175000017500000000516111700173711021054 0ustar thijsthijs * @version $Id: setup.php 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ /** @ignore */ if (! defined('SM_PATH')) define('SM_PATH','../../'); /** * Standard SquirrelMail plugin initialization API. * * @return void */ function squirrelmail_plugin_init_squirrelspell() { global $squirrelmail_plugin_hooks; $squirrelmail_plugin_hooks['compose_button_row']['squirrelspell'] = 'squirrelspell_setup'; $squirrelmail_plugin_hooks['optpage_register_block']['squirrelspell'] = 'squirrelspell_optpage_register_block'; $squirrelmail_plugin_hooks['options_link_and_description']['squirrelspell'] = 'squirrelspell_options'; } /** * This function formats and adds the plugin and its description to the * Options screen. * * @return void */ function squirrelspell_optpage_register_block() { global $optpage_blocks; /** * soupNazi checks if this browser is capable of using the plugin. */ if (!soupNazi()) { /** * The browser checks out. * Register Squirrelspell with the $optionpages array. */ $optpage_blocks[] = array( 'name' => _("SpellChecker Options"), 'url' => '../plugins/squirrelspell/sqspell_options.php', 'desc' => _("Here you may set up how your personal dictionary is stored, edit it, or choose which languages should be available to you when spell-checking."), 'js' => TRUE); } } /** * This function adds a "Check Spelling" link to the "Compose" row * during message composition. * * @return void */ function squirrelspell_setup() { /** * Check if this browser is capable of displaying SquirrelSpell * correctly. */ if (!soupNazi()) { /** * Some people may choose to disable javascript even though their * browser is capable of using it. So these freaks don't complain, * use document.write() so the "Check Spelling" button is not * displayed if js is off in the browser. */ echo "\n"; } } ?>squirrelmail/plugins/squirrelspell/sqspell_functions.php0000644000175000017500000004275111700173711023475 0ustar thijsthijs * @version $Id: sqspell_functions.php 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ /** * This function is the GUI wrapper for the options page. SquirrelSpell * uses it for creating all Options pages. * * @param string $title The title of the page to display * @param string $scriptsrc This is used to link a file.js into the * format. This * allows to separate javascript from the rest of the * plugin and place it into the js/ directory. * @param string $body The body of the message to display. * @return void */ function sqspell_makePage($title, $scriptsrc, $body){ global $color, $SQSPELL_VERSION; if (! sqgetGlobalVar('MOD', $MOD, SQ_GET) ) { $MOD = 'options_main'; } displayPageHeader($color, 'None'); echo " 
\n"; /** * Check if we need to link in a script. */ if($scriptsrc) { echo "\n"; } echo html_tag( 'table', '', 'center', '', 'width="95%" border="0" cellpadding="2" cellspacing="0"' ) . "\n" . html_tag( 'tr', "\n" . html_tag( 'td', '' . $title .'', 'center', $color[9] ) ) . "\n" . html_tag( 'tr', "\n" . html_tag( 'td', '
', 'left' ) ) . "\n" . html_tag( 'tr', "\n" . html_tag( 'td', $body, 'left' ) ) . "\n"; /** * Generate a nice "Return to Options" link, unless this is the * starting page. */ if ($MOD != "options_main"){ echo html_tag( 'tr', "\n" . html_tag( 'td', '
', 'left' ) ) . "\n" . html_tag( 'tr', "\n" . html_tag( 'td', '
' . _("Back to "SpellChecker Options" page") . '', 'center' ) ) . "\n"; } /** * Close the table and display the version. */ echo html_tag( 'tr', "\n" . html_tag( 'td', '
', 'left' ) ) . "\n" . html_tag( 'tr', html_tag( 'td', 'SquirrelSpell ' . $SQSPELL_VERSION, 'center', $color[9] ) ) . "\n\n"; echo ''; } /** * Function similar to the one above. This one is a general wrapper * for the Squirrelspell pop-up window. It's called form nearly * everywhere, except the check_me module, since that one is highly * customized. * * @param string $onload Used to indicate and pass the name of a js function * to call in a format. * @param string $body The content to include. * @return void */ function sqspell_makeWindow($onload, $title, $scriptsrc, $body){ global $color, $SQSPELL_VERSION; displayHtmlHeader($title, ($scriptsrc ? "\n\n" : '')); echo "\n" . html_tag( 'table', "\n" . html_tag( 'tr', "\n" . html_tag( 'td', '' . $title . '', 'center', $color[9] ) ) . "\n" . html_tag( 'tr', "\n" . html_tag( 'td', '
', 'left' ) ) . "\n" . html_tag( 'tr', "\n" . html_tag( 'td', $body, 'left' ) ) . "\n" . html_tag( 'tr', "\n" . html_tag( 'td', '
', 'left' ) ) . "\n" . html_tag( 'tr', "\n" . html_tag( 'td', 'SquirrelSpell ' . $SQSPELL_VERSION, 'center', $color[9] ) ) , '', '', 'width="100%" border="0" cellpadding="2"' ) . "\n\n"; } /** * This function does the encryption and decryption of the user * dictionary. It is only available when PHP is compiled with * mcrypt support (--with-mcrypt). See doc/CRYPTO for more * information. * * @param $mode A string with either of the two recognized values: * "encrypt" or "decrypt". * @param $ckey The key to use for processing (the user's password * in our case. * @param $input Content to decrypt or encrypt, according to $mode. * @return encrypted/decrypted content, or "PANIC" if the * process bails out. */ function sqspell_crypto($mode, $ckey, $input){ /** * Double-check if we have the mcrypt_generic function. Bail out if * not so. */ if (!function_exists('mcrypt_generic')) { return 'PANIC'; } /** * Setup mcrypt routines. */ $td = mcrypt_module_open(MCRYPT_Blowfish, "", MCRYPT_MODE_ECB, ""); $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size ($td), MCRYPT_RAND); mcrypt_generic_init($td, $ckey, $iv); /** * See what we have to do depending on $mode. * 'encrypt' -- Encrypt the content. * 'decrypt' -- Decrypt the content. */ switch ($mode){ case 'encrypt': $crypto = mcrypt_generic($td, $input); break; case 'decrypt': $crypto = mdecrypt_generic($td, $input); /** * See if it decrypted successfully. If so, it should contain * the string "# SquirrelSpell". If not, then bail out. */ if (!strstr($crypto, "# SquirrelSpell")){ $crypto='PANIC'; } break; } /** * Finish up the mcrypt routines and return the processed content. */ mcrypt_generic_deinit ($td); mcrypt_module_close ($td); return $crypto; } /** * This function transparently upgrades the 0.2 dictionary format to the * 0.3 format, since user-defined languages have been added in 0.3 and * the new format keeps user dictionaries selection in the file. * * This function will be retired soon, as it's been a while since anyone * has been using SquirrelSpell-0.2. * * @param $words_string Contents of the 0.2-style user dictionary. * @return Contents of the 0.3-style user dictionary. */ function sqspell_upgradeWordsFile($words_string){ global $SQSPELL_APP_DEFAULT, $SQSPELL_VERSION; /** * Define just one dictionary for this user -- the default. * If the user wants more, s/he can set them up in personal * preferences. See doc/UPGRADING for more info. */ $new_words_string = substr_replace($words_string, "# SquirrelSpell User Dictionary $SQSPELL_VERSION\n# " . "Last Revision: " . date("Y-m-d") . "\n# LANG: $SQSPELL_APP_DEFAULT\n# $SQSPELL_APP_DEFAULT", 0, strpos($words_string, "\n")) . "# End\n"; sqspell_writeWords($new_words_string); return $new_words_string; } /** * Right now it just returns an array with the dictionaries * available to the user for spell-checking. It will probably * do more in the future, as features are added. * * @param string $words The contents of the user's ".words" file. * @return array a strings array with dictionaries available * to this user, e.g. {"English", "Spanish"}, etc. */ function sqspell_getSettings($words){ global $SQSPELL_APP, $SQSPELL_APP_DEFAULT; /** * Check if there is more than one dictionary configured in the * system config. */ if (sizeof($SQSPELL_APP) > 1){ /** * Now load the user prefs. Check if $words was empty -- a bit of * a dirty fall-back. TODO: make it so this is not required. */ if(!$words){ $words=sqspell_getWords(); } if ($words){ /** * This user has a ".words" file. * Find which dictionaries s/he wants to use and load them into * the $langs array. */ preg_match("/# LANG: (.*)/i", $words, $matches); $langs=explode(", ", $matches[1]); } else { /** * User doesn't have a personal dictionary. Grab the default * system setting. */ $langs[0]=$SQSPELL_APP_DEFAULT; } } else { /** * There is no need to read the ".words" file as there is only one * dictionary defined system-wide. */ $langs[0]=$SQSPELL_APP_DEFAULT; } return $langs; } /** * This function returns only user-defined dictionary words that correspond * to the requested language. * * @param $words The contents of the user's ".words" file. * @param $lang Which language words to return, e.g. requesting * "English" will return ONLY the words from user's * English dictionary, disregarding any others. * @return The list of words corresponding to the language * requested. */ function sqspell_getLang($words, $lang){ $start=strpos($words, "# $lang\n"); /** * strpos() will return -1 if no # $lang\n string was found. * Use this to return a zero-length value and indicate that no * words are present in the requested dictionary. */ if (!$start) return ''; /** * The words list will end with a new directive, which will start * with "#". Locate the next "#" and thus find out where the * words end. */ $end=strpos($words, "#", $start+1); $lang_words = substr($words, $start, $end-$start); return $lang_words; } /** * This function operates the user dictionary. If the format is * clear-text, then it just reads the file and returns it. However, if * the file is encrypted (well, "garbled"), then it tries to decrypt * it, checks whether the decryption was successful, troubleshoots if * not, then returns the clear-text dictionary to the app. * * @return the contents of the user's ".words" file, decrypted if * necessary. */ function sqspell_getWords(){ global $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO; $words=""; if (file_exists($SQSPELL_WORDS_FILE)){ /** * Gobble it up. */ $fp=fopen($SQSPELL_WORDS_FILE, 'r'); $words=fread($fp, filesize($SQSPELL_WORDS_FILE)); fclose($fp); } /** * Check if this is an encrypted file by looking for * the string "# SquirrelSpell" in it (the crypto * function does that). */ if ($words && !strstr($words, "# SquirrelSpell")){ /** * This file is encrypted or mangled. Try to decrypt it. * If fails, complain loudly. * * $old_key would be a value submitted by one of the modules with * the user's old mailbox password. I admin, this is rather dirty, * but efficient. ;) */ sqgetGlobalVar('key', $key, SQ_COOKIE); sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION); sqgetGlobalVar('old_key', $old_key, SQ_POST); if ($old_key != '') { $clear_key=$old_key; } else { /** * Get user's password (the key). */ $clear_key = OneTimePadDecrypt($key, $onetimepad); } /** * Invoke the decryption routines. */ $words=sqspell_crypto("decrypt", $clear_key, $words); /** * See if decryption failed. */ if ($words=="PANIC"){ /** * AAAAAAAAAAAH!!!!! OK, ok, breathe! * Let's hope the decryption failed because the user changed his * password. Bring up the option to key in the old password * or wipe the file and start over if everything else fails. * * The _("SquirrelSpell...) line has to be on one line, otherwise * gettext will bork. ;( */ $msg = html_tag( 'p', "\n" . '' . _("ATTENTION:") . '
' . _("SquirrelSpell was unable to decrypt your personal dictionary. This is most likely due to the fact that you have changed your mailbox password. In order to proceed, you will have to supply your old password so that SquirrelSpell can decrypt your personal dictionary. It will be re-encrypted with your new password after this. If you haven't encrypted your dictionary, then it got mangled and is no longer valid. You will have to delete it and start anew. This is also true if you don't remember your old password -- without it, the encrypted data is no longer accessible.") , 'left' ) . "\n" . '
' . "\n" . '
' . "\n" . '' . "\n" . html_tag( 'p', "\n" . '' . _("Delete my dictionary and start a new one") . '
' . _("Decrypt my dictionary with my old password:") . '' , 'left' ) . "\n" . '
' . "\n" . html_tag( 'p', "\n" . '' , 'center' ) . "\n" . '' . "\n"; /** * Add some string vars so they can be i18n'd. */ $msg .= "\n"; /** * See if this happened in the pop-up window or when accessing * the SpellChecker options page. * This is a dirty solution, I agree. TODO: make this prettier. */ global $SCRIPT_NAME; if (strstr($SCRIPT_NAME, "sqspell_options")){ sqspell_makePage(_("Error Decrypting Dictionary"), "decrypt_error.js", $msg); } else { sqspell_makeWindow(null, _("Error Decrypting Dictionary"), "decrypt_error.js", $msg); } exit; } else { /** * OK! Phew. Set the encryption flag to true so we can later on * encrypt it again before saving to HDD. */ $SQSPELL_CRYPTO=true; } } else { /** * No encryption is/was used. Set $SQSPELL_CRYPTO to false, * in case we have to save the dictionary later. */ $SQSPELL_CRYPTO=false; } /** * Check if we need to upgrade the dictionary from version 0.2.x * This is going away soon. */ if (strstr($words, "Dictionary v0.2")){ $words=sqspell_upgradeWordsFile($words); } return $words; } /** * Writes user dictionary into the $username.words file, then changes mask * to 0600. If encryption is needed -- does that, too. * * @param $words The contents of the ".words" file to write. * @return void */ function sqspell_writeWords($words){ global $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO; /** * if $words is empty, create a template entry by calling the * sqspell_makeDummy() function. */ if (!$words){ $words=sqspell_makeDummy(); } if ($SQSPELL_CRYPTO){ /** * User wants to encrypt the file. So be it. * Get the user's password to use as a key. */ sqgetGlobalVar('key', $key, SQ_COOKIE); sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION); $clear_key=OneTimePadDecrypt($key, $onetimepad); /** * Try encrypting it. If fails, scream bloody hell. */ $save_words = sqspell_crypto("encrypt", $clear_key, $words); if ($save_words == 'PANIC'){ /** * AAAAAAAAH! I'm not handling this yet, since obviously * the admin of the site forgot to compile the MCRYPT support in * when upgrading an existing PHP installation. * I will add a handler for this case later, when I can come up * with some work-around... Right now, do nothing. Let the Admin's * head hurt.. ;))) */ } } else { $save_words = $words; } /** * Do the actual writing. */ $fp=fopen($SQSPELL_WORDS_FILE, "w"); fwrite($fp, $save_words); fclose($fp); chmod($SQSPELL_WORDS_FILE, 0600); } function sqspell_deleteWords(){ /** * So I open the door to my enemies, * and I ask can we wipe the slate clean, * but they tell me to please go... * uhm... Well, this just erases the user dictionary file. */ global $SQSPELL_WORDS_FILE; if (file_exists($SQSPELL_WORDS_FILE)){ unlink($SQSPELL_WORDS_FILE); } } /** * Creates an empty user dictionary for the sake of saving prefs or * whatever. * * @return The template to use when storing the user dictionary. */ function sqspell_makeDummy(){ global $SQSPELL_VERSION, $SQSPELL_APP_DEFAULT; $words = "# SquirrelSpell User Dictionary $SQSPELL_VERSION\n" . "# Last Revision: " . date('Y-m-d') . "\n# LANG: $SQSPELL_APP_DEFAULT\n# End\n"; return $words; } /** * This function checks for security attacks. A $MOD variable is * provided in the QUERY_STRING and includes one of the files from the * modules directory ($MOD.mod). See if someone is trying to get out * of the modules directory by providing dots, unicode strings, or * slashes. * * @param string $rMOD the name of the module requested to include. * @return void, since it bails out with an access error if needed. */ function sqspell_ckMOD($rMOD){ if (strstr($rMOD, '.') || strstr($rMOD, '/') || strstr($rMOD, '%') || strstr($rMOD, "\\")){ echo _("Invalid URL"); exit; } } /** * SquirrelSpell version. Don't modify, since it identifies the format * of the user dictionary files and messing with this can do ugly * stuff. :) */ $SQSPELL_VERSION="v0.3.8"; squirrelmail/plugins/squirrelspell/index.php0000644000175000017500000000077011700173711021024 0ustar thijsthijssquirrelmail/plugins/squirrelspell/doc/0000755000175000017500000000000011737431041017750 5ustar thijsthijssquirrelmail/plugins/squirrelspell/doc/ChangeLog0000644000175000017500000000407307426265702021537 0ustar thijsthijsSQUIRRELSPELL v0.3.7 ------ - General formatting updates, javadoc-style comments, and cleanups. - Potential privacy vulnerability fixed (possible symlink attack) - Moving some strings from .js files into .mod or .php so they can be translated. - Miscellaneous code moves and smallish rewrites. v0.3.6 ------ - Remote arbirtary execution as apache user vulnerability fix. v0.3.5 ------- - Making it work with 1.1.1 broke it under 1.0.6. Decided not to support developmental versions after this release. v0.3.4 ------- - Changes to unbreak it in 1.1.1. :) v0.3.3 ------- - Apparently, magic quotes wasn't a bug, but something introduced in 1.0.6, so I took out all magic-quotes escaping routines, since it's done automatically now by validate.php. v0.3.2 ------- - Rolled back changes in v0.3.1 - Workaround for an odd bug with PHP's magic_quotes_gpc - Changed trim to chop so the newline-trimming function doesn't trim leading spaces. - Changed SOUP_NAZI to only deny Opera-4 versions - Moved SQSPELL_VERSION to sqspell_functions.php for easier upgrades. v0.3.1 ------- Changes to make it work with 1.0.5. v0.3 ----- Added vlink and alink settings, plus fixed some colors. v0.3b ------ - Major code re-organization. - Moved modules into separate directory. - Moved most JavaScript out of the main code into separate .js files - Created generic GUI-wrappers for most interface screens. - Added support for multiple international dictionaries. - Added MCRYPT support for encrypting the user dictionaries. - No longer checks lines starting with ">" (reply). - No longer checks anything past the "--" on a single line (signature). - SquirrelSpell options are now on the main OPTIONS page, not on the personal options page. v0.2.1 ------ Added a SoupNazi function. :)) Checks for bad browsers which are known not to work with SquirrelSpell due to their odd JavaScript. v0.2pl1 ------- Fixed the Magic Quotes problems. v0.2 ----- Added user dictionaries. v0.1.1 ------- Added support for aspell v0.1pl1 -------- Fixed Magic Quotes errors. version v0.1 ------------- Initial release. squirrelmail/plugins/squirrelspell/doc/index.php0000644000175000017500000000077011700173711021571 0ustar thijsthijssquirrelmail/plugins/squirrelspell/doc/UPGRADING0000644000175000017500000000126207367712715021232 0ustar thijsthijsFrom version v0.2 to version v0.3 ---------------------------------- The user dictionaries will be converted to v0.3 format. Once they are converted, you can't downgrade back to v0.2. If this scares you, backup all *.words files in your $data_dir somewhere safe. Files are renamed around. config.php is now sqspell_config.php. When you are setting up SQSPELL_DEFAULT_APP in the sqspell_config, keep in mind that this has to reflect whichever dictionary you used in version 0.2. Say, if you used "ispell -d german", you will need to specify German as your SQSPELL_DEFAULT_APP so user dictionaries can be upgraded successfully. Otherwise wrong words will end up in a wrong dictionary. squirrelmail/plugins/squirrelspell/doc/README0000644000175000017500000000342410250421340020621 0ustar thijsthijsSquirrelSpell -------------- SquirrelSpell is a JavaScript-powered spellchecker written to work with SquirrelMail webmail interface. LICENSE: --------- This is free software released under GNU GPL license and comes with no warranty of any kind. You may modify, borrow, or redistribute code as long as it doesn't violate the GNU GPL license. You can read more about this license at http://www.gnu.org/ FEATURES: ---------- SquirrelSpell works with UN*X's ISPELL or ASPELL libraries and SquirrelMail version 1.4 and higher. No PHP recompilation required, unless you wish to enable MCRYPT support. * SpellChecker: ISPELL or ASPELL. It all depends on them. Read configuration parameters in sqspell_config.php. Starting with version v0.3 supports multiple international dictionaries. * User Dictionary: SquirrelSpell adds words to the user dictionary. You may edit your dictionary under options->personal options->Edit my dictionary. * Encryption: Starting with version v0.3 SquirrelSpell is capable of working with encrypted user dictionaries. See doc/CRYPTO for information on how to enable this feature. * i18n and l10n: SquirrelSpell supports any international dictionaries provided by ispell or aspell. However, since there isn't a translation interface available for SquirrelMail plugins, all messages produced by SquirrelSpell will be in English. AUTHOR: -------- This plugin was originally authored by Konstantin Riabitsev (http://www.mricon.com/) and is now maintained by the SquirrelMail Project Team. SUPPORT: --------- Send support questions and bug reports to the plugins mailing list: squirrelmail-plugins@lists.sourceforge.net. When reporting a bug don't forget to mention your browser version, SquirrelMail and SquirrelSpell versions, as well as any other useful info. ENJOY. :) --------- squirrelmail/plugins/squirrelspell/doc/CRYPTO0000644000175000017500000000235510250421340020706 0ustar thijsthijsCRYPTOGRAPHY SUPPORT IN SQUIRRELSPELL -------------------------------------- Starting with version v0.3 SquirrelSpell is capable of working with encrypted user dictionaries. However, this option is only available when PHP is compiled with support for MCRYPT. This is relatively easy -- to enable MCRYPT support, follow instructions at: http://www.php.net/mcrypt NOTE: You will need libmcrypt version 2.4.x or above for SquirrelSpell to work. HOW IT'S DONE -------------- SquirrelSpell encrypts the dictionary with the user's mailbox password, thus making the encryption/decryption process transparent to the user. The algorythm used for encryption is Blowfish, but you may manually override it in the code if you so wish. The only shortcoming this approach has -- when mailbox password is changed, SquirrelSpell asks the user to enter the old password in order to re-encrypt the file with the new key. If the user doesn't remember the password, then the file is lost, unless you want to brute-force it open. The encryption is off by default and users are warned about remembering their passwords before they enable encryption of their personal dictionary. I haven't tested the overhead. If anyone has any benchmarks -- you are welcome to share them. squirrelmail/plugins/squirrelspell/doc/PRIVACY0000644000175000017500000000131110250421340020772 0ustar thijsthijsPRIVACY CONCERNS WHEN USING SQUIRRELSPELL: ------------------------------------------- Beginning with version v0.2 SquirrelSpell saves personal dictionary on the server. This has a potential of a serious privacy issue, therefore you should configure your system to disallow web access to the directory where your user dictionaries are stored. By default they are stored in your $data_dir which you provided in your SquirrelMail config. This is the best option, but you should read the SquirrelMail FAQ's and Readme's on how to secure that directory. Also, see the CRYPTO file for instructions on how to enable encryption of user dictionaries. This is done in order to further enhance the privacy of your users. squirrelmail/plugins/squirrelspell/modules/0000755000175000017500000000000011737431041020653 5ustar thijsthijssquirrelmail/plugins/squirrelspell/modules/check_me.mod0000644000175000017500000003506711700173711023122 0ustar thijsthijs * @version $Id: check_me.mod 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ /** * This function makes a javascript-powered link. Not sure why * Philippe decided to move it outside the main code, but hey. ;) * I bet for the i18n reasons. * * @param $jscode Javascript code to include in the link. * @param $title A little pop-up title to provide for the links. * @param $link The content of the link. * @return void, since this just draws the content. */ function SpellLink($jscode, $title, $link) { echo "$link" . ''; } /** * Declaring globals for users with E_ALL set. */ global $SQSPELL_APP, $attachment_dir, $SQSPELL_EREG, $color; $sqspell_text = $_POST['sqspell_text']; $sqspell_use_app = $_POST['sqspell_use_app']; /** * Now we explode the lines for three reasons: * 1) So we can ignore lines starting with ">" (reply's) * 2) So we can stop processing when we get to "--" on a single line, * which means that the signature is starting * 3) So we can add an extra space at the beginning of each line. This way * ispell/aspell don't treat these as command characters. */ $sqspell_raw_lines = explode("\n", $sqspell_text); for ($i=0; $i= 4.3.0, we can use proc_open and safe mode * and not mess w/ temp files. Otherwise we will do it the old * way, (minus the uneeded call to cat that messes up Wintel * boxen.) * Thanks Ray Ferguson for providing this patch. */ if( check_php_version ( 4, 3 ) ) { $descriptorspec = array( 0 => array('pipe', 'r'), // stdin is a pipe that the child will read from 1 => array('pipe', 'w'), // stdout is a pipe that the child will write to 2 => array('pipe', 'w'), // stderr is a pipe that the child will write to ); $spell_proc = @proc_open($sqspell_command, $descriptorspec, $pipes); if ( ! is_resource ( $spell_proc ) ) { error_box ( sprintf(_("Could not run the spellchecker command (%s)."), htmlspecialchars($sqspell_command) ) , $color ); // close html tags and abort script. echo ""; exit(); } if ( ! @fwrite($pipes[0], $sqspell_new_text) ) { error_box ( _("Error while writing to pipe.") , $color ); // close all three pipes here. for($i=0; $i<=2; $i++) { // disable all fclose error messages @fclose($pipes[$i]); } // close html tags and abort script. echo ""; exit(); } fclose($pipes[0]); $sqspell_output = array(); for($i=1; $i<=2; $i++) { while(!feof($pipes[$i])) { array_push($sqspell_output, rtrim(fgetss($pipes[$i],999),"\r\n")); } fclose($pipes[$i]); } $sqspell_exitcode=proc_close($spell_proc); } else { // add slash to attachment directory, if it does not end with slash. if (substr($attachment_dir, -1) != '/') $attachment_dir = $attachment_dir . '/'; // find unused file in attachment directory do { $floc = $attachment_dir . md5($sqspell_new_text . microtime()); } while (file_exists($floc)); $fp = @fopen($floc, 'w'); if ( ! is_resource ($fp) ) { error_box ( sprintf(_("Could not open temporary file '%s'."), htmlspecialchars($floc) ) , $color ); // failed to open temp file. abort script. echo ""; exit(); } if ( ! @fwrite($fp, $sqspell_new_text) ) { error_box ( sprintf(_("Error while writing to temporary file '%s'."), htmlspecialchars($floc) ) , $color ); // close file descriptor fclose($fp); // failed writing to temp file. abort script. echo ""; exit(); } fclose($fp); exec("$sqspell_command < $floc 2>&1", $sqspell_output, $sqspell_exitcode); unlink($floc); } /** * Check if the execution was successful. Bail out if it wasn't. */ if ($sqspell_exitcode){ $msg= "
" . sprintf(_("I tried to execute '%s', but it returned:"), $sqspell_command) . "
"
     . htmlspecialchars(join("\n", $sqspell_output)) . '
' . '
' . '
'; sqspell_makeWindow(null, _("SquirrelSpell is misconfigured."), null, $msg); exit; } /** * Load the user dictionary. */ $words=sqspell_getLang(sqspell_getWords(), $sqspell_use_app); /** * Define some variables to be used during the processing. */ $current_line=0; $missed_words=Array(); $misses = Array(); $locations = Array(); $errors=0; /** * Now we process the output of sqspell_command (ispell or aspell in * ispell compatibility mode, whichever). I'm going to be scarce on * comments here, since you can just look at the ispell/aspell output * and figure out what's going on. ;) The best way to describe this is * "Dark Magic". */ for ($i=0; $i\n" . "\n" . "\n" . "\n"; displayHtmlHeader(_("SquirrelSpell Results"),$extrajs); echo "\n"; ?>

"; echo $sptag . _("Line with an error:") . ''; ?>
'; ?> '; ?>
'; ?> '; ?>


' . ' '; ?>
' . '
'; sqspell_makeWindow(null, _("No errors found"), null, $msg); } /** * For Emacs weenies: * Local variables: * mode: php * End: * vim: syntax=php */ ?> squirrelmail/plugins/squirrelspell/modules/crypto_badkey.mod0000644000175000017500000000604011700173711024210 0ustar thijsthijs * @version $Id: crypto_badkey.mod 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ global $SCRIPT_NAME; $delete_words = $_POST['delete_words']; if(isset($_POST['old_key'])) { $old_key = $_POST['old_key']; } if ($delete_words=='ON'){ /** * $delete_words is passed via the query_string. If it's set, then * the user asked to delete the file. Erase the bastard and hope * this never happens again. */ sqspell_deleteWords(); /** * See where we were called from -- pop-up window or options page * and call whichever wrapper is appropriate. * I agree, this is dirty. TODO: make it so it's not dirty. */ if (strstr($SCRIPT_NAME, 'sqspell_options')){ $msg='

' . _("Your personal dictionary was erased.") . '

'; sqspell_makePage(_("Dictionary Erased"), null, $msg); } else { /** * The _("Your....") has to be on one line. Otherwise xgettext borks * on getting the strings. */ $msg = '

' . _("Your personal dictionary was erased. Please close this window and click \"Check Spelling\" button again to start your spellcheck over.") . '

' . '

' . '' . '

'; sqspell_makeWindow(null, _("Dictionary Erased"), null, $msg); } exit; } if ($old_key){ /** * User provided another key to try and decrypt the dictionary. * Call sqspell_getWords. If this key fails, the function will * handle it. */ $words=sqspell_getWords(); /** * It worked! Pinky, you're a genius! * Write it back this time encrypted with a new key. */ sqspell_writeWords($words); /** * See where we are and call a necessary GUI-wrapper. * Also dirty. TODO: Make this not dirty. */ if (strstr($SCRIPT_NAME, 'sqspell_options')){ $msg = '

' . _("Your personal dictionary was re-encrypted successfully. Now return to the "SpellChecker options" menu and make your selection again." ) . '

'; sqspell_makePage(_("Successful re-encryption"), null, $msg); } else { $msg = '

' . _("Your personal dictionary was re-encrypted successfully. Please close this window and click \"Check Spelling\" button again to start your spellcheck over.") . '

'; sqspell_makeWindow(null, _("Dictionary re-encrypted"), null, $msg); } exit; } /** * For Emacs weenies: * Local variables: * mode: php * End: * vim: syntax=php */ ?>squirrelmail/plugins/squirrelspell/modules/init.mod0000644000175000017500000000350011700173711022312 0ustar thijsthijs * @version $Id: init.mod 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ /** * See if we need to give user the option of choosing which dictionary * s/he wants to use to spellcheck his message. */ $langs=sqspell_getSettings(null); $msg = '
' . '' . '' . '

'; if (sizeof($langs)==1){ /** * Only one dictionary defined by the user. Submit the form * automatically. */ $onload="sqspell_init(true)"; $msg .= _("Please wait, communicating with the server...") . '

' . ""; } else { /** * More than one dictionary. Let the user choose the dictionary first * then manually submit the form. */ $onload="sqspell_init(false)"; $msg .= _("Please choose which dictionary you would like to use to spellcheck this message:") . '

' . '' . '' . '

'; } $msg .="
\n"; sqspell_makeWindow($onload, _("SquirrelSpell Initiating"), "init.js", $msg); /** * For the Emacs weenies: * Local variables: * mode: php * End: * vim: syntax=php */ ?>squirrelmail/plugins/squirrelspell/modules/options_main.mod0000644000175000017500000000300411700173711024045 0ustar thijsthijs * @version $Id: options_main.mod 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ global $SQSPELL_APP; $msg = '

' . _("Please choose which options you wish to set up:") . '

' . '\n"; sqspell_makePage( _("SquirrelSpell Options Menu"), null, $msg); /** * For Emacs weenies: * Local variables: * mode: php * End: * vim: syntax=php */ ?>squirrelmail/plugins/squirrelspell/modules/index.php0000644000175000017500000000077011700173711022474 0ustar thijsthijssquirrelmail/plugins/squirrelspell/modules/forget_me.mod0000644000175000017500000000466311700173711023331 0ustar thijsthijs * @version $Id: forget_me.mod 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ global $SQSPELL_VERSION; $words_ary = $_POST['words_ary']; $sqspell_use_app = $_POST['sqspell_use_app']; /** * If something needs to be deleted, then $words_ary will be * non-zero length. */ if (sizeof($words_ary)){ $words=sqspell_getWords(); $lang_words = sqspell_getLang($words, $sqspell_use_app); $msg = '

' . sprintf(_("Deleting the following entries from %s dictionary:"), ''.$sqspell_use_app.'') . '

' . "
    \n"; for ($i=0; $i\n"; } $new_words_ary=split("\n", $lang_words); /** * Wipe this lang, if only 2 members in array (no words left). * # Language * # End */ if (sizeof($new_words_ary)<=2) { $lang_words=''; } $new_lang_words = $lang_words; /** * Write the dictionary back to the disk. */ $langs=sqspell_getSettings($words); $words_dic = "# SquirrelSpell User Dictionary $SQSPELL_VERSION\n# " . "Last Revision: " . date("Y-m-d") . "\n# LANG: " . join(", ", $langs) . "\n"; for ($i=0; $i\n"; sqspell_makePage(_("Personal Dictionary Updated"), null, $msg); } else { /** * Click on some words first, Einstein! */ sqspell_makePage(_("Personal Dictionary"), null, '

    ' . _("No changes requested.") . '

    '); } /** * For Emacs weenies: * Local variables: * mode: php * End: * vim: syntax=php */ ?>squirrelmail/plugins/squirrelspell/modules/lang_change.mod0000644000175000017500000000570411700173711023605 0ustar thijsthijs * @version $Id: lang_change.mod 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ if (!sqgetGlobalVar('smtoken',$submitted_token, SQ_POST)) { $submitted_token = ''; } sm_validate_security_token($submitted_token, 3600, TRUE); global $SQSPELL_APP_DEFAULT; $use_langs = $_POST['use_langs']; $lang_default = $_POST['lang_default']; $words = sqspell_getWords(); if (!$words) { $words = sqspell_makeDummy(); } $langs = sqspell_getSettings($words); if (sizeof($use_langs)){ /** * See if the user clicked any options on the previous page. */ if (sizeof($use_langs)>1){ /** * See if s/he wants more than one dictionary. */ if ($use_langs[0]!=$lang_default){ /** * See if we need to juggle the order of the dictionaries * to make the default dictionary first in line. */ if (in_array($lang_default, $use_langs)){ /** * See if the user was dumb and chose a default dictionary * to be something other than the ones he selected. */ $hold = array_shift($use_langs); $lang_string = join(", ", $use_langs); $lang_string = str_replace("$lang_default", "$hold", $lang_string); $lang_string = $lang_default . ", " . $lang_string; } else { /** * Yes, he is dumb. */ $lang_string = join(', ', $use_langs); } } else { /** * No need to juggle the order -- preferred is already first. */ $lang_string = join(', ', $use_langs); } } else { /** * Just one dictionary, please. */ $lang_string = $use_langs[0]; } $lang_array = explode( ',', $lang_string ); $dsp_string = ''; foreach( $lang_array as $a) { $dsp_string .= _(htmlspecialchars(trim($a))) . _(", "); } $dsp_string = substr( $dsp_string, 0, -2 ); $msg = '

    ' . sprintf(_("Settings adjusted to: %s with %s as default dictionary."), ''.$dsp_string.'', ''._(htmlspecialchars($lang_default)).'') . '

    '; } else { /** * No dictionaries selected. Use system default. */ $msg = '

    ' . sprintf(_("Using %s dictionary (system default) for spellcheck." ), ''.$SQSPELL_APP_DEFAULT.'') . '

    '; $lang_string = $SQSPELL_APP_DEFAULT; } $old_lang_string = join(", ", $langs); $words = str_replace("# LANG: $old_lang_string", "# LANG: $lang_string", $words); /** * Write it down where the sun don't shine. */ sqspell_writeWords($words); sqspell_makePage(_("International Dictionaries Preferences Updated"), null, $msg); /** * For Emacs weenies: * Local variables: * mode: php * End: * vim: syntax=php */ squirrelmail/plugins/squirrelspell/modules/.htaccess0000644000175000017500000000001607430021442022441 0ustar thijsthijsDeny from All squirrelmail/plugins/squirrelspell/modules/enc_setup.mod0000644000175000017500000001070311700173711023337 0ustar thijsthijs * @version $Id: enc_setup.mod 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ global $SQSPELL_CRYPTO; /** * Set up some i18n'able wrappers for javascript. */ $msg = '"; $words=sqspell_getWords(); /** * When getting the user dictionary, the SQSPELL_CRYPTO flag will be * set to "true" if the dictionary is encrypted, or "false" if it is * in plain text. */ if ($SQSPELL_CRYPTO){ /** * Current format is encrypted. * Unfortunately, the following text needs to be all on one line, * unless someone fixes xgettext. ;( */ $msg .= '

    ' . _("Your personal dictionary is currently encrypted.") . '

    ' . _("This helps protect your privacy in case the web-mail system gets compromized and your personal dictionary ends up stolen. It is currently encrypted with the password you use to access your mailbox, making it hard for anyone to see what is stored in your personal dictionary.") . '

    ' . '' . _("ATTENTION:") . '
    ' . _("If you forget your password, your personal dictionary will become unaccessible, since it can no longer be decrypted. If you change your mailbox password, SquirrelSpell will recognize it and prompt you for your old password in order to re-encrypt the dictionary with a new key.") . '

    ' . '
    ' . '' . '

    ' . _("Please decrypt my personal dictionary and store it in a clear-text format." ) . '

    ' . '

    ' . '
    '; } else { /** * Current format is clear text. * Unfortunately, the following text needs to be all on one line, * unless someone fixes xgettext. ;( */ $msg .= '

    ' . _("Your personal dictionary is currently not encrypted.") . '

    ' . _("You may wish to encrypt your personal dictionary to protect your privacy in case the webmail system gets compromized and your personal dictionary file gets stolen. When encrypted, the file's contents look garbled and are hard to decrypt without knowing the correct key (which is your mailbox password).") . '

    ' . '' . _("ATTENTION:") . '
    ' . _("If you decide to encrypt your personal dictionary, you must remember that it gets "hashed" with your mailbox password. If you forget your mailbox password and the administrator changes it to a new value, your personal dictionary will become useless and will have to be created anew. However, if you or your system administrator change your mailbox password but you still have the old password at hand, you will be able to enter the old key to re-encrypt the dictionary with the new value.") . '

    ' . '
    ' . '' . '

    ' . _("Please encrypt my personal dictionary and store it in an encrypted format.") . '

    ' . '

    ' . '
    '; } sqspell_makePage(_("Personal Dictionary Crypto Settings"), "crypto_settings.js", $msg); /** * For Emacs weenies: * Local variables: * mode: php * End: * vim: syntax=php */ ?>squirrelmail/plugins/squirrelspell/modules/lang_setup.mod0000644000175000017500000000337711700173711023524 0ustar thijsthijs * @version $Id: lang_setup.mod 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ global $SQSPELL_APP; $msg = '

    ' . _("Please check any available international dictionaries which you would like to use when spellchecking:") . '

    ' . '
    ' . '' . '' . '

    '; /** * Present a nice listing. */ $langs = sqspell_getSettings(null); $add = '

    ' . _("Make this dictionary my default selection:") . " \n"; $add .= "" . _($avail_lang) . "\n"; } $msg .= "

    \n" . $add . "\n"; $msg .= "

    "; sqspell_makePage(_("Add International Dictionaries"), null, $msg); /** * For Emacs weenies: * Local variables: * mode: php * End: * vim: syntax=php */ ?>squirrelmail/plugins/squirrelspell/modules/forget_me_not.mod0000644000175000017500000000437111700173711024205 0ustar thijsthijs * @version $Id: forget_me_not.mod 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ global $SQSPELL_VERSION, $SQSPELL_APP_DEFAULT; $words = $_POST['words']; $sqspell_use_app = $_POST['sqspell_use_app']; /** * Because of the nature of Javascript, there is no way to efficiently * pass an array. Hence, the words will arrive as a string separated by * "%". To get the array, we explode the "%"'s. * Dirty: yes. Is there a better solution? Let me know. ;) */ $new_words = ereg_replace("%", "\n", $words); /** * Load the user dictionary and see if there is anything in it. */ $words=sqspell_getWords(); if (!$words){ /** * First time. */ $words_dic="# SquirrelSpell User Dictionary $SQSPELL_VERSION\n# Last " . "Revision: " . date("Y-m-d") . "\n# LANG: $SQSPELL_APP_DEFAULT\n# $SQSPELL_APP_DEFAULT\n"; $words_dic .= $new_words . "# End\n"; } else { /** * Do some fancy stuff in order to save the dictionary and not mangle the * rest. */ $langs=sqspell_getSettings($words); $words_dic = "# SquirrelSpell User Dictionary $SQSPELL_VERSION\n# " . "Last Revision: " . date("Y-m-d") . "\n# LANG: " . join(", ", $langs) . "\n"; for ($i=0; $i
'; sqspell_makeWindow($onload, _("Personal Dictionary Updated"), null, $msg); squirrelmail/plugins/squirrelspell/modules/edit_dic.mod0000644000175000017500000000616411700173711023124 0ustar thijsthijs * @version $Id: edit_dic.mod 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ global $color; /** * Get the user dictionary and see if it's empty or not. */ $words=sqspell_getWords(); if (!$words){ /** * Agt. Smith: "You're empty." * Neo: "So are you." */ sqspell_makePage(_("Personal Dictionary"), null, '

' . _("No words in your personal dictionary.") . '

'); } else { /** * We're loaded with booty. */ $pre_msg = '

' . _("Please check any words you wish to delete from your dictionary.") . "

\n"; $pre_msg .= "\n"; /** * Get how many dictionaries this user has defined. */ $langs=sqspell_getSettings($words); for ($i=0; $i' . '' . "\n"; } } /** * Check if all dictionaries were empty. */ if (empty($msg)) { $msg = '

' . _("No words in your personal dictionary.") . '

'; } else { $msg .= '
" . sprintf( _("%s dictionary"), $langs[$i] ) . '
' . '
' . '' . '' . '' . '' . "
\n"; $words_ary=explode("\n", $lang_words); /** * There are two lines we need to remove: * 1st: # Language * last: # End */ array_pop($words_ary); array_shift($words_ary); /** * Do some fancy stuff to separate the words into three * columns. */ for ($j=0; $j\n"; } $msg .= ' ' . htmlspecialchars($words_ary[$j])."
\n"; } $msg .= '
" . '' . '

' . "
'; } sqspell_makePage(_("Edit your Personal Dictionary"), null, $msg); } /** * For Emacs weenies: * Local variables: * mode: php * End: * vim: syntax=php */ squirrelmail/plugins/squirrelspell/modules/WHATISTHIS0000644000175000017500000000012107367712715022275 0ustar thijsthijssquirrelspell/modules This is where the loadable modules for SquirrelSpell are. squirrelmail/plugins/squirrelspell/modules/crypto.mod0000644000175000017500000000373711700173711022703 0ustar thijsthijs * @version $Id: crypto.mod 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ /** * Declaring globals for E_ALL */ global $SQSPELL_CRYPTO; switch ($_POST['action']){ case 'encrypt': /** * Let's encrypt the file and save it in an encrypted format. */ $words=sqspell_getWords(); /** * Flip the flag so the sqspell_writeWords function knows to encrypt * the message before writing it to the disk. */ $SQSPELL_CRYPTO=true; /** * Call the function that does the actual encryption_decryption. */ sqspell_writeWords($words); $msg='

' . _("Your personal dictionary has been encrypted and is now stored in an encrypted format.") . '

'; break; case 'decrypt': /** * Let's decrypt the file and save it as plain text. */ $words=sqspell_getWords(); /** * Flip the flag and tell the sqspell_writeWords() function that we * want to save it plaintext. */ $SQSPELL_CRYPTO=false; sqspell_writeWords($words); $msg='

' . _("Your personal dictionary has been decrypted and is now stored as plain text.") . '

'; break; case '': /** * Wait, this shouldn't happen! :) */ $msg = '

'._("No action requested.").'

'; break; } sqspell_makePage( _("Personal Dictionary Crypto Settings"), null, $msg); /** * For Emacs weenies: * Local variables: * mode: php * End: * vim: syntax=php */ ?>squirrelmail/plugins/squirrelspell/sqspell_interface.php0000644000175000017500000000265211700173711023421 0ustar thijsthijs * @version $Id: sqspell_interface.php 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ /** * Load the stuff needed from SquirrelMail * @ignore */ define('SM_PATH','../../'); /* SquirrelMail required files. */ require_once(SM_PATH . 'include/validate.php'); require_once(SM_PATH . 'include/load_prefs.php'); /** * Set up a couple of non-negotiable constants and * defaults. Don't change these, * the setuppable stuff is in * sqspell_config.php */ $SQSPELL_DIR='plugins/squirrelspell/'; $SQSPELL_CRYPTO=FALSE; require_once(SM_PATH . $SQSPELL_DIR . 'sqspell_config.php'); require_once(SM_PATH . $SQSPELL_DIR . 'sqspell_functions.php'); /** * $MOD is the name of the module to invoke. * If $MOD is unspecified, assign "init" to it. Else check for * security breach attempts. */ if(isset($_POST['MOD'])) { $MOD = $_POST['MOD']; } elseif (isset($_GET['MOD'])) { $MOD = $_GET['MOD']; } if (!isset($MOD) || !$MOD){ $MOD='init'; } else { sqspell_ckMOD($MOD); } /* Include the module. */ require_once(SM_PATH . $SQSPELL_DIR . "modules/$MOD.mod"); ?>squirrelmail/plugins/squirrelspell/sqspell_options.php0000644000175000017500000000270711700173711023155 0ustar thijsthijs * @version $Id: sqspell_options.php 14248 2012-01-02 00:18:17Z pdontthink $ * @package plugins * @subpackage squirrelspell */ /** * Load some necessary stuff from SquirrelMail. * @ignore */ define('SM_PATH','../../'); /* SquirrelMail required files. */ require_once(SM_PATH . 'include/validate.php'); require_once(SM_PATH . 'include/load_prefs.php'); require_once(SM_PATH . 'functions/strings.php'); require_once(SM_PATH . 'functions/page_header.php'); /** * Set a couple of constants and defaults. Don't change these, * the configurable stuff is in sqspell_config.php */ $SQSPELL_DIR='plugins/squirrelspell/'; $SQSPELL_CRYPTO=FALSE; require_once(SM_PATH . $SQSPELL_DIR . 'sqspell_config.php'); require_once(SM_PATH . $SQSPELL_DIR . 'sqspell_functions.php'); /** * $MOD is the name of the module to invoke. * If $MOD is unspecified, assign "options_main" to it. Else check for * security breach attempts. */ if(isset($_POST['MOD'])) { $MOD = $_POST['MOD']; } elseif (isset($_GET['MOD'])) { $MOD = $_GET['MOD']; } if(!isset($MOD) || !$MOD) { $MOD = 'options_main'; } else { sqspell_ckMOD($MOD); } /* Load the stuff already. */ require_once(SM_PATH . $SQSPELL_DIR . "modules/$MOD.mod"); ?>squirrelmail/plugins/squirrelspell/sqspell_config.php0000644000175000017500000000203011700173711022714 0ustar thijsthijs 'ispell -a', * 'Spanish' => 'ispell -d spanish -a' ); * You can replace ispell with aspell keeping the same commandline: * $SQSPELL_APP = array( 'English' => 'aspell -a', * 'Spanish' => 'aspell -d spanish -a' ); */ $SQSPELL_APP = array('English' => 'ispell -a', 'Spanish' => 'ispell -d spanish -a'); $SQSPELL_APP_DEFAULT = 'English'; $SQSPELL_WORDS_FILE = getHashedFile($username, $data_dir, "$username.words"); $SQSPELL_EREG = 'ereg'; ?>squirrelmail/plugins/squirrelspell/INSTALL0000644000175000017500000000367111700173711020240 0ustar thijsthijsSquirrelSpell plugin -------------------- Modify the sqspell_config.php file making sure you have ispell or aspell available on your system and located in PHP's path. The squirrelspell doesn't check for that and if it is not available, you're just going to get a "No errors found" message every time. :) Quite pleasing, but not very useful. Read files in "doc" directory -- they explain some features. Enable the plugin either by hand or by running the configure script from your SquirrelMail install directory. NOTE: If you are using php >= 4.3.0 squirrelspell should work in safe mode. Otherwise, you may have to disable safe mode for the squirrelspell directory. APACHE CONF EXAMPLE: php_admin_value safe_mode 0 Enjoy and report bugs. ;) This is an options commented sqspell_config.php 'ispell -a', 'Spanish' => 'ispell -d spanish -a'); /** * Default dictionary */ $SQSPELL_APP_DEFAULT = 'English'; /** * File that stores user's dictionary * * This setting is used only when squirrelspell is upgraded from * older setup. Since 1.5.1 SquirrelSpell stores all settings in * same place that stores other SquirrelMail user preferences. */ $SQSPELL_WORDS_FILE = getHashedFile($username, $data_dir, "$username.words"); squirrelmail/plugins/squirrelspell/js/0000755000175000017500000000000011737431041017617 5ustar thijsthijssquirrelmail/plugins/squirrelspell/js/check_me.js0000644000175000017500000002110711700173711021711 0ustar thijsthijs/** * check_me.js * * Copyright (c) 1999-2012 The SquirrelMail Project Team * Licensed under the GNU GPL. For full terms see the file COPYING. * * This JavaScript app is the driving power of the SquirrelSpell's * main spellchecker window. Hope you have as much pain figuring * it out as it took to write. ;)) * * $Id: check_me.js 14248 2012-01-02 00:18:17Z pdontthink $ */ var CurrentError=0; var CurrentLocation=0; var CurrentLine; var CurrentSymbol; var ChangesMade=false; /** * This function loads spellchecking errors into the form * displayed to the user. * * @return void */ function populateSqspellForm(){ CurrentWord=Word=misses[CurrentError]; WordLocations = locations[CurrentError].split(", "); CurrentLoc = WordLocations[CurrentLocation]; if(CurrentLocation==WordLocations.length-1) { CurrentLocation=0; } else { CurrentLocation++; } tmp = CurrentLoc.split(":"); CurrentLine=parseInt(tmp[0]); CurrentSymbol=parseInt(tmp[1]); document.forms[0].sqspell_error.value=Word; LineValue=sqspell_lines[CurrentLine]; StartWith=0; NewLineValue=""; if (CurrentSymbol > 40){ StartWith=CurrentSymbol-40; NewLineValue = "..."; } EndWith=LineValue.length; EndLine=""; if (EndWith > CurrentSymbol + 40){ EndWith=CurrentSymbol+40; EndLine="..."; } NewLineValue+=LineValue.substring(StartWith, CurrentSymbol) + "*" + Word + "*" + LineValue.substring(CurrentSymbol + Word.length, EndWith) + EndLine; document.forms[0].sqspell_line_area.value=NewLineValue; if (suggestions[CurrentError]){ WordSuggestions = suggestions[CurrentError].split(", "); for (i=0; i= 0){ allLoc = locations[i].split(", "); for (j=0; j lSymbol){ tmp[1] = tmp[1] + difference; allLoc[j] = tmp.join(":"); } } } locations[i] = allLoc.join(", "); } } } /** * This function writes the changes back into the compose form. * * @return void */ function sqspellCommitChanges(){ newSubject = sqspell_lines[0]; newBody = ""; for (i=1; isquirrelmail/plugins/squirrelspell/js/decrypt_error.js0000644000175000017500000000123407426136761023053 0ustar thijsthijs/** * decrypt_error.js * ----------------- * Some client-side form-checks. Trivial stuff. * * $Id: decrypt_error.js 2301 2002-01-31 03:45:53Z graf25 $ * * @author Konstantin Riabitsev ($Author: graf25 $) * @version $Date: 2002-01-31 04:45:53 +0100 (Thu, 31 Jan 2002) $ */ function AYS(){ if (document.forms[0].delete_words.checked && document.forms[0].old_key.value){ alert (ui_candel); return false; } if (!document.forms[0].delete_words.checked && !document.forms[0].old_key.value){ alert(ui_choice); return false; } if (document.forms[0].delete_words.checked) return confirm(ui_willdel); return true; } squirrelmail/plugins/squirrelspell/js/WHATISTHIS0000644000175000017500000000010407367712715021242 0ustar thijsthijssquirrelspell/js These are javascript files used by SquirrelSpell. squirrelmail/plugins/squirrelspell/js/init.js0000644000175000017500000000137011700173711021116 0ustar thijsthijs/** * init.js * * Copyright (c) 1999-2012 The SquirrelMail Project Team * Licensed under the GNU GPL. For full terms see the file COPYING. * * Grabs the text from the SquirrelMail field and submits it to * the squirrelspell. * * $Id: init.js 14248 2012-01-02 00:18:17Z pdontthink $ */ /** * This is the work function. * * @param flag tells the function whether to automatically submit the * form, or wait for user input. True submits the form, while * false doesn't. * @return void */ function sqspell_init(flag){ textToSpell = opener.document.compose.subject.value + "\n" + opener.document.compose.body.value; document.forms[0].sqspell_text.value = textToSpell; if (flag) document.forms[0].submit(); } squirrelmail/plugins/squirrelspell/js/crypto_settings.js0000644000175000017500000000125207426136761023430 0ustar thijsthijs/** * crypto_settings.js * ------------------- * Some client-side checks. Nothing fancy. * * $Id: crypto_settings.js 2301 2002-01-31 03:45:53Z graf25 $ * * @author Konstantin Riabitsev ($Author: graf25 $) * @version $Date: 2002-01-31 04:45:53 +0100 (Thu, 31 Jan 2002) $ */ /** * This function is the only thing. It is called on form submit and * asks the user some questions. */ function checkMe(){ if (!document.forms[0].action.checked){ alert (ui_makesel); return false; } if (document.forms[0].action.value=="encrypt") cmsg=ui_encrypt; if (document.forms[0].action.value=="decrypt") cmsg=ui_decrypt; return confirm(cmsg); } squirrelmail/plugins/spamcop/0000755000175000017500000000000011737431041015737 5ustar thijsthijssquirrelmail/plugins/spamcop/spamcop.php0000644000175000017500000001626511700173711020121 0ustar thijsthijsparent; } if ($response == 'OK') { $subject = encodeHeader($message->rfc822_header->subject); array_shift($body_a); $body = implode('', $body_a) . "\r\n"; $full_localfilename = "$hashed_attachment_dir/$localfilename"; $fp = fopen( $full_localfilename, 'w'); fwrite ($fp, $body); fclose($fp); $composeMessage->initAttachment('message/rfc822','email.txt', $localfilename); } return $composeMessage; } /* GLOBALS */ sqgetGlobalVar('username', $username, SQ_SESSION); sqgetGlobalVar('key', $key, SQ_COOKIE); sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION); sqgetGlobalVar('mailbox', $mailbox, SQ_GET); sqgetGlobalVar('passed_id', $passed_id, SQ_GET); if (! sqgetGlobalVar('startMessage', $startMessage, SQ_GET) ) { $startMessage = 1; } if (! sqgetGlobalVar('passed_ent_id', $passed_ent_id, SQ_GET) ) { $passed_ent_id = 0; } sqgetGlobalVar('compose_messages', $compose_messages, SQ_SESSION); if(! sqgetGlobalVar('composesession', $composesession, SQ_SESSION) ) { $composesession = 0; sqsession_register($composesession, 'composesession'); } /* END GLOBALS */ displayPageHeader($color, $mailbox); $imap_stream = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0); sqimap_mailbox_select($imap_stream, $mailbox); if ($spamcop_method == 'quick_email' || $spamcop_method == 'thorough_email') { // Use email-based reporting -- save as an attachment $session = "$composesession"+1; $composesession = $session; sqsession_register($composesession,'composesession'); if (!isset($compose_messages)) { $compose_messages = array(); } if (!isset($compose_messages[$session]) || ($compose_messages[$session] == NULL)) { $composeMessage = new Message(); $rfc822_header = new Rfc822Header(); $composeMessage->rfc822_header = $rfc822_header; $composeMessage->reply_rfc822_header = ''; $compose_messages[$session] = $composeMessage; sqsession_register($compose_messages,'compose_messages'); } else { $composeMessage=$compose_messages[$session]; } $message = sqimap_get_message($imap_stream, $passed_id, $mailbox); $composeMessage = getMessage_RFC822_Attachment($message, $composeMessage, $passed_id, $passed_ent_id, $imap_stream); $compose_messages[$session] = $composeMessage; sqsession_register($compose_messages, 'compose_messages'); $fn = getPref($data_dir, $username, 'full_name'); $em = getPref($data_dir, $username, 'email_address'); $HowItLooks = $fn . ' '; if ($em != '') $HowItLooks .= '<' . $em . '>'; } echo "

"; echo _("Sending this spam report will give you back a reply with URLs that you can click on to properly report this spam message to the proper authorities. This is a free service. By pressing the \"Send Spam Report\" button, you agree to follow SpamCop's rules/terms of service/etc."); echo "

"; ?>
\n"; echo '\n"; } else { ?>
\n"; } ?>
\n"; } else { $spam_message = mime_fetch_body ($imap_stream, $passed_id, $passed_ent_id, 50000); if (strlen($spam_message) == 50000) { $Warning = "\n[truncated by SpamCop]\n"; $spam_message = substr($spam_message, 0, 50000 - strlen($Warning)) . $Warning; } if (isset($js_web) && $js_web) { ?> "; } ?>
squirrelmail/plugins/spamcop/setup.php0000644000175000017500000001266211700173711017614 0ustar thijsthijs\n"; /* Catch situation when user use quick_email and does not update preferences. User gets web_form link. If prefs are set to quick_email format - they will be updated after clicking the link */ if (! $spamcop_quick_report && $spamcop_method=='quick_email') { $spamcop_method = 'web_form'; } if ($spamcop_method == 'web_form') { ?> _("SpamCop - Spam Reporting"), 'url' => '../plugins/spamcop/options.php', 'desc' => _("Help fight the battle against unsolicited email. SpamCop reads the spam email and determines the correct addresses to send complaints to. Quite fast, really smart, and easy to use."), 'js' => false ); } // When we send the email, we optionally trash it then too function spamcop_while_sending() { global $mailbox, $spamcop_delete, $auto_expunge, $username, $key, $imapServerAddress, $imapPort; // load sqgetGlobalVar() include_once(SM_PATH . 'functions/global.php'); // check if compose.php is called by spamcop plugin if (sqgetGlobalVar('spamcop_is_composing' , $spamcop_is_composing)) { if ($spamcop_delete) { $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0); sqimap_mailbox_select($imapConnection, $mailbox); sqimap_msgs_list_delete($imapConnection, $mailbox, $spamcop_is_composing); if ($auto_expunge) sqimap_mailbox_expunge($imapConnection, $mailbox, true); } // change default email composition setting. Plugin always operates in right frame. // make sure that compose.php redirects to right page. Temporally override. global $compose_new_win; $compose_new_win = false; } } squirrelmail/plugins/spamcop/index.php0000644000175000017500000000076211700173711017561 0ustar thijsthijssquirrelmail/plugins/spamcop/README0000644000175000017500000000235510645123115016621 0ustar thijsthijsSpamCop Reporting Helps you identify spam and send a proper message to the correct address to SpamCop. (See http://spamcop.net/ for more information) Features ======== * Quick one-click interface to report spam via email * Alternate, but immediate form-based processing Description =========== Tired of getting spam? SpamCop helps you report it to the proper people. It even creates spam reports and will mail them off for you. All that is required to send a spam report is about a few seconds of your time and about five clicks. It is strongly suggested you set up a mail forwarder account and have it forwarded to your current mailbox. Sometimes mail reported with SpamCop gets on weird spam mailing lists. If your happens to get on the list, you can then just delete the forwarder and get a new one. Make sure to use the forwarder to sign up for SpamCop and get the required information for the plugin. Installation ============ Go back to the main directory, run configure and add the plugin. API === SquirrelMail hooks used by plugin: * loading_prefs * optpage_register_block * read_body_header_right * compose_send Plugin preference keys: * spamcop_enabled * spamcop_delete * spamcop_save * spamcop_method * spamcop_type * spamcop_id squirrelmail/plugins/spamcop/options.php0000644000175000017500000001771611700173711020154 0ustar thijsthijs" . _("Disable it") . ")\n"; } else { $ret = _("Disabled") . " (" . _("Enable it") . ")\n"; } return $ret; } displayPageHeader($color, 'None'); /* globals */ sqgetGlobalVar('action', $action); sqgetGlobalVar('meth', $meth); sqgetGlobalVar('ID' , $ID); sqgetGlobalVar('username', $username, SQ_SESSION); /* end of globals */ $action = (!isset($action) ? '' : $action); switch ($action) { case 'enable': setPref($data_dir, $username, 'spamcop_enabled', 1); break; case 'disable': setPref($data_dir, $username, 'spamcop_enabled', ''); break; case 'save': setPref($data_dir, $username, 'spamcop_delete', ''); break; case 'delete': setPref($data_dir, $username, 'spamcop_delete', 1); break; case 'meth': if (isset($meth)) { setPref($data_dir, $username, 'spamcop_method', $meth); } break; case 'save_id': if (isset($ID)) { $ID = trim($ID); $ID = preg_replace('/@.*/','',$ID); $ID = preg_replace('/.*\./','',$ID); setPref($data_dir, $username, 'spamcop_id', $ID); } break; } global $spamcop_enabled, $spamcop_delete, $spamcop_quick_report; spamcop_load(); ?>

\n" . '(' . _("Only works with email-based reporting") . ')', 'right','','valign="top"'); echo html_tag('td', spamcop_enable_disable($spamcop_delete,'save','delete'),'','','valign="top"'); ?> " . '(' . _("see below") . ')','right','','valign="top"'); ?>
\n"; ?>
\n"; ?>
' . _("About SpamCop") . '
'; echo _("SpamCop is a free service that greatly assists in finding the true source of the spam and helps in letting the proper people know about the abuse."); echo "

\n"; echo '

'; printf(_("To use it, you must get a SpamCop authorization code. There is a free %ssign up page%s so you can use SpamCop."), '', ''); echo "

\n"; echo '

' . _("Before you sign up, be warned") . '
'; printf(_("Some users have reported that the email addresses used with SpamCop find their way onto spam lists. To be safe, you can just create an email forwarding account and have all SpamCop reports get sent to there. Also, if it gets flooded with spam, you can then just delete that account with no worries about losing your real email address. Just go create an email forwarder somewhere (%s has a %slist of places%s) so that messages from system administrators and what not can be sent to you."), 'Yahoo!', '', ''); echo "

\n"; echo '

'; echo _("Once you have signed up with SpamCop and have received your SpamCop authorization code, you need to enable this plugin by clicking the link above. Once enabled, you go about your normal life. If you encounter a spam message in your mailbox, just view it. On the right-hand side, near the top of where the message is displayed, you will see a link to report this message as spam. Clicking on it brings you to a confirmation page. Confirming that you want the spam report sent will do different things with different reporting methods."); echo "

\n"; echo '

' . _("Email-based reporting") . '
'; echo _("Pressing the button forwards the message to the SpamCop service and will optionally delete the message. From there, you just need to go to your INBOX and quite soon a message should appear from SpamCop. (It gets sent to the account you registered with, so make sure that your mail forwarder works!) Open it up, click on the appropriate link at the top, and a new browser window will open."); echo "

\n"; if ($spamcop_quick_report) { echo '

'; echo _("Currently, the quick reporting just forwards the request to the thorough reporting. Also, it appears that this is for members (non-free) only. Hopefully this will change soon."); echo "

\n"; } echo '

' . _("Web-based reporting") . '
'; echo _("When you press the button on the confirmation page, this will pop open a new browser window and the SpamCop service should appear inside. The message will not be deleted (working on that part), but you won't need to wait for a response email to start the spam reporting."); echo "

\n"; echo '

'; echo _("The SpamCop service will display information as it finds it, so scroll down until you see a form button. It might pause a little while it is looking up information, so be a little patient. Read what it says, and submit the spam. Close the browser window. Press Cancel or click on the appropriate mail folder to see messages and/or delete the spam."); echo "

\n"; echo '

' . _("SpamCop service type") . '
'; echo _("Service type option allows selecting which SpamCop services you are using. Member services use different web reporting forms and does not display nags. You can purchase these services, if you want to support SpamCop."); echo "

\n"; echo '

' . _("More information") . '
'; printf(_("For more information about SpamCop, it's services, spam in general, and many related topics, try reading through SpamCop's %sHelp and Feedback%s section."), '', ''); echo "

\n"; ?> squirrelmail/plugins/sent_subfolders/0000755000175000017500000000000011737431041017476 5ustar thijsthijssquirrelmail/plugins/sent_subfolders/setup.php0000644000175000017500000002731511700173711021354 0ustar thijsthijs 1)) { /* Chop up the folder strings as needed. */ $base_str = $sent_subfolders_base . $delimiter; $mbox_str = substr($args[1], 0, strlen($base_str)); /* Perform the comparison. */ $handleAsSent_result = ( $handleAsSent_result || ($base_str == $mbox_str) || ($sent_subfolders_base == $args[1]) ); } } /** * Loads sent_subfolders settings */ function sent_subfolders_load_prefs() { global $use_sent_subfolders, $data_dir, $username, $sent_folder, $sent_subfolders_setting, $sent_subfolders_base; $use_sent_subfolders = getPref ($data_dir, $username, 'use_sent_subfolders', SMPREF_OFF); $sent_subfolders_setting = getPref ($data_dir, $username, 'sent_subfolders_setting', SMPREF_SENT_SUBFOLDERS_DISABLED); $sent_subfolders_base = getPref ($data_dir, $username, 'sent_subfolders_base', $sent_folder); } /** * Adds sent_subfolders options in folder preferences */ function sent_subfolders_optpage_loadhook_folders() { global $optpage_data, $imapServerAddress, $imapPort; sqgetGlobalVar('username', $username, SQ_SESSION); sqgetGlobalVar('key', $key, SQ_COOKIE); /* Get some imap data we need later. */ $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0); $boxes = sqimap_mailbox_list($imapConnection); sqimap_logout($imapConnection); /* Load the Sent Subfolder Options into an array. */ $optgrp = _("Sent Subfolders Options"); $optvals = array(); $optvals[] = array( 'name' => 'sent_subfolders_setting', 'caption' => _("Use Sent Subfolders"), 'type' => SMOPT_TYPE_STRLIST, 'refresh' => SMOPT_REFRESH_FOLDERLIST, 'posvals' => array(SMPREF_SENT_SUBFOLDERS_DISABLED => _("Disabled"), SMPREF_SENT_SUBFOLDERS_MONTHLY => _("Monthly"), SMPREF_SENT_SUBFOLDERS_QUARTERLY => _("Quarterly"), SMPREF_SENT_SUBFOLDERS_YEARLY => _("Yearly")), 'save' => 'save_option_sent_subfolders_setting' ); $filtered_folders=array_filter($boxes, "filter_folders"); $sent_subfolders_base_values = array('whatever'=>$filtered_folders); $optvals[] = array( 'name' => 'sent_subfolders_base', 'caption' => _("Base Sent Folder"), 'type' => SMOPT_TYPE_FLDRLIST, 'refresh' => SMOPT_REFRESH_FOLDERLIST, 'posvals' => $sent_subfolders_base_values, 'save' => 'save_option_sent_subfolders_base', ); /* Add our option data to the global array. */ $optpage_data['grps'][SMOPT_GRP_SENT_SUBFOLDERS] = $optgrp; $optpage_data['vals'][SMOPT_GRP_SENT_SUBFOLDERS] = $optvals; } /** * Defines folder filtering rules * * Callback function that should exclude some folders from folder listing. * @param array $fldr list of folders. See sqimap_mailbox_list * @return boolean returns true, if folder has to included in folder listing * @access private */ function filter_folders($fldr) { return strtolower($fldr['unformatted'])!='inbox'; } /** * Saves sent_subfolder_options */ function save_option_sent_subfolders_setting($option) { global $data_dir, $username, $use_sent_subfolders, $sent_subfolders_base; /* Set use_sent_subfolders as either on or off. */ if ($option->new_value == SMPREF_SENT_SUBFOLDERS_DISABLED) { setPref($data_dir, $username, 'use_sent_subfolders', SMPREF_OFF); // for lack of anything better setPref($data_dir, $username, 'sent_folder', $sent_subfolders_base); } else { setPref($data_dir, $username, 'use_sent_subfolders', SMPREF_ON); setPref($data_dir, $username, 'move_to_sent', SMPREF_ON); } /* Now just save the option as normal. */ save_option($option); } /** * Update sent_subfolders settings * * function updates default sent folder value and * creates required imap folders */ function sent_subfolders_update_sentfolder() { global $sent_folder, $auto_create_special, $auto_create_done; global $sent_subfolders_base, $sent_subfolders_setting; global $data_dir, $imapServerAddress, $imapPort; global $use_sent_subfolders, $move_to_sent, $imap_server_type; sqgetGlobalVar('username', $username, SQ_SESSION); sqgetGlobalVar('key', $key, SQ_COOKIE); sqgetGlobalVar('delimiter', $delimiter, SQ_SESSION); if ($use_sent_subfolders || $move_to_sent) { $year = date('Y'); $month = date('m'); $quarter = sent_subfolder_getQuarter($month); /* Regarding the structure we've got three main possibilities. One sent holder. level 0. Multiple year holders with messages in it. level 1. Multiple year folders with holders in it. level 2. */ /* if( $imap_server_type == 'uw' ) { $cnd_delimiter = ''; } else { $cnd_delimiter = $delimiter; } */ $cnd_delimiter = $delimiter; switch ($sent_subfolders_setting) { case SMPREF_SENT_SUBFOLDERS_YEARLY: $level = 1; $sent_subfolder = $sent_subfolders_base . $cnd_delimiter . $year; break; case SMPREF_SENT_SUBFOLDERS_QUARTERLY: $level = 2; $sent_subfolder = $sent_subfolders_base . $cnd_delimiter . $year . $delimiter . $quarter; $year_folder = $sent_subfolders_base . $cnd_delimiter . $year; break; case SMPREF_SENT_SUBFOLDERS_MONTHLY: $level = 2; $sent_subfolder = $sent_subfolders_base . $cnd_delimiter . $year . $delimiter . $month; $year_folder = $sent_subfolders_base . $cnd_delimiter . $year; break; case SMPREF_SENT_SUBFOLDERS_DISABLED: default: $level = 0; $sent_subfolder = $sent_folder; $year_folder = $sent_folder; } /* If this folder is NOT the current sent folder, update stuff. */ if ($sent_subfolder != $sent_folder) { /* First, update the sent folder. */ setPref($data_dir, $username, 'sent_folder', $sent_subfolder); setPref($data_dir, $username, 'move_to_sent', SMPREF_ON); $sent_folder = $sent_subfolder; $move_to_sent = SMPREF_ON; /* Auto-create folders, if they do not yet exist. */ if ($sent_folder != 'none') { /* Create the imap connection. */ $ic = sqimap_login ($username, $key, $imapServerAddress, $imapPort, 10); /* Auto-create the year folder, if it does not yet exist. (only for monthly/quarterly modes */ if ($sent_subfolders_setting != SMPREF_SENT_SUBFOLDERS_YEARLY) { if (!sqimap_mailbox_exists($ic, $year_folder)) { sqimap_mailbox_create($ic, $year_folder, ($level==1)?'':'noselect'); } else if (!sqimap_mailbox_is_subscribed($ic, $year_folder)) { sqimap_subscribe($ic, $year_folder); } } /* Auto-create the subfolder, if it does not yet exist. */ if (!sqimap_mailbox_exists($ic, $sent_folder)) { sqimap_mailbox_create($ic, $sent_folder, ''); } else if (!sqimap_mailbox_is_subscribed($ic, $sent_subfolder)) { sqimap_subscribe($ic, $sent_subfolder); } /* Close the imap connection. */ sqimap_logout($ic); } } } } /** * Update the folder settings/auto-create new subfolder */ function save_option_sent_subfolders_base($option) { // first save the option as normal save_option($option); // now update folder settings and auto-create first subfolder if needed sent_subfolders_update_sentfolder(); } /** * Sets quarter subfolder names * * @param string $month numeric month * @return string quarter name (Q + number) */ function sent_subfolder_getQuarter($month) { switch ($month) { case '01': case '02': case '03': $result = '1'; break; case '04': case '05': case '06': $result = '2'; break; case '07': case '08': case '09': $result = '3'; break; case '10': case '11': case '12': $result = '4'; break; default: $result = 'ERR'; } /* Return the current quarter. */ return ('Q' . $result); } /** * detects if mailbox is part of sent_subfolders * * @param string $mb imap folder name * @return boolean 1 - is part of sent_subfolders, 0 - is not part of sent_subfolders */ function sent_subfolders_special_mailbox($mb) { global $data_dir, $username, $sent_folder; sqgetGlobalVar('delimiter', $delimiter, SQ_SESSION); /* if( $imap_server_type == 'uw' ) { $cnd_delimiter = ''; } else { $cnd_delimiter = $delimiter; } */ $cnd_delimiter = $delimiter; $use_sent_subfolders = getPref ($data_dir, $username, 'use_sent_subfolders', SMPREF_OFF); $sent_subfolders_base = getPref($data_dir, $username, 'sent_subfolders_base', $sent_folder); if ($use_sent_subfolders == SMPREF_ON && ($mb == $sent_subfolders_base || stristr($mb,$sent_subfolders_base. $cnd_delimiter) ) ) { return 1; } return 0; } squirrelmail/plugins/sent_subfolders/index.php0000644000175000017500000000077211700173711021321 0ustar thijsthijssquirrelmail/plugins/delete_move_next/0000755000175000017500000000000011737431041017623 5ustar thijsthijssquirrelmail/plugins/delete_move_next/setup.php0000644000175000017500000004052111700173711021473 0ustar thijsthijskey ' . $keys[$i] . ' msgid ' . $msgs[$keys[$i]]['ID'] . '

'; } } function delete_move_expunge_from_all($id) { global $msgs, $msort, $sort, $imapConnection, $mailbox, $uid_support; $delAt = -1; if(isset($msort) && count($msort) > 0) { for ($i = 0; $i < count($msort); $i++) { if ($msgs[$i]['ID'] == $id) { $delAt = $i; } elseif ($msgs[$i]['ID'] > $id) { if (!$uid_support) { $msgs[$i]['ID']--; } } } $msgs = delete_move_del_arr_elem($msgs, $delAt); $msort = delete_move_del_arr_elem($msort, $delAt); if ($sort < 6) { if ($sort % 2) { asort($msort); } else { arsort($msort); } } sqsession_register($msgs, 'msgs'); sqsession_register($msort, 'msort'); } sqimap_mailbox_expunge($imapConnection, $mailbox, true); } function delete_move_next_action() { if ( sqgetGlobalVar('unread_id', $unread_id, SQ_GET) ) { delete_move_next_unread(); } else if ( sqgetGlobalVar('delete_id', $delete_id, SQ_GET) ) { delete_move_next_delete(); fix_sort_array(); } else if ( sqgetGlobalVar('move_id', $move_id, SQ_POST) ) { delete_move_next_move(); fix_sort_array(); } } function delete_move_next_read_t() { global $delete_move_next_t; if($delete_move_next_t == 'on') { delete_move_next_read('top'); } } function delete_move_next_read_b() { global $delete_move_next_b; if ($delete_move_next_b != 'off') { delete_move_next_read('bottom'); } } function delete_move_next_read($currloc) { global $delete_move_next_formATtop, $delete_move_next_formATbottom, $color, $where, $what, $currentArrayIndex, $passed_id, $mailbox, $sort, $startMessage, $delete_id, $move_id, $base_uri, $imapConnection, $auto_expunge, $move_to_trash, $mbx_response, $uid_support, $passed_ent_id, $delete_move_next_show_unread; $urlMailbox = urlencode($mailbox); if (!isset($passed_ent_id)) $passed_ent_id = 0; if (!(($where && $what) || ($currentArrayIndex == -1)) && !$passed_ent_id) { $next = findNextMessage($passed_id); $prev = findPreviousMessage($mbx_response['EXISTS'], $passed_id); $prev_if_del = $prev; $next_if_del = $next; if (!$uid_support && ($auto_expunge || $move_to_trash)) { if ($prev_if_del > $passed_id) { $prev_if_del--; } if ($next_if_del > $passed_id) { $next_if_del--; } } /* Base is illegal within documents * $location = get_location(); * echo "" . */ echo ''. ''. "'; if ($next_if_del < 0) { $next_if_del = $prev_if_del; } if (($delete_move_next_formATtop == 'on') && ($currloc == 'top')) { if ($next_if_del > 0) { delete_move_next_moveNextForm($next_if_del); } else { delete_move_next_moveRightMainForm(); } } if (($delete_move_next_formATbottom != 'off') && ($currloc == 'bottom')) { if ($next_if_del > 0) { delete_move_next_moveNextForm($next_if_del); } else { delete_move_next_moveRightMainForm(); } } echo '
"; if ($prev > 0){ echo "" . _("Delete & Prev") . "" . " | "; if ($delete_move_next_show_unread == 'on') { echo "" . _("Unread & Prev") . "" . " | "; } } else { echo _("Delete & Prev") . " | "; if ($delete_move_next_show_unread == 'on') { echo _("Unread & Prev") . " | "; } } if ($next > 0){ if ($delete_move_next_show_unread == 'on') { echo "" . _("Unread & Next") . " | "; } echo "" . _("Delete & Next") . ""; } else { if ($delete_move_next_show_unread == 'on') { echo _("Unread & Next") . " | "; } echo _("Delete & Next"); } echo '
'; } } function get_move_target_list() { global $imapConnection, $lastTargetMailbox; if (isset($lastTargetMailbox) && !empty($lastTargetMailbox)) { echo sqimap_mailbox_option_list($imapConnection, array(strtolower($lastTargetMailbox))); } else { echo sqimap_mailbox_option_list($imapConnection); } } function delete_move_next_moveNextForm($next) { global $color, $where, $what, $currentArrayIndex, $passed_id, $mailbox, $sort, $startMessage, $delete_id, $move_id, $imapConnection, $base_uri; $urlMailbox = urlencode($mailbox); echo ''. "". "
". "". "". "". _("Move to:") . ' '. ''. ''. '
'. ''. ''; } function delete_move_next_moveRightMainForm() { global $color, $where, $what, $currentArrayIndex, $passed_id, $mailbox, $sort, $startMessage, $delete_id, $move_id, $imapConnection, $base_uri; $urlMailbox = urlencode($mailbox); echo '' . "". "
" . "". "". _("Move to:") . ' ' . ''. ''. '
' . ''. ''; } function delete_move_next_unread() { global $imapConnection; sqgetGlobalVar('unread_id', $unread_id, SQ_GET); if (!sqgetGlobalVar('smtoken',$submitted_token, SQ_GET)) { $submitted_token = ''; } // first, validate security token sm_validate_security_token($submitted_token, 3600, TRUE); sqimap_toggle_flag($imapConnection, $unread_id, '\\Seen', false, true); } function delete_move_next_delete() { global $imapConnection, $auto_expunge; sqgetGlobalVar('delete_id', $delete_id, SQ_GET); sqgetGlobalVar('mailbox', $mailbox, SQ_GET); if (!sqgetGlobalVar('smtoken',$submitted_token, SQ_GET)) { $submitted_token = ''; } // first, validate security token sm_validate_security_token($submitted_token, 3600, TRUE); sqimap_msgs_list_delete($imapConnection, $mailbox, $delete_id); if ($auto_expunge) { delete_move_expunge_from_all($delete_id); // sqimap_mailbox_expunge($imapConnection, $mailbox, true); } } function delete_move_next_move() { global $imapConnection, $mailbox, $auto_expunge, $lastTargetMailbox; sqgetGlobalVar('move_id', $move_id, SQ_POST); sqgetGlobalVar('mailbox', $mailbox, SQ_FORM); sqgetGlobalVar('targetMailbox', $targetMailbox, SQ_POST); if (!sqgetGlobalVar('smtoken',$submitted_token, SQ_POST)) { $submitted_token = ''; } // first, validate security token sm_validate_security_token($submitted_token, 3600, TRUE); // Move message sqimap_msgs_list_move($imapConnection, $move_id, $targetMailbox); if ($auto_expunge) { delete_move_expunge_from_all($move_id); // sqimap_mailbox_expunge($imapConnection, $mailbox, true); } if ($targetMailbox != $lastTargetMailbox) { $lastTargetMailbox = $targetMailbox; sqsession_register($lastTargetMailbox, 'lastTargetMailbox'); } } function delete_move_next_display_inside() { global $username,$data_dir, $delete_move_next_show_unread, $delete_move_next_t, $delete_move_next_formATtop, $delete_move_next_b, $delete_move_next_formATbottom; echo "" . html_tag('td',_("Delete/Unread/Move/Next Buttons:"),'right','','valign="top"') . "\n". '
'; echo '
'. '\n"; } function delete_move_next_display_save() { global $username,$data_dir; if ( sqgetGlobalVar('delete_move_next_ti', $delete_move_next_ti, SQ_POST) ) { setPref($data_dir, $username, 'delete_move_next_t', 'on'); } else { setPref($data_dir, $username, 'delete_move_next_t', "off"); } if ( sqgetGlobalVar('delete_move_next_formATtopi', $delete_move_next_formATtopi, SQ_POST) ) { setPref($data_dir, $username, 'delete_move_next_formATtop', 'on'); } else { setPref($data_dir, $username, 'delete_move_next_formATtop', "off"); } if ( sqgetGlobalVar('delete_move_next_bi', $delete_move_next_bi, SQ_POST) ) { setPref($data_dir, $username, 'delete_move_next_b', 'on'); } else { setPref($data_dir, $username, 'delete_move_next_b', "off"); } if ( sqgetGlobalVar('delete_move_next_formATbottomi', $delete_move_next_formATbottomi, SQ_POST) ) { setPref($data_dir, $username, 'delete_move_next_formATbottom', 'on'); } else { setPref($data_dir, $username, 'delete_move_next_formATbottom', "off"); } if ( sqgetGlobalVar('delete_move_next_show_unread', $delete_move_next_show_unread, SQ_POST) ) { setPref($data_dir, $username, 'delete_move_next_show_unread', 'on'); } else { setPref($data_dir, $username, 'delete_move_next_show_unread', "off"); } } function delete_move_next_loading_prefs() { global $username,$data_dir, $delete_move_next_show_unread, $delete_move_next_t, $delete_move_next_formATtop, $delete_move_next_b, $delete_move_next_formATbottom; $delete_move_next_t = getPref($data_dir, $username, 'delete_move_next_t'); $delete_move_next_b = getPref($data_dir, $username, 'delete_move_next_b'); $delete_move_next_formATtop = getPref($data_dir, $username, 'delete_move_next_formATtop'); $delete_move_next_formATbottom = getPref($data_dir, $username, 'delete_move_next_formATbottom'); $delete_move_next_show_unread = getPref($data_dir, $username, 'delete_move_next_show_unread'); } squirrelmail/plugins/delete_move_next/index.php0000644000175000017500000000077311700173711021447 0ustar thijsthijssquirrelmail/plugins/delete_move_next/README0000644000175000017500000000530010627537255020514 0ustar thijsthijsdelete_move_next -- Version 3.0 By Ben Brillat This is a modified version of Delete Move Next by Bryan Stalcup If you read the mail in your inbox starting with the most recent, this plugin is meant for you. It adds a set of mail management links across the bottom or top of the email. Features ======== * Saves you the need to scroll up to go to the previous or next email * Allows you to delete the current email and view the next or previous message in step * Allows you to move the current email to any mailbox and view the next Description =========== This plugin adds links to the message view for each message. The links include "Previous", "Next", "Delete & Previous", and "Delete & Next", which deletes the current email and displays the next email. Also included is a menu to move the current email to any folder and then display the next email. It helps me keep up with my constantly overflowing inbox. Future Work =========== * You tell me... Limitations (Known bugs) ======================== -If you delete or move an email, then use the "Message List" link at the top left of the header, the message list is pulled from cache, and does not reflect the deleted/moved email(s). To view the current list, click the mailbox link in the left-hand navigation bar. -"Delete & Prev" or "Delete & Next" can result in strange behavior when deleting the last or next to last message in a mailbox when using any sort order other than 0. It won't kill anything, you just might arrive at a message other than the one you were expecting to see. If anyone has any suggestions on this one, please let me know. Installation ============ See the "INSTALL" file. Changes ======= See the "CHANGELOG" file. New versions are available at: http://www.brillat.net/~ben/files/projects/squirrelmail/ Copyright ========= Copyright (C) 2001 Benjamin Brillat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program ("gpl.txt"); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA Contact ======= Let me know what you think: Ben Brillat 74 Punch Bowl Trail W. Kingston, RI 02892 USA squirrelmail/plugins/bug_report/0000755000175000017500000000000011737431042016446 5ustar thijsthijssquirrelmail/plugins/bug_report/setup.php0000644000175000017500000000175511700173711020323 0ustar thijsthijs $value) { if ($key != 0 || $value != '') { $str .= " * $key = $value\n"; } } if ($str == '') { return " * Nothing listed\n"; } return $str; } $browscap = ini_get('browscap'); if(!empty($browscap)) { $browser = get_browser(); } sqgetGlobalVar('HTTP_USER_AGENT', $HTTP_USER_AGENT, SQ_SERVER); if ( ! sqgetGlobalVar('HTTP_USER_AGENT', $HTTP_USER_AGENT, SQ_SERVER) ) $HTTP_USER_AGENT="Browser information is not available."; $body_top = "I subscribe to the squirrelmail-users mailing list.\n" . " [ ] True - No need to CC me when replying\n" . " [ ] False - Please CC me when replying\n" . "\n" . "This bug occurs when I ...\n" . " ... view a particular message\n" . " ... use a specific plugin/function\n" . " ... try to do/view/use ....\n" . "\n\n\n" . "The description of the bug:\n\n\n" . "I can reproduce the bug by:\n\n\n" . "(Optional) I got bored and found the bug occurs in:\n\n\n" . "(Optional) I got really bored and here's a fix:\n\n\n" . "----------------------------------------------\n" . "\nMy browser information:\n" . ' '.$HTTP_USER_AGENT . "\n" ; if(isset($browser)) { $body_top .= " get_browser() information (List)\n" . Show_Array((array) $browser); } $body_top .= "\nMy web server information:\n" . " PHP Version " . phpversion() . "\n" . " PHP Extensions (List)\n" . Show_Array(get_loaded_extensions()) . "\nSquirrelMail-specific information:\n" . " Version: $version\n" . " Plugins (List)\n" . Show_Array($plugins); if (isset($ldap_server) && $ldap_server[0] && ! extension_loaded('ldap')) { $warning = 1; $warnings['ldap'] = "LDAP server defined in SquirrelMail config, " . "but the module is not loaded in PHP"; $corrections['ldap'][] = "Reconfigure PHP with the option '--with-ldap'"; $corrections['ldap'][] = "Then recompile PHP and reinstall"; $corrections['ldap'][] = "-- OR --"; $corrections['ldap'][] = "Reconfigure SquirrelMail to not use LDAP"; } $body = "\nMy IMAP server information:\n" . " Server type: $imap_server_type\n"; /* check imap server's mapping */ $imapServerAddress = sqimap_get_user_server($imapServerAddress, $username); /* * add tls:// prefix, if tls is used. * No need to check for openssl. * User can't use SquirrelMail if this part is misconfigured */ if ($use_imap_tls == true) $imapServerAddress = 'tls://' . $imapServerAddress; $imap_stream = fsockopen ($imapServerAddress, $imapPort, $error_number, $error_string); $server_info = fgets ($imap_stream, 1024); if ($imap_stream) { // SUPRESS HOST NAME $list = explode(' ', $server_info); $list[2] = '[HIDDEN]'; $server_info = implode(' ', $list); $body .= " Server info: $server_info"; fputs ($imap_stream, "a001 CAPABILITY\r\n"); $read = fgets($imap_stream, 1024); $list = explode(' ', $read); array_shift($list); array_shift($list); $read = implode(' ', $list); $body .= " Capabilities: $read"; fputs ($imap_stream, "a002 LOGOUT\r\n"); fclose($imap_stream); } else { $body .= " Unable to connect to IMAP server to get information.\n"; $warning = 1; $warnings['imap'] = "Unable to connect to IMAP server"; $corrections['imap'][] = "Make sure you specified the correct mail server"; $corrections['imap'][] = "Make sure the mail server is running IMAP, not POP"; $corrections['imap'][] = "Make sure the server responds to port $imapPort"; } $warning_html = ''; $warning_num = 0; if (isset($warning) && $warning) { foreach ($warnings as $key => $value) { if ($warning_num == 0) { $body_top .= "WARNINGS WERE REPORTED WITH YOUR SETUP:\n"; $body_top = "WARNINGS WERE REPORTED WITH YOUR SETUP -- SEE BELOW\n\n$body_top"; $warning_html = "

Warnings were reported with your setup:

\n
\n"; } $warning_num ++; $warning_html .= "
$value
\n"; $body_top .= "\n$value\n"; foreach ($corrections[$key] as $corr_val) { $body_top .= " * $corr_val\n"; $warning_html .= "
* $corr_val
\n"; } } $warning_html .= "
\n

$warning_num warning(s) reported.

\n
\n"; $body_top .= "\n$warning_num warning(s) reported.\n"; $body_top .= "----------------------------------------------\n"; } $body = htmlspecialchars($body_top . $body); ?>
'._("Submit a Bug Report").'','center',$color[0]); ?>
'; echo _("Before you send your bug report, please make sure to check this checklist for any common problems."); echo "

\n"; echo '
    '; echo '
  • '; printf(_("Make sure that you are running the most recent copy of %s. You are currently using version %s."), 'SquirrelMail', $version); echo "
  • \n"; echo '
  • '; printf(_("Check to see if your bug is already listed in the %sBug List%s on SourceForge. If it is, we already know about it and are trying to fix it."), '', ''); echo "
  • \n"; echo '
  • '; echo _("Try to make sure that you can repeat it. If the bug happens sporatically, try to document what you did when it happened. If it always occurs when you view a specific message, keep that message around so maybe we can see it."); echo "
  • \n"; echo '
  • '; printf(_("If there were warnings displayed above, try to resolve them yourself. Read the guides in the %s directory where SquirrelMail was installed."), 'doc/'); echo "
  • \n"; echo "
\n"; echo '

'; echo _("Pressing the button below will start a mail message to the developers of SquirrelMail that will contain a lot of information about your system, your browser, how SquirrelMail is set up, and your IMAP server. It will also prompt you for information. Just fill out the sections at the top. If you like, you can scroll down in the message to see what else is being sent."); echo "

\n"; echo '

'; echo _("Please make sure to fill out as much information as you possibly can to give everyone a good chance of finding and removing the bug. Submitting your bug like this will not have it automatically added to the bug list on SourceForge, but someone who gets your message may add it for you."); echo "

\n"; ?>
squirrelmail/plugins/bug_report/README0000644000175000017500000000443710765411605017341 0ustar thijsthijsBug Reporter Plugin For SquirrelMail Need to submit a bug? Need to know valuable system information? Need to be accurate? This should do it for you. Features ======== * You save yourself a lot of typing * By default, this is not enabled. * Provides detailed setup information to help diagnose your problem * Has some warnings that can help out the person submitting the bug report Description =========== When people stumble across a bug, which may happen in a work-in-progress, often times they would like to help out the software and get rid of the bug. Sometimes, these people don't know much about the system and how it is set up -- they know enough to make the bug happen for them. This bug report plugin is designed to gather all of the non-private information for the user automatically, so that the user doesn't need to know more than how to trigger the bug. Future Work =========== * Add more data * Add more warnings Installation ============ NOTE! None of the following is true for this plugin under SquirrelMail version 1.4.x. All you need to do is enable the plugin in the main SquirrelMail configuration. //FIXME: implement the following? Backport it from DEVEL... You must configure this plugin before you enable it in your SquirrelMail installation. The plugin's configuration is stored in one of the following files: config/bug_report_config.php plugins/bug_report/config.php files. The default configuration options can be found in (copy this file to one of the above locations and then edit it to suit you): plugins/bug_report/config_default.php If both configuration files are present, this plugin uses the one in the config/ directory. By default, the plugin will only be visible to users listed in the following files: plugins/bug_report/admins config/admins ... or only to the user that owns the main SquirrelMail configuration file. Other users can use the bug_report plugin if you set a value for the administrator's email address in the plugin configuration file and set $bug_report_allow_users option to TRUE. Once the plugin is configured, go back to the main SquirrelMail directory, run "configure" and enable the plugin. Credits ======= This plugin has been originally developed by Tyler Akins and is now maintained by the SquirrelMail Project Team. squirrelmail/plugins/bug_report/functions.php0000644000175000017500000000244511700173711021170 0ustar thijsthijs 'bug_report_visible', 'caption' => _("Show button in toolbar"), 'type' => SMOPT_TYPE_BOOLEAN, 'refresh' => SMOPT_REFRESH_ALL, 'initial_value' => false ); $optpage_data['vals']['bug_report'] = $optionValues; } squirrelmail/plugins/index.php0000644000175000017500000000073111700173711016113 0ustar thijsthijs 'Test', 'version' => 'CORE', 'summary' => 'This plugin provides some test mechanisms for further diagnosis of the system upon which you are attempting to run SquirrelMail.', 'details' => 'This plugin provides some test mechanisms for further diagnosis of the system upon which you are attempting to run SquirrelMail.', 'requires_configuration' => 0, 'requires_source_patch' => 0, ); } /** * Returns version info about this plugin * */ function test_version() { $info = test_info(); return $info['version']; } squirrelmail/plugins/test/COPYING0000644000175000017500000003557410665436035016334 0ustar thijsthijs GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS squirrelmail/plugins/test/index.php0000644000175000017500000000064011700173711017071 0ustar thijsthijs ngettext Test Strings:

The results of this test depend on your current language (translation) selection (see Options==>Display Preferences) and the corresponding translation strings in locale/xx/LC_MESSAGES/test.mo


";

sq_change_text_domain('squirrelmail');


squirrelmail/plugins/test/README0000644000175000017500000000077111700173711016136 0ustar  thijsthijsTest plugin for SquirrelMail
============================
Version $Id$

Copyright 1999-2012 The SquirrelMail Project Team


Description
===========

This plugin provides some test mechanisms for further
diagnosis of the system upon which you are attempting
to run SquirrelMail.

This plugin is intended as an administrative tool and 
should not be enabled in a production environment.



License
=======

This plugin is released under the GNU General Public
License (see the file COPYING for details).



squirrelmail/plugins/test/decodeheader.php0000644000175000017500000000617311700173711020365 0ustar  thijsthijsdecodeHeader() Test:\n";


if ($default_charset == 'utf-8' || $lossy_encoding) {
    echo '

Test with lossy_encoding OFF

'; } else { echo '

Test with lossy_encoding ON

'; } echo '

Default charset: ' . $default_charset . "
\n" . 'Lossy_encoding: ' . ($lossy_encoding ? 'true' : 'false') . '

'; echo '

The results of this test depend on your current language (translation) selection (see Options==>Display Preferences) (and the character set it employs) and your $lossy_encoding setting (see config/config.php or conf.pl ==> 10 ==> 5).

'; echo '
';


echo "(MDN) 000:\n html chars are not encoded,\n space is not encoded,\n 8bit chars are unmodified\n";
foreach ($header as $test) {
    echo htmlentities(decodeHeader($test, false, false, false));
    echo "\n";
}
echo "--------\n";


echo "(compose) 001:\n html chars are not encoded,\n space is not encoded,\n 8bit chars may be converted or not (depends on \$lossy_encoding and \$default_charset)\n";
foreach ($header as $test) {
    echo htmlentities(decodeHeader($test, false, false, true));
    echo "\n";
}
echo "--------\n";


echo "010\n";
foreach ($header as $test) {
    echo htmlentities(decodeHeader($test, false, true, false));
    echo "\n";
}
echo "--------\n";


echo "011\n";
foreach ($header as $test) {
    echo htmlentities(decodeHeader($test, false, true, true));
    echo "\n";
}
echo "--------\n";


echo "(download) 100\n";
foreach ($header as $test) {
    echo htmlentities(decodeHeader($test, true, false, false));
    echo "\n";
}
echo "--------\n";


echo "101\n";
foreach ($header as $test) {
    echo htmlentities(decodeHeader($test, true, false, true));
    echo "\n";
}
echo "--------\n";


echo "(default) 110\n";
foreach ($header as $test) {
    echo htmlentities(decodeHeader($test, true, true, false));
    echo "\n";
}
echo "--------\n";


echo "111\n";
foreach ($header as $test) {
    echo htmlentities(decodeHeader($test, true, true, true));
    echo "\n";
}
echo "--------\n";


echo '
'; squirrelmail/plugins/test/functions.php0000644000175000017500000000070011700173711017767 0ustar thijsthijs Tests:

decodeHeader() test

ngettext() test

squirrelmail/plugins/demo/0000755000175000017500000000000011737431040015220 5ustar thijsthijssquirrelmail/plugins/demo/setup.php0000644000175000017500000000527511700173711017100 0ustar thijsthijs 'Demo', 'version' => 'CORE', 'summary' => 'This plugin provides test/sample code for many of the hook points in the SquirrelMail core.', 'details' => 'This plugin provides test/sample code for many of the hook points in the SquirrelMail core.', 'requires_configuration' => 0, 'requires_source_patch' => 0, ); } /** * Returns version info about this plugin * */ function demo_version() { $info = demo_info(); return $info['version']; } /** * Add link to menu at top of content pane * * @return void * */ function demo_menuline() { include_once(SM_PATH . 'plugins/demo/functions.php'); demo_menuline_do(); } /** * Inserts an option block in the main SM options page * * @return void * */ function demo_option_link() { include_once(SM_PATH . 'plugins/demo/functions.php'); demo_option_link_do(); } /** * Validate that this plugin is configured correctly * * @return boolean Whether or not there was a * configuration error for this plugin. * */ function demo_check_configuration() { include_once(SM_PATH . 'plugins/demo/functions.php'); return demo_check_configuration_do(); } squirrelmail/plugins/demo/getpot0000755000175000017500000000055310665502651016461 0ustar thijsthijs#!/bin/sh XGETTEXT_OPTIONS="--keyword=_ -keyword=N_ --default-domain=demo --no-location" # Allows controlling language option # (gettext v.0.10.40 = -C, gettext 0.11+ = -L php). if [ $SM_OLD_GETTEXT ] ; then XGETTEXT_OPTIONS="${XGETTEXT_OPTIONS} -C"; else XGETTEXT_OPTIONS="${XGETTEXT_OPTIONS} -L php"; fi xgettext ${XGETTEXT_OPTIONS} *.php --output=demo.pot squirrelmail/plugins/demo/COPYING0000644000175000017500000003543310665502651016271 0ustar thijsthijs GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS squirrelmail/plugins/demo/demo.php0000644000175000017500000000120311700173711016647 0ustar thijsthijsHELLO WORLD'; squirrelmail/plugins/demo/index.php0000644000175000017500000000064011700173711017036 0ustar thijsthijs SquirrelMail Demo Plugin Translation File # Copyright (c) 2007 The Squirrelmail Development Team # This file is distributed under the same license as the SquirrelMail package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: demo\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2007-09-05 11:38-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: SquirrelMail Language Team \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" msgid "Demo" msgstr "" msgid "This is where you would describe what your plugin does." msgstr "" squirrelmail/plugins/demo/README0000644000175000017500000000150511700173711016077 0ustar thijsthijsDemo plugin for SquirrelMail ============================ Version $Id$ Copyright 1999-2012 The SquirrelMail Project Team Description =========== This plugin provides test/sample code for many of the hook points in the SquirrelMail core. It is primarily intended as an aid to plugin authors who can copy the code herein to ensure correct hook code and thus focus on other more important plugin functionality. This plugin should not be enabled in a production environment. Note that the hook code herein is specific to the version of SquirrelMail that it is found in and is not necessarily cross-version compatible. Please consult the demo plugin in all versions of SquirrelMail that your plugin will target. License ======= This plugin is released under the GNU General Public License (see the file COPYING for details). squirrelmail/plugins/demo/functions.php0000644000175000017500000000277211700173711017747 0ustar thijsthijs _("Demo"), 'url' => sqm_baseuri() . 'plugins/demo/demo.php', 'desc' => _("This is where you would describe what your plugin does."), 'js' => FALSE ); sq_change_text_domain('squirrelmail'); } /** * Validate that this plugin is configured correctly * * @return boolean Whether or not there was a * configuration error for this plugin. * */ function demo_check_configuration_do() { // test for something that this plugin requires, print error if // misconfigured or requirements are missing // if (FALSE) // put something meaningful here { do_err('Demo plugin is missing something important', FALSE); return TRUE; // return FALSE if you only want to display a non-critical error } return FALSE; } squirrelmail/plugins/demo/INSTALL0000644000175000017500000000055010665502651016257 0ustar thijsthijsInstalling Demo =============== The Demo plugin comes with SquirrelMail, so you should only need to activate it using the configuration utility. 1) Go to your config directory and run conf.pl. Choose option 8 and move the plugin from the "Available Plugins" category to the "Installed Plugins" category. Save and exit. $ cd config/ $ ./conf.pl squirrelmail/plugins/fortune/0000755000175000017500000000000011737431040015756 5ustar thijsthijssquirrelmail/plugins/fortune/setup.php0000644000175000017500000000250011700173711017622 0ustar thijsthijssquirrelmail/plugins/fortune/README0000644000175000017500000000074510645123115016642 0ustar thijsthijsSimple SquirrelMail plugin that displays a quote above the message listing. Original code contributed by paulm@spider.org, now maintained by the SquirrelMail Project Team. Plugin requires /usr/games/fortune or any other similar program, that outputs short text messages. If you are running PHP in safe_mode, the path to this program must be present in the PHP safe_mode_exec_dir setting. If you are running a chrooted webserver, program must be present inside of your chroot jail. squirrelmail/plugins/fortune/fortune_functions.php0000644000175000017500000000362011700173711022240 0ustar thijsthijs\n". "
\n". "
\n"; echo '
'; echo '
' . _("Today's Fortune") . '

' .
        $sMsg .
        '
'; echo '
'; } /** * Add fortune options * @access private */ function fortune_show_options() { global $optpage_data, $username, $data_dir, $fortune_visible; $fortune_visible = getPref($data_dir, $username, 'fortune_visible'); $optgrp = _("Fortunes"); $optvals = array(); $optvals[] = array( 'name' => 'fortune_visible', 'caption' => _("Show fortunes at top of mailbox"), 'type' => SMOPT_TYPE_BOOLEAN, 'refresh' => SMOPT_REFRESH_NONE ); $optpage_data['grps']['fortune'] = $optgrp; $optpage_data['vals']['fortune'] = $optvals; } squirrelmail/plugins/translate/0000755000175000017500000000000011737431041016272 5ustar thijsthijssquirrelmail/plugins/translate/setup.php0000644000175000017500000010443011700173711020142 0ustar thijsthijsfindDisplayEntity(array(), array('text/plain')); $body = ''; if ( !empty($trans_ar[0]) ) { for ($i = 0; $i < count($trans_ar); $i++) { $body .= formatBody($imapConnection, $message, $color, $wrap_at, $trans_ar[$i], $passed_id, $mailbox, true); } $hookResults = do_hook('message_body', $body); $body = $hookResults[1]; } else { $body = 'Message can\'t be translated'; } $new_body = $body; $trans = get_html_translation_table(HTML_ENTITIES); $trans[' '] = ' '; $trans = array_flip($trans); $new_body = strtr($new_body, $trans); $new_body = urldecode($new_body); $new_body = strip_tags($new_body); /* I really don't like this next part ... */ $new_body = str_replace('"', "''", $new_body); $new_body = strtr($new_body, "\n", ' '); $function = 'translate_form_' . $translate_server; $function($new_body); } /** Closes translation engine form */ function translate_table_end() { ?> _("Translation Options"), 'url' => '../plugins/translate/options.php', 'desc' => _("Which translator should be used when you get messages in a different language?"), 'js' => false ); } /** gets translation preferences */ function translate_pref() { global $username, $data_dir; global $translate_server, $translate_location; global $translate_show_send, $translate_show_read; global $translate_same_window; $translate_server = getPref($data_dir, $username, 'translate_server'); if ($translate_server == '') { $translate_server = 'babelfish'; } $translate_location = getPref($data_dir, $username, 'translate_location'); if ($translate_location == '') { $translate_location = 'center'; } $translate_show_send = getPref($data_dir, $username, 'translate_show_send'); $translate_show_read = getPref($data_dir, $username, 'translate_show_read'); $translate_same_window = getPref($data_dir, $username, 'translate_same_window'); } /** * This function could be sped up. * It basically negates the process if a ! is found in the beginning and * matches a * at the end with 0 or more characters. */ function translate_does_it_match_language($test) { global $squirrelmail_language; $true = 1; $false = 0; $index = 0; $smindex = 0; if (! $test || ! $squirrelmail_language) { return $false; } if ($test[$index] == '!') { $index ++; $true = 0; $false = 1; } if (($index == 0) && ($test == $squirrelmail_language)) { return $true; } while (isset($test[$index]) && $test[$index]) { if ($test[$index] == '*') { return $true; } if ($test[$index] != $squirrelmail_language[$smindex]) { return $false; } $index ++; $smindex ++; } return $false; } /** creates translation engine language selection */ function translate_lang_opt($from, $to, $value, $text) { global $translate_dir; $ret = '