Unifying checksum code into the checksum module

This commit is contained in:
Martin Stockhammer 2018-03-31 19:20:30 +02:00
parent 0d6ee3dbd9
commit fbf5e991b3
37 changed files with 526 additions and 643 deletions

View File

@ -22,8 +22,14 @@ package org.apache.archiva.checksum;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.NullOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@ -35,19 +41,35 @@ import java.util.List;
public class Checksum
{
private static final int BUFFER_SIZE = 32768;
private byte[] result = new byte[0];
public static void update( List<Checksum> checksums, InputStream stream )
throws IOException
public static void update( List<Checksum> checksums, Path file )
throws ChecksumValidationException
{
byte[] buffer = new byte[BUFFER_SIZE];
int size = stream.read( buffer, 0, BUFFER_SIZE );
while ( size >= 0 )
{
for ( Checksum checksum : checksums )
long fileSize;
try (FileChannel channel = FileChannel.open(file, StandardOpenOption.READ )) {
fileSize = channel.size();
long pos = 0;
while (pos<fileSize)
{
checksum.update( buffer, 0, size );
long bufferSize = Math.min(BUFFER_SIZE, fileSize-pos);
MappedByteBuffer buffer = channel.map( FileChannel.MapMode.READ_ONLY, pos, bufferSize);
for ( Checksum checksum : checksums )
{
checksum.update( buffer );
buffer.rewind();
}
fileSize = channel.size();
pos += BUFFER_SIZE;
}
size = stream.read( buffer, 0, BUFFER_SIZE );
for (Checksum checksum : checksums) {
checksum.finish();
}
} catch(FileNotFoundException e)
{
throw new ChecksumValidationException( ChecksumValidationException.ValidationError.FILE_NOT_FOUND, "File that should be parsed, not found: "+e.getMessage(), e );
} catch(IOException e) {
throw new ChecksumValidationException( ChecksumValidationException.ValidationError.READ_ERROR, "Parsing of file failed: "+e.getMessage(), e );
}
}
@ -73,7 +95,17 @@ public class Checksum
public String getChecksum()
{
return Hex.encode( md.digest() );
if (this.result.length==0) {
finish();
}
return Hex.encode( this.result );
}
public byte[] getChecksumBytes() {
if (this.result.length==0) {
finish();
}
return this.result;
}
public ChecksumAlgorithm getAlgorithm()
@ -84,21 +116,63 @@ public class Checksum
public void reset()
{
md.reset();
this.result = new byte[0];
}
public Checksum update( byte[] buffer, int offset, int size )
{
if (this.result.length!=0) {
reset();
}
md.update( buffer, 0, size );
return this;
}
public Checksum update( InputStream stream )
throws IOException
public Checksum update( ByteBuffer buffer)
{
try (DigestInputStream dig = new DigestInputStream( stream, md ))
{
IOUtils.copy( dig, new NullOutputStream() );
if (this.result.length!=0) {
reset();
}
md.update( buffer );
return this;
}
public Checksum finish() {
this.result = md.digest();
return this;
}
public void update( Path file )
throws IOException
{
long fileSize;
try (FileChannel channel = FileChannel.open(file, StandardOpenOption.READ )) {
fileSize = channel.size();
long pos = 0;
while (pos<fileSize)
{
long bufferSize = Math.min(BUFFER_SIZE, fileSize-pos);
MappedByteBuffer buffer = channel.map( FileChannel.MapMode.READ_ONLY, pos, bufferSize);
update( buffer );
buffer.rewind();
fileSize = channel.size();
pos += BUFFER_SIZE;
}
finish();
}
}
public boolean compare(byte[] cmp) {
if (this.result == null || this.result.length==0) {
finish();
}
return md.isEqual( this.result, cmp );
}
public boolean compare(String hexString) {
if (this.result == null || this.result.length==0) {
finish();
}
return md.isEqual(this.result, Hex.decode( hexString ));
}
}

View File

@ -23,6 +23,14 @@ package org.apache.archiva.checksum;
import org.apache.commons.io.FilenameUtils;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Enumeration of available ChecksumAlgorithm techniques.
@ -30,22 +38,34 @@ import java.nio.file.Path;
*
*/
public enum ChecksumAlgorithm {
SHA1("SHA-1", "sha1", "SHA1"),
MD5("MD5", "md5", "MD5");
MD5("MD5", "MD5", "md5"),
SHA1("SHA-1", "SHA1", "sha1", "sha128", "sha-128"),
SHA256("SHA-256", "SHA2", "sha2", "sha256", "sha-256"),
SHA384("SHA-384", "SHA3", "sha3", "sha384", "sha-384"),
SHA512("SHA-512", "SHA5", "sha5", "sha512", "sha-512");
public static ChecksumAlgorithm getByExtension( Path file )
{
String ext = FilenameUtils.getExtension( file.getFileName().toString() ).toLowerCase();
if ( ChecksumAlgorithm.SHA1.getExt().equals( ext ) )
{
return ChecksumAlgorithm.SHA1;
}
else if ( ChecksumAlgorithm.MD5.getExt().equals( ext ) )
{
return ChecksumAlgorithm.MD5;
if (extensionMap.containsKey(ext)) {
return extensionMap.get(ext);
}
throw new IllegalArgumentException( "Filename " + file.getFileName() + " has no valid extension." );
}
throw new IllegalArgumentException( "Filename " + file.getFileName() + " has no associated extension." );
private static final Map<String, ChecksumAlgorithm> extensionMap = new HashMap<>( );
static {
for (ChecksumAlgorithm alg : ChecksumAlgorithm.values()) {
for (String extString : alg.getExt())
{
extensionMap.put( extString, alg );
}
}
}
public static Set<String> getExtensions() {
return extensionMap.keySet();
}
/**
@ -56,7 +76,7 @@ public enum ChecksumAlgorithm {
/**
* The file extension for this ChecksumAlgorithm.
*/
private final String ext;
private final List<String> ext;
/**
* The checksum type, the key that you see in checksum files.
@ -70,11 +90,12 @@ public enum ChecksumAlgorithm {
* @param ext the file extension.
* @param type the checksum type.
*/
private ChecksumAlgorithm( String algorithm, String ext, String type )
private ChecksumAlgorithm( String algorithm, String type, String... ext )
{
this.algorithm = algorithm;
this.ext = ext;
this.ext = Arrays.asList( ext );
this.type = type;
}
public String getAlgorithm()
@ -82,7 +103,7 @@ public enum ChecksumAlgorithm {
return algorithm;
}
public String getExt()
public List<String> getExt()
{
return ext;
}

View File

@ -0,0 +1,84 @@
package org.apache.archiva.checksum;
/*
* 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.
*/
/**
* Simple POJO for storing the data parsed from a checksum file.
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class ChecksumFileContent
{
String checksum;
String fileReference;
boolean formatMatch = false;
public ChecksumFileContent() {
}
public ChecksumFileContent(String checksum, String fileReference, boolean formatMatch) {
this.checksum = checksum;
this.fileReference = fileReference;
this.formatMatch = formatMatch;
}
/**
* The checksum as hex string.
*
* @return
*/
public String getChecksum( )
{
return checksum;
}
public void setChecksum( String checksum )
{
this.checksum = checksum;
}
/**
* The name of the reference file as stored in the checksum file.
* @return
*/
public String getFileReference( )
{
return fileReference;
}
public void setFileReference( String fileReference )
{
this.fileReference = fileReference;
}
/**
* True, if the file content matches a known format
* @return
*/
public boolean isFormatMatch( )
{
return formatMatch;
}
public void setFormatMatch( boolean formatMatch )
{
this.formatMatch = formatMatch;
}
}

View File

@ -0,0 +1,73 @@
package org.apache.archiva.checksum;
/*
* 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 java.nio.file.Path;
/**
*
* Simple POJO used to represent a one-to-one relationship between a reference file and
* a checksum file. The checksum file represents a certain algorithm.
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class ChecksumReference
{
private ChecksummedFile file;
private Path checksumFile;
private ChecksumAlgorithm algorithm;
ChecksumReference( ChecksummedFile file, ChecksumAlgorithm algo, Path checksumFile )
{
this.file = file;
this.algorithm = algo;
}
public ChecksummedFile getFile( )
{
return file;
}
public void setFile( ChecksummedFile file )
{
this.file = file;
}
public ChecksumAlgorithm getAlgorithm( )
{
return algorithm;
}
public void setAlgorithm( ChecksumAlgorithm algorithm )
{
this.algorithm = algorithm;
}
public Path getChecksumFile( )
{
return checksumFile;
}
public void setChecksumFile( Path checksumFile )
{
this.checksumFile = checksumFile;
}
}

View File

@ -26,11 +26,11 @@ package org.apache.archiva.checksum;
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class ChecksumValidationException extends Exception
public class ChecksumValidationException extends RuntimeException
{
public enum ValidationError {
INVALID_FORMAT, DIGEST_ERROR, READ_ERROR, FILE_NOT_FOUND
INVALID_FORMAT, DIGEST_ERROR, READ_ERROR, FILE_NOT_FOUND, BAD_CHECKSUM_FILE_REF
};
final private ValidationError errorType;

View File

@ -20,12 +20,11 @@ package org.apache.archiva.checksum;
*/
import org.apache.archiva.common.utils.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.xml.bind.ValidationException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
@ -35,6 +34,8 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.apache.archiva.checksum.ChecksumValidationException.ValidationError.BAD_CHECKSUM_FILE_REF;
/**
* ChecksummedFile
* <p>Terminology:</p>
@ -69,6 +70,20 @@ public class ChecksummedFile
this.referenceFile = referenceFile;
}
public static ChecksumReference getFromChecksumFile( Path checksumFile )
{
ChecksumAlgorithm alg = ChecksumAlgorithm.getByExtension( checksumFile );
ChecksummedFile file = new ChecksummedFile( getReferenceFile( checksumFile ) );
return new ChecksumReference( file, alg, checksumFile );
}
private static Path getReferenceFile( Path checksumFile )
{
String fileName = checksumFile.getFileName( ).toString( );
return checksumFile.resolveSibling( fileName.substring( 0, fileName.lastIndexOf( '.' ) ) );
}
/**
* Calculate the checksum based on a given checksum.
*
@ -80,12 +95,9 @@ public class ChecksummedFile
throws IOException
{
try (InputStream fis = Files.newInputStream( referenceFile ))
{
Checksum checksum = new Checksum( checksumAlgorithm );
checksum.update( fis );
return checksum.getChecksum();
}
Checksum checksum = new Checksum( checksumAlgorithm );
checksum.update( referenceFile );
return checksum.getChecksum( );
}
/**
@ -98,12 +110,12 @@ public class ChecksummedFile
public Path createChecksum( ChecksumAlgorithm checksumAlgorithm )
throws IOException
{
Path checksumFile = referenceFile.resolveSibling( referenceFile.getFileName() + "." + checksumAlgorithm.getExt() );
Path checksumFile = referenceFile.resolveSibling( referenceFile.getFileName( ) + "." + checksumAlgorithm.getExt( ).get( 0 ) );
Files.deleteIfExists( checksumFile );
String checksum = calculateChecksum( checksumAlgorithm );
Files.write( checksumFile, //
( checksum + " " + referenceFile.getFileName().toString() ).getBytes(), //
StandardOpenOption.CREATE_NEW );
( checksum + " " + referenceFile.getFileName( ).toString( ) ).getBytes( ), //
StandardOpenOption.CREATE_NEW );
return checksumFile;
}
@ -115,7 +127,15 @@ public class ChecksummedFile
*/
public Path getChecksumFile( ChecksumAlgorithm checksumAlgorithm )
{
return referenceFile.resolveSibling( referenceFile.getFileName() + "." + checksumAlgorithm.getExt() );
for ( String ext : checksumAlgorithm.getExt( ) )
{
Path file = referenceFile.resolveSibling( referenceFile.getFileName( ) + "." + checksumAlgorithm.getExt( ) );
if ( Files.exists( file ) )
{
return file;
}
}
return referenceFile.resolveSibling( referenceFile.getFileName( ) + "." + checksumAlgorithm.getExt( ).get( 0 ) );
}
/**
@ -130,10 +150,14 @@ public class ChecksummedFile
* @return true if the checksum is valid for the file it represents. or if the checksum file does not exist.
* @throws IOException if the reading of the checksumFile or the file it refers to fails.
*/
public boolean isValidChecksum( ChecksumAlgorithm algorithm )
throws IOException
public boolean isValidChecksum( ChecksumAlgorithm algorithm) throws ChecksumValidationException
{
return isValidChecksums( new ChecksumAlgorithm[]{ algorithm } );
return isValidChecksum( algorithm, false );
}
public boolean isValidChecksum( ChecksumAlgorithm algorithm, boolean throwExceptions )
throws ChecksumValidationException
{
return isValidChecksums( new ChecksumAlgorithm[]{algorithm} );
}
/**
@ -143,74 +167,92 @@ public class ChecksummedFile
* @param algorithms the algorithms to check for.
* @return true if the checksums report that the the reference file is valid, false if invalid.
*/
public boolean isValidChecksums( ChecksumAlgorithm algorithms[] )
public boolean isValidChecksums( ChecksumAlgorithm algorithms[]) throws ChecksumValidationException
{
return isValidChecksums( algorithms, false );
}
/**
* Checks if the checksums are valid for the referenced file.
* This method throws only exceptions, if throwExceptions is true. Otherwise false will be returned instead.
* @param algorithms The algorithms to verify
* @param throwExceptions If true, exceptions will be thrown, otherwise false will be returned, if a exception occurred.
* @return True, if it is valid, otherwise false.
* @throws ChecksumValidationException
*/
public boolean isValidChecksums( ChecksumAlgorithm algorithms[], boolean throwExceptions) throws ChecksumValidationException
{
try (InputStream fis = Files.newInputStream( referenceFile))
List<Checksum> checksums = new ArrayList<>( algorithms.length );
// Create checksum object for each algorithm.
for ( ChecksumAlgorithm checksumAlgorithm : algorithms )
{
List<Checksum> checksums = new ArrayList<>( algorithms.length );
// Create checksum object for each algorithm.
for ( ChecksumAlgorithm checksumAlgorithm : algorithms )
Path checksumFile = getChecksumFile( checksumAlgorithm );
// Only add algorithm if checksum file exists.
if ( Files.exists( checksumFile ) )
{
Path checksumFile = getChecksumFile( checksumAlgorithm );
// Only add algorithm if checksum file exists.
if ( Files.exists(checksumFile) )
{
checksums.add( new Checksum( checksumAlgorithm ) );
}
checksums.add( new Checksum( checksumAlgorithm ) );
}
// Any checksums?
if ( checksums.isEmpty() )
{
// No checksum objects, no checksum files, default to is invalid.
return false;
}
// Parse file once, for all checksums.
try
{
Checksum.update( checksums, fis );
}
catch ( IOException e )
{
log.warn( "Unable to update checksum:{}", e.getMessage() );
return false;
}
boolean valid = true;
// check the checksum files
try
{
for ( Checksum checksum : checksums )
{
ChecksumAlgorithm checksumAlgorithm = checksum.getAlgorithm();
Path checksumFile = getChecksumFile( checksumAlgorithm );
String rawChecksum = FileUtils.readFileToString( checksumFile , FILE_ENCODING );
String expectedChecksum = parseChecksum( rawChecksum, checksumAlgorithm, referenceFile.getFileName().toString() );
if ( !StringUtils.equalsIgnoreCase( expectedChecksum, checksum.getChecksum() ) )
{
valid = false;
}
}
}
catch ( IOException e )
{
log.warn( "Unable to read / parse checksum: {}", e.getMessage() );
return false;
}
return valid;
}
catch ( IOException e )
// Any checksums?
if ( checksums.isEmpty( ) )
{
log.warn( "Unable to read / parse checksum: {}", e.getMessage() );
// No checksum objects, no checksum files, default to is invalid.
return false;
}
// Parse file once, for all checksums.
try
{
Checksum.update( checksums, referenceFile );
}
catch ( ChecksumValidationException e )
{
log.warn( "Unable to update checksum:{}", e.getMessage( ) );
if (throwExceptions) {
throw e;
} else {
return false;
}
}
boolean valid = true;
// check the checksum files
try
{
for ( Checksum checksum : checksums )
{
ChecksumAlgorithm checksumAlgorithm = checksum.getAlgorithm( );
Path checksumFile = getChecksumFile( checksumAlgorithm );
String expectedChecksum = parseChecksum( checksumFile, checksumAlgorithm, referenceFile.getFileName( ).toString( ), FILE_ENCODING );
if ( !checksum.compare( expectedChecksum ) )
{
valid = false;
}
}
}
catch ( ChecksumValidationException e )
{
log.warn( "Unable to read / parse checksum: {}", e.getMessage( ) );
if (throwExceptions) {
throw e;
} else
{
return false;
}
}
return valid;
}
public Path getReferenceFile( )
{
return referenceFile;
}
/**
@ -229,20 +271,20 @@ public class ChecksummedFile
}
// Any checksums?
if ( checksums.isEmpty() )
if ( checksums.isEmpty( ) )
{
// No checksum objects, no checksum files, default to is valid.
return true;
}
try (InputStream fis = Files.newInputStream( referenceFile ))
try
{
// Parse file once, for all checksums.
Checksum.update( checksums, fis );
Checksum.update( checksums, referenceFile );
}
catch ( IOException e )
catch ( ChecksumValidationException e )
{
log.warn( e.getMessage(), e );
log.warn( e.getMessage( ), e );
return false;
}
@ -251,31 +293,28 @@ public class ChecksummedFile
// check the hash files
for ( Checksum checksum : checksums )
{
ChecksumAlgorithm checksumAlgorithm = checksum.getAlgorithm();
ChecksumAlgorithm checksumAlgorithm = checksum.getAlgorithm( );
try
{
Path checksumFile = getChecksumFile( checksumAlgorithm );
String actualChecksum = checksum.getChecksum();
if ( Files.exists(checksumFile) )
if ( Files.exists( checksumFile ) )
{
String rawChecksum = FileUtils.readFileToString( checksumFile, FILE_ENCODING);
String expectedChecksum = parseChecksum( rawChecksum, checksumAlgorithm, referenceFile.getFileName().toString() );
String expectedChecksum = parseChecksum( checksumFile, checksumAlgorithm, referenceFile.getFileName( ).toString( ), FILE_ENCODING );
if ( !StringUtils.equalsIgnoreCase( expectedChecksum, actualChecksum ) )
if ( !checksum.compare( expectedChecksum ) )
{
// create checksum (again)
FileUtils.writeStringToFile( checksumFile, FILE_ENCODING, actualChecksum + " " + referenceFile.getFileName().toString());
writeChecksumFile( checksumFile, FILE_ENCODING, checksum.getChecksum( ) );
}
}
else
{
FileUtils.writeStringToFile( checksumFile, FILE_ENCODING, actualChecksum + " " + referenceFile.getFileName().toString() );
writeChecksumFile( checksumFile, FILE_ENCODING, checksum.getChecksum( ) );
}
}
catch ( IOException e )
catch ( ChecksumValidationException e )
{
log.warn( e.getMessage(), e );
log.warn( e.getMessage( ), e );
valid = false;
}
}
@ -284,12 +323,17 @@ public class ChecksummedFile
}
private void writeChecksumFile( Path checksumFile, Charset encoding, String checksumHex )
{
FileUtils.writeStringToFile( checksumFile, FILE_ENCODING, checksumHex + " " + referenceFile.getFileName( ).toString( ) );
}
private boolean isValidChecksumPattern( String filename, String path )
{
// check if it is a remote metadata file
Matcher m = METADATA_PATTERN.matcher( path );
if ( m.matches() )
if ( m.matches( ) )
{
return filename.endsWith( path ) || ( "-".equals( filename ) ) || filename.endsWith( "maven-metadata.xml" );
}
@ -304,46 +348,56 @@ public class ChecksummedFile
* the trimmed checksum hex string.
* </p>
*
* @param rawChecksumString
* @param expectedHash
* @param expectedPath
* @param checksumFile The file where the checksum is stored
* @param expectedHash The checksum algorithm to check
* @param expectedPath The filename of the reference file
* @return
* @throws IOException
*/
public String parseChecksum( String rawChecksumString, ChecksumAlgorithm expectedHash, String expectedPath )
throws IOException
public String parseChecksum( Path checksumFile, ChecksumAlgorithm expectedHash, String expectedPath, Charset encoding )
throws ChecksumValidationException
{
String trimmedChecksum = rawChecksumString.replace( '\n', ' ' ).trim();
ChecksumFileContent fc = parseChecksumFile( checksumFile, expectedHash, encoding );
if ( fc.isFormatMatch() && !isValidChecksumPattern( fc.getFileReference( ), expectedPath ) )
{
throw new ChecksumValidationException(BAD_CHECKSUM_FILE_REF,
"The file reference '" + fc.getFileReference( ) + "' in the checksum file does not match expected file: '" + expectedPath + "'" );
}
return fc.getChecksum( );
}
public ChecksumFileContent parseChecksumFile( Path checksumFile, ChecksumAlgorithm expectedHash, Charset encoding )
{
ChecksumFileContent fc = new ChecksumFileContent( );
String rawChecksumString = FileUtils.readFileToString( checksumFile, encoding );
String trimmedChecksum = rawChecksumString.replace( '\n', ' ' ).trim( );
// Free-BSD / openssl
String regex = expectedHash.getType() + "\\s*\\(([^)]*)\\)\\s*=\\s*([a-fA-F0-9]+)";
String regex = expectedHash.getType( ) + "\\s*\\(([^)]*)\\)\\s*=\\s*([a-fA-F0-9]+)";
Matcher m = Pattern.compile( regex ).matcher( trimmedChecksum );
if ( m.matches() )
if ( m.matches( ) )
{
String filename = m.group( 1 );
if ( !isValidChecksumPattern( filename, expectedPath ) )
{
throw new IOException(
"Supplied checksum file '" + filename + "' does not match expected file: '" + expectedPath + "'" );
}
trimmedChecksum = m.group( 2 );
fc.setFileReference( m.group( 1 ) );
fc.setChecksum( m.group( 2 ) );
fc.setFormatMatch( true );
}
else
{
// GNU tools
m = Pattern.compile( "([a-fA-F0-9]+)\\s+\\*?(.+)" ).matcher( trimmedChecksum );
if ( m.matches() )
if ( m.matches( ) )
{
String filename = m.group( 2 );
if ( !isValidChecksumPattern( filename, expectedPath ) )
{
throw new IOException(
"Supplied checksum file '" + filename + "' does not match expected file: '" + expectedPath
+ "'" );
}
trimmedChecksum = m.group( 1 );
fc.setFileReference( m.group( 2 ) );
fc.setChecksum( m.group( 1 ) );
fc.setFormatMatch( true );
}
else
{
fc.setFileReference( "" );
fc.setChecksum( trimmedChecksum );
fc.setFormatMatch( false );
}
}
return trimmedChecksum;
return fc;
}
}

View File

@ -19,6 +19,8 @@ package org.apache.archiva.checksum;
* under the License.
*/
import javax.xml.bind.DatatypeConverter;
/**
* Hex - simple hex conversions.
*
@ -26,21 +28,15 @@ package org.apache.archiva.checksum;
*/
public class Hex
{
private static final byte[] DIGITS = "0123456789abcdef".getBytes();
public static String encode( byte[] data )
{
int l = data.length;
byte[] raw = new byte[l * 2];
for ( int i = 0, j = 0; i < l; i++ )
try
{
raw[j++] = DIGITS[( 0xF0 & data[i] ) >>> 4];
raw[j++] = DIGITS[0x0F & data[i]];
return DatatypeConverter.printHexBinary( data ).trim( ).toLowerCase( );
} catch (IllegalArgumentException e) {
return "";
}
return new String( raw );
}
public static String encode( String raw )
@ -48,4 +44,12 @@ public class Hex
return encode( raw.getBytes() );
}
public static byte[] decode( String data ) {
try
{
return DatatypeConverter.parseHexBinary( data.trim( ) );
} catch (IllegalArgumentException e) {
return new byte[0];
}
}
}

View File

@ -65,4 +65,5 @@ public abstract class AbstractChecksumTestCase
}
return file;
}
}

