001: /*******************************************************************************
002: * Copyright (c) 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.build.jarprocessor;
011:
012: import java.io.*;
013: import java.util.Enumeration;
014: import java.util.jar.JarFile;
015: import java.util.jar.Manifest;
016: import java.util.zip.*;
017:
018: /**
019: * This class removes the signature files from a jar and clean up the manifest.
020: */
021: public class Unsigner {
022: private static final String META_INF = "META-INF"; //$NON-NLS-1$
023: private static final String DSA_EXT = ".DSA"; //$NON-NLS-1$
024: private static final String RSA_EXT = ".RSA"; //$NON-NLS-1$
025: private static final String SF_EXT = ".SF"; //$NON-NLS-1$
026: private static final String META_INF_PREFIX = META_INF + '/';
027:
028: private String[] signers;
029: private File jarFile;
030: private boolean keepManifestContent = false;
031:
032: private boolean isSigned(File file) {
033: ZipFile jar = null;
034: try {
035: jar = new ZipFile(file);
036:
037: if (signers != null) {
038: for (int i = 0; i < signers.length; i++) {
039: if (jar
040: .getEntry((META_INF_PREFIX + signers[i] + SF_EXT)
041: .toUpperCase()) != null)
042: return true;
043: }
044: } else {
045: Enumeration entries = jar.entries();
046: while (entries.hasMoreElements()) {
047: ZipEntry entry = (ZipEntry) entries.nextElement();
048: String entryName = entry.getName();
049: if (entryName.endsWith(SF_EXT)
050: && entryName.startsWith(META_INF))
051: return true;
052: }
053: }
054: return false;
055: } catch (ZipException e) {
056: return false;
057: } catch (IOException e) {
058: return false;
059: } finally {
060: if (jar != null)
061: try {
062: jar.close();
063: } catch (IOException e) {
064: //Ignore
065: }
066: }
067: }
068:
069: public void execute() {
070: processJar(jarFile);
071: }
072:
073: private void processJar(File inputFile) {
074: if (!isSigned(inputFile))
075: return;
076:
077: try {
078: ZipInputStream input = new ZipInputStream(
079: new BufferedInputStream(new FileInputStream(
080: inputFile)));
081: File outputFile = File
082: .createTempFile(
083: "removing.", ".signature", inputFile.getParentFile()); //$NON-NLS-1$ //$NON-NLS-2$
084: ZipOutputStream output = new ZipOutputStream(
085: new BufferedOutputStream(new FileOutputStream(
086: outputFile)));
087:
088: ZipEntry inputZe = input.getNextEntry();
089: byte[] b = new byte[8192];
090: while (inputZe != null) {
091: byte remove = shouldRemove(inputZe);
092: if (remove == 2) {
093: inputZe = input.getNextEntry();
094: continue;
095: }
096:
097: //copy the file or modify the manifest.mf
098: if (remove == 1) {
099: output
100: .putNextEntry(new ZipEntry(inputZe
101: .getName()));
102: Manifest m = new Manifest();
103: m.read(input);
104: m.getEntries().clear(); //This is probably not subtle enough
105: m.write(output);
106: } else {
107: output.putNextEntry(inputZe);
108: while (input.available() != 0) {
109: int read = input.read(b);
110: if (read != -1)
111: output.write(b, 0, read);
112: }
113: }
114: output.closeEntry();
115: input.closeEntry();
116:
117: inputZe = input.getNextEntry();
118: }
119: output.close();
120: input.close();
121: inputFile.delete();
122: outputFile.renameTo(inputFile);
123: } catch (FileNotFoundException e) {
124: //this can't happen we have checked before
125: } catch (IOException e) {
126: e.printStackTrace();
127: }
128: }
129:
130: private byte shouldRemove(ZipEntry entry) {
131: String entryName = entry.getName();
132: if (keepManifestContent == false
133: && entryName.equalsIgnoreCase(JarFile.MANIFEST_NAME)) {
134: return 1;
135: }
136: if (signers != null) {
137: for (int i = 0; i < signers.length; i++) {
138: if (entryName.equalsIgnoreCase(META_INF_PREFIX
139: + signers[i] + SF_EXT)
140: || entryName.equalsIgnoreCase(META_INF_PREFIX
141: + signers[i] + RSA_EXT)
142: || entryName.equalsIgnoreCase(META_INF_PREFIX
143: + signers[i] + DSA_EXT))
144: return 2;
145: }
146: } else {
147: if (entryName.startsWith(META_INF)
148: && (entryName.endsWith(SF_EXT)
149: || entryName.endsWith(RSA_EXT) || entryName
150: .endsWith(DSA_EXT)))
151: return 2;
152: }
153: return 0;
154: }
155:
156: public void setRemoveSigners(String[] fileName) {
157: signers = fileName;
158: }
159:
160: public void setJar(File file) {
161: jarFile = file;
162: }
163:
164: public void setKeepManifestEntries(boolean keep) {
165: keepManifestContent = keep;
166: }
167: }
|