1 /* Copyright (C) 2009-2014, Martin Johansson <martin@fatbob.nu> 2 Copyright (C) 2005-2014, Thorvald Natvig <thorvald@natvig.com> 3 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions 8 are met: 9 10 - Redistributions of source code must retain the above copyright notice, 11 this list of conditions and the following disclaimer. 12 - Redistributions in binary form must reproduce the above copyright notice, 13 this list of conditions and the following disclaimer in the documentation 14 and/or other materials provided with the distribution. 15 - Neither the name of the Developers nor the names of its contributors may 16 be used to endorse or promote products derived from this software without 17 specific prior written permission. 18 19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 35 #include <libconfig.h> 36 37 #include "types.h" 38 #include "conf.h" 39 #include "log.h" 40 41 static config_t configuration; 42 43 #define DEFAULT_WELCOME "Welcome to uMurmur!" 44 #define DEFAULT_MAX_CLIENTS 10 45 #define DEFAULT_MAX_BANDWIDTH 48000 46 #define DEFAULT_BINDPORT 64738 47 #define DEFAULT_BAN_LENGTH (60*60) 48 #define DEFAULT_OPUS_THRESHOLD 100 49 50 const char defaultconfig[] = DEFAULT_CONFIG; 51 52 void Conf_init(const char *conffile) 53 { 54 config_init(&configuration); 55 if (conffile == NULL) 56 conffile = defaultconfig; 57 if (config_read_file(&configuration, conffile) != CONFIG_TRUE) { 58 Log_fatal("Error in config file %s line %d: %s", conffile, 59 config_error_line(&configuration), config_error_text(&configuration)); 60 } 61 } 62 63 bool_t Conf_ok(const char *conffile) 64 { 65 bool_t rc = true; 66 config_init(&configuration); 67 if (conffile == NULL) 68 conffile = defaultconfig; 69 if (config_read_file(&configuration, conffile) != CONFIG_TRUE) { 70 fprintf(stderr, "Error in config file %s line %d: %s\n", conffile, 71 config_error_line(&configuration), config_error_text(&configuration)); 72 rc = false; 73 } 74 config_destroy(&configuration); 75 return rc; 76 } 77 78 void Conf_deinit() 79 { 80 config_destroy(&configuration); 81 } 82 83 const char *getStrConf(param_t param) 84 { 85 config_setting_t *setting = NULL; 86 const char *strsetting = NULL; 87 88 switch (param) { 89 case CERTIFICATE: 90 setting = config_lookup(&configuration, "certificate"); 91 if (!setting) 92 return "/usr/local/etc/umurmur/certificate.crt"; 93 else { 94 if ((strsetting = config_setting_get_string(setting)) != NULL) 95 return strsetting; 96 else 97 return "/usr/local/etc/umurmur/certificate.crt"; 98 } 99 break; 100 case KEY: 101 setting = config_lookup(&configuration, "private_key"); 102 if (!setting) 103 return "/usr/local/etc/umurmur/private_key.key"; 104 else { 105 if ((strsetting = config_setting_get_string(setting)) != NULL) 106 return strsetting; 107 else 108 return "/usr/local/etc/umurmur/private_key.key"; 109 } 110 break; 111 case CAPATH: 112 setting = config_lookup(&configuration, "ca_path"); 113 if (!setting) 114 return NULL; 115 else { 116 if ((strsetting = config_setting_get_string(setting)) != NULL) 117 return strsetting; 118 else 119 return NULL; 120 } 121 break; 122 case PASSPHRASE: 123 setting = config_lookup(&configuration, "password"); 124 if (!setting) 125 return ""; 126 else { 127 if ((strsetting = config_setting_get_string(setting)) != NULL) 128 return strsetting; 129 else 130 return ""; 131 } 132 break; 133 case ADMIN_PASSPHRASE: 134 setting = config_lookup(&configuration, "admin_password"); 135 if (!setting) 136 return ""; 137 else { 138 if ((strsetting = config_setting_get_string(setting)) != NULL) 139 return strsetting; 140 else 141 return ""; 142 } 143 break; 144 case BINDADDR: 145 setting = config_lookup(&configuration, "bindaddr"); 146 if (!setting) 147 return NULL; 148 else { 149 if ((strsetting = config_setting_get_string(setting)) != NULL) 150 return strsetting; 151 else 152 return NULL; 153 } 154 break; 155 case BINDADDR6: 156 setting = config_lookup(&configuration, "bindaddr6"); 157 if (!setting) 158 return NULL; 159 else { 160 if ((strsetting = config_setting_get_string(setting)) != NULL) 161 return strsetting; 162 else 163 return NULL; 164 } 165 break; 166 case WELCOMETEXT: 167 setting = config_lookup(&configuration, "welcometext"); 168 if (!setting) 169 return DEFAULT_WELCOME; 170 else { 171 if ((strsetting = config_setting_get_string(setting)) != NULL) 172 return strsetting; 173 else 174 return DEFAULT_WELCOME; 175 } 176 break; 177 case DEFAULT_CHANNEL: 178 setting = config_lookup(&configuration, "default_channel"); 179 if (!setting) 180 return ""; 181 else { 182 if ((strsetting = config_setting_get_string(setting)) != NULL) 183 return strsetting; 184 else 185 return ""; 186 } 187 break; 188 case USERNAME: 189 setting = config_lookup(&configuration, "username"); 190 if (!setting) 191 return ""; 192 else { 193 if ((strsetting = config_setting_get_string(setting)) != NULL) 194 return strsetting; 195 else 196 return ""; 197 } 198 break; 199 case GROUPNAME: 200 setting = config_lookup(&configuration, "groupname"); 201 if (!setting) 202 return ""; 203 else { 204 if ((strsetting = config_setting_get_string(setting)) != NULL) 205 return strsetting; 206 else 207 return ""; 208 } 209 break; 210 case LOGFILE: 211 setting = config_lookup(&configuration, "logfile"); 212 if (!setting) 213 return NULL; 214 else { 215 if ((strsetting = config_setting_get_string(setting)) != NULL) 216 return strsetting; 217 else 218 return NULL; 219 } 220 break; 221 case BANFILE: 222 setting = config_lookup(&configuration, "banfile"); 223 if (!setting) 224 return NULL; 225 else { 226 if ((strsetting = config_setting_get_string(setting)) != NULL) 227 return strsetting; 228 else 229 return NULL; 230 } 231 break; 232 default: 233 doAssert(false); 234 break; 235 } 236 return NULL; 237 } 238 239 int getIntConf(param_t param) 240 { 241 config_setting_t *setting = NULL; 242 243 switch (param) { 244 case BINDPORT: 245 setting = config_lookup(&configuration, "bindport"); 246 if (!setting) 247 return DEFAULT_BINDPORT; 248 else { 249 return config_setting_get_int(setting); 250 } 251 break; 252 case BINDPORT6: 253 setting = config_lookup(&configuration, "bindport6"); 254 if (!setting) 255 /* If bindport6 is not specified, we default 256 * to whatever bindport is, rather than always 257 * default to 64738 */ 258 return getIntConf(BINDPORT); 259 else { 260 return config_setting_get_int(setting); 261 } 262 break; 263 case BAN_LENGTH: 264 setting = config_lookup(&configuration, "ban_length"); 265 if (!setting) 266 return DEFAULT_BAN_LENGTH; 267 else { 268 return config_setting_get_int(setting); 269 } 270 break; 271 case MAX_BANDWIDTH: 272 setting = config_lookup(&configuration, "max_bandwidth"); 273 if (!setting) 274 return DEFAULT_MAX_BANDWIDTH; 275 else { 276 return config_setting_get_int(setting); 277 } 278 break; 279 case MAX_CLIENTS: 280 setting = config_lookup(&configuration, "max_users"); 281 if (!setting) 282 return DEFAULT_MAX_CLIENTS; 283 else { 284 return config_setting_get_int(setting); 285 } 286 break; 287 case OPUS_THRESHOLD: 288 setting = config_lookup(&configuration, "opus_threshold"); 289 if (!setting) 290 return DEFAULT_OPUS_THRESHOLD; 291 else { 292 return config_setting_get_int(setting); 293 } 294 break; 295 default: 296 doAssert(false); 297 } 298 } 299 300 bool_t getBoolConf(param_t param) 301 { 302 config_setting_t *setting = NULL; 303 304 switch (param) { 305 case ALLOW_TEXTMESSAGE: 306 setting = config_lookup(&configuration, "allow_textmessage"); 307 if (!setting) 308 return true; 309 else 310 return config_setting_get_bool(setting); 311 break; 312 case ENABLE_BAN: 313 setting = config_lookup(&configuration, "enable_ban"); 314 if (!setting) 315 return false; 316 else 317 return config_setting_get_bool(setting); 318 break; 319 case SYNC_BANFILE: 320 setting = config_lookup(&configuration, "sync_banfile"); 321 if (!setting) 322 return false; 323 else 324 return config_setting_get_bool(setting); 325 break; 326 case SHOW_ADDRESSES: 327 setting = config_lookup(&configuration, "show_addresses"); 328 if (!setting) 329 return true; 330 else 331 return config_setting_get_bool(setting); 332 break; 333 default: 334 doAssert(false); 335 } 336 } 337 338 int Conf_getNextChannel(conf_channel_t *chdesc, int index) 339 { 340 config_setting_t *setting = NULL; 341 int maxconfig = 64, ret = 0; 342 char configstr[maxconfig]; 343 344 ret = snprintf(configstr, maxconfig, "channels.[%d].name", index); 345 setting = config_lookup(&configuration, configstr); 346 if (ret >= maxconfig || ret < 0 || setting == NULL) 347 return -1; /* Required */ 348 chdesc->name = config_setting_get_string(setting); 349 350 ret = snprintf(configstr, maxconfig, "channels.[%d].parent", index); 351 setting = config_lookup(&configuration, configstr); 352 if (ret >= maxconfig || ret < 0 || setting == NULL) 353 return -1; /* Required */ 354 chdesc->parent = config_setting_get_string(setting); 355 356 ret = snprintf(configstr, maxconfig, "channels.[%d].description", index); 357 setting = config_lookup(&configuration, configstr); 358 if (ret >= maxconfig || ret < 0 || setting == NULL) /* Optional */ 359 chdesc->description = NULL; 360 else 361 chdesc->description = config_setting_get_string(setting); 362 363 ret = snprintf(configstr, maxconfig, "channels.[%d].password", index); 364 setting = config_lookup(&configuration, configstr); 365 if (ret >= maxconfig || ret < 0 || setting == NULL) /* Optional */ 366 chdesc->password = NULL; 367 else 368 chdesc->password = config_setting_get_string(setting); 369 370 ret = snprintf(configstr, maxconfig, "channels.[%d].noenter", index); 371 setting = config_lookup(&configuration, configstr); 372 if (ret >= maxconfig || ret < 0 || setting == NULL) /* Optional */ 373 chdesc->noenter = false; 374 else 375 chdesc->noenter = config_setting_get_bool(setting); 376 377 ret = snprintf(configstr, maxconfig, "channels.[%d].silent", index); 378 setting = config_lookup(&configuration, configstr); 379 if (ret >= maxconfig || ret < 0 || setting == NULL) /* Optional */ 380 chdesc->silent = false; 381 else 382 chdesc->silent = config_setting_get_bool(setting); 383 384 ret = snprintf(configstr, maxconfig, "channels.[%d].position", index); 385 setting = config_lookup(&configuration, configstr); 386 if (ret >= maxconfig || ret < 0 || setting == NULL) /* Optional */ 387 chdesc->position = 0; 388 else 389 chdesc->position = config_setting_get_int(setting); 390 391 return 0; 392 } 393 394 int Conf_getNextChannelLink(conf_channel_link_t *chlink, int index) 395 { 396 config_setting_t *setting = NULL; 397 int maxconfig = 64, ret = 0; 398 char configstr[maxconfig]; 399 400 ret = snprintf(configstr, maxconfig, "channel_links.[%d].source", index); 401 setting = config_lookup(&configuration, configstr); 402 if (ret >= maxconfig || ret < 0 || setting == NULL) 403 return -1; 404 chlink->source = config_setting_get_string(setting); 405 406 ret = snprintf(configstr, maxconfig, "channel_links.[%d].destination", index); 407 setting = config_lookup(&configuration, configstr); 408 if (ret >= maxconfig || ret < 0 || setting == NULL) 409 return -1; 410 chlink->destination = config_setting_get_string(setting); 411 412 return 0; 413 } 414