Fields Summary |
---|
private static final org.apache.tools.ant.util.FileUtils | FILE_UTILS |
protected String | sigfilename to a signature file |
protected File | signedjarname of a single jar |
protected boolean | internalsfflag for internal sf signing |
protected boolean | sectionsonlysign sections only? |
private boolean | preserveLastModifiedflag to preserve timestamp on modified files |
protected boolean | lazyWhether to assume a jar which has an appropriate .SF file in is already
signed. |
protected File | destDirthe output directory when using paths. |
private org.apache.tools.ant.util.FileNameMapper | mappermapper for todir work |
protected String | tsaurlURL for a tsa; null implies no tsa support |
protected String | tsacertalias for the TSA in the keystore |
public static final String | ERROR_TODIR_AND_SIGNEDJARerror string for unit test verification: {@value} |
public static final String | ERROR_TOO_MANY_MAPPERSerror string for unit test verification: {@value} |
public static final String | ERROR_SIGNEDJAR_AND_PATHSerror string for unit test verification {@value} |
public static final String | ERROR_BAD_MAPerror string for unit test verification: {@value} |
public static final String | ERROR_MAPPER_WITHOUT_DESTerror string for unit test verification: {@value} |
public static final String | ERROR_NO_ALIASerror string for unit test verification: {@value} |
public static final String | ERROR_NO_STOREPASSerror string for unit test verification: {@value} |
Methods Summary |
---|
public void | add(org.apache.tools.ant.util.FileNameMapper newMapper)add a mapper to determine file naming policy. Only used with toDir
processing.
if (mapper != null) {
throw new BuildException(ERROR_TOO_MANY_MAPPERS);
}
mapper = newMapper;
|
private void | addTimestampAuthorityCommands(ExecTask cmd)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.
if (tsaurl != null) {
addValue(cmd, "-tsa");
addValue(cmd, tsaurl);
}
if (tsacert != null) {
addValue(cmd, "-tsacert");
addValue(cmd, tsacert);
}
|
public void | execute()sign the jar(s)
//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();
}
|
public org.apache.tools.ant.util.FileNameMapper | getMapper()get the active mapper; may be null
return mapper;
|
public java.lang.String | getTsacert()get the -tsacert option
return tsacert;
|
public java.lang.String | getTsaurl()get the -tsaurl url
return tsaurl;
|
protected boolean | isSigned(java.io.File file)test for a file being signed, by looking for a signature in the META-INF
directory with our alias.
try {
return IsSigned.isSigned(file, alias);
} catch (IOException e) {
//just log this
log(e.toString(), Project.MSG_VERBOSE);
return false;
}
|
protected boolean | isUpToDate(java.io.File jarFile, java.io.File signedjarFile)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.
If we are signing ourself, the check {@link #isSigned(File)} is used to
trigger the process.
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);
|
public void | setDestDir(java.io.File destDir)Optionally sets the output directory to be used.
this.destDir = destDir;
|
public void | setInternalsf(boolean internalsf)Flag to include the .SF file inside the signature; optional; default
false
this.internalsf = internalsf;
|
public void | setLazy(boolean lazy)flag to control whether the presence of a signature file means a JAR is
signed; optional, default false
this.lazy = lazy;
|
public void | setPreserveLastModified(boolean preserveLastModified)true to indicate that the signed jar modification date remains the same
as the original. Defaults to false
this.preserveLastModified = preserveLastModified;
|
public void | setSectionsonly(boolean sectionsonly)flag to compute hash of entire manifest; optional, default false
this.sectionsonly = sectionsonly;
|
public void | setSigfile(java.lang.String sigfile)name of .SF/.DSA file; optional
// CheckStyle:VisibilityModifier ON
this.sigfile = sigfile;
|
public void | setSignedjar(java.io.File signedjar)name of signed JAR file; optional
this.signedjar = signedjar;
|
public void | setTsacert(java.lang.String tsacert)set the alias in the keystore of the TSA to use;
this.tsacert = tsacert;
|
public void | setTsaurl(java.lang.String tsaurl)
this.tsaurl = tsaurl;
|
private void | signOneJar(java.io.File jarSource, java.io.File jarTarget)Sign one jar.
The signing only takes place if {@link #isUpToDate(File, File)} indicates
that it is needed.
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 (null != targetFile && !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);
}
|