You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ch...@apache.org on 2013/04/01 22:36:56 UTC

git commit: updated refs/heads/SHA512Salted to a18aaed

Updated Branches:
  refs/heads/SHA512Salted [created] a18aaed09


CLOUDSTACK-1870: Adding a SHA512Salted user authenticator plugin
Signed-off-by: Chip Childers <ch...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/a18aaed0
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/a18aaed0
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/a18aaed0

Branch: refs/heads/SHA512Salted
Commit: a18aaed097e977ca65c0fc4a956beb11058ad179
Parents: 6eac422
Author: Chip Childers <ch...@gmail.com>
Authored: Mon Apr 1 16:34:41 2013 -0400
Committer: Chip Childers <ch...@gmail.com>
Committed: Mon Apr 1 16:34:41 2013 -0400

----------------------------------------------------------------------
 plugins/pom.xml                                    |    1 +
 plugins/user-authenticators/sha512salted/pom.xml   |   29 ++++
 .../server/auth/SHA512SaltedUserAuthenticator.java |  120 +++++++++++++++
 .../cloud/server/auth/test/AuthenticatorTest.java  |   63 ++++++++
 4 files changed, 213 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a18aaed0/plugins/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/pom.xml b/plugins/pom.xml
index d7e8deb..c5d3a2c 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -54,6 +54,7 @@
     <module>user-authenticators/md5</module>
     <module>user-authenticators/plain-text</module>
     <module>user-authenticators/sha256salted</module>
+    <module>user-authenticators/sha513salted</module>
     <module>network-elements/dns-notifier</module>
     <module>storage/image/s3</module>
     <module>storage/volume/solidfire</module>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a18aaed0/plugins/user-authenticators/sha512salted/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/sha512salted/pom.xml b/plugins/user-authenticators/sha512salted/pom.xml
