/**
  * Constructor.
  *
  * @param string $extension  The extension not supported on the server.
  * @param string $msg        A non-standard error message to use instead
  *                           of the default.
  */
 public function __construct($extension, $msg = null)
 {
     $this->extension = $extension;
     if (is_null($msg)) {
         $msg = sprintf(Horde_Imap_Client_Translation::t("The server does not support the %s extension."), $extension);
     }
     parent::__construct($msg, self::NOT_SUPPORTED);
 }
Exemple #2
0
 /**
  * @param string $tag  Response tag.
  */
 public function __construct(Horde_Imap_Client_Tokenize $token, $tag)
 {
     $this->tag = $tag;
     parent::__construct($token);
     if (is_null($this->status)) {
         throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("Bad tagged response."));
     }
 }
Exemple #3
0
 /**
  * Handle status responses (see RFC 3501 [7.1]).
  *
  * @param Horde_Imap_Client_Interaction_Server $ob  Server object.
  *
  * @throws Horde_Imap_Client_Exception_ServerResponse
  */
 protected function _responseCode(Horde_Imap_Client_Interaction_Server $ob)
 {
     if (is_null($ob->responseCode)) {
         return;
     }
     $rc = $ob->responseCode;
     switch ($rc->code) {
         case 'ALERT':
             // Defined by RFC 5530 [3] - Treat as an alert for now.
         // Defined by RFC 5530 [3] - Treat as an alert for now.
         case 'CONTACTADMIN':
             if (!isset($this->_temp['alerts'])) {
                 $this->_temp['alerts'] = array();
             }
             $this->_temp['alerts'][] = strval($ob->token);
             break;
         case 'BADCHARSET':
             /* Store valid search charsets if returned by server. */
             $s_charset = array();
             foreach ($rc->data[0] as $val) {
                 $s_charset[$val] = true;
             }
             if (!empty($s_charset)) {
                 $this->_setInit('s_charset', array_merge($this->_init['s_charset'], $s_charset));
             }
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("Charset used in search query is not supported on the mail server."), Horde_Imap_Client_Exception::BADCHARSET, $ob->status, strval($ob->token));
         case 'CAPABILITY':
             $this->_parseCapability($rc->data);
             break;
         case 'PARSE':
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("The mail server was unable to parse the contents of the mail message."), Horde_Imap_Client_Exception::PARSEERROR, $ob->status, strval($ob->token));
         case 'READ-ONLY':
             $this->_mode = Horde_Imap_Client::OPEN_READONLY;
             break;
         case 'READ-WRITE':
             $this->_mode = Horde_Imap_Client::OPEN_READWRITE;
             break;
         case 'TRYCREATE':
             // RFC 3501 [7.1]
             $this->_temp['trycreate'] = true;
             break;
         case 'PERMANENTFLAGS':
             $this->_temp['mailbox']['permflags'] = array_map('strtolower', $rc->data[0]);
             break;
         case 'UIDNEXT':
         case 'UIDVALIDITY':
             $this->_temp['mailbox'][strtolower($rc->code)] = $rc->data[0];
             break;
         case 'UNSEEN':
             /* This is different from the STATUS UNSEEN response - this item,
              * if defined, returns the first UNSEEN message in the mailbox. */
             $this->_temp['mailbox']['firstunseen'] = $rc->data[0];
             break;
         case 'REFERRAL':
             // Defined by RFC 2221
             $this->_temp['referral'] = new Horde_Imap_Client_Url($rc->data[0]);
             break;
         case 'UNKNOWN-CTE':
             // Defined by RFC 3516
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("The mail server was unable to parse the contents of the mail message."), Horde_Imap_Client_Exception::UNKNOWNCTE, $ob->status, strval($ob->token));
         case 'APPENDUID':
         case 'COPYUID':
             // Defined by RFC 4315
             // APPENDUID: [0] = UIDVALIDITY, [1] = UID(s)
             // COPYUID: [0] = UIDVALIDITY, [1] = UIDFROM, [2] = UIDTO
             if ($this->_temp['uidplusmbox']->equals($this->_selected) && $this->_temp['mailbox']['uidvalidity'] != $rc->data[0]) {
                 $this->_temp['mailbox'] = array('uidvalidity' => $rc->data[0]);
                 $this->_temp['searchnotsaved'] = true;
             }
             /* Check for cache expiration (see RFC 4549 [4.1]). */
             $this->_updateCache(new Horde_Imap_Client_Fetch_Results(), array('mailbox' => $this->_temp['uidplusmbox'], 'uidvalid' => $rc->data[0]));
             if ($rc->code == 'APPENDUID') {
                 $this->_temp['appenduid']->add($rc->data[1]);
             } else {
                 $from = $this->getIdsOb($rc->data[1]);
                 $to = $this->getIdsOb($rc->data[2]);
                 $this->_temp['copyuid'] = array_combine($from->ids, $to->ids);
                 $this->_temp['copyuidvalid'] = $rc->data[0];
             }
             break;
         case 'UIDNOTSTICKY':
             // Defined by RFC 4315 [3]
             $this->_temp['mailbox']['uidnotsticky'] = true;
             break;
         case 'BADURL':
             // Defined by RFC 4469 [4.1]
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("Could not save message on server."), Horde_Imap_Client_Exception::CATENATE_BADURL, $ob->status, strval($ob->token));
         case 'TOOBIG':
             // Defined by RFC 4469 [4.2]
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("Could not save message data because it is too large."), Horde_Imap_Client_Exception::CATENATE_TOOBIG, $ob->status, strval($ob->token));
         case 'HIGHESTMODSEQ':
             // Defined by RFC 4551 [3.1.1]
             $this->_temp['modseqs'][] = $rc->data[0];
             break;
         case 'NOMODSEQ':
             // Defined by RFC 4551 [3.1.2]
             $this->_temp['modseqs'][] = 0;
             break;
         case 'MODIFIED':
             // Defined by RFC 4551 [3.2]
             $this->_temp['modified']->add($rc->data[0]);
             break;
         case 'CLOSED':
             // Defined by RFC 5162 [3.7]
             if (isset($this->_temp['qresyncmbox'])) {
                 $this->_temp['mailbox'] = array('name' => $this->_temp['qresyncmbox']);
                 $this->_selected = $this->_temp['qresyncmbox'];
             }
             break;
         case 'NOTSAVED':
             // Defined by RFC 5182 [2.5]
             $this->_temp['searchnotsaved'] = true;
             break;
         case 'BADCOMPARATOR':
             // Defined by RFC 5255 [4.9]
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("The comparison algorithm was not recognized by the server."), Horde_Imap_Client_Exception::BADCOMPARATOR, $ob->status, strval($ob->token));
         case 'METADATA':
             $md = $rc->data[0];
             switch ($md[0]) {
                 case 'LONGENTRIES':
                     // Defined by RFC 5464 [4.2.1]
                     $this->_temp['metadata']['*longentries'] = intval($md[1]);
                     break;
                 case 'MAXSIZE':
                     // Defined by RFC 5464 [4.3]
                     throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("The metadata item could not be saved because it is too large."), Horde_Imap_Client_Exception::METADATA_MAXSIZE, $ob->status, intval($md[1]));
                 case 'NOPRIVATE':
                     // Defined by RFC 5464 [4.3]
                     throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("The metadata item could not be saved because the server does not support private annotations."), Horde_Imap_Client_Exception::METADATA_NOPRIVATE, $ob->status, strval($ob->token));
                 case 'TOOMANY':
                     // Defined by RFC 5464 [4.3]
                     throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("The metadata item could not be saved because the maximum number of annotations has been exceeded."), Horde_Imap_Client_Exception::METADATA_TOOMANY, $ob->status, strval($ob->token));
             }
             break;
         case 'UNAVAILABLE':
             // Defined by RFC 5530 [3]
             $this->_temp['loginerr'] = new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("Remote server is temporarily unavailable."), Horde_Imap_Client_Exception::LOGIN_UNAVAILABLE);
             break;
         case 'AUTHENTICATIONFAILED':
             // Defined by RFC 5530 [3]
             $this->_temp['loginerr'] = new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("Authentication failed."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED);
             break;
         case 'AUTHORIZATIONFAILED':
             // Defined by RFC 5530 [3]
             $this->_temp['loginerr'] = new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("Authentication was successful, but authorization failed."), Horde_Imap_Client_Exception::LOGIN_AUTHORIZATIONFAILED);
             break;
         case 'EXPIRED':
             // Defined by RFC 5530 [3]
             $this->_temp['loginerr'] = new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("Authentication credentials have expired."), Horde_Imap_Client_Exception::LOGIN_EXPIRED);
             break;
         case 'PRIVACYREQUIRED':
             // Defined by RFC 5530 [3]
             $this->_temp['loginerr'] = new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("Operation failed due to a lack of a secure connection."), Horde_Imap_Client_Exception::LOGIN_PRIVACYREQUIRED);
             break;
         case 'NOPERM':
             // Defined by RFC 5530 [3]
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("You do not have adequate permissions to carry out this operation."), Horde_Imap_Client_Exception::NOPERM, $ob->status, strval($ob->token));
         case 'INUSE':
             // Defined by RFC 5530 [3]
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("There was a temporary issue when attempting this operation. Please try again later."), Horde_Imap_Client_Exception::INUSE, $ob->status, strval($ob->token));
         case 'EXPUNGEISSUED':
             // Defined by RFC 5530 [3]
             $this->_temp['expungeissued'] = true;
             break;
         case 'CORRUPTION':
             // Defined by RFC 5530 [3]
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("The mail server is reporting corrupt data in your mailbox."), Horde_Imap_Client_Exception::CORRUPTION, $ob->status, strval($ob->token));
         case 'SERVERBUG':
         case 'CLIENTBUG':
         case 'CANNOT':
             // Defined by RFC 5530 [3]
             $this->writeDebug("ERROR: mail server explicitly reporting an error.\n", Horde_Imap_Client::DEBUG_INFO);
             break;
         case 'LIMIT':
             // Defined by RFC 5530 [3]
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("The mail server has denied the request."), Horde_Imap_Client_Exception::LIMIT, $ob->status, strval($ob->token));
         case 'OVERQUOTA':
             // Defined by RFC 5530 [3]
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("The operation failed because the quota has been exceeded on the mail server."), Horde_Imap_Client_Exception::OVERQUOTA, $ob->status, strval($ob->token));
         case 'ALREADYEXISTS':
             // Defined by RFC 5530 [3]
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("The object could not be created because it already exists."), Horde_Imap_Client_Exception::ALREADYEXISTS, $ob->status, strval($ob->token));
         case 'NONEXISTENT':
             // Defined by RFC 5530 [3]
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("The object could not be deleted because it does not exist."), Horde_Imap_Client_Exception::NONEXISTENT, $ob->status, strval($ob->token));
         case 'USEATTR':
             // Defined by RFC 6154 [3]
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("The special-use attribute requested for the mailbox is not supported."), Horde_Imap_Client_Exception::USEATTR, $ob->status, strval($ob->token));
         case 'XPROXYREUSE':
             // The proxy connection was reused, so no need to do login tasks.
             $this->_temp['proxyreuse'] = true;
             break;
         default:
             // Unknown response codes SHOULD be ignored - RFC 3501 [7.1]
             break;
     }
 }
