diff options
author | Luke Bratch <luke@bratch.co.uk> | 2019-05-27 12:37:46 +0100 |
---|---|---|
committer | Luke Bratch <luke@bratch.co.uk> | 2019-05-27 12:37:46 +0100 |
commit | f0936ca1b231df3c5cb7cf80a1d6a88d7ea980af (patch) | |
tree | 0ab81634a4858c9b10cc7cdf830f1bf2537d7c18 | |
parent | ab84512bc06ade328169d38ffb64f3820aa80dc4 (diff) |
Only do CAP multi-prefix negotiation with clients if the server approved it in the first place.
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | blabouncer.c | 26 |
2 files changed, 26 insertions, 4 deletions
@@ -21,8 +21,4 @@ Test CTCP. Reconnect server if we get disconnected for some reason. -Only do CAP multi-prefix negotiation with client if server approved it in the first place. - Change default certfile and keyfile to be basedir/ instead of $HOME. - -Connecting to Miau has some sort of corruption and doesn't get channels. 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 <ournick> 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); |