Merge branch 'master' of https://github.com/elasticsearch/elasticsearch-shield into doc-feedback
Original commit: elastic/x-pack-elasticsearch@f7a6f816b8
This commit is contained in:
commit
21dfc7bfed
|
@ -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";
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue