]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Allow commands to optionally route themselves using ENCAP
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Wed, 2 Sep 2009 00:44:59 +0000 (00:44 +0000)
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Wed, 2 Sep 2009 00:44:59 +0000 (00:44 +0000)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11602 e03df62e-2008-0410-955e-edbf42e46eb7

include/ctables.h
src/modules/m_sasl.cpp
src/modules/m_spanningtree/encap.cpp
src/modules/m_spanningtree/postcommand.cpp

index b07d3f4e0fd3abddcebe7cacd42f4d0679e70095..a543b7e3756ebc9e230af183d11d99b8c9248de5 100644 (file)
@@ -41,7 +41,9 @@ enum RouteType
 {
        ROUTE_TYPE_LOCALONLY,
        ROUTE_TYPE_BROADCAST,
-       ROUTE_TYPE_UNICAST
+       ROUTE_TYPE_UNICAST,
+       ROUTE_TYPE_OPT_BCAST,
+       ROUTE_TYPE_OPT_UCAST
 };
 
 struct RouteDescriptor
@@ -54,9 +56,16 @@ struct RouteDescriptor
                : type(t), serverdest(d) { }
 };
 
+/** Do not route this command */
 #define ROUTE_LOCALONLY (RouteDescriptor(ROUTE_TYPE_LOCALONLY, ""))
+/** Route this command to all servers, fail if not understood */
 #define ROUTE_BROADCAST (RouteDescriptor(ROUTE_TYPE_BROADCAST, ""))
+/** Route this command to a single server (do nothing if own server name specified) */
 #define ROUTE_UNICAST(x) (RouteDescriptor(ROUTE_TYPE_UNICAST, x))
+/** Route this command to all servers, ignore if not understood */
+#define ROUTE_OPT_BCAST (RouteDescriptor(ROUTE_TYPE_OPT_BCAST, ""))
+/** Route this command to a single server, ignore if not understood */
+#define ROUTE_OPT_UCAST(x) (RouteDescriptor(ROUTE_TYPE_OPT_UCAST, x))
 
 /** A structure that defines a command. Every command available
  * in InspIRCd must be defined as derived from Command.
index 5241a14e57c085c5a58d3e9fe10eb700d3ea8306..b205f91c1d334fc00117bb8cb470dd26828add09 100644 (file)
@@ -51,7 +51,7 @@ class SaslAuthenticator : public classbase
                ServerInstance->PI->SendEncapsulatedData(params);
        }
 
-       SaslResult GetSaslResult(std::string &result_)
+       SaslResult GetSaslResult(const std::string &result_)
        {
                if (result_ == "F")
                        return SASL_FAIL;
@@ -63,25 +63,25 @@ class SaslAuthenticator : public classbase
        }
 
        /* checks for and deals with a state change. */
-       SaslState ProcessInboundMessage(parameterlist &msg)
+       SaslState ProcessInboundMessage(const std::vector<std::string> &msg)
        {
                switch (this->state)
                {
                 case SASL_INIT:
-                       this->agent = msg[2];
-                       this->user->Write("AUTHENTICATE %s", msg[5].c_str());
+                       this->agent = msg[0];
+                       this->user->Write("AUTHENTICATE %s", msg[3].c_str());
                        this->state = SASL_COMM;
                        break;
                 case SASL_COMM:
-                       if (msg[2] != this->agent)
+                       if (msg[0] != this->agent)
                                return this->state;
 
-                       if (msg[4] != "D")
-                               this->user->Write("AUTHENTICATE %s", msg[5].c_str());
+                       if (msg[2] != "D")
+                               this->user->Write("AUTHENTICATE %s", msg[3].c_str());
                        else
                        {
                                this->state = SASL_DONE;
-                               this->result = this->GetSaslResult(msg[5]);
+                               this->result = this->GetSaslResult(msg[3]);
                        }
 
                        break;
@@ -183,18 +183,52 @@ class CommandAuthenticate : public Command
        }
 };
 