Exemple #4
0
 /**
  * Gets a line from the stream and parses it.
  *
  * @return array  An array with the following keys:
  *   - line: (string) The server response text.
  *   - response: (string) Either 'OK', 'END', '+', or ''.
  *
  * @throws Horde_Imap_Client_Exception
  */
 protected function _getLine()
 {
     $ob = array('line' => '', 'response' => '');
     if (feof($this->_stream)) {
         $this->logout();
         throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("POP3 Server closed the connection unexpectedly."), Horde_Imap_Client_Exception::DISCONNECT);
     }
     $read = rtrim(fgets($this->_stream));
     if (empty($read)) {
         return;
     }
     $this->writeDebug($read . "\n", Horde_Imap_Client::DEBUG_SERVER);
     $orig_read = $read;
     $read = explode(' ', $read, 2);
     switch ($read[0]) {
         case '+OK':
             $ob['response'] = 'OK';
             if (isset($read[1]) && $this->queryCapability('RESP-CODES')) {
                 $response = $this->_parseResponseCode($read[1]);
                 $ob['line'] = $response->text;
             }
             break;
         case '-ERR':
             $errcode = 0;
             if (isset($read[1]) && $this->queryCapability('RESP-CODES')) {
                 $response = $this->_parseResponseCode($read[1]);
                 $errtext = $response->text;
                 if (isset($response->code)) {
                     switch ($response->code) {
                         // RFC 2449 [8.1.1]
                         case 'IN-USE':
                             // RFC 2449 [8.1.2]
                         // RFC 2449 [8.1.2]
                         case 'LOGIN-DELAY':
                             $errcode = Horde_Imap_Client_Exception::LOGIN_UNAVAILABLE;
                             break;
                             // RFC 3206 [4]
                         // RFC 3206 [4]
                         case 'SYS/TEMP':
                             $errcode = Horde_Imap_Client_Exception::POP3_TEMP_ERROR;
                             break;
                             // RFC 3206 [4]
                         // RFC 3206 [4]
                         case 'SYS/PERM':
                             $errcode = Horde_Imap_Client_Exception::POP3_PERM_ERROR;
                             break;
                             // RFC 3206 [5]
                         // RFC 3206 [5]
                         case 'AUTH':
                             $errcode = Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED;
                             break;
                     }
                 }
             } else {
                 $errtext = '[No error message provided by server]';
             }
             throw new Horde_Imap_Client_Exception_ServerResponse(Horde_Imap_Client_Translation::t("POP3 error reported by server."), $errcode, '-ERR', $errtext);
         case '.':
             $ob['response'] = 'END';
             break;
         case '+':
             $ob['response'] = '+';
             break;
         default:
             $ob['line'] = $orig_read;
             break;
     }
     return $ob;
 }
