package grith.jgrith.cred; import grisu.jcommons.constants.GridEnvironment; import grisu.jcommons.exceptions.CredentialException; import grith.jgrith.cred.AbstractCred.PROPERTY; import grith.jgrith.myProxy.MyProxy_light; import java.io.File; import java.io.FileOutputStream; import java.util.Arrays; import java.util.Map; import java.util.Properties; import java.util.UUID; import org.apache.commons.lang.StringUtils; import org.globus.common.CoGProperties; import org.globus.myproxy.MyProxyException; import org.globus.util.Util; import org.ietf.jgss.GSSCredential; import org.ietf.jgss.GSSException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.Ostermiller.util.RandPass; import com.google.common.collect.Maps; public class BaseCred { static final Logger myLogger = LoggerFactory.getLogger(BaseCred.class .getName()); public static final String DEFAULT_MYPROXY_FILE_EXTENSION = ".mp"; public static final String DEFAULT_MYPROXY_FILE_LOCATION = CoGProperties .getDefault().getProxyFile() + DEFAULT_MYPROXY_FILE_EXTENSION; public static final int DEFAULT_MIN_LIFETIME_IN_SECONDS = 1200; public static final String CHILD_KEY = "group"; public static final int DEFAULT_PROXY_LIFETIME_IN_SECONDS = 864000; public static String extractMyProxyServerFromUsername(String un) { int index = un.lastIndexOf('@'); if (index <= 0) { return ""; } return un.substring(index + 1); } public static String extractUsernameFromUsername(String un) { int index = un.lastIndexOf('@'); if (index <= 0) { return un; } return un.substring(0, index); } private String myProxyUsername; private char[] myProxyPassword; private String myProxyHost; private int myProxyPort = 7512; protected String localMPPath = DEFAULT_MYPROXY_FILE_LOCATION; private int minLifetimeInSecondsBeforeReDownload = DEFAULT_MIN_LIFETIME_IN_SECONDS; private GSSCredential cachedMyProxyCredential = null; public BaseCred() { this(null, null, null, -1); } public BaseCred(Map<PROPERTY, Object> config) { initMyProxy(config); } public BaseCred(String un, char[] pw) { this(un, pw, null, -1); } public BaseCred(String un, char[] pw, String host) { this(un, pw, host, -1); } public BaseCred(String un, char[] pw, String host, Integer port) { if (StringUtils.isNotBlank(un)) { Map<PROPERTY, Object> config = Maps.newHashMap(); config.put(PROPERTY.MyProxyUsername, un); config.put(PROPERTY.MyProxyPassword, pw); config.put(PROPERTY.MyProxyHost, host); config.put(PROPERTY.MyProxyPort, port); initMyProxy(config); } } public void destroyMyProxy() { if (StringUtils.isNotBlank(localMPPath)) { if (new File(localMPPath).exists()) { myLogger.debug("Deleting proxy file " + localMPPath); Util.destroy(localMPPath); } } if (cachedMyProxyCredential != null) { try { cachedMyProxyCredential.dispose(); } catch (Exception e) { myLogger.debug("Error when disposing cached gss credential.", e); } } Arrays.fill(getMyProxyPassword(), 'x'); } public GSSCredential getGSSCredentialMyProxy() { try { if ((cachedMyProxyCredential == null) || (cachedMyProxyCredential.getRemainingLifetime() < minLifetimeInSecondsBeforeReDownload)) { try { cachedMyProxyCredential = MyProxy_light.getDelegation( getMyProxyHost(), getMyProxyPort(), getMyProxyUsername(), getMyProxyPassword(), 0); } catch (MyProxyException e) { throw new CredentialException( "Could not retrieve myproxy credential '" + getMyProxyUsername() + "' (from: '" + getMyProxyHost() + "')", e); } } } catch (GSSException e) { throw new CredentialException( "Could not get lifetime of credential.", e); } return cachedMyProxyCredential; } public String getMyProxyHost() { if (StringUtils.isBlank(myProxyHost)) { return GridEnvironment.getDefaultMyProxyServer(); } return myProxyHost; } public char[] getMyProxyPassword() { if ((this.myProxyPassword == null) || (this.myProxyPassword.length == 0)) { this.myProxyPassword = new RandPass().getPassChars(10); } return myProxyPassword; } public String getMyProxyPath() { if (StringUtils.isNotBlank(this.localMPPath) && new File(this.localMPPath).exists()) { return this.localMPPath; } return null; } public int getMyProxyPort() { if (myProxyPort <= 0) { return GridEnvironment.getDefaultMyProxyPort(); } return myProxyPort; } public String getMyProxyUsername() { if (StringUtils.isBlank(myProxyUsername)) { this.myProxyUsername = UUID.randomUUID().toString(); } return myProxyUsername; } public int getRemainingLifetimeMyProxy() { try { return getGSSCredentialMyProxy().getRemainingLifetime(); } catch (GSSException e) { throw new CredentialException("Can't get remaining lifetime.", e); } catch (CredentialException ce) { myLogger.debug("Can't get base gsscredential.", ce); return 0; } } protected void initMyProxy(Map<PROPERTY, Object> config) { String un = (String) config.get(PROPERTY.MyProxyUsername); char[] pw = (char[]) config.get(PROPERTY.MyProxyPassword); String host = (String) config.get(PROPERTY.MyProxyHost); int port = -1; try { port = (Integer) config.get(PROPERTY.MyProxyPort); } catch (Exception e) { port = GridEnvironment.getDefaultMyProxyPort(); } if (StringUtils.isBlank(un)) { this.myProxyUsername = UUID.randomUUID().toString(); } else { String temp = extractMyProxyServerFromUsername(un); if (StringUtils.isBlank(temp)) { this.myProxyUsername = un; this.myProxyHost = host; } else { this.myProxyUsername = extractUsernameFromUsername(un); this.myProxyHost = temp; } } if (StringUtils.isBlank(this.myProxyHost)) { this.myProxyHost = GridEnvironment.getDefaultMyProxyServer(); } if ((pw == null) || (pw.length == 0)) { this.myProxyPassword = new RandPass().getPassChars(10); } else { this.myProxyPassword = pw; } if (port <= 0) { port = GridEnvironment.getDefaultMyProxyPort(); } else { this.myProxyPort = port; } } protected void invalidateCachedCredential() { this.cachedMyProxyCredential = null; } public boolean isValidMyProxy() { return (getRemainingLifetimeMyProxy() > 0); } public void saveMyProxy() { saveMyProxy(null); } /** * Saves the metadata file for this myproxy (contains host, username, * password,...). * * Only works if proxy is already stored in the path. * * @param path * the path for the proxy (.mp) will be appended */ public void saveMyProxy(String path) { if (( this instanceof GroupCred) && (StringUtils.isBlank(path)) ) { return; } if (StringUtils.isBlank(path)) { path = CoGProperties.getDefault().getProxyFile(); } File proxyFile = new File(path); if (!proxyFile.exists()) { myLogger.debug("No proxy file exists on {}", path); throw new CredentialException( "Can't save myproxy metadata, proxy file " + path + " does not exist."); } this.localMPPath = path + DEFAULT_MYPROXY_FILE_EXTENSION; File mpProxyFile = new File(localMPPath); Properties prop = new Properties(); if (mpProxyFile.exists()) { myLogger.debug( "MyProxy proxy file already exists, deleting it ({})", localMPPath); } prop.put(PROPERTY.MyProxyUsername.toString(), getMyProxyUsername()); prop.put(PROPERTY.MyProxyPassword.toString(), new String( getMyProxyPassword())); prop.put(PROPERTY.MyProxyHost.toString(), getMyProxyHost()); prop.put(PROPERTY.MyProxyPort.toString(), Integer.toString(getMyProxyPort())); try { prop.store(new FileOutputStream(mpProxyFile), null); Util.setFilePermissions(mpProxyFile.getAbsolutePath(), 600); } catch (Exception e) { throw new CredentialException("Can't store credential metadata.", e); } } public void setMyProxyHost(String mph) { this.myProxyHost = mph; } public void setMyProxyPassword(char[] pw) { this.myProxyPassword = pw; } public void setMyProxyPort(int port) { this.myProxyPort = port; } public void setMyProxyUsername(String username) { if (StringUtils.isBlank(username)) { this.myProxyUsername = null; return; } String tmp = extractMyProxyServerFromUsername(username); if (StringUtils.isNotBlank(tmp)) { this.myProxyHost = tmp; this.myProxyUsername = extractUsernameFromUsername(username); } else { this.myProxyUsername = username; } } @Override public String toString() { if (StringUtils.equals(myProxyHost, GridEnvironment.getDefaultMyProxyServer())) { return myProxyUsername; } else { return myProxyUsername + '@' + myProxyHost; } } }