Author: rgodfrey
Date: Wed Dec 30 14:46:43 2015
New Revision: 1722339
URL: http://svn.apache.org/viewvc?rev=1722339&view=rev
Log:
QPID-6967 : [Java Broker] Add SCRAM-SHA* SASL support to Plain database based
authentication managers
Added:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServerSource.java
(with props)
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServerSourceAdapter.java
(with props)
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractScramAuthenticationManager.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ScramSHA1AuthenticationManager.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ScramSHA256AuthenticationManager.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServer.java
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java?rev=1722339&r1=1722338&r2=1722339&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java
Wed Dec 30 14:46:43 2015
@@ -102,8 +102,7 @@ public abstract class AbstractPasswordFi
/**
- * Looks up the password for a specified user in the password file. Note
this code is <b>not</b> secure since it
- * creates strings of passwords. It should be modified to create only char
arrays which get nulled out.
+ * Looks up the password for a specified user in the password file.
*
* @param name The principal name to lookup
*
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java?rev=1722339&r1=1722338&r2=1722339&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
Wed Dec 30 14:46:43 2015
@@ -36,9 +36,13 @@ import javax.security.sasl.SaslServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import
org.apache.qpid.server.security.auth.manager.ScramSHA1AuthenticationManager;
+import
org.apache.qpid.server.security.auth.manager.ScramSHA256AuthenticationManager;
import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
import org.apache.qpid.server.security.auth.sasl.plain.PlainSaslServer;
+import org.apache.qpid.server.security.auth.sasl.scram.ScramSaslServer;
+import
org.apache.qpid.server.security.auth.sasl.scram.ScramSaslServerSourceAdapter;
/**
* Represents a user database where the account information is stored in a
simple flat file.
@@ -53,18 +57,40 @@ public class PlainPasswordFilePrincipalD
private final Logger _logger =
LoggerFactory.getLogger(PlainPasswordFilePrincipalDatabase.class);
private final Map<String, CallbackHandler> _callbackHandlerMap = new
HashMap<String, CallbackHandler>();
private final List<String> _mechanisms =
Collections.unmodifiableList(Arrays.asList(PlainSaslServer.MECHANISM,
-
CRAMMD5Initialiser.MECHANISM));
+
CRAMMD5Initialiser.MECHANISM,
+
ScramSHA1AuthenticationManager.MECHANISM,
+
ScramSHA256AuthenticationManager.MECHANISM));
+ private final ScramSaslServerSourceAdapter _scramSha1Adapter;
+ private final ScramSaslServerSourceAdapter _scramSha256Adapter;
+
public PlainPasswordFilePrincipalDatabase()
{
PlainInitialiser plainInitialiser = new PlainInitialiser();
plainInitialiser.initialise(this);
_callbackHandlerMap.put(PlainSaslServer.MECHANISM,
plainInitialiser.getCallbackHandler());
+ _callbackHandlerMap.put(ScramSHA1AuthenticationManager.MECHANISM,
plainInitialiser.getCallbackHandler());
+ _callbackHandlerMap.put(ScramSHA256AuthenticationManager.MECHANISM,
plainInitialiser.getCallbackHandler());
+
CRAMMD5Initialiser crammd5Initialiser = new CRAMMD5Initialiser();
crammd5Initialiser.initialise(this);
_callbackHandlerMap.put(CRAMMD5Initialiser.MECHANISM,
crammd5Initialiser.getCallbackHandler());
+ ScramSaslServerSourceAdapter.PasswordSource passwordSource =
+ new ScramSaslServerSourceAdapter.PasswordSource()
+ {
+ @Override
+ public char[] getPassword(final String username)
+ {
+ return lookupPassword(username);
+ }
+ };
+
+ _scramSha1Adapter = new ScramSaslServerSourceAdapter(4096, "HmacSHA1",
passwordSource);
+ _scramSha256Adapter = new ScramSaslServerSourceAdapter(4096,
"HmacSHA256", passwordSource);
+
+
}
@@ -120,7 +146,7 @@ public class PlainPasswordFilePrincipalD
@Override
public SaslServer createSaslServer(String mechanism, String localFQDN,
Principal externalPrincipal) throws SaslException
{
- CallbackHandler callbackHandler = _callbackHandlerMap.get(mechanism);
+ final CallbackHandler callbackHandler =
_callbackHandlerMap.get(mechanism);
if(callbackHandler == null)
{
throw new SaslException("Unsupported mechanism: " + mechanism);
@@ -135,7 +161,16 @@ public class PlainPasswordFilePrincipalD
{
return new PlainSaslServer(callbackHandler);
}
+ else if(ScramSHA1AuthenticationManager.MECHANISM.equals(mechanism))
+ {
+ return new ScramSaslServer(_scramSha1Adapter, mechanism,
"HmacSHA1", "SHA-1");
+ }
+ else if(ScramSHA256AuthenticationManager.MECHANISM.equals(mechanism))
+ {
+ return new ScramSaslServer(_scramSha256Adapter, mechanism,
"HmacSHA256", "SHA-256");
+ }
throw new SaslException("Unsupported mechanism: " + mechanism);
}
+
}
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractScramAuthenticationManager.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractScramAuthenticationManager.java?rev=1722339&r1=1722338&r2=1722339&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractScramAuthenticationManager.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractScramAuthenticationManager.java
Wed Dec 30 14:46:43 2015
@@ -41,10 +41,11 @@ import org.apache.qpid.server.security.a
import org.apache.qpid.server.security.auth.UsernamePrincipal;
import org.apache.qpid.server.security.auth.sasl.plain.PlainAdapterSaslServer;
import org.apache.qpid.server.security.auth.sasl.scram.ScramSaslServer;
+import org.apache.qpid.server.security.auth.sasl.scram.ScramSaslServerSource;
public abstract class AbstractScramAuthenticationManager<X extends
AbstractScramAuthenticationManager<X>>
extends ConfigModelPasswordManagingAuthenticationProvider<X>
- implements PasswordCredentialManagingAuthenticationProvider<X>
+ implements PasswordCredentialManagingAuthenticationProvider<X>,
ScramSaslServerSource
{
public static final String PLAIN = "PLAIN";
@@ -213,4 +214,46 @@ public abstract class AbstractScramAuthe
throw new IllegalArgumentException("User names are restricted to
characters in the ASCII charset");
}
}
+
+ @Override
+ public SaltAndSaltedPassword getSaltAndSaltedPassword(final String
username)
+ {
+ final byte[] salt = getSalt(username);
+ byte[] tmpPassword = null;
+ SaslException tmpException = null;
+
+ try
+ {
+ tmpPassword = getSaltedPassword(username);
+ }
+ catch (SaslException e)
+ {
+ tmpException = e;
+ }
+
+ final byte[] saltedPassword = tmpPassword;
+ final SaslException exception = tmpException;
+
+ return new SaltAndSaltedPassword()
+ {
+ @Override
+ public byte[] getSalt()
+ {
+ return salt;
+ }
+
+ @Override
+ public byte[] getSaltedPassword() throws SaslException
+ {
+ if(exception == null)
+ {
+ return saltedPassword;
+ }
+ else
+ {
+ throw exception;
+ }
+ }
+ };
+ }
}
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ScramSHA1AuthenticationManager.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ScramSHA1AuthenticationManager.java?rev=1722339&r1=1722338&r2=1722339&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ScramSHA1AuthenticationManager.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ScramSHA1AuthenticationManager.java
Wed Dec 30 14:46:43 2015
@@ -34,8 +34,7 @@ public class ScramSHA1AuthenticationMana
public static final String PROVIDER_TYPE = "SCRAM-SHA-1";
private static final String HMAC_NAME = "HmacSHA1";
- static final Charset ASCII = Charset.forName("ASCII");
- private static final String MECHANISM = "SCRAM-SHA-1";
+ public static final String MECHANISM = "SCRAM-SHA-1";
private static final String DIGEST_NAME = "SHA-1";
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ScramSHA256AuthenticationManager.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ScramSHA256AuthenticationManager.java?rev=1722339&r1=1722338&r2=1722339&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ScramSHA256AuthenticationManager.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ScramSHA256AuthenticationManager.java
Wed Dec 30 14:46:43 2015
@@ -34,8 +34,7 @@ public class ScramSHA256AuthenticationMa
public static final String PROVIDER_TYPE = "SCRAM-SHA-256";
private static final String HMAC_NAME = "HmacSHA256";
- static final Charset ASCII = Charset.forName("ASCII");
- private static final String MECHANISM = "SCRAM-SHA-256";
+ public static final String MECHANISM = "SCRAM-SHA-256";
private static final String DIGEST_NAME = "SHA-256";
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServer.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServer.java?rev=1722339&r1=1722338&r2=1722339&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServer.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServer.java
Wed Dec 30 14:46:43 2015
@@ -44,7 +44,7 @@ public class ScramSaslServer implements
private static final Charset ASCII = Charset.forName("ASCII");
- private final AbstractScramAuthenticationManager _authManager;
+ private final ScramSaslServerSource _authManager;
private State _state = State.INITIAL;
private String _nonce;
private String _username;
@@ -52,8 +52,9 @@ public class ScramSaslServer implements
private String _serverFirstMessage;
private String _clientFirstMessageBare;
private byte[] _serverSignature;
+ private ScramSaslServerSource.SaltAndSaltedPassword _saltAndPassword;
- public ScramSaslServer(final AbstractScramAuthenticationManager
authenticationManager,
+ public ScramSaslServer(final ScramSaslServerSource authenticationManager,
final String mechanism,
final String hmacName,
final String digestName)
@@ -130,8 +131,8 @@ public class ScramSaslServer implements
_nonce = parts[3].substring(2) + UUID.randomUUID().toString();
int count = _authManager.getIterationCount();
- byte[] saltBytes = _authManager.getSalt(_username);
- _serverFirstMessage = "r="+_nonce+",s="+
DatatypeConverter.printBase64Binary(saltBytes)+",i=" + count;
+ _saltAndPassword = _authManager.getSaltAndSaltedPassword(_username);
+ _serverFirstMessage = "r="+_nonce+",s="+
DatatypeConverter.printBase64Binary(_saltAndPassword.getSalt())+",i=" + count;
return _serverFirstMessage.getBytes(ASCII);
}
@@ -187,7 +188,7 @@ public class ScramSaslServer implements
String authMessage = _clientFirstMessageBare + "," +
_serverFirstMessage + "," + clientFinalMessageWithoutProof;
- byte[] saltedPassword = _authManager.getSaltedPassword(_username);
+ byte[] saltedPassword = _saltAndPassword.getSaltedPassword();
byte[] clientKey = computeHmac(saltedPassword, "Client Key");
Added:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServerSource.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServerSource.java?rev=1722339&view=auto
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServerSource.java
(added)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServerSource.java
Wed Dec 30 14:46:43 2015
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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 org.apache.qpid.server.security.auth.sasl.scram;
+
+import javax.security.sasl.SaslException;
+
+public interface ScramSaslServerSource
+{
+ int getIterationCount();
+
+ interface SaltAndSaltedPassword
+ {
+ byte[] getSalt();
+
+ byte[] getSaltedPassword() throws SaslException;
+ }
+
+ SaltAndSaltedPassword getSaltAndSaltedPassword(String username);
+
+}
Propchange:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServerSource.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServerSourceAdapter.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServerSourceAdapter.java?rev=1722339&view=auto
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServerSourceAdapter.java
(added)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServerSourceAdapter.java
Wed Dec 30 14:46:43 2015
@@ -0,0 +1,127 @@
+/*
+ *
+ * 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 org.apache.qpid.server.security.auth.sasl.scram;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import javax.security.sasl.SaslException;
+
+import
org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
+
+public class ScramSaslServerSourceAdapter implements ScramSaslServerSource
+{
+ private static final byte[] INT_1 = new byte[]{0, 0, 0, 1};
+
+ private final int _iterationCount;
+ private final String _hmacName;
+ private final SecureRandom _random = new SecureRandom();
+ private final PasswordSource _passwordSource;
+
+ public interface PasswordSource
+ {
+ char[] getPassword(String username);
+ }
+
+ public ScramSaslServerSourceAdapter(final int iterationCount,
+ final String hmacName,
+ final PasswordSource passwordSource)
+ {
+ _iterationCount = iterationCount;
+ _hmacName = hmacName;
+ _passwordSource = passwordSource;
+ }
+
+ @Override
+ public int getIterationCount()
+ {
+ return _iterationCount;
+ }
+
+ @Override
+ public SaltAndSaltedPassword getSaltAndSaltedPassword(final String
username)
+ {
+ final char[] password = _passwordSource.getPassword(username);
+
+ final byte[] salt = new byte[32];
+ _random.nextBytes(salt);
+ return new SaltAndSaltedPassword()
+ {
+ @Override
+ public byte[] getSalt()
+ {
+ return salt;
+ }
+
+ @Override
+ public byte[] getSaltedPassword() throws SaslException
+ {
+ if(password == null)
+ {
+ throw new SaslException("Authentication Failed");
+ }
+ byte[] passwordAsBytes = new byte[password.length];
+ for(int i = 0; i< password.length; i++)
+ {
+ passwordAsBytes[i] = (byte) password[i];
+ }
+ Mac mac = createShaHmac(passwordAsBytes);
+
+ mac.update(salt);
+ mac.update(INT_1);
+ byte[] result = mac.doFinal();
+
+ byte[] previous = null;
+ for(int i = 1; i < getIterationCount(); i++)
+ {
+ mac.update(previous != null? previous: result);
+ previous = mac.doFinal();
+ for(int x = 0; x < result.length; x++)
+ {
+ result[x] ^= previous[x];
+ }
+ }
+
+ return result;
+
+ }
+
+ private Mac createShaHmac(final byte[] keyBytes)
+ {
+ try
+ {
+ SecretKeySpec key = new SecretKeySpec(keyBytes, _hmacName);
+ Mac mac = Mac.getInstance(_hmacName);
+ mac.init(key);
+ return mac;
+ }
+ catch (NoSuchAlgorithmException | InvalidKeyException e)
+ {
+ throw new IllegalArgumentException(e.getMessage(), e);
+ }
+ }
+
+ };
+ }
+}
Propchange:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/scram/ScramSaslServerSourceAdapter.java
------------------------------------------------------------------------------
svn:eol-style = native
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]