/[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

Contents of /auth_pop3.php

Parent Directory Parent Directory | Revision Log Revision Log


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

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