Project

General

Profile

1
package edu.ucsb.nceas.metacat.client.gsi;
2

    
3
import edu.ucsb.nceas.metacat.client.MetacatAuthException;
4
import edu.ucsb.nceas.metacat.client.MetacatClient;
5
import edu.ucsb.nceas.metacat.client.MetacatInaccessibleException;
6
import edu.ucsb.nceas.utilities.HttpMessage;
7
import org.ietf.jgss.GSSCredential;
8

    
9
import java.io.IOException;
10
import java.net.MalformedURLException;
11
import java.net.URL;
12
import java.net.URLStreamHandler;
13
import java.util.Properties;
14

    
15
/** An extension of the Metacat client that uses Grid Security Infrastructure
16
 *  (GSI) enabled HTTPS instead of HTTP to communicate.
17
 *
18
 *  <p>Note that not all client deployments will include the JARs necessary to
19
 *  run this version of the Metacat client; therefore, we should make sure that
20
 *  the superclass (MetacatClient) can run even if this class can't be loaded.
21
 *  That is, catch (and log) NoClassDefFoundError, etc. */
22
public class MetacatGsiClient extends MetacatClient {
23

    
24
	/** The current user's GSS credential, as an alternative to
25
	 *  username/password. Needed for every connection.
26
	 *  Set via {@link #login(GSSCredential)}. */
27
	private GSSCredential credential;
28

    
29
	private void initCredential(GSSCredential credential)
30
		throws MetacatAuthException
31
	{
32
		if (credential == null)
33
			throw new NullPointerException("Credential is null.");
34
		if (this.credential != null)
35
			throw new MetacatAuthException
36
				("Credential already initialized; please create a new "
37
					+ getClass().getName() + " to start a new session.");
38
		this.credential = credential;
39
	}
40

    
41
	public String login(GSSCredential credential)
42
			throws MetacatAuthException, MetacatInaccessibleException
43
	{
44
		initCredential(credential);
45

    
46
		// code below mostly copied from super.login(username, password)
47
		Properties prop = new Properties();
48
		prop.put("action", "login");
49
		prop.put("qformat", "xml");
50

    
51
		String response;
52
		try {
53
			response = sendDataForString(prop, null, null, 0);
54
		} catch (Exception e) {
55
			throw new MetacatInaccessibleException(e);
56
		}
57

    
58
		if (response.indexOf("<login>") == -1) {
59
			setSessionId("");
60
			throw new MetacatAuthException(response);
61
		} else {
62
			int start = response.indexOf("<sessionId>") + 11;
63
			int end = response.indexOf("</sessionId>");
64
			if ((start != -1) && (end != -1)) {
65
				setSessionId(response.substring(start,end));
66
			}
67
		}
68
		return response;
69
	}
70

    
71
	/** Parse the Metacat URL and, if we are using a GSI credential,
72
	 *  ensure that the protocol is an SSL-based one (HTTPS or HTTPG). */
73
	private URL parseAndCheckURL() throws MetacatInaccessibleException {
74
		try {
75
			URL url = new URL(getMetacatUrl().trim());
76

    
77
			if (credential != null) {
78
				URLStreamHandler gsiHandler;
79
				try {
80
					gsiHandler = (URLStreamHandler) Class
81
						.forName("org.globus.net.protocol.https.Handler")
82
						.newInstance();
83
				} catch (Exception e) {
84
					throw new MetacatInaccessibleException
85
						("Unable to create protocol handler for HTTPS+GSI.", e);
86
				}
87
				// reconstruct with correct handler
88
				url = new URL(url.getProtocol(), url.getHost(), url.getPort(),
89
					url.getFile(), gsiHandler);
90
			}
91
			return url;
92
		}
93
		catch (MalformedURLException e) {
94
			throw new MetacatInaccessibleException
95
				("Unable to parse URL to contact Metacat server: \""
96
					+ getMetacatUrl() + "\".", e);
97
		}
98
	}
99

    
100
	/** Create an HttpMessage that can send messages to the server.
101
	 *  If using a GSI credential, use the credential to set up an SSL
102
	 *  connection (HTTPS / HTTPG).  If using HTTP and username/password,
103
	 *  just use a regular HTTP conenction. */
104
	protected HttpMessage createHttpMessage()
105
		throws MetacatInaccessibleException, MetacatAuthException, IOException
106
	{
107
		if (credential != null)
108
			return new HttpGsiMessage(credential, parseAndCheckURL());
109
		else
110
			return super.createHttpMessage();
111
	}
112
}
(1-1/5)