Пример #1
0
 /**
  * Generate a MDN from the message
  *
  * @param object $exception The exception if error handled
  *
  * @return object              The MDN generated
  */
 public function generateMDN($exception = null)
 {
     $mdn = $this->mdnFactory->build($this);
     $message_id = $this->getHeader('message-id');
     $partner = $this->getPartnerTo()->id;
     $mic = $this->getMicChecksum();
     $mdn->setAttribute('Original-Recipient', 'rfc822; "' . $partner . '"');
     $mdn->setAttribute('Final-Recipient', 'rfc822; "' . $partner . '"');
     $mdn->setAttribute('Original-Message-ID', $message_id);
     if ($mic) {
         $mdn->setAttribute('Received-Content-MIC', $mic);
     }
     if (is_null($exception)) {
         $mdn->setMessage('The AS2 message has been received.');
         $mdn->setAttribute('Disposition-Type', 'processed');
     } else {
         if (!$exception instanceof AS2Exception) {
             $exception = new AS2Exception($exception->getMessage());
         }
         $mdn->setMessage($exception->getMessage());
         $mdn->setAttribute('Disposition-Type', 'failure');
         $mdn->setAttribute('Disposition-Modifier', $exception->getLevel() . ': ' . $exception->getMessageShort());
     }
     return $mdn;
 }
Пример #2
0
 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);
 }
Пример #3
0
 /**
  * Handle a request (server side)
  *
  * @param request (If not set, get data from standard input)
  *
  * @return request    The request handled
  */
 public function handle(Request $request)
 {
     // handle any problem in case of SYNC MDN process
     ob_start();
     try {
         $error = null;
         $headers = $request->getHeaders();
         $object = $request->getObject();
     } catch (Exception $e) {
         // get error while handling request
         $error = $e;
         //throw $e;
     }
     //
     $mdn = null;
     if ($object instanceof Message || !is_null($error) && !$object instanceof MDN) {
         $object_type = self::TYPE_MESSAGE;
         $this->eventDispatcher->dispatch('log', new Log(Log::TYPE_INFO, 'Incoming transmission is a Message.'));
         try {
             if (is_null($error)) {
                 $object->decode();
                 $files = $object->getFiles();
                 $this->eventDispatcher->dispatch('log', new Log(Log::TYPE_INFO, count($files) . ' payload(s) found in incoming transmission.'));
                 foreach ($files as $key => $file) {
                     $content = file_get_contents($file['path']);
                     $this->eventDispatcher->dispatch('log', new Log(Log::TYPE_INFO, 'Payload #' . ($key + 1) . ' : ' . round(strlen($content) / 1024, 2) . ' KB / "' . $file['filename'] . '".'));
                     $this->saveMessage($content, array(), 'payload');
                 }
                 $mdn = $object->generateMDN($error);
                 $mdn->encode($object);
             } else {
                 throw $error;
             }
         } catch (Exception $e) {
             $params = array('partner_from' => $headers->getHeader('as2-from'), 'partner_to' => $headers->getHeader('as2-to'));
             $mdn = $this->mdnFactory->build($e, $params);
             $mdn->setAttribute('original-message-id', $headers->getHeader('message-id'));
             $mdn->encode();
         }
     } elseif ($object instanceof MDN) {
         $object_type = self::TYPE_MDN;
         $this->eventDispatcher->dispatch('log', new Log(Log::TYPE_INFO, 'Incoming transmission is a MDN.'));
     } else {
         $this->eventDispatcher->dispatch('log', new Log(Log::TYPE_ERROR, 'Malformed data.'));
     }
     // build MDN
     if (!is_null($error) && $object_type == self::TYPE_MESSAGE) {
         $params = array('partner_from' => $headers->getHeader('as2-from'), 'partner_to' => $headers->getHeader('as2-to'));
         $mdn = $this->mdnFactory->build($e, $params);
         $mdn->setAttribute('original-message-id', $headers->getHeader('message-id'));
         $mdn->encode();
     }
     // send MDN
     if (!is_null($mdn)) {
         if (!$headers->getHeader('receipt-delivery-option')) {
             // SYNC method
             // re-active output data
             ob_end_clean();
             // send headers
             foreach ($mdn->getHeaders() as $key => $value) {
                 $header = str_replace(array("\r", "\n", "\r\n"), '', $key . ': ' . $value);
                 header($header);
             }
             // output MDN
             echo $mdn->getContent();
             $this->eventDispatcher->dispatch('log', new Log(Log::TYPE_INFO, 'An AS2 MDN has been sent.'));
         } else {
             // ASYNC method
             // cut connection and wait a few seconds
             $this->closeConnectionAndWait(5);
             // delegate the mdn sending to the client
             $result = $this->client->sendRequest($mdn);
             if ($result['info']['http_code'] == '200') {
                 $this->eventDispatcher->dispatch('log', new Log(Log::TYPE_INFO, 'An AS2 MDN has been sent.'));
             } else {
                 $this->eventDispatcher->dispatch('log', new Log(Log::TYPE_ERROR, 'An error occurs while sending MDN message : ' . $result['info']['http_code']));
             }
         }
     }
     return $request;
 }