]> arthur.barton.de Git - ngircd-alex.git/commitdiff
Allow forwarding of CONNECT commands.
authorAlexander Barton <alex@barton.de>
Tue, 22 Jul 2008 16:38:05 +0000 (18:38 +0200)
committerAlexander Barton <alex@barton.de>
Wed, 30 Sep 2009 14:00:06 +0000 (16:00 +0200)
The syntax of the CONNECT command now is:

  - CONNECT <server-id>
  - CONNECT <server-id> <port>
  - CONNECT <server-id> <port> <target>
  - CONNECT <server-id> <port> <host> <my-pwd> <peer-pwd>
  - CONNECT <server-id> <port> <host> <my-pwd> <peer-pwd> <target>

Note: the configuration option "AllowRemoteOper" mus be enabled on the
target server to allow forwarding of CONNECT commands.

src/ngircd/irc-oper.c
src/ngircd/parse.c

index 656e9591f801bd11555a21c3a0ca843cd2d89652..f67e947ce17be37a6f8e81a5254dd3352e0219f6 100644 (file)
@@ -230,6 +230,8 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req )
 GLOBAL bool
 IRC_CONNECT(CLIENT * Client, REQUEST * Req)
 {
+       CLIENT *from, *target;
+
        assert(Client != NULL);
        assert(Req != NULL);
 
@@ -237,7 +239,8 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
                return No_Privileges(Client, Req);
 
        /* Bad number of parameters? */
-       if ((Req->argc != 1) && (Req->argc != 2) && (Req->argc != 5))
+       if (Req->argc != 1 && Req->argc != 2 && Req->argc != 3 &&
+           Req->argc != 5 && Req->argc != 6)
                return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
                                          Client_ID(Client), Req->command);
 
@@ -246,36 +249,68 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
                return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
                                          Client_ID(Client), Req->command);
 
-       IRC_SendWallops(Client_ThisServer(), Client_ThisServer(),
-                       "Received CONNECT %s from %s",
-                       Req->argv[0], Client_ID(Client));
+       from = Client;
+       target = Client_ThisServer();
+
+       if (Req->argc == 3 || Req->argc == 6) {
+               /* This CONNECT has a target parameter */
+               if (Client_Type(Client) == CLIENT_SERVER)
+                       from = Client_Search(Req->prefix);
+               if (! from)
+                       return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
+                                       Client_ID(Client), Req->prefix);
+
+               target = (Req->argc == 3) ? Client_Search(Req->argv[2])
+                                         : Client_Search(Req->argv[5]);
+               if (! target || Client_Type(target) != CLIENT_SERVER)
+                       return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
+                                       Client_ID(from), Req->argv[0]);
+       }
+
+       if (target != Client_ThisServer()) {
+               /* Forward CONNECT command ... */
+               if (Req->argc == 3)
+                       IRC_WriteStrClientPrefix(target, from,
+                                "CONNECT %s %s :%s", Req->argv[0],
+                                Req->argv[1], Req->argv[2]);
+               else
+                       IRC_WriteStrClientPrefix(target, from,
+                               "CONNECT %s %s %s %s %s :%s", Req->argv[0],
+                               Req->argv[1], Req->argv[2], Req->argv[3],
+                               Req->argv[4], Req->argv[5]);
+               return CONNECTED;
+       }
 
        Log(LOG_NOTICE | LOG_snotice,
-           "Got CONNECT command from \"%s\" for \"%s\".", Client_Mask(Client),
+           "Got CONNECT command from \"%s\" for \"%s\".", Client_Mask(from),
            Req->argv[0]);
+       IRC_SendWallops(Client_ThisServer(), Client_ThisServer(),
+                       "Received CONNECT %s from %s",
+                       Req->argv[0], Client_ID(from));
 
        switch (Req->argc) {
        case 1:
                if (!Conf_EnablePassiveServer(Req->argv[0]))
-                       return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
-                                                 Client_ID(Client),
+                       return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
+                                                 Client_ID(from),
                                                  Req->argv[0]);
-       break;
+               break;
        case 2:
+       case 3:
                /* Connect configured server */
                if (!Conf_EnableServer
                    (Req->argv[0], (UINT16) atoi(Req->argv[1])))
-                       return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
-                                                 Client_ID(Client),
+                       return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
+                                                 Client_ID(from),
                                                  Req->argv[0]);
-       break;
+               break;
        default:
                /* Add server */
                if (!Conf_AddServer
                    (Req->argv[0], (UINT16) atoi(Req->argv[1]), Req->argv[2],
                     Req->argv[3], Req->argv[4]))
-                       return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
-                                                 Client_ID(Client),
+                       return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
+                                                 Client_ID(from),
                                                  Req->argv[0]);
        }
 
index 5e3f08d0cf77fa26b2da6ad185ccd6f066b3025b..6d53525b6f2754875eae94a9baa565800156ac0a 100644 (file)
@@ -59,7 +59,7 @@ static COMMAND My_Commands[] =
 {
        { "ADMIN", IRC_ADMIN, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
        { "AWAY", IRC_AWAY, CLIENT_USER, 0, 0, 0 },
-       { "CONNECT", IRC_CONNECT, CLIENT_USER, 0, 0, 0 },
+       { "CONNECT", IRC_CONNECT, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
        { "DIE", IRC_DIE, CLIENT_USER, 0, 0, 0 },
        { "DISCONNECT", IRC_DISCONNECT, CLIENT_USER, 0, 0, 0 },
        { "ERROR", IRC_ERROR, 0xFFFF, 0, 0, 0 },