blob: a87cebe7809efd72fef80ad6f245ee1bfeaeec3d [file]
// 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 <gmi/machine_identity.pb.h>
#include <gpowerd_build_config.h>
#include <grpcpp/grpcpp.h>
#include <string>
#include <string_view>
#include <filesystem> // NOLINT
#include "bmc/gmi_reader.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/ext/proto_server_reflection_plugin.h"
#include "grpcpp/health_check_service_interface.h"
#include "absl/base/log_severity.h"
#include "absl/log/log.h"
#include "absl/strings/str_format.h"
#include "absl/status/statusor.h"
#include "zatar/generate_self_signed_cert.h"
#include "bmc/auth_loas3.h"
namespace auth {
using ::grpc::experimental::TlsCustomVerificationCheckRequest;
using ::grpc::experimental::ExternalCertificateVerifier;
using ::grpc::ServerBuilder;
using ::grpc::experimental::FileWatcherCertificateProvider;
using ::grpc::experimental::TlsServerCredentials;
using ::grpc::experimental::TlsServerCredentialsOptions;
using ::grpc::experimental::AuthorizationPolicyProviderInterface;
using ::milotic::authn::SelfSignedCertOptions;
using ::grpc::experimental::FileWatcherAuthorizationPolicyProvider;
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();;
{
absl::Status errStatus = host_name.status();
return absl::NotFoundError("unable to read gmi host name: " +
std::string(errStatus.message()));
}
SelfSignedCertOptions option;
option.server_fqdn = *host_name;
if (absl::Status status =
GenerateSelfSignedCertAndDump(keypair_path, option);
!status.ok())
{
return absl::UnavailableError("unable to write self signed cert: " +
std::string(status.message()));
}
}
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