package org.cagrid.gts.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.configuration.security.KeyStoreType;
import org.cagrid.core.common.FaultHelper;
import org.cagrid.core.common.security.X509Credential;
import org.cagrid.core.soapclient.ClientConfigurer;
import org.cagrid.gts.model.*;
import org.cagrid.gts.service.exception.*;
import org.cagrid.gts.service.impl.db.DBManager;
import org.cagrid.gts.service.impl.db.mysql.MySQLManager;
import org.cagrid.gts.soapclient.GTSSoapClientFactory;
import org.cagrid.gts.ws.client.GTSClient;
import org.cagrid.gts.wsrf.stubs.FindTrustedAuthoritiesRequest;
import org.cagrid.gts.wsrf.stubs.FindTrustedAuthoritiesResponse;
import org.cagrid.gts.wsrf.stubs.GTSPortType;
import org.cagrid.gts.wsrf.stubs.GetTrustLevelsRequest;
import java.util.*;
/**
* @author <A HREF="MAILTO:langella@bmi.osu.edu">Stephen Langella </A>
* @author <A HREF="MAILTO:oster@bmi.osu.edu">Scott Oster </A>
* @author <A HREF="MAILTO:hastings@bmi.osu.edu">Shannon Hastings </A>
* @version $Id: TrustedAuthorityManager.java,v 1.1 2006/03/08 19:48:46 langella Exp $
*/
public class GTS implements TrustedAuthorityLevelRemover, TrustLevelLookup {
private Configuration conf;
private String gtsURI;
private TrustedAuthorityManager trust;
private PermissionManager permissions;
private TrustLevelManager trustLevelManager;
private GTSAuthorityManager authority;
private Map<String, GTSClient> gtsClientCache;
private Object gtsClientCacheMutex = new Object();
private Log log;
private Database db;
private ClientConfigurer configurer= null;
public GTS(Configuration conf, String gtsURI, ClientConfigurer configurer) {
this.conf = conf;
this.gtsURI = gtsURI;
this.configurer = configurer;
this.gtsClientCache = new HashMap<String, GTSClient>();
log = LogFactory.getLog(this.getClass().getName());
DBManager dbManager = new MySQLManager(new MySQLDatabase(this.conf.getConnectionManager(), this.conf.getGTSInternalId()));
this.db = dbManager.getDatabase();
trust = new TrustedAuthorityManager(this.gtsURI, this, dbManager);
trustLevelManager = new TrustLevelManager(this.gtsURI, this, dbManager);
permissions = new PermissionManager(dbManager);
authority = new GTSAuthorityManager(gtsURI, conf.getAuthoritySyncTime(), dbManager);
}
protected Database getDatabase() {
return db;
}
public TrustedAuthority addTrustedAuthority(TrustedAuthority ta, String callerGridIdentity) throws GTSInternalException, IllegalTrustedAuthorityException,
PermissionDeniedException {
checkServiceAdministrator(callerGridIdentity);
return trust.addTrustedAuthority(ta);
}
public TrustedAuthority[] findTrustAuthorities(TrustedAuthorityFilter filter) throws GTSInternalException {
return trust.findTrustAuthorities(filter);
}
public boolean validate(X509Certificate cert, TrustedAuthorityFilter filter) throws GTSInternalException, CertificateValidationException {
X509Certificate[] chain = new X509Certificate[1];
chain[0] = cert;
return this.validate(chain, filter);
}
public boolean validate(X509Certificate[] chain, TrustedAuthorityFilter filter) throws GTSInternalException, CertificateValidationException {
GTSInternalException fault = FaultHelper.createFaultException(GTSInternalException.class, "Operation no longer supported!");
throw fault;
// TODO: MIGRATION: implement
// boolean isValidated = false;
// TrustedAuthority[] list = trust.findTrustAuthorities(filter);
// ProxyPathValidator validator = new ProxyPathValidator();
// if ((list == null) || (list.length == 0)) {
// CertificateValidationFault fault = new CertificateValidationFault();
// fault.setFaultString("Could not validate chain, no trusted roots found!!!");
// throw fault;
// } else {
// java.security.cert.X509Certificate[] trustedCerts = new java.security.cert.X509Certificate[list.length];
// List<java.security.cert.X509CRL> crlList = new ArrayList<java.security.cert.X509CRL>();
// for (int i = 0; i < list.length; i++) {
// try {
// trustedCerts[i] = CertUtil.loadCertificate(list[i].getCertificate().getCertificateEncodedString());
// } catch (Exception e) {
// log.error(e.getMessage(), e);
// GTSInternalFault fault = new GTSInternalFault();
// fault.setFaultString("Unexpected Error loading the certificate for the trusted authority "
// + list[i].getName() + "!!!");
// throw fault;
// }
//
// try {
// if (list[i].getCRL() != null) {
// crlList.add(CertUtil.loadCRL(list[i].getCRL().getCrlEncodedString()));
// }
// } catch (Exception e) {
// log.error(e.getMessage(), e);
// GTSInternalFault fault = new GTSInternalFault();
// fault.setFaultString("Unexpected Error loading the CRL for the trusted authority "
// + list[i].getName() + "!!!");
// throw fault;
// }
//
// }
// java.security.cert.X509CRL[] crls = new java.security.cert.X509CRL[crlList.size()];
// for (int i = 0; i < crlList.size(); i++) {
// crls[i] = (java.security.cert.X509CRL) crlList.get(i);
// }
//
// java.security.cert.X509Certificate[] certChain = new java.security.cert.X509Certificate[chain.length];
// for (int i = 0; i < crlList.size(); i++) {
// try {
// certChain[i] = CertUtil.loadCertificate(chain[i].getCertificateEncodedString());
// } catch (Exception e) {
// log.error(e.getMessage(), e);
// GTSInternalFault fault = new GTSInternalFault();
// fault.setFaultString("Unexpected Error formatting the certificate chain.!!!");
// throw fault;
// }
// }
// try {
// validator.validate(certChain, trustedCerts, CertificateRevocationLists
// .getCertificateRevocationLists(crls));
// isValidated = true;
// } catch (Exception e) {
// CertificateValidationFault fault = new CertificateValidationFault();
// fault.setFaultString("Could not validate chain " + e.getMessage());
// throw fault;
// }
// }
// return isValidated;
}
public void updateTrustedAuthority(TrustedAuthority ta, String callerGridIdentity) throws GTSInternalException, IllegalTrustedAuthorityException,
InvalidTrustedAuthorityException, PermissionDeniedException {
checkServiceAdministrator(callerGridIdentity);
trust.updateTrustedAuthority(ta);
}
public void updateCRL(String trustedAuthorityName, X509CRL crl, String callerGridIdentity) throws GTSInternalException, IllegalTrustedAuthorityException,
InvalidTrustedAuthorityException, PermissionDeniedException {
this.checkAdministratorOfTrustedAuthority(trustedAuthorityName, callerGridIdentity);
TrustedAuthority ta = trust.getTrustedAuthority(trustedAuthorityName);
ta.setCRL(crl);
trust.updateTrustedAuthority(ta);
}
public void removeTrustedAuthority(String name, String callerGridIdentity) throws GTSInternalException, InvalidTrustedAuthorityException,
PermissionDeniedException {
checkServiceAdministrator(callerGridIdentity);
trust.removeTrustedAuthority(name);
permissions.revokePermissions(name);
}
public void addTrustLevel(TrustLevel level, String callerGridIdentity) throws GTSInternalException, IllegalTrustLevelException, PermissionDeniedException {
checkServiceAdministrator(callerGridIdentity);
trustLevelManager.addTrustLevel(level);
}
public void removeTrustLevel(String name, String callerGridIdentity) throws GTSInternalException, InvalidTrustLevelException, IllegalTrustLevelException,
PermissionDeniedException {
checkServiceAdministrator(callerGridIdentity);
trustLevelManager.removeTrustLevel(name);
}
public void updateTrustLevel(TrustLevel level, String callerGridIdentity) throws GTSInternalException, InvalidTrustLevelException,
IllegalTrustLevelException, PermissionDeniedException {
checkServiceAdministrator(callerGridIdentity);
trustLevelManager.updateTrustLevel(level);
}
public TrustLevel[] getTrustLevels(String callerGridIdentity) throws GTSInternalException {
return trustLevelManager.getTrustLevels();
}
public TrustLevel[] getTrustLevels(String gtsSourceURI, String callerGridIdentity) throws GTSInternalException {
return trustLevelManager.getTrustLevels(gtsSourceURI);
}
public TrustLevel getTrustLevel(String name, String callerGridIdentity) throws GTSInternalException, InvalidTrustLevelException {
return trustLevelManager.getTrustLevel(name);
}
public void addPermission(Permission p, String callerGridIdentity) throws GTSInternalException, IllegalPermissionException, PermissionDeniedException {
checkServiceAdministrator(callerGridIdentity);
if ((p.getTrustedAuthorityName() != null) && (!p.getTrustedAuthorityName().equals(org.cagrid.gts.service.impl.Constants.ALL_TRUST_AUTHORITIES))) {
if (!trust.doesTrustedAuthorityExist(p.getTrustedAuthorityName())) {
IllegalPermissionException fault = FaultHelper.createFaultException(IllegalPermissionException.class,
"Cannot add permission, the Trusted Authority (" + p.getTrustedAuthorityName() + ") specified does not exist.");
throw fault;
}
}
permissions.addPermission(p);
}
public Permission[] findPermissions(PermissionFilter filter, String callerGridIdentity) throws GTSInternalException, PermissionDeniedException {
checkServiceAdministrator(callerGridIdentity);
return permissions.findPermissions(filter);
}
public void revokePermission(Permission p, String callerGridIdentity) throws GTSInternalException, InvalidPermissionException, PermissionDeniedException {
checkServiceAdministrator(callerGridIdentity);
permissions.revokePermission(p);
}
public void addAuthority(AuthorityGTS gts, String callerGridIdentity) throws GTSInternalException, IllegalAuthorityException, PermissionDeniedException {
checkServiceAdministrator(callerGridIdentity);
authority.addAuthority(gts);
}
public void updateAuthorityPriorities(AuthorityPriorityUpdate update, String callerGridIdentity) throws GTSInternalException, IllegalAuthorityException,
PermissionDeniedException {
checkServiceAdministrator(callerGridIdentity);
authority.updateAuthorityPriorities(update);
}
public void updateAuthority(AuthorityGTS gts, String callerGridIdentity) throws GTSInternalException, IllegalAuthorityException, InvalidAuthorityException,
PermissionDeniedException {
checkServiceAdministrator(callerGridIdentity);
authority.updateAuthority(gts);
}
public AuthorityGTS[] getAuthorities() throws GTSInternalException {
return authority.getAuthorities();
}
public void removeAuthority(String serviceURI, String callerGridIdentity) throws GTSInternalException, InvalidAuthorityException, PermissionDeniedException {
checkServiceAdministrator(callerGridIdentity);
try {
authority.removeAuthority(serviceURI);
TrustedAuthorityFilter f = new TrustedAuthorityFilter();
f.setSourceGTS(serviceURI);
TrustedAuthority[] ta = this.trust.findTrustAuthorities(f);
boolean error = false;
StringBuffer elist = null;
for (int i = 0; i < ta.length; i++) {
try {
trust.removeTrustedAuthority(ta[i].getName());
} catch (Exception ex) {
log.error(ex);
if (elist == null) {
error = true;
elist = new StringBuffer("Unable to remove the trusted authorities:\n");
}
elist.append(ta[i].getName() + "\n");
}
}
if (error) {
throw new Exception(elist.toString());
}
} catch (Exception e) {
log.error(e);
GTSInternalException fault = FaultHelper.createFaultException(GTSInternalException.class,
"An following unexpected error occurred removing the authority " + serviceURI + ": " + e.getMessage());
FaultHelper.addMessage(fault, e.getMessage());
throw fault;
}
}
private void checkServiceAdministrator(String gridIdentity) throws GTSInternalException, PermissionDeniedException {
if (!permissions.isUserTrustServiceAdmin(gridIdentity)) {
PermissionDeniedException fault = FaultHelper.createFaultException(PermissionDeniedException.class, "You are not a trust service administrator!!!");
throw fault;
}
}
private void checkAdministratorOfTrustedAuthority(String ta, String gridIdentity) throws GTSInternalException, PermissionDeniedException {
if (permissions.isUserTrustServiceAdmin(gridIdentity)) {
return;
}
if (permissions.isUserTrustedAuthorityAdmin(ta, gridIdentity)) {
return;
}
PermissionDeniedException fault = FaultHelper.createFaultException(PermissionDeniedException.class,
"You are not an administrator for the trusted authority " + ta + "!!!");
throw fault;
}
public void clearDatabase() throws GTSInternalException {
trust.clearDatabase();
permissions.clearDatabase();
trustLevelManager.clearDatabase();
authority.clearDatabase();
}
public boolean isTrustLevelUsed(String name) throws GTSInternalException {
TrustedAuthorityFilter f = new TrustedAuthorityFilter();
TrustLevels levels = new TrustLevels();
levels.getTrustLevel().add(name);
f.setTrustLevels(levels);
TrustedAuthority[] ta = this.findTrustAuthorities(f);
if ((ta == null) || (ta.length == 0)) {
return false;
} else {
return true;
}
}
public boolean doesTrustLevelExist(String name) throws GTSInternalException {
if (trustLevelManager.doesTrustLevelExist(name)) {
return true;
} else {
return false;
}
}
public void removeAssociatedTrustedAuthorities(String trustLevel) throws GTSInternalException {
this.trust.removeLevelFromTrustedAuthorities(trustLevel);
}
protected void synchronizeTrustLevels(String authorityServiceURI, List<TrustLevel> levels) {
// Synchronize the Trust Level
// We need to get a list of all the Trusted Authorities provided
// by the source,
// such that we can remove the ones that are not provided in the
// new list
Map<String, Boolean> toBeDeleted = new HashMap<String, Boolean>();
try {
TrustLevel[] existing = this.trustLevelManager.getTrustLevels(authorityServiceURI);
for (int i = 0; i < existing.length; i++) {
toBeDeleted.put(existing[i].getName(), Boolean.TRUE);
}
} catch (Exception e) {
this.log.error("Error synchronizing with the authority " + authorityServiceURI
+ "the following error occurred obtaining the existing trust level: " + e.getMessage(), e);
return;
}
if (levels != null) {
for (TrustLevel level : levels) {
toBeDeleted.remove(level.getName());
try {
if (this.trustLevelManager.doesTrustLevelExist(level.getName())) {
// Perform Update
TrustLevel l = this.trustLevelManager.getTrustLevel(level.getName());
AuthorityGTS updateAuthority = authority.getAuthority(authorityServiceURI);
// Determine if we should peform update
boolean performUpdate = false;
// Check to see if this service is the authority
if (!l.getAuthorityGTS().equals(gtsURI)) {
AuthorityGTS currAuthority = authority.getAuthority(l.getSourceGTS());
// Check to see if the authority GTS is the same
if (currAuthority.getServiceURI().equals(updateAuthority.getServiceURI())) {
performUpdate = true;
this.log.debug("The trust level (" + level.getName() + ") will be updated!!!");
} else if (currAuthority.getPriority() > updateAuthority.getPriority()) {
performUpdate = true;
this.log.debug("The trust level (" + level.getName() + ") will be updated, the authority (" + updateAuthority.getServiceURI()
+ ") has a greater priority then the current source authority (" + currAuthority.getServiceURI() + ")!!!");
} else {
this.log.debug("The trust level(" + level.getName() + ") will NOT be updated, the current source authority ("
+ currAuthority.getServiceURI() + ") has a greater priority then the source authority ("
+ updateAuthority.getServiceURI() + ")!!!");
performUpdate = false;
}
} else {
this.log.debug("The trust level (" + level.getName() + ") will NOT be updated, this GTS is its authority !!!");
performUpdate = false;
}
if (performUpdate) {
level.setIsAuthority(Boolean.FALSE);
level.setSourceGTS(authorityServiceURI);
try {
this.trustLevelManager.updateTrustLevel(level, false);
} catch (Exception e) {
this.log.error("Error synchronizing with the authority " + authorityServiceURI
+ ", the following error occcurred when trying to update the authority, " + level.getName() + ": " + e.getMessage(), e);
continue;
}
}
} else {
this.log.debug("The trusted authority (" + level.getName() + ") will be added with the authority (" + authorityServiceURI
+ ") as the source!!!");
level.setIsAuthority(Boolean.FALSE);
level.setSourceGTS(authorityServiceURI);
try {
this.trustLevelManager.addTrustLevel(level, false);
} catch (Exception e) {
this.log.error("Error synchronizing with the authority " + authorityServiceURI
+ ", the following error occcurred when trying to add the trust level, " + level.getName() + ": " + e.getMessage(), e);
continue;
}
}
} catch (Exception ex) {
this.log.error("Error synchronizing with the authority " + authorityServiceURI + ": " + ex.getMessage(), ex);
continue;
}
}
}
Iterator<String> itr = toBeDeleted.keySet().iterator();
while (itr.hasNext()) {
String name = itr.next();
try {
this.trustLevelManager.removeTrustLevel(name);
this.log.debug("The trust level (" + name + ") was removed because it has been removed from the authority " + authorityServiceURI + "!!!");
} catch (Exception e) {
this.log.error("The trust level (" + name + ") should have been removed because it has been removed from the authority " + authorityServiceURI
+ ", however the following error occurred:" + e.getMessage(), e);
}
}
}
protected void synchronizeTrustedAuthorities(String authorityServiceURI, TrustedAuthority[] trusted) {
// Synchronize the Trusted Authorities
if (trusted != null) {
// We need to get a list of all the trust levels provided
// by the source,
// such that we can remove the ones that are not provided in the
// new list
Map<String, Boolean> toBeDeleted = new HashMap<String, Boolean>();
try {
TrustedAuthorityFilter f = new TrustedAuthorityFilter();
f.setSourceGTS(authorityServiceURI);
TrustedAuthority[] existing = this.trust.findTrustAuthorities(f);
for (int i = 0; i < existing.length; i++) {
toBeDeleted.put(existing[i].getName(), Boolean.TRUE);
}
} catch (Exception e) {
this.log.error("Error synchronizing with the authority " + authorityServiceURI
+ "the following error occurred obtaining the existing Trusted Authorities: " + e.getMessage(), e);
return;
}
for (int j = 0; j < trusted.length; j++) {
try {
toBeDeleted.remove(trusted[j].getName());
if (this.trust.doesTrustedAuthorityExist(trusted[j].getName())) {
// Perform Update
TrustedAuthority ta = this.trust.getTrustedAuthority(trusted[j].getName());
AuthorityGTS updateAuthority = authority.getAuthority(authorityServiceURI);
// Determine if we should peform update
boolean performUpdate = false;
// Check to see if this service is the authority
if (!ta.getAuthorityGTS().equals(gtsURI)) {
AuthorityGTS currAuthority = authority.getAuthority(ta.getSourceGTS());
// Check to see if the authority GTS is the same
if (currAuthority.getServiceURI().equals(updateAuthority.getServiceURI())) {
performUpdate = true;
this.log.debug("The trusted authority (" + ta.getName() + ") will be updated!!!");
} else if (currAuthority.getPriority() > updateAuthority.getPriority()) {
performUpdate = true;
this.log.debug("The trusted authority (" + ta.getName() + ") will be updated, the authority ("
+ updateAuthority.getServiceURI() + ") has a greater priority then the current source authority ("
+ currAuthority.getServiceURI() + ")!!!");
} else {
this.log.debug("The trusted authority (" + ta.getName() + ") will NOT be updated, the current source authority ("
+ currAuthority.getServiceURI() + ") has a greater priority then the source authority ("
+ updateAuthority.getServiceURI() + ")!!!");
performUpdate = false;
}
} else {
this.log.debug("The trusted authority (" + ta.getName() + ") will NOT be updated, this GTS is its authority !!!");
performUpdate = false;
}
if (performUpdate) {
trusted[j].setIsAuthority(Boolean.FALSE);
trusted[j].setSourceGTS(authorityServiceURI);
Calendar c = new GregorianCalendar();
c.add(Calendar.HOUR, updateAuthority.getTimeToLive().getHours());
c.add(Calendar.MINUTE, updateAuthority.getTimeToLive().getMinutes());
c.add(Calendar.SECOND, updateAuthority.getTimeToLive().getSeconds());
trusted[j].setExpires(c.getTimeInMillis());
try {
trust.updateTrustedAuthority(trusted[j], false);
} catch (Exception e) {
this.log.error(
"Error synchronizing with the authority " + authorityServiceURI
+ ", the following error occcurred when trying to update the authority, " + trusted[j].getName() + ": "
+ e.getMessage(), e);
continue;
}
}
} else {
AuthorityGTS updateAuthority = authority.getAuthority(authorityServiceURI);
this.log.debug("The trusted authority (" + trusted[j].getName() + ") will be added with the authority (" + authorityServiceURI
+ ") as the source!!!");
trusted[j].setIsAuthority(Boolean.FALSE);
trusted[j].setSourceGTS(authorityServiceURI);
Calendar c = new GregorianCalendar();
c.add(Calendar.HOUR, updateAuthority.getTimeToLive().getHours());
c.add(Calendar.MINUTE, updateAuthority.getTimeToLive().getMinutes());
c.add(Calendar.SECOND, updateAuthority.getTimeToLive().getSeconds());
trusted[j].setExpires(c.getTimeInMillis());
try {
trust.addTrustedAuthority(trusted[j], false);
} catch (Exception e) {
this.log.error("Error synchronizing with the authority " + authorityServiceURI
+ ", the following error occcurred when trying to add the authority, " + trusted[j].getName() + ": " + e.getMessage(), e);
continue;
}
}
} catch (Exception ex) {
this.log.error("Error synchronizing with the authority " + authorityServiceURI + ": " + ex.getMessage(), ex);
continue;
}
}
Iterator<String> itr = toBeDeleted.keySet().iterator();
while (itr.hasNext()) {
String name = itr.next();
try {
trust.removeTrustedAuthority(name);
this.log.debug("The trusted authority (" + name + ") was removed because it has been removed from the authority " + authorityServiceURI
+ "!!!");
} catch (Exception e) {
this.log.error("The trusted authority (" + name + ") should have been removed because it has been removed from the authority "
+ authorityServiceURI + ", however the following error occurred:" + e.getMessage(), e);
}
}
}
}
private GTSClient getGTSClient(String url) throws Exception {
synchronized (this.gtsClientCacheMutex) {
if (this.gtsClientCache.containsKey(url)) {
return this.gtsClientCache.get(url);
} else {
GTSClient client = new GTSClient(url);
configurer.configureClient(client);
this.gtsClientCache.put(url, client);
return client;
}
}
}
public void synchronizeWithAuthorities() {
log.info("Syncing with authorities.");
AuthorityGTS[] auths = null;
try {
auths = this.getAuthorities();
} catch (Exception ex) {
this.log.error("Error synchronizing with the authorities, could not obtain a list of authorities!!!", ex);
}
if (auths != null) {
TrustedAuthorityFilter filter = new TrustedAuthorityFilter();
filter.setStatus(Status.TRUSTED);
filter.setLifetime(Lifetime.VALID);
for (int i = 0; i < auths.length; i++) {
log.info("Syncing with authority: " + auths[i].getServiceURI());
List<TrustLevel> levels = null;
TrustedAuthority[] trusted = null;
try {
GTSClient client = getGTSClient(auths[i].getServiceURI());
log.debug("Getting trust levels from authority: " + auths[i].getServiceURI());
levels = client.getTrustLevels();
log.debug("Found (" + levels.size() + ") trust levels from authority: " + auths[i].getServiceURI());
log.debug("Getting trusted authorities from authority: " + auths[i].getServiceURI());
trusted = client.findTrustedAuthorities(filter).toArray(new TrustedAuthority[]{});
log.debug("Found (" + trusted.length + ") trusted authorities from authority: " + auths[i].getServiceURI());
} catch (Exception ex) {
log.error("Error synchronizing with the authority " + auths[i].getServiceURI() + ": " + ex.getMessage(), ex);
continue;
}
// Synchronize the Trust Levels
this.synchronizeTrustLevels(auths[i].getServiceURI(), levels);
// Synchronize the Trusted Authorities
this.synchronizeTrustedAuthorities(auths[i].getServiceURI(), trusted);
}
} else {
log.info("No authorities to sync with.");
}
}
}