Implement support for sending pki::RequestCertificate messages in the cluster

refs #5450
This commit is contained in:
Gunnar Beutner 2017-08-23 15:11:32 +02:00
parent b08f5477dc
commit a4684d1bfd
4 changed files with 61 additions and 28 deletions

View File

@ -258,10 +258,41 @@ int PkiUtility::RequestCertificate(const String& host, const String& port, const
Dictionary::Ptr result = response->Get("result"); Dictionary::Ptr result = response->Get("result");
if (result->Contains("ca")) {
try {
StringToCertificate(result->Get("ca"));
} catch (const std::exception& ex) {
Log(LogCritical, "cli")
<< "Could not write CA file: " << DiagnosticInformation(ex, false);
return 1;
}
Log(LogInformation, "cli")
<< "Writing CA certificate to file '" << cafile << "'.";
std::ofstream fpca;
fpca.open(cafile.CStr());
fpca << result->Get("ca");
fpca.close();
if (fpca.fail()) {
Log(LogCritical, "cli")
<< "Could not open CA certificate file '" << cafile << "' for writing.";
return 1;
}
}
if (result->Contains("error")) { if (result->Contains("error")) {
LogSeverity severity; LogSeverity severity;
if (result->Get("status_code") == 1) Value vstatus;
if (!result->Get("status_code", &vstatus))
vstatus = 1;
int status = vstatus;
if (status == 1)
severity = LogCritical; severity = LogCritical;
else { else {
severity = LogInformation; severity = LogInformation;
@ -271,7 +302,7 @@ int PkiUtility::RequestCertificate(const String& host, const String& port, const
Log(severity, "cli") Log(severity, "cli")
<< "!!! " << result->Get("error"); << "!!! " << result->Get("error");
if (result->Get("status_code") == 1) if (status == 1)
return 1; return 1;
else { else {
Log(severity, "cli", "!!!!!!"); Log(severity, "cli", "!!!!!!");
@ -287,13 +318,8 @@ int PkiUtility::RequestCertificate(const String& host, const String& port, const
return 1; return 1;
} }
try { Log(LogInformation, "cli")
StringToCertificate(result->Get("ca")); << "Writing signed certificate to file '" << certfile << "'.";
} catch (const std::exception& ex) {
Log(LogCritical, "cli")
<< "Could not write CA file: " << DiagnosticInformation(ex, false);
return 1;
}
std::ofstream fpcert; std::ofstream fpcert;
fpcert.open(certfile.CStr()); fpcert.open(certfile.CStr());
@ -306,23 +332,6 @@ int PkiUtility::RequestCertificate(const String& host, const String& port, const
return 1; return 1;
} }
Log(LogInformation, "cli")
<< "Writing signed certificate to file '" << certfile << "'.";
std::ofstream fpca;
fpca.open(cafile.CStr());
fpca << result->Get("ca");
fpca.close();
if (fpca.fail()) {
Log(LogCritical, "cli")
<< "Could not open CA certificate file '" << cafile << "' for writing.";
return 1;
}
Log(LogInformation, "cli")
<< "Writing CA certificate to file '" << cafile << "'.";
return 0; return 0;
} }

View File

@ -478,6 +478,15 @@ void ApiListener::SyncClient(const JsonRpcConnection::Ptr& aclient, const Endpoi
endpoint->SetSyncing(true); endpoint->SetSyncing(true);
} }
Zone::Ptr myZone = Zone::GetLocalZone();
if (myZone->GetParent() == eZone) {
Log(LogInformation, "ApiListener")
<< "Requesting new certificate for this Icinga instance from endpoint '" << endpoint->GetName() << "'.";
SendCertificateRequest(aclient);
}
/* Make sure that the config updates are synced /* Make sure that the config updates are synced
* before the logs are replayed. * before the logs are replayed.
*/ */
@ -530,6 +539,19 @@ void ApiListener::SyncClient(const JsonRpcConnection::Ptr& aclient, const Endpoi
<< "Finished syncing endpoint '" << endpoint->GetName() << "' in zone '" << eZone->GetName() << "'."; << "Finished syncing endpoint '" << endpoint->GetName() << "' in zone '" << eZone->GetName() << "'.";
} }
void ApiListener::SendCertificateRequest(const JsonRpcConnection::Ptr& aclient)
{
Dictionary::Ptr message = new Dictionary();
message->Set("jsonrpc", "2.0");
message->Set("method", "pki::RequestCertificate");
Dictionary::Ptr params = new Dictionary();
message->Set("params", params);
JsonRpc::SendMessage(aclient->GetStream(), message);
}
void ApiListener::ApiTimerHandler(void) void ApiListener::ApiTimerHandler(void)
{ {
double now = Utility::GetTime(); double now = Utility::GetTime();

View File

@ -158,6 +158,7 @@ private:
static void ConfigGlobHandler(ConfigDirInformation& config, const String& path, const String& file); static void ConfigGlobHandler(ConfigDirInformation& config, const String& path, const String& file);
void SendConfigUpdate(const JsonRpcConnection::Ptr& aclient); void SendConfigUpdate(const JsonRpcConnection::Ptr& aclient);
void SendCertificateRequest(const JsonRpcConnection::Ptr& aclient);
/* configsync */ /* configsync */
void UpdateConfigObject(const ConfigObject::Ptr& object, const MessageOrigin::Ptr& origin, void UpdateConfigObject(const ConfigObject::Ptr& object, const MessageOrigin::Ptr& origin,

View File

@ -94,10 +94,11 @@ Value RequestCertificateHandler(const MessageOrigin::Ptr& origin, const Dictiona
if (!origin->FromClient->IsAuthenticated()) { if (!origin->FromClient->IsAuthenticated()) {
String salt = listener->GetTicketSalt(); String salt = listener->GetTicketSalt();
if (salt.IsEmpty()) String ticket = params->Get("ticket");
if (salt.IsEmpty() || ticket.IsEmpty())
goto delayed_request; goto delayed_request;
String ticket = params->Get("ticket");
String realTicket = PBKDF2_SHA1(origin->FromClient->GetIdentity(), salt, 50000); String realTicket = PBKDF2_SHA1(origin->FromClient->GetIdentity(), salt, 50000);
if (ticket != realTicket) { if (ticket != realTicket) {