From f0936ca1b231df3c5cb7cf80a1d6a88d7ea980af Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Mon, 27 May 2019 12:37:46 +0100 Subject: Only do CAP multi-prefix negotiation with clients if the server approved it in the first place. --- blabouncer.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'blabouncer.c') diff --git a/blabouncer.c b/blabouncer.c index db0d384..efb2474 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -76,6 +76,7 @@ struct ircdstrings { char ircusername[MAXUSERNAMELEN]; char currentmsg[MAXDATASIZE]; // Holding area for the current server-received IRC message being processed in case it needs building across multiple reads (i.e. a truncated/split message) char mode[MAXDATASIZE]; + int capmultiprefix; // Whether the server approved our CAP multi-prefix request }; // Structure of settings either to be read from the configuration file or set/changed at runtime @@ -1260,6 +1261,21 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli free(strcopyPtr); return 1; } + + // Server CAP received? + if (strncmp(tokens[1], "CAP", strlen(tokens[1])) == 0) { + printf("Server CAP found and it is: %s with length %zd! Analysing...\n", tokens[1], strlen(tokens[1])); + // If the server said "CAP ACK :multi-prefix" then it must have approved our CAP multi-prefix request + if (counter == 5) { + if (strncmp(tokens[2], ircdstrings->ircnick, strlen(tokens[2])) == 0 && + strncmp(tokens[3], "ACK", strlen(tokens[3])) == 0 && + strncmp(tokens[4], ":multi-prefix", strlen(tokens[4])) == 0) { + ircdstrings->capmultiprefix = 1; + } + } + // We didn't handle it + printf("Unhandled server CAP response.\n"); + } } // Don't return if we got here because this means we didn't process something above @@ -1305,6 +1321,14 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli // CAP received? Clients can send CAP before PASS so we have to deal with this even if they are not authenticated yet. if (strncasecmp(tokens[0], "CAP", strlen(tokens[0])) == 0) { + // But only do something if the real server told us it had a CAP (only multi-prefix for now) + if (ircdstrings->capmultiprefix == 1) { + printf("Client CAP received and the server supports CAPs, continuing.\n"); + } else { + printf("Client CAP received but the server doesn't support CAPs, returning.\n"); + free(strcopyPtr); + return 1; + } // Get the real IRC server name from greeting001 // They are now pending CAP negotiation clients[arrindex(clients, sourcefd)].pendingcap = 1; @@ -1875,6 +1899,8 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { ircdstrings.ircusername[0] = '\0'; ircdstrings.currentmsg[0] = '\0'; ircdstrings.mode[0] = '\0'; + // And set non-string things to zero (TODO - Rename this from ircdstrings since it's not all strings any more) + ircdstrings.capmultiprefix = 0; // Populate nick and username from our configuration file for now, real IRCd may change them later (TODO - Is this true of username?) strcpy(ircdstrings.ircnick, settings->ircnick); -- cgit v1.2.3