/** * Attemp to log in to the sieve server. * * It will return false if it fails, true if all is well. This also loads * some arrays up with some handy information: * * capabilities["implementation"] contains the sieve version information * * capabilities["auth"] contains the supported authentication modes by the * SIEVE server. * * capabilities["modules"] contains the built in modules like "reject", * "redirect", etc. * * capabilities["starttls"] , if is set and equal to true, will show that the * server supports the STARTTLS extension. * * capabilities["unknown"] contains miscellaneous/extraneous header info sieve * may have sent * * @return boolean */ function sieve_login() { $this->WriteLog('start connect to ' . $this->host . ':' . $this->port); $this->fp = fsockopen($this->host, $this->port); if ($this->fp == false) { return false; } $this->line = $this->__fgets(1024); //Hack for older versions of Sieve Server. They do not respond with the Cyrus v2. standard //response. They repsond as follows: "Cyrus timsieved v1.0.0" "SASL={PLAIN,........}" //So, if we see IMLEMENTATION in the first line, then we are done. if (preg_match('/IMPLEMENTATION/', $this->line)) { //we're on the Cyrus V2 sieve server while (sieve::status($this->line) == F_DATA) { $this->item = sieve::parse_for_quotes($this->line); if (strcmp($this->item[0], "IMPLEMENTATION") == 0) { $this->capabilities["implementation"] = $this->item[1]; } elseif (strcmp($this->item[0], "SIEVE") == 0 or strcmp($this->item[0], "SASL") == 0) { if (strcmp($this->item[0], "SIEVE") == 0) { $this->cap_type = "modules"; } else { $this->cap_type = "auth"; } $this->modules = explode(" ", $this->item[1]); if (is_array($this->modules)) { foreach ($this->modules as $this->module) { $this->capabilities[$this->cap_type][$this->module] = true; } } elseif (is_string($this->modules)) { $this->capabilites[$this->cap_type][$this->modules] = true; } } elseif (strcmp($this->item[0], "STARTTLS") == 0) { $this->capabilities['starttls'] = true; } else { $this->capabilities["unknown"][] = $this->line; } $this->line = $this->__fgets(1024); } // end while } else { //we're on the older Cyrus V1. server //this version does not support module reporting. We only have auth types. $this->cap_type = "auth"; //break apart at the "Cyrus timsieve...." "SASL={......}" $this->item = sieve::parse_for_quotes($this->line); $this->capabilities["implementation"] = $this->item[0]; //we should have "SASL={..........}" now. Break out the {xx,yyy,zzzz} $this->modules = substr($this->item[1], strpos($this->item[1], "{"), strlen($this->item[1]) - 1); //then split again at the ", " stuff. // $this->modules = split($this->modules, ", "); $this->modules = explode(', ', $this->modules); //fill up our $this->modules property if (is_array($this->modules)) { foreach ($this->modules as $this->module) { $this->capabilities[$this->cap_type][$this->module] = true; } } elseif (is_string($this->modules)) { $this->capabilites[$this->cap_type][$this->module] = true; } } if (sieve::status($this->line) == F_NO) { //here we should do some returning of error codes? $this->error = EC_UNKNOWN; $this->error_raw = "Server not allowing connections."; return false; } /* decision login to decide what type of authentication to use... */ /* Loop through each allowed authentication type and see if the server allows the type */ foreach (explode(" ", $this->auth_types) as $auth_type) { if (isset($this->capabilities["auth"][$auth_type])) { /* We found an auth type that is allowed. */ $this->auth_in_use = $auth_type; } } /* call our authentication program */ return sieve::authenticate(); }