Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
urltrans.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2016 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Kannel Group (http://www.kannel.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  * endorse or promote products derived from this software without
29  * prior written permission. For written permission, please
30  * contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  * nor may "Kannel" appear in their name, without prior written
34  * permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group. For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /*
58  * urltrans.c - URL translations
59  *
60  * Lars Wirzenius
61  */
62 
63 
64 #include <ctype.h>
65 #include <errno.h>
66 #include <limits.h>
67 #include <stdlib.h>
68 #include <string.h>
69 #include <time.h>
70 
71 #include "urltrans.h"
72 #include "gwlib/gwlib.h"
73 #include "gw/sms.h"
74 #include "gw/dlr.h"
75 #include "gw/meta_data.h"
76 
77 
78 /***********************************************************************
79  * Definitions of data structures. These are not visible to the external
80  * world -- they may be accessed only via the functions declared in
81  * urltrans.h.
82  */
83 
84 
85 /*
86  * Hold one keyword/options entity
87  */
89  int type; /* see enumeration in header file */
90  Octstr *pattern; /* url, text or file-name pattern */
91  Octstr *prefix; /* for prefix-cut */
92  Octstr *suffix; /* for suffix-cut */
93  Octstr *faked_sender;/* works only with certain services */
94  Octstr *default_sender;/* Default sender to sendsms-user */
95  long max_messages; /* absolute limit of reply messages */
96  int concatenation; /* send long messages as concatenated SMS's if true */
97  Octstr *split_chars;/* allowed chars to be used to split message */
98  Octstr *split_suffix;/* chars added to end after each split (not last) */
99  int omit_empty; /* if the reply is empty, is notification send */
100  Octstr *header; /* string to be inserted to each SMS */
101  Octstr *footer; /* string to be appended to each SMS */
102  Octstr *alt_charset; /* alternative charset to use towards service */
103  List *accepted_smsc; /* smsc id's allowed to use this service. If not set,
104  all messages can use this service */
105  List *accepted_account; /* account id's allowed to use this service. If not set,
106  all messages can use this service */
107 
108  Octstr *name; /* Translation name */
109  Octstr *username; /* send sms username */
110  Octstr *password; /* password associated */
111  Octstr *forced_smsc;/* if smsc id is forcet to certain for this user */
112  Octstr *default_smsc; /* smsc id if none given in http send-sms request */
113  Octstr *allow_ip; /* allowed IPs to request send-sms with this
114  account */
115  Octstr *deny_ip; /* denied IPs to request send-sms with this account */
116  Octstr *allowed_prefix; /* Prefixes (of sender) allowed in this translation, or... */
117  Octstr *denied_prefix; /* ...denied prefixes */
118  Octstr *allowed_recv_prefix; /* Prefixes (of receiver) allowed in this translation, or... */
119  Octstr *denied_recv_prefix; /* ...denied prefixes */
120  Numhash *white_list; /* To numbers allowed, or ... */
121  Numhash *black_list; /* ...denied numbers */
122 
123  int assume_plain_text; /* for type: octet-stream */
124  int accept_x_kannel_headers; /* do we accept special headers in reply */
125  int strip_keyword; /* POST body */
126  int send_sender; /* POST headers */
127 
128  int args;
131  Octstr *dlr_url; /* URL to call for delivery reports */
132  long dlr_mask; /* DLR event mask */
133 
134  regex_t *keyword_regex; /* the compiled regular expression for the keyword*/
143 };
144 
145 
146 /*
147  * Hold the list of all translations.
148  */
151  List *defaults; /* List of default sms-services */
152  Dict *names; /* Dict of lowercase Octstr names */
153 };
154 
155 
156 /***********************************************************************
157  * Declarations of internal functions. These are defined at the end of
158  * the file.
159  */
160 
161 static long count_occurences(Octstr *str, Octstr *pat);
163 static void destroy_onetrans(void *ot);
166  Octstr *smsc, Octstr *sender, Octstr *receiver,
167  Octstr *account);
168 
169 
170 /***********************************************************************
171  * Implementations of the functions declared in urltrans.h. See the
172  * header for explanations of what they should do.
173  */
174 
175 
176 static void destroy_keyword_list(void *list)
177 {
178  gwlist_destroy(list, NULL);
179 }
180 
181 
183 {
184  URLTranslationList *trans;
185 
186  trans = gw_malloc(sizeof(URLTranslationList));
187  trans->list = gwlist_create();
188  trans->defaults = gwlist_create();
189  trans->names = dict_create(1024, destroy_keyword_list);
190  return trans;
191 }
192 
193 
195 {
198  dict_destroy(trans->names);
199  gw_free(trans);
200 }
201 
202 
204 {
205  URLTranslation *ot;
206  List *list2;
207 
208  ot = create_onetrans(grp);
209  if (ot == NULL)
210  return -1;
211 
212  if (ot->type != TRANSTYPE_SENDSMS && ot->keyword_regex == NULL)
213  gwlist_append(trans->defaults, ot);
214  else
215  gwlist_append(trans->list, ot);
216 
217  list2 = dict_get(trans->names, ot->name);
218  if (list2 == NULL) {
219  list2 = gwlist_create();
220  dict_put(trans->names, ot->name, list2);
221  }
222  gwlist_append(list2, ot);
223 
224  return 0;
225 }
226 
227 
229 {
230  CfgGroup *grp;
231  List *list;
232 
233  list = cfg_get_multi_group(cfg, octstr_imm("sms-service"));
234  while (list && (grp = gwlist_extract_first(list)) != NULL) {
235  if (urltrans_add_one(trans, grp) == -1) {
236  gwlist_destroy(list, NULL);
237  return -1;
238  }
239  }
240  gwlist_destroy(list, NULL);
241 
242  list = cfg_get_multi_group(cfg, octstr_imm("sendsms-user"));
243  while (list && (grp = gwlist_extract_first(list)) != NULL) {
244  if (urltrans_add_one(trans, grp) == -1) {
245  gwlist_destroy(list, NULL);
246  return -1;
247  }
248  }
249  gwlist_destroy(list, NULL);
250 
251  return 0;
252 }
253 
254 
256 {
257  URLTranslation *t = NULL;
258 
259  t = find_translation(trans, msg);
260  if (t == NULL) {
261  t = find_default_translation(trans, msg->sms.smsc_id, msg->sms.sender, msg->sms.receiver, msg->sms.account);
262  }
263 
264  return t;
265 }
266 
267 
269 {
270  URLTranslation *t;
271  List *list;
272 
273  list = dict_get(trans->names, msg->sms.service);
274  if (list != NULL) {
275  t = gwlist_get(list, 0);
276  } else {
277  t = NULL;
278  }
279  return t;
280 }
281 
282 
283 
285 {
286  URLTranslation *t;
287  int i;
288 
289  gw_assert(name != NULL);
290  for (i = 0; i < gwlist_len(trans->list); ++i) {
291  t = gwlist_get(trans->list, i);
292  if (t->type == TRANSTYPE_SENDSMS) {
293  if (octstr_compare(name, t->username) == 0)
294  return t;
295  }
296  }
297  return NULL;
298 }
299 
300 /*
301  * Remove the first word and the whitespace that follows it from
302  * the start of the message data.
303  */
304 static void strip_keyword(Msg *request)
305 {
306  int ch;
307  long pos;
308 
309  pos = 0;
310 
311  for (; (ch = octstr_get_char(request->sms.msgdata, pos)) >= 0; pos++)
312  if (isspace(ch))
313  break;
314 
315  for (; (ch = octstr_get_char(request->sms.msgdata, pos)) >= 0; pos++)
316  if (!isspace(ch))
317  break;
318 
319  octstr_delete(request->sms.msgdata, 0, pos);
320 }
321 
322 
324 {
325  Octstr *enc;
326  Octstr *meta_group, *meta_param;
327  int nextarg, j;
328  struct tm tm;
329  int num_words;
330  List *word_list;
331  Octstr *result;
332  long pattern_len;
333  long pos;
334  int c;
335  long i, k;
336  Octstr *temp;
337 
338  result = octstr_create("");
339 
340  if (request->sms.msgdata) {
341  word_list = octstr_split_words(request->sms.msgdata);
342  num_words = gwlist_len(word_list);
343  } else {
344  word_list = gwlist_create();
345  num_words = 0;
346  }
347 
348  pattern_len = octstr_len(pattern);
349  nextarg = 1;
350  pos = 0;
351  for (;;) {
352  while (pos < pattern_len) {
353  c = octstr_get_char(pattern, pos);
354  if (c == '%' && pos + 1 < pattern_len)
355  break;
356  octstr_append_char(result, c);
357  ++pos;
358  }
359 
360  if (pos == pattern_len)
361  break;
362 
363  switch (octstr_get_char(pattern, pos + 1)) {
364  case 'a':
365  for (j = 0; j < num_words; ++j) {
366  enc = octstr_duplicate(gwlist_get(word_list, j));
367  octstr_url_encode(enc);
368  if (j > 0)
369  octstr_append_char(result, '+');
370  octstr_append(result, enc);
371  octstr_destroy(enc);
372  }
373  break;
374 
375  case 'A':
376  if (request->sms.msgdata) {
377  enc = octstr_duplicate(request->sms.msgdata);
378  octstr_url_encode(enc);
379  octstr_append(result, enc);
380  octstr_destroy(enc);
381  }
382  break;
383 
384  case 'b': /* message payload, URL-encoded */
385  enc = octstr_duplicate(request->sms.msgdata);
386  octstr_url_encode(enc);
387  octstr_append(result, enc);
388  octstr_destroy(enc);
389  break;
390 
391  case 'B': /* billing identifier/information */
392  if (octstr_len(request->sms.binfo)) {
393  enc = octstr_duplicate(request->sms.binfo);
394  octstr_url_encode(enc);
395  octstr_append(result, enc);
396  octstr_destroy(enc);
397  }
398  break;
399 
400  case 'c':
401  octstr_append_decimal(result, request->sms.coding);
402  break;
403 
404  case 'C':
405  if (octstr_len(request->sms.charset)) {
406  octstr_append(result, request->sms.charset);
407  } else {
408  switch (request->sms.coding) {
409  case DC_UNDEF:
410  case DC_7BIT:
411  octstr_append(result, octstr_imm("UTF-8"));
412  break;
413  case DC_8BIT:
414  octstr_append(result, octstr_imm("8-BIT"));
415  break;
416  case DC_UCS2:
417  octstr_append(result, octstr_imm("UTF-16BE"));
418  break;
419  }
420  }
421  break;
422 
423  case 'd':
424  enc = octstr_create("");
425  octstr_append_decimal(enc, request->sms.dlr_mask);
426  octstr_url_encode(enc);
427  octstr_append(result, enc);
428  octstr_destroy(enc);
429  break;
430 
431  case 'D': /* meta_data */
432  if (octstr_len(request->sms.meta_data)) {
433  enc = octstr_duplicate(request->sms.meta_data);
434  octstr_url_encode(enc);
435  octstr_append(result, enc);
436  octstr_destroy(enc);
437  }
438  break;
439 
440  case 'e': /* message payload, printable hexadecimal byte codes */
441  if (octstr_len(request->sms.msgdata)) {
442  enc = octstr_duplicate(request->sms.msgdata);
443  octstr_binary_to_hex(enc, 1);
444  octstr_append(result, enc);
445  octstr_destroy(enc);
446  }
447  break;
448 
449  case 'f': /* smsc number*/
450  if (octstr_len(request->sms.smsc_number)) {
451  enc = octstr_duplicate(request->sms.smsc_number);
452  octstr_url_encode(enc);
453  octstr_append(result, enc);
454  octstr_destroy(enc);
455  }
456  break;
457 
458  case 'F':
459  if (request->sms.foreign_id == NULL)
460  break;
461  enc = octstr_duplicate(request->sms.foreign_id);
462  octstr_url_encode(enc);
463  octstr_append(result, enc);
464  octstr_destroy(enc);
465  break;
466 
467  case 'i':
468  if (request->sms.smsc_id == NULL)
469  break;
470  enc = octstr_duplicate(request->sms.smsc_id);
471  octstr_url_encode(enc);
472  octstr_append(result, enc);
473  octstr_destroy(enc);
474  break;
475 
476  case 'I':
477  if (!uuid_is_null(request->sms.id)) {
478  char id[UUID_STR_LEN + 1];
479  uuid_unparse(request->sms.id, id);
480  octstr_append_cstr(result, id);
481  }
482  break;
483 
484  case 'k':
485  if (num_words <= 0)
486  break;
487  enc = octstr_duplicate(gwlist_get(word_list, 0));
488  octstr_url_encode(enc);
489  octstr_append(result, enc);
490  octstr_destroy(enc);
491  break;
492 
493  case 'm': /* mclass - message class */
494  enc = octstr_create("");
495  octstr_append_decimal(enc, request->sms.mclass);
496  octstr_url_encode(enc);
497  octstr_append(result, enc);
498  octstr_destroy(enc);
499  break;
500 
501  case 'M': /* mwi - message waiting indicator */
502  enc = octstr_create("");
503  octstr_append_decimal(enc, request->sms.mwi);
504  octstr_url_encode(enc);
505  octstr_append(result, enc);
506  octstr_destroy(enc);
507  break;
508 
509  case 'n':
510  if (request->sms.service == NULL)
511  break;
512  enc = octstr_duplicate(request->sms.service);
513  octstr_url_encode(enc);
514  octstr_append(result, enc);
515  octstr_destroy(enc);
516  break;
517 
518  case 'o': /* account information (may be operator id for aggregators */
519  if (octstr_len(request->sms.account)) {
520  enc = octstr_duplicate(request->sms.account);
521  octstr_url_encode(enc);
522  octstr_append(result, enc);
523  octstr_destroy(enc);
524  }
525  break;
526 
527  case 'O': /* DCS */
528  {
529  int dcs;
530  dcs = fields_to_dcs(request, request->sms.alt_dcs);
531  octstr_format_append(result, "%02d", dcs);
532  break;
533  }
534 
535  /* NOTE: the sender and receiver is already switched in
536  * message, so that's why we must use 'sender' when
537  * we want original receiver and vice versa
538  */
539  case 'P':
540  enc = octstr_duplicate(request->sms.sender);
541  octstr_url_encode(enc);
542  octstr_append(result, enc);
543  octstr_destroy(enc);
544  break;
545 
546  case 'p':
547  enc = octstr_duplicate(request->sms.receiver);
548  octstr_url_encode(enc);
549  octstr_append(result, enc);
550  octstr_destroy(enc);
551  break;
552 
553  case 'q':
554  if (strncmp(octstr_get_cstr(request->sms.receiver),"00",2)==0) {
555  enc = octstr_copy(request->sms.receiver, 2,
556  octstr_len(request->sms.receiver));
557  octstr_url_encode(enc);
558  octstr_format_append(result, "%%2B%S", enc);
559  octstr_destroy(enc);
560  } else {
561  enc = octstr_duplicate(request->sms.receiver);
562  octstr_url_encode(enc);
563  octstr_append(result, enc);
564  octstr_destroy(enc);
565  }
566  break;
567 
568  case 'Q':
569  if (strncmp(octstr_get_cstr(request->sms.sender), "00", 2) == 0) {
570  enc = octstr_copy(request->sms.sender, 2,
571  octstr_len(request->sms.sender));
572  octstr_url_encode(enc);
573  octstr_format_append(result, "%%2B%S", enc);
574  octstr_destroy(enc);
575  } else {
576  enc = octstr_duplicate(request->sms.sender);
577  octstr_url_encode(enc);
578  octstr_append(result, enc);
579  octstr_destroy(enc);
580  }
581  break;
582 
583  case 'r':
584  for (j = nextarg; j < num_words; ++j) {
585  enc = octstr_duplicate(gwlist_get(word_list, j));
586  octstr_url_encode(enc);
587  if (j != nextarg)
588  octstr_append_char(result, '+');
589  octstr_append(result, enc);
590  octstr_destroy(enc);
591  }
592  break;
593 
594  case 'R': /* dlr_url */
595  if (octstr_len(request->sms.dlr_url)) {
596  enc = octstr_duplicate(request->sms.dlr_url);
597  octstr_url_encode(enc);
598  octstr_append(result, enc);
599  octstr_destroy(enc);
600  }
601  break;
602 
603  case 's':
604  if (nextarg >= num_words)
605  break;
606  enc = octstr_duplicate(gwlist_get(word_list, nextarg));
607  octstr_url_encode(enc);
608  octstr_append(result, enc);
609  octstr_destroy(enc);
610  ++nextarg;
611  break;
612 
613  case 'S':
614  if (nextarg >= num_words)
615  break;
616  temp = gwlist_get(word_list, nextarg);
617  for (i = 0; i < octstr_len(temp); ++i) {
618  if (octstr_get_char(temp, i) == '*')
619  octstr_append_char(result, '~');
620  else
621  octstr_append_char(result, octstr_get_char(temp, i));
622  }
623  ++nextarg;
624  break;
625 
626  case 't':
627  tm = gw_gmtime(request->sms.time);
628  octstr_format_append(result, "%04d-%02d-%02d+%02d:%02d:%02d",
629  tm.tm_year + 1900,
630  tm.tm_mon + 1,
631  tm.tm_mday,
632  tm.tm_hour,
633  tm.tm_min,
634  tm.tm_sec);
635  break;
636 
637  case 'T':
638  if (request->sms.time == MSG_PARAM_UNDEFINED)
639  break;
640  octstr_format_append(result, "%ld", request->sms.time);
641  break;
642 
643  case 'u':
644  if(octstr_len(request->sms.udhdata)) {
645  enc = octstr_duplicate(request->sms.udhdata);
646  octstr_url_encode(enc);
647  octstr_append(result, enc);
648  octstr_destroy(enc);
649  }
650  break;
651 
652  case 'v':
653  if (request->sms.validity != MSG_PARAM_UNDEFINED) {
654  octstr_format_append(result, "%ld", (request->sms.validity - time(NULL)) / 60);
655  }
656  break;
657 
658  case 'V':
659  if (request->sms.deferred != MSG_PARAM_UNDEFINED) {
660  octstr_format_append(result, "%ld", (request->sms.deferred - time(NULL)) / 60);
661  }
662  break;
663 
664  /*
665  * This allows to pass meta-data individual parameters into urls.
666  * The syntax is as follows: %#group#parameter#
667  * For example: %#smpp#my_param# would be replaced with the value
668  * 'my_param' from the group 'smpp' coming inside the meta_data field.
669  */
670  case '#':
671  /* ASCII 0x23 == '#' */
672  k = octstr_search_char(pattern, 0x23, pos + 2);
673  if (k >= 0) {
674  pos += 2;
675  meta_group = octstr_copy(pattern, pos, (k-pos));
676  pos = k + 1;
677  k = octstr_search_char(pattern, 0x23, pos);
678  if (k >= 0) {
679  meta_param = octstr_copy(pattern, pos, (k-pos));
680  pos = k - 1;
681  if (request->sms.meta_data != NULL) {
682  enc = meta_data_get_value(request->sms.meta_data,
683  octstr_get_cstr(meta_group), meta_param);
684  octstr_url_encode(enc);
685  octstr_append(result, enc);
686  octstr_destroy(enc);
687  }
688  octstr_destroy(meta_param);
689  } else {
690  pos++;
691  }
692  octstr_destroy(meta_group);
693  }
694  break;
695 
696  /* XXX sms.parameters not present in here:
697  * * pid - will we receive this ?
698  * * alt-dcs - shouldn't be required unless we want to inform
699  * which alt-dcs external server should use back
700  * * compress - if we use compression, probably kannel would
701  * decompress and reset this to 0. not required
702  * * rpi - we don't receive these from smsc
703  * * username, password, dlr-url, account - nonsense to send
704  */
705  case '%':
706  octstr_format_append(result, "%%");
707  break;
708 
709  default:
710  octstr_format_append(result, "%%%c",
711  octstr_get_char(pattern, pos + 1));
712  break;
713  }
714 
715  pos += 2;
716  }
717 
718  gwlist_destroy(word_list, octstr_destroy_item);
719 
720  return result;
721 }
722 
723 
724 /*
725  * Trans being NULL means that we are servicing ppg (doing dlr, but this does not
726  * concern us here).
727  */
729 {
730  Octstr *result, *pattern;
731 
732  if (request->sms.sms_type != report_mo && t->type == TRANSTYPE_SENDSMS)
733  return octstr_create("");
734 
735  /* check if this is a delivery report message or not */
736  if (request->sms.sms_type != report_mo) {
737  pattern = t->pattern;
738  } else {
739  /* this is a DLR message */
740  pattern = request->sms.dlr_url;
741  if (octstr_len(pattern) == 0) {
742  if (t && octstr_len(t->dlr_url)) {
743  pattern = t->dlr_url;
744  } else {
745  return octstr_create("");
746  }
747  }
748  }
749 
750  /* We have pulled this out into an own exported function. This
751  * gives other modules the chance to use the same escape code
752  * semantics for Msgs. */
753  result = urltrans_fill_escape_codes(pattern, request);
754 
755  /*
756  * this SHOULD be done in smsbox, not here, but well,
757  * much easier to do here
758  */
759  if (t && (t->type == TRANSTYPE_POST_URL || t->type == TRANSTYPE_POST_XML)
760  && t->strip_keyword)
761  strip_keyword(request);
762 
763  return result;
764 }
765 
766 
768 {
769  return t->type;
770 }
771 
773 {
774  return t->prefix;
775 }
776 
778 {
779  return t->suffix;
780 }
781 
783 {
784  return t->default_sender;
785 }
786 
788 {
789  return t->faked_sender;
790 }
791 
793 {
794  return t->max_messages;
795 }
796 
798 {
799  return t->concatenation;
800 }
801 
803 {
804  return t->split_chars;
805 }
806 
808 {
809  return t->split_suffix;
810 }
811 
813 {
814  return t->omit_empty;
815 }
816 
818 {
819  return t->header;
820 }
821 
823 {
824  return t->footer;
825 }
826 
828 {
829  return t->alt_charset;
830 }
831 
833 {
834  return t->name;
835 }
836 
838 {
839  return t->username;
840 }
841 
843 {
844  return t->password;
845 }
846 
848 {
849  return t->forced_smsc;
850 }
851 
853 {
854  return t->default_smsc;
855 }
856 
858 {
859  return t->allow_ip;
860 }
861 
863 {
864  return t->deny_ip;
865 }
866 
868 {
869  return t->allowed_prefix;
870 }
871 
873 {
874  return t->denied_prefix;
875 }
876 
878 {
879  return t->allowed_recv_prefix;
880 }
881 
883 {
884  return t->denied_recv_prefix;
885 }
886 
888 {
889  return t->white_list;
890 }
891 
893 {
894  return t->white_list_regex;
895 }
896 
898 {
899  return t->black_list;
900 }
901 
903 {
904  return t->black_list_regex;
905 }
906 
908 {
909  return t->assume_plain_text;
910 }
911 
913 {
914  return t->accept_x_kannel_headers;
915 }
916 
918 {
919  return t->strip_keyword;
920 }
921 
923 {
924  return t->send_sender;
925 }
926 
928 {
929  return t->dlr_url;
930 }
931 
933 {
934  return t->dlr_mask;
935 }
936 
937 
938 /***********************************************************************
939  * Internal functions.
940  */
941 
942 
943 /*
944  * Create one URLTranslation. Return NULL for failure, pointer to it for OK.
945  */
947 {
948  URLTranslation *ot;
949  Octstr *url, *post_url, *post_xml, *text, *file, *exec;
950  Octstr *accepted_smsc, *accepted_account, *forced_smsc, *default_smsc;
951  Octstr *grpname;
952  int is_sms_service, regex_flag = REG_EXTENDED;
953  Octstr *accepted_smsc_regex;
954  Octstr *accepted_account_regex;
955  Octstr *allowed_prefix_regex;
956  Octstr *denied_prefix_regex;
957  Octstr *allowed_receiver_prefix_regex;
958  Octstr *denied_receiver_prefix_regex;
961  Octstr *keyword_regex;
962  Octstr *os, *tmp;
963 
964  grpname = cfg_get_group_name(grp);
965  if (grpname == NULL)
966  return NULL;
967 
968  if (octstr_str_compare(grpname, "sms-service") == 0)
969  is_sms_service = 1;
970  else if (octstr_str_compare(grpname, "sendsms-user") == 0)
971  is_sms_service = 0;
972  else {
973  octstr_destroy(grpname);
974  return NULL;
975  }
976  octstr_destroy(grpname);
977 
978  ot = gw_malloc(sizeof(URLTranslation));
979  memset(ot, 0, sizeof(*ot));
980 
981  if (is_sms_service) {
982  cfg_get_bool(&ot->catch_all, grp, octstr_imm("catch-all"));
983 
984  ot->dlr_url = cfg_get(grp, octstr_imm("dlr-url"));
985  if (cfg_get_integer(&ot->dlr_mask, grp, octstr_imm("dlr-mask")) == -1)
986  ot->dlr_mask = DLR_UNDEFINED;
987  ot->alt_charset = cfg_get(grp, octstr_imm("alt-charset"));
988 
989  url = cfg_get(grp, octstr_imm("get-url"));
990  if (url == NULL)
991  url = cfg_get(grp, octstr_imm("url"));
992 
993  post_url = cfg_get(grp, octstr_imm("post-url"));
994  post_xml = cfg_get(grp, octstr_imm("post-xml"));
995  file = cfg_get(grp, octstr_imm("file"));
996  text = cfg_get(grp, octstr_imm("text"));
997  exec = cfg_get(grp, octstr_imm("exec"));
998  if (url != NULL) {
999  ot->type = TRANSTYPE_GET_URL;
1000  ot->pattern = octstr_duplicate(url);
1001  } else if (post_url != NULL) {
1002  ot->type = TRANSTYPE_POST_URL;
1003  ot->pattern = octstr_duplicate(post_url);
1004  ot->catch_all = 1;
1005  } else if (post_xml != NULL) {
1006  ot->type = TRANSTYPE_POST_XML;
1007  ot->pattern = octstr_duplicate(post_xml);
1008  ot->catch_all = 1;
1009  } else if (file != NULL) {
1010  ot->type = TRANSTYPE_FILE;
1011  ot->pattern = octstr_duplicate(file);
1012  } else if (text != NULL) {
1013  ot->type = TRANSTYPE_TEXT;
1014  ot->pattern = octstr_duplicate(text);
1015  } else if (exec != NULL) {
1016  ot->type = TRANSTYPE_EXECUTE;
1017  ot->pattern = octstr_duplicate(exec);
1018  } else {
1019  octstr_destroy(url);
1020  octstr_destroy(post_url);
1021  octstr_destroy(post_xml);
1022  octstr_destroy(file);
1023  octstr_destroy(text);
1024  octstr_destroy(exec);
1025  error(0, "Configuration group `sms-service' "
1026  "did not specify get-url, post-url, post-xml, file or text.");
1027  goto error;
1028  }
1029  octstr_destroy(url);
1030  octstr_destroy(post_url);
1031  octstr_destroy(post_xml);
1032  octstr_destroy(file);
1033  octstr_destroy(text);
1034  octstr_destroy(exec);
1035 
1036  tmp = cfg_get(grp, octstr_imm("keyword"));
1037  keyword_regex = cfg_get(grp, octstr_imm("keyword-regex"));
1038  if (tmp == NULL && keyword_regex == NULL) {
1039  error(0, "Group 'sms-service' must include either 'keyword' or 'keyword-regex'.");
1040  goto error;
1041  }
1042  if (tmp != NULL && keyword_regex != NULL) {
1043  error(0, "Group 'sms-service' may inlcude either 'keyword' or 'keyword-regex'.");
1044  octstr_destroy(tmp);
1045  octstr_destroy(keyword_regex);
1046  goto error;
1047  }
1048 
1049  if (tmp != NULL && octstr_str_compare(tmp, "default") == 0) {
1050  /* default sms-service */
1051  ot->keyword_regex = NULL;
1052  octstr_destroy(tmp);
1053  } else if (tmp != NULL) {
1054  Octstr *aliases;
1055 
1056  /* convert to regex */
1057  regex_flag |= REG_ICASE;
1058  keyword_regex = octstr_format("^[ ]*(%S", tmp);
1059  octstr_destroy(tmp);
1060 
1061  aliases = cfg_get(grp, octstr_imm("aliases"));
1062  if (aliases != NULL) {
1063  long i;
1064  List *l;
1065 
1066  l = octstr_split(aliases, octstr_imm(";"));
1067  octstr_destroy(aliases);
1068 
1069  for (i = 0; i < gwlist_len(l); ++i) {
1070  os = gwlist_get(l, i);
1071  octstr_format_append(keyword_regex, "|%S", os);
1072  }
1074  }
1075 
1076  octstr_append_cstr(keyword_regex, ")[ ]*");
1077  }
1078 
1079  if (keyword_regex != NULL && (ot->keyword_regex = gw_regex_comp(keyword_regex, regex_flag)) == NULL) {
1080  error(0, "Could not compile pattern '%s'", octstr_get_cstr(keyword_regex));
1081  octstr_destroy(keyword_regex);
1082  goto error;
1083  }
1084 
1085  ot->name = cfg_get(grp, octstr_imm("name"));
1086  if (ot->name == NULL)
1087  ot->name = keyword_regex ? octstr_duplicate(keyword_regex) : octstr_create("default");
1088  octstr_destroy(keyword_regex);
1089 
1090  accepted_smsc = cfg_get(grp, octstr_imm("accepted-smsc"));
1091  if (accepted_smsc != NULL) {
1092  ot->accepted_smsc = octstr_split(accepted_smsc, octstr_imm(";"));
1093  octstr_destroy(accepted_smsc);
1094  }
1095  accepted_account = cfg_get(grp, octstr_imm("accepted-account"));
1096  if (accepted_account != NULL) {
1097  ot->accepted_account = octstr_split(accepted_account, octstr_imm(";"));
1098  octstr_destroy(accepted_account);
1099  }
1100  accepted_smsc_regex = cfg_get(grp, octstr_imm("accepted-smsc-regex"));
1101  if (accepted_smsc_regex != NULL) {
1102  if ( (ot->accepted_smsc_regex = gw_regex_comp(accepted_smsc_regex, REG_EXTENDED)) == NULL)
1103  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(accepted_smsc_regex));
1104  octstr_destroy(accepted_smsc_regex);
1105  }
1106  accepted_account_regex = cfg_get(grp, octstr_imm("accepted-account-regex"));
1107  if (accepted_account_regex != NULL) {
1108  if ( (ot->accepted_account_regex = gw_regex_comp(accepted_account_regex, REG_EXTENDED)) == NULL)
1109  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(accepted_account_regex));
1110  octstr_destroy(accepted_account_regex);
1111  }
1112 
1113  cfg_get_bool(&ot->assume_plain_text, grp,
1114  octstr_imm("assume-plain-text"));
1116  octstr_imm("accept-x-kannel-headers"));
1117  cfg_get_bool(&ot->strip_keyword, grp, octstr_imm("strip-keyword"));
1118  cfg_get_bool(&ot->send_sender, grp, octstr_imm("send-sender"));
1119 
1120  ot->prefix = cfg_get(grp, octstr_imm("prefix"));
1121  ot->suffix = cfg_get(grp, octstr_imm("suffix"));
1122  ot->allowed_recv_prefix = cfg_get(grp, octstr_imm("allowed-receiver-prefix"));
1123  allowed_receiver_prefix_regex = cfg_get(grp, octstr_imm("allowed-receiver-prefix-regex"));
1124  if (allowed_receiver_prefix_regex != NULL) {
1125  if ((ot->allowed_receiver_prefix_regex = gw_regex_comp(allowed_receiver_prefix_regex, REG_EXTENDED)) == NULL)
1126  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(allowed_receiver_prefix_regex));
1127  octstr_destroy(allowed_receiver_prefix_regex);
1128  }
1129 
1130  ot->allowed_recv_prefix = cfg_get(grp, octstr_imm("allowed-receiver-prefix"));
1131  ot->denied_recv_prefix = cfg_get(grp, octstr_imm("denied-receiver-prefix"));
1132  denied_receiver_prefix_regex = cfg_get(grp, octstr_imm("denied-receiver-prefix-regex"));
1133  if (denied_receiver_prefix_regex != NULL) {
1134  if ((ot->denied_receiver_prefix_regex = gw_regex_comp(denied_receiver_prefix_regex, REG_EXTENDED)) == NULL)
1135  panic(0, "Could not compile pattern '%s'",octstr_get_cstr(denied_receiver_prefix_regex));
1136  octstr_destroy(denied_receiver_prefix_regex);
1137  }
1138 
1139  ot->args = count_occurences(ot->pattern, octstr_imm("%s"));
1140  ot->args += count_occurences(ot->pattern, octstr_imm("%S"));
1141  ot->has_catchall_arg =
1142  (count_occurences(ot->pattern, octstr_imm("%r")) > 0) ||
1143  (count_occurences(ot->pattern, octstr_imm("%a")) > 0);
1144 
1145  } else {
1146  ot->type = TRANSTYPE_SENDSMS;
1147  ot->pattern = octstr_create("");
1148  ot->args = 0;
1149  ot->has_catchall_arg = 0;
1150  ot->catch_all = 1;
1151  ot->username = cfg_get(grp, octstr_imm("username"));
1152  ot->password = cfg_get(grp, octstr_imm("password"));
1153  ot->dlr_url = cfg_get(grp, octstr_imm("dlr-url"));
1154  grp_dump(grp);
1155  if (ot->password == NULL) {
1156  error(0, "Password required for send-sms user");
1157  goto error;
1158  }
1159  ot->name = cfg_get(grp, octstr_imm("name"));
1160  if (ot->name == NULL)
1161  ot->name = octstr_duplicate(ot->username);
1162 
1163  forced_smsc = cfg_get(grp, octstr_imm("forced-smsc"));
1164  default_smsc = cfg_get(grp, octstr_imm("default-smsc"));
1165  if (forced_smsc != NULL) {
1166  if (default_smsc != NULL) {
1167  info(0, "Redundant default-smsc for send-sms user %s",
1168  octstr_get_cstr(ot->username));
1169  }
1170  ot->forced_smsc = forced_smsc;
1171  octstr_destroy(default_smsc);
1172  } else if (default_smsc != NULL)
1173  ot->default_smsc = default_smsc;
1174 
1175  ot->deny_ip = cfg_get(grp, octstr_imm("user-deny-ip"));
1176  ot->allow_ip = cfg_get(grp, octstr_imm("user-allow-ip"));
1177  ot->default_sender = cfg_get(grp, octstr_imm("default-sender"));
1178  }
1179 
1180  ot->allowed_prefix = cfg_get(grp, octstr_imm("allowed-prefix"));
1181  allowed_prefix_regex = cfg_get(grp, octstr_imm("allowed-prefix-regex"));
1182  if (allowed_prefix_regex != NULL) {
1183  if ((ot->allowed_prefix_regex = gw_regex_comp(allowed_prefix_regex, REG_EXTENDED)) == NULL)
1184  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(allowed_prefix_regex));
1185  octstr_destroy(allowed_prefix_regex);
1186  }
1187  ot->denied_prefix = cfg_get(grp, octstr_imm("denied-prefix"));
1188  denied_prefix_regex = cfg_get(grp, octstr_imm("denied-prefix-regex"));
1189  if (denied_prefix_regex != NULL) {
1190  if ((ot->denied_prefix_regex = gw_regex_comp(denied_prefix_regex, REG_EXTENDED)) == NULL)
1191  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(denied_prefix_regex));
1192  octstr_destroy(denied_prefix_regex);
1193  }
1194 
1195  os = cfg_get(grp, octstr_imm("white-list"));
1196  if (os != NULL) {
1198  octstr_destroy(os);
1199  }
1200  white_list_regex = cfg_get(grp, octstr_imm("white-list-regex"));
1201  if (white_list_regex != NULL) {
1202  if ((ot->white_list_regex = gw_regex_comp(white_list_regex, REG_EXTENDED)) == NULL)
1203  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(white_list_regex));
1204  octstr_destroy(white_list_regex);
1205  }
1206 
1207  os = cfg_get(grp, octstr_imm("black-list"));
1208  if (os != NULL) {
1210  octstr_destroy(os);
1211  }
1212  black_list_regex = cfg_get(grp, octstr_imm("black-list-regex"));
1213  if (black_list_regex != NULL) {
1214  if ((ot->black_list_regex = gw_regex_comp(black_list_regex, REG_EXTENDED)) == NULL)
1215  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(black_list_regex));
1216  octstr_destroy(black_list_regex);
1217  }
1218 
1219  if (cfg_get_integer(&ot->max_messages, grp, octstr_imm("max-messages")) == -1)
1220  ot->max_messages = 1;
1221  cfg_get_bool(&ot->concatenation, grp, octstr_imm("concatenation"));
1222  cfg_get_bool(&ot->omit_empty, grp, octstr_imm("omit-empty"));
1223 
1224  ot->header = cfg_get(grp, octstr_imm("header"));
1225  ot->footer = cfg_get(grp, octstr_imm("footer"));
1226  ot->faked_sender = cfg_get(grp, octstr_imm("faked-sender"));
1227  ot->split_chars = cfg_get(grp, octstr_imm("split-chars"));
1228  ot->split_suffix = cfg_get(grp, octstr_imm("split-suffix"));
1229 
1230  if ( (ot->prefix == NULL && ot->suffix != NULL) ||
1231  (ot->prefix != NULL && ot->suffix == NULL) ) {
1232  warning(0, "Service : suffix and prefix are only used"
1233  " if both are set.");
1234  }
1235  if ((ot->prefix != NULL || ot->suffix != NULL) &&
1236  ot->type != TRANSTYPE_GET_URL) {
1237  warning(0, "Service : suffix and prefix are only used"
1238  " if type is 'get-url'.");
1239  }
1240 
1241  return ot;
1242 
1243 error:
1244  error(0, "Couldn't create a URLTranslation.");
1245  destroy_onetrans(ot);
1246  return NULL;
1247 }
1248 
1249 
1250 /*
1251  * Free one URLTranslation.
1252  */
1253 static void destroy_onetrans(void *p)
1254 {
1255  URLTranslation *ot;
1256 
1257  ot = p;
1258  if (ot != NULL) {
1259  octstr_destroy(ot->dlr_url);
1260  octstr_destroy(ot->pattern);
1261  octstr_destroy(ot->prefix);
1262  octstr_destroy(ot->suffix);
1267  octstr_destroy(ot->header);
1268  octstr_destroy(ot->footer);
1272  octstr_destroy(ot->name);
1273  octstr_destroy(ot->username);
1274  octstr_destroy(ot->password);
1277  octstr_destroy(ot->allow_ip);
1278  octstr_destroy(ot->deny_ip);
1285  if (ot->keyword_regex != NULL) gw_regex_destroy(ot->keyword_regex);
1286  if (ot->accepted_smsc_regex != NULL) gw_regex_destroy(ot->accepted_smsc_regex);
1287  if (ot->accepted_account_regex != NULL) gw_regex_destroy(ot->accepted_account_regex);
1288  if (ot->allowed_prefix_regex != NULL) gw_regex_destroy(ot->allowed_prefix_regex);
1289  if (ot->denied_prefix_regex != NULL) gw_regex_destroy(ot->denied_prefix_regex);
1290  if (ot->allowed_receiver_prefix_regex != NULL) gw_regex_destroy(ot->allowed_receiver_prefix_regex);
1291  if (ot->denied_receiver_prefix_regex != NULL) gw_regex_destroy(ot->denied_receiver_prefix_regex);
1292  if (ot->white_list_regex != NULL) gw_regex_destroy(ot->white_list_regex);
1293  if (ot->black_list_regex != NULL) gw_regex_destroy(ot->black_list_regex);
1294  gw_free(ot);
1295  }
1296 }
1297 
1298 
1299 /*
1300  * checks if the number of passed words matches the service-pattern defined in the
1301  * translation. returns 0 if arguments are okay, -1 otherwise.
1302  */
1303 static int check_num_args(URLTranslation *t, List *words)
1304 {
1305  const int IS_OKAY = 0;
1306  const int NOT_OKAY = -1;
1307  int n;
1308 
1309 
1310  n = gwlist_len(words);
1311  /* check number of arguments */
1312  if (t->catch_all)
1313  return IS_OKAY;
1314 
1315  if (n - 1 == t->args)
1316  return IS_OKAY;
1317 
1318  if (t->has_catchall_arg && n - 1 >= t->args)
1319  return IS_OKAY;
1320 
1321  return NOT_OKAY;
1322 }
1323 
1324 /*
1325  * checks if a request matches the parameters of a URL-Translation, e.g. whether or not
1326  * a user is allowed to use certain services. returns 0 if allowed, -1 if not.
1327  */
1329  Octstr *smsc, Octstr *sender, Octstr *receiver, Octstr *account)
1330 {
1331  const int IS_ALLOWED = 0;
1332  const int NOT_ALLOWED = -1;
1333 
1334  /* if smsc_id set and accepted_smsc exist, accept
1335  * translation only if smsc id is in accept string
1336  */
1337  if (smsc && t->accepted_smsc && !gwlist_search(t->accepted_smsc, smsc, octstr_item_match))
1338  return NOT_ALLOWED;
1339 
1340  if (smsc && t->accepted_smsc_regex && gw_regex_match_pre( t->accepted_smsc_regex, smsc) == 0)
1341  return NOT_ALLOWED;
1342 
1343  /* if account_id set and accepted_account exist, accept
1344  * translation only if smsc id is in accept string
1345  */
1346  if (account && t->accepted_account && !gwlist_search(t->accepted_account, account, octstr_item_match))
1347  return NOT_ALLOWED;
1348 
1349  if (account && t->accepted_account_regex && gw_regex_match_pre( t->accepted_account_regex, account) == 0)
1350  return NOT_ALLOWED;
1351 
1352  /* Have allowed for sender */
1353  if (t->allowed_prefix && !t->denied_prefix && does_prefix_match(t->allowed_prefix, sender) != 1)
1354  return NOT_ALLOWED;
1355 
1356  if (t->allowed_prefix_regex && !t->denied_prefix_regex && gw_regex_match_pre(t->allowed_prefix_regex, sender) == 0)
1357  return NOT_ALLOWED;
1358 
1359  /* Have denied for sender */
1360  if (t->denied_prefix && !t->allowed_prefix && does_prefix_match(t->denied_prefix, sender) == 1)
1361  return NOT_ALLOWED;
1362 
1363  if (t->denied_prefix_regex && !t->allowed_prefix_regex && gw_regex_match_pre(t->denied_prefix_regex, sender) == 1)
1364  return NOT_ALLOWED;
1365 
1366  /* Have allowed for receiver */
1368  return NOT_ALLOWED;
1369 
1371  gw_regex_match_pre(t->allowed_receiver_prefix_regex, receiver) == 0)
1372  return NOT_ALLOWED;
1373 
1374  /* Have denied for receiver */
1375  if (t->denied_recv_prefix && !t->allowed_recv_prefix && does_prefix_match(t->denied_recv_prefix, receiver) == 1)
1376  return NOT_ALLOWED;
1377 
1379  gw_regex_match_pre(t->denied_receiver_prefix_regex, receiver) == 0)
1380  return NOT_ALLOWED;
1381 
1382  if (t->white_list && numhash_find_number(t->white_list, sender) < 1) {
1383  return NOT_ALLOWED;
1384  }
1385 
1386  if (t->white_list_regex && gw_regex_match_pre(t->white_list_regex, sender) == 0) {
1387  return NOT_ALLOWED;
1388  }
1389 
1390  if (t->black_list && numhash_find_number(t->black_list, sender) == 1) {
1391  return NOT_ALLOWED;
1392  }
1393 
1394  if (t->black_list_regex && gw_regex_match_pre(t->black_list_regex, sender) == 1) {
1395  return NOT_ALLOWED;
1396  }
1397 
1398  /* Have allowed and denied */
1399  if (t->denied_prefix && t->allowed_prefix && does_prefix_match(t->allowed_prefix, sender) != 1 &&
1400  does_prefix_match(t->denied_prefix, sender) == 1)
1401  return NOT_ALLOWED;
1402 
1404  gw_regex_match_pre(t->allowed_prefix_regex, sender) == 0 &&
1405  gw_regex_match_pre(t->denied_prefix_regex, sender) == 1)
1406  return NOT_ALLOWED;
1407 
1408  return IS_ALLOWED;
1409 };
1410 
1411 
1412 /* get_matching_translations - iterate over all translations in trans.
1413  * for each translation check whether
1414  * the translation's keyword has already been interpreted as a regexp.
1415  * if not, compile it now,
1416  * otherwise retrieve compilation result from dictionary.
1417  *
1418  * the translations where the word matches the translation's pattern
1419  * are returned in a list
1420  *
1421  */
1423 {
1424  List *list;
1425  long i;
1426  URLTranslation *t;
1427 
1428  gw_assert(trans != NULL && msg != NULL);
1429 
1430  list = gwlist_create();
1431  for (i = 0; i < gwlist_len(trans->list); ++i) {
1432  t = gwlist_get(trans->list, i);
1433 
1434  if (t->keyword_regex == NULL)
1435  continue;
1436 
1437  if (gw_regex_match_pre(t->keyword_regex, msg) == 1) {
1438  debug("", 0, "match found: %s", octstr_get_cstr(t->name));
1439  gwlist_append(list, t);
1440  } else {
1441  debug("", 0, "no match found: %s", octstr_get_cstr(t->name));
1442  }
1443  }
1444 
1445  return list;
1446 }
1447 
1448 /*
1449  * Find the appropriate translation
1450  */
1452 {
1453  Octstr *data;
1454  int i;
1455  URLTranslation *t = NULL;
1456  List *list, *words;
1457 
1458  /* convert tolower and try to match */
1459  data = octstr_duplicate(msg->sms.msgdata);
1460  i = 0;
1461  while((i = octstr_search_char(data, 0, i)) != -1 && i < octstr_len(data) - 1) {
1462  octstr_delete(data, i, 1);
1463  }
1464 
1465  list = get_matching_translations(trans, data);
1466  words = octstr_split_words(data);
1467 
1472  for (i = 0; i < gwlist_len(list); ++i) {
1473  t = gwlist_get(list, i);
1474 
1475  /* TODO check_num_args, do we really need this??? */
1476  if (check_allowed_translation(t, msg->sms.smsc_id, msg->sms.sender, msg->sms.receiver, msg->sms.account) == 0
1477  && check_num_args(t, words) == 0)
1478  break;
1479 
1480  t = NULL;
1481  }
1482 
1483  octstr_destroy(data);
1485  gwlist_destroy(list, NULL);
1486 
1487  return t;
1488 }
1489 
1490 
1492  Octstr *smsc, Octstr *sender, Octstr *receiver,
1493  Octstr *account)
1494 {
1495  URLTranslation *t;
1496  int i;
1497  List *list;
1498 
1499  list = trans->defaults;
1500  t = NULL;
1501  for (i = 0; i < gwlist_len(list); ++i) {
1502  t = gwlist_get(list, i);
1503 
1504  if (check_allowed_translation(t, smsc, sender, receiver, account) == 0)
1505  break;
1506 
1507  t = NULL;
1508  }
1509 
1510  return t;
1511 }
1512 
1513 /*
1514  * Count the number of times `pat' occurs in `str'.
1515  */
1516 static long count_occurences(Octstr *str, Octstr *pat)
1517 {
1518  long count;
1519  long pos;
1520  long len;
1521 
1522  count = 0;
1523  pos = 0;
1524  len = octstr_len(pat);
1525  while ((pos = octstr_search(str, pat, pos)) != -1) {
1526  ++count;
1527  pos += len;
1528  }
1529  return count;
1530 }
1531 
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
int has_catchall_arg
Definition: urltrans.c:129
int urltrans_add_cfg(URLTranslationList *trans, Cfg *cfg)
Definition: urltrans.c:228
regex_t * urltrans_black_list_regex(URLTranslation *t)
Definition: urltrans.c:902
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
Octstr * urltrans_deny_ip(URLTranslation *t)
Definition: urltrans.c:862
URLTranslation * urltrans_find(URLTranslationList *trans, Msg *msg)
Definition: urltrans.c:255
Octstr * urltrans_suffix(URLTranslation *t)
Definition: urltrans.c:777
regex_t * accepted_smsc_regex
Definition: urltrans.c:135
static long count_occurences(Octstr *str, Octstr *pat)
Definition: urltrans.c:1516
Octstr * urltrans_allowed_recv_prefix(URLTranslation *t)
Definition: urltrans.c:877
Octstr * urltrans_forced_smsc(URLTranslation *t)
Definition: urltrans.c:847
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:486
Octstr * urltrans_alt_charset(URLTranslation *t)
Definition: urltrans.c:827
Numhash * urltrans_black_list(URLTranslation *t)
Definition: urltrans.c:897
regex_t * allowed_prefix_regex
Definition: urltrans.c:137
regex_t * urltrans_white_list_regex(URLTranslation *t)
Definition: urltrans.c:892
Octstr * allowed_prefix
Definition: urltrans.c:116
Octstr * urltrans_footer(URLTranslation *t)
Definition: urltrans.c:822
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
int accept_x_kannel_headers
Definition: urltrans.c:124
void gwlist_append(List *list, void *item)
Definition: list.c:179
Octstr * urltrans_default_smsc(URLTranslation *t)
Definition: urltrans.c:852
Octstr * urltrans_password(URLTranslation *t)
Definition: urltrans.c:842
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
struct tm gw_gmtime(time_t t)
Definition: protected.c:137
Definition: msg.h:109
List * accepted_account
Definition: urltrans.c:105
long gwlist_len(List *list)
Definition: list.c:166
Octstr * urltrans_allowed_prefix(URLTranslation *t)
Definition: urltrans.c:867
Octstr * urltrans_split_chars(URLTranslation *t)
Definition: urltrans.c:802
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * urltrans_faked_sender(URLTranslation *t)
Definition: urltrans.c:787
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1515
int concatenation
Definition: urltrans.c:96
Octstr * denied_prefix
Definition: urltrans.c:117
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1068
#define cfg_get(grp, varname)
Definition: cfg.h:86
static Octstr * default_smsc(WAPPushUser *u)
Octstr * allowed_recv_prefix
Definition: urltrans.c:118
#define DC_8BIT
Definition: sms.h:111
void uuid_unparse(const uuid_t uu, char *out)
Definition: gw_uuid.c:561
Octstr * urltrans_dlr_url(URLTranslation *t)
Definition: urltrans.c:927
Octstr * meta_data_get_value(Octstr *data, const char *group, const Octstr *key)
Definition: meta_data.c:368
Octstr * urltrans_username(URLTranslation *t)
Definition: urltrans.c:837
void numhash_destroy(Numhash *table)
Definition: numhash.c:275
void octstr_append_cstr(Octstr *ostr, const char *cstr)
Definition: octstr.c:1509
Octstr * urltrans_denied_prefix(URLTranslation *t)
Definition: urltrans.c:872
static regex_t * black_list_regex
Definition: smsbox.c:139
regex_t * white_list_regex
Definition: urltrans.c:141
Octstr * username
Definition: urltrans.c:109
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
void octstr_binary_to_hex(Octstr *ostr, int uppercase)
Definition: octstr.c:463
int urltrans_assume_plain_text(URLTranslation *t)
Definition: urltrans.c:907
regex_t * allowed_receiver_prefix_regex
Definition: urltrans.c:139
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
FILE * file
Definition: log.c:133
Numhash * numhash_create(const char *seek_url)
Definition: numhash.c:313
static int check_num_args(URLTranslation *t, List *words)
Definition: urltrans.c:1303
Octstr * urltrans_header(URLTranslation *t)
Definition: urltrans.c:817
Octstr * default_sender
Definition: urltrans.c:94
static void strip_keyword(Msg *request)
Definition: urltrans.c:304
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Definition: msg.h:79
Octstr * split_chars
Definition: urltrans.c:97
Definition: cfg.c:164
int does_prefix_match(Octstr *prefix, Octstr *number)
Definition: utils.c:850
int numhash_find_number(Numhash *table, Octstr *nro)
Definition: numhash.c:218
static regex_t * white_list_regex
Definition: smsbox.c:138
int urltrans_dlr_mask(URLTranslation *t)
Definition: urltrans.c:932
Octstr * dlr_url
Definition: urltrans.c:131
void * gwlist_extract_first(List *list)
Definition: list.c:305
void grp_dump(CfgGroup *grp)
Definition: cfg.c:808
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
char * text
Definition: smsc_cimd2.c:921
int uuid_is_null(const uuid_t uu)
Definition: gw_uuid.c:412
Octstr * urltrans_fill_escape_codes(Octstr *pattern, Msg *request)
Definition: urltrans.c:323
Definition: dict.c:116
#define octstr_duplicate(ostr)
Definition: octstr.h:187
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:642
static URLTranslation * create_onetrans(CfgGroup *grp)
Definition: urltrans.c:946
int octstr_item_match(void *item, void *pattern)
Definition: octstr.c:1659
char * name
Definition: smsc_cimd2.c:212
void warning(int err, const char *fmt,...)
Definition: log.c:624
List * octstr_split_words(const Octstr *ostr)
Definition: octstr.c:1600
Octstr * urltrans_default_sender(URLTranslation *t)
Definition: urltrans.c:782
Octstr * prefix
Definition: urltrans.c:91
int omit_empty
Definition: urltrans.c:99
int urltrans_add_one(URLTranslationList *trans, CfgGroup *grp)
Definition: urltrans.c:203
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
int urltrans_omit_empty(URLTranslation *t)
Definition: urltrans.c:812
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:334
int fields_to_dcs(Msg *msg, int mode)
Definition: sms.c:73
Octstr * urltrans_split_suffix(URLTranslation *t)
Definition: urltrans.c:807
gw_assert(wtls_machine->packet_to_send!=NULL)
int urltrans_send_sender(URLTranslation *t)
Definition: urltrans.c:922
int strip_keyword
Definition: urltrans.c:125
int urltrans_type(URLTranslation *t)
Definition: urltrans.c:767
int urltrans_accept_x_kannel_headers(URLTranslation *t)
Definition: urltrans.c:912
#define UUID_STR_LEN
Definition: gw_uuid.h:19
Octstr * default_smsc
Definition: urltrans.c:112
Octstr * urltrans_denied_recv_prefix(URLTranslation *t)
Definition: urltrans.c:882
Octstr * allow_ip
Definition: urltrans.c:113
Octstr * pattern
Definition: urltrans.c:90
Numhash * urltrans_white_list(URLTranslation *t)
Definition: urltrans.c:887
Octstr * urltrans_allow_ip(URLTranslation *t)
Definition: urltrans.c:857
static Cfg * cfg
Definition: smsbox.c:115
#define DLR_UNDEFINED
Definition: dlr.h:70
Octstr * cfg_get_group_name(CfgGroup *grp)
Definition: cfg.c:658
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Numhash * black_list
Definition: urltrans.c:121
void dict_destroy(Dict *dict)
Definition: dict.c:215
regex_t * denied_receiver_prefix_regex
Definition: urltrans.c:140
regex_t * accepted_account_regex
Definition: urltrans.c:136
Octstr * split_suffix
Definition: urltrans.c:98
void octstr_append_decimal(Octstr *ostr, long value)
Definition: octstr.c:1974
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:756
Definition: octstr.c:118
Octstr * deny_ip
Definition: urltrans.c:115
URLTranslationList * urltrans_create(void)
Definition: urltrans.c:182
static int check_allowed_translation(URLTranslation *t, Octstr *smsc, Octstr *sender, Octstr *receiver, Octstr *account)
Definition: urltrans.c:1328
URLTranslation * urltrans_find_service(URLTranslationList *trans, Msg *msg)
Definition: urltrans.c:268
URLTranslation * urltrans_find_username(URLTranslationList *trans, Octstr *name)
Definition: urltrans.c:284
int urltrans_strip_keyword(URLTranslation *t)
Definition: urltrans.c:917
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:739
Octstr * denied_recv_prefix
Definition: urltrans.c:119
#define panic
Definition: log.h:87
Definition: cfg.c:73
#define MSG_PARAM_UNDEFINED
Definition: msg.h:71
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
int urltrans_max_messages(URLTranslation *t)
Definition: urltrans.c:792
Octstr * password
Definition: urltrans.c:110
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505
Octstr * header
Definition: urltrans.c:100
regex_t * black_list_regex
Definition: urltrans.c:142
#define gwlist_create()
Definition: list.h:136
regex_t * denied_prefix_regex
Definition: urltrans.c:138
Octstr * footer
Definition: urltrans.c:101
List * accepted_smsc
Definition: urltrans.c:103
#define DC_UNDEF
Definition: sms.h:109
static URLTranslation * find_default_translation(URLTranslationList *trans, Octstr *smsc, Octstr *sender, Octstr *receiver, Octstr *account)
Definition: urltrans.c:1491
Octstr * urltrans_prefix(URLTranslation *t)
Definition: urltrans.c:772
Octstr * faked_sender
Definition: urltrans.c:93
void urltrans_destroy(URLTranslationList *trans)
Definition: urltrans.c:194
Octstr * suffix
Definition: urltrans.c:92
int assume_plain_text
Definition: urltrans.c:123
static Octstr * url
Definition: test_xmlrpc.c:84
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
Octstr * urltrans_name(URLTranslation *t)
Definition: urltrans.c:832
static Octstr * forced_smsc(WAPPushUser *u)
static URLTranslation * find_translation(URLTranslationList *trans, Msg *msg)
Definition: urltrans.c:1451
regex_t * keyword_regex
Definition: urltrans.c:134
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1638
long max_messages
Definition: urltrans.c:95
Octstr * forced_smsc
Definition: urltrans.c:111
Definition: list.c:102
static Octstr * account
Definition: mtbatch.c:94
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
Octstr * urltrans_get_pattern(URLTranslation *t, Msg *request)
Definition: urltrans.c:728
int urltrans_concatenation(URLTranslation *t)
Definition: urltrans.c:797
Octstr * alt_charset
Definition: urltrans.c:102
void octstr_url_encode(Octstr *ostr)
Definition: octstr.c:1671
static List * get_matching_translations(URLTranslationList *trans, Octstr *msg)
Definition: urltrans.c:1422
Octstr * name
Definition: urltrans.c:108
#define DC_UCS2
Definition: sms.h:112
#define DC_7BIT
Definition: sms.h:110
static void destroy_onetrans(void *ot)
Definition: urltrans.c:1253
static void destroy_keyword_list(void *list)
Definition: urltrans.c:176
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
Numhash * white_list
Definition: urltrans.c:120
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.