/*! * Performs http_query and saves possible result (first body line of reply) * to pvar. * This is the same http_query as used to be in the utils module. */ int http_query(struct sip_msg* _m, char* _url, str* _dst, char* _post) { int res; curl_query_t query_params; memset(&query_params, 0, sizeof(curl_query_t)); query_params.username = NULL; query_params.secret = NULL; query_params.authmethod = default_authmethod; query_params.contenttype = "text/plain"; query_params.post = _post; query_params.clientcert = NULL; query_params.clientkey = NULL; query_params.cacert = NULL; query_params.ciphersuites = NULL; query_params.tlsversion = default_tls_version; query_params.verify_peer = default_tls_verify_peer; query_params.verify_host = default_tls_verify_host; query_params.timeout = default_connection_timeout; query_params.http_follow_redirect = default_http_follow_redirect; query_params.oneline = 1; query_params.maxdatasize = 0; query_params.http_proxy = as_asciiz(&default_http_proxy); query_params.http_proxy_port = default_http_proxy_port; res = curL_query_url(_m, _url, _dst, &query_params); return res; }
static char* get_base_name(str* filename) { char* tmp1, *tmp2, *res; int len; res = NULL; if ((tmp1 = as_asciiz(filename)) == NULL) { ERR("cfg_parser: No memory left\n"); goto error; } if ((tmp2 = basename(tmp1)) == NULL) { ERR("cfg_parser: Error in basename\n"); goto error; } len = strlen(tmp2); if ((res = pkg_malloc(len + 1)) == NULL) { ERR("cfg_parser: No memory left"); goto error; } memcpy(res, tmp2, len + 1); pkg_free(tmp1); return res; error: if (tmp1) pkg_free(tmp1); return NULL; }
/** * @brief Small wrapper around sl_send_reply * * Warapper around sl_send_rply() which accepts parameters that include * config variables * */ static int w_sl_send_reply(struct sip_msg* msg, char* p1, char* p2) { int code, ret; str reason; char* r; if (get_int_fparam(&code, msg, (fparam_t*)p1) < 0) { code = default_code; } if (get_str_fparam(&reason, msg, (fparam_t*)p2) < 0) { reason = default_reason; } if(reason.s[reason.len-1]=='\0') { r = reason.s; } else { r = as_asciiz(&reason); if (r == NULL) r = default_reason.s; } ret = sl_send_reply(msg, code, r); if ((r!=reason.s) && (r!=default_reason.s)) pkg_free(r); return ret; }
int exec_msg(struct sip_msg *msg, str* cmd ) { FILE *pipe; int exit_status; int ret; char* c; ret=-1; /* pessimist: assume error */ c = as_asciiz(cmd); if (!c) { ERR("No memory left\n"); return -1; } pipe=popen( c, "w" ); pkg_free(c); if (pipe==NULL) { LOG(L_ERR, "ERROR: exec_msg: cannot open pipe: %.*s\n", cmd->len, ZSW(cmd->s)); ser_error=E_EXEC; return -1; } if (fwrite(msg->buf, 1, msg->len, pipe)!=msg->len) { LOG(L_ERR, "ERROR: exec_msg: error writing to pipe\n"); ser_error=E_EXEC; goto error01; } /* success */ ret=1; error01: if (ferror(pipe)) { LOG(L_ERR, "ERROR: exec_str: error in pipe: %s\n", strerror(errno)); ser_error=E_EXEC; ret=-1; } exit_status=pclose(pipe); if (WIFEXITED(exit_status)) { /* exited properly .... */ /* return false if script exited with non-zero status */ if (WEXITSTATUS(exit_status)!=0) ret=-1; } else { /* exited erroneously */ LOG(L_ERR, "ERROR: exec_msg: cmd %.*s failed. " "exit_status=%d, errno=%d: %s\n", cmd->len, ZSW(cmd->s), exit_status, errno, strerror(errno) ); ret=-1; } return ret; }
inline static int w_t_reply(struct sip_msg* msg, char* p1, char* p2) { struct cell *t; int code, ret = -1; str reason; char* r; if (msg->REQ_METHOD==METHOD_ACK) { LOG(L_WARN, "WARNING: t_reply: ACKs are not replied\n"); return -1; } if (t_check( msg , 0 )==-1) return -1; t=get_t(); if (!t) { LOG(L_ERR, "ERROR: t_reply: cannot send a t_reply to a message " "for which no T-state has been established\n"); return -1; } if (get_int_fparam(&code, msg, (fparam_t*)p1) < 0) { code = default_code; } if (get_str_fparam(&reason, msg, (fparam_t*)p2) < 0) { reason = default_reason; } r = as_asciiz(&reason); if (r == NULL) r = default_reason.s; /* if called from reply_route, make sure that unsafe version * is called; we are already in a mutex and another mutex in * the safe version would lead to a deadlock */ if (rmode==MODE_ONFAILURE) { DBG("DEBUG: t_reply_unsafe called from w_t_reply\n"); ret = t_reply_unsafe(t, msg, code, r); } else if (rmode==MODE_REQUEST) { ret = t_reply( t, msg, code, r); } else { LOG(L_CRIT, "BUG: w_t_reply entered in unsupported mode\n"); ret = -1; } if (r) pkg_free(r); return ret; }
/** * @brief send stateful reply if transaction was created * * Check if transation was created for respective SIP request and reply * in stateful mode, otherwise send stateless reply * * @param msg - SIP message structure * @param code - reply status code * @param reason - reply reason phrase * @return 1 for success and -1 for failure */ int send_reply(struct sip_msg *msg, int code, str *reason) { char *r = NULL; struct cell *t; int ret = 1; if(reason->s[reason->len-1]=='\0') { r = reason->s; } else { r = as_asciiz(reason); if (r == NULL) { LM_ERR("no pkg for reason phrase\n"); return -1; } } if(sl_bind_tm!=0) { t = tmb.t_gett(); if(t!= NULL && t!=T_UNDEFINED) { if(tmb.t_reply(msg, code, r)< 0) { LM_ERR("failed to reply stateful (tm)\n"); goto error; } LM_DBG("reply in stateful mode (tm)\n"); goto done; } } if(msg->first_line.type==SIP_REPLY) goto error; LM_DBG("reply in stateless mode (sl)\n"); ret = sl_send_reply(msg, code, r); done: if(r!=reason->s) pkg_free(r); return ret; error: if(r!=reason->s) pkg_free(r); return -1; }
int pv_parse_strftime_name(pv_spec_p sp, str *in) { if(sp==NULL || in==NULL || in->len<=0) return -1; sp->pvp.pvn.u.isname.name.s.s = as_asciiz(in); if(sp->pvp.pvn.u.isname.name.s.s==NULL) { LM_ERR("no more pkg\n"); return -1; } sp->pvp.pvn.u.isname.name.s.len = in->len; #if 0 /* to-do: free function for pv name structure */ sp->pvp.pvn.nfree = pkg_free; #endif return 0; }
/*! wrapper of sl_reply_helper - reason is str, tag is str */ int sl_send_reply_dlg(struct sip_msg *msg, int code, str *reason, str *tag) { char *r; int ret; if(reason->s[reason->len-1]=='\0') { r = reason->s; } else { r = as_asciiz(reason); if (r == NULL) { LM_ERR("no pkg for reason phrase\n"); return -1; } } ret = sl_reply_helper(msg, code, r, tag); if (r!=reason->s) pkg_free(r); return ret; }
/*! Run a query based on a connection definition */ int curl_con_query_url_f(struct sip_msg* _m, const str *connection, const str* url, str* result, const char *contenttype, const str* post, int failover) { curl_con_t *conn = NULL; curl_con_pkg_t *pconn = NULL; char *urlbuf = NULL; char *postdata = NULL; curl_query_t query_params; unsigned int maxdatasize = default_maxdatasize; int res; /* Find connection if it exists */ if (!connection) { LM_ERR("No cURL connection specified\n"); return -1; } LM_DBG("******** CURL Connection %.*s\n", connection->len, connection->s); conn = curl_get_connection((str*)connection); if (conn == NULL) { LM_ERR("No cURL connection found: %.*s\n", connection->len, connection->s); return -1; } pconn = curl_get_pkg_connection(conn); if (pconn == NULL) { LM_ERR("No cURL connection data found: %.*s\n", connection->len, connection->s); return -1; } LM_DBG("******** CURL Connection found %.*s\n", connection->len, connection->s); maxdatasize = conn->maxdatasize; if (url && (url->len > 0) && (url->s != NULL)) { int url_len = conn->schema.len + 3 + conn->url.len + 1 + url->len + 1; urlbuf = pkg_malloc(url_len); if (urlbuf == NULL) { res = -1; goto error; } snprintf(urlbuf, url_len, "%.*s://%.*s%s%.*s", conn->schema.len, conn->schema.s, conn->url.len, conn->url.s, (url->s[0] == '/')? "" : "/", url->len, url->s); } else { int url_len = conn->schema.len + 3 + conn->url.len + 1; urlbuf = pkg_malloc(url_len); if (urlbuf == NULL) { res = -1; goto error; } snprintf(urlbuf, url_len, "%.*s://%.*s", conn->schema.len, conn->schema.s, conn->url.len, conn->url.s); } LM_DBG("***** #### ***** CURL URL: %s \n", urlbuf); if (post && (post->len > 0) && (post->s != NULL)) { /* Allocated using pkg_memory */ postdata = as_asciiz((str*)post); if (postdata == NULL) { ERR("Curl: No memory left\n"); res = -1; goto error; } LM_DBG("***** #### ***** CURL POST data: %s Content-type %s\n", postdata, contenttype); } memset(&query_params, 0, sizeof(curl_query_t)); query_params.username = conn->username; query_params.secret = conn->password; query_params.authmethod = conn->authmethod; query_params.contenttype = contenttype ? (char*)contenttype : "text/plain"; query_params.post = postdata; query_params.clientcert = conn->clientcert; query_params.clientkey = conn->clientkey; query_params.cacert = default_tls_cacert; query_params.ciphersuites = conn->ciphersuites; query_params.tlsversion = conn->tlsversion; query_params.verify_peer = conn->verify_peer; query_params.verify_host = conn->verify_host; query_params.timeout = conn->timeout; query_params.http_follow_redirect = conn->http_follow_redirect; query_params.keep_connections = conn->keep_connections; query_params.oneline = 0; query_params.maxdatasize = maxdatasize; query_params.http_proxy_port = conn->http_proxy_port; query_params.failovercon = conn->failover.s ? as_asciiz(&conn->failover) : NULL; query_params.pconn = pconn; if (conn->http_proxy) { query_params.http_proxy = conn->http_proxy; LM_DBG("****** ##### CURL proxy [%s] \n", query_params.http_proxy); } else { LM_DBG("**** Curl HTTP_proxy not set \n"); } res = curL_query_url(_m, urlbuf, result, &query_params); if (res > 1000 && conn->failover.s) { int counter = failover + 1; if (counter >= 2) { LM_DBG("**** No more failovers - returning failure\n"); return (res - 1000); } /* Time for failover */ return curl_con_query_url_f(_m, &conn->failover, url, result, contenttype, post, counter); } LM_DBG("***** #### ***** CURL DONE : %s \n", urlbuf); error: if (urlbuf != NULL) { pkg_free(urlbuf); } if (postdata != NULL) { pkg_free(postdata); } return res; }
static int mod_init(void) { char *dname_src, *bname_src; int i; PyObject *sys_path, *pDir, *pModule, *pFunc, *pArgs; PyThreadState *mainThreadState; dname_src = as_asciiz(&script_name); bname_src = as_asciiz(&script_name); if(dname_src==NULL || bname_src==NULL) { LM_ERR("no more pkg memory\n"); return -1; } dname = strdup(dirname(dname_src)); if (strlen(dname) == 0) dname = "."; bname = strdup(basename(bname_src)); i = strlen(bname); if (bname[i - 1] == 'c' || bname[i - 1] == 'o') i -= 1; if (bname[i - 3] == '.' && bname[i - 2] == 'p' && bname[i - 1] == 'y') { bname[i - 3] = '\0'; } else { LM_ERR("%s: script_name doesn't look like a python script\n", script_name.s); return -1; } Py_Initialize(); PyEval_InitThreads(); mainThreadState = PyThreadState_Get(); format_exc_obj = InitTracebackModule(); if (format_exc_obj == NULL || !PyCallable_Check(format_exc_obj)) { Py_XDECREF(format_exc_obj); PyEval_ReleaseLock(); return -1; } sys_path = PySys_GetObject("path"); /* PySys_GetObject doesn't pass reference! No need to DEREF */ if (sys_path == NULL) { if (!PyErr_Occurred()) PyErr_Format(PyExc_AttributeError, "'module' object 'sys' has no attribute 'path'"); python_handle_exception("mod_init"); Py_DECREF(format_exc_obj); PyEval_ReleaseLock(); return -1; } pDir = PyString_FromString(dname); if (pDir == NULL) { if (!PyErr_Occurred()) PyErr_Format(PyExc_AttributeError, "PyString_FromString() has failed"); python_handle_exception("mod_init"); Py_DECREF(format_exc_obj); PyEval_ReleaseLock(); return -1; } PyList_Insert(sys_path, 0, pDir); Py_DECREF(pDir); if (ap_init_modules() != 0) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_AttributeError, "init_modules() has failed"); python_handle_exception("mod_init"); Py_DECREF(format_exc_obj); PyEval_ReleaseLock(); return -1; } if (python_msgobj_init() != 0) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_AttributeError, "python_msgobj_init() has failed"); python_handle_exception("mod_init"); Py_DECREF(format_exc_obj); PyEval_ReleaseLock(); return -1; } pModule = PyImport_ImportModule(bname); if (pModule == NULL) { if (!PyErr_Occurred()) PyErr_Format(PyExc_ImportError, "No module named '%s'", bname); python_handle_exception("mod_init"); Py_DECREF(format_exc_obj); PyEval_ReleaseLock(); return -1; } pkg_free(dname_src); pkg_free(bname_src); pFunc = PyObject_GetAttrString(pModule, mod_init_fname.s); Py_DECREF(pModule); /* pFunc is a new reference */ if (pFunc == NULL) { if (!PyErr_Occurred()) PyErr_Format(PyExc_AttributeError, "'module' object '%s' has no attribute '%s'", bname, mod_init_fname.s); python_handle_exception("mod_init"); Py_DECREF(format_exc_obj); Py_XDECREF(pFunc); PyEval_ReleaseLock(); return -1; } if (!PyCallable_Check(pFunc)) { if (!PyErr_Occurred()) PyErr_Format(PyExc_AttributeError, "module object '%s' has is not callable attribute '%s'", bname, mod_init_fname.s); python_handle_exception("mod_init"); Py_DECREF(format_exc_obj); Py_XDECREF(pFunc); PyEval_ReleaseLock(); return -1; } pArgs = PyTuple_New(0); if (pArgs == NULL) { python_handle_exception("mod_init"); Py_DECREF(format_exc_obj); Py_DECREF(pFunc); PyEval_ReleaseLock(); return -1; } handler_obj = PyObject_CallObject(pFunc, pArgs); Py_XDECREF(pFunc); Py_XDECREF(pArgs); if (handler_obj == Py_None) { if (!PyErr_Occurred()) PyErr_Format(PyExc_TypeError, "Function '%s' of module '%s' has returned None. Should be a class instance.", mod_init_fname.s, bname); python_handle_exception("mod_init"); Py_DECREF(format_exc_obj); PyEval_ReleaseLock(); return -1; } if (PyErr_Occurred()) { python_handle_exception("mod_init"); Py_XDECREF(handler_obj); Py_DECREF(format_exc_obj); PyEval_ReleaseLock(); return -1; } if (handler_obj == NULL) { LM_ERR("PyObject_CallObject() returned NULL but no exception!\n"); if (!PyErr_Occurred()) PyErr_Format(PyExc_TypeError, "Function '%s' of module '%s' has returned not returned object. Should be a class instance.", mod_init_fname.s, bname); python_handle_exception("mod_init"); Py_DECREF(format_exc_obj); PyEval_ReleaseLock(); return -1; } myThreadState = PyThreadState_New(mainThreadState->interp); PyEval_ReleaseLock(); return 0; }
/* Encode branch info from str */ static inline int decode_branch_info(char *info, str *uri, str *dst, str *path, struct socket_info **sock, unsigned int *flags) { str s, host; int port, proto; char *pos, *at, *tmp; if (info == NULL) { ERR("decode_branch_info: Invalid input string.\n"); return 0; } /* Reset or return arguments to sane defaults */ uri->s = 0; uri->len = 0; dst->s = 0; dst->len = 0; path->s = 0; path->len = 0; *sock = NULL; *flags = 0; /* Make sure that we have at least a non-empty URI string, it is fine if * everything else is missing, but we need at least the URI. */ uri->s = info; if ((pos = strchr(info, '\n')) == NULL) { uri->len = strlen(info); /* We don't even have the URI string, this is bad, report an * error. */ if (uri->len == 0) goto uri_missing; return 1; } uri->len = pos - info; if (uri->len == 0) goto uri_missing; /* If we get here we have at least the branch URI, now try to parse as * much as you can. All output variable have been initialized above, so it * is OK if any of the fields are missing from now on. */ dst->s = at = pos + 1; if ((pos = strchr(at, '\n')) == NULL) { dst->len = strlen(dst->s); return 1; } dst->len = pos - at; path->s = at = pos + 1; if ((pos = strchr(at, '\n')) == NULL) { path->len = strlen(path->s); return 1; } path->len = pos - at; s.s = at = pos + 1; if ((pos = strchr(at, '\n')) == NULL) { /* No LF found, that means we take the string till the final zero * termination character and pass it directly to parse_phostport * without making a zero-terminated copy. */ tmp = s.s; s.len = strlen(s.s); } else { /* Our string is terminated by LF, so we need to make a * zero-terminated copy of the string before we pass it to * parse_phostport. */ s.len = pos - at; if ((tmp = as_asciiz(&s)) == NULL) { ERR("No memory left\n"); return 0; } } if (s.len) { if (parse_phostport(tmp, &host.s, &host.len, &port, &proto) != 0) { LM_ERR("parsing of socket info <%s> failed\n", tmp); if (pos) pkg_free(tmp); return 0; } *sock = grep_sock_info(&host, (unsigned short)port, (unsigned short)proto); if (*sock == 0) { LM_ERR("invalid socket <%s>\n", tmp); if (pos) pkg_free(tmp); return 0; } } if (pos) pkg_free(tmp); else return 1; s.s = at = pos + 1; if ((pos = strchr(at, '\n')) == NULL) s.len = strlen(s.s); else s.len = pos - s.s; if (s.len) { if (str2int(&s, flags) != 0) { LM_ERR("failed to decode flags <%.*s>\n", STR_FMT(&s)); return 0; } } return 1; uri_missing: ERR("decode_branch_info: Cannot decode branch URI.\n"); return 0; }