SSFTestCase.java revision ea1068c292e9b341af6d6b563cd8988a96be20a9
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* or http://forgerock.org/license/CDDLv1.0.html.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2008-2009 Sun Microsystems, Inc.
* Portions Copyright 2011-2015 ForgeRock AS
*/
/**
* Unit test to test the ssf ACI bind rule keyword.
*/
package org.opends.server.authorization.dseecompat;
import java.util.Hashtable;
import javax.naming.Context;
import org.opends.server.TestCaseUtils;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.testng.annotations.*;
import static org.opends.server.config.ConfigConstants.*;
public class SSFTestCase extends AciTestCase {
private static final String newUser="uid=new.user,ou=People,o=test";
private static final String descriptionStr = "description of user.1";
private static final String factory = "com.sun.jndi.ldap.LdapCtxFactory";
private static final String pwdPolicy = "Aci Temp Policy";
private static final String pwdPolicyDN =
"cn=" + pwdPolicy + ",cn=Password Policies,cn=config";
private static final String[] newEntry = new String[] {
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: new.user",
"givenName: New",
"sn: User",
"cn: New User",
"mail: new.user@test.com",
"ds-pwp-password-policy-dn:" + pwdPolicyDN
};
private static final
String integrityACI = "(targetattr=\"" + "*" + "\")" +
"(version 3.0; acl \"integrity aci\";" +
"allow(all) (userdn=\"ldap:///self\" and ssf = \"1\");)";
private static final
String greaterIntegrityACI = "(targetattr=\"" + "*" + "\")" +
"(version 3.0; acl \"greater integrity aci\";" +
"allow(all) (userdn=\"ldap:///self\" and ssf > \"1\");)";
private static final
String medStrengthACI = "(targetattr=\"" + "*" + "\")" +
"(version 3.0; acl \"56 bit key aci\";" +
"allow(all) (userdn=\"ldap:///self\" and ssf = \"56\");)";
private static final
String medStrengthNEACI = "(targetattr=\"" + "*" + "\")" +
"(version 3.0; acl \"NE 56 bit key aci\";" +
"allow(all) (userdn=\"ldap:///self\" and ssf != \"56\");)";
private static final
String hiStrengthACI = "(targetattr=\"" + "*" + "\")" +
"(version 3.0; acl \"128 bit key aci\";" +
"allow(all) (userdn=\"ldap:///self\" and ssf = \"128\");)";
private static final
String hiPlusStrengthACI = "(targetattr=\"" + "*" + "\")" +
"(version 3.0; acl \"greater 128 bit aci\";" +
"allow(all) (userdn=\"ldap:///self\" and ssf > \"128\");)";
@BeforeClass
public void setupClass() throws Exception {
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.dsconfig(
"create-password-policy",
"--type", "password-policy",
"--policy-name", pwdPolicy,
"--set", "password-attribute:userPassword",
"--set", "default-password-storage-scheme: Clear"
);
TestCaseUtils.dsconfig(
"set-sasl-mechanism-handler-prop",
"--handler-name", "DIGEST-MD5",
"--set", "server-fqdn:localhost");
deleteAttrFromAdminEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
String aciLdif=makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN,
G_SCHEMA, G_DSE, G_USER_OPS, G_CONTROL, E_EXTEND_OP);
LDIFAdminModify(aciLdif, DIR_MGR_DN, PWD);
addEntries("o=test");
String newUserLDIF=makeAddEntryLDIF(newUser, newEntry);
LDIFAdd(newUserLDIF, DIR_MGR_DN, PWD, null, LDAPResultCode.SUCCESS);
String pwdILDIF =
makeAddLDIF("userpassword", newUser, "password");
LDIFModify(pwdILDIF, DIR_MGR_DN, PWD);
}
@AfterClass(alwaysRun = true)
public void tearDown() throws Exception {
TestCaseUtils.dsconfig(
"delete-password-policy",
"--policy-name", pwdPolicy
);
TestCaseUtils.dsconfig(
"set-sasl-mechanism-handler-prop",
"--handler-name", "DIGEST-MD5",
"--reset", "server-fqdn",
"--reset", "quality-of-protection");
}
//Valid ssf statements. Not the complete ACI.
@DataProvider(name = "validStatements")
public Object[][] valids() {
return new Object[][] {
{"1"},
{"40"},
{"56"},
{"128"},
{"256"},
{"129"},
};
}
//Invalid ssf statements. Not the complete ACI.
@DataProvider(name = "invalidStatements")
public Object[][] invalids() {
return new Object[][] {
{"-1"},
{"0"},
{"not valid"},
{"1025"},
{"10000"},
};
}
private EnumBindRuleType bindRuleType = EnumBindRuleType.EQUAL_BINDRULE_TYPE;
/**
* Test valid ssf statements.
*
* @param statement The ssf statement to attempt to decode.
* @throws AciException If an unexpected result happens.
*/
@Test(dataProvider = "validStatements")
public void testValidStatements(String statement) throws AciException {
SSF.decode(statement, bindRuleType);
}
/**
* Test invalid ssf statements.
*
* @param statement The ssf statement to attempt to decode.
* @throws Exception If an unexpected result happens.
*/
@Test(expectedExceptions= AciException.class,
dataProvider="invalidStatements")
public void testInvalidStatements(String statement) throws Exception {
try {
SSF.decode(statement, bindRuleType);
} catch (AciException e) {
throw e;
} catch (Exception e) {
System.out.println(
"Invalid ssf <" + statement +
"> threw wrong exception type.");
throw e;
}
throw new RuntimeException(
"Invalid ssf <" + statement +
"> did not throw an exception.");
}
/**
* Test ssf bind rule using ssf value for integrity.
*
* @throws Exception If a test doesn't pass.
*/
@Test
public void testIntegrity() throws Exception {
//set QOP to integrity.
TestCaseUtils.dsconfig(
"set-sasl-mechanism-handler-prop",
"--handler-name", "DIGEST-MD5",
"--set", "quality-of-protection:" + "integrity");
//Configure JNDI props.
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, factory);
int port = TestCaseUtils.getServerLdapPort();
String url = "ldap://localhost:" + Integer.valueOf(port);
env.put(Context.PROVIDER_URL, url);
env.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5");
String principal = "dn:" + newUser;
env.put(Context.SECURITY_PRINCIPAL, principal);
env.put(Context.SECURITY_CREDENTIALS, "password");
//Select integrity QOP.
env.put("javax.security.sasl.qop", "auth-int");
//Add ACI with ssf > 1, should fail.
String addACILDIF = makeAddLDIF("aci", newUser, greaterIntegrityACI);
LDIFModify(addACILDIF, DIR_MGR_DN, PWD);
JNDIModify(env, newUser, "description", descriptionStr,
LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS);
deleteAttrFromEntry(newUser, "aci");
//Add ACI with ssf = 1.
addACILDIF = makeAddLDIF("aci", newUser, integrityACI);
LDIFModify(addACILDIF, DIR_MGR_DN, PWD);
//Should succeed.
JNDIModify(env, newUser, "description", descriptionStr,
LDAPResultCode.SUCCESS);
deleteAttrFromEntry(newUser, "aci");
deleteAttrFromEntry(newUser, "description");
}
/**
* Test confidentiality settings using DIGEST-MD5.
* @throws Exception
*/
@Test
public void testConfidentiality() throws Exception {
//set QOP to integrity.
TestCaseUtils.dsconfig(
"set-sasl-mechanism-handler-prop",
"--handler-name", "DIGEST-MD5",
"--set", "quality-of-protection:" + "confidentiality");
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, factory);
int port = TestCaseUtils.getServerLdapPort();
String url = "ldap://localhost:" + Integer.valueOf(port);
env.put(Context.PROVIDER_URL, url);
env.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5");
String principal = "dn:" + newUser;
env.put(Context.SECURITY_PRINCIPAL, principal);
env.put(Context.SECURITY_CREDENTIALS, "password");
//Select integrity QOP.
env.put("javax.security.sasl.qop", "auth-conf");
//Add ACI with ssf > 1, should succeed.
String addACILDIF = makeAddLDIF("aci", newUser, greaterIntegrityACI);
LDIFModify(addACILDIF, DIR_MGR_DN, PWD);
JNDIModify(env, newUser, "description", descriptionStr,
LDAPResultCode.SUCCESS);
deleteAttrFromEntry(newUser, "aci");
deleteAttrFromEntry(newUser, "description");
//Test medium strength.
addACILDIF = makeAddLDIF("aci", newUser, medStrengthACI);
LDIFModify(addACILDIF, DIR_MGR_DN, PWD);
env.put("javax.security.sasl.strength", "medium");
JNDIModify(env, newUser, "description", descriptionStr,
LDAPResultCode.SUCCESS);
deleteAttrFromEntry(newUser, "aci");
deleteAttrFromEntry(newUser, "description");
//Test medium strength "!="
addACILDIF = makeAddLDIF("aci", newUser, medStrengthNEACI);
LDIFModify(addACILDIF, DIR_MGR_DN, PWD);
env.put("javax.security.sasl.strength", "medium");
JNDIModify(env, newUser, "description", descriptionStr,
LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS);
deleteAttrFromEntry(newUser, "aci");
deleteAttrFromEntry(newUser, "description");
//Test high strength.
// TODO: this hangs sometimes during the JNDIModify (see OPENDJ-256).
addACILDIF = makeAddLDIF("aci", newUser, hiStrengthACI);
LDIFModify(addACILDIF, DIR_MGR_DN, PWD);
env.put("javax.security.sasl.strength", "high");
JNDIModify(env, newUser, "description", descriptionStr,
LDAPResultCode.SUCCESS);
deleteAttrFromEntry(newUser, "aci");
deleteAttrFromEntry(newUser, "description");
//Fail DIGEST-MD5 only goes to 128.
addACILDIF = makeAddLDIF("aci", newUser, hiPlusStrengthACI);
LDIFModify(addACILDIF, DIR_MGR_DN, PWD);
env.put("javax.security.sasl.strength", "high");
JNDIModify(env, newUser, "description", descriptionStr,
LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS);
deleteAttrFromEntry(newUser, "aci");
deleteAttrFromEntry(newUser, "description");
}
}