KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > ui > web > protocol > CmpServlet


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.ui.web.protocol;
15
16 import java.io.ByteArrayOutputStream JavaDoc;
17 import java.io.IOException JavaDoc;
18 import java.util.Properties JavaDoc;
19
20 import javax.servlet.ServletConfig JavaDoc;
21 import javax.servlet.ServletException JavaDoc;
22 import javax.servlet.ServletInputStream JavaDoc;
23 import javax.servlet.http.HttpServlet JavaDoc;
24 import javax.servlet.http.HttpServletRequest JavaDoc;
25 import javax.servlet.http.HttpServletResponse JavaDoc;
26
27 import org.apache.commons.lang.StringUtils;
28 import org.apache.log4j.Logger;
29 import org.ejbca.core.ejb.ServiceLocator;
30 import org.ejbca.core.model.InternalResources;
31 import org.ejbca.core.model.log.Admin;
32 import org.ejbca.core.protocol.IResponseMessage;
33 import org.ejbca.core.protocol.cmp.CmpMessageDispatcher;
34 import org.ejbca.ui.web.RequestHelper;
35 import org.ejbca.ui.web.pub.ServletUtils;
36 import org.ejbca.util.Base64;
37
38
39 /**
40  * Servlet implementing server side of the Certificate Management Protocols (CMP)
41  *
42  * @author tomas
43  * @version $Id: CmpServlet.java,v 1.18 2007/01/03 14:34:12 anatom Exp $
44  *
45  * @web.servlet name = "CmpServlet"
46  * display-name = "CmpServlet"
47  * description="Used to handle CMP (RFC4210) protocol messages"
48  * load-on-startup = "99"
49  *
50  * @web.servlet-mapping url-pattern = "/cmp"
51  *
52  * @web.env-entry description="Allow the client/RA to specify that the CA should not verify POP, set to true to allow no POP (raVerify in the rfc). Default false."
53  * name="allowRaVerifyPopo"
54  * type="java.lang.String"
55  * value="${cmp.allowraverifypopo}"
56  *
57  * @web.env-entry description="Enforce a particual CA instead of taking it from the request. Default empty."
58  * name="defaultCA"
59  * type="java.lang.String"
60  * value="${cmp.defaultca}"
61  *
62  * @web.env-entry description="Defines which component from the DN should be used to look up username in EJBCA. Can be CN, UID or nothing. Nothing means that the DN will be used to look up the user. Default empty."
63  * name="extractUsernameComponent"
64  * type="java.lang.String"
65  * value="${cmp.extractusernamecomponent}"
66  *
67  * @web.env-entry description="If the CMP service should work in 'normal' or 'ra' mode (see docs). Default normal (or empty value means the same)."
68  * name="operationMode"
69  * type="java.lang.String"
70  * value="${cmp.operationmode}"
71  *
72  * @web.env-entry description="Which sort of protection the response messages will have. Default signature."
73  * name="responseProtection"
74  * type="java.lang.String"
75  * value="${cmp.responseprotection}"
76  *
77  * @web.env-entry description="Shared secret between the CA and the RA used to authenticate valid RA messages. Default empty."
78  * name="raAuthenticationSecret"
79  * type="java.lang.String"
80  * value="${cmp.ra.authenticationsecret}"
81  *
82  * @web.env-entry description="Which generation scheme should be used, RANDOM or DN. Default DN."
83  * name="raModeNameGenerationScheme"
84  * type="java.lang.String"
85  * value="${cmp.ra.namegenerationscheme}"
86  *
87  * @web.env-entry description="Parameters for name generation, for DN it can be CN or UID. Default CN."
88  * name="raModeNameGenerationParameters"
89  * type="java.lang.String"
90  * value="${cmp.ra.namegenerationparameters}"
91  *
92  * @web.env-entry description="Prefix to generated name, a string that can contain the markup ${RANDOM} to inser random chars. Default empty."
93  * name="raModeNameGenerationPrefix"
94  * type="java.lang.String"
95  * value="${cmp.ra.namegenerationprefix}"
96  *
97  * @web.env-entry description="Postfix to generated name, a string that can contain the markup ${RANDOM} to inser random chars. Default empty."
98  * name="raModeNameGenerationPostfix"
99  * type="java.lang.String"
100  * value="${cmp.ra.namegenerationpostfix}"
101  *
102  * @web.env-entry description="The endEntityProfile to be used when adding users in RA mode. Default EMPTY."
103  * name="endEntityProfile"
104  * type="java.lang.String"
105  * value="${cmp.ra.endentityprofile}"
106  *
107  * @web.env-entry description="The certificateProfile to be used when adding users in RA mode. Default ENDUSER."
108  * name="certificateProfile"
109  * type="java.lang.String"
110  * value="${cmp.ra.certificateprofile}"
111  *
112  * @web.env-entry description="The CA to be used when adding users in RA mode. Default AdminCA1."
113  * name="caName"
114  * type="java.lang.String"
115  * value="${cmp.ra.caname}"
116  *
117  * @web.ejb-local-ref
118  * name="ejb/SignSessionLocal"
119  * type="Session"
120  * link="RSASignSession"
121  * home="org.ejbca.core.ejb.ca.sign.ISignSessionLocalHome"
122  * local="org.ejbca.core.ejb.ca.sign.ISignSessionLocal"
123  *
124  * @web.ejb-local-ref
125  * name="ejb/UserAdminSessionLocal"
126  * type="Session"
127  * link="UserAdminSession"
128  * home="org.ejbca.core.ejb.ra.IUserAdminSessionLocalHome"
129  * local="org.ejbca.core.ejb.ra.IUserAdminSessionLocal"
130  *
131  * @web.ejb-local-ref
132  * name="ejb/CAAdminSessionLocal"
133  * type="Session"
134  * link="CAAdminSession"
135  * home="org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionLocalHome"
136  * local="org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionLocal"
137  *
138  * @web.ejb-local-ref
139  * name="ejb/CertificateStoreSessionLocal"
140  * type="Session"
141  * link="CertificateStoreSession"
142  * home="org.ejbca.core.ejb.ca.store.ICertificateStoreSessionLocalHome"
143  * local="org.ejbca.core.ejb.ca.store.ICertificateStoreSessionLocal"
144  *
145  */

