00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 #include <errno.h>
00062 #include <unistd.h>
00063 #include <signal.h>
00064 #include <string.h>
00065
00066 #include "gwlib/gwlib.h"
00067 #include "gwlib/regex.h"
00068
00069 #include "msg.h"
00070 #include "sms.h"
00071 #include "dlr.h"
00072 #include "bb.h"
00073 #include "shared.h"
00074 #include "heartbeat.h"
00075 #include "html.h"
00076 #include "urltrans.h"
00077 #include "ota_prov_attr.h"
00078 #include "ota_prov.h"
00079 #include "ota_compiler.h"
00080 #include "xml_shared.h"
00081
00082 #ifdef HAVE_SECURITY_PAM_APPL_H
00083 #include <security/pam_appl.h>
00084 #endif
00085
00086
00087 #define SENDSMS_DEFAULT_CHARS "0123456789 +-"
00088
00089 #define O_DESTROY(a) { if(a) octstr_destroy(a); a = NULL; }
00090
00091
00092 #define HTTP_MAX_RETRIES 0
00093 #define HTTP_RETRY_DELAY 10
00094 #define HTTP_MAX_PENDING 512
00095
00096
00097 volatile sig_atomic_t restart = 0;
00098
00099 static Cfg *cfg;
00100 static long bb_port;
00101 static int bb_ssl = 0;
00102 static long sendsms_port = 0;
00103 static Octstr *sendsms_interface = NULL;
00104 static Octstr *smsbox_id = NULL;
00105 static Octstr *sendsms_url = NULL;
00106 static Octstr *sendota_url = NULL;
00107 static Octstr *xmlrpc_url = NULL;
00108 static Octstr *bb_host;
00109 static Octstr *accepted_chars = NULL;
00110 static int only_try_http = 0;
00111 static URLTranslationList *translations = NULL;
00112 static long sms_max_length = MAX_SMS_OCTETS;
00113 static char *sendsms_number_chars;
00114 static Octstr *global_sender = NULL;
00115 static Octstr *reply_couldnotfetch = NULL;
00116 static Octstr *reply_couldnotrepresent = NULL;
00117 static Octstr *reply_requestfailed = NULL;
00118 static Octstr *reply_emptymessage = NULL;
00119 static int mo_recode = 0;
00120 static Numhash *white_list;
00121 static Numhash *black_list;
00122 static regex_t *white_list_regex = NULL;
00123 static regex_t *black_list_regex = NULL;
00124 static long max_http_retries = HTTP_MAX_RETRIES;
00125 static long http_queue_delay = HTTP_RETRY_DELAY;
00126 static Octstr *ppg_service_name = NULL;
00127
00128 static List *smsbox_requests = NULL;
00129 static List *smsbox_http_requests = NULL;
00130
00131
00132 static Semaphore *max_pending_requests;
00133
00134 int charset_processing (Octstr *charset, Octstr *text, int coding);
00135 static long get_tag(Octstr *body, Octstr *tag, Octstr **value, long pos, int nostrip);
00136
00137
00138
00139
00140
00141
00142 static int immediate_sendsms_reply = 0;
00143 static Dict *client_dict = NULL;
00144 static List *sendsms_reply_hdrs = NULL;
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 static void identify_to_bearerbox(void)
00157 {
00158 Msg *msg;
00159
00160 msg = msg_create(admin);
00161 msg->admin.command = cmd_identify;
00162 msg->admin.boxc_id = octstr_duplicate(smsbox_id);
00163 write_to_bearerbox(msg);
00164 }
00165
00166
00167
00168
00169 static void delayed_http_reply(Msg *msg)
00170 {
00171 HTTPClient *client;
00172 Octstr *os, *answer;
00173 char id[UUID_STR_LEN + 1];
00174 int status;
00175
00176 uuid_unparse(msg->ack.id, id);
00177 os = octstr_create(id);
00178 debug("sms.http", 0, "Got ACK (%ld) of %s", msg->ack.nack, octstr_get_cstr(os));
00179 client = dict_remove(client_dict, os);
00180 if (client == NULL) {
00181 debug("sms.http", 0, "No client - multi-send or ACK to pull-reply");
00182 octstr_destroy(os);
00183 return;
00184 }
00185
00186
00187
00188
00189
00190 switch (msg->ack.nack) {
00191 case ack_success:
00192 status = HTTP_ACCEPTED;
00193 answer = octstr_create("0: Accepted for delivery");
00194 break;
00195 case ack_buffered:
00196 status = HTTP_ACCEPTED;
00197 answer = octstr_create("3: Queued for later delivery");
00198 break;
00199 case ack_failed:
00200 status = HTTP_FORBIDDEN;
00201 answer = octstr_create("Not routable. Do not try again.");
00202 break;
00203 case ack_failed_tmp:
00204 status = HTTP_SERVICE_UNAVAILABLE;
00205 answer = octstr_create("Temporal failure, try again later.");
00206 break;
00207 default:
00208 error(0, "Strange reply from bearerbox!");
00209 status = HTTP_SERVICE_UNAVAILABLE;
00210 answer = octstr_create("Temporal failure, try again later.");
00211 break;
00212 }
00213
00214 http_send_reply(client, status, sendsms_reply_hdrs, answer);
00215
00216 octstr_destroy(answer);
00217 octstr_destroy(os);
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 static void read_messages_from_bearerbox(void)
00227 {
00228 time_t start, t;
00229 int secs;
00230 int total = 0;
00231 int ret;
00232 Msg *msg;
00233
00234 start = t = time(NULL);
00235 while (program_status != shutting_down) {
00236
00237 ret = read_from_bearerbox(&msg, INFINITE_TIME);
00238 if (ret == -1)
00239 break;
00240 else if (ret == 1)
00241 continue;
00242 else if (msg == NULL)
00243 break;
00244
00245 if (msg_type(msg) == admin) {
00246 if (msg->admin.command == cmd_shutdown) {
00247 info(0, "Bearerbox told us to die");
00248 program_status = shutting_down;
00249 } else if (msg->admin.command == cmd_restart) {
00250 info(0, "Bearerbox told us to restart");
00251 restart = 1;
00252 program_status = shutting_down;
00253 }
00254
00255
00256
00257 msg_destroy(msg);
00258 } else if (msg_type(msg) == sms) {
00259 if (total == 0)
00260 start = time(NULL);
00261 total++;
00262 gwlist_produce(smsbox_requests, msg);
00263 } else if (msg_type(msg) == ack) {
00264 if (!immediate_sendsms_reply)
00265 delayed_http_reply(msg);
00266 msg_destroy(msg);
00267 } else {
00268 warning(0, "Received other message than sms/admin, ignoring!");
00269 msg_destroy(msg);
00270 }
00271 }
00272 secs = difftime(time(NULL), start);
00273 info(0, "Received (and handled?) %d requests in %d seconds "
00274 "(%.2f per second)", total, secs, (float)total / secs);
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 static Counter *catenated_sms_counter;
00287
00288
00289
00290
00291
00292
00293
00294 static int send_message(URLTranslation *trans, Msg *msg)
00295 {
00296 int max_msgs;
00297 Octstr *header, *footer, *suffix, *split_chars;
00298 int catenate;
00299 unsigned long msg_sequence, msg_count;
00300 List *list;
00301 Msg *part;
00302
00303 gw_assert(msg != NULL);
00304 gw_assert(msg_type(msg) == sms);
00305
00306 if (trans != NULL)
00307 max_msgs = urltrans_max_messages(trans);
00308 else
00309 max_msgs = 1;
00310
00311 if (max_msgs == 0) {
00312 info(0, "No reply sent, denied.");
00313 return 0;
00314 }
00315
00316
00317
00318
00319
00320
00321 if (smsbox_id != NULL) {
00322 msg->sms.boxc_id = octstr_duplicate(smsbox_id);
00323 }
00324
00325
00326
00327
00328
00329
00330
00331 if (octstr_len(msg->sms.msgdata) == 0 && msg->sms.sms_type == mt_reply) {
00332 if (trans != NULL && urltrans_omit_empty(trans))
00333 return 0;
00334 else
00335 msg->sms.msgdata = octstr_duplicate(reply_emptymessage);
00336 }
00337
00338 if (trans == NULL) {
00339 header = NULL;
00340 footer = NULL;
00341 suffix = NULL;
00342 split_chars = NULL;
00343 catenate = 0;
00344 } else {
00345 header = urltrans_header(trans);
00346 footer = urltrans_footer(trans);
00347 suffix = urltrans_split_suffix(trans);
00348 split_chars = urltrans_split_chars(trans);
00349 catenate = urltrans_concatenation(trans);
00350 }
00351
00352 if (catenate)
00353 msg_sequence = counter_increase(catenated_sms_counter) & 0xFF;
00354 else
00355 msg_sequence = 0;
00356
00357 list = sms_split(msg, header, footer, suffix, split_chars, catenate,
00358 msg_sequence, max_msgs, sms_max_length);
00359 msg_count = gwlist_len(list);
00360
00361 debug("sms", 0, "message length %ld, sending %ld messages",
00362 octstr_len(msg->sms.msgdata), msg_count);
00363
00364
00365
00366
00367
00368
00369
00370 if (catenate) {
00371 Msg *new_msg = msg_duplicate(msg);
00372 octstr_delete(new_msg->sms.msgdata, 0, octstr_len(new_msg->sms.msgdata));
00373 while((part = gwlist_extract_first(list)) != NULL) {
00374 octstr_append(new_msg->sms.msgdata, part->sms.msgdata);
00375 msg_destroy(part);
00376 }
00377 write_to_bearerbox(new_msg);
00378 } else {
00379
00380 while ((part = gwlist_extract_first(list)) != NULL)
00381 write_to_bearerbox(part);
00382 }
00383
00384 gwlist_destroy(list, NULL);
00385
00386 return msg_count;
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 static HTTPCaller *caller;
00399 static Counter *num_outstanding_requests;
00400
00401
00402 struct receiver {
00403 Msg *msg;
00404 URLTranslation *trans;
00405 int method;
00406 Octstr *url;
00407 List *http_headers;
00408 Octstr *body;
00409 unsigned long retries;
00410 };
00411
00412
00413
00414
00415 static void *remember_receiver(Msg *msg, URLTranslation *trans, int method,
00416 Octstr *url, List *headers, Octstr *body,
00417 unsigned int retries)
00418 {
00419 struct receiver *receiver;
00420
00421 counter_increase(num_outstanding_requests);
00422 receiver = gw_malloc(sizeof(*receiver));
00423
00424 receiver->msg = msg_create(sms);
00425
00426 receiver->msg->sms.sender = octstr_duplicate(msg->sms.sender);
00427 receiver->msg->sms.receiver = octstr_duplicate(msg->sms.receiver);
00428
00429 if (trans != NULL && (msg->sms.service == NULL || ppg_service_name == NULL ||
00430 octstr_compare(msg->sms.service, ppg_service_name) != 0)) {
00431 receiver->msg->sms.service = octstr_duplicate(urltrans_name(trans));
00432 } else {
00433 receiver->msg->sms.service = octstr_duplicate(msg->sms.service);
00434 }
00435 receiver->msg->sms.smsc_id = octstr_duplicate(msg->sms.smsc_id);
00436
00437 receiver->msg->sms.sms_type = msg->sms.sms_type;
00438
00439 receiver->trans = trans;
00440
00441
00442 receiver->method = method;
00443 receiver->url = octstr_duplicate(url);
00444 receiver->http_headers = http_header_duplicate(headers);
00445 receiver->body = octstr_duplicate(body);
00446 receiver->retries = retries;
00447
00448 return receiver;
00449 }
00450
00451
00452 static void get_receiver(void *id, Msg **msg, URLTranslation **trans, int *method,
00453 Octstr **url, List **headers, Octstr **body,
00454 unsigned long *retries)
00455 {
00456 struct receiver *receiver;
00457
00458 receiver = id;
00459 *msg = receiver->msg;
00460 *trans = receiver->trans;
00461 *method = receiver->method;
00462 *url = receiver->url;
00463 *headers = receiver->http_headers;
00464 *body = receiver->body;
00465 *retries = receiver->retries;
00466 gw_free(receiver);
00467 counter_decrease(num_outstanding_requests);
00468 }
00469
00470
00471 static long outstanding_requests(void)
00472 {
00473 return counter_value(num_outstanding_requests);
00474 }
00475
00476
00477
00478
00479
00480
00481
00482 static void strip_prefix_and_suffix(Octstr *html, Octstr *prefix,
00483 Octstr *suffix)
00484 {
00485 long prefix_end, suffix_start;
00486
00487 if (prefix == NULL || suffix == NULL)
00488 return;
00489 prefix_end = octstr_case_search(html, prefix, 0);
00490 if (prefix_end == -1)
00491 return;
00492 prefix_end += octstr_len(prefix);
00493 suffix_start = octstr_case_search(html, suffix, prefix_end);
00494 if (suffix_start == -1)
00495 return;
00496 octstr_delete(html, 0, prefix_end);
00497 octstr_truncate(html, suffix_start - prefix_end);
00498 }
00499
00500
00501 static void get_x_kannel_from_headers(List *headers, Octstr **from,
00502 Octstr **to, Octstr **udh,
00503 Octstr **user, Octstr **pass,
00504 Octstr **smsc, int *mclass, int *mwi,
00505 int *coding, int *compress,
00506 int *validity, int *deferred,
00507 int *dlr_mask, Octstr **dlr_url,
00508 Octstr **account, int *pid, int *alt_dcs,
00509 int *rpi, Octstr **binfo, int *priority)
00510 {
00511 Octstr *name, *val;
00512 long l;
00513
00514 for(l=0; l<gwlist_len(headers); l++) {
00515 http_header_get(headers, l, &name, &val);
00516
00517 if (octstr_case_compare(name, octstr_imm("X-Kannel-From")) == 0) {
00518 *from = octstr_duplicate(val);
00519 octstr_strip_blanks(*from);
00520 }
00521 else if (octstr_case_compare(name, octstr_imm("X-Kannel-To")) == 0) {
00522 *to = octstr_duplicate(val);
00523 octstr_strip_blanks(*to);
00524 }
00525 else if (octstr_case_compare(name, octstr_imm("X-Kannel-Username")) == 0) {
00526 if (user != NULL) {
00527 *user = octstr_duplicate(val);
00528 octstr_strip_blanks(*user);
00529 }
00530 }
00531 else if (octstr_case_compare(name, octstr_imm("X-Kannel-Password")) == 0) {
00532 if (pass != NULL) {
00533 *pass = octstr_duplicate(val);
00534 octstr_strip_blanks(*pass);
00535 }
00536 }
00537 else if (octstr_case_compare(name, octstr_imm("X-Kannel-SMSC")) == 0) {
00538 if (smsc != NULL) {
00539 *smsc = octstr_duplicate(val);
00540 octstr_strip_blanks(*smsc);
00541 }
00542 }
00543 else if (octstr_case_compare(name, octstr_imm("X-Kannel-UDH")) == 0) {
00544 *udh = octstr_duplicate(val);
00545 octstr_strip_blanks(*udh);
00546 if (octstr_hex_to_binary(*udh) == -1) {
00547 if (octstr_url_decode(*udh) == -1) {
00548 warning(0, "Invalid UDH received in X-Kannel-UDH");
00549 octstr_destroy(*udh);
00550 *udh = NULL;
00551 }
00552 }
00553 }
00554 else if (octstr_case_compare(name, octstr_imm("X-Kannel-DLR-URL")) == 0) {
00555 *dlr_url = octstr_duplicate(val);
00556 octstr_strip_blanks(*dlr_url);
00557 }
00558 else if (octstr_case_compare(name, octstr_imm("X-Kannel-Account")) == 0) {
00559 *account = octstr_duplicate(val);
00560 octstr_strip_blanks(*account);
00561 }
00562 else if (octstr_case_compare(name, octstr_imm("X-Kannel-BInfo")) == 0) {
00563 *binfo = octstr_duplicate(val);
00564 octstr_strip_blanks(*binfo);
00565 }
00566 else if (octstr_case_compare(name, octstr_imm("X-Kannel-Coding")) == 0) {
00567 sscanf(octstr_get_cstr(val),"%d", coding);
00568 }
00569 else if (octstr_case_compare(name, octstr_imm("X-Kannel-PID")) == 0) {
00570 sscanf(octstr_get_cstr(val),"%d", pid);
00571 }
00572 else if (octstr_case_compare(name, octstr_imm("X-Kannel-MWI")) == 0) {
00573 sscanf(octstr_get_cstr(val),"%d", mwi);
00574 }
00575 else if (octstr_case_compare(name, octstr_imm("X-Kannel-MClass")) == 0) {
00576 sscanf(octstr_get_cstr(val),"%d", mclass);
00577 }
00578 else if (octstr_case_compare(name, octstr_imm("X-Kannel-Alt-DCS")) == 0) {
00579 sscanf(octstr_get_cstr(val),"%d", alt_dcs);
00580 }
00581 else if (octstr_case_compare(name, octstr_imm("X-Kannel-Compress")) == 0) {
00582 sscanf(octstr_get_cstr(val),"%d", compress);
00583 }
00584 else if (octstr_case_compare(name, octstr_imm("X-Kannel-Validity")) == 0) {
00585 sscanf(octstr_get_cstr(val),"%d", validity);
00586 }
00587 else if (octstr_case_compare(name, octstr_imm("X-Kannel-Deferred")) == 0) {
00588 sscanf(octstr_get_cstr(val),"%d", deferred);
00589 }
00590 else if (octstr_case_compare(name, octstr_imm("X-Kannel-DLR-Mask")) == 0) {
00591 sscanf(octstr_get_cstr(val),"%d", dlr_mask);
00592 }
00593 else if (octstr_case_compare(name, octstr_imm("X-Kannel-RPI")) == 0) {
00594 sscanf(octstr_get_cstr(val),"%d", rpi);
00595 }
00596 else if (octstr_case_compare(name, octstr_imm("X-Kannel-Priority")) == 0) {
00597 sscanf(octstr_get_cstr(val),"%d", priority);
00598 }
00599 octstr_destroy(name);
00600 octstr_destroy(val);
00601 }
00602 }
00603
00604 static long get_tag(Octstr *body, Octstr *tag, Octstr **value, long pos, int nostrip) {
00605 long start, end;
00606 int taglen;
00607 Octstr *tmp;
00608
00609 tmp = octstr_create("<");
00610 octstr_append(tmp, tag);
00611 octstr_append(tmp, octstr_imm(">"));
00612 taglen = octstr_len(tmp);
00613
00614 start = octstr_search(body, tmp, pos);
00615 octstr_destroy(tmp);
00616 if(start != -1) {
00617 tmp = octstr_create("</");
00618 octstr_append(tmp, tag);
00619 octstr_append(tmp, octstr_imm(">"));
00620
00621 end = octstr_search(body, tmp, start);
00622 octstr_destroy(tmp);
00623 if(end != -1) {
00624 octstr_destroy(*value);
00625 *value = octstr_copy(body, start + taglen, end - start - taglen);
00626 if(nostrip == 0) {
00627 octstr_strip_blanks(*value);
00628 debug("sms", 0, "XMLParsing: tag <%s> value <%s>", octstr_get_cstr(tag),
00629 octstr_get_cstr(*value));
00630 }
00631 return end + taglen + 1;
00632 } else {
00633 debug("sms", 0, "XMLParsing: end tag </%s> not found", octstr_get_cstr(tag));
00634 return -1;
00635 }
00636 } else {
00637
00638 return -1;
00639 }
00640 }
00641
00642
00643
00644
00645 static void get_x_kannel_from_xml(int requesttype , Octstr **type, Octstr **body,
00646 List *headers, Octstr **from,
00647 Octstr **to, Octstr **udh,
00648 Octstr **user, Octstr **pass,
00649 Octstr **smsc, int *mclass, int *mwi,
00650 int *coding, int *compress,
00651 int *validity, int *deferred,
00652 int *dlr_mask, Octstr **dlr_url,
00653 Octstr **account, int *pid, int *alt_dcs,
00654 int *rpi, List **tolist, Octstr **charset,
00655 Octstr **binfo, int *priority)
00656 {
00657
00658 Octstr *text, *tmp, *tmp2;
00659 long tmplong, where;
00660
00661 tmp = tmp2 = text = NULL;
00662
00663 debug("sms", 0, "XMLParsing: XML: <%s>", octstr_get_cstr(*body));
00664
00665
00666 get_tag(*body, octstr_imm("from"), &tmp, 0, 0);
00667 if(tmp) {
00668 if(requesttype == mt_push) {
00669
00670 get_tag(tmp, octstr_imm("user"), user, 0, 0);
00671 get_tag(tmp, octstr_imm("username"), user, 0, 0);
00672
00673
00674 get_tag(tmp, octstr_imm("pass"), pass, 0, 0);
00675 get_tag(tmp, octstr_imm("password"), pass, 0, 0);
00676 }
00677
00678
00679 get_tag(tmp, octstr_imm("account"), account, 0, 0);
00680
00681
00682 get_tag(tmp, octstr_imm("binfo"), binfo, 0, 0);
00683
00684 O_DESTROY(tmp);
00685 }
00686
00687 get_tag(*body, octstr_imm("oa"), &tmp, 0, 0);
00688 if(tmp) {
00689
00690 get_tag(tmp, octstr_imm("number"), from, 0, 0);
00691 O_DESTROY(tmp);
00692 }
00693
00694 if(requesttype == mt_push) {
00695
00696 *tolist = gwlist_create();
00697 where = get_tag(*body, octstr_imm("da"), &tmp, 0, 0);
00698 if(tmp) {
00699 get_tag(tmp, octstr_imm("number"), to, 0, 0);
00700 gwlist_append(*tolist, octstr_duplicate(*to));
00701 O_DESTROY(*to);
00702
00703 while(tmp && where != -1) {
00704 O_DESTROY(tmp);
00705 where = get_tag(*body, octstr_imm("da"), &tmp, where, 0);
00706 if(tmp) {
00707 get_tag(tmp, octstr_imm("number"), &tmp2, 0, 0);
00708 if(tmp2 != NULL) {
00709 gwlist_append(*tolist, octstr_duplicate(tmp2));
00710 O_DESTROY(tmp2);
00711 }
00712 }
00713 }
00714 }
00715 }
00716
00717
00718 get_tag(*body, octstr_imm("udh"), &tmp, 0, 0);
00719 if(tmp) {
00720 O_DESTROY(*udh);
00721 *udh = octstr_duplicate(tmp);
00722 if(octstr_hex_to_binary(*udh) == -1)
00723 octstr_url_decode(*udh);
00724 O_DESTROY(tmp);
00725 }
00726
00727
00728 get_tag(*body, octstr_imm("to"), &tmp, 0, 0);
00729 if(tmp) {
00730 O_DESTROY(*smsc);
00731 *smsc = tmp;
00732 tmp = NULL;
00733 }
00734
00735
00736 get_tag(*body, octstr_imm("pid"), &tmp, 0, 0);
00737 if(tmp) {
00738 if(octstr_parse_long(&tmplong, tmp, 0, 10) != -1)
00739 *pid = tmplong;
00740 O_DESTROY(tmp);
00741 }
00742
00743
00744 get_tag(*body, octstr_imm("rpi"), &tmp, 0, 0);
00745 if(tmp) {
00746 if(octstr_parse_long(&tmplong, tmp, 0, 10) != -1)
00747 *rpi = tmplong;
00748 O_DESTROY(tmp);
00749 }
00750
00751
00752 get_tag(*body, octstr_imm("dcs"), &tmp, 0, 0);
00753 if(tmp) {
00754
00755 get_tag(tmp, octstr_imm("mclass"), &tmp2, 0, 0);
00756 if(tmp2) {
00757 if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
00758 *mclass = tmplong;
00759 O_DESTROY(tmp2);
00760 }
00761
00762 get_tag(tmp, octstr_imm("mwi"), &tmp2, 0, 0);
00763 if(tmp2) {
00764 if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
00765 *mwi = tmplong;
00766 O_DESTROY(tmp2);
00767 }
00768
00769 get_tag(tmp, octstr_imm("coding"), &tmp2, 0, 0);
00770 if(tmp2) {
00771 if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
00772 *coding = tmplong;
00773 O_DESTROY(tmp2);
00774 }
00775
00776 get_tag(tmp, octstr_imm("compress"), &tmp2, 0, 0);
00777 if(tmp2) {
00778 if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
00779 *compress = tmplong;
00780 O_DESTROY(tmp2);
00781 }
00782
00783 get_tag(tmp, octstr_imm("alt-dcs"), &tmp2, 0, 0);
00784 if(tmp2) {
00785 if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
00786 *alt_dcs = tmplong;
00787 O_DESTROY(tmp2);
00788 }
00789 O_DESTROY(tmp);
00790 }
00791
00792
00793 get_tag(*body, octstr_imm("statusrequest"), &tmp, 0, 0);
00794 if(tmp) {
00795
00796 get_tag(tmp, octstr_imm("dlr-mask"), &tmp2, 0, 0);
00797 if(tmp2) {
00798 if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
00799 *dlr_mask = tmplong;
00800 O_DESTROY(tmp2);
00801 }
00802 get_tag(tmp, octstr_imm("dlr-url"), dlr_url, 0, 0);
00803 O_DESTROY(tmp);
00804 }
00805
00806
00807 get_tag(*body, octstr_imm("vp"), &tmp, 0, 0);
00808 if(tmp) {
00809 get_tag(tmp, octstr_imm("delay"), &tmp2, 0, 0);
00810 if(tmp2) {
00811 if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
00812 *validity = tmplong;
00813 O_DESTROY(tmp2);
00814 }
00815 O_DESTROY(tmp);
00816 }
00817
00818
00819 get_tag(*body, octstr_imm("timing"), &tmp, 0, 0);
00820 if(tmp) {
00821 get_tag(tmp, octstr_imm("delay"), &tmp2, 0, 0);
00822 if(tmp2) {
00823 if(octstr_parse_long(&tmplong, tmp2, 0, 10) != -1)
00824 *deferred = tmplong;
00825 O_DESTROY(tmp2);
00826 }
00827 O_DESTROY(tmp);
00828 }
00829
00830
00831 get_tag(*body, octstr_imm("priority"), &tmp, 0, 0);
00832 if(tmp) {
00833 if(octstr_parse_long(&tmplong, tmp, 0, 10) != -1)
00834 *priority = tmplong;
00835 O_DESTROY(tmp);
00836 }
00837
00838
00839 tmp = find_charset_encoding(*body);
00840 O_DESTROY(*charset);
00841 if(tmp) {
00842 *charset = octstr_duplicate(tmp);
00843 O_DESTROY(tmp);
00844 } else {
00845 *charset = octstr_create("UTF-8");
00846 }
00847
00848
00849 text = NULL;
00850 get_tag(*body, octstr_imm("ud"), &tmp, 0, 0);
00851 if(tmp) {
00852 O_DESTROY(text);
00853 text = octstr_duplicate(tmp);
00854 if(octstr_hex_to_binary(text) == -1)
00855 octstr_url_decode(text);
00856 O_DESTROY(tmp);
00857 }
00858
00859 if(text)
00860 *body = text;
00861 else
00862 *body = octstr_create("");
00863
00864 O_DESTROY(*type);
00865 *type = octstr_create("text/plain");
00866 }
00867
00868
00869 static void fill_message(Msg *msg, URLTranslation *trans,
00870 Octstr *replytext, int octet_stream,
00871 Octstr *from, Octstr *to, Octstr *udh,
00872 int mclass, int mwi, int coding, int compress,
00873 int validity, int deferred,
00874 Octstr *dlr_url, int dlr_mask, int pid, int alt_dcs,
00875 int rpi, Octstr *smsc, Octstr *account,
00876 Octstr *charset, Octstr *binfo, int priority)
00877 {
00878 msg->sms.msgdata = replytext;
00879 msg->sms.time = time(NULL);
00880
00881 if (charset)
00882 msg->sms.charset = charset;
00883
00884 if (dlr_url != NULL) {
00885 if (urltrans_accept_x_kannel_headers(trans)) {
00886 octstr_destroy(msg->sms.dlr_url);
00887 msg->sms.dlr_url = dlr_url;
00888 } else {
00889 warning(0, "Tried to change dlr_url to '%s', denied.",
00890 octstr_get_cstr(dlr_url));
00891 octstr_destroy(dlr_url);
00892 }
00893 }
00894
00895 if (smsc != NULL) {
00896 if (urltrans_accept_x_kannel_headers(trans)) {
00897 octstr_destroy(msg->sms.smsc_id);
00898 msg->sms.smsc_id = smsc;
00899 } else {
00900 warning(0, "Tried to change SMSC to '%s', denied.",
00901 octstr_get_cstr(smsc));
00902 octstr_destroy(smsc);
00903 }
00904 }
00905
00906 if (from != NULL) {
00907 if (urltrans_accept_x_kannel_headers(trans)) {
00908 octstr_destroy(msg->sms.sender);
00909 msg->sms.sender = from;
00910 } else {
00911 warning(0, "Tried to change sender to '%s', denied.",
00912 octstr_get_cstr(from));
00913 octstr_destroy(from);
00914 }
00915 }
00916 if (to != NULL) {
00917 if (urltrans_accept_x_kannel_headers(trans)) {
00918 octstr_destroy(msg->sms.receiver);
00919 msg->sms.receiver = to;
00920 } else {
00921 warning(0, "Tried to change receiver to '%s', denied.",
00922 octstr_get_cstr(to));
00923 octstr_destroy(to);
00924 }
00925 }
00926 if (udh != NULL) {
00927 if (urltrans_accept_x_kannel_headers(trans)) {
00928 octstr_destroy(msg->sms.udhdata);
00929 msg->sms.udhdata = udh;
00930 } else {
00931 warning(0, "Tried to set UDH field, denied.");
00932 O_DESTROY(udh);
00933 }
00934 }
00935 if (mclass != SMS_PARAM_UNDEFINED) {
00936 if (urltrans_accept_x_kannel_headers(trans))
00937 msg->sms.mclass = mclass;
00938 else
00939 warning(0, "Tried to set MClass field, denied.");
00940 }
00941 if (pid != SMS_PARAM_UNDEFINED) {
00942 if (urltrans_accept_x_kannel_headers(trans))
00943 msg->sms.pid = pid;
00944 else
00945 warning(0, "Tried to set PID field, denied.");
00946 }
00947 if (rpi != SMS_PARAM_UNDEFINED) {
00948 if (urltrans_accept_x_kannel_headers(trans))
00949 msg->sms.rpi = rpi;
00950 else
00951 warning(0, "Tried to set RPI field, denied.");
00952 }
00953 if (alt_dcs != SMS_PARAM_UNDEFINED) {
00954 if (urltrans_accept_x_kannel_headers(trans))
00955 msg->sms.alt_dcs = alt_dcs;
00956 else
00957 warning(0, "Tried to set Alt-DCS field, denied.");
00958 }
00959 if (mwi != SMS_PARAM_UNDEFINED) {
00960 if (urltrans_accept_x_kannel_headers(trans))
00961 msg->sms.mwi = mwi;
00962 else
00963 warning(0, "Tried to set MWI field, denied.");
00964 }
00965 if (coding != SMS_PARAM_UNDEFINED) {
00966 if (urltrans_accept_x_kannel_headers(trans))
00967 msg->sms.coding = coding;
00968 else
00969 warning(0, "Tried to set Coding field, denied.");
00970 }
00971 if (compress != SMS_PARAM_UNDEFINED) {
00972 if (urltrans_accept_x_kannel_headers(trans))
00973 msg->sms.compress = compress;
00974 else
00975 warning(0, "Tried to set Compress field, denied.");
00976 }
00977
00978 if ( msg->sms.coding == DC_UNDEF) {
00979 if(octstr_len(udh))
00980 msg->sms.coding = DC_8BIT;
00981 else
00982 msg->sms.coding = DC_7BIT;
00983 }
00984
00985 if (validity != SMS_PARAM_UNDEFINED) {
00986 if (urltrans_accept_x_kannel_headers(trans))
00987 msg->sms.validity = validity;
00988 else
00989 warning(0, "Tried to change validity to '%d', denied.",
00990 validity);
00991 }
00992 if (deferred != SMS_PARAM_UNDEFINED) {
00993 if (urltrans_accept_x_kannel_headers(trans))
00994 msg->sms.deferred = deferred;
00995 else
00996 warning(0, "Tried to change deferred to '%d', denied.",
00997 deferred);
00998 }
00999
01000 if (dlr_mask != SMS_PARAM_UNDEFINED) {
01001 if (urltrans_accept_x_kannel_headers(trans)) {
01002 msg->sms.dlr_mask = dlr_mask;
01003 } else
01004 warning(0, "Tried to change dlr_mask to '%d', denied.",
01005 dlr_mask);
01006 }
01007
01008 if (account) {
01009 if (urltrans_accept_x_kannel_headers(trans)) {
01010 msg->sms.account = account;
01011 } else {
01012 warning(0, "Tried to change account to '%s', denied.",
01013 octstr_get_cstr(account));
01014 octstr_destroy(account);
01015 }
01016 }
01017
01018 if (binfo) {
01019 if (urltrans_accept_x_kannel_headers(trans)) {
01020 msg->sms.binfo = binfo;
01021 } else {
01022 warning(0, "Tried to change billing info to '%s', denied.",
01023 octstr_get_cstr(binfo));
01024 octstr_destroy(binfo);
01025 }
01026 }
01027
01028 if (priority != SMS_PARAM_UNDEFINED) {
01029 if (urltrans_accept_x_kannel_headers(trans))
01030 msg->sms.priority = priority;
01031 else
01032 warning(0, "Tried to change priority to '%d', denied.", priority);
01033 }
01034 }
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044 static void http_queue_thread(void *arg)
01045 {
01046 void *id;
01047 Msg *msg;
01048 URLTranslation *trans;
01049 Octstr *req_url;
01050 List *req_headers;
01051 Octstr *req_body;
01052 unsigned long retries;
01053 int method;
01054
01055 while ((id = gwlist_consume(smsbox_http_requests)) != NULL) {
01056
01057
01058
01059
01060
01061 if (http_queue_delay > 0)
01062 gwthread_sleep(http_queue_delay);
01063
01064 debug("sms.http",0,"HTTP: Queue contains %ld outstanding requests",
01065 gwlist_len(smsbox_http_requests));
01066
01067
01068
01069
01070
01071 get_receiver(id, &msg, &trans, &method, &req_url, &req_headers, &req_body, &retries);
01072
01073 if (retries < max_http_retries) {
01074 id = remember_receiver(msg, trans, method, req_url, req_headers, req_body, ++retries);
01075
01076 debug("sms.http",0,"HTTP: Retrying request <%s> (%ld/%ld)",
01077 octstr_get_cstr(req_url), retries, max_http_retries);
01078
01079
01080 http_start_request(caller, method, req_url, req_headers, req_body,
01081 1, id, NULL);
01082 }
01083
01084 msg_destroy(msg);
01085 octstr_destroy(req_url);
01086 http_destroy_headers(req_headers);
01087 octstr_destroy(req_body);
01088 }
01089 }
01090
01091
01092 static void url_result_thread(void *arg)
01093 {
01094 Octstr *final_url, *req_body, *type, *replytext;
01095 List *reply_headers;
01096 int status, method;
01097 void *id;
01098 Msg *msg;
01099 URLTranslation *trans;
01100 Octstr *req_url;
01101 List *req_headers;
01102 Octstr *text_html, *text_plain, *text_wml, *text_xml;
01103 Octstr *octet_stream;
01104 int octets;
01105 unsigned long retries;
01106 unsigned int queued;
01107
01108 Octstr *reply_body, *charset;
01109 Octstr *udh, *from, *to, *dlr_url, *account, *smsc, *binfo;
01110 int dlr_mask, mclass, mwi, coding, compress, pid, alt_dcs, rpi;
01111 int validity, deferred, priority;
01112
01113 text_html = octstr_imm("text/html");
01114 text_wml = octstr_imm("text/vnd.wap.wml");
01115 text_plain = octstr_imm("text/plain");
01116 text_xml = octstr_imm("text/xml");
01117 octet_stream = octstr_imm("application/octet-stream");
01118
01119 for (;;) {
01120 queued = 0;
01121 id = http_receive_result(caller, &status, &final_url, &reply_headers,
01122 &reply_body);
01123 semaphore_up(max_pending_requests);
01124 if (id == NULL)
01125 break;
01126
01127 octets = 0;
01128 from = to = udh = smsc = dlr_url = account = binfo = charset = NULL;
01129 mclass = mwi = coding = compress = pid = alt_dcs = rpi = dlr_mask
01130 = validity = deferred = priority = SMS_PARAM_UNDEFINED;
01131
01132 get_receiver(id, &msg, &trans, &method, &req_url, &req_headers, &req_body, &retries);
01133
01134 if (status == HTTP_OK || status == HTTP_ACCEPTED) {
01135 http_header_get_content_type(reply_headers, &type, &charset);
01136 if (octstr_case_compare(type, text_html) == 0 ||
01137 octstr_case_compare(type, text_wml) == 0) {
01138 if (trans != NULL)
01139 strip_prefix_and_suffix(reply_body, urltrans_prefix(trans),
01140 urltrans_suffix(trans));
01141 replytext = html_to_sms(reply_body);
01142 octstr_strip_blanks(replytext);
01143 get_x_kannel_from_headers(reply_headers, &from, &to, &udh,
01144 NULL, NULL, &smsc, &mclass, &mwi,
01145 &coding, &compress, &validity,
01146 &deferred, &dlr_mask, &dlr_url,
01147 &account, &pid, &alt_dcs, &rpi,
01148 &binfo, &priority);
01149 } else if (octstr_case_compare(type, text_plain) == 0) {
01150 replytext = octstr_duplicate(reply_body);
01151 octstr_destroy(reply_body);
01152 reply_body = NULL;
01153 get_x_kannel_from_headers(reply_headers, &from, &to, &udh,
01154 NULL, NULL, &smsc, &mclass, &mwi,
01155 &coding, &compress, &validity,
01156 &deferred, &dlr_mask, &dlr_url,
01157 &account, &pid, &alt_dcs, &rpi,
01158 &binfo, &priority);
01159 } else if (octstr_case_compare(type, text_xml) == 0) {
01160 replytext = octstr_duplicate(reply_body);
01161 octstr_destroy(reply_body);
01162 reply_body = NULL;
01163 get_x_kannel_from_xml(mt_reply, &type, &replytext, reply_headers,
01164 &from, &to, &udh, NULL, NULL, &smsc, &mclass, &mwi,
01165 &coding, &compress, &validity, &deferred, &dlr_mask,
01166 &dlr_url, &account, &pid, &alt_dcs, &rpi, NULL, &charset,
01167 &binfo, &priority);
01168 } else if (octstr_case_compare(type, octet_stream) == 0) {
01169 replytext = octstr_duplicate(reply_body);
01170 octstr_destroy(reply_body);
01171 octets = 1;
01172 reply_body = NULL;
01173 get_x_kannel_from_headers(reply_headers, &from, &to, &udh,
01174 NULL, NULL, &smsc, &mclass, &mwi,
01175 &coding, &compress, &validity,
01176 &deferred, &dlr_mask, &dlr_url,
01177 &account, &pid, &alt_dcs, &rpi,
01178 &binfo, &priority);
01179 } else {
01180 replytext = octstr_duplicate(reply_couldnotrepresent);
01181 }
01182
01183 if (charset_processing(charset, replytext, coding) == -1) {
01184 replytext = octstr_duplicate(reply_couldnotrepresent);
01185 }
01186 octstr_destroy(type);
01187 } else if (max_http_retries > retries) {
01188 id = remember_receiver(msg, trans, method, req_url, req_headers, req_body, retries);
01189 gwlist_produce(smsbox_http_requests, id);
01190 queued++;
01191 goto requeued;
01192 } else
01193 replytext = octstr_duplicate(reply_couldnotfetch);
01194
01195 fill_message(msg, trans, replytext, octets, from, to, udh, mclass,
01196 mwi, coding, compress, validity, deferred, dlr_url,
01197 dlr_mask, pid, alt_dcs, rpi, smsc, account, charset,
01198 binfo, priority);
01199
01200 if (final_url == NULL)
01201 final_url = octstr_imm("");
01202 if (reply_body == NULL)
01203 reply_body = octstr_imm("");
01204
01205 if (msg->sms.sms_type != report_mo) {
01206 alog("SMS HTTP-request sender:%s request: '%s' "
01207 "url: '%s' reply: %d '%s'",
01208 octstr_get_cstr(msg->sms.receiver),
01209 (msg->sms.msgdata != NULL) ? octstr_get_cstr(msg->sms.msgdata) : "",
01210 octstr_get_cstr(final_url), status,
01211 (status == HTTP_OK) ? "<< successful >>" : octstr_get_cstr(reply_body));
01212 }
01213
01214 requeued:
01215 octstr_destroy(final_url);
01216 http_destroy_headers(reply_headers);
01217 octstr_destroy(reply_body);
01218 octstr_destroy(req_url);
01219 http_destroy_headers(req_headers);
01220 octstr_destroy(req_body);
01221
01222 if (msg->sms.sms_type != report_mo && !queued) {
01223 if (send_message(trans, msg) < 0)
01224 error(0, "failed to send message to phone");
01225 }
01226 msg_destroy(msg);
01227 }
01228 }
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245 static int obey_request(Octstr **result, URLTranslation *trans, Msg *msg)
01246 {
01247 Octstr *pattern, *xml, *tmp;
01248 List *request_headers;
01249 void *id;
01250 struct tm tm;
01251 char p[22];
01252 int type;
01253 FILE *f;
01254
01255 gw_assert(msg != NULL);
01256 gw_assert(msg_type(msg) == sms);
01257
01258 if (msg->sms.sms_type == report_mo)
01259 type = TRANSTYPE_GET_URL;
01260 else
01261 type = urltrans_type(trans);
01262
01263 pattern = urltrans_get_pattern(trans, msg);
01264 gw_assert(pattern != NULL);
01265
01266 switch (type) {
01267 case TRANSTYPE_TEXT:
01268 debug("sms", 0, "formatted text answer: <%s>",
01269 octstr_get_cstr(pattern));
01270 *result = pattern;
01271 alog("SMS request sender:%s request: '%s' fixed answer: '%s'",
01272 octstr_get_cstr(msg->sms.receiver),
01273 octstr_get_cstr(msg->sms.msgdata),
01274 octstr_get_cstr(pattern));
01275 break;
01276
01277 case TRANSTYPE_FILE:
01278 *result = octstr_read_file(octstr_get_cstr(pattern));
01279 octstr_destroy(pattern);
01280 alog("SMS request sender:%s request: '%s' file answer: '%s'",
01281 octstr_get_cstr(msg->sms.receiver),
01282 octstr_get_cstr(msg->sms.msgdata),
01283 octstr_get_cstr(*result));
01284 break;
01285
01286 case TRANSTYPE_EXECUTE:
01287 semaphore_down(max_pending_requests);
01288 debug("sms.exec", 0, "executing sms-service '%s'",
01289 octstr_get_cstr(pattern));
01290 if ((f = popen(octstr_get_cstr(pattern), "r")) != NULL) {
01291 octstr_destroy(pattern);
01292 *result = octstr_read_pipe(f);
01293 pclose(f);
01294 semaphore_up(max_pending_requests);
01295 alog("SMS request sender:%s request: '%s' file answer: '%s'",
01296 octstr_get_cstr(msg->sms.receiver),
01297 octstr_get_cstr(msg->sms.msgdata),
01298 octstr_get_cstr(*result));
01299 } else {
01300 error(0, "popen failed for '%s': %d: %s",
01301 octstr_get_cstr(pattern), errno, strerror(errno));
01302 *result = NULL;
01303 octstr_destroy(pattern);
01304 return -1;
01305 }
01306 break;
01307
01308
01309
01310
01311 case TRANSTYPE_GET_URL:
01312 request_headers = http_create_empty_headers();
01313 http_header_add(request_headers, "User-Agent", GW_NAME "/" GW_VERSION);
01314 if (trans != 0) {
01315 if (urltrans_send_sender(trans)) {
01316 http_header_add(request_headers, "X-Kannel-From",
01317 octstr_get_cstr(msg->sms.receiver));
01318 }
01319 }
01320
01321 id = remember_receiver(msg, trans, HTTP_METHOD_GET, pattern, request_headers, NULL, 0);
01322 semaphore_down(max_pending_requests);
01323 http_start_request(caller, HTTP_METHOD_GET, pattern, request_headers,
01324 NULL, 1, id, NULL);
01325 octstr_destroy(pattern);
01326 http_destroy_headers(request_headers);
01327 *result = NULL;
01328 return 0;
01329
01330 case TRANSTYPE_POST_URL:
01331 request_headers = http_create_empty_headers();
01332 http_header_add(request_headers, "User-Agent", GW_NAME "/" GW_VERSION);
01333 if (msg->sms.coding == DC_8BIT)
01334 http_header_add(request_headers, "Content-Type",
01335 "application/octet-stream");
01336 else
01337 if(msg->sms.coding == DC_UCS2)
01338 http_header_add(request_headers, "Content-Type", "text/plain; charset=\"UTF-16BE\"");
01339 else {
01340 Octstr *header;
01341 header = octstr_create("text/plain");
01342 if(msg->sms.charset) {
01343 octstr_append(header, octstr_imm("; charset=\""));
01344 octstr_append(header, msg->sms.charset);
01345 octstr_append(header, octstr_imm("\""));
01346 }
01347 http_header_add(request_headers, "Content-Type", octstr_get_cstr(header));
01348 O_DESTROY(header);
01349 }
01350 if (urltrans_send_sender(trans))
01351 http_header_add(request_headers, "X-Kannel-From",
01352 octstr_get_cstr(msg->sms.receiver));
01353 http_header_add(request_headers, "X-Kannel-To",
01354 octstr_get_cstr(msg->sms.sender));
01355
01356 tm = gw_gmtime(msg->sms.time);
01357 sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d",
01358 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
01359 tm.tm_hour, tm.tm_min, tm.tm_sec);
01360 http_header_add(request_headers, "X-Kannel-Time", p);
01361
01362 tm = gw_gmtime(time(NULL));
01363 sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d",
01364 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
01365 tm.tm_hour, tm.tm_min, tm.tm_sec);
01366 http_header_add(request_headers, "Date", p);
01367
01368 if (octstr_len(msg->sms.udhdata)) {
01369 Octstr *os;
01370 os = octstr_duplicate(msg->sms.udhdata);
01371 octstr_url_encode(os);
01372 http_header_add(request_headers, "X-Kannel-UDH",
01373 octstr_get_cstr(os));
01374 octstr_destroy(os);
01375 }
01376 if (octstr_len(msg->sms.smsc_id)) {
01377 Octstr *os;
01378 os = octstr_duplicate(msg->sms.smsc_id);
01379 http_header_add(request_headers, "X-Kannel-SMSC",
01380 octstr_get_cstr(os));
01381 octstr_destroy(os);
01382 }
01383
01384 if(msg->sms.mclass != SMS_PARAM_UNDEFINED) {
01385 Octstr *os;
01386 os = octstr_format("%d",msg->sms.mclass);
01387 http_header_add(request_headers, "X-Kannel-MClass",
01388 octstr_get_cstr(os));
01389 octstr_destroy(os);
01390 }
01391 if(msg->sms.pid != SMS_PARAM_UNDEFINED) {
01392 Octstr *os;
01393 os = octstr_format("%d",msg->sms.pid);
01394 http_header_add(request_headers, "X-Kannel-PID",
01395 octstr_get_cstr(os));
01396 octstr_destroy(os);
01397 }
01398 if(msg->sms.rpi != SMS_PARAM_UNDEFINED) {
01399 Octstr *os;
01400 os = octstr_format("%d",msg->sms.rpi);
01401 http_header_add(request_headers, "X-Kannel-RPI",
01402 octstr_get_cstr(os));
01403 octstr_destroy(os);
01404 }
01405 if(msg->sms.alt_dcs != SMS_PARAM_UNDEFINED) {
01406 Octstr *os;
01407 os = octstr_format("%d",msg->sms.alt_dcs);
01408 http_header_add(request_headers, "X-Kannel-Alt-DCS",
01409 octstr_get_cstr(os));
01410 octstr_destroy(os);
01411 }
01412 if(msg->sms.mwi != SMS_PARAM_UNDEFINED) {
01413 Octstr *os;
01414 os = octstr_format("%d",msg->sms.mwi);
01415 http_header_add(request_headers, "X-Kannel-MWI",
01416 octstr_get_cstr(os));
01417 octstr_destroy(os);
01418 }
01419 if(msg->sms.coding != SMS_PARAM_UNDEFINED) {
01420 Octstr *os;
01421 os = octstr_format("%d",msg->sms.coding);
01422 http_header_add(request_headers, "X-Kannel-Coding",
01423 octstr_get_cstr(os));
01424 octstr_destroy(os);
01425 }
01426 if(msg->sms.compress != SMS_PARAM_UNDEFINED) {
01427 Octstr *os;
01428 os = octstr_format("%d",msg->sms.compress);
01429 http_header_add(request_headers, "X-Kannel-Compress",
01430 octstr_get_cstr(os));
01431 octstr_destroy(os);
01432 }
01433 if (msg->sms.validity != SMS_PARAM_UNDEFINED) {
01434 Octstr *os;
01435 os = octstr_format("%d",msg->sms.validity);
01436 http_header_add(request_headers, "X-Kannel-Validity",
01437 octstr_get_cstr(os));
01438 octstr_destroy(os);
01439 }
01440 if (msg->sms.deferred != SMS_PARAM_UNDEFINED) {
01441 Octstr *os;
01442 os = octstr_format("%d",msg->sms.deferred);
01443 http_header_add(request_headers, "X-Kannel-Deferred",
01444 octstr_get_cstr(os));
01445 octstr_destroy(os);
01446 }
01447 if (octstr_len(msg->sms.service)) {
01448 Octstr *os;
01449 os = octstr_duplicate(msg->sms.service);
01450 http_header_add(request_headers, "X-Kannel-Service",
01451 octstr_get_cstr(os));
01452 octstr_destroy(os);
01453 }
01454 if (octstr_len(msg->sms.binfo)) {
01455 Octstr *os;
01456 os = octstr_duplicate(msg->sms.binfo);
01457 http_header_add(request_headers, "X-Kannel-BInfo",
01458 octstr_get_cstr(os));
01459 octstr_destroy(os);
01460 }
01461 id = remember_receiver(msg, trans, HTTP_METHOD_POST, pattern, request_headers, msg->sms.msgdata, 0);
01462 semaphore_down(max_pending_requests);
01463 http_start_request(caller, HTTP_METHOD_POST, pattern, request_headers,
01464 msg->sms.msgdata, 1, id, NULL);
01465 octstr_destroy(pattern);
01466 http_destroy_headers(request_headers);
01467 *result = NULL;
01468 return 0;
01469
01470 case TRANSTYPE_POST_XML:
01471
01472
01473
01474
01475 #define OCTSTR_APPEND_XML(xml, tag, text) \
01476 octstr_format_append(xml, " \t\t<" tag ">%s</" tag ">\n", \
01477 (text?octstr_get_cstr(text):""));
01478
01479 #define OCTSTR_APPEND_XML_NUMBER(xml, tag, value) \
01480 octstr_format_append(xml, " \t\t<" tag ">%ld</" tag ">\n", (long) value);
01481
01482 request_headers = http_create_empty_headers();
01483 http_header_add(request_headers, "User-Agent", GW_NAME "/" GW_VERSION);
01484 if(msg->sms.coding == DC_UCS2) {
01485 http_header_add(request_headers, "Content-Type",
01486 "text/xml; charset=\"ISO-8859-1\"");
01487 } else {
01488 Octstr *header;
01489 header = octstr_create("text/xml");
01490 if(msg->sms.charset) {
01491 octstr_append(header, octstr_imm("; charset=\""));
01492 octstr_append(header, msg->sms.charset);
01493 octstr_append(header, octstr_imm("\""));
01494 }
01495 http_header_add(request_headers, "Content-Type", octstr_get_cstr(header));
01496 O_DESTROY(header);
01497 }
01498
01499 tm = gw_gmtime(time(NULL));
01500 sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d",
01501 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
01502 tm.tm_hour, tm.tm_min, tm.tm_sec);
01503 http_header_add(request_headers, "Date", p);
01504
01505 xml = octstr_create("");
01506 octstr_append(xml, octstr_imm("<?xml version=\"1.0\" encoding=\""));
01507 if(msg->sms.coding == DC_UCS2 || msg->sms.charset == NULL)
01508 octstr_append(xml, octstr_imm("ISO-8859-1"));
01509 else
01510 octstr_append(xml, msg->sms.charset);
01511 octstr_append(xml, octstr_imm("\"?>\n"));
01512
01513
01514
01515
01516
01517 octstr_append(xml, octstr_imm("<message cid=\"1\">\n"));
01518 octstr_append(xml, octstr_imm("\t<submit>\n"));
01519
01520
01521 if(urltrans_send_sender(trans)) {
01522 tmp = octstr_create("");
01523 OCTSTR_APPEND_XML(tmp, "number", msg->sms.receiver);
01524 OCTSTR_APPEND_XML(xml, "oa", tmp);
01525 octstr_destroy(tmp);
01526 }
01527
01528
01529 tmp = octstr_create("");
01530 OCTSTR_APPEND_XML(tmp, "number", msg->sms.sender);
01531 OCTSTR_APPEND_XML(xml, "da", tmp);
01532 octstr_destroy(tmp);
01533
01534
01535 if(octstr_len(msg->sms.udhdata)) {
01536 Octstr *t;
01537 t = octstr_duplicate(msg->sms.udhdata);
01538 octstr_url_encode(t);
01539 OCTSTR_APPEND_XML(xml, "udh", t);
01540 octstr_destroy(t);
01541 }
01542
01543
01544 if(octstr_len(msg->sms.msgdata)) {
01545 octstr_url_encode(msg->sms.msgdata);
01546 OCTSTR_APPEND_XML(xml, "ud", msg->sms.msgdata);
01547 }
01548
01549
01550 if(msg->sms.pid != SMS_PARAM_UNDEFINED)
01551 OCTSTR_APPEND_XML_NUMBER(xml, "pid", msg->sms.pid);
01552
01553
01554 if(msg->sms.rpi != SMS_PARAM_UNDEFINED)
01555 OCTSTR_APPEND_XML_NUMBER(xml, "rpi", msg->sms.rpi);
01556
01557
01558 tmp = octstr_create("");
01559 if(msg->sms.coding != SMS_PARAM_UNDEFINED)
01560 OCTSTR_APPEND_XML_NUMBER(tmp, "coding", msg->sms.coding);
01561 if(msg->sms.mclass != SMS_PARAM_UNDEFINED)
01562 OCTSTR_APPEND_XML_NUMBER(tmp, "mclass", msg->sms.mclass);
01563 if(msg->sms.alt_dcs != SMS_PARAM_UNDEFINED)
01564 OCTSTR_APPEND_XML_NUMBER(tmp, "alt-dcs", msg->sms.alt_dcs);
01565 if(msg->sms.mwi != SMS_PARAM_UNDEFINED)
01566 OCTSTR_APPEND_XML_NUMBER(tmp, "mwi", msg->sms.mwi);
01567 if(msg->sms.compress != SMS_PARAM_UNDEFINED)
01568 OCTSTR_APPEND_XML_NUMBER(tmp, "compress", msg->sms.compress);
01569 if(octstr_len(tmp))
01570 OCTSTR_APPEND_XML(xml, "dcs", tmp)
01571 octstr_destroy(tmp);
01572
01573
01574 tmp = octstr_create("");
01575 if(msg->sms.deferred != SMS_PARAM_UNDEFINED)
01576 OCTSTR_APPEND_XML_NUMBER(tmp, "delay", msg->sms.deferred);
01577 if(octstr_len(tmp))
01578 OCTSTR_APPEND_XML(xml, "timing", tmp)
01579 octstr_destroy(tmp);
01580
01581
01582 tmp = octstr_create("");
01583 if(msg->sms.validity != SMS_PARAM_UNDEFINED)
01584 OCTSTR_APPEND_XML_NUMBER(tmp, "delay", msg->sms.validity);
01585 if(octstr_len(tmp))
01586 OCTSTR_APPEND_XML(xml, "vp", tmp)
01587 octstr_destroy(tmp);
01588
01589
01590 tm = gw_gmtime(msg->sms.time);
01591 tmp = octstr_format("<year>%04d</year><month>%02d</month>"
01592 "<day>%02d</day><hour>%02d</hour><minute>%02d</minute>"
01593 "<second>%02d</second><timezone>0</timezone>",
01594 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
01595 tm.tm_hour, tm.tm_min, tm.tm_sec);
01596 OCTSTR_APPEND_XML(xml, "at", tmp);
01597 octstr_destroy(tmp);
01598
01599
01600 if (octstr_len(msg->sms.smsc_id)) {
01601 tmp = octstr_create("");
01602 if(octstr_len(msg->sms.smsc_id))
01603 OCTSTR_APPEND_XML(tmp, "account", msg->sms.smsc_id);
01604 if(octstr_len(tmp))
01605 OCTSTR_APPEND_XML(xml, "from", tmp);
01606 O_DESTROY(tmp);
01607 }
01608
01609
01610 if(octstr_len(msg->sms.service)) {
01611 tmp = octstr_create("");
01612 OCTSTR_APPEND_XML(tmp, "service", msg->sms.service);
01613 if(octstr_len(tmp))
01614 OCTSTR_APPEND_XML(xml, "to", tmp);
01615 O_DESTROY(tmp);
01616 }
01617
01618
01619 octstr_append(xml, octstr_imm("\t</submit>\n"));
01620 octstr_append(xml, octstr_imm("</message>\n"));
01621
01622 if(msg->sms.msgdata != NULL)
01623 octstr_destroy(msg->sms.msgdata);
01624
01625 msg->sms.msgdata = xml;
01626
01627 debug("sms", 0, "XMLBuild: XML: <%s>", octstr_get_cstr(msg->sms.msgdata));
01628 id = remember_receiver(msg, trans, HTTP_METHOD_POST, pattern, request_headers, msg->sms.msgdata, 0);
01629 semaphore_down(max_pending_requests);
01630 http_start_request(caller, HTTP_METHOD_POST, pattern, request_headers,
01631 msg->sms.msgdata, 1, id, NULL);
01632 octstr_destroy(pattern);
01633 http_destroy_headers(request_headers);
01634 *result = NULL;
01635 return 0;
01636
01637 case TRANSTYPE_SENDSMS:
01638 error(0, "Got URL translation type SENDSMS for incoming message.");
01639 alog("SMS request sender:%s request: '%s' FAILED bad translation",
01640 octstr_get_cstr(msg->sms.receiver),
01641 octstr_get_cstr(msg->sms.msgdata));
01642 octstr_destroy(pattern);
01643 return -1;
01644
01645 default:
01646 error(0, "Unknown URL translation type %d", urltrans_type(trans));
01647 alog("SMS request sender:%s request: '%s' FAILED unknown translation",
01648 octstr_get_cstr(msg->sms.receiver),
01649 octstr_get_cstr(msg->sms.msgdata));
01650 octstr_destroy(pattern);
01651 return -1;
01652 }
01653
01654 return 1;
01655 }
01656
01657 static void obey_request_thread(void *arg)
01658 {
01659 Msg *msg, *mack, *reply_msg;
01660 Octstr *tmp, *reply;
01661 URLTranslation *trans;
01662 Octstr *p;
01663 int ret, dreport=0;
01664
01665 while ((msg = gwlist_consume(smsbox_requests)) != NULL) {
01666 if (msg->sms.sms_type == report_mo)
01667 dreport = 1;
01668 else
01669 dreport = 0;
01670
01671
01672 if (mo_recode && msg->sms.coding == DC_UCS2) {
01673 int converted = 0;
01674 Octstr *text;
01675
01676 text = octstr_duplicate(msg->sms.msgdata);
01677 if(0 == octstr_recode(octstr_imm("UTF-8"), octstr_imm("UTF-16BE"), text)) {
01678 info(0, "MO message converted from UCS-2 to UTF-8");
01679 octstr_destroy(msg->sms.msgdata);
01680 msg->sms.msgdata = octstr_duplicate(text);
01681 msg->sms.charset = octstr_create("UTF-8");
01682 msg->sms.coding = DC_7BIT;
01683 converted=1;
01684 }
01685 octstr_destroy(text);
01686 }
01687
01688 if (octstr_len(msg->sms.sender) == 0 ||
01689 octstr_len(msg->sms.receiver) == 0) {
01690 error(0, "smsbox_req_thread: no sender/receiver, dump follows:");
01691 msg_dump(msg, 0);
01692
01693
01694
01695 mack = msg_create(ack);
01696 mack->ack.nack = ack_failed;
01697 mack->ack.time = msg->sms.time;
01698 uuid_copy(mack->ack.id, msg->sms.id);
01699 write_to_bearerbox(mack);
01700
01701 msg_destroy(msg);
01702 continue;
01703 }
01704
01705
01706 mack = msg_create(ack);
01707 mack->ack.nack = ack_success;
01708 mack->ack.time = msg->sms.time;
01709 uuid_copy(mack->ack.id, msg->sms.id);
01710
01711
01712
01713
01714
01715 if (dreport) {
01716 if (msg->sms.service == NULL || (msg->sms.service != NULL &&
01717 ppg_service_name != NULL &&
01718 octstr_compare(msg->sms.service, ppg_service_name) == 0)) {
01719 trans = NULL;
01720 } else {
01721 trans = urltrans_find_service(translations, msg);
01722 }
01723
01724 info(0, "Starting delivery report <%s> from <%s>",
01725 octstr_get_cstr(msg->sms.service),
01726 octstr_get_cstr(msg->sms.sender));
01727
01728 } else {
01729 trans = urltrans_find(translations, msg);
01730 if (trans == NULL) {
01731 warning(0, "No translation found for <%s> from <%s> to <%s>",
01732 octstr_get_cstr(msg->sms.msgdata),
01733 octstr_get_cstr(msg->sms.sender),
01734 octstr_get_cstr(msg->sms.receiver));
01735 sms_swap(msg);
01736 goto error;
01737 }
01738
01739 info(0, "Starting to service <%s> from <%s> to <%s>",
01740 octstr_get_cstr(msg->sms.msgdata),
01741 octstr_get_cstr(msg->sms.sender),
01742 octstr_get_cstr(msg->sms.receiver));
01743
01744
01745
01746
01747
01748
01749 tmp = octstr_duplicate(msg->sms.sender);
01750
01751 p = urltrans_faked_sender(trans);
01752 if (p != NULL) {
01753 octstr_destroy(msg->sms.sender);
01754 msg->sms.sender = octstr_duplicate(p);
01755 } else if (global_sender != NULL) {
01756 octstr_destroy(msg->sms.sender);
01757 msg->sms.sender = octstr_duplicate(global_sender);
01758 } else {
01759 octstr_destroy(msg->sms.sender);
01760 msg->sms.sender = octstr_duplicate(msg->sms.receiver);
01761 }
01762 octstr_destroy(msg->sms.receiver);
01763 msg->sms.receiver = tmp;
01764 msg->sms.sms_type = mt_reply;
01765 }
01766
01767
01768
01769 if(msg->sms.service == NULL && trans != NULL)
01770 msg->sms.service = octstr_duplicate(urltrans_name(trans));
01771 ret = obey_request(&reply, trans, msg);
01772 if (ret != 0) {
01773 if (ret == -1) {
01774 error:
01775 error(0, "request failed");
01776
01777
01778 reply = octstr_duplicate(reply_requestfailed);
01779 trans = NULL;
01780 }
01781 if (!dreport) {
01782
01783 reply_msg = msg_create(sms);
01784 reply_msg->sms.sms_type = mt_reply;
01785 reply_msg->sms.sender = msg->sms.sender;
01786 msg->sms.sender = NULL;
01787 reply_msg->sms.receiver = msg->sms.receiver;
01788 msg->sms.receiver = NULL;
01789 reply_msg->sms.smsc_id = msg->sms.smsc_id;
01790 msg->sms.smsc_id = NULL;
01791 reply_msg->sms.msgdata = reply;
01792 reply_msg->sms.time = time(NULL);
01793
01794
01795 if (send_message(trans, reply_msg) < 0)
01796 error(0, "request_thread: failed");
01797
01798
01799 msg_destroy(reply_msg);
01800 }
01801 }
01802
01803 write_to_bearerbox(mack);
01804
01805 msg_destroy(msg);
01806 }
01807 }
01808
01809
01810
01811
01812
01813
01814
01815 #ifdef HAVE_SECURITY_PAM_APPL_H
01816
01817
01818
01819
01820
01821 typedef const struct pam_message pam_message_type;
01822
01823 static const char *PAM_username;
01824 static const char *PAM_password;
01825
01826 static int PAM_conv (int num_msg, pam_message_type **msg,
01827 struct pam_response **resp,
01828 void *appdata_ptr)
01829 {
01830 int count = 0, replies = 0;
01831 struct pam_response *repl = NULL;
01832 int size = sizeof(struct pam_response);
01833
01834 #define GET_MEM \
01835 repl = gw_realloc(repl, size); \
01836 size += sizeof(struct pam_response)
01837 #define COPY_STRING(s) (s) ? gw_strdup(s) : NULL
01838
01839 for (count = 0; count < num_msg; count++) {
01840 switch (msg[count]->msg_style) {
01841 case PAM_PROMPT_ECHO_ON:
01842 GET_MEM;
01843 repl[replies].resp_retcode = PAM_SUCCESS;
01844 repl[replies++].resp = COPY_STRING(PAM_username);
01845
01846 break;
01847
01848 case PAM_PROMPT_ECHO_OFF:
01849 GET_MEM;
01850 repl[replies].resp_retcode = PAM_SUCCESS;
01851 repl[replies++].resp = COPY_STRING(PAM_password);
01852
01853 break;
01854
01855 case PAM_TEXT_INFO:
01856 warning(0, "unexpected message from PAM: %s", msg[count]->msg);
01857 break;
01858
01859 case PAM_ERROR_MSG:
01860 default:
01861
01862 error(0, "unexpected error from PAM: %s", msg[count]->msg);
01863 gw_free(repl);
01864 return PAM_CONV_ERR;
01865 }
01866 }
01867 if (repl)
01868 *resp = repl;
01869 return PAM_SUCCESS;
01870 }
01871
01872 static struct pam_conv PAM_conversation = {
01873 &PAM_conv,
01874 NULL
01875 };
01876
01877
01878 static int authenticate(const char *login, const char *passwd)
01879 {
01880 pam_handle_t *pamh;
01881 int pam_error;
01882
01883 PAM_username = login;
01884 PAM_password = passwd;
01885
01886 pam_error = pam_start("kannel", login, &PAM_conversation, &pamh);
01887 if (pam_error != PAM_SUCCESS ||
01888 (pam_error = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
01889 pam_end(pamh, pam_error);
01890 return 0;
01891 }
01892 pam_end(pamh, PAM_SUCCESS);
01893 info(0, "sendsms used by <%s>", login);
01894 return 1;
01895 }
01896
01897
01898
01899
01900
01901
01902
01903 static int pam_authorise_user(List *list)
01904 {
01905 Octstr *val, *user = NULL;
01906 char *pwd, *login;
01907 int result;
01908
01909 if ((user = http_cgi_variable(list, "user")) == NULL &&
01910 (user = http_cgi_variable(list, "username"))==NULL)
01911 return 0;
01912 login = octstr_get_cstr(user);
01913
01914 if ((val = http_cgi_variable(list, "password")) == NULL &&
01915 (val = http_cgi_variable(list, "pass")) == NULL)
01916 return 0;
01917
01918 pwd = octstr_get_cstr(val);
01919 result = authenticate(login, pwd);
01920
01921 return result;
01922 }
01923
01924 #endif
01925
01926
01927
01928
01929 static Octstr* store_uuid(Msg *msg)
01930 {
01931 char id[UUID_STR_LEN + 1];
01932 Octstr *stored_uuid;
01933
01934 gw_assert(msg != NULL);
01935 gw_assert(!immediate_sendsms_reply);
01936
01937 uuid_unparse(msg->sms.id, id);
01938 stored_uuid = octstr_create(id);
01939
01940 debug("sms.http", 0, "Stored UUID %s", octstr_get_cstr(stored_uuid));
01941
01942
01943
01944
01945 return stored_uuid;
01946 }
01947
01948
01949
01950 static Octstr *smsbox_req_handle(URLTranslation *t, Octstr *client_ip,
01951 HTTPClient *client,
01952 Octstr *from, Octstr *to, Octstr *text,
01953 Octstr *charset, Octstr *udh, Octstr *smsc,
01954 int mclass, int mwi, int coding, int compress,
01955 int validity, int deferred,
01956 int *status, int dlr_mask, Octstr *dlr_url,
01957 Octstr *account, int pid, int alt_dcs, int rpi,
01958 List *receiver, Octstr *binfo, int priority)
01959 {
01960 Msg *msg = NULL;
01961 Octstr *newfrom = NULL;
01962 Octstr *returnerror = NULL;
01963 Octstr *receiv;
01964 Octstr *stored_uuid = NULL;
01965 List *failed_id = NULL;
01966 List *allowed = NULL;
01967 List *denied = NULL;
01968 int no_recv, ret = 0, i;
01969 long del;
01970
01971
01972
01973
01974
01975
01976
01977 if(receiver == NULL) {
01978 receiver = octstr_split_words(to);
01979 }
01980 no_recv = gwlist_len(receiver);
01981
01982
01983
01984
01985
01986 if (udh != NULL && (octstr_len(udh) != octstr_get_char(udh, 0) + 1)) {
01987 returnerror = octstr_create("UDH field misformed, rejected");
01988 goto field_error;
01989 }
01990 if (udh != NULL && octstr_len(udh) > MAX_SMS_OCTETS) {
01991 returnerror = octstr_create("UDH field is too long, rejected");
01992 goto field_error;
01993 }
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003 allowed = gwlist_create();
02004 denied = gwlist_create();
02005
02006 for (i = 0; i < no_recv; i++) {
02007 receiv = gwlist_get(receiver, i);
02008
02009
02010
02011
02012 if (strspn(octstr_get_cstr(receiv), sendsms_number_chars) < octstr_len(receiv)) {
02013 info(0,"Illegal characters in 'to' string ('%s') vs '%s'",
02014 octstr_get_cstr(receiv), sendsms_number_chars);
02015 gwlist_append_unique(denied, receiv, octstr_item_match);
02016 }
02017
02018
02019
02020
02021
02022 if (urltrans_white_list(t) &&
02023 numhash_find_number(urltrans_white_list(t), receiv) < 1) {
02024 info(0, "Number <%s> is not in white-list, message discarded",
02025 octstr_get_cstr(receiv));
02026 gwlist_append_unique(denied, receiv, octstr_item_match);
02027 } else {
02028 gwlist_append_unique(allowed, receiv, octstr_item_match);
02029 }
02030
02031 if (urltrans_white_list_regex(t) &&
02032 gw_regex_match_pre(urltrans_white_list_regex(t), receiv) == 0) {
02033 info(0, "Number <%s> is not in white-list-regex, message discarded",
02034 octstr_get_cstr(receiv));
02035 gwlist_append_unique(denied, receiv, octstr_item_match);
02036 } else {
02037 gwlist_append_unique(allowed, receiv, octstr_item_match);
02038 }
02039
02040 if (urltrans_black_list(t) &&
02041 numhash_find_number(urltrans_black_list(t), receiv) == 1) {
02042 info(0, "Number <%s> is in black-list, message discarded",
02043 octstr_get_cstr(receiv));
02044 gwlist_append_unique(denied, receiv, octstr_item_match);
02045 } else {
02046 gwlist_append_unique(allowed, receiv, octstr_item_match);
02047 }
02048
02049 if (urltrans_black_list_regex(t) &&
02050 gw_regex_match_pre(urltrans_black_list_regex(t), receiv) == 1) {
02051 info(0, "Number <%s> is in black-list-regex, message discarded",
02052 octstr_get_cstr(receiv));
02053 gwlist_append_unique(denied, receiv, octstr_item_match);
02054 } else {
02055 gwlist_append_unique(allowed, receiv, octstr_item_match);
02056 }
02057
02058
02059 if (white_list &&
02060 numhash_find_number(white_list, receiv) < 1) {
02061 info(0, "Number <%s> is not in global white-list, message discarded",
02062 octstr_get_cstr(receiv));
02063 gwlist_append_unique(denied, receiv, octstr_item_match);
02064 } else {
02065 gwlist_append_unique(allowed, receiv, octstr_item_match);
02066 }
02067
02068 if (white_list_regex &&
02069 gw_regex_match_pre(white_list_regex, receiv) == 0) {
02070 info(0, "Number <%s> is not in global white-list-regex, message discarded",
02071 octstr_get_cstr(receiv));
02072 gwlist_append_unique(denied, receiv, octstr_item_match);
02073 } else {
02074 gwlist_append_unique(allowed, receiv, octstr_item_match);
02075 }
02076
02077 if (black_list &&
02078 numhash_find_number(black_list, receiv) == 1) {
02079 info(0, "Number <%s> is in global black-list, message discarded",
02080 octstr_get_cstr(receiv));
02081 gwlist_append_unique(denied, receiv, octstr_item_match);
02082 } else {
02083 gwlist_append_unique(allowed, receiv, octstr_item_match);
02084 }
02085
02086 if (black_list_regex &&
02087 gw_regex_match_pre(black_list_regex, receiv) == 1) {
02088 info(0, "Number <%s> is in global black-list-regex, message discarded",
02089 octstr_get_cstr(receiv));
02090 gwlist_append_unique(denied, receiv, octstr_item_match);
02091 } else {
02092 gwlist_append_unique(allowed, receiv, octstr_item_match);
02093 }
02094 }
02095
02096
02097
02098
02099
02100
02101 for (i = 0; i < gwlist_len(denied); i++) {
02102 receiv = gwlist_get(denied, i);
02103 del = gwlist_delete_matching(allowed, receiv, octstr_item_match);
02104 }
02105
02106
02107 if (gwlist_len(allowed) == 0) {
02108 returnerror = octstr_create("Number(s) has/have been denied by white- and/or black-lists.");
02109 goto field_error;
02110 }
02111
02112 if (urltrans_faked_sender(t) != NULL) {
02113
02114 newfrom = octstr_duplicate(urltrans_faked_sender(t));
02115 } else if (octstr_len(from) > 0) {
02116 newfrom = octstr_duplicate(from);
02117 } else if (urltrans_default_sender(t) != NULL) {
02118 newfrom = octstr_duplicate(urltrans_default_sender(t));
02119 } else if (global_sender != NULL) {
02120 newfrom = octstr_duplicate(global_sender);
02121 } else {
02122 returnerror = octstr_create("Sender missing and no global set, rejected");
02123 goto field_error;
02124 }
02125
02126 info(0, "sendsms sender:<%s:%s> (%s) to:<%s> msg:<%s>",
02127 octstr_get_cstr(urltrans_username(t)),
02128 octstr_get_cstr(newfrom),
02129 octstr_get_cstr(client_ip),
02130 ( to == NULL ? "multi-cast" : octstr_get_cstr(to) ),
02131 ( text == NULL ? "" : octstr_get_cstr(text) ));
02132
02133
02134
02135
02136
02137 msg = msg_create(sms);
02138
02139 msg->sms.service = octstr_duplicate(urltrans_name(t));
02140 msg->sms.sms_type = mt_push;
02141 msg->sms.sender = octstr_duplicate(newfrom);
02142 if(octstr_len(account)) {
02143 if(octstr_len(account) <= 32 &&
02144 octstr_search_chars(account, octstr_imm("[]\n\r"), 0) == -1) {
02145 msg->sms.account = account ? octstr_duplicate(account) : NULL;
02146 } else {
02147 returnerror = octstr_create("Account field misformed, rejected");
02148 goto field_error;
02149 }
02150 }
02151 msg->sms.msgdata = text ? octstr_duplicate(text) : octstr_create("");
02152 msg->sms.udhdata = udh ? octstr_duplicate(udh) : octstr_create("");
02153
02154 if (octstr_len(binfo))
02155 msg->sms.binfo = octstr_duplicate(binfo);
02156
02157 if(octstr_len(dlr_url)) {
02158 if(octstr_len(dlr_url) < 8) {
02159 returnerror = octstr_create("DLR-URL field misformed, rejected");
02160 goto field_error;
02161 } else {
02162 Octstr *tmp;
02163 tmp = octstr_copy(dlr_url, 0, 7);
02164 if(octstr_case_compare(tmp, octstr_imm("http://")) == 0) {
02165 msg->sms.dlr_url = octstr_duplicate(dlr_url);
02166 } else {
02167 O_DESTROY(tmp);
02168 tmp = octstr_copy(dlr_url, 0, 8);
02169 if(octstr_case_compare(tmp, octstr_imm("https://")) != 0) {
02170 returnerror = octstr_create("DLR-URL field misformed, rejected");
02171 O_DESTROY(tmp);
02172 goto field_error;
02173 }
02174 #ifdef HAVE_LIBSSL
02175 msg->sms.dlr_url = octstr_duplicate(dlr_url);
02176 #else
02177 else {
02178 warning(0, "DLR-URL with https but SSL not supported, url is <%s>",
02179 octstr_get_cstr(dlr_url));
02180 }
02181 #endif
02182 }
02183 O_DESTROY(tmp);
02184 }
02185 } else {
02186 msg->sms.dlr_url = octstr_create("");
02187 }
02188
02189 if ( dlr_mask < -1 || dlr_mask > 31 ) {
02190 returnerror = octstr_create("DLR-Mask field misformed, rejected");
02191 goto field_error;
02192 }
02193 msg->sms.dlr_mask = dlr_mask;
02194
02195 if ( mclass < -1 || mclass > 3 ) {
02196 returnerror = octstr_create("MClass field misformed, rejected");
02197 goto field_error;
02198 }
02199 msg->sms.mclass = mclass;
02200
02201 if ( pid < -1 || pid > 255 ) {
02202 returnerror = octstr_create("PID field misformed, rejected");
02203 goto field_error;
02204 }
02205 msg->sms.pid = pid;
02206
02207 if ( rpi < -1 || rpi > 2) {
02208 returnerror = octstr_create("RPI field misformed, rejected");
02209 goto field_error;
02210 }
02211 msg->sms.rpi = rpi;
02212
02213 if ( alt_dcs < -1 || alt_dcs > 1 ) {
02214 returnerror = octstr_create("Alt-DCS field misformed, rejected");
02215 goto field_error;
02216 }
02217 msg->sms.alt_dcs = alt_dcs;
02218
02219 if ( mwi < -1 || mwi > 7 ) {
02220 returnerror = octstr_create("MWI field misformed, rejected");
02221 goto field_error;
02222 }
02223 msg->sms.mwi = mwi;
02224
02225 if ( coding < -1 || coding > 2 ) {
02226 returnerror = octstr_create("Coding field misformed, rejected");
02227 goto field_error;
02228 }
02229 msg->sms.coding = coding;
02230
02231 if ( compress < -1 || compress > 1 ) {
02232 returnerror = octstr_create("Compress field misformed, rejected");
02233 goto field_error;
02234 }
02235 msg->sms.compress = compress;
02236
02237
02238 if ( msg->sms.coding == DC_UNDEF) {
02239 if(octstr_len(udh))
02240 msg->sms.coding = DC_8BIT;
02241 else
02242 msg->sms.coding = DC_7BIT;
02243 }
02244
02245
02246 if ( validity < -1 ) {
02247 returnerror = octstr_create("Validity field misformed, rejected");
02248 goto field_error;
02249 }
02250 msg->sms.validity = validity;
02251
02252 if ( deferred < -1 ) {
02253 returnerror = octstr_create("Deferred field misformed, rejected");
02254 goto field_error;
02255 }
02256 msg->sms.deferred = deferred;
02257
02258 if (priority != SMS_PARAM_UNDEFINED && (priority < 0 || priority > 3)) {
02259 returnerror = octstr_create("Priority field misformed, rejected");
02260 goto field_error;
02261 }
02262 msg->sms.priority = priority;
02263
02264
02265
02266
02267
02268 if (urltrans_forced_smsc(t)) {
02269 msg->sms.smsc_id = octstr_duplicate(urltrans_forced_smsc(t));
02270 if (smsc)
02271 info(0, "send-sms request smsc id ignored, "
02272 "as smsc id forced to %s",
02273 octstr_get_cstr(urltrans_forced_smsc(t)));
02274 } else if (smsc) {
02275 msg->sms.smsc_id = octstr_duplicate(smsc);
02276 } else if (urltrans_default_smsc(t)) {
02277 msg->sms.smsc_id = octstr_duplicate(urltrans_default_smsc(t));
02278 } else
02279 msg->sms.smsc_id = NULL;
02280
02281 if (charset_processing(charset, msg->sms.msgdata, msg->sms.coding) == -1) {
02282 returnerror = octstr_create("Charset or body misformed, rejected");
02283 goto field_error;
02284 }
02285
02286 msg->sms.receiver = NULL;
02287
02288
02289
02290
02291
02292
02293
02294 failed_id = gwlist_create();
02295
02296 if (!immediate_sendsms_reply) {
02297 stored_uuid = store_uuid(msg);
02298 dict_put(client_dict, stored_uuid, client);
02299 }
02300
02301 while ((receiv = gwlist_extract_first(allowed)) != NULL) {
02302
02303 O_DESTROY(msg->sms.receiver);
02304 msg->sms.receiver = octstr_duplicate(receiv);
02305
02306 msg->sms.time = time(NULL);
02307
02308 ret = send_message(t, msg);
02309
02310 if (ret == -1) {
02311
02312 gwlist_append(failed_id, receiv);
02313 } else {
02314
02315 alog("send-SMS request added - sender:%s:%s %s target:%s request: '%s'",
02316 octstr_get_cstr(urltrans_username(t)),
02317 octstr_get_cstr(newfrom), octstr_get_cstr(client_ip),
02318 octstr_get_cstr(receiv),
02319 udh == NULL ? ( text == NULL ? "" : octstr_get_cstr(text) ) : "<< UDH >>");
02320 }
02321 }
02322
02323 if (gwlist_len(failed_id) > 0)
02324 goto transmit_error;
02325
02326 *status = HTTP_ACCEPTED;
02327 returnerror = octstr_create("Sent.");
02328
02329
02330
02331
02332
02333 if (gwlist_len(denied) > 0) {
02334 octstr_format_append(returnerror, " Denied receivers are:");
02335 while ((receiv = gwlist_extract_first(denied)) != NULL) {
02336 octstr_format_append(returnerror, " %s", octstr_get_cstr(receiv));
02337 }
02338 }
02339
02340
02341
02342
02343
02344 if (ret > 1)
02345 octstr_format_append(returnerror, " Message splits: %d", ret);
02346
02347 cleanup:
02348 octstr_destroy(stored_uuid);
02349 gwlist_destroy(failed_id, NULL);
02350 gwlist_destroy(allowed, NULL);
02351 gwlist_destroy(denied, NULL);
02352 gwlist_destroy(receiver, octstr_destroy_item);
02353 octstr_destroy(newfrom);
02354 msg_destroy(msg);
02355
02356 return returnerror;
02357
02358
02359 field_error:
02360 alog("send-SMS request failed - %s",
02361 octstr_get_cstr(returnerror));
02362 *status = HTTP_BAD_REQUEST;
02363
02364 goto cleanup;
02365
02366 transmit_error:
02367 error(0, "sendsms_request: failed");
02368 *status = HTTP_INTERNAL_SERVER_ERROR;
02369 returnerror = octstr_create("Sending failed.");
02370
02371 if (!immediate_sendsms_reply)
02372 dict_remove(client_dict, stored_uuid);
02373
02374
02375
02376
02377
02378 if (no_recv > 1) {
02379 octstr_format_append(returnerror, " Failed receivers are:");
02380 while ((receiv = gwlist_extract_first(failed_id)) != NULL) {
02381 octstr_format_append(returnerror, " %s", octstr_get_cstr(receiv));
02382 }
02383 }
02384
02385 goto cleanup;
02386 }
02387
02388
02389
02390
02391
02392 static URLTranslation *authorise_username(Octstr *username, Octstr *password,
02393 Octstr *client_ip)
02394 {
02395 URLTranslation *t = NULL;
02396
02397 if (username == NULL || password == NULL)
02398 return NULL;
02399
02400 if ((t = urltrans_find_username(translations, username))==NULL)
02401 return NULL;
02402
02403 if (octstr_compare(password, urltrans_password(t))!=0)
02404 return NULL;
02405 else {
02406 Octstr *allow_ip = urltrans_allow_ip(t);
02407 Octstr *deny_ip = urltrans_deny_ip(t);
02408
02409 if (is_allowed_ip(allow_ip, deny_ip, client_ip) == 0) {
02410 warning(0, "Non-allowed connect tried by <%s> from <%s>, ignored",
02411 octstr_get_cstr(username), octstr_get_cstr(client_ip));
02412 return NULL;
02413 }
02414 }
02415
02416 info(0, "sendsms used by <%s>", octstr_get_cstr(username));
02417 return t;
02418 }
02419
02420
02421
02422
02423
02424
02425 static URLTranslation *default_authorise_user(List *list, Octstr *client_ip)
02426 {
02427 Octstr *pass, *user = NULL;
02428
02429 if ((user = http_cgi_variable(list, "username")) == NULL)
02430 user = http_cgi_variable(list, "user");
02431
02432 if ((pass = http_cgi_variable(list, "password")) == NULL)
02433 pass = http_cgi_variable(list, "pass");
02434
02435 return authorise_username(user, pass, client_ip);
02436 }
02437
02438
02439 static URLTranslation *authorise_user(List *list, Octstr *client_ip)
02440 {
02441 #ifdef HAVE_SECURITY_PAM_APPL_H
02442 URLTranslation *t;
02443
02444 t = urltrans_find_username(translations, octstr_imm("pam"));
02445 if (t != NULL) {
02446 if (pam_authorise_user(list))
02447 return t;
02448 else
02449 return NULL;
02450 } else
02451 return default_authorise_user(list, client_ip);
02452 #else
02453 return default_authorise_user(list, client_ip);
02454 #endif
02455 }
02456
02457
02458
02459
02460
02461
02462 static Octstr *smsbox_req_sendsms(List *args, Octstr *client_ip, int *status,
02463 HTTPClient *client)
02464 {
02465 URLTranslation *t = NULL;
02466 Octstr *tmp_string;
02467 Octstr *from, *to, *charset, *text, *udh, *smsc, *dlr_url, *account;
02468 Octstr *binfo;
02469 int dlr_mask, mclass, mwi, coding, compress, validity, deferred, pid;
02470 int alt_dcs, rpi, priority;
02471
02472 from = to = udh = text = smsc = account = dlr_url = charset = binfo = NULL;
02473 mclass = mwi = coding = compress = validity = deferred = dlr_mask =
02474 pid = alt_dcs = rpi = priority = SMS_PARAM_UNDEFINED;
02475
02476
02477 t = authorise_user(args, client_ip);
02478 if (t == NULL) {
02479 *status = HTTP_FORBIDDEN;
02480 return octstr_create("Authorization failed for sendsms");
02481 }
02482
02483 udh = http_cgi_variable(args, "udh");
02484 text = http_cgi_variable(args, "text");
02485 charset = http_cgi_variable(args, "charset");
02486 smsc = http_cgi_variable(args, "smsc");
02487 from = http_cgi_variable(args, "from");
02488 to = http_cgi_variable(args, "to");
02489 account = http_cgi_variable(args, "account");
02490 binfo = http_cgi_variable(args, "binfo");
02491 dlr_url = http_cgi_variable(args, "dlr-url");
02492 if(dlr_url == NULL) {
02493 dlr_url = http_cgi_variable(args, "dlrurl");
02494 if(dlr_url != NULL)
02495 warning(0, "<dlrurl> field used and deprecated. Please use dlr-url instead.");
02496 }
02497 tmp_string = http_cgi_variable(args, "dlr-mask");
02498 if(tmp_string == NULL) {
02499 tmp_string = http_cgi_variable(args, "dlrmask");
02500 if(tmp_string != NULL)
02501 warning(0, "<dlrmask> field used and deprecated. Please use dlr-mask instead.");
02502 }
02503 if(tmp_string != NULL)
02504 sscanf(octstr_get_cstr(tmp_string),"%d", &dlr_mask);
02505
02506 tmp_string = http_cgi_variable(args, "mclass");
02507 if(tmp_string != NULL)
02508 sscanf(octstr_get_cstr(tmp_string),"%d", &mclass);
02509
02510 tmp_string = http_cgi_variable(args, "pid");
02511 if(tmp_string != NULL)
02512 sscanf(octstr_get_cstr(tmp_string),"%d", &pid);
02513
02514 tmp_string = http_cgi_variable(args, "rpi");
02515 if(tmp_string != NULL)
02516 sscanf(octstr_get_cstr(tmp_string),"%d", &rpi);
02517
02518 tmp_string = http_cgi_variable(args, "alt-dcs");
02519 if(tmp_string != NULL)
02520 sscanf(octstr_get_cstr(tmp_string),"%d", &alt_dcs);
02521
02522 tmp_string = http_cgi_variable(args, "mwi");
02523 if(tmp_string != NULL)
02524 sscanf(octstr_get_cstr(tmp_string),"%d", &mwi);
02525
02526 tmp_string = http_cgi_variable(args, "coding");
02527 if(tmp_string != NULL)
02528 sscanf(octstr_get_cstr(tmp_string),"%d", &coding);
02529
02530 tmp_string = http_cgi_variable(args, "compress");
02531 if(tmp_string != NULL)
02532 sscanf(octstr_get_cstr(tmp_string),"%d", &compress);
02533
02534 tmp_string = http_cgi_variable(args, "validity");
02535 if(tmp_string != NULL)
02536 sscanf(octstr_get_cstr(tmp_string),"%d", &validity);
02537
02538 tmp_string = http_cgi_variable(args, "deferred");
02539 if(tmp_string != NULL)
02540 sscanf(octstr_get_cstr(tmp_string),"%d", &deferred);
02541
02542 tmp_string = http_cgi_variable(args, "priority");
02543 if(tmp_string != NULL)
02544 sscanf(octstr_get_cstr(tmp_string),"%d", &priority);
02545
02546
02547
02548
02549 if (to == NULL) {
02550 error(0, "%s got insufficient headers (<to> is NULL)",
02551 octstr_get_cstr(sendsms_url));
02552 *status = HTTP_BAD_REQUEST;
02553 return octstr_create("Missing receiver number, rejected");
02554 }
02555 else if (octstr_len(to) == 0) {
02556 error(0, "%s got empty <to> cgi variable", octstr_get_cstr(sendsms_url));
02557 *status = HTTP_BAD_REQUEST;
02558 return octstr_create("Empty receiver number not allowed, rejected");
02559 }
02560
02561 return smsbox_req_handle(t, client_ip, client, from, to, text, charset, udh,
02562 smsc, mclass, mwi, coding, compress, validity,
02563 deferred, status, dlr_mask, dlr_url, account,
02564 pid, alt_dcs, rpi, NULL, binfo, priority);
02565
02566 }
02567
02568
02569
02570
02571
02572
02573 static Octstr *smsbox_sendsms_post(List *headers, Octstr *body,
02574 Octstr *client_ip, int *status,
02575 HTTPClient *client)
02576 {
02577 URLTranslation *t = NULL;
02578 Octstr *user, *pass, *ret, *type;
02579 List *tolist;
02580 Octstr *text_html, *text_plain, *text_wml, *text_xml, *octet_stream;
02581 Octstr *text;
02582 Octstr *from, *to, *udh, *smsc, *charset, *dlr_url, *account, *binfo;
02583 int dlr_mask, mclass, mwi, coding, compress, validity, deferred;
02584 int pid, alt_dcs, rpi, priority;
02585
02586 text_html = octstr_imm("text/html");
02587 text_wml = octstr_imm("text/vnd.wap.wml");
02588 text_plain = octstr_imm("text/plain");
02589 text_xml = octstr_imm("text/xml");
02590 octet_stream = octstr_imm("application/octet-stream");
02591
02592 user = pass = ret = type = NULL;
02593 tolist = NULL;
02594 from = to = udh = smsc = account = dlr_url = charset = binfo = NULL;
02595 mclass = mwi = coding = compress = validity = deferred = dlr_mask =
02596 pid = alt_dcs = rpi = priority = SMS_PARAM_UNDEFINED;
02597
02598 http_header_get_content_type(headers, &type, &charset);
02599 if (octstr_case_compare(type, text_html) == 0 ||
02600 octstr_case_compare(type, text_wml) == 0) {
02601 text = html_to_sms(body);
02602 octstr_strip_blanks(text);
02603 octstr_destroy(body);
02604 body = text;
02605 get_x_kannel_from_headers(headers, &from, &to, &udh,
02606 &user, &pass, &smsc, &mclass, &mwi,
02607 &coding, &compress, &validity,
02608 &deferred, &dlr_mask, &dlr_url,
02609 &account, &pid, &alt_dcs, &rpi,
02610 &binfo, &priority);
02611 } else if (octstr_case_compare(type, text_plain) == 0 ||
02612 octstr_case_compare(type, octet_stream) == 0) {
02613 get_x_kannel_from_headers(headers, &from, &to, &udh,
02614 &user, &pass, &smsc, &mclass, &mwi,
02615 &coding, &compress, &validity,
02616 &deferred, &dlr_mask, &dlr_url,
02617 &account, &pid, &alt_dcs, &rpi,
02618 &binfo, &priority);
02619 } else if (octstr_case_compare(type, text_xml) == 0) {
02620 get_x_kannel_from_xml(mt_push, &type, &body, headers,
02621 &from, &to, &udh, &user, &pass, &smsc, &mclass,
02622 &mwi, &coding, &compress, &validity, &deferred,
02623 &dlr_mask, &dlr_url, &account, &pid, &alt_dcs,
02624 &rpi, &tolist, &charset, &binfo, &priority);
02625 } else {
02626 *status = HTTP_BAD_REQUEST;
02627 ret = octstr_create("Invalid content-type");
02628 goto error;
02629 }
02630
02631 if (charset_processing(charset, body, coding) == -1) {
02632 *status = HTTP_BAD_REQUEST;
02633 ret = octstr_create("Invalid charset");
02634 goto error2;
02635 }
02636
02637
02638 t = authorise_username(user, pass, client_ip);
02639 if (t == NULL) {
02640 *status = HTTP_FORBIDDEN;
02641 ret = octstr_create("Authorization failed for sendsms");
02642 }
02643 else if (to == NULL && tolist == NULL) {
02644 error(0, "%s got insufficient headers (<to> and <tolist> are NULL)",
02645 octstr_get_cstr(sendsms_url));
02646 *status = HTTP_BAD_REQUEST;
02647 ret = octstr_create("Missing receiver(s) number(s), rejected");
02648 }
02649 else if (to != NULL && octstr_len(to) == 0) {
02650 error(0, "%s got empty <to> cgi variable", octstr_get_cstr(sendsms_url));
02651 *status = HTTP_BAD_REQUEST;
02652 return octstr_create("Empty receiver number not allowed, rejected");
02653 }
02654 else {
02655 if (octstr_case_compare(type,
02656 octstr_imm("application/octet-stream")) == 0) {
02657 if (coding == DC_UNDEF)
02658 coding = DC_8BIT;
02659 } else if (octstr_case_compare(type,
02660 octstr_imm("text/plain")) == 0) {
02661 if (coding == DC_UNDEF)
02662 coding = DC_7BIT;
02663 } else {
02664 error(0, "%s got weird content type %s", octstr_get_cstr(sendsms_url),
02665 octstr_get_cstr(type));
02666 *status = HTTP_UNSUPPORTED_MEDIA_TYPE;
02667 ret = octstr_create("Unsupported content-type, rejected");
02668 }
02669
02670 if (ret == NULL)
02671 ret = smsbox_req_handle(t, client_ip, client, from, to, body, charset,
02672 udh, smsc, mclass, mwi, coding, compress,
02673 validity, deferred, status, dlr_mask,
02674 dlr_url, account, pid, alt_dcs, rpi, tolist,
02675 binfo, priority);
02676
02677 }
02678 error2:
02679 octstr_destroy(user);
02680 octstr_destroy(pass);
02681 octstr_destroy(from);
02682 octstr_destroy(to);
02683 octstr_destroy(udh);
02684 octstr_destroy(smsc);
02685 octstr_destroy(dlr_url);
02686 octstr_destroy(account);
02687 octstr_destroy(binfo);
02688 error:
02689 octstr_destroy(type);
02690 octstr_destroy(charset);
02691 return ret;
02692 }
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706 static Octstr *smsbox_xmlrpc_post(List *headers, Octstr *body,
02707 Octstr *client_ip, int *status)
02708 {
02709 Octstr *ret, *type, *user, *pass;
02710 Octstr *from, *to, *udh, *smsc, *charset, *dlr_url, *account, *binfo;
02711 Octstr *output;
02712 Octstr *method_name;
02713 XMLRPCDocument *msg;
02714
02715 int dlr_mask, mclass, mwi, coding, compress, validity,
02716 deferred, pid, alt_dcs, rpi;
02717
02718 from = to = udh = smsc = account = dlr_url = charset = binfo = NULL;
02719 mclass = mwi = coding = compress = validity = deferred = dlr_mask =
02720 pid = alt_dcs = rpi = -1;
02721
02722 user = pass = ret = NULL;
02723
02724
02725
02726
02727 http_header_get_content_type(headers, &type, &charset);
02728 if (octstr_case_compare(type, octstr_imm("text/xml")) != 0) {
02729 error(0, "Unsupported content-type '%s'", octstr_get_cstr(type));
02730 *status = HTTP_BAD_REQUEST;
02731 ret = octstr_format("Unsupported content-type '%s'", octstr_get_cstr(type));
02732 } else {
02733
02734
02735
02736
02737
02738 msg = xmlrpc_parse_call(body);
02739
02740 if ((xmlrpc_parse_status(msg) != XMLRPC_COMPILE_OK) &&
02741 ((output = xmlrpc_parse_error(msg)) != NULL)) {
02742
02743 error(0, "%s", octstr_get_cstr(output));
02744 *status = HTTP_BAD_REQUEST;
02745 ret = octstr_format("%s", octstr_get_cstr(output));
02746 octstr_destroy(output);
02747 } else {
02748
02749
02750
02751
02752
02753 if (octstr_case_compare((method_name = xmlrpc_get_call_name(msg)),
02754 octstr_imm("sms.send")) != 0) {
02755 error(0, "Unknown method name '%s'", octstr_get_cstr(method_name));
02756 *status = HTTP_BAD_REQUEST;
02757 ret = octstr_format("Unkown method name '%s'",
02758 octstr_get_cstr(method_name));
02759 } else {
02760
02761
02762
02763
02764
02765 }
02766 }
02767
02768 xmlrpc_destroy_call(msg);
02769 }
02770
02771 return ret;
02772 }
02773
02774
02775
02776
02777
02778
02779
02780
02781 static Octstr *smsbox_req_sendota(List *list, Octstr *client_ip, int *status,
02782 HTTPClient *client)
02783 {
02784 Octstr *id, *from, *phonenumber, *smsc, *ota_doc, *doc_type, *account;
02785 CfgGroup *grp;
02786 Octstr *returnerror;
02787 Octstr *stored_uuid = NULL;
02788 List *grplist;
02789 Octstr *p;
02790 URLTranslation *t;
02791 Msg *msg;
02792 int ret, ota_type;
02793
02794 id = phonenumber = smsc = account = NULL;
02795
02796
02797 t = authorise_user(list, client_ip);
02798 if (t == NULL) {
02799 *status = HTTP_FORBIDDEN;
02800 return octstr_create("Authorization failed for sendota");
02801 }
02802
02803 if ((phonenumber = http_cgi_variable(list, "to")) == NULL) {
02804 if ((phonenumber = http_cgi_variable(list, "phonenumber")) == NULL) {
02805 error(0, "%s needs a valid phone number.", octstr_get_cstr(sendota_url));
02806 *status = HTTP_BAD_REQUEST;
02807 return octstr_create("Wrong sendota args.");
02808 }
02809 }
02810
02811 if (urltrans_faked_sender(t) != NULL) {
02812 from = octstr_duplicate(urltrans_faked_sender(t));
02813 } else if ((from = http_cgi_variable(list, "from")) != NULL &&
02814 octstr_len(from) > 0) {
02815 from = octstr_duplicate(from);
02816 } else if (urltrans_default_sender(t) != NULL) {
02817 from = octstr_duplicate(urltrans_default_sender(t));
02818 } else if (global_sender != NULL) {
02819 from = octstr_duplicate(global_sender);
02820 } else {
02821 *status = HTTP_BAD_REQUEST;
02822 return octstr_create("Sender missing and no global set, rejected");
02823 }
02824
02825
02826 if ((ota_doc = http_cgi_variable(list, "text")) != NULL) {
02827 Octstr *sec, *pin;
02828
02829
02830
02831
02832 debug("sms", 0, "OTA service with XML document");
02833 ota_doc = octstr_duplicate(ota_doc);
02834 if ((doc_type = http_cgi_variable(list, "type")) == NULL)
02835 doc_type = octstr_format("%s", "settings");
02836 else
02837 doc_type = octstr_duplicate(doc_type);
02838 if ((sec = http_cgi_variable(list, "sec")) == NULL)
02839 sec = octstr_create("USERPIN");
02840 else
02841 sec = octstr_duplicate(sec);
02842 if ((pin = http_cgi_variable(list, "pin")) == NULL)
02843 pin = octstr_create("12345");
02844 else
02845 pin = octstr_duplicate(pin);
02846
02847 if ((ret = ota_pack_message(&msg, ota_doc, doc_type, from,
02848 phonenumber, sec, pin)) < 0) {
02849 *status = HTTP_BAD_REQUEST;
02850 msg_destroy(msg);
02851 if (ret == -2)
02852 return octstr_create("Erroneous document type, cannot"
02853 " compile\n");
02854 else if (ret == -1)
02855 return octstr_create("Erroneous ota source, cannot compile\n");
02856 }
02857
02858 goto send;
02859
02860 } else {
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871 id = http_cgi_variable(list, "otaid");
02872
02873 grplist = cfg_get_multi_group(cfg, octstr_imm("ota-setting"));
02874 while (grplist && (grp = gwlist_extract_first(grplist)) != NULL) {
02875 p = cfg_get(grp, octstr_imm("ota-id"));
02876 if (id == NULL || (p != NULL && octstr_compare(p, id) == 0)) {
02877 ota_type = 1;
02878 goto found;
02879 }
02880 octstr_destroy(p);
02881 }
02882 gwlist_destroy(grplist, NULL);
02883
02884 grplist = cfg_get_multi_group(cfg, octstr_imm("ota-bookmark"));
02885 while (grplist && (grp = gwlist_extract_first(grplist)) != NULL) {
02886 p = cfg_get(grp, octstr_imm("ota-id"));
02887 if (id == NULL || (p != NULL && octstr_compare(p, id) == 0)) {
02888 ota_type = 0;
02889 goto found;
02890 }
02891 octstr_destroy(p);
02892 }
02893 gwlist_destroy(grplist, NULL);
02894
02895 if (id != NULL)
02896 error(0, "%s can't find any ota-setting or ota-bookmark group with ota-id '%s'.",
02897 octstr_get_cstr(sendota_url), octstr_get_cstr(id));
02898 else
02899 error(0, "%s can't find any ota-setting group.", octstr_get_cstr(sendota_url));
02900 octstr_destroy(from);
02901 *status = HTTP_BAD_REQUEST;
02902 return octstr_create("Missing ota-setting or ota-bookmark group.");
02903 }
02904
02905 found:
02906 octstr_destroy(p);
02907 gwlist_destroy(grplist, NULL);
02908
02909
02910 if (ota_type)
02911 msg = ota_tokenize_settings(grp, from, phonenumber);
02912 else
02913 msg = ota_tokenize_bookmarks(grp, from, phonenumber);
02914
02915 send:
02916
02917 smsc = http_cgi_variable(list, "smsc");
02918 if (urltrans_forced_smsc(t)) {
02919 msg->sms.smsc_id = octstr_duplicate(urltrans_forced_smsc(t));
02920 if (smsc)
02921 info(0, "send-sms request smsc id ignored, as smsc id forced to %s",
02922 octstr_get_cstr(urltrans_forced_smsc(t)));
02923 } else if (smsc) {
02924 msg->sms.smsc_id = octstr_duplicate(smsc);
02925 } else if (urltrans_default_smsc(t)) {
02926 msg->sms.smsc_id = octstr_duplicate(urltrans_default_smsc(t));
02927 } else
02928 msg->sms.smsc_id = NULL;
02929
02930 account = http_cgi_variable(list, "account");
02931 if (octstr_len(account) > 0)
02932 msg->sms.account = octstr_duplicate(account);
02933
02934 octstr_dump(msg->sms.msgdata, 0);
02935
02936 info(0, "%s <%s> <%s>", octstr_get_cstr(sendota_url),
02937 id ? octstr_get_cstr(id) : "<default>", octstr_get_cstr(phonenumber));
02938
02939 if (!immediate_sendsms_reply) {
02940 stored_uuid = store_uuid(msg);
02941 dict_put(client_dict, stored_uuid, client);
02942 }
02943
02944 ret = send_message(t, msg);
02945
02946 if (ret == -1) {
02947 error(0, "sendota_request: failed");
02948 *status = HTTP_INTERNAL_SERVER_ERROR;
02949 returnerror = octstr_create("Sending failed.");
02950 dict_remove(client_dict, stored_uuid);
02951 } else {
02952 *status = HTTP_ACCEPTED;
02953 returnerror = octstr_create("Sent.");
02954 }
02955
02956 msg_destroy(msg);
02957 octstr_destroy(stored_uuid);
02958
02959 return returnerror;
02960 }
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971 static Octstr *smsbox_sendota_post(List *headers, Octstr *body,
02972 Octstr *client_ip, int *status,
02973 HTTPClient *client)
02974 {
02975 Octstr *name, *val, *ret;
02976 Octstr *from, *to, *id, *user, *pass, *smsc;
02977 Octstr *type, *charset, *doc_type, *ota_doc, *sec, *pin;
02978 Octstr *stored_uuid = NULL;
02979 URLTranslation *t;
02980 Msg *msg;
02981 long l;
02982 int r;
02983
02984 id = from = to = user = pass = smsc = NULL;
02985 doc_type = ota_doc = sec = pin = NULL;
02986
02987
02988
02989
02990
02991
02992
02993 for (l = 0; l < gwlist_len(headers); l++) {
02994 http_header_get(headers, l, &name, &val);
02995
02996 if (octstr_case_compare(name, octstr_imm("X-Kannel-OTA-ID")) == 0) {
02997 id = octstr_duplicate(val);
02998 octstr_strip_blanks(id);
02999 }
03000 else if (octstr_case_compare(name, octstr_imm("X-Kannel-From")) == 0) {
03001 from = octstr_duplicate(val);
03002 octstr_strip_blanks(from);
03003 }
03004 else if (octstr_case_compare(name, octstr_imm("X-Kannel-To")) == 0) {
03005 to = octstr_duplicate(val);
03006 octstr_strip_blanks(to);
03007 }
03008 else if (octstr_case_compare(name, octstr_imm("X-Kannel-Username")) == 0) {
03009 user = octstr_duplicate(val);
03010 octstr_strip_blanks(user);
03011 }
03012 else if (octstr_case_compare(name, octstr_imm("X-Kannel-Password")) == 0) {
03013 pass = octstr_duplicate(val);
03014 octstr_strip_blanks(pass);
03015 }
03016 else if (octstr_case_compare(name, octstr_imm("X-Kannel-SMSC")) == 0) {
03017 smsc = octstr_duplicate(val);
03018 octstr_strip_blanks(smsc);
03019 }
03020 else if (octstr_case_compare(name, octstr_imm("X-Kannel-SEC")) == 0) {
03021 sec = octstr_duplicate(val);
03022 octstr_strip_blanks(sec);
03023 }
03024 else if (octstr_case_compare(name, octstr_imm("X-Kannel-PIN")) == 0) {
03025 pin = octstr_duplicate(val);
03026 octstr_strip_blanks(pin);
03027 }
03028 }
03029
03030
03031 if (!sec)
03032 sec = octstr_imm("USERPIN");
03033 if (!pin)
03034 pin = octstr_imm("1234");
03035
03036
03037 t = authorise_username(user, pass, client_ip);
03038 if (t == NULL) {
03039 *status = HTTP_FORBIDDEN;
03040 ret = octstr_create("Authorization failed for sendota");
03041 }
03042
03043 else if (to == NULL) {
03044 error(0, "%s needs a valid phone number.", octstr_get_cstr(sendota_url));
03045 *status = HTTP_BAD_REQUEST;
03046 ret = octstr_create("Wrong sendota args.");
03047 } else {
03048
03049 if (urltrans_faked_sender(t) != NULL) {
03050 from = octstr_duplicate(urltrans_faked_sender(t));
03051 }
03052 else if (from != NULL && octstr_len(from) > 0) {
03053 }
03054 else if (urltrans_default_sender(t) != NULL) {
03055 from = octstr_duplicate(urltrans_default_sender(t));
03056 }
03057 else if (global_sender != NULL) {
03058 from = octstr_duplicate(global_sender);
03059 }
03060 else {
03061 *status = HTTP_BAD_REQUEST;
03062 ret = octstr_create("Sender missing and no global set, rejected");
03063 goto error;
03064 }
03065
03066
03067
03068
03069 http_header_get_content_type(headers, &type, &charset);
03070
03071 if (octstr_case_compare(type,
03072 octstr_imm("application/x-wap-prov.browser-settings")) == 0) {
03073 doc_type = octstr_format("%s", "settings");
03074 }
03075 else if (octstr_case_compare(type,
03076 octstr_imm("application/x-wap-prov.browser-bookmarks")) == 0) {
03077 doc_type = octstr_format("%s", "bookmarks");
03078 }
03079 else if (octstr_case_compare(type,
03080 octstr_imm("text/vnd.wap.connectivity-xml")) == 0) {
03081 doc_type = octstr_format("%s", "oma-settings");
03082 }
03083
03084 if (doc_type == NULL) {
03085 error(0, "%s got weird content type %s", octstr_get_cstr(sendota_url),
03086 octstr_get_cstr(type));
03087 *status = HTTP_UNSUPPORTED_MEDIA_TYPE;
03088 ret = octstr_create("Unsupported content-type, rejected");
03089 } else {
03090
03091
03092
03093
03094
03095 ota_doc = octstr_duplicate(body);
03096
03097 if ((r = ota_pack_message(&msg, ota_doc, doc_type, from, to, sec, pin)) < 0) {
03098 *status = HTTP_BAD_REQUEST;
03099 msg_destroy(msg);
03100 if (r == -2) {
03101 ret = octstr_create("Erroneous document type, cannot"
03102 " compile\n");
03103 goto error;
03104 }
03105 else if (r == -1) {
03106 ret = octstr_create("Erroneous ota source, cannot compile\n");
03107 goto error;
03108 }
03109 }
03110
03111
03112 if (urltrans_forced_smsc(t)) {
03113 msg->sms.smsc_id = octstr_duplicate(urltrans_forced_smsc(t));
03114 if (smsc)
03115 info(0, "send-sms request smsc id ignored, as smsc id forced to %s",
03116 octstr_get_cstr(urltrans_forced_smsc(t)));
03117 } else if (smsc) {
03118 msg->sms.smsc_id = octstr_duplicate(smsc);
03119 } else if (urltrans_default_smsc(t)) {
03120 msg->sms.smsc_id = octstr_duplicate(urltrans_default_smsc(t));
03121 } else
03122 msg->sms.smsc_id = NULL;
03123
03124 info(0, "%s <%s> <%s>", octstr_get_cstr(sendota_url),
03125 id ? octstr_get_cstr(id) : "XML", octstr_get_cstr(to));
03126
03127
03128 if (!immediate_sendsms_reply) {
03129 stored_uuid = store_uuid(msg);
03130 dict_put(client_dict, stored_uuid, client);
03131 }
03132
03133 r = send_message(t, msg);
03134
03135 if (r == -1) {
03136 error(0, "sendota_request: failed");
03137 *status = HTTP_INTERNAL_SERVER_ERROR;
03138 ret = octstr_create("Sending failed.");
03139 if (!immediate_sendsms_reply)
03140 dict_remove(client_dict, stored_uuid);
03141 } else {
03142 *status = HTTP_ACCEPTED;
03143 ret = octstr_create("Sent.");
03144 }
03145
03146 msg_destroy(msg);
03147 octstr_destroy(stored_uuid);
03148
03149 }
03150 }
03151
03152 error:
03153 octstr_destroy(user);
03154 octstr_destroy(pass);
03155 octstr_destroy(smsc);
03156
03157 return ret;
03158 }
03159
03160
03161 static void sendsms_thread(void *arg)
03162 {
03163 HTTPClient *client;
03164 Octstr *ip, *url, *body, *answer;
03165 List *hdrs, *args;
03166 int status;
03167
03168 for (;;) {
03169 client = http_accept_request(sendsms_port, &ip, &url, &hdrs, &body,
03170 &args);
03171 if (client == NULL)
03172 break;
03173
03174 info(0, "smsbox: Got HTTP request <%s> from <%s>",
03175 octstr_get_cstr(url), octstr_get_cstr(ip));
03176
03177
03178
03179
03180
03181
03182
03183 if (octstr_compare(url, sendsms_url) == 0)
03184 {
03185
03186
03187
03188
03189 if (body == NULL)
03190 answer = smsbox_req_sendsms(args, ip, &status, client);
03191 else
03192 answer = smsbox_sendsms_post(hdrs, body, ip, &status, client);
03193 }
03194
03195 else if (octstr_compare(url, xmlrpc_url) == 0)
03196 {
03197
03198
03199
03200 if (body == NULL) {
03201 answer = octstr_create("Incomplete request.");
03202 status = HTTP_BAD_REQUEST;
03203 } else
03204 answer = smsbox_xmlrpc_post(hdrs, body, ip, &status);
03205 }
03206
03207 else if (octstr_compare(url, sendota_url) == 0)
03208 {
03209 if (body == NULL)
03210 answer = smsbox_req_sendota(args, ip, &status, client);
03211 else
03212 answer = smsbox_sendota_post(hdrs, body, ip, &status, client);
03213 }
03214
03215 else {
03216 answer = octstr_create("Unknown request.");
03217 status = HTTP_NOT_FOUND;
03218 }
03219
03220 debug("sms.http", 0, "Status: %d Answer: <%s>", status,
03221 octstr_get_cstr(answer));
03222
03223 octstr_destroy(ip);
03224 octstr_destroy(url);
03225 http_destroy_headers(hdrs);
03226 octstr_destroy(body);
03227 http_destroy_cgiargs(args);
03228
03229 if (immediate_sendsms_reply || status != HTTP_ACCEPTED)
03230 http_send_reply(client, status, sendsms_reply_hdrs, answer);
03231 else {
03232 debug("sms.http", 0, "Delayed reply - wait for bearerbox");
03233 }
03234 octstr_destroy(answer);
03235 }
03236
03237 }
03238
03239
03240
03241
03242
03243
03244 static void signal_handler(int signum) {
03245
03246
03247
03248
03249
03250 if (!gwthread_shouldhandlesignal(signum))
03251 return;
03252
03253 switch (signum) {
03254 case SIGINT:
03255
03256 if (program_status != shutting_down) {
03257 error(0, "SIGINT received, aborting program...");
03258 program_status = shutting_down;
03259 }
03260 break;
03261
03262 case SIGHUP:
03263 warning(0, "SIGHUP received, catching and re-opening logs");
03264 log_reopen();
03265 alog_reopen();
03266 break;
03267
03268
03269
03270
03271
03272 case SIGQUIT:
03273 warning(0, "SIGQUIT received, reporting memory usage.");
03274 gw_check_leaks();
03275 break;
03276 }
03277 }
03278
03279
03280 static void setup_signal_handlers(void) {
03281 struct sigaction act;
03282
03283 act.sa_handler = signal_handler;
03284 sigemptyset(&act.sa_mask);
03285 act.sa_flags = 0;
03286 sigaction(SIGINT, &act, NULL);
03287 sigaction(SIGQUIT, &act, NULL);
03288 sigaction(SIGHUP, &act, NULL);
03289 sigaction(SIGPIPE, &act, NULL);
03290 }
03291
03292
03293
03294 static Cfg *init_smsbox(Cfg *cfg)
03295 {
03296 CfgGroup *grp;
03297 Octstr *logfile;
03298 Octstr *p;
03299 long lvl;
03300 Octstr *http_proxy_host = NULL;
03301 long http_proxy_port = -1;
03302 int http_proxy_ssl = 0;
03303 List *http_proxy_exceptions = NULL;
03304 Octstr *http_proxy_username = NULL;
03305 Octstr *http_proxy_password = NULL;
03306 Octstr *http_proxy_exceptions_regex = NULL;
03307 int ssl = 0;
03308 int lf, m;
03309 long max_req;
03310
03311 bb_port = BB_DEFAULT_SMSBOX_PORT;
03312 bb_ssl = 0;
03313 bb_host = octstr_create(BB_DEFAULT_HOST);
03314 logfile = NULL;
03315 lvl = 0;
03316 lf = m = 1;
03317
03318
03319
03320
03321
03322
03323 grp = cfg_get_single_group(cfg, octstr_imm("core"));
03324
03325 cfg_get_integer(&bb_port, grp, octstr_imm("smsbox-port"));
03326 #ifdef HAVE_LIBSSL
03327 cfg_get_bool(&bb_ssl, grp, octstr_imm("smsbox-port-ssl"));
03328 #endif
03329
03330 cfg_get_integer(&http_proxy_port, grp, octstr_imm("http-proxy-port"));
03331 #ifdef HAVE_LIBSSL
03332 cfg_get_bool(&http_proxy_ssl, grp, octstr_imm("http-proxy-ssl"));
03333 #endif
03334
03335 http_proxy_host = cfg_get(grp,
03336 octstr_imm("http-proxy-host"));
03337 http_proxy_username = cfg_get(grp,
03338 octstr_imm("http-proxy-username"));
03339 http_proxy_password = cfg_get(grp,
03340 octstr_imm("http-proxy-password"));
03341 http_proxy_exceptions = cfg_get_list(grp,
03342 octstr_imm("http-proxy-exceptions"));
03343 http_proxy_exceptions_regex = cfg_get(grp,
03344 octstr_imm("http-proxy-exceptions-regex"));
03345
03346 #ifdef HAVE_LIBSSL
03347 conn_config_ssl(grp);
03348 #endif
03349
03350
03351
03352
03353 grp = cfg_get_single_group(cfg, octstr_imm("smsbox"));
03354 if (grp == NULL)
03355 panic(0, "No 'smsbox' group in configuration");
03356
03357 smsbox_id = cfg_get(grp, octstr_imm("smsbox-id"));
03358
03359 p = cfg_get(grp, octstr_imm("bearerbox-host"));
03360 if (p != NULL) {
03361 octstr_destroy(bb_host);
03362 bb_host = p;
03363 }
03364 cfg_get_integer(&bb_port, grp, octstr_imm("bearerbox-port"));
03365 #ifdef HAVE_LIBSSL
03366 if (cfg_get_bool(&ssl, grp, octstr_imm("bearerbox-port-ssl")) != -1)
03367 bb_ssl = ssl;
03368 #endif
03369
03370 cfg_get_bool(&mo_recode, grp, octstr_imm("mo-recode"));
03371 if(mo_recode < 0)
03372 mo_recode = 0;
03373
03374 reply_couldnotfetch= cfg_get(grp, octstr_imm("reply-couldnotfetch"));
03375 if (reply_couldnotfetch == NULL)
03376 reply_couldnotfetch = octstr_create("Could not fetch content, sorry.");
03377
03378 reply_couldnotrepresent= cfg_get(grp, octstr_imm("reply-couldnotfetch"));
03379 if (reply_couldnotrepresent == NULL)
03380 reply_couldnotrepresent = octstr_create("Result could not be represented "
03381 "as an SMS message.");
03382 reply_requestfailed= cfg_get(grp, octstr_imm("reply-requestfailed"));
03383 if (reply_requestfailed == NULL)
03384 reply_requestfailed = octstr_create("Request Failed");
03385
03386 reply_emptymessage= cfg_get(grp, octstr_imm("reply-emptymessage"));
03387 if (reply_emptymessage == NULL)
03388 reply_emptymessage = octstr_create("<Empty reply from service provider>");
03389
03390 {
03391 Octstr *os;
03392 os = cfg_get(grp, octstr_imm("white-list"));
03393 if (os != NULL) {
03394 white_list = numhash_create(octstr_get_cstr(os));
03395 octstr_destroy(os);
03396 }
03397
03398 os = cfg_get(grp, octstr_imm("white-list-regex"));
03399 if (os != NULL) {
03400 if ((white_list_regex = gw_regex_comp(os, REG_EXTENDED)) == NULL)
03401 panic(0, "Could not compile pattern '%s'", octstr_get_cstr(os));
03402 octstr_destroy(os);
03403 }
03404
03405 os = cfg_get(grp, octstr_imm("black-list"));
03406 if (os != NULL) {
03407 black_list = numhash_create(octstr_get_cstr(os));
03408 octstr_destroy(os);
03409 }
03410 os = cfg_get(grp, octstr_imm("black-list-regex"));
03411 if (os != NULL) {
03412 if ((black_list_regex = gw_regex_comp(os, REG_EXTENDED)) == NULL)
03413 panic(0, "Could not compile pattern '%s'", octstr_get_cstr(os));
03414 octstr_destroy(os);
03415 }
03416 }
03417
03418 cfg_get_integer(&sendsms_port, grp, octstr_imm("sendsms-port"));
03419
03420
03421 sendsms_interface = cfg_get(grp, octstr_imm("sendsms-interface"));
03422
03423 cfg_get_integer(&sms_max_length, grp, octstr_imm("sms-length"));
03424
03425 #ifdef HAVE_LIBSSL
03426 cfg_get_bool(&ssl, grp, octstr_imm("sendsms-port-ssl"));
03427 #endif
03428
03429
03430
03431
03432
03433 if ((sendsms_url = cfg_get(grp, octstr_imm("sendsms-url"))) == NULL)
03434 sendsms_url = octstr_imm("/cgi-bin/sendsms");
03435 if ((xmlrpc_url = cfg_get(grp, octstr_imm("xmlrpc-url"))) == NULL)
03436 xmlrpc_url = octstr_imm("/cgi-bin/xmlrpc");
03437 if ((sendota_url = cfg_get(grp, octstr_imm("sendota-url"))) == NULL)
03438 sendota_url = octstr_imm("/cgi-bin/sendota");
03439
03440 global_sender = cfg_get(grp, octstr_imm("global-sender"));
03441 accepted_chars = cfg_get(grp, octstr_imm("sendsms-chars"));
03442 sendsms_number_chars = accepted_chars ?
03443 octstr_get_cstr(accepted_chars) : SENDSMS_DEFAULT_CHARS;
03444 logfile = cfg_get(grp, octstr_imm("log-file"));
03445
03446 cfg_get_integer(&lvl, grp, octstr_imm("log-level"));
03447
03448 if (logfile != NULL) {
03449 info(0, "Starting to log to file %s level %ld",
03450 octstr_get_cstr(logfile), lvl);
03451 log_open(octstr_get_cstr(logfile), lvl, GW_NON_EXCL);
03452 octstr_destroy(logfile);
03453 }
03454 if (global_sender != NULL) {
03455 info(0, "Service global sender set as '%s'",
03456 octstr_get_cstr(global_sender));
03457 }
03458
03459
03460 cfg_get_bool(&immediate_sendsms_reply, grp, octstr_imm("immediate-sendsms-reply"));
03461
03462
03463 if ((p = cfg_get(grp, octstr_imm("access-log-time"))) != NULL) {
03464 lf = (octstr_case_compare(p, octstr_imm("gmt")) == 0) ? 0 : 1;
03465 octstr_destroy(p);
03466 }
03467
03468
03469 cfg_get_bool(&m, grp, octstr_imm("access-log-clean"));
03470
03471
03472 if ((p = cfg_get(grp, octstr_imm("access-log"))) != NULL) {
03473 info(0, "Logging accesses to '%s'.", octstr_get_cstr(p));
03474 alog_open(octstr_get_cstr(p), lf, m ? 0 : 1);
03475 octstr_destroy(p);
03476 }
03477
03478
03479 cfg_get_integer(&max_http_retries, grp, octstr_imm("http-request-retry"));
03480 cfg_get_integer(&http_queue_delay, grp, octstr_imm("http-queue-delay"));
03481
03482 if (sendsms_port > 0) {
03483 if (http_open_port_if(sendsms_port, ssl, sendsms_interface) == -1) {
03484 if (only_try_http)
03485 error(0, "Failed to open HTTP socket, ignoring it");
03486 else
03487 panic(0, "Failed to open HTTP socket");
03488 } else {
03489 info(0, "Set up send sms service at port %ld", sendsms_port);
03490 gwthread_create(sendsms_thread, NULL);
03491 }
03492 }
03493
03494
03495 if (cfg_get_integer(&max_req, grp, octstr_imm("max-pending-requests")) == -1)
03496 max_req = HTTP_MAX_PENDING;
03497 max_pending_requests = semaphore_create(max_req);
03498
03499
03500
03501
03502 if ((grp = cfg_get_single_group(cfg, octstr_imm("ppg"))) != NULL) {
03503 if ((ppg_service_name = cfg_get(grp, octstr_imm("service-name"))) == NULL)
03504 ppg_service_name = octstr_create("ppg");
03505 }
03506
03507 if (http_proxy_host != NULL && http_proxy_port > 0) {
03508 http_use_proxy(http_proxy_host, http_proxy_port, http_proxy_ssl,
03509 http_proxy_exceptions, http_proxy_username,
03510 http_proxy_password, http_proxy_exceptions_regex);
03511 }
03512
03513 octstr_destroy(http_proxy_host);
03514 octstr_destroy(http_proxy_username);
03515 octstr_destroy(http_proxy_password);
03516 octstr_destroy(http_proxy_exceptions_regex);
03517 gwlist_destroy(http_proxy_exceptions, octstr_destroy_item);
03518
03519 return cfg;
03520 }
03521
03522
03523 static int check_args(int i, int argc, char **argv) {
03524 if (strcmp(argv[i], "-H")==0 || strcmp(argv[i], "--tryhttp")==0) {
03525 only_try_http = 1;
03526 } else
03527 return -1;
03528
03529 return 0;
03530 }
03531
03532
03533 int main(int argc, char **argv)
03534 {
03535 int cf_index;
03536 Octstr *filename;
03537 double heartbeat_freq = DEFAULT_HEARTBEAT;
03538
03539 gwlib_init();
03540 cf_index = get_and_set_debugs(argc, argv, check_args);
03541
03542 setup_signal_handlers();
03543
03544 if (argv[cf_index] == NULL)
03545 filename = octstr_create("kannel.conf");
03546 else
03547 filename = octstr_create(argv[cf_index]);
03548 cfg = cfg_create(filename);
03549
03550 if (cfg_read(cfg) == -1)
03551 panic(0, "Couldn't read configuration from `%s'.", octstr_get_cstr(filename));
03552
03553 octstr_destroy(filename);
03554
03555 report_versions("smsbox");
03556
03557 init_smsbox(cfg);
03558
03559 if (max_http_retries > 0) {
03560 info(0, "Using HTTP request queueing with %ld retries, %lds delay.",
03561 max_http_retries, http_queue_delay);
03562 }
03563
03564 debug("sms", 0, "----------------------------------------------");
03565 debug("sms", 0, GW_NAME " smsbox version %s starting", GW_VERSION);
03566
03567 translations = urltrans_create();
03568 if (translations == NULL)
03569 panic(0, "urltrans_create failed");
03570 if (urltrans_add_cfg(translations, cfg) == -1)
03571 panic(0, "urltrans_add_cfg failed");
03572
03573 client_dict = dict_create(32, NULL);
03574 sendsms_reply_hdrs = http_create_empty_headers();
03575 http_header_add(sendsms_reply_hdrs, "Content-type", "text/html");
03576 http_header_add(sendsms_reply_hdrs, "Pragma", "no-cache");
03577 http_header_add(sendsms_reply_hdrs, "Cache-Control", "no-cache");
03578
03579
03580 caller = http_caller_create();
03581 smsbox_requests = gwlist_create();
03582 smsbox_http_requests = gwlist_create();
03583 gwlist_add_producer(smsbox_requests);
03584 gwlist_add_producer(smsbox_http_requests);
03585 num_outstanding_requests = counter_create();
03586 catenated_sms_counter = counter_create();
03587 gwthread_create(obey_request_thread, NULL);
03588 gwthread_create(url_result_thread, NULL);
03589 gwthread_create(http_queue_thread, NULL);
03590
03591 connect_to_bearerbox(bb_host, bb_port, bb_ssl, NULL );
03592
03593
03594 if (0 > heartbeat_start(write_to_bearerbox, heartbeat_freq,
03595 outstanding_requests)) {
03596 info(0, GW_NAME "Could not start heartbeat.");
03597 }
03598
03599 identify_to_bearerbox();
03600 read_messages_from_bearerbox();
03601
03602 info(0, GW_NAME " smsbox terminating.");
03603
03604 heartbeat_stop(ALL_HEARTBEATS);
03605 http_close_all_ports();
03606 gwthread_join_every(sendsms_thread);
03607 gwlist_remove_producer(smsbox_requests);
03608 gwlist_remove_producer(smsbox_http_requests);
03609 gwthread_join_every(obey_request_thread);
03610 http_caller_signal_shutdown(caller);
03611 gwthread_join_every(url_result_thread);
03612 gwthread_join_every(http_queue_thread);
03613
03614 close_connection_to_bearerbox();
03615 alog_close();
03616 urltrans_destroy(translations);
03617 gw_assert(gwlist_len(smsbox_requests) == 0);
03618 gw_assert(gwlist_len(smsbox_http_requests) == 0);
03619 gwlist_destroy(smsbox_requests, NULL);
03620 gwlist_destroy(smsbox_http_requests, NULL);
03621 http_caller_destroy(caller);
03622 counter_destroy(num_outstanding_requests);
03623 counter_destroy(catenated_sms_counter);
03624 octstr_destroy(bb_host);
03625 octstr_destroy(global_sender);
03626 octstr_destroy(accepted_chars);
03627 octstr_destroy(smsbox_id);
03628 octstr_destroy(sendsms_url);
03629 octstr_destroy(sendota_url);
03630 octstr_destroy(xmlrpc_url);
03631 octstr_destroy(reply_emptymessage);
03632 octstr_destroy(reply_requestfailed);
03633 octstr_destroy(reply_couldnotfetch);
03634 octstr_destroy(reply_couldnotrepresent);
03635 octstr_destroy(sendsms_interface);
03636 octstr_destroy(ppg_service_name);
03637 numhash_destroy(black_list);
03638 numhash_destroy(white_list);
03639 if (white_list_regex != NULL) gw_regex_destroy(white_list_regex);
03640 if (black_list_regex != NULL) gw_regex_destroy(black_list_regex);
03641 semaphore_destroy(max_pending_requests);
03642 cfg_destroy(cfg);
03643
03644 dict_destroy(client_dict);
03645 http_destroy_headers(sendsms_reply_hdrs);
03646
03647
03648
03649
03650
03651 if (restart) {
03652 gwthread_sleep(5.0);
03653 }
03654
03655 gwlib_shutdown();
03656
03657
03658 if (restart)
03659 execvp(argv[0], argv);
03660
03661 return 0;
03662 }
03663
03664 int charset_processing (Octstr *charset, Octstr *body, int coding) {
03665
03666 int resultcode = 0;
03667
03668 if (octstr_len(charset)) {
03669
03670
03671
03672 if (coding == DC_7BIT) {
03673
03674
03675
03676 if (charset_convert(body, octstr_get_cstr(charset), "UTF-8") < 0) {
03677 resultcode = -1;
03678 }
03679 } else if (coding == DC_UCS2) {
03680
03681
03682
03683 if (charset_convert(body, octstr_get_cstr(charset), "UTF-16BE") < 0) {
03684 resultcode = -1;
03685 }
03686 }
03687
03688
03689
03690 }
03691
03692 return resultcode;
03693 }
03694
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.