Skip to content

Commit 376193d

Browse files
committed
app_keyprefetch: Add key to inkeys if loaded but not in config.
Back port a workaround present in res_phreaknet to app_keyprefetch to handle an edge case where the inkey is already loaded by res_crypto, but is not present in the iax.conf section's inkeys setting, for whatever reason. Otherwise, we would load the public key and it would never get used for matching on incoming calls (short of some manual effort to resync by purging keys).
1 parent 4ba099d commit 376193d

1 file changed

Lines changed: 40 additions & 7 deletions

File tree

apps/app_keyprefetch.c

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ static int fetch_exec(struct ast_channel *chan, const char *data)
141141
int reload = 1, newkey = 1, needreload = 0;
142142
struct ast_key *inkey;
143143
char *filepath;
144+
struct ast_config *cfg = NULL;
144145

145146
AST_DECLARE_APP_ARGS(args,
146147
AST_APP_ARG(cat);
@@ -306,8 +307,38 @@ static int fetch_exec(struct ast_channel *chan, const char *data)
306307
}
307308
ast_free(tmp_filename);
308309
}
310+
if (!newkey) {
311+
/* Check if the key is loaded but isn't present in the inkeys in iax.conf.
312+
* If this happens for some reason, we still need to add it. */
313+
struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
314+
char *sfn = "iax.conf";
315+
if ((cfg = ast_config_load2(sfn, "app_keyprefetch", config_flags))) {
316+
const char *currentinkeys = ast_variable_retrieve(cfg, args.cat, "inkeys");
317+
if (currentinkeys) {
318+
char search_str[256];
319+
size_t curlen = strlen(currentinkeys);
320+
/* Surround existing key list with : before/after to ensure we can match even if it's the first or last key name,
321+
* and to avoid false positive on a key name with a partial name match. */
322+
char *haystack = ast_alloca(curlen + 3); /* 2 colons and NUL */
323+
*haystack = ':'; /* Before */
324+
strcpy(haystack + 1, currentinkeys); /* Safe */
325+
haystack[curlen + 1] = ':'; /* After */
326+
haystack[curlen + 2] = '\0';
327+
snprintf(search_str, sizeof(search_str), ":%s:", args.keyname);
328+
if (!strstr(haystack, search_str)) {
329+
ast_debug(1, "Key '%s' is loaded but not an inkey of %s currently (%s), need to add it\n", args.keyname, args.cat, haystack);
330+
newkey = 1;
331+
}
332+
}
333+
}
334+
if (!newkey) {
335+
/* If we don't need the config anymore, we can destroy it now.
336+
* If we set newkey true above, then we keep using it below without reopening. */
337+
ast_config_destroy(cfg);
338+
cfg = NULL;
339+
}
340+
}
309341
if (newkey) { /* add the new key we just got to the list of inkeys allowed */
310-
struct ast_config *cfg;
311342
struct ast_category *category = NULL;
312343
struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
313344
char *sfn = "iax.conf", *dfn = "iax.conf";
@@ -317,12 +348,14 @@ static int fetch_exec(struct ast_channel *chan, const char *data)
317348
ast_debug(1, "Got a new key, '%s', adding to inkeys\n", args.keyname);
318349
pbx_builtin_setvar_helper(chan, "KEYPREFETCHSTATUS", "NEW");
319350

320-
if (!(cfg = ast_config_load2(sfn, "app_keyprefetch", config_flags))) {
321-
ast_log(LOG_WARNING, "Config file not found: %s\n", sfn);
322-
goto done;
323-
} else if (cfg == CONFIG_STATUS_FILEINVALID) {
324-
ast_log(LOG_WARNING, "Config file has invalid format: %s\n", sfn);
325-
goto cfgcleanup;
351+
if (!cfg) { /* Open config, if not already open from the !newkey branch above */
352+
if (!(cfg = ast_config_load2(sfn, "app_keyprefetch", config_flags))) {
353+
ast_log(LOG_WARNING, "Config file not found: %s\n", sfn);
354+
goto done;
355+
} else if (cfg == CONFIG_STATUS_FILEINVALID) {
356+
ast_log(LOG_WARNING, "Config file has invalid format: %s\n", sfn);
357+
goto cfgcleanup;
358+
}
326359
}
327360

328361
while ((category = ast_category_browse_filtered(cfg, cat, category, NULL))) {

0 commit comments

Comments
 (0)