Original commit: elastic/x-pack-elasticsearch@f7a6f816b8
This commit is contained in:
Paul Echeverri 2014-10-20 13:47:26 -07:00
commit 21dfc7bfed
6 changed files with 120 additions and 17 deletions

View File

@ -33,7 +33,7 @@ import java.util.*;
*/ */
public class LdapGroupToRoleMapper extends AbstractComponent { public class LdapGroupToRoleMapper extends AbstractComponent {
public static final String DEFAULT_FILE_NAME = "role_mapping"; public static final String DEFAULT_FILE_NAME = "role_mapping.yml";
public static final String ROLE_MAPPING_FILE_SETTING = "files.role_mapping"; public static final String ROLE_MAPPING_FILE_SETTING = "files.role_mapping";
public static final String USE_UNMAPPED_GROUPS_AS_ROLES_SETTING = "unmapped_groups_as_roles"; public static final String USE_UNMAPPED_GROUPS_AS_ROLES_SETTING = "unmapped_groups_as_roles";

View File

@ -9,6 +9,7 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.Crypt; import org.apache.commons.codec.digest.Crypt;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.Md5Crypt; import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.codec.digest.Sha2Crypt;
import org.elasticsearch.ElasticsearchIllegalArgumentException; import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.common.os.OsUtils; import org.elasticsearch.common.os.OsUtils;
@ -34,9 +35,6 @@ public enum Hasher {
@Override @Override
public boolean verify(SecuredString text, char[] hash) { public boolean verify(SecuredString text, char[] hash) {
String hashStr = new String(hash); String hashStr = new String(hash);
if (hashStr.startsWith(BCRYPT_PREFIX_Y)) {
hashStr = BCRYPT_PREFIX + hashStr.substring(BCRYPT_PREFIX_Y.length());
}
if (hashStr.startsWith(BCRYPT_PREFIX)) { if (hashStr.startsWith(BCRYPT_PREFIX)) {
return BCrypt.checkpw(text, hashStr); return BCrypt.checkpw(text, hashStr);
} }
@ -52,16 +50,94 @@ public enum Hasher {
String passwd64 = Base64.encodeBase64String(DigestUtils.sha1(textBytes)); String passwd64 = Base64.encodeBase64String(DigestUtils.sha1(textBytes));
return hashStr.substring(SHA1_PREFIX.length()).compareTo(passwd64) == 0; return hashStr.substring(SHA1_PREFIX.length()).compareTo(passwd64) == 0;
} }
if (hashStr.startsWith(SHA2_PREFIX_5) || hashStr.startsWith(SHA2_PREFIX_6)) {
return hashStr.compareTo(Sha2Crypt.sha256Crypt(textBytes, hashStr)) == 0;
}
return CRYPT_SUPPORTED ? return CRYPT_SUPPORTED ?
hashStr.compareTo(Crypt.crypt(textBytes, hashStr)) == 0 : // crypt algo hashStr.compareTo(Crypt.crypt(textBytes, hashStr)) == 0 : // crypt algo
text.equals(hashStr); // plain text text.equals(hashStr); // plain text
}
},
BCRYPT() {
@Override
public char[] hash(SecuredString text) {
String salt = org.elasticsearch.shield.authc.support.BCrypt.gensalt();
return BCrypt.hashpw(text, salt).toCharArray();
}
@Override
public boolean verify(SecuredString text, char[] hash) {
String hashStr = new String(hash);
if (!hashStr.startsWith(BCRYPT_PREFIX)) {
return false;
}
return BCrypt.checkpw(text, hashStr);
}
},
MD5() {
@Override
public char[] hash(SecuredString text) {
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
return Md5Crypt.apr1Crypt(textBytes).toCharArray();
}
@Override
public boolean verify(SecuredString text, char[] hash) {
String hashStr = new String(hash);
if (!hashStr.startsWith(APR1_PREFIX)) {
return false;
}
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
return hashStr.compareTo(Md5Crypt.apr1Crypt(textBytes, hashStr)) == 0;
}
},
SHA1() {
@Override
public char[] hash(SecuredString text) {
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
String hash = Base64.encodeBase64String(DigestUtils.sha1(textBytes));
return (SHA1_PREFIX + hash).toCharArray();
}
@Override
public boolean verify(SecuredString text, char[] hash) {
String hashStr = new String(hash);
if (!hashStr.startsWith(SHA1_PREFIX)) {
return false;
}
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
String passwd64 = Base64.encodeBase64String(DigestUtils.sha1(textBytes));
return hashStr.substring(SHA1_PREFIX.length()).compareTo(passwd64) == 0;
}
},
SHA2() {
@Override
public char[] hash(SecuredString text) {
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
return Sha2Crypt.sha256Crypt(textBytes).toCharArray();
}
@Override
public boolean verify(SecuredString text, char[] hash) {
String hashStr = new String(hash);
if (hashStr.startsWith(SHA2_PREFIX_5) || hashStr.startsWith(SHA2_PREFIX_6)) {
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
return hashStr.compareTo(Sha2Crypt.sha256Crypt(textBytes, hashStr)) == 0;
}
return false;
} }
}; };
private static final String APR1_PREFIX = "$apr1$"; private static final String APR1_PREFIX = "$apr1$";
private static final String BCRYPT_PREFIX = "$2a$"; private static final String BCRYPT_PREFIX = "$2a$";
private static final String BCRYPT_PREFIX_Y = "$2y$";
private static final String SHA1_PREFIX = "{SHA}"; private static final String SHA1_PREFIX = "{SHA}";
private static final String SHA2_PREFIX_5 = "$5$";
private static final String SHA2_PREFIX_6 = "$6$";
private static final String PLAIN_PREFIX = "{plain}"; private static final String PLAIN_PREFIX = "{plain}";
static final boolean CRYPT_SUPPORTED = !OsUtils.WINDOWS; static final boolean CRYPT_SUPPORTED = !OsUtils.WINDOWS;

