You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by br...@apache.org on 2008/07/17 09:26:24 UTC

svn commit: r677522 - in /maven/artifact/branches/MNG-2477: ./ src/main/java/org/apache/maven/artifact/manager/ src/main/java/org/apache/maven/artifact/repository/ src/test/java/org/apache/maven/artifact/manager/ src/test/resources/

Author: brett
Date: Thu Jul 17 00:26:23 2008
New Revision: 677522

URL: http://svn.apache.org/viewvc?rev=677522&view=rev
Log:
[MNG-2477] additions to wagon manager and policy to handle the verification of detached PGP signatures

Added:
    maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/SignatureFailedException.java   (with props)
    maven/artifact/branches/MNG-2477/src/test/resources/other-test-signature.asc
    maven/artifact/branches/MNG-2477/src/test/resources/pubring.gpg
      - copied unchanged from r675341, commons/sandbox/openpgp/trunk/src/test/resources/pubring.gpg
    maven/artifact/branches/MNG-2477/src/test/resources/secring.gpg
      - copied unchanged from r675341, commons/sandbox/openpgp/trunk/src/test/resources/secring.gpg
    maven/artifact/branches/MNG-2477/src/test/resources/test-signature.asc
    maven/artifact/branches/MNG-2477/src/test/resources/unknown-but-valid-signature.asc
Modified:
    maven/artifact/branches/MNG-2477/pom.xml
    maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java
    maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/WagonManager.java
    maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryPolicy.java
    maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepository.java
    maven/artifact/branches/MNG-2477/src/test/java/org/apache/maven/artifact/manager/DefaultWagonManagerTest.java

Modified: maven/artifact/branches/MNG-2477/pom.xml
URL: http://svn.apache.org/viewvc/maven/artifact/branches/MNG-2477/pom.xml?rev=677522&r1=677521&r2=677522&view=diff
==============================================================================
--- maven/artifact/branches/MNG-2477/pom.xml (original)
+++ maven/artifact/branches/MNG-2477/pom.xml Thu Jul 17 00:26:23 2008
@@ -85,6 +85,14 @@
       <version>${wagon.version}</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.maven.wagon</groupId>
+      <artifactId>wagon-openpgp</artifactId>
+      <!-- 
+      <version>${wagon.version}</version>
+       -->
+      <version>1.0-beta-4-SNAPSHOT</version>
+    </dependency>
+    <dependency>
       <groupId>aspectj</groupId>
       <artifactId>aspectjrt</artifactId>
       <version>1.5.3</version>

Modified: maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java
URL: http://svn.apache.org/viewvc/maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java?rev=677522&r1=677521&r2=677522&view=diff
==============================================================================
--- maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java (original)
+++ maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java Thu Jul 17 00:26:23 2008
@@ -20,7 +20,9 @@
  */
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.security.NoSuchAlgorithmException;
@@ -31,6 +33,9 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.openpgp.BouncyCastleKeyRing;
+import org.apache.commons.openpgp.KeyRing;
+import org.apache.commons.openpgp.OpenPgpException;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.metadata.ArtifactMetadata;
 import org.apache.maven.artifact.repository.ArtifactRepository;
@@ -42,14 +47,17 @@
 import org.apache.maven.wagon.TransferFailedException;
 import org.apache.maven.wagon.UnsupportedProtocolException;
 import org.apache.maven.wagon.Wagon;
+import org.apache.maven.wagon.WagonException;
 import org.apache.maven.wagon.authentication.AuthenticationException;
 import org.apache.maven.wagon.authentication.AuthenticationInfo;
 import org.apache.maven.wagon.authorization.AuthorizationException;
 import org.apache.maven.wagon.events.TransferListener;
 import org.apache.maven.wagon.observers.ChecksumObserver;
+import org.apache.maven.wagon.openpgp.WagonOpenPgpSignatureVerifierObserver;
 import org.apache.maven.wagon.proxy.ProxyInfo;
 import org.apache.maven.wagon.repository.Repository;
 import org.apache.maven.wagon.repository.RepositoryPermissions;
+import org.bouncycastle.openpgp.PGPException;
 import org.codehaus.plexus.PlexusConstants;
 import org.codehaus.plexus.PlexusContainer;
 import org.codehaus.plexus.component.configurator.BasicComponentConfigurator;
@@ -63,6 +71,7 @@
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
 import org.codehaus.plexus.util.xml.Xpp3Dom;
 
 /** @plexus.component */
@@ -118,6 +127,8 @@
     /** @plexus.requirement */
     private UpdateCheckManager updateCheckManager;
 
+    private KeyRing keyRing = new BouncyCastleKeyRing();
+
     // TODO: this leaks the component in the public api - it is never released back to the container
     public Wagon getWagon( Repository repository )
         throws UnsupportedProtocolException, WagonConfigurationException
