source: release-kits/lirk3/resources/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/SignJar.java@ 14982

Last change on this file since 14982 was 14982, checked in by oranfry, 16 years ago

initial import of LiRK3

File size: 10.4 KB
Line 
1/*
2 * Copyright 2000-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17package org.apache.tools.ant.taskdefs;
18
19import java.io.File;
20import java.io.IOException;
21import java.util.Enumeration;
22import java.util.Vector;
23import java.util.zip.ZipEntry;
24import java.util.zip.ZipFile;
25import org.apache.tools.ant.BuildException;
26import org.apache.tools.ant.DirectoryScanner;
27import org.apache.tools.ant.Project;
28import org.apache.tools.ant.Task;
29import org.apache.tools.ant.types.FileSet;
30import org.apache.tools.ant.util.JavaEnvUtils;
31
32/**
33 * Signs JAR or ZIP files with the javasign command line tool. The
34 * tool detailed dependency checking: files are only signed if they
35 * are not signed. The <tt>signjar</tt> attribute can point to the file to
36 * generate; if this file exists then
37 * its modification date is used as a cue as to whether to resign any JAR file.
38 *
39 * @since Ant 1.1
40 * @ant.task category="java"
41 */
42public class SignJar extends Task {
43
44 /**
45 * The name of the jar file.
46 */
47 protected File jar;
48
49 /**
50 * The alias of signer.
51 */
52 protected String alias;
53
54 /**
55 * The name of keystore file.
56 */
57 private String keystore;
58
59 protected String storepass;
60 protected String storetype;
61 protected String keypass;
62 protected String sigfile;
63 protected File signedjar;
64 protected boolean verbose;
65 protected boolean internalsf;
66 protected boolean sectionsonly;
67
68 /** The maximum amount of memory to use for Jar signer */
69 private String maxMemory;
70
71 /**
72 * the filesets of the jars to sign
73 */
74 protected Vector filesets = new Vector();
75
76 /**
77 * Whether to assume a jar which has an appropriate .SF file in is already
78 * signed.
79 */
80 protected boolean lazy;
81
82
83 /**
84 * Set the maximum memory to be used by the jarsigner process
85 *
86 * @param max a string indicating the maximum memory according to the
87 * JVM conventions (e.g. 128m is 128 Megabytes)
88 */
89 public void setMaxmemory(String max) {
90 maxMemory = max;
91 }
92
93 /**
94 * the jar file to sign; required
95 */
96 public void setJar(final File jar) {
97 this.jar = jar;
98 }
99
100 /**
101 * the alias to sign under; required
102 */
103 public void setAlias(final String alias) {
104 this.alias = alias;
105 }
106
107 /**
108 * keystore location; required
109 */
110 public void setKeystore(final String keystore) {
111 this.keystore = keystore;
112 }
113
114 /**
115 * password for keystore integrity; required
116 */
117 public void setStorepass(final String storepass) {
118 this.storepass = storepass;
119 }
120
121 /**
122 * keystore type; optional
123 */
124 public void setStoretype(final String storetype) {
125 this.storetype = storetype;
126 }
127
128 /**
129 * password for private key (if different); optional
130 */
131 public void setKeypass(final String keypass) {
132 this.keypass = keypass;
133 }
134
135 /**
136 * name of .SF/.DSA file; optional
137 */
138 public void setSigfile(final String sigfile) {
139 this.sigfile = sigfile;
140 }
141
142 /**
143 * name of signed JAR file; optional
144 */
145 public void setSignedjar(final File signedjar) {
146 this.signedjar = signedjar;
147 }
148
149 /**
150 * Enable verbose output when signing
151 * ; optional: default false
152 */
153 public void setVerbose(final boolean verbose) {
154 this.verbose = verbose;
155 }
156
157 /**
158 * Flag to include the .SF file inside the signature;
159 * optional; default false
160 */
161 public void setInternalsf(final boolean internalsf) {
162 this.internalsf = internalsf;
163 }
164
165 /**
166 * flag to compute hash of entire manifest;
167 * optional, default false
168 */
169 public void setSectionsonly(final boolean sectionsonly) {
170 this.sectionsonly = sectionsonly;
171 }
172
173 /**
174 * flag to control whether the presence of a signature
175 * file means a JAR is signed;
176 * optional, default false
177 */
178 public void setLazy(final boolean lazy) {
179 this.lazy = lazy;
180 }
181
182 /**
183 * Adds a set of files to sign
184 * @since Ant 1.4
185 */
186 public void addFileset(final FileSet set) {
187 filesets.addElement(set);
188 }
189
190
191 /**
192 * sign the jar(s)
193 */
194 public void execute() throws BuildException {
195 if (null == jar && filesets.size() == 0) {
196 throw new BuildException("jar must be set through jar attribute "
197 + "or nested filesets");
198 }
199 if (null != jar) {
200 if (filesets.size() != 0) {
201 log("nested filesets will be ignored if the jar attribute has"
202 + " been specified.", Project.MSG_WARN);
203 }
204
205 doOneJar(jar, signedjar);
206 return;
207 } else {
208 // deal with the filesets
209 for (int i = 0; i < filesets.size(); i++) {
210 FileSet fs = (FileSet) filesets.elementAt(i);
211 DirectoryScanner ds = fs.getDirectoryScanner(getProject());
212 String[] jarFiles = ds.getIncludedFiles();
213 for (int j = 0; j < jarFiles.length; j++) {
214 doOneJar(new File(fs.getDir(getProject()), jarFiles[j]), null);
215 }
216 }
217 }
218 }
219
220 /**
221 * sign one jar
222 */
223 private void doOneJar(File jarSource, File jarTarget)
224 throws BuildException {
225
226 if (null == alias) {
227 throw new BuildException("alias attribute must be set");
228 }
229
230 if (null == storepass) {
231 throw new BuildException("storepass attribute must be set");
232 }
233
234 if (isUpToDate(jarSource, jarTarget)) {
235 return;
236 }
237
238 final ExecTask cmd = (ExecTask) getProject().createTask("exec");
239 cmd.setExecutable(JavaEnvUtils.getJdkExecutable("jarsigner"));
240
241 if (maxMemory != null) {
242 cmd.createArg().setValue("-J-Xmx" + maxMemory);
243 }
244
245 if (null != keystore) {
246 // is the keystore a file
247 File keystoreFile = getProject().resolveFile(keystore);
248 if (keystoreFile.exists()) {
249 cmd.createArg().setValue("-keystore");
250 cmd.createArg().setValue(keystoreFile.getPath());
251 } else {
252 // must be a URL - just pass as is
253 cmd.createArg().setValue("-keystore");
254 cmd.createArg().setValue(keystore);
255 }
256 }
257
258 if (null != storepass) {
259 cmd.createArg().setValue("-storepass");
260 cmd.createArg().setValue(storepass);
261 }
262
263 if (null != storetype) {
264 cmd.createArg().setValue("-storetype");
265 cmd.createArg().setValue(storetype);
266 }
267
268 if (null != keypass) {
269 cmd.createArg().setValue("-keypass");
270 cmd.createArg().setValue(keypass);
271 }
272
273 if (null != sigfile) {
274 cmd.createArg().setValue("-sigfile");
275 cmd.createArg().setValue(sigfile);
276 }
277
278 if (null != jarTarget) {
279 cmd.createArg().setValue("-signedjar");
280 cmd.createArg().setValue(jarTarget.toString());
281 }
282
283 if (verbose) {
284 cmd.createArg().setValue("-verbose");
285 }
286
287 if (internalsf) {
288 cmd.createArg().setValue("-internalsf");
289 }
290
291 if (sectionsonly) {
292 cmd.createArg().setValue("-sectionsonly");
293 }
294
295 cmd.createArg().setValue(jarSource.toString());
296
297 cmd.createArg().setValue(alias);
298
299 log("Signing JAR: " + jarSource.getAbsolutePath());
300 cmd.setFailonerror(true);
301 cmd.setTaskName(getTaskName());
302 cmd.execute();
303 }
304
305 protected boolean isUpToDate(File jarFile, File signedjarFile) {
306 if (null == jarFile) {
307 return false;
308 }
309
310 if (null != signedjarFile) {
311
312 if (!jarFile.exists()) {
313 return false;
314 }
315 if (!signedjarFile.exists()) {
316 return false;
317 }
318 if (jarFile.equals(signedjarFile)) {
319 return false;
320 }
321 if (signedjarFile.lastModified() > jarFile.lastModified()) {
322 return true;
323 }
324 } else {
325 if (lazy) {
326 return isSigned(jarFile);
327 }
328 }
329
330 return false;
331 }
332
333 /**
334 * test for a file being signed, by looking for a signature in the META-INF
335 * directory
336 * @param file
337 * @return true if the file is signed
338 */
339 protected boolean isSigned(File file) {
340 final String SIG_START = "META-INF/";
341 final String SIG_END = ".SF";
342
343 if (!file.exists()) {
344 return false;
345 }
346 ZipFile jarFile = null;
347 try {
348 jarFile = new ZipFile(file);
349 if (null == alias) {
350 Enumeration entries = jarFile.entries();
351 while (entries.hasMoreElements()) {
352 String name = ((ZipEntry) entries.nextElement()).getName();
353 if (name.startsWith(SIG_START) && name.endsWith(SIG_END)) {
354 return true;
355 }
356 }
357 return false;
358 } else {
359 return jarFile.getEntry(SIG_START + alias.toUpperCase()
360 + SIG_END) != null;
361 }
362 } catch (IOException e) {
363 return false;
364 } finally {
365 if (jarFile != null) {
366 try {
367 jarFile.close();
368 } catch (IOException e) {
369 }
370 }
371 }
372 }
373}
374
Note: See TracBrowser for help on using the repository browser.