public static boolean isTrustedClusterRequest(final ThreadContext context) { return context.getTransient(ConfigConstants.SG_SSL_TRANSPORT_TRUSTED_CLUSTER_REQUEST) == Boolean.TRUE; } }
private ThreadContext newThreadContext(String sslPrincipal) { ThreadContext threadContext = new ThreadContext(Settings.EMPTY); threadContext.putTransient(ConfigConstants.SG_SSL_PRINCIPAL, sslPrincipal); return threadContext; }
private void putInitialActionClassHeader(String initialActionClassValue, String resolvedActionClass) { if(initialActionClassValue == null) { if(getThreadContext().getHeader(ConfigConstants.SG_INITIAL_ACTION_CLASS_HEADER) == null) { getThreadContext().putHeader(ConfigConstants.SG_INITIAL_ACTION_CLASS_HEADER, resolvedActionClass); } } else { if(getThreadContext().getHeader(ConfigConstants.SG_INITIAL_ACTION_CLASS_HEADER) == null) { getThreadContext().putHeader(ConfigConstants.SG_INITIAL_ACTION_CLASS_HEADER, initialActionClassValue); } } }
@Override protected void addAdditionalContextValues(final String action, final TransportRequest request, final X509Certificate[] localCerts, final X509Certificate[] peerCerts, final String principal) throws Exception { boolean isInterClusterRequest = requestEvalProvider.isInterClusterRequest(request, localCerts, peerCerts, principal); if (isInterClusterRequest) { boolean fromTn = Boolean.parseBoolean(getThreadContext().getHeader("_sg_header_tn")); if(fromTn || cs.getClusterName().value().equals(getThreadContext().getHeader("_sg_remotecn"))) { if (log.isTraceEnabled() && !action.startsWith("internal:")) { log.trace("Is inter cluster request ({}/{}/{})", action, request.getClass(), request.remoteAddress()); } getThreadContext().putTransient(ConfigConstants.SG_SSL_TRANSPORT_INTERCLUSTER_REQUEST, Boolean.TRUE); } else { getThreadContext().putTransient(ConfigConstants.SG_SSL_TRANSPORT_TRUSTED_CLUSTER_REQUEST, Boolean.TRUE); } } else { if (log.isTraceEnabled()) { log.trace("Is not an inter cluster request"); } } super.addAdditionalContextValues(action, request, localCerts, peerCerts, principal); } }
@Override public void dispatchRequest(RestRequest request, RestChannel channel, ThreadContext threadContext) { threadContext.putTransient(ConfigConstants.SG_INJECTED_USER, request.header(ConfigConstants.SG_INJECTED_USER)); originalDispatcher.dispatchRequest(request, channel, threadContext); }
private User impersonate(final TransportRequest tr, final User origPKIuser) throws ElasticsearchSecurityException { final String impersonatedUser = threadPool.getThreadContext().getHeader("sg_impersonate_as"); if(Strings.isNullOrEmpty(impersonatedUser)) { return null; //nothing to do } if (!isInitialized()) { throw new ElasticsearchSecurityException("Could not check for impersonation because Search Guard is not yet initialized"); } if (origPKIuser == null) { throw new ElasticsearchSecurityException("no original PKI user found"); } User aU = origPKIuser; if (adminDns.isAdminDN(impersonatedUser)) { throw new ElasticsearchSecurityException("'"+origPKIuser.getName() + "' is not allowed to impersonate as an adminuser '" + impersonatedUser+"'"); } try { if (impersonatedUser != null && !adminDns.isTransportImpersonationAllowed(new LdapName(origPKIuser.getName()), impersonatedUser)) { throw new ElasticsearchSecurityException("'"+origPKIuser.getName() + "' is not allowed to impersonate as '" + impersonatedUser+"'"); } else if (impersonatedUser != null) { aU = new User(impersonatedUser); if(log.isDebugEnabled()) { log.debug("Impersonate from '{}' to '{}'",origPKIuser.getName(), impersonatedUser); } } } catch (final InvalidNameException e1) { throw new ElasticsearchSecurityException("PKI does not have a valid name ('" + origPKIuser.getName() + "'), should never happen", e1); } return aU; }
@Override public void handleResponse(T response) { contextToRestore.restore(); innerHandler.handleResponse(response); }
@Override public <Request extends ActionRequest, Response extends ActionResponse> void apply(Task task, final String action, Request request, ActionListener<Response> listener, ActionFilterChain<Request, Response> chain) { try (StoredContext ctx = threadContext.newStoredContext(true)){ org.apache.logging.log4j.ThreadContext.clearAll(); apply0(task, action, request, listener, chain); } }
public static String getSafeFromHeader(final ThreadContext context, final String headerName) { if (context == null || headerName == null || headerName.isEmpty()) { return null; } String headerValue = null; Map<String, String> headers = context.getHeaders(); if (!headers.containsKey(headerName) || (headerValue = headers.get(headerName)) == null) { return null; } if (isInterClusterRequest(context) || isTrustedClusterRequest(context) || isDirectRequest(context)) { return headerValue; } return null; }
private void attachSourceFieldContext(ActionRequest request) { if(request instanceof SearchRequest && SourceFieldsContext.isNeeded((SearchRequest) request)) { if(threadContext.getHeader("_sg_source_field_context") == null) { final String serializedSourceFieldContext = Base64Helper.serializeObject(new SourceFieldsContext((SearchRequest) request)); threadContext.putHeader("_sg_source_field_context", serializedSourceFieldContext); } } else if (request instanceof GetRequest && SourceFieldsContext.isNeeded((GetRequest) request)) { if(threadContext.getHeader("_sg_source_field_context") == null) { final String serializedSourceFieldContext = Base64Helper.serializeObject(new SourceFieldsContext((GetRequest) request)); threadContext.putHeader("_sg_source_field_context", serializedSourceFieldContext); } } }
public static boolean isInterClusterRequest(final ThreadContext context) { return context.getTransient(ConfigConstants.SG_SSL_TRANSPORT_INTERCLUSTER_REQUEST) == Boolean.TRUE; }
@Override public void dispatchBadRequest(RestRequest request, RestChannel channel, ThreadContext threadContext, Throwable cause) { threadContext.putTransient(ConfigConstants.SG_INJECTED_USER, request.header(ConfigConstants.SG_INJECTED_USER)); originalDispatcher.dispatchBadRequest(request, channel, threadContext, cause); } }
@Override public void handleException(TransportException e) { contextToRestore.restore(); innerHandler.handleException(e); }
private void ensureCorrectHeaders(final Object remoteAdr, final User origUser, final String origin) { // keep original address if(origin != null && !origin.isEmpty() /*&& !Origin.LOCAL.toString().equalsIgnoreCase(origin)*/ && getThreadContext().getHeader(ConfigConstants.SG_ORIGIN_HEADER) == null) { getThreadContext().putHeader(ConfigConstants.SG_ORIGIN_HEADER, origin); } if(origin == null && getThreadContext().getHeader(ConfigConstants.SG_ORIGIN_HEADER) == null) { getThreadContext().putHeader(ConfigConstants.SG_ORIGIN_HEADER, Origin.LOCAL.toString()); } if (remoteAdr != null && remoteAdr instanceof TransportAddress) { String remoteAddressHeader = getThreadContext().getHeader(ConfigConstants.SG_REMOTE_ADDRESS_HEADER); if(remoteAddressHeader == null) { getThreadContext().putHeader(ConfigConstants.SG_REMOTE_ADDRESS_HEADER, Base64Helper.serializeObject(((TransportAddress) remoteAdr).address())); } /*else { if(!((InetSocketAddress)Base64Helper.deserializeObject(remoteAddressHeader)).equals(((TransportAddress) remoteAdr).address())) { throw new RuntimeException("remote address mismatch "+Base64Helper.deserializeObject(remoteAddressHeader)+"!="+((TransportAddress) remoteAdr).address()); } }*/ } if(origUser != null) { String userHeader = getThreadContext().getHeader(ConfigConstants.SG_USER_HEADER); if(userHeader == null) { getThreadContext().putHeader(ConfigConstants.SG_USER_HEADER, Base64Helper.serializeObject(origUser)); } /*else { if(!((User)Base64Helper.deserializeObject(userHeader)).getName().equals(origUser.getName())) { throw new RuntimeException("user mismatch "+Base64Helper.deserializeObject(userHeader)+"!="+origUser); } }*/ } }
public static boolean isDirectRequest(final ThreadContext context) { return "direct".equals(context.getTransient(ConfigConstants.SG_CHANNEL_TYPE)) || context.getTransient(ConfigConstants.SG_CHANNEL_TYPE) == null; }
protected final boolean isAdminAuthenticatedOrInternalRequest() { final User user = (User) threadContext.getTransient(ConfigConstants.SG_USER); if (user != null && adminDns.isAdmin(user)) { return true; } if ("true".equals(HeaderHelper.getSafeFromHeader(threadContext, ConfigConstants.SG_CONF_REQUEST_HEADER))) { return true; } return false; }
@Override protected void doExecute(WhoAmIRequest request, ActionListener<WhoAmIResponse> listener) { final User user = threadPool.getThreadContext().getTransient(ConfigConstants.SG_USER); final String dn = user==null?threadPool.getThreadContext().getTransient(ConfigConstants.SG_SSL_TRANSPORT_PRINCIPAL):user.getName(); final boolean isAdmin = adminDNs.isAdminDN(dn); final boolean isAuthenticated = isAdmin?true: user != null; final boolean isNodeCertificateRequest = HeaderHelper.isInterClusterRequest(threadPool.getThreadContext()) || HeaderHelper.isTrustedClusterRequest(threadPool.getThreadContext()); listener.onResponse(new WhoAmIResponse(dn, isAdmin, isAuthenticated, isNodeCertificateRequest)); } }
if(threadContext.getTransient(ConfigConstants.SG_XFF_DONE) == Boolean.TRUE) { log.trace("xff resolved {} to {}", request.getRemoteAddress(), isa); } else {
final User user = (User)threadContext.getTransient(ConfigConstants.SG_USER); final TransportAddress remoteAddress = (TransportAddress) threadContext.getTransient(ConfigConstants.SG_REMOTE_ADDRESS);
@Override public AuthCredentials extractCredentials(final RestRequest request, ThreadContext context) { if(context.getTransient(ConfigConstants.SG_XFF_DONE) != Boolean.TRUE) { throw new ElasticsearchSecurityException("xff not done"); } final String userHeader = settings.get("user_header"); final String rolesHeader = settings.get("roles_header"); final String rolesSeparator = settings.get("roles_separator", ","); if(log.isDebugEnabled()) { log.debug("headers {}", request.getHeaders()); log.debug("userHeader {}, value {}", userHeader, userHeader == null?null:request.header(userHeader)); log.debug("rolesHeader {}, value {}", rolesHeader, rolesHeader == null?null:request.header(rolesHeader)); } if (!Strings.isNullOrEmpty(userHeader) && !Strings.isNullOrEmpty((String) request.header(userHeader))) { String[] backendRoles = null; if (!Strings.isNullOrEmpty(rolesHeader) && !Strings.isNullOrEmpty((String) request.header(rolesHeader))) { backendRoles = ((String) request.header(rolesHeader)).split(rolesSeparator); } return new AuthCredentials((String) request.header(userHeader), backendRoles).markComplete(); } else { if(log.isTraceEnabled()) { log.trace("No '{}' header, send 401", userHeader); } return null; } }