Exemple #5
0
 /**
  * Constructor.
  *
  * @param string $message  Error message (non-translated).
  * @param code $code       Error code.
  */
 public function __construct($message = null, $code = null)
 {
     parent::__construct($message, $code);
     $this->raw_msg = $this->message;
     try {
         $this->message = Horde_Imap_Client_Translation::t($this->message);
     } catch (Horde_Translation_Exception $e) {
     }
 }
Exemple #6
0
 /**
  * Convert a string from UTF-8 to UTF7-IMAP.
  *
  * @param string $str     The UTF-8 string.
  * @param boolean $force  Assume $str is UTF-8 (no-autodetection)? If
  *                        false, attempts to auto-detect if string is
  *                        already in UTF7-IMAP.
  *
  * @return string  The converted UTF7-IMAP string.
  * @throws Horde_Imap_Client_Exception
  */
 public static function Utf8ToUtf7Imap($str, $force = true)
 {
     if ($str instanceof Horde_Imap_Client_Mailbox) {
         return $str->utf7imap;
     }
     $str = strval($str);
     /* No need to do conversion if all chars are in US-ASCII range or if
      * no ampersand is present. But will assume that an already encoded
      * ampersand means string is in UTF7-IMAP already. */
     if (!$force && !preg_match('/[\\x80-\\xff]|&$|&(?![,+A-Za-z0-9]*-)/', $str)) {
         return $str;
     }
     /* Try mbstring, if available, which should be faster. Don't use the
      * IMAP utf7_* functions because they are known to be buggy. */
     if (is_null(self::$_mbstring)) {
         self::$_mbstring = extension_loaded('mbstring');
     }
     if (self::$_mbstring) {
         return @mb_convert_encoding($str, 'UTF7-IMAP', 'UTF-8');
     }
     $u8len = strlen($str);
     $i = 0;
     $base64 = false;
     $p = '';
     $ptr =& self::$_base64;
     while ($u8len) {
         $u8 = $str[$i];
         $c = ord($u8);
         if ($c < 0x80) {
             $ch = $c;
             $n = 0;
         } elseif ($c < 0xc2) {
             throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION);
         } elseif ($c < 0xe0) {
             $ch = $c & 0x1f;
             $n = 1;
         } elseif ($c < 0xf0) {
             $ch = $c & 0xf;
             $n = 2;
         } elseif ($c < 0xf8) {
             $ch = $c & 0x7;
             $n = 3;
         } elseif ($c < 0xfc) {
             $ch = $c & 0x3;
             $n = 4;
         } elseif ($c < 0xfe) {
             $ch = $c & 0x1;
             $n = 5;
         } else {
             throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION);
         }
         if ($n > --$u8len) {
             throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION);
         }
         ++$i;
         for ($j = 0; $j < $n; ++$j) {
             $o = ord($str[$i + $j]);
             if (($o & 0xc0) != 0x80) {
                 throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION);
             }
             $ch = $ch << 6 | $o & 0x3f;
         }
         if ($n > 1 && !($ch >> $n * 5 + 1)) {
             throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION);
         }
         $i += $n;
         $u8len -= $n;
         if ($ch < 0x20 || $ch >= 0x7f) {
             if (!$base64) {
                 $p .= '&';
                 $base64 = true;
                 $b = 0;
                 $k = 10;
             }
             if ($ch & ~0xffff) {
                 $ch = 0xfffe;
             }
             $p .= $ptr[$b | $ch >> $k];
             $k -= 6;
             for (; $k >= 0; $k -= 6) {
                 $p .= $ptr[$ch >> $k & 0x3f];
             }
             $b = $ch << -$k & 0x3f;
             $k += 16;
         } else {
             if ($base64) {
                 if ($k > 10) {
                     $p .= $ptr[$b];
                 }
                 $p .= '-';
                 $base64 = false;
             }
             $p .= chr($ch);
             if (chr($ch) == '&') {
                 $p .= '-';
             }
         }
     }
     if ($base64) {
         if ($k > 10) {
             $p .= $ptr[$b];
         }
         $p .= '-';
     }
     return $p;
 }
