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 ****************************************************************/ 019 020 package org.apache.james.jspf.impl; 021 022 import org.apache.commons.cli.CommandLine; 023 import org.apache.commons.cli.CommandLineParser; 024 import org.apache.commons.cli.HelpFormatter; 025 import org.apache.commons.cli.OptionBuilder; 026 import org.apache.commons.cli.Options; 027 import org.apache.commons.cli.ParseException; 028 import org.apache.commons.cli.PosixParser; 029 import org.apache.james.jspf.core.exceptions.SPFErrorConstants; 030 import org.apache.james.jspf.executor.SPFResult; 031 import org.apache.log4j.ConsoleAppender; 032 import org.apache.log4j.Level; 033 import org.apache.log4j.Logger; 034 import org.apache.log4j.SimpleLayout; 035 036 /** 037 * This class is used for commandline usage of JSPF 038 * 039 */ 040 public class SPFQuery { 041 042 private final static int PASS_RCODE = 0; 043 044 private final static int FAIL_RCODE = 1; 045 046 private final static int SOFTFAIL_RCODE = 2; 047 048 private final static int NEUTRAL_RCODE = 3; 049 050 private final static int TEMP_ERROR_RCODE = 4; 051 052 private final static int PERM_ERROR_RCODE = 5; 053 054 private final static int NONE_RCODE = 6; 055 056 private final static int UNKNOWN_RCODE = 255; 057 058 private final static String CMD_IP = "ip"; 059 private final static char CHAR_IP = 'i'; 060 061 private final static String CMD_SENDER = "sender"; 062 private final static char CHAR_SENDER = 's'; 063 064 private final static String CMD_HELO = "helo"; 065 private final static char CHAR_HELO = 'h'; 066 067 private final static String CMD_DEBUG = "debug"; 068 private final static char CHAR_DEBUG = 'd'; 069 070 private final static String CMD_VERBOSE = "verbose"; 071 private final static char CHAR_VERBOSE = 'v'; 072 073 private final static String CMD_DEFAULT_EXP = "default-explanation"; 074 private final static char CHAR_DEFAULT_EXP = 'e'; 075 076 private final static String CMD_BEST_GUESS = "enable-best-guess"; 077 private final static char CHAR_BEST_GUESS = 'b'; 078 079 private final static String CMD_TRUSTED_FORWARDER = "enable-trusted-forwarder"; 080 private final static char CHAR_TRUSTED_FORWARDER = 't'; 081 082 private static Logger logger = Logger.getRootLogger(); 083 084 /** 085 * @param args 086 * The commandline arguments to parse 087 */ 088 public static void main(String[] args) { 089 090 String ip = null; 091 String sender = null; 092 String helo = null; 093 String defaultExplanation = null; 094 boolean useBestGuess = false; 095 boolean useTrustedForwarder = false; 096 097 SimpleLayout layout = new SimpleLayout(); 098 ConsoleAppender consoleAppender = new ConsoleAppender(layout); 099 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 160 OptionBuilder.withLongOpt(CMD_IP); 161 OptionBuilder.withValueSeparator('='); 162 OptionBuilder.withArgName("ip"); 163 OptionBuilder.withDescription("Sender IP address"); 164 OptionBuilder.isRequired(); 165 OptionBuilder.hasArg(); 166 options.addOption(OptionBuilder.create(CHAR_IP)); 167 168 169 OptionBuilder.withLongOpt(CMD_SENDER); 170 OptionBuilder.withValueSeparator('='); 171 OptionBuilder.withArgName("sender"); 172 OptionBuilder.withDescription("Sender address"); 173 OptionBuilder.isRequired(); 174 OptionBuilder.hasArg(); 175 options.addOption(OptionBuilder.create(CHAR_SENDER)); 176 177 OptionBuilder.withLongOpt(CMD_HELO); 178 OptionBuilder.withValueSeparator('='); 179 OptionBuilder.withArgName("helo"); 180 OptionBuilder.withDescription("Helo name"); 181 OptionBuilder.isRequired(); 182 OptionBuilder.hasArg(); 183 options.addOption(OptionBuilder.create(CHAR_HELO)); 184 185 OptionBuilder.withLongOpt(CMD_DEFAULT_EXP); 186 OptionBuilder.withValueSeparator('='); 187 OptionBuilder.withArgName("expl"); 188 OptionBuilder.withDescription("Default explanation"); 189 OptionBuilder.hasArg(); 190 options.addOption(OptionBuilder.create(CHAR_DEFAULT_EXP)); 191 192 OptionBuilder.withLongOpt(CMD_BEST_GUESS); 193 OptionBuilder.withArgName("bestguess"); 194 OptionBuilder.withDescription("Enable 'best guess' rule"); 195 options.addOption(OptionBuilder.create(CHAR_BEST_GUESS)); 196 197 OptionBuilder.withLongOpt(CMD_TRUSTED_FORWARDER); 198 OptionBuilder.withArgName("trustedfwd"); 199 OptionBuilder.withDescription("Enable 'trusted forwarder' rule"); 200 options.addOption(OptionBuilder.create(CHAR_TRUSTED_FORWARDER)); 201 202 OptionBuilder.withLongOpt(CMD_DEBUG); 203 OptionBuilder.withArgName("debug"); 204 OptionBuilder.withDescription("Enable debug"); 205 options.addOption(OptionBuilder.create(CHAR_DEBUG)); 206 207 OptionBuilder.withLongOpt(CMD_VERBOSE); 208 OptionBuilder.withArgName("verbose"); 209 OptionBuilder.withDescription("Enable verbose mode"); 210 options.addOption(OptionBuilder.create(CHAR_VERBOSE)); 211 212 return options; 213 } 214 215 /** 216 * Print out the usage 217 */ 218 private static void usage() { 219 HelpFormatter hf = new HelpFormatter(); 220 hf.printHelp("SPFQuery", generateOptions(), true); 221 System.exit(UNKNOWN_RCODE); 222 } 223 224 /** 225 * Return the return code for the result 226 * 227 * @param result 228 * The result 229 * @return returnCode 230 */ 231 private static int getReturnCode(String result) { 232 233 if (result.equals(SPFErrorConstants.PASS_CONV)) { 234 return PASS_RCODE; 235 } else if (result.equals(SPFErrorConstants.FAIL_CONV)) { 236 return FAIL_RCODE; 237 } else if (result.equals(SPFErrorConstants.SOFTFAIL_CONV)) { 238 return SOFTFAIL_RCODE; 239 } else if (result.equals(SPFErrorConstants.NEUTRAL_CONV)) { 240 return NEUTRAL_RCODE; 241 } else if (result.equals(SPFErrorConstants.TEMP_ERROR_CONV)) { 242 return TEMP_ERROR_RCODE; 243 } else if (result.equals(SPFErrorConstants.PERM_ERROR_CONV)) { 244 return PERM_ERROR_RCODE; 245 } else if (result.equals(SPFErrorConstants.NONE_CONV)) { 246 return NONE_RCODE; 247 } 248 249 return UNKNOWN_RCODE; 250 } 251 252 }