]> granicus.if.org Git - icinga2/commitdiff
Implement SSL support.
authorGunnar Beutner <gunnar.beutner@netways.de>
Tue, 24 Apr 2012 12:02:15 +0000 (14:02 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Tue, 24 Apr 2012 12:02:15 +0000 (14:02 +0200)
37 files changed:
base/application.cpp
base/base.vcxproj
base/component.cpp
base/condvar.cpp
base/configcollection.cpp
base/configcollection.h
base/confighive.cpp
base/confighive.h
base/configobject.cpp
base/i2-base.h
base/object.h
base/socket.cpp
base/socket.h
base/tcpclient.cpp
base/tcpclient.h
base/tcpserver.cpp
base/tcpserver.h
base/tlsclient.cpp [new file with mode: 0644]
base/tlsclient.h [new file with mode: 0644]
base/utility.cpp
base/utility.h
icinga-app/ca.crt [new file with mode: 0644]
icinga-app/ca.key [new file with mode: 0644]
icinga-app/icinga-c1.crt [new file with mode: 0644]
icinga-app/icinga-c1.key [new file with mode: 0644]
icinga-app/icinga-c2.crt [new file with mode: 0644]
icinga-app/icinga-c2.key [new file with mode: 0644]
icinga/endpointmanager.cpp
icinga/endpointmanager.h
icinga/icingaapplication.cpp
icinga/icingaapplication.h
icinga/jsonrpcendpoint.cpp
icinga/jsonrpcendpoint.h
jsonrpc/jsonrpcclient.cpp
jsonrpc/jsonrpcclient.h
jsonrpc/jsonrpcserver.cpp
jsonrpc/jsonrpcserver.h

index def10cce6fd4f3d8241d2b60435a12fd70abaffe..945ee7c0bc9cdbad6399ed56ed07ea6dbcb747b6 100644 (file)
@@ -8,6 +8,11 @@ using namespace icinga;
 
 Application::Ptr I2_EXPORT Application::Instance;
 
+/**
+ * Application
+ *
+ * Constructor for the Application class.
+ */
 Application::Application(void)
 {
 #ifdef _WIN32
@@ -29,8 +34,14 @@ Application::Application(void)
        m_ConfigHive = make_shared<ConfigHive>();
 }
 
+/**
+ * ~Application
+ *
+ * Destructor for the application class.
+ */
 Application::~Application(void)
 {
+       /* stop all components */
        for (map<string, Component::Ptr>::iterator i = m_Components.begin();
            i != m_Components.end(); i++) {
                i->second->Stop();
@@ -45,6 +56,11 @@ Application::~Application(void)
 #endif /* _WIN32 */
 }
 
+/**
+ * RunEventLoop
+ *
+ * Processes events (e.g. sockets and timers).
+ */
 void Application::RunEventLoop(void)
 {
        while (!m_ShuttingDown) {
@@ -141,16 +157,38 @@ void Application::RunEventLoop(void)
        }
 }
 
+/**
+ * Shutdown
+ *
+ * Signals the application to shut down during the next
+ * execution of the event loop.
+ */
 void Application::Shutdown(void)
 {
        m_ShuttingDown = true;
 }
 
+/**
+ * GetConfigHive
+ *
+ * Returns the application's configuration hive.
+ *
+ * @returns The config hive.
+ */
 ConfigHive::Ptr Application::GetConfigHive(void) const
 {
        return m_ConfigHive;
 }
 
+/**
+ * LoadComponent
+ *
+ * Loads a component from a library.
+ *
+ * @param path The path of the component library.
+ * @param componentConfig The configuration for the component.
+ * @returns The component.
+ */
 Component::Ptr Application::LoadComponent(const string& path,
     const ConfigObject::Ptr& componentConfig)
 {
@@ -186,6 +224,13 @@ Component::Ptr Application::LoadComponent(const string& path,
        return component;
 }
 
+/**
+ * RegisterComponent
+ *
+ * Registers a component object and starts it.
+ *
+ * @param component The component.
+ */
 void Application::RegisterComponent(Component::Ptr component)
 {
        component->SetApplication(static_pointer_cast<Application>(shared_from_this()));
@@ -194,18 +239,33 @@ void Application::RegisterComponent(Component::Ptr component)
        component->Start();
 }
 
+/**
+ * UnregisterComponent
+ *
+ * Unregisters a component object and stops it.
+ *
+ * @param component The component.
+ */
 void Application::UnregisterComponent(Component::Ptr component)
 {
        string name = component->GetName();
 
        Log("Unloading component '%s'", name.c_str());
        map<string, Component::Ptr>::iterator i = m_Components.find(name);
-       if (i != m_Components.end()) {
+       if (i != m_Components.end())
                m_Components.erase(i);
-               component->Stop();
-       }
+               
+       component->Stop();
 }
 
+/**
+ * GetComponent
+ *
+ * Finds a loaded component by name.
+ *
+ * @param name The name of the component.
+ * @returns The component or a null pointer if the component could not be found.
+ */
 Component::Ptr Application::GetComponent(const string& name)
 {
        map<string, Component::Ptr>::iterator ci = m_Components.find(name);
@@ -216,6 +276,14 @@ Component::Ptr Application::GetComponent(const string& name)
        return ci->second;
 }
 
+/**
+ * Log
+ *
+ * Logs a message.
+ *
+ * @param format The format string.
+ * @param ... Additional parameters for the format string.
+ */
 void Application::Log(const char *format, ...)
 {
        char message[512];
@@ -229,16 +297,37 @@ void Application::Log(const char *format, ...)
        fprintf(stderr, "%s\n", message);
 }
 
+/**
+ * SetArguments
+ *
+ * Sets the application's arguments.
+ *
+ * @param arguments The arguments.
+ */
 void Application::SetArguments(const vector<string>& arguments)
 {
        m_Arguments = arguments;
 }
 
+/**
+ * GetArguments
+ *
+ * Retrieves the application's arguments.
+ *
+ * @returns The arguments.
+ */
 const vector<string>& Application::GetArguments(void) const
 {
        return m_Arguments;
 }
 
+/**
+ * GetExeDirectory
+ *
+ * Retrieves the directory the application's binary is contained in.
+ *
+ * @returns The directory.
+ */
 string Application::GetExeDirectory(void) const
 {
        static string ExePath;
@@ -314,6 +403,13 @@ string Application::GetExeDirectory(void) const
        return ExePath;
 }
 
+/**
+ * AddComponentSearchDir
+ *
+ * Adds a directory to the component search path.
+ *
+ * @param componentDirectory The directory.
+ */
 void Application::AddComponentSearchDir(const string& componentDirectory)
 {
 #ifdef _WIN32
@@ -323,14 +419,30 @@ void Application::AddComponentSearchDir(const string& componentDirectory)
 #endif /* _WIN32 */
 }
 
+/**
+ * IsDebugging
+ *
+ * Retrieves the debugging mode of the application.
+ *
+ * @returns true if the application is being debugged, false otherwise
+ */
 bool Application::IsDebugging(void) const
 {
        return m_Debugging;
 }
 
 #ifndef _WIN32
+/**
+ * ApplicationSigIntHandler
+ *
+ * Signal handler for SIGINT.
+ *
+ * @param signum The signal number.
+ */
 static void ApplicationSigIntHandler(int signum)
 {
+       assert(signum == SIGINT);
+
        Application::Instance->Shutdown();
 
        struct sigaction sa;
@@ -340,6 +452,16 @@ static void ApplicationSigIntHandler(int signum)
 }
 #endif /* _WIN32 */
 
+/**
+ * RunApplication
+ *
+ * Runs the specified application.
+ *
+ * @param argc The number of arguments.
+ * @param argv The arguments that should be passed to the application.
+ * @param instance The application instance.
+ * @returns The application's exit code.
+ */
 int icinga::RunApplication(int argc, char **argv, Application *instance)
 {
        int result;
index 96447590695f4f18ece3719f2d03365fcae2259c..50b13abfad1ea4358815919ac5dac61155b1d677 100644 (file)
@@ -29,6 +29,7 @@
     <ClCompile Include="tcpsocket.cpp" />
     <ClCompile Include="thread.cpp" />
     <ClCompile Include="timer.cpp" />
+    <ClCompile Include="tlsclient.cpp" />
     <ClCompile Include="unix.cpp" />
     <ClCompile Include="utility.cpp" />
     <ClCompile Include="variant.cpp" />
@@ -56,6 +57,7 @@
     <ClInclude Include="tcpsocket.h" />
     <ClInclude Include="thread.h" />
     <ClInclude Include="timer.h" />
+    <ClInclude Include="tlsclient.h" />
     <ClInclude Include="unix.h" />
     <ClInclude Include="utility.h" />
     <ClInclude Include="variant.h" />
     <Link>
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>ws2_32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;shlwapi.lib;libeay32MTd.lib;ssleay32MTd.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Lib>
       <AdditionalDependencies>ws2_32.lib;shlwapi.lib</AdditionalDependencies>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>ws2_32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;shlwapi.lib;libeay32MT.lib;ssleay32MT.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <Lib>
       <AdditionalDependencies>ws2_32.lib;shlwapi.lib</AdditionalDependencies>
index 4c37bda00d1d84aa76aec19ec134f81f0c475d3d..8f06cf391b8b29910e02ca2ff40c2723bdad8cd2 100644 (file)
@@ -2,21 +2,49 @@
 
 using namespace icinga;
 
+/**
+ * SetApplication
+ *
+ * Sets the application this component belongs to.
+ *
+ * @param application The application.
+ */
 void Component::SetApplication(const Application::WeakPtr& application)
 {
        m_Application = application;
 }
 
+/**
+ * GetApplication
+ *
+ * Retrieves the application this component belongs to.
+ *
+ * @returns The application.
+ */
 Application::Ptr Component::GetApplication(void) const
 {
        return m_Application.lock();
 }
 
+/**
+ * SetConfig
+ *
+ * Sets the configuration for this component.
+ *
+ * @param componentConfig The configuration.
+ */
 void Component::SetConfig(const ConfigObject::Ptr& componentConfig)
 {
        m_Config = componentConfig;
 }
 
+/**
+ * GetConfig
+ *
+ * Retrieves the configuration for this component.
+ *
+ * @returns The configuration.
+ */
 ConfigObject::Ptr Component::GetConfig(void) const
 {
        return m_Config;
index c0c479c4a98a2c9b72f5edfbf66bfd4b7ddc6690..ccc744940473dcd5027b1993615e35a1c9545187 100644 (file)
@@ -2,6 +2,11 @@
 
 using namespace icinga;
 
+/**
+ * CondVar
+ *
+ * Constructor for the CondVar class.
+ */
 CondVar::CondVar(void)
 {
 #ifdef _WIN32
@@ -11,6 +16,11 @@ CondVar::CondVar(void)
 #endif /* _WIN32 */
 }
 
+/**
+ * ~CondVar
+ *
+ * Destructor for the CondVar class.
+ */
 CondVar::~CondVar(void)
 {
 #ifdef _WIN32
@@ -20,6 +30,14 @@ CondVar::~CondVar(void)
 #endif /* _WIN32 */
 }
 
+/**
+ * Wait
+ *
+ * Waits for the condition variable to be signaled. Releases the specified mutex
+ * before it begins to wait and re-acquires the mutex after waiting.
+ *
+ * @param mtx The mutex that should be released during waiting.
+ */
 void CondVar::Wait(Mutex& mtx)
 {
 #ifdef _WIN32
@@ -29,6 +47,11 @@ void CondVar::Wait(Mutex& mtx)
 #endif /* _WIN32 */
 }
 
+/**
+ * Signal
+ *
+ * Wakes up at least one waiting thread.
+ */
 void CondVar::Signal(void)
 {
 #ifdef _WIN32
@@ -38,6 +61,11 @@ void CondVar::Signal(void)
 #endif /* _WIN32 */
 }
 
+/**
+ * Broadcast
+ *
+ * Wakes up all waiting threads.
+ */
 void CondVar::Broadcast(void)
 {
 #ifdef _WIN32
@@ -47,7 +75,13 @@ void CondVar::Broadcast(void)
 #endif /* _WIN32 */
 }
 
-
+/**
+ * Get
+ *
+ * Retrieves the platform-specific condition variable handle.
+ *
+ * @returns The platform-specific condition variable handle.
+ */
 #ifdef _WIN32
 CONDITION_VARIABLE *CondVar::Get(void)
 #else /* _WIN32 */
index aecca6de122c95570931729062b099771a69fbc4..a4c0d640d4d76497055e9d2b64915d9c4e16cfa8 100644 (file)
@@ -2,16 +2,37 @@
 
 using namespace icinga;
 
+/**
+ * SetHive
+ *
+ * Sets the hive this collection belongs to.
+ *
+ * @param hive The hive.
+ */
 void ConfigCollection::SetHive(const ConfigHive::WeakPtr& hive)
 {
        m_Hive = hive;
 }
 
+/**
+ * GetHive
+ *
+ * Retrieves the hive this collection belongs to.
+ *
+ * @returns The hive.
+ */
 ConfigHive::WeakPtr ConfigCollection::GetHive(void) const
 {
        return m_Hive;
 }
 
+/**
+ * AddObject
+ *
+ * Adds a new object to this collection.
+ *
+ * @param object The new object.
+ */
 void ConfigCollection::AddObject(const ConfigObject::Ptr& object)
 {
        RemoveObject(object);
@@ -27,6 +48,13 @@ void ConfigCollection::AddObject(const ConfigObject::Ptr& object)
                hive->OnObjectCreated(ea);
 }
 
+/**
+ * RemoveObject
+ *
+ * Removes an object from this collection
+ *
+ * @param object The object that is to be removed.
+ */
 void ConfigCollection::RemoveObject(const ConfigObject::Ptr& object)
 {
        ObjectIterator oi = Objects.find(object->GetName());
@@ -44,9 +72,18 @@ void ConfigCollection::RemoveObject(const ConfigObject::Ptr& object)
        }
 }
 
-ConfigObject::Ptr ConfigCollection::GetObject(const string& name)
+/**
+ * GetObject
+ *
+ * Retrieves an object by name.
+ *
+ * @param name The name of the object.
+ * @returns The object or a null pointer if the specified object
+ *          could not be found.
+ */
+ConfigObject::Ptr ConfigCollection::GetObject(const string& name) const
 {
-       ObjectIterator oi = Objects.find(name);
+       ObjectConstIterator oi = Objects.find(name);
 
        if (oi == Objects.end())
                return ConfigObject::Ptr();
@@ -54,6 +91,13 @@ ConfigObject::Ptr ConfigCollection::GetObject(const string& name)
        return oi->second;
 }
 
+/**
+ * ForEachObject
+ *
+ * Invokes the specified callback for each object contained in this collection.
+ *
+ * @param callback The callback.
+ */
 void ConfigCollection::ForEachObject(function<int (const EventArgs&)> callback)
 {
        EventArgs ea;
index dd9658c2f2f6e1ba953ed76f359ad9b3431f98c4..6dc1a66ba4ae57af29a9a8b85f2c0189d8c8b1e5 100644 (file)
@@ -16,6 +16,7 @@ public:
        typedef weak_ptr<ConfigCollection> WeakPtr;
 
        typedef map<string, ConfigObject::Ptr>::iterator ObjectIterator;
+       typedef map<string, ConfigObject::Ptr>::const_iterator ObjectConstIterator;
        map<string, ConfigObject::Ptr> Objects;
 
        void SetHive(const weak_ptr<ConfigHive>& hive);
@@ -23,7 +24,7 @@ public:
 
        void AddObject(const ConfigObject::Ptr& object);
        void RemoveObject(const ConfigObject::Ptr& object);
-       ConfigObject::Ptr GetObject(const string& name = string());
+       ConfigObject::Ptr GetObject(const string& name = string()) const;
 
        void ForEachObject(function<int (const EventArgs&)> callback);
 
index b51c15d8c21a0a0ea1679c16e2fe4704c7e0744e..b077b6ac1c703d340ba1a68aa7e4ec1acbf0f2a3 100644 (file)
@@ -2,25 +2,59 @@
 
 using namespace icinga;
 
+/**
+ * AddObject
+ *
+ * Adds a new object to this hive.
+ *
+ * @param object The new object.
+ */
 void ConfigHive::AddObject(const ConfigObject::Ptr& object)
 {
        object->SetHive(static_pointer_cast<ConfigHive>(shared_from_this()));
        GetCollection(object->GetType())->AddObject(object);
 }
 
+/**
+ * RemoveObject
+ *
+ * Removes an object from this hive.
+ *
+ * @param object The object that is to be removed.
+ */
 void ConfigHive::RemoveObject(const ConfigObject::Ptr& object)
 {
        GetCollection(object->GetType())->RemoveObject(object);
 }
 
+/**
+ * GetObject
+ *
+ * Retrieves an object by type and name.
+ *
+ * @param type The type of the object.
+ * @param name The name of the object.
+ * @returns The object or a null pointer if the specified object
+ *          could not be found.
+ */
 ConfigObject::Ptr ConfigHive::GetObject(const string& type, const string& name)
 {
        return GetCollection(type)->GetObject(name);
 }
 
+/**
+ * GetCollection
+ *
+ * Retrieves a collection by name. Creates an empty collection
+ * if the collection doesn't already exist.
+ *
+ * @param collection The name of the collection.
+ * @returns The collection or a null pointer if the specified collection
+ *          could not be found.
+ */
 ConfigCollection::Ptr ConfigHive::GetCollection(const string& collection)
 {
-       CollectionIterator ci = Collections.find(collection);
+       CollectionConstIterator ci = Collections.find(collection);
 
        if (ci == Collections.end()) {
                Collections[collection] = make_shared<ConfigCollection>();
@@ -30,6 +64,13 @@ ConfigCollection::Ptr ConfigHive::GetCollection(const string& collection)
        return ci->second;
 }
 
+/**
+ * ForEachObject
+ *
+ * Invokes the specified callback for each object contained in this hive.
+ *
+ * @param callback The callback.
+ */
 void ConfigHive::ForEachObject(const string& type,
     function<int (const EventArgs&)> callback)
 {
index e5b3bfb6dd1b00c4e8849f076bbe3b09d7c61542..52701ebfe6e8ee078a36653ad1b00abb1e4a28be 100644 (file)
@@ -11,6 +11,7 @@ public:
        typedef weak_ptr<ConfigHive> WeakPtr;
 
        typedef map<string, ConfigCollection::Ptr>::iterator CollectionIterator;
+       typedef map<string, ConfigCollection::Ptr>::const_iterator CollectionConstIterator;
        map<string, ConfigCollection::Ptr> Collections;
 
        void AddObject(const ConfigObject::Ptr& object);
index 2999a6aa9185a597f4252649ea0d1e809e317068..2189348fe3ed728aeabd00a830e980334af12008 100644 (file)
@@ -2,6 +2,14 @@
 
 using namespace icinga;
 
+/**
+ * ConfigObject
+ *
+ * Constructor for the ConfigObject class.
+ *
+ * @param type The type of the object.
+ * @param name The name of the object.
+ */
 ConfigObject::ConfigObject(const string& type, const string& name)
 {
        m_Type = type;
@@ -9,6 +17,13 @@ ConfigObject::ConfigObject(const string& type, const string& name)
        m_Replicated = false;
 }
 
+/**
+ * SetHive
+ *
+ * Sets the hive this object belongs to.
+ *
+ * @param hive The hive.
+ */
 void ConfigObject::SetHive(const ConfigHive::WeakPtr& hive)
 {
        if (m_Hive.lock())
@@ -18,41 +33,99 @@ void ConfigObject::SetHive(const ConfigHive::WeakPtr& hive)
        OnPropertyChanged += bind_weak(&ConfigObject::PropertyChangedHandler, shared_from_this());
 }
 
+/**
+ * GetHive
+ *
+ * Retrieves the hive this object belongs to.
+ *
+ * @returns The hive.
+ */
 ConfigHive::WeakPtr ConfigObject::GetHive(void) const
 {
        return m_Hive;
 }
 
+/**
+ * SetName
+ *
+ * Sets the name of this object.
+ *
+ * @param name The name.
+ */
 void ConfigObject::SetName(const string& name)
 {
        m_Name = name;
 }
 
+/**
+ * GetName
+ *
+ * Retrieves the name of this object.
+ *
+ * @returns The name.
+ */
 string ConfigObject::GetName(void) const
 {
        return m_Name;
 }
 
+/**
+ * SetType
+ *
+ * Sets the type of this object.
+ *
+ * @param type The type.
+ */
 void ConfigObject::SetType(const string& type)
 {
        m_Type = type;
 }
 
+/**
+ * GetType
+ *
+ * Retrieves the type of this object.
+ *
+ * @returns The type.
+ */
 string ConfigObject::GetType(void) const
 {
        return m_Type;
 }
 
+/**
+ * SetReplicated
+ *
+ * Sets whether this object was replicated.
+ *
+ * @param replicated Whether this object was replicated.
+ */
 void ConfigObject::SetReplicated(bool replicated)
 {
        m_Replicated = replicated;
 }
 
+/**
+ * GetReplicated
+ *
+ * Retrieves whether this object was replicated.
+ *
+ * @returns Whether this object was replicated.
+ */
 bool ConfigObject::GetReplicated(void) const
 {
        return m_Replicated;
 }
 
+/**
+ * PropertyChangedHandler
+ *
+ * Handles changed properties by propagating them to the hive
+ * and collection this object is contained in.
+ *
+ * @param dpcea The event arguments.
+ * @returns 0.
+ */
 int ConfigObject::PropertyChangedHandler(const PropertyChangedEventArgs& dpcea)
 {
        ConfigHive::Ptr hive = m_Hive.lock();
index 96dcbb6b8b657d82103f22d5455d66113b5d024e..16388deb008ec359f1b9430ad50df2159ca15d22 100644 (file)
 #include <map>
 #include <list>
 
+#include <openssl/bio.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
 #ifdef HAVE_GCC_ABI_DEMANGLE
 #      include <cxxabi.h>
 #endif /* HAVE_GCC_ABI_DEMANGLE */
@@ -81,6 +85,7 @@ using namespace std::tr1::placeholders;
 #include "tcpsocket.h"
 #include "tcpclient.h"
 #include "tcpserver.h"
+#include "tlsclient.h"
 #include "configobject.h"
 #include "configcollection.h"
 #include "confighive.h"
index cfb5e15f5f93d3de0d12b44f5aa92ad277edcacc..f250d769bb824c73a207485c40cd1240988379c9 100644 (file)
@@ -44,19 +44,6 @@ public:
        }
 };
 
-typedef function<Object::Ptr ()> factory_function;
-
-/**
- * factory<T>
- *
- * Returns a new object of type T.
- */
-template<class T>
-Object::Ptr factory(void)
-{
-       return make_shared<T>();
-}
-
 }
 
 #endif /* OBJECT_H */
index 77b497ff7ed0a88d2142418bc7ec1bc1b2c351ce..7e3770eda6ff23d4fcdec9caa55780e7b0734e8c 100644 (file)
@@ -11,7 +11,7 @@ Socket::Socket(void)
 
 Socket::~Socket(void)
 {
-       Close(true);
+       CloseInternal(true);
 }
 
 void Socket::Start(void)
@@ -45,10 +45,10 @@ SOCKET Socket::GetFD(void) const
 
 void Socket::Close(void)
 {
-       Close(false);
+       CloseInternal(false);
 }
 
-void Socket::Close(bool from_dtor)
+void Socket::CloseInternal(bool from_dtor)
 {
        if (m_FD != INVALID_SOCKET) {
                closesocket(m_FD);
index 9be92459b1f3d644b747a1c843ed8fd3141c199e..1e6aa9881874d768e6d3daffbff09f004dc2cbac 100644 (file)
@@ -23,7 +23,7 @@ protected:
        Socket(void);
 
        void HandleSocketError(void);
-       void Close(bool from_dtor);
+       virtual void CloseInternal(bool from_dtor);
 
 public:
        typedef shared_ptr<Socket> Ptr;
index ff057a2f61134966206eb05e32772c94fcf31440..7b13db5ce323123ee6b837ae1eb70bfa90547782 100644 (file)
@@ -2,14 +2,21 @@
 
 using namespace icinga;
 
-TCPClient::TCPClient(void)
+TCPClient::TCPClient(TCPClientRole role)
 {
+       m_Role = role;
+
        m_SendQueue = make_shared<FIFO>();
        m_RecvQueue = make_shared<FIFO>();
 
        m_PeerPort = 0;
 }
 
+TCPClientRole TCPClient::GetRole(void) const
+{
+       return m_Role;
+}
+
 void TCPClient::Start(void)
 {
        TCPSocket::Start();
@@ -44,6 +51,7 @@ void TCPClient::Connect(const string& hostname, unsigned short port)
                HandleSocketError();
        }
 
+       m_Role = RoleOutbound;
        m_PeerHost = hostname;
        m_PeerPort = port;
 }
@@ -123,3 +131,8 @@ bool TCPClient::WantsToWrite(void) const
 {
        return (m_SendQueue->GetSize() > 0);
 }
+
+TCPClient::Ptr icinga::TCPClientFactory(TCPClientRole role)
+{
+       return make_shared<TCPClient>(role);
+}
index bc7ac4cf74231c9094c3cac14e2fe7bf5c7e2d7b..7395e5f3e4f5c9505e2021c9cb4f416c959da94f 100644 (file)
@@ -4,23 +4,33 @@
 namespace icinga
 {
 
+enum I2_BASE_API TCPClientRole
+{
+       RoleInbound,
+       RoleOutbound
+};
+
 class I2_BASE_API TCPClient : public TCPSocket
 {
 private:
+       TCPClientRole m_Role;
+
        string m_PeerHost;
        int m_PeerPort;
 
        FIFO::Ptr m_SendQueue;
        FIFO::Ptr m_RecvQueue;
 
-       int ReadableEventHandler(const EventArgs& ea);
-       int WritableEventHandler(const EventArgs& ea);
+       virtual int ReadableEventHandler(const EventArgs& ea);
+       virtual int WritableEventHandler(const EventArgs& ea);
 
 public:
        typedef shared_ptr<TCPClient> Ptr;
        typedef weak_ptr<TCPClient> WeakPtr;
 
-       TCPClient(void);
+       TCPClient(TCPClientRole role);
+
+       TCPClientRole GetRole(void) const;
 
        virtual void Start(void);
 
@@ -38,6 +48,8 @@ public:
        Event<EventArgs> OnDataAvailable;
 };
 
+TCPClient::Ptr TCPClientFactory(TCPClientRole role);
+
 }
 
 #endif /* TCPCLIENT_H */
index 2f5f03f5297f9788466ada0ed6b515f89a23f2e7..b857c96d0634f31816eb296e5e28776d0ec5e91d 100644 (file)
@@ -4,15 +4,15 @@ using namespace icinga;
 
 TCPServer::TCPServer(void)
 {
-       m_ClientFactory = factory<TCPClient>;
+       m_ClientFactory = bind(&TCPClientFactory, RoleInbound);
 }
 
-void TCPServer::SetClientFactory(factory_function clientFactory)
+void TCPServer::SetClientFactory(function<TCPClient::Ptr()> clientFactory)
 {
        m_ClientFactory = clientFactory;
 }
 
-factory_function TCPServer::GetFactoryFunction(void)
+function<TCPClient::Ptr()> TCPServer::GetFactoryFunction(void) const
 {
        return m_ClientFactory;
 }
index 2641c4501cc18f9feaa1a5b3ee1c8f947e6652c6..8f551e40dbdae7fad04b1125c9216e6979c4980c 100644 (file)
@@ -17,7 +17,7 @@ class I2_BASE_API TCPServer : public TCPSocket
 private:
        int ReadableEventHandler(const EventArgs& ea);
 
-       factory_function m_ClientFactory;
+       function<TCPClient::Ptr()> m_ClientFactory;
 
 public:
        typedef shared_ptr<TCPServer> Ptr;
@@ -25,8 +25,8 @@ public:
 
        TCPServer(void);
 
-       void SetClientFactory(factory_function function);
-       factory_function GetFactoryFunction(void);
+       void SetClientFactory(function<TCPClient::Ptr()> function);
+       function<TCPClient::Ptr()> GetFactoryFunction(void) const;
 
        virtual void Start();
 
diff --git a/base/tlsclient.cpp b/base/tlsclient.cpp
new file mode 100644 (file)
index 0000000..f749d13
--- /dev/null
@@ -0,0 +1,119 @@
+#include "i2-base.h"
+
+using namespace icinga;
+
+TLSClient::TLSClient(TCPClientRole role, shared_ptr<SSL_CTX> sslContext) : TCPClient(role)
+{
+       m_SSLContext = sslContext;
+}
+
+shared_ptr<X509> TLSClient::GetClientCertificate(void) const
+{
+       return shared_ptr<X509>(SSL_get_certificate(m_SSL.get()), X509_free);
+}
+
+shared_ptr<X509> TLSClient::GetPeerCertificate(void) const
+{
+       return shared_ptr<X509>(SSL_get_peer_certificate(m_SSL.get()), X509_free);
+}
+
+void TLSClient::Start(void)
+{
+       TCPClient::Start();
+
+       m_SSL = shared_ptr<SSL>(SSL_new(m_SSLContext.get()), SSL_free);
+
+       if (!m_SSL)
+               ; /* TODO: deal with error */
+
+       BIO *bio = BIO_new_socket(GetFD(), 0);
+       SSL_set_bio(m_SSL.get(), bio, bio);
+
+       if (GetRole() == RoleInbound)
+               SSL_set_accept_state(m_SSL.get());
+       else
+               SSL_set_connect_state(m_SSL.get());
+}
+
+int TLSClient::ReadableEventHandler(const EventArgs& ea)
+{
+       int rc;
+
+       size_t bufferSize = FIFO::BlockSize / 2;
+       char *buffer = (char *)GetRecvQueue()->GetWriteBuffer(&bufferSize);
+       rc = SSL_read(m_SSL.get(), buffer, bufferSize);
+
+       if (rc <= 0) {
+               switch (SSL_get_error(m_SSL.get(), rc)) {
+                       case SSL_ERROR_WANT_WRITE:
+                       case SSL_ERROR_WANT_READ:
+                               return 0;
+                       case SSL_ERROR_ZERO_RETURN:
+                               Close();
+
+                               return 0;
+                       default:
+                               /* TODO: deal with error */
+
+                               return 0;
+               }
+       }
+
+       GetRecvQueue()->Write(NULL, rc);
+
+       EventArgs dea;
+       dea.Source = shared_from_this();
+       OnDataAvailable(dea);
+
+       return 0;
+}
+
+int TLSClient::WritableEventHandler(const EventArgs& ea)
+{
+       int rc;
+
+       rc = SSL_write(m_SSL.get(), (const char *)GetSendQueue()->GetReadBuffer(), GetSendQueue()->GetSize());
+
+       if (rc <= 0) {
+               switch (SSL_get_error(m_SSL.get(), rc)) {
+                       case SSL_ERROR_WANT_WRITE:
+                       case SSL_ERROR_WANT_READ:
+                               return 0;
+                       case SSL_ERROR_ZERO_RETURN:
+                               Close();
+
+                               return 0;
+                       default:
+                               /* TODO: deal with error */
+
+                               return 0;
+               }
+       }
+
+       GetSendQueue()->Read(NULL, rc);
+
+       return 0;
+}
+
+bool TLSClient::WantsToWrite(void) const
+{
+       if (SSL_want_write(m_SSL.get()))
+               return true;
+
+       if (SSL_state(m_SSL.get()) != SSL_ST_OK)
+               return false;
+
+       return TCPClient::WantsToWrite();
+}
+
+void TLSClient::CloseInternal(bool from_dtor)
+{
+       SSL_shutdown(m_SSL.get());
+
+       TCPClient::CloseInternal(from_dtor);
+}
+
+TCPClient::Ptr icinga::TLSClientFactory(TCPClientRole role, shared_ptr<SSL_CTX> sslContext)
+{
+       return make_shared<TLSClient>(role, sslContext);
+}
diff --git a/base/tlsclient.h b/base/tlsclient.h
new file mode 100644 (file)
index 0000000..8e28b18
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef TLSCLIENT_H
+#define TLSCLIENT_H
+
+namespace icinga
+{
+
+struct I2_BASE_API VerifyCertificateEventArgs : public EventArgs
+{
+       bool ValidCertificate;
+       X509_STORE_CTX *Context;
+};
+
+class I2_BASE_API TLSClient : public TCPClient
+{
+private:
+       shared_ptr<SSL_CTX> m_SSLContext;
+       shared_ptr<SSL> m_SSL;
+
+       virtual int ReadableEventHandler(const EventArgs& ea);
+       virtual int WritableEventHandler(const EventArgs& ea);
+
+       virtual void CloseInternal(bool from_dtor);
+
+public:
+       TLSClient(TCPClientRole role, shared_ptr<SSL_CTX> sslContext);
+
+       shared_ptr<X509> GetClientCertificate(void) const;
+       shared_ptr<X509> GetPeerCertificate(void) const;
+
+       virtual void Start(void);
+
+       virtual bool WantsToWrite(void) const;
+
+       Event<VerifyCertificateEventArgs> OnVerifyCertificate;
+};
+
+TCPClient::Ptr TLSClientFactory(TCPClientRole role, shared_ptr<SSL_CTX> sslContext);
+
+}
+
+#endif /* TLSCLIENT_H */
index f1bd7e970ac2b23422503b9e4619f750b755e1f3..4dd4c7b7a64caff6021750a2d98ce311e43c8920 100644 (file)
@@ -2,6 +2,8 @@
 
 using namespace icinga;
 
+bool I2_EXPORT Utility::m_SSLInitialized = false;
+
 /**
  * Daemonize
  *
@@ -40,3 +42,35 @@ void Utility::Daemonize(void) {
                throw PosixException("setsid failed", errno);
 #endif
 }
+
+void Utility::InitializeOpenSSL(void)
+{
+       if (!m_SSLInitialized) {
+               SSL_library_init();
+               SSL_load_error_strings();
+
+               m_SSLInitialized = true;
+       }
+}
+
+shared_ptr<SSL_CTX> Utility::MakeSSLContext(string pubkey, string privkey, string cakey)
+{
+       InitializeOpenSSL();
+
+       SSL_METHOD *sslMethod = (SSL_METHOD *)TLSv1_method();
+
+       shared_ptr<SSL_CTX> sslContext = shared_ptr<SSL_CTX>(SSL_CTX_new(sslMethod), SSL_CTX_free);
+
+       SSL_CTX_set_mode(sslContext.get(), SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
+
+       if (!SSL_CTX_use_certificate_chain_file(sslContext.get(), pubkey.c_str()))
+               throw InvalidArgumentException("Could not load public X509 key file.");
+
+       if (!SSL_CTX_use_PrivateKey_file(sslContext.get(), privkey.c_str(), SSL_FILETYPE_PEM))
+               throw InvalidArgumentException("Could not load private X509 key file.");
+
+       if (!SSL_CTX_load_verify_locations(sslContext.get(), cakey.c_str(), NULL))
+               throw InvalidArgumentException("Could not load public CA key file.");
+
+       return sslContext;
+}
index d4c7f84714110866bdc261b1095522771d00f565..18c310d81c72f77f9f86fc5b3b459cd1f2a4bcd2 100644 (file)
@@ -12,8 +12,12 @@ namespace icinga
 class I2_BASE_API Utility
 {
 private:
+       static bool m_SSLInitialized;
+
        Utility(void);
 
+       static void InitializeOpenSSL(void);
+
 public:
        /**
         * GetTypeName
@@ -39,6 +43,8 @@ public:
        }
 
        static void Daemonize(void);
+
+       static shared_ptr<SSL_CTX> MakeSSLContext(string pubkey, string privkey, string cakey);
 };
 
 }
diff --git a/icinga-app/ca.crt b/icinga-app/ca.crt
new file mode 100644 (file)
index 0000000..051a17f
--- /dev/null
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICnjCCAgegAwIBAgIJAOP3gULX9+xgMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV
+BAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMRIwEAYDVQQHDAlOdXJlbWJlcmcxFTAT
+BgNVBAoMDE5FVFdBWVMgR21iSDEcMBoGA1UEAwwTSWNpbmdhIFNuYWtlIE9pbCBD
+QTAeFw0xMjA0MjQxMTQyMzFaFw0yMjA0MjIxMTQyMzFaMGgxCzAJBgNVBAYTAkRF
+MRAwDgYDVQQIDAdCYXZhcmlhMRIwEAYDVQQHDAlOdXJlbWJlcmcxFTATBgNVBAoM
+DE5FVFdBWVMgR21iSDEcMBoGA1UEAwwTSWNpbmdhIFNuYWtlIE9pbCBDQTCBnzAN
+BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyxlEqY9AcY0YwpMIsirzy/6o9M29LRa4
+ziHURLugpyTKugtAkS5c2Gyt9lf7gdZBcVZ8KD6cszanQqKlZrl0h74E/S13tDqM
+rhR4DHeZssstn5LNK57WYx/vw84bmd6Yq6SeP4geq0JfO+y3Ruu+eePtQSOSzS9F
+wGpKyAHo4AcCAwEAAaNQME4wHQYDVR0OBBYEFNVJHVPJNwqEcG51lpqZJWVPaysF
+MB8GA1UdIwQYMBaAFNVJHVPJNwqEcG51lpqZJWVPaysFMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQEFBQADgYEAA1CMZgzQuQAslZ/i6OpFmRzuT/0KAfd6s8n6rf+6
+xRvbgLlop8b8XfhhC/IwwoHU0i86o3vV3ZJjEVcdwTDEwpnyCfhFjhXzNZFqL8Ak
+Olqy5HFd/+xysTLbdmhHtBIdOeUK1qz/u9I14A71XWiknjcxHya2Ghxg4yIZVdKh
+oTQ=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/icinga-app/ca.key b/icinga-app/ca.key
new file mode 100644 (file)
index 0000000..8529970
--- /dev/null
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMsZRKmPQHGNGMKT
+CLIq88v+qPTNvS0WuM4h1ES7oKckyroLQJEuXNhsrfZX+4HWQXFWfCg+nLM2p0Ki
+pWa5dIe+BP0td7Q6jK4UeAx3mbLLLZ+SzSue1mMf78POG5nemKuknj+IHqtCXzvs
+t0brvnnj7UEjks0vRcBqSsgB6OAHAgMBAAECgYBg4Ku06cUGpRQjc/lY604hh1bW
+dvD++fCrOs3C/3DRaaZd+hIRbnkRLz4H3M32j9nlkyhkFgGvJqnACk81Yc8oOu86
+Pm7bOdEj8v31qq943NCps5tdKHepXM0Z6A8GjaR2ias39NKxVDacBoFzSDAVArTL
+p6dyqLjsW5Y3INeHmQJBAPB6w9iqa31GLXMEMeP5LA4+2p3aHPQ25ptMCUcp/Vc6
+40GOSIlLb8rfE+q1ZacChv94jSNLybR+U9++8DLIxnMCQQDYNORSo57mVSebDr7e
+Gx8BDbyC+yAgiAi+qfJRekQ0I+R1SxfkCIBSWNrQ944isn0eRcr7+BWVl/WOrVSk
+vccdAkBEwbURU9ib3t7Lzd0941ZXVF1JWL2CjdftexYEBNtsf2fOrJHMv4bdKF8X
+cnn4AF782EjyWI75Tk1I4dzniERFAkBKZ9lzvy9+ISwiJq71DOxclnebtATYbThl
+NWNZOvSh5QBIhXFRXsOak02qwKc/taFte6Nhl30GIGe3lFse3tjZAkBguOZFeSOO
+hIAxMD+QpDUHZRYEjhDtPn3oAkLgBNUdeajffLdt4SmRa26t4QnSAE8kkbadIm6A
+z52CJc8G2ALA
+-----END PRIVATE KEY-----
\ No newline at end of file
diff --git a/icinga-app/icinga-c1.crt b/icinga-app/icinga-c1.crt
new file mode 100644 (file)
index 0000000..02201e4
--- /dev/null
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICtzCCAiCgAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJERTEQ
+MA4GA1UECAwHQmF2YXJpYTESMBAGA1UEBwwJTnVyZW1iZXJnMRUwEwYDVQQKDAxO
+RVRXQVlTIEdtYkgxHDAaBgNVBAMME0ljaW5nYSBTbmFrZSBPaWwgQ0EwHhcNMTIw
+NDI0MTE0NzQ2WhcNMTMwNDI0MTE0NzQ2WjBeMQswCQYDVQQGEwJERTEQMA4GA1UE
+CAwHQmF2YXJpYTESMBAGA1UEBwwJTnVyZW1iZXJnMRUwEwYDVQQKDAxORVRXQVlT
+IEdtYkgxEjAQBgNVBAMMCWljaW5nYS1jMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
+gYkCgYEAysHrzHs9WfQR4cEUx2hFZQmbM+Ssi5L63yqnzxEvVQ3GlM+uIceK1Kvx
+9EexoUDLhxJOaUmigc6Pcs2mAjcpEwObnzW4pLuMKa7ngGLrnUpmmDXdGoxkCbi7
+CP3s5yC7ZZ6bDiPMhRi/TRvY6+uQf+yew5daA3p87jocgRjhRicCAwEAAaN7MHkw
+CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
+dGlmaWNhdGUwHQYDVR0OBBYEFPzsYbQZdbq+pcFJWoenWREW6WhMMB8GA1UdIwQY
+MBaAFNVJHVPJNwqEcG51lpqZJWVPaysFMA0GCSqGSIb3DQEBBQUAA4GBAMLP1GJf
+0hFdrEpGq+NvxTVx7wD30enAot5x2HLx4HuFohQJz/VZ45v+srrA+HEXbBFXPOd4
+nB2XtcDDidFKTt5E03HBwDGGZvnB3f1KXYi7B50imKrwVVzgp5nGBM4hSzWGovEX
+EYofmhk0fQg9qiKQrjwNib/4/b0srwEswfdj
+-----END CERTIFICATE-----
diff --git a/icinga-app/icinga-c1.key b/icinga-app/icinga-c1.key
new file mode 100644 (file)
index 0000000..9f28765
--- /dev/null
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMrB68x7PVn0EeHB
+FMdoRWUJmzPkrIuS+t8qp88RL1UNxpTPriHHitSr8fRHsaFAy4cSTmlJooHOj3LN
+pgI3KRMDm581uKS7jCmu54Bi651KZpg13RqMZAm4uwj97Ocgu2Wemw4jzIUYv00b
+2OvrkH/snsOXWgN6fO46HIEY4UYnAgMBAAECgYBj/1QOG1HcxXT0REe9OP3QoPY8
+l7FJfQnheqYch7syVYL07aBR5Jnh3ZONCLbgcpZuXWbyonBVWMyCsE4Jla7ZYnBB
+plZPMYmzGxEbTM5Bu+PZ0M1NLvdLCRq24IVwTZwBBZ3sr7rVSnAYi2Li0SWQEaCN
+P+PbZP1P9i9WiI+VIQJBAPYBfVWNk3gY1V0YuuH9fmYRBg5/B1qy8bYS9FLVIq2z
+5r7eI1EypcVtyTx6yMmLuWj4mpNOKv5sxQsHalzRo18CQQDS/qPoDqMkDB9r9XeZ
+qS2XQdX6YxzGisqL8vWcZ/Y6YX81qm3Lpp2wEexUXvWXRI5RdguctZFKTVyG/Mic
+C9o5AkAEtvKX+SaiXpd4OUkbm6gYfKsJDBYv/s3zF1nnXH5VpeT+M3Op0raqmfgJ
+WLEQa8UZ5enQeOcKCTudgn7fWIUxAkEAmXWfXP6YZXVzvR+xt08225aEvTItEbKM
+krFJNlLe4aNb1Hp6lO5ALnk6vDq8wSKZqGIFHBtq6vHNZFiix+xO8QJAIZ3pB/Bz
+Il8NjZMg8t/1sJdn32Xe9D0lZRtZTKC8zF/78NDFEo9qqE4Sr1CUfqlx18HXOxCO
+Vg4lv6+jUj+LmA==
+-----END PRIVATE KEY-----
\ No newline at end of file
diff --git a/icinga-app/icinga-c2.crt b/icinga-app/icinga-c2.crt
new file mode 100644 (file)
index 0000000..b3aaa1b
--- /dev/null
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICtzCCAiCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJERTEQ
+MA4GA1UECAwHQmF2YXJpYTESMBAGA1UEBwwJTnVyZW1iZXJnMRUwEwYDVQQKDAxO
+RVRXQVlTIEdtYkgxHDAaBgNVBAMME0ljaW5nYSBTbmFrZSBPaWwgQ0EwHhcNMTIw
+NDI0MTE0NzU1WhcNMTMwNDI0MTE0NzU1WjBeMQswCQYDVQQGEwJERTEQMA4GA1UE
+CAwHQmF2YXJpYTESMBAGA1UEBwwJTnVyZW1iZXJnMRUwEwYDVQQKDAxORVRXQVlT
+IEdtYkgxEjAQBgNVBAMMCWljaW5nYS1jMjCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
+gYkCgYEArOcVui1AWojbPuK/7We9uwIBLaOLfBxQRI3+k6PzzjdtaXT4ijT/DSav
+Q5U4wGOLYh0yuSyqS88QX/DsqDGLXnSVs8mT37bioMOw2XinqaNQ6xK4vyi0FYxS
+ewI6YOkYi7135NEaSUgd82hk4wFtiIb67T7hkHRc7Aui6FmT/SkCAwEAAaN7MHkw
+CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
+dGlmaWNhdGUwHQYDVR0OBBYEFGvpolD5na6L70kNFO1tYGYIwDhqMB8GA1UdIwQY
+MBaAFNVJHVPJNwqEcG51lpqZJWVPaysFMA0GCSqGSIb3DQEBBQUAA4GBAIhhjKWw
+5JKirNidgG9PuD8x47VsRTkESLlq/pS7KjkE1nWCG9JpR5oVSzx2WXomiaAZ4q2C
+WS1z4HD9HF4NbhY+xVBi0Fj/kotuXCCweRo5EVp7Q4fabm1maJemFwMTHGhBLu7a
+v4dquYyOk9Dhkwcjajyn+KWceCoUTdI3LB2t
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/icinga-app/icinga-c2.key b/icinga-app/icinga-c2.key
new file mode 100644 (file)
index 0000000..6ddda86
--- /dev/null
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKznFbotQFqI2z7i
+v+1nvbsCAS2ji3wcUESN/pOj8843bWl0+Io0/w0mr0OVOMBji2IdMrksqkvPEF/w
+7Kgxi150lbPJk9+24qDDsNl4p6mjUOsSuL8otBWMUnsCOmDpGIu9d+TRGklIHfNo
+ZOMBbYiG+u0+4ZB0XOwLouhZk/0pAgMBAAECgYEAkbEavslYm7EMRX4dyXcMCaNT
+yNgxNcBJ5qpbpJ6XVuGfoSf+Mb8cV0GMl38K1hpLHb6Kujwntz9ghedmEwfEbcw0
+TkSaNz1+7omM+485S2YvXJyR1kO8eEKONVlGuxgO/ItiR+e1J6wMnY5JhctgRH6W
+aOqy+5Ua1ATIdiOYrI0CQQDku3CNDOipwDmguBIrlxa+6NsATJRjqFmHqWdu2pYh
+KRl3Sypn+LfhdFRbo3licU5a1OqydGmVpRTpQPJO7MoHAkEAwYPQIGZd/60O2LWV
+M5eLnwKrrQSfrQ/Lngz0Qko4Yo913Ef2PC2QQ6p9cOt3vMPZDK5znlzQbBCa6cAH
+tBvzTwJAT+uaaP5wsRdkS17lomt5XB1aoCEh3Cxvk/JCHL6tpEqLBl6yI4AJJ/KQ
+ozBccmQqv5wToWUBm3MB+nph7+fWswJAMKcQQ6UZCvganHeCzJbUXqUQPo7ECoHH
+IrSFEMmSRY1mB3z8NoMKG0kZArPgxc/DmUGfBfi12gWOvSgvh6PjVwJBALKECoe5
+nmxhHTFbs4+UCFTzp6BGtSBdr6to0ID7ykZWT6kBX/BHUnoJUEpDtNLXzbek/KeI
+ymg0LgRkHoWNpLY=
+-----END PRIVATE KEY-----
\ No newline at end of file
index 6e499fed826129d29fd53389567f4891912d2cbe..1f0d482cc585e3c4fb4a46464dce5cf604067b6e 100644 (file)
@@ -2,6 +2,11 @@
 
 using namespace icinga;
 
+EndpointManager::EndpointManager(shared_ptr<SSL_CTX> sslContext)
+{
+       m_SSLContext = sslContext;
+}
+
 void EndpointManager::SetIdentity(string identity)
 {
        m_Identity = identity;
@@ -14,7 +19,7 @@ string EndpointManager::GetIdentity(void) const
 
 void EndpointManager::AddListener(unsigned short port)
 {
-       JsonRpcServer::Ptr server = make_shared<JsonRpcServer>();
+       JsonRpcServer::Ptr server = make_shared<JsonRpcServer>(m_SSLContext);
        RegisterServer(server);
 
        server->MakeSocket();
@@ -26,7 +31,7 @@ void EndpointManager::AddListener(unsigned short port)
 void EndpointManager::AddConnection(string host, unsigned short port)
 {
        JsonRpcEndpoint::Ptr endpoint = make_shared<JsonRpcEndpoint>();
-       endpoint->Connect(host, port);
+       endpoint->Connect(host, port, m_SSLContext);
        RegisterEndpoint(endpoint);
 }
 
index 34815d7353979e6f4842c310382960b061e0fdba..567a0e0014ffb1777ac7d19db54753e5f73a8a6d 100644 (file)
@@ -11,6 +11,7 @@ struct I2_ICINGA_API NewEndpointEventArgs : public EventArgs
 
 class I2_ICINGA_API EndpointManager : public Object
 {
+       shared_ptr<SSL_CTX> m_SSLContext;
        list<JsonRpcServer::Ptr> m_Servers;
        list<Endpoint::Ptr> m_Endpoints;
        string m_Identity;
@@ -27,6 +28,8 @@ public:
        typedef shared_ptr<EndpointManager> Ptr;
        typedef weak_ptr<EndpointManager> WeakPtr;
 
+       EndpointManager(shared_ptr<SSL_CTX> sslContext);
+
        void SetIdentity(string identity);
        string GetIdentity(void) const;
 
index 9a736c1ba9e2711e6c58d5d7d7d1f260722ab68d..6e7f8ad8687287e1f1b70494be8a4c99f9192274 100644 (file)
@@ -9,11 +9,6 @@
 
 using namespace icinga;
 
-IcingaApplication::IcingaApplication(void)
-{
-       m_EndpointManager = make_shared<EndpointManager>();
-}
-
 int IcingaApplication::Main(const vector<string>& args)
 {
 #ifdef _WIN32
@@ -27,6 +22,10 @@ int IcingaApplication::Main(const vector<string>& args)
                return EXIT_FAILURE;
        }
 
+       shared_ptr<SSL_CTX> sslContext = Utility::MakeSSLContext("icinga-c1.crt", "icinga-c1.key", "ca.crt");
+
+       m_EndpointManager = make_shared<EndpointManager>(sslContext);
+
        string componentDirectory = GetExeDirectory() + "/../lib/icinga";
        AddComponentSearchDir(componentDirectory);
 
index 3205d68972b25d52e64821bf6454cde2874cfdd2..6904e3dac30a32bae5a9bb00b66485063e311258 100644 (file)
@@ -23,8 +23,6 @@ public:
        typedef shared_ptr<IcingaApplication> Ptr;
        typedef weak_ptr<IcingaApplication> WeakPtr;
 
-       IcingaApplication(void);
-
        int Main(const vector<string>& args);
 
        void PrintUsage(const string& programPath);
index fcff316a48a65b740d0b1cb6e6cbb459717fb2fc..edb25c8bb0b88ecc6f888278ab8fd02a60e07c08 100644 (file)
@@ -59,13 +59,13 @@ bool JsonRpcEndpoint::IsAllowedMethodSource(string method) const
        return false;
 }
 
-void JsonRpcEndpoint::Connect(string host, unsigned short port)
+void JsonRpcEndpoint::Connect(string host, unsigned short port, shared_ptr<SSL_CTX> sslContext)
 {
        char portStr[20];
        sprintf(portStr, "%d", port);
        SetAddress("jsonrpc-tcp://" + host + ":" + portStr);
 
-       JsonRpcClient::Ptr client = make_shared<JsonRpcClient>();
+       JsonRpcClient::Ptr client = make_shared<JsonRpcClient>(RoleOutbound, sslContext);
        client->MakeSocket();
        client->Connect(host, port);
        client->Start();
index 7d6b0a1b88f39df3ec958ca6bb794ac43f349988..ac2cfeb1ea0f5500a7ae5309acb9b393d787513e 100644 (file)
@@ -7,6 +7,7 @@ namespace icinga
 class I2_ICINGA_API JsonRpcEndpoint : public Endpoint
 {
 private:
+       shared_ptr<SSL_CTX> m_SSLContext;
        string m_Address;
        JsonRpcClient::Ptr m_Client;
        map<string, Endpoint::Ptr> m_PendingCalls;
@@ -25,7 +26,8 @@ public:
        typedef shared_ptr<JsonRpcEndpoint> Ptr;
        typedef weak_ptr<JsonRpcEndpoint> WeakPtr;
 
-       void Connect(string host, unsigned short port);
+       void Connect(string host, unsigned short port,
+           shared_ptr<SSL_CTX> sslContext);
 
        JsonRpcClient::Ptr GetClient(void);
        void SetClient(JsonRpcClient::Ptr client);
index 10f232ada71e3744a2e19c2eb8e4967be5fbd051..8db0a1cb8f464c6c5c003180b174e811a8b2f570 100644 (file)
@@ -2,9 +2,12 @@
 
 using namespace icinga;
 
+JsonRpcClient::JsonRpcClient(TCPClientRole role, shared_ptr<SSL_CTX> sslContext)
+    : TLSClient(role, sslContext) { }
+
 void JsonRpcClient::Start(void)
 {
-       TCPClient::Start();
+       TLSClient::Start();
 
        OnDataAvailable += bind_weak(&JsonRpcClient::DataAvailableHandler, shared_from_this());
 }
@@ -40,3 +43,8 @@ int JsonRpcClient::DataAvailableHandler(const EventArgs& ea)
 
        return 0;
 }
+
+TCPClient::Ptr icinga::JsonRpcClientFactory(TCPClientRole role, shared_ptr<SSL_CTX> sslContext)
+{
+       return make_shared<JsonRpcClient>(role, sslContext);
+}
index 2ad6f343176dd6ca5358dea0596f54d0d7a0e1c3..8bf77dca971a453eb9b1530f13e8aa11b3ce8a6c 100644 (file)
@@ -12,7 +12,7 @@ struct I2_JSONRPC_API NewMessageEventArgs : public EventArgs
        icinga::Message Message;
 };
 
-class I2_JSONRPC_API JsonRpcClient : public TCPClient
+class I2_JSONRPC_API JsonRpcClient : public TLSClient
 {
 private:
        int DataAvailableHandler(const EventArgs& ea);
@@ -21,6 +21,8 @@ public:
        typedef shared_ptr<JsonRpcClient> Ptr;
        typedef weak_ptr<JsonRpcClient> WeakPtr;
 
+       JsonRpcClient(TCPClientRole role, shared_ptr<SSL_CTX> sslContext);
+
        void SendMessage(const Message& message);
 
        virtual void Start(void);
@@ -28,6 +30,8 @@ public:
        Event<NewMessageEventArgs> OnNewMessage;
 };
 
+TCPClient::Ptr JsonRpcClientFactory(TCPClientRole role, shared_ptr<SSL_CTX> sslContext);
+
 }
 
 #endif /* JSONRPCCLIENT_H */
index 3acde7f4c72465ab68bb4096bfb5a273b11ae313..59aecf84296ee81887c657da295336ee676ea173 100644 (file)
@@ -2,7 +2,7 @@
 
 using namespace icinga;
 
-JsonRpcServer::JsonRpcServer(void)
+JsonRpcServer::JsonRpcServer(shared_ptr<SSL_CTX> sslContext)
 {
-       SetClientFactory(factory<JsonRpcClient>);
+       SetClientFactory(bind(&JsonRpcClientFactory, RoleInbound, sslContext));
 }
index b7feb4ea8ba529519435a477e48ef91ee5089117..7614e98070b08267b5e49a4bbff56e965b215364 100644 (file)
@@ -10,7 +10,7 @@ public:
        typedef shared_ptr<JsonRpcServer> Ptr;
        typedef weak_ptr<JsonRpcServer> WeakPtr;
 
-       JsonRpcServer(void);
+       JsonRpcServer(shared_ptr<SSL_CTX> sslContext);
 };
 
 }