From 72650d4cc41c64136d064967d7fec3726d850fee Mon Sep 17 00:00:00 2001
From: Ludovic Poitou <ludovic.poitou@forgerock.com>
Date: Thu, 14 Oct 2010 11:52:28 +0000
Subject: [PATCH] Multiple enhancements and bug fixes to the SDK (update from OpenDS by matthew_swift):
---
sdk/src/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java | 462 +++++++++++++++++++++++++++++----------------------------
1 files changed, 234 insertions(+), 228 deletions(-)
diff --git a/sdk/src/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java b/sdk/src/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java
index 24b4148..cce0537 100644
--- a/sdk/src/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java
+++ b/sdk/src/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java
@@ -31,9 +31,9 @@
import static com.sun.opends.sdk.messages.Messages.ERR_SASL_PROTOCOL_ERROR;
import static com.sun.opends.sdk.util.StaticUtils.getExceptionMessage;
+import static com.sun.opends.sdk.util.StaticUtils.joinCollection;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
@@ -76,15 +76,69 @@
this.password = initialBindRequest.getPassword();
this.realm = initialBindRequest.getRealm();
+ // Create property map containing all the parameters.
final Map<String, String> props = new HashMap<String, String>();
- props.put(Sasl.QOP, "auth-conf,auth-int,auth");
+ final List<String> qopValues = initialBindRequest.getQOPs();
+ if (!qopValues.isEmpty())
+ {
+ props.put(Sasl.QOP, joinCollection(qopValues, ","));
+ }
+
+ final String cipher = initialBindRequest.getCipher();
+ if (cipher != null)
+ {
+ if (cipher.equalsIgnoreCase(CIPHER_LOW))
+ {
+ props.put(Sasl.STRENGTH, "high,medium,low");
+ }
+ else if (cipher.equalsIgnoreCase(CIPHER_MEDIUM))
+ {
+ props.put(Sasl.STRENGTH, "high,medium");
+ }
+ else if (cipher.equalsIgnoreCase(CIPHER_HIGH))
+ {
+ props.put(Sasl.STRENGTH, "high");
+ }
+ else
+ {
+ // Default strength allows all ciphers, so specifying a single cipher
+ // cannot be incompatible with the strength.
+ props.put("com.sun.security.sasl.digest.cipher", cipher);
+ }
+ }
+
+ final Boolean serverAuth = initialBindRequest.isServerAuth();
+ if (serverAuth != null)
+ {
+ props.put(Sasl.SERVER_AUTH, String.valueOf(serverAuth));
+ }
+
+ Integer size = initialBindRequest.getMaxReceiveBufferSize();
+ if (size != null)
+ {
+ props.put(Sasl.MAX_BUFFER, String.valueOf(size));
+ }
+
+ size = initialBindRequest.getMaxSendBufferSize();
+ if (size != null)
+ {
+ props.put("javax.security.sasl.sendmaxbuffer", String.valueOf(size));
+ }
+
+ for (final Map.Entry<String, String> e : initialBindRequest
+ .getAdditionalAuthParams().entrySet())
+ {
+ props.put(e.getKey(), e.getValue());
+ }
+
+ // Now create the client.
try
{
saslClient = Sasl.createSaslClient(
- new String[] { SASL_MECHANISM_NAME }, initialBindRequest
- .getAuthorizationID(), SASL_DEFAULT_PROTOCOL, serverName,
- props, this);
+ new String[] { SASL_MECHANISM_NAME },
+ initialBindRequest.getAuthorizationID(), SASL_DEFAULT_PROTOCOL,
+ serverName, props, this);
if (saslClient.hasInitialResponse())
{
setNextSASLCredentials(saslClient.evaluateChallenge(new byte[0]));
@@ -125,17 +179,18 @@
try
{
setNextSASLCredentials(saslClient.evaluateChallenge(result
- .getServerSASLCredentials() == null ? new byte[0] :
- result.getServerSASLCredentials().toByteArray()));
+ .getServerSASLCredentials() == null ? new byte[0] : result
+ .getServerSASLCredentials().toByteArray()));
return saslClient.isComplete();
}
catch (final SaslException e)
{
// FIXME: I18N need to have a better error message.
// FIXME: Is this the best result code?
- throw ErrorResultException.wrap(Responses.newResult(
- ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
- "An error occurred during multi-stage authentication")
+ throw ErrorResultException.wrap(Responses
+ .newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR)
+ .setDiagnosticMessage(
+ "An error occurred during multi-stage authentication")
.setCause(e));
}
}
@@ -170,9 +225,9 @@
{
final LocalizableMessage msg = ERR_SASL_PROTOCOL_ERROR.get(
SASL_MECHANISM_NAME, getExceptionMessage(e));
- throw ErrorResultException.wrap(Responses.newResult(
- ResultCode.CLIENT_SIDE_DECODING_ERROR).setDiagnosticMessage(
- msg.toString()).setCause(e));
+ throw ErrorResultException.wrap(Responses
+ .newResult(ResultCode.CLIENT_SIDE_DECODING_ERROR)
+ .setDiagnosticMessage(msg.toString()).setCause(e));
}
}
@@ -190,9 +245,9 @@
{
final LocalizableMessage msg = ERR_SASL_PROTOCOL_ERROR.get(
SASL_MECHANISM_NAME, getExceptionMessage(e));
- throw ErrorResultException.wrap(Responses.newResult(
- ResultCode.CLIENT_SIDE_ENCODING_ERROR).setDiagnosticMessage(
- msg.toString()).setCause(e));
+ throw ErrorResultException.wrap(Responses
+ .newResult(ResultCode.CLIENT_SIDE_ENCODING_ERROR)
+ .setDiagnosticMessage(msg.toString()).setCause(e));
}
}
@@ -234,10 +289,19 @@
+ private final Map<String, String> additionalAuthParams = new LinkedHashMap<String, String>();
+ private final List<String> qopValues = new LinkedList<String>();
+ private String cipher = null;
+
+ // Don't use primitives for these so that we can distinguish between default
+ // settings (null) and values set by the caller.
+ private Boolean serverAuth = null;
+ private Integer maxReceiveBufferSize = null;
+ private Integer maxSendBufferSize = null;
+
private String authenticationID;
private String authorizationID = null;
private ByteString password;
-
private String realm = null;
@@ -255,6 +319,38 @@
/**
* {@inheritDoc}
*/
+ @Override
+ public DigestMD5SASLBindRequest addAdditionalAuthParam(final String name,
+ final String value) throws UnsupportedOperationException,
+ NullPointerException
+ {
+ Validator.ensureNotNull(name, value);
+ additionalAuthParams.put(name, value);
+ return this;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public DigestMD5SASLBindRequest addQOP(final String... qopValues)
+ throws UnsupportedOperationException, NullPointerException
+ {
+ for (final String qopValue : qopValues)
+ {
+ this.qopValues.add(Validator.ensureNotNull(qopValue));
+ }
+ return this;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public BindClient createBindClient(final String serverName)
throws ErrorResultException
{
@@ -266,6 +362,18 @@
/**
* {@inheritDoc}
*/
+ @Override
+ public Map<String, String> getAdditionalAuthParams()
+ {
+ return additionalAuthParams;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public String getAuthenticationID()
{
return authenticationID;
@@ -276,6 +384,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public String getAuthorizationID()
{
return authorizationID;
@@ -286,6 +395,40 @@
/**
* {@inheritDoc}
*/
+ @Override
+ public String getCipher()
+ {
+ return cipher;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getMaxReceiveBufferSize()
+ {
+ return maxReceiveBufferSize == null ? 65536 : maxReceiveBufferSize;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getMaxSendBufferSize()
+ {
+ return maxSendBufferSize == null ? 65536 : maxSendBufferSize;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public ByteString getPassword()
{
return password;
@@ -296,6 +439,18 @@
/**
* {@inheritDoc}
*/
+ @Override
+ public List<String> getQOPs()
+ {
+ return qopValues;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public String getRealm()
{
return realm;
@@ -306,6 +461,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public String getSASLMechanism()
{
return SASL_MECHANISM_NAME;
@@ -316,6 +472,18 @@
/**
* {@inheritDoc}
*/
+ @Override
+ public boolean isServerAuth()
+ {
+ return serverAuth == null ? false : serverAuth;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public DigestMD5SASLBindRequest setAuthenticationID(
final String authenticationID) throws NullPointerException
{
@@ -329,6 +497,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public DigestMD5SASLBindRequest setAuthorizationID(
final String authorizationID)
{
@@ -341,6 +510,46 @@
/**
* {@inheritDoc}
*/
+ @Override
+ public DigestMD5SASLBindRequest setCipher(final String cipher)
+ throws UnsupportedOperationException
+ {
+ this.cipher = cipher;
+ return this;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public DigestMD5SASLBindRequest setMaxReceiveBufferSize(final int size)
+ throws UnsupportedOperationException
+ {
+ maxReceiveBufferSize = size;
+ return this;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public DigestMD5SASLBindRequest setMaxSendBufferSize(final int size)
+ throws UnsupportedOperationException
+ {
+ maxSendBufferSize = size;
+ return this;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public DigestMD5SASLBindRequest setPassword(final ByteString password)
throws NullPointerException
{
@@ -354,6 +563,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public DigestMD5SASLBindRequest setPassword(final String password)
throws NullPointerException
{
@@ -367,6 +577,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public DigestMD5SASLBindRequest setRealm(final String realm)
{
this.realm = realm;
@@ -378,216 +589,11 @@
/**
* {@inheritDoc}
*/
- public QOPOption[] getQOP() {
- String value = System.getProperty(Sasl.QOP);
- if(value == null || value.length() == 0)
- {
- return new QOPOption[]{QOPOption.AUTH};
- }
- String[] values = value.split(",");
- QOPOption[] options = new QOPOption[values.length];
-
- for(int i = 0; i < values.length; i++)
- {
- String v = values[i].trim();
- if(v.equalsIgnoreCase("auth"))
- {
- options[i] = QOPOption.AUTH;
- }
- else if(v.equalsIgnoreCase("auth-int"))
- {
- options[i] = QOPOption.AUTH_INT;
- }
- else if(v.equalsIgnoreCase("auth-conf"))
- {
- options[i] = QOPOption.AUTH_CONF;
- }
- }
- return options;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public CipherOption[] getCipher() {
- String value = System.getProperty(Sasl.STRENGTH);
- if(value == null || value.length() == 0)
- {
- return new CipherOption[]{CipherOption.TRIPLE_DES_RC4,
- CipherOption.DES_RC4_56, CipherOption.RC4_40};
- }
- String[] values = value.split(",");
- CipherOption[] options = new CipherOption[values.length];
-
- for(int i = 0; i < values.length; i++)
- {
- String v = values[i].trim();
- if(v.equalsIgnoreCase("high"))
- {
- options[i] = CipherOption.TRIPLE_DES_RC4;
- }
- else if(v.equalsIgnoreCase("medium"))
- {
- options[i] = CipherOption.DES_RC4_56;
- }
- else if(v.equalsIgnoreCase("low"))
- {
- options[i] = CipherOption.RC4_40;
- }
- }
- return options;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean getServerAuth() {
- String value = System.getProperty(Sasl.SERVER_AUTH);
- return !(value == null || value.length() == 0) &&
- value.equalsIgnoreCase("true");
-
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public int getMaxReceiveBufferSize() {
- String value = System.getProperty(Sasl.MAX_BUFFER);
- if(value == null || value.length() == 0)
- {
- return 65536;
- }
- return Integer.parseInt(value);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public int getMaxSendBufferSize() {
- String value = System.getProperty("javax.security.sasl.sendmaxbuffer");
- if(value == null || value.length() == 0)
- {
- return 65536;
- }
- return Integer.parseInt(value);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public DigestMD5SASLBindRequest setQOP(QOPOption... qopOptions) {
- String values = null;
- for(QOPOption option : qopOptions)
- {
- String value = null;
- if(option == QOPOption.AUTH)
- {
- value = "auth";
- }
- else if(option == QOPOption.AUTH_INT)
- {
- value = "auth-int";
- }
- else if(option == QOPOption.AUTH_CONF)
- {
- value = "auth-conf";
- }
-
- if(value != null)
- {
- if(values == null)
- {
- values = value;
- }
- else
- {
- values += (", " + value);
- }
- }
- }
-
- System.setProperty(Sasl.QOP, values);
- return this;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public DigestMD5SASLBindRequest setCipher(CipherOption... cipherOptions) {
- String values = null;
- for(CipherOption option : cipherOptions)
- {
- String value = null;
- if(option == CipherOption.TRIPLE_DES_RC4)
- {
- value = "high";
- }
- else if(option == CipherOption.DES_RC4_56)
- {
- value = "medium";
- }
- else if(option == CipherOption.RC4_40)
- {
- value = "low";
- }
-
- if(value != null)
- {
- if(values == null)
- {
- values = value;
- }
- else
- {
- values += (", " + value);
- }
- }
- }
-
- System.setProperty(Sasl.STRENGTH, values);
- return this;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public DigestMD5SASLBindRequest setServerAuth(boolean serverAuth) {
- System.setProperty(Sasl.SERVER_AUTH, String.valueOf(serverAuth));
- return this;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public DigestMD5SASLBindRequest setMaxReceiveBufferSize(int maxBuffer) {
- System.setProperty(Sasl.MAX_BUFFER, String.valueOf(maxBuffer));
- return this;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public DigestMD5SASLBindRequest setMaxSendBufferSize(int maxBuffer) {
- System.setProperty("javax.security.sasl.sendmaxbuffer",
- String.valueOf(maxBuffer));
+ @Override
+ public DigestMD5SASLBindRequest setServerAuth(final boolean serverAuth)
+ throws UnsupportedOperationException
+ {
+ this.serverAuth = serverAuth;
return this;
}
--
Gitblit v1.10.0