Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
smsbox.c File Reference
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <inttypes.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include "gwlib/gwlib.h"
#include "gwlib/regex.h"
#include "gwlib/gw-timer.h"
#include "msg.h"
#include "sms.h"
#include "dlr.h"
#include "bb.h"
#include "shared.h"
#include "heartbeat.h"
#include "html.h"
#include "urltrans.h"
#include "ota_prov_attr.h"
#include "ota_prov.h"
#include "ota_compiler.h"
#include "xml_shared.h"

Go to the source code of this file.

Data Structures

struct  TimerItem
 
struct  receiver
 

Macros

#define SENDSMS_DEFAULT_CHARS   "0123456789 +-"
 
#define O_DESTROY(a)   { if(a) octstr_destroy(a); a = NULL; }
 
#define ACCOUNT_MAX_LEN   64
 
#define HTTP_MAX_RETRIES   0
 
#define HTTP_RETRY_DELAY   10 /* in sec. */
 
#define HTTP_MAX_PENDING   512 /* max requests handled in parallel */
 
#define XPATH_SEARCH_OCTSTR(path, var, nostrip)
 
#define XPATH_SEARCH_NUMBER(path, var)
 
#define OCTSTR_APPEND_XML(xml, tag, text)   octstr_format_append(xml, " \t\t<" tag ">%s</" tag ">\n", (text?octstr_get_cstr(text):""))
 
#define OCTSTR_APPEND_XML_OCTSTR(xml, tag, text)
 
#define OCTSTR_APPEND_XML_NUMBER(xml, tag, value)    octstr_format_append(xml, " \t\t<" tag ">%ld</" tag ">\n", (long) value)
 

Typedefs

typedef struct TimerItem TimerItem
 

Functions

static void identify_to_bearerbox (void)
 
static void delayed_http_reply (Msg *msg)
 
static void read_messages_from_bearerbox (void)
 
static int send_message (URLTranslation *trans, Msg *msg)
 
static void * remember_receiver (Msg *msg, URLTranslation *trans, int method, Octstr *url, List *headers, Octstr *body, unsigned int retries)
 
static void get_receiver (void *id, Msg **msg, URLTranslation **trans, int *method, Octstr **url, List **headers, Octstr **body, unsigned long *retries)
 
static long outstanding_requests (void)
 
static void strip_prefix_and_suffix (Octstr *html, Octstr *prefix, Octstr *suffix)
 
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)
 
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)
 
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 void http_queue_thread (void *arg)
 
static void url_result_thread (void *arg)
 
static int obey_request (Octstr **result, URLTranslation *trans, Msg *msg)
 
static void obey_request_thread (void *arg)
 
static Octstrstore_uuid (Msg *msg)
 
static Octstrsmsbox_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)
 
static URLTranslationauthorise_username (Octstr *username, Octstr *password, Octstr *client_ip)
 
static URLTranslationdefault_authorise_user (List *list, Octstr *client_ip)
 
static URLTranslationauthorise_user (List *list, Octstr *client_ip)
 
static Octstrsmsbox_req_sendsms (List *args, Octstr *client_ip, int *status, HTTPClient *client)
 
static Octstrsmsbox_sendsms_post (List *headers, Octstr *body, Octstr *client_ip, int *status, HTTPClient *client)
 
static Octstrsmsbox_xmlrpc_post (List *headers, Octstr *body, Octstr *client_ip, int *status)
 
static Octstrsmsbox_req_sendota (List *list, Octstr *client_ip, int *status, HTTPClient *client)
 
static Octstrsmsbox_sendota_post (List *headers, Octstr *body, Octstr *client_ip, int *status, HTTPClient *client)
 
static void sendsms_thread (void *arg)
 
static void signal_handler (int signum)
 
static void setup_signal_handlers (void)
 
static Cfginit_smsbox (Cfg *cfg)
 
static int check_args (int i, int argc, char **argv)
 
int main (int argc, char **argv)
 

Variables

volatile sig_atomic_t restart = 0
 
static Cfgcfg
 
static long bb_port
 
static int bb_ssl = 0
 
static long sendsms_port = 0
 
static Octstrsendsms_interface = NULL
 
static Octstrsmsbox_id = NULL
 
static Octstrsendsms_url = NULL
 
static Octstrsendota_url = NULL
 
static Octstrxmlrpc_url = NULL
 
static Octstrbb_host
 
static Octstraccepted_chars = NULL
 
static int only_try_http = 0
 
static URLTranslationListtranslations = NULL
 
static long sms_max_length = MAX_SMS_OCTETS
 
static char * sendsms_number_chars
 
static Octstrglobal_sender = NULL
 
static Octstrreply_couldnotfetch = NULL
 
static Octstrreply_couldnotrepresent = NULL
 
static Octstrreply_requestfailed = NULL
 
static Octstrreply_emptymessage = NULL
 
static int mo_recode = 0
 
static Numhashwhite_list
 
static Numhashblack_list
 
static regex_t * white_list_regex = NULL
 
static regex_t * black_list_regex = NULL
 
static long max_http_retries = HTTP_MAX_RETRIES
 
static long http_queue_delay = HTTP_RETRY_DELAY
 
static Octstrppg_service_name = NULL
 
static Listsmsbox_requests = NULL
 
static Listsmsbox_http_requests = NULL
 
static Timersettimerset = NULL
 
static Semaphoremax_pending_requests
 
static int immediate_sendsms_reply = 0
 
static Dictclient_dict = NULL
 
static Listsendsms_reply_hdrs = NULL
 
static Countercatenated_sms_counter
 
static HTTPCallercaller
 
static Counternum_outstanding_requests
 

Macro Definition Documentation

#define ACCOUNT_MAX_LEN   64

Definition at line 99 of file smsbox.c.

Referenced by smsbox_req_handle().

#define HTTP_MAX_PENDING   512 /* max requests handled in parallel */

Definition at line 104 of file smsbox.c.

Referenced by init_smsbox().

#define HTTP_MAX_RETRIES   0

Definition at line 102 of file smsbox.c.

#define HTTP_RETRY_DELAY   10 /* in sec. */

Definition at line 103 of file smsbox.c.

#define OCTSTR_APPEND_XML (   xml,
  tag,
  text 
)    octstr_format_append(xml, " \t\t<" tag ">%s</" tag ">\n", (text?octstr_get_cstr(text):""))

Referenced by obey_request().

#define OCTSTR_APPEND_XML_NUMBER (   xml,
  tag,
  value 
)    octstr_format_append(xml, " \t\t<" tag ">%ld</" tag ">\n", (long) value)

Referenced by obey_request().

#define OCTSTR_APPEND_XML_OCTSTR (   xml,
  tag,
  text 
)
Value:
do { \
xmlDocPtr tmp_doc = xmlNewDoc(BAD_CAST "1.0"); \
xmlChar *xml_escaped = NULL; \
if (text != NULL) xml_escaped = xmlEncodeEntitiesReentrant(tmp_doc, BAD_CAST octstr_get_cstr(text)); \
octstr_format_append(xml, " \t\t<" tag ">%s</" tag ">\n", (xml_escaped != NULL ? (char*)xml_escaped : "")); \
if (xml_escaped != NULL) xmlFree(xml_escaped); \
xmlFreeDoc(tmp_doc); \
} while(0)
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
char * text
Definition: smsc_cimd2.c:921
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505

Referenced by obey_request().

#define SENDSMS_DEFAULT_CHARS   "0123456789 +-"

Definition at line 95 of file smsbox.c.

Referenced by init_smsbox().

#define XPATH_SEARCH_NUMBER (   path,
  var 
)
Value:
do { \
xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); \
if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) { \
var = xmlXPathCastToNumber(xpathObj); \
} \
if (xpathObj != NULL) xmlXPathFreeObject(xpathObj); \
} while(0)

Referenced by get_x_kannel_from_xml().

#define XPATH_SEARCH_OCTSTR (   path,
  var,
  nostrip 
)
Value:
do { \
xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); \
if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) { \
xml_string = xmlXPathCastToString(xpathObj); \
O_DESTROY(var); \
var = octstr_create((const char*) xml_string); \
if(nostrip == 0) \
octstr_strip_blanks(var); \
xmlFree(xml_string); \
} \
if (xpathObj != NULL) xmlXPathFreeObject(xpathObj); \
} while(0)
#define octstr_create(cstr)
Definition: octstr.h:125

Referenced by get_x_kannel_from_xml().

Typedef Documentation

typedef struct TimerItem TimerItem

Function Documentation

static URLTranslation* authorise_user ( List list,
Octstr client_ip 
)
static

Definition at line 2442 of file smsbox.c.

References default_authorise_user(), octstr_imm(), and urltrans_find_username().

Referenced by smsbox_req_sendota(), and smsbox_req_sendsms().

2443 {
2444 #ifdef HAVE_SECURITY_PAM_APPL_H
2445  URLTranslation *t;
2446 
2448  if (t != NULL) {
2449  if (pam_authorise_user(list))
2450  return t;
2451  else
2452  return NULL;
2453  } else
2454  return default_authorise_user(list, client_ip);
2455 #else
2456  return default_authorise_user(list, client_ip);
2457 #endif
2458 }
static URLTranslation * default_authorise_user(List *list, Octstr *client_ip)
Definition: smsbox.c:2428
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
static URLTranslationList * translations
Definition: smsbox.c:127
URLTranslation * urltrans_find_username(URLTranslationList *trans, Octstr *name)
Definition: urltrans.c:284
static URLTranslation* authorise_username ( Octstr username,
Octstr password,
Octstr client_ip 
)
static

Definition at line 2395 of file smsbox.c.

References allow_ip, deny_ip, info(), is_allowed_ip(), octstr_compare(), octstr_get_cstr, urltrans_allow_ip(), urltrans_deny_ip(), urltrans_find_username(), urltrans_password(), and warning().

Referenced by default_authorise_user(), smsbox_sendota_post(), and smsbox_sendsms_post().

2397 {
2398  URLTranslation *t = NULL;
2399 
2400  if (username == NULL || password == NULL)
2401  return NULL;
2402 
2403  if ((t = urltrans_find_username(translations, username))==NULL)
2404  return NULL;
2405 
2406  if (octstr_compare(password, urltrans_password(t))!=0)
2407  return NULL;
2408  else {
2411 
2412  if (is_allowed_ip(allow_ip, deny_ip, client_ip) == 0) {
2413  warning(0, "Non-allowed connect tried by <%s> from <%s>, ignored",
2414  octstr_get_cstr(username), octstr_get_cstr(client_ip));
2415  return NULL;
2416  }
2417  }
2418 
2419  info(0, "sendsms used by <%s>", octstr_get_cstr(username));
2420  return t;
2421 }
void info(int err, const char *fmt,...)
Definition: log.c:636
Octstr * urltrans_deny_ip(URLTranslation *t)
Definition: urltrans.c:862
Octstr * urltrans_password(URLTranslation *t)
Definition: urltrans.c:842
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
int is_allowed_ip(Octstr *allow_ip, Octstr *deny_ip, Octstr *ip)
Definition: utils.c:815
static URLTranslationList * translations
Definition: smsbox.c:127
static Octstr * deny_ip
Definition: bb_udp.c:112
void warning(int err, const char *fmt,...)
Definition: log.c:624
static Octstr * allow_ip
Definition: bb_udp.c:111
Octstr * urltrans_allow_ip(URLTranslation *t)
Definition: urltrans.c:857
Definition: octstr.c:118
URLTranslation * urltrans_find_username(URLTranslationList *trans, Octstr *name)
Definition: urltrans.c:284
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static int check_args ( int  i,
int  argc,
char **  argv 
)
static

Definition at line 3535 of file smsbox.c.

References only_try_http.

Referenced by main().

3535  {
3536  if (strcmp(argv[i], "-H")==0 || strcmp(argv[i], "--tryhttp")==0) {
3537  only_try_http = 1;
3538  } else
3539  return -1;
3540 
3541  return 0;
3542 }
static int only_try_http
Definition: smsbox.c:126
static URLTranslation* default_authorise_user ( List list,
Octstr client_ip 
)
static

Definition at line 2428 of file smsbox.c.

References authorise_username(), and http_cgi_variable().

Referenced by authorise_user().

2429 {
2430  Octstr *pass, *user = NULL;
2431 
2432  if ((user = http_cgi_variable(list, "username")) == NULL)
2433  user = http_cgi_variable(list, "user");
2434 
2435  if ((pass = http_cgi_variable(list, "password")) == NULL)
2436  pass = http_cgi_variable(list, "pass");
2437 
2438  return authorise_username(user, pass, client_ip);
2439 }
static URLTranslation * authorise_username(Octstr *username, Octstr *password, Octstr *client_ip)
Definition: smsbox.c:2395
Octstr * http_cgi_variable(List *list, char *name)
Definition: http.c:2813
Definition: octstr.c:118
static void delayed_http_reply ( Msg msg)
static

Definition at line 185 of file smsbox.c.

References ack_buffered, ack_failed, ack_failed_tmp, ack_success, client(), debug(), dict_remove(), error(), HTTP_ACCEPTED, HTTP_FORBIDDEN, http_send_reply(), HTTP_SERVICE_UNAVAILABLE, octstr_create, octstr_destroy(), octstr_get_cstr, UUID_STR_LEN, and uuid_unparse().

Referenced by read_messages_from_bearerbox().

186 {
188  Octstr *os, *answer;
189  char id[UUID_STR_LEN + 1];
190  int status;
191 
192  uuid_unparse(msg->ack.id, id);
193  os = octstr_create(id);
194  debug("sms.http", 0, "Got ACK (%ld) of %s", msg->ack.nack, octstr_get_cstr(os));
195  client = dict_remove(client_dict, os);
196  if (client == NULL) {
197  debug("sms.http", 0, "No client - multi-send or ACK to pull-reply");
198  octstr_destroy(os);
199  return;
200  }
201  /* XXX this should be fixed so that we really wait for DLR
202  * SMSC accept/deny before doing this - but that is far
203  * more slower, a bit more complex, and is done later on
204  */
205 
206  switch (msg->ack.nack) {
207  case ack_success:
208  status = HTTP_ACCEPTED;
209  answer = octstr_create("0: Accepted for delivery");
210  break;
211  case ack_buffered:
212  status = HTTP_ACCEPTED;
213  answer = octstr_create("3: Queued for later delivery");
214  break;
215  case ack_failed:
216  status = HTTP_FORBIDDEN;
217  answer = octstr_create("Not routable. Do not try again.");
218  break;
219  case ack_failed_tmp:
220  status = HTTP_SERVICE_UNAVAILABLE;
221  answer = octstr_create("Temporal failure, try again later.");
222  break;
223  default:
224  error(0, "Strange reply from bearerbox!");
225  status = HTTP_SERVICE_UNAVAILABLE;
226  answer = octstr_create("Temporal failure, try again later.");
227  break;
228  }
229 
230  http_send_reply(client, status, sendsms_reply_hdrs, answer);
231 
232  octstr_destroy(answer);
233  octstr_destroy(os);
234 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static void client(int port)
Definition: test_udp.c:77
static Dict * client_dict
Definition: smsbox.c:159
void uuid_unparse(const uuid_t uu, char *out)
Definition: gw_uuid.c:561
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void http_send_reply(HTTPClient *client, int status, List *headers, Octstr *body)
Definition: http.c:2671
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
static List * sendsms_reply_hdrs
Definition: smsbox.c:160
#define octstr_create(cstr)
Definition: octstr.h:125
#define UUID_STR_LEN
Definition: gw_uuid.h:19
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
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

Definition at line 827 of file smsbox.c.

References account, charset, DC_7BIT, DC_8BIT, DC_UNDEF, dlr_mask, dlr_url, from, O_DESTROY, octstr_destroy(), octstr_get_cstr, octstr_len(), SMS_PARAM_UNDEFINED, urltrans_accept_x_kannel_headers(), and warning().

Referenced by url_result_thread().

834 {
835  msg->sms.msgdata = replytext;
836  msg->sms.time = time(NULL);
837 
838  if (charset)
839  msg->sms.charset = charset;
840 
841  if (dlr_url != NULL) {
843  octstr_destroy(msg->sms.dlr_url);
844  msg->sms.dlr_url = dlr_url;
845  } else {
846  warning(0, "Tried to change dlr_url to '%s', denied.",
847  octstr_get_cstr(dlr_url));
848  octstr_destroy(dlr_url);
849  }
850  }
851 
852  if (smsc != NULL) {
854  octstr_destroy(msg->sms.smsc_id);
855  msg->sms.smsc_id = smsc;
856  } else {
857  warning(0, "Tried to change SMSC to '%s', denied.",
858  octstr_get_cstr(smsc));
859  octstr_destroy(smsc);
860  }
861  }
862 
863  if (from != NULL) {
865  octstr_destroy(msg->sms.sender);
866  msg->sms.sender = from;
867  } else {
868  warning(0, "Tried to change sender to '%s', denied.",
869  octstr_get_cstr(from));
870  octstr_destroy(from);
871  }
872  }
873  if (to != NULL) {
875  octstr_destroy(msg->sms.receiver);
876  msg->sms.receiver = to;
877  } else {
878  warning(0, "Tried to change receiver to '%s', denied.",
879  octstr_get_cstr(to));
880  octstr_destroy(to);
881  }
882  }
883  if (udh != NULL) {
885  octstr_destroy(msg->sms.udhdata);
886  msg->sms.udhdata = udh;
887  } else {
888  warning(0, "Tried to set UDH field, denied.");
889  O_DESTROY(udh);
890  }
891  }
892  if (mclass != SMS_PARAM_UNDEFINED) {
894  msg->sms.mclass = mclass;
895  else
896  warning(0, "Tried to set MClass field, denied.");
897  }
898  if (pid != SMS_PARAM_UNDEFINED) {
900  msg->sms.pid = pid;
901  else
902  warning(0, "Tried to set PID field, denied.");
903  }
904  if (rpi != SMS_PARAM_UNDEFINED) {
906  msg->sms.rpi = rpi;
907  else
908  warning(0, "Tried to set RPI field, denied.");
909  }
910  if (alt_dcs != SMS_PARAM_UNDEFINED) {
912  msg->sms.alt_dcs = alt_dcs;
913  else
914  warning(0, "Tried to set Alt-DCS field, denied.");
915  }
916  if (mwi != SMS_PARAM_UNDEFINED) {
918  msg->sms.mwi = mwi;
919  else
920  warning(0, "Tried to set MWI field, denied.");
921  }
922  if (coding != SMS_PARAM_UNDEFINED) {
924  msg->sms.coding = coding;
925  else
926  warning(0, "Tried to set Coding field, denied.");
927  }
928  if (compress != SMS_PARAM_UNDEFINED) {
930  msg->sms.compress = compress;
931  else
932  warning(0, "Tried to set Compress field, denied.");
933  }
934  /* Compatibility Mode */
935  if (msg->sms.coding == DC_UNDEF) {
936  if(octstr_len(udh))
937  msg->sms.coding = DC_8BIT;
938  else
939  msg->sms.coding = DC_7BIT;
940  }
941  if (validity != SMS_PARAM_UNDEFINED) {
943  msg->sms.validity = validity * 60 + time(NULL);
944  else
945  warning(0, "Tried to change validity to '%d', denied.", validity);
946  }
947  if (deferred != SMS_PARAM_UNDEFINED) {
949  msg->sms.deferred = deferred * 60 + time(NULL);
950  else
951  warning(0, "Tried to change deferred to '%d', denied.", deferred);
952  }
953  if (dlr_mask != SMS_PARAM_UNDEFINED) {
955  msg->sms.dlr_mask = dlr_mask;
956  } else
957  warning(0, "Tried to change dlr_mask to '%d', denied.", dlr_mask);
958  }
959  if (account) {
961  msg->sms.account = account;
962  } else {
963  warning(0, "Tried to change account to '%s', denied.",
964  octstr_get_cstr(account));
965  octstr_destroy(account);
966  }
967  }
968  if (binfo) {
970  msg->sms.binfo = binfo;
971  } else {
972  warning(0, "Tried to change billing info to '%s', denied.",
973  octstr_get_cstr(binfo));
974  octstr_destroy(binfo);
975  }
976  }
977  if (priority != SMS_PARAM_UNDEFINED) {
979  msg->sms.priority = priority;
980  else
981  warning(0, "Tried to change priority to '%d', denied.", priority);
982  }
983  if (meta_data != NULL) {
985  octstr_destroy(msg->sms.meta_data);
986  msg->sms.meta_data = meta_data;
987  } else {
988  warning(0, "Tried to set Meta-Data field, denied.");
989  octstr_destroy(meta_data);
990  }
991  }
992 }
static Octstr * dlr_mask
Definition: test_ppg.c:106
#define DC_8BIT
Definition: sms.h:111
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * charset
Definition: test_ota.c:68
static Octstr * from
Definition: mtbatch.c:95
static Octstr * dlr_url
Definition: test_ppg.c:107
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define O_DESTROY(a)
Definition: smsbox.c:97
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
int urltrans_accept_x_kannel_headers(URLTranslation *t)
Definition: urltrans.c:912
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
#define DC_UNDEF
Definition: sms.h:109
static Octstr * account
Definition: mtbatch.c:94
#define DC_7BIT
Definition: sms.h:110
static void get_receiver ( void *  id,
Msg **  msg,
URLTranslation **  trans,
int *  method,
Octstr **  url,
List **  headers,
Octstr **  body,
unsigned long *  retries 
)
static

Definition at line 483 of file smsbox.c.

References receiver::body, counter_decrease(), receiver::http_headers, receiver::method, receiver::msg, receiver::retries, receiver::trans, and receiver::url.

Referenced by http_queue_thread(), and url_result_thread().

