// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#ifndef IMPALA_RPC_AUTH_PROVIDER_H
#define IMPALA_RPC_AUTH_PROVIDER_H

#include <string>
#include <boost/thread/mutex.hpp>
#include <sasl/sasl.h>

#include "common/status.h"
#include "rpc/thrift-server.h"
#include "util/openssl-util.h"
#include "util/promise.h"

namespace sasl { class TSasl; }

namespace impala {

/// An AuthProvider creates Thrift transports that are set up to authenticate themselves
/// using a protocol such as Kerberos or PLAIN/SASL. Both server and client transports are
/// provided by this class, using slightly different mechanisms (servers use a factory,
/// clients wrap a pre-provided transport)
class AuthProvider {
 public:
  /// Initialises any state required to perform authentication using this provider.
  virtual Status Start() WARN_UNUSED_RESULT = 0;

  /// Creates a new Thrift transport factory in the out parameter that performs
  /// authorisation per this provider's protocol. The type of the transport returned is
  /// determined by 'underlying_transport_type' and there may be multiple levels of
  /// wrapped transports, eg. a TBufferedTransport around a TSaslServerTransport.
  virtual Status GetServerTransportFactory(
      ThriftServer::TransportType underlying_transport_type,
      const std::string& server_name, MetricGroup* metrics,
      boost::shared_ptr<apache::thrift::transport::TTransportFactory>* factory)
      WARN_UNUSED_RESULT = 0;

  /// Called by Thrift clients to wrap a raw transport with any intermediate transport
  /// that an auth protocol requires.
  /// TODO: Return the correct clients for HTTP base transport. At this point, no clients
  /// for HTTP endpoints are internal to the Impala service, so it should be OK.
  virtual Status WrapClientTransport(const std::string& hostname,
      boost::shared_ptr<apache::thrift::transport::TTransport> raw_transport,
      const std::string& service_name,
      boost::shared_ptr<apache::thrift::transport::TTransport>* wrapped_transport)
      WARN_UNUSED_RESULT = 0;

  /// Setup 'connection_ptr' to get its username with the given transports and sets
  /// 'network_address' based on the underlying socket. The transports should be generated
  /// by the factory returned by GetServerTransportFactory() when called with the same
  /// 'underlying_transport_type'.
  virtual void SetupConnectionContext(
      const boost::shared_ptr<ThriftServer::ConnectionContext>& connection_ptr,
      ThriftServer::TransportType underlying_transport_type,
      apache::thrift::transport::TTransport* input_transport,
      apache::thrift::transport::TTransport* output_transport) = 0;

  /// Returns true if this provider uses Sasl at the transport layer.
  virtual bool is_secure() = 0;

  virtual ~AuthProvider() { }
};

/// Used if either (or both) Kerberos and LDAP auth are desired. For BINARY connections we
/// use Sasl for the communication, and for HTTP connections we use Basic or SPNEGO auth.
/// This "wraps" the underlying communication, in thrift-speak. This is used for both
/// client and server contexts; there is one for internal and one for external
/// communication.
class SecureAuthProvider : public AuthProvider {
 public:
  SecureAuthProvider(bool is_internal)
    : has_ldap_(false), is_internal_(is_internal), needs_kinit_(false) {}

  /// Performs initialization of external state. Kinit if configured to use kerberos.
  /// If we're using ldap, set up appropriate certificate usage.
  virtual Status Start();

  /// Wrap the client transport with a new TSaslClientTransport.  This is only for
  /// internal connections.  Since, as a daemon, we only do Kerberos and not LDAP,
  /// we can go straight to Kerberos.
  /// This is only applicable to Thrift connections and not KRPC connections.
  virtual Status WrapClientTransport(const std::string& hostname,
      boost::shared_ptr<apache::thrift::transport::TTransport> raw_transport,
      const std::string& service_name,
      boost::shared_ptr<apache::thrift::transport::TTransport>* wrapped_transport);

  /// This sets up a mapping between auth types (PLAIN and GSSAPI) and callbacks.
  /// When a connection comes in, thrift will see one of the above on the wire, do
  /// a table lookup, and associate the appropriate callbacks with the connection.
  /// Then presto! You've got authentication for the connection.
  /// This is only applicable to Thrift connections and not KRPC connections.
  virtual Status GetServerTransportFactory(
      ThriftServer::TransportType underlying_transport_type,
      const std::string& server_name, MetricGroup* metrics,
      boost::shared_ptr<apache::thrift::transport::TTransportFactory>* factory);

  /// IF sasl was used, the username will be available from the handshake, and we set it
  /// here. If HTTP Basic or SPNEGO auth was used, the username won't be available until
  /// one or more packets are received, so we register a callback with the transport that
  /// will set the username when it's available.
  virtual void SetupConnectionContext(
      const boost::shared_ptr<ThriftServer::ConnectionContext>& connection_ptr,
      ThriftServer::TransportType underlying_transport_type,
      apache::thrift::transport::TTransport* input_transport,
      apache::thrift::transport::TTransport* output_transport);

  virtual bool is_secure() { return true; }

  /// Initializes kerberos items and checks for sanity.  Failures can occur on a
  /// malformed principal or when setting some environment variables.  Called
  /// prior to Start().
  Status InitKerberos(const std::string& principal, const std::string& keytab_path);

  /// Initializes ldap - just record that we're going to use it.  Called prior to
  /// Start().
  void InitLdap() { has_ldap_ = true; }

  /// Used for testing
  const std::string& principal() const { return principal_; }
  const std::string& service_name() const { return service_name_; }
  const std::string& hostname() const { return hostname_; }
  const std::string& realm() const { return realm_; }
  bool has_ldap() { return has_ldap_; }

 private:
  /// Do we (the server side only) support ldap for this connnection?
  bool has_ldap_;

  /// Hostname of this machine - if kerberos, derived from principal.  If there
  /// is no kerberos, but LDAP is used, then acquired via GetHostname().
  std::string hostname_;

  /// True if internal, false if external.
  bool is_internal_;

  /// All the rest of these private items are Kerberos-specific.

  /// The Kerberos principal. If is_internal_ is true and --be_principal was
  /// supplied, this is --be_principal.  In all other cases this is --principal.
  std::string principal_;

  /// The full path to the keytab where the above principal can be found.
  std::string keytab_file_;

  /// The service name, deduced from the principal. Used by servers to indicate
  /// what service a principal must have a ticket for in order to be granted
  /// access to this service.
  std::string service_name_;

  /// Principal's realm, again derived from principal.
  std::string realm_;

  /// True if tickets for this principal should be obtained.  This is true if
  /// we're an auth provider for an "internal" connection, because we may
  /// function as a client.
  bool needs_kinit_;

  /// Used to generate and verify signatures for cookies.
  AuthenticationHash hash_;

  /// One-time kerberos-specific environment variable setup.  Called by InitKerberos().
  Status InitKerberosEnv() WARN_UNUSED_RESULT;
};

/// This provider implements no authentication, so any connection is immediately
/// successful.  There's no Sasl in the picture.
class NoAuthProvider : public AuthProvider {
 public:
  NoAuthProvider() { }

  virtual Status Start() { return Status::OK(); }

  virtual Status GetServerTransportFactory(
      ThriftServer::TransportType underlying_transport_type,
      const std::string& server_name, MetricGroup* metrics,
      boost::shared_ptr<apache::thrift::transport::TTransportFactory>* factory);

  virtual Status WrapClientTransport(const std::string& hostname,
      boost::shared_ptr<apache::thrift::transport::TTransport> raw_transport,
      const std::string& service_name,
      boost::shared_ptr<apache::thrift::transport::TTransport>* wrapped_transport);

  /// If there is no auth, then we don't have a username available.
  virtual void SetupConnectionContext(
      const boost::shared_ptr<ThriftServer::ConnectionContext>& connection_ptr,
      ThriftServer::TransportType underlying_transport_type,
      apache::thrift::transport::TTransport* input_transport,
      apache::thrift::transport::TTransport* output_transport);

  virtual bool is_secure() { return false; }
};

/// The first entry point to the authentication subsystem.  Performs initialization
/// of Sasl, the global AuthManager, and the two authentication providers.  Appname
/// should generally be argv[0]. Normally, InitAuth() should only be called once.
/// In certain test cases, we may call it more than once. It's important that InitAuth()
/// is called with the same 'appname' if it's called more than once. Otherwise, error
/// status will be returned.
Status InitAuth(const std::string& appname);

}

#endif
