Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00035 #include <string.h>
00036 #include "parse_identity.h"
00037 #include "parse_def.h"
00038 #include "parser_f.h"
00039 #include "../mem/mem.h"
00040 #include "../ut.h"
00041
00042
00043
00044
00045
00046 #define SP(_c) ((_c)=='\t' || (_c)==' ')
00047 inline static int isendofhash (char* p, char* end)
00048 {
00049
00050 if ((p<end && *p=='"')
00051
00052 || ((*p=='\n' || *p=='\r') && p+1==end))
00053 return 1;
00054 else
00055 return 0;
00056 }
00057
00058
00063 int movetomybuffer (char *pstart,
00064 char *pend,
00065 char *pcur,
00066 struct identity_body *ib)
00067 {
00068 char *phashend;
00069
00070 for (phashend = pcur; !isendofhash(phashend, pend); phashend++);
00071
00072 if (!(ib->hash.s=pkg_malloc(phashend-pstart))) {
00073 LOG(L_ERR, "parse_identity: out of memory\n");
00074 return -2;
00075 }
00076 ib->ballocated=1;
00077
00078 memcpy(ib->hash.s, pstart, ib->hash.len);
00079
00080 return 0;
00081 }
00082
00083
00084 void parse_identity(char *buffer, char* end, struct identity_body* ib)
00085 {
00086 char *p=NULL, *pstart=NULL;
00087
00088 if (!buffer || !end || !ib)
00089 goto error;
00090
00091 ib->error=PARSE_ERROR;
00092
00093
00094 *buffer == '"' ? (pstart = buffer + 1) : (pstart = buffer);
00095
00096 ib->hash.s=pstart;
00097 ib->hash.len=0;
00098
00099 for (p = pstart; p < end; p++) {
00100
00101 if (((*p >= 'a' && *p <='z')
00102 || (*p >= 'A' && *p <='Z')
00103 || (*p >= '0' && *p <='9')
00104 || (*p == '+' || *p == '/' || *p == '='))) {
00105 if (ib->ballocated)
00106 ib->hash.s[ib->hash.len]=*p;
00107 ib->hash.len++;
00108 continue;
00109 }
00110
00111
00112 if (*p=='\n' && p+1<end && SP(*(p+1))) {
00113
00114 if (!ib->ballocated && (movetomybuffer(pstart, end, p-1, ib)))
00115 goto error;
00116
00117
00118 for (p+=1; p + 1 < end && SP(*(p + 1)); p++);
00119 continue;
00120 }
00121 if (*p=='\r' && p+2<end && *(p+1)=='\n' && SP(*(p+2))) {
00122 if (!ib->ballocated && (movetomybuffer(pstart, end, p-1, ib)))
00123 goto error;
00124 for (p+=2; p + 1 < end && SP(*(p + 1)); p++);
00125 continue;
00126 }
00127
00128 if (isendofhash(p, end))
00129 break;
00130
00131
00132 goto parseerror;
00133 }
00134
00135
00136 ib->error=PARSE_OK;
00137 return ;
00138
00139 parseerror:
00140 LOG( L_ERR , "ERROR: parse_identity: "
00141 "unexpected char [0x%X]: <<%.*s>> .\n",
00142 *p,(int)(p-buffer), ZSW(buffer));
00143 error:
00144 return ;
00145 }
00146
00147 int parse_identity_header(struct sip_msg *msg)
00148 {
00149 struct identity_body* identity_b;
00150
00151
00152 if ( !msg->identity
00153 && (parse_headers(msg,HDR_IDENTITY_F,0)==-1
00154 || !msg->identity) ) {
00155 LOG(L_ERR,"ERROR:parse_identity_header: bad msg or missing IDENTITY header\n");
00156 goto error;
00157 }
00158
00159
00160 if (msg->identity->parsed)
00161 return 0;
00162
00163 identity_b=pkg_malloc(sizeof(*identity_b));
00164 if (identity_b==0){
00165 LOG(L_ERR, "ERROR:parse_identity_header: out of memory\n");
00166 goto error;
00167 }
00168 memset(identity_b, 0, sizeof(*identity_b));
00169
00170 parse_identity(msg->identity->body.s,
00171 msg->identity->body.s + msg->identity->body.len+1,
00172 identity_b);
00173 if (identity_b->error==PARSE_ERROR){
00174 free_identity(identity_b);
00175 goto error;
00176 }
00177 msg->identity->parsed=(void*)identity_b;
00178
00179 return 0;
00180 error:
00181 return -1;
00182 }
00183
00184 void free_identity(struct identity_body *ib)
00185 {
00186 if (ib->ballocated)
00187 pkg_free(ib->hash.s);
00188 pkg_free(ib);
00189 }