From 67fd69854489a088bc8d90702ba37cecccd6f169 Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Sun, 16 Jun 2019 21:16:29 +0100 Subject: Load all settings from configuration file at startup instead of reading it for certain settings (password/nick/nick2/nick3). --- README | 7 +++---- TODO | 2 +- blabouncer.c | 20 +++++++++++++++++++- config.c | 30 ------------------------------ config.h | 7 +------ functions.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ functions.h | 5 +++++ message.c | 28 +++++++++------------------- structures.h | 3 +++ 9 files changed, 101 insertions(+), 61 deletions(-) diff --git a/README b/README index 2a861c5..e531121 100644 --- a/README +++ b/README @@ -24,14 +24,13 @@ If you don't specify one using "-c /path/to/configuration/file" then the example Certain configuration options can be changed at runtime, either at any time, or by issuing a BLABOUNCER REHASH command or by sending SIGHUP to blabouncer. -These options can be changed at any time as they are re-read when needed: +These options can be changed by issuing a BLABOUNCER REHASH command or by sending SIGHUP to blabouncer: + - nick - nick2 - nick3 - - password - -These options can be changed by issuing a BLABOUNCER REHASH command or by sending SIGHUP to blabouncer: - replaymode - replayseconds + - password - logging - replaylogging - debug diff --git a/TODO b/TODO index 081cb0c..d0d4bf8 100644 --- a/TODO +++ b/TODO @@ -7,4 +7,4 @@ Add various auto replay options: Might need to #include in blabouncer.c to make some operating systems and/or compilers happy. -Load all settings from configuration file at startup instead of referring to it for certain things (password/nick2/nick3). +What happens if an extremely long line is received? diff --git a/blabouncer.c b/blabouncer.c index 22252d7..c9a91aa 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -875,7 +875,13 @@ int main(int argc, char *argv[]) { exit(1); } - // What port should the bouncer listen on + // What is the bouncer password? + if (!getconfstr("password", settings.conffile, settings.password)) { + printf("main(): error getting 'password' from configuration file.\n"); + exit(1); + } + + // What port should the bouncer listen on? if (!getconfstr("clientport", settings.conffile, settings.clientport)) { printf("main(): error getting 'clientport' from configuration file.\n"); exit(1); @@ -887,6 +893,18 @@ int main(int argc, char *argv[]) { exit(1); } + // What is the configured nick2? + if (!getconfstr("nick2", settings.conffile, settings.ircnick2)) { + // Not configured, set to blank string + settings.ircnick2[0] = '\0'; + } + + // What is the configured nick3? + if (!getconfstr("nick3", settings.conffile, settings.ircnick3)) { + // Not configured, set to blank string + settings.ircnick3[0] = '\0'; + } + // What is the configured username? if (!getconfstr("username", settings.conffile, settings.ircusername)) { printf("main(): error getting 'username' from configuration file.\n"); diff --git a/config.c b/config.c index faa153a..9a144cd 100644 --- a/config.c +++ b/config.c @@ -120,36 +120,6 @@ int getconfint(char *confname, char *filename) { return strtol(result, NULL, 10); // Convert resulting string to an integer, base 10 } -// Check the password provided in the string 'str' against what is in -// the configuration file 'filename'. -// Return 0 for password mismatch, or 1 for password match. -int checkpassword(char *password, char *filename) { - char confpassword[MAXCHAR]; - - if (!getconfstr("password", filename, confpassword)) { - debugprint(DEBUG_CRIT, "checkpassword(): error getting configuration option 'password' from configuration file '%s'.\n", filename); - return 0; - } - - // Ensure passwords are the same length - if (strlen(password) != strlen(confpassword)) { - debugprint(DEBUG_SOME, "Password length mismatch!\n"); - return 0; - } - // Ensure passwords match - if (strncmp(password, confpassword, strlen(password)) == 0) { - debugprint(DEBUG_FULL, "confpassword matches password.\n"); - return 1; - } else { - debugprint(DEBUG_SOME, "confpassword does NOT match password!\n"); - return 0; - } - - printf("checkpassword(): unexpectedly got to end of function, quitting.\n"); - debugprint(DEBUG_CRIT, "checkpassword(): unexpectedly got to end of function, quitting.\n"); - exit(1); -} - // Create the default configuration file. // Return 1 on success, 0 on failure. int createconfigfile(char *filename) { diff --git a/config.h b/config.h index b204b5f..2f2db9f 100644 --- a/config.h +++ b/config.h @@ -40,16 +40,11 @@ // getconfstr() returns. int getconfstr(char *confname, char *filename, char* dest); -// Returns the avlue of the configuration option with name +// Returns the value of the configuration option with name // 'confname' from configuration file 'filename'. // Sets errno to 0 on success, or ECONFINT if it fails, in which case the return value is undefined. int getconfint(char *confname, char *filename); -// Check the password provided in the string 'str' against what is in -// the configuration file 'filename'. -// Return 0 for password mismatch, or 1 for password match. -int checkpassword(char *password, char *filename); - // Create the default configuration file. // Return 1 on success, 0 on failure. int createconfigfile(char *filename); diff --git a/functions.c b/functions.c index abffb0b..82a98eb 100644 --- a/functions.c +++ b/functions.c @@ -996,6 +996,33 @@ void cleanexit(SSL *server_ssl, struct client *clients, int sourcefd, struct irc int rehash(struct settings *settings, char *failuremsg) { // TODO - Try to share some/all of this code with the initial main() settings loading + // What is the nick? + char oldircnick[MAXNICKLENGTH]; + strcpy(oldircnick, settings->ircnick); + if (!getconfstr("nick", settings->conffile, settings->ircnick)) { + strcpy(settings->ircnick, oldircnick); + strcpy(failuremsg, "error getting 'nick' from configuration file"); + return 0; + } + + // What is nick2? + char oldircnick2[MAXNICKLENGTH]; + strcpy(oldircnick2, settings->ircnick2); + if (!getconfstr("nick2", settings->conffile, settings->ircnick2)) { + strcpy(settings->ircnick2, oldircnick2); + // Not configured, set to blank string + settings->ircnick2[0] = '\0'; + } + + // What is nick3? + char oldircnick3[MAXNICKLENGTH]; + strcpy(oldircnick3, settings->ircnick3); + if (!getconfstr("nick3", settings->conffile, settings->ircnick3)) { + strcpy(settings->ircnick3, oldircnick3); + // Not configured, set to blank string + settings->ircnick3[0] = '\0'; + } + // What is the auto replay mode? char oldreplaymode[MAXDATASIZE]; strcpy(oldreplaymode, settings->replaymode); @@ -1020,6 +1047,15 @@ int rehash(struct settings *settings, char *failuremsg) { return 0; } + // What is the password? + char oldpassword[MAXCHAR]; + strcpy(oldpassword, settings->password); + if (!getconfstr("password", settings->conffile, settings->password)) { + strcpy(settings->password, oldpassword); + strcpy(failuremsg, "error getting 'password' from configuration file"); + return 0; + } + // Is logging enabled? int oldlogging = settings->logging; settings->logging = getconfint("logging", settings->conffile); @@ -1051,3 +1087,27 @@ int rehash(struct settings *settings, char *failuremsg) { failuremsg[0] = '\0'; return 1; } + +// Check the password provided in the string 'str' against what is in +// the settings structure 'settings'. +// Return 0 for password mismatch, or 1 for password match. +int checkpassword(char *password, struct settings *settings) { + // Ensure passwords are the same length + if (strlen(password) != strlen(settings->password)) { + debugprint(DEBUG_SOME, "Password length mismatch!\n"); + return 0; + } + // Ensure passwords match + if (strncmp(password, settings->password, strlen(password)) == 0) { + debugprint(DEBUG_FULL, "settings->password matches password.\n"); + return 1; + } else { + debugprint(DEBUG_SOME, "settings->password does NOT match password!\n"); + return 0; + } + + printf("checkpassword(): unexpectedly got to end of function, quitting.\n"); + debugprint(DEBUG_CRIT, "checkpassword(): unexpectedly got to end of function, quitting.\n"); + // No messing around with password stuff + exit(EXIT_FAILURE); +} diff --git a/functions.h b/functions.h index 07fdf09..c91bfdc 100644 --- a/functions.h +++ b/functions.h @@ -161,4 +161,9 @@ void cleanexit(SSL *server_ssl, struct client *clients, int sourcefd, struct irc // Returns 1 on success or 0 on failure. int rehash(struct settings *settings, char *failuremsg); +// Check the password provided in the string 'str' against what is in +// the settings structure 'settings'. +// Return 0 for password mismatch, or 1 for password match. +int checkpassword(char *password, struct settings *settings); + #endif diff --git a/message.c b/message.c index 1c58665..0137fd4 100644 --- a/message.c +++ b/message.c @@ -627,43 +627,33 @@ int processservermessage(SSL *server_ssl, char *str, struct client *clients, int debugprint(DEBUG_SOME, "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])); - // Try to get nick2 and nick3 from the configuration file - char nick2[MAXNICKLENGTH]; - char nick3[MAXNICKLENGTH]; - if (!getconfstr("nick2", settings->conffile, nick2)) { - nick2[0] = '\0'; - } - if (!getconfstr("nick3", settings->conffile, nick3)) { - nick3[0] = '\0'; - } - // Do we have both a nick2 and a nick3? (And not tried autonick yet.) - if (nick2[0] && nick3[0] && !ircdstate->autonicknum) { + if (settings->ircnick2[0] && settings->ircnick3[0] && !ircdstate->autonicknum) { // Has nick3 already been tried? - if (strncmp(ircdstate->ircnick, nick3, strlen(settings->ircnick)) == 0) { + if (strncmp(ircdstate->ircnick, settings->ircnick3, strlen(settings->ircnick)) == 0) { // Then try autonick tryautonick(ircdstate); // Has nick2 already been tried? - } else if (strncmp(ircdstate->ircnick, nick2, strlen(settings->ircnick)) == 0) { + } else if (strncmp(ircdstate->ircnick, settings->ircnick2, strlen(settings->ircnick)) == 0) { // Then try nick3 debugprint(DEBUG_SOME, "Trying nick3, nick2 was already tried.\n"); - strcpy(ircdstate->ircnick, nick3); + strcpy(ircdstate->ircnick, settings->ircnick3); // Have neither been tried? } else { // Then try nick2 debugprint(DEBUG_SOME, "Trying nick2, nick3 is also configured.\n"); - strcpy(ircdstate->ircnick, nick2); + strcpy(ircdstate->ircnick, settings->ircnick2); } // Do we only have a nick2? (And not tried autonick yet.) - } else if (nick2[0] && !ircdstate->autonicknum) { + } else if (settings->ircnick2[0] && !ircdstate->autonicknum) { // Has it already been tried? - if (strncmp(ircdstate->ircnick, nick2, strlen(settings->ircnick)) == 0) { + if (strncmp(ircdstate->ircnick, settings->ircnick2, strlen(settings->ircnick)) == 0) { // Then try autonick tryautonick(ircdstate); } else { // Then try it debugprint(DEBUG_SOME, "Trying nick2, nick3 is not configured.\n"); - strcpy(ircdstate->ircnick, nick2); + strcpy(ircdstate->ircnick, settings->ircnick2); } // Do we have neither? (Or have already started autonick.) } else { @@ -740,7 +730,7 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int struct channel *channels, struct settings *settings, char tokens[MAXTOKENS][MAXDATASIZE], int counter) { // 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->conffile)) { + if (checkpassword(tokens[1], settings)) { debugprint(DEBUG_FULL, "Password accepted! Setting fd %d to authenticated.\n", sourcefd); // Find the client in the clients array and set them as authenticated for (int i = 0; i < MAXCLIENTS; i++) { diff --git a/structures.h b/structures.h index 9246fa4..3209b21 100644 --- a/structures.h +++ b/structures.h @@ -56,8 +56,11 @@ struct settings { int replayseconds; char clientport[MAXPORTLEN]; char ircnick[MAXNICKLENGTH]; // In both settings and ircdstate as settings is from our file whereas server may change ircdstate copy + char ircnick2[MAXNICKLENGTH]; + char ircnick3[MAXNICKLENGTH]; char ircusername[MAXUSERNAMELEN]; // (Is this also true for the username? Can the server change that?) char ircrealname[MAXREALNAMELEN]; + char password[MAXDATASIZE]; char autochannels[MAXAUTOCHANLEN]; char ircserver[HOST_NAME_MAX]; char ircserverport[MAXPORTLEN]; -- cgit v1.2.3