68 #include <libxml/tree.h> 69 #include <libxml/parser.h> 70 #include <libxml/xpath.h> 71 #include <libxml/xpathInternals.h> 90 #ifdef HAVE_SECURITY_PAM_APPL_H 91 #include <security/pam_appl.h> 95 #define SENDSMS_DEFAULT_CHARS "0123456789 +-" 97 #define O_DESTROY(a) { if(a) octstr_destroy(a); a = NULL; } 99 #define ACCOUNT_MAX_LEN 64 102 #define HTTP_MAX_RETRIES 0 103 #define HTTP_RETRY_DELAY 10 104 #define HTTP_MAX_PENDING 512 197 debug(
"sms.http", 0,
"No client - multi-send or ACK to pull-reply");
206 switch (
msg->ack.nack) {
221 answer =
octstr_create(
"Temporal failure, try again later.");
224 error(0,
"Strange reply from bearerbox!");
226 answer =
octstr_create(
"Temporal failure, try again later.");
250 start = t = time(NULL);
256 error(0,
"Bearerbox is gone, restarting");
263 else if (
msg == NULL)
268 info(0,
"Bearerbox told us to die");
271 info(0,
"Bearerbox told us to restart");
289 warning(0,
"Received other message than sms/admin, ignoring!");
293 secs = difftime(time(NULL),
start);
294 info(0,
"Received (and handled?) %d requests in %d seconds " 295 "(%.2f per second)", total, secs, (
float)total / secs);
320 unsigned long msg_sequence, msg_count;
333 info(0,
"No reply sent, denied.");
396 if (header == NULL && footer == NULL && suffix == NULL && split_chars == NULL) {
400 list =
sms_split(
msg, header, footer, suffix, split_chars, catenate,
405 debug(
"sms", 0,
"message length %ld, sending %ld messages",
529 long prefix_end, suffix_start;
531 if (prefix == NULL || suffix == NULL)
534 if (prefix_end == -1)
538 if (suffix_start == -1)
548 Octstr **smsc,
int *mclass,
int *mwi,
549 int *
coding,
int *compress,
550 int *validity,
int *deferred,
592 warning(0,
"Invalid UDH received in X-Kannel-UDH");
659 Octstr **smsc,
int *mclass,
int *mwi,
660 int *
coding,
int *compress,
661 int *validity,
int *deferred,
667 xmlDocPtr doc = NULL;
668 xmlXPathContextPtr xpathCtx = NULL;
669 xmlXPathObjectPtr xpathObj = NULL;
684 xpathCtx = xmlXPathNewContext(doc);
685 if (xpathCtx == NULL) {
686 error(0,
"XMLParsing: Could not create xpath context.");
691 #define XPATH_SEARCH_OCTSTR(path, var, nostrip) \ 693 xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); \ 694 if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) { \ 695 xml_string = xmlXPathCastToString(xpathObj); \ 697 var = octstr_create((const char*) xml_string); \ 699 octstr_strip_blanks(var); \ 700 xmlFree(xml_string); \ 702 if (xpathObj != NULL) xmlXPathFreeObject(xpathObj); \ 705 #define XPATH_SEARCH_NUMBER(path, var) \ 707 xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); \ 708 if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) { \ 709 var = xmlXPathCastToNumber(xpathObj); \ 711 if (xpathObj != NULL) xmlXPathFreeObject(xpathObj); \ 715 xpathObj = xmlXPathEvalExpression(BAD_CAST
"/message/submit/from", xpathCtx);
716 if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
717 xmlXPathFreeObject(xpathObj);
738 xpathObj = xmlXPathEvalExpression(BAD_CAST
"/message/submit/da/number/text()", xpathCtx);
739 if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
743 for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) {
744 if (xpathObj->nodesetval->nodeTab[i]->type != XML_TEXT_NODE)
746 xml_string = xmlXPathCastNodeToString(xpathObj->nodesetval->nodeTab[i]);
747 tmp =
octstr_create((
const char*) xpathObj->nodesetval->nodeTab[i]->content);
753 if (xpathObj != NULL)
754 xmlXPathFreeObject(xpathObj);
805 if (doc->encoding != NULL)
833 if (xpathCtx != NULL)
834 xmlXPathFreeContext(xpathCtx);
842 int mclass,
int mwi,
int coding,
int compress,
843 int validity,
int deferred,
848 msg->sms.msgdata = replytext;
849 msg->sms.time = time(NULL);
859 warning(0,
"Tried to change dlr_url to '%s', denied.",
868 msg->sms.smsc_id = smsc;
870 warning(0,
"Tried to change SMSC to '%s', denied.",
881 warning(0,
"Tried to change sender to '%s', denied.",
889 msg->sms.receiver = to;
891 warning(0,
"Tried to change receiver to '%s', denied.",
899 msg->sms.udhdata = udh;
901 warning(0,
"Tried to set UDH field, denied.");
907 msg->sms.mclass = mclass;
909 warning(0,
"Tried to set MClass field, denied.");
915 warning(0,
"Tried to set PID field, denied.");
921 warning(0,
"Tried to set RPI field, denied.");
925 msg->sms.alt_dcs = alt_dcs;
927 warning(0,
"Tried to set Alt-DCS field, denied.");
933 warning(0,
"Tried to set MWI field, denied.");
939 warning(0,
"Tried to set Coding field, denied.");
943 msg->sms.compress = compress;
945 warning(0,
"Tried to set Compress field, denied.");
956 msg->sms.validity = validity * 60 + time(NULL);
958 warning(0,
"Tried to change validity to '%d', denied.", validity);
962 msg->sms.deferred = deferred * 60 + time(NULL);
964 warning(0,
"Tried to change deferred to '%d', denied.", deferred);
976 warning(0,
"Tried to change account to '%s', denied.",
983 msg->sms.binfo = binfo;
985 warning(0,
"Tried to change billing info to '%s', denied.",
992 msg->sms.priority = priority;
994 warning(0,
"Tried to change priority to '%d', denied.", priority);
1001 warning(0,
"Tried to set Meta-Data field, denied.");
1033 debug(
"sms.http",0,
"HTTP: Queue contains %ld outstanding requests",
1048 debug(
"sms.http",0,
"HTTP: Retrying request <%s> (%ld/%ld)",
1066 Octstr *final_url, *req_body, *
type, *replytext;
1067 List *reply_headers;
1074 Octstr *text_html, *text_plain, *text_wml, *text_xml;
1077 unsigned int queued;
1083 int validity, deferred, priority;
1089 octet_stream =
octstr_imm(
"application/octet-stream");
1100 mclass = mwi = compress = pid = alt_dcs = rpi =
dlr_mask =
1122 NULL, NULL, &smsc, &mclass, &mwi,
1123 &
coding, &compress, &validity,
1125 &
account, &pid, &alt_dcs, &rpi,
1132 NULL, NULL, &smsc, &mclass, &mwi,
1133 &
coding, &compress, &validity,
1135 &
account, &pid, &alt_dcs, &rpi,
1142 &
from, &to, &udh, NULL, NULL, &smsc, &mclass, &mwi,
1152 NULL, NULL, &smsc, &mclass, &mwi,
1153 &
coding, &compress, &validity,
1155 &
account, &pid, &alt_dcs, &rpi,
1183 req_headers, req_body,
retries);
1190 if (final_url == NULL)
1192 if (reply_body == NULL)
1201 alog(
"SMS HTTP-request sender:%s request: '%s' url: '%s' reply: %d '%s'",
1220 error(0,
"failed to send message to phone");
1243 Octstr *pattern, *xml, *tmp;
1244 List *request_headers;
1264 debug(
"sms", 0,
"formatted text answer: <%s>",
1267 alog(
"SMS request sender:%s request: '%s' fixed answer: '%s'",
1276 alog(
"SMS request sender:%s request: '%s' file answer: '%s'",
1284 debug(
"sms.exec", 0,
"executing sms-service '%s'",
1291 alog(
"SMS request sender:%s request: '%s' file answer: '%s'",
1296 error(0,
"popen failed for '%s': %d: %s",
1309 http_header_add(request_headers,
"User-Agent", GW_NAME
"/" GW_VERSION);
1310 if (trans != NULL) {
1329 http_header_add(request_headers,
"User-Agent", GW_NAME
"/" GW_VERSION);
1331 http_header_add(request_headers,
"Content-Type",
"application/octet-stream");
1333 http_header_add(request_headers,
"Content-Type",
"text/plain; charset=\"UTF-16BE\"");
1337 if (
msg->sms.charset) {
1354 sprintf(p,
"%04d-%02d-%02d %02d:%02d:%02d",
1355 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
1356 tm.tm_hour, tm.tm_min, tm.tm_sec);
1360 sprintf(p,
"%04d-%02d-%02d %02d:%02d:%02d",
1361 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
1362 tm.tm_hour, tm.tm_min, tm.tm_sec);
1444 request_headers,
msg->sms.msgdata, 0);
1447 msg->sms.msgdata, 1,
id, NULL);
1459 #define OCTSTR_APPEND_XML(xml, tag, text) \ 1460 octstr_format_append(xml, " \t\t<" tag ">%s</" tag ">\n", (text?octstr_get_cstr(text):"")) 1462 #define OCTSTR_APPEND_XML_OCTSTR(xml, tag, text) \ 1464 xmlDocPtr tmp_doc = xmlNewDoc(BAD_CAST "1.0"); \ 1465 xmlChar *xml_escaped = NULL; \ 1466 if (text != NULL) xml_escaped = xmlEncodeEntitiesReentrant(tmp_doc, BAD_CAST octstr_get_cstr(text)); \ 1467 octstr_format_append(xml, " \t\t<" tag ">%s</" tag ">\n", (xml_escaped != NULL ? (char*)xml_escaped : "")); \ 1468 if (xml_escaped != NULL) xmlFree(xml_escaped); \ 1469 xmlFreeDoc(tmp_doc); \ 1472 #define OCTSTR_APPEND_XML_NUMBER(xml, tag, value) \ 1473 octstr_format_append(xml, " \t\t<" tag ">%ld</" tag ">\n", (long) value) 1476 http_header_add(request_headers,
"User-Agent", GW_NAME
"/" GW_VERSION);
1479 "text/xml; charset=\"ISO-8859-1\"");
1483 if(
msg->sms.charset) {
1493 sprintf(p,
"%04d-%02d-%02d %02d:%02d:%02d",
1494 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
1495 tm.tm_hour, tm.tm_min, tm.tm_sec);
1585 "<day>%02d</day><hour>%02d</hour><minute>%02d</minute>" 1586 "<second>%02d</second><timezone>0</timezone>",
1587 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
1588 tm.tm_hour, tm.tm_min, tm.tm_sec);
1620 if (
msg->sms.msgdata != NULL)
1623 msg->sms.msgdata = xml;
1627 request_headers,
msg->sms.msgdata, 0);
1630 msg->sms.msgdata, 1,
id, NULL);
1638 error(0,
"Got URL translation type SENDSMS for incoming message.");
1639 alog(
"SMS request sender:%s request: '%s' FAILED bad translation",
1648 alog(
"SMS request sender:%s request: '%s' FAILED unknown translation",
1661 Msg *
msg, *mack, *reply_msg;
1680 info(0,
"MO message converted from UCS-2 to UTF-8");
1691 error(0,
"smsbox_req_thread: no sender/receiver, dump follows:");
1698 mack->ack.time =
msg->sms.time;
1709 mack->ack.time =
msg->sms.time;
1717 if (
msg->sms.service == NULL || (
msg->sms.service != NULL &&
1725 info(0,
"Starting delivery report <%s> from <%s>",
1731 if (trans == NULL) {
1732 warning(0,
"No translation found for <%s> from <%s> to <%s>",
1740 info(0,
"Starting to service <%s> from <%s> to <%s>",
1752 if (tmp != NULL &&
msg->sms.coding ==
DC_7BIT) {
1754 error(0,
"Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
1778 msg->sms.receiver = tmp;
1784 if (
msg->sms.service == NULL && trans != NULL)
1790 error(0,
"request failed");
1799 reply_msg->sms.sms_type =
mt_reply;
1800 reply_msg->sms.sender =
msg->sms.sender;
1801 msg->sms.sender = NULL;
1802 reply_msg->sms.receiver =
msg->sms.receiver;
1803 msg->sms.receiver = NULL;
1804 reply_msg->sms.smsc_id =
msg->sms.smsc_id;
1805 msg->sms.smsc_id = NULL;
1806 reply_msg->sms.msgdata =
reply;
1807 reply_msg->sms.time = time(NULL);
1811 error(0,
"request_thread: failed");
1830 #ifdef HAVE_SECURITY_PAM_APPL_H 1836 typedef const struct pam_message pam_message_type;
1838 static const char *PAM_username;
1839 static const char *PAM_password;
1841 static int PAM_conv (
int num_msg, pam_message_type **
msg,
1842 struct pam_response **resp,
1845 int count = 0, replies = 0;
1846 struct pam_response *repl = NULL;
1847 int size =
sizeof(
struct pam_response);
1850 repl = gw_realloc(repl, size); \ 1851 size += sizeof(struct pam_response) 1852 #define COPY_STRING(s) (s) ? gw_strdup(s) : NULL 1854 for (count = 0; count < num_msg; count++) {
1855 switch (
msg[count]->msg_style) {
1856 case PAM_PROMPT_ECHO_ON:
1858 repl[replies].resp_retcode = PAM_SUCCESS;
1859 repl[replies++].resp = COPY_STRING(PAM_username);
1863 case PAM_PROMPT_ECHO_OFF:
1865 repl[replies].resp_retcode = PAM_SUCCESS;
1866 repl[replies++].resp = COPY_STRING(PAM_password);
1871 warning(0,
"unexpected message from PAM: %s",
msg[count]->
msg);
1877 error(0,
"unexpected error from PAM: %s",
msg[count]->
msg);
1879 return PAM_CONV_ERR;
1887 static struct pam_conv PAM_conversation = {
1893 static int authenticate(
const char *login,
const char *passwd)
1898 PAM_username = login;
1899 PAM_password = passwd;
1901 pam_error = pam_start(
"kannel", login, &PAM_conversation, &pamh);
1902 if (pam_error != PAM_SUCCESS ||
1903 (pam_error = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
1904 pam_end(pamh, pam_error);
1907 pam_end(pamh, PAM_SUCCESS);
1908 info(0,
"sendsms used by <%s>", login);
1918 static int pam_authorise_user(
List *list)
1920 Octstr *val, *user = NULL;
1934 result = authenticate(login, pwd);
1969 int mclass,
int mwi,
int coding,
int compress,
1970 int validity,
int deferred,
1977 Octstr *returnerror = NULL;
1979 Octstr *stored_uuid = NULL;
1980 List *failed_id = NULL;
1981 List *allowed = NULL;
1982 List *denied = NULL;
1983 int no_recv, ret = 0, i;
2001 returnerror =
octstr_create(
"UDH field misformed, rejected");
2005 returnerror =
octstr_create(
"UDH field is too long, rejected");
2020 for (i = 0; i < no_recv; i++) {
2027 info(0,
"Illegal characters in 'to' string ('%s') vs '%s'",
2038 info(0,
"Number <%s> is not in white-list, message discarded",
2047 info(0,
"Number <%s> is not in white-list-regex, message discarded",
2056 info(0,
"Number <%s> is in black-list, message discarded",
2065 info(0,
"Number <%s> is in black-list-regex, message discarded",
2074 info(0,
"Number <%s> is not in global white-list, message discarded",
2083 info(0,
"Number <%s> is not in global white-list-regex, message discarded",
2092 info(0,
"Number <%s> is in global black-list, message discarded",
2101 info(0,
"Number <%s> is in global black-list-regex, message discarded",
2151 returnerror =
octstr_create(
"Number(s) has/have been denied by white/black lists, " 2152 "or allowed/denied rules.");
2166 returnerror =
octstr_create(
"Sender missing and no global set, rejected");
2170 info(0,
"sendsms sender:<%s:%s> (%s) to:<%s> msg:<%s>",
2191 returnerror =
octstr_create(
"Account field misformed or too long, rejected");
2203 returnerror =
octstr_create(
"DLR-URL field misformed, rejected");
2214 returnerror =
octstr_create(
"DLR-URL field misformed, rejected");
2222 warning(0,
"DLR-URL with https but SSL not supported, url is <%s>",
2233 if (dlr_mask < -1 || dlr_mask > 66) {
2234 returnerror =
octstr_create(
"DLR-Mask field misformed, rejected");
2239 if (mclass < -1 || mclass > 3) {
2240 returnerror =
octstr_create(
"MClass field misformed, rejected");
2243 msg->sms.mclass = mclass;
2245 if (pid < -1 || pid > 255) {
2246 returnerror =
octstr_create(
"PID field misformed, rejected");
2251 if (rpi < -1 || rpi > 2) {
2252 returnerror =
octstr_create(
"RPI field misformed, rejected");
2257 if (alt_dcs < -1 || alt_dcs > 1) {
2258 returnerror =
octstr_create(
"Alt-DCS field misformed, rejected");
2261 msg->sms.alt_dcs = alt_dcs;
2263 if (mwi < -1 || mwi > 7) {
2264 returnerror =
octstr_create(
"MWI field misformed, rejected");
2269 if (coding < -1 || coding > 2) {
2270 returnerror =
octstr_create(
"Coding field misformed, rejected");
2275 if (compress < -1 || compress > 1) {
2276 returnerror =
octstr_create(
"Compress field misformed, rejected");
2279 msg->sms.compress = compress;
2289 if (validity < -1) {
2290 returnerror =
octstr_create(
"Validity field misformed, rejected");
2293 msg->sms.validity = validity * 60 + time(NULL);
2295 if (deferred < -1) {
2296 returnerror =
octstr_create(
"Deferred field misformed, rejected");
2299 msg->sms.deferred = deferred * 60 + time(NULL);
2302 returnerror =
octstr_create(
"Priority field misformed, rejected");
2308 info(0,
"send-sms request priority ignored, " 2313 info(0,
"send-sms request priority ignored, " 2316 msg->sms.priority = priority;
2325 info(0,
"send-sms request smsc id ignored, " 2326 "as smsc id forced to %s",
2333 msg->sms.smsc_id = NULL;
2336 returnerror =
octstr_create(
"Charset or body misformed, rejected");
2342 msg->sms.receiver = NULL;
2362 msg->sms.time = time(NULL);
2371 alog(
"send-SMS request added - sender:%s:%s %s target:%s request: '%s'",
2380 goto transmit_error;
2422 error(0,
"sendsms_request: failed");
2465 warning(0,
"Non-allowed connect tried by <%s> from <%s>, ignored",
2482 Octstr *pass, *user = NULL;
2496 #ifdef HAVE_SECURITY_PAM_APPL_H 2501 if (pam_authorise_user(list))
2524 int dlr_mask, mclass, mwi,
coding, compress, validity, deferred, pid;
2525 int alt_dcs, rpi, priority;
2528 mclass = mwi =
coding = compress = validity = deferred =
dlr_mask =
2550 warning(0,
"<dlrurl> field used and deprecated. Please use dlr-url instead.");
2553 if(tmp_string == NULL) {
2555 if(tmp_string != NULL)
2556 warning(0,
"<dlrmask> field used and deprecated. Please use dlr-mask instead.");
2558 if(tmp_string != NULL)
2562 if(tmp_string != NULL)
2566 if(tmp_string != NULL)
2570 if(tmp_string != NULL)
2574 if(tmp_string != NULL)
2578 if(tmp_string != NULL)
2582 if(tmp_string != NULL)
2586 if(tmp_string != NULL)
2590 if(tmp_string != NULL)
2594 if(tmp_string != NULL)
2598 if(tmp_string != NULL)
2607 error(0,
"%s got insufficient headers (<to> is NULL)",
2615 return octstr_create(
"Empty receiver number not allowed, rejected");
2619 smsc, mclass, mwi,
coding, compress, validity,
2621 pid, alt_dcs, rpi, NULL, binfo, priority,
meta_data);
2637 Octstr *text_html, *text_plain, *text_wml, *text_xml, *octet_stream;
2641 int pid, alt_dcs, rpi, priority;
2647 octet_stream =
octstr_imm(
"application/octet-stream");
2649 user = pass = ret =
type = NULL;
2652 mclass = mwi =
coding = compress = validity = deferred =
dlr_mask =
2662 &user, &pass, &smsc, &mclass, &mwi,
2663 &
coding, &compress, &validity,
2665 &
account, &pid, &alt_dcs, &rpi,
2670 &user, &pass, &smsc, &mclass, &mwi,
2671 &
coding, &compress, &validity,
2673 &
account, &pid, &alt_dcs, &rpi,
2677 &
from, &to, &udh, &user, &pass, &smsc, &mclass,
2678 &mwi, &
coding, &compress, &validity, &deferred,
2693 else if (to == NULL && tolist == NULL) {
2694 error(0,
"%s got insufficient headers (<to> and <tolist> are NULL)",
2697 ret =
octstr_create(
"Missing receiver(s) number(s), rejected");
2699 else if (to != NULL &&
octstr_len(to) == 0) {
2702 ret =
octstr_create(
"Empty receiver number not allowed, rejected");
2706 octstr_imm(
"application/octet-stream")) == 0) {
2722 udh, smsc, mclass, mwi,
coding, compress,
2831 Octstr *stored_uuid = NULL;
2838 id = phonenumber = smsc =
account = NULL;
2866 return octstr_create(
"Sender missing and no global set, rejected");
2876 debug(
"sms", 0,
"OTA service with XML document");
2892 phonenumber, sec, pin)) < 0) {
2899 return octstr_create(
"Erroneous ota source, cannot compile\n");
2940 error(0,
"%s can't find any ota-setting or ota-bookmark group with ota-id '%s'.",
2946 return octstr_create(
"Missing ota-setting or ota-bookmark group.");
2965 info(0,
"send-sms request smsc id ignored, as smsc id forced to %s",
2972 msg->sms.smsc_id = NULL;
2991 error(0,
"sendota_request: failed");
3022 Octstr *stored_uuid = NULL;
3028 id =
from = to = user = pass = smsc = NULL;
3029 doc_type = ota_doc = sec = pin = NULL;
3087 else if (to == NULL) {
3106 ret =
octstr_create(
"Sender missing and no global set, rejected");
3116 octstr_imm(
"application/x-wap-prov.browser-settings")) == 0) {
3120 octstr_imm(
"application/x-wap-prov.browser-bookmarks")) == 0) {
3124 octstr_imm(
"text/vnd.wap.connectivity-xml")) == 0) {
3128 if (doc_type == NULL) {
3150 ret =
octstr_create(
"Erroneous ota source, cannot compile\n");
3159 info(0,
"send-sms request smsc id ignored, as smsc id forced to %s",
3166 msg->sms.smsc_id = NULL;
3180 error(0,
"sendota_request: failed");
3214 ip =
url = body = answer = NULL;
3221 info(0,
"smsbox: Got HTTP request <%s> from <%s>",
3264 debug(
"sms.http", 0,
"Status: %d Answer: <%s>",
status,
3276 debug(
"sms.http", 0,
"Delayed reply - wait for bearerbox");
3301 error(0,
"SIGINT received, aborting program...");
3307 warning(0,
"SIGHUP received, catching and re-opening logs");
3317 warning(0,
"SIGQUIT received, reporting memory usage.");
3325 struct sigaction act;
3328 sigemptyset(&act.sa_mask);
3330 sigaction(SIGINT, &act, NULL);
3331 sigaction(SIGTERM, &act, NULL);
3332 sigaction(SIGQUIT, &act, NULL);
3333 sigaction(SIGHUP, &act, NULL);
3334 sigaction(SIGPIPE, &act, NULL);
3345 Octstr *http_proxy_host = NULL;
3346 long http_proxy_port = -1;
3347 int http_proxy_ssl = 0;
3348 List *http_proxy_exceptions = NULL;
3349 Octstr *http_proxy_username = NULL;
3350 Octstr *http_proxy_password = NULL;
3351 Octstr *http_proxy_exceptions_regex = NULL;
3380 http_proxy_host =
cfg_get(grp,
3382 http_proxy_username =
cfg_get(grp,
3384 http_proxy_password =
cfg_get(grp,
3388 http_proxy_exceptions_regex =
cfg_get(grp,
3400 panic(0,
"No 'smsbox' group in configuration");
3426 "as an SMS message.");
3493 if (logfile != NULL) {
3494 info(0,
"Starting to log to file %s level %ld",
3516 info(0,
"Service global sender set as '%s'",
3546 error(0,
"Failed to open HTTP socket, ignoring it");
3548 panic(0,
"Failed to open HTTP socket");
3571 if (http_proxy_host != NULL && http_proxy_port > 0) {
3573 http_proxy_exceptions, http_proxy_username,
3574 http_proxy_password, http_proxy_exceptions_regex);
3588 if (strcmp(argv[i],
"-H")==0 || strcmp(argv[i],
"--tryhttp")==0) {
3608 if (argv[cf_index] == NULL)
3624 info(0,
"Using HTTP request queueing with %ld retries, %lds delay.",
3628 debug(
"sms", 0,
"----------------------------------------------");
3629 debug(
"sms", 0, GW_NAME
" smsbox version %s starting", GW_VERSION);
3633 panic(0,
"urltrans_create failed");
3635 panic(0,
"urltrans_add_cfg failed");
3661 info(0, GW_NAME
"Could not start heartbeat.");
3667 info(0, GW_NAME
" smsbox terminating.");
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
int urltrans_add_cfg(URLTranslationList *trans, Cfg *cfg)
static void get_x_kannel_from_xml(int requesttype, Octstr **type, Octstr **body, List *headers, Octstr **from, Octstr **to, Octstr **udh, Octstr **user, Octstr **pass, Octstr **smsc, int *mclass, int *mwi, int *coding, int *compress, int *validity, int *deferred, int *dlr_mask, Octstr **dlr_url, Octstr **account, int *pid, int *alt_dcs, int *rpi, List **tolist, Octstr **charset, Octstr **binfo, int *priority, Octstr **meta_data)
void gw_timerset_destroy(Timerset *set)
void msg_dump(Msg *msg, int level)
regex_t * urltrans_black_list_regex(URLTranslation *t)
void error(int err, const char *fmt,...)
void info(int err, const char *fmt,...)
Octstr * urltrans_deny_ip(URLTranslation *t)
#define OCTSTR_APPEND_XML(xml, tag, text)
URLTranslation * urltrans_find(URLTranslationList *trans, Msg *msg)
Octstr * urltrans_suffix(URLTranslation *t)
Msg * msg_duplicate(Msg *msg)
static URLTranslation * default_authorise_user(List *list, Octstr *client_ip)
#define OCTSTR_APPEND_XML_NUMBER(xml, tag, value)
Octstr * urltrans_forced_smsc(URLTranslation *t)
void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
int octstr_str_case_compare(const Octstr *ostr, const char *str)
long octstr_search_chars(const Octstr *ostr, const Octstr *chars, long pos)
Octstr * urltrans_alt_charset(URLTranslation *t)
static Octstr * reply_requestfailed
static Octstr * smsbox_req_handle(URLTranslation *t, Octstr *client_ip, HTTPClient *client, Octstr *from, Octstr *to, Octstr *text, Octstr *charset, Octstr *udh, Octstr *smsc, int mclass, int mwi, int coding, int compress, int validity, int deferred, int *status, int dlr_mask, Octstr *dlr_url, Octstr *account, int pid, int alt_dcs, int rpi, List *receiver, Octstr *binfo, int priority, Octstr *meta_data)
Numhash * urltrans_black_list(URLTranslation *t)
int urltrans_forced_priority(URLTranslation *t)
void http_header_add(List *headers, char *name, char *contents)
static Octstr * method_name
regex_t * urltrans_white_list_regex(URLTranslation *t)
gw_assert(wtls_machine->packet_to_send !=NULL)
Octstr * urltrans_footer(URLTranslation *t)
void http_caller_signal_shutdown(HTTPCaller *caller)
void dict_put(Dict *dict, Octstr *key, void *value)
void counter_destroy(Counter *counter)
static void obey_request_thread(void *arg)
void gwlist_append(List *list, void *item)
static void strip_prefix_and_suffix(Octstr *html, Octstr *prefix, Octstr *suffix)
Octstr * urltrans_default_smsc(URLTranslation *t)
Octstr * urltrans_password(URLTranslation *t)
#define XPATH_SEARCH_OCTSTR(path, var, nostrip)
void semaphore_destroy(Semaphore *semaphore)
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
struct tm gw_gmtime(time_t t)
List * cfg_get_list(CfgGroup *grp, Octstr *varname)
static void read_messages_from_bearerbox(void)
void gwlist_produce(List *list, void *item)
static long sms_max_length
static long max_http_retries
long gwlist_len(List *list)
int restart_box(char **argv)
int octstr_recode(Octstr *tocode, Octstr *fromcode, Octstr *orig)
static void client(int port)
Octstr * octstr_read_pipe(FILE *f)
static HTTPCaller * caller
Octstr * urltrans_allowed_prefix(URLTranslation *t)
void * gwlist_get(List *list, long pos)
Octstr * urltrans_split_chars(URLTranslation *t)
Timer * gw_timer_create(Timerset *set, List *outputlist, void(*callback)(void *))
Octstr * urltrans_faked_sender(URLTranslation *t)
static Octstr * sendota_url
static Octstr * smsbox_req_sendsms(List *args, Octstr *client_ip, int *status, HTTPClient *client)
int read_from_bearerbox(Msg **msg, double seconds)
static void sendsms_thread(void *arg)
int octstr_url_decode(Octstr *ostr)
static Octstr * sendsms_url
static Dict * client_dict
#define cfg_get(grp, varname)
static List * smsbox_requests
void uuid_unparse(const uuid_t uu, char *out)
regex_t * urltrans_denied_prefix_regex(URLTranslation *t)
Octstr * urltrans_dlr_url(URLTranslation *t)
void http_header_get_content_type(List *headers, Octstr **type, Octstr **charset)
static void delayed_http_reply(Msg *msg)
static Octstr * smsbox_xmlrpc_post(List *headers, Octstr *body, Octstr *client_ip, int *status)
Octstr * urltrans_username(URLTranslation *t)
static void setup_signal_handlers(void)
unsigned long counter_decrease(Counter *counter)
int gwthread_shouldhandlesignal(int signal)
void numhash_destroy(Numhash *table)
static long outstanding_requests(void)
Octstr * urltrans_denied_prefix(URLTranslation *t)
void octstr_strip_blanks(Octstr *text)
static Octstr * smsbox_sendota_post(List *headers, Octstr *body, Octstr *client_ip, int *status, HTTPClient *client)
static regex_t * black_list_regex
#define octstr_get_cstr(ostr)
#define octstr_copy(ostr, from, len)
List * sms_split(Msg *orig, Octstr *header, Octstr *footer, Octstr *nonlast_suffix, Octstr *split_chars, int catenate, unsigned long msg_sequence, int max_messages, int max_octets)
int xmlrpc_parse_status(XMLRPCDocument *xrdoc)
void gwthread_join_every(gwthread_func_t *func)
static URLTranslation * authorise_username(Octstr *username, Octstr *password, Octstr *client_ip)
unsigned long counter_increase(Counter *counter)
static Octstr * smsbox_id
static struct pid_list * found
static Octstr * sendsms_interface
int is_allowed_ip(Octstr *allow_ip, Octstr *deny_ip, Octstr *ip)
Cfg * cfg_create(Octstr *filename)
Numhash * numhash_create(const char *seek_url)
Octstr * http_cgi_variable(List *list, char *name)
void heartbeat_stop(long hb_thread)
static long http_queue_delay
void semaphore_down(Semaphore *semaphore)
regex_t * urltrans_allowed_prefix_regex(URLTranslation *t)
void http_destroy_headers(List *headers)
static Octstr * reply_couldnotfetch
Timerset * gw_timerset_create(void)
Octstr * urltrans_header(URLTranslation *t)
void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
void http_destroy_cgiargs(List *args)
#define xmlrpc_parse_call(post_body)
void http_send_reply(HTTPClient *client, int status, List *headers, Octstr *body)
Octstr * octstr_imm(const char *cstr)
static Octstr * smsbox_sendsms_post(List *headers, Octstr *body, Octstr *client_ip, int *status, HTTPClient *client)
static Octstr * accepted_chars
void * dict_remove(Dict *dict, Octstr *key)
int does_prefix_match(Octstr *prefix, Octstr *number)
int numhash_find_number(Numhash *table, Octstr *nro)
Counter * counter_create(void)
static int check_args(int i, int argc, char **argv)
void cfg_destroy(Cfg *cfg)
static regex_t * white_list_regex
int urltrans_dlr_mask(URLTranslation *t)
void * gwlist_extract_first(List *list)
static Cfg * init_smsbox(Cfg *cfg)
static URLTranslationList * translations
void conn_config_ssl(CfgGroup *grp)
HTTPClient * http_accept_request(int port, Octstr **client_ip, Octstr **url, List **headers, Octstr **body, List **cgivars)
void octstr_delete(Octstr *ostr1, long pos, long len)
void gwlist_remove_producer(List *list)
static int send_message(URLTranslation *trans, Msg *msg)
List * http_create_empty_headers(void)
void connect_to_bearerbox(Octstr *host, int port, int ssl, Octstr *our_host)
static Octstr * xmlrpc_url
static Semaphore * max_pending_requests
static void fill_message(Msg *msg, URLTranslation *trans, Octstr *replytext, Octstr *from, Octstr *to, Octstr *udh, int mclass, int mwi, int coding, int compress, int validity, int deferred, Octstr *dlr_url, int dlr_mask, int pid, int alt_dcs, int rpi, Octstr *smsc, Octstr *account, Octstr *charset, Octstr *binfo, int priority, Octstr *meta_data)
static Timerset * timerset
#define octstr_duplicate(ostr)
#define octstr_dump(ostr, level,...)
long octstr_case_search(const Octstr *haystack, const Octstr *needle, long pos)
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
#define SENDSMS_DEFAULT_CHARS
static Octstr * reply_couldnotrepresent
int octstr_item_match(void *item, void *pattern)
void uuid_copy(uuid_t dst, const uuid_t src)
void msg_destroy(Msg *msg)
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
void warning(int err, const char *fmt,...)
List * octstr_split_words(const Octstr *ostr)
Octstr * urltrans_default_sender(URLTranslation *t)
void log_set_syslog_facility(char *facility)
Octstr * xmlrpc_get_call_name(XMLRPCDocument *call)
void alog_open(char *fname, int use_localtm, int use_markers)
Octstr * octstr_format(const char *fmt,...)
volatile sig_atomic_t restart
void octstr_destroy(Octstr *ostr)
int urltrans_omit_empty(URLTranslation *t)
char filename[FILENAME_MAX+1]
#define gwthread_create(func, arg)
static List * sendsms_reply_hdrs
int sms_charset_processing(Octstr *charset, Octstr *body, int coding)
#define octstr_create(cstr)
void octstr_destroy_item(void *os)
Octstr * html_to_sms(Octstr *html)
Octstr * urltrans_split_suffix(URLTranslation *t)
unsigned long counter_value(Counter *counter)
void gwthread_sleep(double seconds)
void log_set_syslog(const char *ident, int syslog_level)
#define SMS_PARAM_UNDEFINED
int urltrans_send_sender(URLTranslation *t)
int urltrans_type(URLTranslation *t)
static Counter * num_outstanding_requests
int urltrans_accept_x_kannel_headers(URLTranslation *t)
static Octstr * ppg_service_name
static Numhash * black_list
static URLTranslation * authorise_user(List *list, Octstr *client_ip)
#define http_receive_result(caller, status, final_url, headers, body)
void gw_timer_elapsed_destroy(Timer *timer)
Octstr * octstr_read_file(const char *filename)
void close_connection_to_bearerbox(void)
Numhash * urltrans_white_list(URLTranslation *t)
Octstr * urltrans_allow_ip(URLTranslation *t)
int http_open_port_if(int port, int ssl, Octstr *interface)
void report_versions(const char *boxname)
int log_open(char *filename, int level, enum excl_state excl)
void semaphore_up(Semaphore *semaphore)
void http_close_all_ports(void)
static Numhash * white_list
long octstr_len(const Octstr *ostr)
struct TimerItem TimerItem
void dict_destroy(Dict *dict)
#define XPATH_SEARCH_NUMBER(path, var)
long gwlist_delete_matching(List *list, void *pat, gwlist_item_matches_t *matches)
void gwlist_append_unique(List *list, void *item, int(*cmp)(void *, void *))
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
#define DEFAULT_HEARTBEAT
static Octstr * reply_emptymessage
void write_to_bearerbox(Msg *pmsg)
long heartbeat_start(hb_send_func_t *send_func, double freq, hb_load_func_t *load_func)
URLTranslationList * urltrans_create(void)
void * gwlist_consume(List *list)
static Octstr * store_uuid(Msg *msg)
void alog(const char *fmt,...)
static void signal_handler(int signum)
void http_use_proxy(Octstr *hostname, int port, int ssl, List *exceptions, Octstr *username, Octstr *password, Octstr *exceptions_regex)
URLTranslation * urltrans_find_service(URLTranslationList *trans, Msg *msg)
URLTranslation * urltrans_find_username(URLTranslationList *trans, Octstr *name)
#define xmlrpc_destroy_call(call)
void debug(const char *place, int err, const char *fmt,...)
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
void gw_timer_elapsed_start(Timer *timer, int interval, void *data)
static Octstr * smsbox_req_sendota(List *list, Octstr *client_ip, int *status, HTTPClient *client)
int octstr_hex_to_binary(Octstr *ostr)
int urltrans_max_messages(URLTranslation *t)
static int immediate_sendsms_reply
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
HTTPCaller * http_caller_create(void)
void octstr_format_append(Octstr *os, const char *fmt,...)
void gwlib_shutdown(void)
List * http_header_duplicate(List *headers)
static List * smsbox_http_requests
Msg * ota_tokenize_settings(CfgGroup *grp, Octstr *from, Octstr *receiver)
static void get_x_kannel_from_headers(List *headers, Octstr **from, Octstr **to, Octstr **udh, Octstr **user, Octstr **pass, Octstr **smsc, int *mclass, int *mwi, int *coding, int *compress, int *validity, int *deferred, int *dlr_mask, Octstr **dlr_url, Octstr **account, int *pid, int *alt_dcs, int *rpi, Octstr **binfo, int *priority, Octstr **meta_data)
void octstr_truncate(Octstr *ostr, int new_len)
static Counter * catenated_sms_counter
void http_caller_destroy(HTTPCaller *caller)
Msg * ota_tokenize_bookmarks(CfgGroup *grp, Octstr *from, Octstr *receiver)
static void url_result_thread(void *arg)
Octstr * urltrans_prefix(URLTranslation *t)
static void identify_to_bearerbox(void)
void urltrans_destroy(URLTranslationList *trans)
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
static void http_queue_thread(void *arg)
void gwlist_add_producer(List *list)
#define BB_DEFAULT_SMSBOX_PORT
void http_set_client_timeout(long timeout)
int octstr_get_char(const Octstr *ostr, long pos)
static void * remember_receiver(Msg *msg, URLTranslation *trans, int method, Octstr *url, List *headers, Octstr *body, unsigned int retries)
int get_and_set_debugs(int argc, char **argv, int(*find_own)(int index, int argc, char **argv))
#define DLR_IS_ENABLED(dlr)
int urltrans_max_priority(URLTranslation *t)
Octstr * urltrans_name(URLTranslation *t)
Semaphore * semaphore_create(long n)
static char * sendsms_number_chars
static Octstr * alt_charset
static XMLRPCDocument * msg
Octstr * urltrans_get_pattern(URLTranslation *t, Msg *request)
#define OCTSTR_APPEND_XML_OCTSTR(xml, tag, text)
static int obey_request(Octstr **result, URLTranslation *trans, Msg *msg)
Octstr * xmlrpc_parse_error(XMLRPCDocument *xrdoc)
int urltrans_concatenation(URLTranslation *t)
int ota_pack_message(Msg **msg, Octstr *ota_doc, Octstr *doc_type, Octstr *from, Octstr *phone_number, Octstr *sec, Octstr *pin)
void octstr_url_encode(Octstr *ostr)
static void get_receiver(void *id, Msg **msg, URLTranslation **trans, int *method, Octstr **url, List **headers, Octstr **body, unsigned long *retries)
static Octstr * global_sender
static Octstr * meta_data
static void reply(HTTPClient *c, List *push_headers)
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
int main(int argc, char **argv)
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)