// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SHILL_EAP_CREDENTIALS_H_
#define SHILL_EAP_CREDENTIALS_H_

#include <memory>
#include <optional>
#include <string>
#include <vector>

#include <gtest/gtest_prod.h>  // for FRIEND_TEST
#include <libpasswordprovider/password_provider.h>

#include "shill/data_types.h"
#include "shill/technology.h"

namespace shill {

class CertificateFile;
class Error;
class KeyValueStore;
class Metrics;
class PropertyStore;
class StoreInterface;

class EapCredentials {
 public:
  EapCredentials();
  EapCredentials(const EapCredentials&) = delete;
  EapCredentials& operator=(const EapCredentials&) = delete;

  virtual ~EapCredentials();

  // Add property accessors to the EAP credential parameters in |this| to
  // |store|.
  void InitPropertyStore(PropertyStore* store);

  // Returns true if |property| is used for authentication in EapCredentials.
  static bool IsEapAuthenticationProperty(const std::string property);

  // Returns true if a connection can be made with |this| credentials using
  // either passphrase or certificates.
  virtual bool IsConnectable() const;

  // Returns true if a connection can be made with |this| credentials using
  // only passphrase properties.
  virtual bool IsConnectableUsingPassphrase() const;

  // Loads EAP properties from |storage| in group |id|.
  virtual void Load(const StoreInterface* store, const std::string& id);

  // Load EAP properties from key/value store |store|.
  virtual void Load(const KeyValueStore& store);

  // Load EAP properties from another EapCredentials set |eap|.
  virtual void Load(const EapCredentials& eap);

  void MigrateDeprecatedStorage(StoreInterface* storage,
                                const std::string& id) const;

  // Output metrics about this EAP connection to |metrics| with technology
  // |technology|.
  virtual void OutputConnectionMetrics(Metrics* metrics,
                                       Technology technology) const;

  // Populate the wpa_supplicant DBus parameter map |params| with the
  // credentials in |this|.  To do so, this function may use |certificate_file|
  // to export CA certificates to be passed to wpa_supplicant.
  virtual void PopulateSupplicantProperties(CertificateFile* certificate_file,
                                            KeyValueStore* params) const;

  // Save EAP properties to |storage| in group |id|.  If |save_credentials|
  // is true, passwords and identities that are a part of the credentials are
  // also saved.
  virtual void Save(StoreInterface* store,
                    const std::string& id,
                    bool save_credentials) const;

  // Restore EAP properties to their initial state.
  virtual void Reset();

  // Setter that guards against emptying the "Key Management" value.
  virtual bool SetKeyManagement(const std::string& key_management,
                                Error* error);

  // Returns true if |type| is one of the subject alternative name types
  // supported by wpa_supplicant.
  static bool ValidSubjectAlternativeNameMatchType(const std::string& type);

  // Returns true if `domain_suffix_match` is a valid FQDN. A FQDN is composed
  // of labels separated by dots (.), with the following restrictions (according
  // to rfc1034#section-3.5, rfc2181#section-11, rfc1123#section-2):
  // - (rfc1034+rfc1123) Labels must start with a letter or digit.
  // - (rfc1034) Labels must end with a letter or digit
  // - (rfc1034) Labels must have as interior characters only letters, digits,
  // and hyphen (-).
  // - (rfc1034) Labels must be 63 characters or less.
  // - (rfc2181) The full domain name is limited to 255 octets.
  // - (rfc1123) The highest-level component (i.e. the top level domain) label
  // will be alphabetic.
  static bool ValidDomainSuffixMatch(const std::string& domain_suffix_match);

  // Returns the domain suffix match list in the format used by
  // wpa_supplicant by translating |domain_suffix_match_list| and filtering out
  // entries that are not valid domain names according to
  // `ValidDomainSuffixMatch`.
  static std::optional<std::string> TranslateDomainSuffixMatch(
      const std::vector<std::string>& domain_suffix_match_list);

  // Returns subject alternative name match in the format used by
  // wpa_supplicant by translating |subject_alternative_name_match_list|.
  static std::optional<std::string> TranslateSubjectAlternativeNameMatch(
      const std::vector<std::string>& subject_alternative_name_match_list);

  std::string GetEapPassword(Error* error) const;

  // Getters and setters.
  virtual const std::string& cert_id() const { return cert_id_; }
  virtual const std::string& identity() const { return identity_; }
  void set_identity(const std::string& identity) { identity_ = identity; }
  virtual const std::string& key_id() const { return key_id_; }
  virtual const std::string& key_management() const { return key_management_; }
  virtual const std::string& password() const { return password_; }
  virtual void set_password(const std::string& password) {
    password_ = password;
  }
  virtual bool use_system_cas() const { return use_system_cas_; }
  virtual void set_use_system_cas(bool use_system_cas) {
    use_system_cas_ = use_system_cas;
  }
  virtual const std::string& pin() const { return pin_; }
  virtual const std::string& method() const { return eap_; }
  virtual const std::string& inner_method() const { return inner_eap_; }
  virtual const std::vector<std::string>& ca_cert_pem() const {
    return ca_cert_pem_;
  }
  virtual const std::string& subject_match() const { return subject_match_; }
  virtual const std::vector<std::string>& subject_alternative_name_match_list()
      const {
    return subject_alternative_name_match_list_;
  }
  virtual const std::vector<std::string>& domain_suffix_match_list() const {
    return domain_suffix_match_list_;
  }

