strcommon.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * Copyright (C) 2007 voice-system.ro
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022 
00023  */
00029 #include "../../ut.h"
00030 #include "strcommon.h"
00031 
00035 int escape_common(char *dst, char *src, int src_len)
00036 {
00037         int i, j;
00038 
00039         if(dst==0 || src==0 || src_len<=0)
00040                 return 0;
00041         j = 0;
00042         for(i=0; i<src_len; i++)
00043         {
00044                 switch(src[i])
00045                 {
00046                         case '\'':
00047                                 dst[j++] = '\\';
00048                                 dst[j++] = src[i];
00049                                 break;
00050                         case '"':
00051                                 dst[j++] = '\\';
00052                                 dst[j++] = src[i];
00053                                 break;
00054                         case '\\':
00055                                 dst[j++] = '\\';
00056                                 dst[j++] = src[i];
00057                                 break;
00058                         case '\0':
00059                                 dst[j++] = '\\';
00060                                 dst[j++] = '0';
00061                                 break;
00062                         default:
00063                                 dst[j++] = src[i];
00064                 }
00065         }
00066         return j;
00067 }
00068 
00072 int unescape_common(char *dst, char *src, int src_len)
00073 {
00074         int i, j;
00075 
00076         if(dst==0 || src==0 || src_len<=0)
00077                 return 0;
00078         j = 0;
00079         i = 0;
00080         while(i<src_len)
00081         {
00082                 if(src[i]=='\\' && i+1<src_len)
00083                 {
00084                         switch(src[i+1])
00085                         {
00086                                 case '\'':
00087                                         dst[j++] = '\'';
00088                                         i++;
00089                                         break;
00090                                 case '"':
00091                                         dst[j++] = '"';
00092                                         i++;
00093                                         break;
00094                                 case '\\':
00095                                         dst[j++] = '\\';
00096                                         i++;
00097                                         break;
00098                                 case '0':
00099                                         dst[j++] = '\0';
00100                                         i++;
00101                                         break;
00102                                 default:
00103                                         dst[j++] = src[i];
00104                         }
00105                 } else {
00106                         dst[j++] = src[i];
00107                 }
00108                 i++;
00109         }
00110         return j;
00111 }
00112 
00114 void compute_md5(char *dst, char *src, int src_len)
00115 {
00116         MD5_CTX context;
00117         unsigned char digest[16];
00118         MD5Init (&context);
00119         MD5Update (&context, src, src_len);
00120         U_MD5Final (digest, &context);
00121         string2hex(digest, 16, dst);
00122 }
00123 
00125 int unescape_user(str *sin, str *sout)
00126 {
00127         char *at, *p, c;
00128 
00129         if(sin==NULL || sout==NULL || sin->s==NULL || sout->s==NULL
00130                         || sin->len<0 || sout->len < sin->len+1)
00131                 return -1;
00132 
00133         at = sout->s;
00134         p  = sin->s;
00135         while(p < sin->s+sin->len)
00136         {
00137             if (*p == '%')
00138                 {
00139                         p++;
00140                         switch (*p)
00141                         {
00142                                 case '0':
00143                                 case '1':
00144                                 case '2':
00145                                 case '3':
00146                                 case '4':
00147                                 case '5':
00148                                 case '6':
00149                                 case '7':
00150                                 case '8':
00151                                 case '9':
00152                                     c = (*p - '0') << 4;
00153                             break;
00154                                 case 'a':
00155                                 case 'b':
00156                                 case 'c':
00157                                 case 'd':
00158                                 case 'e':
00159                                 case 'f':
00160                                     c = (*p - 'a' + 10) << 4;
00161                             break;
00162                                 case 'A':
00163                                 case 'B':
00164                                 case 'C':
00165                                 case 'D':
00166                                 case 'E':
00167                                 case 'F':
00168                                     c = (*p - 'A' + 10) << 4;
00169                             break;
00170                                 default:
00171                                     LM_ERR("invalid hex digit <%u>\n", (unsigned int)*p);
00172                                     return -1;
00173                         }
00174                         p++;
00175                         switch (*p)
00176                         {
00177                                 case '0':
00178                                 case '1':
00179                                 case '2':
00180                                 case '3':
00181                                 case '4':
00182                                 case '5':
00183                                 case '6':
00184                                 case '7':
00185                                 case '8':
00186                                 case '9':
00187                                     c =  c + (*p - '0');
00188                             break;
00189                                 case 'a':
00190                                 case 'b':
00191                                 case 'c':
00192                                 case 'd':
00193                                 case 'e':
00194                                 case 'f':
00195                                     c = c + (*p - 'a' + 10);
00196                             break;
00197                                 case 'A':
00198                                 case 'B':
00199                                 case 'C':
00200                                 case 'D':
00201                                 case 'E':
00202                                 case 'F':
00203                                     c = c + (*p - 'A' + 10);
00204                             break;
00205                                 default:
00206                                     LM_ERR("invalid hex digit <%u>\n", (unsigned int)*p);
00207                                     return -1;
00208                         }
00209                         if ((c < 32) || (c > 126))
00210                         {
00211                             LM_ERR("invalid escaped character <%u>\n", (unsigned int)c);
00212                             return -1;
00213                         }
00214                         *at++ = c;
00215             } else {
00216                         *at++ = *p;
00217             }
00218                 p++;
00219         }
00220 
00221         *at = 0;
00222         sout->len = at - sout->s;
00223         
00224         LM_DBG("unescaped string is <%s>\n", sout->s);
00225         return 0;
00226 }
00227 
00236 int escape_user(str *sin, str *sout)
00237 {
00238 
00239         char *at, *p;
00240         unsigned char x;
00241 
00242         if(sin==NULL || sout==NULL || sin->s==NULL || sout->s==NULL
00243                         || sin->len<0 || sout->len < 3*sin->len+1)
00244                 return -1;
00245 
00246 
00247         at = sout->s;
00248         p  = sin->s;
00249         while (p < sin->s+sin->len)
00250         {
00251             if (*p < 32 || *p > 126)
00252                 {
00253                         LM_ERR("invalid escaped character <%u>\n", (unsigned int)*p);
00254                         return -1;
00255             }
00256             if (isdigit((int)*p) || ((*p >= 'A') && (*p <= 'Z')) ||
00257                                 ((*p >= 'a') && (*p <= 'z')))
00258                 {
00259                         *at = *p;
00260             } else {
00261                         switch (*p) {
00262                                 case '-':
00263                                 case '_':
00264                                 case '.':
00265                                 case '!':
00266                                 case '~':
00267                                 case '*':
00268                                 case '\'':
00269                                 case '(':
00270                                 case ')':
00271                                 case '&':
00272                                 case '=':
00273                                 case '+':
00274                                 case '$':
00275                                 case ',':
00276                                 case ';':
00277                                 case '?':
00278                                     *at = *p;
00279                                 break;
00280                                 default:
00281                                     *at++ = '%';
00282                                     x = (*p) >> 4;
00283                                     if (x < 10)
00284                                         {
00285                                                 *at++ = x + '0';
00286                                     } else {
00287                                                 *at++ = x - 10 + 'a';
00288                                     }
00289                                     x = (*p) & 0x0f;
00290                                     if (x < 10) {
00291                                                 *at = x + '0';
00292                                     } else {
00293                                                 *at = x - 10 + 'a';
00294                                     }
00295                         }
00296             }
00297             at++;
00298             p++;
00299         }
00300         *at = 0;
00301         sout->len = at - sout->s;
00302         LM_DBG("escaped string is <%s>\n", sout->s);
00303         return 0;
00304 }
00305 
00306 
00307 int unescape_param(str *sin, str *sout)
00308 {
00309     return unescape_user(sin, sout);
00310 }
00311 
00312 
00317 int escape_param(str *sin, str *sout)
00318 {
00319     char *at, *p;
00320     unsigned char x;
00321 
00322     if (sin==NULL || sout==NULL || sin->s==NULL || sout->s==NULL ||
00323         sin->len<0 || sout->len < 3*sin->len+1)
00324         return -1;
00325 
00326     at = sout->s;
00327     p  = sin->s;
00328     while (p < sin->s+sin->len) {
00329         if (*p < 32 || *p > 126) {
00330             LM_ERR("invalid escaped character <%u>\n", (unsigned int)*p);
00331             return -1;
00332         }
00333         switch (*p) {
00334         case ' ':
00335         case '?':
00336         case '&':
00337         case '=':
00338         case ',':
00339         case ';':
00340         case '"':
00341         case '+':
00342             *at++ = '%';
00343             x = (*p) >> 4;
00344             if (x < 10)
00345             {
00346                 *at++ = x + '0';
00347             } else {
00348                 *at++ = x - 10 + 'a';
00349             }
00350             x = (*p) & 0x0f;
00351             if (x < 10) {
00352                 *at = x + '0';
00353             } else {
00354                 *at = x - 10 + 'a';
00355             }
00356             break;
00357         default:
00358             *at = *p;
00359         }
00360         at++;
00361         p++;
00362     }
00363     *at = 0;
00364     sout->len = at - sout->s;
00365     LM_DBG("escaped string is <%s>\n", sout->s);
00366 
00367     return 0;
00368 }
00369