1 package org.apache.maven.plugins.jarsigner;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedInputStream;
23 import java.io.BufferedOutputStream;
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.util.zip.ZipEntry;
29 import java.util.zip.ZipInputStream;
30 import java.util.zip.ZipOutputStream;
31
32 import org.apache.maven.plugin.MojoExecutionException;
33 import org.codehaus.plexus.util.FileUtils;
34 import org.codehaus.plexus.util.IOUtil;
35 import org.codehaus.plexus.util.StringUtils;
36 import org.codehaus.plexus.util.cli.Commandline;
37
38
39
40
41
42
43
44
45
46
47 public class JarsignerSignMojo
48 extends AbstractJarsignerMojo
49 {
50
51
52
53
54
55
56 private String keystore;
57
58
59
60
61
62
63 private String storepass;
64
65
66
67
68
69
70 private String keypass;
71
72
73
74
75
76
77 private String sigfile;
78
79
80
81
82
83
84 private String storetype;
85
86
87
88
89
90
91 private String providerName;
92
93
94
95
96
97
98 private String providerClass;
99
100
101
102
103
104
105 private String providerArg;
106
107
108
109
110
111
112
113 private String alias;
114
115
116
117
118
119
120
121
122 private boolean removeExistingSignatures;
123
124 protected Commandline getCommandline( final File archive, final Commandline commandLine )
125 {
126 if ( archive == null )
127 {
128 throw new NullPointerException( "archive" );
129 }
130 if ( commandLine == null )
131 {
132 throw new NullPointerException( "commandLine" );
133 }
134
135 if ( !StringUtils.isEmpty( this.keystore ) )
136 {
137 commandLine.createArg().setValue( "-keystore" );
138 commandLine.createArg().setValue( this.keystore );
139 }
140 if ( !StringUtils.isEmpty( this.storepass ) )
141 {
142 commandLine.createArg().setValue( "-storepass" );
143 commandLine.createArg().setValue( this.storepass );
144 }
145 if ( !StringUtils.isEmpty( this.keypass ) )
146 {
147 commandLine.createArg().setValue( "-keypass" );
148 commandLine.createArg().setValue( this.keypass );
149 }
150 if ( !StringUtils.isEmpty( this.storetype ) )
151 {
152 commandLine.createArg().setValue( "-storetype" );
153 commandLine.createArg().setValue( this.storetype );
154 }
155 if ( !StringUtils.isEmpty( this.providerName ) )
156 {
157 commandLine.createArg().setValue( "-providerName" );
158 commandLine.createArg().setValue( this.providerName );
159 }
160 if ( !StringUtils.isEmpty( this.providerClass ) )
161 {
162 commandLine.createArg().setValue( "-providerClass" );
163 commandLine.createArg().setValue( this.providerClass );
164 }
165 if ( !StringUtils.isEmpty( this.providerArg ) )
166 {
167 commandLine.createArg().setValue( "-providerArg" );
168 commandLine.createArg().setValue( this.providerArg );
169 }
170 if ( !StringUtils.isEmpty( this.sigfile ) )
171 {
172 commandLine.createArg().setValue( "-sigfile" );
173 commandLine.createArg().setValue( this.sigfile );
174 }
175
176 commandLine.createArg().setFile( archive );
177
178 if ( !StringUtils.isEmpty( this.alias ) )
179 {
180 commandLine.createArg().setValue( this.alias );
181 }
182
183 return commandLine;
184 }
185
186 protected String getCommandlineInfo( final Commandline commandLine )
187 {
188 String commandLineInfo = commandLine != null ? commandLine.toString() : null;
189
190 if ( commandLineInfo != null )
191 {
192 commandLineInfo = StringUtils.replace( commandLineInfo, this.keypass, "'*****'" );
193 commandLineInfo = StringUtils.replace( commandLineInfo, this.storepass, "'*****'" );
194 }
195
196 return commandLineInfo;
197 }
198
199 protected void preProcessArchive( final File archive )
200 throws MojoExecutionException
201 {
202 if ( removeExistingSignatures )
203 {
204 unsignArchive( archive );
205 }
206 }
207
208
209
210
211
212
213
214
215 private void unsignArchive( final File jarFile )
216 throws MojoExecutionException
217 {
218 if ( getLog().isDebugEnabled() )
219 {
220 getLog().debug( "Unsigning " + jarFile );
221 }
222
223 File unsignedFile = new File( jarFile.getAbsolutePath() + ".unsigned" );
224
225 ZipInputStream zis = null;
226 ZipOutputStream zos = null;
227 try
228 {
229 zis = new ZipInputStream( new BufferedInputStream( new FileInputStream( jarFile ) ) );
230 zos = new ZipOutputStream( new BufferedOutputStream( new FileOutputStream( unsignedFile ) ) );
231
232 for ( ZipEntry ze = zis.getNextEntry(); ze != null; ze = zis.getNextEntry() )
233 {
234 if ( isSignatureFile( ze.getName() ) )
235 {
236 if ( getLog().isDebugEnabled() )
237 {
238 getLog().debug( " Removing " + ze.getName() );
239 }
240
241 continue;
242 }
243
244 zos.putNextEntry( ze );
245
246 IOUtil.copy( zis, zos );
247 }
248
249 }
250 catch ( IOException e )
251 {
252 throw new MojoExecutionException( "Failed to unsign archive " + jarFile + ": " + e.getMessage(), e );
253 }
254 finally
255 {
256 IOUtil.close( zis );
257 IOUtil.close( zos );
258 }
259
260 try
261 {
262 FileUtils.rename( unsignedFile, jarFile );
263 }
264 catch ( IOException e )
265 {
266 throw new MojoExecutionException( "Failed to unsign archive " + jarFile + ": " + e.getMessage(), e );
267 }
268 }
269
270
271
272
273
274
275
276
277 private boolean isSignatureFile( String entryName )
278 {
279 if ( entryName.regionMatches( true, 0, "META-INF", 0, 8 ) )
280 {
281 entryName = entryName.replace( '\\', '/' );
282
283 if ( entryName.indexOf( '/' ) == 8 && entryName.lastIndexOf( '/' ) == 8 )
284 {
285 if ( entryName.regionMatches( true, entryName.length() - 3, ".SF", 0, 3 ) )
286 {
287 return true;
288 }
289 if ( entryName.regionMatches( true, entryName.length() - 4, ".DSA", 0, 4 ) )
290 {
291 return true;
292 }
293 if ( entryName.regionMatches( true, entryName.length() - 4, ".RSA", 0, 4 ) )
294 {
295 return true;
296 }
297 }
298 }
299
300 return false;
301 }
302
303 }