/** * Build message and encode it (signing and/or crypting) * */ public function encode() { if (!$this->getPartnerFrom() instanceof Partner || !$this->getPartnerTo() instanceof Partner) { throw new AS2Exception('Object not properly initialized'); } // initialisation $this->mic_checksum = false; $this->setMessageId(self::generateMessageID($this->getPartnerFrom())); // chargement et construction du message $files = $this->getFiles(); // initial message creation : mime_part // TODO : use adapter to build multipart file try { // managing all files (parts) $parts = array(); foreach ($files as $file) { $mime_part = new Horde_MIME_Part($file['mimetype']); $mime_part->setContents(file_get_contents($file['path'])); $mime_part->setName($file['filename']); if ($file['encoding']) { $mime_part->setTransferEncoding($file['encoding']); } $parts[] = $mime_part; } if (count($parts) > 1) { // handling multipart file $mime_part = new Horde_MIME_Part('multipart/mixed'); foreach ($parts as $part) { $mime_part->addPart($part); } } else { // handling mono part (body) $mime_part = $parts[0]; } $file = Adapter::getTempFilename(); file_put_contents($file, $mime_part->toString()); } catch (Exception $e) { throw $e; return false; } // signing file if wanted by Partner_To if ($this->getPartnerTo()->sec_signature_algorithm != Partner::SIGN_NONE) { try { $file = $this->adapter->sign($file, $this->getPartnerTo()->send_compress, $this->getPartnerTo()->send_encoding); $this->is_signed = true; //echo file_get_contents($file); $this->mic_checksum = $this->getMicChecksum($file); } catch (Exception $e) { throw $e; return false; } } // crypting file if wanted by Partner_To if ($this->getPartnerTo()->sec_encrypt_algorithm != Partner::CRYPT_NONE) { try { $file = $this->adapter->encrypt($file); $this->is_crypted = true; } catch (Exception $e) { throw $e; return false; } } $this->path = $file; /*if ($mime_part->getTransferEncoding() == 'base64'){ file_put_contents($this->path, base64_decode($mime_part->toString(false))); } else{ file_put_contents($this->path, $mime_part->toString()); }*/ // headers setup $headers = array('AS2-From' => '"' . $this->getPartnerFrom()->id . '"', 'AS2-To' => '"' . $this->getPartnerTo()->id . '"', 'AS2-Version' => '1.0', 'From' => $this->getPartnerFrom()->email, 'Subject' => $this->getPartnerFrom()->send_subject, 'Message-ID' => $this->getMessageId(), 'Mime-Version' => '1.0', 'Disposition-Notification-To' => $this->getPartnerFrom()->send_url, 'Recipient-Address' => $this->getPartnerTo()->send_url, 'User-Agent' => 'AS2Secure - PHP Lib for AS2 message encoding / decoding'); if ($this->getPartnerTo()->mdn_signed) { $headers['Disposition-Notification-Options'] = 'signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, sha1'; } if ($this->getPartnerTo()->mdn_request == Partner::ACK_ASYNC) { $headers['Receipt-Delivery-Option'] = $this->getPartnerFrom()->send_url; } $this->headers = new Header($headers); // look for additionnal headers from message // eg : content-type $content = file_get_contents($this->path); $this->headers->addHeadersFromMessage($content); if (strpos($content, "\n\n") !== false) { $content = substr($content, strpos($content, "\n\n") + 2); } file_put_contents($this->path, $content); return true; }
/** * Retrieve a specific MIME part. * * @param string $id The MIME_Part ID string. * * @return MIME_Part The MIME_Part requested, or false if the part * doesn't exist. */ public function &getPart($id) { if ($this->_build) { $part = parent::getPart($id); } else { $this->buildMessage(); $part = $this->getPart($id); } if (is_a($part, 'Horde_MIME_Message')) { $newpart =& new Horde_MIME_Part(); $skip = array('_build', '_defaultServer'); foreach (array_keys(get_object_vars($part)) as $key) { /* Ignore local variables that aren't a part of the original * class. */ if (!in_array($key, $skip)) { $newpart->{$key} =& $part->{$key}; } } return $newpart; } else { return $part; } }
/** * Encode and generate MDN from attributes and message (if exists) * * @param object $message The refering message */ public function encode($message = null) { // container $container = new Horde_MIME_Part('multipart/report', ' '); // first part $text = new Horde_MIME_Part('text/plain', $this->getMessage(), MIME_DEFAULT_CHARSET, null, '7bit'); // add human readable message $container->addPart($text); // second part $lines = new Header(); $lines->addHeader('Reporting-UA', 'AS2Secure - PHP Lib for AS2 message encoding / decoding'); if ($this->getPartnerFrom()) { $lines->addHeader('Original-Recipient', 'rfc822; "' . $this->getPartnerFrom()->id . '"'); $lines->addHeader('Final-Recipient', 'rfc822; "' . $this->getPartnerFrom()->id . '"'); } $lines->addHeader('Original-Message-ID', $this->getAttribute('original-message-id')); $lines->addHeader('Disposition', $this->getAttribute('action-mode') . '/' . $this->getAttribute('sending-mode') . '; ' . $this->getAttribute('disposition-type')); if ($this->getAttribute('disposition-type') != self::TYPE_PROCESSED) { $lines->addHeader('Disposition', $lines->getHeader('Disposition') . ': ' . $this->getAttribute('disposition-modifier')); } if ($this->getAttribute('received-content-mic')) { $lines->addHeader('Received-Content-MIC', $this->getAttribute('received-content-mic')); } // build computer readable message $mdn = new Horde_MIME_Part('message/disposition-notification', $lines, MIME_DEFAULT_CHARSET, null, '7bit'); $container->addPart($mdn); $this->setMessageId(self::generateMessageID($this->getPartnerFrom())); // headers setup $this->headers = new Header(array('AS2-Version' => '1.0', 'Message-ID' => $this->getMessageId(), 'Mime-Version' => '1.0', 'Server' => 'AS2Secure - PHP Lib for AS2 message encoding / decoding', 'User-Agent' => 'AS2Secure - PHP Lib for AS2 message encoding / decoding')); $this->headers->addHeaders($container->header()); if ($this->getPartnerFrom()) { $headers_from = array('AS2-From' => '"' . $this->getPartnerFrom()->id . '"', 'From' => $this->getPartnerFrom()->email, 'Subject' => $this->getPartnerFrom()->mdn_subject, 'Disposition-Notification-To' => $this->getPartnerFrom()->send_url); $this->headers->addHeaders($headers_from); } if ($this->getPartnerTo()) { $headers_to = array('AS2-To' => '"' . $this->getPartnerTo()->id . '"', 'Recipient-Address' => $this->getPartnerTo()->send_url); $this->headers->addHeaders($headers_to); } if ($message && ($url = $message->getHeader('Receipt-Delivery-Option')) && $this->getPartnerFrom()) { $this->url = $url; $this->headers->addHeader('Recipient-Address', $this->getPartnerFrom()->send_url); } $this->path = Adapter::getTempFilename(); // signing if requested if ($message && $message->getHeader('Disposition-Notification-Options')) { file_put_contents($this->path, $container->toCanonicalString(true)); $this->path = $this->adapter->sign($this->path); $content = file_get_contents($this->path); $this->headers->addHeadersFromMessage($content); // TODO : replace with futur AS2MimePart to separate content from header if (strpos($content, "\n\n") !== false) { $content = substr($content, strpos($content, "\n\n") + 2); } file_put_contents($this->path, ltrim($content)); } else { file_put_contents($this->path, $container->toCanonicalString(false)); $content = $container->toString(); } }