00001
00056 #include "sip.h"
00057 #include "thig.h"
00058
00059 #include "thig_ims_enc.h"
00060
00061 #include "../../mem/mem.h"
00062 #include "../../parser/parse_hname2.h"
00063 #include "../../parser/parse_rr.h"
00064 #include "../../parser/parse_uri.h"
00065
00066 extern str icscf_thig_path_str;
00067 extern str icscf_thig_rr_str;
00068 extern str icscf_thig_name_str;
00069 extern str icscf_thig_host_str;
00070 extern int icscf_thig_port;
00071 extern str icscf_thig_port_str;
00072 extern str icscf_thig_param_str;
00073
00074
00075
00076 void print_string(char*text,char* str , int len){
00077 int i;
00078 LOG(L_ALERT,"%s",text);
00079 for( i=0;i<len;i++)
00080 printf("%c",*(str++));
00081 printf("\n");
00082 }
00083
00084 void print_str(char* text , str str_text){
00085 print_string(text,str_text.s,str_text.len);
00086 }
00087
00088
00102 int I_THIG_add_Path(struct sip_msg* msg, char* str1, char* str2)
00103 {
00104 int ret;
00105 str x;
00106 LOG(L_ALERT,"DBG:"M_NAME":I_add_THIG_Path: Adding THIG Path header\n");
00107 STR_PKG_DUP(x,icscf_thig_path_str,"pkg");
00108 ret=cscf_add_header_first(msg,&x,HDR_OTHER_T);
00109 if (!ret){
00110 LOG(L_ALERT,"DBG:"M_NAME":I_add_THIG_Path: Error adding Path for THIG\n");
00111 return CSCF_RETURN_FALSE;
00112 }
00113 return CSCF_RETURN_TRUE;
00114 out_of_memory:
00115 return CSCF_RETURN_ERROR;
00116 }
00117
00130 int I_THIG_add_RR(struct sip_msg* msg, char* str1, char* str2)
00131 {
00132 int ret;
00133 str x;
00134 LOG(L_ALERT,"DBG:"M_NAME":I_add_THIG_RR: Adding THIG Record-Route header\n");
00135 STR_PKG_DUP(x,icscf_thig_rr_str,"pkg");
00136 ret=cscf_add_header_first(msg,&x,HDR_RECORDROUTE_T);
00137 if (!ret){
00138 LOG(L_ALERT,"DBG:"M_NAME":I_add_THIG_RR: Error adding Record-Route for THIG\n");
00139 return CSCF_RETURN_FALSE;
00140 }
00141 return CSCF_RETURN_TRUE;
00142 out_of_memory:
00143 return CSCF_RETURN_ERROR;
00144 }
00145
00146
00147 str s_hdr_src={": \r\n",4};
00148 str s_new_hdr_1={"<sip:",5};
00149 str s_new_hdr_2={";lr>",4};
00150 str s_new_hdr_3={"SIP/2.0/UDP ",12};
00151
00160 int I_THIG_encrypt_header(struct sip_msg* msg, char* str1, char* str2)
00161 {
00162 str hdr_name={0,0};
00163 char hdr_str[64];
00164 struct hdr_field *hdr=0,hdr_search;
00165 str orig={0,0},enc={0,0},repl={0,0};
00166
00167 hdr_name.s = str1;
00168 hdr_name.len = strlen(str1);
00169
00170 memcpy(hdr_str,hdr_name.s,hdr_name.len);
00171 memcpy(hdr_str+hdr_name.len,s_hdr_src.s,s_hdr_src.len);
00172 if (!parse_hname2(hdr_str,hdr_str+hdr_name.len+s_hdr_src.len,&hdr_search)){
00173 LOG(L_ERR,"ERR:"M_NAME":I_THIG_encrypt_header: Error parsing header name <%.*s> !!!\n",hdr_name.len,hdr_name.s);
00174 return CSCF_RETURN_ERROR;
00175 }
00176
00177 LOG(L_ALERT,"DBG:"M_NAME":I_THIG_encrypt_header: Encrypting header %.*s\n",hdr_name.len,hdr_name.s);
00178 for(hdr = (hdr_search.type==HDR_OTHER_T) ? cscf_get_next_header(msg,hdr_name,hdr) : cscf_get_next_header_type(msg,hdr_search.type,hdr);
00179 hdr;
00180 hdr = (hdr_search.type==HDR_OTHER_T) ? cscf_get_next_header(msg,hdr_name,hdr) : cscf_get_next_header_type(msg,hdr_search.type,hdr))
00181 {
00182 orig.s = hdr->body.s;
00183 orig.len = hdr->body.len ;
00184
00185 LOG(L_ALERT,"DBG:"M_NAME":I_THIG_encrypt_header: Orig: <%.*s>\n",orig.len,orig.s);
00186 enc = thig_encrypt(orig);
00187 if (!enc.len) {
00188 LOG(L_ERR,"ERR:"M_NAME":I_THIG_encrypt_header: error encrypting <%.*s>. THIG skipeed!!!\n",orig.len,orig.s);
00189 return CSCF_RETURN_FALSE;
00190 }
00191
00192 repl.len = hdr_name.len + icscf_thig_host_str.len + 1 + icscf_thig_port_str.len + 1 + icscf_thig_param_str.len + 1 + enc.len;
00193
00194 if (hdr->type==HDR_VIA_T) repl.len += s_new_hdr_3.len;
00195 else repl.len += s_new_hdr_1.len + s_new_hdr_2.len;
00196
00197 repl.s = pkg_malloc(repl.len);
00198 if (!repl.s){
00199 LOG(L_ERR,"ERR:"M_NAME":I_THIG_encrypt_header: error allocating %d bytes. THIG skipeed!!!\n",repl.len);
00200 pkg_free(enc.s);
00201 return CSCF_RETURN_FALSE;
00202 }
00203 repl.len = 0;
00204 if (hdr->type==HDR_VIA_T) {
00205 STR_APPEND(repl,s_new_hdr_3);
00206 STR_APPEND(repl,icscf_thig_host_str);
00207 repl.s[repl.len++]=':';
00208 STR_APPEND(repl,icscf_thig_port_str);
00209 repl.s[repl.len++]=';';
00210 STR_APPEND(repl,icscf_thig_param_str);
00211 repl.s[repl.len++]='=';
00212 STR_APPEND(repl,enc);
00213 }else{
00214 STR_APPEND(repl,s_new_hdr_1);
00215 STR_APPEND(repl,icscf_thig_host_str);
00216 repl.s[repl.len++]=':';
00217 STR_APPEND(repl,icscf_thig_port_str);
00218 repl.s[repl.len++]=';';
00219 STR_APPEND(repl,icscf_thig_param_str);
00220 repl.s[repl.len++]='=';
00221 STR_APPEND(repl,enc);
00222 STR_APPEND(repl,s_new_hdr_2);
00223 }
00224 pkg_free(enc.s);
00225 LOG(L_ALERT,"DBG:"M_NAME":I_THIG_encrypt_header: Enc : <%.*s>\n",repl.len,repl.s);
00226 cscf_replace_string(msg,orig,repl);
00227 }
00228 return CSCF_RETURN_TRUE;
00229 }
00230
00231
00232
00241 int I_THIG_decrypt_header(struct sip_msg* msg, char* str1, char* str2)
00242 {
00243 str hdr_name={0,0};
00244 char hdr_str[64];
00245 struct hdr_field *hdr=0,hdr_search;
00246 str orig={0,0},dec={0,0};
00247 struct via_body *vb;
00248 struct via_param *vp;
00249 rr_t *rr;
00250 struct sip_uri uri;
00251 int i,k;
00252
00253 hdr_name.s = str1;
00254 hdr_name.len = strlen(str1);
00255
00256 memcpy(hdr_str,hdr_name.s,hdr_name.len);
00257 memcpy(hdr_str+hdr_name.len,s_hdr_src.s,s_hdr_src.len);
00258 if (!parse_hname2(hdr_str,hdr_str+hdr_name.len+s_hdr_src.len,&hdr_search)){
00259 LOG(L_ERR,"ERR:"M_NAME":I_THIG_decrypt_header: Error parsing header name <%.*s> !!!\n",hdr_name.len,hdr_name.s);
00260 return CSCF_RETURN_ERROR;
00261 }
00262
00263 LOG(L_ALERT,"DBG:"M_NAME":I_THIG_decrypt_header: Decrypting header %.*s\n",hdr_name.len,hdr_name.s);
00264 for(hdr = (hdr_search.type==HDR_OTHER_T) ? cscf_get_next_header(msg,hdr_name,hdr) : cscf_get_next_header_type(msg,hdr_search.type,hdr);
00265 hdr;
00266 hdr = (hdr_search.type==HDR_OTHER_T) ? cscf_get_next_header(msg,hdr_name,hdr) : cscf_get_next_header_type(msg,hdr_search.type,hdr))
00267 {
00268 if (hdr->type==HDR_VIA_T){
00269 if (!hdr->parsed){
00270 vb = pkg_malloc(sizeof(struct via_body));
00271 if (!vb){
00272 LOG(L_ERR,"ERR:"M_NAME":I_THIG_decrypt_header: Error allocating %d bytes\n",sizeof(struct via_body));
00273 return CSCF_RETURN_ERROR;
00274 }
00275 parse_via(hdr->body.s,hdr->body.s+hdr->body.len,vb);
00276 hdr->parsed = vb;
00277 }
00278
00279 for(vb = hdr->parsed;vb;vb = vb->next)
00280 {
00281 if (vb->port != icscf_thig_port ||
00282 vb->host.len != icscf_thig_host_str.len ||
00283 strncasecmp(vb->host.s,icscf_thig_host_str.s,icscf_thig_host_str.len)!=0){
00284 continue;
00285 }
00286 k=0;
00287 for(vp=vb->param_lst;vp;vp=vp->next)
00288 if (vp->name.len == icscf_thig_param_str.len &&
00289 strncasecmp(vp->name.s,icscf_thig_param_str.s,icscf_thig_param_str.len)==0){
00290 k=1;
00291 orig = vp->value;
00292 break;
00293 }
00294 if (!k) continue;
00295 LOG(L_ALERT,"DBG:"M_NAME":I_THIG_decrypt_header: Orig: <%.*s>\n",orig.len,orig.s);
00296 dec = thig_decrypt(orig);
00297 if (!dec.len) {
00298 LOG(L_ERR,"ERR:"M_NAME":I_THIG_decrypt_header: error decrypting <%.*s>. THIG skipeed!!!\n",orig.len,orig.s);
00299 return CSCF_RETURN_FALSE;
00300 }
00301 orig.s = vb->name.s;
00302 orig.len = vb->last_param->value.s - orig.s + vb->last_param->value.len;
00303 if (!cscf_replace_string(msg,orig,dec)){
00304 LOG(L_ERR,"ERR:"M_NAME":I_THIG_decrypt_header: error replacing string!!!\n");
00305 return CSCF_RETURN_FALSE;
00306 }
00307 }
00308 }else{
00309 if (!hdr->parsed){
00310 if (parse_rr(hdr)<0){
00311 LOG(L_ERR,"ERR:"M_NAME":I_THIG_decrypt_header: Error parsing as *Route header <%.*s>\n",hdr->body.len,hdr->body.s);
00312 continue;
00313 }
00314 }
00315 rr = hdr->parsed;
00316 if (!rr) {
00317 LOG(L_ERR,"ERR:"M_NAME":I_THIG_decrypt_header: no rr in this header <%.*s>\n",hdr->body.len,hdr->body.s);
00318 continue;
00319 }
00320 while(rr){
00321 if (parse_uri(rr->nameaddr.uri.s,rr->nameaddr.uri.len,&uri)!=0){
00322 LOG(L_ERR,"ERR:"M_NAME":I_THIG_decrypt_header: error parsing uri <%.*s>\n",rr->nameaddr.uri.len,rr->nameaddr.uri.s);
00323 continue;
00324 }
00325 if (uri.port_no!=icscf_thig_port ||
00326 uri.host.len!=icscf_thig_host_str.len ||
00327 strncasecmp(uri.host.s,icscf_thig_host_str.s,icscf_thig_host_str.len)!=0){
00328 continue;
00329 }
00330 k=0;
00331 for(i=0;i<uri.params.len-icscf_thig_param_str.len;i++)
00332 if (strncasecmp(uri.params.s,icscf_thig_param_str.s,icscf_thig_param_str.len)==0){
00333 k = 1;
00334 i+=icscf_thig_param_str.len+1;
00335 orig.s = uri.params.s+i;
00336 orig.len = 0;
00337 while(i<uri.params.len && uri.params.s[i]!=';' && uri.params.s[i]!='&'){
00338 i++;
00339 orig.len++;
00340 }
00341 }
00342 if (!k) continue;
00343 LOG(L_ALERT,"DBG:"M_NAME":I_THIG_decrypt_header: Orig: <%.*s>\n",orig.len,orig.s);
00344 dec = thig_decrypt(orig);
00345 if (!dec.len) {
00346 LOG(L_ERR,"ERR:"M_NAME":I_THIG_decrypt_header: error decrypting <%.*s>. THIG skipeed!!!\n",orig.len,orig.s);
00347 return CSCF_RETURN_FALSE;
00348 }
00349 orig.s = rr->nameaddr.name.s;
00350 orig.len = rr->len;
00351 if (!cscf_replace_string(msg,orig,dec)){
00352 LOG(L_ERR,"ERR:"M_NAME":I_THIG_decrypt_header: error replacing string!!!\n");
00353 return CSCF_RETURN_FALSE;
00354 }
00355 rr = rr->next;
00356 }
00357 }
00358 }
00359 return CSCF_RETURN_TRUE;
00360 }
00361
00371 int I_THIG_encrypt_all_headers(struct sip_msg* msg, char* str1, char* str2)
00372 {
00373 int ret;
00374 ret = I_THIG_encrypt_header(msg,"Via",0);
00375 if (ret!=CSCF_RETURN_TRUE) return ret;
00376 ret = I_THIG_encrypt_header(msg,"Route",0);
00377 if (ret!=CSCF_RETURN_TRUE) return ret;
00378 ret = I_THIG_encrypt_header(msg,"Record-Route",0);
00379 if (ret!=CSCF_RETURN_TRUE) return ret;
00380 ret = I_THIG_encrypt_header(msg,"Service-Route",0);
00381 if (ret!=CSCF_RETURN_TRUE) return ret;
00382
00383 return 1;
00384 }
00385
00395 int I_THIG_decrypt_all_headers(struct sip_msg* msg, char* str1, char* str2)
00396 {
00397 int ret;
00398 ret = I_THIG_decrypt_header(msg,"Via",0);
00399 if (ret!=CSCF_RETURN_TRUE) return ret;
00400 ret = I_THIG_decrypt_header(msg,"Route",0);
00401 if (ret!=CSCF_RETURN_TRUE) return ret;
00402 ret = I_THIG_decrypt_header(msg,"Record-Route",0);
00403 if (ret!=CSCF_RETURN_TRUE) return ret;
00404
00405
00406
00407 return 1;
00408 }