@Test
  public void testNoHeaderRemoved() throws MessagingException {
    GenericMailet mailet = setupMockedMailet("h1", "h2");
    Mail mail = getMockedMail(getMockedMimeMessage());

    // Get sure both headers are present
    Assert.assertNotNull("Header present", mail.getMessage().getHeader(HEADER1));
    Assert.assertNotNull("Header present", mail.getMessage().getHeader(HEADER2));

    mailet.service(mail);

    // Both header should be removed
    Assert.assertNotNull("Header present", mail.getMessage().getHeader(HEADER1));
    Assert.assertNotNull("header present", mail.getMessage().getHeader(HEADER2));
  }
  private void sendReplyFromPostmaster(Mail mail, String stringContent) {
    try {
      MailAddress notifier = getMailetContext().getPostmaster();

      MailAddress senderMailAddress = mail.getSender();

      MimeMessage message = mail.getMessage();
      // Create the reply message
      MimeMessage reply = new MimeMessage(Session.getDefaultInstance(System.getProperties(), null));

      // Create the list of recipients in the Address[] format
      InternetAddress[] rcptAddr = new InternetAddress[1];
      rcptAddr[0] = senderMailAddress.toInternetAddress();
      reply.setRecipients(Message.RecipientType.TO, rcptAddr);

      // Set the sender...
      reply.setFrom(notifier.toInternetAddress());

      // Create the message body
      MimeMultipart multipart = new MimeMultipart();
      // Add message as the first mime body part
      MimeBodyPart part = new MimeBodyPart();
      part.setContent(stringContent, "text/plain");
      part.setHeader(RFC2822Headers.CONTENT_TYPE, "text/plain");
      multipart.addBodyPart(part);

      reply.setContent(multipart);
      reply.setHeader(RFC2822Headers.CONTENT_TYPE, multipart.getContentType());

      // Create the list of recipients in our MailAddress format
      Set<MailAddress> recipients = new HashSet<MailAddress>();
      recipients.add(senderMailAddress);

      // Set additional headers
      if (reply.getHeader(RFC2822Headers.DATE) == null) {
        reply.setHeader(RFC2822Headers.DATE, rfc822DateFormat.format(new java.util.Date()));
      }
      String subject = message.getSubject();
      if (subject == null) {
        subject = "";
      }
      if (subject.indexOf("Re:") == 0) {
        reply.setSubject(subject);
      } else {
        reply.setSubject("Re:" + subject);
      }
      reply.setHeader(RFC2822Headers.IN_REPLY_TO, message.getMessageID());

      // Send it off...
      getMailetContext().sendMail(notifier, recipients, reply);
    } catch (Exception e) {
      log("Exception found sending reply", e);
    }
  }
 /**
  * Writes the mail message to the given mail node.
  *
  * @param node mail node
  * @param mail mail message
  * @throws MessagingException if a messaging error occurs
  * @throws RepositoryException if a repository error occurs
  * @throws IOException if an IO error occurs
  */
 private void setMail(Node node, Mail mail)
     throws MessagingException, RepositoryException, IOException {
   setState(node, mail.getState());
   setLastUpdated(node, mail.getLastUpdated());
   setError(node, mail.getErrorMessage());
   setRemoteHost(node, mail.getRemoteHost());
   setRemoteAddr(node, mail.getRemoteAddr());
   setSender(node, mail.getSender());
   setRecipients(node, mail.getRecipients());
   setMessage(node, mail.getMessage());
   setAttributes(node, mail);
 }
 /**
  * Takes the message and adds a header to it.
  *
  * @param mail the mail being processed
  * @throws MessagingException if an error arises during message processing
  */
 public void service(Mail mail) {
   try {
     MimeMessage message = mail.getMessage();
     Classifier classifier = new Classifier(message);
     String classification = classifier.getClassification();
     // if ( !classification.equals("Normal") ) {
     message.setHeader(headerName, classification);
     message.saveChanges();
     // }
   } catch (javax.mail.MessagingException me) {
     log("Error classifying message: " + me.getMessage());
   }
 }
