⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 signjar.java

📁 Use the links below to download a source distribution of Ant from one of our mirrors. It is good pra
💻 JAVA
字号:
/* *  Licensed to the Apache Software Foundation (ASF) under one or more *  contributor license agreements.  See the NOTICE file distributed with *  this work for additional information regarding copyright ownership. *  The ASF licenses this file to You under the Apache License, Version 2.0 *  (the "License"); you may not use this file except in compliance with *  the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * *  Unless required by applicable law or agreed to in writing, software *  distributed under the License is distributed on an "AS IS" BASIS, *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  See the License for the specific language governing permissions and *  limitations under the License. * */package org.apache.tools.ant.taskdefs;import java.io.File;import java.io.IOException;import java.util.Iterator;import org.apache.tools.ant.BuildException;import org.apache.tools.ant.Project;import org.apache.tools.ant.taskdefs.condition.IsSigned;import org.apache.tools.ant.types.Path;import org.apache.tools.ant.types.resources.FileResource;import org.apache.tools.ant.util.FileUtils;import org.apache.tools.ant.util.IdentityMapper;import org.apache.tools.ant.util.FileNameMapper;/** * Signs JAR or ZIP files with the javasign command line tool. The tool detailed * dependency checking: files are only signed if they are not signed. The * <tt>signjar</tt> attribute can point to the file to generate; if this file * exists then its modification date is used as a cue as to whether to resign * any JAR file. * * Timestamp driven signing is based on the unstable and inadequately documented * information in the Java1.5 docs * @see <a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/time-of-signing-beta1.html"> * beta documentation</a> * @ant.task category="java" * @since Ant 1.1 */public class SignJar extends AbstractJarSignerTask {    // CheckStyle:VisibilityModifier OFF - bc    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();    /**     * name to a signature file     */    protected String sigfile;    /**     * name of a single jar     */    protected File signedjar;    /**     * flag for internal sf signing     */    protected boolean internalsf;    /**     * sign sections only?     */    protected boolean sectionsonly;    /**     * flag to preserve timestamp on modified files     */    private boolean preserveLastModified;    /**     * Whether to assume a jar which has an appropriate .SF file in is already     * signed.     */    protected boolean lazy;    /**     * the output directory when using paths.     */    protected File destDir;    /**     * mapper for todir work     */    private FileNameMapper mapper;    /**     * URL for a tsa; null implies no tsa support     */    protected String tsaurl;    /**     * alias for the TSA in the keystore     */    protected String tsacert;    /**     * error string for unit test verification: {@value}     */    public static final String ERROR_TODIR_AND_SIGNEDJAR            = "'destdir' and 'signedjar' cannot both be set";    /**     * error string for unit test verification: {@value}     */    public static final String ERROR_TOO_MANY_MAPPERS = "Too many mappers";    /**     * error string for unit test verification {@value}     */    public static final String ERROR_SIGNEDJAR_AND_PATHS        = "You cannot specify the signed JAR when using paths or filesets";    /**     * error string for unit test verification: {@value}     */    public static final String ERROR_BAD_MAP = "Cannot map source file to anything sensible: ";    /**     * error string for unit test verification: {@value}     */    public static final String ERROR_MAPPER_WITHOUT_DEST        = "The destDir attribute is required if a mapper is set";    /**     * error string for unit test verification: {@value}     */    public static final String ERROR_NO_ALIAS = "alias attribute must be set";    /**     * error string for unit test verification: {@value}     */    public static final String ERROR_NO_STOREPASS = "storepass attribute must be set";    // CheckStyle:VisibilityModifier ON    /**     * name of .SF/.DSA file; optional     *     * @param sigfile the name of the .SF/.DSA file     */    public void setSigfile(final String sigfile) {        this.sigfile = sigfile;    }    /**     * name of signed JAR file; optional     *     * @param signedjar the name of the signed jar file     */    public void setSignedjar(final File signedjar) {        this.signedjar = signedjar;    }    /**     * Flag to include the .SF file inside the signature; optional; default     * false     *     * @param internalsf if true include the .SF file inside the signature     */    public void setInternalsf(final boolean internalsf) {        this.internalsf = internalsf;    }    /**     * flag to compute hash of entire manifest; optional, default false     *     * @param sectionsonly flag to compute hash of entire manifest     */    public void setSectionsonly(final boolean sectionsonly) {        this.sectionsonly = sectionsonly;    }    /**     * flag to control whether the presence of a signature file means a JAR is     * signed; optional, default false     *     * @param lazy flag to control whether the presence of a signature     */    public void setLazy(final boolean lazy) {        this.lazy = lazy;    }    /**     * Optionally sets the output directory to be used.     *     * @param destDir the directory in which to place signed jars     * @since Ant 1.7     */    public void setDestDir(File destDir) {        this.destDir = destDir;    }    /**     * add a mapper to determine file naming policy. Only used with toDir     * processing.     *     * @param newMapper the mapper to add.     * @since Ant 1.7     */    public void add(FileNameMapper newMapper) {        if (mapper != null) {            throw new BuildException(ERROR_TOO_MANY_MAPPERS);        }        mapper = newMapper;    }    /**     * get the active mapper; may be null     * @return mapper or null     * @since Ant 1.7     */    public FileNameMapper getMapper() {        return mapper;    }    /**     * get the -tsaurl url     * @return url or null     * @since Ant 1.7     */    public String getTsaurl() {        return tsaurl;    }    /**     *     * @param tsaurl the tsa url.     * @since Ant 1.7     */    public void setTsaurl(String tsaurl) {        this.tsaurl = tsaurl;    }    /**     * get the -tsacert option     * @since Ant 1.7     * @return a certificate alias or null     */    public String getTsacert() {        return tsacert;    }    /**     * set the alias in the keystore of the TSA to use;     * @param tsacert the cert alias.     */    public void setTsacert(String tsacert) {        this.tsacert = tsacert;    }    /**     * sign the jar(s)     *     * @throws BuildException on errors     */    public void execute() throws BuildException {        //validation logic        final boolean hasJar = jar != null;        final boolean hasSignedJar = signedjar != null;        final boolean hasDestDir = destDir != null;        final boolean hasMapper = mapper != null;        if (!hasJar && !hasResources()) {            throw new BuildException(ERROR_NO_SOURCE);        }        if (null == alias) {            throw new BuildException(ERROR_NO_ALIAS);        }        if (null == storepass) {            throw new BuildException(ERROR_NO_STOREPASS);        }        if (hasDestDir && hasSignedJar) {            throw new BuildException(ERROR_TODIR_AND_SIGNEDJAR);        }        if (hasResources() && hasSignedJar) {            throw new BuildException(ERROR_SIGNEDJAR_AND_PATHS);        }        //this isnt strictly needed, but by being fussy now,        //we can change implementation details later        if (!hasDestDir && hasMapper) {            throw new BuildException(ERROR_MAPPER_WITHOUT_DEST);        }        beginExecution();        try {            //special case single jar handling with signedjar attribute set            if (hasJar && hasSignedJar) {                // single jar processing                signOneJar(jar, signedjar);                //return here.                return;            }            //the rest of the method treats single jar like            //a nested path with one file            Path sources = createUnifiedSourcePath();            //set up our mapping policy            FileNameMapper destMapper;            if (hasMapper) {                destMapper = mapper;            } else {                //no mapper? use the identity policy                destMapper = new IdentityMapper();            }            //at this point the paths are set up with lists of files,            //and the mapper is ready to map from source dirs to dest files            //now we iterate through every JAR giving source and dest names            // deal with the paths            Iterator iter = sources.iterator();            while (iter.hasNext()) {                FileResource fr = (FileResource) iter.next();                //calculate our destination directory; it is either the destDir                //attribute, or the base dir of the fileset (for in situ updates)                File toDir = hasDestDir ? destDir : fr.getBaseDir();                //determine the destination filename via the mapper                String[] destFilenames = destMapper.mapFileName(fr.getName());                if (destFilenames == null || destFilenames.length != 1) {                    //we only like simple mappers.                    throw new BuildException(ERROR_BAD_MAP + fr.getFile());                }                File destFile = new File(toDir, destFilenames[0]);                signOneJar(fr.getFile(), destFile);            }        } finally {            endExecution();        }    }    /**     * Sign one jar.     * <p/>     * The signing only takes place if {@link #isUpToDate(File, File)} indicates     * that it is needed.     *     * @param jarSource source to sign     * @param jarTarget target; may be null     * @throws BuildException     */    private void signOneJar(File jarSource, File jarTarget)            throws BuildException {        File targetFile = jarTarget;        if (targetFile == null) {            targetFile = jarSource;        }        if (isUpToDate(jarSource, targetFile)) {            return;        }        long lastModified = jarSource.lastModified();        final ExecTask cmd = createJarSigner();        setCommonOptions(cmd);        bindToKeystore(cmd);        if (null != sigfile) {            addValue(cmd, "-sigfile");            String value = this.sigfile;            addValue(cmd, value);        }        //DO NOT SET THE -signedjar OPTION if source==dest        //unless you like fielding hotspot crash reports        if (!jarSource.equals(targetFile)) {            addValue(cmd, "-signedjar");            addValue(cmd, targetFile.getPath());        }        if (internalsf) {            addValue(cmd, "-internalsf");        }        if (sectionsonly) {            addValue(cmd, "-sectionsonly");        }        //add -tsa operations if declared        addTimestampAuthorityCommands(cmd);        //JAR source is required        addValue(cmd, jarSource.getPath());        //alias is required for signing        addValue(cmd, alias);        log("Signing JAR: "            + jarSource.getAbsolutePath()            + " to "            + targetFile.getAbsolutePath()            + " as " + alias);        cmd.execute();        // restore the lastModified attribute        if (preserveLastModified) {            targetFile.setLastModified(lastModified);        }    }    /**     * If the tsa parameters are set, this passes them to the command.     * There is no validation of java version, as third party JDKs     * may implement this on earlier/later jarsigner implementations.     * @param cmd the exec task.     */    private void addTimestampAuthorityCommands(final ExecTask cmd) {        if (tsaurl != null) {            addValue(cmd, "-tsa");            addValue(cmd, tsaurl);        }        if (tsacert != null) {            addValue(cmd, "-tsacert");            addValue(cmd, tsacert);        }    }    /**     * Compare a jar file with its corresponding signed jar. The logic for this     * is complex, and best explained in the source itself. Essentially if     * either file doesnt exist, or the destfile has an out of date timestamp,     * then the return value is false.     * <p/>     * If we are signing ourself, the check {@link #isSigned(File)} is used to     * trigger the process.     *     * @param jarFile       the unsigned jar file     * @param signedjarFile the result signed jar file     * @return true if the signedjarFile is considered up to date     */    protected boolean isUpToDate(File jarFile, File signedjarFile) {        if (null == jarFile || !jarFile.exists()) {            //these are pathological cases, but retained in case somebody            //subclassed us.            return false;        }        //we normally compare destination with source        File destFile = signedjarFile;        if (destFile == null) {            //but if no dest is specified, compare source to source            destFile = jarFile;        }        //if, by any means, the destfile and source match,        if (jarFile.equals(destFile)) {            if (lazy) {                //we check the presence of signatures on lazy signing                return isSigned(jarFile);            }            //unsigned or non-lazy self signings are always false            return false;        }        //if they are different, the timestamps are used        return FILE_UTILS.isUpToDate(jarFile, destFile);    }    /**     * test for a file being signed, by looking for a signature in the META-INF     * directory with our alias.     *     * @param file the file to be checked     * @return true if the file is signed     * @see IsSigned#isSigned(File, String)     */    protected boolean isSigned(File file) {        try {            return IsSigned.isSigned(file, alias);        } catch (IOException e) {            //just log this            log(e.toString(), Project.MSG_VERBOSE);            return false;        }    }    /**     * true to indicate that the signed jar modification date remains the same     * as the original. Defaults to false     *     * @param preserveLastModified if true preserve the last modified time     */    public void setPreserveLastModified(boolean preserveLastModified) {        this.preserveLastModified = preserveLastModified;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -