mirror of https://github.com/Icinga/icinga2.git
parent
3fd20d56aa
commit
f433679b13
|
@ -6,4 +6,6 @@ object ApiListener "api" {
|
|||
cert_path = SysconfDir + "/icinga2/pki/" + NodeName + ".crt"
|
||||
key_path = SysconfDir + "/icinga2/pki/" + NodeName + ".key"
|
||||
ca_path = SysconfDir + "/icinga2/pki/ca.crt"
|
||||
|
||||
//ticket_salt = "<secret key>"
|
||||
}
|
||||
|
|
|
@ -918,7 +918,7 @@ void Application::DeclareLocalStateDir(const String& path)
|
|||
*/
|
||||
String Application::GetZonesDir(void)
|
||||
{
|
||||
return ScriptVariable::Get("ZonesDir");
|
||||
return ScriptVariable::Get("ZonesDir", &Empty);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -938,7 +938,8 @@ void Application::DeclareZonesDir(const String& path)
|
|||
*/
|
||||
String Application::GetPkgDataDir(void)
|
||||
{
|
||||
return ScriptVariable::Get("PkgDataDir");
|
||||
String defaultValue = "";
|
||||
return ScriptVariable::Get("PkgDataDir", &Empty);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -958,7 +959,7 @@ void Application::DeclarePkgDataDir(const String& path)
|
|||
*/
|
||||
String Application::GetIncludeConfDir(void)
|
||||
{
|
||||
return ScriptVariable::Get("IncludeConfDir");
|
||||
return ScriptVariable::Get("IncludeConfDir", &Empty);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -978,7 +979,7 @@ void Application::DeclareIncludeConfDir(const String& path)
|
|||
*/
|
||||
String Application::GetStatePath(void)
|
||||
{
|
||||
return ScriptVariable::Get("StatePath");
|
||||
return ScriptVariable::Get("StatePath", &Empty);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -998,7 +999,7 @@ void Application::DeclareStatePath(const String& path)
|
|||
*/
|
||||
String Application::GetObjectsPath(void)
|
||||
{
|
||||
return ScriptVariable::Get("ObjectsPath");
|
||||
return ScriptVariable::Get("ObjectsPath", &Empty);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1018,7 +1019,7 @@ void Application::DeclareObjectsPath(const String& path)
|
|||
*/
|
||||
String Application::GetPidPath(void)
|
||||
{
|
||||
return ScriptVariable::Get("PidPath");
|
||||
return ScriptVariable::Get("PidPath", &Empty);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -51,12 +51,16 @@ Value ScriptVariable::GetData(void) const
|
|||
return m_Data;
|
||||
}
|
||||
|
||||
Value ScriptVariable::Get(const String& name)
|
||||
Value ScriptVariable::Get(const String& name, const Value *defaultValue)
|
||||
{
|
||||
ScriptVariable::Ptr sv = GetByName(name);
|
||||
|
||||
if (!sv)
|
||||
if (!sv) {
|
||||
if (defaultValue)
|
||||
return *defaultValue;
|
||||
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Tried to access undefined script variable '" + name + "'"));
|
||||
}
|
||||
|
||||
return sv->GetData();
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
static ScriptVariable::Ptr GetByName(const String& name);
|
||||
static void Unregister(const String& name);
|
||||
|
||||
static Value Get(const String& name);
|
||||
static Value Get(const String& name, const Value *defaultValue = NULL);
|
||||
static ScriptVariable::Ptr Set(const String& name, const Value& value, bool overwrite = true, bool make_const = false);
|
||||
|
||||
private:
|
||||
|
|
|
@ -161,7 +161,15 @@ size_t TlsStream::Read(void *buffer, size_t count)
|
|||
std::ostringstream msgbuf;
|
||||
char errbuf[120];
|
||||
|
||||
m_Socket->Poll(true, false);
|
||||
bool want_read;
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_SSLLock);
|
||||
want_read = SSL_want_read(m_SSL.get());
|
||||
}
|
||||
|
||||
if (want_read)
|
||||
m_Socket->Poll(true, false);
|
||||
|
||||
boost::mutex::scoped_lock alock(m_IOActionLock);
|
||||
|
||||
|
@ -213,7 +221,15 @@ void TlsStream::Write(const void *buffer, size_t count)
|
|||
std::ostringstream msgbuf;
|
||||
char errbuf[120];
|
||||
|
||||
m_Socket->Poll(false, true);
|
||||
bool want_write;
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_SSLLock);
|
||||
want_write = SSL_want_write(m_SSL.get());
|
||||
}
|
||||
|
||||
if (want_write)
|
||||
m_Socket->Poll(false, true);
|
||||
|
||||
boost::mutex::scoped_lock alock(m_IOActionLock);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "base/convert.hpp"
|
||||
#include "base/logger_fwd.hpp"
|
||||
#include "base/context.hpp"
|
||||
#include "base/application.hpp"
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
@ -110,29 +111,31 @@ shared_ptr<SSL_CTX> MakeSSLContext(const String& pubkey, const String& privkey,
|
|||
<< errinfo_openssl_error(ERR_peek_error()));
|
||||
}
|
||||
|
||||
if (!SSL_CTX_load_verify_locations(sslContext.get(), cakey.CStr(), NULL)) {
|
||||
msgbuf << "Error loading and verifying locations in ca key file '" << cakey << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
|
||||
Log(LogCritical, "SSL", msgbuf.str());
|
||||
BOOST_THROW_EXCEPTION(openssl_error()
|
||||
<< boost::errinfo_api_function("SSL_CTX_load_verify_locations")
|
||||
<< errinfo_openssl_error(ERR_peek_error())
|
||||
<< boost::errinfo_file_name(cakey));
|
||||
if (!cakey.IsEmpty()) {
|
||||
if (!SSL_CTX_load_verify_locations(sslContext.get(), cakey.CStr(), NULL)) {
|
||||
msgbuf << "Error loading and verifying locations in ca key file '" << cakey << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
|
||||
Log(LogCritical, "SSL", msgbuf.str());
|
||||
BOOST_THROW_EXCEPTION(openssl_error()
|
||||
<< boost::errinfo_api_function("SSL_CTX_load_verify_locations")
|
||||
<< errinfo_openssl_error(ERR_peek_error())
|
||||
<< boost::errinfo_file_name(cakey));
|
||||
}
|
||||
|
||||
STACK_OF(X509_NAME) *cert_names;
|
||||
|
||||
cert_names = SSL_load_client_CA_file(cakey.CStr());
|
||||
if (cert_names == NULL) {
|
||||
msgbuf << "Error loading client ca key file '" << cakey << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
|
||||
Log(LogCritical, "SSL", msgbuf.str());
|
||||
BOOST_THROW_EXCEPTION(openssl_error()
|
||||
<< boost::errinfo_api_function("SSL_load_client_CA_file")
|
||||
<< errinfo_openssl_error(ERR_peek_error())
|
||||
<< boost::errinfo_file_name(cakey));
|
||||
}
|
||||
|
||||
SSL_CTX_set_client_CA_list(sslContext.get(), cert_names);
|
||||
}
|
||||
|
||||
STACK_OF(X509_NAME) *cert_names;
|
||||
|
||||
cert_names = SSL_load_client_CA_file(cakey.CStr());
|
||||
if (cert_names == NULL) {
|
||||
msgbuf << "Error loading client ca key file '" << cakey << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
|
||||
Log(LogCritical, "SSL", msgbuf.str());
|
||||
BOOST_THROW_EXCEPTION(openssl_error()
|
||||
<< boost::errinfo_api_function("SSL_load_client_CA_file")
|
||||
<< errinfo_openssl_error(ERR_peek_error())
|
||||
<< boost::errinfo_file_name(cakey));
|
||||
}
|
||||
|
||||
SSL_CTX_set_client_CA_list(sslContext.get(), cert_names);
|
||||
|
||||
return sslContext;
|
||||
}
|
||||
|
||||
|
@ -268,7 +271,7 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
|
|||
X509_NAME *subject = X509_NAME_new();
|
||||
X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC, (unsigned char *)cn.CStr(), -1, -1, 0);
|
||||
|
||||
X509 *cert = CreateCert(key, subject, subject, key, ca);
|
||||
shared_ptr<X509> cert = CreateCert(key, subject, subject, key, ca);
|
||||
|
||||
X509_NAME_free(subject);
|
||||
|
||||
|
@ -276,10 +279,8 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
|
|||
|
||||
bio = BIO_new(BIO_s_file());
|
||||
BIO_write_filename(bio, const_cast<char *>(certfile.CStr()));
|
||||
PEM_write_bio_X509(bio, cert);
|
||||
PEM_write_bio_X509(bio, cert.get());
|
||||
BIO_free(bio);
|
||||
|
||||
X509_free(cert);
|
||||
}
|
||||
|
||||
if (!csrfile.IsEmpty()) {
|
||||
|
@ -311,7 +312,7 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
|
|||
return 1;
|
||||
}
|
||||
|
||||
X509 *CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PKEY *cakey, bool ca, const String& serialfile)
|
||||
shared_ptr<X509> CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PKEY *cakey, bool ca, const String& serialfile)
|
||||
{
|
||||
X509 *cert = X509_new();
|
||||
ASN1_INTEGER_set(X509_get_serialNumber(cert), 1);
|
||||
|
@ -337,7 +338,79 @@ X509 *CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PK
|
|||
|
||||
X509_sign(cert, cakey, EVP_sha1());
|
||||
|
||||
return cert;
|
||||
return shared_ptr<X509>(cert, X509_free);
|
||||
}
|
||||
|
||||
String GetIcingaCADir(void)
|
||||
{
|
||||
return Application::GetLocalStateDir() + "/lib/icinga2/ca";
|
||||
}
|
||||
|
||||
shared_ptr<X509> CreateCertIcingaCA(EVP_PKEY *pubkey, X509_NAME *subject)
|
||||
{
|
||||
std::stringstream msgbuf;
|
||||
char errbuf[120];
|
||||
|
||||
String cadir = GetIcingaCADir();
|
||||
|
||||
String cakeyfile = cadir + "/ca.key";
|
||||
|
||||
RSA *rsa;
|
||||
|
||||
BIO *cakeybio = BIO_new_file(const_cast<char *>(cakeyfile.CStr()), "r");
|
||||
|
||||
if (!cakeybio) {
|
||||
msgbuf << "Could not open CA key file '" << cakeyfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
|
||||
Log(LogCritical, "SSL", msgbuf.str());
|
||||
return shared_ptr<X509>();
|
||||
}
|
||||
|
||||
rsa = PEM_read_bio_RSAPrivateKey(cakeybio, NULL, NULL, NULL);
|
||||
|
||||
if (!rsa) {
|
||||
msgbuf << "Could not read RSA key from CA key file '" << cakeyfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
|
||||
Log(LogCritical, "SSL", msgbuf.str());
|
||||
return shared_ptr<X509>();
|
||||
}
|
||||
|
||||
BIO_free(cakeybio);
|
||||
|
||||
String cacertfile = cadir + "/ca.crt";
|
||||
|
||||
shared_ptr<X509> cacert = GetX509Certificate(cacertfile);
|
||||
|
||||
EVP_PKEY *privkey = EVP_PKEY_new();
|
||||
EVP_PKEY_assign_RSA(privkey, rsa);
|
||||
|
||||
return CreateCert(pubkey, subject, X509_get_subject_name(cacert.get()), privkey, false, cadir + "/serial.txt");
|
||||
}
|
||||
|
||||
String CertificateToString(const shared_ptr<X509>& cert)
|
||||
{
|
||||
BIO *mem = BIO_new(BIO_s_mem());
|
||||
PEM_write_bio_X509(mem, cert.get());
|
||||
|
||||
char *data;
|
||||
long len = BIO_get_mem_data(mem, &data);
|
||||
|
||||
String result = String(data, data + len);
|
||||
|
||||
BIO_free(mem);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String PBKDF2_SHA512(const String& password, const String& salt, int iterations)
|
||||
{
|
||||
unsigned char digest[SHA512_DIGEST_LENGTH];
|
||||
PKCS5_PBKDF2_HMAC(password.CStr(), password.GetLength(), reinterpret_cast<const unsigned char *>(salt.CStr()), salt.GetLength(),
|
||||
iterations, EVP_sha512(), sizeof(digest), digest);
|
||||
|
||||
char output[SHA512_DIGEST_LENGTH*2+1];
|
||||
for (int i = 0; i < 32; i++)
|
||||
sprintf(output + 2 * i, "%02x", digest[i]);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
String SHA256(const String& s)
|
||||
|
@ -371,9 +444,8 @@ String SHA256(const String& s)
|
|||
<< errinfo_openssl_error(ERR_peek_error()));
|
||||
}
|
||||
|
||||
int i;
|
||||
char output[SHA256_DIGEST_LENGTH*2+1];
|
||||
for (i = 0; i < 32; i++)
|
||||
for (int i = 0; i < 32; i++)
|
||||
sprintf(output + 2 * i, "%02x", digest[i]);
|
||||
|
||||
return output;
|
||||
|
|
|
@ -35,12 +35,16 @@ namespace icinga
|
|||
{
|
||||
|
||||
void I2_BASE_API InitializeOpenSSL(void);
|
||||
shared_ptr<SSL_CTX> I2_BASE_API MakeSSLContext(const String& pubkey, const String& privkey, const String& cakey);
|
||||
shared_ptr<SSL_CTX> I2_BASE_API MakeSSLContext(const String& pubkey, const String& privkey, const String& cakey = String());
|
||||
void I2_BASE_API AddCRLToSSLContext(const shared_ptr<SSL_CTX>& context, const String& crlPath);
|
||||
String I2_BASE_API GetCertificateCN(const shared_ptr<X509>& certificate);
|
||||
shared_ptr<X509> I2_BASE_API GetX509Certificate(const String& pemfile);
|
||||
int I2_BASE_API MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile = String(), const String& certfile = String(), bool ca = false);
|
||||
X509 * I2_BASE_API CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PKEY *cakey, bool ca, const String& serialfile = String());
|
||||
shared_ptr<X509> I2_BASE_API CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PKEY *cakey, bool ca, const String& serialfile = String());
|
||||
String I2_BASE_API GetIcingaCADir(void);
|
||||
String I2_BASE_API CertificateToString(const shared_ptr<X509>& cert);
|
||||
shared_ptr<X509> I2_BASE_API CreateCertIcingaCA(EVP_PKEY *pubkey, X509_NAME *subject);
|
||||
String I2_BASE_API PBKDF2_SHA512(const String& password, const String& salt, int iterations);
|
||||
String I2_BASE_API SHA256(const String& s);
|
||||
|
||||
class I2_BASE_API openssl_error : virtual public std::exception, virtual public boost::exception { };
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
set(cli_SOURCES
|
||||
featureenablecommand.cpp featuredisablecommand.cpp featurelistcommand.cpp
|
||||
objectlistcommand.cpp
|
||||
pkinewcacommand.cpp pkinewcertcommand.cpp pkisigncsrcommand.cpp
|
||||
pkinewcacommand.cpp pkinewcertcommand.cpp pkisigncsrcommand.cpp pkirequestcommand.cpp pkiticketcommand.cpp
|
||||
daemoncommand.cpp
|
||||
)
|
||||
|
||||
|
@ -28,7 +28,7 @@ endif()
|
|||
|
||||
add_library(cli SHARED ${cli_SOURCES})
|
||||
|
||||
target_link_libraries(cli ${Boost_LIBRARIES} base config)
|
||||
target_link_libraries(cli ${Boost_LIBRARIES} base config remote)
|
||||
|
||||
set_target_properties (
|
||||
cli PROPERTIES
|
||||
|
|
|
@ -68,73 +68,11 @@ int PKISignCSRCommand::Run(const boost::program_options::variables_map& vm, cons
|
|||
|
||||
BIO_free(csrbio);
|
||||
|
||||
String cadir = Application::GetLocalStateDir() + "/lib/icinga2/ca";
|
||||
shared_ptr<X509> cert = CreateCertIcingaCA(X509_REQ_get_pubkey(req), X509_REQ_get_subject_name(req));
|
||||
|
||||
String cakeyfile = cadir + "/ca.key";
|
||||
X509_REQ_free(req);
|
||||
|
||||
RSA *rsa;
|
||||
|
||||
BIO *cakeybio = BIO_new_file(const_cast<char *>(cakeyfile.CStr()), "r");
|
||||
|
||||
if (!cakeybio) {
|
||||
msgbuf << "Could not open CA key file '" << cakeyfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
|
||||
Log(LogCritical, "SSL", msgbuf.str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
rsa = PEM_read_bio_RSAPrivateKey(cakeybio, NULL, NULL, NULL);
|
||||
|
||||
if (!rsa) {
|
||||
msgbuf << "Could not read RSA key from CA key file '" << cakeyfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
|
||||
Log(LogCritical, "SSL", msgbuf.str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
BIO_free(cakeybio);
|
||||
|
||||
String cacertfile = cadir + "/ca.crt";
|
||||
|
||||
BIO *cacertbio = BIO_new_file(const_cast<char *>(cacertfile.CStr()), "r");
|
||||
|
||||
if (!cacertbio) {
|
||||
msgbuf << "Could not open CA certificate file '" << cakeyfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
|
||||
Log(LogCritical, "SSL", msgbuf.str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
X509 *cacert = PEM_read_bio_X509(cacertbio, NULL, NULL, NULL);
|
||||
|
||||
if (!cacert) {
|
||||
msgbuf << "Could not read X509 certificate from CA certificate file '" << cakeyfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
|
||||
Log(LogCritical, "SSL", msgbuf.str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
BIO_free(cacertbio);
|
||||
|
||||
EVP_PKEY *privkey = EVP_PKEY_new();
|
||||
EVP_PKEY_assign_RSA(privkey, rsa);
|
||||
|
||||
EVP_PKEY *pubkey = X509_REQ_get_pubkey(req);
|
||||
|
||||
X509 *cert = CreateCert(pubkey, X509_REQ_get_subject_name(req), X509_get_subject_name(cacert), privkey, false);
|
||||
|
||||
EVP_PKEY_free(pubkey);
|
||||
X509_free(cacert);
|
||||
|
||||
BIO *certbio = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
|
||||
if (!PEM_write_bio_X509(certbio, cert)) {
|
||||
BIO_free(certbio);
|
||||
|
||||
msgbuf << "Could not write X509 certificate: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
|
||||
Log(LogCritical, "SSL", msgbuf.str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
X509_free(cert);
|
||||
|
||||
BIO_free(certbio);
|
||||
std::cout << CertificateToString(cert);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,10 @@ using namespace icinga;
|
|||
|
||||
static Value SetLogPositionHandler(const MessageOrigin& origin, const Dictionary::Ptr& params);
|
||||
REGISTER_APIFUNCTION(SetLogPosition, log, &SetLogPositionHandler);
|
||||
static Value RequestCertificateHandler(const MessageOrigin& origin, const Dictionary::Ptr& params);
|
||||
REGISTER_APIFUNCTION(RequestCertificate, pki, &RequestCertificateHandler);
|
||||
|
||||
ApiClient::ApiClient(const String& identity, bool authenticated, const Stream::Ptr& stream, ConnectionRole role)
|
||||
ApiClient::ApiClient(const String& identity, bool authenticated, const TlsStream::Ptr& stream, ConnectionRole role)
|
||||
: m_Identity(identity), m_Authenticated(authenticated), m_Stream(stream), m_Role(role), m_Seen(Utility::GetTime())
|
||||
{
|
||||
if (authenticated)
|
||||
|
@ -60,7 +62,7 @@ Endpoint::Ptr ApiClient::GetEndpoint(void) const
|
|||
return m_Endpoint;
|
||||
}
|
||||
|
||||
Stream::Ptr ApiClient::GetStream(void) const
|
||||
TlsStream::Ptr ApiClient::GetStream(void) const
|
||||
{
|
||||
return m_Stream;
|
||||
}
|
||||
|
@ -220,3 +222,41 @@ Value SetLogPositionHandler(const MessageOrigin& origin, const Dictionary::Ptr&
|
|||
|
||||
return Empty;
|
||||
}
|
||||
|
||||
Value RequestCertificateHandler(const MessageOrigin& origin, const Dictionary::Ptr& params)
|
||||
{
|
||||
if (!params)
|
||||
return Empty;
|
||||
|
||||
ApiListener::Ptr listener = ApiListener::GetInstance();
|
||||
String salt = listener->GetTicketSalt();
|
||||
|
||||
Dictionary::Ptr result = make_shared<Dictionary>();
|
||||
|
||||
if (salt.IsEmpty()) {
|
||||
result->Set("error", "Ticket salt is not configured.");
|
||||
return result;
|
||||
}
|
||||
|
||||
String ticket = params->Get("ticket");
|
||||
String realTicket = PBKDF2_SHA512(origin.FromClient->GetIdentity(), salt, 50000);
|
||||
|
||||
if (ticket != realTicket) {
|
||||
result->Set("error", "Invalid ticket.");
|
||||
return result;
|
||||
}
|
||||
|
||||
shared_ptr<X509> cert = origin.FromClient->GetStream()->GetPeerCertificate();
|
||||
|
||||
EVP_PKEY *pubkey = X509_get_pubkey(cert.get());
|
||||
X509_NAME *subject = X509_get_subject_name(cert.get());
|
||||
|
||||
shared_ptr<X509> newcert = CreateCertIcingaCA(pubkey, subject);
|
||||
result->Set("cert", CertificateToString(newcert));
|
||||
|
||||
String cacertfile = GetIcingaCADir() + "/ca.crt";
|
||||
shared_ptr<X509> cacert = GetX509Certificate(cacertfile);
|
||||
result->Set("ca", CertificateToString(cacert));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#define APICLIENT_H
|
||||
|
||||
#include "remote/endpoint.hpp"
|
||||
#include "base/stream.hpp"
|
||||
#include "base/tlsstream.hpp"
|
||||
#include "base/timer.hpp"
|
||||
#include "base/workqueue.hpp"
|
||||
#include "remote/i2-remote.hpp"
|
||||
|
@ -45,14 +45,14 @@ class I2_REMOTE_API ApiClient : public Object
|
|||
public:
|
||||
DECLARE_PTR_TYPEDEFS(ApiClient);
|
||||
|
||||
ApiClient(const String& identity, bool authenticated, const Stream::Ptr& stream, ConnectionRole role);
|
||||
ApiClient(const String& identity, bool authenticated, const TlsStream::Ptr& stream, ConnectionRole role);
|
||||
|
||||
void Start(void);
|
||||
|
||||
String GetIdentity(void) const;
|
||||
bool IsAuthenticated(void) const;
|
||||
Endpoint::Ptr GetEndpoint(void) const;
|
||||
Stream::Ptr GetStream(void) const;
|
||||
TlsStream::Ptr GetStream(void) const;
|
||||
ConnectionRole GetRole(void) const;
|
||||
|
||||
void Disconnect(void);
|
||||
|
@ -64,7 +64,7 @@ private:
|
|||
String m_Identity;
|
||||
bool m_Authenticated;
|
||||
Endpoint::Ptr m_Endpoint;
|
||||
Stream::Ptr m_Stream;
|
||||
TlsStream::Ptr m_Stream;
|
||||
ConnectionRole m_Role;
|
||||
double m_Seen;
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ class ApiListener : DynamicObject
|
|||
|
||||
[config] bool accept_config;
|
||||
|
||||
[config] String ticket_salt;
|
||||
|
||||
[state] double log_message_timestamp;
|
||||
|
||||
String identity;
|
||||
|
|
|
@ -32,7 +32,9 @@
|
|||
%attribute %string "bind_host",
|
||||
%attribute %string "bind_port",
|
||||
|
||||
%attribute %number "accept_config"
|
||||
%attribute %number "accept_config",
|
||||
|
||||
%attribute %string "ticket_salt"
|
||||
}
|
||||
|
||||
%type Endpoint {
|
||||
|
|
Loading…
Reference in New Issue