summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2019-05-19 15:11:05 +0100
committerLuke Bratch <luke@bratch.co.uk>2019-05-19 15:11:05 +0100
commit3b85b88516fbc4c793a456674265b6a64d92eee2 (patch)
treea27e9475210d06aa3c9dd706a258a8469305ea3c
parent52d426544ce976f81cbd626fbba343c066ed88d0 (diff)
Only relay WHOIS and WHOWAS requests to the server and their responses to the requesting client. Also fix flag for pending LIST responses.
-rw-r--r--blabouncer.c147
1 files changed, 143 insertions, 4 deletions
diff --git a/blabouncer.c b/blabouncer.c
index f85e58c..846695b 100644
--- a/blabouncer.c
+++ b/blabouncer.c
@@ -7,7 +7,6 @@
// - Perhaps rename clients.ssl and server_ssl since they may not even be OpenSSL sockets
// - Is it possible to replay JOINs/PARTs accurately?
// - Add help output for missing certs
-// - Only relay WHOIS replies to requesting client
// - Remove any old channel name/mode/prefix code that isn't needed any more
// "server" means the real IRC server
@@ -110,6 +109,8 @@ struct client {
int pendingban; // Whether the client is waiting to hear back from a "MODE #channel b" command
int pendingwho; // Whether the client is waiting to hear back from a "MODE #channel" command
int pendinglist; // Whether the client is waiting to hear back from a "LIST" command
+ int pendingwhois; // Whether the client is waiting to hear back from a "WHOIS" command
+ int pendingwhowas; // Whether the client is waiting to hear back from a "WHOWAS" command
int pendingnames; // Count of RPL_NAMREPLYs the client is waiting on.
};
@@ -285,6 +286,8 @@ int disconnectclient(int fd, struct client *clients, struct ircdstrings *ircdstr
clients[i].pendingban = 0;
clients[i].pendingwho = 0;
clients[i].pendinglist = 0;
+ clients[i].pendingwhois = 0;
+ clients[i].pendingwhowas = 0;
clients[i].pendingnames = 0;
// Finish up with OpenSSL
SSL_free(clients[i].ssl);
@@ -1002,11 +1005,34 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
// Relay to all pending clients
for (int i = 0; i < MAXCLIENTS; i++) {
- if (clients[i].pendingwho == 1 && clients[i].fd) {
+ if (clients[i].pendinglist == 1 && clients[i].fd) {
sendtoclient(clients[i].fd, str, clients, settings);
// And clear the pending flag if it's 323 (RPL_LISTEND)
if (strncmp(tokens[1], "323", strlen(tokens[1])) == 0) {
- clients[i].pendingwho = 0;
+ clients[i].pendinglist = 0;
+ }
+ }
+ }
+
+ free(strcopyPtr);
+ return 1;
+ }
+
+ // Server 307 (RPL_SUSERHOST), 311 (RPL_WHOISUSER), 312 (RPL_WHOISSERVER), 317 (RPL_WHOISIDLE), 319 (RPL_WHOISCHANNELS), or 318 (RPL_ENDOFWHOIS) received?
+ // Send to any clients who requested a WHOIS.
+ if (strncmp(tokens[1], "307", strlen(tokens[1])) == 0 || strncmp(tokens[1], "311", strlen(tokens[1])) == 0 ||
+ strncmp(tokens[1], "312", strlen(tokens[1])) == 0 || strncmp(tokens[1], "317", strlen(tokens[1])) == 0 ||
+ strncmp(tokens[1], "319", strlen(tokens[1])) == 0 || strncmp(tokens[1], "318", strlen(tokens[1])) == 0) {
+ printf("Server 307 RPL_SUSERHOST, 311 RPL_WHOISUSER, 312 RPL_WHOISSERVER, 317 RPL_WHOISIDLE, 319 RPL_WHOISCHANNELS, or 318 RPL_ENDOFWHOIS "
+ "found and it is: %s with length %zd! Sending to clients who are pending one of these.\n", tokens[1], strlen(tokens[1]));
+
+ // Relay to all pending clients
+ for (int i = 0; i < MAXCLIENTS; i++) {
+ if (clients[i].pendingwhois == 1 && clients[i].fd) {
+ sendtoclient(clients[i].fd, str, clients, settings);
+ // And clear the pending flag if it's 318 RPL_ENDOFWHOIS
+ if (strncmp(tokens[1], "318", strlen(tokens[1])) == 0) {
+ clients[i].pendingwhois = 0;
}
}
}
@@ -1015,6 +1041,99 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
return 1;
}
+ // Server 307 (RPL_SUSERHOST), 311 (RPL_WHOISUSER), 317 (RPL_WHOISIDLE), 319 (RPL_WHOISCHANNELS), or 318 (RPL_ENDOFWHOIS) received?
+ // Send to any clients who requested a WHOIS.
+ if (strncmp(tokens[1], "307", strlen(tokens[1])) == 0 || strncmp(tokens[1], "311", strlen(tokens[1])) == 0 ||
+ strncmp(tokens[1], "317", strlen(tokens[1])) == 0 || strncmp(tokens[1], "319", strlen(tokens[1])) == 0 ||
+ strncmp(tokens[1], "318", strlen(tokens[1])) == 0) {
+ printf("Server 307 RPL_SUSERHOST, 311 RPL_WHOISUSER, 317 RPL_WHOISIDLE, 319 RPL_WHOISCHANNELS, or 318 RPL_ENDOFWHOIS "
+ "found and it is: %s with length %zd! Sending to clients who are pending one of these.\n", tokens[1], strlen(tokens[1]));
+
+ // Relay to all pending clients
+ for (int i = 0; i < MAXCLIENTS; i++) {
+ if (clients[i].pendingwhowas == 1 && clients[i].fd) {
+ sendtoclient(clients[i].fd, str, clients, settings);
+ // And clear the pending flag if it's 318 RPL_ENDOFWHOIS
+ if (strncmp(tokens[1], "318", strlen(tokens[1])) == 0) {
+ clients[i].pendingwhowas = 0;
+ }
+ }
+ }
+
+ free(strcopyPtr);
+ return 1;
+ }
+
+ // Server 314 (RPL_WHOWASUSER), 406 (ERR_WASNOSUCHNICK), or 369 (RPL_ENDOFWHOWAS) received?
+ // Send to any clients who requested a WHOWAS.
+ if (strncmp(tokens[1], "314", strlen(tokens[1])) == 0 || strncmp(tokens[1], "406", strlen(tokens[1])) == 0 || strncmp(tokens[1], "369", strlen(tokens[1])) == 0) {
+ printf("314 (RPL_WHOWASUSER), 406 (ERR_WASNOSUCHNICK), or 369 (RPL_ENDOFWHOWAS) "
+ "found and it is: %s with length %zd! Sending to clients who are pending one of these.\n", tokens[1], strlen(tokens[1]));
+
+ // Relay to all pending clients
+ for (int i = 0; i < MAXCLIENTS; i++) {
+ if (clients[i].pendingwhowas == 1 && clients[i].fd) {
+ sendtoclient(clients[i].fd, str, clients, settings);
+ // And clear the pending flag if it's 369 RPL_ENDOFWHOWAS
+ if (strncmp(tokens[1], "369", strlen(tokens[1])) == 0) {
+ clients[i].pendingwhowas = 0;
+ }
+ }
+ }
+
+ free(strcopyPtr);
+ return 1;
+ }
+
+ // Server 312 (RPL_WHOISSERVER) received? Check to see if anyone was pending a WHOIS or a WHOWAS and send to them, if not send to everyone.
+ if (strncmp(tokens[1], "312", strlen(tokens[1])) == 0) {
+ printf("Server 312 (RPL_WHOISSERVER) found and it is: %s with length %zd! Sending to clients who are pending this or to everyone if nobody is.\n", tokens[1], strlen(tokens[1]));
+
+ int waspending = 0;
+
+ // Relay to all pending clients
+ for (int i = 0; i < MAXCLIENTS; i++) {
+ if (clients[i].pendingwhois == 1 || clients[i].pendingwhowas == 1) {
+ sendtoclient(clients[i].fd, str, clients, settings);
+ // Note that we were pending this
+ waspending = 1;
+ }
+ }
+
+ // If no client was pending this, send to everyone
+ if (!waspending) {
+ sendtoallclients(clients, str, 0, settings);
+ }
+
+ free(strcopyPtr);
+ return 1;
+ }
+
+
+ // Server 401 (ERR_NOSUCHNICK) received? Check to see if anyone was pending a WHOIS and send to them, if not send to everyone.
+ if (strncmp(tokens[1], "401", strlen(tokens[1])) == 0) {
+ printf("Server 401 (ERR_NOSUCHNICK) found and it is: %s with length %zd! Sending to clients who are pending this or to everyone if nobody is.\n", tokens[1], strlen(tokens[1]));
+
+ int waspending = 0;
+
+ // Relay to all pending clients
+ for (int i = 0; i < MAXCLIENTS; i++) {
+ if (clients[i].pendingwhois == 1) {
+ sendtoclient(clients[i].fd, str, clients, settings);
+ // Note that we were pending this
+ waspending = 1;
+ }
+ }
+
+ // If no client was pending this, send to everyone
+ if (!waspending) {
+ sendtoallclients(clients, str, 0, settings);
+ }
+
+ free(strcopyPtr);
+ return 1;
+ }
+
// Server 432 (ERR_ERRONEUSNICKNAME) or 433 (ERR_NICKNAMEINUSE) received? See which nick we're on and try another.
if (strncmp(tokens[1], "432", strlen(tokens[1])) == 0 || strncmp(tokens[1], "433", strlen(tokens[1])) == 0) {
printf("Server 432 (ERR_ERRONEUSNICKNAME) or 433 (ERR_NICKNAMEINUSE) found and it is: %s with length %zd! Trying another nick...\n", tokens[1], strlen(tokens[1]));
@@ -1350,7 +1469,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
// LIST requested, mark the client as waiting for the reply (so not all clients get it) and send it on the server
if (strncmp(tokens[0], "LIST", strlen(tokens[0])) == 0) {
printf("Client LIST found and it is: %s with length %zd! Marking as pending.\n", tokens[0], strlen(tokens[0]));
- clients[arrindex(clients, sourcefd)].pendingwho = 1;
+ clients[arrindex(clients, sourcefd)].pendinglist = 1;
// Either way, send it on the server
sendtoserver(server_ssl, str, strlen(str), sourcefd, clients, settings);
@@ -1358,6 +1477,24 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
return 1;
}
+ // Client WHOIS received, send straight on to server and mark the client as pending the response
+ if (strncmp(tokens[0], "WHOIS", strlen(tokens[0])) == 0) {
+ printf("Client WHOIS found and it is: %s with length %zd! Sending to server and setting client as pending.\n", tokens[0], strlen(tokens[0]));
+ clients[arrindex(clients, sourcefd)].pendingwhois = 1;
+ sendtoserver(server_ssl, str, strlen(str), sourcefd, clients, settings);
+ free(strcopyPtr);
+ return 1;
+ }
+
+ // Client WHOWAS received, send straight on to server and mark the client as pending the response
+ if (strncmp(tokens[0], "WHOWAS", strlen(tokens[0])) == 0) {
+ printf("Client WHOWAS found and it is: %s with length %zd! Sending to server and setting client as pending.\n", tokens[0], strlen(tokens[0]));
+ clients[arrindex(clients, sourcefd)].pendingwhowas = 1;
+ sendtoserver(server_ssl, str, strlen(str), sourcefd, clients, settings);
+ free(strcopyPtr);
+ return 1;
+ }
+
// Custom BLABOUNCER command received
// Case insensitive comparisons here since clients won't be recognising and uppercasing these commands
if (strncasecmp(tokens[0], "BLABOUNCER", strlen(tokens[0])) == 0) {
@@ -1549,6 +1686,8 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) {
clients[i].pendingban = 0;
clients[i].pendingwho = 0;
clients[i].pendinglist = 0;
+ clients[i].pendingwhois = 0;
+ clients[i].pendingwhowas = 0;
clients[i].pendingnames = 0;
}