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 }