blob: 870822b0758cbaccba2e3acd223c970352c44486 [file] [log] [blame]
// gpowerd is a the safe power local agent for BMC.
// It implements the SafePowerLocalAgent service, andis responsible for
// actuating power cycles on the machine.
#include "bmc/auth.h"
#include <gpowerd_build_config.h>
#include <filesystem> // NOLINT(build/c++17)
#include <memory>
#include <string>
#include <system_error> // NOLINT(build/c++11)
#include <utility>
#include "bmc/auth_loas3.h"
#include "bmc/gmi_reader.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_format.h"
#include "grpc/grpc_security_constants.h"
#include "grpcpp/security/authorization_policy_provider.h"
#include "grpcpp/security/server_credentials.h"
#include "grpcpp/security/tls_certificate_provider.h"
#include "grpcpp/security/tls_certificate_verifier.h"
#include "grpcpp/security/tls_credentials_options.h"
#include "grpcpp/server_builder.h"
#include "grpcpp/support/status.h"
#include "zatar/generate_self_signed_cert.h"
namespace auth {
using ::grpc::experimental::AuthorizationPolicyProviderInterface;
using ::grpc::experimental::ExternalCertificateVerifier;
using ::grpc::experimental::FileWatcherAuthorizationPolicyProvider;
using ::grpc::experimental::FileWatcherCertificateProvider;
using ::grpc::experimental::TlsServerCredentials;
using ::grpc::experimental::TlsServerCredentialsOptions;
using ::milotic::authn::SelfSignedCertOptions;
absl::StatusOr<std::shared_ptr<grpc::ServerCredentials>> GetCredsInfo() {
#ifdef LOAS3_AUTH
SetupLoas3();
#else
LOG(WARNING) << "LOAS3 is not enabled";
#endif
std::error_code file_error;
bool file_exist = std::filesystem::exists(kZatarCertFilePath, file_error);
if (file_error) {
return absl::NotFoundError("tls file path error: " + file_error.message() +
"file path: " + std::string(kZatarCertFilePath));
}
std::string keypair_path;
if (file_exist) {
keypair_path = std::string(kZatarCertFilePath);
} else {
// cert is not present (self sign a cert)
keypair_path = absl::StrFormat("/tmp/gpowerd_self_signed_%d.pem", getpid());
absl::StatusOr<std::string> host_name = gmi_reader::ReadGmiHostName();
if (!host_name.ok()) {
LOG(ERROR) << "unable to read gmi host name: " << host_name.status();
return host_name.status();
}
SelfSignedCertOptions option;
option.server_fqdn = *host_name;
if (absl::Status status =
GenerateSelfSignedCertAndDump(keypair_path, option);
!status.ok()) {
LOG(ERROR) << "unable to write self signed cert: " << status;
return status;
}
}
auto certificateProvider = std::make_shared<FileWatcherCertificateProvider>(
keypair_path, keypair_path, std::string(kTrustBundleFilePath),
/* refresh_interval_sec */ 30);
TlsServerCredentialsOptions options(certificateProvider);
options.watch_root_certs();
options.set_root_cert_name("Zatar");
options.watch_identity_key_cert_pairs();
options.set_cert_request_type(
GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
#ifdef LOAS3_AUTH
auto cert_verifier = ExternalCertificateVerifier::Create<PeerVerifier>();
options.set_certificate_verifier(std::move(cert_verifier));
#endif
std::shared_ptr<grpc::ServerCredentials> tlsServerCredentials =
TlsServerCredentials(options);
if (tlsServerCredentials == nullptr) {
LOG(ERROR) << "tls Server Credentials error:";
return absl::NotFoundError("tls Server Credentials error");
}
return tlsServerCredentials;
}
absl::StatusOr<std::shared_ptr<AuthorizationPolicyProviderInterface>>
GetAuthPolicy() {
grpc::Status policy_status;
std::shared_ptr<AuthorizationPolicyProviderInterface> policy =
FileWatcherAuthorizationPolicyProvider::Create(
std::string(kGpowerDCertAuthZPolicy),
/* policy refresh_interval_sec = 30 */ 30, &policy_status);
if (!policy_status.ok()) {
return absl::NotFoundError(
"failed to load policy file error: " + policy_status.error_message() +
"file path:" + std::string(kGpowerDCertAuthZPolicy));
}
return policy;
}
} // namespace auth