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;
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 );
}
}
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()
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 ));
+ }
}
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.
*
*/
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;
+ if (extensionMap.containsKey(ext)) {
+ return extensionMap.get(ext);
}
- else if ( ChecksumAlgorithm.MD5.getExt().equals( ext ) )
- {
- return ChecksumAlgorithm.MD5;
+ throw new IllegalArgumentException( "Filename " + file.getFileName() + " has no valid 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 );
+ }
}
+ }
- throw new IllegalArgumentException( "Filename " + file.getFileName() + " has no associated extension." );
+ public static Set<String> getExtensions() {
+ return extensionMap.keySet();
}
/**
/**
* 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.
* @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()
return algorithm;
}
- public String getExt()
+ public List<String> getExt()
{
return ext;
}
--- /dev/null
+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;
+ }
+}
--- /dev/null
+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;
+ }
+}
--- /dev/null
+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.
+ */
+
+/**
+ * Exception thrown by the ChecksumValidator
+ *
+ * Has an error type for different validation errors.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class ChecksumValidationException extends RuntimeException
+{
+
+ public enum ValidationError {
+ INVALID_FORMAT, DIGEST_ERROR, READ_ERROR, FILE_NOT_FOUND, BAD_CHECKSUM_FILE_REF
+ };
+
+ final private ValidationError errorType;
+
+ public ChecksumValidationException( ValidationError errorType )
+ {
+ super( );
+ this.errorType = errorType;
+ }
+
+ public ChecksumValidationException( ValidationError errorType, String message )
+ {
+ super( message );
+ this.errorType = errorType;
+ }
+
+ public ChecksumValidationException( ValidationError errorType, String message, Throwable cause )
+ {
+ super( message, cause );
+ this.errorType = errorType;
+ }
+
+ public ChecksumValidationException( ValidationError errorType, Throwable cause )
+ {
+ super( cause );
+ this.errorType = errorType;
+ }
+
+ public ValidationError getErrorType() {
+ return errorType;
+ }
+}
*/
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;
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>
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.
*
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( );
}
/**
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;
}
*/
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 ) );
}
/**
* @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 isValidChecksum( algorithm, false );
+ }
+ public boolean isValidChecksum( ChecksumAlgorithm algorithm, boolean throwExceptions )
+ throws ChecksumValidationException
{
- return isValidChecksums( new ChecksumAlgorithm[]{ algorithm } );
+ return isValidChecksums( new ChecksumAlgorithm[]{algorithm} );
}
/**
* @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 );
+ }
- try (InputStream fis = Files.newInputStream( referenceFile))
- {
- List<Checksum> checksums = new ArrayList<>( algorithms.length );
- // Create checksum object for each algorithm.
- for ( ChecksumAlgorithm checksumAlgorithm : algorithms )
- {
- Path checksumFile = getChecksumFile( checksumAlgorithm );
+ /**
+ * 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
+ {
- // Only add algorithm if checksum file exists.
- if ( Files.exists(checksumFile) )
- {
- checksums.add( new Checksum( checksumAlgorithm ) );
- }
- }
+ List<Checksum> checksums = new ArrayList<>( algorithms.length );
+ // Create checksum object for each algorithm.
+ for ( ChecksumAlgorithm checksumAlgorithm : algorithms )
+ {
+ Path checksumFile = getChecksumFile( checksumAlgorithm );
- // Any checksums?
- if ( checksums.isEmpty() )
+ // Only add algorithm if checksum file exists.
+ if ( Files.exists( checksumFile ) )
{
- // No checksum objects, no checksum files, default to is invalid.
- return false;
+ checksums.add( new Checksum( checksumAlgorithm ) );
}
+ }
- // Parse file once, for all checksums.
- try
- {
- Checksum.update( checksums, fis );
- }
- catch ( IOException e )
- {
- log.warn( "Unable to update checksum:{}", e.getMessage() );
+ // 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, referenceFile );
+ }
+ catch ( ChecksumValidationException e )
+ {
+ log.warn( "Unable to update checksum:{}", e.getMessage( ) );
+ if (throwExceptions) {
+ throw e;
+ } else {
return false;
}
+ }
- boolean valid = true;
+ boolean valid = true;
- // check the checksum files
- try
+ // check the checksum files
+ try
+ {
+ for ( Checksum checksum : checksums )
{
- for ( Checksum checksum : checksums )
- {
- ChecksumAlgorithm checksumAlgorithm = checksum.getAlgorithm();
- Path checksumFile = getChecksumFile( checksumAlgorithm );
+ ChecksumAlgorithm checksumAlgorithm = checksum.getAlgorithm( );
+ Path checksumFile = getChecksumFile( checksumAlgorithm );
- 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, checksum.getChecksum() ) )
- {
- valid = false;
- }
+ if ( !checksum.compare( expectedChecksum ) )
+ {
+ valid = false;
}
}
- catch ( IOException e )
+ }
+ catch ( ChecksumValidationException e )
+ {
+ log.warn( "Unable to read / parse checksum: {}", e.getMessage( ) );
+ if (throwExceptions) {
+ throw e;
+ } else
{
- log.warn( "Unable to read / parse checksum: {}", e.getMessage() );
return false;
}
-
- return valid;
- }
- catch ( IOException e )
- {
- log.warn( "Unable to read / parse checksum: {}", e.getMessage() );
- return false;
}
+
+ return valid;
+ }
+
+ public Path getReferenceFile( )
+ {
+ return referenceFile;
}
/**
}
// 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;
}
// 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;
}
}
}
+ 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" );
}
* 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
+ {
+ 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 )
{
- String trimmedChecksum = rawChecksumString.replace( '\n', ' ' ).trim();
+ 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;
}
}
* under the License.
*/
+import javax.xml.bind.DatatypeConverter;
+
/**
* Hex - simple hex conversions.
*
*/
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 )
return encode( raw.getBytes() );
}
+ public static byte[] decode( String data ) {
+ try
+ {
+ return DatatypeConverter.parseHexBinary( data.trim( ) );
+ } catch (IllegalArgumentException e) {
+ return new byte[0];
+ }
+ }
}
*/
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;
*/
@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()
@Test
public void testUpdateMany()
- throws IOException
+ throws IOException, ChecksumValidationException
{
Checksum checksumSha1 = new Checksum( ChecksumAlgorithm.SHA1 );
Checksum checksumMd5 = new Checksum( ChecksumAlgorithm.MD5 );
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() );
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;
@Test
public void testFixChecksum()
- throws IOException
+ throws IOException, ChecksumValidationException
{
Path jarFile = createTestableJar( "examples/redback-authz-open.jar" );
Path sha1File = jarFile.resolveSibling( jarFile.getFileName()+ ".sha1" );
@Test
public void testIsValidChecksum()
- throws IOException
+ throws IOException, ChecksumValidationException
{
Path jarFile = createTestableJar( "examples/redback-authz-open.jar", true, false );
@Test
public void testIsValidChecksumInvalidSha1Format()
- throws IOException
+ throws IOException, ChecksumValidationException
{
Path jarFile = createTestableJar( "examples/redback-authz-open.jar" );
Path sha1File = jarFile.resolveSibling( jarFile.getFileName() + ".sha1" );
@Test
public void testIsValidChecksumNoChecksumFiles()
- throws IOException
+ throws IOException, ChecksumValidationException
{
Path jarFile = createTestableJar( "examples/redback-authz-open.jar", false, false );
@Test
public void testIsValidChecksumSha1AndMd5()
- throws IOException
+ throws IOException, ChecksumValidationException
{
Path jarFile = createTestableJar( "examples/redback-authz-open.jar", true, true );
@Test
public void testIsValidChecksumSha1NoMd5()
- throws IOException
+ throws IOException, ChecksumValidationException
{
Path jarFile = createTestableJar( "examples/redback-authz-open.jar", true, false );
@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 );
}
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." );
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." );
<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>
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},
+++ /dev/null
-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.
- */
-
-/**
- * Exception thrown by the ChecksumValidator
- *
- * Has an error type for different validation errors.
- *
- * @author Martin Stockhammer <martin_s@apache.org>
- */
-public class ChecksumValidationException extends Exception
-{
-
- public enum ValidationError {
- INVALID_FORMAT, DIGEST_ERROR, READ_ERROR, FILE_NOT_FOUND
- };
-
- final private ValidationError errorType;
-
- public ChecksumValidationException( ValidationError errorType )
- {
- super( );
- this.errorType = errorType;
- }
-
- public ChecksumValidationException( ValidationError errorType, String message )
- {
- super( message );
- this.errorType = errorType;
- }
-
- public ChecksumValidationException( ValidationError errorType, String message, Throwable cause )
- {
- super( message, cause );
- this.errorType = errorType;
- }
-
- public ChecksumValidationException( ValidationError errorType, Throwable cause )
- {
- super( cause );
- this.errorType = errorType;
- }
-
- public ValidationError getErrorType() {
- return errorType;
- }
-}
+++ /dev/null
-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() );
- }
-
-
-}
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) )
* 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;
private String description = "Validate checksums against file.";
- ThreadLocal<ChecksumValidator> validatorThreadLocal = new ThreadLocal<>();
-
private Path repositoryDir;
private List<String> includes;
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." );
@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 )
{
+++ /dev/null
-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( )
- {
- }
-}
\ No newline at end of file
+++ /dev/null
-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
+++ /dev/null
-079fe13e970ae7311172df6657f36892 checksumTest1.txt
+++ /dev/null
-079fe13e970ae7311172df6657f36892 checksumTest1.txt
+++ /dev/null
-01e14abba5401e1a63be468f9c3b723167f27dc8 checksumTest1.txt
+++ /dev/null
-ae7278e7bdfd8d7c06f9b1932ddccdddb0061a58a893aec3f00932e53ef9c794 checksumTest1.txt
+++ /dev/null
-a52efc629f256cd2b390f080ab7e23fc706ab9e2c8948cea2bd8504a70894f69f44f48e83c889edc82b40b673b575bad checksumTest1.txt
+++ /dev/null
-b2340bbf150403725fdf6a6f340a8a33bb9526bad7e0220f1dfea67d5a06217bc1d5c3a773b083ed8c9f5352c94ecc6da2a6d8a33ad0347566f0acc55e042fde checksumTest1.txt
+++ /dev/null
-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
+++ /dev/null
-f3b8a0ebd9ce6dd66c2830c46eeb62dc
+++ /dev/null
-b293f144df87783d66020a0f73654be459673054
+++ /dev/null
-0DD0E1EFBF8F699A0EF286A271D8210CE2E80702AD5528F36592C89985D6B151
+++ /dev/null
-5a5d1b11fdc498da5a592205714117656f40fea644adab07f110e1d512c79c6ded126972c1693483f21b592dd2030878
+++ /dev/null
-a379ef07490328fb934fcadfa1b7794e532782c2097d3aa82e41ff9bd86527830f711a0c456af65a14a511bad73ddc08a30593d74ec6d42bcc9ee0747acfdf91
+++ /dev/null
-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
+++ /dev/null
-f3b8a0ebd9ce6dd66c2830c46eeb62dc
+++ /dev/null
-b293f144df87783d66020a0f73654be459673054
+++ /dev/null
-0dd0e1efbf8f699a0ef286a271d8210ce2e80702ad5528f36592c89985d6b151
+++ /dev/null
-5a5d1b11fdc498da5a592205714117656f40fea644adab07f110e1d512c79c6ded126972c1693483f21b592dd2030878
+++ /dev/null
-a379ef07490328fb934fcadfa1b7794e532782c2097d3aa82e41ff9bd86527830f711a0c456af65a14a511bad73ddc08a30593d74ec6d42bcc9ee0747acfdf91
+++ /dev/null
-f3b8a0ebd9ce6dd66c2830c46eeb62dc
for ( ChecksumAlgorithm algorithm : algorithms )
{
- Path file = localFile.toAbsolutePath().resolveSibling( localFile.getFileName() + "." + algorithm.getExt() );
+ Path file = checksum.getChecksumFile( algorithm );
try
{
Files.deleteIfExists( file );
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;
@PostConstruct
public void initialize()
- throws InitializationException
{
log.info( "Initialized {}", this.getClass().getName() );
}