diff --git a/ldap-connector/src/main/java/com/innoq/ldap/connector/LdapGroup.java b/ldap-connector/src/main/java/com/innoq/ldap/connector/LdapGroup.java index bf3b688..3743016 100644 --- a/ldap-connector/src/main/java/com/innoq/ldap/connector/LdapGroup.java +++ b/ldap-connector/src/main/java/com/innoq/ldap/connector/LdapGroup.java @@ -120,6 +120,9 @@ public int compareTo(LdapGroup t) { if (t == null) { return 1; } + if (getCn() == null && t.getCn() != null) { + return -1; + } return getCn().compareTo(t.getCn()); } diff --git a/ldap-connector/src/main/java/com/innoq/ldap/connector/LdapHelper.java b/ldap-connector/src/main/java/com/innoq/ldap/connector/LdapHelper.java index e054b11..85f1d2a 100644 --- a/ldap-connector/src/main/java/com/innoq/ldap/connector/LdapHelper.java +++ b/ldap-connector/src/main/java/com/innoq/ldap/connector/LdapHelper.java @@ -864,7 +864,11 @@ private ModificationItem[] buildModificationsForGroup(final LdapGroup newLdapGro } for (String key : oldLdapGroup.getKeys()) { - if (!groupMemberAttribut.equals(key) + if (LdapKeys.MODIFY_TIMESTAMP.equals(key) || + LdapKeys.MODIFIERS_NAME.equals(key) || + LdapKeys.ENTRY_UUID.equals(key)) { + Logger.warn(key+" should be readonly, but different!"); + } else if (!groupMemberAttribut.equals(key) && !LdapKeys.OBJECT_CLASS.equals(key) && newLdapGroup.get(key) == null) { attrs.put(key, newLdapGroup.get(key)); @@ -965,7 +969,11 @@ private ModificationItem[] buildModificationsForEntry(final LdapEntry newLdapEnt } } for (String key : oldLdapEntry.getKeys()) { - if (!LdapKeys.OBJECT_CLASS.equals(key) && newLdapEntry.get(key) == null) { + if (LdapKeys.MODIFY_TIMESTAMP.equals(key) || + LdapKeys.MODIFIERS_NAME.equals(key) || + LdapKeys.ENTRY_UUID.equals(key)) { + Logger.warn(key+" should be readonly, but different!"); + } else if (!LdapKeys.OBJECT_CLASS.equals(key) && newLdapEntry.get(key) == null) { attrs.put(key, newLdapEntry.get(key)); dels.add(key); } @@ -1001,7 +1009,11 @@ private ModificationItem[] buildModificationsForUser(final LdapUser newLdapUser, } } for (String key : oldLdapUser.getKeys()) { - if (!LdapKeys.OBJECT_CLASS.equals(key) && newLdapUser.get(key) == null) { + if (LdapKeys.MODIFY_TIMESTAMP.equals(key) || + LdapKeys.MODIFIERS_NAME.equals(key) || + LdapKeys.ENTRY_UUID.equals(key)) { + Logger.warn(key+" should be readonly, but different!"); + } else if (!LdapKeys.OBJECT_CLASS.equals(key) && newLdapUser.get(key) == null) { attrs.put(key, newLdapUser.get(key)); dels.add(key); } diff --git a/ldap-connector/src/main/java/com/innoq/ldap/connector/LdapUser.java b/ldap-connector/src/main/java/com/innoq/ldap/connector/LdapUser.java index 12a0b9d..c33b197 100644 --- a/ldap-connector/src/main/java/com/innoq/ldap/connector/LdapUser.java +++ b/ldap-connector/src/main/java/com/innoq/ldap/connector/LdapUser.java @@ -21,11 +21,16 @@ import java.util.Set; import java.util.TreeSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * LdapUser 04.12.2011 */ public class LdapUser extends LdapNode implements Comparable { + private final Logger Logger = LoggerFactory.getLogger(LdapUser.class); + /** * Users uid. */ @@ -65,8 +70,14 @@ public LdapUser(String uid, LdapHelper instance) { public Set getGroups() { if (this.groups == null) { this.groups = new TreeSet<>(); + LdapGroup g; for (Node n : LdapHelper.getInstance().getGroupsForUser(this)) { - this.groups.add((LdapGroup) n); + g = (LdapGroup) n; + if(g != null && g.getCn() != null) { + this.groups.add(g); + } else { + Logger.warn("Entry " + n.getDn() + " is not a valid Group!"); + } } } return this.groups; @@ -135,6 +146,9 @@ public int compareTo(LdapUser t) { if (t == null) { return 1; } + if (getUid() == null && t.getUid() != null) { + return -1; + } return getUid().compareTo(t.getUid()); } diff --git a/ldap-connector/src/main/resources/esapi/ESAPI.properties b/ldap-connector/src/main/resources/esapi/ESAPI.properties index c23c6af..f98cc5a 100644 --- a/ldap-connector/src/main/resources/esapi/ESAPI.properties +++ b/ldap-connector/src/main/resources/esapi/ESAPI.properties @@ -1,5 +1,5 @@ # -# OWASP Enterprise Security API (ESAPI) Properties file -- TEST Version +# OWASP Enterprise Security API (ESAPI) Properties file -- PRODUCTION Version # # This file is part of the Open Web Application Security Project (OWASP) # Enterprise Security API (ESAPI) project. For details, please see @@ -45,10 +45,10 @@ # # If true, then print all the ESAPI properties set here when they are loaded. # If false, they are not printed. Useful to reduce output when running JUnit tests. -# If you need to troubleshoot a properties related problem, turning this on may help, -# but we leave it off for running JUnit tests. (It will be 'true' in the one delivered -# as part of production ESAPI, mostly for backward compatibility.) -ESAPI.printProperties=false +# If you need to troubleshoot a properties related problem, turning this on may help. +# This is 'false' in the src/test/resources/.esapi version. It is 'true' by +# default for reasons of backward compatibility with earlier ESAPI versions. +ESAPI.printProperties=true # ESAPI is designed to be easily extensible. You can use the reference implementation # or implement your own providers to take advantage of your enterprise's security @@ -77,7 +77,6 @@ ESAPI.IntrusionDetector=org.owasp.esapi.reference.DefaultIntrusionDetector # Log4JFactory Requires log4j.xml or log4j.properties in classpath - http://www.laliluna.de/log4j-tutorial.html ESAPI.Logger=org.owasp.esapi.reference.Log4JLogFactory #ESAPI.Logger=org.owasp.esapi.reference.JavaLogFactory -#ESAPI.Logger=org.owasp.esapi.reference.ExampleExtendedLog4JLogFactory ESAPI.Randomizer=org.owasp.esapi.reference.DefaultRandomizer ESAPI.Validator=org.owasp.esapi.reference.DefaultValidator @@ -108,7 +107,7 @@ Authenticator.AbsoluteTimeoutDuration=120 # multiple encoding is strongly discouraged. Encoder.AllowMultipleEncoding=false -# Mixed encoding is when multiple different encoding formats are applied, or when +# Mixed encoding is when multiple different encoding formats are applied, or when # multiple formats are nested. Allowing multiple encoding is strongly discouraged. Encoder.AllowMixedEncoding=false @@ -146,21 +145,12 @@ Encoder.DefaultCodecList=HTMLEntityCodec,PercentCodec,JavaScriptCodec # where you can specify a SecretKey. (Note that if you are using the 256-bit AES, # that requires downloading the special jurisdiction policy files mentioned above.) # -# ***** IMPORTANT: These are for JUnit testing. Test files may have been -# encrypted using these values so do not change these or -# those tests will fail. The version under -# src/main/resources/.esapi/ESAPI.properties -# will be delivered with Encryptor.MasterKey and -# Encryptor.MasterSalt set to the empty string. -# -# FINAL NOTE: -# If Maven changes these when run, that needs to be fixed. -# 256-bit key... requires unlimited strength jurisdiction policy files -### Encryptor.MasterKey=pJhlri8JbuFYDgkqtHmm9s0Ziug2PE7ovZDyEPm4j14= -# 128-bit key -Encryptor.MasterKey=a6H9is3hEVGKB4Jut+lOVA== -Encryptor.MasterSalt=SbftnvmEWD5ZHHP+pX3fqugNysc= -# Encryptor.MasterSalt= +# ***** IMPORTANT: Do NOT forget to replace these with your own values! ***** +# To calculate these values, you can run: +# java -classpath esapi.jar org.owasp.esapi.reference.crypto.JavaEncryptor +# +#Encryptor.MasterKey= +#Encryptor.MasterSalt= # Provides the default JCE provider that ESAPI will "prefer" for its symmetric # encryption and hashing. (That is it will look to this provider first, but it @@ -232,15 +222,8 @@ Encryptor.cipher_modes.combined_modes=GCM,CCM,IAPM,EAX,OCB,CWC # Note: We will add support for streaming modes like CFB & OFB once # we add support for 'specified' to the property 'Encryptor.ChooseIVMethod' # (probably in ESAPI 2.1). -# -# IMPORTANT NOTE: In the official ESAPI.properties we do *NOT* include ECB -# here as this is an extremely weak mode. However, we *must* -# allow it here so we can test ECB mode. That is important -# since the logic is somewhat different (i.e., ECB mode does -# not use an IV). # DISCUSS: Better name? -# NOTE: ECB added only for testing purposes. Don't try this at home! -Encryptor.cipher_modes.additional_allowed=CBC,ECB +Encryptor.cipher_modes.additional_allowed=CBC # 128-bit is almost always sufficient and appears to be more resistant to # related key attacks than is 256-bit AES. Use '_' to use default key size @@ -268,7 +251,7 @@ Encryptor.ChooseIVMethod=random # If you choose to use a fixed IV, then you must place a fixed IV here that # is known to all others who are sharing your secret key. The format should # be a hex string that is the same length as the cipher block size for the -# cipher algorithm that you are using. The following is an example for AES +# cipher algorithm that you are using. The following is an *example* for AES # from an AES test vector for AES-128/CBC as described in: # NIST Special Publication 800-38A (2001 Edition) # "Recommendation for Block Cipher Modes of Operation". @@ -307,13 +290,19 @@ Encryptor.DigitalSignatureAlgorithm=SHA1withDSA Encryptor.DigitalSignatureKeyLength=1024 Encryptor.RandomAlgorithm=SHA1PRNG Encryptor.CharacterEncoding=UTF-8 + +# This is the Pseudo Random Function (PRF) that ESAPI's Key Derivation Function +# (KDF) normally uses. Note this is *only* the PRF used for ESAPI's KDF and +# *not* what is used for ESAPI's MAC. (Currently, HmacSHA1 is always used for +# the MAC, mostly to keep the overall size at a minimum.) +# # Currently supported choices for JDK 1.5 and 1.6 are: # HmacSHA1 (160 bits), HmacSHA256 (256 bits), HmacSHA384 (384 bits), and # HmacSHA512 (512 bits). # Note that HmacMD5 is *not* supported for the PRF used by the KDF even though -# these JDKs support it. +# the JDKs support it. See the ESAPI 2.0 Symmetric Encryption User Guide +# further details. Encryptor.KDF.PRF=HmacSHA256 - #=========================================================================== # ESAPI HttpUtilties # @@ -324,8 +313,7 @@ Encryptor.KDF.PRF=HmacSHA256 # # Default file upload location (remember to escape backslashes with \\) HttpUtilities.UploadDir=C:\\ESAPI\\testUpload -# let this default to java.io.tmpdir for testing -#HttpUtilities.UploadTempDir=C:\\temp +HttpUtilities.UploadTempDir=C:\\temp # Force flags on cookies, if you use HttpUtilities to set cookies HttpUtilities.ForceHttpOnlySession=false HttpUtilities.ForceSecureSession=false @@ -348,9 +336,16 @@ HttpUtilities.HttpSessionIdName=JSESSIONID #=========================================================================== # ESAPI Executor -# CHECKME - Not sure what this is used for, but surely it should be made OS independent. -Executor.WorkingDirectory=C:\\Windows\\Temp -Executor.ApprovedExecutables=C:\\Windows\\System32\\cmd.exe,C:\\Windows\\System32\\runas.exe +# CHECKME - This should be made OS independent. Don't use unsafe defaults. +# # Examples only -- do NOT blindly copy! +# For Windows: +# Executor.WorkingDirectory=C:\\Windows\\Temp +# Executor.ApprovedExecutables=C:\\Windows\\System32\\cmd.exe,C:\\Windows\\System32\\runas.exe +# For *nux, MacOS: +# Executor.WorkingDirectory=/tmp +# Executor.ApprovedExecutables=/bin/bash +Executor.WorkingDirectory= +Executor.ApprovedExecutables= #=========================================================================== @@ -437,31 +432,30 @@ Validator.ConfigurationFile=validation.properties Validator.AccountName=^[a-zA-Z0-9]{3,20}$ Validator.SystemCommand=^[a-zA-Z\\-\\/]{1,64}$ Validator.RoleName=^[a-z]{1,20}$ + +#the word TEST below should be changed to your application +#name - only relative URL's are supported Validator.Redirect=^\\/test.*$ # Global HTTP Validation Rules # Values with Base64 encoded data (e.g. encrypted state) will need at least [a-zA-Z0-9\/+=] Validator.HTTPScheme=^(http|https)$ Validator.HTTPServerName=^[a-zA-Z0-9_.\\-]*$ +Validator.HTTPParameterName=^[a-zA-Z0-9_]{1,32}$ +Validator.HTTPParameterValue=^[a-zA-Z0-9.\\-\\/+=@_ ]*$ Validator.HTTPCookieName=^[a-zA-Z0-9\\-_]{1,32}$ Validator.HTTPCookieValue=^[a-zA-Z0-9\\-\\/+=_ ]*$ # Note that max header name capped at 150 in SecurityRequestWrapper! Validator.HTTPHeaderName=^[a-zA-Z0-9\\-_]{1,50}$ Validator.HTTPHeaderValue=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$ +Validator.HTTPContextPath=^\\/?[a-zA-Z0-9.\\-\\/_]*$ Validator.HTTPServletPath=^[a-zA-Z0-9.\\-\\/_]*$ Validator.HTTPPath=^[a-zA-Z0-9.\\-_]*$ +Validator.HTTPQueryString=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ %]*$ +Validator.HTTPURI=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$ Validator.HTTPURL=^.*$ Validator.HTTPJSESSIONID=^[A-Z0-9]{10,30}$ -# Contributed by Fraenku@gmx.ch -# Googlecode Issue 116 (http://code.google.com/p/owasp-esapi-java/issues/detail?id=116) -Validator.HTTPParameterName=^[a-zA-Z0-9_\\-]{1,32}$ -Validator.HTTPParameterValue=^[\\p{L}\\p{N}.\\-/+=_ !$*?@]{0,1000}$ -Validator.HTTPContextPath=^/[a-zA-Z0-9.\\-_]*$ -Validator.HTTPQueryString=^([a-zA-Z0-9_\\-]{1,32}=[\\p{L}\\p{N}.\\-/+=_ !$*?@%]*&?)*$ -Validator.HTTPURI=^/([a-zA-Z0-9.\\-_]*/?)*$ - - # Validation of file related input Validator.FileName=^[a-zA-Z0-9!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$ Validator.DirectoryName=^[a-zA-Z0-9:/\\\\!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$ @@ -469,4 +463,3 @@ Validator.DirectoryName=^[a-zA-Z0-9:/\\\\!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$ # Validation of dates. Controls whether or not 'lenient' dates are accepted. # See DataFormat.setLenient(boolean flag) for further details. Validator.AcceptLenientDates=false - diff --git a/ldap-connector/src/main/resources/esapi/validation.properties b/ldap-connector/src/main/resources/esapi/validation.properties new file mode 100644 index 0000000..433fa0b --- /dev/null +++ b/ldap-connector/src/main/resources/esapi/validation.properties @@ -0,0 +1,29 @@ +# The ESAPI validator does many security checks on input, such as canonicalization +# and whitelist validation. Note that all of these validation rules are applied *after* +# canonicalization. Double-encoded characters (even with different encodings involved, +# are never allowed. +# +# To use: +# +# First set up a pattern below. You can choose any name you want, prefixed by the word +# "Validation." For example: +# Validation.Email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$ +# +# Then you can validate in your code against the pattern like this: +# ESAPI.validator().isValidInput("User Email", input, "Email", maxLength, allowNull); +# Where maxLength and allowNull are set for you needs, respectively. +# +# But note, when you use boolean variants of validation functions, you lose critical +# canonicalization. It is preferable to use the "get" methods (which throw exceptions) and +# and use the returned user input which is in canonical form. Consider the following: +# +# try { +# someObject.setEmail(ESAPI.validator().getValidInput("User Email", input, "Email", maxLength, allowNull)); +# +Validator.SafeString=^[.\\p{Alnum}\\p{Space}]{0,1024}$ +Validator.Email=^[A-Za-z0-9._%'-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$ +Validator.IPAddress=^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ +Validator.URL=^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\:\\'\\/\\\\\\+=&%\\$#_]*)?$ +Validator.CreditCard=^(\\d{4}[- ]?){3}\\d{4}$ +Validator.SSN=^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$ + diff --git a/ldap-connector/src/test/java/com/innoq/ldap/connector/TestGroup.java b/ldap-connector/src/test/java/com/innoq/ldap/connector/TestGroup.java index 9df3ba4..7e7ffd0 100644 --- a/ldap-connector/src/test/java/com/innoq/ldap/connector/TestGroup.java +++ b/ldap-connector/src/test/java/com/innoq/ldap/connector/TestGroup.java @@ -35,7 +35,7 @@ public class TestGroup { private static LdapHelper HELPER; private static final Logger LOG = Logger.getLogger(TestUser.class.getName()); - private static String CN; + private static String CN1, CN2; private static LdapUser testUser1, testUser2; public TestGroup() { @@ -44,7 +44,8 @@ public TestGroup() { @BeforeClass public static void setUpClass() throws Exception { HELPER = Utils.getHelper(); - CN = "G1_" + System.currentTimeMillis(); + CN1 = "G1_" + System.currentTimeMillis(); + CN2 = "G2_" + System.currentTimeMillis(); testUser1 = HELPER.getUserTemplate("U1_" + System.currentTimeMillis()); testUser1.set("cn", testUser1.getUid()); HELPER.setUser(testUser1); @@ -75,23 +76,23 @@ public void testGroupLoad() { @Test public void testCreateGroup() throws Exception { - Node n1 = HELPER.getGroup(CN); + Node n1 = HELPER.getGroup(CN1); assertTrue(n1.isEmpty()); LdapGroup g1 = Utils.getTestGroup("test"); - g1 = Utils.updatedGroup(g1, CN); + g1 = Utils.updatedGroup(g1, CN1); if (HELPER.setGroup(g1)) { - LOG.log(Level.INFO, "created Group {0}", CN); + LOG.log(Level.INFO, "created Group {0}", CN1); } - n1 = HELPER.getGroup(CN); + n1 = HELPER.getGroup(CN1); assertFalse(n1.isEmpty()); Utils.removeTestGroup(g1); } @Test public void testCreateGroupWithMetadata() throws Exception { - LdapGroup g1 = Utils.createTestGroup(CN); + LdapGroup g1 = Utils.createTestGroup(CN1); String[] parts; - g1 = (LdapGroup) HELPER.getGroup(CN); + g1 = (LdapGroup) HELPER.getGroup(CN1); assertNotNull(g1.getModifiersName()); parts = g1.getModifiersName().split("="); assertTrue(parts.length > 0); @@ -103,41 +104,50 @@ public void testCreateGroupWithMetadata() throws Exception { Utils.removeTestGroup(g1); } + @Test + public void testCompareGroups() throws Exception { + LdapGroup g1 = Utils.createTestGroup(CN1); + LdapGroup g2 = Utils.createTestGroup(CN2); + assertTrue(g1.compareTo(g2) != 0); + Utils.removeTestGroup(g1); + Utils.removeTestGroup(g2); + } + @Test public void testAddUserToGroup() throws Exception { - LdapGroup g1 = Utils.createTestGroup(CN); + LdapGroup g1 = Utils.createTestGroup(CN1); g1.addUser(testUser1); if (HELPER.setGroup(g1)) { - LOG.log(Level.INFO, "updated Group {0}", CN); + LOG.log(Level.INFO, "updated Group {0}", CN1); } - g1 = (LdapGroup) HELPER.getGroup(CN); + g1 = (LdapGroup) HELPER.getGroup(CN1); g1.debug(); Utils.removeTestGroup(g1); } @Test public void testRemoveUserFromGroup() throws Exception { - LdapGroup g1 = Utils.createTestGroup(CN); + LdapGroup g1 = Utils.createTestGroup(CN1); String[] usernames = {"U2_" + System.currentTimeMillis(), "U3_" + System.currentTimeMillis()}; if (HELPER.setGroup(g1)) { - LOG.log(Level.INFO, "updated Group {0}", CN); + LOG.log(Level.INFO, "updated Group {0}", CN1); } List users = Utils.createTestUsers(usernames); for (LdapUser user : users) { g1.addUser(user); } HELPER.setGroup(g1); - g1 = (LdapGroup) HELPER.getGroup(CN); + g1 = (LdapGroup) HELPER.getGroup(CN1); int count; count = g1.getUsers().size(); - LOG.log(Level.INFO, "getUsers() count Group {0} is {1}", new Object[]{CN, count}); + LOG.log(Level.INFO, "getUsers() count Group {0} is {1}", new Object[]{CN1, count}); g1.debug(); assertTrue(count > 1); g1.rmUser(users.get(0)); HELPER.setGroup(g1); - g1 = (LdapGroup) HELPER.getGroup(CN); - LOG.log(Level.INFO, "user count Group {0} is {1}", new Object[]{CN, g1.getUsers().size()}); + g1 = (LdapGroup) HELPER.getGroup(CN1); + LOG.log(Level.INFO, "user count Group {0} is {1}", new Object[]{CN1, g1.getUsers().size()}); g1.debug(); assertTrue(g1.getUsers().size() == (count - 1)); Utils.removeTestGroup(g1); @@ -146,20 +156,20 @@ public void testRemoveUserFromGroup() throws Exception { @Test public void testRemoveUserFromGroupNotAllowed() throws Exception { - LdapGroup g1 = Utils.createTestGroup(CN); + LdapGroup g1 = Utils.createTestGroup(CN1); assertTrue(g1.getUsers().size() == 1); Node principal = HELPER.getPrincipal(); LdapUser principalUser = (LdapUser) principal; g1.rmUser(principalUser); HELPER.setGroup(g1); - LdapGroup g2 = Utils.createTestGroup(CN); + LdapGroup g2 = Utils.createTestGroup(CN1); assertTrue(g2.getUsers().size() == 1); Utils.removeTestGroup(g1); } @Test public void testLoadPrincipalUserFromGroup() throws Exception { - LdapGroup g1 = Utils.createTestGroup(CN); + LdapGroup g1 = Utils.createTestGroup(CN1); assertTrue(g1.getUsers().size() == 1); Node principal = HELPER.getPrincipal(); LdapUser principalUser = (LdapUser) principal; @@ -176,16 +186,16 @@ public void testAddUsersToGroup() throws Exception { testUser2 = HELPER.getUserTemplate("U4_" + System.currentTimeMillis()); testUser2.set("cn", testUser2.getUid()); HELPER.setUser(testUser2); - LdapGroup g1 = Utils.createTestGroup(CN); + LdapGroup g1 = Utils.createTestGroup(CN1); g1.addUser(testUser1); g1.addUser(testUser2); HELPER.setGroup(g1); - g1 = (LdapGroup) HELPER.getGroup(CN); - LOG.log(Level.INFO, "user count Group {0} is {1}", new Object[]{CN, g1.getUsers().size()}); + g1 = (LdapGroup) HELPER.getGroup(CN1); + LOG.log(Level.INFO, "user count Group {0} is {1}", new Object[]{CN1, g1.getUsers().size()}); assertTrue(g1.getUsers().size() > 2); Set members = HELPER.getUsersForGroup(g1); - LOG.log(Level.INFO, "getUsersForGroup() count Group {0} is {1}", new Object[]{CN, members.size()}); + LOG.log(Level.INFO, "getUsersForGroup() count Group {0} is {1}", new Object[]{CN1, members.size()}); g1.debug(); assertTrue(members.size() > 2); @@ -194,12 +204,12 @@ public void testAddUsersToGroup() throws Exception { @Test public void testUpdateGroup() throws Exception { - LdapGroup g1 =Utils.createTestGroup(CN); + LdapGroup g1 =Utils.createTestGroup(CN1); assertNull(g1.get("description")); - g1.set("description", "Group " + CN); + g1.set("description", "Group " + CN1); HELPER.setGroup(g1); - g1 = (LdapGroup) HELPER.getGroup(CN); - assertEquals(g1.get("description"), "Group " + CN); + g1 = (LdapGroup) HELPER.getGroup(CN1); + assertEquals(g1.get("description"), "Group " + CN1); Utils.removeTestGroup(g1); } @@ -208,10 +218,10 @@ public void testUpdateExistingGroup() throws Exception { LdapGroup g1 = (LdapGroup) HELPER.getGroup("users"); LOG.log(Level.INFO, "Group users description: {0}", g1.get("description")); String description = g1.get("description"); - g1.set("description", description + CN); + g1.set("description", description + CN1); HELPER.setGroup(g1); g1 = (LdapGroup) HELPER.getGroup("users"); - assertEquals(g1.get("description"), description + CN); + assertEquals(g1.get("description"), description + CN1); g1.set("description", description); HELPER.setGroup(g1); g1 = (LdapGroup) HELPER.getGroup("users"); @@ -220,9 +230,9 @@ public void testUpdateExistingGroup() throws Exception { @Test public void testUpdateEmptyGroup() throws Exception { - LdapGroup g1 = Utils.createTestGroup(CN); + LdapGroup g1 = Utils.createTestGroup(CN1); int count = g1.getUsers().size(); - LOG.log(Level.INFO, "user count Group {0} is {1}", new Object[]{CN, count}); + LOG.log(Level.INFO, "user count Group {0} is {1}", new Object[]{CN1, count}); g1.debug(); List users = new ArrayList(); for (LdapUser user : g1.getUsers()) { @@ -232,9 +242,9 @@ public void testUpdateEmptyGroup() throws Exception { g1.rmUser(user); } HELPER.setGroup(g1); - g1 = (LdapGroup) HELPER.getGroup(CN); + g1 = (LdapGroup) HELPER.getGroup(CN1); count = g1.getUsers().size(); - LOG.log(Level.INFO, "user count Group {0} is {1}", new Object[]{CN, count}); + LOG.log(Level.INFO, "user count Group {0} is {1}", new Object[]{CN1, count}); g1.debug(); assertTrue(g1.getUsers().size() == 1); Utils.removeTestGroup(g1); @@ -242,15 +252,15 @@ public void testUpdateEmptyGroup() throws Exception { @Test public void testDeleteGroup() throws Exception { - LdapGroup g1 = Utils.createTestGroup(CN); + LdapGroup g1 = Utils.createTestGroup(CN1); try { if (HELPER.rmGroup(g1)) { - LOG.log(Level.INFO, "deleted Group {0}", CN); + LOG.log(Level.INFO, "deleted Group {0}", CN1); } } catch (Exception ex) { LOG.log(Level.SEVERE, "setGroup fails", ex); } - g1 = (LdapGroup) HELPER.getGroup(CN); + g1 = (LdapGroup) HELPER.getGroup(CN1); assertTrue(g1.isEmpty()); } } diff --git a/ldap-connector/src/test/java/com/innoq/ldap/connector/TestUser.java b/ldap-connector/src/test/java/com/innoq/ldap/connector/TestUser.java index 944c927..9b950e9 100644 --- a/ldap-connector/src/test/java/com/innoq/ldap/connector/TestUser.java +++ b/ldap-connector/src/test/java/com/innoq/ldap/connector/TestUser.java @@ -31,34 +31,33 @@ public class TestUser { private static LdapHelper HELPER; private static final Logger LOGGER = Logger.getLogger(TestUser.class.getName()); - private static String UID; - private static String PW; + private static String UID1, UID2; public TestUser() { HELPER = Utils.getHelper(); - UID = "UX_" + System.currentTimeMillis(); - PW = UID.substring(0, 5) + UID.substring(5); - LOGGER.log(Level.INFO, "UID: {0}", UID); + UID1 = "U1_" + System.currentTimeMillis(); + UID2 = "U2_" + System.currentTimeMillis(); + LOGGER.log(Level.INFO, "UID: {0}", UID1); } @Test public void testCreateUser() throws Exception { - Node u1 = HELPER.getUser(UID); + Node u1 = HELPER.getUser(UID1); assertTrue(u1.isEmpty()); - LdapUser t1 = Utils.getTestUser(UID); - t1.setPassword(UID); - t1 = Utils.updatedUser(t1, UID); - assertTrue("testCreateUser " + UID + " for login failed", HELPER.setUser(t1)); - u1 = HELPER.getUser(UID); + LdapUser t1 = Utils.getTestUser(UID1); + t1.setPassword(UID1); + t1 = Utils.updatedUser(t1, UID1); + assertTrue("testCreateUser " + UID1 + " for login failed", HELPER.setUser(t1)); + u1 = HELPER.getUser(UID1); assertFalse(u1.isEmpty()); Utils.removeTestUser(t1); } @Test public void testCreateUserWithMetadata() throws Exception { - LdapUser u1 = Utils.createTestUser(UID); + LdapUser u1 = Utils.createTestUser(UID1); String[] parts; - u1 = (LdapUser) HELPER.getUser(UID); + u1 = (LdapUser) HELPER.getUser(UID1); assertNotNull(u1.getModifiersName()); parts = u1.getModifiersName().split("="); assertTrue(parts.length > 0); @@ -69,15 +68,24 @@ public void testCreateUserWithMetadata() throws Exception { assertTrue(u1.getModifyTimestamp().contains("Z")); Utils.removeTestUser(u1); } + + @Test + public void testCompareUsers() throws Exception { + LdapUser u1 = Utils.createTestUser(UID1); + LdapUser u2 = Utils.createTestUser(UID2); + assertTrue(u1.compareTo(u2) != 0); + Utils.removeTestUser(u1); + Utils.removeTestUser(u2); + } @Test public void testLoginWithNull() throws Exception { boolean login; - LdapUser t1 = Utils.createTestUser(UID); - login = HELPER.checkCredentials(UID, null); - assertFalse("testValidLogin: should be false for " + UID + ":null", login); - login = HELPER.checkCredentials(null, UID); - assertFalse("testValidLogin: should be false for null:" + UID, login); + LdapUser t1 = Utils.createTestUser(UID1); + login = HELPER.checkCredentials(UID1, null); + assertFalse("testValidLogin: should be false for " + UID1 + ":null", login); + login = HELPER.checkCredentials(null, UID1); + assertFalse("testValidLogin: should be false for null:" + UID1, login); login = HELPER.checkCredentials(null, null); assertFalse("testValidLogin: should be false for null:null", login); Utils.removeTestUser(t1); @@ -85,24 +93,24 @@ public void testLoginWithNull() throws Exception { @Test public void testValidLogin() throws Exception { - LdapUser t1 = Utils.createTestUser(UID); - t1.setPassword(UID); - assertTrue("testValidLogin " + UID + " for login failed", HELPER.setUser(t1)); - boolean login = HELPER.checkCredentials(UID, UID); - assertTrue("testValidLogin: should be true for " + UID, login); + LdapUser t1 = Utils.createTestUser(UID1); + t1.setPassword(UID1); + assertTrue("testValidLogin " + UID1 + " for login failed", HELPER.setUser(t1)); + boolean login = HELPER.checkCredentials(UID1, UID1); + assertTrue("testValidLogin: should be true for " + UID1, login); assertTrue(Utils.removeTestUser(t1)); } @Test public void testInvalidLogin() { - boolean login = HELPER.checkCredentials(UID, "test"); - assertFalse("testInvalidLogin: should be false " + UID, login); + boolean login = HELPER.checkCredentials(UID1, "test"); + assertFalse("testInvalidLogin: should be false " + UID1, login); } @Test public void testUserLoad() throws Exception { - LdapUser testUser = Utils.createTestUser(UID); - LdapUser ldapUser = (LdapUser) HELPER.getUser(UID); + LdapUser testUser = Utils.createTestUser(UID1); + LdapUser ldapUser = (LdapUser) HELPER.getUser(UID1); LOGGER.log(Level.INFO, "testUser: {0}", testUser); LOGGER.log(Level.INFO, "ldapUser: {0}", ldapUser); assertFalse("User should be not new!", ldapUser.isNew()); @@ -112,11 +120,11 @@ public void testUserLoad() throws Exception { @Test public void testAlterUser() throws Exception { - LdapUser user1 = Utils.createTestUser(UID); + LdapUser user1 = Utils.createTestUser(UID1); user1.set("description", "altered Test User"); user1.set("sn", "Test User"); - assertTrue("testAlterUser " + UID + " fails", HELPER.setUser(user1)); - LdapUser user2 = (LdapUser) HELPER.getUser(UID); + assertTrue("testAlterUser " + UID1 + " fails", HELPER.setUser(user1)); + LdapUser user2 = (LdapUser) HELPER.getUser(UID1); assertTrue("should be \n 'altered Test User' but was \n " + user2.get("description"), "altered Test User".equals(user2.get("description"))); assertTrue("should be \n 'Test User' but was \n " + user2.get("sn"), "Test User".equals(user2.get("sn"))); @@ -125,10 +133,10 @@ public void testAlterUser() throws Exception { @Test public void testAlterPassword() throws Exception { - LdapUser user1 = Utils.createTestUser(UID); + LdapUser user1 = Utils.createTestUser(UID1); user1.setPassword("test2"); - assertTrue("testAlterPassword " + UID + " fails", HELPER.setUser(user1)); - boolean login = HELPER.checkCredentials(UID, "test2"); + assertTrue("testAlterPassword " + UID1 + " fails", HELPER.setUser(user1)); + boolean login = HELPER.checkCredentials(UID1, "test2"); assertTrue("should be true", login); assertTrue(Utils.removeTestUser(user1)); } @@ -139,28 +147,28 @@ public void testAlterPasswordAsUser() throws Exception { String pass1, pass2; pass1 = "test2"; pass2 = "test3"; - LdapUser user1 = Utils.createTestUser(UID); + LdapUser user1 = Utils.createTestUser(UID1); user1.setPassword(pass1); - assertTrue("testAlterPasswordAsUser=>setUser " + UID + " fails", HELPER.setUser(user1)); - login = HELPER.checkCredentials(UID, pass1); + assertTrue("testAlterPasswordAsUser=>setUser " + UID1 + " fails", HELPER.setUser(user1)); + login = HELPER.checkCredentials(UID1, pass1); assertTrue("should be true", login); user1.setPassword(pass2); - assertTrue("testAlterPasswordAsUser=>setUserAsUser " + UID + " fails", HELPER.setUserAsUser(user1, UID, pass1)); - login = HELPER.checkCredentials(UID, pass2); + assertTrue("testAlterPasswordAsUser=>setUserAsUser " + UID1 + " fails", HELPER.setUserAsUser(user1, UID1, pass1)); + login = HELPER.checkCredentials(UID1, pass2); assertTrue("should be true", login); assertTrue(Utils.removeTestUser(user1)); } @Test public void testAvatar() throws Exception { - LdapUser user1 = Utils.createTestUser(UID); - user1 = (LdapUser) HELPER.getUser(UID); + LdapUser user1 = Utils.createTestUser(UID1); + user1 = (LdapUser) HELPER.getUser(UID1); assertNull(user1.getAvatar()); String dummyPath = Utils.generatePath("src", "test", "resources")+"dummy.png"; File avatar1 = Utils.getFile(dummyPath); user1.setAvatar(avatar1); HELPER.setUser(user1); - user1 = (LdapUser) HELPER.getUser(UID); + user1 = (LdapUser) HELPER.getUser(UID1); File avatar2 = user1.getAvatar(); assertEquals(avatar1.length(), avatar2.length()); assertTrue(Utils.compareFiles(avatar1, avatar2)); @@ -169,21 +177,21 @@ public void testAvatar() throws Exception { @Test public void testUpdateUser() throws Exception { - LdapUser u1 = Utils.createTestUser(UID); + LdapUser u1 = Utils.createTestUser(UID1); assertNull(u1.get("o")); - u1.set("description", "Company for " + UID); + u1.set("description", "Company for " + UID1); HELPER.setUser(u1); - u1 = (LdapUser) HELPER.getUser(UID); - assertEquals(u1.get("description"), "Company for " + UID); + u1 = (LdapUser) HELPER.getUser(UID1); + assertEquals(u1.get("description"), "Company for " + UID1); assertTrue(Utils.removeTestUser(u1)); } @Test public void testDeleteUser() throws Exception { - LdapUser u1 = Utils.createTestUser(UID); + LdapUser u1 = Utils.createTestUser(UID1); assertFalse(u1.isEmpty()); - assertTrue("deleted User " + UID + " failed!", HELPER.rmUser(u1)); - u1 = (LdapUser) HELPER.getUser(UID); + assertTrue("deleted User " + UID1 + " failed!", HELPER.rmUser(u1)); + u1 = (LdapUser) HELPER.getUser(UID1); assertTrue(u1.isEmpty()); Utils.removeTestUser(u1); } @@ -201,8 +209,8 @@ public void testPrincipalDN() { @Test public void testUserDN() throws Exception { - LdapUser testUser = Utils.createTestUser(UID); - LdapUser ldapUser = (LdapUser) HELPER.getUser(UID); + LdapUser testUser = Utils.createTestUser(UID1); + LdapUser ldapUser = (LdapUser) HELPER.getUser(UID1); assertEquals(testUser.getDn(), ldapUser.getDn()); LOGGER.log(Level.INFO, "User getDN(): User matches: {0} == {1}", new String[]{testUser.getDn(), ldapUser.getDn()}); assertEquals(testUser.get("dn"), ldapUser.get("dn")); diff --git a/ldap-connector/src/test/resources/esapi/ESAPI.properties b/ldap-connector/src/test/resources/esapi/ESAPI.properties index c23c6af..2727d4a 100644 --- a/ldap-connector/src/test/resources/esapi/ESAPI.properties +++ b/ldap-connector/src/test/resources/esapi/ESAPI.properties @@ -469,4 +469,3 @@ Validator.DirectoryName=^[a-zA-Z0-9:/\\\\!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$ # Validation of dates. Controls whether or not 'lenient' dates are accepted. # See DataFormat.setLenient(boolean flag) for further details. Validator.AcceptLenientDates=false - diff --git a/ldap-connector/src/test/resources/esapi/validation.properties b/ldap-connector/src/test/resources/esapi/validation.properties new file mode 100644 index 0000000..433fa0b --- /dev/null +++ b/ldap-connector/src/test/resources/esapi/validation.properties @@ -0,0 +1,29 @@ +# The ESAPI validator does many security checks on input, such as canonicalization +# and whitelist validation. Note that all of these validation rules are applied *after* +# canonicalization. Double-encoded characters (even with different encodings involved, +# are never allowed. +# +# To use: +# +# First set up a pattern below. You can choose any name you want, prefixed by the word +# "Validation." For example: +# Validation.Email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$ +# +# Then you can validate in your code against the pattern like this: +# ESAPI.validator().isValidInput("User Email", input, "Email", maxLength, allowNull); +# Where maxLength and allowNull are set for you needs, respectively. +# +# But note, when you use boolean variants of validation functions, you lose critical +# canonicalization. It is preferable to use the "get" methods (which throw exceptions) and +# and use the returned user input which is in canonical form. Consider the following: +# +# try { +# someObject.setEmail(ESAPI.validator().getValidInput("User Email", input, "Email", maxLength, allowNull)); +# +Validator.SafeString=^[.\\p{Alnum}\\p{Space}]{0,1024}$ +Validator.Email=^[A-Za-z0-9._%'-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$ +Validator.IPAddress=^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ +Validator.URL=^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\:\\'\\/\\\\\\+=&%\\$#_]*)?$ +Validator.CreditCard=^(\\d{4}[- ]?){3}\\d{4}$ +Validator.SSN=^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$ +