summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEndi Sukma Dewata <edewata@redhat.com>2012-07-07 00:14:13 -0500
committerEndi Sukma Dewata <edewata@redhat.com>2012-07-30 11:21:58 -0500
commit2d427ce0008fb43ae9f6c02301ce6793a42904b9 (patch)
tree053fbdd575aae8dd06a8e8b90f39b6060d7b635d
parentc4636a5b56bd3e0f18fb3afd0b930729d58ce1f6 (diff)
downloadpki-2d427ce0008fb43ae9f6c02301ce6793a42904b9.tar.gz
pki-2d427ce0008fb43ae9f6c02301ce6793a42904b9.tar.xz
pki-2d427ce0008fb43ae9f6c02301ce6793a42904b9.zip
Added support for basic authentication.
The CMSRestClient has been modified to support basic authentication and handle HTTP redirection. The basic authentication can be used as follows: pki -U <server uri> -u <username> -w <password> user-find Some protected REST services might require secure connection. If the user tries to call these services over HTTP the CLI will handle the redirection automatically to an HTTPS port. Ticket #107
-rw-r--r--base/common/src/com/netscape/cms/client/cli/ClientConfig.java16
-rw-r--r--base/common/src/com/netscape/cms/client/cli/MainCLI.java8
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/CMSRestClient.java131
3 files changed, 140 insertions, 15 deletions
diff --git a/base/common/src/com/netscape/cms/client/cli/ClientConfig.java b/base/common/src/com/netscape/cms/client/cli/ClientConfig.java
index bad8ba626..8b5380805 100644
--- a/base/common/src/com/netscape/cms/client/cli/ClientConfig.java
+++ b/base/common/src/com/netscape/cms/client/cli/ClientConfig.java
@@ -52,6 +52,7 @@ public class ClientConfig {
String certDatabase;
String certNickname;
+ String username;
String password;
@XmlElement(name="ServerURI")
@@ -85,6 +86,15 @@ public class ClientConfig {
this.certNickname = certNickname;
}
+ @XmlElement(name="Username")
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
@XmlElement(name="Password")
public String getPassword() {
return password;
@@ -102,6 +112,7 @@ public class ClientConfig {
result = prime * result + ((certNickname == null) ? 0 : certNickname.hashCode());
result = prime * result + ((password == null) ? 0 : password.hashCode());
result = prime * result + ((serverURI == null) ? 0 : serverURI.hashCode());
+ result = prime * result + ((username == null) ? 0 : username.hashCode());
return result;
}
@@ -134,6 +145,11 @@ public class ClientConfig {
return false;
} else if (!serverURI.equals(other.serverURI))
return false;
+ if (username == null) {
+ if (other.username != null)
+ return false;
+ } else if (!username.equals(other.username))
+ return false;
return true;
}
diff --git a/base/common/src/com/netscape/cms/client/cli/MainCLI.java b/base/common/src/com/netscape/cms/client/cli/MainCLI.java
index 0367cbbfd..50c90d892 100644
--- a/base/common/src/com/netscape/cms/client/cli/MainCLI.java
+++ b/base/common/src/com/netscape/cms/client/cli/MainCLI.java
@@ -107,6 +107,10 @@ public class MainCLI extends CLI {
option.setArgName("nickname");
options.addOption(option);
+ option = new Option("u", true, "Username");
+ option.setArgName("username");
+ options.addOption(option);
+
option = new Option("w", true, "Password");
option.setArgName("password");
options.addOption(option);
@@ -131,6 +135,7 @@ public class MainCLI extends CLI {
String certDatabase = cmd.getOptionValue("d");
String certNickname = cmd.getOptionValue("n");
+ String username = cmd.getOptionValue("u");
String password = cmd.getOptionValue("w");
// convert into absolute path
@@ -140,6 +145,9 @@ public class MainCLI extends CLI {
if (certNickname != null)
config.setCertNickname(certNickname);
+ if (username != null)
+ config.setUsername(username);
+
if (password != null)
config.setPassword(password);
}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/CMSRestClient.java b/base/common/src/com/netscape/cms/servlet/csadmin/CMSRestClient.java
index 6a38464dc..2317eac47 100644
--- a/base/common/src/com/netscape/cms/servlet/csadmin/CMSRestClient.java
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/CMSRestClient.java
@@ -1,5 +1,6 @@
package com.netscape.cms.servlet.csadmin;
+import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@@ -7,18 +8,33 @@ import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
+import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.List;
import org.apache.commons.httpclient.ConnectTimeoutException;
+import org.apache.http.Header;
+import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
+import org.apache.http.ProtocolException;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.auth.params.AuthPNames;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.params.AuthPolicy;
+import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.scheme.LayeredSchemeSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeSocketFactory;
+import org.apache.http.impl.client.ClientParamsStack;
import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.client.DefaultRedirectStrategy;
+import org.apache.http.impl.client.EntityEnclosingRequestWrapper;
+import org.apache.http.impl.client.RequestWrapper;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import org.jboss.resteasy.client.ClientExecutor;
@@ -29,6 +45,8 @@ import org.jboss.resteasy.client.core.BaseClientResponse;
import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;
import org.jboss.resteasy.client.core.extractors.ClientErrorHandler;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.AlreadyInitializedException;
import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
import org.mozilla.jss.ssl.SSLSocket;
@@ -47,26 +65,87 @@ public abstract class CMSRestClient {
public CMSRestClient(ClientConfig config) {
this.config = config;
- DefaultHttpClient httpclient = new DefaultHttpClient();
+ DefaultHttpClient httpClient = new DefaultHttpClient();
- httpclient.addRequestInterceptor(new HttpRequestInterceptor() {
+ // Register https scheme.
+ Scheme scheme = new Scheme("https", 443, new JSSProtocolSocketFactory());
+ httpClient.getConnectionManager().getSchemeRegistry().register(scheme);
+
+ if (config.getUsername() != null && config.getPassword() != null) {
+ List<String> authPref = new ArrayList<String>();
+ authPref.add(AuthPolicy.BASIC);
+ httpClient.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF, authPref);
+
+ httpClient.getCredentialsProvider().setCredentials(
+ AuthScope.ANY,
+ new UsernamePasswordCredentials(config.getUsername(), config.getPassword()));
+ }
+
+ httpClient.addRequestInterceptor(new HttpRequestInterceptor() {
@Override
public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
- if (verbose) System.out.println("HTTP Request: "+request.getRequestLine());
+ if (verbose) {
+ System.out.println("HTTP request: "+request.getRequestLine());
+ for (Header header : request.getAllHeaders()) {
+ System.out.println(" "+header.getName()+": "+header.getValue());
+ }
+ }
+
+ // Set the request parameter to follow redirections.
+ HttpParams params = request.getParams();
+ if (params instanceof ClientParamsStack) {
+ ClientParamsStack paramsStack = (ClientParamsStack)request.getParams();
+ params = paramsStack.getRequestParams();
+ }
+ HttpClientParams.setRedirecting(params, true);
}
});
- httpclient.addResponseInterceptor(new HttpResponseInterceptor() {
+ httpClient.addResponseInterceptor(new HttpResponseInterceptor() {
+ @Override
public void process(HttpResponse response, HttpContext context) throws HttpException, IOException {
- if (verbose) System.out.println("HTTP Response: "+response.getStatusLine());
+ if (verbose) {
+ System.out.println("HTTP response: "+response.getStatusLine());
+ for (Header header : response.getAllHeaders()) {
+ System.out.println(" "+header.getName()+": "+header.getValue());
+ }
+ }
}
});
- // register https scheme
- Scheme scheme = new Scheme("https", 443, new JSSProtocolSocketFactory());
- httpclient.getConnectionManager().getSchemeRegistry().register(scheme);
+ httpClient.setRedirectStrategy(new DefaultRedirectStrategy() {
+ @Override
+ public HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context)
+ throws ProtocolException {
+
+ HttpUriRequest uriRequest = super.getRedirect(request, response, context);
+
+ URI uri = uriRequest.getURI();
+ if (verbose) System.out.println("HTTP redirect: "+uri);
+
+ // Redirect the original request to the new URI.
+ RequestWrapper wrapper;
+ if (request instanceof HttpEntityEnclosingRequest) {
+ wrapper = new EntityEnclosingRequestWrapper((HttpEntityEnclosingRequest)request);
+ } else {
+ wrapper = new RequestWrapper(request);
+ }
+ wrapper.setURI(uri);
- executor = new ApacheHttpClient4Executor(httpclient);
+ return wrapper;
+ }
+
+ @Override
+ public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context)
+ throws ProtocolException {
+
+ // The default redirection policy does not redirect POST or PUT.
+ // This overrides the policy to follow redirections for all HTTP methods.
+ return response.getStatusLine().getStatusCode() == 302;
+ }
+ });
+
+ executor = new ApacheHttpClient4Executor(httpClient);
providerFactory = ResteasyProviderFactory.getInstance();
providerFactory.addClientErrorInterceptor(new CMSErrorInterceptor());
errorHandler = new ClientErrorHandler(providerFactory.getClientErrorInterceptors());
@@ -98,7 +177,7 @@ public abstract class CMSRestClient {
}
}
- //For other errors return false
+ // For other errors return false.
return false;
}
@@ -120,12 +199,34 @@ public abstract class CMSRestClient {
UnknownHostException,
ConnectTimeoutException {
+ // Initialize JSS before using SSLSocket,
+ // otherwise it will throw UnsatisfiedLinkError.
+ if (config.getCertDatabase() == null) {
+ try {
+ // No database specified, use $HOME/.pki/nssdb.
+ File homeDir = new File(System.getProperty("user.home"));
+ File pkiDir = new File(homeDir, ".pki");
+ File nssdbDir = new File(pkiDir, "nssdb");
+ nssdbDir.mkdirs();
+
+ CryptoManager.initialize(nssdbDir.getAbsolutePath());
+
+ } catch (AlreadyInitializedException e) {
+ // ignore
+
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+
+ } else {
+ // Database specified, already initialized by the main program.
+ }
+
String hostName = null;
int port = 0;
if (remoteAddress != null) {
hostName = remoteAddress.getHostName();
port = remoteAddress.getPort();
-
}
int localPort = 0;
@@ -160,14 +261,14 @@ public abstract class CMSRestClient {
@Override
public boolean isSecure(Socket sock) {
- //We only use this factory in the case of SSL Connections
+ // We only use this factory in the case of SSL Connections.
return true;
}
@Override
- public Socket createLayeredSocket(Socket arg0, String arg1, int arg2, boolean arg3) throws IOException,
- UnknownHostException {
- //This method implementation is required to get SSL working.
+ public Socket createLayeredSocket(Socket socket, String target, int port, boolean autoClose)
+ throws IOException, UnknownHostException {
+ // This method implementation is required to get SSL working.
return null;
}