/[docman]/auth_pop3.php
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /auth_pop3.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Fri Jan 26 09:32:48 2001 UTC (22 years ago) by dpavlin
Branch: MAIN
changes to allow pluggable authentification modules

1 dpavlin 1.1 <?
2    
3     /*
4     Document manager auth_pop3.php module
5    
6     WARNING: this modules uses e-mail address to check
7     login and password against pop3 server! e-mail must be
8     in following form:
9    
10     login_on_pop3_server@pop3_server.domain
11    
12     That should actually be also a vaild e-mail address
13    
14    
15     this module is uses class.POP3.php3 which is included
16     after this function
17     */
18    
19     function auth_pop3($user) {
20     $email = explode("@",$user[3]);
21     $pop3 = new POP3();
22     $pop3->connect($email[1]);
23     $Count = $pop3->login($email[0],$GLOBALS[PHP_AUTH_PW]);
24     if ( $Count && $Count != -1 ) {
25     $pop3->quit();
26     return 1;
27     }
28     $pop3->quit();
29     return 0;
30     }
31    
32     //--------------------------------------------------------------------------
33    
34     /*
35     class.POP3.php3 v1.0 99/03/24 CDI cdi@thewebmasters.net
36     Copyright (c) 1999 - CDI (cdi@thewebmasters.net) All Rights Reserved
37    
38     An RFC 1939 compliant wrapper class for the POP3 protocol.
39     */
40    
41     class POP3
42     {
43     var $ERROR = ""; // Error string.
44    
45     var $TIMEOUT = 60; // Default timeout before giving up on a
46     // network operation.
47    
48     var $COUNT = -1; // Mailbox msg count
49    
50     var $BUFFER = 512; // Socket buffer for socket fgets() calls.
51     // Per RFC 1939 the returned line a POP3
52     // server can send is 512 bytes.
53    
54     var $FP = ""; // The connection to the server's
55     // file descriptor
56    
57     var $MAILSERVER = ""; // Set this to hard code the server name
58    
59     var $DEBUG = false; // set to true to echo pop3
60     // commands and responses to error_log
61     // this WILL log passwords!
62    
63     var $BANNER = ""; // Holds the banner returned by the
64     // pop server - used for apop()
65    
66     var $RFC1939 = true; // Set by noop(). See rfc1939.txt
67     //
68    
69     var $ALLOWAPOP = false; // Allow or disallow apop()
70     // This must be set to true
71     // manually.
72    
73     function POP3 ( $server = "", $timeout = "" )
74     {
75     settype($this->BUFFER,"integer");
76     if(!empty($server))
77     {
78     // Do not allow programs to alter MAILSERVER
79     // if it is already specified. They can get around
80     // this if they -really- want to, so don't count on it.
81     if(empty($this->MAILSERVER))
82     {
83     $this->MAILSERVER = $server;
84     }
85     }
86     if(!empty($timeout))
87     {
88     settype($timeout,"integer");
89     $this->TIMEOUT = $timeout;
90     set_time_limit($timeout);
91     }
92     return true;
93     }
94    
95     function update_timer ()
96     {
97     set_time_limit($this->TIMEOUT);
98     return true;
99     }
100    
101     function connect ($server, $port = 110)
102     {
103     // Opens a socket to the specified server. Unless overridden,
104     // port defaults to 110. Returns true on success, false on fail
105    
106     // If MAILSERVER is set, override $server with it's value
107    
108     if(!empty($this->MAILSERVER))
109     {
110     $server = $this->MAILSERVER;
111     }
112    
113     if(empty($server))
114     {
115     $this->ERROR = "POP3 connect: No server specified";
116     unset($this->FP);
117     return false;
118     }
119    
120     $fp = fsockopen("$server", $port, &$errno, &$errstr);
121    
122     if(!$fp)
123     {
124     $this->ERROR = "POP3 connect: Error [$errno] [$errstr]";
125     unset($this->FP);
126     return false;
127     }
128    
129     set_socket_blocking($fp,-1);
130     $this->update_timer();
131     $reply = fgets($fp,$this->BUFFER);
132     $reply = $this->strip_clf($reply);
133     if($this->DEBUG) { error_log("POP3 SEND [connect: $server] GOT [$reply]",0); }
134     if(!$this->is_ok($reply))
135     {
136     $this->ERROR = "POP3 connect: Error [$reply]";
137     unset($this->FP);
138     return false;
139     }
140     $this->FP = $fp;
141     $this->BANNER = $this->parse_banner($reply);
142     $this->RFC1939 = $this->noop();
143     if($this->RFC1939)
144     {
145     $this->ERROR = "POP3: premature NOOP OK, NOT an RFC 1939 Compliant server";
146     $this->quit();
147     return false;
148     }
149     return true;
150     }
151    
152     function noop ()
153     {
154     if(!isset($this->FP))
155     {
156     $this->ERROR = "POP3 noop: No connection to server";
157     return false;
158     }
159     $cmd = "NOOP";
160     $reply = $this->send_cmd($cmd);
161     if(!$this->is_ok($reply))
162     {
163     return false;
164     }
165     return true;
166     }
167    
168     function user ($user = "")
169     {
170     // Sends the USER command, returns true or false
171    
172     if(empty($user))
173     {
174     $this->ERROR = "POP3 user: no user id submitted";
175     return false;
176     }
177     if(!isset($this->FP))
178     {
179     $this->ERROR = "POP3 user: connection not established";
180     return false;
181     }
182     $reply = $this->send_cmd("USER $user");
183     if(!$this->is_ok($reply))
184     {
185     $this->ERROR = "POP3 user: Error [$reply]";
186     return false;
187     }
188     return true;
189     }
190    
191     function pass ($pass = "")
192     {
193     // Sends the PASS command, returns # of msgs in mailbox,
194     // returns false (undef) on Auth failure
195    
196     if(empty($pass))
197     {
198     $this->ERROR = "POP3 pass: no password submitted";
199     return false;
200     }
201     if(!isset($this->FP))
202     {
203     $this->ERROR = "POP3 pass: connection not established";
204     return false;
205     }
206     $reply = $this->send_cmd("PASS $pass");
207     if(!$this->is_ok($reply))
208     {
209     $this->ERROR = "POP3 pass: authentication failed [$reply]";
210     $this->quit();
211     return false;
212     }
213     // Auth successful.
214     $count = $this->last("count");
215     $this->COUNT = $count;
216     $this->RFC1939 = $this->noop();
217     if(!$this->RFC1939)
218     {
219     $this->ERROR = "POP3 pass: NOOP failed. Server not RFC 1939 compliant";
220     $this->quit();
221     return false;
222     }
223     return $count;
224     }
225    
226     function apop ($login,$pass)
227     {
228     // Attempts an APOP login. If this fails, it'll
229     // try a standard login. YOUR SERVER MUST SUPPORT
230     // THE USE OF THE APOP COMMAND!
231     // (apop is optional per rfc1939)
232    
233     if(!isset($this->FP))
234     {
235     $this->ERROR = "POP3 apop: No connection to server";
236     return false;
237     }
238    
239     if(!$this->ALLOWAPOP)
240     {
241     $retVal = $this->login($login,$pass);
242     return $retVal;
243     }
244    
245     if(empty($login))
246     {
247     $this->ERROR = "POP3 apop: No login ID submitted";
248     return false;
249     }
250     if(empty($pass))
251     {
252     $this->ERROR = "POP3 apop: No password submitted";
253     return false;
254     }
255     $banner = $this->BANNER;
256     if( (!$banner) or (empty($banner)) )
257     {
258     $this->ERROR = "POP3 apop: No server banner - aborted";
259     $retVal = $this->login($login,$pass);
260     return $retVal;
261     }
262     $AuthString = $banner;
263     $AuthString .= $pass;
264     $APOPString = md5($AuthString);
265     $cmd = "APOP $login $APOPString";
266     $reply = $this->send_cmd($cmd);
267     if(!$this->is_ok($reply))
268     {
269     $this->ERROR = "POP3 apop: apop authentication failed - abort";
270     $retVal = $this->login($login,$pass);
271     return $retVal;
272     }
273     // Auth successful.
274     $count = $this->last("count");
275     $this->COUNT = $count;
276     $this->RFC1939 = $this->noop();
277     if(!$this->RFC1939)
278     {
279     $this->ERROR = "POP3 apop: NOOP failed. Server not RFC 1939 compliant";
280     $this->quit();
281     return false;
282     }
283     return $count;
284     }
285    
286     function login ($login = "", $pass = "")
287     {
288     // Sends both user and pass. Returns # of msgs in mailbox or
289     // false on failure (or -1, if the error occurs while getting
290     // the number of messages.)
291    
292     if(!isset($this->FP))
293     {
294     $this->ERROR = "POP3 login: No connection to server";
295     return false;
296     }
297     $fp = $this->FP;
298     if(!$this->user($login))
299     {
300     // Preserve the error generated by user()
301     return false;
302     }
303     $count = $this->pass($pass);
304     if( (!$count) or ($count == -1) )
305     {
306     // Preserve the error generated by last() and pass()
307     return false;
308     }
309     return $count;
310     }
311    
312     function top ($msgNum, $numLines = "0")
313     {
314     // Gets the header and first $numLines of the msg body
315     // returns data in an array with each returned line being
316     // an array element. If $numLines is empty, returns
317     // only the header information, and none of the body.
318    
319     if(!isset($this->FP))
320     {
321     $this->ERROR = "POP3 top: No connection to server";
322     return false;
323     }
324     $this->update_timer();
325    
326     $fp = $this->FP;
327     $buffer = $this->BUFFER;
328     $cmd = "TOP $msgNum $numLines";
329     fwrite($fp, "TOP $msgNum $numLines\r\n");
330     $reply = fgets($fp, $buffer);
331     $reply = $this->strip_clf($reply);
332     if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
333     if(!$this->is_ok($reply))
334     {
335     $this->ERROR = "POP3 top: Error [$reply]";
336     return false;
337     }
338    
339     $count = 0;
340     $MsgArray = array();
341    
342     $line = fgets($fp,$buffer);
343     while ( !ereg("^\.\r\n",$line))
344     {
345     $MsgArray[$count] = $line;
346     $count++;
347     $line = fgets($fp,$buffer);
348     if(empty($line)) { break; }
349     }
350    
351     return $MsgArray;
352     }
353    
354     function pop_list ($msgNum = "")
355     {
356     // If called with an argument, returns that msgs' size in octets
357     // No argument returns an associative array of undeleted
358     // msg numbers and their sizes in octets
359    
360     if(!isset($this->FP))
361     {
362     $this->ERROR = "POP3 pop_list: No connection to server";
363     return false;
364     }
365     $fp = $this->FP;
366     $Total = $this->COUNT;
367     if( (!$Total) or ($Total == -1) )
368     {
369     return false;
370     }
371     if($Total == 0)
372     {
373     return array("0","0");
374     // return -1; // mailbox empty
375     }
376    
377     $this->update_timer();
378    
379     if(!empty($msgNum))
380     {
381     $cmd = "LIST $msgNum";
382     fwrite($fp,"$cmd\r\n");
383     $reply = fgets($fp,$this->BUFFER);
384     $reply = $this->strip_clf($reply);
385     if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
386     if(!$this->is_ok($reply))
387     {
388     $this->ERROR = "POP3 pop_list: Error [$reply]";
389     return false;
390     }
391     list($junk,$num,$size) = explode(" ",$reply);
392     return $size;
393     }
394     $cmd = "LIST";
395     $reply = $this->send_cmd($cmd);
396     if(!$this->is_ok($reply))
397     {
398     $reply = $this->strip_clf($reply);
399     $this->ERROR = "POP3 pop_list: Error [$reply]";
400     return false;
401     }
402     $MsgArray = array();
403     $MsgArray[0] = $Total;
404     for($msgC=1;$msgC <= $Total; $msgC++)
405     {
406     if($msgC > $Total) { break; }
407     $line = fgets($fp,$this->BUFFER);
408     $line = $this->strip_clf($line);
409     if(ereg("^\.",$line))
410     {
411     $this->ERROR = "POP3 pop_list: Premature end of list";
412     return false;
413     }
414     list($thisMsg,$msgSize) = explode(" ",$line);
415     settype($thisMsg,"integer");
416     if($thisMsg != $msgC)
417     {
418     $MsgArray[$msgC] = "deleted";
419     }
420     else
421     {
422     $MsgArray[$msgC] = $msgSize;
423     }
424     }
425     return $MsgArray;
426     }
427    
428     function get ($msgNum)
429     {
430     // Retrieve the specified msg number. Returns an array
431     // where each line of the msg is an array element.
432    
433     if(!isset($this->FP))
434     {
435     $this->ERROR = "POP3 get: No connection to server";
436     return false;
437     }
438    
439     $this->update_timer();
440    
441     $fp = $this->FP;
442     $buffer = $this->BUFFER;
443     $cmd = "RETR $msgNum";
444     $reply = $this->send_cmd($cmd);
445    
446     if(!$this->is_ok($reply))
447     {
448     $this->ERROR = "POP3 get: Error [$reply]";
449     return false;
450     }
451    
452     $count = 0;
453     $MsgArray = array();
454    
455     $line = fgets($fp,$buffer);
456     while ( !ereg("^\.\r\n",$line))
457     {
458     $MsgArray[$count] = $line;
459     $count++;
460     $line = fgets($fp,$buffer);
461     if(empty($line)) { break; }
462     }
463     return $MsgArray;
464     }
465    
466     function last ( $type = "count" )
467     {
468     // Returns the highest msg number in the mailbox.
469     // returns -1 on error, 0+ on success, if type != count
470     // results in a popstat() call (2 element array returned)
471    
472     $last = -1;
473     if(!isset($this->FP))
474     {
475     $this->ERROR = "POP3 last: No connection to server";
476     return $last;
477     }
478    
479     $reply = $this->send_cmd("STAT");
480     if(!$this->is_ok($reply))
481     {
482     $this->ERROR = "POP3 last: error [$reply]";
483     return $last;
484     }
485    
486     $Vars = explode(" ",$reply);
487     $count = $Vars[1];
488     $size = $Vars[2];
489     settype($count,"integer");
490     settype($size,"integer");
491     if($type != "count")
492     {
493     return array($count,$size);
494     }
495     return $count;
496     }
497    
498     function reset ()
499     {
500     // Resets the status of the remote server. This includes
501     // resetting the status of ALL msgs to not be deleted.
502     // This method automatically closes the connection to the server.
503    
504     if(!isset($this->FP))
505     {
506     $this->ERROR = "POP3 reset: No connection to server";
507     return false;
508     }
509     $reply = $this->send_cmd("RSET");
510     if(!$this->is_ok($reply))
511     {
512     // The POP3 RSET command -never- gives a -ERR
513     // response - if it ever does, something truely
514     // wild is going on.
515    
516     $this->ERROR = "POP3 reset: Error [$reply]";
517     @error_log("POP3 reset: ERROR [$reply]",0);
518     }
519     $this->quit();
520     return true;
521     }
522    
523     function send_cmd ( $cmd = "" )
524     {
525     // Sends a user defined command string to the
526     // POP server and returns the results. Useful for
527     // non-compliant or custom POP servers.
528     // Do NOT include the \r\n as part of your command
529     // string - it will be appended automatically.
530    
531     // The return value is a standard fgets() call, which
532     // will read up to $this->BUFFER bytes of data, until it
533     // encounters a new line, or EOF, whichever happens first.
534    
535     // This method works best if $cmd responds with only
536     // one line of data.
537    
538     if(!isset($this->FP))
539     {
540     $this->ERROR = "POP3 send_cmd: No connection to server";
541     return false;
542     }
543    
544     if(empty($cmd))
545     {
546     $this->ERROR = "POP3 send_cmd: Empty command string";
547     return "";
548     }
549    
550     $fp = $this->FP;
551     $buffer = $this->BUFFER;
552     $this->update_timer();
553     fwrite($fp,"$cmd\r\n");
554     $reply = fgets($fp,$buffer);
555     $reply = $this->strip_clf($reply);
556     if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
557     return $reply;
558     }
559    
560     function quit ()
561     {
562     // Closes the connection to the POP3 server, deleting
563     // any msgs marked as deleted.
564    
565     if(!isset($this->FP))
566     {
567     $this->ERROR = "POP3 quit: connection does not exist";
568     return false;
569     }
570     $fp = $this->FP;
571     $cmd = "QUIT";
572     fwrite($fp,"$cmd\r\n");
573     $reply = fgets($fp,$this->BUFFER);
574     $reply = $this->strip_clf($reply);
575     if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
576     fclose($fp);
577     unset($this->FP);
578     return true;
579     }
580    
581     function popstat ()
582     {
583     // Returns an array of 2 elements. The number of undeleted
584     // msgs in the mailbox, and the size of the mbox in octets.
585    
586     $PopArray = $this->last("array");
587    
588     if($PopArray == -1) { return false; }
589    
590     if( (!$PopArray) or (empty($PopArray)) )
591     {
592     return false;
593     }
594     return $PopArray;
595     }
596    
597     function uidl ($msgNum = "")
598     {
599     // Returns the UIDL of the msg specified. If called with
600     // no arguments, returns an associative array where each
601     // undeleted msg num is a key, and the msg's uidl is the element
602     // Array element 0 will contain the total number of msgs
603    
604     if(!isset($this->FP))
605     {
606     $this->ERROR = "POP3 uidl: No connection to server";
607     return false;
608     }
609    
610     $fp = $this->FP;
611     $buffer = $this->BUFFER;
612    
613     if(!empty($msgNum))
614     {
615     $cmd = "UIDL $msgNum";
616     $reply = $this->send_cmd($cmd);
617     if(!$this->is_ok($reply))
618     {
619     $this->ERROR = "POP3 uidl: Error [$reply]";
620     return false;
621     }
622     list ($ok,$num,$myUidl) = explode(" ",$reply);
623     return $myUidl;
624     }
625     else
626     {
627     $this->update_timer();
628    
629     $UIDLArray = array();
630     $Total = $this->COUNT;
631     $UIDLArray[0] = $Total;
632    
633     if ($Total < 1)
634     {
635     return $UIDLArray;
636     }
637     $cmd = "UIDL";
638     fwrite($fp, "UIDL\r\n");
639     $reply = fgets($fp, $buffer);
640     $reply = $this->strip_clf($reply);
641     if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
642     if(!$this->is_ok($reply))
643     {
644     $this->ERROR = "POP3 uidl: Error [$reply]";
645     return false;
646     }
647    
648     $line = "";
649     $count = 1;
650     $line = fgets($fp,$buffer);
651     while ( !ereg("^\.\r\n",$line))
652     {
653     if(ereg("^\.\r\n",$line))
654     {
655     break;
656     }
657     list ($msg,$msgUidl) = explode(" ",$line);
658     $msgUidl = $this->strip_clf($msgUidl);
659     if($count == $msg)
660     {
661     $UIDLArray[$msg] = $msgUidl;
662     }
663     else
664     {
665     $UIDLArray[$count] = "deleted";
666     }
667     $count++;
668     $line = fgets($fp,$buffer);
669     }
670     }
671     return $UIDLArray;
672     }
673    
674     function delete ($msgNum = "")
675     {
676     // Flags a specified msg as deleted. The msg will not
677     // be deleted until a quit() method is called.
678    
679     if(!isset($this->FP))
680     {
681     $this->ERROR = "POP3 delete: No connection to server";
682     return false;
683     }
684     if(empty($msgNum))
685     {
686     $this->ERROR = "POP3 delete: No msg number submitted";
687     return false;
688     }
689     $reply = $this->send_cmd("DELE $msgNum");
690     if(!$this->is_ok($reply))
691     {
692     $this->ERROR = "POP3 delete: Command failed [$reply]";
693     return false;
694     }
695     return true;
696     }
697    
698     // *********************************************************
699    
700     // The following methods are internal to the class.
701    
702     function is_ok ($cmd = "")
703     {
704     // Return true or false on +OK or -ERR
705    
706     if(empty($cmd)) { return false; }
707     if ( ereg ("^\+OK", $cmd ) ) { return true; }
708     return false;
709     }
710    
711     function strip_clf ($text = "")
712     {
713     // Strips \r\n from server responses
714    
715     if(empty($text)) { return $text; }
716     $stripped = ereg_replace("\r","",$text);
717     $stripped = ereg_replace("\n","",$stripped);
718     return $stripped;
719     }
720    
721     function parse_banner ( $server_text )
722     {
723     $outside = true;
724     $banner = "";
725     $length = strlen($server_text);
726     for($count =0; $count < $length; $count++)
727     {
728     $digit = substr($server_text,$count,1);
729     if(!empty($digit))
730     {
731     if( (!$outside) and ($digit != '<') and ($digit != '>') )
732     {
733     $banner .= $digit;
734     }
735     if ($digit == '<')
736     {
737     $outside = false;
738     }
739     if($digit == '>')
740     {
741     $outside = true;
742     }
743     }
744     }
745     $banner = $this->strip_clf($banner); // Just in case
746     return "<$banner>";
747     }
748    
749     } // End class
750    
751     ?>

  ViewVC Help
Powered by ViewVC 1.1.26