486 {
487  struct receiver *receiver;
488 
489  receiver = id;
490  *msg = receiver->msg;
491  *trans = receiver->trans;
492  *method = receiver->method;
493  *url = receiver->url;
494  *headers = receiver->http_headers;
495  *body = receiver->body;
496  *retries = receiver->retries;
497  gw_free(receiver);
499 }
List * http_headers
Definition: smsbox.c:438
Octstr * url
Definition: smsbox.c:437
int method
Definition: smsbox.c:436
unsigned long counter_decrease(Counter *counter)
Definition: counter.c:155
Msg * msg
Definition: smsbox.c:434
static long retries
Definition: test_ppg.c:116
URLTranslation * trans
Definition: smsbox.c:435
static int method
Definition: test_http.c:76
Octstr * body
Definition: smsbox.c:439
unsigned long retries
Definition: smsbox.c:440
static Counter * num_outstanding_requests
Definition: smsbox.c:430
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 
)
static

Definition at line 532 of file smsbox.c.

References gwlist_len(), http_header_get(), name, octstr_case_compare(), octstr_destroy(), octstr_duplicate, octstr_get_cstr, octstr_hex_to_binary(), octstr_imm(), octstr_strip_blanks(), octstr_url_decode(), and warning().

Referenced by smsbox_sendsms_post(), and url_result_thread().

541 {
542  Octstr *name, *val;
543  long l;
544 
545  for(l=0; l<gwlist_len(headers); l++) {
546  http_header_get(headers, l, &name, &val);
547 
548  if (octstr_case_compare(name, octstr_imm("X-Kannel-From")) == 0) {
549  *from = octstr_duplicate(val);
550  octstr_strip_blanks(*from);
551  }
552  else if (octstr_case_compare(name, octstr_imm("X-Kannel-To")) == 0) {
553  *to = octstr_duplicate(val);
554  octstr_strip_blanks(*to);
555  }
556  else if (octstr_case_compare(name, octstr_imm("X-Kannel-Username")) == 0) {
557  if (user != NULL) {
558  *user = octstr_duplicate(val);
559  octstr_strip_blanks(*user);
560  }
561  }
562  else if (octstr_case_compare(name, octstr_imm("X-Kannel-Password")) == 0) {
563  if (pass != NULL) {
564  *pass = octstr_duplicate(val);
565  octstr_strip_blanks(*pass);
566  }
567  }
568  else if (octstr_case_compare(name, octstr_imm("X-Kannel-SMSC")) == 0) {
569  if (smsc != NULL) {
570  *smsc = octstr_duplicate(val);
571  octstr_strip_blanks(*smsc);
572  }
573  }
574  else if (octstr_case_compare(name, octstr_imm("X-Kannel-UDH")) == 0) {
575  *udh = octstr_duplicate(val);
576  octstr_strip_blanks(*udh);
577  if (octstr_hex_to_binary(*udh) == -1) {
578  if (octstr_url_decode(*udh) == -1) {
579  warning(0, "Invalid UDH received in X-Kannel-UDH");
580  octstr_destroy(*udh);
581  *udh = NULL;
582  }
583  }
584  }
585  else if (octstr_case_compare(name, octstr_imm("X-Kannel-DLR-URL")) == 0) {
586  *dlr_url = octstr_duplicate(val);
587  octstr_strip_blanks(*dlr_url);
588  }
589  else if (octstr_case_compare(name, octstr_imm("X-Kannel-Account")) == 0) {
590  *account = octstr_duplicate(val);
591  octstr_strip_blanks(*account);
592  }
593  else if (octstr_case_compare(name, octstr_imm("X-Kannel-BInfo")) == 0) {
594  *binfo = octstr_duplicate(val);
595  octstr_strip_blanks(*binfo);
596  }
597  else if (octstr_case_compare(name, octstr_imm("X-Kannel-Coding")) == 0) {
598  sscanf(octstr_get_cstr(val),"%d", coding);
599  }
600  else if (octstr_case_compare(name, octstr_imm("X-Kannel-PID")) == 0) {
601  sscanf(octstr_get_cstr(val),"%d", pid);
602  }
603  else if (octstr_case_compare(name, octstr_imm("X-Kannel-MWI")) == 0) {
604  sscanf(octstr_get_cstr(val),"%d", mwi);
605  }
606  else if (octstr_case_compare(name, octstr_imm("X-Kannel-MClass")) == 0) {
607  sscanf(octstr_get_cstr(val),"%d", mclass);
608  }
609  else if (octstr_case_compare(name, octstr_imm("X-Kannel-Alt-DCS")) == 0) {
610  sscanf(octstr_get_cstr(val),"%d", alt_dcs);
611  }
612  else if (octstr_case_compare(name, octstr_imm("X-Kannel-Compress")) == 0) {
613  sscanf(octstr_get_cstr(val),"%d", compress);
614  }
615  else if (octstr_case_compare(name, octstr_imm("X-Kannel-Validity")) == 0) {
616  sscanf(octstr_get_cstr(val),"%d", validity);
617  }
618  else if (octstr_case_compare(name, octstr_imm("X-Kannel-Deferred")) == 0) {
619  sscanf(octstr_get_cstr(val),"%d", deferred);
620  }
621  else if (octstr_case_compare(name, octstr_imm("X-Kannel-DLR-Mask")) == 0) {
622  sscanf(octstr_get_cstr(val),"%d", dlr_mask);
623  }
624  else if (octstr_case_compare(name, octstr_imm("X-Kannel-RPI")) == 0) {
625  sscanf(octstr_get_cstr(val),"%d", rpi);
626  }
627  else if (octstr_case_compare(name, octstr_imm("X-Kannel-Priority")) == 0) {
628  sscanf(octstr_get_cstr(val),"%d", priority);
629  }
630  else if (octstr_case_compare(name, octstr_imm("X-Kannel-Meta-Data")) == 0) {
631  *meta_data = octstr_duplicate(val);
632  octstr_strip_blanks(*meta_data);
633  }
634  octstr_destroy(name);
635  octstr_destroy(val);
636  }
637 }
static Octstr * dlr_mask
Definition: test_ppg.c:106
void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
Definition: http.c:2879
long gwlist_len(List *list)
Definition: list.c:166
int octstr_url_decode(Octstr *ostr)
Definition: octstr.c:1744
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
#define octstr_duplicate(ostr)
Definition: octstr.h:187
char * name
Definition: smsc_cimd2.c:212
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
int octstr_hex_to_binary(Octstr *ostr)
Definition: octstr.c:492
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 
)
static

Definition at line 642 of file smsbox.c.

References debug(), error(), gwlist_append(), gwlist_create, mt_push, O_DESTROY, octstr_append(), octstr_create, octstr_destroy(), octstr_get_cstr, octstr_hex_to_binary(), octstr_len(), octstr_str_case_compare(), octstr_strip_blanks(), octstr_truncate(), octstr_url_decode(), text, XPATH_SEARCH_NUMBER, and XPATH_SEARCH_OCTSTR.

Referenced by smsbox_sendsms_post(), and url_result_thread().

653 {
654  xmlDocPtr doc = NULL;
655  xmlXPathContextPtr xpathCtx = NULL;
656  xmlXPathObjectPtr xpathObj = NULL;
657  xmlChar *xml_string;
658  Octstr *text = NULL, *tmp = NULL;
659 
660  if (*body == NULL)
661  return;
662 
663  debug("sms", 0, "XMLParsing: XML: <%s>", octstr_get_cstr(*body));
664 
665  /* ok, start parsing */
666  doc = xmlParseMemory(octstr_get_cstr(*body), octstr_len(*body));
667  if (doc == NULL) {
668  error(0, "XMLParsing: Could not parse xmldoc: <%s>", octstr_get_cstr(*body));
669  return;
670  }
671  xpathCtx = xmlXPathNewContext(doc);
672  if (xpathCtx == NULL) {
673  error(0, "XMLParsing: Could not create xpath context.");
674  xmlFreeDoc(doc);
675  return;
676  }
677 
678 #define XPATH_SEARCH_OCTSTR(path, var, nostrip) \
679  do { \
680  xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); \
681  if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) { \
682  xml_string = xmlXPathCastToString(xpathObj); \
683  O_DESTROY(var); \
684  var = octstr_create((const char*) xml_string); \
685  if(nostrip == 0) \
686  octstr_strip_blanks(var); \
687  xmlFree(xml_string); \
688  } \
689  if (xpathObj != NULL) xmlXPathFreeObject(xpathObj); \
690  } while(0)
691 
692 #define XPATH_SEARCH_NUMBER(path, var) \
693  do { \
694  xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); \
695  if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) { \
696  var = xmlXPathCastToNumber(xpathObj); \
697  } \
698  if (xpathObj != NULL) xmlXPathFreeObject(xpathObj); \
699  } while(0)
700 
701  /* auth */
702  xpathObj = xmlXPathEvalExpression(BAD_CAST "/message/submit/from", xpathCtx);
703  if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
704  xmlXPathFreeObject(xpathObj);
705  if(requesttype == mt_push) {
706  /* user */
707  XPATH_SEARCH_OCTSTR("/message/submit/from/user", *user, 0);
708  XPATH_SEARCH_OCTSTR("/message/submit/from/username", *user, 0);
709 
710  /* pass */
711  XPATH_SEARCH_OCTSTR("/message/submit/from/pass", *pass, 0);
712  XPATH_SEARCH_OCTSTR("/message/submit/from/password", *pass, 0);
713  }
714 
715  /* account */
716  XPATH_SEARCH_OCTSTR("/message/submit/from/account", *account, 0);
717 
718  /* binfo */
719  XPATH_SEARCH_OCTSTR("/message/submit/from/binfo", *binfo, 0);
720  }
721 
722  XPATH_SEARCH_OCTSTR("/message/submit/oa/number", *from, 0);
723 
724  /* to (da/number) Multiple tags */
725  xpathObj = xmlXPathEvalExpression(BAD_CAST "/message/submit/da/number/text()", xpathCtx);
726  if (xpathObj != NULL && !xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
727  int i;
728 
729  *tolist = gwlist_create();
730  for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) {
731  if (xpathObj->nodesetval->nodeTab[i]->type != XML_TEXT_NODE)
732  continue;
733  xml_string = xmlXPathCastNodeToString(xpathObj->nodesetval->nodeTab[i]);
734  tmp = octstr_create((const char*) xpathObj->nodesetval->nodeTab[i]->content);
735  xmlFree(xml_string);
736  octstr_strip_blanks(tmp);
737  gwlist_append(*tolist, tmp);
738  }
739  }
740  if (xpathObj != NULL)
741  xmlXPathFreeObject(xpathObj);
742 
743  /* udh */
744  XPATH_SEARCH_OCTSTR("/message/submit/udh", *udh, 0);
745  if(*udh != NULL && octstr_hex_to_binary(*udh) == -1)
746  octstr_url_decode(*udh);
747 
748  /* smsc */
749  XPATH_SEARCH_OCTSTR("/message/submit/smsc", *smsc, 0);
750  if (*smsc == NULL)
751  XPATH_SEARCH_OCTSTR("/message/submit/to", *smsc, 0);
752 
753  /* pid */
754  XPATH_SEARCH_NUMBER("/message/submit/pid", *pid);
755 
756  /* rpi */
757  XPATH_SEARCH_NUMBER("/message/submit/rpi", *rpi);
758 
759  /* dcs* (dcs/ *) */
760  /* mclass (dcs/mclass) */
761  XPATH_SEARCH_NUMBER("/message/submit/dcs/mclass", *mclass);
762  /* mwi (dcs/mwi) */
763  XPATH_SEARCH_NUMBER("/message/submit/dcs/mwi", *mwi);
764  /* coding (dcs/coding) */
765  XPATH_SEARCH_NUMBER("/message/submit/dcs/coding", *coding);
766  /* compress (dcs/compress) */
767  XPATH_SEARCH_NUMBER("/message/submit/dcs/compress", *compress);
768  /* alt-dcs (dcs/alt-dcs) */
769  XPATH_SEARCH_NUMBER("/message/submit/dcs/alt-dcs", *alt_dcs);
770 
771 
772  /* statusrequest* (statusrequest/ *) */
773  /* dlr-mask (statusrequest/dlr-mask) */
774  XPATH_SEARCH_NUMBER("/message/submit/statusrequest/dlr-mask", *dlr_mask);
775  /* dlr-url */
776  XPATH_SEARCH_OCTSTR("/message/submit/statusrequest/dlr-url", *dlr_url, 0);
777 
778  /* validity (vp/delay) */
779  XPATH_SEARCH_NUMBER("/message/submit/vp/delay", *validity);
780 
781  /* deferred (timing/delay) */
782  XPATH_SEARCH_NUMBER("/message/submit/timing/delay", *deferred);
783 
784  /* priority */
785  XPATH_SEARCH_NUMBER("/message/submit/priority", *priority);
786 
787  /* meta_data */
788  XPATH_SEARCH_OCTSTR("/message/submit/meta-data", *meta_data, 0);
789 
790  /* charset from <?xml...encoding=?> */
791  O_DESTROY(*charset);
792  if (doc->encoding != NULL)
793  *charset = octstr_create((const char*) doc->encoding);
794  else
795  *charset = octstr_create("UTF-8");
796 
797  /* text */
798  /* first try to receive type, default text */
799  tmp = NULL;
800  XPATH_SEARCH_OCTSTR("/message/submit/ud/@type", tmp, 0);
801  /* now receive message body */
802  XPATH_SEARCH_OCTSTR("/message/submit/ud", text, 0);
803  if (text != NULL) {
804  if (tmp != NULL && octstr_str_case_compare(tmp, "binary") == 0)
805  octstr_hex_to_binary(text);
806  else
807  octstr_url_decode(text);
808  }
809  octstr_destroy(tmp);
810 
811  octstr_truncate(*body, 0);
812  if(text != NULL) {
813  octstr_append(*body, text);
814  octstr_destroy(text);
815  }
816 
817  O_DESTROY(*type);
818  *type = octstr_create("text/plain");
819 
820  if (xpathCtx != NULL)
821  xmlXPathFreeContext(xpathCtx);
822  if (doc != NULL)
823  xmlFreeDoc(doc);
824 }
static Octstr * dlr_mask
Definition: test_ppg.c:106
void error(int err, const char *fmt,...)
Definition: log.c:612
int octstr_str_case_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:984
void gwlist_append(List *list, void *item)
Definition: list.c:179
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
int octstr_url_decode(Octstr *ostr)
Definition: octstr.c:1744
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Definition: msg.h:108
char * text
Definition: smsc_cimd2.c:921
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
#define O_DESTROY(a)
Definition: smsbox.c:97
#define XPATH_SEARCH_OCTSTR(path, var, nostrip)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int octstr_hex_to_binary(Octstr *ostr)
Definition: octstr.c:492
#define gwlist_create()
Definition: list.h:136
#define XPATH_SEARCH_NUMBER(path, var)
void octstr_truncate(Octstr *ostr, int new_len)
Definition: octstr.c:1325
static void http_queue_thread ( void *  arg)
static

Definition at line 1002 of file smsbox.c.

References debug(), get_receiver(), gw_timer_elapsed_destroy(), gwlist_consume(), gwlist_len(), http_destroy_headers(), http_start_request(), TimerItem::id, max_http_retries, method, msg, msg_destroy(), octstr_destroy(), octstr_get_cstr, remember_receiver(), retries, TimerItem::timer, and receiver::trans.

Referenced by main().

