Browse code

sbc: adds string modifiers, like $_u(value) - VALUE

- uppercase
- lowercase
- length
- md5

Stefan Sayer authored on 06/02/2012 18:18:19
Showing 7 changed files
... ...
@@ -29,7 +29,7 @@
29 29
 #include "AmSipHeaders.h"
30 30
 #include "AmUtils.h"
31 31
 #include "SBC.h" // for RegexMapper SBCFactory::regex_mappings
32
-
32
+#include <algorithm>
33 33
 
34 34
 void replaceParsedParam(const string& s, size_t p,
35 35
 			const AmUriParser& parsed, string& res) {
... ...
@@ -336,6 +336,62 @@ string replaceParameters(const string& s,
336 336
 	  skip_chars = skip_p-p;
337 337
 	} break;
338 338
 
339
+	case '_': { // modify
340
+	  if (s.length()<p+4) { // $_O()
341
+	    WARN("Error parsing $_ modifier replacement (short string)\n");
342
+	    break;
343
+	  }
344
+
345
+	  char operation = s[p+1];
346
+	  if (operation != 'U' && operation != 'l') {
347
+	    WARN("Error parsing $_%c string modifier: unknown operator '%c'\n",
348
+		 operation, operation);
349
+	  }
350
+
351
+	  if (s[p+2] != '(') {
352
+	    WARN("Error parsing $U upcase replacement (missing '(')\n");
353
+	    break;
354
+	  }
355
+
356
+	  size_t skip_p = p+3;
357
+	  skip_p = skip_to_end_of_brackets(s, skip_p);
358
+
359
+	  if (skip_p==s.length()) {
360
+	    WARN("Error parsing $_ modifier (unclosed brackets)\n");
361
+	    skip_chars = skip_p-p;
362
+	    break;
363
+	  }
364
+
365
+	  string br_str = s.substr(p+3, skip_p-p-3);
366
+	  string br_str_replaced = replaceParameters(br_str, "$_*(...)",
367
+						     req, app_param,
368
+						     ruri_parser, from_parser, to_parser);
369
+	  br_str = br_str_replaced;
370
+	  switch(operation) {
371
+	  case 'u': // uppercase
372
+	    transform(br_str_replaced.begin(), br_str_replaced.end(),
373
+		      br_str_replaced.begin(), ::toupper); break;
374
+	  case 'l': // lowercase
375
+	    transform(br_str_replaced.begin(), br_str_replaced.end(),
376
+		      br_str_replaced.begin(), ::tolower); break;
377
+
378
+	  case 's': // size (string length)
379
+	    br_str_replaced = int2str((unsigned int)br_str.length());
380
+	    break;
381
+
382
+	  case '5': // md5
383
+	    br_str_replaced = calculateMD5(br_str);
384
+	    break;
385
+
386
+	  default: break;
387
+	  }
388
+	  DBG("applied operator '%c': '%s' => '%s'\n", operation,
389
+	      br_str.c_str(), br_str_replaced.c_str());
390
+	  res+=br_str_replaced;
391
+
392
+	  skip_chars = skip_p-p;
393
+	} break;
394
+
339 395
 	default: {
340 396
 	  WARN("unknown replace pattern $%c%c\n",
341 397
 	       s[p], s[p+1]);
... ...
@@ -1108,3 +1108,45 @@ bool run_regex_mapping(const RegexMappingVector& mapping, const char* test_s,
1108 1108
   }
1109 1109
   return false;
1110 1110
 }
1111
+
1112
+// These function comes basically from ser's uac module 
1113
+void cvt_hex(HASH bin, HASHHEX hex)
1114
+{
1115
+  unsigned short i;
1116
+  unsigned char j;
1117
+
1118
+  for (i = 0; i<HASHLEN; i++)
1119
+    {
1120
+      j = (bin[i] >> 4) & 0xf;
1121
+      if (j <= 9)
1122
+	{
1123
+	  hex[i * 2] = (j + '0');
1124
+	} else {
1125
+	  hex[i * 2] = (j + 'a' - 10);
1126
+	}
1127
+
1128
+      j = bin[i] & 0xf;
1129
+
1130
+      if (j <= 9)
1131
+	{
1132
+	  hex[i * 2 + 1] = (j + '0');
1133
+	} else {
1134
+	  hex[i * 2 + 1] = (j + 'a' - 10);
1135
+	}
1136
+    };
1137
+
1138
+  hex[HASHHEXLEN] = '\0';
1139
+}
1140
+
1141
+/** get an MD5 hash of a string */
1142
+string calculateMD5(const string& input) {
1143
+  MD5_CTX Md5Ctx;
1144
+  HASH H;
1145
+  HASHHEX HH;
1146
+
1147
+  MD5Init(&Md5Ctx);
1148
+  MD5Update(&Md5Ctx, (unsigned char*)input.c_str(), input.length());
1149
+  MD5Final(H, &Md5Ctx);
1150
+  cvt_hex(H, HH);
1151
+  return string((const char*)HH);
1152
+}
... ...
@@ -42,6 +42,14 @@ using std::string;
42 42
 #include <utility>
43 43
 #include <map>
44 44
 
45
+#include "md5.h"
46
+
47
+#define HASHLEN 16
48
+typedef unsigned char HASH[HASHLEN];
49
+
50
+#define HASHHEXLEN 32
51
+typedef unsigned char HASHHEX[HASHHEXLEN+1];
52
+
45 53
 //#define FIFO_PERM S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
46 54
 
47 55
 #define PARAM_HDR "P-App-Param"
... ...
@@ -273,6 +281,14 @@ bool read_regex_mapping(const string& fname, const char* sep,
273 281
  */
274 282
 bool run_regex_mapping(const RegexMappingVector& mapping, const char* test_s,
275 283
 		       string& result);
284
+
285
+
286
+/** convert a binary MD5 hash to hex representation */
287
+void cvt_hex(HASH bin, HASHHEX hex);
288
+
289
+/** get an MD5 hash of a string */
290
+string calculateMD5(const string& input);
291
+
276 292
 #endif
277 293
 
278 294
 // Local Variables:
... ...
@@ -38,5 +38,4 @@ typedef struct {
38 38
 void MD5Init(MD5_CTX *);
39 39
 void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
40 40
 void MD5Final(unsigned char [16], MD5_CTX *);
41
-
42 41
 #endif /* MD5_H */
... ...
@@ -410,36 +410,6 @@ bool UACAuth::do_auth(const UACAuthDigestChallenge& challenge,
410 410
   return true;
411 411
 }
412 412
 
413
-// These functions come basically from ser's uac module 
414
-static inline void cvt_hex(HASH bin, HASHHEX hex)
415
-{
416
-  unsigned short i;
417
-  unsigned char j;
418
-
419
-  for (i = 0; i<HASHLEN; i++)
420
-    {
421
-      j = (bin[i] >> 4) & 0xf;
422
-      if (j <= 9)
423
-	{
424
-	  hex[i * 2] = (j + '0');
425
-	} else {
426
-	  hex[i * 2] = (j + 'a' - 10);
427
-	}
428
-
429
-      j = bin[i] & 0xf;
430
-
431
-      if (j <= 9)
432
-	{
433
-	  hex[i * 2 + 1] = (j + '0');
434
-	} else {
435
-	  hex[i * 2 + 1] = (j + 'a' - 10);
436
-	}
437
-    };
438
-
439
-  hex[HASHHEXLEN] = '\0';
440
-}
441
-
442
-
443 413
 /* 
444 414
  * calculate H(A1)
445 415
  */
... ...
@@ -32,17 +32,12 @@
32 32
 #include "AmSession.h"
33 33
 #include "AmOfferAnswer.h"
34 34
 #include "ampi/UACAuthAPI.h"
35
+#include "AmUtils.h"
35 36
 
36 37
 #include <string>
37 38
 using std::string;
38 39
 #include <map>
39 40
 
40
-#define HASHLEN 16
41
-typedef unsigned char HASH[HASHLEN];
42
-
43
-#define HASHHEXLEN 32
44
-typedef unsigned char HASHHEX[HASHHEXLEN+1];
45
-
46 41
 /** \brief Challenge in uac auth */
47 42
 struct UACAuthDigestChallenge {
48 43
   std::string realm;
... ...
@@ -189,6 +189,11 @@ The patterns which can be used are the following:
189 189
   $M(value=>regexmap) - map a value (any pattern) to a regexmap (see below)
190 190
     Example: $M($fU=>usermap)
191 191
 
192
+  $_*(value) - string modifiers: 
193
+   $_u(value)   - value to uppercase (e.g.: $_u($fh) From host in uppercase)
194
+   $_l(value)   - value to lowercase (e.g.: $_l($fh) From host in lowercase)
195
+   $_s(value)   - length of value (e.g.: $_s($fU) string length of From user)
196
+   $_5(value)   - MD5 of value
192 197
 
193 198
   \\  -> \
194 199
   \$  -> $