// Copyright 2020 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SYSTEM_PROXY_SERVER_PROXY_H_
#define SYSTEM_PROXY_SERVER_PROXY_H_

#include <list>
#include <map>
#include <memory>
#include <string>

#include <base/files/file_descriptor_watcher_posix.h>
#include <base/files/scoped_file.h>
#include <base/functional/callback_forward.h>
#include <base/memory/weak_ptr.h>
#include <brillo/asynchronous_signal_handler.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST
#include <net-base/ipv4_address.h>
#include <net-base/socket.h>

#include "system-proxy/curl_scopers.h"

namespace system_proxy {

using OnProxyResolvedCallback =
    base::OnceCallback<void(const std::list<std::string>&)>;
using OnAuthAcquiredCallback =
    base::RepeatingCallback<void(const std::string&)>;

class ProxyConnectJob;

// ServerProxy listens for connections from the host (system services, ARC++
// apps) and sets-up connections to the remote server.
// Note: System-proxy only supports proxying over IPv4 networks.
class ServerProxy {
 public:
  explicit ServerProxy(base::OnceClosure quit_closure);
  ServerProxy(const ServerProxy&) = delete;
  ServerProxy& operator=(const ServerProxy&) = delete;
  virtual ~ServerProxy();

  void Init();

  // Creates a proxy resolution request that is forwarded to the parent process
  // trough the standard output. When the request is resolved, the parent
  // process will send the result trough the standard input.
  // |callback| will be called when the proxy is resolved, with the list of
  // proxy servers as parameter ,or in case of failure, with a list containing
  // only the direct proxy.
  void ResolveProxy(const std::string& target_url,
                    OnProxyResolvedCallback callback);
  // Creates an authentication required request that is forwarded to the parent
  // process trough the standard output. When the request is resolved, the
  // parent process will send the result trough the standard input. |callback|
  // will be called when the credentials associated to the protection space
  // given by the input parameters, or empty strings in case of failure or
  // missing credentials. |bad_cached_credentials| are the incorrect credentials
  // previously used for authentication; can be an empty string if no
  // credentials were used in the initial request.
  void AuthenticationRequired(const std::string& proxy_url,
                              const std::string& scheme,
                              const std::string& realm,
                              const std::string& bad_cached_credentials,
                              OnAuthAcquiredCallback callback);

 protected:
  virtual int GetStdinPipe();
  virtual int GetStdoutPipe();
  virtual void HandleStdinReadable();
  virtual void OnConnectionAccept();

 private:
  friend class ServerProxyTest;
  FRIEND_TEST(ServerProxyTest, FetchCredentials);
  FRIEND_TEST(ServerProxyTest, FetchListeningAddress);
  FRIEND_TEST(ServerProxyTest, HandleConnectRequest);
  FRIEND_TEST(ServerProxyTest, HandlePendingJobs);
  FRIEND_TEST(ServerProxyTest, SetupConnection);
  FRIEND_TEST(ServerProxyTest, HandleCanceledJobWhilePendingProxyResolution);
  FRIEND_TEST(ServerProxyTest, HandlePendingAuthRequests);
  FRIEND_TEST(ServerProxyTest, HandlePendingAuthRequestsCachedCredentials);
  FRIEND_TEST(ServerProxyTest, HandlePendingAuthRequestsNoCredentials);
  FRIEND_TEST(ServerProxyTest, ClearUserCredentials);
  FRIEND_TEST(ServerProxyTest, AuthRequestsBadCachedCredentials);

  bool HandleSignal(const struct signalfd_siginfo& siginfo);

  void CreateListeningSocket();

  // Called by |ProxyConnectJob| after setting up the connection with the remote
  // server via the remote proxy server. If the connection is successful, |fwd|
  // corresponds to the tunnel between the client and the server that has
  // started to forward data. In case of failure, |fwd| is empty.
  void OnConnectionSetupFinished(std::unique_ptr<CurlForwarder> fwd,
                                 ProxyConnectJob* connect_job);

  // Called when the proxy resolution result for |target_url| is received via
  // the standard input (see |ResolveProxy| method). |proxy_servers| will always
  // contain at least one entry, the direct proxy.
  void OnProxyResolved(const std::string& target_url,
                       const std::list<std::string>& proxy_servers);

  void OnCredentialsReceived();

  // Sets the environment variables for kerberos authentication.
  void SetKerberosEnv(bool kerberos_enabled);

  // Notifies proxy connect jobs which are pending authentication that
  // credentials were provided for the protection space identified by
  // |auth_credentials_key|. Called when the parent process sends credentials
  // along with the associated protection space via the standard input.
  void AuthCredentialsProvided(const std::string& auth_credentials_key,
                               const std::string& credentials);

  // The proxy listening address.
  std::optional<net_base::IPv4Address> listening_addr_;
  int listening_port_;

  // The user name and password to use for proxy authentication in the format
  // compatible with libcurl's CURLOPT_USERPWD: both user name and password URL
  // encoded and separated by colon. Only set for system traffic. If set, the
  // credentials will be applied to any connection, regardless of the remote
  // proxy it's connecting to or the challenge response.
  std::string system_credentials_;

  // Curl compatible bit-mask list of proxy authenticated schemes that can be
  // used with the policy set credentials.
  int64_t system_credentials_auth_schemes_ = 0;

  std::unique_ptr<net_base::Socket> listening_fd_;

  // List of SocketForwarders that corresponds to the TCP tunnel between the
  // local client and the remote proxy, forwarding data between the TCP
  // connection initiated by the local client to the local proxy and the TCP
  // connection initiated by the local proxy to the remote proxy.
  std::list<std::unique_ptr<CurlForwarder>> forwarders_;

  std::map<ProxyConnectJob*, std::unique_ptr<ProxyConnectJob>>
      pending_connect_jobs_;

  // Collection of ongoing proxy resolution requests. The key represents the
  // target url to be resolved and it's mapped to a list of callbaks to pending
  // connect jobs that are connecting to the same target url.
  std::map<std::string, std::list<OnProxyResolvedCallback>>
      pending_proxy_resolution_requests_;

  // Collection of ongoing authentication requests. The key represents the
  // ProtectionSpace proto message (proxy url, scheme and realm) associated with
  // the request, serialized as a string. The value is a list of callbaks to
  // pending connect jobs that are awaiting authentication and have received a
  // challenge with the same scheme and realm from the same proxy server.
  std::map<std::string, std::list<OnAuthAcquiredCallback>>
      pending_auth_required_requests_;

  // Stores HTTP authentication identities acquired from the user and challenge
  // info. The credentials are mapped by the protection space (origin, realm,
  // scheme) and can only be used in response to challenges corresponding to
  // this specific triple, as opposed to |system_credentials_| which, if set,
  // can be used for any protection space.
  std::map<std::string, std::string> auth_cache_;

  base::OnceClosure quit_closure_;
  std::unique_ptr<base::FileDescriptorWatcher::Controller> stdin_watcher_;
  std::unique_ptr<base::FileDescriptorWatcher::Controller> fd_watcher_;
  brillo::AsynchronousSignalHandler signal_handler_;

  base::WeakPtrFactory<ServerProxy> weak_ptr_factory_;
};
}  // namespace system_proxy

#endif  // SYSTEM_PROXY_SERVER_PROXY_H_
