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)