From 094ffe37ccbead1e98a69da0306ae8d2e7f3978f Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Fri, 15 Oct 2010 23:27:24 -0400 Subject: [PATCH] mod_erlang_event: Support for reading erlang cookie from a file mod_erlang_event will now try to read $HOME/.erlang.cookie if no cookie is specified in the config file. You can specify an arbitary cookie file via the 'cookie-file' parameter in the config file. The cookie file MUST be readable by the user freeswitch is running as (either the owner or root) and the file MUST NOT be readable/writeable/executable by any other user (eg 0400 permissions). Thanks to James Aimonetti for the idea and the original patch. --- .../mod_erlang_event/mod_erlang_event.c | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c index 848a2c58ea..f2a20f34c9 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c @@ -1015,6 +1015,53 @@ static void launch_listener_thread(listener_t *listener) } +static int read_cookie_from_file(char *filename) { + int fd; + char cookie[MAXATOMLEN+1]; + char *end; + struct stat buf; + ssize_t res; + + if (!stat(filename, &buf)) { + if ((buf.st_mode & S_IRWXG) || (buf.st_mode & S_IRWXO)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s must only be accessible by owner only.\n", filename); + return 2; + } + if (buf.st_size > MAXATOMLEN) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s contains a cookie larger than the maximum atom size of %d.\n", filename, MAXATOMLEN); + return 2; + } + fd = open(filename, O_RDONLY); + if (fd < 1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to open cookie file %s : %d.\n", filename, errno); + return 2; + } + + if ((res = read(fd, cookie, MAXATOMLEN)) < 1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to read cookie file %s : %d.\n", filename, errno); + } + + cookie[MAXATOMLEN+1] = '\0'; + + /* replace any end of line characters with a null */ + if ((end = strchr(cookie, '\n'))) { + *end = '\0'; + } + + if ((end = strchr(cookie, '\r'))) { + *end = '\0'; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Read %d bytes from cookie file %s.\n", (int)res, filename); + + set_pref_cookie(cookie); + return 0; + } else { + /* don't error here, because we might be blindly trying to read $HOME/.erlang.cookie, and that can fail silently */ + return 1; + } +} + static int config(void) { @@ -1041,6 +1088,10 @@ static int config(void) prefs.port = (uint16_t) atoi(val); } else if (!strcmp(var, "cookie")) { set_pref_cookie(val); + } else if (!strcmp(var, "cookie-file")) { + if (read_cookie_from_file(val) == 1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to read cookie from %s\n", val); + } } else if (!strcmp(var, "nodename")) { set_pref_nodename(val); } else if (!strcmp(var, "compat-rel")) { @@ -1075,7 +1126,21 @@ static int config(void) } if (zstr(prefs.cookie)) { - set_pref_cookie("ClueCon"); + int res; + char* home_dir = getenv("HOME"); + char path_buf[1024]; + + if (!zstr(home_dir)) { + /* $HOME/.erlang.cookie */ + switch_snprintf(path_buf, sizeof(path_buf), "%s%s%s", home_dir, SWITCH_PATH_SEPARATOR, ".erlang.cookie"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Checking for cookie at path: %s\n", path_buf); + + res = read_cookie_from_file(path_buf); + if (res) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No cookie or valid cookie file specified, using default cookie\n"); + set_pref_cookie("ClueCon"); + } + } } if (!prefs.port) {