From: Gunnar Beutner Date: Fri, 20 Apr 2012 08:38:11 +0000 (+0200) Subject: Implemented pseudo-authentication handshake. X-Git-Tag: v0.0.1~615 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1a128e2f660e192be273940359ffdba548f358b7;p=icinga2 Implemented pseudo-authentication handshake. --- diff --git a/components/configrpc/configrpccomponent.cpp b/components/configrpc/configrpccomponent.cpp index 15d1cc035..29a6cf984 100644 --- a/components/configrpc/configrpccomponent.cpp +++ b/components/configrpc/configrpccomponent.cpp @@ -34,11 +34,16 @@ void ConfigRpcComponent::Start(void) m_ConfigRpcEndpoint->RegisterMethodSource("config::PropertyChanged"); } + m_ConfigRpcEndpoint->RegisterMethodHandler("message::Welcome", bind_weak(&ConfigRpcComponent::WelcomeMessageHandler, shared_from_this())); + m_ConfigRpcEndpoint->RegisterMethodHandler("config::ObjectCreated", bind_weak(&ConfigRpcComponent::RemoteObjectUpdatedHandler, shared_from_this())); m_ConfigRpcEndpoint->RegisterMethodHandler("config::ObjectRemoved", bind_weak(&ConfigRpcComponent::RemoteObjectRemovedHandler, shared_from_this())); m_ConfigRpcEndpoint->RegisterMethodHandler("config::PropertyChanged", bind_weak(&ConfigRpcComponent::RemoteObjectUpdatedHandler, shared_from_this())); endpointManager->RegisterEndpoint(m_ConfigRpcEndpoint); + + endpointManager->OnNewEndpoint += bind_weak(&ConfigRpcComponent::NewEndpointHandler, shared_from_this()); + endpointManager->ForeachEndpoint(bind(&ConfigRpcComponent::NewEndpointHandler, this, _1)); } void ConfigRpcComponent::Stop(void) @@ -46,6 +51,28 @@ void ConfigRpcComponent::Stop(void) // TODO: implement } +int ConfigRpcComponent::NewEndpointHandler(const NewEndpointEventArgs& ea) +{ + if (ea.Endpoint->HasIdentity()) { + JsonRpcRequest request; + request.SetVersion("2.0"); + request.SetMethod("config::FetchObjects"); + ea.Endpoint->ProcessRequest(m_ConfigRpcEndpoint, request); + } + + return 0; +} + +int ConfigRpcComponent::WelcomeMessageHandler(const NewRequestEventArgs& ea) +{ + NewEndpointEventArgs neea; + neea.Source = shared_from_this(); + neea.Endpoint = ea.Sender; + NewEndpointHandler(neea); + + return 0; +} + JsonRpcRequest ConfigRpcComponent::MakeObjectMessage(const ConfigObject::Ptr& object, string method, bool includeProperties) { JsonRpcRequest msg; diff --git a/components/configrpc/configrpccomponent.h b/components/configrpc/configrpccomponent.h index 7b65cf9e8..92b00b243 100644 --- a/components/configrpc/configrpccomponent.h +++ b/components/configrpc/configrpccomponent.h @@ -11,6 +11,9 @@ private: IcingaApplication::Ptr GetIcingaApplication(void); + int NewEndpointHandler(const NewEndpointEventArgs& ea); + int WelcomeMessageHandler(const NewRequestEventArgs& ea); + int LocalObjectCreatedHandler(const ConfigObjectEventArgs& ea); int LocalObjectRemovedHandler(const ConfigObjectEventArgs& ea); int LocalPropertyChangedHandler(const ConfigObjectEventArgs& ea); diff --git a/icinga/endpoint.cpp b/icinga/endpoint.cpp index 7fd8e791f..38f6f8148 100644 --- a/icinga/endpoint.cpp +++ b/icinga/endpoint.cpp @@ -2,6 +2,21 @@ using namespace icinga; +string Endpoint::GetIdentity(void) const +{ + return m_Identity; +} + +void Endpoint::SetIdentity(string identity) +{ + m_Identity = identity; +} + +bool Endpoint::HasIdentity(void) const +{ + return !m_Identity.empty(); +} + EndpointManager::Ptr Endpoint::GetEndpointManager(void) const { return m_EndpointManager.lock(); diff --git a/icinga/endpoint.h b/icinga/endpoint.h index efe509934..96591a2e2 100644 --- a/icinga/endpoint.h +++ b/icinga/endpoint.h @@ -14,6 +14,7 @@ struct I2_ICINGA_API NewMethodEventArgs : public EventArgs class I2_ICINGA_API Endpoint : public Object { private: + string m_Identity; set m_MethodSinks; set m_MethodSources; @@ -23,6 +24,10 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; + string GetIdentity(void) const; + void SetIdentity(string identity); + bool HasIdentity(void) const; + shared_ptr GetEndpointManager(void) const; void SetEndpointManager(weak_ptr manager); diff --git a/icinga/i2-icinga.h b/icinga/i2-icinga.h index a17e5557d..9e8b28717 100644 --- a/icinga/i2-icinga.h +++ b/icinga/i2-icinga.h @@ -17,5 +17,7 @@ #include "endpointmanager.h" #include "icingaapplication.h" #include "subscriptioncomponent.h" +#include "subscriptionmessage.h" +#include "identitymessage.h" #endif /* I2ICINGA_H */ diff --git a/icinga/icinga.vcxproj b/icinga/icinga.vcxproj index 90df9d096..1a773372e 100644 --- a/icinga/icinga.vcxproj +++ b/icinga/icinga.vcxproj @@ -14,8 +14,10 @@ + + @@ -23,8 +25,10 @@ + + diff --git a/icinga/identitymessage.cpp b/icinga/identitymessage.cpp new file mode 100644 index 000000000..22bbf7ddb --- /dev/null +++ b/icinga/identitymessage.cpp @@ -0,0 +1,3 @@ +#include "i2-icinga.h" + +using namespace icinga; diff --git a/icinga/identitymessage.h b/icinga/identitymessage.h new file mode 100644 index 000000000..714e26f3a --- /dev/null +++ b/icinga/identitymessage.h @@ -0,0 +1,27 @@ +#ifndef IDENTITYMESSAGE_H +#define IDENTITYMESSAGE_H + +namespace icinga +{ + +class I2_ICINGA_API IdentityMessage : public Message +{ + +public: + IdentityMessage(void) : Message() { } + IdentityMessage(const Message& message) : Message(message) { } + + inline bool GetIdentity(string *value) const + { + return GetDictionary()->GetValueString("identity", value); + } + + inline void SetIdentity(const string& value) + { + GetDictionary()->SetValueString("identity", value); + } +}; + +} + +#endif /* IDENTITYMESSAGE_H */ diff --git a/icinga/jsonrpcendpoint.cpp b/icinga/jsonrpcendpoint.cpp index ce322483f..6e58c64c1 100644 --- a/icinga/jsonrpcendpoint.cpp +++ b/icinga/jsonrpcendpoint.cpp @@ -23,6 +23,16 @@ void JsonRpcEndpoint::SetClient(JsonRpcClient::Ptr client) client->OnNewMessage += bind_weak(&JsonRpcEndpoint::NewMessageHandler, shared_from_this()); client->OnClosed += bind_weak(&JsonRpcEndpoint::ClientClosedHandler, shared_from_this()); client->OnError += bind_weak(&JsonRpcEndpoint::ClientErrorHandler, shared_from_this()); + + JsonRpcRequest request; + request.SetVersion("2.0"); + request.SetMethod("message::SetIdentity"); + + IdentityMessage params; + params.SetIdentity("keks"); + request.SetParams(params); + + client->SendMessage(request); } bool JsonRpcEndpoint::IsLocal(void) const @@ -63,21 +73,6 @@ int JsonRpcEndpoint::NewMessageHandler(const NewMessageEventArgs& nmea) string method; if (message.GetDictionary()->GetValueString("method", &method)) { JsonRpcRequest request = message; - Message params; - string method; - - if (request.GetMethod(&method) && request.GetParams(¶ms) && - (method == "message::Subscribe" || method == "message::Provide")) { - string sub_method; - if (params.GetDictionary()->GetValueString("method", &sub_method)) { - if (method == "message::Subscribe") - RegisterMethodSink(sub_method); - else - RegisterMethodSource(sub_method); - } - - return 0; - } string id; if (request.GetID(&id)) @@ -85,6 +80,8 @@ int JsonRpcEndpoint::NewMessageHandler(const NewMessageEventArgs& nmea) else GetEndpointManager()->SendMulticastRequest(sender, request, false); } else { + JsonRpcResponse response = message; + // TODO: deal with response messages throw NotImplementedException(); } diff --git a/icinga/subscriptioncomponent.cpp b/icinga/subscriptioncomponent.cpp index b30688689..f614afc6b 100644 --- a/icinga/subscriptioncomponent.cpp +++ b/icinga/subscriptioncomponent.cpp @@ -17,8 +17,10 @@ void SubscriptionComponent::Start(void) m_SubscriptionEndpoint = make_shared(); m_SubscriptionEndpoint->RegisterMethodHandler("message::Subscribe", bind_weak(&SubscriptionComponent::SubscribeMessageHandler, shared_from_this())); m_SubscriptionEndpoint->RegisterMethodHandler("message::Provide", bind_weak(&SubscriptionComponent::ProvideMessageHandler, shared_from_this())); + m_SubscriptionEndpoint->RegisterMethodHandler("message::SetIdentity", bind_weak(&SubscriptionComponent::IdentityMessageHandler, shared_from_this())); m_SubscriptionEndpoint->RegisterMethodSource("message::Subscribe"); m_SubscriptionEndpoint->RegisterMethodSource("message::Provide"); + m_SubscriptionEndpoint->RegisterMethodSource("message::Welcome"); EndpointManager::Ptr mgr = GetIcingaApplication()->GetEndpointManager(); mgr->OnNewEndpoint += bind_weak(&SubscriptionComponent::NewEndpointHandler, shared_from_this()); @@ -80,8 +82,10 @@ int SubscriptionComponent::SubscribeMessageHandler(const NewRequestEventArgs& nr if (!nrea.Request.GetParams(¶ms)) return 0; + SubscriptionMessage subscriptionMessage = params; + string method; - if (!params.GetDictionary()->GetValueString("method", &method)) + if (!subscriptionMessage.GetMethod(&method)) return 0; nrea.Sender->RegisterMethodSink(method); @@ -94,10 +98,35 @@ int SubscriptionComponent::ProvideMessageHandler(const NewRequestEventArgs& nrea if (!nrea.Request.GetParams(¶ms)) return 0; + SubscriptionMessage subscriptionMessage = params; + string method; - if (!params.GetDictionary()->GetValueString("method", &method)) + if (!subscriptionMessage.GetMethod(&method)) return 0; nrea.Sender->RegisterMethodSource(method); return 0; } + +int SubscriptionComponent::IdentityMessageHandler(const NewRequestEventArgs& nrea) +{ + Message params; + if (!nrea.Request.GetParams(¶ms)) + return 0; + + IdentityMessage identityMessage = params; + + string identity; + if (!identityMessage.GetIdentity(&identity)) + return 0; + + nrea.Sender->SetIdentity(identity); + + /* there's no authentication for now, just tell them it's ok to send messages */ + JsonRpcRequest request; + request.SetVersion("2.0"); + request.SetMethod("message::Welcome"); + nrea.Sender->ProcessRequest(m_SubscriptionEndpoint, request); + + return 0; +} diff --git a/icinga/subscriptioncomponent.h b/icinga/subscriptioncomponent.h index b58bb8a5b..3c5a185e8 100644 --- a/icinga/subscriptioncomponent.h +++ b/icinga/subscriptioncomponent.h @@ -14,6 +14,7 @@ private: int NewEndpointHandler(const NewEndpointEventArgs& neea); int SubscribeMessageHandler(const NewRequestEventArgs& nrea); int ProvideMessageHandler(const NewRequestEventArgs& nrea); + int IdentityMessageHandler(const NewRequestEventArgs& nrea); int SyncSubscription(Endpoint::Ptr target, string type, const NewMethodEventArgs& nmea); int SyncSubscriptions(Endpoint::Ptr target, const NewEndpointEventArgs& neea); diff --git a/icinga/subscriptionmessage.cpp b/icinga/subscriptionmessage.cpp new file mode 100644 index 000000000..22bbf7ddb --- /dev/null +++ b/icinga/subscriptionmessage.cpp @@ -0,0 +1,3 @@ +#include "i2-icinga.h" + +using namespace icinga; diff --git a/icinga/subscriptionmessage.h b/icinga/subscriptionmessage.h new file mode 100644 index 000000000..5e56e1a66 --- /dev/null +++ b/icinga/subscriptionmessage.h @@ -0,0 +1,27 @@ +#ifndef SUBSCRIPTIONMESSAGE_H +#define SUBSCRIPTIONMESSAGE_H + +namespace icinga +{ + +class I2_ICINGA_API SubscriptionMessage : public Message +{ + +public: + SubscriptionMessage(void) : Message() { } + SubscriptionMessage(const Message& message) : Message(message) { } + + inline bool GetMethod(string *value) const + { + return GetDictionary()->GetValueString("method", value); + } + + inline void SetMethod(const string& value) + { + GetDictionary()->SetValueString("method", value); + } +}; + +} + +#endif /* SUBSCRIPTIONMESSAGE_H */