1003 {
1004  void *id;
1005  Msg *msg;
1007  Octstr *req_url;
1008  List *req_headers;
1009  Octstr *req_body;
1010  unsigned long retries;
1011  int method;
1012  TimerItem *i;
1013 
1014  while ((i = gwlist_consume(smsbox_http_requests)) != NULL) {
1015  /*
1016  * The timer thread has injected the item to retry the
1017  * HTTP call again now.
1018  */
1019 
1020  debug("sms.http",0,"HTTP: Queue contains %ld outstanding requests",
1022 
1023  /*
1024  * Get all required HTTP request data from the queue and reconstruct
1025  * the id pointer for later lookup in url_result_thread.
1026  */
1027  get_receiver(i->id, &msg, &trans, &method, &req_url, &req_headers, &req_body, &retries);
1028 
1030  gw_free(i);
1031 
1032  if (retries < max_http_retries) {
1033  id = remember_receiver(msg, trans, method, req_url, req_headers, req_body, ++retries);
1034 
1035  debug("sms.http",0,"HTTP: Retrying request <%s> (%ld/%ld)",
1036  octstr_get_cstr(req_url), retries, max_http_retries);
1037 
1038  /* re-queue this request to the HTTPCaller list */
1039  http_start_request(caller, method, req_url, req_headers, req_body,
1040  1, id, NULL);
1041  }
1042 
1043  msg_destroy(msg);
1044  octstr_destroy(req_url);
1045  http_destroy_headers(req_headers);
1046  octstr_destroy(req_body);
1047  }
1048 }
static long max_http_retries
Definition: smsbox.c:140
long gwlist_len(List *list)
Definition: list.c:166
static HTTPCaller * caller
Definition: smsbox.c:429
void * id
Definition: smsbox.c:109
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void http_destroy_headers(List *headers)
Definition: http.c:2856
void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
Definition: http.c:1745
Definition: msg.h:79
static long retries
Definition: test_ppg.c:116
void msg_destroy(Msg *msg)
Definition: msg.c:132
URLTranslation * trans
Definition: smsbox.c:435
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
static int method
Definition: test_http.c:76
void gw_timer_elapsed_destroy(Timer *timer)
Definition: gw-timer.c:240
Definition: octstr.c:118
void * gwlist_consume(List *list)
Definition: list.c:427
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static List * smsbox_http_requests
Definition: smsbox.c:145
static void * remember_receiver(Msg *msg, URLTranslation *trans, int method, Octstr *url, List *headers, Octstr *body, unsigned int retries)
Definition: smsbox.c:446
Timer * timer
Definition: smsbox.c:108
Definition: list.c:102
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static void get_receiver(void *id, Msg **msg, URLTranslation **trans, int *method, Octstr **url, List **headers, Octstr **body, unsigned long *retries)
Definition: smsbox.c:483
static void identify_to_bearerbox ( void  )
static

Definition at line 172 of file smsbox.c.

References cmd_identify, msg, msg_create, octstr_duplicate, and write_to_bearerbox().

Referenced by main().

173 {
174  Msg *msg;
175 
176  msg = msg_create(admin);
177  msg->admin.command = cmd_identify;
178  msg->admin.boxc_id = octstr_duplicate(smsbox_id);
179  write_to_bearerbox(msg);
180 }
#define msg_create(type)
Definition: msg.h:136
static Octstr * smsbox_id
Definition: smsbox.c:120
Definition: msg.h:79
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void write_to_bearerbox(Msg *pmsg)
Definition: shared.c:142
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static Cfg* init_smsbox ( Cfg cfg)
static

Definition at line 3287 of file smsbox.c.

References alog_open(), BB_DEFAULT_HOST, BB_DEFAULT_SMSBOX_PORT, bb_port, bb_ssl, black_list_regex, cfg, cfg_get, cfg_get_bool(), cfg_get_integer(), cfg_get_list(), cfg_get_single_group(), conn_config_ssl(), error(), GW_NON_EXCL, gwlist_destroy(), gwthread_create, HTTP_MAX_PENDING, http_open_port_if(), http_queue_delay, http_set_client_timeout(), http_use_proxy(), immediate_sendsms_reply, info(), lf, log_open(), log_set_syslog(), log_set_syslog_facility(), max_http_retries, mo_recode, numhash_create(), octstr_case_compare(), octstr_compare(), octstr_create, octstr_destroy(), octstr_destroy_item(), octstr_get_cstr, octstr_imm(), octstr_parse_long(), only_try_http, panic, semaphore_create(), SENDSMS_DEFAULT_CHARS, sendsms_number_chars, sendsms_port, sendsms_thread(), sms_max_length, ssl, and white_list_regex.

Referenced by main().

3288 {
3289  CfgGroup *grp;
3290  Octstr *logfile;
3291  Octstr *p;
3292  long lvl, value;
3293  Octstr *http_proxy_host = NULL;
3294  long http_proxy_port = -1;
3295  int http_proxy_ssl = 0;
3296  List *http_proxy_exceptions = NULL;
3297  Octstr *http_proxy_username = NULL;
3298  Octstr *http_proxy_password = NULL;
3299  Octstr *http_proxy_exceptions_regex = NULL;
3300  int ssl = 0;
3301  int lf, m;
3302  long max_req;
3303 
3305  bb_ssl = 0;
3307  logfile = NULL;
3308  lvl = 0;
3309  lf = m = 1;
3310 
3311  /*
3312  * first we take the port number in bearerbox and other values from the
3313  * core group in configuration file
3314  */
3315 
3316  grp = cfg_get_single_group(cfg, octstr_imm("core"));
3317 
3318  cfg_get_integer(&bb_port, grp, octstr_imm("smsbox-port"));
3319 #ifdef HAVE_LIBSSL
3320  cfg_get_bool(&bb_ssl, grp, octstr_imm("smsbox-port-ssl"));
3321 #endif /* HAVE_LIBSSL */
3322 
3323  cfg_get_integer(&http_proxy_port, grp, octstr_imm("http-proxy-port"));
3324 #ifdef HAVE_LIBSSL
3325  cfg_get_bool(&http_proxy_ssl, grp, octstr_imm("http-proxy-ssl"));
3326 #endif /* HAVE_LIBSSL */
3327 
3328  http_proxy_host = cfg_get(grp,
3329  octstr_imm("http-proxy-host"));
3330  http_proxy_username = cfg_get(grp,
3331  octstr_imm("http-proxy-username"));
3332  http_proxy_password = cfg_get(grp,
3333  octstr_imm("http-proxy-password"));
3334  http_proxy_exceptions = cfg_get_list(grp,
3335  octstr_imm("http-proxy-exceptions"));
3336  http_proxy_exceptions_regex = cfg_get(grp,
3337  octstr_imm("http-proxy-exceptions-regex"));
3338 
3339 #ifdef HAVE_LIBSSL
3340  conn_config_ssl(grp);
3341 #endif
3342 
3343  /*
3344  * get the remaining values from the smsbox group
3345  */
3346  grp = cfg_get_single_group(cfg, octstr_imm("smsbox"));
3347  if (grp == NULL)
3348  panic(0, "No 'smsbox' group in configuration");
3349 
3350  smsbox_id = cfg_get(grp, octstr_imm("smsbox-id"));
3351 
3352  p = cfg_get(grp, octstr_imm("bearerbox-host"));
3353  if (p != NULL) {
3355  bb_host = p;
3356  }
3357  cfg_get_integer(&bb_port, grp, octstr_imm("bearerbox-port"));
3358 #ifdef HAVE_LIBSSL
3359  if (cfg_get_bool(&ssl, grp, octstr_imm("bearerbox-port-ssl")) != -1)
3360  bb_ssl = ssl;
3361 #endif /* HAVE_LIBSSL */
3362 
3363  cfg_get_bool(&mo_recode, grp, octstr_imm("mo-recode"));
3364  if(mo_recode < 0)
3365  mo_recode = 0;
3366 
3367  reply_couldnotfetch= cfg_get(grp, octstr_imm("reply-couldnotfetch"));
3368  if (reply_couldnotfetch == NULL)
3369  reply_couldnotfetch = octstr_create("Could not fetch content, sorry.");
3370 
3371  reply_couldnotrepresent= cfg_get(grp, octstr_imm("reply-couldnotfetch"));
3372  if (reply_couldnotrepresent == NULL)
3373  reply_couldnotrepresent = octstr_create("Result could not be represented "
3374  "as an SMS message.");
3375  reply_requestfailed= cfg_get(grp, octstr_imm("reply-requestfailed"));
3376  if (reply_requestfailed == NULL)
3377  reply_requestfailed = octstr_create("Request Failed");
3378 
3379  reply_emptymessage= cfg_get(grp, octstr_imm("reply-emptymessage"));
3380  if (reply_emptymessage == NULL)
3381  reply_emptymessage = octstr_create("<Empty reply from service provider>");
3382 
3383  {
3384  Octstr *os;
3385  os = cfg_get(grp, octstr_imm("white-list"));
3386  if (os != NULL) {
3388  octstr_destroy(os);
3389  }
3390 
3391  os = cfg_get(grp, octstr_imm("white-list-regex"));
3392  if (os != NULL) {
3393  if ((white_list_regex = gw_regex_comp(os, REG_EXTENDED)) == NULL)
3394  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(os));
3395  octstr_destroy(os);
3396  }
3397 
3398  os = cfg_get(grp, octstr_imm("black-list"));
3399  if (os != NULL) {
3401  octstr_destroy(os);
3402  }
3403  os = cfg_get(grp, octstr_imm("black-list-regex"));
3404  if (os != NULL) {
3405  if ((black_list_regex = gw_regex_comp(os, REG_EXTENDED)) == NULL)
3406  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(os));
3407  octstr_destroy(os);
3408  }
3409  }
3410 
3411  cfg_get_integer(&sendsms_port, grp, octstr_imm("sendsms-port"));
3412 
3413  /* check if want to bind to a specific interface */
3414  sendsms_interface = cfg_get(grp, octstr_imm("sendsms-interface"));
3415 
3416  cfg_get_integer(&sms_max_length, grp, octstr_imm("sms-length"));
3417 
3418 #ifdef HAVE_LIBSSL
3419  cfg_get_bool(&ssl, grp, octstr_imm("sendsms-port-ssl"));
3420 #endif /* HAVE_LIBSSL */
3421 
3422  /*
3423  * load the configuration settings for the sendsms and sendota URIs
3424  * else assume the default URIs, st.
3425  */
3426  if ((sendsms_url = cfg_get(grp, octstr_imm("sendsms-url"))) == NULL)
3427  sendsms_url = octstr_imm("/cgi-bin/sendsms");
3428  if ((xmlrpc_url = cfg_get(grp, octstr_imm("xmlrpc-url"))) == NULL)
3429  xmlrpc_url = octstr_imm("/cgi-bin/xmlrpc");
3430  if ((sendota_url = cfg_get(grp, octstr_imm("sendota-url"))) == NULL)
3431  sendota_url = octstr_imm("/cgi-bin/sendota");
3432 
3433  global_sender = cfg_get(grp, octstr_imm("global-sender"));
3434  accepted_chars = cfg_get(grp, octstr_imm("sendsms-chars"));
3437  logfile = cfg_get(grp, octstr_imm("log-file"));
3438 
3439  cfg_get_integer(&lvl, grp, octstr_imm("log-level"));
3440 
3441  if (logfile != NULL) {
3442  info(0, "Starting to log to file %s level %ld",
3443  octstr_get_cstr(logfile), lvl);
3444  log_open(octstr_get_cstr(logfile), lvl, GW_NON_EXCL);
3445  octstr_destroy(logfile);
3446  }
3447  if ((p = cfg_get(grp, octstr_imm("syslog-level"))) != NULL) {
3448  long level;
3449  Octstr *facility;
3450  if ((facility = cfg_get(grp, octstr_imm("syslog-facility"))) != NULL) {
3452  octstr_destroy(facility);
3453  }
3454  if (octstr_compare(p, octstr_imm("none")) == 0) {
3455  log_set_syslog(NULL, 0);
3456  } else if (octstr_parse_long(&level, p, 0, 10) > 0) {
3457  log_set_syslog("smsbox", level);
3458  }
3459  octstr_destroy(p);
3460  } else {
3461  log_set_syslog(NULL, 0);
3462  }
3463  if (global_sender != NULL) {
3464  info(0, "Service global sender set as '%s'",
3466  }
3467 
3468  /* should smsbox reply to sendsms immediate or wait for bearerbox ack */
3469  cfg_get_bool(&immediate_sendsms_reply, grp, octstr_imm("immediate-sendsms-reply"));
3470 
3471  /* determine which timezone we use for access logging */
3472  if ((p = cfg_get(grp, octstr_imm("access-log-time"))) != NULL) {
3473  lf = (octstr_case_compare(p, octstr_imm("gmt")) == 0) ? 0 : 1;
3474  octstr_destroy(p);
3475  }
3476 
3477  /* should predefined markers be used, ie. prefixing timestamp */
3478  cfg_get_bool(&m, grp, octstr_imm("access-log-clean"));
3479 
3480  /* open access-log file */
3481  if ((p = cfg_get(grp, octstr_imm("access-log"))) != NULL) {
3482  info(0, "Logging accesses to '%s'.", octstr_get_cstr(p));
3483  alog_open(octstr_get_cstr(p), lf, m ? 0 : 1);
3484  octstr_destroy(p);
3485  }
3486 
3487  /* HTTP queueing values */
3488  cfg_get_integer(&max_http_retries, grp, octstr_imm("http-request-retry"));
3489  cfg_get_integer(&http_queue_delay, grp, octstr_imm("http-queue-delay"));
3490 
3491  if (sendsms_port > 0) {
3492  if (http_open_port_if(sendsms_port, ssl, sendsms_interface) == -1) {
3493  if (only_try_http)
3494  error(0, "Failed to open HTTP socket, ignoring it");
3495  else
3496  panic(0, "Failed to open HTTP socket");
3497  } else {
3498  info(0, "Set up send sms service at port %ld", sendsms_port);
3500  }
3501  }
3502 
3503  /* set maximum allowed MO/DLR requests in parallel */
3504  if (cfg_get_integer(&max_req, grp, octstr_imm("max-pending-requests")) == -1)
3505  max_req = HTTP_MAX_PENDING;
3507 
3508  if (cfg_get_integer(&value, grp, octstr_imm("http-timeout")) == 0)
3509  http_set_client_timeout(value);
3510 
3511  /*
3512  * Reading the name we are using for ppg services from ppg core group
3513  */
3514  if ((grp = cfg_get_single_group(cfg, octstr_imm("ppg"))) != NULL) {
3515  if ((ppg_service_name = cfg_get(grp, octstr_imm("service-name"))) == NULL)
3517  }
3518 
3519  if (http_proxy_host != NULL && http_proxy_port > 0) {
3520  http_use_proxy(http_proxy_host, http_proxy_port, http_proxy_ssl,
3521  http_proxy_exceptions, http_proxy_username,
3522  http_proxy_password, http_proxy_exceptions_regex);
3523  }
3524 
3525  octstr_destroy(http_proxy_host);
3526  octstr_destroy(http_proxy_username);
3527  octstr_destroy(http_proxy_password);
3528  octstr_destroy(http_proxy_exceptions_regex);
3529  gwlist_destroy(http_proxy_exceptions, octstr_destroy_item);
3530 
3531  return cfg;
3532 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
static Octstr * reply_requestfailed
Definition: smsbox.c:133
int ssl
Semaphore * semaphore_create(long n)
Definition: semaphore.c:81
List * cfg_get_list(CfgGroup *grp, Octstr *varname)
Definition: cfg.c:787
static long sms_max_length
Definition: smsbox.c:128
static long max_http_retries
Definition: smsbox.c:140
static Octstr * sendota_url
Definition: smsbox.c:122
static void sendsms_thread(void *arg)
Definition: smsbox.c:3153
#define BB_DEFAULT_HOST
Definition: bb.h:67
static Octstr * sendsms_url
Definition: smsbox.c:121
#define cfg_get(grp, varname)
Definition: cfg.h:86
static regex_t * black_list_regex
Definition: smsbox.c:139
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static Octstr * smsbox_id
Definition: smsbox.c:120
static Octstr * sendsms_interface
Definition: smsbox.c:119
Numhash * numhash_create(const char *seek_url)
Definition: numhash.c:313
static long http_queue_delay
Definition: smsbox.c:141
static Octstr * reply_couldnotfetch
Definition: smsbox.c:131
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
static Octstr * accepted_chars
Definition: smsbox.c:125
static regex_t * white_list_regex
Definition: smsbox.c:138
void conn_config_ssl(CfgGroup *grp)
Definition: conn.c:1472
static Octstr * bb_host
Definition: smsbox.c:124
static Octstr * xmlrpc_url
Definition: smsbox.c:123
static int mo_recode
Definition: smsbox.c:135
static Semaphore * max_pending_requests
Definition: smsbox.c:151
#define SENDSMS_DEFAULT_CHARS
Definition: smsbox.c:95
static Octstr * reply_couldnotrepresent
Definition: smsbox.c:132
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
#define HTTP_MAX_PENDING
Definition: smsbox.c:104
void log_set_syslog_facility(char *facility)
Definition: log.c:242
void alog_open(char *fname, int use_localtm, int use_markers)
Definition: accesslog.c:129
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define gwthread_create(func, arg)
Definition: gwthread.h:90
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:334
void log_set_syslog(const char *ident, int syslog_level)
Definition: log.c:248
static Octstr * ppg_service_name
Definition: smsbox.c:142
static Numhash * black_list
Definition: smsbox.c:137
int http_open_port_if(int port, int ssl, Octstr *interface)
Definition: http.c:2472
int log_open(char *filename, int level, enum excl_state excl)
Definition: log.c:339
static Cfg * cfg
Definition: smsbox.c:115
static Numhash * white_list
Definition: smsbox.c:136
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:756
static Octstr * reply_emptymessage
Definition: smsbox.c:134
Definition: octstr.c:118
void http_use_proxy(Octstr *hostname, int port, int ssl, List *exceptions, Octstr *username, Octstr *password, Octstr *exceptions_regex)
Definition: http.c:268
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:739
#define panic
Definition: log.h:87
static long sendsms_port
Definition: smsbox.c:118
Definition: cfg.c:73
static int immediate_sendsms_reply
Definition: smsbox.c:158
static long bb_port
Definition: smsbox.c:116
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:747
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:636
#define BB_DEFAULT_SMSBOX_PORT
Definition: bb.h:68
void http_set_client_timeout(long timeout)
Definition: http.c:1736
static int bb_ssl
Definition: smsbox.c:117
static int only_try_http
Definition: smsbox.c:126
static char * sendsms_number_chars
Definition: smsbox.c:129
Definition: list.c:102
static Octstr * lf
Definition: smsc_smasi.c:222
static Octstr * global_sender
Definition: smsbox.c:130
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
int main ( int  argc,
char **  argv 
)

Definition at line 3545 of file smsbox.c.

References ALL_HEARTBEATS, alog_close(), bb_port, bb_ssl, black_list_regex, cfg_create(), cfg_destroy(), cfg_read(), check_args(), close_connection_to_bearerbox(), connect_to_bearerbox(), counter_create(), counter_destroy(), debug(), DEFAULT_HEARTBEAT, dict_create(), dict_destroy(), filename, get_and_set_debugs(), gw_assert(), gw_timerset_create(), gw_timerset_destroy(), gwlib_init(), gwlib_shutdown(), gwlist_add_producer(), gwlist_create, gwlist_destroy(), gwlist_len(), gwlist_remove_producer(), gwthread_create, gwthread_join_every(), gwthread_sleep(), heartbeat_start(), heartbeat_stop(), http_caller_create(), http_caller_destroy(), http_caller_signal_shutdown(), http_close_all_ports(), http_create_empty_headers(), http_destroy_headers(), http_header_add(), http_queue_delay, http_queue_thread(), identify_to_bearerbox(), info(), init_smsbox(), log_close_all(), max_http_retries, numhash_destroy(), obey_request_thread(), octstr_create, octstr_destroy(), octstr_get_cstr, outstanding_requests(), panic, read_messages_from_bearerbox(), report_versions(), restart, restart_box(), semaphore_destroy(), sendsms_thread(), setup_signal_handlers(), url_result_thread(), urltrans_add_cfg(), urltrans_create(), urltrans_destroy(), white_list_regex, and write_to_bearerbox().

3546 {
3547  int cf_index;
3548  Octstr *filename;
3549  double heartbeat_freq = DEFAULT_HEARTBEAT;
3550 
3551  gwlib_init();
3552  cf_index = get_and_set_debugs(argc, argv, check_args);
3553 
3555 
3556  if (argv[cf_index] == NULL)
3557  filename = octstr_create("kannel.conf");
3558  else
3559  filename = octstr_create(argv[cf_index]);
3560  cfg = cfg_create(filename);
3561 
3562  if (cfg_read(cfg) == -1)
3563  panic(0, "Couldn't read configuration from `%s'.", octstr_get_cstr(filename));
3564 
3565  octstr_destroy(filename);
3566 
3567  report_versions("smsbox");
3568 
3569  init_smsbox(cfg);
3570 
3571  if (max_http_retries > 0) {
3572  info(0, "Using HTTP request queueing with %ld retries, %lds delay.",
3574  }
3575 
3576  debug("sms", 0, "----------------------------------------------");
3577  debug("sms", 0, GW_NAME " smsbox version %s starting", GW_VERSION);
3578 
3580  if (translations == NULL)
3581  panic(0, "urltrans_create failed");
3582  if (urltrans_add_cfg(translations, cfg) == -1)
3583  panic(0, "urltrans_add_cfg failed");
3584 
3585  client_dict = dict_create(32, NULL);
3587  http_header_add(sendsms_reply_hdrs, "Content-type", "text/html");
3588  http_header_add(sendsms_reply_hdrs, "Pragma", "no-cache");
3589  http_header_add(sendsms_reply_hdrs, "Cache-Control", "no-cache");
3590 
3591 
3603 
3604  connect_to_bearerbox(bb_host, bb_port, bb_ssl, NULL /* bb_our_host */);
3605  /* XXX add our_host if required */
3606 
3607  if (0 > heartbeat_start(write_to_bearerbox, heartbeat_freq,
3609  info(0, GW_NAME "Could not start heartbeat.");
3610  }
3611 
3614 
3615  info(0, GW_NAME " smsbox terminating.");
3616 
3626 
3628  alog_close();
3653  if (white_list_regex != NULL) gw_regex_destroy(white_list_regex);
3654  if (black_list_regex != NULL) gw_regex_destroy(black_list_regex);
3656  cfg_destroy(cfg);
3657 
3660 
3661  /*
3662  * Just sleep for a while to get bearerbox chance to restart.
3663  * Otherwise we will fail while trying to connect to bearerbox!
3664  */
3665  if (restart) {
3666  gwthread_sleep(10.0);
3667  /* now really restart */
3668  restart_box(argv);
3669  }
3670 
3671  log_close_all();
3672  gwlib_shutdown();
3673 
3674  return 0;
3675 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
int urltrans_add_cfg(URLTranslationList *trans, Cfg *cfg)
Definition: urltrans.c:228
void gw_timerset_destroy(Timerset *set)
Definition: gw-timer.c:190
void info(int err, const char *fmt,...)
Definition: log.c:636
static Octstr * reply_requestfailed
Definition: smsbox.c:133
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
void http_caller_signal_shutdown(HTTPCaller *caller)
Definition: http.c:913
void counter_destroy(Counter *counter)
Definition: counter.c:110
static void obey_request_thread(void *arg)
Definition: smsbox.c:1646
static void read_messages_from_bearerbox(void)
Definition: smsbox.c:242
static long max_http_retries
Definition: smsbox.c:140
long gwlist_len(List *list)
Definition: list.c:166
int restart_box(char **argv)
Definition: shared.c:279
static HTTPCaller * caller
Definition: smsbox.c:429
static Octstr * sendota_url
Definition: smsbox.c:122
static void sendsms_thread(void *arg)
Definition: smsbox.c:3153
static Octstr * sendsms_url
Definition: smsbox.c:121
static Dict * client_dict
Definition: smsbox.c:159
static List * smsbox_requests
Definition: smsbox.c:144
static void setup_signal_handlers(void)
Definition: smsbox.c:3272
void numhash_destroy(Numhash *table)
Definition: numhash.c:275
static long outstanding_requests(void)
Definition: smsbox.c:502
static regex_t * black_list_regex
Definition: smsbox.c:139
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void gwthread_join_every(gwthread_func_t *func)
static Octstr * smsbox_id
Definition: smsbox.c:120
static Octstr * sendsms_interface
Definition: smsbox.c:119
Cfg * cfg_create(Octstr *filename)
Definition: cfg.c:318
void heartbeat_stop(long hb_thread)
Definition: heartbeat.c:160
static long http_queue_delay
Definition: smsbox.c:141
int cfg_read(Cfg *cfg)
Definition: cfg.c:452
void http_destroy_headers(List *headers)
Definition: http.c:2856
static Octstr * reply_couldnotfetch
Definition: smsbox.c:131
Timerset * gw_timerset_create(void)
Definition: gw-timer.c:177
void log_close_all(void)
Definition: log.c:305
static Octstr * accepted_chars
Definition: smsbox.c:125
Counter * counter_create(void)
Definition: counter.c:94
static int check_args(int i, int argc, char **argv)
Definition: smsbox.c:3535
void cfg_destroy(Cfg *cfg)
Definition: cfg.c:331
static regex_t * white_list_regex
Definition: smsbox.c:138
static Cfg * init_smsbox(Cfg *cfg)
Definition: smsbox.c:3287
static URLTranslationList * translations
Definition: smsbox.c:127
void gwlist_remove_producer(List *list)
Definition: list.c:401
static Octstr * bb_host
Definition: smsbox.c:124
List * http_create_empty_headers(void)
Definition: http.c:2849
void connect_to_bearerbox(Octstr *host, int port, int ssl, Octstr *our_host)
Definition: shared.c:108
static Octstr * xmlrpc_url
Definition: smsbox.c:123
static Semaphore * max_pending_requests
Definition: smsbox.c:151
static Timerset * timerset
Definition: smsbox.c:148
static Octstr * reply_couldnotrepresent
Definition: smsbox.c:132
void semaphore_destroy(Semaphore *semaphore)
Definition: semaphore.c:104
volatile sig_atomic_t restart
Definition: smsbox.c:113
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
char filename[FILENAME_MAX+1]
Definition: log.c:135
#define gwthread_create(func, arg)
Definition: gwthread.h:90
static List * sendsms_reply_hdrs
Definition: smsbox.c:160
#define octstr_create(cstr)
Definition: octstr.h:125
gw_assert(wtls_machine->packet_to_send!=NULL)
void gwthread_sleep(double seconds)
static Counter * num_outstanding_requests
Definition: smsbox.c:430
static Octstr * ppg_service_name
Definition: smsbox.c:142
static Numhash * black_list
Definition: smsbox.c:137
#define ALL_HEARTBEATS
Definition: heartbeat.h:68
void close_connection_to_bearerbox(void)
Definition: shared.c:122
void report_versions(const char *boxname)
Definition: utils.c:539
static Cfg * cfg
Definition: smsbox.c:115
void http_close_all_ports(void)
Definition: http.c:2515
static Numhash * white_list
Definition: smsbox.c:136
void dict_destroy(Dict *dict)
Definition: dict.c:215
#define DEFAULT_HEARTBEAT
Definition: heartbeat.h:67
static Octstr * reply_emptymessage
Definition: smsbox.c:134
void write_to_bearerbox(Msg *pmsg)
Definition: shared.c:142
Definition: octstr.c:118
long heartbeat_start(hb_send_func_t *send_func, double freq, hb_load_func_t *load_func)
Definition: heartbeat.c:126
URLTranslationList * urltrans_create(void)
Definition: urltrans.c:182
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
#define panic
Definition: log.h:87
static long bb_port
Definition: smsbox.c:116
HTTPCaller * http_caller_create(void)
Definition: http.c:897
void alog_close(void)
Definition: accesslog.c:111
void gwlib_shutdown(void)
Definition: gwlib.c:94
static List * smsbox_http_requests
Definition: smsbox.c:145
#define gwlist_create()
Definition: list.h:136
static Counter * catenated_sms_counter
Definition: smsbox.c:307
void http_caller_destroy(HTTPCaller *caller)
Definition: http.c:907
void gwlib_init(void)
Definition: gwlib.c:78
static void url_result_thread(void *arg)
Definition: smsbox.c:1051
static void identify_to_bearerbox(void)
Definition: smsbox.c:172
void urltrans_destroy(URLTranslationList *trans)
Definition: urltrans.c:194
static void http_queue_thread(void *arg)
Definition: smsbox.c:1002
void gwlist_add_producer(List *list)
Definition: list.c:383
int get_and_set_debugs(int argc, char **argv, int(*find_own)(int index, int argc, char **argv))
Definition: utils.c:626
static int bb_ssl
Definition: smsbox.c:117
static Octstr * global_sender
Definition: smsbox.c:130
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static int obey_request ( Octstr **  result,
URLTranslation trans,
Msg msg 
)
static

Definition at line 1228 of file smsbox.c.

References alog(), DC_8BIT, DC_UCS2, debug(), error(), gw_assert(), gw_gmtime(), http_create_empty_headers(), http_destroy_headers(), http_header_add(), HTTP_METHOD_GET, HTTP_METHOD_POST, http_start_request(), O_DESTROY, octstr_append(), OCTSTR_APPEND_XML, OCTSTR_APPEND_XML_NUMBER, OCTSTR_APPEND_XML_OCTSTR, octstr_create, octstr_destroy(), octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_imm(), octstr_len(), octstr_read_file(), octstr_read_pipe(), octstr_url_encode(), remember_receiver(), report_mo, semaphore_down(), semaphore_up(), SMS_PARAM_UNDEFINED, TRANSTYPE_EXECUTE, TRANSTYPE_FILE, TRANSTYPE_GET_URL, TRANSTYPE_POST_URL, TRANSTYPE_POST_XML, TRANSTYPE_SENDSMS, TRANSTYPE_TEXT, type, urltrans_get_pattern(), urltrans_send_sender(), and urltrans_type().

Referenced by obey_request_thread().

1229 {
1230  Octstr *pattern, *xml, *tmp;
1231  List *request_headers;
1232  void *id;
1233  struct tm tm;
1234  char p[22];
1235  int type;
1236  FILE *f;
1237 
1238  gw_assert(msg != NULL);
1239  gw_assert(msg_type(msg) == sms);
1240 
1241  if (msg->sms.sms_type == report_mo)
1242  type = TRANSTYPE_GET_URL;
1243  else
1244  type = urltrans_type(trans);
1245 
1246  pattern = urltrans_get_pattern(trans, msg);
1247  gw_assert(pattern != NULL);
1248 
1249  switch (type) {
1250  case TRANSTYPE_TEXT:
1251  debug("sms", 0, "formatted text answer: <%s>",
1252  octstr_get_cstr(pattern));
1253  *result = pattern;
1254  alog("SMS request sender:%s request: '%s' fixed answer: '%s'",
1255  octstr_get_cstr(msg->sms.receiver),
1256  octstr_get_cstr(msg->sms.msgdata),
1257  octstr_get_cstr(pattern));
1258  break;
1259 
1260  case TRANSTYPE_FILE:
1261  *result = octstr_read_file(octstr_get_cstr(pattern));
1262  octstr_destroy(pattern);
1263  alog("SMS request sender:%s request: '%s' file answer: '%s'",
1264  octstr_get_cstr(msg->sms.receiver),
1265  octstr_get_cstr(msg->sms.msgdata),
1266  octstr_get_cstr(*result));
1267  break;
1268 
1269  case TRANSTYPE_EXECUTE:
1271  debug("sms.exec", 0, "executing sms-service '%s'",
1272  octstr_get_cstr(pattern));
1273  if ((f = popen(octstr_get_cstr(pattern), "r")) != NULL) {
1274  octstr_destroy(pattern);
1275  *result = octstr_read_pipe(f);
1276  pclose(f);
1278  alog("SMS request sender:%s request: '%s' file answer: '%s'",
1279  octstr_get_cstr(msg->sms.receiver),
1280  octstr_get_cstr(msg->sms.msgdata),
1281  octstr_get_cstr(*result));
1282  } else {
1283  error(0, "popen failed for '%s': %d: %s",
1284  octstr_get_cstr(pattern), errno, strerror(errno));
1285  *result = NULL;
1286  octstr_destroy(pattern);
1287  return -1;
1288  }
1289  break;
1290 
1291  /*
1292  * No Kannel headers when we are sending dlrs to wap push
1293  */
1294  case TRANSTYPE_GET_URL:
1295  request_headers = http_create_empty_headers();
1296  http_header_add(request_headers, "User-Agent", GW_NAME "/" GW_VERSION);
1297  if (trans != NULL) {
1298  if (urltrans_send_sender(trans)) {
1299  http_header_add(request_headers, "X-Kannel-From",
1300  octstr_get_cstr(msg->sms.receiver));
1301  }
1302  }
1303 
1304  id = remember_receiver(msg, trans, HTTP_METHOD_GET, pattern, request_headers, NULL, 0);
1306  http_start_request(caller, HTTP_METHOD_GET, pattern, request_headers,
1307  NULL, 1, id, NULL);
1308  octstr_destroy(pattern);
1309  http_destroy_headers(request_headers);
1310  *result = NULL;
1311  return 0;
1312  break;
1313 
1314  case TRANSTYPE_POST_URL:
1315  request_headers = http_create_empty_headers();
1316  http_header_add(request_headers, "User-Agent", GW_NAME "/" GW_VERSION);
1317  if (msg->sms.coding == DC_8BIT)
1318  http_header_add(request_headers, "Content-Type", "application/octet-stream");
1319  else if(msg->sms.coding == DC_UCS2)
1320  http_header_add(request_headers, "Content-Type", "text/plain; charset=\"UTF-16BE\"");
1321  else {
1322  Octstr *header;
1323  header = octstr_create("text/plain");
1324  if (msg->sms.charset) {
1325  octstr_append(header, octstr_imm("; charset=\""));
1326  octstr_append(header, msg->sms.charset);
1327  octstr_append(header, octstr_imm("\""));
1328  } else {
1329  octstr_append(header, octstr_imm("; charset=\"UTF-8\""));
1330  }
1331  http_header_add(request_headers, "Content-Type", octstr_get_cstr(header));
1332  O_DESTROY(header);
1333  }
1334  if (urltrans_send_sender(trans))
1335  http_header_add(request_headers, "X-Kannel-From",
1336  octstr_get_cstr(msg->sms.receiver));
1337  http_header_add(request_headers, "X-Kannel-To",
1338  octstr_get_cstr(msg->sms.sender));
1339 
1340  tm = gw_gmtime(msg->sms.time);
1341  sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d",
1342  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
1343  tm.tm_hour, tm.tm_min, tm.tm_sec);
1344  http_header_add(request_headers, "X-Kannel-Time", p);
1345 
1346  tm = gw_gmtime(time(NULL));
1347  sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d",
1348  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
1349  tm.tm_hour, tm.tm_min, tm.tm_sec);
1350  http_header_add(request_headers, "Date", p); /* HTTP RFC 14.18 */
1351 
1352  if (octstr_len(msg->sms.udhdata)) {
1353  Octstr *os;
1354  os = octstr_duplicate(msg->sms.udhdata);
1355  octstr_url_encode(os);
1356  http_header_add(request_headers, "X-Kannel-UDH", octstr_get_cstr(os));
1357  octstr_destroy(os);
1358  }
1359  if (octstr_len(msg->sms.smsc_id)) {
1360  Octstr *os;
1361  os = octstr_duplicate(msg->sms.smsc_id);
1362  http_header_add(request_headers, "X-Kannel-SMSC", octstr_get_cstr(os));
1363  octstr_destroy(os);
1364  }
1365 
1366  if (msg->sms.mclass != SMS_PARAM_UNDEFINED) {
1367  Octstr *os;
1368  os = octstr_format("%d",msg->sms.mclass);
1369  http_header_add(request_headers, "X-Kannel-MClass", octstr_get_cstr(os));
1370  octstr_destroy(os);
1371  }
1372  if (msg->sms.pid != SMS_PARAM_UNDEFINED) {
1373  Octstr *os;
1374  os = octstr_format("%d",msg->sms.pid);
1375  http_header_add(request_headers, "X-Kannel-PID", octstr_get_cstr(os));
1376  octstr_destroy(os);
1377  }
1378  if (msg->sms.rpi != SMS_PARAM_UNDEFINED) {
1379  Octstr *os;
1380  os = octstr_format("%d",msg->sms.rpi);
1381  http_header_add(request_headers, "X-Kannel-RPI", octstr_get_cstr(os));
1382  octstr_destroy(os);
1383  }
1384  if (msg->sms.alt_dcs != SMS_PARAM_UNDEFINED) {
1385  Octstr *os;
1386  os = octstr_format("%d",msg->sms.alt_dcs);
1387  http_header_add(request_headers, "X-Kannel-Alt-DCS", octstr_get_cstr(os));
1388  octstr_destroy(os);
1389  }
1390  if (msg->sms.mwi != SMS_PARAM_UNDEFINED) {
1391  Octstr *os;
1392  os = octstr_format("%d",msg->sms.mwi);
1393  http_header_add(request_headers, "X-Kannel-MWI", octstr_get_cstr(os));
1394  octstr_destroy(os);
1395  }
1396  if (msg->sms.coding != SMS_PARAM_UNDEFINED) {
1397  Octstr *os;
1398  os = octstr_format("%d",msg->sms.coding);
1399  http_header_add(request_headers, "X-Kannel-Coding", octstr_get_cstr(os));
1400  octstr_destroy(os);
1401  }
1402  if (msg->sms.compress != SMS_PARAM_UNDEFINED) {
1403  Octstr *os;
1404  os = octstr_format("%d",msg->sms.compress);
1405  http_header_add(request_headers, "X-Kannel-Compress", octstr_get_cstr(os));
1406  octstr_destroy(os);
1407  }
1408  if (msg->sms.validity != SMS_PARAM_UNDEFINED) {
1409  Octstr *os;
1410  os = octstr_format("%d", (msg->sms.validity - time(NULL)) / 60);
1411  http_header_add(request_headers, "X-Kannel-Validity", octstr_get_cstr(os));
1412  octstr_destroy(os);
1413  }
1414  if (msg->sms.deferred != SMS_PARAM_UNDEFINED) {
1415  Octstr *os;
1416  os = octstr_format("%d", (msg->sms.deferred - time(NULL)) / 60);
1417  http_header_add(request_headers, "X-Kannel-Deferred", octstr_get_cstr(os));
1418  octstr_destroy(os);
1419  }
1420  if (octstr_len(msg->sms.service)) {
1421  http_header_add(request_headers, "X-Kannel-Service", octstr_get_cstr(msg->sms.service));
1422  }
1423  if (octstr_len(msg->sms.binfo)) {
1424  http_header_add(request_headers, "X-Kannel-BInfo", octstr_get_cstr(msg->sms.binfo));
1425  }
1426  if (octstr_len(msg->sms.meta_data)) {
1427  http_header_add(request_headers, "X-Kannel-Meta-Data", octstr_get_cstr(msg->sms.meta_data));
1428  }
1429 
1430  id = remember_receiver(msg, trans, HTTP_METHOD_POST, pattern,
1431  request_headers, msg->sms.msgdata, 0);
1433  http_start_request(caller, HTTP_METHOD_POST, pattern, request_headers,
1434  msg->sms.msgdata, 1, id, NULL);
1435  octstr_destroy(pattern);
1436  http_destroy_headers(request_headers);
1437  *result = NULL;
1438  return 0;
1439  break;
1440 
1441  case TRANSTYPE_POST_XML:
1442 
1443  /* XXX The first two chars are beeing eaten somewhere and
1444  * only sometimes - something must be ungry */
1445 
1446 #define OCTSTR_APPEND_XML(xml, tag, text) \
1447  octstr_format_append(xml, " \t\t<" tag ">%s</" tag ">\n", (text?octstr_get_cstr(text):""))
1448 
1449 #define OCTSTR_APPEND_XML_OCTSTR(xml, tag, text) \
1450  do { \
1451  xmlDocPtr tmp_doc = xmlNewDoc(BAD_CAST "1.0"); \
1452  xmlChar *xml_escaped = NULL; \
1453  if (text != NULL) xml_escaped = xmlEncodeEntitiesReentrant(tmp_doc, BAD_CAST octstr_get_cstr(text)); \
1454  octstr_format_append(xml, " \t\t<" tag ">%s</" tag ">\n", (xml_escaped != NULL ? (char*)xml_escaped : "")); \
1455  if (xml_escaped != NULL) xmlFree(xml_escaped); \
1456  xmlFreeDoc(tmp_doc); \
1457  } while(0)
1458 
1459 #define OCTSTR_APPEND_XML_NUMBER(xml, tag, value) \
1460  octstr_format_append(xml, " \t\t<" tag ">%ld</" tag ">\n", (long) value)
1461 
1462  request_headers = http_create_empty_headers();
1463  http_header_add(request_headers, "User-Agent", GW_NAME "/" GW_VERSION);
1464  if (msg->sms.coding == DC_UCS2) {
1465  http_header_add(request_headers, "Content-Type",
1466  "text/xml; charset=\"ISO-8859-1\""); /* for account and other strings */
1467  } else {
1468  Octstr *header;
1469  header = octstr_create("text/xml");
1470  if(msg->sms.charset) {
1471  octstr_append(header, octstr_imm("; charset=\""));
1472  octstr_append(header, msg->sms.charset);
1473  octstr_append(header, octstr_imm("\""));
1474  }
1475  http_header_add(request_headers, "Content-Type", octstr_get_cstr(header));
1476  O_DESTROY(header);
1477  }
1478 
1479  tm = gw_gmtime(time(NULL));
1480  sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d",
1481  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
1482  tm.tm_hour, tm.tm_min, tm.tm_sec);
1483  http_header_add(request_headers, "Date", p); /* HTTP RFC 14.18 */
1484 
1485  xml = octstr_create("");
1486  octstr_append(xml, octstr_imm("<?xml version=\"1.0\" encoding=\""));
1487  if (msg->sms.coding == DC_UCS2 || msg->sms.charset == NULL)
1488  octstr_append(xml, octstr_imm("ISO-8859-1"));
1489  else
1490  octstr_append(xml, msg->sms.charset);
1491  octstr_append(xml, octstr_imm("\"?>\n"));
1492 
1493  /*
1494  * XXX damn windows that breaks with this :
1495  * octstr_append(xml, octstr_imm("<!DOCTYPE message SYSTEM \"SMSmessage.dtd\">\n"));
1496  */
1497  octstr_append(xml, octstr_imm("<message cid=\"1\">\n"));
1498  octstr_append(xml, octstr_imm("\t<submit>\n"));
1499 
1500  /* oa */
1501  if (urltrans_send_sender(trans)) {
1502  tmp = octstr_create("");
1503  OCTSTR_APPEND_XML_OCTSTR(tmp, "number", msg->sms.receiver);
1504  OCTSTR_APPEND_XML(xml, "oa", tmp);
1505  octstr_destroy(tmp);
1506  }
1507 
1508  /* da */
1509  tmp = octstr_create("");
1510  OCTSTR_APPEND_XML_OCTSTR(tmp, "number", msg->sms.sender);
1511  OCTSTR_APPEND_XML(xml, "da", tmp);
1512  octstr_destroy(tmp);
1513 
1514  /* udh */
1515  if (octstr_len(msg->sms.udhdata)) {
1516  Octstr *t;
1517  t = octstr_duplicate(msg->sms.udhdata);
1518  octstr_url_encode(t);
1519  OCTSTR_APPEND_XML_OCTSTR(xml, "udh", t);
1520  octstr_destroy(t);
1521  }
1522 
1523  /* ud */
1524  if (octstr_len(msg->sms.msgdata)) {
1525  octstr_url_encode(msg->sms.msgdata);
1526  OCTSTR_APPEND_XML_OCTSTR(xml, "ud", msg->sms.msgdata);
1527  }
1528 
1529  /* pid */
1530  if (msg->sms.pid != SMS_PARAM_UNDEFINED)
1531  OCTSTR_APPEND_XML_NUMBER(xml, "pid", msg->sms.pid);
1532 
1533  /* rpi */
1534  if (msg->sms.rpi != SMS_PARAM_UNDEFINED)
1535  OCTSTR_APPEND_XML_NUMBER(xml, "rpi", msg->sms.rpi);
1536 
1537  /* dcs */
1538  tmp = octstr_create("");
1539  if (msg->sms.coding != SMS_PARAM_UNDEFINED)
1540  OCTSTR_APPEND_XML_NUMBER(tmp, "coding", msg->sms.coding);
1541  if (msg->sms.mclass != SMS_PARAM_UNDEFINED)
1542  OCTSTR_APPEND_XML_NUMBER(tmp, "mclass", msg->sms.mclass);
1543  if (msg->sms.alt_dcs != SMS_PARAM_UNDEFINED)
1544  OCTSTR_APPEND_XML_NUMBER(tmp, "alt-dcs", msg->sms.alt_dcs);
1545  if (msg->sms.mwi != SMS_PARAM_UNDEFINED)
1546  OCTSTR_APPEND_XML_NUMBER(tmp, "mwi", msg->sms.mwi);
1547  if (msg->sms.compress != SMS_PARAM_UNDEFINED)
1548  OCTSTR_APPEND_XML_NUMBER(tmp, "compress", msg->sms.compress);
1549  if (octstr_len(tmp))
1550  OCTSTR_APPEND_XML(xml, "dcs", tmp);
1551  octstr_destroy(tmp);
1552 
1553  /* deferred (timing/delay) */
1554  tmp = octstr_create("");
1555  if(msg->sms.deferred != SMS_PARAM_UNDEFINED)
1556  OCTSTR_APPEND_XML_NUMBER(tmp, "delay", (msg->sms.deferred - time(NULL)) / 60);
1557  if(octstr_len(tmp))
1558  OCTSTR_APPEND_XML(xml, "timing", tmp);
1559  octstr_destroy(tmp);
1560 
1561  /* validity (vp/delay) */
1562  tmp = octstr_create("");
1563  if(msg->sms.validity != SMS_PARAM_UNDEFINED)
1564  OCTSTR_APPEND_XML_NUMBER(tmp, "delay", (msg->sms.validity - time(NULL)) / 60);
1565  if(octstr_len(tmp))
1566  OCTSTR_APPEND_XML(xml, "vp", tmp);
1567  octstr_destroy(tmp);
1568 
1569  /* time (at) */
1570  tm = gw_gmtime(msg->sms.time);
1571  tmp = octstr_format("<year>%04d</year><month>%02d</month>"
1572  "<day>%02d</day><hour>%02d</hour><minute>%02d</minute>"
1573  "<second>%02d</second><timezone>0</timezone>",
1574  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
1575  tm.tm_hour, tm.tm_min, tm.tm_sec);
1576  OCTSTR_APPEND_XML(xml, "at", tmp);
1577  octstr_destroy(tmp);
1578 
1579  /* smsc */
1580  if (octstr_len(msg->sms.smsc_id)) {
1581  tmp = octstr_create("");
1582  if (octstr_len(msg->sms.smsc_id))
1583  OCTSTR_APPEND_XML_OCTSTR(tmp, "account", msg->sms.smsc_id);
1584  if (octstr_len(tmp))
1585  OCTSTR_APPEND_XML(xml, "from", tmp);
1586  O_DESTROY(tmp);
1587  }
1588 
1589  /* service = to/service */
1590  if (octstr_len(msg->sms.service)) {
1591  tmp = octstr_create("");
1592  OCTSTR_APPEND_XML_OCTSTR(tmp, "service", msg->sms.service);
1593  if (octstr_len(tmp))
1594  OCTSTR_APPEND_XML(xml, "to", tmp);
1595  O_DESTROY(tmp);
1596  }
1597 
1598  /* meta_data */
1599  if (octstr_len(msg->sms.meta_data)) {
1600  OCTSTR_APPEND_XML_OCTSTR(xml, "meta-data", msg->sms.meta_data);
1601  }
1602 
1603  /* End XML */
1604  octstr_append(xml, octstr_imm("\t</submit>\n"));
1605  octstr_append(xml, octstr_imm("</message>\n"));
1606 
1607  if (msg->sms.msgdata != NULL)
1608  octstr_destroy(msg->sms.msgdata);
1609 
1610  msg->sms.msgdata = xml;
1611 
1612  debug("sms", 0, "XMLBuild: XML: <%s>", octstr_get_cstr(msg->sms.msgdata));
1613  id = remember_receiver(msg, trans, HTTP_METHOD_POST, pattern,
1614  request_headers, msg->sms.msgdata, 0);
1616  http_start_request(caller, HTTP_METHOD_POST, pattern, request_headers,
1617  msg->sms.msgdata, 1, id, NULL);
1618  octstr_destroy(pattern);
1619  http_destroy_headers(request_headers);
1620  *result = NULL;
1621  return 0;
1622  break;
1623 
1624  case TRANSTYPE_SENDSMS:
1625  error(0, "Got URL translation type SENDSMS for incoming message.");
1626  alog("SMS request sender:%s request: '%s' FAILED bad translation",
1627  octstr_get_cstr(msg->sms.receiver),
1628  octstr_get_cstr(msg->sms.msgdata));
1629  octstr_destroy(pattern);
1630  return -1;
1631  break;
1632 
1633  default:
1634  error(0, "Unknown URL translation type %d", urltrans_type(trans));
1635  alog("SMS request sender:%s request: '%s' FAILED unknown translation",
1636  octstr_get_cstr(msg->sms.receiver),
1637  octstr_get_cstr(msg->sms.msgdata));
1638  octstr_destroy(pattern);
1639  return -1;
1640  break;
1641  }
1642 
1643  return 1;
1644 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define OCTSTR_APPEND_XML(xml, tag, text)
#define OCTSTR_APPEND_XML_NUMBER(xml, tag, value)
void semaphore_up(Semaphore *semaphore)
Definition: semaphore.c:118
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
struct tm gw_gmtime(time_t t)
Definition: protected.c:137
Definition: msg.h:109
Octstr * octstr_read_pipe(FILE *f)
Definition: octstr.c:1578
static HTTPCaller * caller
Definition: smsbox.c:429
msg_type
Definition: msg.h:73
int type
Definition: smsc_cimd2.c:215
void semaphore_down(Semaphore *semaphore)
Definition: semaphore.c:132
#define DC_8BIT
Definition: sms.h:111
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void http_destroy_headers(List *headers)
Definition: http.c:2856
void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
Definition: http.c:1745
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
List * http_create_empty_headers(void)
Definition: http.c:2849
static Semaphore * max_pending_requests
Definition: smsbox.c:151
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
#define O_DESTROY(a)
Definition: smsbox.c:97
gw_assert(wtls_machine->packet_to_send!=NULL)
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
int urltrans_send_sender(URLTranslation *t)
Definition: urltrans.c:922
int urltrans_type(URLTranslation *t)
Definition: urltrans.c:767
Octstr * octstr_read_file(const char *filename)
Definition: octstr.c:1546
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void alog(const char *fmt,...)
Definition: accesslog.c:206
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static void * remember_receiver(Msg *msg, URLTranslation *trans, int method, Octstr *url, List *headers, Octstr *body, unsigned int retries)
Definition: smsbox.c:446
Definition: list.c:102
Octstr * urltrans_get_pattern(URLTranslation *t, Msg *request)
Definition: urltrans.c:728
#define OCTSTR_APPEND_XML_OCTSTR(xml, tag, text)
void octstr_url_encode(Octstr *ostr)
Definition: octstr.c:1671
#define DC_UCS2
Definition: sms.h:112
static void obey_request_thread ( void *  arg)
static

Definition at line 1646 of file smsbox.c.

References ack_failed, ack_success, charset_convert(), DC_7BIT, DC_UCS2, error(), gwlist_consume(), info(), mo_recode, msg, msg_create, msg_destroy(), msg_dump(), mt_reply, obey_request(), octstr_compare(), octstr_create, octstr_destroy(), octstr_duplicate, octstr_get_cstr, octstr_imm(), octstr_len(), octstr_recode(), reply(), report_mo, send_message(), sms_swap(), text, urltrans_alt_charset(), urltrans_faked_sender(), urltrans_find(), urltrans_find_service(), urltrans_name(), uuid_copy(), warning(), and write_to_bearerbox().

Referenced by main().

1647 {
1648  Msg *msg, *mack, *reply_msg;
1649  Octstr *tmp, *reply;
1650  URLTranslation *trans;
1651  Octstr *p;
1652  int ret, dreport=0;
1653 
1654  while ((msg = gwlist_consume(smsbox_requests)) != NULL) {
1655 
1656  if (msg->sms.sms_type == report_mo)
1657  dreport = 1;
1658  else
1659  dreport = 0;
1660 
1661  /* Recode to UTF-8 the MO message if possible */
1662  if (mo_recode && msg->sms.coding == DC_UCS2) {
1663  Octstr *text;
1664 
1665  text = octstr_duplicate(msg->sms.msgdata);
1666  if (octstr_recode(octstr_imm("UTF-8"), octstr_imm("UTF-16BE"), text) == 0) {
1667  info(0, "MO message converted from UCS-2 to UTF-8");
1668  octstr_destroy(msg->sms.msgdata);
1669  msg->sms.msgdata = octstr_duplicate(text);
1670  msg->sms.charset = octstr_create("UTF-8");
1671  msg->sms.coding = DC_7BIT;
1672  }
1673  octstr_destroy(text);
1674  }
1675 
1676  if (octstr_len(msg->sms.sender) == 0 ||
1677  octstr_len(msg->sms.receiver) == 0) {
1678  error(0, "smsbox_req_thread: no sender/receiver, dump follows:");
1679  msg_dump(msg, 0);
1680  /*
1681  * Send NACK to bearerbox, otherwise message remains in store file.
1682  */
1683  mack = msg_create(ack);
1684  mack->ack.nack = ack_failed;
1685  mack->ack.time = msg->sms.time;
1686  uuid_copy(mack->ack.id, msg->sms.id);
1687  write_to_bearerbox(mack);
1688 
1689  msg_destroy(msg);
1690  continue;
1691  }
1692 
1693  /* create ack message to be sent afterwards */
1694  mack = msg_create(ack);
1695  mack->ack.nack = ack_success;
1696  mack->ack.time = msg->sms.time;
1697  uuid_copy(mack->ack.id, msg->sms.id);
1698 
1699  /*
1700  * no smsbox services when we are doing ppg dlr - so trans would be
1701  * NULL in this case.
1702  */
1703  if (dreport) {
1704  if (msg->sms.service == NULL || (msg->sms.service != NULL &&
1705  ppg_service_name != NULL &&
1706  octstr_compare(msg->sms.service, ppg_service_name) == 0)) {
1707  trans = NULL;
1708  } else {
1709  trans = urltrans_find_service(translations, msg);
1710  }
1711 
1712  info(0, "Starting delivery report <%s> from <%s>",
1713  octstr_get_cstr(msg->sms.service),
1714  octstr_get_cstr(msg->sms.sender));
1715 
1716  } else {
1717  trans = urltrans_find(translations, msg);
1718  if (trans == NULL) {
1719  warning(0, "No translation found for <%s> from <%s> to <%s>",
1720  octstr_get_cstr(msg->sms.msgdata),
1721  octstr_get_cstr(msg->sms.sender),
1722  octstr_get_cstr(msg->sms.receiver));
1723  sms_swap(msg);
1724  goto error;
1725  }
1726 
1727  info(0, "Starting to service <%s> from <%s> to <%s>",
1728  octstr_get_cstr(msg->sms.msgdata),
1729  octstr_get_cstr(msg->sms.sender),
1730  octstr_get_cstr(msg->sms.receiver));
1731 
1732  /*
1733  * Transcode to an alt-charset encoding if requested for sms-service.
1734  * This ensures that legacy systems using Kannel 1.4.1 which used
1735  * latin1 as internal encoding can issue the same content to the
1736  * application servers.
1737  */
1738  tmp = urltrans_alt_charset(trans);
1739  if (tmp != NULL && msg->sms.coding == DC_7BIT) {
1740  if (charset_convert(msg->sms.msgdata, "UTF-8", octstr_get_cstr(tmp)) != 0) {
1741  error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
1742  "UTF-8", octstr_get_cstr(tmp));
1743  }
1744  }
1745 
1746  /*
1747  * now, we change the sender (receiver now 'cause we swap them later)
1748  * if faked-sender or similar set. Note that we ignore if the
1749  * replacement fails.
1750  */
1751  tmp = octstr_duplicate(msg->sms.sender);
1752 
1753  p = urltrans_faked_sender(trans);
1754  if (p != NULL) {
1755  octstr_destroy(msg->sms.sender);
1756  msg->sms.sender = octstr_duplicate(p);
1757  } else if (global_sender != NULL) {
1758  octstr_destroy(msg->sms.sender);
1759  msg->sms.sender = octstr_duplicate(global_sender);
1760  } else {
1761  octstr_destroy(msg->sms.sender);
1762  msg->sms.sender = octstr_duplicate(msg->sms.receiver);
1763  }
1764  octstr_destroy(msg->sms.receiver);
1765  msg->sms.receiver = tmp;
1766  msg->sms.sms_type = mt_reply;
1767  }
1768 
1769  /* TODO: check if the sender is approved to use this service */
1770 
1771  if (msg->sms.service == NULL && trans != NULL)
1772  msg->sms.service = octstr_duplicate(urltrans_name(trans));
1773  ret = obey_request(&reply, trans, msg);
1774  if (ret != 0) {
1775  if (ret == -1) {
1776 error:
1777  error(0, "request failed");
1778  /* XXX this can be something different, according to
1779  urltranslation */
1781  trans = NULL; /* do not use any special translation */
1782  }
1783  if (!dreport) {
1784  /* create reply message */
1785  reply_msg = msg_create(sms);
1786  reply_msg->sms.sms_type = mt_reply;
1787  reply_msg->sms.sender = msg->sms.sender;
1788  msg->sms.sender = NULL;
1789  reply_msg->sms.receiver = msg->sms.receiver;
1790  msg->sms.receiver = NULL;
1791  reply_msg->sms.smsc_id = msg->sms.smsc_id;
1792  msg->sms.smsc_id = NULL;
1793  reply_msg->sms.msgdata = reply;
1794  reply_msg->sms.time = time(NULL); /* set current time */
1795 
1796  /* send message */
1797  if (send_message(trans, reply_msg) < 0)
1798  error(0, "request_thread: failed");
1799 
1800  /* cleanup */
1801  msg_destroy(reply_msg);
1802  }
1803  }
1804 
1805  write_to_bearerbox(mack); /* implicit msg_destroy */
1806 
1807  msg_destroy(msg);
1808  }
1809 }
void msg_dump(Msg *msg, int level)
Definition: msg.c:152
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
URLTranslation * urltrans_find(URLTranslationList *trans, Msg *msg)
Definition: urltrans.c:255
Octstr * urltrans_alt_charset(URLTranslation *t)
Definition: urltrans.c:827
static Octstr * reply_requestfailed
Definition: smsbox.c:133
Definition: msg.h:109
int octstr_recode(Octstr *tocode, Octstr *fromcode, Octstr *orig)
Definition: octstr.c:2574
Octstr * urltrans_faked_sender(URLTranslation *t)
Definition: urltrans.c:787
static List * smsbox_requests
Definition: smsbox.c:144
#define msg_create(type)
Definition: msg.h:136
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Definition: msg.h:79
static URLTranslationList * translations
Definition: smsbox.c:127
char * text
Definition: smsc_cimd2.c:921
static int send_message(URLTranslation *trans, Msg *msg)
Definition: smsbox.c:315
static int mo_recode
Definition: smsbox.c:135
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void uuid_copy(uuid_t dst, const uuid_t src)
Definition: gw_uuid.c:150
void msg_destroy(Msg *msg)
Definition: msg.c:132
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
static Octstr * ppg_service_name
Definition: smsbox.c:142
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
void write_to_bearerbox(Msg *pmsg)
Definition: shared.c:142
Definition: octstr.c:118
void * gwlist_consume(List *list)
Definition: list.c:427
URLTranslation * urltrans_find_service(URLTranslationList *trans, Msg *msg)
Definition: urltrans.c:268
int sms_swap(Msg *msg)
Definition: sms.c:201
Definition: msg.h:107
Octstr * urltrans_name(URLTranslation *t)
Definition: urltrans.c:832
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static int obey_request(Octstr **result, URLTranslation *trans, Msg *msg)
Definition: smsbox.c:1228
static Octstr * global_sender
Definition: smsbox.c:130
#define DC_UCS2
Definition: sms.h:112
static void reply(HTTPClient *c, List *push_headers)
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589
#define DC_7BIT
Definition: sms.h:110
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static long outstanding_requests ( void  )
static

Definition at line 502 of file smsbox.c.

References counter_value().

Referenced by main().

503 {
505 }
unsigned long counter_value(Counter *counter)
Definition: counter.c:145
static Counter * num_outstanding_requests
Definition: smsbox.c:430
static void read_messages_from_bearerbox ( void  )
static

Definition at line 242 of file smsbox.c.

References cmd_restart, cmd_shutdown, delayed_http_reply(), error(), gwlist_produce(), immediate_sendsms_reply, INFINITE_TIME, info(), msg, msg_destroy(), read_from_bearerbox(), restart, shutting_down, start, and warning().

Referenced by main().

243 {
244  time_t start, t;
245  int secs;
246  int total = 0;
247  int ret;
248  Msg *msg;
249 
250  start = t = time(NULL);
251  while (program_status != shutting_down) {
252  /* block infinite for reading messages */
253  ret = read_from_bearerbox(&msg, INFINITE_TIME);
254  if (ret == -1) {
255  if (program_status != shutting_down) {
256  error(0, "Bearerbox is gone, restarting");
258  restart = 1;
259  }
260  break;
261  } else if (ret == 1) /* timeout */
262  continue;
263  else if (msg == NULL) /* just to be sure, may not happens */
264  break;
265 
266  if (msg_type(msg) == admin) {
267  if (msg->admin.command == cmd_shutdown) {
268  info(0, "Bearerbox told us to die");
270  } else if (msg->admin.command == cmd_restart) {
271  info(0, "Bearerbox told us to restart");
272  restart = 1;
274  }
275  /*
276  * XXXX here should be suspend/resume, add RSN
277  */
278  msg_destroy(msg);
279  } else if (msg_type(msg) == sms) {
280  if (total == 0)
281  start = time(NULL);
282  total++;
284  } else if (msg_type(msg) == ack) {
286  delayed_http_reply(msg);
287  msg_destroy(msg);
288  } else {
289  warning(0, "Received other message than sms/admin, ignoring!");
290  msg_destroy(msg);
291  }
292  }
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);
296 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
void gwlist_produce(List *list, void *item)
Definition: list.c:411
program_status
Definition: shared.h:79
int read_from_bearerbox(Msg **msg, double seconds)
Definition: shared.c:220
msg_type
Definition: msg.h:73
static List * smsbox_requests
Definition: smsbox.c:144
static void delayed_http_reply(Msg *msg)
Definition: smsbox.c:185
#define INFINITE_TIME
Definition: shared.h:73
Definition: msg.h:79
void msg_destroy(Msg *msg)
Definition: msg.c:132
void warning(int err, const char *fmt,...)
Definition: log.c:624
volatile sig_atomic_t restart
Definition: smsbox.c:113
static int immediate_sendsms_reply
Definition: smsbox.c:158
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static int start
static void* remember_receiver ( Msg msg,
URLTranslation trans,
int  method,
Octstr url,
List headers,
Octstr body,
unsigned int  retries 
)
static

Definition at line 446 of file smsbox.c.

References receiver::body, counter_increase(), http_header_duplicate(), receiver::http_headers, method, receiver::method, receiver::msg, msg_create, octstr_compare(), octstr_duplicate, retries, receiver::retries, receiver::trans, receiver::url, and urltrans_name().

Referenced by http_queue_thread(), obey_request(), and url_result_thread().

449 {
450  struct receiver *receiver;
451 
453  receiver = gw_malloc(sizeof(*receiver));
454 
455  receiver->msg = msg_create(sms);
456 
457  receiver->msg->sms.sender = octstr_duplicate(msg->sms.sender);
458  receiver->msg->sms.receiver = octstr_duplicate(msg->sms.receiver);
459  /* ppg_service_name should always be not NULL here */
460  if (trans != NULL && (msg->sms.service == NULL || ppg_service_name == NULL ||
461  octstr_compare(msg->sms.service, ppg_service_name) != 0)) {
462  receiver->msg->sms.service = octstr_duplicate(urltrans_name(trans));
463  } else {
464  receiver->msg->sms.service = octstr_duplicate(msg->sms.service);
465  }
466  receiver->msg->sms.smsc_id = octstr_duplicate(msg->sms.smsc_id);
467  /* to remember if it's a DLR http get */
468  receiver->msg->sms.sms_type = msg->sms.sms_type;
469 
470  receiver->trans = trans;
471 
472  /* remember the HTTP request if we need to queue this */
473  receiver->method = method;
474  receiver->url = octstr_duplicate(url);
475  receiver->http_headers = http_header_duplicate(headers);
476  receiver->body = octstr_duplicate(body);
477  receiver->retries = retries;
478 
479  return receiver;
480 }
List * http_headers
Definition: smsbox.c:438
Octstr * url
Definition: smsbox.c:437
int method
Definition: smsbox.c:436
#define msg_create(type)
Definition: msg.h:136
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
Msg * msg
Definition: smsbox.c:434
static long retries
Definition: test_ppg.c:116
#define octstr_duplicate(ostr)
Definition: octstr.h:187
URLTranslation * trans
Definition: smsbox.c:435
static int method
Definition: test_http.c:76
Octstr * body
Definition: smsbox.c:439
unsigned long retries
Definition: smsbox.c:440
static Counter * num_outstanding_requests
Definition: smsbox.c:430
static Octstr * ppg_service_name
Definition: smsbox.c:142
List * http_header_duplicate(List *headers)
Definition: http.c:2946
Octstr * urltrans_name(URLTranslation *t)
Definition: urltrans.c:832
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static int send_message ( URLTranslation trans,
Msg msg 
)
static

Definition at line 315 of file smsbox.c.

References counter_increase(), debug(), gw_assert(), gwlist_destroy(), gwlist_extract_first(), gwlist_len(), info(), msg_destroy(), msg_duplicate(), mt_reply, octstr_append(), octstr_delete(), octstr_duplicate, octstr_len(), sms_max_length, sms_split(), urltrans_concatenation(), urltrans_dlr_mask(), urltrans_dlr_url(), urltrans_footer(), urltrans_header(), urltrans_max_messages(), urltrans_omit_empty(), urltrans_split_chars(), urltrans_split_suffix(), and write_to_bearerbox().

Referenced by obey_request_thread(), smsbox_req_handle(), smsbox_req_sendota(), smsbox_sendota_post(), and url_result_thread().

316 {
317  int max_msgs;
318  Octstr *header, *footer, *suffix, *split_chars;
319  int catenate;
320  unsigned long msg_sequence, msg_count;
321  List *list;
322  Msg *part;
323 
324  gw_assert(msg != NULL);
325  gw_assert(msg_type(msg) == sms);
326 
327  if (trans != NULL)
328  max_msgs = urltrans_max_messages(trans);
329  else
330  max_msgs = 1;
331 
332  if (max_msgs == 0) {
333  info(0, "No reply sent, denied.");
334  return 0;
335  }
336 
337  /*
338  * Encode our smsbox-id to the msg structure.
339  * This will allow bearerbox to return specific answers to the
340  * same smsbox, mainly for DLRs and SMS proxy modes.
341  */
342  if (smsbox_id != NULL) {
343  msg->sms.boxc_id = octstr_duplicate(smsbox_id);
344  }
345 
346  /*
347  * Empty message? Two alternatives have to be handled:
348  * a) it's a HTTP sms-service reply: either ignore it or
349  * substitute the "empty" warning defined
350  * b) it's a sendsms HTTP interface call: leave the message empty
351  */
352  if (octstr_len(msg->sms.msgdata) == 0 && msg->sms.sms_type == mt_reply) {
353  if (trans != NULL && urltrans_omit_empty(trans))
354  return 0;
355  else
356  msg->sms.msgdata = octstr_duplicate(reply_emptymessage);
357  }
358 
359  if (trans == NULL) {
360  header = NULL;
361  footer = NULL;
362  suffix = NULL;
363  split_chars = NULL;
364  catenate = 0;
365  } else {
366  header = urltrans_header(trans);
367  footer = urltrans_footer(trans);
368  suffix = urltrans_split_suffix(trans);
369  split_chars = urltrans_split_chars(trans);
370  catenate = urltrans_concatenation(trans);
371 
372  /*
373  * If there hasn't been yet any DLR-URL set in the message
374  * and we have configured values from the URLTranslation,
375  * hence the 'group = sms-service' context group, then use
376  * them in the message.
377  */
378  if (msg->sms.dlr_url == NULL &&
379  (msg->sms.dlr_url = octstr_duplicate(urltrans_dlr_url(trans))) != NULL)
380  msg->sms.dlr_mask = urltrans_dlr_mask(trans);
381  }
382 
383  if (catenate)
384  msg_sequence = counter_increase(catenated_sms_counter) & 0xFF;
385  else
386  msg_sequence = 0;
387 
388  list = sms_split(msg, header, footer, suffix, split_chars, catenate,
389  msg_sequence, max_msgs, sms_max_length);
390  msg_count = gwlist_len(list);
391 
392  debug("sms", 0, "message length %ld, sending %ld messages",
393  octstr_len(msg->sms.msgdata), msg_count);
394 
395  /*
396  * In order to get catenated msgs work properly, we
397  * have moved catenation to bearerbox.
398  * So here we just need to put splitted msgs into one again and send
399  * to bearerbox that will care about catenation.
400  */
401  if (catenate) {
402  Msg *new_msg = msg_duplicate(msg);
403  octstr_delete(new_msg->sms.msgdata, 0, octstr_len(new_msg->sms.msgdata));
404  while((part = gwlist_extract_first(list)) != NULL) {
405  octstr_append(new_msg->sms.msgdata, part->sms.msgdata);
406  msg_destroy(part);
407  }
408  write_to_bearerbox(new_msg);
409  } else {
410  /* msgs are the independent parts so sent those as is */
411  while ((part = gwlist_extract_first(list)) != NULL)
412  write_to_bearerbox(part);
413  }
414 
415  gwlist_destroy(list, NULL);
416 
417  return msg_count;
418 }
void info(int err, const char *fmt,...)
Definition: log.c:636
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
Octstr * urltrans_footer(URLTranslation *t)
Definition: urltrans.c:822
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
static long sms_max_length
Definition: smsbox.c:128
long gwlist_len(List *list)
Definition: list.c:166
Octstr * urltrans_split_chars(URLTranslation *t)
Definition: urltrans.c:802
msg_type
Definition: msg.h:73
Octstr * urltrans_dlr_url(URLTranslation *t)
Definition: urltrans.c:927
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)
Definition: sms.c:309
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
static Octstr * smsbox_id
Definition: smsbox.c:120
Octstr * urltrans_header(URLTranslation *t)
Definition: urltrans.c:817
Definition: msg.h:79
int urltrans_dlr_mask(URLTranslation *t)
Definition: urltrans.c:932
void * gwlist_extract_first(List *list)
Definition: list.c:305
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void msg_destroy(Msg *msg)
Definition: msg.c:132
int urltrans_omit_empty(URLTranslation *t)
Definition: urltrans.c:812
Octstr * urltrans_split_suffix(URLTranslation *t)
Definition: urltrans.c:807
gw_assert(wtls_machine->packet_to_send!=NULL)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
static Octstr * reply_emptymessage
Definition: smsbox.c:134
void write_to_bearerbox(Msg *pmsg)
Definition: shared.c:142
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int urltrans_max_messages(URLTranslation *t)
Definition: urltrans.c:792
static Counter * catenated_sms_counter
Definition: smsbox.c:307
Definition: msg.h:107
Definition: list.c:102
int urltrans_concatenation(URLTranslation *t)
Definition: urltrans.c:797
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static void sendsms_thread ( void *  arg)
static

