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
00028
00029
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <sys/types.h>
00034 #include <sys/socket.h>
00035 #include <netinet/in.h>
00036 #include <netdb.h>
00037 #include <string.h>
00038
00039
00040 #include "../../mem/mem.h"
00041 #include "../../mem/shm_mem.h"
00042
00043
00044 #include "../../dprint.h"
00045 #include "../../str.h"
00046 #include "../../ut.h"
00047
00048
00049 #include "../../parser/digest/digest.h"
00050 #include "../../parser/parse_uri.h"
00051 #include "../../parser/parse_from.h"
00052 #include "../../parser/parse_to.h"
00053
00054
00055 #include "../../data_lump_rpl.h"
00056
00057
00058 #include "diameter_msg.h"
00059 #include "auth_diameter.h"
00060 #include "defs.h"
00061 #include "../auth/api.h"
00062 #include "authorize.h"
00063 #include "tcp_comm.h"
00064
00065 static str dia_401_err = str_init(MESSAGE_401);
00066 static str dia_403_err = str_init("Forbidden");
00067 static str dia_407_err = str_init(MESSAGE_407);
00068 static str dia_400_err = str_init(MESSAGE_400);
00069 static str dia_500_err = str_init(MESSAGE_500);
00070
00071
00072
00073
00074 int get_uri(struct sip_msg* m, str** uri)
00075 {
00076 if ((REQ_LINE(m).method.len == 8) &&
00077 (memcmp(REQ_LINE(m).method.s, "REGISTER", 8) == 0))
00078 {
00079
00080 if (!m->to && ((parse_headers(m, HDR_TO_F, 0) == -1)|| (!m->to)))
00081 {
00082 LM_ERR("the To header field was not found or malformed\n");
00083
00084
00085 return -1;
00086 }
00087 *uri = &(get_to(m)->uri);
00088 }
00089 else
00090 {
00091 if (parse_from_header(m)<0)
00092 {
00093 LM_ERR("failed to parse FROM header\n");
00094
00095
00096 return -1;
00097 }
00098 *uri = &(get_from(m)->uri);
00099 }
00100
00101
00102 return 0;
00103 }
00104
00105
00106
00107 int get_realm(struct sip_msg* m, int hftype, struct sip_uri* u)
00108 {
00109 str uri;
00110
00111
00112 if ((REQ_LINE(m).method.len==8)
00113 && !memcmp(REQ_LINE(m).method.s, "REGISTER", 8)
00114 && (hftype == HDR_AUTHORIZATION_T) )
00115 {
00116
00117 if (!m->to && ((parse_headers(m, HDR_TO_F, 0) == -1) || (!m->to)))
00118 {
00119 LM_ERR("failed to parse TO header\n");
00120
00121 return -1;
00122 }
00123
00124
00125 uri = get_to(m)->uri;
00126 }
00127 else
00128 {
00129 if (parse_from_header(m)<0)
00130 {
00131 LM_ERR("failed to parse FROM header\n");
00132
00133 return -1;
00134 }
00135
00136 uri = get_from(m)->uri;
00137 }
00138
00139
00140 if (parse_uri(uri.s, uri.len, u) < 0)
00141 {
00142 LM_ERR("failed to parse URI\n");
00143 return -1;
00144 }
00145
00146
00147 return 0;
00148 }
00149
00150
00151 int find_credentials(struct sip_msg* _m, str* _realm, int _hftype,
00152 struct hdr_field** _h)
00153 {
00154 struct hdr_field** hook, *ptr, *prev;
00155 int res;
00156 hdr_flags_t hdr_flags;
00157 str* r;
00158
00159 switch(_hftype)
00160 {
00161 case HDR_AUTHORIZATION_T:
00162 hook = &(_m->authorization);
00163 hdr_flags=HDR_AUTHORIZATION_F;
00164 break;
00165 case HDR_PROXYAUTH_T:
00166 hook = &(_m->proxy_auth);
00167 hdr_flags=HDR_PROXYAUTH_F;
00168 break;
00169 default:
00170 hook = &(_m->authorization);
00171 hdr_flags=HDR_T2F(_hftype);
00172 break;
00173 }
00174
00175
00176 if (*hook == 0)
00177 if (parse_headers(_m, hdr_flags, 0) == -1)
00178 {
00179 LM_ERR("failed to parse headers\n");
00180 return -1;
00181 }
00182
00183 ptr = *hook;
00184
00185
00186
00187
00188 while(ptr)
00189 {
00190 res = parse_credentials(ptr);
00191 if (res < 0)
00192 {
00193 LM_ERR("failed to parse credentials\n");
00194 return (res == -1) ? -2 : -3;
00195 }
00196 else
00197 if (res == 0)
00198 {
00199 r = &(((auth_body_t*)(ptr->parsed))->digest.realm);
00200
00201 if (r->len == _realm->len)
00202 {
00203 if (!strncasecmp(_realm->s, r->s, r->len))
00204 {
00205 *_h = ptr;
00206 return 0;
00207 }
00208 }
00209 }
00210
00211 prev = ptr;
00212 if (parse_headers(_m, hdr_flags, 1) == -1)
00213 {
00214 LM_ERR("failed to parse headers\n");
00215 return -4;
00216 }
00217 else
00218 {
00219 if (prev != _m->last_header)
00220 {
00221 if (_m->last_header->type == _hftype) ptr = _m->last_header;
00222 else break;
00223 }
00224 else break;
00225 }
00226 }
00227
00228
00229 return 1;
00230 }
00231
00232
00233 auth_result_t diam_pre_auth(struct sip_msg* _m, str* _realm, int _hftype,
00234 struct hdr_field** _h)
00235 {
00236 int ret;
00237 struct sip_uri uri;
00238
00239 if ((_m->REQ_METHOD == METHOD_ACK) || (_m->REQ_METHOD == METHOD_CANCEL))
00240 return AUTHORIZED;
00241
00242
00243 if (_realm==0 || _realm->len == 0)
00244 {
00245 if (get_realm(_m, _hftype, &uri) < 0)
00246 {
00247 LM_ERR("failed to extract realm\n");
00248 if (send_resp(_m, 400, &dia_400_err, 0, 0) == -1)
00249 {
00250 LM_ERR("failed to send 400 reply\n");
00251 }
00252 return ERROR;
00253 }
00254
00255 *_realm = uri.host;
00256 }
00257
00258 ret = find_credentials(_m, _realm, _hftype, _h);
00259 if (ret < 0)
00260 {
00261 LM_ERR("credentials not found\n");
00262 if (send_resp(_m, (ret == -2) ? 500 : 400,
00263 (ret == -2) ? &dia_500_err : &dia_400_err, 0, 0) == -1)
00264 {
00265 LM_ERR("failed to send 400 reply\n");
00266 }
00267 return ERROR;
00268 }
00269 else
00270 if (ret > 0)
00271 {
00272 LM_ERR("credentials with given realm not found\n");
00273 return NO_CREDENTIALS;
00274 }
00275
00276
00277 return DO_AUTHORIZATION;
00278 }
00279
00280
00281
00282 int authorize(struct sip_msg* msg, pv_elem_t* realm, int hftype)
00283 {
00284 auth_result_t ret;
00285 struct hdr_field* h;
00286 auth_body_t* cred = NULL;
00287 str* uri;
00288 struct sip_uri puri;
00289 str domain;
00290
00291 if (realm) {
00292 if (pv_printf_s(msg, realm, &domain)!=0) {
00293 LM_ERR("pv_printf_s failed\n");
00294 return AUTH_ERROR;
00295 }
00296 } else {
00297 domain.len = 0;
00298 domain.s = 0;
00299 }
00300
00301
00302 ret = diam_pre_auth(msg, &domain, hftype, &h);
00303
00304 switch(ret)
00305 {
00306 case NO_CREDENTIALS: cred = NULL;
00307 break;
00308
00309 case DO_AUTHORIZATION: cred = (auth_body_t*)h->parsed;
00310 break;
00311 default: return ret;
00312 }
00313
00314 if (get_uri(msg, &uri) < 0)
00315 {
00316 LM_ERR("From/To URI not found\n");
00317 return AUTH_ERROR;
00318 }
00319
00320 if (parse_uri(uri->s, uri->len, &puri) < 0)
00321 {
00322 LM_ERR("failed to parse From/To URI\n");
00323 return AUTH_ERROR;
00324 }
00325
00326
00327
00328
00329 if(msg->parsed_uri_ok==0 && parse_sip_msg_uri(msg)<0)
00330 {
00331 LM_ERR("failed to parse the Request-URI\n");
00332 return AUTH_ERROR;
00333 }
00334
00335
00336 if(cred)
00337 {
00338 if (puri.host.len != cred->digest.realm.len)
00339 {
00340 LM_DBG("credentials realm and URI host do not match\n");
00341 return AUTH_ERROR;
00342 }
00343
00344 if (strncasecmp(puri.host.s, cred->digest.realm.s, puri.host.len) != 0)
00345 {
00346 LM_DBG("credentials realm and URI host do not match\n");
00347 return AUTH_ERROR;
00348 }
00349 }
00350
00351 if( diameter_authorize(cred?h:NULL, &msg->first_line.u.request.method,
00352 puri, msg->parsed_uri, msg->id, rb) != 1)
00353 {
00354 send_resp(msg, 500, &dia_500_err, NULL, 0);
00355 return AUTH_ERROR;
00356 }
00357
00358 if( srv_response(msg, rb, hftype) != 1 )
00359 return AUTH_ERROR;
00360
00361 mark_authorized_cred(msg, h);
00362
00363 return AUTHORIZED;
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 int diameter_authorize(struct hdr_field* hdr, str* p_method, struct sip_uri uri,
00378 struct sip_uri ruri, unsigned int m_id, rd_buf_t* rb)
00379 {
00380 str method, user_name;
00381 AAAMessage *req;
00382 AAA_AVP *avp, *position;
00383 int name_flag, port_flag;
00384 dig_cred_t* cred;
00385 unsigned int tmp;
00386
00387 if ( !p_method )
00388 {
00389 LM_ERR("invalid parameter value\n");
00390 return -1;
00391 }
00392
00393 if ( (req=AAAInMessage(AA_REQUEST, AAA_APP_NASREQ))==NULL)
00394 return -1;
00395
00396 if(hdr && hdr->parsed)
00397 cred = &(((auth_body_t*)hdr->parsed)->digest);
00398 else
00399 cred = NULL;
00400
00401 method = *p_method;
00402
00403 if(!cred)
00404 {
00405
00406 user_name.s = 0;
00407 user_name.len = uri.user.len + uri.host.len;
00408 if(user_name.len>0)
00409 {
00410 user_name.len += 2;
00411 user_name.s = (char*)ad_malloc(user_name.len*sizeof(char));
00412 memset(user_name.s, 0, user_name.len);
00413
00414 memcpy(user_name.s, uri.user.s, uri.user.len);
00415 if(uri.user.len>0)
00416 {
00417 memcpy(user_name.s+uri.user.len, "@", 1);
00418 memcpy(user_name.s+uri.user.len+1, uri.host.s, uri.host.len);
00419 }
00420 else
00421 memcpy(user_name.s, uri.host.s, uri.host.len);
00422 }
00423
00424 if( (avp=AAACreateAVP(AVP_User_Name, 0, 0, user_name.s,
00425 user_name.len, AVP_FREE_DATA)) == 0)
00426 {
00427 LM_ERR("no more pkg memory left!\n");
00428 if(user_name.len>0)
00429 pkg_free(user_name.s);
00430 goto error;
00431 }
00432 if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
00433 {
00434 LM_ERR("avp not added \n");
00435 goto error1;
00436 }
00437 }
00438 else
00439 {
00440
00441 if (cred->username.domain.len>0)
00442 {
00443 if( (avp=AAACreateAVP(AVP_User_Name, 0, 0, cred->username.whole.s,
00444 cred->username.whole.len, AVP_DUPLICATE_DATA)) == 0)
00445 {
00446 LM_ERR("no more pkg memory left!\n");
00447 goto error;
00448 }
00449
00450 if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
00451 {
00452 LM_ERR("avp not added \n");
00453 goto error1;
00454 }
00455 }
00456 else
00457 {
00458 user_name.s = 0;
00459 user_name.len = cred->username.user.len + cred->realm.len;
00460 if(user_name.len>0)
00461 {
00462 user_name.s = ad_malloc(user_name.len);
00463 if (!user_name.s)
00464 {
00465 LM_ERR(" no more pkg memory left\n");
00466 goto error;
00467 }
00468 memcpy(user_name.s, cred->username.whole.s,
00469 cred->username.whole.len);
00470 if(cred->username.whole.len>0)
00471 {
00472 user_name.s[cred->username.whole.len] = '@';
00473 memcpy(user_name.s + cred->username.whole.len + 1,
00474 cred->realm.s, cred->realm.len);
00475 }
00476 else
00477 memcpy(user_name.s, cred->realm.s, cred->realm.len);
00478 }
00479
00480 if( (avp=AAACreateAVP(AVP_User_Name, 0, 0, user_name.s,
00481 user_name.len, AVP_FREE_DATA)) == 0)
00482 {
00483 LM_ERR(" no more pkg memory left!\n");
00484 if(user_name.len>0)
00485 pkg_free(user_name.s);
00486 goto error;
00487 }
00488
00489 if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
00490 {
00491 LM_ERR(" avp not added \n");
00492 goto error1;
00493 }
00494 }
00495 }
00496
00497
00498 LM_DBG("******* m_id=%d\n", m_id);
00499 tmp = m_id;
00500 if( (avp=AAACreateAVP(AVP_SIP_MSGID, 0, 0, (char*)(&tmp),
00501 sizeof(m_id), AVP_DUPLICATE_DATA)) == 0)
00502 {
00503 LM_ERR(" no more pkg memory left!\n");
00504 goto error;
00505 }
00506 if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
00507 {
00508 LM_ERR(" avp not added \n");
00509 goto error1;
00510 }
00511
00512
00513
00514
00515 if( (avp=AAACreateAVP(AVP_Service_Type, 0, 0, SIP_AUTHENTICATION,
00516 SERVICE_LEN, AVP_DUPLICATE_DATA)) == 0)
00517 {
00518 LM_ERR(" no more pkg memory left!\n");
00519 goto error;
00520 }
00521 if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
00522 {
00523 LM_ERR(" avp not added \n");
00524 goto error1;
00525 }
00526
00527
00528 if( (avp=AAACreateAVP(AVP_Destination_Realm, 0, 0, uri.host.s,
00529 uri.host.len, AVP_DUPLICATE_DATA)) == 0)
00530 {
00531 LM_ERR(" no more pkg memory left!\n");
00532 goto error;
00533 }
00534
00535 #ifdef DEBUG
00536 LM_DBG("Destination Realm: %.*s\n", uri.host.len, uri.host.s);
00537 #endif
00538
00539 if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
00540 {
00541 LM_ERR(" avp not added \n");
00542 goto error1;
00543 }
00544
00545
00546 user_name.len = ruri.user.len + ruri.host.len + ruri.port.len + 2;
00547 user_name.s = (char*)ad_malloc(user_name.len*sizeof(char));
00548 memset(user_name.s, 0, user_name.len);
00549 memcpy(user_name.s, ruri.user.s, ruri.user.len);
00550
00551 name_flag= 0;
00552 if(ruri.user.s)
00553 {
00554 name_flag = 1;
00555 memcpy(user_name.s+ruri.user.len, "@", 1);
00556 }
00557
00558 memcpy(user_name.s+ruri.user.len+name_flag, ruri.host.s, ruri.host.len);
00559
00560 port_flag=0;
00561 if(ruri.port.s)
00562 {
00563 port_flag = 1;
00564 memcpy(user_name.s+ruri.user.len+ruri.host.len+1, ":", 1);
00565 }
00566 memcpy(user_name.s+ruri.user.len+ruri.host.len+name_flag+port_flag,
00567 ruri.port.s, ruri.port.len);
00568 #ifdef DEBUG
00569 LM_DBG(": AVP_Resource=%.*s\n", user_name.len, user_name.s);
00570 #endif
00571
00572 if( (avp=AAACreateAVP(AVP_Resource, 0, 0, user_name.s,
00573 user_name.len, AVP_FREE_DATA)) == 0)
00574 {
00575 LM_ERR(" no more pkg memory left!\n");
00576 if(user_name.s)
00577 pkg_free(user_name.s);
00578 goto error;
00579 }
00580 if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
00581 {
00582 LM_ERR(" avp not added \n");
00583 goto error1;
00584 }
00585
00586 if(cred)
00587 {
00588
00589 if( (avp=AAACreateAVP(AVP_Response, 0, 0, hdr->body.s,
00590 hdr->body.len, AVP_DUPLICATE_DATA)) == 0)
00591 {
00592 LM_ERR(" no more pkg memory left!\n");
00593 goto error;
00594 }
00595
00596 position = AAAGetLastAVP(&(req->avpList));
00597 if( AAAAddAVPToMessage(req, avp, position)!= AAA_ERR_SUCCESS)
00598
00599 {
00600 LM_ERR(" avp not added \n");
00601 goto error1;
00602 }
00603
00604
00605 if( (avp=AAACreateAVP(AVP_Method, 0, 0, p_method->s,
00606 p_method->len, AVP_DUPLICATE_DATA)) == 0)
00607 {
00608 LM_ERR(" no more pkg memory left!\n");
00609 goto error;
00610 }
00611
00612 position = AAAGetLastAVP(&(req->avpList));
00613 if( AAAAddAVPToMessage(req, avp, position)!= AAA_ERR_SUCCESS)
00614
00615 {
00616 LM_ERR(" avp not added \n");
00617 goto error1;
00618 }
00619
00620
00621 }
00622 #ifdef DEBUG
00623 AAAPrintMessage(req);
00624 #endif
00625
00626
00627 if(AAABuildMsgBuffer(req) != AAA_ERR_SUCCESS)
00628 {
00629 LM_ERR(" message buffer not created\n");
00630 goto error;
00631 }
00632
00633 if(sockfd==AAA_NO_CONNECTION)
00634 {
00635 sockfd = init_mytcp(diameter_client_host, diameter_client_port);
00636 if(sockfd==AAA_NO_CONNECTION)
00637 {
00638 LM_ERR(" failed to reconnect to Diameter client\n");
00639 goto error;
00640 }
00641 }
00642
00643
00644 switch( tcp_send_recv(sockfd, req->buf.s, req->buf.len, rb, m_id) )
00645 {
00646 case AAA_ERROR:
00647 LM_ERR(" message sending to the"
00648 " DIAMETER backend authorization server failed\n");
00649 goto error;
00650
00651 case AAA_CONN_CLOSED:
00652 LM_NOTICE("connection to Diameter"
00653 " client closed.It will be reopened by the next request\n");
00654 close(sockfd);
00655 sockfd = AAA_NO_CONNECTION;
00656 goto error;
00657
00658 case AAA_TIMEOUT:
00659 LM_NOTICE("no response received\n");
00660 close(sockfd);
00661 sockfd = AAA_NO_CONNECTION;
00662 goto error;
00663 }
00664
00665 AAAFreeMessage(&req);
00666 return 1;
00667
00668 error1:
00669 AAAFreeAVP(&avp);
00670 error:
00671 AAAFreeMessage(&req);
00672 return -1;
00673 }
00674
00675
00676 int srv_response(struct sip_msg* msg, rd_buf_t * rb, int hftype)
00677 {
00678 int auth_hf_len=0, ret=0;
00679 char* auth_hf;
00680
00681 switch(rb->ret_code)
00682 {
00683 case AAA_AUTHORIZED:
00684 return 1;
00685
00686 case AAA_NOT_AUTHORIZED:
00687 send_resp(msg, 403, &dia_403_err, NULL, 0);
00688 return -1;
00689
00690 case AAA_SRVERR:
00691 send_resp(msg, 500, &dia_500_err, NULL, 0);
00692 return -1;
00693
00694 case AAA_CHALENGE:
00695 if(hftype==HDR_AUTHORIZATION_T)
00696 {
00697 auth_hf_len = WWW_AUTH_CHALLENGE_LEN+rb->chall_len;
00698 auth_hf = (char*)ad_malloc(auth_hf_len*(sizeof(char)));
00699 memset(auth_hf, 0, auth_hf_len);
00700 memcpy(auth_hf,WWW_AUTH_CHALLENGE, WWW_AUTH_CHALLENGE_LEN);
00701 memcpy(auth_hf+WWW_AUTH_CHALLENGE_LEN, rb->chall,
00702 rb->chall_len);
00703
00704 ret = send_resp(msg, 401, &dia_401_err, auth_hf, auth_hf_len);
00705
00706 }
00707 else
00708 {
00709 auth_hf_len = PROXY_AUTH_CHALLENGE_LEN+rb->chall_len;
00710 auth_hf = (char*)ad_malloc(auth_hf_len*(sizeof(char)));
00711 memset(auth_hf, 0, auth_hf_len);
00712 memcpy(auth_hf, PROXY_AUTH_CHALLENGE, PROXY_AUTH_CHALLENGE_LEN);
00713 memcpy(auth_hf + PROXY_AUTH_CHALLENGE_LEN, rb->chall,
00714 rb->chall_len);
00715 ret = send_resp(msg, 407, &dia_407_err, auth_hf, auth_hf_len);
00716 }
00717
00718 if (auth_hf) pkg_free(auth_hf);
00719
00720 if (ret == -1)
00721 {
00722 LM_ERR("failed to send challenge to the client of SER\n");
00723 return -1;
00724 }
00725 return -1;
00726 }
00727
00728
00729 return -1;
00730 }
00731
00732
00733
00734
00735
00736
00737 int send_resp(struct sip_msg* m, int code, str* reason,
00738 char* hdr, int hdr_len)
00739 {
00740
00741 if ((hdr) && (hdr_len)) {
00742 if (add_lump_rpl( m, hdr, hdr_len, LUMP_RPL_HDR)==0) {
00743 LM_ERR("unable to append hdr\n");
00744 return -1;
00745 }
00746 }
00747
00748 return slb.send_reply(m, code, reason);
00749 }
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766