/** * Copyright (c) 2006 by Know-Center, Graz, Austria * * This software is the confidential and proprietary information of Know-Center, * Graz, Austria. You shall not disclose such Confidential Information and shall * use it only in accordance with the terms of the license agreement you entered * into with Know-Center. * * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. * * $Id: Sign.java,v 1.7 2006/10/11 07:39:13 wprinz Exp $ */ package at.knowcenter.wag.egov.egiz.web.servlets; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URL; import java.util.Iterator; import java.util.List; 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 org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import at.gv.egiz.pdfas.exceptions.ErrorCode; import at.gv.egiz.pdfas.exceptions.ErrorCodeHelper; import at.gv.egiz.pdfas.exceptions.external.ExternalErrorException; import at.gv.egiz.pdfas.framework.input.PdfDataSource; import at.gv.egiz.pdfas.utils.WebUtils; import at.gv.egiz.pdfas.web.SignSessionInformation; import at.gv.egiz.pdfas.web.helper.SignServletHelper; import at.gv.egiz.pdfas.web.helper.TempDirHelper; import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; import at.knowcenter.wag.egov.egiz.exceptions.PlaceholderException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; import at.knowcenter.wag.egov.egiz.pdf.TablePos; import at.knowcenter.wag.egov.egiz.web.ExternAppInformation; import at.knowcenter.wag.egov.egiz.web.FormFields; import at.knowcenter.wag.egov.egiz.web.SessionAttributes; /** * This method is the sign servlet for the pdf-as web application. It takes get * and post requests fill out jsp templates and give the user feedback about the * results of the sign process * * @author wlackner * @author wprinz */ public class SignServlet extends HttpServlet { /** * SVUID. */ private static final long serialVersionUID = -4156938216903740438L; /** * The log. */ private static Log log = LogFactory.getLog(SignServlet.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); } // The sign servlet is used for processing the upload only. // Authentication is deactivated. if required - make an own servlet. // /** // * @author modified by tknall // */ // public void doGet(HttpServletRequest request, HttpServletResponse response) // throws ServletException, IOException // { // String authenticate = request.getHeader(AUTH); // if (authenticate != null) // { // logger_.info("authenticate:" + authenticate); // if (authenticate.indexOf(AUTH_BASIC) == 0) // { // authenticate = authenticate.substring(AUTH_BASIC.length() + 1); // logger_.info("authenticate:" + authenticate); // authenticate = new String(CodingHelper.decodeBase64(authenticate), // "UTF-8"); // logger_.info("authenticate:" + authenticate); // // String[] auth_value = authenticate.split(":"); // String user_name = auth_value[0]; // String user_password = auth_value[1]; // logger_.info("username:" + user_name); // // start modification tknall // // logger_.info("password:" + user_password); // logger_.info("password:XXXXXXXXXXXX"); // // stop modification tknall // // HttpSession session = request.getSession(); // session.setAttribute(SessionAttributes.ATTRIBUTE_USER_NAME, user_name); // session.setAttribute(SessionAttributes.ATTRIBUTE_USER_PASSWORD, // user_password); // // dispatch(request, response, "/jsp/signupload.jsp"); // return; // } // // start modification tknall // } else { // String user_name = ""; // String user_password = ""; // logger_.info("authenticate:User has not been authenticated!"); // logger_.info("username: UNKNOWN"); // logger_.info("password: XXXXXXXXXXXX"); // HttpSession session = request.getSession(); // session.setAttribute("uname", user_name); // session.setAttribute("upass", user_password); // dispatch(request, response, "/jsp/signupload.jsp"); // } // request.setAttribute("error", "Falsche Authentifikation"); // request.setAttribute("cause", "Passwort oder Benutzername ist falsch"); // dispatch(request, response, "/jsp/error.jsp"); // // stop modification tknall // } /** * Processes the sign upload. * * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse) */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { UploadedData ud = null; ExternAppInformation exappinf = null; TablePos pos = null; // for performance measurement long startTime = 0; long fileSize = 0; if (log.isInfoEnabled()) { startTime = System.currentTimeMillis(); } // check if pdf-as has been called by external webapp if (request.getParameter(FormFields.FIELD_PDF_URL) != null) { String preview = (String) request.getParameter(FormFields.FIELD_PREVIEW); String sig_type = (String) request.getParameter(FormFields.FIELD_SIGNATURE_TYPE); String sig_app = (String) request.getParameter(FormFields.FIELD_CONNECTOR); String sig_mode = (String) request.getParameter(FormFields.FIELD_MODE); String filename = (String) request.getParameter(FormFields.FIELD_FILENAME); String pdf_url = (String) request.getParameter(FormFields.FIELD_PDF_URL); String pdf_id = (String) request.getParameter(FormFields.FIELD_PDF_ID); String pdf_length = (String) request.getParameter(FormFields.FIELD_FILE_LENGTH); String invoke_url = (String) request.getParameter(FormFields.FIELD_INVOKE_APP_URL); String session_id = (String) request.getParameter(FormFields.FIELD_SESSION_ID); String sig_pos_y = (String) request.getParameter(FormFields.FIELD_SIGPOS_Y); String sig_pos_p = (String) request.getParameter(FormFields.FIELD_SIGPOS_P); // added by tknall if (sig_pos_y != null && sig_pos_p != null) { try { pos = new TablePos("y:" + sig_pos_y + ";p:" + sig_pos_p); } catch (PDFDocumentException e) { log.warn("Unable to create signature position object: " + e.getMessage(), e); } } else { log.debug("No signature position provided."); } // fixed by tknall: if we already have parameters "&" must be used instead of "?" String paramSeparator = (pdf_url.indexOf("?") != -1) ? "&" : "?"; String query = pdf_url + paramSeparator + FormFields.FIELD_PDF_ID + "=" + pdf_id; // wprinz: rem: this allocation is useless // byte[] extern_pdf = new byte[Integer.parseInt(pdf_length)]; URL source_url = new URL(query); InputStream is = source_url.openStream(); // extern_pdf = toByteArray(is); // set UploadedData object... UploadedData ud_extern = new UploadedData(); ud_extern.file_name = filename; ud_extern.pdfDataSource = TempDirHelper.placePdfIntoTempDir(is, filename); // ud_extern.pdf = extern_pdf; // ud_extern.preview = preview.equalsIgnoreCase("true") ? true : false; ud_extern.preview = "true".equalsIgnoreCase(preview); ud_extern.sig_app = sig_app; ud_extern.sig_mode = sig_mode; ud_extern.sig_type = sig_type; ud = ud_extern; exappinf = new ExternAppInformation(invoke_url, pdf_id, session_id); } else { try { // tzefferer: modified // UploadedData ud = retrieveUploadedDataFromRequest(request); UploadedData ud_form = retrieveUploadedDataFromRequest(request); ud = ud_form; // end modify } catch (Exception e) { // Error retrieving data request.setAttribute("error", "Fehler beim Upload der Daten"); request.setAttribute("cause", "Beim Upload der Daten ist ein Fehler aufgetreten."); dispatch(request, response, "/jsp/error.jsp"); return; } } try { ud.pdfDataSource = PdfAS.applyStrictMode(ud.pdfDataSource); SignSessionInformation si = new SignSessionInformation(); // SessionTable.generateSessionInformationObject(); si.connector = ud.sig_app; si.application = "sign"; si.mode = ud.sig_mode; si.pdfDataSource = ud.pdfDataSource; si.type = ud.sig_type; si.filename = formatFileName(ud.file_name); si.download_inline = ud.download_inline; // added tzefferer: si.exappinf = exappinf; si.pos = pos; // end add request.getSession().setAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION, si); // String user_name = (String) // request.getSession().getAttribute(SessionAttributes.ATTRIBUTE_USER_NAME); // String user_password = (String) // request.getSession().getAttribute(SessionAttributes.ATTRIBUTE_USER_PASSWORD); // si.user_name = user_name; // si.user_password = user_password; SignServletHelper.prepareSign(si); if (ud.preview) { String submit_url = response.encodeURL(request.getContextPath() + "/SignPreview"); // String signature_data_url = response.encodeURL(WebUtils.addJSessionID(request.getContextPath() + "/RetrieveSignatureData", request)); String signature_data_url = response.encodeURL(WebUtils.buildRetrieveSignatureDataURL(request, response)); request.setAttribute("submit_url", submit_url); request.setAttribute("signature_data_url", signature_data_url); dispatch(request, response, "/jsp/signpreview.jsp"); return; } SignServletHelper.finishSign(si, request, response, getServletContext()); // for performance measurement if (log.isInfoEnabled()) { long endTime = System.currentTimeMillis(); // String toReport = "SIGN;" + si.mode + ";" + si.filename + ";"+ fileSize + ";" + String toReport = "SIGN;" + si.mode + ";XXX;"+ fileSize + ";" + (endTime - startTime); log.info(toReport); } } catch (PresentableException e) { log.error(e.getMessage(), e); prepareDispatchToErrorPage(e, request); dispatch(request, response, "/jsp/error.jsp"); } } // tzefferer:added public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } // end add protected UploadedData retrieveUploadedDataFromRequest(HttpServletRequest request) throws ServletException, UnsupportedEncodingException, FileUploadException, PDFDocumentException { DiskFileItemFactory fif = new DiskFileItemFactory(); fif.setRepository(SettingsReader.getTemporaryDirectory()); ServletFileUpload sfu = new ServletFileUpload(fif); List items = sfu.parseRequest(request); FileItem preview_fi = null; FileItem sig_type_fi = null; FileItem sig_app_fi = null; FileItem mode_fi = null; FileItem file_upload_fi = null; FileItem download_fi = null; Iterator it = items.iterator(); while (it.hasNext()) { FileItem item = (FileItem) it.next(); log.debug("item = " + item.getFieldName()); //$NON-NLS-1$ if (log.isDebugEnabled()) { if (item.isFormField()) { String item_string = item.getString("UTF-8"); //$NON-NLS-1$ log.debug(" form field string = " + item_string); //$NON-NLS-1$ } else { log.debug(" filename = " + item.getName()); //$NON-NLS-1$ log.debug(" filesize = " + item.getSize()); //$NON-NLS-1$ } } if (item.getFieldName().equals(FormFields.FIELD_PREVIEW)) { preview_fi = item; continue; } if (item.getFieldName().equals(FormFields.FIELD_SIGNATURE_TYPE)) { sig_type_fi = item; continue; } if (item.getFieldName().equals(FormFields.FIELD_CONNECTOR)) { sig_app_fi = item; continue; } if (item.getFieldName().equals(FormFields.FIELD_MODE)) { mode_fi = item; continue; } if (item.getFieldName().equals(FormFields.FIELD_UPLOAD)) { file_upload_fi = item; continue; } if (item.getFieldName().equals(FormFields.FIELD_DOWNLOAD)) { download_fi = item; continue; } throw new ServletException("unrecognized POST data."); //$NON-NLS-1$ } if (preview_fi == null || sig_type_fi == null || sig_app_fi == null || file_upload_fi == null || download_fi == null) { throw new ServletException("Insufficient data provided in request"); //$NON-NLS-1$ } String mode = mode_fi.getString("UTF-8"); //$NON-NLS-1$ if (!mode.equals(FormFields.VALUE_MODE_BINARY) && !mode.equals(FormFields.VALUE_MODE_TEXTUAL) && !mode.equals(FormFields.VALUE_MODE_DETACHED)) { throw new ServletException("The mode '" + mode + "' is unrecognized."); //$NON-NLS-1$ //$NON-NLS-2$ } String preview_str = preview_fi.getString("UTF-8"); //$NON-NLS-1$ boolean preview = false; if (preview_str.equals("true")) //$NON-NLS-1$ { preview = true; } boolean download_inline = true; if (download_fi.getString("UTF-8").equals(FormFields.VALUE_DOWNLOAD_ATTACHMENT)) //$NON-NLS-1$ { download_inline = false; } String sig_type = sig_type_fi.getString("UTF-8"); //$NON-NLS-1$ String sig_app = sig_app_fi.getString("UTF-8"); //$NON-NLS-1$ String doc_file_name = TempDirHelper.extractFileNameSuffix(file_upload_fi.getName()); log.debug("file content type =" + file_upload_fi.getContentType()); //$NON-NLS-1$ String extension = VerifyServlet.extractExtension(doc_file_name); if (extension != null && !extension.equals("pdf")) //$NON-NLS-1$ { throw new PDFDocumentException(201, "The provided file '" + doc_file_name + "' doesn't have the PDF extension (.pdf)."); //$NON-NLS-1$//$NON-NLS-2$ } if (file_upload_fi.getSize() <= 0) { throw new PDFDocumentException(250, "The document is empty."); //$NON-NLS-1$ } PdfDataSource pdfDataSource = null; try { pdfDataSource = TempDirHelper.placePdfIntoTempDir(file_upload_fi.getInputStream(), doc_file_name); } catch (IOException e) { throw new PDFDocumentException(201, "Couldn't store the file in the temp dir.", e); } // byte[] pdf = file_upload_fi.get(); UploadedData ud = new UploadedData(); ud.preview = preview; ud.download_inline = download_inline; ud.sig_type = sig_type; ud.sig_app = sig_app; ud.sig_mode = mode; ud.file_name = doc_file_name; ud.pdfDataSource = pdfDataSource; return ud; } public static void prepareDispatchToErrorPage(PresentableException pe, HttpServletRequest request) { request.setAttribute("PresentableException", pe); // if (pe instanceof ErrorCodeException) // { request.setAttribute("error", "Fehler " + pe.getErrorCode()); String cause = ErrorCodeHelper.getMessageForErrorCode(pe.getErrorCode()); if (pe instanceof ExternalErrorException) { ExternalErrorException eee = (ExternalErrorException) pe; cause = eee.getExternalErrorCode() + ": " + eee.getExternalErrorMessage(); } request.setAttribute("cause", cause); if (pe.getErrorCode() == ErrorCode.PLACEHOLDER_EXCEPTION) { PlaceholderException phe = null; if (pe instanceof PlaceholderException) { phe = (PlaceholderException) pe; } else { phe = (PlaceholderException) pe.getCause(); } request.setAttribute("cause", "Der Platzhalter des Feldes " + phe.getField() + " ist um " + phe.getMissing() + " Bytes zu kurz. " + cause); } // } // else // { // request.setAttribute("error", "PresentableException"); // request.setAttribute("cause", pe.toString()); // } } public void dispatchToPreview(String document_text, String connector, String mode, String signature_type, String submit_url, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("document_text", document_text); request.setAttribute("connector", connector); request.setAttribute("mode", mode); request.setAttribute("signature_type", signature_type); request.setAttribute("submit_url", submit_url); dispatch(request, response, "/jsp/signpreview.jsp"); } /** * Formats the file name so that it is suitable for content disposition. * * @param file_name * The file name. * @return Returns the formatted file name. */ public static String formatFileName(String file_name) { File file = new File(file_name); String file_name_only = file.getName(); // the file_name contains \\ ==> remove them so Internet Explorer works // correctly. return file_name_only; } // tzefferer: added public static byte[] toByteArray(InputStream inputStream) throws IOException { if (inputStream == null) { return null; } ByteArrayOutputStream out = new ByteArrayOutputStream(8192); int n; byte[] buffer = new byte[2048]; BufferedInputStream bufIn = new BufferedInputStream(inputStream); try { while ((n = bufIn.read(buffer)) != -1) { out.write(buffer, 0, n); } } finally { if (bufIn != null) { bufIn.close(); } } return out.toByteArray(); } // end add protected static class UploadedData { protected boolean preview = false; protected boolean download_inline = false; protected String sig_type = null; protected String sig_app = null; protected String sig_mode = null; protected String file_name = null; protected PdfDataSource pdfDataSource = null; // protected byte[] pdf = null; } }