From 38bd2b2761b7d0f556945ffad78f73536e12e157 Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Fri, 6 Sep 2019 21:41:28 +0100 Subject: Send remote IP addresses instead of fd numbers in NOTICEs to clients and print both in related debugprint()s. --- TODO | 2 -- blabouncer.c | 13 +++++++++---- functions.c | 9 +++++---- message.c | 10 ++++++---- structures.h | 1 + 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/TODO b/TODO index a4ada59..4e76790 100644 --- a/TODO +++ b/TODO @@ -4,8 +4,6 @@ Support arrays or similar in the configuration file (for nick(s), connectcommand All the TODOs sprinkled throughout the code! -Use connecting/disconnecting IPs instead of fd numbers in NOTICEs and both in debug. - Option to include date in replay log replay. (I think) replay log can cause non-existent user to appear in channel (e.g. ~19:00 on 12/08/2019 for me) diff --git a/blabouncer.c b/blabouncer.c index e0c41f8..17ce41c 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -402,6 +402,7 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { clients[i].pendingnames = 0; clients[i].pendingcap = 0; clients[i].clientcode[0] = '\0'; + clients[i].remoteip[0] = '\0'; } // Struct of various strings from and for the real IRCd (such as the greeting strings, the real IRCd's name, @@ -769,17 +770,21 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { // If not using TLS then cast newfd to SSL* even though it will just be the original newfd int really clients[j].ssl = (SSL*)(long int)newfd; } + + // Record the remote IP address of this client in the clients array + strncpy(clients[j].remoteip, inet_ntop(remoteaddr.ss_family, get_in_addr((struct sockaddr*)&remoteaddr), remoteIP, INET6_ADDRSTRLEN), INET6_ADDRSTRLEN); + break; } } + // TODO - Handle the "find a free element" loop not finding a free element debugprint(DEBUG_FULL, "bouncer-client: new connection from %s on socket %d\n", - inet_ntop(remoteaddr.ss_family, get_in_addr((struct sockaddr*)&remoteaddr), - remoteIP, INET6_ADDRSTRLEN), newfd); + clients[arrindex(clients, i)].remoteip, newfd); // Alert other clients about the new connection char alertmsg[MAXDATASIZE]; - if (!snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :blabouncer: new client connected from %s with fd %d.", ircdstate.ircnick, - inet_ntop(remoteaddr.ss_family, get_in_addr((struct sockaddr*)&remoteaddr), remoteIP, INET6_ADDRSTRLEN), newfd)) { + if (!snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :blabouncer: new client connected from %s.", ircdstate.ircnick, + clients[arrindex(clients, i)].remoteip)) { fprintf(stderr, "Error while preparing new client connection NOTICE!\n"); debugprint(DEBUG_CRIT, "Error while preparing new client connection NOTICE!\n"); alertmsg[0] = '\0'; diff --git a/functions.c b/functions.c index 8557f7a..b9f1080 100644 --- a/functions.c +++ b/functions.c @@ -557,11 +557,11 @@ int sendtoserver(SSL *server_ssl, char *strsrc, int str_len, int clientfd, struc // Also set its authentication and registration statuses to 0. // Also set the pending statuses to 0 int disconnectclient(int fd, struct client *clients, struct ircdstate *ircdstate, struct settings *settings, struct clientcodes *clientcodes) { - debugprint(DEBUG_SOME, "disconnectclient(): disconnecting client fd '%d'\n", fd); + debugprint(DEBUG_SOME, "disconnectclient(): disconnecting client %s with fd '%d'\n", clients[arrindex(clients, fd)].remoteip, fd); // Alert other clients about the disconnection (don't send yet, we haven't removed from the clients array yet) char alertmsg[MAXDATASIZE]; - if (!snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :blabouncer: client with fd %d has disconnected.", ircdstate->ircnick, fd)) { + if (!snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :blabouncer: client %s has disconnected.", ircdstate->ircnick, clients[arrindex(clients, fd)].remoteip)) { fprintf(stderr, "Error while preparing authentication failure NOTICE!\n"); debugprint(DEBUG_CRIT, "Error while preparing authentication failure NOTICE!\n"); alertmsg[0] = '\0'; @@ -591,6 +591,7 @@ int disconnectclient(int fd, struct client *clients, struct ircdstate *ircdstate clients[i].pendingnames = 0; clients[i].pendingcap = 0; clients[i].clientcode[0] = '\0'; + clients[i].remoteip[0] = '\0'; if (settings->clienttls) { // Finish up with OpenSSL if using client TLS SSL_free(clients[i].ssl); @@ -1049,8 +1050,8 @@ void cleanexit(SSL *server_ssl, struct client *clients, int sourcefd, struct irc // Tell clients and debug log if (sourcefd) { - snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Exiting on request from client with fd '%d', message '%s'.", ircdstate->ircnick, sourcefd, quitmsg); - debugprint(DEBUG_CRIT, "Exiting on request from client with fd '%d', message '%s'.\n", sourcefd, quitmsg); + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Exiting on request from client %s, message '%s'.", ircdstate->ircnick, clients[arrindex(clients, sourcefd)].remoteip, quitmsg); + debugprint(DEBUG_CRIT, "Exiting on request from client %s with fd '%d', message '%s'.\n", clients[arrindex(clients, sourcefd)].remoteip, sourcefd, quitmsg); } else { snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Exiting on request (not from a client), message '%s'.", ircdstate->ircnick, quitmsg); debugprint(DEBUG_CRIT, "Exiting on request (not from a client), message '%s'.\n", quitmsg); diff --git a/message.c b/message.c index f360e99..0373ef3 100644 --- a/message.c +++ b/message.c @@ -731,7 +731,7 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int // PASS received? User is trying to log in, check their password. if (strncasecmp(tokens[0], "PASS", strlen(tokens[0])) == 0) { if (checkpassword(tokens[1], settings)) { - debugprint(DEBUG_FULL, "Password accepted! Setting fd %d to authenticated.\n", sourcefd); + debugprint(DEBUG_FULL, "Password accepted! Setting client %s with fd %d to authenticated.\n", clients[arrindex(clients, sourcefd)].remoteip, sourcefd); // Find the client in the clients array and set them as authenticated for (int i = 0; i < MAXCLIENTS; i++) { if (clients[i].fd == sourcefd) { @@ -740,7 +740,8 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int debugprint(DEBUG_FULL, "Found and authenticated fd in arr_authed.\n"); // Alert other clients about the successful authentication char alertmsg[MAXDATASIZE]; - if (!snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :blabouncer: new client with fd %d has successfully authenticated.", ircdstate->ircnick, sourcefd)) { + if (!snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :blabouncer: new client %s has successfully authenticated.", ircdstate->ircnick, + clients[arrindex(clients, sourcefd)].remoteip)) { fprintf(stderr, "Error while preparing authentication success NOTICE!\n"); debugprint(DEBUG_CRIT, "Error while preparing authentication success NOTICE!\n"); alertmsg[0] = '\0'; @@ -750,11 +751,12 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int } } } else { - debugprint(DEBUG_SOME, "Password rejected, disconnecting fd %d.\n", sourcefd); + debugprint(DEBUG_SOME, "Password rejected, disconnecting client %s with fd %d.\n", clients[arrindex(clients, sourcefd)].remoteip, sourcefd); disconnectclient(sourcefd, clients, ircdstate, settings, clientcodes); // Alert other clients about the failed authentication char alertmsg[MAXDATASIZE]; - if (!snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :blabouncer: new client with fd %d has failed to authenticate.", ircdstate->ircnick, sourcefd)) { + if (!snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :blabouncer: new client %s has failed to authenticate.", ircdstate->ircnick, + clients[arrindex(clients, sourcefd)].remoteip)) { fprintf(stderr, "Error while preparing authentication failure NOTICE!\n"); debugprint(DEBUG_CRIT, "Error while preparing authentication failure NOTICE!\n"); alertmsg[0] = '\0'; diff --git a/structures.h b/structures.h index d9b1f7f..a959a92 100644 --- a/structures.h +++ b/structures.h @@ -99,6 +99,7 @@ struct client { int pendingnames; // Count of RPL_NAMREPLYs the client is waiting on. int pendingcap; // Whether the client is still negotiating IRCv3 CAPabilities. 0 = no, 1 = yes, -1 = just finished (so register them as if they had just sent USER). char clientcode[CLIENTCODELEN]; // This client's client code + char remoteip[INET6_ADDRSTRLEN]; // Client's remote IP address (assume up to IPv6 size) }; // Structure of client codes. Used to track the last time a client identifying as a given client connected to handle auto replay for a known client. -- cgit v1.2.3