Definition at line 3153 of file smsbox.c.

References client(), debug(), http_accept_request(), HTTP_ACCEPTED, HTTP_BAD_REQUEST, http_destroy_cgiargs(), http_destroy_headers(), HTTP_NOT_FOUND, http_send_reply(), immediate_sendsms_reply, info(), octstr_compare(), octstr_create, octstr_destroy(), octstr_get_cstr, sendsms_port, smsbox_req_sendota(), smsbox_req_sendsms(), smsbox_sendota_post(), smsbox_sendsms_post(), smsbox_xmlrpc_post(), and url.

Referenced by init_smsbox(), and main().

3154  {
3155  HTTPClient *client;
3156  Octstr *ip, *url, *body, *answer;
3157  List *hdrs, *args;
3158  int status;
3159 
3160  for (;;) {
3161  /* reset request wars */
3162  ip = url = body = answer = NULL;
3163  hdrs = args = NULL;
3164 
3165  client = http_accept_request(sendsms_port, &ip, &url, &hdrs, &body, &args);
3166  if (client == NULL)
3167  break;
3168 
3169  info(0, "smsbox: Got HTTP request <%s> from <%s>",
3170  octstr_get_cstr(url), octstr_get_cstr(ip));
3171 
3172  /*
3173  * determine which kind of HTTP request this is any
3174  * call the necessary routine for it
3175  */
3176 
3177  /* sendsms */
3178  if (octstr_compare(url, sendsms_url) == 0) {
3179  /*
3180  * decide if this is a GET or POST request and let the
3181  * related routine handle the checking
3182  */
3183  if (body == NULL)
3184  answer = smsbox_req_sendsms(args, ip, &status, client);
3185  else
3186  answer = smsbox_sendsms_post(hdrs, body, ip, &status, client);
3187  }
3188  /* XML-RPC */
3189  else if (octstr_compare(url, xmlrpc_url) == 0) {
3190  /*
3191  * XML-RPC request needs to have a POST body
3192  */
3193  if (body == NULL) {
3194  answer = octstr_create("Incomplete request.");
3195  status = HTTP_BAD_REQUEST;
3196  } else
3197  answer = smsbox_xmlrpc_post(hdrs, body, ip, &status);
3198  }
3199  /* sendota */
3200  else if (octstr_compare(url, sendota_url) == 0) {
3201  if (body == NULL)
3202  answer = smsbox_req_sendota(args, ip, &status, client);
3203  else
3204  answer = smsbox_sendota_post(hdrs, body, ip, &status, client);
3205  }
3206  /* add aditional URI compares here */
3207  else {
3208  answer = octstr_create("Unknown request.");
3209  status = HTTP_NOT_FOUND;
3210  }
3211 
3212  debug("sms.http", 0, "Status: %d Answer: <%s>", status,
3213  octstr_get_cstr(answer));
3214 
3215  octstr_destroy(ip);
3216  octstr_destroy(url);
3217  http_destroy_headers(hdrs);
3218  octstr_destroy(body);
3219  http_destroy_cgiargs(args);
3220 
3221  if (immediate_sendsms_reply || status != HTTP_ACCEPTED)
3222  http_send_reply(client, status, sendsms_reply_hdrs, answer);
3223  else {
3224  debug("sms.http", 0, "Delayed reply - wait for bearerbox");
3225  }
3226  octstr_destroy(answer);
3227  }
3228 
3229 }
void info(int err, const char *fmt,...)
Definition: log.c:636
static void client(int port)
Definition: test_udp.c:77
static Octstr * sendota_url
Definition: smsbox.c:122
static Octstr * smsbox_req_sendsms(List *args, Octstr *client_ip, int *status, HTTPClient *client)
Definition: smsbox.c:2465
static Octstr * sendsms_url
Definition: smsbox.c:121
static Octstr * smsbox_xmlrpc_post(List *headers, Octstr *body, Octstr *client_ip, int *status)
Definition: smsbox.c:2704
static Octstr * smsbox_sendota_post(List *headers, Octstr *body, Octstr *client_ip, int *status, HTTPClient *client)
Definition: smsbox.c:2963
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void http_destroy_headers(List *headers)
Definition: http.c:2856
void http_destroy_cgiargs(List *args)
Definition: http.c:2795
void http_send_reply(HTTPClient *client, int status, List *headers, Octstr *body)
Definition: http.c:2671
static Octstr * smsbox_sendsms_post(List *headers, Octstr *body, Octstr *client_ip, int *status, HTTPClient *client)
Definition: smsbox.c:2578
HTTPClient * http_accept_request(int port, Octstr **client_ip, Octstr **url, List **headers, Octstr **body, List **cgivars)
Definition: http.c:2574
static Octstr * xmlrpc_url
Definition: smsbox.c:123
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
static List * sendsms_reply_hdrs
Definition: smsbox.c:160
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * body
Definition: smsbox.c:439
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static long sendsms_port
Definition: smsbox.c:118
static Octstr * smsbox_req_sendota(List *list, Octstr *client_ip, int *status, HTTPClient *client)
Definition: smsbox.c:2773
static int immediate_sendsms_reply
Definition: smsbox.c:158
static Octstr * url
Definition: test_xmlrpc.c:84
Definition: list.c:102
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static void setup_signal_handlers ( void  )
static

