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