new file mode 100644
index 0000000..8ff1454
--- /dev/null
+++ b/plugins/user-authenticators/sha512salted/pom.xml
@@ -0,0 +1,29 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>cloud-plugin-user-authenticator-sha512salted</artifactId>
+  <name>Apache CloudStack Plugin - User Authenticator SHA512 Salted</name>
+  <parent>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloudstack-plugins</artifactId>
+    <version>4.2.0-SNAPSHOT</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+</project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a18aaed0/plugins/user-authenticators/sha512salted/src/com/cloud/server/auth/SHA512SaltedUserAuthenticator.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/sha512salted/src/com/cloud/server/auth/SHA512SaltedUserAuthenticator.java b/plugins/user-authenticators/sha512salted/src/com/cloud/server/auth/SHA512SaltedUserAuthenticator.java
new file mode 100644
index 0000000..abb38c1
--- /dev/null
+++ b/plugins/user-authenticators/sha512salted/src/com/cloud/server/auth/SHA512SaltedUserAuthenticator.java
@@ -0,0 +1,120 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.server.auth;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.bouncycastle.util.encoders.Base64;
+
+import com.cloud.user.UserAccount;
+import com.cloud.user.dao.UserAccountDao;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@Local(value={UserAuthenticator.class})
+public class SHA512SaltedUserAuthenticator extends DefaultUserAuthenticator {
+    public static final Logger s_logger = Logger.getLogger(SHA512SaltedUserAuthenticator.class);
+
+    @Inject
+    private UserAccountDao _userAccountDao;
+    private static int s_saltlen = 20;
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params)
+            throws ConfigurationException {
+        super.configure(name, params);
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.server.auth.UserAuthenticator#authenticate(java.lang.String, java.lang.String, java.lang.Long, java.util.Map)
+     */
+    @Override
+    public boolean authenticate(String username, String password,
+            Long domainId, Map<String, Object[]> requestParameters) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Retrieving user: " + username);
+        }
+        UserAccount user = _userAccountDao.getUserAccount(username, domainId);
+        if (user == null) {
+            s_logger.debug("Unable to find user with " + username + " in domain " + domainId);
+            return false;
+        }
+
+        try {
+            String storedPassword[] = user.getPassword().split(":");
+            if (storedPassword.length != 2) {
+                s_logger.warn("The stored password for " + username + " isn't in the right format for this authenticator");
+                return false;
+            }
+            byte salt[] = Base64.decode(storedPassword[0]);
+            String hashedPassword = encode(password, salt);
+            return storedPassword[1].equals(hashedPassword);
+        } catch (NoSuchAlgorithmException e) {
+            throw new CloudRuntimeException("Unable to hash password", e);
+        } catch (UnsupportedEncodingException e) {
+            throw new CloudRuntimeException("Unable to hash password", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.server.auth.UserAuthenticator#encode(java.lang.String)
+     */
+    @Override
+    public String encode(String password) {
+        // 1. Generate the salt
+        SecureRandom randomGen;
+        try {
+            randomGen = SecureRandom.getInstance("SHA1PRNG");
+
+            byte salt[] = new byte[s_saltlen];
+            randomGen.nextBytes(salt);
+
+            String saltString = new String(Base64.encode(salt));
+            String hashString = encode(password, salt);
+
+            // 3. concatenate the two and return
+            return saltString + ":" + hashString;
+        } catch (NoSuchAlgorithmException e) {
+            throw new CloudRuntimeException("Unable to hash password", e);
+        } catch (UnsupportedEncodingException e) {
+            throw new CloudRuntimeException("Unable to hash password", e);
+        }
+    }
+
+    public String encode(String password, byte[] salt) throws UnsupportedEncodingException, NoSuchAlgorithmException {
+        byte[] passwordBytes = password.getBytes("UTF-8");
+        byte[] hashSource = new byte[passwordBytes.length + s_saltlen];
+        System.arraycopy(passwordBytes, 0, hashSource, 0, passwordBytes.length);
+        System.arraycopy(salt, 0, hashSource, passwordBytes.length, s_saltlen);
+
+        // 2. Hash the password with the salt
+        MessageDigest md = MessageDigest.getInstance("SHA-512");
+        md.update(hashSource);
+        byte[] digest = md.digest();
+
+        return new String(Base64.encode(digest));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a18aaed0/plugins/user-authenticators/sha512salted/test/src/com/cloud/server/auth/test/AuthenticatorTest.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/sha512salted/test/src/com/cloud/server/auth/test/AuthenticatorTest.java b/plugins/user-authenticators/sha512salted/test/src/com/cloud/server/auth/test/AuthenticatorTest.java
new file mode 100644
index 0000000..c4c82e9
--- /dev/null
+++ b/plugins/user-authenticators/sha512salted/test/src/com/cloud/server/auth/test/AuthenticatorTest.java
@@ -0,0 +1,63 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package src.com.cloud.server.auth.test;
+
+import static org.junit.Assert.*;
+
+import java.io.UnsupportedEncodingException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+
+import javax.naming.ConfigurationException;
+
+import org.bouncycastle.util.encoders.Base64;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.cloud.server.auth.SHA512SaltedUserAuthenticator;
+
+public class AuthenticatorTest {
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@Test
+	public void testEncode() throws UnsupportedEncodingException, NoSuchAlgorithmException {
+		SHA512SaltedUserAuthenticator authenticator = 
+				new SHA512SaltedUserAuthenticator();
+
+		try {
+			authenticator.configure("SHA512", Collections.<String,Object>emptyMap());
+		} catch (ConfigurationException e) {
+			fail(e.toString());
+		}
+		
+		String encodedPassword = authenticator.encode("password");
+        
+		String storedPassword[] = encodedPassword.split(":");
+        assertEquals ("hash must consist of two components", storedPassword.length, 2);
+
+        byte salt[] = Base64.decode(storedPassword[0]);
+        String hashedPassword = authenticator.encode("password", salt);
+        
+        assertEquals("compare hashes", storedPassword[1], hashedPassword);
+
+	}
+
+}