@@ -353,8 +364,12 @@
             }
             catch ( TransferFailedException e )
             {
-                getLogger().debug( "Unable to get resource '" + artifact.getId() + "' from repository " +
-                    repository.getId() + " (" + repository.getUrl() + ")", e );
+                String msg =
+                    "Unable to get resource '" + artifact.getId() + "' from repository " + repository.getId() + " ("
+                        + repository.getUrl() + ")\nDue to: " + e.getMessage()
+                        + "\nRemaining repositories will be checked before failing.";
+                getLogger().warn( msg );
+                getLogger().debug( "Unable to get resource", e );
             }
         }
 
@@ -400,7 +415,7 @@
             try
             {
                 getRemoteFile( getMirrorRepository( repository ), artifact.getFile(), remotePath, downloadMonitor,
-                               policy.getChecksumPolicy(), false );
+                               policy, false );
             }
             finally
             {
@@ -426,7 +441,7 @@
                 try
                 {
                     getRemoteFile( getMirrorRepository( repository ), artifact.getFile(), remotePath, downloadMonitor,
-                                   policy.getChecksumPolicy(), false );
+                                   policy, false );
                 }
                 catch ( ResourceDoesNotExistException e )
                 {
@@ -458,7 +473,8 @@
         {
             getLogger().debug( "Trying repository " + repository.getId() );
 
-            getRemoteFile( getMirrorRepository( repository ), artifact.getFile(), remotePath, downloadMonitor, policy.getChecksumPolicy(), false );
+            getRemoteFile( getMirrorRepository( repository ), artifact.getFile(), remotePath, downloadMonitor, policy,
+                           false );
 
             getLogger().debug( "  Artifact resolved" );
 
@@ -474,7 +490,8 @@
     {
         String remotePath = repository.pathOfRemoteRepositoryMetadata( metadata );
 
-        getRemoteFile( getMirrorRepository( repository ), destination, remotePath, null, checksumPolicy, true );
+        getRemoteFile( getMirrorRepository( repository ), destination, remotePath, null, checksumPolicy,
+                       ArtifactRepositoryPolicy.SIGNATURE_POLICY_IGNORE, true );
     }
 
     public void getArtifactMetadataFromDeploymentRepository( ArtifactMetadata metadata, ArtifactRepository repository,
@@ -483,18 +500,35 @@
     {
         String remotePath = repository.pathOfRemoteRepositoryMetadata( metadata );
 
-        getRemoteFile( repository, destination, remotePath, null, checksumPolicy, true );
+        getRemoteFile( repository, destination, remotePath, null, checksumPolicy,
+                       ArtifactRepositoryPolicy.SIGNATURE_POLICY_IGNORE, true );
     }
 
     private void getRemoteFile( ArtifactRepository repository,
                                 File destination,
                                 String remotePath,
                                 TransferListener downloadMonitor,
+                                ArtifactRepositoryPolicy policy,
+                                boolean force )
+        throws TransferFailedException, ResourceDoesNotExistException
+    {
+        String checksumPolicy = policy.getChecksumPolicy();
+        
+        String signaturePolicy = policy.getSignaturePolicy();
+        
+        getRemoteFile( repository, destination, remotePath, downloadMonitor, checksumPolicy, signaturePolicy, force );
+    }
+    
+    private void getRemoteFile( ArtifactRepository repository,
+                                File destination,
+                                String remotePath,
+                                TransferListener downloadMonitor,
                                 String checksumPolicy,
+                                String signaturePolicy,
                                 boolean force )
         throws TransferFailedException, ResourceDoesNotExistException
     {
-        // TODO: better excetpions - transfer failed is not enough?
+        // TODO: better exceptions - transfer failed is not enough?
 
         failIfNotOnline();
 
@@ -524,11 +558,45 @@
 
         boolean downloaded = false;
 
+        WagonOpenPgpSignatureVerifierObserver pgpObserver = null;
         try
         {
             wagon.connect( new Repository( repository.getId(), repository.getUrl() ),
                 getAuthenticationInfo( repository.getId() ), getProxy( protocol ) );
 
+            // don't fetch the signature if it's ignored
+            if ( !ArtifactRepositoryPolicy.SIGNATURE_POLICY_IGNORE.equalsIgnoreCase( signaturePolicy ) )
+            {                
+                try
+                {
+                    pgpObserver = getTempSignatureFile( destination, remotePath, wagon );
+                }
+                catch ( SignatureFailedException e )
+                {
+                    if ( ArtifactRepositoryPolicy.SIGNATURE_POLICY_FAIL.equalsIgnoreCase( signaturePolicy ) )
+                    {
+                        throw e;
+                    }
+                    else
+                    {
+                        getLogger().warn( e.getMessage() );
+                    }
+                }
+                catch ( IOException e )
+                {
+                    String msg = "An error occurred reading the signature file: " + e.getMessage();
+                    if ( ArtifactRepositoryPolicy.SIGNATURE_POLICY_FAIL.equalsIgnoreCase( signaturePolicy ) )
+                    {
+                        throw new SignatureFailedException( msg, e );
+                    }
+                    else
+                    {
+                        getLogger().warn( msg );
+                        getLogger().debug( msg, e );
+                    }
+                }
+            }
+            
             boolean firstRun = true;
             boolean retry = true;
 
@@ -546,7 +614,10 @@
 
                     md5ChecksumObserver = addChecksumObserver( wagon, CHECKSUM_ALGORITHMS[i++] );
                     sha1ChecksumObserver = addChecksumObserver( wagon, CHECKSUM_ALGORITHMS[i++] );
-
+                    if ( pgpObserver != null )
+                    {
+                        wagon.addTransferListener( pgpObserver );
+                    }
                     // reset the retry flag.
                     retry = false;
 
@@ -579,6 +650,10 @@
                 }
                 finally
                 {
+                    if ( pgpObserver != null )
+                    {
+                        wagon.removeTransferListener( pgpObserver );
+                    }
                     wagon.removeTransferListener( md5ChecksumObserver );
                     wagon.removeTransferListener( sha1ChecksumObserver );
                 }
@@ -685,6 +760,22 @@
 
         if ( downloaded )
         {
+            if ( pgpObserver != null )
+            {
+                if ( !pgpObserver.getStatus().isValid() )
+                {
+                    String msg = "Invalid signature for artifact '" + remotePath + "'";
+                    if ( ArtifactRepositoryPolicy.SIGNATURE_POLICY_FAIL.equalsIgnoreCase( signaturePolicy ) )
+                    {
+                        throw new SignatureFailedException( msg );
+                    }
+                    else
+                    {
+                        getLogger().warn( msg );
+                    }
+                }
+            }
+            
             if ( !temp.exists() )
             {
                 throw new ResourceDoesNotExistException( "Downloaded file does not exist: " + temp );
@@ -713,6 +804,61 @@
         }
     }
 
+    private WagonOpenPgpSignatureVerifierObserver getTempSignatureFile( File destination, String remotePath, Wagon wagon )
+        throws IOException, SignatureFailedException
+    {
+        WagonOpenPgpSignatureVerifierObserver pgpObserver = null;
+        
+        if ( downloadMonitor != null )
+        {
+            wagon.removeTransferListener( downloadMonitor );
+        }
+
+        File sigFile = null;
+        try
+        {
+            File tempSignatureFile = getRemoteVerificationFile( destination, remotePath, ".asc", wagon );
+            sigFile = copyTempFile( destination, ".asc", tempSignatureFile );
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            getLogger().debug( e.getMessage(), e );
+            throw new SignatureFailedException( "No signature was found for the artifact in the remote repository: '"
+                + remotePath + "'" );
+        }
+        catch ( WagonException e )
+        {
+            getLogger().debug( e.getMessage(), e );
+            throw new SignatureFailedException( "An error occurred receiving the remote signature for: '" + remotePath
+                + "': " + e.getMessage() );
+        }
+        finally
+        {
+            if ( downloadMonitor != null )
+            {
+                wagon.addTransferListener( downloadMonitor );
+            }
+        }
+        
+        InputStream signature = null;
+        try
+        {
+            signature = new FileInputStream( sigFile );
+            
+            pgpObserver = new WagonOpenPgpSignatureVerifierObserver( signature, keyRing );
+        }
+        catch ( OpenPgpException e )
+        {
+            throw new SignatureFailedException( "An error occurred reading the signature file: '" + remotePath + "': "
+                + e.getMessage(), e );
+        }
+        finally
+        {
+            IOUtil.close( signature );
+        }
+        return pgpObserver;
+    }
+
     public ArtifactRepository getMirrorRepository( ArtifactRepository repository )
     {
         ArtifactRepository mirror = getMirror( repository );
@@ -765,17 +911,27 @@
                                  String remotePath,
                                  String checksumFileExtension,
                                  Wagon wagon )
-        throws ResourceDoesNotExistException, TransferFailedException, AuthorizationException
-    {
+        throws ResourceDoesNotExistException, ChecksumFailedException
+    {        
+        // grab it first, because it's about to change...
+        String actualChecksum = checksumObserver.getActualChecksum();
+
+        File tempChecksumFile;
         try
         {
-            // grab it first, because it's about to change...
-            String actualChecksum = checksumObserver.getActualChecksum();
-
-            File tempChecksumFile = new File( tempDestination + checksumFileExtension + ".tmp" );
-            tempChecksumFile.deleteOnExit();
-            wagon.get( remotePath + checksumFileExtension, tempChecksumFile );
+            tempChecksumFile = getRemoteVerificationFile( tempDestination, remotePath, checksumFileExtension, wagon );
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            throw e;
+        }
+        catch ( WagonException e )
+        {
+            throw new ChecksumFailedException( "An error occurred receiving the remote checksum: " + e.getMessage(), e );
+        }
 
+        try
+        {
             String expectedChecksum = FileUtils.fileRead( tempChecksumFile, "UTF-8" );
 
             // remove whitespaces at the end
@@ -799,13 +955,7 @@
             }
             if ( expectedChecksum.equalsIgnoreCase( actualChecksum ) )
             {
-                File checksumFile = new File( destination + checksumFileExtension );
-                if ( checksumFile.exists() )
-                {
-                    checksumFile.delete();
-                }
-                FileUtils.copyFile( tempChecksumFile, checksumFile );
-                tempChecksumFile.delete();
+                copyTempFile( destination, checksumFileExtension, tempChecksumFile );
             }
             else
             {
@@ -819,6 +969,30 @@
         }
     }
 
+    private File getRemoteVerificationFile( File tempDestination, String remotePath, String extension, Wagon wagon )
+        throws ResourceDoesNotExistException, WagonException
+    {
+        getLogger().debug( "Retrieving: " + remotePath + extension );
+        File tempChecksumFile = new File( tempDestination + extension + ".tmp" );
+        tempChecksumFile.deleteOnExit();
+        wagon.get( remotePath + extension, tempChecksumFile );
+        return tempChecksumFile;
+    }
+
+    private File copyTempFile( File destination, String extension, File tempFile )
+        throws IOException
+    {
+        File checksumFile = new File( destination + extension );
+        if ( checksumFile.exists() )
+        {
+            checksumFile.delete();
+        }
+        FileUtils.copyFile( tempFile, checksumFile );
+        tempFile.delete();
+        
+        return checksumFile;
+    }
+
 
     private void disconnectWagon( Wagon wagon )
     {
@@ -1180,6 +1354,15 @@
 
         serverConfigurationMap.put( repositoryId, xmlConf );
     }
+    
+    public void registerPublicKeyRing( InputStream inputStream )
+        throws IOException, PGPException
+    {
+        // TODO: remove PGPException
+        this.keyRing.addPublicKeyRing( inputStream );
+        
+        // TODO: debug logging of keys
+    }
 
     public void setDefaultRepositoryPermissions( RepositoryPermissions defaultRepositoryPermissions )
     {

Added: maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/SignatureFailedException.java
URL: http://svn.apache.org/viewvc/maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/SignatureFailedException.java?rev=677522&view=auto
==============================================================================
--- maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/SignatureFailedException.java (added)
+++ maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/SignatureFailedException.java Thu Jul 17 00:26:23 2008
@@ -0,0 +1,42 @@
+package org.apache.maven.artifact.manager;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.wagon.TransferFailedException;
+
+/**
+ * Occurs when a download signature verification fails.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @version $Id: ChecksumFailedException.java 638298 2008-03-18 10:05:50Z bentmann $
+ */
+public class SignatureFailedException
+    extends TransferFailedException
+{
+    public SignatureFailedException( String s )
+    {
+        super( s );
+    }
+
+    public SignatureFailedException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+}

Propchange: maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/SignatureFailedException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/SignatureFailedException.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/WagonManager.java
URL: http://svn.apache.org/viewvc/maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/WagonManager.java?rev=677522&r1=677521&r2=677522&view=diff
==============================================================================
--- maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/WagonManager.java (original)
+++ maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/manager/WagonManager.java Thu Jul 17 00:26:23 2008
@@ -19,6 +19,12 @@
  * under the License.
  */
 
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.List;
+
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.metadata.ArtifactMetadata;
 import org.apache.maven.artifact.repository.ArtifactRepository;
@@ -31,15 +37,10 @@
 import org.apache.maven.wagon.proxy.ProxyInfo;
 import org.apache.maven.wagon.repository.Repository;
 import org.apache.maven.wagon.repository.RepositoryPermissions;
+import org.bouncycastle.openpgp.PGPException;
 import org.codehaus.plexus.PlexusContainer;
 import org.codehaus.plexus.util.xml.Xpp3Dom;
 
-import java.io.File;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * Manages <a href="http://maven.apache.org/wagon">Wagon</a> related operations in Maven.
  *
@@ -173,4 +174,7 @@
     void setDefaultRepositoryPermissions( RepositoryPermissions permissions );
 
     ArtifactRepository getMirrorRepository( ArtifactRepository repository );
+
+    void registerPublicKeyRing( InputStream fileInputStream )
+        throws IOException, PGPException;
 }

Modified: maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryPolicy.java
URL: http://svn.apache.org/viewvc/maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryPolicy.java?rev=677522&r1=677521&r2=677522&view=diff
==============================================================================
--- maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryPolicy.java (original)
+++ maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryPolicy.java Thu Jul 17 00:26:23 2008
@@ -45,11 +45,19 @@
 
     public static final String CHECKSUM_POLICY_IGNORE = "ignore";
 
+    public static final String SIGNATURE_POLICY_FAIL = "fail";
+
+    public static final String SIGNATURE_POLICY_WARN = "warn";
+
+    public static final String SIGNATURE_POLICY_IGNORE = "ignore";
+
     private boolean enabled;
 
     private String updatePolicy;
 
     private String checksumPolicy;
+    
+    private String signaturePolicy = SIGNATURE_POLICY_IGNORE;
 
     public ArtifactRepositoryPolicy()
     {
@@ -74,7 +82,18 @@
         }
         this.checksumPolicy = checksumPolicy;
     }
-
+    
+    public ArtifactRepositoryPolicy( boolean enabled, String updatePolicy, String checksumPolicy, String signaturePolicy )
+    {
+        this( enabled, updatePolicy, checksumPolicy );
+        
+        if ( checksumPolicy == null )
+        {
+            checksumPolicy = SIGNATURE_POLICY_IGNORE;
+        }
+        this.signaturePolicy = signaturePolicy;
+    }
+    
     public void setEnabled( boolean enabled )
     {
         this.enabled = enabled;
@@ -90,6 +109,11 @@
         this.checksumPolicy = checksumPolicy;
     }
 
+    public void setSignaturePolicy( String signaturePolicy )
+    {
+        this.signaturePolicy = signaturePolicy;
+    }
+
     public boolean isEnabled()
     {
         return enabled;
@@ -105,6 +129,11 @@
         return checksumPolicy;
     }
 
+    public String getSignaturePolicy()
+    {
+        return signaturePolicy;
+    }
+
     public boolean checkOutOfDate( Date lastModified )
     {
         boolean checkForUpdates = false;

Modified: maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepository.java
URL: http://svn.apache.org/viewvc/maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepository.java?rev=677522&r1=677521&r2=677522&view=diff
==============================================================================
--- maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepository.java (original)
+++ maven/artifact/branches/MNG-2477/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepository.java Thu Jul 17 00:26:23 2008
@@ -99,7 +99,7 @@
         if ( snapshots == null )
         {
             snapshots = new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
-                ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE );
+                ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE, ArtifactRepositoryPolicy.SIGNATURE_POLICY_IGNORE );
         }
 
         this.snapshots = snapshots;
@@ -107,7 +107,7 @@
         if ( releases == null )
         {
             releases = new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
-                ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE );
+                ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE, ArtifactRepositoryPolicy.SIGNATURE_POLICY_FAIL );
         }
 
         this.releases = releases;

Modified: maven/artifact/branches/MNG-2477/src/test/java/org/apache/maven/artifact/manager/DefaultWagonManagerTest.java
URL: http://svn.apache.org/viewvc/maven/artifact/branches/MNG-2477/src/test/java/org/apache/maven/artifact/manager/DefaultWagonManagerTest.java?rev=677522&r1=677521&r2=677522&view=diff
==============================================================================
--- maven/artifact/branches/MNG-2477/src/test/java/org/apache/maven/artifact/manager/DefaultWagonManagerTest.java (original)
+++ maven/artifact/branches/MNG-2477/src/test/java/org/apache/maven/artifact/manager/DefaultWagonManagerTest.java Thu Jul 17 00:26:23 2008
@@ -46,6 +46,7 @@
 import org.apache.maven.wagon.repository.Repository;
 import org.codehaus.plexus.PlexusTestCase;
 import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
 import org.codehaus.plexus.util.xml.Xpp3Dom;
 import org.easymock.MockControl;
 
@@ -68,16 +69,24 @@
         super.setUp();
 
         wagonManager = (DefaultWagonManager) lookup( WagonManager.ROLE );
+        wagonManager.registerPublicKeyRing( getClass().getResourceAsStream( "/pubring.gpg" ) );
         
         artifactFactory = (ArtifactFactory) lookup( ArtifactFactory.ROLE );
     }
     
