From 30d6f9b62d680344d80cd56f20f72d640c4c3b3b Mon Sep 17 00:00:00 2001 From: Ionut Ionita Date: Fri, 10 Oct 2014 14:24:36 +0300 Subject: [PATCH 1/4] added exec(cmd,output,input,avpenv) function for exec module --- modules/exec/README | 51 +++++++- modules/exec/doc/exec_admin.xml | 66 +++++++++- modules/exec/exec.c | 151 +++++++++++++++++++++- modules/exec/exec.h | 4 +- modules/exec/exec.so | Bin 0 -> 266772 bytes modules/exec/exec_hf.c | 4 +- modules/exec/exec_hf.h | 3 + modules/exec/exec_mod.c | 213 +++++++++++++++++++++++++++++++- modules/exec/kill.c | 45 +++++++ modules/exec/kill.h | 1 + 10 files changed, 525 insertions(+), 13 deletions(-) create mode 100755 modules/exec/exec.so diff --git a/modules/exec/README b/modules/exec/README index 48f73ae22d9..22924defe23 100644 --- a/modules/exec/README +++ b/modules/exec/README @@ -35,6 +35,7 @@ Jan Janak 1.4.2. exec_msg(command) 1.4.3. exec_avp(command[, avplist]) 1.4.4. exec_getenv(environment_variable[, avp]) + 1.4.5. exec(command, [output], [input], [envavp]) 1.5. Known Issues @@ -47,6 +48,7 @@ Jan Janak 1.5. exec_msg usage 1.6. exec_avp usage 1.7. exec_getenv usage + 1.8. exec usage Chapter 1. Admin Guide @@ -120,9 +122,10 @@ modparam("exec", "time_to_kill", 20) 1.3.3. async (integer) - Turns on the asynchronous mode for the 'exec_msg' function. All - commands will be executed by a different process and the caller - will continue its flow, without waiting for a response. + Turns on the asynchronous mode for the 'exec_msg' and 'exec' + functions. All commands will be executed by a different process + and the caller will continue its flow, without waiting for a + response. Default value is 0 (disabled). @@ -243,6 +246,48 @@ exec_getenv("HOSTNAME"); exec_getenv("HOSTNAME", "$avp(localhost)"); ... +1.4.5. exec(command, [output], [input], [envavp]) + + Executes an external command. The input is passed to the + standard input of the new process, if specified, and the output + is saved in the output variable. + + Meaning of the parameters is as follows: + * command - command to be executed.It can include + pseudovariables. + * output - pseudovariable where to store the output from the + standard output of the command. Keep in mind that if this + parameter is set, the async paramater will not be taken in + consideration. + * input - String to be passed to the standard input of the + command. The string can be given as a pseudovariable. + * envavp - Avp where to store the values for the environment + variables to be passed for the command. The names of the + environment variables will be "OSIPS_EXEC_#" where # will + start from 0. For example if you store 2 values into an avp + ("a" and "b") OSIPS_EXEC_0 will contain the first value and + OSIPS_EXEC_1 the second value. + + WARNING: any OpenSIPS pseudo-vars which may contain special + bash characters should be placed inside quotes, e.g. + exec_getenv("'$ct'"); + + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, + LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE, + ONREPLY_ROUTE. + + Example 1.8. exec usage +... +$avp(env) = "a"; +$avp(env) = "b"; +exec("ls -l", "$var(out)",, "$avp(env)"); +xlog("The output is $var(out)\n"); +... +$var(input) = "input"; +exec("/home/../myscript.sh",, "this is my $var(input) for exec\n", "$avp +(env)"); +... + 1.5. Known Issues When imposing an execution timeout using time_to_kill, make diff --git a/modules/exec/doc/exec_admin.xml b/modules/exec/doc/exec_admin.xml index f35287e1a5a..f1dad5136cd 100644 --- a/modules/exec/doc/exec_admin.xml +++ b/modules/exec/doc/exec_admin.xml @@ -148,9 +148,9 @@ modparam("exec", "time_to_kill", 20)
<varname>async</varname> (integer) - Turns on the asynchronous mode for the 'exec_msg' function. All commands - will be executed by a different process and the caller will continue - its flow, without waiting for a response. + Turns on the asynchronous mode for the 'exec_msg' and 'exec' functions. + All commands will be executed by a different process and the caller will + continue its flow, without waiting for a response. @@ -332,6 +332,66 @@ exec_getenv("HOSTNAME", "$avp(localhost)");
+
+ + <function moreinfo="none">exec(command, [output], [input], [envavp])</function> + + + Executes an external command. The input is passed to the standard input of the new + process, if specified, and the output is saved in the output variable. + + Meaning of the parameters is as follows: + + + command - command to be executed.It can include + pseudovariables. + + + + output - pseudovariable where to store the output + from the standard output of the command. Keep in mind that if this parameter + is set, the async paramater will not be taken in consideration. + + + + input - String to be passed to the standard input + of the command. The string can be given as a pseudovariable. + + + + envavp - Avp where to store the values for the + environment variables to be passed for the command. The names of the environment + variables will be "OSIPS_EXEC_#" where # will start from 0. For example if you + store 2 values into an avp ("a" and "b") OSIPS_EXEC_0 will contain the first value + and OSIPS_EXEC_1 the second value. + + + + + WARNING: any OpenSIPS pseudo-vars which may contain special bash + characters should be placed inside quotes, e.g. exec_getenv("'$ct'"); + + + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, + LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE, ONREPLY_ROUTE. + + + <function moreinfo="none">exec</function> usage + +... +$avp(env) = "a"; +$avp(env) = "b"; +exec("ls -l", "$var(out)",, "$avp(env)"); +xlog("The output is $var(out)\n"); +... +$var(input) = "input"; +exec("/home/../myscript.sh",, "this is my $var(input) for exec\n", "$avp(env)"); +... + + +
+ + diff --git a/modules/exec/exec.c b/modules/exec/exec.c index abb6d4f6fe8..063b48e94e7 100644 --- a/modules/exec/exec.c +++ b/modules/exec/exec.c @@ -49,6 +49,7 @@ #include "../../usr_avp.h" #include "../../ut.h" #include "../../trim.h" +#include "../../mod_fix.h" #include "exec.h" #include "kill.h" @@ -106,10 +107,33 @@ int exec_msg(struct sip_msg *msg, char *cmd ) return ret; } +int exec_write_input(FILE** stream, str* input) +{ + if (fwrite(input->s, 1, input->len, *stream) != input->len) { + LM_ERR("failed to write to pipe\n"); + ser_error=E_EXEC; + return -1; + } + + if (ferror(*stream)) { + LM_ERR("writing pipe: %s\n", strerror(errno)); + ser_error=E_EXEC; + return -1; + } + + pclose(*stream); + + return 0; +} + void exec_async_proc(int rank) { - int pid, status; + #define READ 0 + #define WRITE 1 + + int pid, status, fds[2]; exec_cmd_t *cmd, *prev; + FILE* stream; LM_DBG("started asyncronous process with rank %d\n", rank); @@ -120,14 +144,32 @@ void exec_async_proc(int rank) for (cmd = exec_async_list->first; cmd && cmd->pid; cmd = cmd->next); lock_release(exec_async_list->lock); + if (cmd && cmd->input.len && cmd->input.s) { + if (pipe(fds) != 0) { + LM_ERR("failed to create pipe (%d: %s)\n", + errno, strerror(errno)); + } + } + if (cmd) { if ((pid = fork()) < 0) { LM_ERR("failed to fork\n"); } else if (pid) { exec_async_list->active_childs++; cmd->pid = pid; + + if (cmd->input.s && cmd->input.len) { + close(fds[READ]); + stream = fdopen(fds[WRITE], "w"); + exec_write_input(&stream, &cmd->input); + } + schedule_to_kill(pid); } else { + close(fds[WRITE]); + dup2(fds[READ], 0); + close(fds[READ]); + LM_DBG("running command %s (%d)\n", cmd->cmd, getpid()); execl("/bin/sh", "/bin/sh", "-c", cmd->cmd, NULL); @@ -175,14 +217,23 @@ void exec_async_proc(int rank) if (!exec_async_list->first && !exec_async_list->active_childs) usleep(SLEEP_INTERVAL); } + + #undef READ + #undef WRITE + } -int exec_async(struct sip_msg *msg, char *cmd ) +int exec_async(struct sip_msg *msg, char *cmd, str* input) { exec_cmd_t *elem; /* alloc memory for command */ - elem = shm_malloc(sizeof(exec_cmd_t) + strlen(cmd) + 1); + if (input == NULL) + elem = shm_malloc(sizeof(exec_cmd_t) + strlen(cmd) + 1); + else + elem = shm_malloc(sizeof(exec_cmd_t) + strlen(cmd) + 1 + + input->len); + if (!elem) { LM_ERR("no more shm memory\n"); goto error; @@ -191,6 +242,12 @@ int exec_async(struct sip_msg *msg, char *cmd ) elem->cmd = (char *)(elem + 1); memcpy(elem->cmd, cmd, strlen(cmd) + 1); + if (input) { + elem->input.s = (char*)elem->cmd + strlen(cmd) + 1; + memcpy(elem->input.s, input->s, input->len); + elem->input.len = input->len; + } + /* add command in list at the end */ lock_get(exec_async_list->lock); if (exec_async_list->last) { @@ -472,3 +529,91 @@ int exec_getenv(struct sip_msg *msg, char *cmd, pvname_list_p avpl) error: return ret; } + + +int exec_sync(struct sip_msg* msg, str* command, str* input, gparam_p outvar) +{ + #define MAX_LINE_SIZE 1024 + #define MAX_BUF_SIZE 128 * MAX_LINE_SIZE + + pid_t pid; + int exit_status, ret; + FILE *pin, *pout; + char buf[MAX_BUF_SIZE], tmpbuf[MAX_LINE_SIZE]; + int buflen=0, tmplen; + pv_value_t outval; + + if (input && outvar) { + pid = __rw_popen(command->s, &pin, &pout); + } else if (input) { + pid = __popen(command->s, "w", &pin); + } else if (outvar) { + pid = __popen(command->s, "r", &pout); + } else { + pid = fork(); + if (pid == 0) { + execl("/bin/sh", "/bin/sh", "-c", command->s, NULL); + exit(-1); + } + } + + if (input->len) { + if (fwrite(input->s, 1, input->len, pin) != input->len) { + LM_ERR("failed to write to pipe\n"); + ser_error=E_EXEC; + goto error; + } + + if (ferror(pin)) { + LM_ERR("writing pipe: %s\n", strerror(errno)); + ser_error=E_EXEC; + goto error; + } + pclose(pin); + } + + schedule_to_kill(pid); + wait(&exit_status); + + if (outvar) { + while (fgets(tmpbuf, MAX_LINE_SIZE, pout)) { + tmplen = strlen(tmpbuf); + memcpy(buf+buflen, tmpbuf, tmplen); + buflen += tmplen; + } + + outval.flags = PV_VAL_STR; + outval.rs.s = buf; + outval.rs.len = buflen; + + if (buflen && + pv_set_value(msg, &outvar->v.pve->spec, 0, &outval) < 0) { + LM_ERR("cannot set output pv value\n"); + return -1; + } + } + + ret=1; + +error: + if (outvar && ferror(pout)) { + LM_ERR("reading pipe: %s\n", strerror(errno)); + ser_error=E_EXEC; + ret=-1; + } + + if (outvar) + pclose(pout); + + if (WIFEXITED(exit_status)) { + if (WEXITSTATUS(exit_status)!=0) ret=-1; + } else { + LM_ERR("cmd %s failed. exit_status=%d, errno=%d: %s\n", + command->s, exit_status, errno, strerror(errno)); + ret=-1; + } + + return ret; + #undef MAX_LINE_SIZE + #undef MAX_BUF_SIZE +} diff --git a/modules/exec/exec.h b/modules/exec/exec.h index 72ad6e66f36..6e130540c3c 100644 --- a/modules/exec/exec.h +++ b/modules/exec/exec.h @@ -30,6 +30,7 @@ typedef struct _exec_cmd { char *cmd; + str input; int pid; struct _exec_cmd *next; } exec_cmd_t; @@ -45,12 +46,13 @@ extern exec_list_p exec_async_list; /* process that waits for asyncronous executions */ void exec_async_proc(int rank); -int exec_async(struct sip_msg *msg, char *cmd ); +int exec_async(struct sip_msg *msg, char *cmd, str* input ); int exec_str(struct sip_msg *msg, char *cmd, char *param, int param_len); int exec_msg(struct sip_msg *msg, char *cmd ); int exec_avp(struct sip_msg *msg, char *cmd, pvname_list_p avpl); int exec_getenv(struct sip_msg *msg, char *cmd, pvname_list_p avpl); +int exec_sync(struct sip_msg* msg, str* command, str* input, gparam_p outvar); #endif diff --git a/modules/exec/exec.so b/modules/exec/exec.so new file mode 100755 index 0000000000000000000000000000000000000000..58e5aab9ea1441ae00f6d87ec489f4a84863fc99 GIT binary patch literal 266772 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 U*{$$}+(nLd37lnoWE=m`GyqQyqR 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 GivAC;V@nMH literal 0 HcmV?d00001 diff --git a/modules/exec/exec_hf.c b/modules/exec/exec_hf.c index aadaa87e7c6..fddd11df94d 100644 --- a/modules/exec/exec_hf.c +++ b/modules/exec/exec_hf.c @@ -92,7 +92,7 @@ static int insert_hf( struct hf_wrapper **list, struct hdr_field *hf ) return 1; } -static void release_hf_struct( struct hf_wrapper *list ) +void release_hf_struct( struct hf_wrapper *list ) { struct hf_wrapper *i, *j, *nexts, *nexto; @@ -287,7 +287,7 @@ static int print_var(struct hf_wrapper *w, int offset) } } -static void release_vars(struct hf_wrapper *list) +void release_vars(struct hf_wrapper *list) { while(list) { if (list->envvar) { diff --git a/modules/exec/exec_hf.h b/modules/exec/exec_hf.h index f68621bb32a..7c368dd5156 100644 --- a/modules/exec/exec_hf.h +++ b/modules/exec/exec_hf.h @@ -117,5 +117,8 @@ extern char **environ; environment_t *set_env(struct sip_msg *msg); void unset_env(environment_t *backup_env); +void release_hf_struct ( struct hf_wrapper *list); +void release_vars(struct hf_wrapper* list); +environment_t *replace_env(struct hf_wrapper *list); #endif diff --git a/modules/exec/exec_mod.c b/modules/exec/exec_mod.c index 523f0c8c7ee..22d36e516d3 100644 --- a/modules/exec/exec_mod.c +++ b/modules/exec/exec_mod.c @@ -29,6 +29,7 @@ #include +#include #include "../../sr_module.h" #include "../../parser/msg_parser.h" @@ -36,6 +37,8 @@ #include "../../dprint.h" #include "../../mod_fix.h" #include "../../parser/parse_uri.h" +#include "../../ut.h" +#include #include "exec.h" #include "kill.h" @@ -43,6 +46,7 @@ + unsigned int time_to_kill=0; unsigned int async=0; @@ -52,8 +56,10 @@ inline static int w_exec_dset(struct sip_msg* msg, char* cmd, char* foo); inline static int w_exec_msg(struct sip_msg* msg, char* cmd, char* foo); inline static int w_exec_avp(struct sip_msg* msg, char* cmd, char* avpl); inline static int w_exec_getenv(struct sip_msg* msg, char* cmd, char* avpl); +inline static int w_exec(struct sip_msg* msg, char* cmd, char* out, char* in, char* avp_env); static int exec_avp_fixup(void** param, int param_no); +static int exec_fixup(void** param, int param_no); inline static void exec_shutdown(void); @@ -71,6 +77,8 @@ static cmd_export_t cmds[] = { REQUEST_ROUTE|FAILURE_ROUTE|LOCAL_ROUTE|STARTUP_ROUTE|TIMER_ROUTE|EVENT_ROUTE|ONREPLY_ROUTE}, {"exec_getenv", (cmd_function)w_exec_getenv, 2, exec_avp_fixup, 0, REQUEST_ROUTE|FAILURE_ROUTE|LOCAL_ROUTE|STARTUP_ROUTE|TIMER_ROUTE|EVENT_ROUTE|ONREPLY_ROUTE}, + {"exec", (cmd_function)w_exec, 4, exec_fixup, 0, + REQUEST_ROUTE|FAILURE_ROUTE|LOCAL_ROUTE|STARTUP_ROUTE|TIMER_ROUTE|EVENT_ROUTE|ONREPLY_ROUTE}, {0, 0, 0, 0, 0, 0} }; @@ -115,12 +123,15 @@ struct module_exports exports= { void exec_shutdown(void) { + if (time_to_kill) destroy_kill(); + } static int mod_init( void ) { + LM_INFO("exec - initializing\n"); if (time_to_kill) initialize_kill(); @@ -220,7 +231,7 @@ inline static int w_exec_msg(struct sip_msg* msg, char* cmd, char* foo) LM_DBG("executing [%s]\n", command.s); if(async) - ret=exec_async(msg, command.s); + ret=exec_async(msg, command.s, NULL); else ret=exec_msg(msg, command.s); if (setvars) { @@ -315,4 +326,204 @@ static int exec_avp_fixup(void** param, int param_no) return 0; } +static int exec_fixup(void** param, int param_no) +{ + gparam_p out_var; + pv_elem_t* model; + str s; + + if (*param) + switch (param_no) { + case 1: /* cmd */ + return fixup_spve(param); + case 2: /* output var */ + if (fixup_spve(param)) { + LM_ERR("cannot fix output var\n"); + return -1; + } + + out_var = *param; + if (out_var->type != GPARAM_TYPE_PVE) { + LM_ERR("output var must be a single variable\n"); + return -1; + } + + if (out_var->v.pve->spec.setf == NULL) { + LM_ERR("output var must be writable\n"); + return -1; + } + + return 0; + case 3: /* input vars */ + s.s = *param; + s.len = strlen(s.s); + if (pv_parse_format(&s, &model)) { + LM_ERR("wrong format [%s] for param no %d!\n", + (char*)*param, param_no); + pkg_free(s.s); + return E_UNSPEC; + } + *param = (void *)model; + + return 0; + case 4: /* environment avp */ + if (fixup_spve(param)) { + LM_ERR("cannot fix output var\n"); + return -1; + } + out_var = *param; + if (out_var->type != GPARAM_TYPE_PVE) { + LM_ERR("env var must be a single variable\n"); + return -1; + } + + if (out_var->v.pve->spec.type != PVT_AVP) { + LM_ERR("env var must be avp typed\n"); + return -1; + } + + return 0; + default: + LM_ERR("Invalid parameter number %d\n", param_no); + return -1; + } + return 0; +} + +static inline int setenvvar(struct hf_wrapper** hf, int_str* value, int idx) +{ + #define OSIPS_EXEC "OSIPS_EXEC_" + + + int len=0; + str sidx; + + sidx.s = int2str((unsigned long)idx, &sidx.len); + + (*hf)->envvar=pkg_malloc(strlen(OSIPS_EXEC) + sidx.len + 1/*=*/ + + (*value).s.len + 1/*\0*/); + if ((*hf)->envvar==0) { + LM_ERR("no more pkg mem\n"); + return -1; + } + + memcpy((*hf)->envvar, OSIPS_EXEC, strlen(OSIPS_EXEC)); + len=strlen(OSIPS_EXEC); + + memcpy((*hf)->envvar+len, sidx.s, sidx.len); + len+=sidx.len; + + (*hf)->envvar[len++] = '='; + + memcpy((*hf)->envvar+len, (*value).s.s, (*value).s.len); + + (*hf)->envvar[len+(*value).s.len] = '\0'; + + (*hf)->next_other=(*hf)->next_same=NULL; + + return 0; + + #undef OSIPS_EXEC + +} + +static struct hf_wrapper* get_avp_values_list(struct sip_msg* msg, pv_param_p avp) +{ + + int avp_name, idx=0; + unsigned short name_type; + int_str value; + struct usr_avp* avp_ptr=0; + struct hf_wrapper *hf=0, *hf_head; + + if (pv_get_avp_name(msg, avp, &avp_name, &name_type) < 0) { + LM_ERR("cannot get avp name\n"); + return 0; + } + + if ((avp_ptr=search_first_avp( name_type, avp_name, &value, 0)) == 0) { + LM_ERR("cannot get first avp value\n"); + return 0; + } + + hf=pkg_malloc(sizeof(struct hf_wrapper)); + if (!hf) + goto memerr; + + setenvvar(&hf, &value, idx++); + hf_head=hf; + + while (search_next_avp( avp_ptr, &value) != 0) { + hf->next_other=pkg_malloc(sizeof(struct hf_wrapper)); + if (!hf) + goto memerr; + + hf=hf->next_other; + + setenvvar(&hf, &value, idx++); + + avp_ptr = avp_ptr->next; + if (avp_ptr->id > avp_name) + break; + } + + return hf_head; +memerr: + LM_ERR("no more pkg mem\n"); + return 0; + +} + + +static int w_exec(struct sip_msg* msg, char* cmd, char* out, char* in, char* avp_env) +{ + #define MAX_LINE_SIZE 1024 + #define MAX_BUF_SIZE 128 * MAX_LINE_SIZE + + str command; + str input = {NULL, 0}; + int ret; + struct hf_wrapper *hf=0; + environment_t* backup_env=0; + gparam_p outvar = (gparam_p)out; + + if (msg == 0 || cmd == 0) + return -1; + + /* fetch command */ + if(fixup_get_svalue(msg, (gparam_p)cmd, &command)!=0) { + LM_ERR("invalid command parameter"); + return -1; + } + + /* fetch input */ + if (in != NULL) { + if (pv_printf_s(msg, (pv_elem_p)in, &input)!=0) + return -1; + } + + if (avp_env != NULL) { + if ((hf=get_avp_values_list(msg, &((gparam_p)avp_env)->v.pve->spec.pvp)) == 0) + return -1; + backup_env=replace_env(hf); + if (!backup_env) { + LM_ERR("replace env failed\n"); + release_vars(hf); + release_hf_struct(hf); + return -1; + } + release_hf_struct(hf); + } + + if (!out && async) { + ret = exec_async(msg, command.s, &input); + } else { + ret = exec_sync(msg, &command, &input, outvar); + } + + if (backup_env) + unset_env(backup_env); + + return ret; +} diff --git a/modules/exec/kill.c b/modules/exec/kill.c index 3134c7e3fea..621b12560e2 100644 --- a/modules/exec/kill.c +++ b/modules/exec/kill.c @@ -164,6 +164,51 @@ pid_t __popen(const char *cmd, const char *type, FILE **stream) return ret; } +pid_t __rw_popen(const char* cmd, FILE** stream_in, FILE** stream_out) +{ + #define READ 0 + #define WRITE 1 + + pid_t ret; + int r_fds[2], w_fds[2]; + + if (pipe(r_fds) != 0) { + LM_ERR("failed to create reading pipe (%d: %s)\n", errno, strerror(errno)); + return -1; + } + + if (pipe(w_fds) != 0) { + LM_ERR("failed to writing create pipe (%d: %s)\n", errno, strerror(errno)); + return -1; + } + + ret = fork(); + if (ret == 0) { + /* reading pipe */ + close(r_fds[READ]); + dup2(r_fds[WRITE], 1); + close(r_fds[WRITE]); + + /* writing pipe */ + close(w_fds[WRITE]); + dup2(w_fds[READ], 0); + close(w_fds[READ]); + + execl("/bin/sh", "/bin/sh", "-c", cmd, NULL); + + exit(-1); + } + + close(w_fds[READ]); + *stream_in = fdopen(w_fds[WRITE], "w"); + + close(r_fds[WRITE]); + *stream_out = fdopen(r_fds[READ], "r"); + + return ret; + +} + int schedule_to_kill( int pid ) { struct timer_link *tl; diff --git a/modules/exec/kill.h b/modules/exec/kill.h index e519d80ed98..8c75535b162 100644 --- a/modules/exec/kill.h +++ b/modules/exec/kill.h @@ -51,6 +51,7 @@ int schedule_to_kill( int pid ); * @stream: stream to be returned to the caller */ pid_t __popen(const char *cmd, const char *type, FILE **stream); +pid_t __rw_popen(const char *cmd, FILE **stream_in, FILE** stream_out); #endif From 4ae853ce00a9f7710d37d95ae7647df97abbe11d Mon Sep 17 00:00:00 2001 From: Ionut Ionita Date: Fri, 24 Oct 2014 17:20:49 +0300 Subject: [PATCH 2/4] added StartTLS support for LDAP module --- modules/ldap/README | 87 ++++++++++++++++++---- modules/ldap/doc/ldap_admin.xml | 125 ++++++++++++++++++++++++++------ modules/ldap/ld_session.c | 57 ++++++++++++++- modules/ldap/ld_session.h | 14 ++++ modules/ldap/ldap_connect.c | 114 +++++++++++++++++++++++++++++ modules/ldap/ldap_connect.h | 6 ++ modules/ldap/ldap_mod.c | 3 +- 7 files changed, 367 insertions(+), 39 deletions(-) diff --git a/modules/ldap/README b/modules/ldap/README index 3b59c2e1af0..43e0237de9e 100644 --- a/modules/ldap/README +++ b/modules/ldap/README @@ -84,14 +84,18 @@ Christian Schlatter 1.4. ldap_bind_password example 1.5. ldap_network_timeout example 1.6. ldap_client_bind_timeout example - 1.7. Example LDAP Configuration File - 1.8. config_file parameter usage - 1.9. Example Usage of ldap_url - 1.10. Example Usage - 1.11. Example Usage - 1.12. Example Usage - 1.13. Example Usage + 1.7. ldap_ca_cert_file example + 1.8. ldap_cert_file example + 1.9. ldap_key_file example + 1.10. ldap_require_certificate example + 1.11. Example LDAP Configuration File + 1.12. config_file parameter usage + 1.13. Example Usage of ldap_url 1.14. Example Usage + 1.15. Example Usage + 1.16. Example Usage + 1.17. Example Usage + 1.18. Example Usage 2.1. Example code fragment to load LDAP module API 2.2. Example LDAP module API function call @@ -114,6 +118,7 @@ Chapter 1. Admin Guide * Configurable LDAP connection and bind timeouts * Module API for LDAP search operations that can be used by other OpenSIPS modules + * StartTLS support The module implementation makes use of the open source OpenLDAP library available on most UNIX/Linux platforms. Besides LDAP @@ -278,6 +283,12 @@ ldap_bind_dn = "cn=sip_proxy,ou=accounts,dc=example,dc=com ldap_bind_password = "pwd" ldap_network_timeout = 500 ldap_client_bind_timeout = 500 +ldap_ca_cert_file = "/usr/share/ca-certificates/mycert. +pem" +ldap_cert_file = "/var/my-certificate/certificate.pe +m" +ldap_key_file = "/var/my-certificate/key.pem" +ldap_require_certificate = "ALLOW" The configuration keys are explained in the following section. This LDAP session can be referred to in the routing script by @@ -354,13 +365,54 @@ ldap_network_timeout = 500 ; setting TCP timeout to 500 ms ldap_client_bind_timeout = 1000 + ldap_ca_cert_file (optional) + LDAP full path of the CA certificate file. + + No default value. It is mandatory in case you wish to + use StartTLS + + Example 1.7. ldap_ca_cert_file example + +ldap_ca_cert_file = "/usr/local/CAcert.pem" + + ldap_cert_file (optional) + LDAP full path of the certificate file. + + No default value. It is mandatory in case you wish to + use StartTLS + + Example 1.8. ldap_cert_file example + +ldap_cert_file = "/usr/local/mycert.pem" + + ldap_key_file (optional) + LDAP full path of the key file. + + No default value. It is mandatory in case you wish to + use StartTLS + + Example 1.9. ldap_key_file example + +ldap_key_file = "/usr/local/mykey.pem" + + ldap_require_certificate (optional) + LDAP peer certificate checking strategy, one of "NEVER", + "HARD", "DEMAND", "ALLOW", "TRY". Lower case letters are + also accepted. + + Default value "NEVER". + + Example 1.10. ldap_require_certificate example + +ldap_require_certificate = "NEVER" + 1.3.3. Configuration File Example The following configuration file example includes two LDAP session definitions that could be used e.g. for accessing H.350 data and do phone number to name mappings. - Example 1.7. Example LDAP Configuration File + Example 1.11. Example LDAP Configuration File # LDAP session "sipaccounts": # # - using LDAPv3 (default) @@ -372,6 +424,11 @@ ldap_bind_dn = "cn=sip_proxy,ou=accounts,dc=example,dc=com" ldap_bind_password = "pwd" ldap_network_timeout = 500 ldap_client_bind_timeout = 500 +#using StartTLS +ldap_ca_cert_file = "/ldap/path/to/ca/certificate.pem" +ldap_cert_file = "/ldap/path/to/certificate.pem" +ldap_key_file = "/ldap/path/to/key/file.pem" +ldap_require_certificate = "NEVER" # LDAP session "campus": @@ -393,7 +450,7 @@ ldap_client_bind_timeout = 500 Default value: /usr/local/etc/opensips/ldap.cfg - Example 1.8. config_file parameter usage + Example 1.12. config_file parameter usage modparam("ldap", "config_file", "/etc/opensips/ldap.ini") 1.5. Exported Functions @@ -419,7 +476,7 @@ modparam("ldap", "config_file", "/etc/opensips/ldap.ini") OpenSIPS pseudo variables and AVPs included in ldap_url do get substituted with their value. - Example 1.9. Example Usage of ldap_url + Example 1.13. Example Usage of ldap_url Search with LDAP session named sipaccounts, base ou=sip,dc=example,dc=com, one level deep using search @@ -453,7 +510,7 @@ ldap://ldap_1/dc=example,dc=com? This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - Example 1.10. Example Usage + Example 1.14. Example Usage ... # ldap search if (!ldap_search("ldap://sipaccounts/ou=sip,dc=example,dc=com??one?(cn=$ @@ -537,7 +594,7 @@ regex_subst]) This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - Example 1.11. Example Usage + Example 1.15. Example Usage ... # ldap_search call @@ -610,7 +667,7 @@ regex_subst]) This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - Example 1.12. Example Usage + Example 1.16. Example Usage ... # ldap_search call ... @@ -660,7 +717,7 @@ if (!ldap_result_check("sn/$ru", "/^sip:([^@]).*$/\1/")) This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - Example 1.13. Example Usage + Example 1.17. Example Usage ... # ldap_search call ... @@ -719,7 +776,7 @@ if (ldap_result_next()) This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - Example 1.14. Example Usage + Example 1.18. Example Usage ... if (!ldap_filter_url_encode("cn=$avp(name)", "$avp(name_esc)")) { diff --git a/modules/ldap/doc/ldap_admin.xml b/modules/ldap/doc/ldap_admin.xml index 28e94f436be..7f0ac734b45 100644 --- a/modules/ldap/doc/ldap_admin.xml +++ b/modules/ldap/doc/ldap_admin.xml @@ -5,7 +5,7 @@ Overview The LDAP module implements an LDAP search interface for OpenSIPS. It exports script functions to perform an LDAP search operation and to store the search results as OpenSIPS AVPs. This allows for using LDAP directory data in the OpenSIPS SIP message routing script. - + The following features are offered by the LDAP module: @@ -29,12 +29,15 @@ Module API for LDAP search operations that can be used by other OpenSIPS modules - - + + StartTLS support + + + The module implementation makes use of the open source OpenLDAP library available on most UNIX/Linux platforms. Besides LDAP server failover and automatic reconnect, this module can handle multiple LDAP sessions concurrently allowing to access data stored on different LDAP servers. Each OpenSIPS worker process maintains one LDAP TCP connection per configured LDAP server. This enables parallel execution of LDAP requests and offloads LDAP concurrency control to the LDAP server(s). - - An LDAP search module API is provided that can be used by other OpenSIPS modules. A module using this API does not have to implement LDAP connection management and configuration, while still having access to the full OpenLDAP API for searching and result handling. - + + An LDAP search module API is provided that can be used by other OpenSIPS modules. A module using this API does not have to implement LDAP connection management and configuration, while still having access to the full OpenLDAP API for searching and result handling. + Since LDAP server implementations are optimized for fast read access they are a good choice to store SIP provisioning data. Performance tests have shown that this module achieves lower data access times and higher call rates than other database modules like e.g. the OpenSIPS MYSQL module.
@@ -47,11 +50,11 @@ The ldap_search function () performs an LDAP search operation. It expects an LDAP URL as input which includes the LDAP session name and search parameters. provides a quick overview on LDAP URLs. - + The result of an LDAP search is stored internally and can be accessed with one of the ldap_result* functions. ldap_result () stores resulting LDAP attribute value as AVPs. ldap_result_check () is a convenience function to compare a string with LDAP attribute values using regular expression matching. Finally, ldap_result_next () allows to handle LDAP search queries that return more than one LDAP entry. - + All ldap_result* functions do always access the LDAP result set from the last ldap_search call. This should be kept in mind when calling ldap_search more than once in the OpenSIPS configuration script. @@ -160,10 +163,10 @@ Non-URL characters in an LDAP URL have to be escaped using - percent-encoding (refer to section 2.1 of RFC 4516). In particular + percent-encoding (refer to section 2.1 of RFC 4516). In particular this means that any "?" character in an LDAP URL component must be written as "%3F", since "?" is used as a URL delimiter. - The exported function ldap_filter_url_encode () + The exported function ldap_filter_url_encode () implements RFC 4515/4516 LDAP search filter and URL escaping rules. @@ -231,6 +234,10 @@ ldap_bind_dn = "cn=sip_proxy,ou=accounts,dc=example,dc=com" ldap_bind_password = "pwd" ldap_network_timeout = 500 ldap_client_bind_timeout = 500 +ldap_ca_cert_file = "/usr/share/ca-certificates/mycert.pem" +ldap_cert_file = "/var/my-certificate/certificate.pem" +ldap_key_file = "/var/my-certificate/key.pem" +ldap_require_certificate = "ALLOW" The configuration keys are explained in the following section. This LDAP session can be referred @@ -259,7 +266,7 @@ ldap_client_bind_timeout = 500 ldap_server_url = "ldap://localhost" ldap_server_url = "ldap://ldap.example.com:7777" -ldap_server_url = "ldap://ldap1.example.com, +ldap_server_url = "ldap://ldap1.example.com, ldap://ldap2.example.com:80389" @@ -353,6 +360,75 @@ ldap_server_url = "ldap://ldap1.example.com, + + ldap_ca_cert_file (optional) + + + LDAP full path of the CA certificate file. + + No default value. It is mandatory in case you wish to use StartTLS + + + <varname>ldap_ca_cert_file</varname> + example + + ldap_ca_cert_file = "/usr/local/CAcert.pem" + + + + + + ldap_cert_file (optional) + + + LDAP full path of the certificate file. + + No default value. It is mandatory in case you wish to use StartTLS + + + <varname>ldap_cert_file</varname> + example + + ldap_cert_file = "/usr/local/mycert.pem" + + + + + + ldap_key_file (optional) + + + LDAP full path of the key file. + + No default value. It is mandatory in case you wish to use StartTLS + + + <varname>ldap_key_file</varname> + example + + ldap_key_file = "/usr/local/mykey.pem" + + + + + + ldap_require_certificate (optional) + + + LDAP peer certificate checking strategy, one of "NEVER", "HARD", "DEMAND", "ALLOW", "TRY". + Lower case letters are also accepted. + + Default value "NEVER". + + + <varname>ldap_require_certificate</varname> + example + + ldap_require_certificate = "NEVER" + + + +
@@ -378,6 +454,11 @@ ldap_bind_dn = "cn=sip_proxy,ou=accounts,dc=example,dc=com" ldap_bind_password = "pwd" ldap_network_timeout = 500 ldap_client_bind_timeout = 500 +#using StartTLS +ldap_ca_cert_file = "/ldap/path/to/ca/certificate.pem" +ldap_cert_file = "/ldap/path/to/certificate.pem" +ldap_key_file = "/ldap/path/to/key/file.pem" +ldap_require_certificate = "NEVER" # LDAP session "campus": @@ -523,7 +604,7 @@ ldap://ldap_1/dc=example,dc=com? This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - + Example Usage @@ -568,9 +649,9 @@ ldap_result("telephoneNumber/$avp(tel_number)"); part of an attribute value should be stored as AVP. - An AVP can either be of type string or integer. As default, ldap_result stores LDAP attribute values as AVP of type string. The optional avp_type parameter can be used to explicitly specify the type of the AVP. It can be either str for string, or int for integer. If avp_type is specified as int then ldap_result tries to convert the LDAP attribute values to integer. In this case, the values are only stored as AVP if the conversion to integer is succesfull. + An AVP can either be of type string or integer. As default, ldap_result stores LDAP attribute values as AVP of type string. The optional avp_type parameter can be used to explicitly specify the type of the AVP. It can be either str for string, or int for integer. If avp_type is specified as int then ldap_result tries to convert the LDAP attribute values to integer. In this case, the values are only stored as AVP if the conversion to integer is succesfull. - + Function Parameters: @@ -593,7 +674,7 @@ ldap_result("telephoneNumber/$avp(tel_number)"); $avp(12) - + avp_type @@ -650,7 +731,7 @@ ldap_result("telephoneNumber/$avp(tel_number)"); This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - + Example Usage @@ -673,7 +754,7 @@ if (!ldap_result("SIPIdentityServiceLevel/$avp(service_level)")) # internal error sl_send_reply("500", "Internal server error"); exit; - default: + default: exit; } } @@ -767,7 +848,7 @@ ldap_result("SIPIdentitySIPURI/$avp(10)", "/^[^@]+@(.+)$/\1/"); This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - + Example Usage @@ -861,7 +942,7 @@ if (ldap_result_next()) if (ldap_result_next()) { ldap_result("telephonenumber/$avp(tel4)"); -} +} ... @@ -873,7 +954,7 @@ if (ldap_result_next()) This function applies the following escaping rules to string and stores the result in AVP avp_spec: - + ldap_filter_url_encode() escaping rules @@ -934,7 +1015,7 @@ if (ldap_result_next())
The string stored in AVP avp_spec can be safely used in an LDAP - URL filter string. + URL filter string. Function Parameters: @@ -1000,7 +1081,7 @@ if (!ldap_filter_url_encode("cn=$avp(name)", "$avp(name_esc)")) xlog("L_INFO", "encoded LDAP filter component: [$avp(name_esc)]\n"); if (ldap_search( - "ldap://h350/ou=commObjects,dc=example,dc=com??sub?($avp(name_esc))")) + "ldap://h350/ou=commObjects,dc=example,dc=com??sub?($avp(name_esc))")) { ... } ... diff --git a/modules/ldap/ld_session.c b/modules/ldap/ld_session.c index 6fc484db288..1872aa3f29a 100644 --- a/modules/ldap/ld_session.c +++ b/modules/ldap/ld_session.c @@ -43,7 +43,8 @@ int add_ld_session(char* _name, LDAP* _ldh, dictionary* _d) { struct ld_session* current = ld_sessions; struct ld_session* new_lds = NULL; - char *host_name, *bind_dn, *bind_pwd; + char *host_name, *bind_dn, *bind_pwd, *bind_cacert, *bind_cert, *bind_key, + *bind_req_cert; int client_search_timeout_ms, client_bind_timeout_ms, network_timeout_ms; new_lds = (struct ld_session*)pkg_malloc(sizeof(struct ld_session)); @@ -139,6 +140,59 @@ int add_ld_session(char* _name, LDAP* _ldh, dictionary* _d) memset(new_lds->bind_pwd, 0, strlen(bind_pwd)+1); strcpy(new_lds->bind_pwd, bind_pwd); + /* bind_cacert*/ + bind_cacert = iniparser_getstring( + _d, + get_ini_key_name(_name, CFG_N_LDAP_CACERTFILE), + CFG_DEF_LDAP_CACERTFILE); + new_lds->cacertfile = (char*)pkg_malloc(strlen(bind_cacert)+1); + if (new_lds->cacertfile == NULL) { + LM_ERR("no memory\n"); + return -1; + } + memset(new_lds->cacertfile, 0, strlen(bind_cacert)+1); + strcpy(new_lds->cacertfile, bind_cacert); + + /* bind_certfile */ + bind_cert = iniparser_getstring( + _d, + get_ini_key_name(_name, CFG_N_LDAP_CERTFILE), + CFG_DEF_LDAP_CERTFILE); + new_lds->certfile = (char*)pkg_malloc(strlen(bind_cert)+1); + if (new_lds->certfile == NULL) { + LM_ERR("no memory\n"); + return -1; + } + memset(new_lds->certfile, 0, strlen(bind_cert)+1); + strcpy(new_lds->certfile, bind_cert); + + /* bind_key */ + bind_key = iniparser_getstring( + _d, + get_ini_key_name(_name, CFG_N_LDAP_KEYFILE), + CFG_DEF_LDAP_KEYFILE); + new_lds->keyfile = (char*)pkg_malloc(strlen(bind_key)+1); + if (new_lds->keyfile == NULL) { + LM_ERR("no memory\n"); + return -1; + } + memset(new_lds->keyfile, 0, strlen(bind_key)+1); + strcpy(new_lds->keyfile, bind_key); + + /* bind_req_cert */ + bind_req_cert = iniparser_getstring( + _d, + get_ini_key_name(_name, CFG_N_LDAP_REQCERT), + CFG_DEF_LDAP_REQCERT); + new_lds->req_cert = (char*)pkg_malloc(strlen(bind_req_cert)+1); + if (new_lds->req_cert == NULL) { + LM_ERR("no memory\n"); + return -1; + } + memset(new_lds->req_cert, 0, strlen(bind_req_cert)+1); + strcpy(new_lds->req_cert, bind_req_cert); + + /* calculate_ha1 */ new_lds->calculate_ha1 = iniparser_getboolean( _d, @@ -146,6 +200,7 @@ int add_ld_session(char* _name, LDAP* _ldh, dictionary* _d) CFG_DEF_CALCULATE_HA1); + if (current == NULL) { ld_sessions = new_lds; diff --git a/modules/ldap/ld_session.h b/modules/ldap/ld_session.h index e197fe48953..6f5f6b530d8 100644 --- a/modules/ldap/ld_session.h +++ b/modules/ldap/ld_session.h @@ -50,6 +50,10 @@ struct ld_session { char* bind_dn; char* bind_pwd; int calculate_ha1; + char* cacertfile; + char* certfile; + char* keyfile; + char* req_cert; struct ld_session* next; }; @@ -63,6 +67,11 @@ struct ld_session { #define CFG_N_LDAP_BIND_PWD "ldap_bind_password" #define CFG_N_CALCULATE_HA1 "calculate_ha1" +#define CFG_N_LDAP_CACERTFILE "ldap_ca_cert_file" +#define CFG_N_LDAP_CERTFILE "ldap_cert_file" +#define CFG_N_LDAP_KEYFILE "ldap_key_file" +#define CFG_N_LDAP_REQCERT "ldap_require_certificate" + #define CFG_DEF_HOST_NAME "" #define CFG_DEF_LDAP_SERVER_URL NULL @@ -76,6 +85,11 @@ struct ld_session { #define CFG_LDAP_CLIENT_SEARCH_TIMEOUT_MIN 2000 +#define CFG_DEF_LDAP_CACERTFILE "" +#define CFG_DEF_LDAP_CERTFILE "" +#define CFG_DEF_LDAP_KEYFILE "" +#define CFG_DEF_LDAP_REQCERT "NEVER" + extern int add_ld_session(char* _name, LDAP* _ldh, dictionary* _d); extern struct ld_session* get_ld_session(char* _name); extern int free_ld_sessions(); diff --git a/modules/ldap/ldap_connect.c b/modules/ldap/ldap_connect.c index 55bb6eebb0b..4c7fbf45040 100644 --- a/modules/ldap/ldap_connect.c +++ b/modules/ldap/ldap_connect.c @@ -42,10 +42,83 @@ #include "../../mem/mem.h" #include "../../ut.h" +static inline int ldap_word2upper(char* input) +{ + int index=0; + + while (input[index] == ' ') + input++; + + while (input[index] != '\0') { + if (input[index] >= 'a' && input[index] <= 'z') { + input[index++] -= 32; + continue; + } + + if (input[index] <= 'A' && input[index] >= 'Z') { + LM_ERR("invalid req_cert parameter!" + " must contain only letters\n"); + return -1; + } + + index++; + } + + return 0; +} + +static inline int get_req_cert_param(char* req_cert) +{ + #define DWORD(s) ( *s + (*(s+1) << 8) + (*(s+2) << 16) + (*(s+3) << 24)) + + switch (DWORD(req_cert)) { + case NEVE: + if (*(req_cert+4) != 'R' || *(req_cert+5) != '\0') + goto error; + return LDAP_OPT_X_TLS_NEVER; + case DEMA: + if (*(req_cert+4) != 'N' || *(req_cert+5) != 'D' || + *(req_cert+6) != '\0') + goto error; + return LDAP_OPT_X_TLS_DEMAND; + case ALLO: + if (*(req_cert+4) != 'W' || *(req_cert+5) != '\0') + goto error; + return LDAP_OPT_X_TLS_ALLOW; + case HARD: + if (*(req_cert+4) != '\0') + goto error; + return LDAP_OPT_X_TLS_HARD; + case TRY: + return LDAP_OPT_X_TLS_TRY; + default : + goto error; + + } + +error: + LM_ERR("invalid req_cert parameter [%s]!" + "OPTIONS: NEVER|DEMAND|ALLOW|HARD|TRY\n", req_cert); + return -1; + #undef DWORD +} + + int ldap_connect(char* _ld_name) { + #define W_SET_OPTION(handle, opt, str, name) \ + do { \ + if (ldap_set_option( handle, opt, str) \ + != LDAP_OPT_SUCCESS) { \ + LM_ERR("[%s]: could not set " # opt " [%s]\n" \ + , name, str); \ + return -1; \ + } \ + } while (0); + int rc; int ldap_proto_version; + int req_cert_value; struct ld_session* lds; struct berval ldap_cred; struct berval* ldap_credp; @@ -177,6 +250,47 @@ int ldap_connect(char* _ld_name) ldap_credp = &ldap_cred; } + /* configure tls */ + if (*lds->cacertfile && *lds->certfile && *lds->keyfile) { + + W_SET_OPTION(lds->handle, LDAP_OPT_X_TLS_CACERTFILE, + lds->cacertfile, _ld_name); + + W_SET_OPTION(lds->handle, LDAP_OPT_X_TLS_CERTFILE, + lds->certfile, _ld_name); + + W_SET_OPTION(lds->handle, LDAP_OPT_X_TLS_KEYFILE, + lds->keyfile, _ld_name); + + if (ldap_word2upper(lds->req_cert) != 0) + return -1; + + if ((req_cert_value = get_req_cert_param(lds->req_cert)) < 0) + return -1; + + if (ldap_set_option( lds->handle, LDAP_OPT_X_TLS_REQUIRE_CERT, + &req_cert_value) != LDAP_OPT_SUCCESS) { + LM_ERR("[%s]: could not set LDAP_OPT_X_TLS_REQUIRE_CERT [%s]\n" + , _ld_name, lds->req_cert); + return -1; + } + + int ret = + ldap_start_tls_s(lds->handle, NULL, NULL); + if (ret != LDAP_SUCCESS) { + LM_ERR("ERROR %d %s\n", ret, ldap_err2string(ret)); + LM_ERR("cannot start tls! Check certificates and" + " keyfile path and access rights\n"); + return -1; + } + + LM_INFO("Using StartTLS for session [%s]\n", _ld_name); + } else if (*lds->cacertfile || *lds->certfile || *lds->keyfile) { + LM_WARN("ldap_ca_certfile, ldap_cert_file and ldap_key_file" + " must be set in order to use StartTLS. " + "No StartTLS configured!\n"); + } + /* * ldap_sasl_bind (LDAP_SASL_SIMPLE) */ diff --git a/modules/ldap/ldap_connect.h b/modules/ldap/ldap_connect.h index 898f4e22b7f..1be4578eec2 100644 --- a/modules/ldap/ldap_connect.h +++ b/modules/ldap/ldap_connect.h @@ -36,6 +36,12 @@ #include "../../str.h" #include "../../dprint.h" +#define NEVE 0x4556454E +#define DEMA 0x414D4544 +#define ALLO 0x4F4C4C41 +#define HARD 0x44524148 +#define TRY 0x00595254 + extern int ldap_connect(char* _ld_name); extern int ldap_disconnect(char* _ld_name); extern int ldap_reconnect(char* _ld_name); diff --git a/modules/ldap/ldap_mod.c b/modules/ldap/ldap_mod.c index 9761279fc6c..8d058aff530 100644 --- a/modules/ldap/ldap_mod.c +++ b/modules/ldap/ldap_mod.c @@ -84,6 +84,7 @@ static int w_ldap_result_check_2(struct sip_msg* msg, * Default module parameter values */ #define DEF_LDAP_CONFIG "/usr/local/etc/opensips/ldap.cfg" +#define DEF_REQ_CERT "NEVER" /* * Module parameter variables @@ -128,7 +129,7 @@ static cmd_export_t cmds[] = { */ static param_export_t params[] = { - {"config_file", STR_PARAM, &ldap_config}, + {"config_file", STR_PARAM, &ldap_config.s}, {0, 0, 0} }; From 9b7a31a011d5ae28859fc3a8706648ae02e0beb2 Mon Sep 17 00:00:00 2001 From: Ionut Ionita Date: Fri, 24 Oct 2014 18:01:27 +0300 Subject: [PATCH 3/4] fixed: verify exec buffer overflow and fread --- modules/exec/README | 2 +- modules/exec/doc/exec_admin.xml | 24 ++++++++++++------------ modules/exec/exec.c | 8 ++++++-- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/modules/exec/README b/modules/exec/README index 22924defe23..61077d54ed4 100644 --- a/modules/exec/README +++ b/modules/exec/README @@ -270,7 +270,7 @@ exec_getenv("HOSTNAME", "$avp(localhost)"); WARNING: any OpenSIPS pseudo-vars which may contain special bash characters should be placed inside quotes, e.g. - exec_getenv("'$ct'"); + exec("update-stats.sh '$ct'"); This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE, diff --git a/modules/exec/doc/exec_admin.xml b/modules/exec/doc/exec_admin.xml index f1dad5136cd..232661e9fb8 100644 --- a/modules/exec/doc/exec_admin.xml +++ b/modules/exec/doc/exec_admin.xml @@ -1,9 +1,9 @@ - + &adminguide; - +
Overview @@ -16,23 +16,23 @@ - SIP_HF_<hf_name> contains value of each header field in - request. If a header field occurred multiple times, values are - concatenated and comma-separated. <hf_name> is in capital - letters. Ff a header-field name occurred in compact form, + SIP_HF_<hf_name> contains value of each header field in + request. If a header field occurred multiple times, values are + concatenated and comma-separated. <hf_name> is in capital + letters. Ff a header-field name occurred in compact form, <hf_name> is canonical. - SIP_TID is transaction identifier. All request retransmissions or - CANCELs/ACKs associated with a previous INVITE result in the same + SIP_TID is transaction identifier. All request retransmissions or + CANCELs/ACKs associated with a previous INVITE result in the same value. - SIP_DID is dialog identifier, which is the same as to-tag. + SIP_DID is dialog identifier, which is the same as to-tag. Initially, it is empty. @@ -48,7 +48,7 @@ - SIP_RURI is current request &uri; (if + SIP_RURI is current request &uri; (if unchanged, equal to original). @@ -217,7 +217,7 @@ exec_dset("ruri-changer.sh '$ct'"); of the command is ignored. - See sip-server/modules/exec/etc/exec.cfg in the source tarball for + See sip-server/modules/exec/etc/exec.cfg in the source tarball for information on usage. Meaning of the parameters is as follows: @@ -369,7 +369,7 @@ exec_getenv("HOSTNAME", "$avp(localhost)"); WARNING: any OpenSIPS pseudo-vars which may contain special bash - characters should be placed inside quotes, e.g. exec_getenv("'$ct'"); + characters should be placed inside quotes, e.g. exec("update-stats.sh '$ct'"); This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, diff --git a/modules/exec/exec.c b/modules/exec/exec.c index 063b48e94e7..56f55d8c0b6 100644 --- a/modules/exec/exec.c +++ b/modules/exec/exec.c @@ -576,8 +576,12 @@ int exec_sync(struct sip_msg* msg, str* command, str* input, gparam_p outvar) wait(&exit_status); if (outvar) { - while (fgets(tmpbuf, MAX_LINE_SIZE, pout)) { - tmplen = strlen(tmpbuf); + while ((tmplen = fread(tmpbuf, 1, MAX_LINE_SIZE, pout))) { + + if ((buflen + tmplen) >= MAX_BUF_SIZE) { + LM_WARN("no more space in output buffer\n"); + break; + } memcpy(buf+buflen, tmpbuf, tmplen); buflen += tmplen; } From b1b39e1d51a32b04227e9f8b58bfa94d1dca4c9e Mon Sep 17 00:00:00 2001 From: Ionut Ionita Date: Tue, 28 Oct 2014 18:47:16 +0200 Subject: [PATCH 4/4] stderr support for exec function --- modules/exec/README | 13 +++-- modules/exec/doc/exec_admin.xml | 14 +++++- modules/exec/exec.c | 84 +++++++++++++++++++++------------ modules/exec/exec.h | 2 +- modules/exec/exec_mod.c | 14 +++--- modules/exec/kill.c | 82 ++++++++++++++++++++++---------- modules/exec/kill.h | 2 +- 7 files changed, 141 insertions(+), 70 deletions(-) diff --git a/modules/exec/README b/modules/exec/README index 61077d54ed4..3fe8ed72a19 100644 --- a/modules/exec/README +++ b/modules/exec/README @@ -35,7 +35,8 @@ Jan Janak 1.4.2. exec_msg(command) 1.4.3. exec_avp(command[, avplist]) 1.4.4. exec_getenv(environment_variable[, avp]) - 1.4.5. exec(command, [output], [input], [envavp]) + 1.4.5. exec(command, [output], [input], + [error],[envavp]) 1.5. Known Issues @@ -246,7 +247,7 @@ exec_getenv("HOSTNAME"); exec_getenv("HOSTNAME", "$avp(localhost)"); ... -1.4.5. exec(command, [output], [input], [envavp]) +1.4.5. exec(command, [output], [input], [error],[envavp]) Executes an external command. The input is passed to the standard input of the new process, if specified, and the output @@ -256,11 +257,13 @@ exec_getenv("HOSTNAME", "$avp(localhost)"); * command - command to be executed.It can include pseudovariables. * output - pseudovariable where to store the output from the - standard output of the command. Keep in mind that if this + standard output of the process. Keep in mind that if this parameter is set, the async paramater will not be taken in consideration. * input - String to be passed to the standard input of the command. The string can be given as a pseudovariable. + * error - pseudovariable where to store the error from the + standard error of the process. * envavp - Avp where to store the values for the environment variables to be passed for the command. The names of the environment variables will be "OSIPS_EXEC_#" where # will @@ -272,6 +275,10 @@ exec_getenv("HOSTNAME", "$avp(localhost)"); bash characters should be placed inside quotes, e.g. exec("update-stats.sh '$ct'"); + WARNING: "input"/"output"/"error" parameters are not designed + for a large amount of data so one should be careful when using + them because server could considerably be slowed down. + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE, ONREPLY_ROUTE. diff --git a/modules/exec/doc/exec_admin.xml b/modules/exec/doc/exec_admin.xml index 232661e9fb8..3e53a7291fb 100644 --- a/modules/exec/doc/exec_admin.xml +++ b/modules/exec/doc/exec_admin.xml @@ -334,7 +334,7 @@ exec_getenv("HOSTNAME", "$avp(localhost)");
- <function moreinfo="none">exec(command, [output], [input], [envavp])</function> + <function moreinfo="none">exec(command, [output], [input], [error],[envavp])</function> Executes an external command. The input is passed to the standard input of the new @@ -349,7 +349,7 @@ exec_getenv("HOSTNAME", "$avp(localhost)"); output - pseudovariable where to store the output - from the standard output of the command. Keep in mind that if this parameter + from the standard output of the process. Keep in mind that if this parameter is set, the async paramater will not be taken in consideration. @@ -358,6 +358,11 @@ exec_getenv("HOSTNAME", "$avp(localhost)"); of the command. The string can be given as a pseudovariable. + + error - pseudovariable where to store the error from + the standard error of the process. + + envavp - Avp where to store the values for the environment variables to be passed for the command. The names of the environment @@ -372,6 +377,11 @@ exec_getenv("HOSTNAME", "$avp(localhost)"); characters should be placed inside quotes, e.g. exec("update-stats.sh '$ct'"); + WARNING: "input"/"output"/"error" parameters are not designed for a large amount of + data so one should be careful when using them because server could considerably be + slowed down. + + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE, ONREPLY_ROUTE. diff --git a/modules/exec/exec.c b/modules/exec/exec.c index 56f55d8c0b6..0ae41b76621 100644 --- a/modules/exec/exec.c +++ b/modules/exec/exec.c @@ -531,24 +531,51 @@ int exec_getenv(struct sip_msg *msg, char *cmd, pvname_list_p avpl) } -int exec_sync(struct sip_msg* msg, str* command, str* input, gparam_p outvar) +static int read_and_write2var(struct sip_msg* msg, FILE** strm, gparam_p outvar) { #define MAX_LINE_SIZE 1024 - #define MAX_BUF_SIZE 128 * MAX_LINE_SIZE + #define MAX_BUF_SIZE 32 * MAX_LINE_SIZE - pid_t pid; - int exit_status, ret; - FILE *pin, *pout; - char buf[MAX_BUF_SIZE], tmpbuf[MAX_LINE_SIZE]; int buflen=0, tmplen; pv_value_t outval; + char buf[MAX_BUF_SIZE], tmpbuf[MAX_LINE_SIZE]; + + while((tmplen=fread(tmpbuf, 1, MAX_LINE_SIZE, *strm))) { + if ((buflen + tmplen) >= MAX_BUF_SIZE) { + LM_WARN("no more space in output buffer\n"); + break; + } + memcpy(buf+buflen, tmpbuf, tmplen); + buflen += tmplen; + + outval.flags = PV_VAL_STR; + outval.rs.s = buf; + outval.rs.len = buflen; + + if (buflen && + pv_set_value(msg, &outvar->v.pve->spec, 0, &outval) < 0) { + LM_ERR("cannot set output pv value\n"); + return -1; + } + } + + return 0; + + #undef MAX_LINE_SIZE + #undef MAX_BUF_SIZE +} - if (input && outvar) { - pid = __rw_popen(command->s, &pin, &pout); - } else if (input) { - pid = __popen(command->s, "w", &pin); - } else if (outvar) { - pid = __popen(command->s, "r", &pout); +int exec_sync(struct sip_msg* msg, str* command, str* input, gparam_p outvar, gparam_p errvar) +{ + + pid_t pid; + int exit_status, ret; + FILE *pin, *pout, *perr; + + if (input || outvar || errvar) { + pid = ___popen(command->s, input ? &pin : NULL, + outvar ? &pout : NULL, + errvar ? &perr : NULL); } else { pid = fork(); if (pid == 0) { @@ -565,7 +592,6 @@ int exec_sync(struct sip_msg* msg, str* command, str* input, gparam_p outvar) } if (ferror(pin)) { - LM_ERR("writing pipe: %s\n", strerror(errno)); ser_error=E_EXEC; goto error; } @@ -576,23 +602,15 @@ int exec_sync(struct sip_msg* msg, str* command, str* input, gparam_p outvar) wait(&exit_status); if (outvar) { - while ((tmplen = fread(tmpbuf, 1, MAX_LINE_SIZE, pout))) { - - if ((buflen + tmplen) >= MAX_BUF_SIZE) { - LM_WARN("no more space in output buffer\n"); - break; - } - memcpy(buf+buflen, tmpbuf, tmplen); - buflen += tmplen; + if (read_and_write2var(msg, &pout, outvar) < 0) { + LM_ERR("failed reading from pipe\n"); + return -1; } + } - outval.flags = PV_VAL_STR; - outval.rs.s = buf; - outval.rs.len = buflen; - - if (buflen && - pv_set_value(msg, &outvar->v.pve->spec, 0, &outval) < 0) { - LM_ERR("cannot set output pv value\n"); + if (errvar) { + if (read_and_write2var(msg, &perr, errvar) < 0) { + LM_ERR("failed reading stderr from pipe\n"); return -1; } } @@ -606,8 +624,16 @@ int exec_sync(struct sip_msg* msg, str* command, str* input, gparam_p outvar) ret=-1; } + if (errvar && ferror(perr)) { + LM_ERR("err pipe: %s\n", strerror(errno)); + ser_error=E_EXEC; + ret=-1; + } + if (outvar) pclose(pout); + if (errvar) + pclose(perr); if (WIFEXITED(exit_status)) { if (WEXITSTATUS(exit_status)!=0) ret=-1; @@ -618,6 +644,4 @@ int exec_sync(struct sip_msg* msg, str* command, str* input, gparam_p outvar) } return ret; - #undef MAX_LINE_SIZE - #undef MAX_BUF_SIZE } diff --git a/modules/exec/exec.h b/modules/exec/exec.h index 6e130540c3c..77bec619de2 100644 --- a/modules/exec/exec.h +++ b/modules/exec/exec.h @@ -52,7 +52,7 @@ int exec_str(struct sip_msg *msg, char *cmd, char *param, int param_len); int exec_msg(struct sip_msg *msg, char *cmd ); int exec_avp(struct sip_msg *msg, char *cmd, pvname_list_p avpl); int exec_getenv(struct sip_msg *msg, char *cmd, pvname_list_p avpl); -int exec_sync(struct sip_msg* msg, str* command, str* input, gparam_p outvar); +int exec_sync(struct sip_msg* msg, str* command, str* input, gparam_p outvar, gparam_p errvar); #endif diff --git a/modules/exec/exec_mod.c b/modules/exec/exec_mod.c index 22d36e516d3..8b63698fc63 100644 --- a/modules/exec/exec_mod.c +++ b/modules/exec/exec_mod.c @@ -56,7 +56,7 @@ inline static int w_exec_dset(struct sip_msg* msg, char* cmd, char* foo); inline static int w_exec_msg(struct sip_msg* msg, char* cmd, char* foo); inline static int w_exec_avp(struct sip_msg* msg, char* cmd, char* avpl); inline static int w_exec_getenv(struct sip_msg* msg, char* cmd, char* avpl); -inline static int w_exec(struct sip_msg* msg, char* cmd, char* out, char* in, char* avp_env); +inline static int w_exec(struct sip_msg* msg, char* cmd, char* out, char* in, char* err, char* avp_env); static int exec_avp_fixup(void** param, int param_no); static int exec_fixup(void** param, int param_no); @@ -77,7 +77,7 @@ static cmd_export_t cmds[] = { REQUEST_ROUTE|FAILURE_ROUTE|LOCAL_ROUTE|STARTUP_ROUTE|TIMER_ROUTE|EVENT_ROUTE|ONREPLY_ROUTE}, {"exec_getenv", (cmd_function)w_exec_getenv, 2, exec_avp_fixup, 0, REQUEST_ROUTE|FAILURE_ROUTE|LOCAL_ROUTE|STARTUP_ROUTE|TIMER_ROUTE|EVENT_ROUTE|ONREPLY_ROUTE}, - {"exec", (cmd_function)w_exec, 4, exec_fixup, 0, + {"exec", (cmd_function)w_exec, 5, exec_fixup, 0, REQUEST_ROUTE|FAILURE_ROUTE|LOCAL_ROUTE|STARTUP_ROUTE|TIMER_ROUTE|EVENT_ROUTE|ONREPLY_ROUTE}, {0, 0, 0, 0, 0, 0} }; @@ -337,6 +337,7 @@ static int exec_fixup(void** param, int param_no) case 1: /* cmd */ return fixup_spve(param); case 2: /* output var */ + case 4: /* error var */ if (fixup_spve(param)) { LM_ERR("cannot fix output var\n"); return -1; @@ -366,7 +367,7 @@ static int exec_fixup(void** param, int param_no) *param = (void *)model; return 0; - case 4: /* environment avp */ + case 5: /* environment avp */ if (fixup_spve(param)) { LM_ERR("cannot fix output var\n"); return -1; @@ -475,10 +476,8 @@ static struct hf_wrapper* get_avp_values_list(struct sip_msg* msg, pv_param_p av } -static int w_exec(struct sip_msg* msg, char* cmd, char* out, char* in, char* avp_env) +static int w_exec(struct sip_msg* msg, char* cmd, char* out, char* in, char* err ,char* avp_env) { - #define MAX_LINE_SIZE 1024 - #define MAX_BUF_SIZE 128 * MAX_LINE_SIZE str command; str input = {NULL, 0}; @@ -486,6 +485,7 @@ static int w_exec(struct sip_msg* msg, char* cmd, char* out, char* in, char* avp struct hf_wrapper *hf=0; environment_t* backup_env=0; gparam_p outvar = (gparam_p)out; + gparam_p errvar = (gparam_p)err; if (msg == 0 || cmd == 0) @@ -519,7 +519,7 @@ static int w_exec(struct sip_msg* msg, char* cmd, char* out, char* in, char* avp if (!out && async) { ret = exec_async(msg, command.s, &input); } else { - ret = exec_sync(msg, &command, &input, outvar); + ret = exec_sync(msg, &command, &input, outvar, errvar); } if (backup_env) diff --git a/modules/exec/kill.c b/modules/exec/kill.c index 621b12560e2..8b15ac738e9 100644 --- a/modules/exec/kill.c +++ b/modules/exec/kill.c @@ -164,49 +164,79 @@ pid_t __popen(const char *cmd, const char *type, FILE **stream) return ret; } -pid_t __rw_popen(const char* cmd, FILE** stream_in, FILE** stream_out) +pid_t ___popen(const char* cmd, FILE** strm_w, FILE** strm_r, FILE** strm_e) { - #define READ 0 - #define WRITE 1 +#define OPEN_PIPE(strm, fds) \ + do { \ + if (strm) { \ + if (pipe(fds) != 0) { \ + LM_ERR("failed to create reading pipe (%d: %s)\n", \ + errno, strerror(errno)); \ + return -1; \ + } \ + } \ + } while (0); + +/* + * cl - pipe end to be closed + * op - pipe end to be redirected + * re - fds where to redirect 'op' + */ +#define CLOSE_AND_REDIRECT(strm, fds, cl, op, re) \ + do { \ + if (strm) { \ + close(fds[cl]); \ + dup2(fds[op], re); \ + close(fds[op]); \ + } \ + } while (0); + +#define CLOSE_END_AND_OPEN_STREAM(strm, way, fds, end2close) \ + do { \ + if (strm) { \ + close(fds[end2close]); \ + *strm = fdopen(fds[(1^end2close)], way); \ + } \ + }while (0); pid_t ret; - int r_fds[2], w_fds[2]; + int r_fds[2], w_fds[2], e_fds[2]; - if (pipe(r_fds) != 0) { - LM_ERR("failed to create reading pipe (%d: %s)\n", errno, strerror(errno)); - return -1; + if (strm_r == NULL && strm_w == NULL && strm_e == NULL) { + LM_WARN("no descriptor redirect required\n"); } - if (pipe(w_fds) != 0) { - LM_ERR("failed to writing create pipe (%d: %s)\n", errno, strerror(errno)); - return -1; - } + OPEN_PIPE(strm_w, w_fds); + OPEN_PIPE(strm_r, r_fds); + OPEN_PIPE(strm_e, e_fds); - ret = fork(); - if (ret == 0) { - /* reading pipe */ - close(r_fds[READ]); - dup2(r_fds[WRITE], 1); - close(r_fds[WRITE]); + ret=fork(); + + if (ret==0) { + /* write pipe */ + CLOSE_AND_REDIRECT(strm_w, w_fds, 1, 0 ,0); - /* writing pipe */ - close(w_fds[WRITE]); - dup2(w_fds[READ], 0); - close(w_fds[READ]); + /* read pipe */ + CLOSE_AND_REDIRECT(strm_r, r_fds, 0, 1, 1); + + /* error pipe */ + CLOSE_AND_REDIRECT(strm_e, e_fds, 0, 1, 2); execl("/bin/sh", "/bin/sh", "-c", cmd, NULL); exit(-1); } - close(w_fds[READ]); - *stream_in = fdopen(w_fds[WRITE], "w"); - - close(r_fds[WRITE]); - *stream_out = fdopen(r_fds[READ], "r"); + CLOSE_END_AND_OPEN_STREAM(strm_w, "w", w_fds, 0); + CLOSE_END_AND_OPEN_STREAM(strm_r, "r", r_fds, 1); + CLOSE_END_AND_OPEN_STREAM(strm_e, "r", e_fds, 1); return ret; +#undef OPEN_PIPE +#undef CLOSE_AND_REDIRECT +#undef CLOSE_AND_OPEN_STREAM + } int schedule_to_kill( int pid ) diff --git a/modules/exec/kill.h b/modules/exec/kill.h index 8c75535b162..cdc2be42f75 100644 --- a/modules/exec/kill.h +++ b/modules/exec/kill.h @@ -51,7 +51,7 @@ int schedule_to_kill( int pid ); * @stream: stream to be returned to the caller */ pid_t __popen(const char *cmd, const char *type, FILE **stream); -pid_t __rw_popen(const char *cmd, FILE **stream_in, FILE** stream_out); +pid_t ___popen(const char *cmd, FILE **, FILE**, FILE**); #endif