/** * */ package at.knowcenter.wag.egov.egiz.web.servlets; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Properties; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import at.gv.egiz.pdfas.exceptions.framework.SignatorException; import at.gv.egiz.pdfas.framework.SignatorFactory; import at.gv.egiz.pdfas.framework.signator.Signator; import at.gv.egiz.pdfas.web.SignSessionInformation; import at.gv.egiz.pdfas.web.VerifySessionInformation; import at.gv.egiz.pdfas.web.helper.SessionHelper; import at.gv.egiz.pdfas.web.helper.SignServletHelper; import at.gv.egiz.pdfas.web.helper.TempDirHelper; import at.knowcenter.wag.egov.egiz.PdfASID; import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; import at.knowcenter.wag.egov.egiz.exceptions.InvalidIDException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; import at.knowcenter.wag.egov.egiz.exceptions.SignatorFactoryException; import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; import at.knowcenter.wag.egov.egiz.sig.SignatureResponse; import at.knowcenter.wag.egov.egiz.sig.connectors.ConnectorChooser; import at.knowcenter.wag.egov.egiz.sig.connectors.LocalConnector; import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection; import at.knowcenter.wag.egov.egiz.web.FormFields; import at.knowcenter.wag.egov.egiz.web.LocalRequest; import at.knowcenter.wag.egov.egiz.web.LocalRequestHelper; import at.knowcenter.wag.egov.egiz.web.SessionAttributes; /** * @author wprinz * */ public class DataURLServlet extends HttpServlet { /** * SVUID. */ private static final long serialVersionUID = -5846618335843762752L; /** * The log. */ private static Log log = LogFactory.getLog(DataURLServlet.class); protected void dispatch(HttpServletRequest request, HttpServletResponse response, String resource) throws ServletException, IOException { dispatch(request, response, resource, getServletContext()); } protected static void dispatch(HttpServletRequest request, HttpServletResponse response, String resource, ServletContext context) throws ServletException, IOException { response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); RequestDispatcher disp = context.getRequestDispatcher(resource); disp.forward(request, response); } protected void dispatchToResults(List results, HttpServletRequest request, HttpServletResponse response, String backToListURL) throws ServletException, IOException { request.setAttribute("results", results); request.setAttribute("btlurl", backToListURL); dispatch(request, response, "/jsp/results.jsp"); } protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } private static void temporaryRedirect(String redirectURL, HttpServletResponse response) throws IOException { String encodedRedirect = response.encodeRedirectURL(redirectURL); response.addHeader("Location", encodedRedirect); response.setContentType("text/xml"); response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT); String nop = ""; PrintWriter pw = response.getWriter(); response.setCharacterEncoding("UTF-8"); response.setContentLength(nop.getBytes("UTF-8").length); log.debug("Redirecting via NullOperationRequest to " + encodedRedirect + "."); pw.println(nop); pw.flush(); pw.close(); } /** * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { log.debug("Data URL is accessed."); //$NON-NLS-1$ try { Object sessionObject = SessionHelper.getSession(request); checkRequestCharacterEncoding(request); if (sessionObject instanceof SignSessionInformation) { SignSessionInformation si = (SignSessionInformation)sessionObject; processSign(request, response, si); } else { VerifySessionInformation si = (VerifySessionInformation) sessionObject; processVerify(request, response, si); } } catch (PresentableException e) { log.error(e); SignServlet.prepareDispatchToErrorPage(e, request); dispatch(request, response, "/jsp/error.jsp"); } log.debug("DataURL access finished."); //$NON-NLS-1$ } protected void checkRequestCharacterEncoding(HttpServletRequest request) throws UnsupportedEncodingException { log.debug("Request character encoding = " + request.getCharacterEncoding()); //$NON-NLS-1$ // if (request.getCharacterEncoding() == null || request.getCharacterEncoding().equals("UTF-8")) //$NON-NLS-1$ if (request.getCharacterEncoding() == null || request.getCharacterEncoding().length() <= 0) //$NON-NLS-1$ { log.error("The BKU didn't set a character encoding for the request."); //$NON-NLS-1$ log.warn("Manually setting character encoding to UTF-8"); //$NON-NLS-1$ request.setCharacterEncoding("UTF-8"); //$NON-NLS-1$ } } protected boolean isNullResponse(String xml_response) { return xml_response.indexOf("NullOperationResponse") >= 0; } protected void processSign(HttpServletRequest request, HttpServletResponse response, SignSessionInformation si) throws ServletException, IOException, ConnectorException, SignatorException, SignatorFactoryException { log.trace("processSign"); String xml_response = request.getParameter("XMLResponse"); //$NON-NLS-1$ log.debug("xml_response = " + xml_response); //$NON-NLS-1$ if (isNullResponse(xml_response)) { log.debug("Received a NullOperationResponse -> answering with the first request."); //$NON-NLS-1$ assert si.outputAvailable == false; assert si.response_properties == null; log.debug("There are still requests to be performed -> answering with request."); //$NON-NLS-1$ LocalRequest local_request = si.localRequest; String request_string = local_request.getRequestString(); log.debug("request = " + request_string); response.setContentType("text/xml"); response.setCharacterEncoding("UTF-8"); response.getWriter().println(request_string); } else { log.debug("Received a normal response -> storing the response."); //$NON-NLS-1$ Properties response_properties = new Properties(); response_properties.setProperty(BKUPostConnection.RESPONSE_STRING_KEY, xml_response); si.response_properties = response_properties; log.debug("All requests have been processed -> processing the responses."); //$NON-NLS-1$ // Sign if (!si.outputAvailable) { LocalConnector c = ConnectorChooser.chooseLocalConnectorForSign(si.connector, si.type, "loc ref content not needed here"); //$NON-NLS-1$ si.si.setSignSignatureObject(c.analyzeSignResponse(si.response_properties)); PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); Signator signator = SignatorFactory.createSignator(algorithm); si.output = TempDirHelper.createTempDataSink(si.filename + "_signed.pdf"); signator.finishSign(si.si, si.output); si.outputAvailable = true; } if (si.output.getMimeType().equals("text/xml") && si.outputAvailable) { // For "detached" signatures, the return value (data sink) is the response xml, // but when passed through the BKU it is interpreted as another request // which will generate a return code 1501 // Then PDF-AS would answer with the response as well generating // another 1501 and so forth. // Therefor return it as TXT. response.setContentType("text/plain"); response.setCharacterEncoding("UTF-8"); response.getWriter().println("Das detached XML kann nicht direkt durch die BKU geschliffen werden, weil diese es als Request interpretieren würde. Daher das XML als Text:"); response.getWriter().println(si.si.getSignSignatureObject().response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY)); } else { HttpSession session = request.getSession(true); log.debug("Putting signed document into session (" + session.getId() + ")."); session.setAttribute(SessionAttributes.SIGNED_PDF_DOCUMENT, si); // String serverURL = LocalRequestHelper.getLocalServerAddress(request, response); String downloadURL = response.encodeRedirectURL(LocalRequestHelper.getLocalContextAddress(request, response) + "/ProvidePDF"); log.debug("Creating download URL \"" + downloadURL + "\"."); session.setAttribute(SessionAttributes.DOWNLOAD_URL_FOR_SIGNED_PDF_DOCUMENT, downloadURL); // String redirectURL = response.encodeRedirectURL("/pdf-as/jsp/download.jsp"); // log.debug("Redirecting to " + redirectURL + "."); // response.sendRedirect(redirectURL); temporaryRedirect(LocalRequestHelper.getLocalContextAddress(request, response) + "/jsp/download.jsp", response); return; // SignServletHelper.returnSignResponse(si, response); } } } protected void processVerify(HttpServletRequest request, HttpServletResponse response, VerifySessionInformation si) throws ServletException, IOException, ConnectorException, InvalidIDException { log.trace("processVerify"); String xml_response = request.getParameter("XMLResponse"); //$NON-NLS-1$ log.debug("xml_response = " + xml_response); //$NON-NLS-1$ if (isNullResponse(xml_response)) { log.debug("Received a NullOperationResponse -> answering with the first request."); //$NON-NLS-1$ assert si.currentLocalOperation.current_operation == 0; } else { log.debug("Recieved a normal response -> storing the response."); //$NON-NLS-1$ Properties response_properties = new Properties(); response_properties.setProperty(BKUPostConnection.RESPONSE_STRING_KEY, xml_response); si.currentLocalOperation.finishCurrentOperation(response_properties); } if (!si.currentLocalOperation.isFinished()) { log.debug("There are still requests to be performed -> answering with request #" + si.currentLocalOperation.current_operation); //$NON-NLS-1$ LocalRequest local_request = si.currentLocalOperation.getCurrentLocalRequest(); String request_string = local_request.getRequestString(); response.setContentType("text/xml"); response.setCharacterEncoding("UTF-8"); response.getWriter().println(request_string); } else { log.debug("All requests have been processed -> processing the responses."); //$NON-NLS-1$ List results = new ArrayList(); for (int i = 0; i < si.currentLocalOperation.response_properties.length; i++) { SignatureHolder sh = (SignatureHolder) si.currentLocalOperation.holders_to_be_verified.get(i); PdfASID sig_kz = sh.getSignatureObject().getKZ(); String sig_id = sh.getSignatureObject().getSignationIds(); LocalConnector c = ConnectorChooser.chooseLocalConnectorForVerify(si.connector, sig_kz, sig_id, si.type, "loc ref content not needed here"); //$NON-NLS-1$ SignatureResponse sig_resp = c.analyzeVerifyResponse(si.currentLocalOperation.response_properties[i]); results.add(sig_resp); } si.currentLocalOperation = null; URL btlURL = new URL(LocalRequestHelper.getLocalContextAddress(request, response) + "/jsp/verifylist.jsp"); String backToListURL = response.encodeURL(btlURL.toString()); dispatchToResults(results, request, response, backToListURL); } } }