/******************************************************************************* * Copyright 2014 by E-Government Innovation Center EGIZ, 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. ******************************************************************************/ package at.gv.egiz.pdfas.web.servlets; import java.io.File; import java.io.IOException; import java.util.List; 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.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import at.gv.egiz.pdfas.common.exceptions.PDFASError; import at.gv.egiz.pdfas.common.exceptions.PdfAsException; import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel; import at.gv.egiz.pdfas.lib.api.verify.VerifyResult; import at.gv.egiz.pdfas.web.exception.PdfAsWebException; import at.gv.egiz.pdfas.web.filter.UserAgentFilter; import at.gv.egiz.pdfas.web.helper.PdfAsHelper; import at.gv.egiz.pdfas.web.helper.PdfAsParameterExtractor; import at.gv.egiz.pdfas.web.helper.RemotePDFFetcher; import at.gv.egiz.pdfas.web.helper.VerifyEncoder; import at.gv.egiz.pdfas.web.helper.VerifyResultEncoder; import at.gv.egiz.pdfas.web.stats.StatisticEvent; import at.gv.egiz.pdfas.web.stats.StatisticFrontend; import at.gv.egiz.pdfas.web.stats.StatisticEvent.Operation; import at.gv.egiz.pdfas.web.stats.StatisticEvent.Source; import at.gv.egiz.pdfas.web.stats.StatisticEvent.Status; /** * Servlet implementation class VerifyServlet */ public class VerifyServlet extends HttpServlet { private static final long serialVersionUID = 1L; private static final Logger logger = LoggerFactory .getLogger(VerifyServlet.class); private static final String UPLOAD_PDF_DATA = "pdf-file"; private static final String UPLOAD_DIRECTORY = "upload"; private static final int THRESHOLD_SIZE = 1024 * 1024 * 3; // 3MB private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB /** * @see HttpServlet#HttpServlet() */ public VerifyServlet() { super(); } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.info("Get verify request"); String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request); PdfAsHelper.setErrorURL(request, response, errorUrl); StatisticEvent statisticEvent = new StatisticEvent(); statisticEvent.setStartNow(); statisticEvent.setSource(Source.WEB); statisticEvent.setOperation(Operation.VERIFY); statisticEvent.setUserAgent(UserAgentFilter.getUserAgent()); try { // Mandatory Parameters on Get Request: String invokeUrl = PdfAsParameterExtractor.getInvokeURL(request); PdfAsHelper.setInvokeURL(request, response, invokeUrl); String invokeTarget = PdfAsParameterExtractor.getInvokeTarget(request); PdfAsHelper.setInvokeTarget(request, response, invokeTarget); String pdfUrl = PdfAsParameterExtractor.getPdfUrl(request); if (pdfUrl == null) { throw new PdfAsWebException( "No PDF URL given! Use POST request to sign without PDF URL."); } byte[] pdfData = RemotePDFFetcher.fetchPdfFile(pdfUrl); doVerify(request, response, pdfData, statisticEvent); } catch (Throwable e) { statisticEvent.setStatus(Status.ERROR); statisticEvent.setException(e); if(e instanceof PDFASError) { statisticEvent.setErrorCode(((PDFASError)e).getCode()); } statisticEvent.setEndNow(); statisticEvent.setTimestampNow(); StatisticFrontend.getInstance().storeEvent(statisticEvent); statisticEvent.setLogged(true); logger.warn("Generic Error: ", e); PdfAsHelper.setSessionException(request, response, e.getMessage(), e); PdfAsHelper.gotoError(getServletContext(), request, response); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.info("Post verify request"); String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request); PdfAsHelper.setErrorURL(request, response, errorUrl); StatisticEvent statisticEvent = new StatisticEvent(); statisticEvent.setStartNow(); statisticEvent.setSource(Source.WEB); statisticEvent.setOperation(Operation.VERIFY); statisticEvent.setUserAgent(UserAgentFilter.getUserAgent()); try { byte[] filecontent = null; // checks if the request actually contains upload file if (!ServletFileUpload.isMultipartContent(request)) { // No Uploaded data! if (PdfAsParameterExtractor.getPdfUrl(request) != null) { doGet(request, response); return; } else { throw new PdfAsWebException("No Signature data defined!"); } } else { // configures upload settings DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(THRESHOLD_SIZE); factory.setRepository(new File(System .getProperty("java.io.tmpdir"))); ServletFileUpload upload = new ServletFileUpload(factory); upload.setFileSizeMax(MAX_FILE_SIZE); upload.setSizeMax(MAX_REQUEST_SIZE); // constructs the directory path to store upload file String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY; // creates the directory if it does not exist File uploadDir = new File(uploadPath); if (!uploadDir.exists()) { uploadDir.mkdir(); } List formItems = upload.parseRequest(request); logger.debug(formItems.size() + " Items in form data"); if (formItems.size() < 1) { // No Uploaded data! // Try do get // No Uploaded data! if (PdfAsParameterExtractor.getPdfUrl(request) != null) { doGet(request, response); return; } else { throw new PdfAsWebException( "No Signature data defined!"); } } else { for (int i = 0; i < formItems.size(); i++) { Object obj = formItems.get(i); if (obj instanceof FileItem) { FileItem item = (FileItem) obj; if (item.getFieldName().equals(UPLOAD_PDF_DATA)) { filecontent = item.get(); try { File f = new File(item.getName()); String name = f.getName(); logger.debug("Got upload: " + item.getName()); if (name != null) { if (!(name.endsWith(".pdf") || name .endsWith(".PDF"))) { name += ".pdf"; } logger.debug("Setting Filename in session: " + name); PdfAsHelper.setPDFFileName(request, name); } } catch (Throwable e) { logger.warn("In resolving filename", e); } if (filecontent.length < 10) { filecontent = null; } else { logger.debug("Found pdf Data! Size: " + filecontent.length); } } else { request.setAttribute(item.getFieldName(), item.getString()); logger.debug("Setting " + item.getFieldName() + " = " + item.getString()); } } else { logger.debug(obj.getClass().getName() + " - " + obj.toString()); } } } } if (filecontent == null) { if (PdfAsParameterExtractor.getPdfUrl(request) != null) { filecontent = RemotePDFFetcher .fetchPdfFile(PdfAsParameterExtractor .getPdfUrl(request)); } } if (filecontent == null) { Object sourceObj = request.getAttribute("source"); if (sourceObj != null) { String source = sourceObj.toString(); if (source.equals("internal")) { request.setAttribute("FILEERR", true); request.getRequestDispatcher("index.jsp").forward( request, response); statisticEvent.setStatus(Status.ERROR); statisticEvent.setException(new Exception("No file uploaded")); statisticEvent.setEndNow(); statisticEvent.setTimestampNow(); StatisticFrontend.getInstance().storeEvent(statisticEvent); statisticEvent.setLogged(true); return; } } throw new PdfAsException("No Signature data available"); } doVerify(request, response, filecontent, statisticEvent); } catch (Throwable e) { statisticEvent.setStatus(Status.ERROR); statisticEvent.setException(e); if(e instanceof PDFASError) { statisticEvent.setErrorCode(((PDFASError)e).getCode()); } statisticEvent.setEndNow(); statisticEvent.setTimestampNow(); StatisticFrontend.getInstance().storeEvent(statisticEvent); statisticEvent.setLogged(true); logger.warn("Generic Error: ", e); PdfAsHelper.setSessionException(request, response, e.getMessage(), e); PdfAsHelper.gotoError(getServletContext(), request, response); } } protected void doVerify(HttpServletRequest request, HttpServletResponse response, byte[] pdfData, StatisticEvent statisticEvent) throws Exception { SignatureVerificationLevel lvl = PdfAsParameterExtractor .getVerificationLevel(request); PdfAsHelper.setVerificationLevel(request, lvl); String format = PdfAsParameterExtractor.getFormat(request); logger.debug("doVerify"); logger.info("Starting verification of pdf dokument"); logger.debug("Format: " + format); List results = PdfAsHelper.synchornousVerify(pdfData, -1, lvl, PdfAsParameterExtractor.getPreProcessorMap(request)); PdfAsHelper.setVerificationResult(request, results); // Create HTML Snippet for each Verification Result // Put these results into the web page // Or create a JSON response with the verification results for automated // processing VerifyResultEncoder encoder = VerifyEncoder.getEncoder(format); if(encoder == null) { encoder = VerifyEncoder.getEncoder(PdfAsParameterExtractor.PARAM_HTML); } statisticEvent.setStatus(Status.OK); statisticEvent.setEndNow(); statisticEvent.setTimestampNow(); StatisticFrontend.getInstance().storeEvent(statisticEvent); statisticEvent.setLogged(true); encoder.produce(request, response, results); } }