Module: sems
Branch: master
Commit: 6d247332a1c4c0e65f0d2acaecde6fe3774570d3
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=6d247332a1c4c0e65f0d2acaecde6fe3774570d3

Author: Stefan Sayer <[email protected]>
Committer: Stefan Sayer <[email protected]>
Date:   Mon Feb  6 19:18:19 2012 +0100

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

 - uppercase
 - lowercase
 - length
 - md5

---

 apps/sbc/ParamReplacer.cpp        |   58 ++++++++++++++++++++++++++++++++++++-
 core/AmUtils.cpp                  |   42 ++++++++++++++++++++++++++
 core/AmUtils.h                    |   16 ++++++++++
 core/md5.h                        |    1 -
 core/plug-in/uac_auth/UACAuth.cpp |   30 -------------------
 core/plug-in/uac_auth/UACAuth.h   |    7 +----
 doc/Readme.sbc.txt                |    5 +++
 7 files changed, 121 insertions(+), 38 deletions(-)

diff --git a/apps/sbc/ParamReplacer.cpp b/apps/sbc/ParamReplacer.cpp
index fa009f1..3241f44 100644
--- a/apps/sbc/ParamReplacer.cpp
+++ b/apps/sbc/ParamReplacer.cpp
@@ -29,7 +29,7 @@
 #include "AmSipHeaders.h"
 #include "AmUtils.h"
 #include "SBC.h" // for RegexMapper SBCFactory::regex_mappings
