/** * Copyright 2006 by Know-Center, Graz, Austria * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a * joint initiative of the Federal Chancellery Austria and Graz University of * Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. * * $Id: Verify.java,v 1.7 2006/10/11 07:39:13 wprinz Exp $ */ package at.gv.egiz.pdfas.web.servlets; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.Iterator; import java.util.List; import javax.servlet.RequestDispatcher; 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.api.PdfAs; import at.gv.egiz.pdfas.api.analyze.AnalyzeParameters; import at.gv.egiz.pdfas.api.analyze.AnalyzeResult; import at.gv.egiz.pdfas.api.commons.Constants; import at.gv.egiz.pdfas.api.exceptions.PdfAsException; import at.gv.egiz.pdfas.api.internal.PdfAsInternal; import at.gv.egiz.pdfas.api.io.DataSource; import at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters; import at.gv.egiz.pdfas.api.verify.VerifyResult; import at.gv.egiz.pdfas.api.verify.VerifyResults; import at.gv.egiz.pdfas.web.FormFields; import at.gv.egiz.pdfas.web.helper.ApiHelper; import at.gv.egiz.pdfas.web.helper.LocalRequestHelper; import at.gv.egiz.pdfas.web.helper.WebSettingsReader; import at.gv.egiz.pdfas.web.io.ByteArrayPdfDataSource; import at.gv.egiz.pdfas.web.io.TextDataSource; import at.gv.egiz.pdfas.web.session.SessionAttributes; import at.gv.egiz.pdfas.web.session.VerifySessionInformation; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException; /** * This method is the verify 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 verify process. * * @author wlackner * @author wprinz */ public class VerifyServlet extends HttpServlet { /** * SVUID. */ private static final long serialVersionUID = 309198792358636766L; /** * The log. */ private static Log log = LogFactory.getLog(SignServlet.class); protected void dispatch(HttpServletRequest request, HttpServletResponse response, String resource) throws ServletException, IOException { response.setContentType("text/html"); //$NON-NLS-1$ response.setCharacterEncoding("UTF-8"); //$NON-NLS-1$ RequestDispatcher disp = getServletContext().getRequestDispatcher(resource); disp.forward(request, response); } protected void dispatchToResults(VerifyResults verifyResults, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("results", verifyResults); //$NON-NLS-1$ dispatch(request, response, "/jsp/results.jsp"); //$NON-NLS-1$ } /** * Processes the verify 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 { // for performance measurement long startTime = 0; if (log.isInfoEnabled()) { startTime = System.currentTimeMillis(); } try { UploadedData ud = retrieveUploadedDataFromRequest(request); VerifySessionInformation si = new VerifySessionInformation(); si.connector = ud.sig_app; si.application = "verify"; si.mode = null; si.inputDataSource = ud.dataSource; si.type = null; si.file_name = ud.file_name; //afitzek si.startTime = startTime; // si.user_name = null; // si.user_password = null; PdfAs pdfAs = ApiHelper.getPdfAsFromContext(getServletContext()); PdfAsInternal pdfAsInternal = ApiHelper.getPdfAsInternalFromContext(getServletContext()); AnalyzeParameters analyzeParameters = new AnalyzeParameters(); analyzeParameters.setDocument(ud.dataSource); analyzeParameters.setVerifyMode(Constants.VERIFY_MODE_FULL_CONSERVATIVE); AnalyzeResult analyzeResult = pdfAs.analyze(analyzeParameters); si.analyzeResult = analyzeResult; request.getSession().setAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION, si); if (ud.preview) { dispatch(request, response, "/jsp/verifylist.jsp"); } else { if (LocalRequestHelper.isConnectorLocal(si.connector)) { String dispatch_to = LocalRequestHelper.processLocalVerify(pdfAsInternal, si, analyzeResult.getSignatures(), request, response); dispatch(request, response, dispatch_to); return; } VerifyAfterAnalysisParameters verifyAfterAnalysisParameters = new VerifyAfterAnalysisParameters(); verifyAfterAnalysisParameters.setAnalyzeResult(si.analyzeResult); verifyAfterAnalysisParameters.setSignatureDevice(si.connector); verifyAfterAnalysisParameters.setVerifySignatureIndex(-1); VerifyResults verifyResults = pdfAs.verify(verifyAfterAnalysisParameters); si.verifyResults = verifyResults; dispatchToResults(verifyResults, request, response); // for performance measurement if (log.isInfoEnabled()) { long endTime = System.currentTimeMillis(); String toReport = "VERIFY;"+ ud.file_name + ";"+ 0 + ";" + (endTime - startTime) + ";" + debugVerifyResults(verifyResults); log.info(toReport); } } } catch (FileUploadException e) { request.setAttribute("error", "Fehler beim Upload der Daten"); request.setAttribute("cause", "Beim Upload der Daten ist ein Fehler aufgetreten."); dispatch(request, response, "/jsp/error_verify.jsp"); } catch (PdfAsException e) { log.error(e.getMessage(), e); SignServlet.prepareDispatchToErrorPage(e, request); dispatch(request, response, "/jsp/error_verify.jsp"); } } protected UploadedData retrieveUploadedDataFromRequest(HttpServletRequest request) throws ServletException, UnsupportedEncodingException, FileUploadException, PDFDocumentException { DiskFileItemFactory fif = new DiskFileItemFactory(); fif.setRepository(WebSettingsReader.getTemporaryDirectory()); ServletFileUpload sfu = new ServletFileUpload(fif); List items = sfu.parseRequest(request); FileItem upload_fi = null; FileItem connector_fi = null; // FileItem mode_fi = null; FileItem preview_fi = null; String characterEncoding = request.getCharacterEncoding(); log.debug("request character encoding = " + characterEncoding); { Iterator it = items.iterator(); while (it.hasNext()) { FileItem item = (FileItem) it.next(); log.debug("item = " + item.getFieldName()); //$NON-NLS-1$ 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_UPLOAD)) { upload_fi = item; continue; } if (item.getFieldName().equals(FormFields.FIELD_CONNECTOR)) { connector_fi = item; continue; } if (item.getFieldName().equals(FormFields.FIELD_PREVIEW)) { preview_fi = item; continue; } throw new ServletException("unrecognized POST data."); //$NON-NLS-1$ } } if (upload_fi == null || connector_fi == null || /* mode_fi == null || */preview_fi == null) { throw new ServletException("Unsufficient data provided in request."); //$NON-NLS-1$ } String connector = connector_fi.getString("UTF-8"); //$NON-NLS-1$ String preview_str = preview_fi.getString("UTF-8"); //$NON-NLS-1$ if (!preview_str.equals(FormFields.VALUE_TRUE) && !preview_str.equals(FormFields.VALUE_FALSE)) { throw new ServletException("The preview '" + preview_str + "' is unrecognized."); //$NON-NLS-1$//$NON-NLS-2$ } boolean preview = false; if (preview_str.equals(FormFields.VALUE_TRUE)) { preview = true; } // process the request DataSource dataSource = convertUploadToDataSource(upload_fi); UploadedData ud = new UploadedData(); ud.preview = preview; ud.sig_app = connector; ud.file_name = upload_fi.getName(); ud.dataSource = dataSource; // ud.file_data = document_bytes; return ud; } protected DataSource convertUploadToDataSource(FileItem upload_fi) throws PDFDocumentException { log.debug("file content type =" + upload_fi.getContentType()); //$NON-NLS-1$ log.debug("file size = " + upload_fi.getSize()); //$NON-NLS-1$ if (upload_fi.getSize() <= 0) { throw new PDFDocumentException(250, "The document is empty."); //$NON-NLS-1$ } // TR: do not check MIME-type of incoming file - might vary depending on the browser used if ((upload_fi.getContentType() != null ) && ((upload_fi.getContentType().startsWith("application/pdf") || upload_fi.getContentType().startsWith("application/x-download") ))) { return new ByteArrayPdfDataSource(upload_fi.get()); } try { // String fileNameSuffix = TempDirHelper.extractFileNameSuffix(upload_fi.getName()); String text = new String(upload_fi.get(), "UTF-8"); //$NON-NLS-1$ TextDataSource textDataSource = new TextDataSource(text); return textDataSource; } catch (IOException e) { throw new PDFDocumentException(201, e); } } /** * Extracts the extension from a file name string. * *

* The extension of a file name is whatever text follows the last '.'. *

* * @param file_name * The file name. * @return Returns the extension. If the file name ends with the '.', then an * empty string is returned. If the file name doesn't contain any '.' * or file_name is null, null is returned. */ public static String extractExtension(String file_name) { if (file_name == null) { return null; } int dot_index = file_name.lastIndexOf('.'); if (dot_index < 0) { return null; } return file_name.substring(dot_index + 1); } protected static class UploadedData { protected boolean preview = false; protected String sig_app = null; protected String file_name = null; protected DataSource dataSource = null; } /** * Formats the verification results for debugging. Returns 0 if no error occurs or the sum of all error-codes. * * @param verifyResults * * @param writer * The output sink to write the formatted text to. * @throws SettingNotFoundException * Forwarded exception. */ public static int debugVerifyResults(VerifyResults verifyResults) throws SettingNotFoundException { int toreturn = 0; Iterator it = verifyResults.getResults().iterator(); while (it.hasNext()) { VerifyResult result = (VerifyResult) it.next(); toreturn += result.getValueCheckCode().getCode(); } return toreturn; } public boolean isPDF(byte[] data) { final byte[] PDF_MAGIC_NUMBER = { (byte) 0x25, (byte) 0x50, (byte) 0x44, (byte) 0x46 }; // %PDF if (data == null || data.length < PDF_MAGIC_NUMBER.length) { return false; } byte[] documentHeader = new byte[PDF_MAGIC_NUMBER.length]; System.arraycopy(data, 0, documentHeader, 0, documentHeader.length); return Arrays.equals(documentHeader, PDF_MAGIC_NUMBER); } }