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
00062
00063
00064 #include <ctype.h>
00065 #include <errno.h>
00066 #include <limits.h>
00067 #include <stdlib.h>
00068 #include <string.h>
00069 #include <time.h>
00070
00071 #include "urltrans.h"
00072 #include "gwlib/gwlib.h"
00073 #include "gw/sms.h"
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 struct URLTranslation {
00087 int type;
00088 Octstr *pattern;
00089 Octstr *prefix;
00090 Octstr *suffix;
00091 Octstr *faked_sender;
00092 Octstr *default_sender;
00093 long max_messages;
00094 int concatenation;
00095 Octstr *split_chars;
00096 Octstr *split_suffix;
00097 int omit_empty;
00098 Octstr *header;
00099 Octstr *footer;
00100 List *accepted_smsc;
00101
00102 List *accepted_account;
00103
00104
00105 Octstr *name;
00106 Octstr *username;
00107 Octstr *password;
00108 Octstr *forced_smsc;
00109 Octstr *default_smsc;
00110 Octstr *allow_ip;
00111
00112 Octstr *deny_ip;
00113 Octstr *allowed_prefix;
00114 Octstr *denied_prefix;
00115 Octstr *allowed_recv_prefix;
00116 Octstr *denied_recv_prefix;
00117 Numhash *white_list;
00118 Numhash *black_list;
00119
00120 int assume_plain_text;
00121 int accept_x_kannel_headers;
00122 int strip_keyword;
00123 int send_sender;
00124
00125 int args;
00126 int has_catchall_arg;
00127 int catch_all;
00128 Octstr *dlr_url;
00129
00130 regex_t *keyword_regex;
00131 regex_t *accepted_smsc_regex;
00132 regex_t *accepted_account_regex;
00133 regex_t *allowed_prefix_regex;
00134 regex_t *denied_prefix_regex;
00135 regex_t *allowed_receiver_prefix_regex;
00136 regex_t *denied_receiver_prefix_regex;
00137 regex_t *white_list_regex;
00138 regex_t *black_list_regex;
00139 };
00140
00141
00142
00143
00144
00145 struct URLTranslationList {
00146 List *list;
00147 List *defaults;
00148 Dict *names;
00149 };
00150
00151
00152
00153
00154
00155
00156
00157 static long count_occurences(Octstr *str, Octstr *pat);
00158 static URLTranslation *create_onetrans(CfgGroup *grp);
00159 static void destroy_onetrans(void *ot);
00160 static URLTranslation *find_translation(URLTranslationList *trans, Msg *msg);
00161 static URLTranslation *find_default_translation(URLTranslationList *trans,
00162 Octstr *smsc, Octstr *sender, Octstr *receiver,
00163 Octstr *account);
00164
00165
00166
00167
00168
00169
00170
00171
00172 static void destroy_keyword_list(void *list)
00173 {
00174 gwlist_destroy(list, NULL);
00175 }
00176
00177
00178 URLTranslationList *urltrans_create(void)
00179 {
00180 URLTranslationList *trans;
00181
00182 trans = gw_malloc(sizeof(URLTranslationList));
00183 trans->list = gwlist_create();
00184 trans->defaults = gwlist_create();
00185 trans->names = dict_create(1024, destroy_keyword_list);
00186 return trans;
00187 }
00188
00189
00190 void urltrans_destroy(URLTranslationList *trans)
00191 {
00192 gwlist_destroy(trans->list, destroy_onetrans);
00193 gwlist_destroy(trans->defaults, destroy_onetrans);
00194 dict_destroy(trans->names);
00195 gw_free(trans);
00196 }
00197
00198
00199 int urltrans_add_one(URLTranslationList *trans, CfgGroup *grp)
00200 {
00201 URLTranslation *ot;
00202 List *list2;
00203
00204 ot = create_onetrans(grp);
00205 if (ot == NULL)
00206 return -1;
00207
00208 if (ot->type != TRANSTYPE_SENDSMS && ot->keyword_regex == NULL)
00209 gwlist_append(trans->defaults, ot);
00210 else
00211 gwlist_append(trans->list, ot);
00212
00213 list2 = dict_get(trans->names, ot->name);
00214 if (list2 == NULL) {
00215 list2 = gwlist_create();
00216 dict_put(trans->names, ot->name, list2);
00217 }
00218 gwlist_append(list2, ot);
00219
00220 return 0;
00221 }
00222
00223
00224 int urltrans_add_cfg(URLTranslationList *trans, Cfg *cfg)
00225 {
00226 CfgGroup *grp;
00227 List *list;
00228
00229 list = cfg_get_multi_group(cfg, octstr_imm("sms-service"));
00230 while (list && (grp = gwlist_extract_first(list)) != NULL) {
00231 if (urltrans_add_one(trans, grp) == -1) {
00232 gwlist_destroy(list, NULL);
00233 return -1;
00234 }
00235 }
00236 gwlist_destroy(list, NULL);
00237
00238 list = cfg_get_multi_group(cfg, octstr_imm("sendsms-user"));
00239 while (list && (grp = gwlist_extract_first(list)) != NULL) {
00240 if (urltrans_add_one(trans, grp) == -1) {
00241 gwlist_destroy(list, NULL);
00242 return -1;
00243 }
00244 }
00245 gwlist_destroy(list, NULL);
00246
00247 return 0;
00248 }
00249
00250
00251 URLTranslation *urltrans_find(URLTranslationList *trans, Msg *msg)
00252 {
00253 URLTranslation *t = NULL;
00254
00255 t = find_translation(trans, msg);
00256 if (t == NULL) {
00257 t = find_default_translation(trans, msg->sms.smsc_id, msg->sms.sender, msg->sms.receiver, msg->sms.account);
00258 }
00259
00260 return t;
00261 }
00262
00263
00264 URLTranslation *urltrans_find_service(URLTranslationList *trans, Msg *msg)
00265 {
00266 URLTranslation *t;
00267 List *list;
00268
00269 list = dict_get(trans->names, msg->sms.service);
00270 if (list != NULL) {
00271 t = gwlist_get(list, 0);
00272 } else {
00273 t = NULL;
00274 }
00275 return t;
00276 }
00277
00278
00279
00280 URLTranslation *urltrans_find_username(URLTranslationList *trans, Octstr *name)
00281 {
00282 URLTranslation *t;
00283 int i;
00284
00285 gw_assert(name != NULL);
00286 for (i = 0; i < gwlist_len(trans->list); ++i) {
00287 t = gwlist_get(trans->list, i);
00288 if (t->type == TRANSTYPE_SENDSMS) {
00289 if (octstr_compare(name, t->username) == 0)
00290 return t;
00291 }
00292 }
00293 return NULL;
00294 }
00295
00296
00297
00298
00299
00300 static void strip_keyword(Msg *request)
00301 {
00302 int ch;
00303 long pos;
00304
00305 pos = 0;
00306
00307 for (; (ch = octstr_get_char(request->sms.msgdata, pos)) >= 0; pos++)
00308 if (isspace(ch))
00309 break;
00310
00311 for (; (ch = octstr_get_char(request->sms.msgdata, pos)) >= 0; pos++)
00312 if (!isspace(ch))
00313 break;
00314
00315 octstr_delete(request->sms.msgdata, 0, pos);
00316 }
00317
00318
00319 Octstr *urltrans_fill_escape_codes(Octstr *pattern, Msg *request)
00320 {
00321 Octstr *enc;
00322 int nextarg, j;
00323 struct tm tm;
00324 int num_words;
00325 List *word_list;
00326 Octstr *result;
00327 long pattern_len;
00328 long pos;
00329 int c;
00330 long i;
00331 Octstr *temp;
00332
00333 result = octstr_create("");
00334
00335 if (request->sms.msgdata) {
00336 word_list = octstr_split_words(request->sms.msgdata);
00337 num_words = gwlist_len(word_list);
00338 } else {
00339 word_list = gwlist_create();
00340 num_words = 0;
00341 }
00342
00343 pattern_len = octstr_len(pattern);
00344 nextarg = 1;
00345 pos = 0;
00346 for (;;) {
00347 while (pos < pattern_len) {
00348 c = octstr_get_char(pattern, pos);
00349 if (c == '%' && pos + 1 < pattern_len)
00350 break;
00351 octstr_append_char(result, c);
00352 ++pos;
00353 }
00354
00355 if (pos == pattern_len)
00356 break;
00357
00358 switch (octstr_get_char(pattern, pos + 1)) {
00359 case 'a':
00360 for (j = 0; j < num_words; ++j) {
00361 enc = octstr_duplicate(gwlist_get(word_list, j));
00362 octstr_url_encode(enc);
00363 if (j > 0)
00364 octstr_append_char(result, '+');
00365 octstr_append(result, enc);
00366 octstr_destroy(enc);
00367 }
00368 break;
00369
00370 case 'A':
00371 if (request->sms.msgdata) {
00372 enc = octstr_duplicate(request->sms.msgdata);
00373 octstr_url_encode(enc);
00374 octstr_append(result, enc);
00375 octstr_destroy(enc);
00376 }
00377 break;
00378
00379 case 'b':
00380 enc = octstr_duplicate(request->sms.msgdata);
00381 octstr_url_encode(enc);
00382 octstr_append(result, enc);
00383 octstr_destroy(enc);
00384 break;
00385
00386 case 'B':
00387 if (octstr_len(request->sms.binfo)) {
00388 enc = octstr_duplicate(request->sms.binfo);
00389 octstr_url_encode(enc);
00390 octstr_append(result, enc);
00391 octstr_destroy(enc);
00392 }
00393 break;
00394
00395 case 'c':
00396 octstr_append_decimal(result, request->sms.coding);
00397 break;
00398
00399 case 'C':
00400 if(octstr_len(request->sms.charset)) {
00401 octstr_append(result, request->sms.charset);
00402 } else {
00403 switch (request->sms.coding) {
00404 case DC_UNDEF:
00405 case DC_7BIT:
00406 octstr_append(result, octstr_imm("UTF-8"));
00407 break;
00408 case DC_8BIT:
00409 octstr_append(result, octstr_imm("8-BIT"));
00410 break;
00411 case DC_UCS2:
00412 octstr_append(result, octstr_imm("UTF-16BE"));
00413 break;
00414 }
00415 }
00416 break;
00417
00418 case 'd':
00419 enc = octstr_create("");
00420 octstr_append_decimal(enc, request->sms.dlr_mask);
00421 octstr_url_encode(enc);
00422 octstr_append(result, enc);
00423 octstr_destroy(enc);
00424 break;
00425
00426 case 'f':
00427 if (octstr_len(request->sms.smsc_number)) {
00428 enc = octstr_duplicate(request->sms.smsc_number);
00429 octstr_url_encode(enc);
00430 octstr_append(result, enc);
00431 octstr_destroy(enc);
00432 }
00433 break;
00434
00435 case 'i':
00436 if (request->sms.smsc_id == NULL)
00437 break;
00438 enc = octstr_duplicate(request->sms.smsc_id);
00439 octstr_url_encode(enc);
00440 octstr_append(result, enc);
00441 octstr_destroy(enc);
00442 break;
00443
00444 case 'I':
00445 if (!uuid_is_null(request->sms.id)) {
00446 char id[UUID_STR_LEN + 1];
00447 uuid_unparse(request->sms.id, id);
00448 octstr_append_cstr(result, id);
00449 }
00450 break;
00451
00452 case 'k':
00453 if (num_words <= 0)
00454 break;
00455 enc = octstr_duplicate(gwlist_get(word_list, 0));
00456 octstr_url_encode(enc);
00457 octstr_append(result, enc);
00458 octstr_destroy(enc);
00459 break;
00460
00461 case 'm':
00462 enc = octstr_create("");
00463 octstr_append_decimal(enc, request->sms.mclass);
00464 octstr_url_encode(enc);
00465 octstr_append(result, enc);
00466 octstr_destroy(enc);
00467 break;
00468
00469 case 'M':
00470 enc = octstr_create("");
00471 octstr_append_decimal(enc, request->sms.mwi);
00472 octstr_url_encode(enc);
00473 octstr_append(result, enc);
00474 octstr_destroy(enc);
00475 break;
00476
00477 case 'n':
00478 if (request->sms.service == NULL)
00479 break;
00480 enc = octstr_duplicate(request->sms.service);
00481 octstr_url_encode(enc);
00482 octstr_append(result, enc);
00483 octstr_destroy(enc);
00484 break;
00485
00486 case 'o':
00487 if (octstr_len(request->sms.account)) {
00488 enc = octstr_duplicate(request->sms.account);
00489 octstr_url_encode(enc);
00490 octstr_append(result, enc);
00491 octstr_destroy(enc);
00492 }
00493 break;
00494
00495 case 'O':
00496 {
00497 int dcs;
00498 dcs = fields_to_dcs(request, request->sms.alt_dcs);
00499 octstr_format_append(result, "%02d", dcs);
00500 break;
00501 }
00502
00503
00504
00505
00506
00507 case 'P':
00508 enc = octstr_duplicate(request->sms.sender);
00509 octstr_url_encode(enc);
00510 octstr_append(result, enc);
00511 octstr_destroy(enc);
00512 break;
00513
00514 case 'p':
00515 enc = octstr_duplicate(request->sms.receiver);
00516 octstr_url_encode(enc);
00517 octstr_append(result, enc);
00518 octstr_destroy(enc);
00519 break;
00520
00521 case 'q':
00522 if (strncmp(octstr_get_cstr(request->sms.receiver),"00",2)==0) {
00523 enc = octstr_copy(request->sms.receiver, 2,
00524 octstr_len(request->sms.receiver));
00525 octstr_url_encode(enc);
00526 octstr_format_append(result, "%%2B%S", enc);
00527 octstr_destroy(enc);
00528 } else {
00529 enc = octstr_duplicate(request->sms.receiver);
00530 octstr_url_encode(enc);
00531 octstr_append(result, enc);
00532 octstr_destroy(enc);
00533 }
00534 break;
00535
00536 case 'Q':
00537 if (strncmp(octstr_get_cstr(request->sms.sender), "00", 2) == 0) {
00538 enc = octstr_copy(request->sms.sender, 2,
00539 octstr_len(request->sms.sender));
00540 octstr_url_encode(enc);
00541 octstr_format_append(result, "%%2B%S", enc);
00542 octstr_destroy(enc);
00543 } else {
00544 enc = octstr_duplicate(request->sms.sender);
00545 octstr_url_encode(enc);
00546 octstr_append(result, enc);
00547 octstr_destroy(enc);
00548 }
00549 break;
00550
00551 case 'r':
00552 for (j = nextarg; j < num_words; ++j) {
00553 enc = octstr_duplicate(gwlist_get(word_list, j));
00554 octstr_url_encode(enc);
00555 if (j != nextarg)
00556 octstr_append_char(result, '+');
00557 octstr_append(result, enc);
00558 octstr_destroy(enc);
00559 }
00560 break;
00561
00562 case 's':
00563 if (nextarg >= num_words)
00564 break;
00565 enc = octstr_duplicate(gwlist_get(word_list, nextarg));
00566 octstr_url_encode(enc);
00567 octstr_append(result, enc);
00568 octstr_destroy(enc);
00569 ++nextarg;
00570 break;
00571
00572 case 'S':
00573 if (nextarg >= num_words)
00574 break;
00575 temp = gwlist_get(word_list, nextarg);
00576 for (i = 0; i < octstr_len(temp); ++i) {
00577 if (octstr_get_char(temp, i) == '*')
00578 octstr_append_char(result, '~');
00579 else
00580 octstr_append_char(result, octstr_get_char(temp, i));
00581 }
00582 ++nextarg;
00583 break;
00584
00585 case 't':
00586 tm = gw_gmtime(request->sms.time);
00587 octstr_format_append(result, "%04d-%02d-%02d+%02d:%02d:%02d",
00588 tm.tm_year + 1900,
00589 tm.tm_mon + 1,
00590 tm.tm_mday,
00591 tm.tm_hour,
00592 tm.tm_min,
00593 tm.tm_sec);
00594 break;
00595
00596 case 'T':
00597 if (request->sms.time == MSG_PARAM_UNDEFINED)
00598 break;
00599 octstr_format_append(result, "%ld", request->sms.time);
00600 break;
00601
00602 case 'u':
00603 if(octstr_len(request->sms.udhdata)) {
00604 enc = octstr_duplicate(request->sms.udhdata);
00605 octstr_url_encode(enc);
00606 octstr_append(result, enc);
00607 octstr_destroy(enc);
00608 }
00609 break;
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 case '%':
00622 octstr_format_append(result, "%%");
00623 break;
00624
00625 default:
00626 octstr_format_append(result, "%%%c",
00627 octstr_get_char(pattern, pos + 1));
00628 break;
00629 }
00630
00631 pos += 2;
00632 }
00633
00634 gwlist_destroy(word_list, octstr_destroy_item);
00635
00636 return result;
00637 }
00638
00639
00640
00641
00642
00643
00644 Octstr *urltrans_get_pattern(URLTranslation *t, Msg *request)
00645 {
00646 Octstr *result, *pattern;
00647
00648 if (request->sms.sms_type != report_mo && t->type == TRANSTYPE_SENDSMS)
00649 return octstr_create("");
00650
00651
00652 if (request->sms.sms_type != report_mo) {
00653 pattern = t->pattern;
00654 } else {
00655
00656 pattern = request->sms.dlr_url;
00657 if (octstr_len(pattern) == 0) {
00658 if (t && octstr_len(t->dlr_url)) {
00659 pattern = t->dlr_url;
00660 } else {
00661 return octstr_create("");
00662 }
00663 }
00664 }
00665
00666
00667
00668
00669 result = urltrans_fill_escape_codes(pattern, request);
00670
00671
00672
00673
00674
00675 if (t && (t->type == TRANSTYPE_POST_URL || t->type == TRANSTYPE_POST_XML)
00676 && t->strip_keyword)
00677 strip_keyword(request);
00678
00679 return result;
00680 }
00681
00682
00683 int urltrans_type(URLTranslation *t)
00684 {
00685 return t->type;
00686 }
00687
00688 Octstr *urltrans_prefix(URLTranslation *t)
00689 {
00690 return t->prefix;
00691 }
00692
00693 Octstr *urltrans_suffix(URLTranslation *t)
00694 {
00695 return t->suffix;
00696 }
00697
00698 Octstr *urltrans_default_sender(URLTranslation *t)
00699 {
00700 return t->default_sender;
00701 }
00702
00703 Octstr *urltrans_faked_sender(URLTranslation *t)
00704 {
00705 return t->faked_sender;
00706 }
00707
00708 int urltrans_max_messages(URLTranslation *t)
00709 {
00710 return t->max_messages;
00711 }
00712
00713 int urltrans_concatenation(URLTranslation *t)
00714 {
00715 return t->concatenation;
00716 }
00717
00718 Octstr *urltrans_split_chars(URLTranslation *t)
00719 {
00720 return t->split_chars;
00721 }
00722
00723 Octstr *urltrans_split_suffix(URLTranslation *t)
00724 {
00725 return t->split_suffix;
00726 }
00727
00728 int urltrans_omit_empty(URLTranslation *t)
00729 {
00730 return t->omit_empty;
00731 }
00732
00733 Octstr *urltrans_header(URLTranslation *t)
00734 {
00735 return t->header;
00736 }
00737
00738 Octstr *urltrans_footer(URLTranslation *t)
00739 {
00740 return t->footer;
00741 }
00742
00743 Octstr *urltrans_name(URLTranslation *t)
00744 {
00745 return t->name;
00746 }
00747
00748 Octstr *urltrans_username(URLTranslation *t)
00749 {
00750 return t->username;
00751 }
00752
00753 Octstr *urltrans_password(URLTranslation *t)
00754 {
00755 return t->password;
00756 }
00757
00758 Octstr *urltrans_forced_smsc(URLTranslation *t)
00759 {
00760 return t->forced_smsc;
00761 }
00762
00763 Octstr *urltrans_default_smsc(URLTranslation *t)
00764 {
00765 return t->default_smsc;
00766 }
00767
00768 Octstr *urltrans_allow_ip(URLTranslation *t)
00769 {
00770 return t->allow_ip;
00771 }
00772
00773 Octstr *urltrans_deny_ip(URLTranslation *t)
00774 {
00775 return t->deny_ip;
00776 }
00777
00778 Octstr *urltrans_allowed_prefix(URLTranslation *t)
00779 {
00780 return t->allowed_prefix;
00781 }
00782
00783 Octstr *urltrans_denied_prefix(URLTranslation *t)
00784 {
00785 return t->denied_prefix;
00786 }
00787
00788 Octstr *urltrans_allowed_recv_prefix(URLTranslation *t)
00789 {
00790 return t->allowed_recv_prefix;
00791 }
00792
00793 Octstr *urltrans_denied_recv_prefix(URLTranslation *t)
00794 {
00795 return t->denied_recv_prefix;
00796 }
00797
00798 Numhash *urltrans_white_list(URLTranslation *t)
00799 {
00800 return t->white_list;
00801 }
00802
00803 regex_t *urltrans_white_list_regex(URLTranslation *t)
00804 {
00805 return t->white_list_regex;
00806 }
00807
00808 Numhash *urltrans_black_list(URLTranslation *t)
00809 {
00810 return t->black_list;
00811 }
00812
00813 regex_t *urltrans_black_list_regex(URLTranslation *t)
00814 {
00815 return t->black_list_regex;
00816 }
00817
00818 int urltrans_assume_plain_text(URLTranslation *t)
00819 {
00820 return t->assume_plain_text;
00821 }
00822
00823 int urltrans_accept_x_kannel_headers(URLTranslation *t)
00824 {
00825 return t->accept_x_kannel_headers;
00826 }
00827
00828 int urltrans_strip_keyword(URLTranslation *t)
00829 {
00830 return t->strip_keyword;
00831 }
00832
00833 int urltrans_send_sender(URLTranslation *t)
00834 {
00835 return t->send_sender;
00836 }
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 static URLTranslation *create_onetrans(CfgGroup *grp)
00849 {
00850 URLTranslation *ot;
00851 Octstr *url, *post_url, *post_xml, *text, *file, *exec;
00852 Octstr *accepted_smsc, *accepted_account, *forced_smsc, *default_smsc;
00853 Octstr *grpname;
00854 int is_sms_service;
00855 Octstr *accepted_smsc_regex;
00856 Octstr *accepted_account_regex;
00857 Octstr *allowed_prefix_regex;
00858 Octstr *denied_prefix_regex;
00859 Octstr *allowed_receiver_prefix_regex;
00860 Octstr *denied_receiver_prefix_regex;
00861 Octstr *white_list_regex;
00862 Octstr *black_list_regex;
00863 Octstr *keyword_regex;
00864 Octstr *os, *tmp;
00865
00866 grpname = cfg_get_group_name(grp);
00867 if (grpname == NULL)
00868 return NULL;
00869
00870 if (octstr_str_compare(grpname, "sms-service") == 0)
00871 is_sms_service = 1;
00872 else if (octstr_str_compare(grpname, "sendsms-user") == 0)
00873 is_sms_service = 0;
00874 else {
00875 octstr_destroy(grpname);
00876 return NULL;
00877 }
00878 octstr_destroy(grpname);
00879
00880 ot = gw_malloc(sizeof(URLTranslation));
00881 memset(ot, 0, sizeof(*ot));
00882
00883 if (is_sms_service) {
00884 cfg_get_bool(&ot->catch_all, grp, octstr_imm("catch-all"));
00885
00886 ot->dlr_url = cfg_get(grp, octstr_imm("dlr-url"));
00887
00888 url = cfg_get(grp, octstr_imm("get-url"));
00889 if (url == NULL)
00890 url = cfg_get(grp, octstr_imm("url"));
00891
00892 post_url = cfg_get(grp, octstr_imm("post-url"));
00893 post_xml = cfg_get(grp, octstr_imm("post-xml"));
00894 file = cfg_get(grp, octstr_imm("file"));
00895 text = cfg_get(grp, octstr_imm("text"));
00896 exec = cfg_get(grp, octstr_imm("exec"));
00897 if (url != NULL) {
00898 ot->type = TRANSTYPE_GET_URL;
00899 ot->pattern = octstr_duplicate(url);
00900 } else if (post_url != NULL) {
00901 ot->type = TRANSTYPE_POST_URL;
00902 ot->pattern = octstr_duplicate(post_url);
00903 ot->catch_all = 1;
00904 } else if (post_xml != NULL) {
00905 ot->type = TRANSTYPE_POST_XML;
00906 ot->pattern = octstr_duplicate(post_xml);
00907 ot->catch_all = 1;
00908 } else if (file != NULL) {
00909 ot->type = TRANSTYPE_FILE;
00910 ot->pattern = octstr_duplicate(file);
00911 } else if (text != NULL) {
00912 ot->type = TRANSTYPE_TEXT;
00913 ot->pattern = octstr_duplicate(text);
00914 } else if (exec != NULL) {
00915 ot->type = TRANSTYPE_EXECUTE;
00916 ot->pattern = octstr_duplicate(exec);
00917 } else {
00918 octstr_destroy(url);
00919 octstr_destroy(post_url);
00920 octstr_destroy(post_xml);
00921 octstr_destroy(file);
00922 octstr_destroy(text);
00923 octstr_destroy(exec);
00924 error(0, "Configuration group `sms-service' "
00925 "did not specify get-url, post-url, post-xml, file or text.");
00926 goto error;
00927 }
00928 octstr_destroy(url);
00929 octstr_destroy(post_url);
00930 octstr_destroy(post_xml);
00931 octstr_destroy(file);
00932 octstr_destroy(text);
00933 octstr_destroy(exec);
00934
00935 tmp = cfg_get(grp, octstr_imm("keyword"));
00936 keyword_regex = cfg_get(grp, octstr_imm("keyword-regex"));
00937 if (tmp == NULL && keyword_regex == NULL) {
00938 error(0, "Group 'sms-service' must include either 'keyword' or 'keyword-regex'.");
00939 goto error;
00940 }
00941 if (tmp != NULL && keyword_regex != NULL) {
00942 error(0, "Group 'sms-service' may inlcude either 'keyword' or 'keyword-regex'.");
00943 octstr_destroy(tmp);
00944 octstr_destroy(keyword_regex);
00945 goto error;
00946 }
00947
00948 if (tmp != NULL && octstr_str_compare(tmp, "default") == 0) {
00949
00950 ot->keyword_regex = NULL;
00951 octstr_destroy(tmp);
00952 } else if (tmp != NULL) {
00953 Octstr *aliases;
00954
00955
00956 octstr_convert_range(tmp, 0, octstr_len(tmp), tolower);
00957 keyword_regex = octstr_format("^[ ]*(%S", tmp);
00958 octstr_destroy(tmp);
00959
00960 aliases = cfg_get(grp, octstr_imm("aliases"));
00961 if (aliases != NULL) {
00962 long i;
00963 List *l;
00964
00965 l = octstr_split(aliases, octstr_imm(";"));
00966 octstr_destroy(aliases);
00967
00968 for (i = 0; i < gwlist_len(l); ++i) {
00969 os = gwlist_get(l, i);
00970 octstr_convert_range(os, 0, octstr_len(os), tolower);
00971 octstr_format_append(keyword_regex, "|%S", os);
00972 }
00973 gwlist_destroy(l, octstr_destroy_item);
00974 }
00975
00976 octstr_append_cstr(keyword_regex, ")[ ]*");
00977 }
00978
00979 if (keyword_regex != NULL && (ot->keyword_regex = gw_regex_comp(keyword_regex, REG_EXTENDED)) == NULL) {
00980 error(0, "Could not compile pattern '%s'", octstr_get_cstr(keyword_regex));
00981 octstr_destroy(keyword_regex);
00982 goto error;
00983 }
00984
00985 ot->name = cfg_get(grp, octstr_imm("name"));
00986 if (ot->name == NULL)
00987 ot->name = keyword_regex ? octstr_duplicate(keyword_regex) : octstr_create("default");
00988 octstr_destroy(keyword_regex);
00989
00990 accepted_smsc = cfg_get(grp, octstr_imm("accepted-smsc"));
00991 if (accepted_smsc != NULL) {
00992 ot->accepted_smsc = octstr_split(accepted_smsc, octstr_imm(";"));
00993 octstr_destroy(accepted_smsc);
00994 }
00995 accepted_account = cfg_get(grp, octstr_imm("accepted-account"));
00996 if (accepted_account != NULL) {
00997 ot->accepted_account = octstr_split(accepted_account, octstr_imm(";"));
00998 octstr_destroy(accepted_account);
00999 }
01000 accepted_smsc_regex = cfg_get(grp, octstr_imm("accepted-smsc-regex"));
01001 if (accepted_smsc_regex != NULL) {
01002 if ( (ot->accepted_smsc_regex = gw_regex_comp(accepted_smsc_regex, REG_EXTENDED)) == NULL)
01003 panic(0, "Could not compile pattern '%s'", octstr_get_cstr(accepted_smsc_regex));
01004 octstr_destroy(accepted_smsc_regex);
01005 }
01006 accepted_account_regex = cfg_get(grp, octstr_imm("accepted-account-regex"));
01007 if (accepted_account_regex != NULL) {
01008 if ( (ot->accepted_account_regex = gw_regex_comp(accepted_account_regex, REG_EXTENDED)) == NULL)
01009 panic(0, "Could not compile pattern '%s'", octstr_get_cstr(accepted_account_regex));
01010 octstr_destroy(accepted_account_regex);
01011 }
01012
01013 cfg_get_bool(&ot->assume_plain_text, grp,
01014 octstr_imm("assume-plain-text"));
01015 cfg_get_bool(&ot->accept_x_kannel_headers, grp,
01016 octstr_imm("accept-x-kannel-headers"));
01017 cfg_get_bool(&ot->strip_keyword, grp, octstr_imm("strip-keyword"));
01018 cfg_get_bool(&ot->send_sender, grp, octstr_imm("send-sender"));
01019
01020 ot->prefix = cfg_get(grp, octstr_imm("prefix"));
01021 ot->suffix = cfg_get(grp, octstr_imm("suffix"));
01022 ot->allowed_recv_prefix = cfg_get(grp, octstr_imm("allowed-receiver-prefix"));
01023 allowed_receiver_prefix_regex = cfg_get(grp, octstr_imm("allowed-receiver-prefix-regex"));
01024 if (allowed_receiver_prefix_regex != NULL) {
01025 if ((ot->allowed_receiver_prefix_regex = gw_regex_comp(allowed_receiver_prefix_regex, REG_EXTENDED)) == NULL)
01026 panic(0, "Could not compile pattern '%s'", octstr_get_cstr(allowed_receiver_prefix_regex));
01027 octstr_destroy(allowed_receiver_prefix_regex);
01028 }
01029
01030 ot->allowed_recv_prefix = cfg_get(grp, octstr_imm("allowed-receiver-prefix"));
01031 ot->denied_recv_prefix = cfg_get(grp, octstr_imm("denied-receiver-prefix"));
01032 denied_receiver_prefix_regex = cfg_get(grp, octstr_imm("denied-receiver-prefix-regex"));
01033 if (denied_receiver_prefix_regex != NULL) {
01034 if ((ot->denied_receiver_prefix_regex = gw_regex_comp(denied_receiver_prefix_regex, REG_EXTENDED)) == NULL)
01035 panic(0, "Could not compile pattern '%s'",octstr_get_cstr(denied_receiver_prefix_regex));
01036 octstr_destroy(denied_receiver_prefix_regex);
01037 }
01038
01039 ot->args = count_occurences(ot->pattern, octstr_imm("%s"));
01040 ot->args += count_occurences(ot->pattern, octstr_imm("%S"));
01041 ot->has_catchall_arg =
01042 (count_occurences(ot->pattern, octstr_imm("%r")) > 0) ||
01043 (count_occurences(ot->pattern, octstr_imm("%a")) > 0);
01044
01045 } else {
01046 ot->type = TRANSTYPE_SENDSMS;
01047 ot->pattern = octstr_create("");
01048 ot->args = 0;
01049 ot->has_catchall_arg = 0;
01050 ot->catch_all = 1;
01051 ot->username = cfg_get(grp, octstr_imm("username"));
01052 ot->password = cfg_get(grp, octstr_imm("password"));
01053 ot->dlr_url = cfg_get(grp, octstr_imm("dlr-url"));
01054 grp_dump(grp);
01055 if (ot->password == NULL) {
01056 error(0, "Password required for send-sms user");
01057 goto error;
01058 }
01059 ot->name = cfg_get(grp, octstr_imm("name"));
01060 if (ot->name == NULL)
01061 ot->name = octstr_duplicate(ot->username);
01062
01063 forced_smsc = cfg_get(grp, octstr_imm("forced-smsc"));
01064 default_smsc = cfg_get(grp, octstr_imm("default-smsc"));
01065 if (forced_smsc != NULL) {
01066 if (default_smsc != NULL) {
01067 info(0, "Redundant default-smsc for send-sms user %s",
01068 octstr_get_cstr(ot->username));
01069 }
01070 ot->forced_smsc = forced_smsc;
01071 octstr_destroy(default_smsc);
01072 } else if (default_smsc != NULL)
01073 ot->default_smsc = default_smsc;
01074
01075 ot->deny_ip = cfg_get(grp, octstr_imm("user-deny-ip"));
01076 ot->allow_ip = cfg_get(grp, octstr_imm("user-allow-ip"));
01077 ot->default_sender = cfg_get(grp, octstr_imm("default-sender"));
01078 }
01079
01080 ot->allowed_prefix = cfg_get(grp, octstr_imm("allowed-prefix"));
01081 allowed_prefix_regex = cfg_get(grp, octstr_imm("allowed-prefix-regex"));
01082 if (allowed_prefix_regex != NULL) {
01083 if ((ot->allowed_prefix_regex = gw_regex_comp(allowed_prefix_regex, REG_EXTENDED)) == NULL)
01084 panic(0, "Could not compile pattern '%s'", octstr_get_cstr(allowed_prefix_regex));
01085 octstr_destroy(allowed_prefix_regex);
01086 }
01087 ot->denied_prefix = cfg_get(grp, octstr_imm("denied-prefix"));
01088 denied_prefix_regex = cfg_get(grp, octstr_imm("denied-prefix-regex"));
01089 if (denied_prefix_regex != NULL) {
01090 if ((ot->denied_prefix_regex = gw_regex_comp(denied_prefix_regex, REG_EXTENDED)) == NULL)
01091 panic(0, "Could not compile pattern '%s'", octstr_get_cstr(denied_prefix_regex));
01092 octstr_destroy(denied_prefix_regex);
01093 }
01094
01095 os = cfg_get(grp, octstr_imm("white-list"));
01096 if (os != NULL) {
01097 ot->white_list = numhash_create(octstr_get_cstr(os));
01098 octstr_destroy(os);
01099 }
01100 white_list_regex = cfg_get(grp, octstr_imm("white-list-regex"));
01101 if (white_list_regex != NULL) {
01102 if ((ot->white_list_regex = gw_regex_comp(white_list_regex, REG_EXTENDED)) == NULL)
01103 panic(0, "Could not compile pattern '%s'", octstr_get_cstr(white_list_regex));
01104 octstr_destroy(white_list_regex);
01105 }
01106
01107 os = cfg_get(grp, octstr_imm("black-list"));
01108 if (os != NULL) {
01109 ot->black_list = numhash_create(octstr_get_cstr(os));
01110 octstr_destroy(os);
01111 }
01112 black_list_regex = cfg_get(grp, octstr_imm("black-list-regex"));
01113 if (black_list_regex != NULL) {
01114 if ((ot->black_list_regex = gw_regex_comp(black_list_regex, REG_EXTENDED)) == NULL)
01115 panic(0, "Could not compile pattern '%s'", octstr_get_cstr(black_list_regex));
01116 octstr_destroy(black_list_regex);
01117 }
01118
01119 if (cfg_get_integer(&ot->max_messages, grp, octstr_imm("max-messages")) == -1)
01120 ot->max_messages = 1;
01121 cfg_get_bool(&ot->concatenation, grp, octstr_imm("concatenation"));
01122 cfg_get_bool(&ot->omit_empty, grp, octstr_imm("omit-empty"));
01123
01124 ot->header = cfg_get(grp, octstr_imm("header"));
01125 ot->footer = cfg_get(grp, octstr_imm("footer"));
01126 ot->faked_sender = cfg_get(grp, octstr_imm("faked-sender"));
01127 ot->split_chars = cfg_get(grp, octstr_imm("split-chars"));
01128 ot->split_suffix = cfg_get(grp, octstr_imm("split-suffix"));
01129
01130 if ( (ot->prefix == NULL && ot->suffix != NULL) ||
01131 (ot->prefix != NULL && ot->suffix == NULL) ) {
01132 warning(0, "Service : suffix and prefix are only used"
01133 " if both are set.");
01134 }
01135 if ((ot->prefix != NULL || ot->suffix != NULL) &&
01136 ot->type != TRANSTYPE_GET_URL) {
01137 warning(0, "Service : suffix and prefix are only used"
01138 " if type is 'get-url'.");
01139 }
01140
01141 return ot;
01142
01143 error:
01144 error(0, "Couldn't create a URLTranslation.");
01145 destroy_onetrans(ot);
01146 return NULL;
01147 }
01148
01149
01150
01151
01152
01153 static void destroy_onetrans(void *p)
01154 {
01155 URLTranslation *ot;
01156
01157 ot = p;
01158 if (ot != NULL) {
01159 octstr_destroy(ot->dlr_url);
01160 octstr_destroy(ot->pattern);
01161 octstr_destroy(ot->prefix);
01162 octstr_destroy(ot->suffix);
01163 octstr_destroy(ot->default_sender);
01164 octstr_destroy(ot->faked_sender);
01165 octstr_destroy(ot->split_chars);
01166 octstr_destroy(ot->split_suffix);
01167 octstr_destroy(ot->header);
01168 octstr_destroy(ot->footer);
01169 gwlist_destroy(ot->accepted_smsc, octstr_destroy_item);
01170 gwlist_destroy(ot->accepted_account, octstr_destroy_item);
01171 octstr_destroy(ot->name);
01172 octstr_destroy(ot->username);
01173 octstr_destroy(ot->password);
01174 octstr_destroy(ot->forced_smsc);
01175 octstr_destroy(ot->default_smsc);
01176 octstr_destroy(ot->allow_ip);
01177 octstr_destroy(ot->deny_ip);
01178 octstr_destroy(ot->allowed_prefix);
01179 octstr_destroy(ot->denied_prefix);
01180 octstr_destroy(ot->allowed_recv_prefix);
01181 octstr_destroy(ot->denied_recv_prefix);
01182 numhash_destroy(ot->white_list);
01183 numhash_destroy(ot->black_list);
01184 if (ot->keyword_regex != NULL) gw_regex_destroy(ot->keyword_regex);
01185 if (ot->accepted_smsc_regex != NULL) gw_regex_destroy(ot->accepted_smsc_regex);
01186 if (ot->accepted_account_regex != NULL) gw_regex_destroy(ot->accepted_account_regex);
01187 if (ot->allowed_prefix_regex != NULL) gw_regex_destroy(ot->allowed_prefix_regex);
01188 if (ot->denied_prefix_regex != NULL) gw_regex_destroy(ot->denied_prefix_regex);
01189 if (ot->allowed_receiver_prefix_regex != NULL) gw_regex_destroy(ot->allowed_receiver_prefix_regex);
01190 if (ot->denied_receiver_prefix_regex != NULL) gw_regex_destroy(ot->denied_receiver_prefix_regex);
01191 if (ot->white_list_regex != NULL) gw_regex_destroy(ot->white_list_regex);
01192 if (ot->black_list_regex != NULL) gw_regex_destroy(ot->black_list_regex);
01193 gw_free(ot);
01194 }
01195 }
01196
01197
01198
01199
01200
01201
01202 static int check_num_args(URLTranslation *t, List *words)
01203 {
01204 const int IS_OKAY = 0;
01205 const int NOT_OKAY = -1;
01206 int n;
01207
01208
01209 n = gwlist_len(words);
01210
01211 if (t->catch_all)
01212 return IS_OKAY;
01213
01214 if (n - 1 == t->args)
01215 return IS_OKAY;
01216
01217 if (t->has_catchall_arg && n - 1 >= t->args)
01218 return IS_OKAY;
01219
01220 return NOT_OKAY;
01221 }
01222
01223
01224
01225
01226
01227 static int check_allowed_translation(URLTranslation *t,
01228 Octstr *smsc, Octstr *sender, Octstr *receiver, Octstr *account)
01229 {
01230 const int IS_ALLOWED = 0;
01231 const int NOT_ALLOWED = -1;
01232
01233
01234
01235
01236 if (smsc && t->accepted_smsc && !gwlist_search(t->accepted_smsc, smsc, octstr_item_match))
01237 return NOT_ALLOWED;
01238
01239 if (smsc && t->accepted_smsc_regex && gw_regex_match_pre( t->accepted_smsc_regex, smsc) == 0)
01240 return NOT_ALLOWED;
01241
01242
01243
01244
01245 if (account && t->accepted_account && !gwlist_search(t->accepted_account, account, octstr_item_match))
01246 return NOT_ALLOWED;
01247
01248 if (account && t->accepted_account_regex && gw_regex_match_pre( t->accepted_account_regex, account) == 0)
01249 return NOT_ALLOWED;
01250
01251
01252 if (t->allowed_prefix && !t->denied_prefix && does_prefix_match(t->allowed_prefix, sender) != 1)
01253 return NOT_ALLOWED;
01254
01255 if (t->allowed_prefix_regex && !t->denied_prefix_regex && gw_regex_match_pre(t->allowed_prefix_regex, sender) == 0)
01256 return NOT_ALLOWED;
01257
01258
01259 if (t->denied_prefix && !t->allowed_prefix && does_prefix_match(t->denied_prefix, sender) == 1)
01260 return NOT_ALLOWED;
01261
01262 if (t->denied_prefix_regex && !t->allowed_prefix_regex && gw_regex_match_pre(t->denied_prefix_regex, sender) == 1)
01263 return NOT_ALLOWED;
01264
01265
01266 if (t->allowed_recv_prefix && !t->denied_recv_prefix && does_prefix_match(t->allowed_recv_prefix, receiver) != 1)
01267 return NOT_ALLOWED;
01268
01269 if (t->allowed_receiver_prefix_regex && !t->denied_receiver_prefix_regex &&
01270 gw_regex_match_pre(t->allowed_receiver_prefix_regex, receiver) == 0)
01271 return NOT_ALLOWED;
01272
01273
01274 if (t->denied_recv_prefix && !t->allowed_recv_prefix && does_prefix_match(t->denied_recv_prefix, receiver) == 1)
01275 return NOT_ALLOWED;
01276
01277 if (t->denied_receiver_prefix_regex && !t->allowed_receiver_prefix_regex &&
01278 gw_regex_match_pre(t->denied_receiver_prefix_regex, receiver) == 0)
01279 return NOT_ALLOWED;
01280
01281 if (t->white_list && numhash_find_number(t->white_list, sender) < 1) {
01282 return NOT_ALLOWED;
01283 }
01284
01285 if (t->white_list_regex && gw_regex_match_pre(t->white_list_regex, sender) == 0) {
01286 return NOT_ALLOWED;
01287 }
01288
01289 if (t->black_list && numhash_find_number(t->black_list, sender) == 1) {
01290 return NOT_ALLOWED;
01291 }
01292
01293 if (t->black_list_regex && gw_regex_match_pre(t->black_list_regex, sender) == 1) {
01294 return NOT_ALLOWED;
01295 }
01296
01297
01298 if (t->denied_prefix && t->allowed_prefix && does_prefix_match(t->allowed_prefix, sender) != 1 &&
01299 does_prefix_match(t->denied_prefix, sender) == 1)
01300 return NOT_ALLOWED;
01301
01302 if (t->denied_prefix_regex && t->allowed_prefix_regex &&
01303 gw_regex_match_pre(t->allowed_prefix_regex, sender) == 0 &&
01304 gw_regex_match_pre(t->denied_prefix_regex, sender) == 1)
01305 return NOT_ALLOWED;
01306
01307 return IS_ALLOWED;
01308 };
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321 static List *get_matching_translations(URLTranslationList *trans, Octstr *msg)
01322 {
01323 List *list;
01324 long i;
01325 URLTranslation *t;
01326
01327 gw_assert(trans != NULL && msg != NULL);
01328
01329 list = gwlist_create();
01330 for (i = 0; i < gwlist_len(trans->list); ++i) {
01331 t = gwlist_get(trans->list, i);
01332
01333 if (t->keyword_regex == NULL)
01334 continue;
01335
01336 if (gw_regex_match_pre(t->keyword_regex, msg) == 1) {
01337 debug("", 0, "match found: %s", octstr_get_cstr(t->name));
01338 gwlist_append(list, t);
01339 } else {
01340 debug("", 0, "no match found: %s", octstr_get_cstr(t->name));
01341 }
01342 }
01343
01344 return list;
01345 }
01346
01347
01348
01349
01350 static URLTranslation *find_translation(URLTranslationList *trans, Msg *msg)
01351 {
01352 Octstr *data;
01353 int i;
01354 URLTranslation *t = NULL;
01355 List *list, *words;
01356
01357
01358 data = octstr_duplicate(msg->sms.msgdata);
01359 octstr_convert_range(data, 0, octstr_len(data), tolower);
01360 i = 0;
01361 while((i = octstr_search_char(data, 0, i)) != -1 && i < octstr_len(data) - 1) {
01362 octstr_delete(data, i, 1);
01363 }
01364
01365 list = get_matching_translations(trans, data);
01366 words = octstr_split_words(data);
01367
01372 for (i = 0; i < gwlist_len(list); ++i) {
01373 t = gwlist_get(list, i);
01374
01375
01376 if (check_allowed_translation(t, msg->sms.smsc_id, msg->sms.sender, msg->sms.receiver, msg->sms.account) == 0
01377 && check_num_args(t, words) == 0)
01378 break;
01379
01380 t = NULL;
01381 }
01382
01383 octstr_destroy(data);
01384 gwlist_destroy(words, octstr_destroy_item);
01385 gwlist_destroy(list, NULL);
01386
01387 return t;
01388 }
01389
01390
01391 static URLTranslation *find_default_translation(URLTranslationList *trans,
01392 Octstr *smsc, Octstr *sender, Octstr *receiver,
01393 Octstr *account)
01394 {
01395 URLTranslation *t;
01396 int i;
01397 List *list;
01398
01399 list = trans->defaults;
01400 t = NULL;
01401 for (i = 0; i < gwlist_len(list); ++i) {
01402 t = gwlist_get(list, i);
01403
01404 if (check_allowed_translation(t, smsc, sender, receiver, account) == 0)
01405 break;
01406
01407 t = NULL;
01408 }
01409
01410 return t;
01411 }
01412
01413
01414
01415
01416 static long count_occurences(Octstr *str, Octstr *pat)
01417 {
01418 long count;
01419 long pos;
01420 long len;
01421
01422 count = 0;
01423 pos = 0;
01424 len = octstr_len(pat);
01425 while ((pos = octstr_search(str, pat, pos)) != -1) {
01426 ++count;
01427 pos += len;
01428 }
01429 return count;
01430 }
01431
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.