+    public void tearDown() 
+        throws Exception
+    {
+        release( wagonManager );
+        release( artifactFactory );
+    }
+    
     public void testUnnecessaryRepositoryLookup() throws Exception {
         Artifact artifact = createTestPomArtifact( "target/test-data/get-missing-pom" );
 
         List<ArtifactRepository> repos = new ArrayList<ArtifactRepository>();
-        repos.add(new DefaultArtifactRepository( "repo1", "string://url1", new ArtifactRepositoryLayoutStub() ));
-        repos.add(new DefaultArtifactRepository( "repo2", "string://url2", new ArtifactRepositoryLayoutStub() ));
+        repos.add( createStringRepo( "string://url1" ) );
+        repos.add( createStringRepo( "string://url2" ) );
 
         StringWagon wagon = (StringWagon) wagonManager.getWagon( "string" );
         wagon.addExpectedContent( repos.get(0).getLayout().pathOf( artifact ), "expected" );
@@ -495,9 +504,17 @@
 
     private ArtifactRepository createStringRepo()
     {
-        ArtifactRepository repo =
-            new DefaultArtifactRepository( "id", "string://url", new ArtifactRepositoryLayoutStub() );
-        return repo;
+        return createStringRepo( "string://url" );
+    }
+
+    private ArtifactRepository createStringRepo( String url )
+    {
+        ArtifactRepositoryPolicy policy =
+            new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
+                                          ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE,
+                                          ArtifactRepositoryPolicy.SIGNATURE_POLICY_IGNORE );        
+        
+        return new DefaultArtifactRepository( "id", url, new ArtifactRepositoryLayoutStub(), policy, policy );
     }
     
     /**
@@ -768,6 +785,167 @@
                      wagon.getTransferEventSupport().hasTransferListener( transferListener ) );
     }
 
+    public void testIncorrectSignatureVerificationJar() throws Exception
+    {
+        ArtifactRepositoryPolicy policy = getSignaturePolicy( ArtifactRepositoryPolicy.SIGNATURE_POLICY_FAIL );
+        
+        ArtifactRepository repo = createStringRepo( policy );
+        
+        Artifact artifact = createTestArtifact( "target/test-data/signature-verification", "jar" );
+                
+        createWagonWithSignedContent( "/other-test-signature.asc" );
+
+        try
+        {
+            wagonManager.getArtifact( artifact, repo, true );
+            fail( "Should have failed signature check" );
+        }
+        catch ( SignatureFailedException e )
+        {
+            assertTrue( true );
+        }
+    }
+
+    private ArtifactRepositoryPolicy getSignaturePolicy( String policy )
+    {
+        return new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
+                                             ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE, policy );
+    }
+
+    public void testIncorrectSignatureVerificationJarIgnore() throws Exception
+    {
+        ArtifactRepositoryPolicy policy = getSignaturePolicy( ArtifactRepositoryPolicy.SIGNATURE_POLICY_IGNORE );
+        ArtifactRepository repo = createStringRepo( policy );
+        
+        Artifact artifact = createTestArtifact( "target/test-data/signature-verification", "jar" );
+                
+        createWagonWithSignedContent( "/other-test-signature.asc" );
+
+        wagonManager.getArtifact( artifact, repo, true );
+    }
+
+    public void testIncorrectSignatureVerificationJarWarn() throws Exception
+    {
+        ArtifactRepositoryPolicy policy = getSignaturePolicy( ArtifactRepositoryPolicy.SIGNATURE_POLICY_WARN );
+        ArtifactRepository repo = createStringRepo( policy );
+        
+        Artifact artifact = createTestArtifact( "target/test-data/signature-verification", "jar" );
+                
+        createWagonWithSignedContent( "/other-test-signature.asc" );
+
+        wagonManager.getArtifact( artifact, repo, true );
+    }
+
+    private ArtifactRepository createStringRepo( ArtifactRepositoryPolicy policy )
+    {
+        ArtifactRepository repo =
+            new DefaultArtifactRepository( "id", "string://url", new ArtifactRepositoryLayoutStub(), policy, policy );
+        return repo;
+    }
+
+    public void testSignatureVerificationJar() throws Exception
+    {
+        ArtifactRepositoryPolicy policy = getSignaturePolicy( ArtifactRepositoryPolicy.SIGNATURE_POLICY_FAIL );
+        
+        ArtifactRepository repo = createStringRepo( policy );
+        
+        Artifact artifact = createTestArtifact( "target/test-data/signature-verification", "jar" );
+        
+        createWagonWithSignedContent( "/test-signature.asc" );
+
+        wagonManager.getArtifact( artifact, repo, true );
+    }
+    
+    public void testMissingSignatureVerificationJar() throws Exception
+    {
+        ArtifactRepositoryPolicy policy = getSignaturePolicy( ArtifactRepositoryPolicy.SIGNATURE_POLICY_FAIL );
+        
+        ArtifactRepository repo = createStringRepo( policy );
+        
+        Artifact artifact = createTestArtifact( "target/test-data/signature-verification", "jar" );
+                
+        createWagonWithSignedContent();
+
+        try
+        {
+            wagonManager.getArtifact( artifact, repo, true );
+            fail( "Should have failed signature check" );
+        }
+        catch ( SignatureFailedException e )
+        {
+            assertTrue( true );
+        }
+    }
+    
+    public void testMissingSignatureVerificationJarIgnored() throws Exception
+    {
+        ArtifactRepositoryPolicy policy = getSignaturePolicy( ArtifactRepositoryPolicy.SIGNATURE_POLICY_IGNORE );
+        ArtifactRepository repo = createStringRepo( policy );
+        
+        Artifact artifact = createTestArtifact( "target/test-data/signature-verification", "jar" );
+                
+        createWagonWithSignedContent();
+
+        wagonManager.getArtifact( artifact, repo, true );
+    }
+
+    public void testMissingSignatureVerificationJarWarn() throws Exception
+    {
+        ArtifactRepositoryPolicy policy = getSignaturePolicy( ArtifactRepositoryPolicy.SIGNATURE_POLICY_WARN );
+        ArtifactRepository repo = createStringRepo( policy );
+        
+        Artifact artifact = createTestArtifact( "target/test-data/signature-verification", "jar" );
+                
+        createWagonWithSignedContent();
+
+        wagonManager.getArtifact( artifact, repo, true );
+    }
+
+    public void testUnknownSignatureVerificationJar() throws Exception
+    {
+        ArtifactRepositoryPolicy policy = getSignaturePolicy( ArtifactRepositoryPolicy.SIGNATURE_POLICY_FAIL );
+        
+        ArtifactRepository repo = createStringRepo( policy );
+        
+        Artifact artifact = createTestArtifact( "target/test-data/signature-verification", "jar" );
+                
+        createWagonWithSignedContent( "/unknown-but-valid-signature.asc" );
+
+        try
+        {
+            wagonManager.getArtifact( artifact, repo, true );
+            fail( "Should have failed signature check" );
+        }
+        catch ( SignatureFailedException e )
+        {
+            assertTrue( true );
+        }
+    }
+    
+    public void testUnknownSignatureVerificationJarIgnored() throws Exception
+    {
+        ArtifactRepositoryPolicy policy = getSignaturePolicy( ArtifactRepositoryPolicy.SIGNATURE_POLICY_IGNORE );
+        ArtifactRepository repo = createStringRepo( policy );
+        
+        Artifact artifact = createTestArtifact( "target/test-data/signature-verification", "jar" );
+                
+        createWagonWithSignedContent( "/unknown-but-valid-signature.asc" );
+
+        wagonManager.getArtifact( artifact, repo, true );
+    }
+
+    public void testUnknownSignatureVerificationJarWarn() throws Exception
+    {
+        ArtifactRepositoryPolicy policy = getSignaturePolicy( ArtifactRepositoryPolicy.SIGNATURE_POLICY_WARN );
+        ArtifactRepository repo = createStringRepo( policy );
+        
+        Artifact artifact = createTestArtifact( "target/test-data/signature-verification", "jar" );
+                
+        createWagonWithSignedContent( "/unknown-but-valid-signature.asc" );
+
+        wagonManager.getArtifact( artifact, repo, true );
+    }
+
     /**
      * Checks the verification of checksums.
      */
