View Javadoc
1   package org.apache.maven.plugins.gpg;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.util.List;
25  
26  import org.apache.maven.plugin.MojoExecutionException;
27  import org.apache.maven.plugin.logging.Log;
28  import org.apache.maven.project.MavenProject;
29  
30  /**
31   * A base class for all classes that implements signing of files.
32   *
33   * @author Dennis Lundberg
34   * @since 1.5
35   */
36  public abstract class AbstractGpgSigner
37  {
38      private static final String GPG_PASSPHRASE = "gpg.passphrase";
39  
40      public static final String SIGNATURE_EXTENSION = ".asc";
41  
42      protected boolean useAgent;
43  
44      protected boolean isInteractive = true;
45  
46      protected boolean defaultKeyring = true;
47  
48      protected String keyname;
49  
50      private Log log;
51  
52      protected String passphrase;
53  
54      private File outputDir;
55  
56      private File buildDir;
57  
58      private File baseDir;
59  
60      protected File homeDir;
61  
62      protected String secretKeyring;
63  
64      protected String publicKeyring;
65  
66      protected String lockMode;
67  
68      protected List<String> args;
69  
70      public Log getLog()
71      {
72          return log;
73      }
74  
75      public void setArgs( List<String> args )
76      {
77          this.args = args;
78      }
79  
80      public void setInteractive( boolean b )
81      {
82          isInteractive = b;
83      }
84  
85      public void setLockMode( String lockMode )
86      {
87          this.lockMode = lockMode;
88      }
89  
90      public void setUseAgent( boolean b )
91      {
92          useAgent = b;
93      }
94  
95      public void setDefaultKeyring( boolean enabled )
96      {
97          defaultKeyring = enabled;
98      }
99  
100     public void setKeyName( String s )
101     {
102         keyname = s;
103     }
104 
105     public void setLog( Log log )
106     {
107         this.log = log;
108     }
109 
110     public void setPassPhrase( String s )
111     {
112         passphrase = s;
113     }
114 
115     public void setOutputDirectory( File out )
116     {
117         outputDir = out;
118     }
119 
120     public void setBuildDirectory( File out )
121     {
122         buildDir = out;
123     }
124 
125     public void setBaseDirectory( File out )
126     {
127         baseDir = out;
128     }
129 
130     public void setHomeDirectory( File homeDirectory )
131     {
132         homeDir = homeDirectory;
133     }
134 
135     public void setSecretKeyring( String path )
136     {
137         secretKeyring = path;
138     }
139 
140     public void setPublicKeyring( String path )
141     {
142         publicKeyring = path;
143     }
144 
145     /**
146      * Create a detached signature file for the provided file.
147      *
148      * @param file The file to sign
149      * @return A reference to the generated signature file
150      * @throws MojoExecutionException if signature generation fails
151      */
152     public File generateSignatureForArtifact( File file )
153         throws MojoExecutionException
154     {
155         // ----------------------------------------------------------------------------
156         // Set up the file and directory for the signature file
157         // ----------------------------------------------------------------------------
158 
159         File signature = new File( file + SIGNATURE_EXTENSION );
160 
161         boolean isInBuildDir = false;
162         if ( buildDir != null )
163         {
164             File parent = signature.getParentFile();
165             if ( buildDir.equals( parent ) )
166             {
167                 isInBuildDir = true;
168             }
169         }
170         if ( !isInBuildDir && outputDir != null )
171         {
172             String fileDirectory = "";
173             File signatureDirectory = signature;
174 
175             while ( ( signatureDirectory = signatureDirectory.getParentFile() ) != null )
176             {
177                 if ( !signatureDirectory.equals( baseDir ) )
178                 {
179                     fileDirectory = signatureDirectory.getName() + File.separatorChar + fileDirectory;
180                 }
181                 else
182                 {
183                     break;
184                 }
185             }
186             signatureDirectory = new File( outputDir, fileDirectory );
187             if ( !signatureDirectory.exists() )
188             {
189                 signatureDirectory.mkdirs();
190             }
191             signature = new File( signatureDirectory, file.getName() + SIGNATURE_EXTENSION );
192         }
193 
194         if ( signature.exists() )
195         {
196             signature.delete();
197         }
198 
199         // ----------------------------------------------------------------------------
200         // Generate the signature file
201         // ----------------------------------------------------------------------------
202 
203         generateSignatureForFile( file, signature );
204 
205         return signature;
206     }
207 
208     /**
209      * Generate the detached signature file for the provided file.
210      *
211      * @param file The file to sign
212      * @param signature The file in which the generate signature will be put
213      * @throws MojoExecutionException if signature generation fails
214      */
215     protected abstract void generateSignatureForFile( File file, File signature )
216         throws MojoExecutionException;
217 
218     private MavenProject findReactorProject( MavenProject prj )
219     {
220         if ( prj.getParent() != null && prj.getParent().getBasedir() != null && prj.getParent().getBasedir().exists() )
221         {
222             return findReactorProject( prj.getParent() );
223         }
224         return prj;
225     }
226 
227     public String getPassphrase( MavenProject project )
228         throws IOException
229     {
230         String pass = null;
231 
232         if ( project != null )
233         {
234             pass = project.getProperties().getProperty( GPG_PASSPHRASE );
235             if ( pass == null )
236             {
237                 MavenProject prj2 = findReactorProject( project );
238                 pass = prj2.getProperties().getProperty( GPG_PASSPHRASE );
239             }
240         }
241         if ( pass == null )
242         {
243             pass = new String( readPassword( "GPG Passphrase: " ) );
244         }
245         if ( project != null )
246         {
247             findReactorProject( project ).getProperties().setProperty( GPG_PASSPHRASE, pass );
248         }
249         return pass;
250     }
251 
252     private char[] readPassword( String prompt )
253         throws IOException
254     {
255         return System.console().readPassword();
256     }
257 }