drill-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (DRILL-4280) Kerberos Authentication
Date Fri, 03 Feb 2017 02:13:52 GMT

    [ https://issues.apache.org/jira/browse/DRILL-4280?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15850930#comment-15850930
] 

ASF GitHub Bot commented on DRILL-4280:
---------------------------------------

Github user sohami commented on a diff in the pull request:

    https://github.com/apache/drill/pull/578#discussion_r99261692
  
    --- Diff: exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/UserClient.java
---
    @@ -88,22 +129,183 @@ public void submitQuery(UserResultsListener resultsListener, RunQuery
query) {
         send(queryResultHandler.getWrappedListener(resultsListener), RpcType.RUN_QUERY, query,
QueryId.class);
       }
     
    -  public void connect(RpcConnectionHandler<ServerConnection> handler, DrillbitEndpoint
endpoint,
    -                      UserProperties props, UserBitShared.UserCredentials credentials)
{
    +  public CheckedFuture<Void, RpcException> connect(DrillbitEndpoint endpoint, DrillProperties
parameters,
    +                                                   UserCredentials credentials) {
    +    final FutureHandler handler = new FutureHandler();
         UserToBitHandshake.Builder hsBuilder = UserToBitHandshake.newBuilder()
             .setRpcVersion(UserRpcConfig.RPC_VERSION)
             .setSupportListening(true)
             .setSupportComplexTypes(supportComplexTypes)
             .setSupportTimeout(true)
             .setCredentials(credentials)
    -        .setClientInfos(UserRpcUtils.getRpcEndpointInfos(clientName));
    +        .setClientInfos(UserRpcUtils.getRpcEndpointInfos(clientName))
    +        .setSaslSupport(SaslSupport.SASL_AUTH)
    +        .setProperties(parameters.serializeForServer());
    +    this.properties = parameters;
    +
    +    connectAsClient(queryResultHandler.getWrappedConnectionHandler(handler),
    +        hsBuilder.build(), endpoint.getAddress(), endpoint.getUserPort());
    +    return handler;
    +  }
    +
    +  /**
    +   * Check (after {@link #connect connecting}) if server requires authentication.
    +   *
    +   * @return true if server requires authentication
    +   */
    +  public boolean serverRequiresAuthentication() {
    +    return supportedAuthMechs != null;
    +  }
    +
    +  /**
    +   * Returns a list of supported authentication mechanism. If called before {@link #connect
connecting},
    +   * returns null. If called after {@link #connect connecting}, returns a list of supported
mechanisms
    +   * iff authentication is required.
    +   *
    +   * @return list of supported authentication mechanisms
    +   */
    +  public List<String> getSupportedAuthenticationMechanisms() {
    +    return supportedAuthMechs;
    +  }
     
    -    if (props != null) {
    -      hsBuilder.setProperties(props);
    +  /**
    +   * Authenticate to the server asynchronously. Returns a future that {@link CheckedFuture#checkedGet
results}
    +   * in null if authentication succeeds, or throws a {@link SaslException} with relevant
message if
    +   * authentication fails.
    +   *
    +   * This method uses properties provided at {@link #connect connection time} and override
them with the
    +   * given properties, if any.
    +   *
    +   * @param overrides parameter overrides
    +   * @return result of authentication request
    +   */
    +  public CheckedFuture<Void, SaslException> authenticate(final DrillProperties
overrides) {
    +    if (supportedAuthMechs == null) {
    +      throw new IllegalStateException("Server does not require authentication.");
         }
    +    properties.merge(overrides);
    +    final Map<String, String> propertiesMap = properties.stringPropertiesAsMap();
     
    -    this.connectAsClient(queryResultHandler.getWrappedConnectionHandler(handler),
    -        hsBuilder.build(), endpoint.getAddress(), endpoint.getUserPort());
    +    final SettableFuture<Void> settableFuture = SettableFuture.create(); // future
used in SASL exchange
    +    final CheckedFuture<Void, SaslException> future =
    +        new AbstractCheckedFuture<Void, SaslException>(settableFuture) {
    +
    +          @Override
    +          protected SaslException mapException(Exception e) {
    +            if (connection != null) {
    +              connection.close(); // to ensure connection is dropped
    +            }
    +            if (e instanceof ExecutionException) {
    +              final Throwable cause = e.getCause();
    +              if (cause instanceof SaslException) {
    +                return new SaslException("Authentication failed: " + cause.getMessage(),
cause);
    +              }
    +            }
    +            return new SaslException("Authentication failed unexpectedly.", e);
    +          }
    +        };
    +
    +    final AuthenticatorFactory factory;
    +    try {
    +      factory = getAuthenticatorFactory();
    +    } catch (final SaslException e) {
    +      settableFuture.setException(e);
    +      return future;
    +    }
    +
    +    final String mechanismName = factory.getSimpleName();
    +    logger.trace("Will try to login for {} mechanism.", mechanismName);
    +    final UserGroupInformation ugi;
    +    try {
    +      ugi = factory.createAndLoginUser(propertiesMap);
    +    } catch (final IOException e) {
    +      settableFuture.setException(e);
    +      return future;
    +    }
    +
    +    logger.trace("Will try to authenticate to server using {} mechanism.", mechanismName);
    +    final SaslClient saslClient;
    +    try {
    +      saslClient = factory.createSaslClient(ugi, propertiesMap);
    +      connection.setSaslClient(saslClient);
    +    } catch (final SaslException e) {
    +      settableFuture.setException(e);
    +      return future;
    +    }
    +
    +    if (saslClient == null) {
    +      settableFuture.setException(new SaslException("Cannot initiate authentication.
Insufficient credentials?"));
    +      return future;
    +    }
    +
    +    logger.trace("Initiating SASL exchange.");
    +    new AuthenticationOutcomeListener<>(this, connection, RpcType.SASL_MESSAGE,
ugi, new RpcOutcomeListener<Void>(){
    +
    +      @Override
    +      public void failed(RpcException ex) {
    +        settableFuture.setException(ex);
    +      }
    +
    +      @Override
    +      public void success(Void value, ByteBuf buffer) {
    +        authComplete = true;
    +        settableFuture.set(null);
    +      }
    +
    +      @Override
    +      public void interrupted(InterruptedException e) {
    +        settableFuture.setException(e);
    +      }
    +    })
    +        .initiate(mechanismName);
    --- End diff --
    
    please move this up.


> Kerberos Authentication
> -----------------------
>
>                 Key: DRILL-4280
>                 URL: https://issues.apache.org/jira/browse/DRILL-4280
>             Project: Apache Drill
>          Issue Type: Improvement
>            Reporter: Keys Botzum
>            Assignee: Sudheesh Katkam
>              Labels: security
>
> Drill should support Kerberos based authentication from clients. This means that both
the ODBC and JDBC drivers as well as the web/REST interfaces should support inbound Kerberos.
For Web this would most likely be SPNEGO while for ODBC and JDBC this will be more generic
Kerberos.
> Since Hive and much of Hadoop supports Kerberos there is a potential for a lot of reuse
of ideas if not implementation.
> Note that this is related to but not the same as https://issues.apache.org/jira/browse/DRILL-3584




--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Mime
View raw message