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