/**
  * Convert the output from mimeDecode::decode() into a structure that
  * matches imap_fetchstructure() output.
  *
  * @access private
  *
  * @param stdClass &$ob The output from mimeDecode::decode().
  */
 protected static function _convertMimeDecodeData(&$ob)
 {
     /* Primary content-type. */
     if (!isset($ob->ctype_primary)) {
         $ob->ctype_primary = 'application';
         $ob->ctype_secondary = 'octet-stream';
     }
     $ob->type = intval(Horde_MIME::type($ob->ctype_primary));
     /* Secondary content-type. */
     if (isset($ob->ctype_secondary)) {
         $ob->subtype = Horde_String::upper($ob->ctype_secondary);
         $ob->ifsubtype = 1;
     } else {
         $ob->ifsubtype = 0;
     }
     /* Content transfer encoding. */
     if (isset($ob->headers['content-transfer-encoding'])) {
         $ob->encoding = Horde_MIME::encoding($ob->headers['content-transfer-encoding']);
     }
     /* Content-type and Disposition parameters. */
     $param_types = array('ctype_parameters' => 'parameters', 'd_parameters' => 'dparameters');
     foreach ($param_types as $param_key => $param_value) {
         $if_var = 'if' . $param_value;
         if (isset($ob->{$param_key})) {
             $ob->{$if_var} = 1;
             $ob->{$param_value} = array();
             foreach ($ob->{$param_key} as $key => $val) {
                 $newOb =& new stdClass();
                 $newOb->attribute = $key;
                 $newOb->value = $val;
                 array_push($ob->{$param_value}, $newOb);
             }
         } else {
             $ob->{$if_var} = 0;
         }
     }
     /* Content-Disposition. */
     if (isset($ob->headers['content-disposition'])) {
         $ob->ifdisposition = 1;
         $hdr = $ob->headers['content-disposition'];
         $pos = strpos($hdr, ';');
         if ($pos !== false) {
             $hdr = substr($hdr, 0, $pos);
         }
         $ob->disposition = $hdr;
     } else {
         $ob->ifdisposition = 0;
     }
     /* Content-ID. */
     if (isset($ob->headers['content-id'])) {
         $ob->ifid = 1;
         $ob->id = $ob->headers['content-id'];
     } else {
         $ob->ifid = 0;
     }
     /* Get file size (if 'body' text is set). */
     if (isset($ob->body)) {
         $ob->bytes = strlen($ob->body);
     }
     /* Process parts also. */
     if (isset($ob->parts)) {
         reset($ob->parts);
         while (list($key, ) = each($ob->parts)) {
             Horde_MIME_Structure::_convertMimeDecodeData($ob->parts[$key]);
         }
     }
 }
 public function getObject()
 {
     // setup of full message
     $content = $this->getHeaders(true) . "\n\n";
     $content .= file_get_contents($this->getPath());
     $input = Adapter::getTempFilename();
     file_put_contents($input, $content);
     // setup of mailmime decoder
     $params = array('include_bodies' => false, 'decode_headers' => true, 'decode_bodies' => false, 'input' => false);
     $decoder = new Mail_mimeDecode(file_get_contents($input));
     $structure = $decoder->decode($params);
     $mimetype = $structure->ctype_primary . '/' . $structure->ctype_secondary;
     // handle crypted content
     $crypted = false;
     if (strtolower($mimetype) == 'application/pkcs7-mime') {
         try {
             // rewrite message into base64 encoding
             $content = file_get_contents($input);
             $mime_part = Horde_MIME_Structure::parseTextMIMEMessage($content);
             $input = Adapter::getTempFilename();
             file_put_contents($input, $mime_part->toString(true));
             $this->eventDispatcher->dispatch('log', new Log(Log::TYPE_INFO, 'AS2 message is encrypted.'));
             $input = $this->adapter->decrypt($input);
             $this->eventDispatcher->dispatch('log', new Log(Log::TYPE_INFO, 'The data has been decrypted using the key "' . $this->getPartnerTo() . '".'));
             $crypted = true;
             // reload extracted content to get mimetype
             $decoder = new Mail_mimeDecode(file_get_contents($input));
             $structure = $decoder->decode($params);
             $mimetype = $structure->ctype_primary . '/' . $structure->ctype_secondary;
         } catch (Exception $e) {
             throw new AS2Exception($e->getMessage(), 3);
         }
     }
     // handle signed content
     $signed = false;
     $mic = false;
     if (strtolower($mimetype) == 'multipart/signed') {
         try {
             $this->eventDispatcher->dispatch('log', new Log(Log::TYPE_INFO, 'AS2 message is signed.'));
             // get MicChecksum from signature
             $mic = $this->adapter->getMicChecksum($input);
             $input = $this->adapter->verify($input);
             $signed = true;
             $this->eventDispatcher->dispatch('log', new Log(Log::TYPE_INFO, 'The sender used the algorithm "' . $structure->ctype_parameters['micalg'] . '" to sign the message.'));
             // reload extracted content to get mimetype
             $decoder = new Mail_mimeDecode(file_get_contents($input));
             $structure = $decoder->decode($params);
             $mimetype = $structure->ctype_primary . '/' . $structure->ctype_secondary;
             $this->eventDispatcher->dispatch('log', new Log(Log::TYPE_INFO, 'Using certificate "' . $this->getPartnerFrom() . '" to verify signature.'));
         } catch (Exception $e) {
             throw new AS2Exception($e->getMessage(), 5);
         }
     } else {
         // check requested algo
         $mic = Adapter::calculateMicChecksum($input, 'sha1');
     }
     // security check
     if (strtolower($mimetype) == 'multipart/report') {
         // check about sign
         /*if ($this->getPartnerFrom()->sec_signature_algorithm == Partner::SIGN_NONE && !$this->getPartnerFrom()->mdn_signed && $signed){
               throw new AS2Exception('AS2 message is signed and shouldn\'t be.', 4);
           }
           else*/
         if ($this->getPartnerFrom()->sec_signature_algorithm != Partner::SIGN_NONE && $this->getPartnerFrom()->mdn_signed && !$signed) {
             throw new AS2Exception('AS2 message is not signed and should be.', 4);
         }
     } else {
         // check about crypt
         /*if ($this->getPartnerFrom()->sec_encrypt_algorithm == Partner::CRYPT_NONE && $crypted){
               throw new AS2Exception('AS2 message is crypted and shouldn\'t be.', 4);
           }
           else*/
         if ($this->getPartnerFrom()->sec_encrypt_algorithm != Partner::CRYPT_NONE && !$crypted) {
             throw new AS2Exception('AS2 message is not crypted and should be.', 4);
         }
         // check about sign
         /*if ($this->getPartnerFrom()->sec_signature_algorithm == Partner::SIGN_NONE && $signed){
               throw new AS2Exception('AS2 message is signed and shouldn\'t be.', 4);
           }
           else*/
         if ($this->getPartnerFrom()->sec_signature_algorithm != Partner::SIGN_NONE && !$signed) {
             throw new AS2Exception('AS2 message is not signed and should be.', 4);
         }
     }
     try {
         // build object with extracted content
         $message = file_get_contents($input);
         $mime_part = Horde_MIME_Structure::parseTextMIMEMessage($message);
         switch (strtolower($mimetype)) {
             case 'multipart/report':
                 $params = array('partner_from' => $this->getPartnerTo(), 'partner_to' => $this->getPartnerFrom(), 'is_file' => false, 'mic' => $mic);
                 $object = $this->mdnFactory->build($mime_part, $params);
                 return $object;
             default:
                 $params = array('partner_from' => $this->getPartnerFrom(), 'partner_to' => $this->getPartnerTo(), 'is_file' => false, 'mic' => $mic);
                 $object = $this->messageFactory->build($mime_part, $params);
                 $object->setHeaders($this->getHeaders());
                 return $object;
         }
     } catch (Exception $e) {
         throw new AS2Exception($e->getMessage(), 6);
     }
     throw new AS2Exception('Unexpected error while handling message.', 6);
 }