View Javadoc

1   /*
2    * AbstractWebCommand.java
3    *
4    * Created on November 4, 2004, 10:07 AM
5    */
6   package gov.bnl.gums.command;
7   
8   import gov.bnl.gums.admin.*;
9   import gov.bnl.gums.util.CertToolkit;
10  
11  import java.security.cert.X509Certificate;
12  import java.net.ConnectException;
13  
14  import javax.net.ssl.X509KeyManager;
15  
16  import org.apache.axis.AxisFault;
17  import org.apache.commons.cli.*;
18  import org.apache.log4j.Logger;
19  
20  import org.glite.security.trustmanager.ContextWrapper;
21  
22  /**
23   * Class to provide general command line utilities such as
24   * argument parsing and authentication
25   * 
26   * @author Gabriele Carcassi, Jay Packard
27   */
28  public abstract class AbstractCommand {
29  	static protected AbstractCommand command;
30  
31  	/*static {
32  		String vomsdir;
33  		Logger.getLogger(org.glite.security.trustmanager.CRLFileTrustManager.class.getName()).setLevel(Level.ERROR);
34  		Logger.getLogger("org.glite.security.trustmanager.axis.AXISSocketFactory").setLevel(Level.OFF);
35  		Logger.getLogger("org.glite.security.util.DirectoryList").setLevel(Level.OFF);
36  		VOMSValidator.setTrustStore(new BasicVOMSTrustStore(System.getProperty("sslCAFiles"), 12*3600*1000));
37  	}*/
38  	
39      static public void main(String[] args) {
40          command.execute(args);
41      }
42      
43  	private Logger log = Logger.getLogger(AbstractCommand.class);
44      private String clientDN;
45      private boolean usingProxy;
46      protected String commandName;
47      protected String syntax;
48      protected String description;
49      protected boolean failOnArguments;
50      
51      /**
52       * Creates a new AbstractWebCommand object.
53       */
54      public AbstractCommand() {
55          String className = getClass().getName();
56  
57          commandName = CommandLineToolkit.getCommandName(className);
58      }
59      
60      /**
61       * Extracting the client DN
62       */
63      private void initClientCred() {
64          // If DN is already found, no need to find it again...
65          if (clientDN != null) return;
66          
67          log.trace("Retrieving client credentials");
68          
69          try {
70              ContextWrapper wrapper = new ContextWrapper(System.getProperties());
71              X509KeyManager manager = wrapper.getKeyManager();
72              String[] aliases = manager.getClientAliases("RSA", null);
73              
74              if ((aliases == null) || (aliases.length == 0)) {
75                  System.err.println("\nThe user credentials loading failed");
76                  System.exit(-1);
77              }
78              
79              X509Certificate[] chain = manager.getCertificateChain(aliases[0]);
80              
81              X509Certificate cert = chain[0];
82              log.trace("Certificate retrieved: " + cert);
83              clientDN = CertToolkit.getUserDN(cert);
84              String commaDN = cert.getSubjectX500Principal().toString();
85              String certDN = CertToolkit.convertDN(commaDN);
86              log.trace("Certificate subject: " + certDN);
87              log.trace("Client DN: " + clientDN);
88              if (!clientDN.equals(certDN)) {
89                  log.trace("Using proxy");
90                  usingProxy = true;
91              } else {
92                  log.trace("Not using proxy");
93                  usingProxy = false;
94              }
95          } catch (Exception e) {
96              log.error("Couldn't retrieve client credentials", e);
97              return;
98          }
99      }
100     
101     protected abstract Options buildOptions();
102 
103     protected abstract void execute(CommandLine cmd) throws Exception;
104 
105     @SuppressWarnings("static-access")
106 	protected void execute(String[] args) {
107         Options options = buildOptions();
108         Option help = OptionBuilder.withLongOpt("help")
109                                    .withDescription("print this message")
110                                    .create();
111 
112         //new Option("?", "help",false,"print this message");
113         options.addOption(help);
114 
115         CommandLine cmd = parse(options, args);
116 
117         try {
118             execute(cmd);
119         } catch (AxisFault e) {
120             if (e.getCause() != null) {
121                 log.info("An error ocurred when connecting to GUMS", e);
122 
123                 if (e.getCause() instanceof ConnectException) {
124                     System.err.println(
125                         "Couldn't connect to the GUMS server. " +
126                         "Check that your gums-client.properties configuration is pointing to the correct server, " +
127                         "that there are no firewall or network problem, and that the server is up.");
128                     System.err.println(
129                         "[Error message: " +
130                         e.getCause().getMessage() + "]");
131                 } else if (e.getCause() instanceof java.security.cert.CertificateExpiredException) {
132                     System.err.println("Please renew your proxy, or renew your certificate if expired.");
133                     System.err.println(
134                         "[Error message: " +
135                         e.getCause().getMessage() + "]");
136                 } else if ((e.getCause() instanceof java.security.cert.CertificateException) && 
137                            (e.getCause().getMessage().indexOf("(No such file or directory)") != -1) &&
138                            (e.getCause().getMessage().indexOf("/tmp/x509up_u") != -1)) {
139                     System.err.println("Couldn't find your proxy: please generate your proxy");
140                     System.err.println(
141                         "[Error message: " +
142                         e.getCause().getMessage() + "]");
143                 } else if ((e.getCause() instanceof java.security.cert.CertificateException) &&
144                            (e.getCause().getMessage().indexOf("(Permission denied)") != -1) &&
145                            (e.getCause().getMessage().indexOf("key.pem") != -1)) {
146                     System.err.println("Couldn't read the private key: check that you are running as the correct user and check private key file ownership");
147                     System.err.println(
148                         "[Error message: " +
149                         e.getCause().getMessage() + "]");
150                 } else {
151                     System.err.println(
152                         "An error occurred when connecting to GUMS: " +
153                         e.getCause().getMessage());
154                 }
155                 
156             } else {
157                 if (e.getFaultString().indexOf("(0)null") != -1) {
158                     System.err.println("There was a problem connecting to the GUMS server.");
159                     System.err.println("Try using an old-style proxy (i.e. 'grid-proxy-init -old').");
160                     System.err.println(
161                         "[Error message: " +
162                         e.getMessage() + "]");
163                 } else {
164                     System.err.println(
165                         "An error occurred when connecting to GUMS: " +
166                         e.getMessage());
167                     log.info("An error occurred when connecting to GUMS", e);
168                 }
169             }
170             System.exit(-1);
171         } catch (Exception e) {
172             System.out.println("Unexpected error: " + e.getMessage());
173             System.out.println("Full stack trace follows (give it to support):");
174             System.out.println("-------------------------");
175             e.printStackTrace(System.out);
176             log.error("Unexpected error", e);
177             System.exit(-1);
178         }
179     }
180 
181     protected void failForWrongParameters(String message) {
182         System.out.println(message);
183         System.out.println("Try `gums " + commandName +
184             " --help' for more information.");
185         System.exit(-1);
186     }
187 
188     protected String getClientDN() {
189         initClientCred();
190         return clientDN;
191     }
192 
193     protected abstract GUMSAPI getGums(String gumsUrl);
194     
195     protected boolean isUsingProxy() {
196         initClientCred();
197         return usingProxy;
198     }
199 
200     protected CommandLine parse(Options options, String[] args) {
201         CommandLineParser parser = new BasicParser();
202         CommandLine commands = null;
203 
204         try {
205             commands = parser.parse(options, args);
206 
207             if (commands.hasOption("help")) {
208                 printHelp(options);
209                 System.exit(0);
210             }
211 
212             if (failOnArguments && (commands.getArgs() != null) &&
213                     (commands.getArgs().length > 0)) {
214                 System.out.println("The command doesn't accept arguments");
215                 printHelp(options);
216                 System.exit(-1);
217             }
218         } catch (UnrecognizedOptionException e) {
219             System.out.println(e.getMessage());
220             printHelp(options);
221             log.debug("Bogus option", e);
222             System.exit(-1);
223         } catch (ParseException pe) {
224             System.out.println("Command line error:" + pe.getMessage());
225             printHelp(options);
226             log.info("Command line error", pe);
227             System.exit(-1);
228         }
229 
230         return commands;
231     }
232 
233     protected void printHelp(Options options) {
234         HelpFormatter formatter = new HelpFormatter();
235 
236         formatter.printHelp("gums " + commandName + " " + syntax,
237             description + "\n\nOptions:", options, "");
238     }
239 }