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 return readPasswordJava16( prompt );
259 } catch ( IOException e ) {
260 throw e;
261 }
262 catch ( NoSuchMethodException e )
263 {
264 return readPasswordJava15( prompt );
265 }
266 catch ( IllegalAccessException e )
267 {
268 return readPasswordJava15( prompt );
269 }
270 catch ( InvocationTargetException e )
271 {
272 return readPasswordJava15( prompt );
273 }
274 }
275
276 private String readPasswordJava16( String prompt )
277 throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException
278 {
279 Method consoleMethod = System.class.getMethod( "console" );
280 Object console = consoleMethod.invoke( null );
281 if ( console == null )
282 {
283 throw new IllegalAccessException( "console was null" );
284 }
285 Method readPasswordMethod = console.getClass().getMethod( "readPassword", String.class, Object[].class );
286 return new String( (char[]) readPasswordMethod.invoke( console, prompt, null ) );
287 }
288
289 private String readPasswordJava15( String prompt )
290 throws IOException
291 {
292 BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) );
293 while ( System.in.available() != 0 )
294 {
295
296
297 System.in.read();
298 }
299
300 System.out.print( prompt );
301 System.out.print( ' ' );
302 MaskingThread thread = new MaskingThread();
303 thread.start();
304 try
305 {
306
307 return in.readLine();
308 }
309 finally
310 {
311
312 thread.stopMasking();
313
314 }
315 }
316
317
318 class MaskingThread
319 extends Thread
320 {
321 private volatile boolean stop;
322
323
324
325
326 public void run()
327 {
328
329
330
331 int priority = Thread.currentThread().getPriority();
332 Thread.currentThread().setPriority( Thread.MAX_PRIORITY );
333
334 try
335 {
336 stop = false;
337 while ( !stop )
338 {
339
340 System.out.print( "\010*" );
341 try
342 {
343
344 Thread.sleep( 1 );
345 }
346 catch ( InterruptedException iex )
347 {
348 Thread.currentThread().interrupt();
349 return;
350 }
351 }
352 }
353 finally
354 {
355
356 Thread.currentThread().setPriority( priority );
357 }
358 }
359
360
361
362
363 public void stopMasking()
364 {
365 this.stop = true;
366 }
367 }
368 }