c53018f253939a20a6261162683baa5c08fb89c8
[squirrelmail.git] / plugins / squirrelspell / sqspell_functions.php
1 <?php
2
3 /**
4 ** sqspell_functions.php -- All SquirrelSpell-wide functions are in this file.
5 **
6 ** Copyright (c) 1999-2001 The SquirrelMail development team
7 ** Licensed under the GNU GPL. For full terms see the file COPYING.
8 **
9 **
10 **
11 ** $Id$
12 **/
13
14 function sqspell_makePage($title, $scriptsrc, $body){
15 /*
16 ** GUI wrap-around for the OPTIONS page.
17 */
18 global $color, $SQSPELL_VERSION, $MOD;
19 displayPageHeader($color, 'None');
20
21 echo "&nbsp;<br>\n";
22 if($scriptsrc) {
23 echo "<script type=\"text/javascript\" src=\"js/$scriptsrc\"></script>\n";
24 }
25 echo '<table width="95%" align="center" border="0" cellpadding="2" cellspacing="0">'.
26 '<tr>'.
27 "<td bgcolor=\"$color[9]\" align=center>".
28 "<strong>$title</strong>".
29 '</td>'.
30 '</tr>'.
31 '<tr><td><hr></td></tr>'.
32 "<tr><td>$body</td></tr>";
33 if ($MOD!="options_main"){
34 // Generate a nice return-to-main link.
35 echo '<tr><td><hr></td></tr>'.
36 '<tr><td align="center"><a href="sqspell_options.php">' .
37 _("Back to &quot;SpellChecker Options&quot; page") . '</a></td></tr>';
38 }
39 echo '<tr><td><hr></td></tr>'.
40 '<tr>'.
41 "<td bgcolor=\"$color[9]\" align=center>".
42 "SquirrelSpell $SQSPELL_VERSION".
43 '</td>'.
44 '</tr>'.
45 '</table>';
46 }
47
48 function sqspell_makeWindow($onload, $title, $scriptsrc, $body){
49
50 /*
51 ** GUI wrap-around for the pop-up window interface.
52 */
53 global $color, $SQSPELL_VERSION, $theme_css;
54
55 echo "<html>\n".
56 "<head>\n".
57 "<title>$title</title>\n";
58 if ($theme_css != "") {
59 echo "<LINK REL=\"stylesheet\" TYPE=\"text/css\" HREF=\"$theme_css\">\n";
60 }
61 if ($scriptsrc){
62 echo "<script type=\"text/javascript\" src=\"js/$scriptsrc\"></script>\n";
63 }
64 echo "</head>\n".
65 "<body text=\"$color[8]\" bgcolor=\"$color[4]\" link=\"$color[7]\" vlink=\"$color[7]\" alink=\"$color[7]\"";
66 if ($onload) {
67 echo " onload=\"$onload\"";
68 }
69 echo '>'.
70 '<table width="100%" border="0" cellpadding="2">'.
71 '<tr>'.
72 "<td bgcolor=\"$color[9]\" align=center>".
73 "<strong>$title</strong>".
74 '</td>'.
75 '</tr>'.
76 '<tr><td><hr></td></tr>'.
77 '<tr>'.
78 "<td>$body</td>".
79 '</tr>'.
80 '<tr><td><hr></td></tr>'.
81 '<tr>'.
82 "<td bgcolor=\"$color[9]\" align=center>".
83 "SquirrelSpell $SQSPELL_VERSION".
84 '</td>'.
85 '</tr>'.
86 '</table>'.
87 "</body>\n</html>\n";
88 }
89
90 function sqspell_crypto($mode, $ckey, $input){
91 //
92 // This function does the encryption and decryption of the user
93 // dictionary. It is only available when PHP is compiled
94 // --with-mcrypt. See doc/CRYPTO for more information.
95 //
96 if (!function_exists(mcrypt_generic)) {
97 return 'PANIC';
98 }
99 $td = mcrypt_module_open(MCRYPT_Blowfish, "", MCRYPT_MODE_ECB, "");
100 $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
101 mcrypt_generic_init($td, $ckey, $iv);
102 switch ($mode){
103 case 'encrypt':
104 $crypto = mcrypt_generic($td, $input);
105 break;
106 case 'decrypt':
107 $crypto = mdecrypt_generic($td, $input);
108 // See if it decrypted successfully. If so, it should contain
109 // the string "# SquirrelSpell".
110 if (!strstr($crypto, "# SquirrelSpell"))
111 $crypto='PANIC';
112 break;
113 }
114 mcrypt_generic_end ($td);
115 return $crypto;
116 }
117
118 function sqspell_upgradeWordsFile($words_string){
119 /*
120 ** This function transparently upgrades the 0.2 dictionary format to
121 ** 0.3, since user-defined languages have been added in 0.3 and
122 ** the new format keeps user dictionaries selection in the file.
123 */
124 global $SQSPELL_APP_DEFAULT, $SQSPELL_VERSION;
125
126 /* Define just one dictionary for this user -- the default.
127 ** If the user wants more, s/he can set them up in personal
128 ** preferences. See doc/UPGRADING for more info.
129 */
130 $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";
131 sqspell_writeWords($new_words_string);
132 return $new_words_string;
133 }
134
135 function sqspell_getSettings($words){
136 /*
137 ** Right now it just returns an array with the dictionaries
138 ** available to the user for spell-checking. It will probably
139 ** do more in the future, as features are added.
140 */
141 global $SQSPELL_APP, $SQSPELL_APP_DEFAULT;
142 if (sizeof($SQSPELL_APP) > 1){
143 // OK, so there are more than one dictionary option.
144 // Now load the user prefs.
145 if(!$words)
146 $words=sqspell_getWords();
147 if ($words){
148 // find which dictionaries user wants to use
149 preg_match("/# LANG: (.*)/i", $words, $matches);
150 $langs=explode(", ", $matches[1]);
151 } else {
152 // User doesn't have a personal dictionary. Set him up with
153 // a default setting.
154 $langs[0]=$SQSPELL_APP_DEFAULT;
155 }
156 } else {
157 // There is only one dictionary defined system-wide.
158 $langs[0]=$SQSPELL_APP_DEFAULT;
159 }
160 return $langs;
161 }
162
163 function sqspell_getLang($words, $lang){
164 //
165 // Returns words of a specific user dictionary.
166 //
167 $start=strpos($words, "# $lang\n");
168 if (!$start) return '';
169 $end=strpos($words, "#", $start+1);
170 $lang_words = substr($words, $start, $end-$start);
171 return $lang_words;
172 }
173
174 function sqspell_getWords(){
175 //
176 // This baby operates the user dictionary. If the format is clear-text,
177 // then it just reads the file and returns it. However, if the file is
178 // encrypted, then it decrypts it, checks whether the decryption was
179 // successful, troubleshoots if not, then returns the clear-text dictionary
180 // to the app.
181 //
182 global $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO;
183 $words="";
184 if (file_exists($SQSPELL_WORDS_FILE)){
185 // Gobble it up.
186 $fp=fopen($SQSPELL_WORDS_FILE, 'r');
187 $words=fread($fp, filesize($SQSPELL_WORDS_FILE));
188 fclose($fp);
189 }
190 // Check if this is an encrypted file by looking for
191 // the string "# SquirrelSpell" in it.
192 if ($words && !strstr($words, "# SquirrelSpell")){
193 // This file is encrypted or mangled. Try to decrypt it.
194 // If fails, raise hell.
195 global $key, $onetimepad, $old_key;
196 if ($old_key) {
197 // an override in case user is trying to decrypt a dictionary
198 // with his old password
199 $clear_key=$old_key;
200 } else {
201 // get user's password (the key).
202 $clear_key = OneTimePadDecrypt($key, $onetimepad);
203 }
204 // decrypt
205 $words=sqspell_crypto("decrypt", $clear_key, $words);
206 if ($words=="PANIC"){
207 // AAAAAAAAAAAH!!!!! OK, ok, breathe!
208 // Let's hope the decryption failed because the user changed his
209 // password. Bring up the option to key in the old password
210 // or wipe the file and start over if everything else fails.
211 $msg='<p>'.
212 '<strong>' . _("ATTENTION:") . '</strong><br>' .
213 _("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.<br>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.").
214 "</p>
215 <blockquote>
216 <form method=\"post\" onsubmit=\"return AYS()\">
217 <input type=\"hidden\" name=\"MOD\" value=\"crypto_badkey\">
218 <p><input type=\"checkbox\" name=\"delete_words\" value=\"ON\">" . _("Delete my dictionary and start a new one") . '<br>'.
219 _("Decrypt my dictionary with my old password:") . "<input name=\"old_key\" size=\"10\"></p>
220 </blockquote>
221 <p align=\"center\"><input type=\"submit\" value=\"" . _("Proceed") . " &gt;&gt;\"></p>
222 </form>
223 ";
224 // See if this happened in the pop-up window or when accessing
225 // the SpellChecker options page.
226 global $SCRIPT_NAME;
227 if (strstr($SCRIPT_NAME, "sqspell_options"))
228 sqspell_makePage( _("Error Decrypting Dictionary"), "decrypt_error.js", $msg);
229 else
230 sqspell_makeWindow(null, _("Error Decrypting Dictionary"), "decrypt_error.js", $msg);
231 exit;
232 } else {
233 // OK! Phew. Set the encryption flag to true so we can later on
234 // encrypt it again before saving to HDD.
235 $SQSPELL_CRYPTO=true;
236 }
237 } else {
238 // No encryption is used. Set $SQSPELL_CRYPTO to false, in case we have to
239 // save the dictionary later.
240 $SQSPELL_CRYPTO=false;
241 }
242 // Check if we need to upgrade the dictionary from version 0.2.x
243 if (strstr($words, "Dictionary v0.2")) $words=sqspell_upgradeWordsFile($words);
244 return $words;
245 }
246
247 function sqspell_writeWords($words){
248 //
249 // Writes user dictionary into the $username.words file, then changes mask
250 // to 0600. If encryption is needed -- does that, too.
251 //
252 global $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO;
253 // if $words is empty, create a template entry.
254 if (!$words) $words=sqspell_makeDummy();
255 if ($SQSPELL_CRYPTO){
256 // User wants to encrypt the file. So be it.
257 // get his password to use as a key.
258 global $key, $onetimepad;
259 $clear_key=OneTimePadDecrypt($key, $onetimepad);
260 // Try encrypting it. If fails, scream bloody hell.
261 $save_words = sqspell_crypto("encrypt", $clear_key, $words);
262 if ($save_words == 'PANIC'){
263 /*
264 ** AAAAAAAAH! I'm not handling this yet, since obviously
265 ** the admin of the site forgot to compile the MCRYPT support in.
266 ** I will add a handler for this case later, when I can come up
267 ** with some work-around... Right now, do nothing. Let the Admin's
268 ** head hurt.. ;)))
269 */
270 }
271 } else {
272 $save_words = $words;
273 }
274 $fp=fopen($SQSPELL_WORDS_FILE, "w");
275 fwrite($fp, $save_words);
276 fclose($fp);
277 chmod($SQSPELL_WORDS_FILE, 0600);
278 }
279
280 function sqspell_deleteWords(){
281 /*
282 ** so I open the door to my enemies,
283 ** and I ask can we wipe the slate clean,
284 ** but they tell me to please go...
285 ** uhm... Well, this just erases the user dictionary file.
286 */
287 global $SQSPELL_WORDS_FILE;
288 if (file_exists($SQSPELL_WORDS_FILE)) unlink($SQSPELL_WORDS_FILE);
289 }
290
291 function sqspell_makeDummy(){
292 //
293 // Creates an empty user dictionary for the sake of saving prefs or
294 // whatever.
295 //
296 global $SQSPELL_VERSION, $SQSPELL_APP_DEFAULT;
297 $words="# SquirrelSpell User Dictionary $SQSPELL_VERSION\n# Last Revision: " . date('Y-m-d') . "\n# LANG: $SQSPELL_APP_DEFAULT\n# End\n";
298 return $words;
299 }
300
301 /**
302 VERSION:
303 ---------
304 SquirrelSpell version. Don't modify, since it identifies the format
305 of the user dictionary files and messing with this can do ugly
306 stuff. :)
307 **/
308 $SQSPELL_VERSION="v0.3.5";
309
310 ?>