 private:
  friend class EapCredentialsTest;
  FRIEND_TEST(EapCredentialsTest, LoadAndSave);
  FRIEND_TEST(EapCredentialsTest, Load);
  FRIEND_TEST(ServiceTest, LoadEap);
  FRIEND_TEST(ServiceTest, SaveEap);

  static const char kStorageCredentialEapAnonymousIdentity[];
  static const char kStorageCredentialEapIdentity[];
  static const char kStorageCredentialEapPassword[];

  static const char kStorageEapCACertID[];
  static const char kStorageEapCACertPEM[];
  static const char kStorageEapCertID[];
  static const char kStorageEapEap[];
  static const char kStorageEapInnerEap[];
  static const char kStorageEapTLSVersionMax[];
  static const char kStorageEapKeyID[];
  static const char kStorageEapKeyManagement[];
  static const char kStorageEapPin[];
  static const char kStorageEapSubjectMatch[];
  static const char kStorageEapUseProactiveKeyCaching[];
  static const char kStorageEapUseSystemCAs[];
  static const char kStorageEapUseLoginPassword[];

  // Returns true if the current EAP authentication type requires certificate
  // authentication and any of the client credentials are provided via
  // referencea cypto token.
  bool ClientAuthenticationUsesCryptoToken() const;

  // Expose a property in |store|, with the name |name|.
  //
  // Reads of the property will be handled by invoking |get|.
  // Writes to the property will be handled by invoking |set|.
  void HelpRegisterDerivedString(
      PropertyStore* store,
      const std::string& name,
      std::string (EapCredentials::*get)(Error* error),
      bool (EapCredentials::*set)(const std::string& value, Error* error));

  // Expose a property in |store|, with the name |name|.
  //
  // Reads of the property will be handled by invoking |get|.
  //
  // Clearing the property will be handled by invoking |clear|, or
  // calling |set| with |default_value| (whichever is non-NULL).  It
  // is an error to call this method with both |clear| and
  // |default_value| non-NULL.
  void HelpRegisterWriteOnlyDerivedString(
      PropertyStore* store,
      const std::string& name,
      bool (EapCredentials::*set)(const std::string& value, Error* error),
      void (EapCredentials::*clear)(Error* error),
      const std::string* default_value);

  // Setters for write-only RPC properties.
  bool SetEapPassword(const std::string& password, Error* error);

  // RPC getter for key_management_.
  std::string GetKeyManagement(Error* error);

  // When there is an inner EAP type, use this identity for the outer.
  std::string anonymous_identity_;
  // Locator for the client certificate within the security token.
  std::string cert_id_;
  // Who we identify ourselves as to the EAP authenticator.
  std::string identity_;
  // Locator for the client private key within the security token.
  std::string key_id_;
  // Key management algorithm to use after EAP succeeds.
  std::string key_management_;
  // Password to use for EAP methods which require one.
  std::string password_;
  // PIN code for accessing the security token.
  std::string pin_;

  // Locator for the CA certificate within the security token.
  std::string ca_cert_id_;
  // Raw PEM contents of the CA certificate.
  std::vector<std::string> ca_cert_pem_;
  // The outer or only EAP authentication type.
  std::string eap_;
  // The inner EAP authentication type.
  std::string inner_eap_;
  // The highest TLS version supplicant is allowed to negotiate.
  std::string tls_version_max_;
  // If non-empty, string to match remote subject against before connecting.
  std::string subject_match_;
  // A list of serialized subject alternative names (SANs) to be matched against
  // the alternative subject name of the authentication server certificate. When
  // multiple match strings are specified, a match with any one of the values is
  // considered a sufficient match for the server certificate.
  std::vector<std::string> subject_alternative_name_match_list_;
  //  A list of constraints for the server domain name. If set, the entries will
  //  be used as suffix match requirements against the dNSName element(s) of the
  //  alternative subject name of an authentication server. When multiple match
  //  strings are specified, a match with any one of the values is considered a
  //  sufficient match for the server certificate.
  std::vector<std::string> domain_suffix_match_list_;
  // If true, use the system-wide CA database to authenticate the remote.
  bool use_system_cas_;
  // If true, use per network proactive key caching.
  bool use_proactive_key_caching_;
  // If true, use the user's stored login password as the password.
  bool use_login_password_;

  std::unique_ptr<password_provider::PasswordProviderInterface>
      password_provider_;
};

}  // namespace shill

#endif  // SHILL_EAP_CREDENTIALS_H_