View File

@ -29,9 +29,12 @@ public class SSLConfig {
private String[] ciphers; private String[] ciphers;
public SSLConfig(Settings componentSettings, Settings defaultSettings, boolean defaultRequireClientAuth) { public SSLConfig(Settings componentSettings, Settings defaultSettings, boolean defaultRequireClientAuth) {
SSLTrustConfig sslTrustConfig = new SSLTrustConfig(componentSettings, defaultSettings);
this.clientAuth = componentSettings.getAsBoolean("require.client.auth", defaultSettings.getAsBoolean("require.client.auth", defaultRequireClientAuth)); this.clientAuth = componentSettings.getAsBoolean("require.client.auth", defaultSettings.getAsBoolean("require.client.auth", defaultRequireClientAuth));
TrustManager[] trustManagers = null;
if (clientAuth) {
trustManagers = new SSLTrustConfig(componentSettings, defaultSettings).getTrustManagers();
}
String keyStore = componentSettings.get("keystore", defaultSettings.get("keystore", System.getProperty("javax.net.ssl.keyStore"))); String keyStore = componentSettings.get("keystore", defaultSettings.get("keystore", System.getProperty("javax.net.ssl.keyStore")));
String keyStorePassword = componentSettings.get("keystore_password", defaultSettings.get("keystore_password", System.getProperty("javax.net.ssl.keyStorePassword"))); String keyStorePassword = componentSettings.get("keystore_password", defaultSettings.get("keystore_password", System.getProperty("javax.net.ssl.keyStorePassword")));
String keyStoreAlgorithm = componentSettings.get("keystore_algorithm", defaultSettings.get("keystore_algorithm", System.getProperty("ssl.KeyManagerFactory.algorithm"))); String keyStoreAlgorithm = componentSettings.get("keystore_algorithm", defaultSettings.get("keystore_algorithm", System.getProperty("ssl.KeyManagerFactory.algorithm")));
@ -69,7 +72,7 @@ public class SSLConfig {
try { try {
String algorithm = componentSettings.get("context_algorithm", defaultSettings.get("shield.ssl.context_algorithm", "TLS")); String algorithm = componentSettings.get("context_algorithm", defaultSettings.get("shield.ssl.context_algorithm", "TLS"));
sslContext = SSLContext.getInstance(algorithm); sslContext = SSLContext.getInstance(algorithm);
sslContext.init(kmf.getKeyManagers(), sslTrustConfig.getTrustManagers(), null); sslContext.init(kmf.getKeyManagers(), trustManagers, null);
} catch (Exception e) { } catch (Exception e) {
throw new ElasticsearchSSLException("Failed to initialize the SSLContext", e); throw new ElasticsearchSSLException("Failed to initialize the SSLContext", e);
} }

View File

@ -48,7 +48,7 @@ public class FileUserPasswdStoreTests extends ElasticsearchTestCase {
assertThat(users, notNullValue()); assertThat(users, notNullValue());
assertThat(users.size(), is(6)); assertThat(users.size(), is(6));
assertThat(users.get("bcrypt"), notNullValue()); assertThat(users.get("bcrypt"), notNullValue());
assertThat(new String(users.get("bcrypt")), equalTo("$2y$05$zxnP0vdREMxnEpkLCDI2OuSaSk/QEKA2.A42iOpI6U2u.RLLOWm1e")); assertThat(new String(users.get("bcrypt")), equalTo("$2a$05$zxnP0vdREMxnEpkLCDI2OuSaSk/QEKA2.A42iOpI6U2u.RLLOWm1e"));
assertThat(users.get("bcrypt10"), notNullValue()); assertThat(users.get("bcrypt10"), notNullValue());
assertThat(new String(users.get("bcrypt10")), equalTo("$2y$10$FMhmFjwU5.qxQ/BsEciS9OqcJVkFMgXMo4uH5CelOR1j4N9zIv67e")); assertThat(new String(users.get("bcrypt10")), equalTo("$2y$10$FMhmFjwU5.qxQ/BsEciS9OqcJVkFMgXMo4uH5CelOR1j4N9zIv67e"));
assertThat(users.get("md5"), notNullValue()); assertThat(users.get("md5"), notNullValue());

View File

@ -5,7 +5,6 @@
*/ */
package org.elasticsearch.shield.authc.support; package org.elasticsearch.shield.authc.support;
import org.elasticsearch.common.os.OsUtils;
import org.elasticsearch.test.ElasticsearchTestCase; import org.elasticsearch.test.ElasticsearchTestCase;
import org.junit.Test; import org.junit.Test;
@ -15,11 +14,11 @@ import org.junit.Test;
public class HasherTests extends ElasticsearchTestCase { public class HasherTests extends ElasticsearchTestCase {
@Test @Test
public void testHtpasswdToolGenerated() throws Exception { public void testHtpasswd_ToolGenerated() throws Exception {
Hasher hasher = Hasher.HTPASSWD; Hasher hasher = Hasher.HTPASSWD;
SecuredString passwd = SecuredStringTests.build("test123"); SecuredString passwd = SecuredStringTests.build("test123");
assertTrue(hasher.verify(passwd, "$2a$05$zxnP0vdREMxnEpkLCDI2OuSaSk/QEKA2.A42iOpI6U2u.RLLOWm1e".toCharArray())); assertTrue(hasher.verify(passwd, "$2a$05$zxnP0vdREMxnEpkLCDI2OuSaSk/QEKA2.A42iOpI6U2u.RLLOWm1e".toCharArray()));
assertTrue(hasher.verify(passwd, "$2a$10$FMhmFjwU5.qxQ/BsEciS9OqcJVkFMgXMo4uH5CelOR1j4N9zIv67e".toCharArray())); assertTrue(hasher.verify(passwd, "$2a$10$vNMk6GyVUU./7YSZB6BGPuozm921GVPw/Pdukzd09s.sL2rIWROU6".toCharArray()));
assertTrue(hasher.verify(passwd, "$apr1$R3DdqiAZ$aljIkaIVPSarmDMlJUBBP.".toCharArray())); assertTrue(hasher.verify(passwd, "$apr1$R3DdqiAZ$aljIkaIVPSarmDMlJUBBP.".toCharArray()));
if (!Hasher.CRYPT_SUPPORTED) { if (!Hasher.CRYPT_SUPPORTED) {
assertTrue(hasher.verify(passwd, "test123".toCharArray())); assertTrue(hasher.verify(passwd, "test123".toCharArray()));
@ -28,12 +27,37 @@ public class HasherTests extends ElasticsearchTestCase {
} }
assertTrue(hasher.verify(passwd, "{plain}test123".toCharArray())); assertTrue(hasher.verify(passwd, "{plain}test123".toCharArray()));
assertTrue(hasher.verify(passwd, "{SHA}cojt0Pw//L6ToM8G41aOKFIWh7w=".toCharArray())); assertTrue(hasher.verify(passwd, "{SHA}cojt0Pw//L6ToM8G41aOKFIWh7w=".toCharArray()));
assertTrue(hasher.verify(passwd, "$5$RsqcsPiF$51tIIXf6oZb3Awox6FWNhITVlM/aW3oa8uN2eptIf54".toCharArray()));
} }
@Test @Test
public void testHtpasswdSelfGenerated() throws Exception { public void testHtpasswd_SelfGenerated() throws Exception {
Hasher hasher = Hasher.HTPASSWD; testHasherSelfGenerated(Hasher.HTPASSWD);
}
@Test
public void testBcrypt_SelfGenerated() throws Exception {
testHasherSelfGenerated(Hasher.BCRYPT);
}
@Test
public void testMd5_SelfGenerated() throws Exception {
testHasherSelfGenerated(Hasher.MD5);
}
@Test
public void testSha1_SelfGenerated() throws Exception {
testHasherSelfGenerated(Hasher.SHA1);
}
@Test
public void testSha2_SelfGenerated() throws Exception {
testHasherSelfGenerated(Hasher.SHA2);
}
public void testHasherSelfGenerated(Hasher hasher) throws Exception {
SecuredString passwd = SecuredStringTests.build("test123"); SecuredString passwd = SecuredStringTests.build("test123");
assertTrue(hasher.verify(passwd, hasher.hash(passwd))); assertTrue(hasher.verify(passwd, hasher.hash(passwd)));
} }
} }

View File

@ -1,4 +1,4 @@
bcrypt: $2y$05$zxnP0vdREMxnEpkLCDI2OuSaSk/QEKA2.A42iOpI6U2u.RLLOWm1e bcrypt: $2a$05$zxnP0vdREMxnEpkLCDI2OuSaSk/QEKA2.A42iOpI6U2u.RLLOWm1e
md5: $apr1$R3DdqiAZ$aljIkaIVPSarmDMlJUBBP. md5: $apr1$R3DdqiAZ$aljIkaIVPSarmDMlJUBBP.
crypt: hsP1PYSLsEEvs crypt: hsP1PYSLsEEvs
plain: {plain}test123 plain: {plain}test123