Example #5
0
  /**
   * @see
   *     org.apache.james.smtpserver.JamesMessageHook#onMessage(org.apache.james.protocols.smtp.SMTPSession,
   *     org.apache.mailet.Mail)
   */
  public HookResult onMessage(SMTPSession session, Mail mail) {

    try {
      MimeMessage message = mail.getMessage();
      SpamAssassinInvoker sa = new SpamAssassinInvoker(spamdHost, spamdPort);
      sa.scanMail(message);

      // Add the headers
      for (String key : sa.getHeadersAsAttribute().keySet()) {
        mail.setAttribute(key, sa.getHeadersAsAttribute().get(key));
      }

      // Check if rejectionHits was configured
      if (spamdRejectionHits > 0) {
        try {
          double hits = Double.parseDouble(sa.getHits());

          // if the hits are bigger the rejectionHits reject the
          // message
          if (spamdRejectionHits <= hits) {
            String buffer =
                "Rejected message from "
                    + session.getAttachment(SMTPSession.SENDER, State.Transaction).toString()
                    + " from host "
                    + session.getRemoteAddress().getHostName()
                    + " ("
                    + session.getRemoteAddress().getAddress().getHostAddress()
                    + ") This message reach the spam hits treshold. Required rejection hits: "
                    + spamdRejectionHits
                    + " hits: "
                    + hits;
            session.getLogger().info(buffer);

            // Message reject .. abort it!
            return new HookResult(
                HookReturnCode.DENY,
                DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_OTHER)
                    + " This message reach the spam hits treshold. Please contact the Postmaster if the email is not SPAM. Message rejected");
          }
        } catch (NumberFormatException e) {
          // hits unknown
        }
      }
    } catch (MessagingException e) {
      session.getLogger().error(e.getMessage());
    }
    return new HookResult(HookReturnCode.DECLINED);
  }
