KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > core > model > ca > publisher > GeneralPurposeCustomPublisher


1 /*************************************************************************
2  * *
3  * EJBCA: The OpenSource Certificate Authority *
4  * *
5  * This software is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU Lesser General Public *
7  * License as published by the Free Software Foundation; either *
8  * version 2.1 of the License, or any later version. *
9  * *
10  * See terms of license at gnu.org. *
11  * *
12  *************************************************************************/

13  
14 package org.ejbca.core.model.ca.publisher;
15
16 import java.io.BufferedReader JavaDoc;
17 import java.io.File JavaDoc;
18 import java.io.FileNotFoundException JavaDoc;
19 import java.io.FileOutputStream JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.io.InputStreamReader JavaDoc;
22 import java.security.cert.Certificate JavaDoc;
23 import java.security.cert.CertificateEncodingException JavaDoc;
24 import java.util.Properties JavaDoc;
25
26 import org.apache.log4j.Logger;
27 import org.ejbca.core.ejb.ca.store.CertificateDataBean;
28 import org.ejbca.core.model.InternalResources;
29 import org.ejbca.core.model.log.Admin;
30 import org.ejbca.core.model.ra.ExtendedInformation;
31
32 /**
33  * This class is used for publishing to user defined script or command.
34  *
35  * @version $Id: GeneralPurposeCustomPublisher.java,v 1.5.2.3 2007/04/10 10:42:20 jeklund Exp $
36  */

