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