Definition at line 3272 of file smsbox.c.

References signal_handler().

Referenced by main().

3272  {
3273  struct sigaction act;
3274 
3275  act.sa_handler = signal_handler;
3276  sigemptyset(&act.sa_mask);
3277  act.sa_flags = 0;
3278  sigaction(SIGINT, &act, NULL);
3279  sigaction(SIGTERM, &act, NULL);
3280  sigaction(SIGQUIT, &act, NULL);
3281  sigaction(SIGHUP, &act, NULL);
3282  sigaction(SIGPIPE, &act, NULL);
3283 }
static void signal_handler(int signum)
Definition: smsbox.c:3236
static void signal_handler ( int  signum)
static

Definition at line 3236 of file smsbox.c.

References alog_reopen(), error(), gwthread_shouldhandlesignal(), log_reopen(), shutting_down, and warning().

Referenced by setup_signal_handlers().

3236  {
3237  /* On some implementations (i.e. linuxthreads), signals are delivered
3238  * to all threads. We only want to handle each signal once for the
3239  * entire box, and we let the gwthread wrapper take care of choosing
3240  * one.
3241  */
3242  if (!gwthread_shouldhandlesignal(signum))
3243  return;
3244 
3245  switch (signum) {
3246  case SIGINT:
3247  case SIGTERM:
3248  if (program_status != shutting_down) {
3249  error(0, "SIGINT received, aborting program...");
3251  }
3252  break;
3253 
3254  case SIGHUP:
3255  warning(0, "SIGHUP received, catching and re-opening logs");
3256  log_reopen();
3257  alog_reopen();
3258  break;
3259 
3260  /*
3261  * It would be more proper to use SIGUSR1 for this, but on some
3262  * platforms that's reserved by the pthread support.
3263  */
3264  case SIGQUIT:
3265  warning(0, "SIGQUIT received, reporting memory usage.");
3266  gw_check_leaks();
3267  break;
3268  }
3269 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void log_reopen(void)
Definition: log.c:261
program_status
Definition: shared.h:79
int gwthread_shouldhandlesignal(int signal)
void warning(int err, const char *fmt,...)
Definition: log.c:624
void alog_reopen(void)
Definition: accesslog.c:85
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 
)
static

