diff --git a/src/main/java/org/elasticsearch/shield/ShieldException.java b/src/main/java/org/elasticsearch/shield/ShieldException.java deleted file mode 100644 index bec613bbaef..00000000000 --- a/src/main/java/org/elasticsearch/shield/ShieldException.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.shield; - -import org.elasticsearch.ElasticsearchException; -import org.elasticsearch.common.collect.Tuple; - -/** - * - */ -public class ShieldException extends ElasticsearchException.WithRestHeadersException { - - public ShieldException(String msg, Tuple... headers) { - super(msg, headers); - } - - public ShieldException(String msg, Throwable cause, Tuple... headers) { - super(msg, headers); - initCause(cause); - } -} diff --git a/src/main/java/org/elasticsearch/shield/ShieldPlugin.java b/src/main/java/org/elasticsearch/shield/ShieldPlugin.java index af135a0d71b..9c26ab09419 100644 --- a/src/main/java/org/elasticsearch/shield/ShieldPlugin.java +++ b/src/main/java/org/elasticsearch/shield/ShieldPlugin.java @@ -98,7 +98,7 @@ public class ShieldPlugin extends AbstractPlugin { } int i = userSetting.indexOf(":"); if (i < 0 || i == userSetting.length() - 1) { - throw new ShieldSettingsException("invalid [shield.user] settings. must be in the form of \":\""); + throw new IllegalArgumentException("invalid [shield.user] setting. must be in the form of \":\""); } String username = userSetting.substring(0, i); String password = userSetting.substring(i + 1); diff --git a/src/main/java/org/elasticsearch/shield/ShieldSettingsException.java b/src/main/java/org/elasticsearch/shield/ShieldSettingsException.java deleted file mode 100644 index b47e5e89d43..00000000000 --- a/src/main/java/org/elasticsearch/shield/ShieldSettingsException.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.shield; - -/** - * - */ -public class ShieldSettingsException extends ShieldException { - - public ShieldSettingsException(String msg) { - super(msg); - } - - public ShieldSettingsException(String msg, Throwable cause) { - super(msg, cause); - } - -} diff --git a/src/main/java/org/elasticsearch/shield/User.java b/src/main/java/org/elasticsearch/shield/User.java index be74019c838..a0500f48582 100644 --- a/src/main/java/org/elasticsearch/shield/User.java +++ b/src/main/java/org/elasticsearch/shield/User.java @@ -5,6 +5,7 @@ */ package org.elasticsearch.shield; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -39,7 +40,7 @@ public abstract class User { if (input.readBoolean()) { String name = input.readString(); if (!System.NAME.equals(name)) { - throw new ShieldException("invalid system user"); + throw new ElasticsearchException("invalid system user"); } return SYSTEM; } diff --git a/src/main/java/org/elasticsearch/shield/action/ShieldActionFilter.java b/src/main/java/org/elasticsearch/shield/action/ShieldActionFilter.java index 84d61c52cfb..7cf5ee2bd87 100644 --- a/src/main/java/org/elasticsearch/shield/action/ShieldActionFilter.java +++ b/src/main/java/org/elasticsearch/shield/action/ShieldActionFilter.java @@ -25,7 +25,6 @@ import org.elasticsearch.shield.authz.AuthorizationException; import org.elasticsearch.shield.authz.AuthorizationService; import org.elasticsearch.shield.authz.Privilege; import org.elasticsearch.shield.crypto.CryptoService; -import org.elasticsearch.shield.crypto.SignatureException; import org.elasticsearch.shield.license.LicenseEventsNotifier; import org.elasticsearch.shield.license.LicenseService; @@ -142,9 +141,9 @@ public class ShieldActionFilter extends AbstractComponent implements ActionFilte return request; - } catch (SignatureException se) { + } catch (IllegalArgumentException|IllegalStateException e) { auditTrail.tamperedRequest(user, action, request); - throw new AuthorizationException("invalid request: " + se.getMessage()); + throw new AuthorizationException("invalid request: " + e.getMessage()); } } diff --git a/src/main/java/org/elasticsearch/shield/action/authc/cache/TransportClearRealmCacheAction.java b/src/main/java/org/elasticsearch/shield/action/authc/cache/TransportClearRealmCacheAction.java index 81ec380ad2c..d513bf65166 100644 --- a/src/main/java/org/elasticsearch/shield/action/authc/cache/TransportClearRealmCacheAction.java +++ b/src/main/java/org/elasticsearch/shield/action/authc/cache/TransportClearRealmCacheAction.java @@ -14,7 +14,6 @@ import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.shield.authc.Realm; -import org.elasticsearch.shield.authc.RealmMissingException; import org.elasticsearch.shield.authc.Realms; import org.elasticsearch.shield.authc.support.CachingUsernamePasswordRealm; import org.elasticsearch.threadpool.ThreadPool; @@ -73,7 +72,7 @@ public class TransportClearRealmCacheAction extends TransportNodesAction BASIC_AUTH_HEADER = Tuple.tuple("WWW-Authenticate", new String[]{"Basic realm=\"" + ShieldPlugin.NAME + "\""}); +public class AuthenticationException extends ElasticsearchException.WithRestHeadersException { + + public static final Map> HEADERS = Collections.singletonMap("WWW-Authenticate", Collections.singletonList("Basic realm=\"" + ShieldPlugin.NAME + "\"")); public AuthenticationException(String msg) { - super(msg, BASIC_AUTH_HEADER); + this(msg, null); } public AuthenticationException(String msg, Throwable cause) { - super(msg, cause, BASIC_AUTH_HEADER); + super(msg, cause, HEADERS); } @Override diff --git a/src/main/java/org/elasticsearch/shield/authc/RealmMissingException.java b/src/main/java/org/elasticsearch/shield/authc/RealmMissingException.java deleted file mode 100644 index 2e2dbb2d5b7..00000000000 --- a/src/main/java/org/elasticsearch/shield/authc/RealmMissingException.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.shield.authc; - -import org.elasticsearch.rest.RestStatus; -import org.elasticsearch.shield.ShieldException; - -/** - * - */ -public class RealmMissingException extends ShieldException { - - public RealmMissingException(String msg) { - super(msg); - } - - @Override - public RestStatus status() { - return RestStatus.NOT_FOUND; - } -} diff --git a/src/main/java/org/elasticsearch/shield/authc/Realms.java b/src/main/java/org/elasticsearch/shield/authc/Realms.java index 38bd4dea536..1e6969544c8 100644 --- a/src/main/java/org/elasticsearch/shield/authc/Realms.java +++ b/src/main/java/org/elasticsearch/shield/authc/Realms.java @@ -12,7 +12,6 @@ import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; -import org.elasticsearch.shield.ShieldSettingsException; import org.elasticsearch.shield.ShieldSettingsFilter; import org.elasticsearch.shield.authc.esusers.ESUsersRealm; @@ -75,11 +74,11 @@ public class Realms extends AbstractLifecycleComponent implements Iterab Settings realmSettings = realmsSettings.getAsSettings(name); String type = realmSettings.get("type"); if (type == null) { - throw new ShieldSettingsException("missing realm type for [" + name + "] realm"); + throw new IllegalArgumentException("missing realm type for [" + name + "] realm"); } Realm.Factory factory = factories.get(type); if (factory == null) { - throw new ShieldSettingsException("unknown realm type [" + type + "] set for realm [" + name + "]"); + throw new IllegalArgumentException("unknown realm type [" + type + "] set for realm [" + name + "]"); } factory.filterOutSensitiveSettings(name, settingsFilter); RealmConfig config = new RealmConfig(name, realmSettings, settings, env); @@ -93,7 +92,7 @@ public class Realms extends AbstractLifecycleComponent implements Iterab // this is an internal realm factory, let's make sure we didn't already registered one // (there can only be one instance of an internal realm) if (internalTypes.contains(type)) { - throw new ShieldSettingsException("multiple [" + type + "] realms are configured. [" + type + + throw new IllegalArgumentException("multiple [" + type + "] realms are configured. [" + type + "] is an internal realm and therefore there can only be one such realm configured"); } internalTypes.add(type); @@ -124,11 +123,11 @@ public class Realms extends AbstractLifecycleComponent implements Iterab Settings realmSettings = realmsSettings.getAsSettings(name); String type = realmSettings.get("type"); if (type == null) { - throw new ShieldSettingsException("missing realm type for [" + name + "] realm"); + throw new IllegalArgumentException("missing realm type for [" + name + "] realm"); } if (type.equals(realmType)) { if (result != null) { - throw new ShieldSettingsException("multiple [" + realmType + "] realms are configured. only one [" + realmType + "] may be configured"); + throw new IllegalArgumentException("multiple [" + realmType + "] realms are configured. only one [" + realmType + "] may be configured"); } result = realmSettings; } diff --git a/src/main/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectoryException.java b/src/main/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectoryException.java deleted file mode 100644 index fb6ecea8ac4..00000000000 --- a/src/main/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectoryException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.shield.authc.activedirectory; - -import org.elasticsearch.shield.ShieldException; - -/** - * ActiveDirectoryExceptions typically wrap {@link com.unboundid.ldap.sdk.LDAPException}, and have an additional - * parameter of DN attached to each message. - */ -public class ActiveDirectoryException extends ShieldException { - - public ActiveDirectoryException(String msg){ - super(msg); - } - - public ActiveDirectoryException(String msg, Throwable cause){ - super(msg, cause); - } - - public ActiveDirectoryException(String msg, String dn) { - this(msg, dn, null); - } - - public ActiveDirectoryException(String msg, String dn, Throwable cause) { - super( msg + "; DN=[" + dn + "]", cause); - } -} diff --git a/src/main/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectoryGroupsResolver.java b/src/main/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectoryGroupsResolver.java index a18a99fbc5c..3435491ff5d 100644 --- a/src/main/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectoryGroupsResolver.java +++ b/src/main/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectoryGroupsResolver.java @@ -12,6 +12,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.shield.authc.AuthenticationException; import org.elasticsearch.shield.authc.ldap.support.LdapSearchScope; import org.elasticsearch.shield.authc.ldap.support.LdapSession.GroupsResolver; @@ -43,7 +44,8 @@ public class ActiveDirectoryGroupsResolver implements GroupsResolver { try { results = search(connection, searchRequest, logger); } catch (LDAPException e) { - throw new ActiveDirectoryException("failed to fetch AD groups", userDn, e); + // TODO parameterize + throw new AuthenticationException("failed to fetch AD groups for DN [" + userDn + "]", e); } ImmutableList.Builder groups = ImmutableList.builder(); @@ -70,7 +72,7 @@ public class ActiveDirectoryGroupsResolver implements GroupsResolver { } return Filter.createORFilter(orFilters); } catch (LDAPException e) { - throw new ActiveDirectoryException("failed to fetch AD groups", userDn, e); + throw new AuthenticationException("failed to fetch AD groups for DN [" + userDn + "]", e); } } diff --git a/src/main/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectorySessionFactory.java b/src/main/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectorySessionFactory.java index b216864afb3..b331e12b8d2 100644 --- a/src/main/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectorySessionFactory.java +++ b/src/main/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectorySessionFactory.java @@ -9,8 +9,8 @@ import com.google.common.primitives.Ints; import com.unboundid.ldap.sdk.*; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.shield.ShieldSettingsException; import org.elasticsearch.shield.ShieldSettingsFilter; +import org.elasticsearch.shield.authc.AuthenticationException; import org.elasticsearch.shield.authc.RealmConfig; import org.elasticsearch.shield.authc.ldap.support.LdapSearchScope; import org.elasticsearch.shield.authc.ldap.support.LdapSession; @@ -21,6 +21,8 @@ import org.elasticsearch.shield.ssl.ClientSSLService; import javax.net.SocketFactory; +import java.io.IOException; + import static org.elasticsearch.shield.authc.ldap.support.LdapUtils.createFilter; import static org.elasticsearch.shield.authc.ldap.support.LdapUtils.search; @@ -52,7 +54,7 @@ public class ActiveDirectorySessionFactory extends SessionFactory { Settings settings = config.settings(); domainName = settings.get(AD_DOMAIN_NAME_SETTING); if (domainName == null) { - throw new ShieldSettingsException("missing [" + AD_DOMAIN_NAME_SETTING + "] setting for active directory"); + throw new IllegalArgumentException("missing [" + AD_DOMAIN_NAME_SETTING + "] setting for active directory"); } String domainDN = buildDnFromDomain(domainName); userSearchDN = settings.get(AD_USER_SEARCH_BASEDN_SETTING, domainDN); @@ -93,13 +95,13 @@ public class ActiveDirectorySessionFactory extends SessionFactory { * @return An authenticated */ @Override - public LdapSession session(String userName, SecuredString password) { + public LdapSession session(String userName, SecuredString password) throws Exception { LDAPConnection connection; try { connection = ldapServerSet.getConnection(); } catch (LDAPException e) { - throw new ActiveDirectoryException("failed to connect to any active directory servers", e); + throw new IOException("failed to connect to any active directory servers", e); } String userPrincipal = userName + "@" + domainName; @@ -110,15 +112,16 @@ public class ActiveDirectorySessionFactory extends SessionFactory { SearchResult results = search(connection, searchRequest, logger); int numResults = results.getEntryCount(); if (numResults > 1) { - throw new ActiveDirectoryException("search for user [" + userName + "] by principle name yielded multiple results"); + throw new IllegalStateException("search for user [" + userName + "] by principle name yielded multiple results"); } else if (numResults < 1) { - throw new ActiveDirectoryException("search for user [" + userName + "] by principle name yielded no results"); + throw new IllegalStateException("search for user [" + userName + "] by principle name yielded no results"); } String dn = results.getSearchEntries().get(0).getDN(); return new LdapSession(connectionLogger, connection, dn, groupResolver, timeout); } catch (LDAPException e) { connection.close(); - throw new ActiveDirectoryException("unable to authenticate user [" + userName + "] to active directory domain [" + domainName + "]", e); + // TODO think more about this exception... + throw new AuthenticationException("unable to authenticate user [" + userName + "] to active directory domain [" + domainName + "]", e); } } diff --git a/src/main/java/org/elasticsearch/shield/authc/esusers/FileUserPasswdStore.java b/src/main/java/org/elasticsearch/shield/authc/esusers/FileUserPasswdStore.java index 050fa043adf..0d32ca60b9e 100644 --- a/src/main/java/org/elasticsearch/shield/authc/esusers/FileUserPasswdStore.java +++ b/src/main/java/org/elasticsearch/shield/authc/esusers/FileUserPasswdStore.java @@ -12,7 +12,6 @@ import org.elasticsearch.common.inject.internal.Nullable; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; -import org.elasticsearch.shield.ShieldException; import org.elasticsearch.shield.ShieldPlugin; import org.elasticsearch.shield.authc.RealmConfig; import org.elasticsearch.shield.authc.support.Hasher; @@ -129,7 +128,7 @@ public class FileUserPasswdStore { try { lines = Files.readAllLines(path, Charsets.UTF_8); } catch (IOException ioe) { - throw new ShieldException("could not read users file [" + path.toAbsolutePath() + "]", ioe); + throw new IllegalStateException("could not read users file [" + path.toAbsolutePath() + "]", ioe); } ImmutableMap.Builder users = ImmutableMap.builder(); diff --git a/src/main/java/org/elasticsearch/shield/authc/ldap/LdapRealm.java b/src/main/java/org/elasticsearch/shield/authc/ldap/LdapRealm.java index 310f14e106f..57f79205b8a 100644 --- a/src/main/java/org/elasticsearch/shield/authc/ldap/LdapRealm.java +++ b/src/main/java/org/elasticsearch/shield/authc/ldap/LdapRealm.java @@ -8,7 +8,6 @@ package org.elasticsearch.shield.authc.ldap; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.rest.RestController; -import org.elasticsearch.shield.ShieldSettingsException; import org.elasticsearch.shield.ShieldSettingsFilter; import org.elasticsearch.shield.authc.RealmConfig; import org.elasticsearch.shield.authc.ldap.support.AbstractLdapRealm; @@ -56,7 +55,7 @@ public class LdapRealm extends AbstractLdapRealm { Settings searchSettings = config.settings().getAsSettings("user_search"); if (!searchSettings.names().isEmpty()) { if (config.settings().getAsArray(LdapSessionFactory.USER_DN_TEMPLATES_SETTING).length > 0) { - throw new ShieldSettingsException("settings were found for both user search and user template modes of operation. Please remove the settings for the\n" + throw new IllegalArgumentException("settings were found for both user search and user template modes of operation. Please remove the settings for the\n" + "mode you do not wish to use. For more details refer to the ldap authentication section of the Shield guide."); } return new LdapUserSearchSessionFactory(config, clientSSLService); diff --git a/src/main/java/org/elasticsearch/shield/authc/ldap/LdapSessionFactory.java b/src/main/java/org/elasticsearch/shield/authc/ldap/LdapSessionFactory.java index 4e60524fbff..56512174c89 100644 --- a/src/main/java/org/elasticsearch/shield/authc/ldap/LdapSessionFactory.java +++ b/src/main/java/org/elasticsearch/shield/authc/ldap/LdapSessionFactory.java @@ -7,7 +7,7 @@ package org.elasticsearch.shield.authc.ldap; import com.unboundid.ldap.sdk.*; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.shield.ShieldSettingsException; +import org.elasticsearch.shield.authc.AuthenticationException; import org.elasticsearch.shield.authc.RealmConfig; import org.elasticsearch.shield.authc.ldap.support.LdapSession; import org.elasticsearch.shield.authc.ldap.support.LdapSession.GroupsResolver; @@ -16,6 +16,7 @@ import org.elasticsearch.shield.authc.support.SecuredString; import org.elasticsearch.shield.ssl.ClientSSLService; import javax.net.SocketFactory; +import java.io.IOException; import java.text.MessageFormat; import java.util.Locale; @@ -40,7 +41,7 @@ public class LdapSessionFactory extends SessionFactory { Settings settings = config.settings(); userDnTemplates = settings.getAsArray(USER_DN_TEMPLATES_SETTING); if (userDnTemplates == null) { - throw new ShieldSettingsException("missing required LDAP setting [" + USER_DN_TEMPLATES_SETTING + "]"); + throw new IllegalArgumentException("missing required LDAP setting [" + USER_DN_TEMPLATES_SETTING + "]"); } this.ldapServerSet = serverSet(config.settings(), sslService); groupResolver = groupResolver(settings); @@ -50,7 +51,7 @@ public class LdapSessionFactory extends SessionFactory { // Parse LDAP urls String[] ldapUrls = settings.getAsArray(URLS_SETTING); if (ldapUrls == null || ldapUrls.length == 0) { - throw new ShieldSettingsException("missing required LDAP setting [" + URLS_SETTING + "]"); + throw new IllegalArgumentException("missing required LDAP setting [" + URLS_SETTING + "]"); } LDAPServers servers = new LDAPServers(ldapUrls); LDAPConnectionOptions options = connectionOptions(settings); @@ -78,13 +79,13 @@ public class LdapSessionFactory extends SessionFactory { * @return authenticated exception */ @Override - public LdapSession session(String username, SecuredString password) { + public LdapSession session(String username, SecuredString password) throws Exception { LDAPConnection connection; try { connection = ldapServerSet.getConnection(); } catch (LDAPException e) { - throw new ShieldLdapException("failed to connect to any LDAP servers", e); + throw new IOException("failed to connect to any LDAP servers", e); } LDAPException lastException = null; @@ -106,7 +107,7 @@ public class LdapSessionFactory extends SessionFactory { } connection.close(); - throw new ShieldLdapException("failed LDAP authentication", lastException); + throw new AuthenticationException("failed LDAP authentication", lastException); } /** diff --git a/src/main/java/org/elasticsearch/shield/authc/ldap/LdapUserSearchSessionFactory.java b/src/main/java/org/elasticsearch/shield/authc/ldap/LdapUserSearchSessionFactory.java index a31aa02a02f..edd0e14cc13 100644 --- a/src/main/java/org/elasticsearch/shield/authc/ldap/LdapUserSearchSessionFactory.java +++ b/src/main/java/org/elasticsearch/shield/authc/ldap/LdapUserSearchSessionFactory.java @@ -7,11 +7,12 @@ package org.elasticsearch.shield.authc.ldap; import com.google.common.primitives.Ints; import com.unboundid.ldap.sdk.*; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.shield.ShieldSettingsException; import org.elasticsearch.shield.ShieldSettingsFilter; +import org.elasticsearch.shield.authc.AuthenticationException; import org.elasticsearch.shield.authc.RealmConfig; import org.elasticsearch.shield.authc.ldap.support.LdapSearchScope; import org.elasticsearch.shield.authc.ldap.support.LdapSession; @@ -21,6 +22,7 @@ import org.elasticsearch.shield.authc.support.SecuredString; import org.elasticsearch.shield.ssl.ClientSSLService; import javax.net.SocketFactory; +import java.io.IOException; import java.util.Locale; import static com.unboundid.ldap.sdk.Filter.createEqualityFilter; @@ -46,7 +48,7 @@ public class LdapUserSearchSessionFactory extends SessionFactory { Settings settings = config.settings(); userSearchBaseDn = settings.get("user_search.base_dn"); if (userSearchBaseDn == null) { - throw new ShieldSettingsException("user_search base_dn must be specified"); + throw new IllegalArgumentException("user_search base_dn must be specified"); } scope = LdapSearchScope.resolve(settings.get("user_search.scope"), LdapSearchScope.SUB_TREE); userAttribute = settings.get("user_search.attribute", DEFAULT_USERNAME_ATTRIBUTE); @@ -74,7 +76,7 @@ public class LdapUserSearchSessionFactory extends SessionFactory { String entryDn = settings.get("user_search.pool.health_check.dn", (bindRequest == null) ? null : bindRequest.getBindDN()); if (entryDn == null) { pool.close(); - throw new ShieldSettingsException("[bind_dn] has not been specified so a value must be specified for [user_search.pool.health_check.dn] or [user_search.pool.health_check.enabled] must be set to false"); + throw new IllegalArgumentException("[bind_dn] has not been specified so a value must be specified for [user_search.pool.health_check.dn] or [user_search.pool.health_check.enabled] must be set to false"); } long healthCheckInterval = settings.getAsTime("user_search.pool.health_check.interval", DEFAULT_HEALTH_CHECK_INTERVAL).millis(); // Checks the status of the LDAP connection at a specified interval in the background. We do not check on @@ -86,7 +88,7 @@ public class LdapUserSearchSessionFactory extends SessionFactory { } return pool; } catch (LDAPException e) { - throw new ShieldLdapException("unable to connect to any LDAP servers", e); + throw new ElasticsearchException("unable to connect to any LDAP servers", e); } } @@ -103,7 +105,7 @@ public class LdapUserSearchSessionFactory extends SessionFactory { // Parse LDAP urls String[] ldapUrls = settings.getAsArray(URLS_SETTING); if (ldapUrls == null || ldapUrls.length == 0) { - throw new ShieldSettingsException("missing required LDAP setting [" + URLS_SETTING + "]"); + throw new IllegalArgumentException("missing required LDAP setting [" + URLS_SETTING + "]"); } LDAPServers servers = new LDAPServers(ldapUrls); LDAPConnectionOptions options = connectionOptions(settings); @@ -124,34 +126,34 @@ public class LdapUserSearchSessionFactory extends SessionFactory { } @Override - public LdapSession session(String user, SecuredString password) { + public LdapSession session(String user, SecuredString password) throws Exception { SearchRequest request = new SearchRequest(userSearchBaseDn, scope.scope(), createEqualityFilter(userAttribute, encodeValue(user)), Strings.EMPTY_ARRAY); request.setTimeLimitSeconds(Ints.checkedCast(timeout.seconds())); try { SearchResultEntry entry = searchForEntry(connectionPool, request, logger); if (entry == null) { - throw new ShieldLdapException("failed to find user [" + user + "] with search base [" + userSearchBaseDn + "] scope [" + scope.toString().toLowerCase(Locale.ENGLISH) +"]"); + throw new AuthenticationException("failed to find user [" + user + "] with search base [" + userSearchBaseDn + "] scope [" + scope.toString().toLowerCase(Locale.ENGLISH) +"]"); } String dn = entry.getDN(); tryBind(dn, password); return new LdapSession(logger, connectionPool, dn, groupResolver, timeout); } catch (LDAPException e) { - throw new ShieldLdapException("failed to authenticate user [" + user + "]", e); + throw new AuthenticationException("failed to authenticate user [" + user + "]", e); } } - private void tryBind(String dn, SecuredString password) { + private void tryBind(String dn, SecuredString password) throws IOException { LDAPConnection bindConnection; try { bindConnection = serverSet.getConnection(); } catch (LDAPException e) { - throw new ShieldLdapException("unable to connect to any LDAP servers for bind", e); + throw new IOException("unable to connect to any LDAP servers for bind", e); } try { bindConnection.bind(dn, new String(password.internalChars())); } catch (LDAPException e) { - throw new ShieldLdapException("failed LDAP authentication", dn, e); + throw new AuthenticationException("failed LDAP authentication for DN [" + dn + "]", e); } finally { bindConnection.close(); } diff --git a/src/main/java/org/elasticsearch/shield/authc/ldap/SearchGroupsResolver.java b/src/main/java/org/elasticsearch/shield/authc/ldap/SearchGroupsResolver.java index 56d07c165bb..ad89481590b 100644 --- a/src/main/java/org/elasticsearch/shield/authc/ldap/SearchGroupsResolver.java +++ b/src/main/java/org/elasticsearch/shield/authc/ldap/SearchGroupsResolver.java @@ -11,7 +11,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.shield.ShieldSettingsException; +import org.elasticsearch.shield.authc.AuthenticationException; import org.elasticsearch.shield.authc.ldap.support.LdapSearchScope; import org.elasticsearch.shield.authc.ldap.support.LdapSession.GroupsResolver; @@ -37,7 +37,7 @@ class SearchGroupsResolver implements GroupsResolver { public SearchGroupsResolver(Settings settings) { baseDn = settings.get("base_dn"); if (baseDn == null) { - throw new ShieldSettingsException("base_dn must be specified"); + throw new IllegalArgumentException("base_dn must be specified"); } filter = settings.get("filter", GROUP_SEARCH_DEFAULT_FILTER); userAttribute = settings.get("user_attribute"); @@ -57,7 +57,7 @@ class SearchGroupsResolver implements GroupsResolver { groups.add(entry.getDN()); } } catch (LDAPException e) { - throw new ShieldLdapException("could not search for LDAP groups", userDn, e); + throw new AuthenticationException("could not search for LDAP groups for DN [" + userDn + "]", e); } return groups; @@ -70,11 +70,11 @@ class SearchGroupsResolver implements GroupsResolver { SearchResultEntry results = searchForEntry(connection, request, logger); Attribute attribute = results.getAttribute(userAttribute); if (attribute == null) { - throw new ShieldLdapException("no results returned for attribute [" + userAttribute + "]", userDn); + throw new AuthenticationException("no results returned for DN [" + userDn + "] attribute [" + userAttribute + "]"); } return attribute.getValue(); } catch (LDAPException e) { - throw new ShieldLdapException("could not retrieve attribute [" + userAttribute + "]", userDn, e); + throw new AuthenticationException("could not retrieve attribute [" + userAttribute + "] for DN [" + userDn + "]", e); } } } diff --git a/src/main/java/org/elasticsearch/shield/authc/ldap/ShieldLdapException.java b/src/main/java/org/elasticsearch/shield/authc/ldap/ShieldLdapException.java deleted file mode 100644 index 9287c54812a..00000000000 --- a/src/main/java/org/elasticsearch/shield/authc/ldap/ShieldLdapException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.shield.authc.ldap; - -import org.elasticsearch.shield.ShieldException; - -/** - * LdapExceptions typically wrap {@link com.unboundid.ldap.sdk.LDAPException}, and have an additional - * parameter of DN attached to each message. - */ -public class ShieldLdapException extends ShieldException { - - public ShieldLdapException(String msg){ - super(msg); - } - - public ShieldLdapException(String msg, Throwable cause){ - super(msg, cause); - } - - public ShieldLdapException(String msg, String dn) { - this(msg, dn, null); - } - - public ShieldLdapException(String msg, String dn, Throwable cause) { - super( msg + "; LDAP DN=[" + dn + "]", cause); - } -} diff --git a/src/main/java/org/elasticsearch/shield/authc/ldap/UserAttributeGroupsResolver.java b/src/main/java/org/elasticsearch/shield/authc/ldap/UserAttributeGroupsResolver.java index e3a34a8aa57..07f9e4e41f5 100644 --- a/src/main/java/org/elasticsearch/shield/authc/ldap/UserAttributeGroupsResolver.java +++ b/src/main/java/org/elasticsearch/shield/authc/ldap/UserAttributeGroupsResolver.java @@ -7,6 +7,7 @@ package org.elasticsearch.shield.authc.ldap; import com.google.common.primitives.Ints; import com.unboundid.ldap.sdk.*; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; @@ -47,7 +48,7 @@ class UserAttributeGroupsResolver implements GroupsResolver { String[] values = attributeReturned.getValues(); return Arrays.asList(values); } catch (LDAPException e) { - throw new ShieldLdapException("could not look up group attributes for user", userDn, e); + throw new ElasticsearchException("could not look up group attributes for DN [{}]", e, userDn); } } } diff --git a/src/main/java/org/elasticsearch/shield/authc/ldap/support/LdapSearchScope.java b/src/main/java/org/elasticsearch/shield/authc/ldap/support/LdapSearchScope.java index cb7221e8243..b3e28bf652a 100644 --- a/src/main/java/org/elasticsearch/shield/authc/ldap/support/LdapSearchScope.java +++ b/src/main/java/org/elasticsearch/shield/authc/ldap/support/LdapSearchScope.java @@ -6,7 +6,6 @@ package org.elasticsearch.shield.authc.ldap.support; import com.unboundid.ldap.sdk.SearchScope; -import org.elasticsearch.shield.authc.ldap.ShieldLdapException; import java.util.Locale; @@ -39,7 +38,7 @@ public enum LdapSearchScope { case "one_level" : return ONE_LEVEL; case "sub_tree" : return SUB_TREE; default: - throw new ShieldLdapException("Unknown search scope [" + scope + "]"); + throw new IllegalArgumentException("Unknown search scope [" + scope + "]"); } } } diff --git a/src/main/java/org/elasticsearch/shield/authc/ldap/support/LdapUtils.java b/src/main/java/org/elasticsearch/shield/authc/ldap/support/LdapUtils.java index dd2a4af98f6..290d9d8fd50 100644 --- a/src/main/java/org/elasticsearch/shield/authc/ldap/support/LdapUtils.java +++ b/src/main/java/org/elasticsearch/shield/authc/ldap/support/LdapUtils.java @@ -7,7 +7,6 @@ package org.elasticsearch.shield.authc.ldap.support; import com.unboundid.ldap.sdk.*; import org.elasticsearch.common.logging.ESLogger; -import org.elasticsearch.shield.authc.ldap.ShieldLdapException; import javax.naming.ldap.Rdn; import java.text.MessageFormat; @@ -24,7 +23,7 @@ public final class LdapUtils { try { return new DN(dn); } catch (LDAPException e) { - throw new ShieldLdapException("invalid DN [" + dn + "]", e); + throw new IllegalArgumentException("invalid DN [" + dn + "]", e); } } diff --git a/src/main/java/org/elasticsearch/shield/authc/ldap/support/SessionFactory.java b/src/main/java/org/elasticsearch/shield/authc/ldap/support/SessionFactory.java index 0663718c40b..70afbc82dcf 100644 --- a/src/main/java/org/elasticsearch/shield/authc/ldap/support/SessionFactory.java +++ b/src/main/java/org/elasticsearch/shield/authc/ldap/support/SessionFactory.java @@ -14,7 +14,6 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.shield.ShieldSettingsException; import org.elasticsearch.shield.authc.RealmConfig; import org.elasticsearch.shield.authc.support.SecuredString; @@ -71,8 +70,10 @@ public abstract class SessionFactory { * * @param user The name of the user to authenticate the connection with. * @param password The password of the user + * @return LdapSession representing a connection to LDAP as the provided user + * @throws Exception if an error occurred when creating the session */ - public abstract LdapSession session(String user, SecuredString password); + public abstract LdapSession session(String user, SecuredString password) throws Exception; protected static LDAPConnectionOptions connectionOptions(Settings settings) { LDAPConnectionOptions options = new LDAPConnectionOptions(); @@ -103,7 +104,7 @@ public abstract class SessionFactory { addresses[i] = url.getHost(); ports[i] = url.getPort(); } catch (LDAPException e) { - throw new ShieldSettingsException("unable to parse configured LDAP url [" + urls[i] +"]", e); + throw new IllegalArgumentException("unable to parse configured LDAP url [" + urls[i] +"]", e); } } } @@ -133,7 +134,7 @@ public abstract class SessionFactory { if (!allSecure && !allClear) { //No mixing is allowed because we use the same socketfactory - throw new ShieldSettingsException("configured LDAP protocols are not all equal " + + throw new IllegalArgumentException("configured LDAP protocols are not all equal " + "(ldaps://.. and ldap://..): [" + Strings.arrayToCommaDelimitedString(ldapUrls) + "]"); } diff --git a/src/main/java/org/elasticsearch/shield/authc/pki/PkiRealm.java b/src/main/java/org/elasticsearch/shield/authc/pki/PkiRealm.java index b77e760312d..2b0633f84d6 100644 --- a/src/main/java/org/elasticsearch/shield/authc/pki/PkiRealm.java +++ b/src/main/java/org/elasticsearch/shield/authc/pki/PkiRealm.java @@ -11,7 +11,6 @@ import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.shield.ShieldSettingsException; import org.elasticsearch.shield.ShieldSettingsFilter; import org.elasticsearch.shield.User; import org.elasticsearch.shield.authc.AuthenticationToken; @@ -144,7 +143,7 @@ public class PkiRealm extends Realm { String password = settings.get("truststore.password"); if (password == null) { - throw new ShieldSettingsException("no truststore password configured"); + throw new IllegalArgumentException("no truststore password configured"); } String trustStoreAlgorithm = settings.get("truststore.algorithm", System.getProperty("ssl.TrustManagerFactory.algorithm", TrustManagerFactory.getDefaultAlgorithm())); @@ -159,7 +158,7 @@ public class PkiRealm extends Realm { trustFactory.init(ks); trustManagers = trustFactory.getTrustManagers(); } catch (Exception e) { - throw new ShieldSettingsException("failed to load specified truststore", e); + throw new IllegalArgumentException("failed to load specified truststore", e); } List trustManagerList = new ArrayList<>(); @@ -170,7 +169,7 @@ public class PkiRealm extends Realm { } if (trustManagerList.isEmpty()) { - throw new ShieldSettingsException("no valid certificates found in truststore"); + throw new IllegalArgumentException("no valid certificates found in truststore"); } return trustManagerList.toArray(new X509TrustManager[trustManagerList.size()]); diff --git a/src/main/java/org/elasticsearch/shield/authc/support/DnRoleMapper.java b/src/main/java/org/elasticsearch/shield/authc/support/DnRoleMapper.java index 99d5a5c66f1..a1bc524e4be 100644 --- a/src/main/java/org/elasticsearch/shield/authc/support/DnRoleMapper.java +++ b/src/main/java/org/elasticsearch/shield/authc/support/DnRoleMapper.java @@ -14,7 +14,6 @@ import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.shield.ShieldPlugin; -import org.elasticsearch.shield.ShieldSettingsException; import org.elasticsearch.shield.authc.RealmConfig; import org.elasticsearch.watcher.FileChangesListener; import org.elasticsearch.watcher.FileWatcher; @@ -135,7 +134,7 @@ public class DnRoleMapper { return ImmutableMap.copyOf(dnToRoles); } catch (IOException e) { - throw new ShieldSettingsException("could not read realm [" + realmType + "/" + realmName + "] role mappings file [" + path.toAbsolutePath() + "]", e); + throw new ElasticsearchException("could not read realm [" + realmType + "/" + realmName + "] role mappings file [" + path.toAbsolutePath() + "]", e); } } diff --git a/src/main/java/org/elasticsearch/shield/authc/support/Hasher.java b/src/main/java/org/elasticsearch/shield/authc/support/Hasher.java index 1b6ffd9a3ab..ade6bd0aabf 100644 --- a/src/main/java/org/elasticsearch/shield/authc/support/Hasher.java +++ b/src/main/java/org/elasticsearch/shield/authc/support/Hasher.java @@ -7,8 +7,6 @@ package org.elasticsearch.shield.authc.support; import com.google.common.base.Charsets; import org.elasticsearch.common.Base64; -import org.elasticsearch.shield.ShieldException; -import org.elasticsearch.shield.ShieldSettingsException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -261,7 +259,7 @@ public enum Hasher { public static Hasher resolve(String name) { Hasher hasher = resolve(name, null); if (hasher == null) { - throw new ShieldSettingsException("unknown hash function [" + name + "]"); + throw new IllegalArgumentException("unknown hash function [" + name + "]"); } return hasher; } @@ -278,7 +276,7 @@ public enum Hasher { try { digest = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { - throw new ShieldException("unsupported digest algorithm [MD5]. Please verify you are running on Java 7 or above", e); + throw new IllegalStateException("unsupported digest algorithm [MD5]. Please verify you are running on Java 7 or above", e); } } @@ -288,7 +286,7 @@ public enum Hasher { md5.reset(); return md5; } catch (CloneNotSupportedException e) { - throw new ShieldException("could not create MD5 digest", e); + throw new IllegalStateException("could not create MD5 digest", e); } } } @@ -301,7 +299,7 @@ public enum Hasher { try { digest = MessageDigest.getInstance("SHA-1"); } catch (NoSuchAlgorithmException e) { - throw new ShieldException("unsupported digest algorithm [SHA-1]", e); + throw new IllegalStateException("unsupported digest algorithm [SHA-1]", e); } } @@ -311,7 +309,7 @@ public enum Hasher { sha1.reset(); return sha1; } catch (CloneNotSupportedException e) { - throw new ShieldException("could not create SHA-1 digest", e); + throw new IllegalStateException("could not create SHA-1 digest", e); } } } @@ -324,7 +322,7 @@ public enum Hasher { try { digest = MessageDigest.getInstance("SHA-256"); } catch (NoSuchAlgorithmException e) { - throw new ShieldException("unsupported digest algorithm [SHA-256]. Please verify you are running on Java 7 or above", e); + throw new IllegalStateException("unsupported digest algorithm [SHA-256]. Please verify you are running on Java 7 or above", e); } } @@ -334,7 +332,7 @@ public enum Hasher { sha.reset(); return sha; } catch (CloneNotSupportedException e) { - throw new ShieldException("could not create [SHA-256] digest", e); + throw new IllegalStateException("could not create [SHA-256] digest", e); } } } diff --git a/src/main/java/org/elasticsearch/shield/authz/AuthorizationException.java b/src/main/java/org/elasticsearch/shield/authz/AuthorizationException.java index 16ffb8e6ce9..433fbf1ab09 100644 --- a/src/main/java/org/elasticsearch/shield/authz/AuthorizationException.java +++ b/src/main/java/org/elasticsearch/shield/authz/AuthorizationException.java @@ -5,13 +5,11 @@ */ package org.elasticsearch.shield.authz; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.rest.RestStatus; -import org.elasticsearch.shield.ShieldException; -/** - * - */ -public class AuthorizationException extends ShieldException { +// FIXME move this class to core and change package... +public class AuthorizationException extends ElasticsearchException { public AuthorizationException(String msg) { super(msg); diff --git a/src/main/java/org/elasticsearch/shield/authz/Privilege.java b/src/main/java/org/elasticsearch/shield/authz/Privilege.java index e7ac4e7c4de..8e628870e54 100644 --- a/src/main/java/org/elasticsearch/shield/authz/Privilege.java +++ b/src/main/java/org/elasticsearch/shield/authz/Privilege.java @@ -22,7 +22,6 @@ import org.elasticsearch.action.search.MultiSearchAction; import org.elasticsearch.action.search.SearchAction; import org.elasticsearch.action.suggest.SuggestAction; import org.elasticsearch.common.Strings; -import org.elasticsearch.shield.ShieldException; import org.elasticsearch.shield.support.AutomatonPredicate; import org.elasticsearch.shield.support.Automatons; @@ -208,12 +207,12 @@ public abstract class Privilege

> { public static void addCustom(String name, String... actionPatterns) { for (String pattern : actionPatterns) { if (!Index.ACTION_MATCHER.apply(pattern)) { - throw new ShieldException("cannot register custom index privilege [" + name + "]. index action must follow the 'indices:*' format"); + throw new IllegalArgumentException("cannot register custom index privilege [" + name + "]. index action must follow the 'indices:*' format"); } } Index custom = new Index(name, actionPatterns); if (values.contains(custom)) { - throw new ShieldException("cannot register custom index privilege [" + name + "] as it already exists."); + throw new IllegalArgumentException("cannot register custom index privilege [" + name + "] as it already exists."); } values.add(custom); } @@ -316,12 +315,12 @@ public abstract class Privilege

> { public static void addCustom(String name, String... actionPatterns) { for (String pattern : actionPatterns) { if (!Cluster.ACTION_MATCHER.apply(pattern)) { - throw new ShieldException("cannot register custom cluster privilege [" + name + "]. cluster aciton must follow the 'cluster:*' format"); + throw new IllegalArgumentException("cannot register custom cluster privilege [" + name + "]. cluster aciton must follow the 'cluster:*' format"); } } Cluster custom = new Cluster(name, actionPatterns); if (values.contains(custom)) { - throw new ShieldException("cannot register custom cluster privilege [" + name + "] as it already exists."); + throw new IllegalArgumentException("cannot register custom cluster privilege [" + name + "] as it already exists."); } values.add(custom); } diff --git a/src/main/java/org/elasticsearch/shield/crypto/InternalCryptoService.java b/src/main/java/org/elasticsearch/shield/crypto/InternalCryptoService.java index dfb2c864296..c883d8aee85 100644 --- a/src/main/java/org/elasticsearch/shield/crypto/InternalCryptoService.java +++ b/src/main/java/org/elasticsearch/shield/crypto/InternalCryptoService.java @@ -12,9 +12,7 @@ import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; -import org.elasticsearch.shield.ShieldException; import org.elasticsearch.shield.ShieldPlugin; -import org.elasticsearch.shield.ShieldSettingsException; import org.elasticsearch.shield.authc.support.CharArrays; import org.elasticsearch.watcher.FileChangesListener; import org.elasticsearch.watcher.FileWatcher; @@ -82,15 +80,16 @@ public class InternalCryptoService extends AbstractLifecycleComponent(listeners); this.encryptionAlgorithm = settings.get("shield.encryption.algorithm", DEFAULT_ENCRYPTION_ALGORITHM); this.keyLength = settings.getAsInt("shield.encryption_key.length", DEFAULT_KEY_LENGTH); - if (keyLength % 8 != 0) { - throw new ShieldSettingsException("invalid key length [" + keyLength + "]. value must be a multiple of 8"); - } this.ivLength = keyLength / 8; this.keyAlgorithm = settings.get("shield.encryption_key.algorithm", DEFAULT_KEY_ALGORITH); } @Override protected void doStart() throws ElasticsearchException { + if (keyLength % 8 != 0) { + throw new IllegalArgumentException("invalid key length [" + keyLength + "]. value must be a multiple of 8"); + } + keyFile = resolveSystemKey(settings, env); systemKey = readSystemKey(keyFile); encryptionKey = encryptionKey(systemKey, keyLength, keyAlgorithm); @@ -131,7 +130,7 @@ public class InternalCryptoService extends AbstractLifecycleComponent= maxTries) { - throw new ShieldException("Failed to start server bootstrap [" + tries + "] times, stopping", t); + throw new RuntimeException("Failed to start server bootstrap [" + tries + "] times, stopping", t); } tries++; }