diff options
| author | Luke Bratch <luke@bratch.co.uk> | 2021-01-18 21:51:00 +0000 | 
|---|---|---|
| committer | Luke Bratch <luke@bratch.co.uk> | 2021-01-18 21:51:00 +0000 | 
| commit | a16d9bdecb572bb266a84ec90767d613ce8ce255 (patch) | |
| tree | 865c745fab117969647ea722334f35304595a7d5 | |
| parent | 323e273bc7dbc2b244e536a10b6c370651c76b8a (diff) | |
Make the "channels" configuration file entry an array.
| -rw-r--r-- | TODO | 4 | ||||
| -rw-r--r-- | blabouncer.c | 27 | ||||
| -rw-r--r-- | blabouncer.conf.example | 9 | ||||
| -rw-r--r-- | config.c | 9 | ||||
| -rw-r--r-- | functions.c | 46 | ||||
| -rw-r--r-- | structures.h | 4 | 
6 files changed, 51 insertions, 48 deletions
@@ -4,8 +4,6 @@ Configurable rotation of replay and debug logs.  Configurable timestamp format in logs. -Add a make install/uninstall/etc., add an "INSTALL" file, include a dependency listing. -  macOS compiler may need limits.h included in structures.h.  "Starting log replay...." followed by "Unable to read replay log file!" even though replay seemed to work? @@ -16,6 +14,6 @@ Can memory usage be reduced further?  (e.g. better channel struct management)  Ability to load new certificate whilst running. -Make the "channels" configuration file entry an array. +JOINing a channel that is a substring of another channel breaks all sorts (e.g. both #blabouncer and #blabounce).  Crash when requesting 30 hour replay. diff --git a/blabouncer.c b/blabouncer.c index 982d504..89add3e 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -1052,12 +1052,27 @@ int main(int argc, char *argv[]) {    }    // What, if anything, are the configured auto channels? -  if (!getconfstr("channels", settings.conffile, settings.autochannels)) { -    settings.autochannels[0] = '\0'; -  } else { -    // If something was set, make sure it's not too long -    if (strlen(settings.autochannels) >= MAXAUTOCHANLEN) { -      printf("main(): 'channels' option in configuration file is too long.\n"); +  ret = getconfarr("channels", settings.conffile, settings.autochannels); +  if (!ret) { +    for (int i = 0; i < MAXCONFARR; i++) { +      settings.autochannels[i][0] = '\0'; +    } +  } else if (ret == -1) { +    // Remove any newlines from the middle of the string so error printing works nicely +    for (size_t i = 0; i < strlen(settings.autochannels[0]) - 1; i++) { +      if (settings.autochannels[0][i] == '\n') { +        settings.autochannels[0][i] = ' '; +      } +    } +    printf("main(): error getting 'autochannels' from configuration file: %s", settings.autochannels[0]); +    exit(1); +  } + +  // Make sure channel/key pairs aren't too long (since getconfarr() has to use MAXDATASIZE for all string lengths) +  for (int i = 0; i < MAXCONFARR; i++) { +    // +1 for the space between channel name and keys +    if (settings.autochannels[i][0] && strlen(settings.autochannels[i]) > MAXCHANLENGTH + 1 + MAXCHANKEYLEN) { +      printf("main(): error: specified channel name/key pair '%s' is too long, maximum lengths are %d (name) and %d (key).\n", settings.autochannels[i], MAXCHANLENGTH, MAXCHANKEYLEN);        exit(1);      }    } diff --git a/blabouncer.conf.example b/blabouncer.conf.example index 0513fdc..d77689c 100644 --- a/blabouncer.conf.example +++ b/blabouncer.conf.example @@ -32,9 +32,12 @@ nicks = {  username = "bounceusr"  realname = "Mr Bla Bouncer" -# Channels to automatically join (comma-separated list, defaults to none) -# Put channel keywords/passwords after channel names following a space. -#channels = "#blabouncer keyword,#test" +# Channels to automatically join (defaults to none) +# Put channel keys/passwords after channel names (separated with a space) +channels = { +  "#blabouncer keyword" +  "#test" +}  # Auto replay mode upon a bouncer client connecting  # "none" = Don't auto replay @@ -344,9 +344,12 @@ int createconfigfile(char *filename) {    "username = \"bounceusr\"\n"    "realname = \"Mr Bla Bouncer\"\n"    "\n" -  "# Channels to automatically join (comma-separated list, defaults to none)\n" -  "# Put channel keywords/passwords after channel names following a space.\n" -  "#channels = \"#blabouncer keyword,#test\"\n" +  "# Channels to automatically join (defaults to none)\n" +  "# Put channel keys/passwords after channel names (separated with a space)\n" +  "channels = {\n" +  "  \"#blabouncer keyword\"\n" +  "  \"#test\"\n" +  "}\n"    "\n"    "# Auto replay mode upon a bouncer client connecting\n"    "# \"none\" = Don't auto replay\n" diff --git a/functions.c b/functions.c index 5dd7586..6ed1d2f 100644 --- a/functions.c +++ b/functions.c @@ -1027,47 +1027,31 @@ int numclients(struct client *clients) {  // joined in the configuration file.  // Returns 1 on success or 0 on failure.  int joinautochannels(SSL *server_ssl, struct client *clients, struct settings *settings) { -  if (strlen(settings->autochannels) == 0) { +  if (settings->autochannels[0][0] == '\0') {      // None configured      debugprint(DEBUG_FULL, "joinautochannels(): none configured.\n");      return 1;    } -  // Split string up into each channel -  char tokens[MAXAUTOCHANLEN][MAXCHANLENGTH]; -  int counter = 0; - -  // Copy to a temporary string -  char *strcopy = strdup(settings->autochannels); -  // Keep track of initial pointer for free()ing later -  char *strcopyPtr = strcopy; - -  char *token; - -  // Split on commas -  while ((token = strsep(&strcopy, ",")) != NULL) { -    if (*token  == '\0') continue; // Skip consecutive matches -    if (counter >= MAXAUTOCHANLEN) break; // Too many tokens -    debugprint(DEBUG_FULL, "  >> Auto channel: '%s', length '%ld'.\n", token, strlen(token)); -    // Copy into the token array (strlen + 1 to get the NULL terminator) -    strncpy(tokens[counter], token, strlen(token) + 1); -    if (strlen(tokens[counter]) > MAXCHANLENGTH) { -      printf("error: channel name '%s' from configuration file too long, max length is '%d'.\n", tokens[counter], MAXCHANLENGTH); -      debugprint(DEBUG_CRIT, "error: channel name '%s' from configuration file too long, max length is '%d'.\n", tokens[counter], MAXCHANLENGTH); -      exit(1); +  // Join all the channels +  for (int i = 0; i < MAXCONFARR; i++) { +    // Unless there are none left in the array +    if (settings->autochannels[i][0] == '\0') { +      debugprint(DEBUG_FULL, "joinautochannels(): Finishing joining %d channels.\n", i); +      return 1;      } -    counter++; -  } -  // Join all the channels -  for (int i = 0; i < counter; i++) { -    debugprint(DEBUG_FULL, "joinautochannels(): Joining '%s'.\n", tokens[i]); +    debugprint(DEBUG_FULL, "joinautochannels(): Joining '%s'.\n", settings->autochannels[i]);      char joinmsg[MAXDATASIZE]; -    snprintf(joinmsg, MAXDATASIZE, "JOIN %s", tokens[i]); -    sendtoserver(server_ssl, joinmsg, strlen(joinmsg), 0, clients, settings); +    if (!snprintf(joinmsg, MAXDATASIZE, "JOIN %s", settings->autochannels[i])) { +      fprintf(stderr, "joinautochannels(): Error while preparing JOIN message!\n"); +      debugprint(DEBUG_CRIT, "joinautochannels(): Error while preparing JOIN message\n"); +      joinmsg[0] = '\0'; +    } else { +      sendtoserver(server_ssl, joinmsg, strlen(joinmsg), 0, clients, settings); +    }    } -  free(strcopyPtr);    // TODO - Can we fail here?  Return 0 if so and make callers handle this if so.    return 1;  } diff --git a/structures.h b/structures.h index 26b7439..9e5f575 100644 --- a/structures.h +++ b/structures.h @@ -22,11 +22,11 @@  #define MAXDATASIZE 513 // max number of bytes we can get at once (RFC2812 says 512, plus one for null terminator)  #define MAXCHANLENGTH 50 // 50 according to RFC 2811 and RFC 2822 +#define MAXCHANKEYLEN 24 // Maxium channel key length, 23 determined by testing various clients/servers (plus one for null terminator)  #define MAXNICKLENGTH 64 // Randomly picked (TODO - is there an actual maximum number (ignoring the RFC preference of 9)?)  #define MAXUSERNAMELEN 64 // Randomly picked (TODO - is there an actual maximum username length?)  #define MAXREALNAMELEN 128 // Randomly picked (TODO - is there an actual maximum real name length?)  #define MAXPORTLEN 6 // Up to 65535, so 5 characters + 1 for null -#define MAXAUTOCHANLEN 1024 // Randomly picked maximum length of the auto channel list  #define CLIENTCODELEN 17 // Max length of a client code + 1 for null  #define MAXCLIENTCODES 64 // Max number of client codes to track  #define MAXCONFARR 10 // Max number of entries that a configuration array can have @@ -67,7 +67,7 @@ struct settings {    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 autochannels[MAXCONFARR][MAXDATASIZE]; // MAXDATASIZE instead of MAXCHANLENGTH + 1 + MAXCHANKEYLEN so getconfarr() only has one string size to deal with    char ircserver[HOST_NAME_MAX];    char ircserverport[MAXPORTLEN];    char ircserverpassword[MAXDATASIZE - 5]; // -5 for "PASS "  | 
