001: /****************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one *
003: * or more contributor license agreements. See the NOTICE file *
004: * distributed with this work for additional information *
005: * regarding copyright ownership. The ASF licenses this file *
006: * to you under the Apache License, Version 2.0 (the *
007: * "License"); you may not use this file except in compliance *
008: * with the License. You may obtain a copy of the License at *
009: * *
010: * http://www.apache.org/licenses/LICENSE-2.0 *
011: * *
012: * Unless required by applicable law or agreed to in writing, *
013: * software distributed under the License is distributed on an *
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015: * KIND, either express or implied. See the License for the *
016: * specific language governing permissions and limitations *
017: * under the License. *
018: ****************************************************************/package org.apache.james.jspf.impl;
019:
020: import org.apache.commons.cli.CommandLine;
021: import org.apache.commons.cli.CommandLineParser;
022: import org.apache.commons.cli.HelpFormatter;
023: import org.apache.commons.cli.OptionBuilder;
024: import org.apache.commons.cli.Options;
025: import org.apache.commons.cli.ParseException;
026: import org.apache.commons.cli.PosixParser;
027: import org.apache.james.jspf.core.exceptions.SPFErrorConstants;
028: import org.apache.james.jspf.executor.SPFResult;
029: import org.apache.log4j.ConsoleAppender;
030: import org.apache.log4j.Level;
031: import org.apache.log4j.Logger;
032: import org.apache.log4j.SimpleLayout;
033:
034: /**
035: * This class is used for commandline usage of JSPF
036: *
037: */
038: public class SPFQuery {
039:
040: private final static int PASS_RCODE = 0;
041:
042: private final static int FAIL_RCODE = 1;
043:
044: private final static int SOFTFAIL_RCODE = 2;
045:
046: private final static int NEUTRAL_RCODE = 3;
047:
048: private final static int TEMP_ERROR_RCODE = 4;
049:
050: private final static int PERM_ERROR_RCODE = 5;
051:
052: private final static int NONE_RCODE = 6;
053:
054: private final static int UNKNOWN_RCODE = 255;
055:
056: private final static String CMD_IP = "ip";
057: private final static char CHAR_IP = 'i';
058:
059: private final static String CMD_SENDER = "sender";
060: private final static char CHAR_SENDER = 's';
061:
062: private final static String CMD_HELO = "helo";
063: private final static char CHAR_HELO = 'h';
064:
065: private final static String CMD_DEBUG = "debug";
066: private final static char CHAR_DEBUG = 'd';
067:
068: private final static String CMD_VERBOSE = "verbose";
069: private final static char CHAR_VERBOSE = 'v';
070:
071: private final static String CMD_DEFAULT_EXP = "default-explanation";
072: private final static char CHAR_DEFAULT_EXP = 'e';
073:
074: private final static String CMD_BEST_GUESS = "enable-best-guess";
075: private final static char CHAR_BEST_GUESS = 'b';
076:
077: private final static String CMD_TRUSTED_FORWARDER = "enable-trusted-forwarder";
078: private final static char CHAR_TRUSTED_FORWARDER = 't';
079:
080: private static Logger logger = Logger.getRootLogger();
081:
082: /**
083: * @param args
084: * The commandline arguments to parse
085: */
086: public static void main(String[] args) {
087:
088: String ip = null;
089: String sender = null;
090: String helo = null;
091: String defaultExplanation = null;
092: boolean useBestGuess = false;
093: boolean useTrustedForwarder = false;
094:
095: SimpleLayout layout = new SimpleLayout();
096: ConsoleAppender consoleAppender = new ConsoleAppender(layout);
097: logger.addAppender(consoleAppender);
098:
099: logger.setLevel(Level.ERROR);
100:
101: Options options = generateOptions();
102: CommandLineParser parser = new PosixParser();
103:
104: try {
105: CommandLine line = parser.parse(options, args);
106:
107: ip = line.getOptionValue(CHAR_IP);
108: sender = line.getOptionValue(CHAR_SENDER);
109: helo = line.getOptionValue(CHAR_HELO);
110: defaultExplanation = line.getOptionValue(CHAR_DEFAULT_EXP);
111: useBestGuess = line.hasOption(CHAR_BEST_GUESS);
112: useTrustedForwarder = line
113: .hasOption(CHAR_TRUSTED_FORWARDER);
114: // check if all needed values was set
115: if (ip != null && sender != null && helo != null) {
116:
117: if (line.hasOption(CHAR_DEBUG))
118: logger.setLevel(Level.DEBUG);
119: if (line.hasOption(CHAR_VERBOSE))
120: logger.setLevel(Level.TRACE);
121:
122: SPF spf = new DefaultSPF(new Log4JLogger(logger));
123:
124: // Check if we should set a costum default explanation
125: if (defaultExplanation != null) {
126: spf.setDefaultExplanation(defaultExplanation);
127: }
128:
129: // Check if we should use best guess
130: if (useBestGuess == true) {
131: spf.setUseBestGuess(true);
132: }
133:
134: if (useTrustedForwarder == true) {
135: spf.setUseTrustedForwarder(true);
136: }
137:
138: SPFResult result = spf.checkSPF(ip, sender, helo);
139: System.out.println(result.getResult());
140: System.out.println(result.getHeader());
141: System.exit(getReturnCode(result.getResult()));
142:
143: } else {
144: usage();
145: }
146: } catch (ParseException e) {
147: usage();
148: }
149: }
150:
151: /**
152: * Return the generated Options
153: *
154: * @return options
155: */
156: private static Options generateOptions() {
157: Options options = new Options();
158: options.addOption(OptionBuilder.withLongOpt(CMD_IP)
159: .withValueSeparator('=').withArgName("ip")
160: .withDescription("Sender IP address").isRequired()
161: .hasArg().create(CHAR_IP));
162: options.addOption(OptionBuilder.withLongOpt(CMD_SENDER)
163: .withValueSeparator('=').withArgName("sender")
164: .withDescription("Sender address").isRequired()
165: .hasArg().create(CHAR_SENDER));
166: options.addOption(OptionBuilder.withLongOpt(CMD_HELO)
167: .withValueSeparator('=').withArgName("helo")
168: .withDescription("Helo name").isRequired().hasArg()
169: .create(CHAR_HELO));
170: options.addOption(OptionBuilder.withLongOpt(CMD_DEFAULT_EXP)
171: .withValueSeparator('=').withArgName("expl")
172: .withDescription("Default explanation").hasArg()
173: .create(CHAR_DEFAULT_EXP));
174: options.addOption(OptionBuilder.withLongOpt(CMD_BEST_GUESS)
175: .withArgName("bestguess").withDescription(
176: "Enable 'best guess' rule").create(
177: CHAR_BEST_GUESS));
178: options.addOption(OptionBuilder.withLongOpt(
179: CMD_TRUSTED_FORWARDER).withArgName("trustedfwd")
180: .withDescription("Enable 'trusted forwarder' rule")
181: .create(CHAR_TRUSTED_FORWARDER));
182: options.addOption(OptionBuilder.withLongOpt(CMD_DEBUG)
183: .withArgName("debug").withDescription("Enable debug")
184: .create(CHAR_DEBUG));
185: options.addOption(OptionBuilder.withLongOpt(CMD_VERBOSE)
186: .withArgName("verbose").withDescription(
187: "Enable verbose mode").create(CHAR_VERBOSE));
188: return options;
189: }
190:
191: /**
192: * Print out the usage
193: */
194: private static void usage() {
195: HelpFormatter hf = new HelpFormatter();
196: hf.printHelp("SPFQuery", generateOptions(), true);
197: System.exit(UNKNOWN_RCODE);
198: }
199:
200: /**
201: * Return the return code for the result
202: *
203: * @param result
204: * The result
205: * @return returnCode
206: */
207: private static int getReturnCode(String result) {
208:
209: if (result.equals(SPFErrorConstants.PASS_CONV)) {
210: return PASS_RCODE;
211: } else if (result.equals(SPFErrorConstants.FAIL_CONV)) {
212: return FAIL_RCODE;
213: } else if (result.equals(SPFErrorConstants.SOFTFAIL_CONV)) {
214: return SOFTFAIL_RCODE;
215: } else if (result.equals(SPFErrorConstants.NEUTRAL_CONV)) {
216: return NEUTRAL_RCODE;
217: } else if (result.equals(SPFErrorConstants.TEMP_ERROR_CONV)) {
218: return TEMP_ERROR_RCODE;
219: } else if (result.equals(SPFErrorConstants.PERM_ERROR_CONV)) {
220: return PERM_ERROR_RCODE;
221: } else if (result.equals(SPFErrorConstants.NONE_CONV)) {
222: return NONE_RCODE;
223: }
224:
225: return UNKNOWN_RCODE;
226: }
227:
228: }
|