146 public class CmpServlet extends HttpServlet JavaDoc {
147     private static final Logger log = Logger.getLogger(CmpServlet.class);
148     /** Internal localization of logs and errors */
149     private static final InternalResources intres = InternalResources.getInstance();
150     
151     private Properties JavaDoc properties;
152     /**
153      * Inits the CMP servlet
154      *
155      * @param config servlet configuration
156      *
157      * @throws ServletException on error during initialization
158      */

159     public void init(ServletConfig JavaDoc config) throws ServletException JavaDoc {
160         super.init(config);
161         properties = new Properties JavaDoc();
162         String JavaDoc str = ServiceLocator.getInstance().getString("java:comp/env/allowRaVerifyPopo");
163         if (StringUtils.equals("true", str)) {
164             log.debug("allowRAVerifyPopo=true");
165             properties.setProperty("allowRaVerifyPopo", "true");
166         }
167         str = ServiceLocator.getInstance().getString("java:comp/env/defaultCA");
168         log.debug("defaultCA="+str);
169         if (StringUtils.isNotEmpty(str)) {
170             properties.setProperty("defaultCA", str);
171         }
172         str = ServiceLocator.getInstance().getString("java:comp/env/extractUsernameComponent");
173         log.debug("extractUsernameComponent="+str);
174         if (StringUtils.isNotEmpty(str)) {
175             properties.setProperty("extractUsernameComponent", str);
176         }
177         str = ServiceLocator.getInstance().getString("java:comp/env/operationMode");
178         log.debug("operationMode="+str);
179         if (StringUtils.isNotEmpty(str)) {
180             properties.setProperty("operationMode", str);
181         }
182         str = ServiceLocator.getInstance().getString("java:comp/env/raModeNameGenerationScheme");
183         log.debug("raModeNameGenerationScheme="+str);
184         if (StringUtils.isNotEmpty(str)) {
185             properties.setProperty("raModeNameGenerationScheme", str);
186         }
187         str = ServiceLocator.getInstance().getString("java:comp/env/raModeNameGenerationParameters");
188         log.debug("raModeNameGenerationParameters="+str);
189         if (StringUtils.isNotEmpty(str)) {
190             properties.setProperty("raModeNameGenerationParameters", str);
191         }
192         str = ServiceLocator.getInstance().getString("java:comp/env/raModeNameGenerationPrefix");
193         log.debug("raModeNameGenerationPrefix="+str);
194         if (StringUtils.isNotEmpty(str)) {
195             properties.setProperty("raModeNameGenerationPrefix", str);
196         }
197         str = ServiceLocator.getInstance().getString("java:comp/env/raModeNameGenerationPostfix");
198         log.debug("raModeNameGenerationPostfix="+str);
199         if (StringUtils.isNotEmpty(str)) {
200             properties.setProperty("raModeNameGenerationPostfix", str);
201         }
202         str = ServiceLocator.getInstance().getString("java:comp/env/responseProtection");
203         if (StringUtils.isNotEmpty(str)) {
204             log.debug("responseProtection="+str);
205             properties.setProperty("responseProtection", str);
206         }
207         str = ServiceLocator.getInstance().getString("java:comp/env/raAuthenticationSecret");
208         if (StringUtils.isNotEmpty(str)) {
209             log.debug("raAuthenticationSecret is not null");
210             properties.setProperty("raAuthenticationSecret", str);
211         }
212         str = ServiceLocator.getInstance().getString("java:comp/env/endEntityProfile");
213         if (StringUtils.isNotEmpty(str)) {
214             log.debug("endEntityProfile="+str);
215             properties.setProperty("endEntityProfile", str);
216         }
217         str = ServiceLocator.getInstance().getString("java:comp/env/certificateProfile");
218         if (StringUtils.isNotEmpty(str)) {
219             log.debug("certificateProfile="+str);
220             properties.setProperty("certificateProfile", str);
221         }
222         str = ServiceLocator.getInstance().getString("java:comp/env/caName");
223         if (StringUtils.isNotEmpty(str)) {
224             log.debug("caName="+str);
225             properties.setProperty("caName", str);
226         }
227     }
228     
229     /**
230      * Handles HTTP post
231      *
232      * @param request java standard arg
233      * @param response java standard arg
234      *
235      * @throws IOException input/output error
236      * @throws ServletException if the post could not be handled
237      */

238     public void doPost(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
239     throws IOException JavaDoc, ServletException JavaDoc {
240         log.debug(">doPost()");
241         /*
242          POST
243          <binary CMP message>
244          */

245         ServletInputStream JavaDoc sin = request.getInputStream();
246         // This small code snippet is inspired/copied from apache IO utils by Tomas Gustavsson...
247
ByteArrayOutputStream JavaDoc output = new ByteArrayOutputStream JavaDoc();
248         byte[] buf = new byte[1024];
249         int n = 0;
250         while (-1 != (n = sin.read(buf))) {
251             output.write(buf, 0, n);
252         }
253         service(output.toByteArray(), request.getRemoteAddr(), response);
254         log.debug("<doPost()");
255     } //doPost
256

257     /**
258      * Handles HTTP get
259      *
260      * @param request java standard arg
261      * @param response java standard arg
262      *
263      * @throws IOException input/output error
264      * @throws ServletException if the post could not be handled
265      */

266     public void doGet(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
267     throws java.io.IOException JavaDoc, ServletException JavaDoc {
268         log.debug(">doGet()");
269         
270         log.info("Received un-allowed method GET in CMP servlet: query string=" + request.getQueryString());
271         response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "You can only use POST!");
272         
273         log.debug("<doGet()");
274     } // doGet
275

276     private void service(byte[] message, String JavaDoc remoteAddr, HttpServletResponse JavaDoc response) throws IOException JavaDoc {
277         try {
278             if ((message == null)) {
279                 log.error("Got request missing message.");
280                 response.sendError(HttpServletResponse.SC_BAD_REQUEST, "A message must be supplied!");
281                 return;
282             }
283             
284             // We must use an administrator with rights to create users
285
Admin administrator = new Admin(Admin.TYPE_RA_USER, remoteAddr);
286             if (log.isDebugEnabled()) {
287                 log.debug("Received a CMP message by HTTP: " + new String JavaDoc(Base64.encode(message)));
288             }
289             String JavaDoc iMsg = intres.getLocalizedMessage("cmp.receivedmsg", remoteAddr);
290             log.info(iMsg);
291             CmpMessageDispatcher dispatcher = new CmpMessageDispatcher(administrator, properties);
292             IResponseMessage resp = dispatcher.dispatch(message);
293             // If resp is null, it means we have nothing to send back
294
if (resp != null) {
295                 // Add no-cache headers as defined in draft-ietf-pkix-cmp-transport-protocols-05.txt
296
ServletUtils.addCacheHeaders(response);
297                 // Send back CMP response
298
RequestHelper.sendBinaryBytes(resp.getResponseMessage(), response, "application/pkixcmp", null);
299                 iMsg = intres.getLocalizedMessage("cmp.sentresponsemsg", remoteAddr);
300                 log.info(iMsg);
301             }
302         } catch (Exception JavaDoc e) {
303             log.error("Error in CmpServlet:", e);
304             response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
305         }
306     }
307     
308 } // ScepServlet
309
Popular Tags