+class CommandSASL : public Command
+{
+       Module* Creator;
+ public:
+       CommandSASL(InspIRCd* Instance, Module* creator) : Command(Instance, "SASL", 0, 2), Creator(creator)
+       {
+               this->source = "m_sasl.so";
+               this->disabled = true; // should not be called by users
+       }
+
+       CmdResult Handle(const std::vector<std::string>& parameters, User *user)
+       {
+               User* target = ServerInstance->FindNick(parameters[1]);
+               if (!target)
+               {
+                       ServerInstance->Logs->Log("m_sasl", DEBUG,"User not found in sasl ENCAP event: %s", parameters[1].c_str());
+                       return CMD_FAILURE;
+               }
+
+               SaslAuthenticator *sasl;
+               if (!target->GetExt("sasl_authenticator", sasl))
+                       return CMD_FAILURE;
+
+               SaslState state = sasl->ProcessInboundMessage(parameters);
+               if (state == SASL_DONE)
+               {
+                       delete sasl;
+                       target->Shrink("sasl");
+               }
+               return CMD_SUCCESS;
+       }
+};
 
 class ModuleSASL : public Module
 {
-       CommandAuthenticate sasl;
+       CommandAuthenticate auth;
+       CommandSASL sasl;
  public:
 
        ModuleSASL(InspIRCd* Me)
-               : Module(Me), sasl(Me, this)
+               : Module(Me), auth(Me, this), sasl(Me, this)
        {
                Implementation eventlist[] = { I_OnEvent, I_OnUserRegister, I_OnPostConnect, I_OnUserDisconnect, I_OnCleanup };
                ServerInstance->Modules->Attach(eventlist, this, 5);
 
+               ServerInstance->AddCommand(&auth);
                ServerInstance->AddCommand(&sasl);
 
                if (!ServerInstance->Modules->Find("m_services_account.so") || !ServerInstance->Modules->Find("m_cap.so"))
@@ -255,32 +289,6 @@ class ModuleSASL : public Module
        virtual void OnEvent(Event *ev)
        {
                GenericCapHandler(ev, "sasl", "sasl");
-
-               if (ev->GetEventID() == "encap_received")
-               {
-                       parameterlist* parameters = (parameterlist*)ev->GetData();
-
-                       if ((*parameters)[1] != "SASL")
-                               return;
-
-                       User* target = ServerInstance->FindNick((*parameters)[3]);
-                       if (!target)
-                       {
-                               ServerInstance->Logs->Log("m_sasl", DEBUG,"User not found in sasl ENCAP event: %s", (*parameters)[3].c_str());
-                               return;
-                       }
-
-                       SaslAuthenticator *sasl_;
-                       if (!target->GetExt("sasl_authenticator", sasl_))
-                               return;
-
-                       SaslState state = sasl_->ProcessInboundMessage(*parameters);
-                       if (state == SASL_DONE)
-                       {
-                               delete sasl_;
-                               target->Shrink("sasl");
-                       }
-               }
        }
 };
 
index c56f8dc74f0437f9ee9f45c3c140f992cd6764f2..7b85a49d0ae163e0535148a5f49819a4d252e9d6 100644 (file)
 
 
 
-/** remote MOTD. leet, huh? */
+/** ENCAP */
 bool TreeSocket::Encap(const std::string &prefix, parameterlist &params)
 {
        if (params.size() > 1)
        {
                if (InspIRCd::Match(ServerInstance->Config->GetSID(), params[0]))
                {
-                       Event event((char*) &params, (Module*)this->Utils->Creator, "encap_received");
-                       event.Send(ServerInstance);
+                       User* who = this->ServerInstance->FindUUID(prefix);
+                       if (!who)
+                               who = Utils->ServerUser;
+
+                       parameterlist plist(params.begin() + 2, params.end());
+                       ServerInstance->CallCommandHandler(params[1].c_str(), plist, who);
+                       // discard return value, ENCAP shall succeed even if the command does not exist
                }
                
                params[params.size() - 1] = ":" + params[params.size() - 1];
index 428079c23f31d997db2131ec1289e856343b6d94..545ad3bfb73aa5750a48fe428f18044eadb99cf8 100644 (file)
@@ -39,25 +39,43 @@ void ModuleSpanningTree::OnPostCommand(const std::string &command, const std::ve
 
        RouteDescriptor routing = thiscmd->GetRouting(user, parameters);
 
+       std::string sent_cmd = command;
+       parameterlist params;
+
        if (routing.type == ROUTE_TYPE_LOCALONLY)
+       {
                return;
+       }
+       else if (routing.type == ROUTE_TYPE_OPT_BCAST)
+       {
+               params.push_back("*");
+               params.push_back(command);
+               sent_cmd = "ENCAP";
+       }
+       else if (routing.type == ROUTE_TYPE_OPT_UCAST)
+       {
+               params.push_back(routing.serverdest);
+               params.push_back(command);
+               sent_cmd = "ENCAP";
+       }
+       else
+       {
+               Module* srcmodule = ServerInstance->Modules->Find(thiscmd->source);
 
-       Module* srcmodule = ServerInstance->Modules->Find(thiscmd->source);
-
-       if (srcmodule && !(srcmodule->GetVersion().Flags & VF_COMMON)) {
-               ServerInstance->Logs->Log("m_spanningtree",ERROR,"Routed command %s from non-VF_COMMON module %s",
-                       command.c_str(), thiscmd->source.c_str());
-               return;
+               if (srcmodule && !(srcmodule->GetVersion().Flags & VF_COMMON)) {
+                       ServerInstance->Logs->Log("m_spanningtree",ERROR,"Routed command %s from non-VF_COMMON module %s",
+                               command.c_str(), thiscmd->source.c_str());
+                       return;
+               }
        }
 
        std::string output_text;
        ServerInstance->Parser->TranslateUIDs(thiscmd->translation, parameters, output_text, true, thiscmd);
 
-       parameterlist params;
        params.push_back(output_text);
 
-       if (routing.type == ROUTE_TYPE_BROADCAST)
-               Utils->DoOneToMany(user->uuid, command, params);
+       if (routing.type == ROUTE_TYPE_BROADCAST || routing.type == ROUTE_TYPE_OPT_BCAST)
+               Utils->DoOneToMany(user->uuid, sent_cmd, params);
        else
-               Utils->DoOneToOne(user->uuid, command, params, routing.serverdest);
+               Utils->DoOneToOne(user->uuid, sent_cmd, params, routing.serverdest);
 }