-
+#include <algorithm>
 
 void replaceParsedParam(const string& s, size_t p,
                        const AmUriParser& parsed, string& res) {
@@ -336,6 +336,62 @@ string replaceParameters(const string& s,
          skip_chars = skip_p-p;
        } break;
 
+       case '_': { // modify
+         if (s.length()<p+4) { // $_O()
+           WARN("Error parsing $_ modifier replacement (short string)\n");
+           break;
+         }
+
+         char operation = s[p+1];
+         if (operation != 'U' && operation != 'l') {
+           WARN("Error parsing $_%c string modifier: unknown operator '%c'\n",
+                operation, operation);
+         }
+
+         if (s[p+2] != '(') {
+           WARN("Error parsing $U upcase replacement (missing '(')\n");
+           break;
+         }
+
+         size_t skip_p = p+3;
+         skip_p = skip_to_end_of_brackets(s, skip_p);
+
+         if (skip_p==s.length()) {
+           WARN("Error parsing $_ modifier (unclosed brackets)\n");
+           skip_chars = skip_p-p;
+           break;
+         }
+
+         string br_str = s.substr(p+3, skip_p-p-3);
+         string br_str_replaced = replaceParameters(br_str, "$_*(...)",
+                                                    req, app_param,
+                                                    ruri_parser, from_parser, 
to_parser);
+         br_str = br_str_replaced;
+         switch(operation) {
+         case 'u': // uppercase
+           transform(br_str_replaced.begin(), br_str_replaced.end(),
+                     br_str_replaced.begin(), ::toupper); break;
+         case 'l': // lowercase
+           transform(br_str_replaced.begin(), br_str_replaced.end(),
+                     br_str_replaced.begin(), ::tolower); break;
+
+         case 's': // size (string length)
+           br_str_replaced = int2str((unsigned int)br_str.length());
+           break;
+
+         case '5': // md5
+           br_str_replaced = calculateMD5(br_str);
+           break;
+
+         default: break;
+         }
+         DBG("applied operator '%c': '%s' => '%s'\n", operation,
+             br_str.c_str(), br_str_replaced.c_str());
+         res+=br_str_replaced;
+
+         skip_chars = skip_p-p;
+       } break;
+
        default: {
          WARN("unknown replace pattern $%c%c\n",
               s[p], s[p+1]);
diff --git a/core/AmUtils.cpp b/core/AmUtils.cpp
index f4ad187..b6e1569 100644
--- a/core/AmUtils.cpp
+++ b/core/AmUtils.cpp
@@ -1108,3 +1108,45 @@ bool run_regex_mapping(const RegexMappingVector& 
mapping, const char* test_s,
   }
   return false;
 }
+
+// These function comes basically from ser's uac module 
+void cvt_hex(HASH bin, HASHHEX hex)
+{
+  unsigned short i;
+  unsigned char j;
+
+  for (i = 0; i<HASHLEN; i++)
+    {
+      j = (bin[i] >> 4) & 0xf;
+      if (j <= 9)
+       {
+         hex[i * 2] = (j + '0');
+       } else {
+         hex[i * 2] = (j + 'a' - 10);
+       }
+
+      j = bin[i] & 0xf;
+
+      if (j <= 9)
+       {
+         hex[i * 2 + 1] = (j + '0');
+       } else {
+         hex[i * 2 + 1] = (j + 'a' - 10);
+       }
+    };
+
+  hex[HASHHEXLEN] = '\0';
+}
+
+/** get an MD5 hash of a string */
+string calculateMD5(const string& input) {
+  MD5_CTX Md5Ctx;
+  HASH H;
+  HASHHEX HH;
+
+  MD5Init(&Md5Ctx);
+  MD5Update(&Md5Ctx, (unsigned char*)input.c_str(), input.length());
+  MD5Final(H, &Md5Ctx);
+  cvt_hex(H, HH);
+  return string((const char*)HH);
+}
diff --git a/core/AmUtils.h b/core/AmUtils.h
index fe2f6f2..2d8b170 100644
--- a/core/AmUtils.h
+++ b/core/AmUtils.h
@@ -42,6 +42,14 @@ using std::string;
 #include <utility>
 #include <map>
 
+#include "md5.h"
+
+#define HASHLEN 16
+typedef unsigned char HASH[HASHLEN];
+
+#define HASHHEXLEN 32
+typedef unsigned char HASHHEX[HASHHEXLEN+1];
+
 //#define FIFO_PERM S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
 
 #define PARAM_HDR "P-App-Param"
@@ -273,6 +281,14 @@ bool read_regex_mapping(const string& fname, const char* 
sep,
  */
 bool run_regex_mapping(const RegexMappingVector& mapping, const char* test_s,
                       string& result);
+
+
+/** convert a binary MD5 hash to hex representation */
+void cvt_hex(HASH bin, HASHHEX hex);
+
+/** get an MD5 hash of a string */
+string calculateMD5(const string& input);
+
 #endif
 
 // Local Variables:
diff --git a/core/md5.h b/core/md5.h
index 84c43b4..1552a08 100644
--- a/core/md5.h
+++ b/core/md5.h
@@ -38,5 +38,4 @@ typedef struct {
 void MD5Init(MD5_CTX *);
 void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
 void MD5Final(unsigned char [16], MD5_CTX *);
-
 #endif /* MD5_H */
diff --git a/core/plug-in/uac_auth/UACAuth.cpp 
b/core/plug-in/uac_auth/UACAuth.cpp
index ed7d992..1998bd1 100644
--- a/core/plug-in/uac_auth/UACAuth.cpp
+++ b/core/plug-in/uac_auth/UACAuth.cpp
@@ -410,36 +410,6 @@ bool UACAuth::do_auth(const UACAuthDigestChallenge& 
challenge,
   return true;
 }
 
-// These functions come basically from ser's uac module 
-static inline void cvt_hex(HASH bin, HASHHEX hex)
-{
-  unsigned short i;
-  unsigned char j;
-
-  for (i = 0; i<HASHLEN; i++)
-    {
-      j = (bin[i] >> 4) & 0xf;
-      if (j <= 9)
-       {
-         hex[i * 2] = (j + '0');
-       } else {
-         hex[i * 2] = (j + 'a' - 10);
-       }
-
-      j = bin[i] & 0xf;
-
-      if (j <= 9)
-       {
-         hex[i * 2 + 1] = (j + '0');
-       } else {
-         hex[i * 2 + 1] = (j + 'a' - 10);
-       }
-    };
-
-  hex[HASHHEXLEN] = '\0';
-}
-
-
 /* 
  * calculate H(A1)
  */
diff --git a/core/plug-in/uac_auth/UACAuth.h b/core/plug-in/uac_auth/UACAuth.h
index 9346770..537d8a1 100644
--- a/core/plug-in/uac_auth/UACAuth.h
+++ b/core/plug-in/uac_auth/UACAuth.h
@@ -32,17 +32,12 @@
 #include "AmSession.h"
 #include "AmOfferAnswer.h"
 #include "ampi/UACAuthAPI.h"
+#include "AmUtils.h"
 
 #include <string>
 using std::string;
 #include <map>
 
-#define HASHLEN 16
-typedef unsigned char HASH[HASHLEN];
-
-#define HASHHEXLEN 32
-typedef unsigned char HASHHEX[HASHHEXLEN+1];
-
 /** \brief Challenge in uac auth */
 struct UACAuthDigestChallenge {
   std::string realm;
diff --git a/doc/Readme.sbc.txt b/doc/Readme.sbc.txt
index 9ef5ab9..b062230 100644
--- a/doc/Readme.sbc.txt
+++ b/doc/Readme.sbc.txt
@@ -189,6 +189,11 @@ The patterns which can be used are the following:
   $M(value=>regexmap) - map a value (any pattern) to a regexmap (see below)
     Example: $M($fU=>usermap)
 
+  $_*(value) - string modifiers: 
+   $_u(value)   - value to uppercase (e.g.: $_u($fh) From host in uppercase)
+   $_l(value)   - value to lowercase (e.g.: $_l($fh) From host in lowercase)
+   $_s(value)   - length of value (e.g.: $_s($fU) string length of From user)
+   $_5(value)   - MD5 of value
 
   \\  -> \
   \$  -> $

_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to