ever more
[squirrelmail.git] / plugins / squirrelspell / sqspell_functions.php
CommitLineData
849bdf42 1<?php
2/**
3 SQSPELL_FUNCTIONS.PHP
4 --------------
5 All SquirrelSpell-wide functions are in this file.
6 **/
7
8function sqspell_makePage($title, $scriptsrc, $body){
9 //
10 // GUI wrap-around for the OPTIONS page.
11 //
12 global $color, $SQSPELL_VERSION, $MOD;
13 displayPageHeader($color, "None");
14 ?>
15 &nbsp;<br>
16 <?php if($scriptsrc) { ?>
17 <script type="text/javascript" src="js/<?php echo $scriptsrc ?>"></script>
18 <?php } ?>
19 <table width="95%" align="center" border="0" cellpadding="2" cellspacing="0">
20 <tr>
21 <td bgcolor="<?php echo $color[9] ?>" align="center">
22 <strong><?php echo $title ?></strong>
23 </td>
24 </tr>
25 <tr><td><hr></td></tr>
26 <tr><td>
27 <?php echo $body ?>
28 </td></tr>
29 <?php if ($MOD!="options_main"){
30 // Generate a nice return-to-main link.
31 ?>
32 <tr><td><hr></td></tr>
33 <tr><td align="center"><a href="sqspell_options.php">Back to &quot;SpellChecker Options&quot; page</a></td></tr>
34 <?php } ?>
35 <tr><td><hr></td></tr>
36 <tr>
37 <td bgcolor="<?php echo $color[9] ?>" align="center">
38 SquirrelSpell <?php echo $SQSPELL_VERSION ?>
39 </td>
40 </tr>
41 </table>
42 <?php
43}
44
45function sqspell_makeWindow($onload, $title, $scriptsrc, $body){
46 //
47 // GUI wrap-around for the pop-up window interface.
48 //
49 global $color, $SQSPELL_VERSION;
50 ?>
51 <html>
52 <head>
53 <title><?php echo $title ?></title>
54 <?php if ($scriptsrc){ ?>
55 <script type="text/javascript" src="js/<?php echo $scriptsrc ?>"></script>
56 <?php } ?>
57 </head>
58 <body text="<?php echo $color[8] ?>"
59 bgcolor="<?php echo $color[4] ?>"
60 link="<?php echo $color[7] ?>"
61 vlink="<?php echo $color[7] ?>"
62 alink="<?php echo $color[7] ?>"<?php
63 if ($onload) echo " onload=\"$onload\""; ?>>
64 <table width="100%" border="0" cellpadding="2">
65 <tr>
66 <td bgcolor="<?php echo $color[9] ?>" align="center">
67 <strong><?php echo $title ?></strong>
68 </td>
69 </tr>
70 <tr>
71 <td><hr></td>
72 </tr>
73 <tr>
74 <td>
75 <?php echo $body ?>
76 </td>
77 </tr>
78 <tr>
79 <td><hr></td>
80 </tr>
81 <tr>
82 <td bgcolor="<?php echo $color[9] ?>" align="center">
83 SquirrelSpell <?php echo $SQSPELL_VERSION ?>
84 </td>
85 </tr>
86 </table>
87 </body>
88 </html>
89 <?php
90}
91
92function sqspell_crypto($mode, $ckey, $input){
93 //
94 // This function does the encryption and decryption of the user
95 // dictionary. It is only available when PHP is compiled
96 // --with-mcrypt. See doc/CRYPTO for more information.
97 //
98 if (!function_exists(mcrypt_generic)) return "PANIC";
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")) $crypto="PANIC";
111 break;
112 }
113 mcrypt_generic_end ($td);
114 return $crypto;
115}
116
117function sqspell_upgradeWordsFile($words_string){
118 //
119 // This function transparently upgrades the 0.2 dictionary format to
120 // 0.3, since user-defined languages have been added in 0.3 and
121 // the new format keeps user dictionaries selection in the file.
122 //
123 global $SQSPELL_APP_DEFAULT, $SQSPELL_VERSION;
124
125 // Define just one dictionary for this user -- the default.
126 // If the user wants more, s/he can set them up in personal
127 // preferences. See doc/UPGRADING for more info.
128 $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";
129 sqspell_writeWords($new_words_string);
130 return $new_words_string;
131}
132
133function sqspell_getSettings($words){
134 //
135 // Right now it just returns an array with the dictionaries
136 // available to the user for spell-checking. It will probably
137 // do more in the future, as features are added.
138 //
139 global $SQSPELL_APP, $SQSPELL_APP_DEFAULT;
140 if (sizeof($SQSPELL_APP) > 1){
141 // OK, so there are more than one dictionary option.
142 // Now load the user prefs.
143 if(!$words) $words=sqspell_getWords();
144 if ($words){
145 // find which dictionaries user wants to use
146 preg_match("/# LANG: (.*)/i", $words, $matches);
147 $langs=explode(", ", $matches[1]);
148 } else {
149 // User doesn't have a personal dictionary. Set him up with
150 // a default setting.
151 $langs[0]=$SQSPELL_APP_DEFAULT;
152 }
153 } else {
154 // There is only one dictionary defined system-wide.
155 $langs[0]=$SQSPELL_APP_DEFAULT;
156 }
157 return $langs;
158}
159
160function sqspell_getLang($words, $lang){
161 //
162 // Returns words of a specific user dictionary.
163 //
164 $start=strpos($words, "# $lang\n");
165 if (!$start) return "";
166 $end=strpos($words, "#", $start+1);
167 $lang_words = substr($words, $start, $end-$start);
168 return $lang_words;
169}
170
171function sqspell_getWords(){
172 //
173 // This baby operates the user dictionary. If the format is clear-text,
174 // then it just reads the file and returns it. However, if the file is
175 // encrypted, then it decrypts it, checks whether the decryption was
176 // successful, troubleshoots if not, then returns the clear-text dictionary
177 // to the app.
178 //
179 global $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO;
180 $words="";
181 if (file_exists($SQSPELL_WORDS_FILE)){
182 // Gobble it up.
183 $fp=fopen($SQSPELL_WORDS_FILE, "r");
184 $words=fread($fp, filesize($SQSPELL_WORDS_FILE));
185 fclose($fp);
186 }
187 // Check if this is an encrypted file by looking for
188 // the string "# SquirrelSpell" in it.
189 if ($words && !strstr($words, "# SquirrelSpell")){
190 // This file is encrypted or mangled. Try to decrypt it.
191 // If fails, raise hell.
192 global $key, $onetimepad, $old_key;
193 if ($old_key) {
194 // an override in case user is trying to decrypt a dictionary
195 // with his old password
196 $clear_key=$old_key;
197 } else {
198 // get user's password (the key).
199 $clear_key = OneTimePadDecrypt($key, $onetimepad);
200 }
201 // decrypt
202 $words=sqspell_crypto("decrypt", $clear_key, $words);
203 if ($words=="PANIC"){
204 // AAAAAAAAAAAH!!!!! OK, ok, breathe!
205 // Let's hope the decryption failed because the user changed his
206 // password. Bring up the option to key in the old password
207 // or wipe the file and start over if everything else fails.
208 $msg="<p>
209 <strong>ATTENTION:</strong><br>
210 SquirrelSpell was unable to decrypt your personal dictionary. This is most likely
211 due to the fact that you have changed your mailbox password. In order to proceed,
212 you will have to supply your old password so that SquirrelSpell can decrypt your
213 personal dictionary. It will be re-encrypted with your new password after this.<br>
214 If you haven't encrypted your dictionary, then it got mangled and is no longer
215 valid. You will have to delete it and start anew. This is also true if you don't
216 remember your old password -- without it, the encrypted data is no longer
217 accessible.</p>
218 <blockquote>
219 <form method=\"post\" onsubmit=\"return AYS()\">
220 <input type=\"hidden\" name=\"MOD\" value=\"crypto_badkey\">
221 <p><input type=\"checkbox\" name=\"delete_words\" value=\"ON\"> Delete my dictionary and start a new one<br>
222 Decrypt my dictionary with my old password: <input name=\"old_key\" size=\"10\"></p>
223 </blockquote>
224 <p align=\"center\"><input type=\"submit\" value=\"Proceed &gt;&gt;\"></p>
225 </form>
226 ";
227 // See if this happened in the pop-up window or when accessing
228 // the SpellChecker options page.
229 global $SCRIPT_NAME;
230 if (strstr($SCRIPT_NAME, "sqspell_options"))
231 sqspell_makePage("Error Decrypting Dictionary", "decrypt_error.js", $msg);
232 else sqspell_makeWindow(null, "Error Decrypting Dictionary", "decrypt_error.js", $msg);
233 exit;
234 } else {
235 // OK! Phew. Set the encryption flag to true so we can later on
236 // encrypt it again before saving to HDD.
237 $SQSPELL_CRYPTO=true;
238 }
239 } else {
240 // No encryption is used. Set $SQSPELL_CRYPTO to false, in case we have to
241 // save the dictionary later.
242 $SQSPELL_CRYPTO=false;
243 }
244 // Check if we need to upgrade the dictionary from version 0.2.x
245 if (strstr($words, "Dictionary v0.2")) $words=sqspell_upgradeWordsFile($words);
246 return $words;
247}
248
249function sqspell_writeWords($words){
250 //
251 // Writes user dictionary into the $username.words file, then changes mask
252 // to 0600. If encryption is needed -- does that, too.
253 //
254 global $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO;
255 // if $words is empty, create a template entry.
256 if (!$words) $words=sqspell_makeDummy();
257 if ($SQSPELL_CRYPTO){
258 // User wants to encrypt the file. So be it.
259 // get his password to use as a key.
260 global $key, $onetimepad;
261 $clear_key=OneTimePadDecrypt($key, $onetimepad);
262 // Try encrypting it. If fails, scream bloody hell.
263 $save_words = sqspell_crypto("encrypt", $clear_key, $words);
264 if ($save_words=="PANIC"){
265 // AAAAAAAAH! I'm not handling this yet, since obviously
266 // the admin of the site forgot to compile the MCRYPT support in.
267 // I will add a handler for this case later, when I can come up
268 // with some work-around... Right now, do nothing. Let the Admin's
269 // head hurt.. ;)))
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
280function 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
291function 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
311?>