Definition at line 1952 of file smsbox.c.

References ACCOUNT_MAX_LEN, alog(), black_list_regex, DC_7BIT, DC_8BIT, DC_UNDEF, dict_put(), dict_remove(), dlr_mask, error(), gwlist_append(), gwlist_append_unique(), gwlist_create, gwlist_delete_matching(), gwlist_destroy(), gwlist_extract_first(), gwlist_get(), gwlist_len(), HTTP_ACCEPTED, HTTP_BAD_REQUEST, HTTP_INTERNAL_SERVER_ERROR, immediate_sendsms_reply, info(), MAX_SMS_OCTETS, msg_create, msg_destroy(), mt_push, numhash_find_number(), O_DESTROY, octstr_case_compare(), octstr_copy, octstr_create, octstr_destroy(), octstr_destroy_item(), octstr_duplicate, octstr_format_append(), octstr_get_char(), octstr_get_cstr, octstr_imm(), octstr_item_match(), octstr_len(), octstr_search_chars(), octstr_split_words(), send_message(), sendsms_number_chars, sms_charset_processing(), SMS_PARAM_UNDEFINED, store_uuid(), urltrans_black_list(), urltrans_black_list_regex(), urltrans_default_sender(), urltrans_default_smsc(), urltrans_faked_sender(), urltrans_forced_smsc(), urltrans_name(), urltrans_username(), urltrans_white_list(), urltrans_white_list_regex(), warning(), and white_list_regex.

Referenced by smsbox_req_sendsms(), and smsbox_sendsms_post().

