| <?xml version="1.0" encoding="UTF-8"?> |
| <pmd-cpd> |
| <duplication lines="27" tokens="165"> |
| <file line="291" path="/Users/briandemers/dev/source/shiro-1.2.x/core/src/main/java/org/apache/shiro/realm/ldap/DefaultLdapContextFactory.java"/> |
| <file line="523" path="/Users/briandemers/dev/source/shiro-1.2.x/core/src/main/java/org/apache/shiro/realm/ldap/JndiLdapContextFactory.java"/> |
| <codefragment> |
| <![CDATA[ |
| protected void validateAuthenticationInfo(Hashtable<String, Object> environment) |
| throws AuthenticationException |
| { |
| // validate when using Simple auth both principal and credentials are set |
| if(SIMPLE_AUTHENTICATION_MECHANISM_NAME.equals(environment.get(Context.SECURITY_AUTHENTICATION))) { |
| |
| // only validate credentials if we have a non-empty principal |
| if( environment.get(Context.SECURITY_PRINCIPAL) != null && |
| StringUtils.hasText( String.valueOf( environment.get(Context.SECURITY_PRINCIPAL) ))) { |
| |
| Object credentials = environment.get(Context.SECURITY_CREDENTIALS); |
| |
| // from the FAQ, we need to check for empty credentials: |
| // http://docs.oracle.com/javase/tutorial/jndi/ldap/faq.html |
| if( credentials == null || |
| (credentials instanceof byte[] && ((byte[])credentials).length <= 0) || // empty byte[] |
| (credentials instanceof char[] && ((char[])credentials).length <= 0) || // empty char[] |
| (String.class.isInstance(credentials) && !StringUtils.hasText(String.valueOf(credentials)))) { |
| |
| throw new javax.naming.AuthenticationException("LDAP Simple authentication requires both a " |
| + "principal and credentials."); |
| } |
| } |
| } |
| } |
| |
| } |
| ]]> |
| </codefragment> |
| </duplication> |
| <duplication lines="71" tokens="155"> |
| <file line="225" path="/Users/briandemers/dev/source/shiro-1.2.x/core/src/main/java/org/apache/shiro/crypto/hash/AbstractHash.java"/> |
| <file line="360" path="/Users/briandemers/dev/source/shiro-1.2.x/core/src/main/java/org/apache/shiro/crypto/hash/SimpleHash.java"/> |
| <codefragment> |
| <![CDATA[ |
| } |
| |
| /** |
| * Returns a hex-encoded string of the underlying {@link #getBytes byte array}. |
| * <p/> |
| * This implementation caches the resulting hex string so multiple calls to this method remain efficient. |
| * However, calling {@link #setBytes setBytes} will null the cached value, forcing it to be recalculated the |
| * next time this method is called. |
| * |
| * @return a hex-encoded string of the underlying {@link #getBytes byte array}. |
| */ |
| public String toHex() { |
| if (this.hexEncoded == null) { |
| this.hexEncoded = Hex.encodeToString(getBytes()); |
| } |
| return this.hexEncoded; |
| } |
| |
| /** |
| * Returns a Base64-encoded string of the underlying {@link #getBytes byte array}. |
| * <p/> |
| * This implementation caches the resulting Base64 string so multiple calls to this method remain efficient. |
| * However, calling {@link #setBytes setBytes} will null the cached value, forcing it to be recalculated the |
| * next time this method is called. |
| * |
| * @return a Base64-encoded string of the underlying {@link #getBytes byte array}. |
| */ |
| public String toBase64() { |
| if (this.base64Encoded == null) { |
| //cache result in case this method is called multiple times. |
| this.base64Encoded = Base64.encodeToString(getBytes()); |
| } |
| return this.base64Encoded; |
| } |
| |
| /** |
| * Simple implementation that merely returns {@link #toHex() toHex()}. |
| * |
| * @return the {@link #toHex() toHex()} value. |
| */ |
| public String toString() { |
| return toHex(); |
| } |
| |
| /** |
| * Returns {@code true} if the specified object is a Hash and its {@link #getBytes byte array} is identical to |
| * this Hash's byte array, {@code false} otherwise. |
| * |
| * @param o the object (Hash) to check for equality. |
| * @return {@code true} if the specified object is a Hash and its {@link #getBytes byte array} is identical to |
| * this Hash's byte array, {@code false} otherwise. |
| */ |
| public boolean equals(Object o) { |
| if (o instanceof Hash) { |
| Hash other = (Hash) o; |
| return MessageDigest.isEqual(getBytes(), other.getBytes()); |
| } |
| return false; |
| } |
| |
| /** |
| * Simply returns toHex().hashCode(); |
| * |
| * @return toHex().hashCode() |
| */ |
| public int hashCode() { |
| if (this.bytes == null || this.bytes.length == 0) { |
| return 0; |
| } |
| return Arrays.hashCode(this.bytes); |
| } |
| ]]> |
| </codefragment> |
| </duplication> |
| <duplication lines="29" tokens="100"> |
| <file line="199" path="/Users/briandemers/dev/source/shiro-1.2.x/core/src/main/java/org/apache/shiro/crypto/hash/AbstractHash.java"/> |
| <file line="330" path="/Users/briandemers/dev/source/shiro-1.2.x/core/src/main/java/org/apache/shiro/crypto/hash/SimpleHash.java"/> |
| <codefragment> |
| <![CDATA[ |
| return hash(bytes, salt, DEFAULT_ITERATIONS); |
| } |
| |
| /** |
| * Hashes the specified byte array using the given {@code salt} for the specified number of iterations. |
| * |
| * @param bytes the bytes to hash |
| * @param salt the salt to use for the initial hash |
| * @param hashIterations the number of times the the {@code bytes} will be hashed (for attack resiliency). |
| * @return the hashed bytes. |
| * @throws UnknownAlgorithmException if the {@link #getAlgorithmName() algorithmName} is not available. |
| */ |
| protected byte[] hash(byte[] bytes, byte[] salt, int hashIterations) throws UnknownAlgorithmException { |
| MessageDigest digest = getDigest(getAlgorithmName()); |
| if (salt != null) { |
| digest.reset(); |
| digest.update(salt); |
| } |
| byte[] hashed = digest.digest(bytes); |
| int iterations = hashIterations - 1; //already hashed once above |
| //iterate remaining number: |
| for (int i = 0; i < iterations; i++) { |
| digest.reset(); |
| hashed = digest.digest(hashed); |
| } |
| return hashed; |
| } |
| |
| public boolean isEmpty() { |
| ]]> |
| </codefragment> |
| </duplication> |
| </pmd-cpd> |