/* Copyright 2006 VPAC
*
* This file is part of proxy_light.
* proxy_light is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
* proxy_light is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with proxy_light; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package grith.jgrith.vomsProxy;
import gridpp.portal.voms.VOMSAttributeCertificate;
import grisu.jcommons.exceptions.CredentialException;
import grisu.model.info.dto.VO;
import grith.jgrith.utils.CredentialHelpers;
import java.io.File;
import java.util.ArrayList;
import org.bouncycastle.asn1.x509.AttributeCertificate;
import org.globus.gsi.GlobusCredential;
import org.globus.gsi.GlobusCredentialException;
import org.globus.tools.proxy.DefaultGridProxyModel;
import org.ietf.jgss.GSSCredential;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A VomsProxy is a wrapper for a {@link GlobusCredential} that has got a voms
* attribute certificate attached to it. This class also provides all the
* methods to easily create such a proxy in Java.
*
* Internally this class uses a {@link GlobusCredential} as a kind of "base"
* credential which will be created prior to getting the voms attribute
* certificate. This "base" proxy is used to contact the voms server which in
* turn will issue the attribute certificate for the group the user requested
* (if he is a member, that is).
*
* The magic happens in the classes {@link VomsProxyCredential} and
* {@link VOMSAttributeCertificate}.
*
* At the moment you only can specify the (sub-)group you want the proxy to have
* information included. If we should need more detailed information in the
* proxy I'll change this so that you can specify the command to the voms server
* directly.
*
* @author Markus Binsteiner
*
*/
public class VomsProxy {
static final Logger myLogger = LoggerFactory.getLogger(VomsProxy.class.getName());
/**
* This one creates a voms proxy with the requested vo information and
* returns it as GSSCredential. It's a convenience method so you don't have
* to create a VomsProxy wrapper object if you don't need to.
*
* @param vo
* the vo you want to have the proxy for
* @param group
* the group you want to have the proxy for (example:
* /APACGrid/NGAdmin)
* @param passphrase
* the passphrase of your local private key
* @param lifetime_in_hours
* how long the proxy should be valid
* @throws Exception
* if something went wrong
*/
public static GSSCredential init(VO vo, String group, char[] passphrase,
int lifetime_in_hours) throws CredentialException {
VomsProxy vomsproxy = null;
try {
vomsproxy = new VomsProxy(vo, group, passphrase,
lifetime_in_hours * 3600 * 1000);
} catch (Exception e) {
LocalVomsProxy.myLogger.error("Could not create voms proxy: "
+ e.getMessage());
throw new CredentialException(e);
}
if ((vomsproxy == null) || (vomsproxy.getVomsProxyCredential() == null)) {
LocalVomsProxy.myLogger.error("Voms proxy is null.");
throw new NullPointerException(
"VomsProxy or VomsProxyCredentail is null.");
}
try {
vomsproxy.getVomsProxyCredential().verify();
} catch (GlobusCredentialException e) {
LocalVomsProxy.myLogger.error("Voms proxy is not valid: "
+ e.getMessage());
throw new CredentialException(e);
}
return CredentialHelpers.wrapGlobusCredential(vomsproxy
.getVomsProxyCredential());
}
public static boolean isVomsProxy(GlobusCredential cred) {
try {
new VomsProxy(cred);
} catch (Exception e) {
return false;
}
return true;
}
private VO vo = null;
private String command = null;
private String order = null;
private long lifetime_in_ms = -1;
private GlobusCredential baseProxy = null;
private VomsProxyCredential vomsProxyCredential = null;
private final AttributeCertificate ac = null;
private ArrayList<String> vomsInfo = null;
/**
* Creates a VomsProxy by parsing a file that contains a voms-enabled X509
* proxy.
*
* @param proxyFile
* the proxy file
* @throws NoVomsProxyException
* if the proxy is not a voms proxy
*/
public VomsProxy(File proxyFile) throws Exception {
try {
// not really the base proxy, but who cares...
baseProxy = CredentialHelpers.loadGlobusCredential(proxyFile);
baseProxy.verify();
} catch (Exception e) {
myLogger.error("Could not load valid credential from file \""
+ proxyFile.toString() + "\": " + e.getMessage());
}
vomsProxyCredential = new VomsProxyCredential(baseProxy);
}
public VomsProxy(GlobusCredential credential) throws Exception {
// not really the base proxy, but who cares...
baseProxy = credential;
baseProxy.verify();
vomsProxyCredential = new VomsProxyCredential(baseProxy);
}
/**
* This creates a VomsProxy using usercert.pem and userkey.pem in the
* default globus location to create a intermediate proxy that is used to
* attach the voms attribute certificate to. You have to provide the
* passphrase of the private key.
*
* @param vo
* the vo you want to have the proxy for
* @param group
* the group you want to have the proxy for (example:
* /APACGrid/NGAdmin)
* @param passphrase
* the passphrase of the private key
* @param lifetime_in_ms
* the lifetime of the proxy (and the voms attribute certificate)
* in milliseconds
* @throws Exception
*/
public VomsProxy(VO vo, String group, char[] passphrase, long lifetime_in_ms)
throws Exception {
this.vo = vo;
this.lifetime_in_ms = lifetime_in_ms;
// this is the command that is sent to the voms server
// possible commands:
// A - This means get everything the server knows about you
// G/group - This means get group informations. /group should be
// /vo-name.
// This is the default request used by voms-proxy-init
// Rrole - This means grant me the specified role, in all groups in
// which you can grant it.
// Bgroup:role - This means grant me the specified role in the specified
// group.
this.command = "G" + group;
this.order = group;
// create the proxy now
try {
createDefaultBaseProxy(passphrase, this.lifetime_in_ms);
} catch (Exception e) {
myLogger.error("Could not create base proxy: " + e.getMessage());
throw e;
}
try {
// create the voms attribute certificate
createAttributeCertificate(baseProxy, this.vo, this.lifetime_in_ms);
} catch (Exception e) {
myLogger.error("Could not create voms attribute certificate: "
+ e.getMessage());
throw e;
}
}
/**
* Creates a VomsProxy using the {@link GlobusCredential} you provide. The
* constructor tries to contact the voms server and get an attribute
* certificate for the requested VO/group and then attaches this attribute
* certificate to the {@link GlobusCredential}.
*
* Use getVomsProxyCredential() to get the actual voms proxy.
*
* @param vo
* the VO you want the proxy forprivate
* @param group
* the (sub-)group within the VO you want the proxy for (example:
* /APACGrid/NGAdmin)
* @param baseProxy
* a valid GlobusCredential (with the appropriate dn the voms
* server has in it's database)
* @param lifetime_in_ms
* the lifetime of the proxy (and the voms attribute certificate)
* in milliseconds
* @throws Exception
* if somethings gone wrong
*/
public VomsProxy(VO vo, String group, GlobusCredential baseProxy,
long lifetime_in_ms) throws Exception {
this.vo = vo;
this.lifetime_in_ms = lifetime_in_ms;
// this is the command that is sent to the voms server
// possible commands:
// A - This means get everything the server knows about you
// G/group - This means get group informations. /group should be
// /vo-name.
// This is the default request used by voms-proxy-init
// Rrole - This means grant me the specified role, in all groups in
// which you can grant it.
// Bgroup:role - This means grant me the specified role in the specified
// group.
this.command = "G" + group;
this.order = group;
try {
// check whether the base proxy is valid, if not: break
baseProxy.verify();
} catch (GlobusCredentialException e) {
myLogger.error("Can't create Voms attribute certificate because base proxy is not valid: "
+ e.getMessage());
throw new Exception(
"Can't create Voms attribute certificate because base proxy is not valid: "
+ e.getMessage());
}
try {
// create the voms attribute certificate
createAttributeCertificate(baseProxy, this.vo, this.lifetime_in_ms);
} catch (Exception e) {
myLogger.error("Could not create voms attribute certificate: "
+ e.getMessage());
throw e;
}
}
private void createAttributeCertificate(GlobusCredential baseCred, VO vo,
long lifetime_in_ms) throws Exception {
// create the VomsProxyCredential
vomsProxyCredential = new VomsProxyCredential(baseCred, vo, command,
order, new Long(lifetime_in_ms / 1000).intValue());
// hm. something went wrong
// myLogger.error("Could not create AttributeCertificate: "+e.getMessage());
// check whether the vomsProxyCredential really was created
if (this.vomsProxyCredential == null) {
throw new Exception("Voms attribute certificate is null.");
}
vomsInfo = null;
}
/**
* Create a "plain" GlobusCredential first which is used to attach the VOMS
* Attribute certificate to
*
* @param passphrase
* the passphrase of the private key
* @param lifetime_in_ms
* the lifetime of the proxy in milliseconds
* @return true if the creation of the proxy worked, wrong if not
* @throws Exception
*/
private void createDefaultBaseProxy(char[] passphrase, long lifetime_in_ms)
throws Exception {
// get the default model for local proxies
DefaultGridProxyModel model = new DefaultGridProxyModel();
// the the lifetime of the "base" GlobusCredential
model.getProperties().setProxyLifeTime(
new Long((lifetime_in_ms) / (1000 * 3600)).intValue());
// create the "base" GlobusCredential
this.baseProxy = model.createProxy(new String(passphrase));
}
/**
* Returns the default fqan of this voms proxy.
*
* @param fullString
* whether you want the full String or only VO and group
* @return the default fqan or null if it couldn't be established.
*/
public String getDefaultFqan(boolean fullString) {
if (vomsProxyCredential == null) {
return null;
}
try {
VOMSAttributeCertificate vomsac = new VOMSAttributeCertificate(
vomsProxyCredential.getAttributeCertificate());
String defFqan = vomsac.getVOMSFQANs().get(0);
if (fullString) {
return defFqan;
} else {
return VomsHelpers.removeRoleAndCapabilityPart(defFqan);
}
} catch (Exception e) {
myLogger.error("Couldn't get default fqan of VomsProxy: "
+ e.getLocalizedMessage());
return null;
}
}
/**
* Retrieves information from the {@link VOMSAttributeCertificate}
*
* @return output similar to the commandline voms-proxy-info
*/
public ArrayList<String> getVomsInfo() {
if (vomsInfo == null) {
vomsInfo = vomsProxyCredential.vomsInfo();
}
return vomsInfo;
}
/**
* If not null, this one returns the actual voms proxy credential
*
* @return the {@link GlobusCredential} with the attached voms attribute
* certificate or null if something went wrong during creation
*/
public GlobusCredential getVomsProxyCredential() {
if (vomsProxyCredential == null) {
return null;
}
return vomsProxyCredential.getVomsProxy();
}
}