| // 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 |