@@ -777,8 +955,7 @@
         ArtifactRepositoryPolicy policy =
             new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
                                           ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL );
-        ArtifactRepository repo =
-            new DefaultArtifactRepository( "id", "string://url", new ArtifactRepositoryLayoutStub(), policy, policy );
+        ArtifactRepository repo = createStringRepo( policy );
 
         Artifact artifact =
             new DefaultArtifact( "sample.group", "sample-art", VersionRange.createFromVersion( "1.0" ), "scope",
@@ -791,27 +968,13 @@
         wagon.addExpectedContent( "path", "lower-case-checksum" );
         wagon.addExpectedContent( "path.sha1", "2a25dc564a3b34f68237fc849066cbc7bb7a36a1" );
 
-        try
-        {
-            wagonManager.getArtifact( artifact, repo, true );
-        }
-        catch ( ChecksumFailedException e )
-        {
-            fail( "Checksum verification did not pass: " + e.getMessage() );
-        }
+        wagonManager.getArtifact( artifact, repo, true );
 
         wagon.clearExpectedContent();
         wagon.addExpectedContent( "path", "upper-case-checksum" );
         wagon.addExpectedContent( "path.sha1", "B7BB97D7D0B9244398D9B47296907F73313663E6" );
 
-        try
-        {
-            wagonManager.getArtifact( artifact, repo, true );
-        }
-        catch ( ChecksumFailedException e )
-        {
-            fail( "Checksum verification did not pass: " + e.getMessage() );
-        }
+        wagonManager.getArtifact( artifact, repo, true );
 
         wagon.clearExpectedContent();
         wagon.addExpectedContent( "path", "expected-failure" );
@@ -831,27 +994,13 @@
         wagon.addExpectedContent( "path", "lower-case-checksum" );
         wagon.addExpectedContent( "path.md5", "50b2cf50a103a965efac62b983035cac" );
 
-        try
-        {
-            wagonManager.getArtifact( artifact, repo, true );
-        }
-        catch ( ChecksumFailedException e )
-        {
-            fail( "Checksum verification did not pass: " + e.getMessage() );
-        }
+        wagonManager.getArtifact( artifact, repo, true );
 
         wagon.clearExpectedContent();
         wagon.addExpectedContent( "path", "upper-case-checksum" );
         wagon.addExpectedContent( "path.md5", "842F568FCCFEB7E534DC72133D42FFDC" );
 
-        try
-        {
-            wagonManager.getArtifact( artifact, repo, true );
-        }
-        catch ( ChecksumFailedException e )
-        {
-            fail( "Checksum verification did not pass: " + e.getMessage() );
-        }
+        wagonManager.getArtifact( artifact, repo, true );
 
         wagon.clearExpectedContent();
         wagon.addExpectedContent( "path", "expected-failure" );
@@ -868,6 +1017,23 @@
         }
     }
 
