1 7 8 package org.enhydra.oyster.smime; 9 10 import org.enhydra.oyster.exception.SMIMEException; 11 import org.enhydra.oyster.activation.StreamDataSource; 12 import org.enhydra.oyster.mail.MultipartGenerator; 13 import org.enhydra.oyster.util.ConvertAssist; 14 import org.enhydra.oyster.util.PFXUtils; 15 import org.enhydra.oyster.mail.ContentAnalyzer; 16 import org.enhydra.oyster.crypto.consts.KeyStoreConstants; 17 import javax.mail.Session ; 18 import javax.mail.Transport ; 19 import javax.mail.MessagingException ; 20 import javax.mail.internet.MimeMessage ; 21 import javax.mail.internet.MimeBodyPart ; 22 import javax.mail.internet.MimeMultipart ; 23 import javax.mail.internet.InternetAddress ; 24 import javax.activation.DataHandler ; 25 import javax.activation.FileDataSource ; 26 import javax.activation.MimetypesFileTypeMap ; 27 import java.util.Vector ; 28 import java.util.Properties ; 29 import java.io.File ; 30 import java.io.InputStream ; 31 import java.io.FileInputStream ; 32 import java.io.ByteArrayInputStream ; 33 import java.security.Security ; 34 import sun.security.provider.Sun; 35 import org.bouncycastle.jce.provider.BouncyCastleProvider; 36 import java.security.KeyStore ; 37 import java.security.cert.X509Certificate ; 38 import java.security.cert.CertificateFactory ; 39 40 import java.io.*; 41 42 49 public class BaseSMIMEObject implements KeyStoreConstants 50 { 51 52 55 protected MimeMessage message; 56 57 61 protected boolean contentPresence = false; 62 63 67 protected boolean externalMessagePresence = false; 68 69 72 protected Vector bodyPartArray = new Vector (0, 1); 73 74 75 78 protected Vector certArray = new Vector (0, 1); 79 80 83 protected boolean indicatorTo = false; 84 85 95 protected String charsetEnc = null; 96 97 103 protected BaseSMIMEObject () 104 { 105 Security.addProvider(new BouncyCastleProvider()); Security.addProvider(new Sun()); } 108 109 134 protected BaseSMIMEObject (String smtpHost, String fromAddress, String subject, 135 String content, String charset) throws SMIMEException 136 { 137 this(); 138 try { 139 initMimeMessage(smtpHost, fromAddress, subject, content, charset); 140 } 141 catch(Exception e) { 142 throw SMIMEException.getInstance(this, e, "constructor"); 143 } 144 } 145 146 147 166 protected BaseSMIMEObject (String smtpHost, String fromAddress, String subject, 167 String charset) throws SMIMEException 168 { 169 this(smtpHost, fromAddress, subject, null, charset); 170 } 171 172 173 190 protected BaseSMIMEObject (MimeMessage mimeMessage) throws SMIMEException 191 { 192 try { 193 Security.addProvider(new BouncyCastleProvider()); Security.addProvider(new Sun()); 196 this.message = new MimeMessage (mimeMessage); 197 message.removeHeader("TO"); 198 message.removeHeader("CC"); 199 message.removeHeader("BCC"); 200 201 externalMessagePresence = true; 202 } 203 catch(Exception e) { 204 throw SMIMEException.getInstance(this, e, "constructor"); 205 } 206 } 207 208 209 233 public void initMimeMessage(String smtpHost, String fromAddress, String subject, 234 String content, String charset) throws SMIMEException 235 { 236 if (smtpHost == null | fromAddress == null) 237 throw new SMIMEException(this, 1041); 238 239 this.charsetEnc = charset; 240 241 Properties sesProp = new Properties (); 242 sesProp.setProperty("mail.smtp.host", smtpHost); 243 Session ses = Session.getInstance(sesProp); 244 message = new MimeMessage (ses); 245 try { 246 InternetAddress from = new InternetAddress (fromAddress); 247 message.setFrom(from); 248 if (subject != null) { 249 if(charset != null) 250 message.setSubject(subject, charset); 251 else 252 message.setSubject(subject); 253 } 254 if (content != null) { 255 MimeBodyPart mbp = new MimeBodyPart (); 256 if(charset != null) 257 mbp.setText(content, charset); 258 else 259 mbp.setText(content); 260 mbp.setText(content); 261 bodyPartArray.addElement(mbp); 262 contentPresence = true; 263 } 264 } 265 catch(Exception e) { 266 throw SMIMEException.getInstance(this, e, "initMimeMessage"); 267 } 268 } 269 270 271 282 public void setCharsetEncoding(String charset) { 283 this.charsetEnc = charset; 284 } 285 286 287 380 public void setContent(String content, String type, String path, InputStream [] resources, 381 String externalPlainText) throws SMIMEException { 382 383 if(content != null) { 384 ByteArrayInputStream bais = null; 385 try { 386 if(this.charsetEnc != null) 387 bais = new ByteArrayInputStream ( content.getBytes(this.charsetEnc) ); 388 else 389 bais = new ByteArrayInputStream ( content.getBytes("ISO-8859-1") ); 390 } 391 catch(Exception e) { 392 throw SMIMEException.getInstance(this, e, "setContent"); 393 } 394 this.setContent(bais, type, path, resources, externalPlainText); 395 396 } 397 else 398 throw new SMIMEException(this, 1035); 399 } 400 401 426 public void setContent(String content, String type, String path, InputStream [] resources) 427 throws SMIMEException { 428 429 this.setContent(content, type, path, resources, null); 430 } 431 432 433 465 public void setContent(InputStream content, String type, String path, 466 InputStream [] resources, String externalPlainText) throws SMIMEException { 467 if(contentPresence) 468 throw new SMIMEException(this, 1049); 469 if(content != null) { 470 try { 471 if(type.equalsIgnoreCase("text/plain")) { 472 MimeBodyPart mbp = new MimeBodyPart (); 473 String temp = null; 474 if(this.charsetEnc != null) { 475 temp = new String (ConvertAssist.inStreamToByteArray(content), this.charsetEnc); 476 mbp.setText(temp, this.charsetEnc); 477 } 478 else { 479 temp = new String (ConvertAssist.inStreamToByteArray(content), "ISO-8859-1"); 480 mbp.setText(temp, "ISO-8859-1"); 481 } 482 bodyPartArray.add(0, mbp); 483 contentPresence = true; 484 } 485 else if(type.equalsIgnoreCase("text/html")) { 486 MimeMultipart htmlMultipart = 487 MultipartGenerator.getHtmlMultipart(content, path, resources, externalPlainText); 488 bodyPartArray.add(0, htmlMultipart); 489 contentPresence = true; 490 } 491 else 492 throw new SMIMEException(this, 1048); 493 } 494 catch(Exception e) { 495 throw SMIMEException.getInstance(this, e, "setContent"); 496 } 497 } 498 else 499 throw new SMIMEException(this, 1035); 500 } 501 502 503 531 public void setContent(InputStream content, String type, String path, 532 InputStream [] resources) throws SMIMEException { 533 this.setContent(content, type, path, resources, null); 534 } 535 536 537 563 public void setContent(InputStream content, String type, String externalPlainText) throws SMIMEException { 564 if(contentPresence) 565 throw new SMIMEException(this, 1049); 566 if(content != null) { 567 try { 568 if(type.equalsIgnoreCase("text/plain")) { 569 MimeBodyPart mbp = new MimeBodyPart (); 570 String temp = null; 571 if(this.charsetEnc != null) { 572 temp = new String (ConvertAssist.inStreamToByteArray(content), this.charsetEnc); 573 mbp.setText(temp, this.charsetEnc); 574 } 575 else { 576 temp = new String (ConvertAssist.inStreamToByteArray(content), "ISO-8859-1"); 577 mbp.setText(temp, "ISO-8859-1"); 578 } 579 580 bodyPartArray.add(0, mbp); 581 contentPresence = true; 582 } 583 else if(type.equalsIgnoreCase("text/html")) { 584 MimeMultipart htmlMultipart = MultipartGenerator.getHtmlMultipart(content); 585 bodyPartArray.add(0, htmlMultipart); 586 contentPresence = true; 587 } 588 else 589 throw new SMIMEException(this, 1048); 590 } 591 catch(Exception e) { 592 throw SMIMEException.getInstance(this, e, "setContent"); 593 } 594 } 595 else 596 throw new SMIMEException(this, 1035); 597 } 598 599 600 617 public void setContent(InputStream content, String type) throws SMIMEException { 618 this.setContent(content, type, null); 619 } 620 621 622 623 649 public void setContent(String content, String type, String externalPlainText) throws SMIMEException { 650 651 if(content != null) { 652 ByteArrayInputStream bais = null; 653 try { 654 if(this.charsetEnc != null) 655 bais = new ByteArrayInputStream ( content.getBytes(this.charsetEnc) ); 656 else 657 bais = new ByteArrayInputStream ( content.getBytes("ISO-8859-1") ); 658 } 659 catch(Exception e) { 660 throw SMIMEException.getInstance(this, e, "setContent"); 661 } 662 this.setContent(bais, type); 663 664 } 665 else 666 throw new SMIMEException(this, 1035); 667 } 668 669 670 687 public void setContent(String content, String type) throws SMIMEException { 688 689 this.setContent(content, type, null); 690 } 691 692 717 public void setContent(File inFile, String type, String externalPlainText) throws SMIMEException { 718 719 if(contentPresence) 720 throw new SMIMEException(this, 1049); 721 if(inFile != null && inFile.exists()) { 722 try { 723 File inFileAbs = inFile.getAbsoluteFile().getCanonicalFile(); 724 String content = ConvertAssist.fileToString(inFileAbs); 725 this.setContent(content, type, inFile.getParent(), null, externalPlainText); 726 } 727 catch(Exception e) { 728 throw SMIMEException.getInstance(this, e, "setContent"); 729 } 730 } 731 else 732 throw new SMIMEException(this, 1034); 733 } 734 735 751 public void setContent(File inFile, String type) throws SMIMEException { 752 this.setContent(inFile, type, null); 753 } 754 755 768 public void addAttachment (String fileName) throws SMIMEException 769 { 770 File fn = new File (fileName); 771 this.addAttachment(fn); 772 } 773 774 792 public void addAttachment (String fileName, String encoding) throws SMIMEException 793 { 794 File fn = new File (fileName); 795 this.addAttachment(fn, encoding); 796 } 797 798 811 public void addAttachment (File file) throws SMIMEException 812 { 813 if(!file.exists()) 814 throw new SMIMEException(this, 1034); 815 try { 816 FileInputStream fis = new FileInputStream (file); 817 int u = fis.available(); 818 this.addAttachment(fis, file.getName()); 819 } 820 catch(Exception e) { 821 throw SMIMEException.getInstance(this, e, "addAttachment"); 822 } 823 } 824 825 843 public void addAttachment (File file, String encoding) throws SMIMEException 844 { 845 if(!file.exists()) 846 throw new SMIMEException(this, 1034); 847 try { 848 FileInputStream fis = new FileInputStream (file); 849 int u = fis.available(); 850 this.addAttachment(fis, file.getName(), encoding); 851 } 852 catch(Exception e) { 853 throw SMIMEException.getInstance(this, e, "addAttachment"); 854 } 855 } 856 857 874 public void addAttachment (InputStream data, String fileName) throws SMIMEException 875 { 876 MimeBodyPart attachment = new MimeBodyPart (); 877 try { 878 StreamDataSource streamDataSrc = new StreamDataSource( data, fileName ); 879 attachment.setDataHandler( new DataHandler (streamDataSrc) ); 880 attachment.setDisposition(attachment.ATTACHMENT); 881 attachment.setFileName(fileName); 882 883 ContentAnalyzer analyzer = new ContentAnalyzer(); 884 analyzer.isFor7BitEncoding(streamDataSrc.getInputStream()); 885 String encoding = analyzer.getPreferedEncoding(); 886 if( !streamDataSrc.getContentType().toLowerCase().startsWith("text/") && 887 encoding.equalsIgnoreCase("quoted-printable") ) 888 encoding = "base64"; 889 890 attachment.setHeader("Content-Transfer-Encoding", encoding); 891 892 bodyPartArray.addElement(attachment); 893 } 894 catch(Exception e) { 895 throw SMIMEException.getInstance(this, e, "addAttachment"); 896 } 897 } 898 899 917 public void addAttachment (InputStream data, String fileName, String encoding) throws SMIMEException 918 { 919 MimeBodyPart attachment = new MimeBodyPart (); 920 try { 921 StreamDataSource streamDataSrc = new StreamDataSource( data, fileName ); 922 attachment.setDataHandler( new DataHandler (streamDataSrc) ); 923 attachment.setDisposition(attachment.ATTACHMENT); 924 attachment.setFileName(fileName); 925 926 if( !(encoding.equalsIgnoreCase("7bit") || 927 encoding.equalsIgnoreCase("quoted-printable") || 928 encoding.equalsIgnoreCase("base64")) ) 929 throw new SMIMEException(this, 1036); 930 931 attachment.setHeader("Content-Transfer-Encoding", encoding); 932 933 bodyPartArray.addElement(attachment); 934 } 935 catch(Exception e) { 936 throw SMIMEException.getInstance(this, e, "addAttachment"); 937 } 938 } 939 940 941 956 protected void addRecipient (String recipientAddress, String type, String cerFileName) 957 throws SMIMEException 958 { 959 try { 960 if (!type.equalsIgnoreCase("TO") && !type.equalsIgnoreCase("BCC") && !type.equalsIgnoreCase("CC")) 961 throw new SMIMEException(this, 1042); 962 if (type.equalsIgnoreCase("TO")) { 963 message.addRecipients(MimeMessage.RecipientType.TO, recipientAddress); 964 indicatorTo = true; 965 } 966 else if (type.equalsIgnoreCase("CC")) 967 message.addRecipients(MimeMessage.RecipientType.CC, recipientAddress); 968 else if (type.equalsIgnoreCase("BCC")) 969 message.addRecipients(MimeMessage.RecipientType.BCC, recipientAddress); 970 971 if(cerFileName != null) { 972 X509Certificate cert = null; 973 InputStream inStream = new FileInputStream (cerFileName); 974 CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); 975 cert = (X509Certificate ) cf.generateCertificate(inStream); 976 inStream.close(); 977 978 certArray.addElement(cert); } 980 } 981 catch(Exception e) { 982 throw SMIMEException.getInstance(this, e, "addRecipient"); 983 } 984 } 985 986 987 1005 protected void addRecipient (String recipientAddress, String type, KeyStore kStore, String alias) 1006 throws SMIMEException 1007 { 1008 try { 1009 if (!type.equalsIgnoreCase("TO") && !type.equalsIgnoreCase("BCC") && !type.equalsIgnoreCase("CC")) 1010 throw new SMIMEException(this, 1042); 1011 if (type.equalsIgnoreCase("TO")) { 1012 message.addRecipients(MimeMessage.RecipientType.TO, recipientAddress); 1013 indicatorTo = true; 1014 } 1015 else if (type.equalsIgnoreCase("CC")) 1016 message.addRecipients(MimeMessage.RecipientType.CC, recipientAddress); 1017 else if (type.equalsIgnoreCase("BCC")) 1018 message.addRecipients(MimeMessage.RecipientType.BCC, recipientAddress); 1019 1020 if(kStore != null) { 1021 X509Certificate cert = null; 1022 if (alias != null) 1023 cert = (X509Certificate ) kStore.getCertificate(alias); 1024 else { 1025 X509Certificate [] temp509 = PFXUtils.getCertificateChain(kStore); 1026 if (temp509 != null && temp509.length > 0) 1027 cert = temp509[0]; 1028 else 1029 cert = PFXUtils.getPFXOwnerX509Certificate(kStore); 1030 } 1031 1032 certArray.addElement(cert); } 1034 1035 } 1036 catch(Exception e) { 1037 throw SMIMEException.getInstance(this, e, "addRecipient"); 1038 } 1039 } 1040 1041 1042 1070 protected void addRecipient (String recipientAddress, String type, String ksPath, 1071 String ksType, String password, String alias ) throws SMIMEException 1072 { 1073 try { 1074 char[] paswCh = password.toCharArray(); 1075 File fks = new File (ksPath); 1076 if (! (fks.exists() && fks.isFile())) 1077 throw new SMIMEException(this, 1034); 1078 1079 if (ksPath != null) { 1080 if (ksType == null) this.addRecipient(recipientAddress, type, ksPath); 1082 else { 1083 FileInputStream fis = new FileInputStream (fks); 1084 KeyStore kStore = KeyStore.getInstance(ksType); 1085 kStore.load(fis, paswCh); 1086 fis.close(); 1087 1088 this.addRecipient(recipientAddress, type, kStore, alias); 1089 } 1090 } 1091 else 1092 this.addRecipient(recipientAddress, type, null, null); 1093 } 1094 catch(Exception e) { 1095 throw SMIMEException.getInstance(this, e, "addRecipient"); 1096 } 1097 } 1098 1099 1100 1101 1109 public void setReply (String replyAddress) throws SMIMEException 1110 { 1111 try { 1112 InternetAddress reply[] = new InternetAddress [1]; 1113 reply[0] = new InternetAddress (replyAddress); 1114 message.setReplyTo(reply); 1115 } 1116 catch(Exception e) { 1117 throw SMIMEException.getInstance(this, e, "addRecipient"); 1118 } 1119 } 1120 1121 1125 public MimeMessage getMimeMessage() { 1126 return message; 1127 } 1128 1129 1130 1137 public void reset() { 1138 this.contentPresence = false; 1139 this.externalMessagePresence = false; 1140 this.bodyPartArray.removeAllElements(); 1141 this.certArray .removeAllElements(); 1142 this.indicatorTo = false; 1143 } 1144 1145 1150 public void send() throws MessagingException { 1151 Transport.send(message); 1152 } 1153 1154} 1155 | Popular Tags |