/** * 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); }