+    private void createWagonWithSignedContent( String signatureResource )
+        throws UnsupportedProtocolException, IOException
+    {
+        StringWagon wagon = createWagonWithSignedContent();
+        wagon.addExpectedContent( "path.asc", IOUtil.toString( getClass().getResourceAsStream( signatureResource ) ) );
+    }
+
+    private StringWagon createWagonWithSignedContent()
+        throws UnsupportedProtocolException
+    {
+        StringWagon wagon = (StringWagon) wagonManager.getWagon( "string" );
+        wagon.clearExpectedContent();
+        wagon.addExpectedContent( "path", "signed-text\n" );
+        wagon.addExpectedContent( "path.sha1", "36e0a272f6861ccea6be4433fa8c25cd5ba52794" );
+        return wagon;
+    }
+
     private void assertWagon( String protocol )
         throws Exception
     {

Added: maven/artifact/branches/MNG-2477/src/test/resources/other-test-signature.asc
URL: http://svn.apache.org/viewvc/maven/artifact/branches/MNG-2477/src/test/resources/other-test-signature.asc?rev=677522&view=auto
==============================================================================
--- maven/artifact/branches/MNG-2477/src/test/resources/other-test-signature.asc (added)
+++ maven/artifact/branches/MNG-2477/src/test/resources/other-test-signature.asc Thu Jul 17 00:26:23 2008
@@ -0,0 +1,7 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.8 (Darwin)
+
+iEYEABECAAYFAkh4EHMACgkQTusOMqfRa9RYrgCfcdY1jrLEZ+CQWh5EHpeOioHB
+ZMIAn05ds5p6W4sRTtbB2dOxUnE35aPI
+=iP86
+-----END PGP SIGNATURE-----

Added: maven/artifact/branches/MNG-2477/src/test/resources/test-signature.asc
URL: http://svn.apache.org/viewvc/maven/artifact/branches/MNG-2477/src/test/resources/test-signature.asc?rev=677522&view=auto
==============================================================================
--- maven/artifact/branches/MNG-2477/src/test/resources/test-signature.asc (added)
+++ maven/artifact/branches/MNG-2477/src/test/resources/test-signature.asc Thu Jul 17 00:26:23 2008
@@ -0,0 +1,8 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.8 (Darwin)
+
+iEYEABECAAYFAkh4DyAACgkQTusOMqfRa9RXNACgu0A3JBtaYD/X57G8pZbh25Yo
+F1sAn19t2IzYqBlGP5PFsug5wCt690W4
+=cfP2
+-----END PGP SIGNATURE-----
+

Added: maven/artifact/branches/MNG-2477/src/test/resources/unknown-but-valid-signature.asc
URL: http://svn.apache.org/viewvc/maven/artifact/branches/MNG-2477/src/test/resources/unknown-but-valid-signature.asc?rev=677522&view=auto
==============================================================================
--- maven/artifact/branches/MNG-2477/src/test/resources/unknown-but-valid-signature.asc (added)
+++ maven/artifact/branches/MNG-2477/src/test/resources/unknown-but-valid-signature.asc Thu Jul 17 00:26:23 2008
@@ -0,0 +1,7 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.8 (Darwin)
+
+iEYEABECAAYFAkh7UKIACgkQGzJptpuIuDdgnwCferfunQll9kt8cpHlTxDnYPKs
+N/gAoKiJ2wbi2v0CuaHzSyoR9Sxtd+zG
+=aIT1
+-----END PGP SIGNATURE-----