/_jppf/classes/pop3emailclient/pop3_old.php
PHP | 772 lines | 662 code | 59 blank | 51 comment | 149 complexity | c68f0165830e7a3499d07fa5309bb072 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1
- <?php
- /*
- * pop3.php
- *
- * @(#) $Header: /home/mlemos/cvsroot/pop3/pop3.php,v 1.18 2006/06/12 21:02:39 mlemos Exp $
- *
- */
- class pop3_class
- {
- var $hostname="";
- var $port=110;
- var $tls=0;
- var $quit_handshake=0;
- var $error="";
- var $authentication_mechanism="USER";
- var $realm="";
- var $workstation="";
- var $join_continuation_header_lines=1;
-
- var $is_data="";
- /* Private variables - DO NOT ACCESS */
- var $connection=0;
- var $state="DISCONNECTED";
- var $greeting="";
- var $must_update=0;
- var $debug=0;
- var $html_debug=0;
- var $next_token="";
- var $message_buffer="";
- /* Private methods - DO NOT CALL */
- Function Tokenize($string,$separator="")
- {
- if(!strcmp($separator,""))
- {
- $separator=$string;
- $string=$this->next_token;
- }
- for($character=0;$character<strlen($separator);$character++)
- {
- if(GetType($position=strpos($string,$separator[$character]))=="integer")
- $found=(IsSet($found) ? min($found,$position) : $position);
- }
- if(IsSet($found))
- {
- $this->next_token=substr($string,$found+1);
- return(substr($string,0,$found));
- }
- else
- {
- $this->next_token="";
- return($string);
- }
- }
- Function SetError($error)
- {
- return($this->error=$error);
- }
- Function OutputDebug($message)
- {
- $message.="\n";
- if($this->html_debug)
- $message=str_replace("\n","<br />\n",HtmlSpecialChars($message));
- echo $message;
- flush();
- }
- Function GetLine()
- {
- for($line="";;)
- {
- if(feof($this->connection))
- return(0);
- $line.=fgets($this->connection,100);
- $length=strlen($line);
- if($length>=2
- && substr($line,$length-2,2)=="\r\n")
- {
- $line=substr($line,0,$length-2);
- if($this->debug)
- $this->OutputDebug("S $line");
- return($line);
- }
- }
- }
- Function PutLine($line)
- {
- if($this->debug)
- $this->OutputDebug("C $line");
- return(fputs($this->connection,"$line\r\n"));
- }
- Function OpenConnection()
- {
- if($this->tls)
- {
- $version=explode(".",function_exists("phpversion") ? phpversion() : "3.0.7");
- $php_version=intval($version[0])*1000000+intval($version[1])*1000+intval($version[2]);
- if($php_version<4003000)
- return("establishing TLS connections requires at least PHP version 4.3.0");
- if(!function_exists("extension_loaded")
- || !extension_loaded("openssl"))
- return("establishing TLS connections requires the OpenSSL extension enabled");
- }
- if($this->hostname=="")
- return($this->SetError("2 it was not specified a valid hostname"));
- if($this->debug)
- $this->OutputDebug("Connecting to ".$this->hostname." ...");
- if(($this->connection=@fsockopen(($this->tls ? "tls://" : "").$this->hostname,$this->port,$error))==0)
- {
- switch($error)
- {
- case -3:
- return($this->SetError("-3 socket could not be created"));
- case -4:
- return($this->SetError("-4 dns lookup on hostname \"$hostname\" failed"));
- case -5:
- return($this->SetError("-5 connection refused or timed out"));
- case -6:
- return($this->SetError("-6 fdopen() call failed"));
- case -7:
- return($this->SetError("-7 setvbuf() call failed"));
- default:
- return($this->SetError($error." could not connect to the host \"".$this->hostname."\""));
- }
- }
- return("");
- }
- Function CloseConnection()
- {
- if($this->debug)
- $this->OutputDebug("Closing connection.");
- if($this->connection!=0)
- {
- fclose($this->connection);
- $this->connection=0;
- }
- }
- /* Public methods */
- /* Open method - set the object variable $hostname to the POP3 server address. */
- Function Open()
- {
- if($this->state!="DISCONNECTED")
- return($this->SetError("1 a connection is already opened"));
- if(($error=$this->OpenConnection())!="")
- return($error);
- $this->greeting=$this->GetLine();
- if(GetType($this->greeting)!="string"
- || $this->Tokenize($this->greeting," ")!="+OK")
- {
- $this->CloseConnection();
- return($this->SetError("3 POP3 server greeting was not found"));
- }
- $this->Tokenize("<");
- $this->must_update=0;
- $this->state="AUTHORIZATION";
- return("");
- }
- /* Close method - this method must be called at least if there are any
- messages to be deleted */
- Function Close()
- {
- if($this->state=="DISCONNECTED")
- return($this->SetError("no connection was opened"));
- if($this->must_update
- || $this->quit_handshake)
- {
- if($this->PutLine("QUIT")==0)
- return($this->SetError("Could not send the QUIT command"));
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not get quit command response"));
- if($this->Tokenize($response," ")!="+OK")
- return($this->SetError("Could not quit the connection: ".$this->Tokenize("\r\n")));
- }
- $this->CloseConnection();
- $this->state="DISCONNECTED";
- return("");
- }
- /* Login method - pass the user name and password of POP account. Set
- $apop to 1 or 0 wether you want to login using APOP method or not. */
- Function Login($user,$password,$apop=0)
- {
- if($this->state!="AUTHORIZATION")
- return($this->SetError("connection is not in AUTHORIZATION state"));
- if($apop)
- {
- if(!strcmp($this->greeting,""))
- return($this->SetError("Server does not seem to support APOP authentication"));
- if($this->PutLine("APOP $user ".md5("<".$this->greeting.">".$password))==0)
- return($this->SetError("Could not send the APOP command"));
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not get APOP login command response"));
- if($this->Tokenize($response," ")!="+OK")
- return($this->SetError("APOP login failed: ".$this->Tokenize("\r\n")));
- }
- else
- {
- $authenticated=0;
- if(strcmp($this->authentication_mechanism,"USER")
- && function_exists("class_exists")
- && class_exists("sasl_client_class"))
- {
- if(strlen($this->authentication_mechanism))
- $mechanisms=array($this->authentication_mechanism);
- else
- {
- $mechanisms=array();
- if($this->PutLine("CAPA")==0)
- return($this->SetError("Could not send the CAPA command"));
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not get CAPA command response"));
- if(!strcmp($this->Tokenize($response," "),"+OK"))
- {
- for(;;)
- {
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not retrieve the supported authentication methods"));
- switch($this->Tokenize($response," "))
- {
- case ".":
- break 2;
- case "SASL":
- for($method=1;strlen($mechanism=$this->Tokenize(" "));$method++)
- $mechanisms[]=$mechanism;
- break;
- }
- }
- }
- }
- $sasl=new sasl_client_class;
- $sasl->SetCredential("user",$user);
- $sasl->SetCredential("password",$password);
- if(strlen($this->realm))
- $sasl->SetCredential("realm",$this->realm);
- if(strlen($this->workstation))
- $sasl->SetCredential("workstation",$this->workstation);
- do
- {
- $status=$sasl->Start($mechanisms,$message,$interactions);
- }
- while($status==SASL_INTERACT);
- switch($status)
- {
- case SASL_CONTINUE:
- break;
- case SASL_NOMECH:
- if(strlen($this->authentication_mechanism))
- return($this->SetError("authenticated mechanism ".$this->authentication_mechanism." may not be used: ".$sasl->error));
- break;
- default:
- return($this->SetError("Could not start the SASL authentication client: ".$sasl->error));
- }
- if(strlen($sasl->mechanism))
- {
- if($this->PutLine("AUTH ".$sasl->mechanism.(IsSet($message) ? " ".base64_encode($message) : ""))==0)
- return("Could not send the AUTH command");
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return("Could not get AUTH command response");
- switch($this->Tokenize($response," "))
- {
- case "+OK":
- $response="";
- break;
- case "+":
- $response=base64_decode($this->Tokenize("\r\n"));
- break;
- default:
- return($this->SetError("Authentication error: ".$this->Tokenize("\r\n")));
- }
- for(;!$authenticated;)
- {
- do
- {
- $status=$sasl->Step($response,$message,$interactions);
- }
- while($status==SASL_INTERACT);
- switch($status)
- {
- case SASL_CONTINUE:
- if($this->PutLine(base64_encode($message))==0)
- return("Could not send message authentication step message");
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return("Could not get authentication step message response");
- switch($this->Tokenize($response," "))
- {
- case "+OK":
- $authenticated=1;
- break;
- case "+":
- $response=base64_decode($this->Tokenize("\r\n"));
- break;
- default:
- return($this->SetError("Authentication error: ".$this->Tokenize("\r\n")));
- }
- break;
- default:
- return($this->SetError("Could not process the SASL authentication step: ".$sasl->error));
- }
- }
- }
- }
- if(!$authenticated)
- {
- if($this->PutLine("USER $user")==0)
- return($this->SetError("Could not send the USER command"));
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not get user login entry response"));
- if($this->Tokenize($response," ")!="+OK")
- return($this->SetError("User error: ".$this->Tokenize("\r\n")));
- if($this->PutLine("PASS $password")==0)
- return($this->SetError("Could not send the PASS command"));
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not get login password entry response"));
- if($this->Tokenize($response," ")!="+OK")
- return($this->SetError("Password error: ".$this->Tokenize("\r\n")));
- }
- }
- $this->state="TRANSACTION";
- return("");
- }
- /* Statistics method - pass references to variables to hold the number of
- messages in the mail box and the size that they take in bytes. */
- Function Statistics(&$messages,&$size)
- {
- if($this->state!="TRANSACTION")
- return($this->SetError("connection is not in TRANSACTION state"));
- if($this->PutLine("STAT")==0)
- return($this->SetError("Could not send the STAT command"));
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not get the statistics command response"));
- if($this->Tokenize($response," ")!="+OK")
- return($this->SetError("Could not get the statistics: ".$this->Tokenize("\r\n")));
- $messages=$this->Tokenize(" ");
- $size=$this->Tokenize(" ");
- return("");
- }
- /* ListMessages method - the $message argument indicates the number of a
- message to be listed. If you specify an empty string it will list all
- messages in the mail box. The $unique_id flag indicates if you want
- to list the each message unique identifier, otherwise it will
- return the size of each message listed. If you list all messages the
- result will be returned in an array. */
- Function ListMessages($message,$unique_id)
- {
- if($this->state!="TRANSACTION")
- return($this->SetError("connection is not in TRANSACTION state"));
- if($unique_id)
- $list_command="UIDL";
- else
- $list_command="LIST";
- if($this->PutLine("$list_command".($message ? " ".$message : ""))==0)
- return($this->SetError("Could not send the $list_command command"));
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not get message list command response"));
- if($this->Tokenize($response," ")!="+OK")
- return($this->SetError("Could not get the message listing: ".$this->Tokenize("\r\n")));
- if($message=="")
- {
- for($messages=array();;)
- {
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not get message list response"));
- if($response==".")
- break;
- $message=intval($this->Tokenize($response," "));
- if($unique_id)
- $messages[$message]=$this->Tokenize(" ");
- else
- $messages[$message]=intval($this->Tokenize(" "));
- }
- return($messages);
- }
- else
- {
- $message=intval($this->Tokenize(" "));
- $value=$this->Tokenize(" ");
- return($unique_id ? $value : intval($value));
- }
- }
- /* RetrieveMessage method - the $message argument indicates the number of
- a message to be listed. Pass a reference variables that will hold the
- arrays of the $header and $body lines. The $lines argument tells how
- many lines of the message are to be retrieved. Pass a negative number
- if you want to retrieve the whole message. */
- Function RetrieveMessage($message,&$headers,&$body,$lines)
- {
- if($this->state!="TRANSACTION")
- return($this->SetError("connection is not in TRANSACTION state"));
- if($lines<0)
- {
- $command="RETR";
- $arguments="$message";
- }
- else
- {
- $command="TOP";
- $arguments="$message $lines";
- }
-
-
-
- if($this->PutLine("$command $arguments")==0)
- return($this->SetError("Could not send the $command command"));
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not get message retrieval command response"));
- if($this->Tokenize($response," ")!="+OK")
- return($this->SetError("Could not retrieve the message: ".$this->Tokenize("\r\n")));
-
-
- for($headers=$body=array(),$line=0;;)
- {
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not retrieve the message"));
- switch($response)
- {
- case ".":
- return("");
- case "":
- break 2;
- default:
- if(substr($response,0,1)==".")
- $response=substr($response,1,strlen($response)-1);
- break;
- }
- if($this->join_continuation_header_lines
- && $line>0
- && ($response[0]=="\t"
- || $response[0]==" "))
- $headers[$line-1].=$response;
- else
- {
- $headers[$line]=$response;
- $line++;
- }
- }
- for($line=0;;$line++)
- {
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not retrieve the message"));
- switch($response)
- {
- case ".":
- return("");
- default:
- if(substr($response,0,1)==".")
- $response=substr($response,1,strlen($response)-1);
- break;
- }
- $body[$line]=$response;
- }
- return("");
- }
- /* RetrieveMessageRaw method - the $message argument indicates the number of
- a message to be listed. Pass a reference variable that will hold the
- raw data of the message The $lines argument tells how
- many lines of the message are to be retrieved. Pass a negative number
- if you want to retrieve the whole message. */
- Function RetrieveMessageRaw($message,&$rawdata,$lines)
- {
- $rawdata='';
-
- if($this->state!="TRANSACTION")
- return($this->SetError("connection is not in TRANSACTION state"));
- if($lines<0)
- {
- $command="RETR";
- $arguments="$message";
- }
- else
- {
- $command="TOP";
- $arguments="$message $lines";
- }
-
-
-
- if($this->PutLine("$command $arguments")==0)
- return($this->SetError("Could not send the $command command"));
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not get message retrieval command response"));
- if($this->Tokenize($response," ")!="+OK")
- return($this->SetError("Could not retrieve the message: ".$this->Tokenize("\r\n")));
-
- $rawdata='';
-
- for(;;)
- {
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not retrieve the message"));
- switch($response)
- {
- case ".":
- $rawdata.=$response."\r\n";
- return("");
- default:
- $rawdata.=$response."\r\n";
- break;
- }
-
- }
- return("");
- }
-
-
-
- /* OpenMessage method - the $message argument indicates the number of
- a message to be opened. The $lines argument tells how many lines of
- the message are to be retrieved. Pass a negative number if you want
- to retrieve the whole message. */
- Function OpenMessage($message, $lines=-1)
- {
- if($this->state!="TRANSACTION")
- return($this->SetError("connection is not in TRANSACTION state"));
- if($lines<0)
- {
- $command="RETR";
- $arguments="$message";
- }
- else
- {
- $command="TOP";
- $arguments="$message $lines";
- }
- if($this->PutLine("$command $arguments")==0)
- return($this->SetError("Could not send the $command command"));
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not get message retrieval command response"));
- if($this->Tokenize($response," ")!="+OK")
- return($this->SetError("Could not retrieve the message: ".$this->Tokenize("\r\n")));
- $this->state="GETMESSAGE";
- $this->message_buffer="";
- return("");
- }
- /* GetMessage method - the $count argument indicates the number of bytes
- to be read from an opened message. The $message returns by reference
- the data read from the message. The $end_of_message argument returns
- by reference a boolean value indicated whether it was reached the end
- of the message. */
- Function GetMessage($count, &$message, &$end_of_message)
- {
- if($this->state!="GETMESSAGE")
- return($this->SetError("connection is not in GETMESSAGE state"));
- $message="";
- $end_of_message=0;
- while($count>strlen($this->message_buffer)
- && !$end_of_message)
- {
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not retrieve the message headers"));
- if(!strcmp($response,"."))
- {
- $end_of_message=1;
- $this->state="TRANSACTION";
- break;
- }
- else
- {
- if(substr($response,0,1)==".")
- $response=substr($response,1,strlen($response)-1);
- $this->message_buffer.=$response."\r\n";
- }
- }
- if($end_of_message
- || $count>=strlen($this->message_buffer))
- {
- $message=$this->message_buffer;
- $this->message_buffer="";
- }
- else
- {
- $message=substr($this->message_buffer, 0, $count);
- $this->message_buffer=substr($this->message_buffer, $count);
- }
- return("");
- }
- /* DeleteMessage method - the $message argument indicates the number of
- a message to be marked as deleted. Messages will only be effectively
- deleted upon a successful call to the Close method. */
- Function DeleteMessage($message)
- {
- if($this->state!="TRANSACTION")
- return($this->SetError("connection is not in TRANSACTION state"));
- if($this->PutLine("DELE $message")==0)
- return($this->SetError("Could not send the DELE command"));
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not get message delete command response"));
- if($this->Tokenize($response," ")!="+OK")
- return($this->SetError("Could not delete the message: ".$this->Tokenize("\r\n")));
- $this->must_update=1;
- return("");
- }
- /* ResetDeletedMessages method - Reset the list of marked to be deleted
- messages. No messages will be marked to be deleted upon a successful
- call to this method. */
- Function ResetDeletedMessages()
- {
- if($this->state!="TRANSACTION")
- return($this->SetError("connection is not in TRANSACTION state"));
- if($this->PutLine("RSET")==0)
- return($this->SetError("Could not send the RSET command"));
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not get reset deleted messages command response"));
- if($this->Tokenize($response," ")!="+OK")
- return($this->SetError("Could not reset deleted messages: ".$this->Tokenize("\r\n")));
- $this->must_update=0;
- return("");
- }
- /* IssueNOOP method - Just pings the server to prevent it auto-close the
- connection after an idle timeout (tipically 10 minutes). Not very
- useful for most likely uses of this class. It's just here for
- protocol support completeness. */
- Function IssueNOOP()
- {
- if($this->state!="TRANSACTION")
- return($this->SetError("connection is not in TRANSACTION state"));
- if($this->PutLine("NOOP")==0)
- return($this->SetError("Could not send the NOOP command"));
- $response=$this->GetLine();
- if(GetType($response)!="string")
- return($this->SetError("Could not NOOP command response"));
- if($this->Tokenize($response," ")!="+OK")
- return($this->SetError("Could not issue the NOOP command: ".$this->Tokenize("\r\n")));
- return("");
- }
- };
- class pop3_stream
- {
- var $report_errors = 1;
- var $message = 0;
- var $read = 0;
- var $buffer = "";
- var $end_of_message=0;
- Function SetError($error)
- {
- if($this->report_errors)
- trigger_error($error);
- return(FALSE);
- }
- Function stream_open($path, $mode, $options, &$opened_path)
- {
- $this->report_errors = (($options & STREAM_REPORT_ERRORS) !=0);
- if(strcmp($mode, "r"))
- return($this->SetError("the message can only be opened for reading"));
- $url=parse_url($path);
- $this->pop3=new pop3_class;
- if(IsSet($url["host"]))
- $this->pop3->hostname=$url["host"];
- if(IsSet($url["port"]))
- $this->pop3->port=intval($url["port"]);
- if(IsSet($url["scheme"])
- && !strcmp($url["scheme"],"pop3s"))
- $this->pop3->tls=1;
- if(!IsSet($url["user"]))
- return($this->SetError("it was not specified a valid POP3 user"));
- if(!IsSet($url["pass"]))
- return($this->SetError("it was not specified a valid POP3 password"));
- if(!IsSet($url["path"])
- || strcmp(intval($path=substr($url["path"],1)),$path))
- return($this->SetError("it was not specified a valid message to retrieve"));
- $apop=0;
- if(IsSet($url["query"]))
- {
- parse_str($url["query"],$query);
- if(IsSet($query["debug"]))
- $this->pop3->debug = intval($query["debug"]);
- if(IsSet($query["html_debug"]))
- $this->pop3->html_debug = intval($query["html_debug"]);
- if(IsSet($query["tls"]))
- $this->pop3->tls = intval($query["tls"]);
- if(IsSet($query["apop"]))
- $apop = intval($query["apop"]);
- if(IsSet($query["realm"]))
- $this->pop3->realm = UrlDecode($query["realm"]);
- if(IsSet($query["workstation"]))
- $this->pop3->workstation = UrlDecode($query["workstation"]);
- if(IsSet($query["authentication_mechanism"]))
- $this->pop3->realm = UrlDecode($query["authentication_mechanism"]);
- }
- if(strlen($error=$this->pop3->Open()))
- return($this->SetError($error));
- if(strlen($error=$this->pop3->Login(UrlDecode($url["user"]), UrlDecode($url["pass"]),$apop))
- || strlen($error=$this->pop3->OpenMessage($this->message = intval($path),-1)))
- {
- $this->pop3->Close();
- return($this->SetError($error));
- }
- $this->end_of_message=FALSE;
- if($options & STREAM_USE_PATH)
- $opened_path=$path;
- $this->read = 0;
- $this->buffer = "";
- return(TRUE);
- }
- Function stream_eof()
- {
- if($this->read==0)
- return(FALSE);
- return($this->end_of_message);
- }
- Function stream_read($count)
- {
- if($count<=0)
- return($this->SetError("it was not specified a valid length of the message to read"));
- if($this->end_of_message)
- return("");
- if(strlen($error=$this->pop3->GetMessage($count, $read, $this->end_of_message)))
- return($this->SetError($error));
- $this->read += strlen($read);
- return($read);
- }
- };
- ?>