1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.james.fetchmail;
23
24 import java.net.UnknownHostException;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Enumeration;
28 import java.util.Iterator;
29 import java.util.StringTokenizer;
30
31 import javax.mail.Address;
32 import javax.mail.Flags;
33 import javax.mail.MessagingException;
34 import javax.mail.internet.InternetAddress;
35 import javax.mail.internet.MimeMessage;
36 import javax.mail.internet.ParseException;
37
38 import org.apache.james.core.MailImpl;
39 import org.apache.mailet.base.RFC2822Headers;
40 import org.apache.mailet.Mail;
41 import org.apache.mailet.MailAddress;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173 public class MessageProcessor extends ProcessorAbstract
174 {
175 private MimeMessage fieldMessageIn;
176
177
178
179
180 private boolean fieldRecipientNotFound = false;
181
182
183
184
185 private boolean fieldRemoteRecipient = true;
186
187
188
189
190 private Boolean fieldRemoteReceivedHeaderInvalid;
191
192
193
194
195 private boolean fieldUserUndefined = false;
196
197
198
199
200 private Boolean fieldMaxMessageSizeExceeded;
201
202
203
204
205
206 static final private String fieldRFC2822RECEIVEDHeaderFields =
207 "from by via with id for ;";
208
209
210
211
212 private boolean fieldBlacklistedRecipient = false;
213
214
215
216
217 private String fieldRemoteDomain;
218
219
220
221
222 private String fieldRemoteAddress;
223
224
225
226
227 private String fieldRemoteHostName;
228
229
230
231
232 private boolean fieldDefaultSenderLocalPart = false;
233
234
235
236
237 private boolean fieldDefaultSenderDomainPart = false;
238
239
240
241
242 private boolean fieldDefaultRemoteAddress = false;
243
244
245
246
247
248
249 private MessageProcessor(Account account)
250 {
251 super(account);
252 }
253
254
255
256
257
258
259
260
261 MessageProcessor(
262 MimeMessage messageIn,
263 Account account)
264 {
265 this(account);
266 setMessageIn(messageIn);
267 }
268
269
270
271
272
273
274
275 public void process() throws MessagingException
276 {
277
278 if (getLogger().isDebugEnabled())
279 {
280 StringBuffer logMessageBuffer =
281 new StringBuffer("Attempting delivery of message with id. ");
282 logMessageBuffer.append(getMessageIn().getMessageID());
283 getLogger().debug(logMessageBuffer.toString());
284 }
285
286
287 MailAddress intendedRecipient = getIntendedRecipient();
288 setRecipientNotFound(null == intendedRecipient);
289
290 if (isRecipientNotFound())
291 {
292 if (isDeferRecipientNotFound())
293 {
294
295 String messageID = getMessageIn().getMessageID();
296 if (!getDeferredRecipientNotFoundMessageIDs()
297 .contains(messageID))
298 {
299 getDeferredRecipientNotFoundMessageIDs().add(messageID);
300 if (getLogger().isDebugEnabled())
301 {
302 StringBuffer messageBuffer =
303 new StringBuffer("Deferred processing of message for which the intended recipient could not be found. Message ID: ");
304 messageBuffer.append(messageID);
305 getLogger().debug(messageBuffer.toString());
306 }
307 return;
308 }
309 else
310 {
311 getDeferredRecipientNotFoundMessageIDs().remove(messageID);
312 if (getLogger().isDebugEnabled())
313 {
314 StringBuffer messageBuffer =
315 new StringBuffer("Processing deferred message for which the intended recipient could not be found. Message ID: ");
316 messageBuffer.append(messageID);
317 getLogger().debug(messageBuffer.toString());
318 }
319 }
320 }
321
322 if (isRejectRecipientNotFound())
323 {
324 rejectRecipientNotFound();
325 return;
326 }
327 intendedRecipient = getRecipient();
328 StringBuffer messageBuffer =
329 new StringBuffer("Intended recipient not found. Using configured recipient as new envelope recipient - ");
330 messageBuffer.append(intendedRecipient);
331 messageBuffer.append('.');
332 logStatusInfo(messageBuffer.toString());
333 }
334
335
336 setBlacklistedRecipient(isBlacklistedRecipient(intendedRecipient));
337 setRemoteRecipient(!isLocalServer(intendedRecipient));
338 setUserUndefined(!isLocalRecipient(intendedRecipient));
339
340
341 if (isRejectBlacklisted() && isBlacklistedRecipient())
342 {
343 rejectBlacklistedRecipient(intendedRecipient);
344 return;
345 }
346
347 if (isRejectRemoteRecipient() && isRemoteRecipient())
348 {
349 rejectRemoteRecipient(intendedRecipient);
350 return;
351 }
352
353 if (isRejectUserUndefined() && isUserUndefined())
354 {
355 rejectUserUndefined(intendedRecipient);
356 return;
357 }
358
359 if (isRejectMaxMessageSizeExceeded()
360 && isMaxMessageSizeExceeded().booleanValue())
361 {
362 rejectMaxMessageSizeExceeded(getMessageIn().getSize());
363 return;
364 }
365
366 if (isRejectRemoteReceivedHeaderInvalid()
367 && isRemoteReceivedHeaderInvalid().booleanValue())
368 {
369 rejectRemoteReceivedHeaderInvalid();
370 return;
371 }
372
373
374
375
376
377
378
379
380
381 Mail mail = null;
382 try
383 {
384 mail = createMail(createMessage(), intendedRecipient);
385 }
386 catch (ParseException ex)
387 {
388 handleParseException(ex);
389 return;
390 }
391 catch (UnknownHostException ex)
392 {
393 handleUnknownHostException(ex);
394 return;
395 }
396
397 addMailAttributes(mail);
398 addErrorMessages(mail);
399
400
401 if (isBouncing())
402 {
403 handleBouncing(mail);
404 return;
405 }
406
407
408 sendMail(mail);
409 }
410
411
412
413
414
415
416 protected void rejectRemoteRecipient(MailAddress recipient)
417 throws MessagingException
418 {
419
420 if (!isLeaveRemoteRecipient())
421 setMessageDeleted();
422
423 if (isMarkRemoteRecipientSeen())
424 setMessageSeen();
425
426 StringBuffer messageBuffer =
427 new StringBuffer("Rejected mail intended for remote recipient: ");
428 messageBuffer.append(recipient);
429 messageBuffer.append('.');
430 logStatusInfo(messageBuffer.toString());
431
432 return;
433 }
434
435
436
437
438
439
440 protected void rejectBlacklistedRecipient(MailAddress recipient)
441 throws MessagingException
442 {
443
444 if (!isLeaveBlacklisted())
445 setMessageDeleted();
446 if (isMarkBlacklistedSeen())
447 setMessageSeen();
448
449 StringBuffer messageBuffer =
450 new StringBuffer("Rejected mail intended for blacklisted recipient: ");
451 messageBuffer.append(recipient);
452 messageBuffer.append('.');
453 logStatusInfo(messageBuffer.toString());
454
455 return;
456 }
457
458
459
460
461
462 protected void rejectRecipientNotFound() throws MessagingException
463 {
464
465 if (!isLeaveRecipientNotFound())
466 setMessageDeleted();
467
468 if (isMarkRecipientNotFoundSeen())
469 setMessageSeen();
470
471 StringBuffer messageBuffer =
472 new StringBuffer("Rejected mail for which a sole intended recipient could not be found.");
473 messageBuffer.append(" Recipients: ");
474 Address[] allRecipients = getMessageIn().getAllRecipients();
475 for (int i = 0; i < allRecipients.length; i++)
476 {
477 messageBuffer.append(allRecipients[i]);
478 messageBuffer.append(' ');
479 }
480 messageBuffer.append('.');
481 logStatusInfo(messageBuffer.toString());
482 return;
483 }
484
485
486
487
488
489
490 protected void rejectUserUndefined(MailAddress recipient)
491 throws MessagingException
492 {
493
494 if (!isLeaveUserUndefined())
495 setMessageDeleted();
496
497 if (isMarkUserUndefinedSeen())
498 setMessageSeen();
499
500 StringBuffer messageBuffer =
501 new StringBuffer("Rejected mail intended for undefined user: ");
502 messageBuffer.append(recipient);
503 messageBuffer.append('.');
504 logStatusInfo(messageBuffer.toString());
505
506 return;
507 }
508
509
510
511
512
513
514 protected void rejectMaxMessageSizeExceeded(int messageSize)
515 throws MessagingException
516 {
517
518 if (!isLeaveMaxMessageSizeExceeded())
519 setMessageDeleted();
520
521 if (isMarkMaxMessageSizeExceededSeen())
522 setMessageSeen();
523
524 StringBuffer messageBuffer =
525 new StringBuffer("Rejected mail exceeding message size limit. Message size: ");
526 messageBuffer.append(messageSize/1024);
527 messageBuffer.append("KB.");
528 logStatusInfo(messageBuffer.toString());
529
530 return;
531 }
532
533
534
535
536
537 protected void rejectRemoteReceivedHeaderInvalid()
538 throws MessagingException
539 {
540
541 if (!isLeaveRemoteReceivedHeaderInvalid())
542 setMessageDeleted();
543
544 if (isMarkRemoteReceivedHeaderInvalidSeen())
545 setMessageSeen();
546
547 StringBuffer messageBuffer =
548 new StringBuffer("Rejected mail with an invalid Received: header at index ");
549 messageBuffer.append(getRemoteReceivedHeaderIndex());
550 messageBuffer.append(".");
551 logStatusInfo(messageBuffer.toString());
552 return;
553 }
554
555
556
557
558
559
560
561
562
563
564
565 protected MimeMessage createMessage() throws MessagingException
566 {
567
568 MimeMessage messageOut = null;
569 if (isMaxMessageSizeExceeded().booleanValue())
570 messageOut = createEmptyMessage();
571 else
572 messageOut = new MimeMessage(getMessageIn());
573
574
575
576
577 messageOut.addHeader("X-fetched-from", getFetchTaskName());
578
579 return messageOut;
580 }
581
582
583
584
585
586
587
588
589
590 protected MimeMessage createEmptyMessage()
591 throws MessagingException
592 {
593
594 MimeMessage messageOut = new MimeMessage(getSession());
595
596
597 Enumeration headersInEnum = getMessageIn().getAllHeaderLines();
598 while (headersInEnum.hasMoreElements())
599 messageOut.addHeaderLine((String) headersInEnum.nextElement());
600 messageOut.setSubject(getMessageIn().getSubject());
601
602
603 messageOut.setText("");
604
605
606 messageOut.saveChanges();
607
608 return messageOut;
609 }
610
611
612
613
614
615
616
617
618
619 protected Mail createMail(MimeMessage message, MailAddress recipient)
620 throws MessagingException, UnknownHostException
621 {
622 Collection recipients = new ArrayList(1);
623 recipients.add(recipient);
624 MailImpl mail =
625 new MailImpl(getServer().getId(), getSender(), recipients, message);
626
627
628 if (getRemoteAddress() == null || getRemoteHostName() == null)
629 {
630 mail.setRemoteAddr("127.0.0.1");
631 mail.setRemoteHost("localhost");
632 setDefaultRemoteAddress(true);
633 logStatusInfo("Remote address could not be determined. Using localhost/127.0.0.1");
634 }
635 else
636 {
637 mail.setRemoteAddr(getRemoteAddress());
638 mail.setRemoteHost(getRemoteHostName());
639 setDefaultRemoteAddress(false);
640 }
641
642 if (getLogger().isDebugEnabled())
643 {
644 StringBuffer messageBuffer =
645 new StringBuffer("Created mail with name: ");
646 messageBuffer.append(mail.getName());
647 messageBuffer.append(", sender: ");
648 messageBuffer.append(mail.getSender());
649 messageBuffer.append(", recipients: ");
650 Iterator recipientIterator = mail.getRecipients().iterator();
651 while (recipientIterator.hasNext())
652 {
653 messageBuffer.append(recipientIterator.next());
654 messageBuffer.append(' ');
655 }
656 messageBuffer.append(", remote address: ");
657 messageBuffer.append(mail.getRemoteAddr());
658 messageBuffer.append(", remote host name: ");
659 messageBuffer.append(mail.getRemoteHost());
660 messageBuffer.append('.');
661 getLogger().debug(messageBuffer.toString());
662 }
663 return mail;
664 }
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679 protected MailAddress getSender() throws MessagingException
680 {
681 String from = null;
682 InternetAddress internetAddress = null;
683
684 try {
685 from = ((InternetAddress) getMessageIn().getFrom()[0]).getAddress().trim();
686 setDefaultSenderLocalPart(false);
687 }
688 catch (Exception _) {
689 from = getDefaultLocalPart();
690 setDefaultSenderLocalPart(true);
691 StringBuffer buffer = new StringBuffer(32);
692 buffer.append("Sender localpart is absent. Using default value (");
693 buffer.append(getDefaultLocalPart());
694 buffer.append(')');
695 logStatusInfo(buffer.toString());
696 }
697
698
699 if (from.indexOf('@') < 0)
700 {
701 StringBuffer fromBuffer = new StringBuffer(from);
702 fromBuffer.append('@');
703 fromBuffer.append(getDefaultDomainName());
704 internetAddress = new InternetAddress(fromBuffer.toString());
705 setDefaultSenderDomainPart(true);
706
707 StringBuffer buffer = new StringBuffer(32);
708 buffer.append("Sender domain is absent. Using default value (");
709 buffer.append(getDefaultDomainName());
710 buffer.append(')');
711 logStatusInfo(buffer.toString());
712 }
713 else
714 {
715 internetAddress = new InternetAddress(from);
716 setDefaultSenderDomainPart(false);
717 }
718
719 return new MailAddress(internetAddress);
720 }
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748 protected String computeRemoteDomain() throws MessagingException
749 {
750 StringBuffer domainBuffer = new StringBuffer();
751 String[] headers = null;
752
753 if (getRemoteReceivedHeaderIndex() > -1)
754 headers = getMessageIn().getHeader(RFC2822Headers.RECEIVED);
755
756
757
758 boolean hasHeaders = (null == headers ? false : headers.length > 0);
759
760
761 if (hasHeaders)
762 {
763 final String headerTokens = " \n\r";
764
765
766 for (int headerIndex =
767 headers.length > getRemoteReceivedHeaderIndex()
768 ? getRemoteReceivedHeaderIndex()
769 : headers.length - 1;
770 headerIndex >= 0 && domainBuffer.length() == 0;
771 headerIndex--)
772 {
773
774 StringTokenizer tokenizer =
775 new StringTokenizer(headers[headerIndex], headerTokens);
776 boolean inFrom = false;
777 while (!inFrom && tokenizer.hasMoreTokens())
778 inFrom = tokenizer.nextToken().equals("from");
779
780
781 while (inFrom && tokenizer.hasMoreTokens())
782 {
783 String token = tokenizer.nextToken();
784 inFrom = (getRFC2822RECEIVEDHeaderFields().indexOf(token) == -1);
785 if (inFrom)
786 {
787 domainBuffer.append(token);
788 domainBuffer.append(' ');
789 }
790 }
791 }
792 }
793
794
795
796
797
798 if (domainBuffer.length() == 0)
799 {
800 try
801 {
802 domainBuffer.append(getDNSServer().getLocalHost().getCanonicalHostName());
803 }
804 catch (UnknownHostException ue)
805 {
806 domainBuffer.append("[127.0.0.1]");
807 }
808 }
809 return domainBuffer.toString().trim();
810 }
811
812
813
814
815
816
817
818 protected void handleBouncing(Mail mail) throws MessagingException
819 {
820 mail.setState(Mail.ERROR);
821 setMessageDeleted();
822
823 mail.setErrorMessage(
824 "This mail from FetchMail task "
825 + getFetchTaskName()
826 + " seems to be bouncing!");
827 logStatusError("Message is bouncing! Deleted from message store and moved to the Error repository.");
828 }
829
830
831
832
833
834
835 protected void handleParseException(ParseException ex)
836 throws MessagingException
837 {
838
839 if (!isLeaveUndeliverable())
840 setMessageDeleted();
841 if (isMarkUndeliverableSeen())
842 setMessageSeen();
843 logStatusWarn("Message could not be delivered due to an error parsing a mail address.");
844 if (getLogger().isDebugEnabled())
845 {
846 StringBuffer messageBuffer =
847 new StringBuffer("UNDELIVERABLE Message ID: ");
848 messageBuffer.append(getMessageIn().getMessageID());
849 getLogger().debug(messageBuffer.toString(), ex);
850 }
851 }
852
853
854
855
856
857
858 protected void handleUnknownHostException(UnknownHostException ex)
859 throws MessagingException
860 {
861
862 if (!isLeaveUndeliverable())
863 setMessageDeleted();
864
865 if (isMarkUndeliverableSeen())
866 setMessageSeen();
867
868 logStatusWarn("Message could not be delivered due to an error determining the remote domain.");
869 if (getLogger().isDebugEnabled())
870 {
871 StringBuffer messageBuffer =
872 new StringBuffer("UNDELIVERABLE Message ID: ");
873 messageBuffer.append(getMessageIn().getMessageID());
874 getLogger().debug(messageBuffer.toString(), ex);
875 }
876 }
877
878
879
880
881
882
883 protected boolean isLocalRecipient(MailAddress recipient)
884 {
885 return isLocalServer(recipient) && getLocalUsers().contains(recipient.getUser());
886 }
887
888
889
890
891
892
893 protected boolean isLocalServer(MailAddress recipient)
894 {
895 return getServer().isLocalServer(recipient.getHost());
896 }
897
898
899
900
901
902
903 protected boolean isBlacklistedRecipient(MailAddress recipient)
904 {
905 return getBlacklist().contains(recipient);
906 }
907
908
909
910
911
912
913
914 protected boolean isBouncing() throws MessagingException
915 {
916 Enumeration enumeration =
917 getMessageIn().getMatchingHeaderLines(
918 new String[] { "X-fetched-from" });
919 int count = 0;
920 while (enumeration.hasMoreElements())
921 {
922 String header = (String) enumeration.nextElement();
923 if (header.equals(getFetchTaskName()))
924 count++;
925 }
926 return count >= 3;
927 }
928
929
930
931
932
933
934 protected void sendMail(Mail mail) throws MessagingException
935 {
936
937 getServer().sendMail(mail);
938
939
940 if (!isLeave())
941 setMessageDeleted();
942
943 if (isMarkSeen())
944 setMessageSeen();
945
946
947 StringBuffer messageBuffer =
948 new StringBuffer("Spooled message to recipients: ");
949 Iterator recipientIterator = mail.getRecipients().iterator();
950 while (recipientIterator.hasNext())
951 {
952 messageBuffer.append(recipientIterator.next());
953 messageBuffer.append(' ');
954 }
955 messageBuffer.append('.');
956 logStatusInfo(messageBuffer.toString());
957 }
958
959
960
961
962
963
964
965
966
967
968
969
970
971 protected String getEnvelopeRecipient(MimeMessage msg) throws MessagingException
972 {
973 String res = getCustomRecipientHeader();
974 if (res != null && res.length() > 0) {
975 String[] headers = msg.getHeader(getCustomRecipientHeader());
976 if (headers != null) {
977 String mailFor = headers[0];
978 if (mailFor.startsWith("<") && mailFor.endsWith(">"))
979 mailFor = mailFor.substring(1, (mailFor.length() - 1));
980 return mailFor;
981 }
982 } else {
983 try
984 {
985 Enumeration enumeration =
986 msg.getMatchingHeaderLines(new String[] { "Received" });
987 while (enumeration.hasMoreElements())
988 {
989 String received = (String) enumeration.nextElement();
990
991 int nextSearchAt = 0;
992 int i = 0;
993 int start = 0;
994 int end = 0;
995 boolean hasBracket = false;
996 boolean usableAddress = false;
997 while (!usableAddress && (i != -1))
998 {
999 hasBracket = false;
1000 i = received.indexOf("for ", nextSearchAt);
1001 if (i > 0)
1002 {
1003 start = i + 4;
1004 end = 0;
1005 nextSearchAt = start;
1006 for (int c = start; c < received.length(); c++)
1007 {
1008 char ch = received.charAt(c);
1009 switch (ch)
1010 {
1011 case '<' :
1012 hasBracket = true;
1013 continue;
1014 case '@' :
1015 usableAddress = true;
1016 continue;
1017 case ' ' :
1018 end = c;
1019 break;
1020 case ';' :
1021 end = c;
1022 break;
1023 }
1024 if (end > 0)
1025 break;
1026 }
1027 }
1028 }
1029 if (usableAddress)
1030 {
1031
1032 String mailFor = received.substring(start, end);
1033
1034
1035 if (mailFor.startsWith("<") && mailFor.endsWith(">"))
1036 mailFor = mailFor.substring(1, (mailFor.length() - 1));
1037
1038 return mailFor;
1039 }
1040 }
1041 }
1042 catch (MessagingException me)
1043 {
1044 logStatusWarn("No Received headers found.");
1045 }
1046 }
1047 return null;
1048 }
1049
1050
1051
1052
1053
1054
1055
1056 protected MailAddress getIntendedRecipient() throws MessagingException
1057 {
1058
1059
1060 if (isIgnoreRecipientHeader())
1061 {
1062 StringBuffer messageBuffer =
1063 new StringBuffer("Ignoring recipient header. Using configured recipient as new envelope recipient: ");
1064 messageBuffer.append(getRecipient());
1065 messageBuffer.append('.');
1066 logStatusInfo(messageBuffer.toString());
1067 return getRecipient();
1068 }
1069
1070
1071
1072 String targetRecipient = getEnvelopeRecipient(getMessageIn());
1073 if (targetRecipient != null)
1074 {
1075 MailAddress recipient = new MailAddress(targetRecipient);
1076 StringBuffer messageBuffer =
1077 new StringBuffer("Using original envelope recipient as new envelope recipient: ");
1078 messageBuffer.append(recipient);
1079 messageBuffer.append('.');
1080 logStatusInfo(messageBuffer.toString());
1081 return recipient;
1082 }
1083
1084
1085
1086
1087
1088 Address[] allRecipients = getMessageIn().getAllRecipients();
1089 if (allRecipients.length == 1)
1090 {
1091 MailAddress recipient =
1092 new MailAddress((InternetAddress) allRecipients[0]);
1093 StringBuffer messageBuffer =
1094 new StringBuffer("Using sole recipient header address as new envelope recipient: ");
1095 messageBuffer.append(recipient);
1096 messageBuffer.append('.');
1097 logStatusInfo(messageBuffer.toString());
1098 return recipient;
1099 }
1100
1101 return null;
1102 }
1103
1104
1105
1106
1107
1108 protected MimeMessage getMessageIn()
1109 {
1110 return fieldMessageIn;
1111 }
1112
1113
1114
1115
1116
1117 protected void setMessageIn(MimeMessage messageIn)
1118 {
1119 fieldMessageIn = messageIn;
1120 }
1121
1122
1123
1124
1125
1126 protected boolean isRemoteRecipient()
1127 {
1128 return fieldRemoteRecipient;
1129 }
1130
1131
1132
1133
1134
1135
1136 protected boolean isPreviouslyUnprocessed()
1137 {
1138 return true;
1139 }
1140
1141
1142
1143
1144
1145 protected void logStatusInfo(String detailMsg) throws MessagingException
1146 {
1147 getLogger().info(getStatusReport(detailMsg).toString());
1148 }
1149
1150
1151
1152
1153
1154 protected void logStatusWarn(String detailMsg) throws MessagingException
1155 {
1156 getLogger().warn(getStatusReport(detailMsg).toString());
1157 }
1158
1159
1160
1161
1162
1163 protected void logStatusError(String detailMsg) throws MessagingException
1164 {
1165 getLogger().error(getStatusReport(detailMsg).toString());
1166 }
1167
1168
1169
1170
1171
1172
1173
1174
1175 protected StringBuffer getStatusReport(String detailMsg) throws MessagingException
1176 {
1177 StringBuffer messageBuffer = new StringBuffer(detailMsg);
1178 if (detailMsg.length() > 0)
1179 messageBuffer.append(' ');
1180 messageBuffer.append("Message ID: ");
1181 messageBuffer.append(getMessageIn().getMessageID());
1182 messageBuffer.append(". Flags: Seen = ");
1183 messageBuffer.append(new Boolean(isMessageSeen()));
1184 messageBuffer.append(", Delete = ");
1185 messageBuffer.append(new Boolean(isMessageDeleted()));
1186 messageBuffer.append('.');
1187 return messageBuffer;
1188 }
1189
1190
1191
1192
1193
1194 protected boolean isUserUndefined()
1195 {
1196 return fieldUserUndefined;
1197 }
1198
1199
1200
1201
1202
1203 protected boolean isMessageDeleted() throws MessagingException
1204 {
1205 return getMessageIn().isSet(Flags.Flag.DELETED);
1206 }
1207
1208
1209
1210
1211
1212 protected boolean isMessageSeen() throws MessagingException
1213 {
1214 return getMessageIn().isSet(Flags.Flag.SEEN);
1215 }
1216
1217
1218
1219
1220
1221 protected void setMessageDeleted() throws MessagingException
1222 {
1223 getMessageIn().setFlag(Flags.Flag.DELETED, true);
1224 }
1225
1226
1227
1228
1229
1230 protected void setMessageSeen() throws MessagingException
1231 {
1232
1233
1234 if (!getMessageIn()
1235 .getFolder()
1236 .getPermanentFlags()
1237 .contains(Flags.Flag.SEEN))
1238 handleMarkSeenNotPermanent();
1239 else
1240 getMessageIn().setFlag(Flags.Flag.SEEN, true);
1241 }
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253 protected void handleMarkSeenNotPermanent() throws MessagingException
1254 {
1255 getMessageIn().setFlag(Flags.Flag.SEEN, true);
1256 logStatusWarn("Message marked as SEEN, but the folder does not support a permanent SEEN flag.");
1257 }
1258
1259
1260
1261
1262
1263 protected boolean isBlacklistedRecipient()
1264 {
1265 return fieldBlacklistedRecipient;
1266 }
1267
1268
1269
1270
1271
1272 protected void setRemoteRecipient(boolean localRecipient)
1273 {
1274 fieldRemoteRecipient = localRecipient;
1275 }
1276
1277
1278
1279
1280
1281 protected void setUserUndefined(boolean userUndefined)
1282 {
1283 fieldUserUndefined = userUndefined;
1284 }
1285
1286
1287
1288
1289
1290 protected void addMailAttributes(Mail aMail) throws MessagingException
1291 {
1292 aMail.setAttribute(
1293 getAttributePrefix() + "taskName",
1294 getFetchTaskName());
1295
1296 aMail.setAttribute(
1297 getAttributePrefix() + "folderName",
1298 getMessageIn().getFolder().getFullName());
1299
1300 if (isRemoteRecipient())
1301 aMail.setAttribute(
1302 getAttributePrefix() + "isRemoteRecipient",
1303 null);
1304
1305 if (isUserUndefined())
1306 aMail.setAttribute(getAttributePrefix() + "isUserUndefined", null);
1307
1308 if (isBlacklistedRecipient())
1309 aMail.setAttribute(
1310 getAttributePrefix() + "isBlacklistedRecipient",
1311 null);
1312
1313 if (isRecipientNotFound())
1314 aMail.setAttribute(
1315 getAttributePrefix() + "isRecipientNotFound",
1316 null);
1317
1318 if (isMaxMessageSizeExceeded().booleanValue())
1319 aMail.setAttribute(
1320 getAttributePrefix() + "isMaxMessageSizeExceeded",
1321 new Integer(getMessageIn().getSize()).toString());
1322
1323 if (isRemoteReceivedHeaderInvalid().booleanValue())
1324 aMail.setAttribute(
1325 getAttributePrefix() + "isRemoteReceivedHeaderInvalid",
1326 null);
1327
1328 if (isDefaultSenderLocalPart())
1329 aMail.setAttribute(
1330 getAttributePrefix() + "isDefaultSenderLocalPart",
1331 null);
1332
1333 if (isDefaultSenderDomainPart())
1334 aMail.setAttribute(
1335 getAttributePrefix() + "isDefaultSenderDomainPart",
1336 null);
1337
1338 if (isDefaultRemoteAddress())
1339 aMail.setAttribute(
1340 getAttributePrefix() + "isDefaultRemoteAddress",
1341 null);
1342 }
1343
1344
1345
1346
1347
1348 protected void addErrorMessages(Mail mail) throws MessagingException
1349 {
1350 if (isMaxMessageSizeExceeded().booleanValue())
1351 {
1352 StringBuffer msgBuffer =
1353 new StringBuffer("550 - Rejected - This message has been rejected as the message size of ");
1354 msgBuffer.append(getMessageIn().getSize() * 1000 / 1024 / 1000f);
1355 msgBuffer.append("KB exceeds the maximum permitted size of ");
1356 msgBuffer.append(getMaxMessageSizeLimit() / 1024);
1357 msgBuffer.append("KB.");
1358 mail.setErrorMessage(msgBuffer.toString());
1359 }
1360 }
1361
1362
1363
1364
1365
1366 protected void setBlacklistedRecipient(boolean blacklisted)
1367 {
1368 fieldBlacklistedRecipient = blacklisted;
1369 }
1370
1371
1372
1373
1374
1375 protected boolean isRecipientNotFound()
1376 {
1377 return fieldRecipientNotFound;
1378 }
1379
1380
1381
1382
1383
1384 protected void setRecipientNotFound(boolean recipientNotFound)
1385 {
1386 fieldRecipientNotFound = recipientNotFound;
1387 }
1388
1389
1390
1391
1392
1393 protected String getRemoteDomain() throws MessagingException
1394 {
1395 String remoteDomain;
1396 if (null == (remoteDomain = getRemoteDomainBasic()))
1397 {
1398 updateRemoteDomain();
1399 return getRemoteDomain();
1400 }
1401 return remoteDomain;
1402 }
1403
1404
1405
1406
1407
1408 private String getRemoteDomainBasic()
1409 {
1410 return fieldRemoteDomain;
1411 }
1412
1413
1414
1415
1416
1417 protected void setRemoteDomain(String remoteDomain)
1418 {
1419 fieldRemoteDomain = remoteDomain;
1420 }
1421
1422
1423
1424
1425 protected void updateRemoteDomain() throws MessagingException
1426 {
1427 setRemoteDomain(computeRemoteDomain());
1428 }
1429
1430
1431
1432
1433
1434
1435
1436
1437 protected String computeRemoteAddress()
1438 throws MessagingException, UnknownHostException
1439 {
1440 String domain = getRemoteDomain();
1441 String address = null;
1442 String validatedAddress = null;
1443 int ipAddressStart = domain.indexOf('[');
1444 int ipAddressEnd = -1;
1445 if (ipAddressStart > -1)
1446 ipAddressEnd = domain.indexOf(']', ipAddressStart);
1447 if (ipAddressEnd > -1)
1448 address = domain.substring(ipAddressStart + 1, ipAddressEnd);
1449 else
1450 {
1451 int hostNameEnd = domain.indexOf(' ');
1452 if (hostNameEnd == -1)
1453 hostNameEnd = domain.length();
1454 address = domain.substring(0, hostNameEnd);
1455 }
1456 validatedAddress = getDNSServer().getByName(address).getHostAddress();
1457
1458 return validatedAddress;
1459 }
1460
1461
1462
1463
1464
1465
1466
1467
1468 protected String computeRemoteHostName()
1469 throws MessagingException, UnknownHostException
1470 {
1471 return getDNSServer().getHostName(getDNSServer().getByName(getRemoteAddress()));
1472 }
1473
1474
1475
1476
1477
1478 protected String getRemoteAddress()
1479 throws MessagingException, UnknownHostException
1480 {
1481 String remoteAddress;
1482 if (null == (remoteAddress = getRemoteAddressBasic()))
1483 {
1484 updateRemoteAddress();
1485 return getRemoteAddress();
1486 }
1487 return remoteAddress;
1488 }
1489
1490
1491
1492
1493
1494 private String getRemoteAddressBasic()
1495 {
1496 return fieldRemoteAddress;
1497 }
1498
1499
1500
1501
1502
1503 protected String getRemoteHostName()
1504 throws MessagingException, UnknownHostException
1505 {
1506 String remoteHostName;
1507 if (null == (remoteHostName = getRemoteHostNameBasic()))
1508 {
1509 updateRemoteHostName();
1510 return getRemoteHostName();
1511 }
1512 return remoteHostName;
1513 }
1514
1515
1516
1517
1518
1519 private String getRemoteHostNameBasic()
1520 {
1521 return fieldRemoteHostName;
1522 }
1523
1524
1525
1526
1527
1528 protected void setRemoteAddress(String remoteAddress)
1529 {
1530 fieldRemoteAddress = remoteAddress;
1531 }
1532
1533
1534
1535
1536 protected void updateRemoteAddress()
1537 throws MessagingException, UnknownHostException
1538 {
1539 setRemoteAddress(computeRemoteAddress());
1540 }
1541
1542
1543
1544
1545
1546 protected void setRemoteHostName(String remoteHostName)
1547 {
1548 fieldRemoteHostName = remoteHostName;
1549 }
1550
1551
1552
1553
1554 protected void updateRemoteHostName()
1555 throws MessagingException, UnknownHostException
1556 {
1557 setRemoteHostName(computeRemoteHostName());
1558 }
1559
1560
1561
1562
1563
1564 public static String getRFC2822RECEIVEDHeaderFields()
1565 {
1566 return fieldRFC2822RECEIVEDHeaderFields;
1567 }
1568
1569
1570
1571
1572
1573 protected Boolean isMaxMessageSizeExceeded() throws MessagingException
1574 {
1575 Boolean isMaxMessageSizeExceeded = null;
1576 if (null
1577 == (isMaxMessageSizeExceeded = isMaxMessageSizeExceededBasic()))
1578 {
1579 updateMaxMessageSizeExceeded();
1580 return isMaxMessageSizeExceeded();
1581 }
1582 return isMaxMessageSizeExceeded;
1583 }
1584
1585
1586
1587
1588 protected void updateMaxMessageSizeExceeded() throws MessagingException
1589 {
1590 setMaxMessageSizeExceeded(computeMaxMessageSizeExceeded());
1591 }
1592
1593
1594
1595
1596
1597 protected Boolean computeMaxMessageSizeExceeded() throws MessagingException
1598 {
1599 if (0 == getMaxMessageSizeLimit())
1600 return Boolean.FALSE;
1601 return new Boolean(getMessageIn().getSize() > getMaxMessageSizeLimit());
1602 }
1603
1604
1605
1606
1607
1608 private Boolean isMaxMessageSizeExceededBasic()
1609 {
1610 return fieldMaxMessageSizeExceeded;
1611 }
1612
1613
1614
1615
1616
1617 protected void setMaxMessageSizeExceeded(Boolean maxMessageSizeExceeded)
1618 {
1619 fieldMaxMessageSizeExceeded = maxMessageSizeExceeded;
1620 }
1621
1622
1623
1624
1625
1626 protected Boolean isRemoteReceivedHeaderInvalid() throws MessagingException
1627 {
1628 Boolean isInvalid = null;
1629 if (null == (isInvalid = isRemoteReceivedHeaderInvalidBasic()))
1630 {
1631 updateRemoteReceivedHeaderInvalid();
1632 return isRemoteReceivedHeaderInvalid();
1633 }
1634 return isInvalid;
1635 }
1636
1637
1638
1639
1640
1641 protected Boolean computeRemoteReceivedHeaderInvalid()
1642 throws MessagingException
1643 {
1644 Boolean isInvalid = Boolean.FALSE;
1645 try
1646 {
1647 getRemoteAddress();
1648 }
1649 catch (UnknownHostException e)
1650 {
1651 isInvalid = Boolean.TRUE;
1652 }
1653 return isInvalid;
1654 }
1655
1656
1657
1658
1659
1660 private Boolean isRemoteReceivedHeaderInvalidBasic()
1661 {
1662 return fieldRemoteReceivedHeaderInvalid;
1663 }
1664
1665
1666
1667
1668
1669 protected void setRemoteReceivedHeaderInvalid(Boolean remoteReceivedHeaderInvalid)
1670 {
1671 fieldRemoteReceivedHeaderInvalid = remoteReceivedHeaderInvalid;
1672 }
1673
1674
1675
1676
1677 protected void updateRemoteReceivedHeaderInvalid() throws MessagingException
1678 {
1679 setRemoteReceivedHeaderInvalid(computeRemoteReceivedHeaderInvalid());
1680 }
1681
1682
1683
1684
1685
1686 protected boolean isDefaultSenderDomainPart()
1687 {
1688 return fieldDefaultSenderDomainPart;
1689 }
1690
1691
1692
1693
1694
1695 protected boolean isDefaultSenderLocalPart()
1696 {
1697 return fieldDefaultSenderLocalPart;
1698 }
1699
1700
1701
1702
1703
1704 protected void setDefaultSenderDomainPart(boolean defaultSenderDomainPart)
1705 {
1706 fieldDefaultSenderDomainPart = defaultSenderDomainPart;
1707 }
1708
1709
1710
1711
1712
1713 protected void setDefaultSenderLocalPart(boolean defaultSenderLocalPart)
1714 {
1715 fieldDefaultSenderLocalPart = defaultSenderLocalPart;
1716 }
1717
1718
1719
1720
1721
1722 protected boolean isDefaultRemoteAddress()
1723 {
1724 return fieldDefaultRemoteAddress;
1725 }
1726
1727
1728
1729
1730
1731 protected void setDefaultRemoteAddress(boolean defaultRemoteAddress)
1732 {
1733 fieldDefaultRemoteAddress = defaultRemoteAddress;
1734 }
1735
1736 }