1 package org.apache.maven.plugin.gpg;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.File;
24 import java.io.IOException;
25 import java.io.InputStreamReader;
26 import java.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28 import java.util.List;
29
30 import org.apache.maven.plugin.MojoExecutionException;
31 import org.apache.maven.plugin.logging.Log;
32 import org.apache.maven.project.MavenProject;
33
34
35
36
37
38
39
40 public abstract class AbstractGpgSigner
41 {
42 public static final String SIGNATURE_EXTENSION = ".asc";
43
44 protected boolean useAgent;
45
46 protected boolean isInteractive = true;
47
48 protected boolean defaultKeyring = true;
49
50 protected String keyname;
51
52 private Log log;
53
54 protected String passphrase;
55
56 private File outputDir;
57
58 private File buildDir;
59
60 private File baseDir;
61
62 protected File homeDir;
63
64 protected String secretKeyring;
65
66 protected String publicKeyring;
67
68 protected String lockMode;
69
70 protected List<String> args;
71
72 public Log getLog()
73 {
74 return log;
75 }
76
77 public void setArgs( List<String> args )
78 {
79 this.args = args;
80 }
81
82 public void setInteractive( boolean b )
83 {
84 isInteractive = b;
85 }
86
87 public void setLockMode( String lockMode )
88 {
89 this.lockMode = lockMode;
90 }
91
92 public void setUseAgent( boolean b )
93 {
94 useAgent = b;
95 }
96
97 public void setDefaultKeyring( boolean enabled )
98 {
99 defaultKeyring = enabled;
100 }
101
102 public void setKeyName( String s )
103 {
104 keyname = s;
105 }
106
107 public void setLog( Log log )
108 {
109 this.log = log;
110 }
111
112 public void setPassPhrase( String s )
113 {
114 passphrase = s;
115 }
116
117 public void setOutputDirectory( File out )
118 {
119 outputDir = out;
120 }
121
122 public void setBuildDirectory( File out )
123 {
124 buildDir = out;
125 }
126
127 public void setBaseDirectory( File out )
128 {
129 baseDir = out;
130 }
131
132 public void setHomeDirectory( File homeDirectory )
133 {
134 homeDir = homeDirectory;
135 }
136
137 public void setSecretKeyring( String path )
138 {
139 secretKeyring = path;
140 }
141
142 public void setPublicKeyring( String path )
143 {
144 publicKeyring = path;
145 }
146
147
148
149
150
151
152
153
154 public File generateSignatureForArtifact( File file )
155 throws MojoExecutionException
156 {
157
158
159
160
161 File signature = new File( file + SIGNATURE_EXTENSION );
162
163 boolean isInBuildDir = false;
164 if ( buildDir != null )
165 {
166 File parent = signature.getParentFile();
167 if ( buildDir.equals( parent ) )
168 {
169 isInBuildDir = true;
170 }
171 }
172 if ( !isInBuildDir && outputDir != null )
173 {
174 String fileDirectory = "";
175 File signatureDirectory = signature;
176
177 while ( ( signatureDirectory = signatureDirectory.getParentFile() ) != null )
178 {
179 if ( !signatureDirectory.equals( baseDir ) )
180 {
181 fileDirectory = signatureDirectory.getName() + File.separatorChar + fileDirectory;
182 }
183 else
184 {
185 break;
186 }
187 }
188 signatureDirectory = new File( outputDir, fileDirectory );
189 if ( !signatureDirectory.exists() )
190 {
191 signatureDirectory.mkdirs();
192 }
193 signature = new File( signatureDirectory, file.getName() + SIGNATURE_EXTENSION );
194 }
195
196 if ( signature.exists() )
197 {
198 signature.delete();
199 }
200
201
202
203
204
205 generateSignatureForFile( file, signature );
206
207 return signature;
208 }
209
210
211
212
213
214
215
216
217 protected abstract void generateSignatureForFile( File file, File signature )
218 throws MojoExecutionException;
219
220 private MavenProject findReactorProject( MavenProject prj )
221 {
222 if ( prj.getParent() != null && prj.getParent().getBasedir() != null && prj.getParent().getBasedir().exists() )
223 {
224 return findReactorProject( prj.getParent() );
225 }
226 return prj;
227 }
228
229 public String getPassphrase( MavenProject project )
230 throws IOException
231 {
232 String pass = null;
233
234 if ( project != null )
235 {
236 pass = project.getProperties().getProperty( "gpg.passphrase" );
237 if ( pass == null )
238 {
239 MavenProject prj2 = findReactorProject( project );
240 pass = prj2.getProperties().getProperty( "gpg.passphrase" );
241 }
242 }
243 if ( pass == null )
244 {
245 pass = readPassword( "GPG Passphrase: " );
246 }
247 if ( project != null )
248 {
249 findReactorProject( project ).getProperties().setProperty( "gpg.passphrase", pass );
250 }
251 return pass;
252 }
253
254 private String readPassword( String prompt )
255 throws IOException
256 {
257 try
258 {
259 return readPasswordJava16( prompt );
260 }
261 catch ( IOException e )
262 {
263 throw e;
264 }
265 catch ( NoSuchMethodException e )
266 {
267 return readPasswordJava15( prompt );
268 }
269 catch ( IllegalAccessException e )
270 {
271 return readPasswordJava15( prompt );
272 }
273 catch ( InvocationTargetException e )
274 {
275 return readPasswordJava15( prompt );
276 }
277 }
278
279 private String readPasswordJava16( String prompt )
280 throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException
281 {
282 Method consoleMethod = System.class.getMethod( "console" );
283 Object console = consoleMethod.invoke( null );
284 if ( console == null )
285 {
286 throw new IllegalAccessException( "console was null" );
287 }
288 Method readPasswordMethod = console.getClass().getMethod( "readPassword", String.class, Object[].class );
289 return new String( (char[]) readPasswordMethod.invoke( console, prompt, null ) );
290 }
291
292 private String readPasswordJava15( String prompt )
293 throws IOException
294 {
295 BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) );
296 while ( System.in.available() != 0 )
297 {
298
299
300 System.in.read();
301 }
302
303 System.out.print( prompt );
304 System.out.print( ' ' );
305 MaskingThread thread = new MaskingThread();
306 thread.start();
307 try
308 {
309
310 return in.readLine();
311 }
312 finally
313 {
314
315 thread.stopMasking();
316
317 }
318 }
319
320
321 class MaskingThread
322 extends Thread
323 {
324 private volatile boolean stop;
325
326
327
328
329 public void run()
330 {
331
332
333
334 int priority = Thread.currentThread().getPriority();
335 Thread.currentThread().setPriority( Thread.MAX_PRIORITY );
336
337 try
338 {
339 stop = false;
340 while ( !stop )
341 {
342
343 System.out.print( "\010*" );
344 try
345 {
346
347 Thread.sleep( 1 );
348 }
349 catch ( InterruptedException iex )
350 {
351 Thread.currentThread().interrupt();
352 return;
353 }
354 }
355 }
356 finally
357 {
358
359 Thread.currentThread().setPriority( priority );
360 }
361 }
362
363
364
365
366 public void stopMasking()
367 {
368 this.stop = true;
369 }
370 }
371 }