37 public class GeneralPurposeCustomPublisher implements ICustomPublisher{
38     private static Logger log = Logger.getLogger(GeneralPurposeCustomPublisher.class);
39     private static final InternalResources intres = InternalResources.getInstance();
40
41     public static final String JavaDoc crlExternalCommandPropertyName = "crl.application";
42     public static final String JavaDoc certExternalCommandPropertyName = "cert.application";
43     public static final String JavaDoc revokeExternalCommandPropertyName = "revoke.application";
44     public static final String JavaDoc crlFailOnErrorCodePropertyName = "crl.failOnErrorCode";
45     public static final String JavaDoc certFailOnErrorCodePropertyName = "cert.failOnErrorCode";
46     public static final String JavaDoc revokeFailOnErrorCodePropertyName = "revoke.failOnErrorCode";
47     public static final String JavaDoc crlFailOnStandardErrorPropertyName = "crl.failOnStandardError";
48     public static final String JavaDoc certFailOnStandardErrorPropertyName = "cert.failOnStandardError";
49     public static final String JavaDoc revokeFailOnStandardErrorPropertyName = "revoke.failOnStandardError";
50     
51     private String JavaDoc crlExternalCommandFileName = null;
52     private String JavaDoc certExternalCommandFileName = null;
53     private String JavaDoc revokeExternalCommandFileName = null;
54     private boolean crlFailOnErrorCode = true;
55     private boolean certFailOnErrorCode = true;
56     private boolean revokeFailOnErrorCode = true;
57     private boolean crlFailOnStandardError = true;
58     private boolean certFailOnStandardError = true;
59     private boolean revokeFailOnStandardError = true;
60
61     /**
62      * Creates a new instance of DummyCustomPublisher
63      */

64     public GeneralPurposeCustomPublisher() {}
65
66     /**
67      * Load used properties.
68      * @param properties The properties to load.
69      *
70      * @see org.ejbca.core.model.ca.publisher.ICustomPublisher#init(java.util.Properties)
71      */

72     public void init(Properties JavaDoc properties) {
73         log.debug("Initializing GeneralPurposeCustomPublisher");
74         // Extract system properties
75
if ( properties.getProperty(crlFailOnErrorCodePropertyName) != null ) {
76             crlFailOnErrorCode = properties.getProperty(crlFailOnErrorCodePropertyName).equalsIgnoreCase("true");
77         }
78         if ( properties.getProperty(crlFailOnStandardErrorPropertyName) != null ) {
79             crlFailOnStandardError = properties.getProperty(crlFailOnStandardErrorPropertyName).equalsIgnoreCase("true");
80         }
81         if ( properties.getProperty(crlExternalCommandPropertyName) != null ) {
82             crlExternalCommandFileName = properties.getProperty(crlExternalCommandPropertyName);
83         }
84         if ( properties.getProperty(certFailOnErrorCodePropertyName) != null ) {
85             certFailOnErrorCode = properties.getProperty(certFailOnErrorCodePropertyName).equalsIgnoreCase("true");
86         }
87         if ( properties.getProperty(certFailOnStandardErrorPropertyName) != null ) {
88             certFailOnStandardError = properties.getProperty(certFailOnStandardErrorPropertyName).equalsIgnoreCase("true");
89         }
90         if ( properties.getProperty(certExternalCommandPropertyName) != null ) {
91             certExternalCommandFileName = properties.getProperty(certExternalCommandPropertyName);
92         }
93         if ( properties.getProperty(revokeFailOnErrorCodePropertyName) != null ) {
94             revokeFailOnErrorCode = properties.getProperty(revokeFailOnErrorCodePropertyName).equalsIgnoreCase("true");
95         }
96         if ( properties.getProperty(revokeFailOnStandardErrorPropertyName) != null ) {
97             revokeFailOnStandardError = properties.getProperty(revokeFailOnStandardErrorPropertyName).equalsIgnoreCase("true");
98         }
99         if ( properties.getProperty(revokeExternalCommandPropertyName) != null ) {
100             revokeExternalCommandFileName = properties.getProperty(revokeExternalCommandPropertyName);
101         }
102     } // init
103

104     /**
105      * Writes crtificate to temporary file and executes an external command with the full pathname
106      * of the temporary file as argument. The temporary file is the encoded form of the certificate
107      * e.g. X.509 certificates would be encoded as ASN.1 DER. All parameters but incert are ignored.
108      * @param incert The certificate
109      * @param username The username
110      * @param type The certificate type
111      *
112      * @see org.ejbca.core.model.ca.publisher.ICustomPublisher#storeCertificate(org.ejbca.core.model.log.Admin, java.security.cert.Certificate, java.lang.String, java.lang.String, int, int)
113      */

114     public boolean storeCertificate(Admin admin, Certificate JavaDoc incert, String JavaDoc username, String JavaDoc password, String JavaDoc cafp, int status, int type, long revocationDate, int revocationReason, ExtendedInformation extendedinformation) throws PublisherException {
115         log.debug(">storeCertificate, Storing Certificate for user: " + username);
116         // Don't publish non-active certificates
117
if (status != CertificateDataBean.CERT_ACTIVE) {
118             return true;
119         }
120         // Make sure that an external command was specified
121
if ( certExternalCommandFileName == null ) {
122             String JavaDoc msg = intres.getLocalizedMessage("publisher.errormissingproperty", certExternalCommandPropertyName);
123             log.error(msg);
124             throw new PublisherException(msg);
125         }
126         // Run internal method to create tempfile and run the command
127
try {
128             runWithTempFile(certExternalCommandFileName, incert.getEncoded(), certFailOnErrorCode, certFailOnStandardError, String.valueOf(type));
129         } catch (CertificateEncodingException JavaDoc e) {
130             String JavaDoc msg = intres.getLocalizedMessage("publisher.errorcertconversion");
131             log.error(msg);
132             throw new PublisherException(msg);
133         }
134         return true;
135     } // storeCertificate
136

137     /**
138      * Writes the CRL to a temporary file and executes an external command with the temporary file as argument.
139      * By default, a PublisherException is thrown if the external command returns with an errorlevel or outputs
140      * to stderr.
141      *
142      * @see org.ejbca.core.model.ca.publisher.ICustomPublisher#storeCRL(org.ejbca.core.model.log.Admin, byte[], java.lang.String, int)
143      */

144     public boolean storeCRL(Admin admin, byte[] incrl, String JavaDoc cafp, int number) throws PublisherException {
145         log.debug(">storeCRL, Storing CRL");
146         // Verify initialization
147
if ( crlExternalCommandFileName == null ) {
148             String JavaDoc msg = intres.getLocalizedMessage("publisher.errormissingproperty", crlExternalCommandPropertyName);
149             log.error(msg);
150             throw new PublisherException(msg);
151         }
152         // Run internal method to create tempfile and run the command
153
runWithTempFile(crlExternalCommandFileName, incrl, crlFailOnErrorCode, crlFailOnStandardError, null);
154         return true;
155     }
156
157     /**
158      * Writes crtificate to temporary file and executes an external command with the full pathname
159      * of the temporary file as argument. The temporary file is the encoded form of the certificate
160      * e.g. X.509 certificates would be encoded as ASN.1 DER. All parameters but cert are ignored.
161      * @param cert The certificate
162      *
163      * @see org.ejbca.core.model.ca.publisher.ICustomPublisher#revokeCertificate(org.ejbca.core.model.log.Admin, java.security.cert.Certificate, int)
164      */

165     public void revokeCertificate(Admin admin, Certificate JavaDoc cert, int reason) throws PublisherException {
166         log.debug(">revokeCertificate, Rekoving Certificate");
167         // Verify initialization
168
if ( revokeExternalCommandFileName == null ) {
169             String JavaDoc msg = intres.getLocalizedMessage("publisher.errormissingproperty", revokeExternalCommandPropertyName);
170             log.error(msg);
171             throw new PublisherException(msg);
172         }
173         // Run internal method to create tempfile and run the command
174
try {
175             runWithTempFile(revokeExternalCommandFileName, cert.getEncoded(), revokeFailOnErrorCode, revokeFailOnStandardError, String.valueOf(reason));
176         } catch (CertificateEncodingException JavaDoc e) {
177             String JavaDoc msg = intres.getLocalizedMessage("publisher.errorcertconversion");
178             log.error(msg);
179             throw new PublisherException(msg);
180         }
181     } // revokeCertificate
182

183     /**
184      * Check if the specified external excutable file(s) exist.
185      * @param admin Ignored
186      *
187      * @see org.ejbca.core.model.ca.publisher.ICustomPublisher#testConnection(org.ejbca.core.model.log.Admin)
188      */

189     public void testConnection(Admin admin) throws PublisherConnectionException {
190         log.debug("testConnection, Testing connection");
191         // Test if specified commands exist
192
if ( crlExternalCommandFileName != null ) {
193             if ( !(new File JavaDoc(crlExternalCommandFileName)).exists() ) {
194                 String JavaDoc msg = intres.getLocalizedMessage("publisher.commandnotfound", crlExternalCommandFileName);
195                 log.error(msg);
196                 throw new PublisherConnectionException(msg);
197             }
198         }
199         if ( certExternalCommandFileName != null ) {
200             if ( !(new File JavaDoc(certExternalCommandFileName)).exists() ) {
201                 String JavaDoc msg = intres.getLocalizedMessage("publisher.commandnotfound", certExternalCommandFileName);
202                 log.error(msg);
203                 throw new PublisherConnectionException(msg);
204             }
205         }
206         if ( revokeExternalCommandFileName != null ) {
207             if ( !(new File JavaDoc(revokeExternalCommandFileName)).exists() ) {
208                 String JavaDoc msg = intres.getLocalizedMessage("publisher.commandnotfound", revokeExternalCommandFileName);
209                 log.error(msg);
210                 throw new PublisherConnectionException(msg);
211             }
212         }
213     } // testConnection
214

215     /**
216      * Does nothing.
217      */

218     protected void finalize() throws Throwable JavaDoc {
219         log.debug(">finalize, doing nothing");
220         super.finalize();
221     } // finalize
222

223     /**
224      * Writes a byte-array to a temporary file and executes the given command with the file as argument. The
225      * function will, depending on its parameters, fail if output to standard error from the command was
226      * detected or the command returns with an non-zero exit code.
227      *
228      * @param externalCommand The command to run.
229      * @param bytes The buffer with content to write to the file.
230      * @param failOnCode Determines if the method should fail on a non-zero exit code.
231      * @param failOnOutput Determines if the method should fail on output to standard error.
232      * @param additionalArguments Added to the command after the tempfiles name
233      * @throws PublisherException
234      */

235     private void runWithTempFile(String JavaDoc externalCommand, byte[] bytes, boolean failOnCode, boolean failOnOutput, String JavaDoc additionalArguments) throws PublisherException {
236         // Create temporary file
237
File JavaDoc tempFile = null;
238         FileOutputStream JavaDoc fos = null;
239         try {
240             tempFile = File.createTempFile("GeneralPurposeCustomPublisher", ".tmp");
241             fos = new FileOutputStream JavaDoc(tempFile);
242             fos.write(bytes);
243             //fos.close();
244
} catch (FileNotFoundException JavaDoc e) {
245             String JavaDoc msg = intres.getLocalizedMessage("publisher.errortempfile");
246             log.error(msg, e);
247             throw new PublisherException(msg);
248         } catch (IOException JavaDoc e) {
249             try {
250                 fos.close();
251             } catch (IOException JavaDoc e1) {
252             }
253             tempFile.delete();
254             String JavaDoc msg = intres.getLocalizedMessage("publisher.errortempfile");
255             log.error(msg, e);
256             throw new PublisherException(msg);
257         }
258         // Exec file from properties with the file as an argument
259
String JavaDoc tempFileName = null;
260         try {
261             tempFileName = tempFile.getCanonicalPath();
262             String JavaDoc[] cmdcommand = (externalCommand).split("\\s");
263             String JavaDoc[] cmdargs;
264             if ( additionalArguments == null ) {
265                 String JavaDoc[] cmdargst = { tempFileName };
266                 cmdargs = cmdargst;
267             } else {
268                 String JavaDoc[] cmdargst = { tempFileName, additionalArguments };
269                 cmdargs = cmdargst;
270             }
271             String JavaDoc[] cmdarray = new String JavaDoc[cmdcommand.length+cmdargs.length];
272             System.arraycopy(cmdcommand, 0, cmdarray, 0, cmdcommand.length);
273             System.arraycopy(cmdargs, 0, cmdarray, cmdcommand.length, cmdargs.length);
274             Process JavaDoc externalProcess = Runtime.getRuntime().exec( cmdarray, null, null);
275             //Process externalProcess = Runtime.getRuntime().exec( externalCommand + " " + tempFileName + " " + additionalArguments);
276
BufferedReader JavaDoc stdError = new BufferedReader JavaDoc( new InputStreamReader JavaDoc( externalProcess.getErrorStream() ) );
277             BufferedReader JavaDoc stdInput = new BufferedReader JavaDoc( new InputStreamReader JavaDoc( externalProcess.getInputStream() ) );
278             while ( stdInput.readLine() != null ) { } // Required under win32 to avoid lock
279
String JavaDoc stdErrorOutput = null;
280             // Check errorcode and the external applications output to stderr
281
if ( ((externalProcess.waitFor() != 0) && failOnCode) || (stdError.ready() && failOnOutput )) {
282                 tempFile.delete();
283                 String JavaDoc errTemp = null;
284                 while ( stdError.ready() && (errTemp = stdError.readLine()) != null ) {
285                     if (stdErrorOutput == null) {
286                         stdErrorOutput = errTemp;
287                     } else {
288                         stdErrorOutput += "\n" + errTemp;
289                     }
290                 }
291                 String JavaDoc msg = intres.getLocalizedMessage("publisher.errorexternalapp", externalCommand);
292                 if ( stdErrorOutput != null ) {
293                         msg += " - " + stdErrorOutput + " - "+ tempFileName;
294                 }
295                 log.error(msg);
296                 throw new PublisherException(msg);
297             }
298         } catch (IOException JavaDoc e) {
299             String JavaDoc msg = intres.getLocalizedMessage("publisher.errorexternalapp", externalCommand);
300             log.error(msg, e);
301             throw new PublisherException(msg);
302         } catch (InterruptedException JavaDoc e) {
303             String JavaDoc msg = intres.getLocalizedMessage("publisher.errorexternalapp", externalCommand);
304             log.error(msg, e);
305             throw new PublisherException(msg);
306         } finally {
307             try {
308                 fos.close();
309             } catch (IOException JavaDoc e1) {
310             }
311             // Remove temporary file or schedule for delete if delete fails.
312
if ( !tempFile.delete() ) {
313                 tempFile.deleteOnExit();
314                 log.info( intres.getLocalizedMessage("publisher.errordeletetempfile", tempFileName) );
315             }
316         }
317     } // runWithTempFile
318
} // GeneralPurposeCustomPublisher
319
Popular Tags