334d8ee76a82e6375bfb221b3f97fd9f5a8b3b94
[atutor.git] / mods / wiki / plugins / email_protect.php
1 <?php
2
3  # This plugin protects email addresses from getting seen by spambots,
4  # by the cost of additional effort for real persons, who really want
5  # to mail someone.
6  #
7  # It is __really safe__ because it protects addresses with a request
8  # <FORM> before the real email address gets shown on a page. It seems
9  # impossible to me that there are already all that intelligent spambots
10  # available, which can automatically fill out a <form> to access the
11  # following page. Also bots are unlikely to ever perform POST requests,
12  # because this would damage too many web interfaces.
13  # The 'cipher' method is really unimportant, when it comes to tricking
14  # automated harvesters.
15  #
16  # Additionally it generates faked/trap email addresses to annoy the
17  # marketing mafia.
18  
19
20  #-- change these from time to time:
21  define("EWIKI_PAGE_EMAIL", "ProtectedEmail");
22  define("EWIKI_EMAILPROT_UNLOCK", 1);
23  define("EWIKI_UP_ENCEMAIL", "encoded_email");
24  define("EWIKI_UP_NOSPAMBOT", "i_am_no_spambot");
25  define("EWIKI_UP_REQUESTLV", "rl");
26  define("EWIKI_FAKE_EMAIL_LOOP", 8);
27  $ewiki_config["feedbots_tarpits"] = "@spamassassin.taint.org,@123webhosting.org,@e.mailsiphon.com,@heypete.com,@ncifcrf.gov";
28  $ewiki_config["feedbots_badguys"] = "@riaa.com,@whitehouse.gov,@aol.com,@microsoft.com";
29  @$ewiki_config["ua"] .= " EmailProtect/2.1";
30
31  #-- text, translations
32  $ewiki_t["en"]["PROTE0"] = "Protected Email Address";
33  $ewiki_t["en"]["PROTE1"] = "The email address you've clicked on is protected by this form, so it won't get found by <a href=\"http://google.com/search?q=spambots\">spambots</a> (automated search engines, which crawl the net for addresses just for the entertainment of the marketing mafia).";
34  $ewiki_t["en"]["PROTE2"] = "The page you're going to edit contains at least one email address. To protect it we must ensure that no spambot reaches the edit box (with the email address in cleartext).";
35  $ewiki_t["en"]["PROTE4"] = "I'm no spambot, really!";
36  $ewiki_t["en"]["PROTE5"] = "<b>generate more faked email addresses</b>";
37  $ewiki_t["en"]["PROTE6"] = "the email address you've clicked on is:";
38  $ewiki_t["en"]["PROTE7"] = "<b>spammers, please eat these:</b>";
39
40  $ewiki_t["de"]["PROTE0"] = "Geschützte EMail-Adresse";
41  $ewiki_t["de"]["PROTE1"] = "Die EMail-Adresse, die du angeklickt hast, wird durch dieses Formular vor <a href=\"http://google.com/search?q=spambots\">spambots</a> (automatisierte Suchwerkzeuge, die das Netz zur Freude der MarketingMafia nach Adressen abgrasen) beschützt.";
42  $ewiki_t["de"]["PROTE2"] = "Die Seite, die du ändern willst, enthält momentan wenigstens eine EMail-Adresse. Um diese zu schützen müssen wir sicherstellen, daß kein Spambot an die Edit-Box kommt (weil dort die Adresse ja im Klartext steht).";
43  $ewiki_t["de"]["PROTE4"] = "Ich bin wirklich kein Spambot!";
44  $ewiki_t["de"]["PROTE5"] = "<b>noch mehr fingierte Adressen anzeigen</b>";
45  $ewiki_t["de"]["PROTE6"] = "die EMail-Adresse die du angeklickt hast lautet:";
46  $ewiki_t["de"]["PROTE7"] = "<b>Liebe Spammer, bitte freßt das:</b>";
47
48  #-- plugin glue
49  $ewiki_plugins["page"][EWIKI_PAGE_EMAIL] = "ewiki_email_protect_form";
50  if (!EWIKI_EMAILPROT_UNLOCK || !@$_COOKIE[EWIKI_UP_NOSPAMBOT]) {
51     $ewiki_plugins["link_url"][] = "ewiki_email_protect_link";
52     $ewiki_plugins["edit_hook"][] = "ewiki_email_protect_edit_hook";
53     $ewiki_plugins["page_final"][] = "ewiki_email_protect_enctext";
54  }
55
56
57
58  /* helps protecting addresses on generated/dynamic pages, and
59     for action pages (diff, info, links, ...)    
60  */
61  function ewiki_email_protect_enctext(&$html, $id, $data, $action) {
62
63     global $ewiki_config;
64
65     #-- only activate if _feedbots() wasn't active, for info/ or
66     #   diff/ action or for page plugins
67     $a_secure = array("info", "diff");
68     if (!isset($ewiki_config["@"]) && (in_array($action, $a_secure) || ewiki_array($GLOBALS["ewiki_plugins"]["page"], $id))) {
69
70        $html = preg_replace('/(?:(?:<a[^>]+href="mailto:)?([-_+\w\d.]+@[-\w\d.]+\.[\w]{2,5})(?:"[^>]*>[-_+\w\d.@]+<\/a>)?)/me',
71                '"<a href=\"".ewiki_email_protect_encode("\1",2).
72                 "\">".ewiki_email_protect_encode("\1",0)."</a>"',
73                $html);
74     }
75  }
76
77
78  /* ewiki_format() callback function to replace mailto: links with
79   * encoded redirection URLs
80   */
81  function ewiki_email_protect_link(&$href, &$title) {
82
83      if (substr($href, 0, 7) == "mailto:") {
84
85          $href = substr($href, 7);
86
87          $href = ewiki_email_protect_encode($href, 2);
88          $title = ewiki_email_protect_encode($title, 0);
89      }
90  }
91
92
93
94  /* the edit box for every page must be protected as well - else all
95   * mail addresses would still show up in the wikimarkup (cleartext)
96   */
97  function ewiki_email_protect_edit_hook($id, &$data, &$hidden_postdata) {
98
99     $hidden_postdata[EWIKI_UP_NOSPAMBOT] = 1;
100
101     if (empty($_REQUEST[EWIKI_UP_NOSPAMBOT])
102         && strpos($data["content"], "@")
103         && preg_match('/\w\w@([-\w]+\.)+\w\w/', $data["content"])   )
104     {
105        $url = ewiki_script("edit", $id);
106        $o = ewiki_email_protect_form($id, $data, "edit", "PROTE2", $url);
107        return($o);
108     }
109
110     if (!empty($_POST[EWIKI_UP_NOSPAMBOT]) && empty($_COOKIE[EWIKI_UP_NOSPAMBOT]) && EWIKI_HTTP_HEADERS) {
111        setcookie(EWIKI_UP_NOSPAMBOT, "grant_access", time()+7*24*3600, "/");
112     }
113
114  }
115
116
117
118  /* this places a <FORM METHOD="POST"> in between the WikiPage with the
119   * encoded mail address URL and the page with the clearly readable
120   * mailto: string
121   */
122  function ewiki_email_protect_form($id, $data=0, $action=0, $text="PROTE1", $url="") {
123     global $ewiki_config;
124
125     $html = "<h3>" . ewiki_t("PROTE0") . "</h3>\n";
126
127     #-- get encoded-email parameter
128     if ($url || ($email = @$_REQUEST[EWIKI_UP_ENCEMAIL])) {
129
130           #-- check for unlock cookie / post variable
131           if (empty($_REQUEST[EWIKI_UP_NOSPAMBOT])) {
132
133              if (empty($url)) {
134                 $url = ewiki_script("", EWIKI_PAGE_EMAIL);
135              }
136
137              $html .= ewiki_t($text) . "<br /><br /><br />\n";
138
139              $html .= '<form action="' . $url .
140                       '" method="POST" enctype="multipart/form-data" encoding="iso-8859-1">';
141              $html .= '<input type="hidden" name="'.EWIKI_UP_ENCEMAIL.'" value="' . $email . '">';
142              foreach (array_merge($_GET, $_POST) as $var=>$value) {
143                 if (($var != "id") && ($var != EWIKI_UP_ENCEMAIL) && ($var != EWIKI_UP_NOSPAMBOT)) {
144                    $html .= '<input type="hidden" name="' . htmlentities($var) . '" value="' . htmlentities($value) . '">';
145                 }
146              }
147              $html .= '<input type="checkbox" name="'.EWIKI_UP_NOSPAMBOT.'" value="true" id="no_spambot_checkbox"><label for="no_spambot_checkbox"> ' . ewiki_t("PROTE4") . '</label><br /><br />';
148              $html .= '<input type="submit" name="go"></form><br /><br />';
149
150              if (EWIKI_FAKE_EMAIL_LOOP) {
151                 $html .= "\n" . ewiki_t("PROTE7") . "<br />\n";
152                 $html .= ewiki_email_protect_feedbots();
153              }
154           }
155
156           #-- display deciphered email address
157           else {
158              $email = ewiki_email_protect_encode($email, -1);
159
160              $html .= ewiki_t("PROTE6") . "<br />";
161              $html .= '<a href="mailto:' . $email . '">' . $email . '</a>';
162
163              if (EWIKI_HTTP_HEADERS && empty($_COOKIE[EWIKI_UP_NOSPAMBOT])) {
164                 setcookie(EWIKI_UP_NOSPAMBOT, "grant_access", time()+7*24*3600, "/");
165              }
166
167              #-- must disable the page plugin mangling filter manually
168              $ewiki_config["@"] = 0;  // flag value doesn't matter here
169           }
170     }
171     else {
172        // $html .= "This page makes no sense standalone.";
173        $html .= "No encoded email address given in parameters.";
174     }
175
176     return($html);
177  }
178
179
180
181  /* security really does not depend on how good "encoding" is, because
182   * bots cannot automatically guess that one is actually used
183   */
184  function ewiki_email_protect_encode($string, $func) {
185
186     switch ($func) {
187
188        case 0:  // garbage shown email address
189           if (strpos($string, "mailto:") === 0) {
190              $string = substr($string, 7);
191           }
192           while (($rd = strrpos($string, ".")) > strpos($string, "@")) {
193              $string = substr($string, 0, $rd);
194           }
195           $string = strtr($string, "@.-_", "»·±¯");
196           break;
197
198        case 1:  // encode
199           $string = str_rot17($string);
200           $string = base64_encode($string);
201           break;
202
203        case -1:  // decode
204           $string = base64_decode($string);
205           $string = str_rot17($string);
206           break;       
207
208        case 2:  // url
209           $string = ewiki_script("", EWIKI_PAGE_EMAIL,
210              array(EWIKI_UP_ENCEMAIL => ewiki_email_protect_encode($string, 1))
211           );
212           break;
213
214     }
215
216     return($string);
217  }
218
219
220
221  /* this is a non-portable string encoding function which ensures that
222   * encoded strings can only be decoded when requested by the same client
223   * or user in the same dialup session (IP address must match)
224   * feel free to exchange the random garbage string with anything else
225   */
226  function str_rot17($string) {
227     if (!defined("STR_ROT17")) {
228        $i = @$_SERVER["SERVER_SOFTWARE"] .
229             @$_SERVER["HTTP_USER_AGENT"] .
230             @$_SERVER["REMOTE_ADDR"];
231        $i .= 'MxQXF^e-0OKC1\\s{\"?i!8PRoNnljHf65`Eb&A(\':g[D}_|S#~3hG>*9yvdI%<=.urcp/@$ZkqL,TWBw]a;72UzYJ)4mt+ V';
232        $f = "";
233        while (strlen($i)) {
234           if (strpos($f, $i[0]) === false) {
235              $f .= $i[0];
236           }
237           $i = substr($i, 1);
238        }
239        define("STR_ROT17", $f);
240     }
241     return(strtr($string, STR_ROT17, strrev(STR_ROT17)));
242  }
243
244
245
246  /* this function emits some html with random (fake) email addresses
247   * and spambot traps
248   */
249  function ewiki_email_protect_feedbots($limit=EWIKI_FAKE_EMAIL_LOOP) {
250
251     global $ewiki_config;
252     
253     $html = "";
254     srand(time()/17-1000*microtime());
255
256     #-- once _this_ function was called, all @s shall be send as-is
257     $ewiki_config["@"] = 1;
258
259     #-- spamtraps, and companys/orgs fighting for spammers rights
260     $domains = explode(",",
261        $ewiki_config["feedbots_tarpits"]. "," .$ewiki_config["feedbots_badguys"]
262     );
263     $traps = explode(" ", "blockme@relays.osirusoft.com simon.templar@rfc1149.net james.bond@ada-france.org anton.dvorak@ada.eu.org amandahannah44@hotmail.com usenet@fsck.me.uk meatcan2@beatrice.rutgers.edu heystupid@artsackett.com listme@dsbl.org bill@caradoc.org spamtrap@spambouncer.org spamtrap@woozle.org gfy@spamblocked.com listme@blacklist.woody.ch tarpit@lathi.net");
264     $word_parts = explode(" ", "er an Ma ar on in el en le ll Ca ne ri De Mar Ha Br La Co St Ro ie Sh Mc re or Be li ra Al la al Da Ja il es te Le ha na Ka Ch is Ba nn ey nd He tt ch Ho Ke Ga Pa Wi Do st ma Mi Sa Me he to Car ro et ol ck ic Lo Mo ni ell Gr Bu Bo Ra ia de Jo El am An Re rt at Pe Li Je She Sch ea Sc it se Cha Har Sha Tr as ng rd rr Wa so Ki Ar Bra th Ta ta Wil be Cl ur ee ge ac ay au Fr ns son Ge us nt lo ti ss Cr os Hu We Cor Di ton Ri ke Ste Du No me Go Va Si man Bri ce Lu rn ad da ill Gi Th and rl ry Ros Sta sh To Se ett ley ou Ne ld Bar Ber lin ai Mac Dar Na ve no ul Fa ann Bur ow Ko rs ing Fe Ru Te Ni hi ki yn ly lle Ju Del Su mi Bl di lli Gu ine do Ve Gar ei Hi vi Gra Sto Ti Hol Vi ed ir oo em Bre Man ter Bi Van Bro Col id Fo Po Kr ard ber sa Con ick Cla Mu Bla Pr Ad So om io ho ris un her Wo Chr Her Kat Mil Tre Fra ig Mel od nc yl Ale Jer Mcc Lan lan si Dan Kar Mat Gre ue rg Fi Sp ari Str Mer San Cu rm Mon Win Bel Nor ut ah Pi gh av ci Don ot dr lt ger co Ben Lor Fl Jac Wal Ger tte mo Er ga ert tr ian Cro ff Ver Lin Gil Ken Che Jan nne arr va ers all Cal Cas Hil Han Dor Gl ag we Ed Em ran han Cle im arl wa ug ls ca Ric Par Kel Hen Nic len sk uc ina ste ab err Or Am Mor Fer Rob Luc ob Lar Bea ner pe lm ba ren lla der ec ric Ash Ant Fre rri Den Ham Mic Dem Is As Au che Leo nna rin enn Mal Jam Mad Mcg Wh Ab War Ol ler Whi Es All For ud ord Dea eb nk Woo tin ore art Dr tz Ly Pat Per Kri Min Bet rie Flo rne Joh nni Ce Ty Za ins eli ye rc eo ene ist ev Der Des Val And Can Shi ak Gal Cat Eli May Ea rk nge Fu Qu nie oc um ath oll bi ew Far ich Cra The Ran ani Dav Tra Sal Gri Mos Ang Ter mb Jay les Kir Tu hr oe Tri lia Fin mm aw dy cke itt ale wi eg est ier ze ru sc My lb har ka mer sti br ya Gen Hay a b c d e f g h i j k l m n o p q r s t u v w x y z");
265     $word_delims = explode(" ", "0 1 2 3 3 3 4 5 5 6 7 8 9 - - - - - - - _ _ _ _ _ _ _ . . . . . . .");
266     $n_dom = count($domains)-1;
267     $n_trp = count($traps)-1;
268     $n_wpt = count($word_parts)-1;
269     $n_wdl = count($word_delims)-1;
270
271     for ($n = 1; $n < $limit; $n++) {
272
273        // email name part
274        $m = "";
275        while (strlen($m) < rand(3,17)) {
276           $a = $word_parts[nat_rand($n_wpt)];
277           if (!empty($m)) {
278              $a = strtolower($a);
279              if (rand(1,9)==5) {
280                 $m .= $word_delims[rand(0,$n_wdl)];
281              }
282           }
283           $m .= $a;
284        }
285
286        // add domain
287        switch ($dom = $domains[rand(0, $n_dom)]) {
288
289           case "@123webhosting.org":
290              $m = strtr($_SERVER["REMOTE_ADDR"], ".", "-")."-".$_SERVER["SERVER_NAME"]."-".time();
291              break;
292
293           default:
294        }
295        $m .= $dom;
296
297        $html .= '<a href="mailto:'.$m.'">'.$m.'</a>'.",\n";
298     }
299
300     $html .= '<a href="mailto:'.$traps[rand(0, $n_trp)].'">'.$traps[rand(0, $n_trp)].'</a>';
301
302     if (($rl = 1 + @$_REQUEST[EWIKI_UP_REQUESTLV]) < EWIKI_FAKE_EMAIL_LOOP) {
303        $html .= ",\n" . '<br /><a href="' .
304              ewiki_script("", EWIKI_PAGE_EMAIL,
305                array(
306                   EWIKI_UP_ENCEMAIL=>ewiki_email_protect_encode($m, 1),
307                   EWIKI_UP_REQUESTLV=>"$rl"
308                )
309              ) . '">' . ewiki_t("PROTE5") . '</a><br />' . "\n";
310        ($rl > 1) && sleep(3);
311     }
312
313     sleep(1);
314     return($html);
315  }
316
317
318
319  function nat_rand($max, $dr=0.5) {
320     $x = $max+1;
321     while ($x > $max) {
322        $x = rand(0, $max * 1000)/100;
323        $x = $x * $dr + $x * $x / 2 * (1-$dr) / $max;
324     }
325     return((int)$x);
326  }
327
328
329 ?>