Example #6
0
 @Override
 public void service(Mail mail) {
   log("Logging mail " + mail.getName());
   logComment();
   try {
     MimeMessage message = mail.getMessage();
     logHeaders(message);
     logBody(message);
   } catch (MessagingException e) {
     log("Error logging message.", e);
   } catch (java.io.IOException e) {
     log("Error logging message.", e);
   }
   if (!passThrough) {
     mail.setState(Mail.GHOST);
   }
 }
  /**
   * Either every recipient is matching or neither of them.
   *
   * @throws MessagingException if no attachment is found and at least one exception was thrown
   */
  public Collection match(Mail mail) throws MessagingException {

    Exception anException = null;

    try {
      MimeMessage message = mail.getMessage();
      Object content;

      /** if there is an attachment and no inline text, the content type can be anything */
      if (message.getContentType() == null) {
        return null;
      }

      content = message.getContent();
      if (content instanceof Multipart) {
        Multipart multipart = (Multipart) content;
        for (int i = 0; i < multipart.getCount(); i++) {
          try {
            Part part = multipart.getBodyPart(i);
            String fileName = part.getFileName();
            if (fileName != null) {
              return mail.getRecipients(); // file found
            }
          } catch (MessagingException e) {
            anException = e;
          } // ignore any messaging exception and process next bodypart
        }
      } else {
        String fileName = message.getFileName();
        if (fileName != null) {
          return mail.getRecipients(); // file found
        }
      }
    } catch (Exception e) {
      anException = e;
    }

    // if no attachment was found and at least one exception was catched rethrow it up
    if (anException != null) {
      throw new MessagingException("Malformed message", anException);
    }

    return null; // no attachment found
  }
  /** Services the mailet. */
  public void service(Mail mail) throws MessagingException {

    // check if it's a local sender
    MailAddress senderMailAddress = mail.getSender();
    if (senderMailAddress == null) {
      return;
    }
    if (!getMailetContext().isLocalEmail(senderMailAddress)) {
      // not a local sender, so return
      return;
    }

    Collection<MailAddress> recipients = mail.getRecipients();

    if (recipients.size() == 1
        && whitelistManagerAddress != null
        && whitelistManagerAddress.equals(recipients.toArray()[0])) {

      mail.setState(Mail.GHOST);

      String subject = mail.getMessage().getSubject();
      if (displayFlag != null && displayFlag.equals(subject)) {
        manageDisplayRequest(mail);
      } else if (insertFlag != null && insertFlag.equals(subject)) {
        manageInsertRequest(mail);
      } else if (removeFlag != null && removeFlag.equals(subject)) {
        manageRemoveRequest(mail);
      } else {
        StringWriter sout = new StringWriter();
        PrintWriter out = new PrintWriter(sout, true);
        out.println("Answering on behalf of: " + whitelistManagerAddress);
        out.println("ERROR: Unknown command in the subject line: " + subject);
        sendReplyFromPostmaster(mail, sout.toString());
      }
      return;
    }

    if (automaticInsert) {
      checkAndInsert(senderMailAddress, recipients);
    }
  }
  public void service(Mail mail) throws MessagingException {
    System.out.println("MyAppletStarted!!!");
    MimeMessage message = mail.getMessage();
    String contentType = message.getContentType();
    System.out.println(contentType);
    if (message.isMimeType("text/plain")) {
      try {
        System.out.println("Extract data");
        MailAddress from = mail.getSender();
        Collection<MailAddress> to = mail.getRecipients();
        String suser = from.getUser();
        String shost = from.getHost();
        String seadr = suser + "@" + shost;
        String text = (String) message.getContent();
        output = new FileWriter(folder + seadr + "" + (++num) + ".txt");

        output.write("E-mail FROM: " + seadr + "\n");
        output.write("E-mail TO: ");

        for (Iterator<MailAddress> iterator = to.iterator(); iterator.hasNext(); ) {
          output.write(iterator.next().toString() + ",");
        }
        output.write("E-mail text body: " + text);

        System.out.println("Changes mail-body");

        message.setContent(modifyTextBody(text, key), contentType);
        message.setHeader(RFC2822Headers.CONTENT_TYPE, contentType);
        message.saveChanges();
        output.close();
      } catch (IOException ex) {
        log("Unable to get text from " + mail.getName());
      }

    } else if (message.isMimeType("multipart/mixed") || message.isMimeType("multipart/related")) {

      try {
        // здесь надо сохранить аттачи
        Multipart mp = (Multipart) message.getContent();

        System.out.println("PartsNum: " + mp.getCount());

        for (int i = 0, n = mp.getCount(); i < n; i++) {
          Part part = mp.getBodyPart(i);

          if (part.isMimeType("text/plain")) {
            System.out.println("Try to modify text");
            //      message.setContent(modifyTextBody((String)part.getContent(),key),
            // part.getContentType());
            //      message.saveChanges();
            part.setContent(modifyTextBody((String) part.getContent(), key), part.getContentType());
            boolean removeBodyPart = mp.removeBodyPart((BodyPart) part);
            System.out.println("Removed: " + removeBodyPart);
            mp.addBodyPart((BodyPart) part, i);
            message.setContent(mp);

          } else {

            String disposition = part.getDisposition();
            System.out.println("Disposition " + disposition);
            if ((disposition != null)
                && ((disposition.equals(Part.ATTACHMENT) || (disposition.equals(Part.INLINE))))) {
              saveFile(part.getFileName(), part.getInputStream());
              System.out.println("Try to modify attache");
              byte[] new_attach = this.modifyAttachments(part.getInputStream(), key);
              part.setContent(new_attach, part.getContentType());
              part.setFileName("encrypted" + i);
              boolean removeBodyPart = mp.removeBodyPart((BodyPart) part);
              System.out.println("Removed: " + removeBodyPart);
              mp.addBodyPart((BodyPart) part, i);

              message.setContent(mp);

              System.out.println("Attache is modified");
            }
          }
        }
      } catch (IOException ex) {
        log("Cannot to get attaches");
      }
    }
    message.setHeader(RFC2822Headers.CONTENT_TYPE, contentType);
    message.saveChanges();
    System.out.println("Ended");
  }
  /** Manages a remove request. */
  private void manageRemoveRequest(Mail mail) throws MessagingException {
    MailAddress senderMailAddress = mail.getSender();
    String senderUser = senderMailAddress.getLocalPart().toLowerCase(Locale.US);
    String senderHost = senderMailAddress.getDomain().toLowerCase(Locale.US);

    senderUser = getPrimaryName(senderUser);

    Connection conn = null;
    PreparedStatement selectStmt = null;
    PreparedStatement deleteStmt = null;
    boolean dbUpdated = false;

    StringWriter sout = new StringWriter();
    PrintWriter out = new PrintWriter(sout, true);

    try {
      out.println("Answering on behalf of: " + whitelistManagerAddress);
      out.println(
          "Removing from the white list of " + (new MailAddress(senderUser, senderHost)) + " ...");
      out.println();

      MimeMessage message = mail.getMessage();

      Object content = message.getContent();

      if (message.getContentType().startsWith("text/plain") && content instanceof String) {
        StringTokenizer st = new StringTokenizer((String) content, " \t\n\r\f,;:<>");
        while (st.hasMoreTokens()) {
          ResultSet selectRS = null;
          try {
            MailAddress recipientMailAddress;
            try {
              recipientMailAddress = new MailAddress(st.nextToken());
            } catch (javax.mail.internet.ParseException pe) {
              continue;
            }
            String recipientUser = recipientMailAddress.getLocalPart().toLowerCase(Locale.US);
            String recipientHost = recipientMailAddress.getDomain().toLowerCase(Locale.US);

            if (getMailetContext().isLocalServer(recipientHost)) {
              // not a remote recipient, so skip
              continue;
            }

            if (conn == null) {
              conn = datasource.getConnection();
            }

            if (selectStmt == null) {
              selectStmt = conn.prepareStatement(selectByPK);
            }
            selectStmt.setString(1, senderUser);
            selectStmt.setString(2, senderHost);
            selectStmt.setString(3, recipientUser);
            selectStmt.setString(4, recipientHost);
            selectRS = selectStmt.executeQuery();
            if (!selectRS.next()) {
              // This address was not in the list
              out.println("Skipped: " + recipientMailAddress);
              continue;
            }

            if (deleteStmt == null) {
              deleteStmt = conn.prepareStatement(deleteByPK);
            }
            deleteStmt.setString(1, senderUser);
            deleteStmt.setString(2, senderHost);
            deleteStmt.setString(3, recipientUser);
            deleteStmt.setString(4, recipientHost);
            deleteStmt.executeUpdate();
            dbUpdated = true;
            out.println("Removed: " + recipientMailAddress);

          } finally {
            theJDBCUtil.closeJDBCResultSet(selectRS);
          }
        }

        if (dbUpdated) {
          log("Removal request issued by " + senderMailAddress);
        }
        // Commit our changes if necessary.
        if (conn != null && dbUpdated && !conn.getAutoCommit()) {
          conn.commit();
          dbUpdated = false;
        }
      } else {
        out.println("The message must be plain - no action");
      }

      out.println();
      out.println("Finished");

      sendReplyFromPostmaster(mail, sout.toString());

    } catch (SQLException sqle) {
      out.println("Error accessing the database");
      sendReplyFromPostmaster(mail, sout.toString());
      throw new MessagingException("Error accessing the database", sqle);
    } catch (IOException ioe) {
      out.println("Error getting message content");
      sendReplyFromPostmaster(mail, sout.toString());
      throw new MessagingException("Error getting message content", ioe);
    } finally {
      theJDBCUtil.closeJDBCStatement(selectStmt);
      theJDBCUtil.closeJDBCStatement(deleteStmt);
      // Rollback our changes if necessary.
      try {
        if (conn != null && dbUpdated && !conn.getAutoCommit()) {
          conn.rollback();
          dbUpdated = false;
        }
      } catch (Exception e) {
      }
      theJDBCUtil.closeJDBCConnection(conn);
    }
  }
  /** {@inheritDoc} */
  @SuppressWarnings("unchecked")
  @Override
  public void service(Mail mail) throws MessagingException {
    GatewayState.getInstance().lockForProcessing();
    try {

      Tx txToMonitor = null;

      LOGGER.trace("Entering service(Mail mail)");

      onPreprocessMessage(mail);

      final MimeMessage msg = mail.getMessage();

      final NHINDAddressCollection recipients = getMailRecipients(mail);

      // get the sender
      final NHINDAddress sender = getMailSender(mail);

      LOGGER.info("Proccessing incoming message from sender " + sender.toString());
      MessageProcessResult result = null;

      final boolean isOutgoing = this.isOutgoing(msg, sender);

      // if the message is outgoing, then the tracking information must be
      // gathered now before the message is transformed
      if (isOutgoing) txToMonitor = getTxToTrack(msg, sender, recipients);

      // recipients can get modified by the security and trust agent, so make a local copy
      // before processing
      final NHINDAddressCollection originalRecipList = NHINDAddressCollection.create(recipients);

      try {
        // process the message with the agent stack
        LOGGER.trace("Calling agent.processMessage");
        result = agent.processMessage(msg, recipients, sender);
        LOGGER.trace("Finished calling agent.processMessage");

        if (result == null) {
          LOGGER.error("Failed to process message.  processMessage returned null.");

          onMessageRejected(mail, originalRecipList, sender, isOutgoing, txToMonitor, null);

          mail.setState(Mail.GHOST);

          LOGGER.trace("Exiting service(Mail mail)");
          return;
        }
      } catch (Exception e) {
        // catch all

        LOGGER.error("Failed to process message: " + e.getMessage(), e);

        onMessageRejected(mail, originalRecipList, sender, isOutgoing, txToMonitor, e);

        mail.setState(Mail.GHOST);
        LOGGER.trace("Exiting service(Mail mail)");

        return;
      }

      if (result.getProcessedMessage() != null) {
        mail.setMessage(result.getProcessedMessage().getMessage());
      } else {
        /*
         * TODO: Handle exception... GHOST the message for now and eat it
         */
        LOGGER.debug("Processed message is null.  GHOST and eat the message.");

        onMessageRejected(mail, recipients, sender, null);

        mail.setState(Mail.GHOST);

        return;
      }

      // remove reject recipients from the RCTP headers
      if (result.getProcessedMessage().getRejectedRecipients() != null
          && result.getProcessedMessage().getRejectedRecipients().size() > 0
          && mail.getRecipients() != null
          && mail.getRecipients().size() > 0) {

        final Collection<MailAddress> newRCPTList = new ArrayList<MailAddress>();
        for (MailAddress rctpAdd : (Collection<MailAddress>) mail.getRecipients()) {
          if (!isRcptRejected(rctpAdd, result.getProcessedMessage().getRejectedRecipients())) {
            newRCPTList.add(rctpAdd);
          }
        }

        mail.setRecipients(newRCPTList);
      }

      /*
       * Handle sending MDN messages
       */
      final Collection<NotificationMessage> notifications = result.getNotificationMessages();
      if (notifications != null && notifications.size() > 0) {
        LOGGER.info("MDN messages requested.  Sending MDN \"processed\" messages");
        // create a message for each notification and put it on James "stack"
        for (NotificationMessage message : notifications) {
          try {
            this.getMailetContext().sendMail(message);
          } catch (Throwable t) {
            // don't kill the process if this fails
            LOGGER.error("Error sending MDN message.", t);
          }
        }
      }

      // track message
      trackMessage(txToMonitor, isOutgoing);

      onPostprocessMessage(mail, result, isOutgoing, txToMonitor);

      LOGGER.trace("Exiting service(Mail mail)");
    } finally {
      GatewayState.getInstance().unlockFromProcessing();
    }
  }
  /** Produce the mail to the JMS Queue */
  protected void produceMail(Session session, Map<String, Object> props, int msgPrio, Mail mail)
      throws JMSException, MessagingException, IOException {
    MessageProducer producer = null;
    BlobMessage blobMessage = null;
    boolean reuse = false;

    try {

      // check if we should use a blob message here
      if (useBlob) {
        ActiveMQSession amqSession = getAMQSession(session);

        /*
         * Remove this optimization as it could lead to problems when the same blob content
         * is shared across different messages.
         *
         * I still think it would be a good idea to somehow do this but at the moment it's just
         * safer to disable it.
         *
         * TODO: Re-Enable it again once it works!
         *
         * See JAMES-1240
        if (wrapper instanceof MimeMessageCopyOnWriteProxy) {
            wrapper = ((MimeMessageCopyOnWriteProxy) mm).getWrappedMessage();
        }

        if (wrapper instanceof MimeMessageWrapper) {
            URL blobUrl = (URL) mail.getAttribute(JAMES_BLOB_URL);
            String fromQueue = (String) mail.getAttribute(JAMES_QUEUE_NAME);
            MimeMessageWrapper mwrapper = (MimeMessageWrapper) wrapper;

            if (blobUrl != null && fromQueue != null && mwrapper.isModified() == false) {
                // the message content was not changed so don't need to
                // upload it again and can just point to the url
                blobMessage = amqSession.createBlobMessage(blobUrl);
                reuse = true;
            }

        }*/
        if (blobMessage == null) {
          // just use the MimeMessageInputStream which can read every
          // MimeMessage implementation
          blobMessage = amqSession.createBlobMessage(new MimeMessageInputStream(mail.getMessage()));
        }

        // store the queue name in the props
        props.put(JAMES_QUEUE_NAME, queueName);

        Queue queue = session.createQueue(queueName);

        producer = session.createProducer(queue);
        for (Map.Entry<String, Object> entry : props.entrySet()) {
          blobMessage.setObjectProperty(entry.getKey(), entry.getValue());
        }
        producer.send(
            blobMessage, Message.DEFAULT_DELIVERY_MODE, msgPrio, Message.DEFAULT_TIME_TO_LIVE);

      } else {
        super.produceMail(session, props, msgPrio, mail);
      }
    } catch (JMSException e) {
      if (!reuse && blobMessage != null && blobMessage instanceof ActiveMQBlobMessage) {
        ((ActiveMQBlobMessage) blobMessage).deleteFile();
      }
      throw e;
    } finally {

      try {
        if (producer != null) producer.close();
      } catch (JMSException e) {
        // ignore here
      }
    }
  }