001 /**
002 * BdkimUsageExample.java
003 * Copyright (c) 2011, Casey Connor
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or without modification,
007 * are permitted provided that the following conditions are met:
008 *
009 * - Redistributions of source code must retain the above copyright notice, this
010 * list of conditions and the following disclaimer.
011 * - Redistributions in binary form must reproduce the above copyright notice,
012 * this list of conditions and the following disclaimer in the documentation
013 * and/or other materials provided with the distribution.
014 * - Neither the name of Lacinato nor the names of its contributors may be used to
015 * endorse or promote products derived from this software without specific prior
016 * written permission.
017 *
018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
019 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
020 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
021 * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
022 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
023 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
024 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
025 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
026 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027 *
028 * http://lacinato.com/cm/software/emailrelated/bdkim
029 *
030 * This is an example of how to use the BdkimAnalyzer. The main method takes a command-line argument for the path to a raw email message file
031 * (containing all raw RFC-2822 headers and message content). It sends the message to the BDKIM perl server (which must be running and
032 * configured) and prints the results returned from the server to stdout.
033 *
034 * @author Casey Connor -- lacinato.com
035 * @version 1.0
036 */
037
038 package com.lacinato.tools.examples;
039
040 import com.lacinato.tools.bdkim.BdkimAnalyzer;
041 import com.lacinato.tools.bdkim.AuthVerificationException;
042 import com.lacinato.tools.bdkim.BdkimAnalyzer.SignatureResults;
043
044 import java.io.*;
045
046 /**
047 * <a href="http://lacinato.com/cm/software/emailrelated/bdkim">http://lacinato.com/cm/software/emailrelated/bdkim</a>
048 * <p/>
049 * This is a simple example of how to use the BdkimAnalyzer (and perhaps also useful for testing.) See the sourc code
050 * for the details.
051 * <p/>
052 * The main() method takes three command-line arguments:<br/>
053 * - the path to a raw email message file (containing all raw headers and message content, etc)<br/>
054 * - the hostname or IP address of the BDKIM perl server (e.g. "localhost")<br/>
055 * - the port that the BDKIM perl server is using (e.g. 12300)
056 * <p/>
057 * It sends the message over to the BDKIM perl server (which must be configured and running) and
058 * prints the results returned from the server to stdout.
059 * <p/>
060 * For information on the BdkimAnalyzer.SignatureResults object, which contains the results in a
061 * structured form, see documentation for that class.
062 *
063 * @author Casey Connor -- <a href="http://lacinato.com">lacinato.com</a>
064 * @version 1.0
065 */
066 public class BdkimUsageExample
067 {
068 public static void main(String[] args)
069 {
070 // args[0] is filename
071 // args[1] is hostname of BDKIM server (e.g. "localhost")
072 // args[2] is the port of the BDKIM server (e.g. 12300)
073 if (args.length < 3)
074 {
075 System.out.println("supply file name, host, and port!");
076 System.exit(1);
077 }
078
079 // read in the source file:
080 String message_txt = null;
081 try { message_txt = readMessageFile(args[0]); }
082 catch (Exception e) { System.out.println("Got exception opening message file: " + e); System.exit(1); }
083
084 // The lines have to have proper \r\n email message line-endings. You can either ensure proper
085 // line endings in the file itself before it is read in, here in Java (or your custom client), or on the
086 // perl side. We don't need to clean line endings because the deafult config of BdkimAnalyzer and
087 // BDKIM cleans them for us, but this is here in case you need it for testing, etc.
088 // message_txt = cleanLineEndings(message_txt);
089
090 // make a new analyzer instance and configure it (in your program keep this reference around for re-use):
091 BdkimAnalyzer analyzer = new BdkimAnalyzer();
092 analyzer.setHost(args[1]);
093 try { analyzer.setPort(Integer.parseInt(args[2])); }
094 catch (NumberFormatException nfe) { System.out.println("bad port number specified!"); System.exit(1); }
095
096 BdkimAnalyzer.SignatureResults results = null;
097
098 // compute the results (this sends to the BDKIM server):
099 try { results = analyzer.determineDkimStatuses(message_txt); }
100 catch (AuthVerificationException ave)
101 {
102 System.out.println("Got exception when attempting to determineDkimStatuses: " + ave);
103 return;
104 }
105
106 // Use the results:
107
108 System.out.println("Summary result (not recommended for precise use): " + SignatureResults.resultToString(results.getSummaryResult()));
109
110 System.out.println("\ntoString() result is as follows: " + results);
111
112 System.out.println("\nResults per signature:");
113
114 int num_sigs;
115
116 if ((num_sigs = results.getNumberOfSignatures()) == 0)
117 System.out.println("NONE - there were no signatures found in the message.");
118 else
119 {
120 for (int i = 0; i < num_sigs; i++)
121 {
122 System.out.println("-----------");
123 System.out.println("Signature at index " + i + ":");
124 System.out.println("Result: " + SignatureResults.resultToString(results.getResult(i)));
125 System.out.println("Verbose result: " + results.getRawResult(i));
126 System.out.println("Domain: " + results.getDomain(i));
127 System.out.println("Headers signed by signature: " + results.getRawHeaderList(i));
128 // could also fetch getHeaderList for an array form of the same
129 }
130 }
131 }
132
133 /**
134 * Unused in default code above, but provided in case it's useful to you.
135 */
136 @SuppressWarnings("unused")
137 private static String cleanLineEndings(String message_text)
138 {
139 BufferedReader my_bufr = new BufferedReader(new StringReader(message_text));
140
141 String line;
142 StringBuffer outp = new StringBuffer(message_text.length());
143
144 try
145 {
146 while ((line = my_bufr.readLine()) != null)
147 {
148 outp.append(line + "\r\n");
149 }
150 }
151 catch (IOException ioe)
152 {
153 System.out.println("Strange... couldn't fix line endings. Data is corrupt and will not work. IOException: " + ioe);
154 return(outp.toString());
155 }
156
157 return(outp.toString());
158 }
159
160 /**
161 * Read the file in.
162 */
163 private static String readMessageFile(String path) throws FileNotFoundException, IOException
164 {
165 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(path)));
166
167 boolean go = true;
168 byte[] buf = new byte[4096];
169 int read = -1;
170 StringBuffer message_txt = new StringBuffer();
171
172 while (go)
173 {
174 read = bis.read(buf, 0, 4096);
175 if (read > 0) message_txt.append(new String(buf, 0, read));
176 else go = false;
177 }
178
179 bis.close();
180 return(message_txt.toString());
181 }
182 }
|