Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ SPDX-License-Identifier: Apache-2.0

<groupId>org.italiangrid</groupId>
<artifactId>voms-api-java</artifactId>
<version>3.3.6</version>
<version>3.3.7-SNAPSHOT</version>
<packaging>jar</packaging>

<name>voms-api-java</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,48 +35,45 @@

/**
*
* The default implementation for the VOMS trust store. This implementation
* <b>does not</b> refresh the trust information on a periodic basis. For an
* updating trust store see {@link DefaultUpdatingVOMSTrustStore}.
* The default implementation for the VOMS trust store. This implementation <b>does not</b> refresh
* the trust information on a periodic basis. For an updating trust store see
* {@link DefaultUpdatingVOMSTrustStore}.
*
* @author Andrea Ceccanti
*
*/
public class DefaultVOMSTrustStore implements VOMSTrustStore {

/**
* The default directory where local VOMS trust information is rooted:
* {@value #DEFAULT_VOMS_DIR}
* The default directory where local VOMS trust information is rooted: {@value #DEFAULT_VOMS_DIR}
**/
public static final String DEFAULT_VOMS_DIR = "/etc/grid-security/vomsdir";

/**
* The filename suffix used to match certificates in the VOMS local trust
* directories
* The filename suffix used to match certificates in the VOMS local trust directories
**/
public static final String CERTIFICATE_FILENAME_SUFFIX = ".pem";

/**
* The filename suffix used to match LSC files in the VOMS local trust
* directories
* The filename suffix used to match LSC files in the VOMS local trust directories
**/
public static final String LSC_FILENAME_SUFFIX = ".lsc";

/**
* The list of local trusted directories that is searched for trust
* information (certs or LSC files)
* The list of local trusted directories that is searched for trust information (certs or LSC
* files)
**/
private final List<String> localTrustedDirs;

/** Map of local parsed AA certificates keyed by certificate subject hash **/
private Map<String, X509Certificate> localAACertificatesByHash = new HashMap<String, X509Certificate>();
private Map<String, X509Certificate> localAACertificatesByHash =
new HashMap<String, X509Certificate>();

/** The set of local parsed LSC information keyed by VO **/
private Map<String, Set<LSCInfo>> localLSCInfo = new HashMap<String, Set<LSCInfo>>();

/**
* The trust store status listener that will be notified of changes in this
* trust store
* The trust store status listener that will be notified of changes in this trust store
**/
private VOMSTrustStoreStatusListener listener;

Expand All @@ -92,12 +89,12 @@ public class DefaultVOMSTrustStore implements VOMSTrustStore {
/** A lock to guard the setting of the status listener **/
protected final Object listenerLock = new Object();

private final List<String> voNames;

/**
* Builds a list of trusted directories containing only
* {@link #DEFAULT_VOMS_DIR}.
* Builds a list of trusted directories containing only {@link #DEFAULT_VOMS_DIR}.
*
* @return a list of default trusted directory containing the
* {@link #DEFAULT_VOMS_DIR}
* @return a list of default trusted directory containing the {@link #DEFAULT_VOMS_DIR}
**/
protected static List<String> buildDefaultTrustedDirs() {

Expand All @@ -108,24 +105,27 @@ protected static List<String> buildDefaultTrustedDirs() {

/**
*
* @param localTrustDirs
* a non-null list of local trust directories
* @param listener
* the {@link VOMSTrustStoreStatusListener} to use for this trust
* store
* @throws IllegalArgumentException
* when the list passed as argument is null
* @param localTrustDirs a non-null list of local trust directories
* @param listener the {@link VOMSTrustStoreStatusListener} to use for this trust store
* @throws IllegalArgumentException when the list passed as argument is null
*
*/
public DefaultVOMSTrustStore(List<String> localTrustDirs,
VOMSTrustStoreStatusListener listener) {
public DefaultVOMSTrustStore(List<String> localTrustDirs, VOMSTrustStoreStatusListener listener) {

this(localTrustDirs, null, listener);
}

public DefaultVOMSTrustStore(List<String> localTrustDirs, List<String> voNames,
VOMSTrustStoreStatusListener listener) {

if (localTrustDirs == null)
if (localTrustDirs == null) {
throw new IllegalArgumentException(
"Please provide a non-null list of local trust directories!");
"Please provide a non-null list of local trust directories!");
}

this.localTrustedDirs = localTrustDirs;
this.listener = listener;
this.voNames = voNames;
loadTrustInformation();
}

Expand All @@ -142,8 +142,7 @@ public DefaultVOMSTrustStore(List<String> localTrustDirs) {
/**
* Default constructor.
*
* Sets the local trusted directories to the default of
* {@value #DEFAULT_VOMS_DIR}.
* Sets the local trusted directories to the default of {@value #DEFAULT_VOMS_DIR}.
*
*
*/
Expand All @@ -167,8 +166,8 @@ public List<X509Certificate> getLocalAACertificates() {
read.lock();

try {
return Collections.unmodifiableList(new ArrayList<X509Certificate>(
localAACertificatesByHash.values()));
return Collections
.unmodifiableList(new ArrayList<X509Certificate>(localAACertificatesByHash.values()));
} finally {
read.unlock();
}
Expand Down Expand Up @@ -200,9 +199,8 @@ public LSCInfo getLSC(String voName, String hostname) {
}

/**
* Loads all the certificates in the local directory. Only files with the
* extension matching the {@link #CERTIFICATE_FILENAME_PATTERN} are
* considered.
* Loads all the certificates in the local directory. Only files with the extension matching the
* {@link #CERTIFICATE_FILENAME_PATTERN} are considered.
*
* @param directory
*/
Expand All @@ -228,8 +226,8 @@ public boolean accept(File dir, String name) {
}

/**
* Loads a VOMS AA certificate from a given file and stores this certificate
* in the local map of trusted VOMS AA certificate.
* Loads a VOMS AA certificate from a given file and stores this certificate in the local map of
* trusted VOMS AA certificate.
*
* @param file
*/
Expand All @@ -239,8 +237,8 @@ private void loadCertificateFromFile(File file) {

try {

X509Certificate aaCert = CertificateUtils.loadCertificate(
new FileInputStream(file), Encoding.PEM);
X509Certificate aaCert =
CertificateUtils.loadCertificate(new FileInputStream(file), Encoding.PEM);

// Get certificate subject hash, using the CANL implementation for CA
// files
Expand All @@ -254,9 +252,9 @@ private void loadCertificateFromFile(File file) {
}

} catch (IOException e) {
String errorMessage = String.format(
"Error parsing VOMS trusted certificate from %s. Reason: %s",
file.getAbsolutePath(), e.getMessage());
String errorMessage =
String.format("Error parsing VOMS trusted certificate from %s. Reason: %s",
file.getAbsolutePath(), e.getMessage());
throw new VOMSError(errorMessage, e);
}

Expand Down Expand Up @@ -299,8 +297,7 @@ public boolean accept(File dir, String name) {
// In the VOMS trust anchor structure, LSC files are named as
// <hostname>.lsc where hostname
// is the name of host where the VOMS AA is running
String hostname = lscFileName.substring(0,
lscFileName.indexOf(LSC_FILENAME_SUFFIX));
String hostname = lscFileName.substring(0, lscFileName.indexOf(LSC_FILENAME_SUFFIX));

LSCInfo info = null;

Expand All @@ -322,46 +319,43 @@ public boolean accept(File dir, String name) {
}

/**
* Performs basic sanity checks performed on a file supposed to hold a VOMS AA
* certificate.
* Performs basic sanity checks performed on a file supposed to hold a VOMS AA certificate.
*
* @param certFile
*/
private void certificateFileSanityChecks(File certFile) {

if (!certFile.exists())
throw new VOMSError("Local VOMS trusted certificate does not exist:"
+ certFile.getAbsolutePath());
throw new VOMSError(
"Local VOMS trusted certificate does not exist:" + certFile.getAbsolutePath());

if (!certFile.canRead())
throw new VOMSError("Local VOMS trusted certificate is not readable:"
+ certFile.getAbsolutePath());
throw new VOMSError(
"Local VOMS trusted certificate is not readable:" + certFile.getAbsolutePath());

}

/**
* Performs basic sanity checks on a directory that is supposed to contain
* VOMS AA certificates and LSC files.
* Performs basic sanity checks on a directory that is supposed to contain VOMS AA certificates
* and LSC files.
*
* @param directory
*/
private void directorySanityChecks(File directory) {

if (!directory.exists())
throw new VOMSError("Local trust directory does not exists:"
+ directory.getAbsolutePath());
throw new VOMSError("Local trust directory does not exists:" + directory.getAbsolutePath());

if (!directory.isDirectory())
throw new VOMSError("Local trust directory is not a directory:"
+ directory.getAbsolutePath());
throw new VOMSError(
"Local trust directory is not a directory:" + directory.getAbsolutePath());

if (!directory.canRead())
throw new VOMSError("Local trust directory is not readable:"
+ directory.getAbsolutePath());
throw new VOMSError("Local trust directory is not readable:" + directory.getAbsolutePath());

if (!directory.canExecute())
throw new VOMSError("Local trust directory is not traversable:"
+ directory.getAbsolutePath());
throw new VOMSError(
"Local trust directory is not traversable:" + directory.getAbsolutePath());

}

Expand All @@ -380,7 +374,7 @@ public void loadTrustInformation() {

if (localTrustedDirs.isEmpty()) {
throw new VOMSError(
"No local trust directory was specified for this trust store. Please provide at least one path where LSC and VOMS service certificates will be searched for.");
"No local trust directory was specified for this trust store. Please provide at least one path where LSC and VOMS service certificates will be searched for.");
}

cleanupStores();
Expand All @@ -404,8 +398,11 @@ public boolean accept(File pathname) {
});

for (File voDir : voDirs) {
loadLSCFromDirectory(voDir);
loadCertificatesFromDirectory(voDir);

if (voNames == null || voNames.contains(voDir.getName())) {
loadLSCFromDirectory(voDir);
loadCertificatesFromDirectory(voDir);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
package org.italiangrid.voms.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.FileInputStream;
Expand All @@ -20,6 +22,7 @@

import org.italiangrid.voms.VOMSError;
import org.italiangrid.voms.store.impl.DefaultVOMSTrustStore;
import org.italiangrid.voms.util.NullListener;
import org.junit.Test;

import eu.emi.security.authn.x509.impl.CertificateUtils;
Expand All @@ -34,17 +37,16 @@ public class TestDefaultVOMSTrustStore {
@Test(expected = VOMSError.class)
public void testEmptyTrustDirsFailure() {

@SuppressWarnings({ "unused", "unchecked" })
DefaultVOMSTrustStore store = new DefaultVOMSTrustStore(
Collections.EMPTY_LIST);
@SuppressWarnings({"unused", "unchecked"})
DefaultVOMSTrustStore store = new DefaultVOMSTrustStore(Collections.EMPTY_LIST);

}

@Test(expected = VOMSError.class)
public void testNonExistentTrustDirsFailure() {

List<String> trustDirs = Arrays.asList(new String[] { "/etc/do/not/exist",
"/etc/grid-security/vomsdir" });
List<String> trustDirs =
Arrays.asList(new String[] {"/etc/do/not/exist", "/etc/grid-security/vomsdir"});

@SuppressWarnings("unused")
DefaultVOMSTrustStore store = new DefaultVOMSTrustStore(trustDirs);
Expand Down Expand Up @@ -75,22 +77,48 @@ public void testEmptyTrustDir() {
}

@Test
public void testCertificateParsing() throws FileNotFoundException,
IOException {
public void testCertificateParsing() throws FileNotFoundException, IOException {

String vomsDir = "src/test/resources/vomsdir";
String certFileName = "src/test/resources/vomsdir/test-host.cnaf.infn.it.pem";
X509Certificate cert = CertificateUtils.loadCertificate(
new FileInputStream(certFileName), Encoding.PEM);
X509Certificate cert =
CertificateUtils.loadCertificate(new FileInputStream(certFileName), Encoding.PEM);

List<String> trustDirs = Arrays.asList(new String[] { vomsDir });
List<String> trustDirs = Arrays.asList(new String[] {vomsDir});

DefaultVOMSTrustStore store = new DefaultVOMSTrustStore(trustDirs);

assertEquals(1, store.getLocalAACertificates().size());

assertTrue(cert.getSubjectX500Principal().equals(
store.getLocalAACertificates().get(0).getSubjectX500Principal()));
assertTrue(cert.getSubjectX500Principal()
.equals(store.getLocalAACertificates().get(0).getSubjectX500Principal()));
}

@Test
public void testAllLSCInStore() {

List<String> trustDirs = Arrays.asList("src/test/resources/vomsdir");

DefaultVOMSTrustStore store = new DefaultVOMSTrustStore(trustDirs, NullListener.INSTANCE);

assertNotNull(store.getLSC("test.vo", "test-host.cnaf.infn.it"));
assertNotNull(store.getLSC("test.vo", "test-multichain.cnaf.infn.it"));
assertNotNull(store.getLSC("test.vo.1", "wilco.cnaf.infn.it"));

}

@Test
public void testLSCForVoInStore() {

List<String> trustDirs = Arrays.asList("src/test/resources/vomsdir");

DefaultVOMSTrustStore store =
new DefaultVOMSTrustStore(trustDirs, Arrays.asList("test.vo"), NullListener.INSTANCE);

assertNotNull(store.getLSC("test.vo", "test-host.cnaf.infn.it"));
assertNotNull(store.getLSC("test.vo", "test-multichain.cnaf.infn.it"));
assertNull(store.getLSC("test.vo.1", "wilco.cnaf.infn.it"));

}

public void testUpdatingVOMSTrustStore() {
Expand Down