1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.geronimo.javamail.transport.smtp;
21
22 import java.io.BufferedReader;
23 import java.io.BufferedOutputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.InputStreamReader;
27 import java.io.OutputStream;
28 import java.io.PrintStream;
29 import java.io.PrintWriter;
30 import java.io.UnsupportedEncodingException;
31 import java.lang.reflect.InvocationTargetException;
32 import java.lang.reflect.Method;
33 import java.net.InetAddress;
34 import java.net.Socket;
35 import java.net.SocketException;
36 import java.util.ArrayList;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.StringTokenizer;
40
41 import javax.mail.Address;
42 import javax.mail.AuthenticationFailedException;
43 import javax.mail.Message;
44 import javax.mail.MessagingException;
45 import javax.mail.internet.InternetAddress;
46 import javax.mail.internet.MimeMessage;
47 import javax.mail.internet.MimeMultipart;
48 import javax.mail.internet.MimePart;
49 import javax.mail.Session;
50
51 import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
52 import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
53 import org.apache.geronimo.javamail.util.CountingOutputStream;
54 import org.apache.geronimo.javamail.util.MailConnection;
55 import org.apache.geronimo.javamail.util.MIMEOutputStream;
56 import org.apache.geronimo.javamail.util.ProtocolProperties;
57 import org.apache.geronimo.mail.util.Base64;
58 import org.apache.geronimo.mail.util.XText;
59
60
61
62
63
64
65 public class SMTPConnection extends MailConnection {
66 protected static final String MAIL_SMTP_QUITWAIT = "quitwait";
67 protected static final String MAIL_SMTP_EXTENSION = "mailextension";
68 protected static final String MAIL_SMTP_EHLO = "ehlo";
69 protected static final String MAIL_SMTP_ALLOW8BITMIME = "allow8bitmime";
70 protected static final String MAIL_SMTP_REPORT_SUCCESS = "reportsuccess";
71 protected static final String MAIL_SMTP_STARTTLS_ENABLE = "starttls.enable";
72 protected static final String MAIL_SMTP_AUTH = "auth";
73 protected static final String MAIL_SMTP_FROM = "from";
74 protected static final String MAIL_SMTP_DSN_RET = "dsn.ret";
75 protected static final String MAIL_SMTP_SUBMITTER = "submitter";
76
77
78
79
80 protected static final int DEFAULT_NNTP_PORT = 119;
81
82
83 protected SMTPReply lastServerResponse = null;
84
85
86 protected BufferedReader reader;
87
88 protected PrintWriter writer;
89
90
91 protected boolean reportSuccess;
92
93 protected boolean serverTLS = false;
94
95 protected boolean useTLS = false;
96
97 protected boolean use8bit = false;
98
99
100
101
102
103
104 public SMTPConnection(ProtocolProperties props) {
105 super(props);
106
107
108 reportSuccess = props.getBooleanProperty(MAIL_SMTP_REPORT_SUCCESS, false);
109
110 useTLS = props.getBooleanProperty(MAIL_SMTP_STARTTLS_ENABLE, false);
111
112 use8bit = props.getBooleanProperty(MAIL_SMTP_ALLOW8BITMIME, false);
113 }
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 public boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
129
130
131
132
133
134 boolean mustAuthenticate = props.getBooleanProperty(MAIL_SMTP_AUTH, false);
135
136
137
138
139
140
141 if (mustAuthenticate && (username == null || password == null)) {
142 debugOut("Failing connection for missing authentication information");
143 return false;
144 }
145
146 super.protocolConnect(host, port, username, password);
147
148 try {
149
150 getConnection();
151
152
153 if (!getWelcome()) {
154 debugOut("Error getting welcome message");
155 throw new MessagingException("Error in getting welcome msg");
156 }
157
158
159 if (!sendHandshake()) {
160 debugOut("Error getting processing handshake message");
161 throw new MessagingException("Error in saying EHLO to server");
162 }
163
164
165 if (!processAuthentication()) {
166 debugOut("User authentication failure");
167 throw new AuthenticationFailedException("Error authenticating with server");
168 }
169 } catch (IOException e) {
170 debugOut("I/O exception establishing connection", e);
171 throw new MessagingException("Connection error", e);
172 }
173 debugOut("Successful connection");
174 return true;
175 }
176
177
178
179
180
181
182
183
184 public void close() throws MessagingException {
185
186 if (socket == null) {
187 return;
188 }
189 try {
190
191 sendQuit();
192 } finally {
193
194
195
196 closeServerConnection();
197 }
198 }
199
200 public String toString() {
201 return "SMTPConnection host: " + serverHost + " port: " + serverPort;
202 }
203
204
205
206
207
208
209
210
211
212
213
214 protected boolean sendMailFrom(Message message) throws MessagingException {
215
216
217 String from = null;
218
219
220
221 if (message instanceof SMTPMessage) {
222 from = ((SMTPMessage) message).getEnvelopeFrom();
223 }
224
225
226 if (from == null || from.length() == 0) {
227
228 from = props.getProperty(MAIL_SMTP_FROM);
229 }
230
231
232 if (from == null || from.length() == 0) {
233 Address[] fromAddresses = message.getFrom();
234
235
236
237 if (fromAddresses != null && fromAddresses.length > 0) {
238 from = ((InternetAddress) fromAddresses[0]).getAddress();
239 }
240
241
242 else {
243 InternetAddress local = InternetAddress.getLocalAddress(session);
244 if (local != null) {
245 from = local.getAddress();
246 }
247 }
248 }
249
250 if (from == null || from.length() == 0) {
251 throw new MessagingException("no FROM address");
252 }
253
254 StringBuffer command = new StringBuffer();
255
256
257 command.append("MAIL FROM: ");
258 command.append(fixEmailAddress(from));
259
260
261
262
263 if (supportsExtension("8BITMIME")) {
264
265
266 if (use8bit || (message instanceof SMTPMessage && ((SMTPMessage)message).getAllow8bitMIME())) {
267
268 command.append(" BODY=8BITMIME");
269
270
271
272 if (convertTransferEncoding((MimeMessage)message)) {
273
274
275 message.saveChanges();
276 }
277 }
278 }
279
280
281 if (supportsExtension("SIZE")) {
282 int estimate = getSizeEstimate(message);
283 if (estimate > 0) {
284 command.append(" SIZE=" + estimate);
285 }
286 }
287
288
289
290 if (supportsExtension("DSN")) {
291 String returnNotification = null;
292
293
294
295 if (message instanceof SMTPMessage) {
296
297 switch (((SMTPMessage) message).getReturnOption()) {
298 case SMTPMessage.RETURN_FULL:
299 returnNotification = "FULL";
300 break;
301
302 case SMTPMessage.RETURN_HDRS:
303 returnNotification = "HDRS";
304 break;
305 }
306 }
307
308
309
310 if (returnNotification == null) {
311
312 returnNotification = props.getProperty(MAIL_SMTP_DSN_RET);
313 }
314
315
316
317 if (returnNotification != null) {
318 command.append(" RET=");
319 command.append(returnNotification);
320 }
321 }
322
323
324
325
326
327 if (supportsExtension("AUTH")) {
328 String submitter = null;
329
330
331 if (message instanceof SMTPMessage) {
332 submitter = ((SMTPMessage) message).getSubmitter();
333 }
334
335 if (submitter == null) {
336
337 submitter = props.getProperty(MAIL_SMTP_SUBMITTER);
338 }
339
340
341 if (submitter != null) {
342 command.append(" AUTH=");
343 try {
344
345 command.append(new String(XText.encode(submitter.getBytes("US-ASCII"))));
346 } catch (UnsupportedEncodingException e) {
347 throw new MessagingException("Invalid submitter value " + submitter);
348 }
349 }
350 }
351
352 String extension = null;
353
354
355
356
357 if (message instanceof SMTPMessage) {
358 extension = ((SMTPMessage) message).getMailExtension();
359 }
360
361 if (extension == null) {
362 extension = props.getProperty(MAIL_SMTP_EXTENSION);
363 }
364
365
366 if (extension != null && extension.length() != 0) {
367
368 command.append(' ');
369 command.append(extension);
370 }
371
372
373 SMTPReply line = sendCommand(command.toString());
374
375
376 return line.getCode() == SMTPReply.COMMAND_ACCEPTED;
377 }
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404 protected boolean convertTransferEncoding(MimePart bodyPart)
405 {
406 boolean converted = false;
407 try {
408
409
410 if (bodyPart.isMimeType("multipart/")) {
411 MimeMultipart parts = (MimeMultipart)bodyPart.getContent();
412 for (int i = 0; i < parts.getCount(); i++) {
413
414 converted = converted && convertTransferEncoding((MimePart)parts.getBodyPart(i));
415 }
416 }
417 else {
418
419 String encoding = bodyPart.getEncoding();
420 if (encoding != null) {
421 encoding = encoding.toLowerCase();
422 if (encoding.equals("quoted-printable") || encoding.equals("base64")) {
423
424
425 if (isValid8bit(bodyPart.getInputStream())) {
426
427
428
429
430
431
432
433
434
435
436
437 bodyPart.setContent(bodyPart.getContent(), bodyPart.getContentType());
438
439
440
441 bodyPart.setHeader("Content-Transfer-Encoding", "8bit");
442 converted = true;
443 }
444 }
445 }
446 }
447 } catch (MessagingException e) {
448 } catch (IOException e) {
449 }
450 return converted;
451 }
452
453
454
455
456
457 protected boolean getWelcome() throws MessagingException {
458 SMTPReply line = getReply();
459
460
461 return !line.isError();
462 }
463
464
465
466
467
468
469
470
471
472
473
474
475 protected int getSizeEstimate(Message msg) {
476
477 try {
478 CountingOutputStream outputStream = new CountingOutputStream();
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494 MIMEOutputStream mimeOut = new MIMEOutputStream(outputStream);
495
496 msg.writeTo(mimeOut);
497
498
499 mimeOut.forceTerminatingLineBreak();
500
501 mimeOut.flush();
502
503 return outputStream.getCount();
504 } catch (IOException e) {
505 return 0;
506 } catch (MessagingException e) {
507 return 0;
508 }
509 }
510
511
512
513
514
515
516
517 protected void sendData(Message msg) throws MessagingException {
518
519
520 SMTPReply line = sendCommand("DATA");
521
522 if (line.isError()) {
523 throw new MessagingException("Error issuing SMTP 'DATA' command: " + line);
524 }
525
526
527 try {
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542 MIMEOutputStream mimeOut = new MIMEOutputStream(outputStream);
543
544 msg.writeTo(mimeOut);
545
546
547 mimeOut.writeSMTPTerminator();
548
549 mimeOut.flush();
550 } catch (IOException e) {
551 throw new MessagingException(e.toString());
552 } catch (MessagingException e) {
553 throw new MessagingException(e.toString());
554 }
555
556
557
558 try {
559 line = new SMTPReply(receiveLine(TIMEOUT * 2));
560 } catch (MalformedSMTPReplyException e) {
561 throw new MessagingException(e.toString());
562 } catch (MessagingException e) {
563 throw new MessagingException(e.toString());
564 }
565
566 if (line.isError()) {
567 throw new MessagingException("Error issuing SMTP 'DATA' command: " + line);
568 }
569 }
570
571
572
573
574 protected void sendQuit() throws MessagingException {
575
576
577
578
579 if (props.getBooleanProperty(MAIL_SMTP_QUITWAIT, true)) {
580
581 sendCommand("QUIT");
582 } else {
583
584 sendLine("QUIT");
585 }
586 }
587
588
589
590
591
592
593
594
595
596
597
598
599 public SendStatus sendRcptTo(InternetAddress addr, String dsn) throws MessagingException {
600
601
602
603
604 StringBuffer command = new StringBuffer();
605
606
607 command.append("RCPT TO: ");
608 command.append(fixEmailAddress(addr.getAddress()));
609
610
611 if (dsn != null) {
612 command.append(" NOTIFY=");
613 command.append(dsn);
614 }
615
616
617 String commandString = command.toString();
618
619 SMTPReply line = sendCommand(commandString);
620
621 switch (line.getCode()) {
622
623 case SMTPReply.COMMAND_ACCEPTED:
624 case SMTPReply.ADDRESS_NOT_LOCAL:
625
626 return new SendStatus(SendStatus.SUCCESS, addr, commandString, line);
627
628
629 case SMTPReply.PARAMETER_SYNTAX_ERROR:
630 case SMTPReply.INVALID_COMMAND_SEQUENCE:
631 case SMTPReply.MAILBOX_NOT_FOUND:
632 case SMTPReply.INVALID_MAILBOX:
633 case SMTPReply.USER_NOT_LOCAL:
634
635 return new SendStatus(SendStatus.INVALID_ADDRESS, addr, commandString, line);
636
637
638 case SMTPReply.SERVICE_NOT_AVAILABLE:
639 case SMTPReply.MAILBOX_BUSY:
640 case SMTPReply.PROCESSING_ERROR:
641 case SMTPReply.INSUFFICIENT_STORAGE:
642 case SMTPReply.MAILBOX_FULL:
643
644 return new SendStatus(SendStatus.SEND_FAILURE, addr, commandString, line);
645
646
647 default:
648
649 return new SendStatus(SendStatus.GENERAL_ERROR, addr, commandString, line);
650 }
651 }
652
653
654
655
656
657
658
659
660
661
662
663 protected SMTPReply sendCommand(String data) throws MessagingException {
664 sendLine(data);
665 return getReply();
666 }
667
668
669
670
671 protected void sendLine(String data) throws MessagingException {
672 if (socket == null || !socket.isConnected()) {
673 throw new MessagingException("no connection");
674 }
675 try {
676 outputStream.write(data.getBytes());
677 outputStream.write(CR);
678 outputStream.write(LF);
679 outputStream.flush();
680 } catch (IOException e) {
681 throw new MessagingException(e.toString());
682 }
683 }
684
685
686
687
688
689
690
691 protected String receiveLine() throws MessagingException {
692 return receiveLine(TIMEOUT);
693 }
694
695
696
697
698
699
700 protected SMTPReply getReply() throws MessagingException {
701 try {
702 lastServerResponse = new SMTPReply(receiveLine());
703
704
705 while (lastServerResponse.isContinued()) {
706 lastServerResponse.addLine(receiveLine());
707 }
708 } catch (MalformedSMTPReplyException e) {
709 throw new MessagingException(e.toString());
710 } catch (MessagingException e) {
711 throw e;
712 }
713 return lastServerResponse;
714 }
715
716
717
718
719
720
721
722 public SMTPReply getLastServerResponse() {
723 return lastServerResponse;
724 }
725
726
727
728
729
730
731
732
733 protected String receiveLine(int delayMillis) throws MessagingException {
734 if (socket == null || !socket.isConnected()) {
735 throw new MessagingException("no connection");
736 }
737
738 int timeout = 0;
739
740 try {
741
742 timeout = socket.getSoTimeout();
743
744 socket.setSoTimeout(delayMillis);
745
746 StringBuffer buff = new StringBuffer();
747
748 int c;
749 boolean crFound = false, lfFound = false;
750
751 while ((c = inputStream.read()) != -1 && crFound == false && lfFound == false) {
752
753
754
755 if (c == CR) {
756 crFound = true;
757 } else if (c == LF) {
758 lfFound = true;
759 } else {
760 buff.append((char) c);
761 }
762 }
763
764 String line = buff.toString();
765 return line;
766
767 } catch (SocketException e) {
768 throw new MessagingException(e.toString());
769 } catch (IOException e) {
770 throw new MessagingException(e.toString());
771 } finally {
772 try {
773 socket.setSoTimeout(timeout);
774 } catch (SocketException e) {
775
776 }
777 }
778 }
779
780
781
782
783
784
785
786
787
788
789
790
791 protected String fixEmailAddress(String mail) {
792 if (mail.charAt(0) == '<') {
793 return mail;
794 }
795 return "<" + mail + ">";
796 }
797
798
799
800
801
802
803 protected boolean sendHandshake() throws MessagingException {
804
805 boolean useEhlo = props.getBooleanProperty(MAIL_SMTP_EHLO, true);
806
807
808 if (useEhlo) {
809 if (!sendEhlo()) {
810 sendHelo();
811 }
812 } else {
813
814 sendHelo();
815 }
816
817 if (useTLS) {
818
819
820 if (!serverTLS) {
821 throw new MessagingException("Server doesn't support required transport level security");
822 }
823
824
825 getConnectedTLSSocket();
826
827
828
829
830
831
832 if (!sendEhlo()) {
833 throw new MessagingException("Failure sending EHLO command to SMTP server");
834 }
835 }
836
837
838 return true;
839 }
840
841
842
843
844
845
846 protected void getConnectedTLSSocket() throws MessagingException {
847 debugOut("Attempting to negotiate STARTTLS with server " + serverHost);
848
849 SMTPReply line = sendCommand("STARTTLS");
850
851 if (line.getCode() != SMTPReply.SERVICE_READY) {
852 debugOut("STARTTLS command rejected by SMTP server " + serverHost);
853 throw new MessagingException("Unable to make TLS server connection");
854 }
855
856 debugOut("STARTTLS command accepted");
857
858
859 super.getConnectedTLSSocket();
860 }
861
862
863
864
865
866
867
868
869
870
871 protected boolean sendEhlo() throws MessagingException {
872 sendLine("EHLO " + getLocalHost());
873
874 SMTPReply reply = getReply();
875
876
877
878
879
880 if (reply.getCode() != SMTPReply.COMMAND_ACCEPTED) {
881 return false;
882 }
883
884
885 capabilities = new HashMap();
886 authentications = new ArrayList();
887
888 List lines = reply.getLines();
889
890 for (int i = 1; i < lines.size(); i++) {
891
892 processExtension((String)lines.get(i));
893 }
894 return true;
895 }
896
897
898
899
900
901
902 protected void sendHelo() throws MessagingException {
903
904
905 capabilities = new HashMap();
906 authentications = new ArrayList();
907
908 sendLine("HELO " + getLocalHost());
909
910 SMTPReply line = getReply();
911
912
913
914
915
916 if (line.getCode() != SMTPReply.COMMAND_ACCEPTED) {
917 throw new MessagingException("Failure sending HELO command to SMTP server");
918 }
919 }
920
921
922
923
924
925
926 public boolean getStartTLS() {
927 return useTLS;
928 }
929
930
931
932
933
934
935
936
937 public void setStartTLS(boolean start) {
938 useTLS = start;
939 }
940
941
942
943
944
945
946
947
948
949 protected void processExtension(String extension) {
950 debugOut("Processing extension " + extension);
951 String extensionName = extension.toUpperCase();
952 String argument = "";
953
954 int delimiter = extension.indexOf(' ');
955
956
957 if (delimiter != -1) {
958 extensionName = extension.substring(0, delimiter).toUpperCase();
959 argument = extension.substring(delimiter + 1);
960 }
961
962
963 capabilities.put(extensionName, argument);
964
965
966
967 if (extensionName.equals("AUTH")) {
968
969 if (argument == null) {
970 authentications.add("LOGIN");
971 } else {
972
973 StringTokenizer tokenizer = new StringTokenizer(argument);
974
975 while (tokenizer.hasMoreTokens()) {
976 String mechanism = tokenizer.nextToken().toUpperCase();
977 authentications.add(mechanism);
978 }
979 }
980 }
981
982 else if (extensionName.equals("AUTH=LOGIN")) {
983 authentications.add("LOGIN");
984 }
985
986 else if (extensionName.equals("STARTTLS")) {
987
988 serverTLS = true;
989 }
990 }
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004 public String extensionParameter(String name) {
1005 if (capabilities != null) {
1006 return (String)capabilities.get(name);
1007 }
1008 return null;
1009 }
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022 public boolean supportsExtension(String name) {
1023
1024 return extensionParameter(name) != null;
1025 }
1026
1027
1028
1029
1030
1031
1032
1033
1034 protected boolean processAuthentication() throws MessagingException {
1035
1036 if (!props.getBooleanProperty(MAIL_SMTP_AUTH, false)) {
1037 return true;
1038 }
1039
1040
1041
1042
1043 if (username == null || password == null) {
1044 return false;
1045 }
1046
1047
1048 ClientAuthenticator authenticator = getSaslAuthenticator();
1049 if (authenticator == null) {
1050 throw new MessagingException("Unable to obtain SASL authenticator");
1051 }
1052
1053
1054 if (debug) {
1055 debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
1056 }
1057
1058
1059
1060 if (authenticator.hasInitialResponse()) {
1061 StringBuffer command = new StringBuffer();
1062
1063 command.append("AUTH ");
1064
1065 command.append(authenticator.getMechanismName());
1066 command.append(" ");
1067
1068 command.append(new String(Base64.encode(authenticator.evaluateChallenge(null))));
1069
1070 sendLine(command.toString());
1071 }
1072
1073 else {
1074 StringBuffer command = new StringBuffer();
1075
1076 command.append("AUTH ");
1077
1078 command.append(authenticator.getMechanismName());
1079
1080 sendLine(command.toString());
1081 }
1082
1083
1084
1085
1086 while (true) {
1087
1088 SMTPReply line;
1089 try {
1090 line = new SMTPReply(receiveLine());
1091 } catch (MalformedSMTPReplyException e) {
1092 throw new MessagingException(e.toString());
1093 } catch (MessagingException e) {
1094 throw e;
1095 }
1096
1097
1098
1099 if (line.getCode() == SMTPReply.AUTHENTICATION_COMPLETE) {
1100 debugOut("Successful SMTP authentication");
1101 return true;
1102 }
1103
1104 else if (line.getCode() == SMTPReply.AUTHENTICATION_CHALLENGE) {
1105
1106
1107
1108 if (authenticator.isComplete()) {
1109 return false;
1110 }
1111
1112
1113 byte[] challenge = Base64.decode(line.getMessage().getBytes());
1114
1115
1116
1117 sendLine(new String(Base64.encode(authenticator.evaluateChallenge(challenge))));
1118 }
1119
1120
1121
1122 else {
1123 if (debug) {
1124 debugOut("Authentication failure " + line);
1125 }
1126 return false;
1127 }
1128 }
1129 }
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139 protected ClientAuthenticator getSaslAuthenticator() {
1140 return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
1141 }
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160 protected boolean isValid8bit(InputStream inStream) {
1161 try {
1162 int ch;
1163 int lineLength = 0;
1164 while ((ch = inStream.read()) >= 0) {
1165
1166 if (ch == 0) {
1167 return false;
1168 }
1169
1170 else if (ch == '\r') {
1171
1172
1173 ch = inStream.read();
1174 if (ch != '\n') {
1175 return false;
1176 }
1177
1178 lineLength = 0;
1179 }
1180 else {
1181
1182 lineLength++;
1183
1184 if (lineLength > 998) {
1185 return false;
1186 }
1187 }
1188
1189 }
1190 } catch (IOException e) {
1191 return false;
1192 }
1193
1194 return true;
1195 }
1196
1197
1198
1199
1200
1201
1202 static public class SendStatus {
1203 public final static int SUCCESS = 0;
1204
1205 public final static int INVALID_ADDRESS = 1;
1206
1207 public final static int SEND_FAILURE = 2;
1208
1209 public final static int GENERAL_ERROR = 3;
1210
1211
1212 int status;
1213
1214
1215 InternetAddress address;
1216
1217
1218 String cmd;
1219
1220
1221 SMTPReply reply;
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235 public SendStatus(int s, InternetAddress a, String c, SMTPReply r) {
1236 this.cmd = c;
1237 this.status = s;
1238 this.address = a;
1239 this.reply = r;
1240 }
1241
1242
1243
1244
1245
1246
1247 public int getStatus() {
1248 return this.status;
1249 }
1250
1251
1252
1253
1254
1255
1256
1257 public InternetAddress getAddress() {
1258 return this.address;
1259 }
1260
1261
1262
1263
1264
1265
1266 public SMTPReply getReply() {
1267 return reply;
1268 }
1269
1270
1271
1272
1273
1274
1275
1276 public String getCommand() {
1277 return cmd;
1278 }
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290 public MessagingException getException(boolean reportSuccess) {
1291 if (status != SUCCESS) {
1292 return new SMTPAddressFailedException(address, cmd, reply.getCode(), reply.getMessage());
1293 } else {
1294 if (reportSuccess) {
1295 return new SMTPAddressSucceededException(address, cmd, reply.getCode(), reply.getMessage());
1296 }
1297 }
1298 return null;
1299 }
1300 }
1301
1302
1303
1304
1305
1306
1307
1308 public void resetConnection() throws MessagingException {
1309
1310
1311
1312 SMTPReply last = lastServerResponse;
1313
1314
1315 SMTPReply line = sendCommand("RSET");
1316
1317
1318 if (line.getCode() != SMTPReply.COMMAND_ACCEPTED) {
1319 close();
1320 }
1321
1322 lastServerResponse = last;
1323 }
1324
1325
1326
1327
1328
1329
1330
1331 public boolean getReportSuccess() {
1332 return reportSuccess;
1333 }
1334
1335
1336
1337
1338
1339
1340
1341 public void setReportSuccess(boolean report) {
1342 reportSuccess = report;
1343 }
1344 }
1345