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
