]> granicus.if.org Git - icinga2/blob - lib/cli/casigncommand.cpp
add some object locking to the Dump method (which could theoreticylly suffer from...
[icinga2] / lib / cli / casigncommand.cpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #include "cli/casigncommand.hpp"
4 #include "remote/apilistener.hpp"
5 #include "base/logger.hpp"
6 #include "base/application.hpp"
7 #include "base/tlsutility.hpp"
8
9 using namespace icinga;
10
11 REGISTER_CLICOMMAND("ca/sign", CASignCommand);
12
13 String CASignCommand::GetDescription() const
14 {
15         return "Signs an outstanding certificate request.";
16 }
17
18 String CASignCommand::GetShortDescription() const
19 {
20         return "signs an outstanding certificate request";
21 }
22
23 int CASignCommand::GetMinArguments() const
24 {
25         return 1;
26 }
27
28 ImpersonationLevel CASignCommand::GetImpersonationLevel() const
29 {
30         return ImpersonateIcinga;
31 }
32
33 /**
34  * The entry point for the "ca sign" CLI command.
35  *
36  * @returns An exit status.
37  */
38 int CASignCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
39 {
40         String requestFile = ApiListener::GetCertificateRequestsDir() + "/" + ap[0] + ".json";
41
42         if (!Utility::PathExists(requestFile)) {
43                 Log(LogCritical, "cli")
44                         << "No request exists for fingerprint '" << ap[0] << "'.";
45                 return 1;
46         }
47
48         Dictionary::Ptr request = Utility::LoadJsonFile(requestFile);
49
50         if (!request)
51                 return 1;
52
53         String certRequestText = request->Get("cert_request");
54
55         std::shared_ptr<X509> certRequest = StringToCertificate(certRequestText);
56
57         if (!certRequest) {
58                 Log(LogCritical, "cli", "Certificate request is invalid. Could not parse X.509 certificate for the 'cert_request' attribute.");
59                 return 1;
60         }
61
62         std::shared_ptr<X509> certResponse = CreateCertIcingaCA(certRequest);
63
64         BIO *out = BIO_new(BIO_s_mem());
65         X509_NAME_print_ex(out, X509_get_subject_name(certRequest.get()), 0, XN_FLAG_ONELINE & ~ASN1_STRFLGS_ESC_MSB);
66
67         char *data;
68         long length;
69         length = BIO_get_mem_data(out, &data);
70
71         String subject = String(data, data + length);
72         BIO_free(out);
73
74         if (!certResponse) {
75                 Log(LogCritical, "cli")
76                         << "Could not sign certificate for '" << subject << "'.";
77                 return 1;
78         }
79
80         request->Set("cert_response", CertificateToString(certResponse));
81
82         Utility::SaveJsonFile(requestFile, 0600, request);
83
84         Log(LogInformation, "cli")
85                 << "Signed certificate for '" << subject << "'.";
86
87         return 0;
88 }