View File

@ -20,12 +20,16 @@ package org.apache.archiva.checksum;
*/
import junit.framework.TestCase;
import org.apache.archiva.common.utils.FileUtils;
import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
@ -36,9 +40,10 @@ import java.util.List;
*/
@RunWith( ArchivaBlockJUnit4ClassRunner.class )
public class ChecksumTest
extends TestCase
extends AbstractChecksumTestCase
{
private static final String UNSET_SHA1 = "da39a3ee5e6b4b0d3255bfef95601890afd80709";
private static final Charset FILE_ENCODING = Charset.forName( "UTF-8" );
@Test
public void testConstructSha1()
@ -68,7 +73,7 @@ public class ChecksumTest
@Test
public void testUpdateMany()
throws IOException
throws IOException, ChecksumValidationException
{
Checksum checksumSha1 = new Checksum( ChecksumAlgorithm.SHA1 );
Checksum checksumMd5 = new Checksum( ChecksumAlgorithm.MD5 );
@ -76,11 +81,11 @@ public class ChecksumTest
checksums.add( checksumSha1 );
checksums.add( checksumMd5 );
byte buf[] = ( "You know, I'm sick of following my dreams, man. "
+ "I'm just going to ask where they're going and hook up with 'em later. - Mitch Hedberg" ).getBytes();
Path checkFile = getTestOutputDir().resolve( "test-file1.txt" );
FileUtils.writeStringToFile( checkFile, FILE_ENCODING, "You know, I'm sick of following my dreams, man. "
+ "I'm just going to ask where they're going and hook up with 'em later. - Mitch Hedberg");
ByteArrayInputStream stream = new ByteArrayInputStream( buf );
Checksum.update( checksums, stream );
Checksum.update( checksums, checkFile );
assertEquals( "Checksum SHA1", "e396119ae0542e85a74759602fd2f81e5d36d762", checksumSha1.getChecksum() );
assertEquals( "Checksum MD5", "21c2c5ca87ec018adacb2e2fb3432219", checksumMd5.getChecksum() );

View File

@ -25,6 +25,7 @@ import org.junit.Before;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
@ -139,7 +140,7 @@ public class ChecksummedFileTest
@Test
public void testFixChecksum()
throws IOException
throws IOException, ChecksumValidationException
{
Path jarFile = createTestableJar( "examples/redback-authz-open.jar" );
Path sha1File = jarFile.resolveSibling( jarFile.getFileName()+ ".sha1" );
@ -167,7 +168,7 @@ public class ChecksummedFileTest
@Test
public void testIsValidChecksum()
throws IOException
throws IOException, ChecksumValidationException
{
Path jarFile = createTestableJar( "examples/redback-authz-open.jar", true, false );
@ -177,7 +178,7 @@ public class ChecksummedFileTest
@Test
public void testIsValidChecksumInvalidSha1Format()
throws IOException
throws IOException, ChecksumValidationException
{
Path jarFile = createTestableJar( "examples/redback-authz-open.jar" );
Path sha1File = jarFile.resolveSibling( jarFile.getFileName() + ".sha1" );
@ -192,7 +193,7 @@ public class ChecksummedFileTest
@Test
public void testIsValidChecksumNoChecksumFiles()
throws IOException
throws IOException, ChecksumValidationException
{
Path jarFile = createTestableJar( "examples/redback-authz-open.jar", false, false );
@ -204,7 +205,7 @@ public class ChecksummedFileTest
@Test
public void testIsValidChecksumSha1AndMd5()
throws IOException
throws IOException, ChecksumValidationException
{
Path jarFile = createTestableJar( "examples/redback-authz-open.jar", true, true );
@ -215,7 +216,7 @@ public class ChecksummedFileTest
@Test
public void testIsValidChecksumSha1NoMd5()
throws IOException
throws IOException, ChecksumValidationException
{
Path jarFile = createTestableJar( "examples/redback-authz-open.jar", true, false );
@ -227,40 +228,43 @@ public class ChecksummedFileTest
@Test
public void testParseChecksum()
throws IOException
throws IOException, ChecksumValidationException
{
String expected = SERVLETAPI_SHA1
+ " /home/projects/maven/repository-staging/to-ibiblio/maven2/servletapi/servletapi/2.4/servletapi-2.4.pom";
Path expectedFile = getTestOutputDir().resolve("servletapi-2.4.pom.sha1");
FileUtils.writeStringToFile( expectedFile, FILE_ENCODING, SERVLETAPI_SHA1
+ " /home/projects/maven/repository-staging/to-ibiblio/maven2/servletapi/servletapi/2.4/servletapi-2.4.pom");
Path testfile = getTestResource( "examples/redback-authz-open.jar" );
ChecksummedFile checksummedFile = new ChecksummedFile( testfile );
String s = checksummedFile.parseChecksum( expected, ChecksumAlgorithm.SHA1,
"servletapi/servletapi/2.4/servletapi-2.4.pom" );
String s = checksummedFile.parseChecksum( expectedFile, ChecksumAlgorithm.SHA1,
"servletapi/servletapi/2.4/servletapi-2.4.pom", FILE_ENCODING);
assertEquals( "Checksum doesn't match", SERVLETAPI_SHA1, s );
}
@Test
public void testParseChecksumAltDash1()
throws IOException
throws IOException, ChecksumValidationException
{
String expected = SERVLETAPI_SHA1 + " -";
Path expectedFile = getTestOutputDir().resolve("redback-authz-open.jar.sha1");
FileUtils.writeStringToFile( expectedFile, FILE_ENCODING, SERVLETAPI_SHA1 + " -");
Path testfile = getTestResource( "examples/redback-authz-open.jar" );
ChecksummedFile checksummedFile = new ChecksummedFile( testfile );
String s = checksummedFile.parseChecksum( expected, ChecksumAlgorithm.SHA1,
"servletapi/servletapi/2.4/servletapi-2.4.pom" );
String s = checksummedFile.parseChecksum( expectedFile, ChecksumAlgorithm.SHA1,
"servletapi/servletapi/2.4/servletapi-2.4.pom", FILE_ENCODING );
assertEquals( "Checksum doesn't match", SERVLETAPI_SHA1, s );
}
@Test
public void testParseChecksumAltDash2()
throws IOException
throws IOException, ChecksumValidationException
{
String expected = "SHA1(-)=" + SERVLETAPI_SHA1;
Path expectedFile = getTestOutputDir().resolve("redback-authz-open.jar.sha1");
FileUtils.writeStringToFile( expectedFile, FILE_ENCODING, "SHA1(-)=" + SERVLETAPI_SHA1);
Path testfile = getTestResource( "examples/redback-authz-open.jar" );
ChecksummedFile checksummedFile = new ChecksummedFile( testfile );
String s = checksummedFile.parseChecksum( expected, ChecksumAlgorithm.SHA1,
"servletapi/servletapi/2.4/servletapi-2.4.pom" );
String s = checksummedFile.parseChecksum( expectedFile, ChecksumAlgorithm.SHA1,
"servletapi/servletapi/2.4/servletapi-2.4.pom" , FILE_ENCODING);
assertEquals( "Checksum doesn't match", SERVLETAPI_SHA1, s );
}
@ -268,16 +272,17 @@ public class ChecksummedFileTest
public void testRemoteMetadataChecksumFilePathSha1()
throws IOException
{
String expected = REMOTE_METADATA_SHA1 + " /home/test/repository/examples/metadata/maven-metadata.xml";
Path expectedFile = getTestOutputDir().resolve("maven-metadata-remote.xml.sha1");
FileUtils.writeStringToFile( expectedFile, FILE_ENCODING, REMOTE_METADATA_SHA1 + " /home/test/repository/examples/metadata/maven-metadata.xml");
Path testfile = getTestResource( "examples/metadata/maven-metadata-remote.xml" );
ChecksummedFile checksummedFile = new ChecksummedFile( testfile );
try
{
String s = checksummedFile.parseChecksum( expected, ChecksumAlgorithm.SHA1, "maven-metadata-remote.xml" );
String s = checksummedFile.parseChecksum( expectedFile, ChecksumAlgorithm.SHA1, "maven-metadata-remote.xml", FILE_ENCODING );
assertEquals( "Checksum doesn't match", REMOTE_METADATA_SHA1, s );
}
catch ( IOException e )
catch ( ChecksumValidationException e )
{
e.printStackTrace();
fail( "IOException should not occur." );
@ -288,16 +293,17 @@ public class ChecksummedFileTest
public void testRemoteMetadataChecksumFilePathMd5()
throws IOException
{
String expected = REMOTE_METADATA_MD5 + " ./examples/metadata/maven-metadata.xml";
Path expectedFile = getTestOutputDir().resolve( "maven-metadata.xml.md5" );
FileUtils.writeStringToFile( expectedFile, FILE_ENCODING, REMOTE_METADATA_MD5 + " ./examples/metadata/maven-metadata.xml");
Path testfile = getTestResource( "examples/metadata/maven-metadata-remote.xml" );
ChecksummedFile checksummedFile = new ChecksummedFile( testfile );
try
{
String s = checksummedFile.parseChecksum( expected, ChecksumAlgorithm.MD5, "maven-metadata-remote.xml" );
String s = checksummedFile.parseChecksum( expectedFile, ChecksumAlgorithm.MD5, "maven-metadata-remote.xml", FILE_ENCODING );
assertEquals( "Checksum doesn't match", REMOTE_METADATA_MD5, s );
}
catch ( IOException e )
catch ( ChecksumValidationException e )
{
e.printStackTrace();
fail( "IOException should not occur." );

View File

@ -42,6 +42,10 @@
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-consumer-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-checksum</artifactId>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-repository-admin-api</artifactId>
@ -223,7 +227,6 @@
org.apache.commons.io;version="[1.4,2)",
org.apache.commons.lang*;version="[2.4,3)",
org.springframework*;version="[3,4)",
org.codehaus.plexus.digest,
org.apache.archiva.redback.components.registry,
org.apache.archiva.metadata.model*;version=${project.version},
org.apache.archiva.metadata.repository.storage.maven2*;version=${project.version},

View File

@ -1,181 +0,0 @@
package org.apache.archiva.checksum;
/*
* 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 javax.xml.bind.DatatypeConverter;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import static org.apache.archiva.checksum.ChecksumValidationException.ValidationError.*;
/**
* Class for validating checksums.
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class ChecksumValidator
{
private final int NOT_INITALIZED = 0;
private final int INITIALIZING = 1;
private final int INITIALIZED = 2;
private AtomicInteger status = new AtomicInteger( NOT_INITALIZED );
private static final Map<String, String> supportedTypes = new HashMap<>( );
public ChecksumValidator() {
init();
}
private void init() {
int val;
if (status.compareAndSet( NOT_INITALIZED, INITIALIZING ))
{
try
{
supportedTypes.put( "md5", "MD5" );
supportedTypes.put( "sha1", "SHA-1" );
supportedTypes.put( "sha-1", "SHA-1" );
supportedTypes.put( "sha2", "SHA-256" );
supportedTypes.put( "sha256", "SHA-256" );
supportedTypes.put( "sha-256", "SHA-256" );
supportedTypes.put( "sha3", "SHA-384" );
supportedTypes.put( "sha384", "SHA-384" );
supportedTypes.put( "sha-384", "SHA-384" );
supportedTypes.put( "sha5", "SHA-512" );
supportedTypes.put( "sha512", "SHA-512" );
supportedTypes.put( "sha-512", "SHA-512" );
} finally
{
status.set(INITIALIZED);
}
} else if ((val = status.intValue())!=INITIALIZED) {
do
{
try
{
Thread.currentThread().sleep(100);
val = status.intValue();
}
catch ( InterruptedException e )
{
// Ignore
}
} while(val!=INITIALIZED);
}
}
public boolean isValidChecksum(Path checksumFile) throws ChecksumValidationException
{
String fileName = checksumFile.getFileName().toString();
if (!Files.exists( checksumFile )) {
throw new ChecksumValidationException( FILE_NOT_FOUND, "Checksum file does not exist: "+checksumFile );
}
String extension = fileName.substring( fileName.lastIndexOf( '.' )+1).toLowerCase();
String digestType = this.supportedTypes.get(extension);
if (digestType==null) {
throw new ChecksumValidationException( INVALID_FORMAT, "The extension '"+extension+"' ist not known." );
}
Path checkFile = null;
try
{
MessageDigest md = MessageDigest.getInstance( digestType );
checkFile = getCheckFile( checksumFile );
byte[] computedChecksum = computeHash( checkFile, md );
byte[] readChecksum = readHashFile( checksumFile );
return md.isEqual( computedChecksum, readChecksum );
}
catch ( NoSuchAlgorithmException e )
{
throw new ChecksumValidationException( DIGEST_ERROR, "The digest is not supported "+digestType );
}
catch ( IOException e )
{
throw new ChecksumValidationException( READ_ERROR, "Error while computing the checksum of "+checkFile+": "+e.getMessage(), e);
}
}
private Path getCheckFile(Path checksumFile) {
String fileName = checksumFile.getFileName().toString();
String newName = fileName.substring(0, fileName.lastIndexOf('.'));
return checksumFile.getParent().resolve(newName);
}
public Set<String> getSupportedExtensions() {
return supportedTypes.keySet();
}
public byte[] computeHash(Path file, MessageDigest digest) throws IOException
{
byte[] result;
try(FileChannel inChannel = FileChannel.open( file, StandardOpenOption.READ ))
{
MappedByteBuffer buffer = inChannel.map( FileChannel.MapMode.READ_ONLY, 0, inChannel.size( ) );
digest.update( buffer );
result = digest.digest( );
}
return result;
}
public byte[] computeHash(Path file, String type) throws ChecksumValidationException, NoSuchAlgorithmException, IOException
{
if (!supportedTypes.containsKey( type )) {
throw new ChecksumValidationException( INVALID_FORMAT );
}
return computeHash( file, MessageDigest.getInstance( supportedTypes.get(type) ) );
}
public byte[] readHashFile(Path file) throws IOException
{
StringBuilder sb = new StringBuilder( );
try(BufferedReader reader = Files.newBufferedReader( file, StandardCharsets.US_ASCII )){
int ci;
while((ci = reader.read()) != -1) {
char c = (char)ci;
if (Character.isWhitespace( c )) {
break;
} else {
sb.append(c);
}
}
return convertFromHex( sb.toString() );
}
}
protected String convertToHex(byte[] array) {
return DatatypeConverter.printHexBinary( array ).trim().toLowerCase();
}
protected byte[] convertFromHex(String checksum) {
return DatatypeConverter.parseHexBinary( checksum.trim().toLowerCase() );
}
}

View File

@ -155,25 +155,16 @@ public class ArtifactMissingChecksumsConsumer
private void createFixChecksum( String path, ChecksumAlgorithm checksumAlgorithm )
{
Path artifactFile = repositoryDir.resolve(path);
Path checksumFile = repositoryDir.resolve(path + "." + checksumAlgorithm.getExt( ) );
Path checksumFile = repositoryDir.resolve(path + "." + checksumAlgorithm.getExt( ).get(0) );
if ( Files.exists(checksumFile) )
{
checksum = new ChecksummedFile( artifactFile);
try
if ( !checksum.isValidChecksum( checksumAlgorithm ) )
{
if ( !checksum.isValidChecksum( checksumAlgorithm ) )
{
checksum.fixChecksums( new ChecksumAlgorithm[]{checksumAlgorithm} );
log.info( "Fixed checksum file {}", checksumFile.toAbsolutePath( ) );
triggerConsumerInfo( "Fixed checksum file " + checksumFile.toAbsolutePath( ) );
}
}
catch ( IOException e )
{
log.error( "Cannot calculate checksum for file {} :", checksumFile, e );
triggerConsumerError( TYPE_CHECKSUM_CANNOT_CALC, "Cannot calculate checksum for file " + checksumFile +
": " + e.getMessage( ) );
checksum.fixChecksums( new ChecksumAlgorithm[]{checksumAlgorithm} );
log.info( "Fixed checksum file {}", checksumFile.toAbsolutePath( ) );
triggerConsumerInfo( "Fixed checksum file " + checksumFile.toAbsolutePath( ) );
}
}
else if ( !Files.exists(checksumFile) )

View File

@ -19,8 +19,10 @@ package org.apache.archiva.consumers.core;
* under the License.
*/
import org.apache.archiva.checksum.ChecksumAlgorithm;
import org.apache.archiva.checksum.ChecksumReference;
import org.apache.archiva.checksum.ChecksumValidationException;
import org.apache.archiva.checksum.ChecksumValidator;
import org.apache.archiva.checksum.ChecksummedFile;
import org.apache.archiva.consumers.AbstractMonitoredConsumer;
import org.apache.archiva.consumers.ConsumerException;
import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
@ -63,8 +65,6 @@ public class ValidateChecksumConsumer
private String description = "Validate checksums against file.";
ThreadLocal<ChecksumValidator> validatorThreadLocal = new ThreadLocal<>();
private Path repositoryDir;
private List<String> includes;
@ -123,16 +123,11 @@ public class ValidateChecksumConsumer
public void processFile( String path )
throws ConsumerException
{
ChecksumValidator validator;
if ((validator=validatorThreadLocal.get())==null) {
validator = new ChecksumValidator();
validatorThreadLocal.set(validator);
}
Path checksumFile = this.repositoryDir.resolve( path );
try
{
if ( !validator.isValidChecksum( checksumFile ) )
ChecksumReference cf = ChecksummedFile.getFromChecksumFile( checksumFile );
if ( !cf.getFile().isValidChecksum( cf.getAlgorithm(), true ) )
{
log.warn( "The checksum for {} is invalid.", checksumFile );
triggerConsumerWarning( NOT_VALID_CHECKSUM, "The checksum for " + checksumFile + " is invalid." );
@ -164,12 +159,7 @@ public class ValidateChecksumConsumer
@PostConstruct
public void initialize( )
{
ChecksumValidator validator;
if ((validator=validatorThreadLocal.get())==null) {
validator = new ChecksumValidator();
validatorThreadLocal.set(validator);
}
Set<String> extensions = validator.getSupportedExtensions();
Set<String> extensions = ChecksumAlgorithm.getExtensions();
includes = new ArrayList<>( extensions.size() );
for ( String ext : extensions )
{

View File

@ -1,145 +0,0 @@
package org.apache.archiva.checksum;
/*
* 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.junit.Test;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
/**
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class ChecksumValidatorTest
{
@Test
public void isValidChecksum( ) throws URISyntaxException, ChecksumValidationException
{
ChecksumValidator validator = new ChecksumValidator();
String fileName = "checksum/checksumTest1.txt";
List<String> exts = Arrays.asList( "md5", "sha1", "sha2", "sha3", "sha5" );
for(String ext : exts)
{
Path hashFile = Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( fileName + "."+ext ).toURI( ) );
assertTrue( validator.isValidChecksum( hashFile ) );
}
fileName = "checksum/checksumTest2.txt";
for(String ext : exts)
{
Path hashFile = Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( fileName + "."+ext ).toURI( ) );
assertTrue( validator.isValidChecksum( hashFile ) );
}
}
@Test
public void isInValidChecksum( ) throws URISyntaxException, ChecksumValidationException
{
ChecksumValidator validator = new ChecksumValidator();
String fileName = "checksum/checksumTest3.txt";
List<String> exts = Arrays.asList( "md5", "sha1", "sha2", "sha3", "sha5" );
for(String ext : exts)
{
Path hashFile = Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( fileName + "."+ext ).toURI( ) );
assertFalse( validator.isValidChecksum( hashFile ) );
}
}
@Test
public void isInvalidExtension( ) throws URISyntaxException, ChecksumValidationException
{
ChecksumValidator validator = new ChecksumValidator();
String fileName = "checksum/checksumTest1.txt";
String ext = "md8";
try
{
Path hashFile = Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( fileName + "." + ext ).toURI( ) );
validator.isValidChecksum( hashFile );
} catch (ChecksumValidationException e) {
assertEquals(ChecksumValidationException.ValidationError.INVALID_FORMAT, e.getErrorType());
}
}
@Test
public void computeFileDoesNotExist( ) throws URISyntaxException, ChecksumValidationException
{
ChecksumValidator validator = new ChecksumValidator();
String fileName = "checksum/checksumTest4.txt";
String ext = "md5";
try
{
Path hashFile = Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( fileName + "." + ext ).toURI( ) );
validator.isValidChecksum( hashFile );
} catch (ChecksumValidationException e) {
assertEquals(ChecksumValidationException.ValidationError.READ_ERROR, e.getErrorType());
}
}
@Test
public void checksumFileDoesNotExist( ) throws URISyntaxException, ChecksumValidationException
{
ChecksumValidator validator = new ChecksumValidator();
String fileName = "checksumTest5.txt";
String ext = "md5";
try
{
Path sibling = Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "checksum/checksumTest1.txt." + ext ).toURI( ) );
Path hashFile = sibling.getParent().resolve(fileName);
validator.isValidChecksum( hashFile );
} catch (ChecksumValidationException e) {
assertEquals(ChecksumValidationException.ValidationError.FILE_NOT_FOUND, e.getErrorType());
}
}
@Test
public void computeHash( ) throws URISyntaxException, NoSuchAlgorithmException, IOException, ChecksumValidationException
{
ChecksumValidator validator = new ChecksumValidator();
Map<String, String> hashes = new HashMap<>( );
hashes.put("md5","079fe13e970ae7311172df6657f36892");
hashes.put("sha1", "01e14abba5401e1a63be468f9c3b723167f27dc8");
hashes.put("sha2", "ae7278e7bdfd8d7c06f9b1932ddccdddb0061a58a893aec3f00932e53ef9c794");
hashes.put("sha3", "a52efc629f256cd2b390f080ab7e23fc706ab9e2c8948cea2bd8504a70894f69f44f48e83c889edc82b40b673b575bad");
hashes.put("sha5", "b2340bbf150403725fdf6a6f340a8a33bb9526bad7e0220f1dfea67d5a06217bc1d5c3a773b083ed8c9f5352c94ecc6da2a6d8a33ad0347566f0acc55e042fde");
Path hashFile = Paths.get( Thread.currentThread( ).getContextClassLoader( ).getResource( "checksum/checksumTest1.txt").toURI( ) );
for (String key : hashes.keySet()) {
byte[] expectedSum = validator.convertFromHex( hashes.get(key) );
byte[] computedSum = validator.computeHash( hashFile, key );
assertArrayEquals( expectedSum, computedSum );
}
}
@Test
public void readHashFile( )
{
}
}

View File

@ -1,26 +0,0 @@
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum
dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero
eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel
eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto
odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis
nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et
gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur

View File

@ -1 +0,0 @@
01e14abba5401e1a63be468f9c3b723167f27dc8 checksumTest1.txt

View File

@ -1 +0,0 @@
ae7278e7bdfd8d7c06f9b1932ddccdddb0061a58a893aec3f00932e53ef9c794 checksumTest1.txt

View File

@ -1 +0,0 @@
a52efc629f256cd2b390f080ab7e23fc706ab9e2c8948cea2bd8504a70894f69f44f48e83c889edc82b40b673b575bad checksumTest1.txt

View File

@ -1 +0,0 @@
b2340bbf150403725fdf6a6f340a8a33bb9526bad7e0220f1dfea67d5a06217bc1d5c3a773b083ed8c9f5352c94ecc6da2a6d8a33ad0347566f0acc55e042fde checksumTest1.txt

View File

@ -1,27 +0,0 @@
Check 2
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum
dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero
eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel
eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto
odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis
nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et
gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur

View File

@ -1 +0,0 @@
0DD0E1EFBF8F699A0EF286A271D8210CE2E80702AD5528F36592C89985D6B151

View File

@ -1 +0,0 @@
5a5d1b11fdc498da5a592205714117656f40fea644adab07f110e1d512c79c6ded126972c1693483f21b592dd2030878

View File

@ -1 +0,0 @@
a379ef07490328fb934fcadfa1b7794e532782c2097d3aa82e41ff9bd86527830f711a0c456af65a14a511bad73ddc08a30593d74ec6d42bcc9ee0747acfdf91

View File

@ -1,25 +0,0 @@
Check 3
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum
dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero
eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel
eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto
odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis
nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et
gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur

View File

@ -1 +0,0 @@
0dd0e1efbf8f699a0ef286a271d8210ce2e80702ad5528f36592c89985d6b151

View File

@ -1 +0,0 @@
5a5d1b11fdc498da5a592205714117656f40fea644adab07f110e1d512c79c6ded126972c1693483f21b592dd2030878

View File

@ -1 +0,0 @@
a379ef07490328fb934fcadfa1b7794e532782c2097d3aa82e41ff9bd86527830f711a0c456af65a14a511bad73ddc08a30593d74ec6d42bcc9ee0747acfdf91

View File

@ -118,7 +118,7 @@ public class ChecksumPolicy
for ( ChecksumAlgorithm algorithm : algorithms )
{
Path file = localFile.toAbsolutePath().resolveSibling( localFile.getFileName() + "." + algorithm.getExt() );
Path file = checksum.getChecksumFile( algorithm );
try
{
Files.deleteIfExists( file );

View File

@ -38,7 +38,6 @@ import org.apache.archiva.repository.scanner.RepositoryScanner;
import org.apache.archiva.repository.scanner.RepositoryScannerException;
import org.apache.archiva.scheduler.repository.model.RepositoryTask;
import org.apache.commons.lang.StringUtils;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@ -83,7 +82,6 @@ public class ArchivaRepositoryScanningTaskExecutor
@PostConstruct
public void initialize()
throws InitializationException
{
log.info( "Initialized {}", this.getClass().getName() );
}