View Javadoc

1   /****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  package org.apache.james.jspf.impl;
21  
22  import org.apache.commons.cli.CommandLine;
23  import org.apache.commons.cli.CommandLineParser;
24  import org.apache.commons.cli.HelpFormatter;
25  import org.apache.commons.cli.OptionBuilder;
26  import org.apache.commons.cli.Options;
27  import org.apache.commons.cli.ParseException;
28  import org.apache.commons.cli.PosixParser;
29  import org.apache.james.jspf.core.exceptions.SPFErrorConstants;
30  import org.apache.james.jspf.executor.SPFResult;
31  import org.apache.log4j.ConsoleAppender;
32  import org.apache.log4j.Level;
33  import org.apache.log4j.Logger;
34  import org.apache.log4j.SimpleLayout;
35  
36  /**
37   * This class is used for commandline usage of JSPF
38   * 
39   */
40  public class SPFQuery {
41  
42      private final static int PASS_RCODE = 0;
43  
44      private final static int FAIL_RCODE = 1;
45  
46      private final static int SOFTFAIL_RCODE = 2;
47  
48      private final static int NEUTRAL_RCODE = 3;
49  
50      private final static int TEMP_ERROR_RCODE = 4;
51  
52      private final static int PERM_ERROR_RCODE = 5;
53  
54      private final static int NONE_RCODE = 6;
55  
56      private final static int UNKNOWN_RCODE = 255;
57  
58      private final static String CMD_IP = "ip";
59      private final static char CHAR_IP = 'i';
60  
61      private final static String CMD_SENDER = "sender";
62      private final static char CHAR_SENDER = 's';
63  
64      private final static String CMD_HELO = "helo";
65      private final static char CHAR_HELO = 'h';
66  
67      private final static String CMD_DEBUG = "debug";
68      private final static char CHAR_DEBUG = 'd';
69  
70      private final static String CMD_VERBOSE = "verbose";
71      private final static char CHAR_VERBOSE = 'v';
72  
73      private final static String CMD_DEFAULT_EXP = "default-explanation";
74      private final static char CHAR_DEFAULT_EXP = 'e';
75  
76      private final static String CMD_BEST_GUESS = "enable-best-guess";
77      private final static char CHAR_BEST_GUESS = 'b';
78      
79      private final static String CMD_TRUSTED_FORWARDER = "enable-trusted-forwarder";
80      private final static char CHAR_TRUSTED_FORWARDER = 't';
81  
82      private static Logger logger = Logger.getRootLogger();
83  
84      /**
85       * @param args
86       *            The commandline arguments to parse
87       */
88      public static void main(String[] args) {
89  
90          String ip = null;
91          String sender = null;
92          String helo = null;
93          String defaultExplanation = null;
94          boolean useBestGuess = false;
95          boolean useTrustedForwarder = false;
96  
97          SimpleLayout layout = new SimpleLayout();
98          ConsoleAppender consoleAppender = new ConsoleAppender(layout);
99          logger.addAppender(consoleAppender);
100 
101         logger.setLevel(Level.ERROR);
102 
103         Options options = generateOptions();
104         CommandLineParser parser = new PosixParser();
105 
106         try {
107             CommandLine line = parser.parse(options, args);
108 
109             ip = line.getOptionValue(CHAR_IP);
110             sender = line.getOptionValue(CHAR_SENDER);
111             helo = line.getOptionValue(CHAR_HELO);
112             defaultExplanation = line.getOptionValue(CHAR_DEFAULT_EXP);
113             useBestGuess = line.hasOption(CHAR_BEST_GUESS);
114             useTrustedForwarder = line.hasOption(CHAR_TRUSTED_FORWARDER);
115             // check if all needed values was set
116             if (ip != null && sender != null && helo != null) {
117 
118                 if (line.hasOption(CHAR_DEBUG))
119                     logger.setLevel(Level.DEBUG);
120                 if (line.hasOption(CHAR_VERBOSE))
121                     logger.setLevel(Level.TRACE);
122 
123                 SPF spf = new DefaultSPF(new Log4JLogger(logger));
124 
125                 // Check if we should set a costum default explanation
126                 if (defaultExplanation != null) {
127                     spf.setDefaultExplanation(defaultExplanation);
128                 }
129 
130                 // Check if we should use best guess
131                 if (useBestGuess == true) {
132                     spf.setUseBestGuess(true);
133                 }
134                 
135                 if (useTrustedForwarder == true) {
136                     spf.setUseTrustedForwarder(true);
137                 }
138 
139                 SPFResult result = spf.checkSPF(ip, sender, helo);
140                 System.out.println(result.getResult());
141                 System.out.println(result.getHeader());
142                 System.exit(getReturnCode(result.getResult()));
143 
144             } else {
145                 usage();
146             }
147         } catch (ParseException e) {
148             usage();
149         }
150     }
151 
152     /**
153      * Return the generated Options
154      * 
155      * @return options
156      */
157     private static Options generateOptions() {
158         Options options = new Options();
159         options.addOption(OptionBuilder
160                 .withLongOpt(CMD_IP)
161                 .withValueSeparator('=')
162                 .withArgName("ip")
163                 .withDescription("Sender IP address")
164                 .isRequired()
165                 .hasArg()
166                 .create(CHAR_IP));
167         options.addOption(OptionBuilder
168                 .withLongOpt(CMD_SENDER)
169                 .withValueSeparator('=')
170                 .withArgName("sender")
171                 .withDescription("Sender address")
172                 .isRequired()
173                 .hasArg()
174                 .create(CHAR_SENDER));
175         options.addOption(OptionBuilder
176                 .withLongOpt(CMD_HELO)
177                 .withValueSeparator('=')
178                 .withArgName("helo")
179                 .withDescription("Helo name")
180                 .isRequired()
181                 .hasArg()
182                 .create(CHAR_HELO));
183         options.addOption(OptionBuilder
184                 .withLongOpt(CMD_DEFAULT_EXP)
185                 .withValueSeparator('=')
186                 .withArgName("expl")
187                 .withDescription("Default explanation")
188                 .hasArg()
189                 .create(CHAR_DEFAULT_EXP));
190         options.addOption(OptionBuilder
191                 .withLongOpt(CMD_BEST_GUESS)
192                 .withArgName("bestguess")
193                 .withDescription("Enable 'best guess' rule")
194                 .create(CHAR_BEST_GUESS));
195         options.addOption(OptionBuilder
196                 .withLongOpt(CMD_TRUSTED_FORWARDER)
197                 .withArgName("trustedfwd")
198                 .withDescription("Enable 'trusted forwarder' rule")
199                 .create(CHAR_TRUSTED_FORWARDER));
200         options.addOption(OptionBuilder
201                 .withLongOpt(CMD_DEBUG)
202                 .withArgName("debug")
203                 .withDescription("Enable debug")
204                 .create(CHAR_DEBUG));
205         options.addOption(OptionBuilder
206                 .withLongOpt(CMD_VERBOSE)
207                 .withArgName("verbose")
208                 .withDescription("Enable verbose mode")
209                 .create(CHAR_VERBOSE));
210         return options;
211     }
212 
213     /**
214      * Print out the usage
215      */
216     private static void usage() {
217         HelpFormatter hf = new HelpFormatter();
218         hf.printHelp("SPFQuery", generateOptions(), true);
219         System.exit(UNKNOWN_RCODE);
220     }
221 
222     /**
223      * Return the return code for the result
224      * 
225      * @param result
226      *            The result
227      * @return returnCode
228      */
229     private static int getReturnCode(String result) {
230 
231         if (result.equals(SPFErrorConstants.PASS_CONV)) {
232             return PASS_RCODE;
233         } else if (result.equals(SPFErrorConstants.FAIL_CONV)) {
234             return FAIL_RCODE;
235         } else if (result.equals(SPFErrorConstants.SOFTFAIL_CONV)) {
236             return SOFTFAIL_RCODE;
237         } else if (result.equals(SPFErrorConstants.NEUTRAL_CONV)) {
238             return NEUTRAL_RCODE;
239         } else if (result.equals(SPFErrorConstants.TEMP_ERROR_CONV)) {
240             return TEMP_ERROR_RCODE;
241         } else if (result.equals(SPFErrorConstants.PERM_ERROR_CONV)) {
242             return PERM_ERROR_RCODE;
243         } else if (result.equals(SPFErrorConstants.NONE_CONV)) {
244             return NONE_RCODE;
245         }
246 
247         return UNKNOWN_RCODE;
248     }
249 
250 }