Author: ogusakov Date: Sun Aug 24 10:21:40 2008 New Revision: 688532 URL: http://svn.apache.org/viewvc?rev=688532&view=rev Log: added signature and verification tests, added repo manager
Added: maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-api/src/main/java/org/apache/maven/mercury/repository/api/RepositoryManager.java maven/sandbox/trunk/mercury/mercury-util/src/test/ maven/sandbox/trunk/mercury/mercury-util/src/test/java/ maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/ maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/ maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/ maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/ maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/ maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java maven/sandbox/trunk/mercury/mercury-util/src/test/resources/ maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar (with props) maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar.asc maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar.sha1 maven/sandbox/trunk/mercury/mercury-util/src/test/resources/bad.asc maven/sandbox/trunk/mercury/mercury-util/src/test/resources/pgp/ maven/sandbox/trunk/mercury/mercury-util/src/test/resources/pgp/pubring.gpg (with props) maven/sandbox/trunk/mercury/mercury-util/src/test/resources/pgp/secring.gpg (with props) Modified: maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-api/src/main/java/org/apache/maven/mercury/repository/api/RemoteRepository.java maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-remote-m2/src/main/java/org/apache/maven/mercury/repository/remote/m2/RemoteRepositoryM2.java maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties Modified: maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-api/src/main/java/org/apache/maven/mercury/repository/api/RemoteRepository.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-api/src/main/java/org/apache/maven/mercury/repository/api/RemoteRepository.java?rev=688532&r1=688531&r2=688532&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-api/src/main/java/org/apache/maven/mercury/repository/api/RemoteRepository.java (original) +++ maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-api/src/main/java/org/apache/maven/mercury/repository/api/RemoteRepository.java Sun Aug 24 10:21:40 2008 @@ -1,5 +1,7 @@ package org.apache.maven.mercury.repository.api; +import java.util.List; + import org.apache.maven.mercury.transport.api.Server; @@ -27,5 +29,8 @@ public interface RemoteRepository extends Repository { + /** + * this is the Server with many useful fields to describe the home of this remote repo + */ Server getServer(); } Added: maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-api/src/main/java/org/apache/maven/mercury/repository/api/RepositoryManager.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-api/src/main/java/org/apache/maven/mercury/repository/api/RepositoryManager.java?rev=688532&view=auto ============================================================================== --- maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-api/src/main/java/org/apache/maven/mercury/repository/api/RepositoryManager.java (added) +++ maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-api/src/main/java/org/apache/maven/mercury/repository/api/RepositoryManager.java Sun Aug 24 10:21:40 2008 @@ -0,0 +1,39 @@ +package org.apache.maven.mercury.repository.api; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.maven.mercury.artifact.Quality; + +/** + * + * + * @author Oleg Gusakov + * @version $Id$ + * + */ +public class RepositoryManager +{ + protected static transient List<Repository> _repoList = Collections.synchronizedList( new ArrayList<Repository>(8) ); + + void setRepositories() + { + + } + + List<Repository> getRepositories() + { + return _repoList; + } + + LocalRepository findLocal( Quality aq ) + { + for( Repository r : _repoList ) + { + if( r.isLocal() && !r.isReadOnly() && r.isAcceptedQuality( aq ) ) + return (LocalRepository)r; + } + return null; + } +} Modified: maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-remote-m2/src/main/java/org/apache/maven/mercury/repository/remote/m2/RemoteRepositoryM2.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-remote-m2/src/main/java/org/apache/maven/mercury/repository/remote/m2/RemoteRepositoryM2.java?rev=688532&r1=688531&r2=688532&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-remote-m2/src/main/java/org/apache/maven/mercury/repository/remote/m2/RemoteRepositoryM2.java (original) +++ maven/sandbox/trunk/mercury/mercury-repo/mercury-repo-remote-m2/src/main/java/org/apache/maven/mercury/repository/remote/m2/RemoteRepositoryM2.java Sun Aug 24 10:21:40 2008 @@ -2,6 +2,7 @@ import org.apache.maven.mercury.builder.api.MetadataProcessor; import org.apache.maven.mercury.repository.api.AbstractRepository; +import org.apache.maven.mercury.repository.api.LocalRepository; import org.apache.maven.mercury.repository.api.NonExistentProtocolException; import org.apache.maven.mercury.repository.api.RemoteRepository; import org.apache.maven.mercury.repository.api.RepositoryException; @@ -68,4 +69,12 @@ } //---------------------------------------------------------------------------------- //---------------------------------------------------------------------------------- + /* (non-Javadoc) + * @see org.apache.maven.mercury.repository.api.RemoteRepository#addLocalRepository(org.apache.maven.mercury.repository.api.LocalRepository) + */ + public void addLocalRepository( LocalRepository localRepo ) + { + // TODO Auto-generated method stub + + } } Modified: maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java?rev=688532&r1=688531&r2=688532&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java (original) +++ maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/FileUtil.java Sun Aug 24 10:21:40 2008 @@ -10,6 +10,8 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.security.acl.Group; +import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -21,6 +23,7 @@ import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.OptionGroup; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.maven.mercury.crypto.api.StreamObserverException; @@ -92,10 +95,14 @@ } //--------------------------------------------------------------------------------------------------------------- - private static void copyFile( File f, File toDir ) + private static void copyFile( File f, File toFile ) throws IOException { - File fOut = new File(toDir, f.getName() ); + File fOut = null; + if( toFile.isDirectory() ) + fOut = new File(toFile, f.getName() ); + else + fOut = toFile; FileInputStream fis = new FileInputStream(f); writeRawData( fOut, fis ); } @@ -331,7 +338,7 @@ } //--------------------------------------------------------------------------------------------------------------- - public static void sign( File f, Set<StreamVerifierFactory> vFacs, boolean force ) + public static void sign( File f, Set<StreamVerifierFactory> vFacs, boolean recurse, boolean force ) throws IOException, StreamObserverException { if( vFacs == null || vFacs.size() < 1 ) @@ -339,9 +346,12 @@ if( f.isDirectory() ) { + if( ! recurse ) + return; + File [] kids = f.listFiles(); for( File kid : kids ) - sign( kid, vFacs, force ); + sign( kid, vFacs, recurse, force ); return; } @@ -398,10 +408,103 @@ } //--------------------------------------------------------------------------------------------------------------- + public static void verify( File f, Set<StreamVerifierFactory> vFacs, boolean recurse, boolean force ) + throws IOException, StreamObserverException + { + if( vFacs == null || vFacs.size() < 1 ) + return; + + if( f.isDirectory() ) + { + if( !recurse ) + return; + + File [] kids = f.listFiles(); + for( File kid : kids ) + verify( kid, vFacs, recurse, force ); + return; + } + + String fName = f.getAbsolutePath(); + + HashSet<StreamVerifier> vs = new HashSet<StreamVerifier>( vFacs.size() ); + for( StreamVerifierFactory vf : vFacs ) + { + StreamVerifier sv = vf.newInstance(); + String ext = sv.getAttributes().getExtension(); + + // don't verify signature files + if( fName.endsWith( ext ) ) + return; + + File sf = new File( fName+ext ); + if( !sf.exists() ) + { + if( force ) + throw new StreamVerifierException( _lang.getMessage( "no.mandatory.signature", f.getAbsolutePath(), sf.getAbsolutePath() )); + else + continue; + } + else + { + String sig = readRawDataAsString( sf ); + sv.initSignature( sig ); + } + vs.add( sv ); + } + + byte [] buf = new byte[ DEFAULT_BUFFER_SIZE ]; + FileInputStream fis = null; + try + { + fis = new FileInputStream( f ); + int n = -1; + + while( (n=fis.read( buf )) != -1 ) + { + for( StreamVerifier sv : vs ) + { + sv.bytesReady( buf, 0, n ); + } + } + + List<String> fl = null; + char comma = ' '; + + for( StreamVerifier sv : vs ) + { + if( sv.verifySignature() ) + continue; + + if( fl == null ) + fl = new ArrayList<String>(4); + + fl.add( sv.getAttributes().getExtension().replace( '.', comma ) ); + comma = ','; + } + + if( fl != null ) + { + throw new StreamVerifierException( _lang.getMessage( "file.failed.verification", f.getAbsolutePath(), fl.toString() ) ); + } + } + finally + { + if( fis != null ) try { fis.close(); } catch( Exception any ) {} + } + + } + //--------------------------------------------------------------------------------------------------------------- @SuppressWarnings("static-access") public static void main( String[] args ) throws IOException, StreamObserverException { + Option sign = new Option( "sign", _lang.getMessage( "option.sign" ) ); + Option verify = new Option( "verify", _lang.getMessage( "option.verify" ) ); + OptionGroup cmd = new OptionGroup(); + cmd.addOption( sign ); + cmd.addOption( verify ); + Option recurce = new Option( "r", _lang.getMessage( "option.r" ) ); Option force = new Option( "force", _lang.getMessage( "option.force" ) ); Option sha1 = new Option( "sha1", _lang.getMessage( "option.sha1" ) ); @@ -424,6 +527,9 @@ ; Options options = new Options(); + options.addOptionGroup( cmd ); + options.addOption( sign ); + options.addOption( verify ); options.addOption( recurce ); options.addOption( force ); options.addOption( sha1 ); @@ -482,11 +588,11 @@ vFacs.add( new SHA1VerifierFactory(true,false) ); } - signAll( commandLine.getArgList(), vFacs, commandLine.hasOption( "r" ), commandLine.hasOption( "force" ) ); + signAll( commandLine.getArgList(), vFacs, commandLine.hasOption( "r" ), commandLine.hasOption( "force" ), commandLine.hasOption( "sign" ) ); } //--------------------------------------------------------------------------------------------------------------- - private static void signAll( List<String> fileNames, Set<StreamVerifierFactory> vFacs, boolean recurse, boolean force ) + private static void signAll( List<String> fileNames, Set<StreamVerifierFactory> vFacs, boolean recurse, boolean force, boolean sign ) throws IOException, StreamObserverException { if( vFacs == null || vFacs.size() < 1 ) @@ -510,7 +616,10 @@ System.out.println( _lang.getMessage( "file.is.directory", fName )); continue; } - sign( f, vFacs, force ); + if( sign ) + sign( f, vFacs, recurse, force ); + else + verify( f, vFacs, recurse, force ); } } //--------------------------------------------------------------------------------------------------------------- Modified: maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties?rev=688532&r1=688531&r2=688532&view=diff ============================================================================== --- maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties (original) +++ maven/sandbox/trunk/mercury/mercury-util/src/main/java/org/apache/maven/mercury/util/Messages.properties Sun Aug 24 10:21:40 2008 @@ -2,6 +2,8 @@ no.signature.file=Verifier for {0} is mandatory, but file {1} does not exist cannot.read.signature.file=Cannot read signature file {0}, error: {1} option.sha1=produce SHA1 signatures +option.sign=create signatures for specified algorithms. Use -force to overwrite existing ones +option.verify=verify signatures for specified algorithms. Use -force to fail on non-existing signatures option.pgp=produce PGP signatures, requires -keyring and -keyid options option.keyring=full path of the secret keyring file option.keyid=id of the key in the secret keyring file to be used in the signature @@ -11,4 +13,8 @@ bad.pgp.args=pgp option requires both -keyring and -keyid to be specified no.verifiers=No signature generators requested - exiting file.not.exists=File "{0}" does not exist. Skipping .. -file.is.directory=File "{0}" is a folder and no recursive option is specified. Skipping .. \ No newline at end of file +file.is.directory=File "{0}" is a folder and no recursive option is specified. Skipping .. +no.mandatory.signature=Mandatory signature {1} does not exist for file {0} +file.failed.verification=File {0} failed following verifications: {1} + +test.no.exception=Expected exception never thrown: {0} \ No newline at end of file Added: maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java?rev=688532&view=auto ============================================================================== --- maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java (added) +++ maven/sandbox/trunk/mercury/mercury-util/src/test/java/org/apache/maven/mercury/util/FileUtilTest.java Sun Aug 24 10:21:40 2008 @@ -0,0 +1,154 @@ +package org.apache.maven.mercury.util; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; + +import org.apache.maven.mercury.crypto.api.StreamObserverException; +import org.apache.maven.mercury.crypto.api.StreamVerifierAttributes; +import org.apache.maven.mercury.crypto.api.StreamVerifierException; +import org.apache.maven.mercury.crypto.api.StreamVerifierFactory; +import org.apache.maven.mercury.crypto.pgp.PgpStreamVerifierFactory; +import org.apache.maven.mercury.crypto.sha.SHA1VerifierFactory; +import org.codehaus.plexus.i18n.DefaultLanguage; +import org.codehaus.plexus.i18n.Language; + +import junit.framework.TestCase; + +/** + * + * + * @author Oleg Gusakov + * @version $Id$ + * + */ +public class FileUtilTest + extends TestCase +{ + private static final Language _lang = new DefaultLanguage( FileUtilTest.class ); + + private static final String publicKeyFile = "/pgp/pubring.gpg"; + private static final String secretKeyFile = "/pgp/secring.gpg"; + private static final String keyId = "0EDB5D91141BC4F2"; + private static final String secretKeyPass = "testKey82"; + + private File testDir; + private File a; + private File b; + private File bAsc; + private File badAsc; + + HashSet<StreamVerifierFactory> vFacs; + //---------------------------------------------------------------------------------------- + @Override + protected void setUp() + throws Exception + { + testDir = new File("./target/test-classes"); + a = new File( testDir, "a.jar" ); + b = new File( testDir, "b.jar" ); + bAsc = new File( testDir, "b.jar.asc" ); + badAsc = new File( testDir, "bad.asc" ); + + FileUtil.copy( a, b, true ); + + vFacs = new HashSet<StreamVerifierFactory>(2); + + tearDown(); + } + //---------------------------------------------------------------------------------------- + @Override + protected void tearDown() + throws Exception + { + bAsc.delete(); + } + //---------------------------------------------------------------------------------------- + private void setPgp( boolean generator ) + throws StreamVerifierException + { + if( generator ) + vFacs.add( + new PgpStreamVerifierFactory( + new StreamVerifierAttributes( PgpStreamVerifierFactory.DEFAULT_EXTENSION, false, true ) + , getClass().getResourceAsStream( secretKeyFile ) + , keyId + , secretKeyPass + ) + ); + else + vFacs.add( + new PgpStreamVerifierFactory( + new StreamVerifierAttributes( PgpStreamVerifierFactory.DEFAULT_EXTENSION, false, true ) + , getClass().getResourceAsStream( publicKeyFile ) + ) + ); + + } + //---------------------------------------------------------------------------------------- + private void setSha1( boolean generator ) + { + vFacs.add( new SHA1VerifierFactory(false,false) ); + } + //---------------------------------------------------------------------------------------- + public void testVerifyGood() + throws IOException, StreamObserverException + { + setPgp( false ); + FileUtil.verify( a, vFacs, false, true ); + } + //---------------------------------------------------------------------------------------- + public void testVerifyBad() + throws IOException, StreamObserverException + { + setPgp( false ); + FileUtil.copy( badAsc, bAsc, true ); + + try + { + FileUtil.verify( b, vFacs, false, false ); + } + catch( StreamObserverException e ) + { + System.out.println( "Caught expected exception: "+e.getMessage() ); + return; + } + fail( _lang.getMessage( "test.no.exception", StreamObserverException.class.getName() ) ); + } + //---------------------------------------------------------------------------------------- + public void testVerifyNoSigNoForce() + throws IOException, StreamObserverException + { + setPgp( false ); + FileUtil.verify( b, vFacs, false, false ); + } + //---------------------------------------------------------------------------------------- + public void testVerifyNoSigForce() + throws IOException, StreamVerifierException + { + setPgp( false ); + + try + { + FileUtil.verify( b, vFacs, false, true ); + } + catch( StreamObserverException e ) + { + System.out.println( "Caught expected exception: "+e.getMessage() ); + return; + } + fail( _lang.getMessage( "test.no.exception", StreamObserverException.class.getName() ) ); + } + //---------------------------------------------------------------------------------------- + public void testSign() + throws IOException, StreamObserverException + { + setPgp( true ); + FileUtil.sign( b, vFacs, false, true ); + + vFacs.clear(); + setPgp( false ); + FileUtil.verify( b, vFacs, false, true ); + } + //---------------------------------------------------------------------------------------- +} Added: maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar?rev=688532&view=auto ============================================================================== Binary file - no diff available. Propchange: maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar.asc URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar.asc?rev=688532&view=auto ============================================================================== --- maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar.asc (added) +++ maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar.asc Sun Aug 24 10:21:40 2008 @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- +Version: BCPG v1.40 + +iEYEABECAAYFAkivNOcACgkQDttdkRQbxPJuQgCfbLCJldGo59ggjxNyIbRbIqcs +OrwAnih+uOC4Elw5UJ2Wekdjl37jJbak +=i1JE +-----END PGP SIGNATURE----- Added: maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar.sha1 URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar.sha1?rev=688532&view=auto ============================================================================== --- maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar.sha1 (added) +++ maven/sandbox/trunk/mercury/mercury-util/src/test/resources/a.jar.sha1 Sun Aug 24 10:21:40 2008 @@ -0,0 +1 @@ +e1003a0a66dae77515259c5e591ea1cfd73c2859 \ No newline at end of file Added: maven/sandbox/trunk/mercury/mercury-util/src/test/resources/bad.asc URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/test/resources/bad.asc?rev=688532&view=auto ============================================================================== --- maven/sandbox/trunk/mercury/mercury-util/src/test/resources/bad.asc (added) +++ maven/sandbox/trunk/mercury/mercury-util/src/test/resources/bad.asc Sun Aug 24 10:21:40 2008 @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- +Version: BCPG v1.40 + +iEYEABECAAYFAkivNOcACgkQDttdkRQbxPI6twCeI7VvcHQG6U3WZzIISSvB5sAY +kcgAn2jHpt7cn7mYtjdjzusCCoz4N4rP +=kmbj +-----END PGP SIGNATURE----- Added: maven/sandbox/trunk/mercury/mercury-util/src/test/resources/pgp/pubring.gpg URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/test/resources/pgp/pubring.gpg?rev=688532&view=auto ============================================================================== Binary file - no diff available. Propchange: maven/sandbox/trunk/mercury/mercury-util/src/test/resources/pgp/pubring.gpg ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: maven/sandbox/trunk/mercury/mercury-util/src/test/resources/pgp/secring.gpg URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-util/src/test/resources/pgp/secring.gpg?rev=688532&view=auto ============================================================================== Binary file - no diff available. Propchange: maven/sandbox/trunk/mercury/mercury-util/src/test/resources/pgp/secring.gpg ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream