sdk/src/org/opends/sdk/requests/DigestMD5SASLBindRequest.java
@@ -67,6 +67,62 @@ /** * Supported quality-of-protection options. */ public static enum QOPOption { /** * Authentication only. */ AUTH, /** * Authentication plus integrity protection. */ AUTH_INT, /** * Authentication plus integrity and confidentiality protection. */ AUTH_CONF } /** * Cipher options for use with the security layer. */ public static enum CipherOption { /** * Triple DES * The "triple DES" cipher in CBC mode with EDE with the * same key for each E stage (aka "two keys mode") for a * total key length of 112 bits. * <p> * RC4 128 bits * The RC4 cipher with a 128 bit key. */ TRIPLE_DES_RC4, /** * DES * The Data Encryption Standard (DES) cipher [FIPS] in * cipher block chaining (CBC) mode with a 56 bit key. * <p> * RC4 56 bits * The RC4 cipher with a 56 bit key. */ DES_RC4_56, /** * RC4 40 bits * The RC4 cipher with a 40 bit key. */ RC4_40 } /** * {@inheritDoc} */ DigestMD5SASLBindRequest addControl(Control control) @@ -167,6 +223,64 @@ /** * Returns the quality-of-protection options to use. * The order of the list specifies the preference order. * * @return The list of quality-of-protection options to use. */ QOPOption[] getQOP(); /** * Returns the ciphers to use with the optional security layer * offered by the {@code AUTH_CONF} quality-of-protection. The order * of the list specifies the preference order. When there is * more than one choice for a particular option, the cipher * selected depends on the availability of the ciphers in the * underlying platform. * * @return The list of cipher options to use. */ CipherOption[] getCipher(); /** * Returns whether the server must authenticate to the client. * * @return {@code true} if the server must authenticate * to the client or {@code false} otherwise. */ boolean getServerAuth(); /** * Returns the maximum size of the receive buffer in bytes. * The actual maximum number of bytes will * be the minimum of this number and the peer's maximum send * buffer size. * * @return The maximum size of the receive buffer in bytes. */ int getMaxReceiveBufferSize(); /** * Returns the maximum size of the send buffer in bytes. * The actual maximum number of bytes will * be the minimum of this number and the peer's maximum receive * buffer size. * * @return The maximum size of the send buffer in bytes. */ int getMaxSendBufferSize(); /** * Sets the authentication ID of the user. The authentication ID usually has * the form "dn:" immediately followed by the distinguished name of the user, * or "u:" followed by a user ID string, but other forms are permitted. @@ -253,4 +367,67 @@ DigestMD5SASLBindRequest setRealm(String realm) throws UnsupportedOperationException, NullPointerException; /** * Specifies the quality-of-protection options to use. * The order of the list specifies the preference order. * * @param qopOptions The list of quality-of-protection options to * use. * @return This bind request. */ DigestMD5SASLBindRequest setQOP(QOPOption... qopOptions); /** * Specifies the ciphers to use with the optional security layer * offered by the {@code AUTH_CONF} quality-of-protection. The order * of the list specifies the preference order. When there is * more than one choice for a particular option, the cipher * selected depends on the availability of the ciphers in the * underlying platform. * * @param cipherOptions The list of cipher options to use. * @return his bind request. */ DigestMD5SASLBindRequest setCipher(CipherOption... cipherOptions); /** * Specifies whether the server must authenticate to the client. * * @param serverAuth {@code true} if the server must authenticate * to the client or {@code false} otherwise. * @return This bind request. */ DigestMD5SASLBindRequest setServerAuth(boolean serverAuth); /** * Specifies the maximum size of the receive buffer in bytes. * The actual maximum number of bytes will * be the minimum of this number and the peer's maximum send * buffer size. * * @param maxBuffer The maximum size of the receive buffer in bytes. * @return This bind request. */ DigestMD5SASLBindRequest setMaxReceiveBufferSize(int maxBuffer); /** * Specifies the maximum size of the send buffer in bytes. * The actual maximum number of bytes will * be the minimum of this number and the peer's maximum receive * buffer size. * * @param maxBuffer The maximum size of the send buffer in bytes. * @return This bind request. */ DigestMD5SASLBindRequest setMaxSendBufferSize(int maxBuffer); } sdk/src/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java
@@ -375,6 +375,224 @@ /** * {@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)); return this; } @Override public String toString() { sdk/src/org/opends/sdk/requests/GSSAPISASLBindRequest.java
@@ -66,6 +66,29 @@ /** * Supported quality-of-protection options. */ public static enum QOPOption { /** * Authentication only. */ AUTH, /** * Authentication plus integrity protection. */ AUTH_INT, /** * Authentication plus integrity and confidentiality protection. */ AUTH_CONF } /** * {@inheritDoc} */ GSSAPISASLBindRequest addControl(Control control) @@ -197,6 +220,52 @@ /** * Returns the quality-of-protection options to use. * The order of the list specifies the preference order. * * @return The list of quality-of-protection options to use. */ QOPOption[] getQOP(); /** * Returns whether the server must authenticate to the client. * The default is {@code false}. * * @return {@code true} if the server must authenticate * to the client or {@code false} otherwise. */ boolean getServerAuth(); /** * Returns the maximum size of the receive buffer in bytes. The * default is 65536. The actual maximum number of bytes will * be the minimum of this number and the peer's maximum send * buffer size. * * @return The maximum size of the receive buffer in bytes. */ int getMaxReceiveBufferSize(); /** * Returns the maximum size of the send buffer in bytes. The * default is 65536. The actual maximum number of bytes will * be the minimum of this number and the peer's maximum receive * buffer size. * * @return The maximum size of the send buffer in bytes. */ int getMaxSendBufferSize(); /** * Sets the authentication ID of the user, which should be the user's Kerberos * principal. The authentication ID usually has the form "dn:" immediately * followed by the distinguished name of the user, or "u:" followed by a user @@ -327,4 +396,53 @@ */ GSSAPISASLBindRequest setSubject(Subject subject) throws NullPointerException; /** * Specifies the quality-of-protection options to use. * The order of the list specifies the preference order. * * @param qopOptions The list of quality-of-protection options to * use. * @return This bind request. */ GSSAPISASLBindRequest setQOP(QOPOption... qopOptions); /** * Specifies whether the server must authenticate to the client. * * @param serverAuth {@code true} if the server must authenticate * to the client or {@code false} otherwise. * @return This bind request. */ GSSAPISASLBindRequest setServerAuth(boolean serverAuth); /** * Specifies the maximum size of the receive buffer in bytes. * The actual maximum number of bytes will * be the minimum of this number and the peer's maximum send * buffer size. * * @param maxBuffer The maximum size of the receive buffer in bytes. * @return This bind request. */ GSSAPISASLBindRequest setMaxReceiveBufferSize(int maxBuffer); /** * Specifies the maximum size of the send buffer in bytes. * The actual maximum number of bytes will * be the minimum of this number and the peer's maximum receive * buffer size. * * @param maxBuffer The maximum size of the send buffer in bytes. * @return This bind request. */ GSSAPISASLBindRequest setMaxSendBufferSize(int maxBuffer); } sdk/src/org/opends/sdk/requests/GSSAPISASLBindRequestImpl.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. * Copyright 2009-2010 Sun Microsystems, Inc. */ package org.opends.sdk.requests; @@ -539,6 +539,150 @@ /** * {@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 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 GSSAPISASLBindRequest 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 GSSAPISASLBindRequest setServerAuth(boolean serverAuth) { System.setProperty(Sasl.SERVER_AUTH, String.valueOf(serverAuth)); return this; } /** * {@inheritDoc} */ public GSSAPISASLBindRequest setMaxReceiveBufferSize(int maxBuffer) { System.setProperty(Sasl.MAX_BUFFER, String.valueOf(maxBuffer)); return this; } /** * {@inheritDoc} */ public GSSAPISASLBindRequest setMaxSendBufferSize(int maxBuffer) { System.setProperty("javax.security.sasl.sendmaxbuffer", String.valueOf(maxBuffer)); return this; } /** * {@inheritDoc} */ @Override public String toString() { sdk/tests/unit-tests-testng/src/org/opends/sdk/ConnectionFactoryTestCase.java
@@ -35,6 +35,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.opends.sdk.requests.DigestMD5SASLBindRequest; import org.opends.sdk.requests.Requests; import org.opends.sdk.requests.SearchRequest; import org.testng.annotations.BeforeClass; @@ -148,7 +149,9 @@ factories[6][0] = new AuthenticatedConnectionFactory( new LDAPConnectionFactory("localhost", TestCaseUtils.getLdapPort(), options), Requests.newDigestMD5SASLBindRequest("id:user", ByteString.valueOf("password"))); ByteString.valueOf("password")).setQOP( DigestMD5SASLBindRequest.QOPOption.AUTH_CONF).setCipher( DigestMD5SASLBindRequest.CipherOption.TRIPLE_DES_RC4)); return factories; } sdk/tests/unit-tests-testng/src/org/opends/sdk/requests/DigestMD5SASLBindRequestTestCase.java
@@ -31,7 +31,12 @@ import org.opends.sdk.ByteString; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.util.Arrays; import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertEquals; /** @@ -68,4 +73,53 @@ return ops; } @Test(dataProvider = "DigestMD5SASLBindRequests") public void testQOP(DigestMD5SASLBindRequest request) throws Exception { DigestMD5SASLBindRequest.QOPOption [] options = new DigestMD5SASLBindRequest.QOPOption[]{ DigestMD5SASLBindRequest.QOPOption.AUTH, DigestMD5SASLBindRequest.QOPOption.AUTH_INT, DigestMD5SASLBindRequest.QOPOption.AUTH_CONF}; request.setQOP(options); DigestMD5SASLBindRequest.QOPOption [] results = request.getQOP(); for(int i = 0; i < options.length; i++) { assertEquals(options[i], results[i]); } } @Test(dataProvider = "DigestMD5SASLBindRequests" ) public void testStrength(DigestMD5SASLBindRequest request) throws Exception { DigestMD5SASLBindRequest.CipherOption[] options = new DigestMD5SASLBindRequest.CipherOption[]{ DigestMD5SASLBindRequest.CipherOption.RC4_40, DigestMD5SASLBindRequest.CipherOption.TRIPLE_DES_RC4, DigestMD5SASLBindRequest.CipherOption.DES_RC4_56}; request.setCipher(options); assertTrue(Arrays.deepEquals(options, request.getCipher())); } @Test(dataProvider = "DigestMD5SASLBindRequests") public void testServerAuth(DigestMD5SASLBindRequest request) throws Exception { request.setServerAuth(true); assertEquals(request.getServerAuth(), true); } @Test(dataProvider = "DigestMD5SASLBindRequests") public void testSendBuffer(DigestMD5SASLBindRequest request) throws Exception { request.setMaxSendBufferSize(1024); assertEquals(request.getMaxSendBufferSize(), 1024); } @Test(dataProvider = "DigestMD5SASLBindRequests") public void testRecieveBuffer(DigestMD5SASLBindRequest request) throws Exception {; request.setMaxReceiveBufferSize(1024); assertEquals(request.getMaxReceiveBufferSize(), 1024); } } sdk/tests/unit-tests-testng/src/org/opends/sdk/requests/GSSAPISASLBindRequestTestCase.java
@@ -31,13 +31,17 @@ import org.opends.sdk.ByteString; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.util.Arrays; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; /** * Tests GSSAPI SASL Bind requests. */ public abstract class GSSAPISASLBindRequestTestCase extends BindRequestTestCase public class GSSAPISASLBindRequestTestCase extends BindRequestTestCase { @DataProvider(name = "GSSAPISASLBindRequests") public Object[][] getGSSAPISASLBindRequests() throws Exception @@ -67,4 +71,43 @@ } return ops; } @Test(enabled = false) public void testBindClient(BindRequest request) throws Exception { // Should setup a test krb server... super.testBindClient(request); } @Test(dataProvider = "GSSAPISASLBindRequests") public void testQOP(GSSAPISASLBindRequest request) throws Exception { GSSAPISASLBindRequest.QOPOption [] options = new GSSAPISASLBindRequest.QOPOption[]{ GSSAPISASLBindRequest.QOPOption.AUTH, GSSAPISASLBindRequest.QOPOption.AUTH_INT, GSSAPISASLBindRequest.QOPOption.AUTH_CONF}; request.setQOP(options); assertTrue(Arrays.deepEquals(options, request.getQOP())); } @Test(dataProvider = "GSSAPISASLBindRequests") public void testServerAuth(GSSAPISASLBindRequest request) throws Exception { request.setServerAuth(true); assertEquals(request.getServerAuth(), true); } @Test(dataProvider = "GSSAPISASLBindRequests") public void testSendBuffer(GSSAPISASLBindRequest request) throws Exception { request.setMaxSendBufferSize(512); assertEquals(request.getMaxSendBufferSize(), 512); } @Test(dataProvider = "GSSAPISASLBindRequests") public void testRecieveBuffer(GSSAPISASLBindRequest request) throws Exception { request.setMaxReceiveBufferSize(512); assertEquals(request.getMaxReceiveBufferSize(), 512); } }