00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00030 #include <errno.h>
00031
00032 #include "../../parser/parser_f.h"
00033 #include "../../parser/parse_from.h"
00034 #include "../../parser/parse_cseq.h"
00035 #include "../../parser/parse_content.h"
00036 #include "../../parser/parse_uri.h"
00037 #include "../../parser/keys.h"
00038 #include "../../parser/contact/parse_contact.h"
00039
00040 #include "../../modules/tm/ut.h"
00041 #include "../../data_lump.h"
00042 #include "../../msg_translator.h"
00043 #include "auth_identity.h"
00044
00045
00046 struct hdr_field glb_contact;
00047 char *glb_siphdr=NULL;
00048 char *glb_msgbody=NULL;
00049
00050 static int tohdr_proc(str *sout, str *soutopt, struct sip_msg *msg);
00051 static int in_contacthdr_proc(str *sout, str *soutopt, struct sip_msg *msg);
00052 static int out_contacthdr_proc(str *sout, str *soutopt, struct sip_msg *msg);
00053 static int in_msgbody_proc(str *sout, str *soutopt, struct sip_msg *msg);
00054 static int out_msgbody_proc(str *sout, str *soutopt, struct sip_msg *msg);
00055 static void free_out_contacthdr(void);
00056 static void free_out_msgbody(void);
00057
00058
00059
00060 #define LOWER_BYTE(b) ((b) | 0x20)
00061 #define LOWER_DWORD(d) ((d) | 0x20202020)
00062
00063 #define READ(val) \
00064 (*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
00065
00066 static char *auth_next_line(char *buf, char *buf_end);
00067 static inline char* skip_ws(char* p, unsigned int size);
00068 static char *auth_get_hf_name(char *begin, char *end, enum _hdr_types_t *type);
00069 static int get_contact_body(char *buf, unsigned int len, str *sout);
00070
00071
00072
00073
00074
00075
00076
00077 int fromhdr_proc(str *sout, str *soutopt, struct sip_msg *msg)
00078 {
00079 if ((!msg->from) && (parse_headers(msg, HDR_FROM_F, 0) == -1)) {
00080 LOG(L_ERR, "AUTH_IDENTITY:fromhdr_proc: Error while parsing FROM header\n");
00081 return AUTH_ERROR;
00082 }
00083 if (!msg->from) {
00084 LOG(L_ERR, "AUTH_IDENTITY:fromhdr_proc: FROM header field is not found\n");
00085 return AUTH_NOTFOUND;
00086 }
00087
00088 if ((!(msg->from)->parsed) && (parse_from_header(msg) < 0)) {
00089 LOG(L_ERR, "AUTH_IDENTITY:fromhdr_proc: Error while parsing FROM body\n");
00090 return AUTH_ERROR;
00091 }
00092
00093 if (sout)
00094 *sout=get_from(msg)->uri;
00095
00096 if (soutopt)
00097 *soutopt=get_from(msg)->tag_value;
00098
00099 return AUTH_OK;
00100 }
00101
00102
00103 static int tohdr_proc(str *sout, str *soutopt, struct sip_msg *msg)
00104 {
00105 if (!msg->to && (parse_headers(msg, HDR_TO_F, 0) == -1)) {
00106 LOG(L_ERR, "AUTH_IDENTITY:tohdr_proc: Error while parsing TO header\n");
00107 return AUTH_ERROR;
00108 }
00109 if (!msg->to) {
00110 LOG(L_ERR, "AUTH_IDENTITY:tohdr_proc: TO header field is not found\n");
00111 return AUTH_NOTFOUND;
00112 }
00113 if (!msg->to->parsed) {
00114 LOG(L_ERR, "AUTH_IDENTITY:tohdr_proc: TO is not parsed\n");
00115 return AUTH_ERROR;
00116 }
00117
00118 if (sout)
00119 *sout=((struct to_body*)msg->to->parsed)->uri;
00120
00121 return AUTH_OK;
00122 }
00123
00124
00125 int callidhdr_proc(str *sout, str *soutopt, struct sip_msg *msg)
00126 {
00127 if (!msg->callid && (parse_headers(msg, HDR_CALLID_F, 0) == -1)) {
00128 LOG(L_ERR, "AUTH_IDENTITY:callidhdr_proc: error while parsing CALLID header\n");
00129 return AUTH_ERROR;
00130 }
00131 if (!msg->callid) {
00132 LOG(L_ERR, "AUTH_IDENTITY:callidhdr_proc: CALLID header field is not found\n");
00133 return AUTH_NOTFOUND;
00134 }
00135
00136 if (sout)
00137 *sout=msg->callid->body;
00138
00139 return AUTH_OK;
00140 }
00141
00142
00143 int cseqhdr_proc(str *sout, str *soutopt, struct sip_msg *msg)
00144 {
00145 if (!msg->cseq && (parse_headers(msg, HDR_CSEQ_F, 0) == -1)) {
00146 LOG(L_ERR, "AUTH_IDENTITY:cseqhdr_proc: Error while parsing CSEQ header\n");
00147 return AUTH_ERROR;
00148 }
00149 if (!msg->cseq) {
00150 LOG(L_ERR, "AUTH_IDENTITY:cseqhdr_proc: CSEQ header field is not found\n");
00151 return AUTH_NOTFOUND;
00152 }
00153 if (!msg->cseq->parsed) {
00154 LOG(L_ERR, "AUTH_IDENTITY:cseqhdr_proc: CSEQ is not parsed\n");
00155 return AUTH_ERROR;
00156 }
00157
00158 if (sout)
00159 *sout=get_cseq(msg)->number;
00160 if (soutopt)
00161 *soutopt=get_cseq(msg)->method;
00162
00163 return AUTH_OK;
00164 }
00165
00166
00167 int datehdr_proc(str *sout, str *soutopt, struct sip_msg *msg)
00168 {
00169 if ((!msg->date) && (parse_headers(msg, HDR_DATE_F, 0) == -1)) {
00170 LOG(L_ERR, "AUTH_IDENTITY:datehdr_proc: Error while parsing DATE header\n");
00171 return AUTH_ERROR;
00172 }
00173 if (!msg->date) {
00174 LOG(AUTH_DBG_LEVEL, "AUTH_IDENTITY:datehdr_proc: DATE header field is not found\n");
00175 return AUTH_NOTFOUND;
00176 }
00177
00178 if ((!(msg->date)->parsed) && (parse_date_header(msg) < 0)) {
00179 LOG(L_ERR, "AUTH_IDENTITY:datehdr_proc: Error while parsing DATE body\n");
00180 return AUTH_ERROR;
00181 }
00182
00183 if (sout)
00184 *sout=msg->date->body;
00185
00186 return AUTH_OK;
00187 }
00188
00189
00190 static int in_contacthdr_proc(str *sout, str *soutopt, struct sip_msg *msg)
00191 {
00192 if (!msg->contact && (parse_headers(msg, HDR_CONTACT_F, 0) == -1)) {
00193 LOG(L_ERR, "AUTH_IDENTITY:in_contacthdr_proc: Error while parsing CONTACT header\n");
00194 return AUTH_ERROR;
00195 }
00196 if (!msg->contact) {
00197 return AUTH_NOTFOUND;
00198 }
00199
00200 if (!msg->contact->parsed && (parse_contact(msg->contact) < 0)) {
00201 LOG(L_ERR, "AUTH_IDENTITY:in_contacthdr_proc: Error while parsing CONTACT body\n");
00202 return AUTH_ERROR;
00203 }
00204
00205 if (sout)
00206 *sout=((contact_body_t*)msg->contact->parsed)->contacts->uri;
00207
00208 return AUTH_OK;
00209 }
00210
00211
00212 static int out_contacthdr_proc(str *sout, str *soutopt, struct sip_msg *msg)
00213 {
00214 unsigned int ulen;
00215 int ierror;
00216 struct dest_info dst;
00217 int ires;
00218
00219
00220 #ifdef USE_DNS_FAILOVER
00221
00222 if ((uri2dst(NULL, &dst, msg, GET_NEXT_HOP(msg), PROTO_NONE) == 0)
00223 #else
00224 if ((uri2dst(&dst, msg, GET_NEXT_HOP(msg), PROTO_NONE) == 0)
00225 #endif
00226 || (dst.send_sock == 0)) {
00227 LOG(L_ERR, "AUTH_IDENTITY:out_contacthdr_proc: Can't determinate destination socket\n");
00228 return -1;
00229 }
00230
00231
00232 glb_siphdr=build_only_headers(msg, 1, &ulen, &ierror, &dst);
00233
00234 if (ierror)
00235 return -2;
00236
00237 memset(&glb_contact, 0, sizeof(glb_contact));
00238
00239
00240 ires=get_contact_body(glb_siphdr, ulen, &glb_contact.body);
00241 if (ires==AUTH_NOTFOUND) {
00242 pkg_free(glb_siphdr); glb_siphdr=NULL;
00243 return AUTH_NOTFOUND;
00244 }
00245 if (ires!=AUTH_OK) {
00246 pkg_free(glb_siphdr); glb_siphdr=NULL;
00247 return AUTH_ERROR;
00248 }
00249
00250 if (parse_contact(&glb_contact) < 0) {
00251 pkg_free(glb_siphdr); glb_siphdr=NULL;
00252 return AUTH_ERROR;
00253 }
00254
00255 if (sout)
00256 *sout=((contact_body_t*)glb_contact.parsed)->contacts->uri;
00257
00258 return AUTH_OK;
00259 }
00260
00261
00262 int identityhdr_proc(str *sout, str *soutopt, struct sip_msg *msg)
00263 {
00264 if (!msg->identity && (parse_headers(msg, HDR_IDENTITY_F, 0) == -1)) {
00265 LOG(L_ERR, "AUTH_IDENTITY:identityhdr_proc: Error while parsing IDENTITY header\n");
00266 return AUTH_ERROR;
00267 }
00268 if (!msg->identity) {
00269 return AUTH_NOTFOUND;
00270 }
00271
00272 if ((!(msg->identity)->parsed) && (parse_identity_header(msg) < 0)) {
00273 LOG(L_ERR, "AUTH_IDENTITY:identityhdr_proc: Error while parsing IDENTITY body\n");
00274 return AUTH_ERROR;
00275 }
00276
00277 if (sout)
00278 *sout=get_identity(msg)->hash;
00279
00280 return AUTH_OK;
00281 }
00282
00283
00284 int identityinfohdr_proc(str *sout, str *soutopt, struct sip_msg *msg)
00285 {
00286 if (!msg->identity_info && (parse_headers(msg, HDR_IDENTITY_INFO_F, 0) == -1)) {
00287 LOG(L_ERR, "AUTH_IDENTITY:identityinfohdr_proc: Error while parsing IDENTITY-INFO header\n");
00288 return AUTH_ERROR;
00289 }
00290 if (!msg->identity_info) {
00291 LOG(L_ERR, "AUTH_IDENTITY:identityinfohdr_proc: IDENTITY-INFO header field is not found\n");
00292 return AUTH_NOTFOUND;
00293 }
00294
00295 if ((!(msg->identity_info)->parsed) && (parse_identityinfo_header(msg) < 0)) {
00296 LOG(L_ERR, "AUTH_IDENTITY:identityinfohdr_proc: Error while parsing IDENTITY-INFO body\n");
00297 return AUTH_ERROR;
00298 }
00299
00300 if (sout)
00301 *sout=get_identityinfo(msg)->uri;
00302 if (soutopt)
00303 *soutopt=get_identityinfo(msg)->domain;
00304
00305 return AUTH_OK;
00306 }
00307
00308
00309 static int in_msgbody_proc(str *sout, str *soutopt, struct sip_msg *msg)
00310 {
00311 if (!sout)
00312 return AUTH_OK;
00313
00314 sout->s = get_body(msg);
00315 if (!sout->s || sout->s[0] == 0) {
00316 sout->len = 0;
00317 } else {
00318 if (!msg->content_length) {
00319 LOG(L_ERR, "AUTH_IDENTITY:route_msgbody_proc: no Content-Length header found!\n");
00320 return AUTH_ERROR;
00321 }
00322 sout->len = get_content_length(msg);
00323 }
00324
00325 return AUTH_OK;
00326 }
00327
00328
00329 static int out_msgbody_proc(str *sout, str *soutopt, struct sip_msg *msg)
00330 {
00331
00332 unsigned int len;
00333 int err;
00334 struct dest_info dst;
00335 char scontentlen[AUTH_CONTENTLENGTH_LENGTH];
00336
00337
00338 if (!sout)
00339 return AUTH_OK;
00340
00341 #ifdef USE_DNS_FAILOVER
00342
00343 if ((uri2dst(NULL, &dst, msg, GET_NEXT_HOP(msg), PROTO_NONE) == 0)
00344 #else
00345 if ((uri2dst(&dst, msg, GET_NEXT_HOP(msg), PROTO_NONE) == 0)
00346 #endif
00347 || (dst.send_sock == 0)) {
00348 LOG(L_ERR, "AUTH_IDENTITY:rtend_msgbody_proc: Can't determinate destination socket\n");
00349 return -1;
00350 }
00351
00352
00353 sout->s = glb_msgbody = build_body(msg, &len, &err, &dst);
00354 if (err) {
00355 LOG(L_ERR, "AUTH_IDENTITY:rtend_msgbody_proc: Can't build body (%d)\n", err);
00356 return -2;
00357 }
00358
00359 sout->len = (int)len;
00360
00361
00362
00363
00364
00365
00366
00367 if (!msg->content_length && dst.proto==PROTO_UDP) {
00368 snprintf(scontentlen, sizeof(scontentlen), "Content-Length: %d\r\n", len);
00369 scontentlen[sizeof(scontentlen)-1]=0;
00370
00371 if (append_hf(msg, scontentlen, HDR_OTHER_T)) {
00372 pkg_free(glb_msgbody);
00373 glb_msgbody=NULL;
00374 return -3;
00375 }
00376 }
00377
00378 return AUTH_OK;
00379 }
00380
00381
00382 static void free_out_contacthdr(void)
00383 {
00384 void** h_parsed;
00385
00386 h_parsed=&glb_contact.parsed;
00387 if (glb_siphdr) {
00388 pkg_free(glb_siphdr);
00389 glb_siphdr=NULL;
00390 }
00391
00392 if (glb_contact.parsed)
00393 free_contact((contact_body_t**)h_parsed);
00394 }
00395
00396
00397 static void free_out_msgbody(void)
00398 {
00399 if (glb_msgbody) {
00400 pkg_free(glb_msgbody);
00401 glb_msgbody=NULL;
00402 }
00403 }
00404
00405
00406 int digeststr_asm(dynstr *sout, struct sip_msg *msg, str *sdate, int iflags)
00407 {
00408
00409 dgst_part incoming_sip_digest_desc[] = {
00410 { DS_FROM, fromhdr_proc, NULL, DS_REQUIRED },
00411 { DS_TO, tohdr_proc, NULL, DS_REQUIRED },
00412 { DS_CALLID, callidhdr_proc, NULL, DS_REQUIRED },
00413 { DS_CSEQ, cseqhdr_proc, NULL, DS_REQUIRED },
00414 { DS_DATE, datehdr_proc, NULL, DS_NOTREQUIRED },
00415 { DS_CONTACT, in_contacthdr_proc, NULL, DS_NOTREQUIRED },
00416 { DS_BODY, in_msgbody_proc, NULL, DS_NOTREQUIRED },
00417 { 0, NULL, NULL, 0 }
00418 };
00419
00420 dgst_part outgoing_sip_digest_desc[] = {
00421 { DS_FROM, fromhdr_proc, NULL, DS_REQUIRED },
00422 { DS_TO, tohdr_proc, NULL, DS_REQUIRED },
00423 { DS_CALLID, callidhdr_proc, NULL, DS_REQUIRED },
00424 { DS_CSEQ, cseqhdr_proc, NULL, DS_REQUIRED },
00425 { DS_DATE, datehdr_proc, NULL, DS_NOTREQUIRED },
00426 { DS_CONTACT, out_contacthdr_proc, free_out_contacthdr, DS_NOTREQUIRED },
00427 { DS_BODY, out_msgbody_proc, free_out_msgbody, DS_NOTREQUIRED },
00428 { 0, NULL, NULL, 0 }
00429 };
00430 dgst_part *pactpart;
00431 dgst_part *sip_digest_desc;
00432 str sact, sactopt;
00433 int i1;
00434 int iRes;
00435
00436
00437 if ((iflags & AUTH_INCOMING_BODY) ^ (iflags & AUTH_OUTGOING_BODY)) {
00438 (iflags & AUTH_INCOMING_BODY) ?
00439 (sip_digest_desc = incoming_sip_digest_desc) :
00440 (sip_digest_desc = outgoing_sip_digest_desc);
00441 } else
00442
00443 return -1;
00444
00445 resetstr_dynstr(sout);
00446
00447 for (pactpart=&sip_digest_desc[0],i1=0; pactpart[i1].itype; i1++) {
00448 iRes=pactpart[i1].pfunc(&sact, &sactopt, msg);
00449
00450
00451 if (iRes==AUTH_ERROR
00452 || (iRes==AUTH_NOTFOUND && (pactpart[i1].iflag & DS_REQUIRED)))
00453 return -1;
00454
00455 switch (pactpart[i1].itype) {
00456
00457 case DS_CSEQ:
00458 if (app2dynstr(sout,&sact))
00459 return -1;
00460 if (app2dynchr(sout,' '))
00461 return -2;
00462 if (app2dynstr(sout,&sactopt))
00463 return -3;
00464 break;
00465 case DS_DATE:
00466 if (iRes==AUTH_NOTFOUND) {
00467 if (iflags & AUTH_ADD_DATE) {
00468 if (app2dynstr(sout,sdate))
00469 return -8;
00470 } else {
00471
00472 LOG(L_ERR, "AUTH_IDENTITY:digeststr_asm: DATE header is not found\n");
00473 return -9;
00474 }
00475 }
00476 default:
00477 if (iRes==AUTH_NOTFOUND)
00478 break;
00479 if (app2dynstr(sout,&sact))
00480 return -10;
00481 }
00482
00483
00484 if (pactpart[i1].pfreefunc)
00485 pactpart[i1].pfreefunc();
00486
00487
00488 if (pactpart[i1+1].itype) {
00489
00490 if (app2dynchr(sout,'|'))
00491 return -11;
00492 }
00493 }
00494
00495 return 0;
00496 }
00497
00498
00499 int append_hf(struct sip_msg* msg, char *str1, enum _hdr_types_t type)
00500 {
00501 struct lump* anchor;
00502 char* s;
00503 int len;
00504
00505 if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
00506 LOG(L_ERR, "AUTH_IDENTITY:append_hf: Error while parsing message\n");
00507 return -1;
00508 }
00509
00510 anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, type);
00511 if (anchor == 0) {
00512 LOG(L_ERR, "AUTH_IDENTITY:append_hf: Can't get anchor\n");
00513 return -1;
00514 }
00515
00516 len=strlen(str1);
00517
00518 s = (char*)pkg_malloc(len);
00519 if (!s) {
00520 LOG(L_ERR, "AUTH_IDENTITY:append_hf: No memory left\n");
00521 return -1;
00522 }
00523
00524 memcpy(s, str1, len);
00525
00526 if (insert_new_lump_before(anchor, s, len, type) == 0) {
00527 LOG(L_ERR, "AUTH_IDENTITY:append_hf: Can't insert lump\n");
00528 pkg_free(s);
00529 return -1;
00530 }
00531 return 0;
00532 }
00533
00534
00535 int append_date(str *sdate, int idatesize, time_t *tout, struct sip_msg *msg)
00536 {
00537 char date_hf[AUTH_TIME_LENGTH];
00538 char date_str[AUTH_TIME_LENGTH];
00539 time_t tdate_now;
00540 struct tm *bd_time;
00541 size_t ilen;
00542 int istrlen;
00543
00544
00545 if ((tdate_now=time(0)) < 0) {
00546 LOG(L_ERR, "AUTH_IDENTITY:append_date: time error %s\n", strerror(errno));
00547 return -1;
00548 }
00549 if (!(bd_time=gmtime(&tdate_now))) {
00550 LOG(L_ERR, "AUTH_IDENTITY:append_date: gmtime error\n");
00551 return -2;
00552 }
00553
00554 ilen=strftime(date_str, sizeof(date_str), AUTH_TIME_FORMAT, bd_time);
00555 if (ilen > sizeof(date_hf) - strlen("Date: \r\n") || ilen==0) {
00556 LOG(L_ERR, "AUTH_IDENTITY:append_date: unexpected time length\n");
00557 return -3;
00558 }
00559
00560
00561 istrlen=strlen("Date: ");
00562 memcpy(date_hf,"Date: ",istrlen);
00563 memcpy(date_hf+istrlen,date_str,ilen);
00564 istrlen+=ilen;
00565 date_hf[istrlen]='\r'; date_hf[istrlen+1]='\n'; date_hf[istrlen+2]=0;
00566 if (append_hf(msg, date_hf, HDR_DATE_T))
00567 return -4;
00568
00569 if (sdate && idatesize >= ilen) {
00570 memcpy(sdate->s, date_str, ilen);
00571 sdate->len=ilen;
00572 } else
00573 return -5;
00574 if (tout)
00575 *tout=tdate_now;
00576
00577 return 0;
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588 static char *auth_next_line(char *buf, char *buf_end)
00589 {
00590 char *c;
00591
00592 c = buf;
00593 do {
00594 while ((c < buf_end) && (*c != '\n')) c++;
00595 if (c < buf_end) c++;
00596 if ((c < buf_end) && (*c == '\r')) c++;
00597
00598 } while ((c < buf_end) && ((*c == ' ') || (*c == '\t')));
00599
00600 return c;
00601 }
00602
00603
00604
00605
00606
00607 static inline char* skip_ws(char* p, unsigned int size)
00608 {
00609 char* end;
00610
00611 end = p + size;
00612 for(; p < end; p++) {
00613 if ((*p != ' ') && (*p != '\t')) return p;
00614 }
00615 return p;
00616 }
00617
00618
00619 static char *auth_get_hf_name(char *begin, char *end, enum _hdr_types_t *type)
00620 {
00621 char *p;
00622 unsigned int val;
00623
00624
00625 if (end - begin < 4) {
00626 *type = HDR_ERROR_T;
00627 return begin;
00628 }
00629
00630 p = begin;
00631 val = LOWER_DWORD(READ(p));
00632
00633 switch(val) {
00634 case _cont_:
00635 p+=4;
00636 switch (LOWER_DWORD(READ(p))) {
00637 case _act1_:
00638 *type = HDR_CONTACT_T;
00639 return (p + 4);
00640 case _act2_:
00641 *type = HDR_CONTACT_T;
00642 p += 4;
00643 goto dc_end;
00644 }
00645 default:
00646
00647 switch(LOWER_BYTE(*p)) {
00648 case 'm':
00649 switch(*(p + 1)) {
00650 case ' ':
00651 *type = HDR_CONTACT_T;
00652 p += 2;
00653 goto dc_end;
00654 case ':':
00655 *type = HDR_CONTACT_T;
00656 return (p + 2);
00657 }
00658 default:
00659 *type = HDR_OTHER_T;
00660 break;
00661 }
00662 }
00663
00664 dc_end:
00665 p = skip_ws(p, end - p);
00666 if (*p != ':') {
00667 goto other;
00668 } else {
00669 return (p + 1);
00670 }
00671
00672
00673 other:
00674 p = q_memchr(p, ':', end - p);
00675 if (!p) {
00676 *type = HDR_ERROR_T;
00677 return 0;
00678 } else {
00679 *type = HDR_OTHER_T;
00680 return (p + 1);
00681 }
00682
00683 return p;
00684 }
00685
00686
00687
00688 static int get_contact_body(char *buf, unsigned int len, str *sout)
00689 {
00690 char *end, *s, *tmp, *match;
00691 enum _hdr_types_t hf_type;
00692
00693
00694 end = buf + len;
00695 s = buf;
00696
00697 memset(sout, 0, sizeof(*sout));
00698
00699 while (s < end) {
00700 if ((*s == '\n') || (*s == '\r')) {
00701
00702 hf_type = HDR_EOH_T;
00703 } else {
00704
00705 if (!(s = auth_get_hf_name(s, end, &hf_type)))
00706 return AUTH_ERROR;
00707 }
00708
00709 switch(hf_type) {
00710 case HDR_CONTACT_T:
00711 tmp=eat_lws_end(s, end);
00712 if (tmp>=end) {
00713 LOG(L_ERR, "AUTH_IDENTITY:get_contact_body: get_hdr_field: HF empty\n");
00714 return AUTH_ERROR;
00715 }
00716 sout->s=tmp;
00717
00718 do{
00719 match=q_memchr(tmp, '\n', end-tmp);
00720 if (match){
00721 match++;
00722 }else {
00723 LOG(L_ERR, "AUTH_IDENTITY:get_contact_body: bad msg body\n");
00724 return AUTH_ERROR;
00725 }
00726 tmp=match;
00727 } while( match<end &&( (*match==' ')||(*match=='\t') ) );
00728 tmp=match;
00729 sout->len=match-sout->s;
00730 trim_r(*sout);
00731 return AUTH_OK;
00732 break;
00733 case HDR_ERROR_T:
00734 return AUTH_ERROR;
00735 default:
00736 s = auth_next_line(s, end);
00737 }
00738 }
00739
00740 return AUTH_NOTFOUND;
00741 }