Exemple #7
0
 /**
  * Parses and verifies the digest challenge.
  *
  * @param string $challenge  The digest challenge
  *
  * @return array  The parsed challenge as an array with directives as keys.
  *
  * @throws Horde_Imap_Client_Exception
  */
 protected function _parseChallenge($challenge)
 {
     $tokens = array('maxbuf' => 65536, 'realm' => '');
     preg_match_all('/([a-z-]+)=("[^"]+(?<!\\\\)"|[^,]+)/i', $challenge, $matches, PREG_SET_ORDER);
     foreach ($matches as $val) {
         $tokens[$val[1]] = trim($val[2], '"');
     }
     // Required directives.
     if (!isset($tokens['nonce']) || !isset($tokens['algorithm'])) {
         throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("Authentication failure."), 'SERVER_CONNECT');
     }
     return $tokens;
 }
Exemple #8
0
 /**
  * Expunge deleted messages from the given mailbox.
  *
  * @param mixed $mailbox  The mailbox to expunge. Either a
  *                        Horde_Imap_Client_Mailbox object or a string
  *                        (UTF-8).
  * @param array $options  Additional options:
  *   - ids: (Horde_Imap_Client_Ids) A list of messages to expunge, but
  *          only if they are also flagged as deleted.
  *          DEFAULT: All messages marked as deleted will be expunged.
  *   - list: (boolean) If true, returns the list of expunged messages
  *           (UIDs only).
  *           DEFAULT: false
  *
  * @return Horde_Imap_Client_Ids  If 'list' option is true, returns the
  *                                UID list of expunged messages.
  *
  * @throws Horde_Imap_Client_Exception
  */
 public function expunge($mailbox, array $options = array())
 {
     // Open mailbox call will handle the login.
     $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_READWRITE);
     /* Don't expunge if the mailbox is readonly. */
     if ($this->_mode == Horde_Imap_Client::OPEN_READONLY) {
         throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::t("Cannot expunge read-only mailbox."), Horde_Imap_Client_Exception::MAILBOX_READONLY);
     }
     if (empty($options['ids'])) {
         $options['ids'] = $this->getIdsOb(Horde_Imap_Client_Ids::ALL);
     } elseif ($options['ids']->isEmpty()) {
         return $this->getIdsOb();
     }
     return $this->_expunge($options);
 }
Exemple #9
0
 /**
  * Constructor.
  *
  * @param string $charset  The charset that was attempted to be converted
  *                         to.
  */
 public function __construct($charset)
 {
     $this->charset = $charset;
     parent::__construct(Horde_Imap_Client_Translation::t("Cannot convert search query text to new charset"), self::BADCHARSET);
 }
Exemple #10
0
 /**
  * Constructor.
  *
  * @param string $msg  Error message (non-translated).
  * @param code $code   Error code.
  */
 public function __construct($message = null, $code = null)
 {
     parent::__construct($message, $code);
     $this->raw_msg = $this->message;
     $this->message = Horde_Imap_Client_Translation::t($this->message);
 }
Exemple #11
0
 /**
  * Constructor.
  *
  * @param string $feature  The feature not supported in POP3.
  */
 public function __construct($feature)
 {
     parent::__construct(sprintf(Horde_Imap_Client_Translation::t("%s not supported on POP3 servers."), $feature), self::NOT_SUPPORTED);
 }