1961 {
1962  Msg *msg = NULL;
1963  Octstr *newfrom = NULL;
1964  Octstr *returnerror = NULL;
1965  Octstr *receiv;
1966  Octstr *stored_uuid = NULL;
1967  List *failed_id = NULL;
1968  List *allowed = NULL;
1969  List *denied = NULL;
1970  int no_recv, ret = 0, i;
1971 
1972  /*
1973  * Multi-cast messages with several receivers in 'to' are handled
1974  * in a loop. We only change sms.time and sms.receiver within the
1975  * loop below, because everything else is identical for all receivers.
1976  * If receiver is not null, to list is already present on it
1977  */
1978  if(receiver == NULL) {
1979  receiver = octstr_split_words(to);
1980  }
1981  no_recv = gwlist_len(receiver);
1982 
1983  /*
1984  * check if UDH length is legal, or otherwise discard the
1985  * message, to prevent intentional buffer overflow schemes
1986  */
1987  if (udh != NULL && (octstr_len(udh) != octstr_get_char(udh, 0) + 1)) {
1988  returnerror = octstr_create("UDH field misformed, rejected");
1989  goto field_error;
1990  }
1991  if (udh != NULL && octstr_len(udh) > MAX_SMS_OCTETS) {
1992  returnerror = octstr_create("UDH field is too long, rejected");
1993  goto field_error;
1994  }
1995 
1996  /*
1997  * Check for white and black lists, first for the URLTranlation
1998  * lists and then for the global lists.
1999  *
2000  * Set the 'allowed' and 'denied' lists accordingly to process at
2001  * least all allowed receiver messages. This is a constrain
2002  * walk through all disallowing rules within the lists.
2003  */
2004  allowed = gwlist_create();
2005  denied = gwlist_create();
2006 
2007  for (i = 0; i < no_recv; i++) {
2008  receiv = gwlist_get(receiver, i);
2009 
2010  /*
2011  * Check if there are any illegal characters in the 'to' scheme
2012  */
2013  if (strspn(octstr_get_cstr(receiv), sendsms_number_chars) < octstr_len(receiv)) {
2014  info(0,"Illegal characters in 'to' string ('%s') vs '%s'",
2016  gwlist_append_unique(denied, receiv, octstr_item_match);
2017  }
2018 
2019  /*
2020  * First of all fill the two lists systematicaly by the rules,
2021  * then we will revice the lists.
2022  */
2023  if (urltrans_white_list(t) &&
2024  numhash_find_number(urltrans_white_list(t), receiv) < 1) {
2025  info(0, "Number <%s> is not in white-list, message discarded",
2026  octstr_get_cstr(receiv));
2027  gwlist_append_unique(denied, receiv, octstr_item_match);
2028  } else {
2029  gwlist_append_unique(allowed, receiv, octstr_item_match);
2030  }
2031 
2032  if (urltrans_white_list_regex(t) &&
2033  gw_regex_match_pre(urltrans_white_list_regex(t), receiv) == 0) {
2034  info(0, "Number <%s> is not in white-list-regex, message discarded",
2035  octstr_get_cstr(receiv));
2036  gwlist_append_unique(denied, receiv, octstr_item_match);
2037  } else {
2038  gwlist_append_unique(allowed, receiv, octstr_item_match);
2039  }
2040 
2041  if (urltrans_black_list(t) &&
2042  numhash_find_number(urltrans_black_list(t), receiv) == 1) {
2043  info(0, "Number <%s> is in black-list, message discarded",
2044  octstr_get_cstr(receiv));
2045  gwlist_append_unique(denied, receiv, octstr_item_match);
2046  } else {
2047  gwlist_append_unique(allowed, receiv, octstr_item_match);
2048  }
2049 
2050  if (urltrans_black_list_regex(t) &&
2051  gw_regex_match_pre(urltrans_black_list_regex(t), receiv) == 1) {
2052  info(0, "Number <%s> is in black-list-regex, message discarded",
2053  octstr_get_cstr(receiv));
2054  gwlist_append_unique(denied, receiv, octstr_item_match);
2055  } else {
2056  gwlist_append_unique(allowed, receiv, octstr_item_match);
2057  }
2058 
2059 
2060  if (white_list &&
2061  numhash_find_number(white_list, receiv) < 1) {
2062  info(0, "Number <%s> is not in global white-list, message discarded",
2063  octstr_get_cstr(receiv));
2064  gwlist_append_unique(denied, receiv, octstr_item_match);
2065  } else {
2066  gwlist_append_unique(allowed, receiv, octstr_item_match);
2067  }
2068 
2069  if (white_list_regex &&
2070  gw_regex_match_pre(white_list_regex, receiv) == 0) {
2071  info(0, "Number <%s> is not in global white-list-regex, message discarded",
2072  octstr_get_cstr(receiv));
2073  gwlist_append_unique(denied, receiv, octstr_item_match);
2074  } else {
2075  gwlist_append_unique(allowed, receiv, octstr_item_match);
2076  }
2077 
2078  if (black_list &&
2079  numhash_find_number(black_list, receiv) == 1) {
2080  info(0, "Number <%s> is in global black-list, message discarded",
2081  octstr_get_cstr(receiv));
2082  gwlist_append_unique(denied, receiv, octstr_item_match);
2083  } else {
2084  gwlist_append_unique(allowed, receiv, octstr_item_match);
2085  }
2086 
2087  if (black_list_regex &&
2088  gw_regex_match_pre(black_list_regex, receiv) == 1) {
2089  info(0, "Number <%s> is in global black-list-regex, message discarded",
2090  octstr_get_cstr(receiv));
2091  gwlist_append_unique(denied, receiv, octstr_item_match);
2092  } else {
2093  gwlist_append_unique(allowed, receiv, octstr_item_match);
2094  }
2095  }
2096 
2097  /*
2098  * Now we have to revise the 'allowed' and 'denied' lists by walking
2099  * the 'denied' list and check if items are also present in 'allowed',
2100  * then we will discard them from 'allowed'.
2101  */
2102  for (i = 0; i < gwlist_len(denied); i++) {
2103  receiv = gwlist_get(denied, i);
2104  gwlist_delete_matching(allowed, receiv, octstr_item_match);
2105  }
2106 
2107  /* have all receivers been denied by list rules?! */
2108  if (gwlist_len(allowed) == 0) {
2109  returnerror = octstr_create("Number(s) has/have been denied by white- and/or black-lists.");
2110  goto field_error;
2111  }
2112 
2113  if (urltrans_faked_sender(t) != NULL) {
2114  /* discard previous from */
2116  } else if (octstr_len(from) > 0) {
2117  newfrom = octstr_duplicate(from);
2118  } else if (urltrans_default_sender(t) != NULL) {
2120  } else if (global_sender != NULL) {
2121  newfrom = octstr_duplicate(global_sender);
2122  } else {
2123  returnerror = octstr_create("Sender missing and no global set, rejected");
2124  goto field_error;
2125  }
2126 
2127  info(0, "sendsms sender:<%s:%s> (%s) to:<%s> msg:<%s>",
2129  octstr_get_cstr(newfrom),
2130  octstr_get_cstr(client_ip),
2131  ( to == NULL ? "multi-cast" : octstr_get_cstr(to) ),
2132  ( text == NULL ? "" : octstr_get_cstr(text) ));
2133 
2134  /*
2135  * Create the msg structure and fill the types. Note that sms.receiver
2136  * and sms.time are set in the multi-cast support loop below.
2137  */
2138  msg = msg_create(sms);
2139 
2140  msg->sms.service = octstr_duplicate(urltrans_name(t));
2141  msg->sms.sms_type = mt_push;
2142  msg->sms.sender = octstr_duplicate(newfrom);
2143  if(octstr_len(account)) {
2144  if(octstr_len(account) <= ACCOUNT_MAX_LEN &&
2145  octstr_search_chars(account, octstr_imm("[]\n\r"), 0) == -1) {
2146  msg->sms.account = account ? octstr_duplicate(account) : NULL;
2147  } else {
2148  returnerror = octstr_create("Account field misformed or too long, rejected");
2149  goto field_error;
2150  }
2151  }
2152  msg->sms.msgdata = text ? octstr_duplicate(text) : octstr_create("");
2153  msg->sms.udhdata = udh ? octstr_duplicate(udh) : octstr_create("");
2154 
2155  if (octstr_len(binfo))
2156  msg->sms.binfo = octstr_duplicate(binfo);
2157 
2158  if(octstr_len(dlr_url)) {
2159  if(octstr_len(dlr_url) < 8) { /* http(s):// */
2160  returnerror = octstr_create("DLR-URL field misformed, rejected");
2161  goto field_error;
2162  } else {
2163  Octstr *tmp;
2164  tmp = octstr_copy(dlr_url, 0, 7);
2165  if(octstr_case_compare(tmp, octstr_imm("http://")) == 0) {
2166  msg->sms.dlr_url = octstr_duplicate(dlr_url);
2167  } else {
2168  O_DESTROY(tmp);
2169  tmp = octstr_copy(dlr_url, 0, 8);
2170  if(octstr_case_compare(tmp, octstr_imm("https://")) != 0) {
2171  returnerror = octstr_create("DLR-URL field misformed, rejected");
2172  O_DESTROY(tmp);
2173  goto field_error;
2174  }
2175 #ifdef HAVE_LIBSSL
2176  msg->sms.dlr_url = octstr_duplicate(dlr_url);
2177 #else /* HAVE_LIBSSL */
2178  else {
2179  warning(0, "DLR-URL with https but SSL not supported, url is <%s>",
2180  octstr_get_cstr(dlr_url));
2181  }
2182 #endif /* HAVE_LIBSSL */
2183  }
2184  O_DESTROY(tmp);
2185  }
2186  } else {
2187  msg->sms.dlr_url = octstr_create("");
2188  }
2189 
2190  if ( dlr_mask < -1 || dlr_mask > 66 ) { /* 01000010 */
2191  returnerror = octstr_create("DLR-Mask field misformed, rejected");
2192  goto field_error;
2193  }
2194  msg->sms.dlr_mask = dlr_mask;
2195 
2196  if ( mclass < -1 || mclass > 3 ) {
2197  returnerror = octstr_create("MClass field misformed, rejected");
2198  goto field_error;
2199  }
2200  msg->sms.mclass = mclass;
2201 
2202  if ( pid < -1 || pid > 255 ) {
2203  returnerror = octstr_create("PID field misformed, rejected");
2204  goto field_error;
2205  }
2206  msg->sms.pid = pid;
2207 
2208  if ( rpi < -1 || rpi > 2) {
2209  returnerror = octstr_create("RPI field misformed, rejected");
2210  goto field_error;
2211  }
2212  msg->sms.rpi = rpi;
2213 
2214  if ( alt_dcs < -1 || alt_dcs > 1 ) {
2215  returnerror = octstr_create("Alt-DCS field misformed, rejected");
2216  goto field_error;
2217  }
2218  msg->sms.alt_dcs = alt_dcs;
2219 
2220  if ( mwi < -1 || mwi > 7 ) {
2221  returnerror = octstr_create("MWI field misformed, rejected");
2222  goto field_error;
2223  }
2224  msg->sms.mwi = mwi;
2225 
2226  if ( coding < -1 || coding > 2 ) {
2227  returnerror = octstr_create("Coding field misformed, rejected");
2228  goto field_error;
2229  }
2230  msg->sms.coding = coding;
2231 
2232  if ( compress < -1 || compress > 1 ) {
2233  returnerror = octstr_create("Compress field misformed, rejected");
2234  goto field_error;
2235  }
2236  msg->sms.compress = compress;
2237 
2238  /* Compatibility Mode */
2239  if ( msg->sms.coding == DC_UNDEF) {
2240  if(octstr_len(udh))
2241  msg->sms.coding = DC_8BIT;
2242  else
2243  msg->sms.coding = DC_7BIT;
2244  }
2245 
2246 
2247  if (validity < -1) {
2248  returnerror = octstr_create("Validity field misformed, rejected");
2249  goto field_error;
2250  } else if (validity != SMS_PARAM_UNDEFINED)
2251  msg->sms.validity = validity * 60 + time(NULL);
2252 
2253  if (deferred < -1) {
2254  returnerror = octstr_create("Deferred field misformed, rejected");
2255  goto field_error;
2256  } else if (deferred != SMS_PARAM_UNDEFINED)
2257  msg->sms.deferred = deferred * 60 + time(NULL);
2258 
2259  if (priority != SMS_PARAM_UNDEFINED && (priority < 0 || priority > 3)) {
2260  returnerror = octstr_create("Priority field misformed, rejected");
2261  goto field_error;
2262  }
2263  msg->sms.priority = priority;
2264 
2265 
2266  /* new smsc-id argument - we should check this one, if able,
2267  but that's advanced logics -- Kalle */
2268 
2269  if (urltrans_forced_smsc(t)) {
2270  msg->sms.smsc_id = octstr_duplicate(urltrans_forced_smsc(t));
2271  if (smsc)
2272  info(0, "send-sms request smsc id ignored, "
2273  "as smsc id forced to %s",
2275  } else if (smsc) {
2276  msg->sms.smsc_id = octstr_duplicate(smsc);
2277  } else if (urltrans_default_smsc(t)) {
2278  msg->sms.smsc_id = octstr_duplicate(urltrans_default_smsc(t));
2279  } else
2280  msg->sms.smsc_id = NULL;
2281 
2282  if (sms_charset_processing(charset, msg->sms.msgdata, msg->sms.coding) == -1) {
2283  returnerror = octstr_create("Charset or body misformed, rejected");
2284  goto field_error;
2285  }
2286 
2287  msg->sms.meta_data = octstr_duplicate(meta_data);
2288 
2289  msg->sms.receiver = NULL;
2290 
2291  /*
2292  * All checks are done, now add multi-cast request support by
2293  * looping through 'allowed'. This should work for any
2294  * number of receivers within 'to'. If the message fails append
2295  * it to 'failed_id'.
2296  */
2297  failed_id = gwlist_create();
2298 
2299  if (!immediate_sendsms_reply) {
2300  stored_uuid = store_uuid(msg);
2301  dict_put(client_dict, stored_uuid, client);
2302  }
2303 
2304  while ((receiv = gwlist_extract_first(allowed)) != NULL) {
2305 
2306  O_DESTROY(msg->sms.receiver);
2307  msg->sms.receiver = octstr_duplicate(receiv);
2308 
2309  msg->sms.time = time(NULL);
2310  /* send the message and return number of splits */
2311  ret = send_message(t, msg);
2312 
2313  if (ret == -1) {
2314  /* add the receiver to the failed list */
2315  gwlist_append(failed_id, receiv);
2316  } else {
2317  /* log the sending as successful for this particular message */
2318  alog("send-SMS request added - sender:%s:%s %s target:%s request: '%s'",
2320  octstr_get_cstr(newfrom), octstr_get_cstr(client_ip),
2321  octstr_get_cstr(receiv),
2322  udh == NULL ? ( text == NULL ? "" : octstr_get_cstr(text) ) : "<< UDH >>");
2323  }
2324  }
2325 
2326  if (gwlist_len(failed_id) > 0)
2327  goto transmit_error;
2328 
2329  *status = HTTP_ACCEPTED;
2330  returnerror = octstr_create("Sent.");
2331 
2332  /*
2333  * Append all denied receivers to the returned body in case this is
2334  * a multi-cast send request
2335  */
2336  if (gwlist_len(denied) > 0) {
2337  octstr_format_append(returnerror, " Denied receivers are:");
2338  while ((receiv = gwlist_extract_first(denied)) != NULL) {
2339  octstr_format_append(returnerror, " %s", octstr_get_cstr(receiv));
2340  }
2341  }
2342 
2343  /*
2344  * Append number of splits to returned body.
2345  * This may be used by the calling client.
2346  */
2347  if (ret > 1)
2348  octstr_format_append(returnerror, " Message splits: %d", ret);
2349 
2350 cleanup:
2351  octstr_destroy(stored_uuid);
2352  gwlist_destroy(failed_id, NULL);
2353  gwlist_destroy(allowed, NULL);
2354  gwlist_destroy(denied, NULL);
2356  octstr_destroy(newfrom);
2357  msg_destroy(msg);
2358 
2359  return returnerror;
2360 
2361 
2362 field_error:
2363  alog("send-SMS request failed - %s",
2364  octstr_get_cstr(returnerror));
2366 
2367  goto cleanup;
2368 
2369 transmit_error:
2370  error(0, "sendsms_request: failed");
2372  returnerror = octstr_create("Sending failed.");
2373 
2375  dict_remove(client_dict, stored_uuid);
2376 
2377  /*
2378  * Append all receivers to the returned body in case this is
2379  * a multi-cast send request
2380  */
2381  if (no_recv > 1) {
2382  octstr_format_append(returnerror, " Failed receivers are:");
2383  while ((receiv = gwlist_extract_first(failed_id)) != NULL) {
2384  octstr_format_append(returnerror, " %s", octstr_get_cstr(receiv));
2385  }
2386  }
2387 
2388  goto cleanup;
2389 }
static Octstr * dlr_mask
Definition: test_ppg.c:106
regex_t * urltrans_black_list_regex(URLTranslation *t)
Definition: urltrans.c:902
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
#define MAX_SMS_OCTETS
Definition: sms.h:129
Octstr * urltrans_forced_smsc(URLTranslation *t)
Definition: urltrans.c:847
long octstr_search_chars(const Octstr *ostr, const Octstr *chars, long pos)
Definition: octstr.c:1050
Numhash * urltrans_black_list(URLTranslation *t)
Definition: urltrans.c:897
regex_t * urltrans_white_list_regex(URLTranslation *t)
Definition: urltrans.c:892
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
void gwlist_append(List *list, void *item)
Definition: list.c:179
Octstr * urltrans_default_smsc(URLTranslation *t)
Definition: urltrans.c:852
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * urltrans_faked_sender(URLTranslation *t)
Definition: urltrans.c:787
#define ACCOUNT_MAX_LEN
Definition: smsbox.c:99
static Dict * client_dict
Definition: smsbox.c:159
#define DC_8BIT
Definition: sms.h:111
Octstr * urltrans_username(URLTranslation *t)
Definition: urltrans.c:837
#define msg_create(type)
Definition: msg.h:136
static regex_t * black_list_regex
Definition: smsbox.c:139
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
Definition: msg.h:108
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Definition: msg.h:79
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
int numhash_find_number(Numhash *table, Octstr *nro)
Definition: numhash.c:218
static regex_t * white_list_regex
Definition: smsbox.c:138
void * gwlist_extract_first(List *list)
Definition: list.c:305
static int send_message(URLTranslation *trans, Msg *msg)
Definition: smsbox.c:315
#define octstr_duplicate(ostr)
Definition: octstr.h:187
int octstr_item_match(void *item, void *pattern)
Definition: octstr.c:1659
void msg_destroy(Msg *msg)
Definition: msg.c:132
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
void warning(int err, const char *fmt,...)
Definition: log.c:624
List * octstr_split_words(const Octstr *ostr)
Definition: octstr.c:1600
Octstr * urltrans_default_sender(URLTranslation *t)
Definition: urltrans.c:782
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
int sms_charset_processing(Octstr *charset, Octstr *body, int coding)
Definition: sms.c:419
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:334
#define O_DESTROY(a)
Definition: smsbox.c:97
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
static Numhash * black_list
Definition: smsbox.c:137
Numhash * urltrans_white_list(URLTranslation *t)
Definition: urltrans.c:887
static Numhash * white_list
Definition: smsbox.c:136
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
long gwlist_delete_matching(List *list, void *pat, gwlist_item_matches_t *matches)
Definition: list.c:240
void gwlist_append_unique(List *list, void *item, int(*cmp)(void *, void *))
Definition: list.c:190
Definition: octstr.c:118
static Octstr * store_uuid(Msg *msg)
Definition: smsbox.c:1931
void alog(const char *fmt,...)
Definition: accesslog.c:206
static int immediate_sendsms_reply
Definition: smsbox.c:158
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505
#define gwlist_create()
Definition: list.h:136
#define DC_UNDEF
Definition: sms.h:109
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
Octstr * urltrans_name(URLTranslation *t)
Definition: urltrans.c:832
static char * sendsms_number_chars
Definition: smsbox.c:129
Definition: list.c:102
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static Octstr * global_sender
Definition: smsbox.c:130
#define DC_7BIT
Definition: sms.h:110
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static Octstr* smsbox_req_sendota ( List list,
Octstr client_ip,
int *  status,
HTTPClient client 
)
static

Definition at line 2773 of file smsbox.c.

References account, authorise_user(), cfg_get, cfg_get_multi_group(), debug(), dict_put(), dict_remove(), error(), found, from, gwlist_destroy(), gwlist_extract_first(), HTTP_ACCEPTED, HTTP_BAD_REQUEST, http_cgi_variable(), HTTP_FORBIDDEN, HTTP_INTERNAL_SERVER_ERROR, immediate_sendsms_reply, info(), msg, msg_destroy(), octstr_compare(), octstr_create, octstr_destroy(), octstr_dump, octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_imm(), octstr_len(), ota_pack_message(), ota_tokenize_bookmarks(), ota_tokenize_settings(), send_message(), store_uuid(), urltrans_default_sender(), urltrans_default_smsc(), urltrans_faked_sender(), and urltrans_forced_smsc().

Referenced by sendsms_thread().

2775 {
2776  Octstr *id, *from, *phonenumber, *smsc, *ota_doc, *doc_type, *account;
2777  CfgGroup *grp;
2778  Octstr *returnerror;
2779  Octstr *stored_uuid = NULL;
2780  List *grplist;
2781  Octstr *p;
2782  URLTranslation *t;
2783  Msg *msg;
2784  int ret, ota_type;
2785 
2786  id = phonenumber = smsc = account = NULL;
2787 
2788  /* check the username and password */
2789  t = authorise_user(list, client_ip);
2790  if (t == NULL) {
2792  return octstr_create("Authorization failed for sendota");
2793  }
2794 
2795  if ((phonenumber = http_cgi_variable(list, "to")) == NULL) {
2796  if ((phonenumber = http_cgi_variable(list, "phonenumber")) == NULL) {
2797  error(0, "%s needs a valid phone number.", octstr_get_cstr(sendota_url));
2799  return octstr_create("Wrong sendota args.");
2800  }
2801  }
2802 
2803  if (urltrans_faked_sender(t) != NULL) {
2805  } else if ((from = http_cgi_variable(list, "from")) != NULL &&
2806  octstr_len(from) > 0) {
2807  from = octstr_duplicate(from);
2808  } else if (urltrans_default_sender(t) != NULL) {
2810  } else if (global_sender != NULL) {
2812  } else {
2814  return octstr_create("Sender missing and no global set, rejected");
2815  }
2816 
2817  /* check does we have an external XML source for configuration */
2818  if ((ota_doc = http_cgi_variable(list, "text")) != NULL) {
2819  Octstr *sec, *pin;
2820 
2821  /*
2822  * We are doing the XML OTA compiler mode for this request
2823  */
2824  debug("sms", 0, "OTA service with XML document");
2825  ota_doc = octstr_duplicate(ota_doc);
2826  if ((doc_type = http_cgi_variable(list, "type")) == NULL)
2827  doc_type = octstr_format("%s", "settings");
2828  else
2829  doc_type = octstr_duplicate(doc_type);
2830  if ((sec = http_cgi_variable(list, "sec")) == NULL)
2831  sec = octstr_create("USERPIN");
2832  else
2833  sec = octstr_duplicate(sec);
2834  if ((pin = http_cgi_variable(list, "pin")) == NULL)
2835  pin = octstr_create("12345");
2836  else
2837  pin = octstr_duplicate(pin);
2838 
2839  if ((ret = ota_pack_message(&msg, ota_doc, doc_type, from,
2840  phonenumber, sec, pin)) < 0) {
2842  msg_destroy(msg);
2843  if (ret == -2)
2844  return octstr_create("Erroneous document type, cannot"
2845  " compile\n");
2846  else if (ret == -1)
2847  return octstr_create("Erroneous ota source, cannot compile\n");
2848  }
2849 
2850  goto send;
2851 
2852  } else {
2853 
2854  /*
2855  * We are doing the ota-settings or ota-bookmark group mode
2856  * for this request.
2857  *
2858  * Check if a ota-setting ID has been given and decide which OTA
2859  * properties to be send to the client otherwise try to find a
2860  * ota-bookmark ID. If none is found then send the default
2861  * ota-setting group, which is the first within the config file.
2862  */
2863  id = http_cgi_variable(list, "otaid");
2864 
2865  grplist = cfg_get_multi_group(cfg, octstr_imm("ota-setting"));
2866  while (grplist && (grp = gwlist_extract_first(grplist)) != NULL) {
2867  p = cfg_get(grp, octstr_imm("ota-id"));
2868  if (id == NULL || (p != NULL && octstr_compare(p, id) == 0)) {
2869  ota_type = 1;
2870  goto found;
2871  }
2872  octstr_destroy(p);
2873  }
2874  gwlist_destroy(grplist, NULL);
2875 
2876  grplist = cfg_get_multi_group(cfg, octstr_imm("ota-bookmark"));
2877  while (grplist && (grp = gwlist_extract_first(grplist)) != NULL) {
2878  p = cfg_get(grp, octstr_imm("ota-id"));
2879  if (id == NULL || (p != NULL && octstr_compare(p, id) == 0)) {
2880  ota_type = 0;
2881  goto found;
2882  }
2883  octstr_destroy(p);
2884  }
2885  gwlist_destroy(grplist, NULL);
2886 
2887  if (id != NULL)
2888  error(0, "%s can't find any ota-setting or ota-bookmark group with ota-id '%s'.",
2890  else
2891  error(0, "%s can't find any ota-setting group.", octstr_get_cstr(sendota_url));
2892  octstr_destroy(from);
2894  return octstr_create("Missing ota-setting or ota-bookmark group.");
2895  }
2896 
2897 found:
2898  octstr_destroy(p);
2899  gwlist_destroy(grplist, NULL);
2900 
2901  /* tokenize the OTA settings or bookmarks group and return the message */
2902  if (ota_type)
2903  msg = ota_tokenize_settings(grp, from, phonenumber);
2904  else
2905  msg = ota_tokenize_bookmarks(grp, from, phonenumber);
2906 
2907 send:
2908  /* we still need to check if smsc is forced for this */
2909  smsc = http_cgi_variable(list, "smsc");
2910  if (urltrans_forced_smsc(t)) {
2911  msg->sms.smsc_id = octstr_duplicate(urltrans_forced_smsc(t));
2912  if (smsc)
2913  info(0, "send-sms request smsc id ignored, as smsc id forced to %s",
2915  } else if (smsc) {
2916  msg->sms.smsc_id = octstr_duplicate(smsc);
2917  } else if (urltrans_default_smsc(t)) {
2918  msg->sms.smsc_id = octstr_duplicate(urltrans_default_smsc(t));
2919  } else
2920  msg->sms.smsc_id = NULL;
2921 
2922  account = http_cgi_variable(list, "account");
2923  if (octstr_len(account) > 0)
2924  msg->sms.account = octstr_duplicate(account);
2925 
2926  octstr_dump(msg->sms.msgdata, 0);
2927 
2928  info(0, "%s <%s> <%s>", octstr_get_cstr(sendota_url),
2929  id ? octstr_get_cstr(id) : "<default>", octstr_get_cstr(phonenumber));
2930 
2931  if (!immediate_sendsms_reply) {
2932  stored_uuid = store_uuid(msg);
2933  dict_put(client_dict, stored_uuid, client);
2934  }
2935 
2936  ret = send_message(t, msg);
2937 
2938  if (ret == -1) {
2939  error(0, "sendota_request: failed");
2941  returnerror = octstr_create("Sending failed.");
2942  dict_remove(client_dict, stored_uuid);
2943  } else {
2944  *status = HTTP_ACCEPTED;
2945  returnerror = octstr_create("Sent.");
2946  }
2947 
2948  msg_destroy(msg);
2949  octstr_destroy(stored_uuid);
2950 
2951  return returnerror;
2952 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
Octstr * urltrans_forced_smsc(URLTranslation *t)
Definition: urltrans.c:847
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
Octstr * urltrans_default_smsc(URLTranslation *t)
Definition: urltrans.c:852
Octstr * urltrans_faked_sender(URLTranslation *t)
Definition: urltrans.c:787
static Octstr * sendota_url
Definition: smsbox.c:122
static Dict * client_dict
Definition: smsbox.c:159
#define cfg_get(grp, varname)
Definition: cfg.h:86
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static struct pid_list * found
Octstr * http_cgi_variable(List *list, char *name)
Definition: http.c:2813
static Octstr * from
Definition: mtbatch.c:95
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Definition: msg.h:79
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
void * gwlist_extract_first(List *list)
Definition: list.c:305
static int send_message(URLTranslation *trans, Msg *msg)
Definition: smsbox.c:315
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:642
void msg_destroy(Msg *msg)
Definition: msg.c:132
Octstr * urltrans_default_sender(URLTranslation *t)
Definition: urltrans.c:782
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
static URLTranslation * authorise_user(List *list, Octstr *client_ip)
Definition: smsbox.c:2442
static Cfg * cfg
Definition: smsbox.c:115
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
static Octstr * store_uuid(Msg *msg)
Definition: smsbox.c:1931
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
Definition: cfg.c:73
static int immediate_sendsms_reply
Definition: smsbox.c:158
Msg * ota_tokenize_settings(CfgGroup *grp, Octstr *from, Octstr *receiver)
Definition: ota_prov.c:259
Msg * ota_tokenize_bookmarks(CfgGroup *grp, Octstr *from, Octstr *receiver)
Definition: ota_prov.c:540
Definition: list.c:102
static Octstr * account
Definition: mtbatch.c:94
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int ota_pack_message(Msg **msg, Octstr *ota_doc, Octstr *doc_type, Octstr *from, Octstr *phone_number, Octstr *sec, Octstr *pin)
Definition: ota_prov.c:207
static Octstr * global_sender
Definition: smsbox.c:130
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static Octstr* smsbox_req_sendsms ( List args,
Octstr client_ip,
int *  status,
HTTPClient client 
)
static

Definition at line 2465 of file smsbox.c.

References account, authorise_user(), charset, dlr_mask, dlr_url, error(), from, HTTP_BAD_REQUEST, http_cgi_variable(), HTTP_FORBIDDEN, octstr_create, octstr_get_cstr, octstr_len(), SMS_PARAM_UNDEFINED, smsbox_req_handle(), text, and warning().

Referenced by sendsms_thread().

2467 {
2468  URLTranslation *t = NULL;
2469  Octstr *tmp_string;
2470  Octstr *from, *to, *charset, *text, *udh, *smsc, *dlr_url, *account;
2471  Octstr *binfo, *meta_data;
2472  int dlr_mask, mclass, mwi, coding, compress, validity, deferred, pid;
2473  int alt_dcs, rpi, priority;
2474 
2475  from = to = udh = text = smsc = account = dlr_url = charset = binfo = meta_data = NULL;
2476  mclass = mwi = coding = compress = validity = deferred = dlr_mask =
2477  pid = alt_dcs = rpi = priority = SMS_PARAM_UNDEFINED;
2478 
2479  /* check the username and password */
2480  t = authorise_user(args, client_ip);
2481  if (t == NULL) {
2483  return octstr_create("Authorization failed for sendsms");
2484  }
2485 
2486  udh = http_cgi_variable(args, "udh");
2487  text = http_cgi_variable(args, "text");
2488  charset = http_cgi_variable(args, "charset");
2489  smsc = http_cgi_variable(args, "smsc");
2490  from = http_cgi_variable(args, "from");
2491  to = http_cgi_variable(args, "to");
2492  account = http_cgi_variable(args, "account");
2493  binfo = http_cgi_variable(args, "binfo");
2494  dlr_url = http_cgi_variable(args, "dlr-url");
2495  if(dlr_url == NULL) { /* deprecated dlrurl without "-" */
2496  dlr_url = http_cgi_variable(args, "dlrurl");
2497  if(dlr_url != NULL)
2498  warning(0, "<dlrurl> field used and deprecated. Please use dlr-url instead.");
2499  }
2500  tmp_string = http_cgi_variable(args, "dlr-mask");
2501  if(tmp_string == NULL) { /* deprecated dlrmask without "-" */
2502  tmp_string = http_cgi_variable(args, "dlrmask");
2503  if(tmp_string != NULL)
2504  warning(0, "<dlrmask> field used and deprecated. Please use dlr-mask instead.");
2505  }
2506  if(tmp_string != NULL)
2507  sscanf(octstr_get_cstr(tmp_string),"%d", &dlr_mask);
2508 
2509  tmp_string = http_cgi_variable(args, "mclass");
2510  if(tmp_string != NULL)
2511  sscanf(octstr_get_cstr(tmp_string),"%d", &mclass);
2512 
2513  tmp_string = http_cgi_variable(args, "pid");
2514  if(tmp_string != NULL)
2515  sscanf(octstr_get_cstr(tmp_string),"%d", &pid);
2516 
2517  tmp_string = http_cgi_variable(args, "rpi");
2518  if(tmp_string != NULL)
2519  sscanf(octstr_get_cstr(tmp_string),"%d", &rpi);
2520 
2521  tmp_string = http_cgi_variable(args, "alt-dcs");
2522  if(tmp_string != NULL)
2523  sscanf(octstr_get_cstr(tmp_string),"%d", &alt_dcs);
2524 
2525  tmp_string = http_cgi_variable(args, "mwi");
2526  if(tmp_string != NULL)
2527  sscanf(octstr_get_cstr(tmp_string),"%d", &mwi);
2528 
2529  tmp_string = http_cgi_variable(args, "coding");
2530  if(tmp_string != NULL)
2531  sscanf(octstr_get_cstr(tmp_string),"%d", &coding);
2532 
2533  tmp_string = http_cgi_variable(args, "compress");
2534  if(tmp_string != NULL)
2535  sscanf(octstr_get_cstr(tmp_string),"%d", &compress);
2536 
2537  tmp_string = http_cgi_variable(args, "validity");
2538  if(tmp_string != NULL)
2539  sscanf(octstr_get_cstr(tmp_string),"%d", &validity);
2540 
2541  tmp_string = http_cgi_variable(args, "deferred");
2542  if(tmp_string != NULL)
2543  sscanf(octstr_get_cstr(tmp_string),"%d", &deferred);
2544 
2545  tmp_string = http_cgi_variable(args, "priority");
2546  if(tmp_string != NULL)
2547  sscanf(octstr_get_cstr(tmp_string),"%d", &priority);
2548 
2549  meta_data = http_cgi_variable(args, "meta-data");
2550 
2551  /*
2552  * we required "to" to be defined
2553  */
2554  if (to == NULL) {
2555  error(0, "%s got insufficient headers (<to> is NULL)",
2558  return octstr_create("Missing receiver number, rejected");
2559  }
2560  else if (octstr_len(to) == 0) {
2561  error(0, "%s got empty <to> cgi variable", octstr_get_cstr(sendsms_url));
2563  return octstr_create("Empty receiver number not allowed, rejected");
2564  }
2565 
2566  return smsbox_req_handle(t, client_ip, client, from, to, text, charset, udh,
2567  smsc, mclass, mwi, coding, compress, validity,
2568  deferred, status, dlr_mask, dlr_url, account,
2569  pid, alt_dcs, rpi, NULL, binfo, priority, meta_data);
2570 
2571 }
static Octstr * dlr_mask
Definition: test_ppg.c:106
void error(int err, const char *fmt,...)
Definition: log.c:612
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)
Definition: smsbox.c:1952
static Octstr * sendsms_url
Definition: smsbox.c:121
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * charset
Definition: test_ota.c:68
Octstr * http_cgi_variable(List *list, char *name)
Definition: http.c:2813
static Octstr * from
Definition: mtbatch.c:95
static Octstr * dlr_url
Definition: test_ppg.c:107
char * text
Definition: smsc_cimd2.c:921
void warning(int err, const char *fmt,...)
Definition: log.c:624
#define octstr_create(cstr)
Definition: octstr.h:125
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
static URLTranslation * authorise_user(List *list, Octstr *client_ip)
Definition: smsbox.c:2442
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
static Octstr * account
Definition: mtbatch.c:94
static Octstr* smsbox_sendota_post ( List headers,
Octstr body,
Octstr client_ip,
int *  status,
HTTPClient client 
)
static

Definition at line 2963 of file smsbox.c.

References authorise_username(), charset, dict_put(), dict_remove(), error(), from, gwlist_len(), HTTP_ACCEPTED, HTTP_BAD_REQUEST, HTTP_FORBIDDEN, http_header_get(), http_header_get_content_type(), HTTP_INTERNAL_SERVER_ERROR, HTTP_UNSUPPORTED_MEDIA_TYPE, immediate_sendsms_reply, info(), msg, msg_destroy(), name, octstr_case_compare(), octstr_create, octstr_destroy(), octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_imm(), octstr_len(), octstr_strip_blanks(), ota_pack_message(), send_message(), store_uuid(), type, urltrans_default_sender(), urltrans_default_smsc(), urltrans_faked_sender(), and urltrans_forced_smsc().

Referenced by sendsms_thread().

2966 {
2967  Octstr *name, *val, *ret;
2968  Octstr *from, *to, *id, *user, *pass, *smsc;
2969  Octstr *type, *charset, *doc_type, *ota_doc, *sec, *pin;
2970  Octstr *stored_uuid = NULL;
2971  URLTranslation *t;
2972  Msg *msg;
2973  long l;
2974  int r;
2975 
2976  id = from = to = user = pass = smsc = NULL;
2977  doc_type = ota_doc = sec = pin = NULL;
2978 
2979  /*
2980  * process all special HTTP headers
2981  *
2982  * XXX can't we do this better?
2983  * Obviously http_header_find_first() does this
2984  */
2985  for (l = 0; l < gwlist_len(headers); l++) {
2986  http_header_get(headers, l, &name, &val);
2987 
2988  if (octstr_case_compare(name, octstr_imm("X-Kannel-OTA-ID")) == 0) {
2989  id = octstr_duplicate(val);
2990  octstr_strip_blanks(id);
2991  }
2992  else if (octstr_case_compare(name, octstr_imm("X-Kannel-From")) == 0) {
2993  from = octstr_duplicate(val);
2994  octstr_strip_blanks(from);
2995  }
2996  else if (octstr_case_compare(name, octstr_imm("X-Kannel-To")) == 0) {
2997  to = octstr_duplicate(val);
2998  octstr_strip_blanks(to);
2999  }
3000  else if (octstr_case_compare(name, octstr_imm("X-Kannel-Username")) == 0) {
3001  user = octstr_duplicate(val);
3002  octstr_strip_blanks(user);
3003  }
3004  else if (octstr_case_compare(name, octstr_imm("X-Kannel-Password")) == 0) {
3005  pass = octstr_duplicate(val);
3006  octstr_strip_blanks(pass);
3007  }
3008  else if (octstr_case_compare(name, octstr_imm("X-Kannel-SMSC")) == 0) {
3009  smsc = octstr_duplicate(val);
3010  octstr_strip_blanks(smsc);
3011  }
3012  else if (octstr_case_compare(name, octstr_imm("X-Kannel-SEC")) == 0) {
3013  sec = octstr_duplicate(val);
3014  octstr_strip_blanks(sec);
3015  }
3016  else if (octstr_case_compare(name, octstr_imm("X-Kannel-PIN")) == 0) {
3017  pin = octstr_duplicate(val);
3018  octstr_strip_blanks(pin);
3019  }
3020  }
3021 
3022  /* apply defaults */
3023  if (!sec)
3024  sec = octstr_imm("USERPIN");
3025  if (!pin)
3026  pin = octstr_imm("1234");
3027 
3028  /* check the username and password */
3029  t = authorise_username(user, pass, client_ip);
3030  if (t == NULL) {
3032  ret = octstr_create("Authorization failed for sendota");
3033  }
3034  /* let's see if we have at least a target msisdn */
3035  else if (to == NULL) {
3036  error(0, "%s needs a valid phone number.", octstr_get_cstr(sendota_url));
3038  ret = octstr_create("Wrong sendota args.");
3039  } else {
3040 
3041  if (urltrans_faked_sender(t) != NULL) {
3043  }
3044  else if (from != NULL && octstr_len(from) > 0) {
3045  }
3046  else if (urltrans_default_sender(t) != NULL) {
3048  }
3049  else if (global_sender != NULL) {
3051  }
3052  else {
3054  ret = octstr_create("Sender missing and no global set, rejected");
3055  goto error;
3056  }
3057 
3058  /*
3059  * get the content-type of the body document
3060  */
3061  http_header_get_content_type(headers, &type, &charset);
3062 
3063  if (octstr_case_compare(type,
3064  octstr_imm("application/x-wap-prov.browser-settings")) == 0) {
3065  doc_type = octstr_format("%s", "settings");
3066  }
3067  else if (octstr_case_compare(type,
3068  octstr_imm("application/x-wap-prov.browser-bookmarks")) == 0) {
3069  doc_type = octstr_format("%s", "bookmarks");
3070  }
3071  else if (octstr_case_compare(type,
3072  octstr_imm("text/vnd.wap.connectivity-xml")) == 0) {
3073  doc_type = octstr_format("%s", "oma-settings");
3074  }
3075 
3076  if (doc_type == NULL) {
3077  error(0, "%s got weird content type %s", octstr_get_cstr(sendota_url),
3078  octstr_get_cstr(type));
3080  ret = octstr_create("Unsupported content-type, rejected");
3081  } else {
3082 
3083  /*
3084  * ok, this is want we expect
3085  * now lets compile the whole thing
3086  */
3087  ota_doc = octstr_duplicate(body);
3088 
3089  if ((r = ota_pack_message(&msg, ota_doc, doc_type, from, to, sec, pin)) < 0) {
3091  msg_destroy(msg);
3092  if (r == -2) {
3093  ret = octstr_create("Erroneous document type, cannot"
3094  " compile\n");
3095  goto error;
3096  }
3097  else if (r == -1) {
3098  ret = octstr_create("Erroneous ota source, cannot compile\n");
3099  goto error;
3100  }
3101  }
3102 
3103  /* we still need to check if smsc is forced for this */
3104  if (urltrans_forced_smsc(t)) {
3105  msg->sms.smsc_id = octstr_duplicate(urltrans_forced_smsc(t));
3106  if (smsc)
3107  info(0, "send-sms request smsc id ignored, as smsc id forced to %s",
3109  } else if (smsc) {
3110  msg->sms.smsc_id = octstr_duplicate(smsc);
3111  } else if (urltrans_default_smsc(t)) {
3112  msg->sms.smsc_id = octstr_duplicate(urltrans_default_smsc(t));
3113  } else
3114  msg->sms.smsc_id = NULL;
3115 
3116  info(0, "%s <%s> <%s>", octstr_get_cstr(sendota_url),
3117  id ? octstr_get_cstr(id) : "XML", octstr_get_cstr(to));
3118 
3119 
3120  if (!immediate_sendsms_reply) {
3121  stored_uuid = store_uuid(msg);
3122  dict_put(client_dict, stored_uuid, client);
3123  }
3124 
3125  r = send_message(t, msg);
3126 
3127  if (r == -1) {
3128  error(0, "sendota_request: failed");
3130  ret = octstr_create("Sending failed.");
3132  dict_remove(client_dict, stored_uuid);
3133  } else {
3134  *status = HTTP_ACCEPTED;
3135  ret = octstr_create("Sent.");
3136  }
3137 
3138  msg_destroy(msg);
3139  octstr_destroy(stored_uuid);
3140 
3141  }
3142  }
3143 
3144 error:
3145  octstr_destroy(user);
3146  octstr_destroy(pass);
3147  octstr_destroy(smsc);
3148 
3149  return ret;
3150 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
Octstr * urltrans_forced_smsc(URLTranslation *t)
Definition: urltrans.c:847
void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
Definition: http.c:2879
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
Octstr * urltrans_default_smsc(URLTranslation *t)
Definition: urltrans.c:852
long gwlist_len(List *list)
Definition: list.c:166
Octstr * urltrans_faked_sender(URLTranslation *t)
Definition: urltrans.c:787
static Octstr * sendota_url
Definition: smsbox.c:122
int type
Definition: smsc_cimd2.c:215
static Dict * client_dict
Definition: smsbox.c:159
void http_header_get_content_type(List *headers, Octstr **type, Octstr **charset)
Definition: http.c:3202
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static URLTranslation * authorise_username(Octstr *username, Octstr *password, Octstr *client_ip)
Definition: smsbox.c:2395
Octstr * charset
Definition: test_ota.c:68
static Octstr * from
Definition: mtbatch.c:95
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Definition: msg.h:79
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
static int send_message(URLTranslation *trans, Msg *msg)
Definition: smsbox.c:315
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void msg_destroy(Msg *msg)
Definition: msg.c:132
char * name
Definition: smsc_cimd2.c:212
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
Octstr * urltrans_default_sender(URLTranslation *t)
Definition: urltrans.c:782
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
static Octstr * store_uuid(Msg *msg)
Definition: smsbox.c:1931
static int immediate_sendsms_reply
Definition: smsbox.c:158
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int ota_pack_message(Msg **msg, Octstr *ota_doc, Octstr *doc_type, Octstr *from, Octstr *phone_number, Octstr *sec, Octstr *pin)
Definition: ota_prov.c:207
static Octstr * global_sender
Definition: smsbox.c:130
static Octstr* smsbox_sendsms_post ( List headers,
Octstr body,
Octstr client_ip,
int *  status,
HTTPClient client 
)
static

Definition at line 2578 of file smsbox.c.

References account, authorise_username(), charset, DC_7BIT, DC_8BIT, DC_UNDEF, dlr_mask, dlr_url, error(), from, get_x_kannel_from_headers(), get_x_kannel_from_xml(), html_to_sms(), HTTP_BAD_REQUEST, HTTP_FORBIDDEN, http_header_get_content_type(), HTTP_UNSUPPORTED_MEDIA_TYPE, mt_push, octstr_case_compare(), octstr_create, octstr_destroy(), octstr_get_cstr, octstr_imm(), octstr_len(), octstr_strip_blanks(), SMS_PARAM_UNDEFINED, smsbox_req_handle(), text, and type.

Referenced by sendsms_thread().

2581 {
2582  URLTranslation *t = NULL;
2583  Octstr *user, *pass, *ret, *type;
2584  List *tolist;
2585  Octstr *text_html, *text_plain, *text_wml, *text_xml, *octet_stream;
2586  Octstr *text;
2587  Octstr *from, *to, *udh, *smsc, *charset, *dlr_url, *account, *binfo, *meta_data;
2588  int dlr_mask, mclass, mwi, coding, compress, validity, deferred;
2589  int pid, alt_dcs, rpi, priority;
2590 
2591  text_html = octstr_imm("text/html");
2592  text_wml = octstr_imm("text/vnd.wap.wml");
2593  text_plain = octstr_imm("text/plain");
2594  text_xml = octstr_imm("text/xml");
2595  octet_stream = octstr_imm("application/octet-stream");
2596 
2597  user = pass = ret = type = NULL;
2598  tolist = NULL;
2599  from = to = udh = smsc = account = dlr_url = charset = binfo = meta_data = NULL;
2600  mclass = mwi = coding = compress = validity = deferred = dlr_mask =
2601  pid = alt_dcs = rpi = priority = SMS_PARAM_UNDEFINED;
2602 
2603  http_header_get_content_type(headers, &type, &charset);
2604  if (octstr_case_compare(type, text_html) == 0 ||
2605  octstr_case_compare(type, text_wml) == 0) {
2606  text = html_to_sms(body);
2607  octstr_strip_blanks(text);
2608  body = text;
2609  get_x_kannel_from_headers(headers, &from, &to, &udh,
2610  &user, &pass, &smsc, &mclass, &mwi,
2611  &coding, &compress, &validity,
2612  &deferred, &dlr_mask, &dlr_url,
2613  &account, &pid, &alt_dcs, &rpi,
2614  &binfo, &priority, &meta_data);
2615  } else if (octstr_case_compare(type, text_plain) == 0 ||
2616  octstr_case_compare(type, octet_stream) == 0) {
2617  get_x_kannel_from_headers(headers, &from, &to, &udh,
2618  &user, &pass, &smsc, &mclass, &mwi,
2619  &coding, &compress, &validity,
2620  &deferred, &dlr_mask, &dlr_url,
2621  &account, &pid, &alt_dcs, &rpi,
2622  &binfo, &priority, &meta_data);
2623  } else if (octstr_case_compare(type, text_xml) == 0) {
2624  get_x_kannel_from_xml(mt_push, &type, &body, headers,
2625  &from, &to, &udh, &user, &pass, &smsc, &mclass,
2626  &mwi, &coding, &compress, &validity, &deferred,
2627  &dlr_mask, &dlr_url, &account, &pid, &alt_dcs,
2628  &rpi, &tolist, &charset, &binfo, &priority, &meta_data);
2629  } else {
2631  ret = octstr_create("Invalid content-type");
2632  goto error;
2633  }
2634 
2635  /* check the username and password */
2636  t = authorise_username(user, pass, client_ip);
2637  if (t == NULL) {
2639  ret = octstr_create("Authorization failed for sendsms");
2640  }
2641  else if (to == NULL && tolist == NULL) {
2642  error(0, "%s got insufficient headers (<to> and <tolist> are NULL)",
2645  ret = octstr_create("Missing receiver(s) number(s), rejected");
2646  }
2647  else if (to != NULL && octstr_len(to) == 0) {
2648  error(0, "%s got empty <to> cgi variable", octstr_get_cstr(sendsms_url));
2650  ret = octstr_create("Empty receiver number not allowed, rejected");
2651  }
2652  else {
2653  if (octstr_case_compare(type,
2654  octstr_imm("application/octet-stream")) == 0) {
2655  if (coding == DC_UNDEF)
2656  coding = DC_8BIT; /* XXX Force UCS-2 with DC Field */
2657  } else if (octstr_case_compare(type,
2658  octstr_imm("text/plain")) == 0) {
2659  if (coding == DC_UNDEF)
2660  coding = DC_7BIT;
2661  } else {
2662  error(0, "%s got weird content type %s", octstr_get_cstr(sendsms_url),
2663  octstr_get_cstr(type));
2665  ret = octstr_create("Unsupported content-type, rejected");
2666  }
2667 
2668  if (ret == NULL)
2669  ret = smsbox_req_handle(t, client_ip, client, from, to, body, charset,
2670  udh, smsc, mclass, mwi, coding, compress,
2671  validity, deferred, status, dlr_mask,
2672  dlr_url, account, pid, alt_dcs, rpi, tolist,
2673  binfo, priority, meta_data);
2674 
2675  }
2676  octstr_destroy(user);
2677  octstr_destroy(pass);
2678  octstr_destroy(from);
2679  octstr_destroy(to);
2680  octstr_destroy(udh);
2681  octstr_destroy(smsc);
2682  octstr_destroy(dlr_url);
2683  octstr_destroy(account);
2684  octstr_destroy(binfo);
2685  octstr_destroy(meta_data);
2686 error:
2687  octstr_destroy(type);
2688  octstr_destroy(charset);
2689  return ret;
2690 }
static Octstr * dlr_mask
Definition: test_ppg.c:106
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)
Definition: smsbox.c:642
void error(int err, const char *fmt,...)
Definition: log.c:612
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)
Definition: smsbox.c:1952
static Octstr * sendsms_url
Definition: smsbox.c:121
int type
Definition: smsc_cimd2.c:215
#define DC_8BIT
Definition: sms.h:111
void http_header_get_content_type(List *headers, Octstr **type, Octstr **charset)
Definition: http.c:3202
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static URLTranslation * authorise_username(Octstr *username, Octstr *password, Octstr *client_ip)
Definition: smsbox.c:2395
Octstr * charset
Definition: test_ota.c:68
static Octstr * from
Definition: mtbatch.c:95
Definition: msg.h:108
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
static Octstr * dlr_url
Definition: test_ppg.c:107
char * text
Definition: smsc_cimd2.c:921
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * html_to_sms(Octstr *html)
Definition: html.c:283
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
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)
Definition: smsbox.c:532
#define DC_UNDEF
Definition: sms.h:109
Definition: list.c:102
static Octstr * account
Definition: mtbatch.c:94
#define DC_7BIT
Definition: sms.h:110
static Octstr* smsbox_xmlrpc_post ( List headers,
Octstr body,
Octstr client_ip,
int *  status 
)
static

Definition at line 2704 of file smsbox.c.

References charset, error(), HTTP_BAD_REQUEST, http_header_get_content_type(), method_name, msg, octstr_case_compare(), octstr_destroy(), octstr_format(), octstr_get_cstr, octstr_imm(), type, XMLRPC_COMPILE_OK, xmlrpc_destroy_call, xmlrpc_get_call_name(), xmlrpc_parse_call, xmlrpc_parse_error(), and xmlrpc_parse_status().

Referenced by sendsms_thread().

2706 {
2707  Octstr *ret, *type;
2708  Octstr *charset;
2709  Octstr *output;
2712 
2713  charset = NULL;
2714  ret = NULL;
2715 
2716  /*
2717  * check if the content type is valid for this request
2718  */
2719  http_header_get_content_type(headers, &type, &charset);
2720  if (octstr_case_compare(type, octstr_imm("text/xml")) != 0) {
2721  error(0, "Unsupported content-type '%s'", octstr_get_cstr(type));
2723  ret = octstr_format("Unsupported content-type '%s'", octstr_get_cstr(type));
2724  } else {
2725 
2726  /*
2727  * parse the body of the request and check if it is a valid XML-RPC
2728  * structure
2729  */
2730  msg = xmlrpc_parse_call(body);
2731 
2732  if ((xmlrpc_parse_status(msg) != XMLRPC_COMPILE_OK) &&
2733  ((output = xmlrpc_parse_error(msg)) != NULL)) {
2734  /* parse failure */
2735  error(0, "%s", octstr_get_cstr(output));
2737  ret = octstr_format("%s", octstr_get_cstr(output));
2738  octstr_destroy(output);
2739  } else {
2740 
2741  /*
2742  * at least the structure has been valid, now check for the
2743  * required methodName and the required variables
2744  */
2745  if (octstr_case_compare((method_name = xmlrpc_get_call_name(msg)),
2746  octstr_imm("sms.send")) != 0) {
2747  error(0, "Unknown method name '%s'", octstr_get_cstr(method_name));
2749  ret = octstr_format("Unkown method name '%s'",
2750  octstr_get_cstr(method_name));
2751  } else {
2752 
2753  /*
2754  * TODO: check for the required struct members
2755  */
2756 
2757  }
2758  }
2759 
2760  xmlrpc_destroy_call(msg);
2761  }
2762 
2763  return ret;
2764 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static Octstr * method_name
Definition: test_http.c:86
int type
Definition: smsc_cimd2.c:215
void http_header_get_content_type(List *headers, Octstr **type, Octstr **charset)
Definition: http.c:3202
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
int xmlrpc_parse_status(XMLRPCDocument *xrdoc)
Definition: xmlrpc.c:1348
Octstr * charset
Definition: test_ota.c:68
#define xmlrpc_parse_call(post_body)
Definition: xmlrpc.h:161
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
Octstr * xmlrpc_get_call_name(XMLRPCDocument *call)
Definition: xmlrpc.c:1056
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
#define xmlrpc_destroy_call(call)
Definition: xmlrpc.h:165
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
Octstr * xmlrpc_parse_error(XMLRPCDocument *xrdoc)
Definition: xmlrpc.c:1356
static Octstr* store_uuid ( Msg msg)
static

Definition at line 1931 of file smsbox.c.

References debug(), gw_assert(), immediate_sendsms_reply, octstr_create, octstr_get_cstr, UUID_STR_LEN, and uuid_unparse().

Referenced by smsbox_req_handle(), smsbox_req_sendota(), and smsbox_sendota_post().

1932 {
1933  char id[UUID_STR_LEN + 1];
1934  Octstr *stored_uuid;
1935 
1936  gw_assert(msg != NULL);
1938 
1939  uuid_unparse(msg->sms.id, id);
1940  stored_uuid = octstr_create(id);
1941 
1942  debug("sms.http", 0, "Stored UUID %s", octstr_get_cstr(stored_uuid));
1943 
1944  /* this octstr is then used to store the HTTP client into
1945  * client_dict, if need to, in sendsms_thread */
1946 
1947  return stored_uuid;
1948 }
void uuid_unparse(const uuid_t uu, char *out)
Definition: gw_uuid.c:561
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_create(cstr)
Definition: octstr.h:125
gw_assert(wtls_machine->packet_to_send!=NULL)
#define UUID_STR_LEN
Definition: gw_uuid.h:19
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static int immediate_sendsms_reply
Definition: smsbox.c:158
static void strip_prefix_and_suffix ( Octstr html,
Octstr prefix,
Octstr suffix 
)
static

Definition at line 513 of file