auth_diameter/authorize.c

Go to the documentation of this file.
00001 /*
00002  * $Id: authorize.c 5598 2009-02-12 19:15:00Z miconda $
00003  *
00004  * Digest Authentication - Diameter support
00005  *
00006  * Copyright (C) 2001-2003 FhG Fokus
00007  *`
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  * 
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  * History:
00025  * -------
00026  * 2003-09-11: updated to new build_lump_rpl() interface (bogdan)
00027  * 2003-11-11: build_lump_rpl() removed, add_lump_rpl() has flags  (bogdan)
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 /* memory management */
00040 #include "../../mem/mem.h"
00041 #include "../../mem/shm_mem.h"
00042 
00043 /* printing messages, dealing with strings and other utils */
00044 #include "../../dprint.h"
00045 #include "../../str.h"
00046 #include "../../ut.h"
00047 
00048 /* digest parser headers */
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 /* necessary when dealing with lumps */
00055 #include "../../data_lump_rpl.h"
00056 
00057 /* headers defined by this module */
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 /* Extract URI depending on the request from To or From header */
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       /* REGISTER */
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          /* it was a REGISTER and an error appeared when parsing TO header*/
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          /* an error appeared when parsing FROM header */
00096          return -1;
00097       }
00098       *uri = &(get_from(m)->uri);
00099    }
00100 
00101     /* success */
00102    return 0;
00103 }
00104 
00105 
00106 /* Return parsed To or From host part of the parsed uri (that is realm) */
00107 int get_realm(struct sip_msg* m, int hftype, struct sip_uri* u)
00108 {
00109    str uri;
00110 
00111    /* extracting the uri */
00112    if ((REQ_LINE(m).method.len==8)
00113                && !memcmp(REQ_LINE(m).method.s, "REGISTER", 8) 
00114                && (hftype == HDR_AUTHORIZATION_T) ) 
00115    { 
00116       /* REGISTER */
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          /* signal the error */
00121          return -1;
00122       }
00123       
00124        /* Body of To header field is parsed automatically */
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          /* signal the error */
00133          return -1;
00134       }
00135 
00136       uri = get_from(m)->uri;
00137    }
00138    
00139    /* parsing the uri */
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    /* everything was OK */
00147    return 0;
00148 }
00149 
00150 /* Find credentials with given realm in a SIP message header */
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    /* If the credentials haven't been parsed yet, do it now */
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    /* Iterate through the credentials of the message to find 
00186       credentials with given realm 
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      /* Credentials with given realm not found */
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    /* if no realm supplied, find out now */
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 /* Authorize digest credentials */
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    /* see what is to do after a first look at the message */
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 // user.s = (char *)pkg_malloc(puri.user.len);
00326 // un_escape(&(puri.user), &user);
00327    
00328    /* parse the ruri, if not yet */
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    /* preliminary check */
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  * This function creates and submits diameter authentication request as per
00370  * draft-srinivas-aaa-basic-digest-00.txt. 
00371  * Service type of the request is Authenticate-Only.
00372  * Returns:
00373  *        1 - success
00374  *       -1 - error
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       /* Username AVP */
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 /* it is a SIP message with credentials */
00439    {
00440       /* Add Username AVP */
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    /* SIP_MSGID AVP */
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    /* SIP Service AVP */
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    /* Destination-Realm AVP */
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    /* Resource AVP */
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) /* it is a SIP message with credentials */
00587    {
00588       /* Response AVP */
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       /* Method AVP */
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    /* build a AAA message buffer */
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    /* send the message to the DIAMETER CLIENT */
00644    switch( tcp_send_recv(sockfd, req->buf.s, req->buf.len, rb, m_id) )
00645    {
00646       case AAA_ERROR: /* a transmission error occurred */
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 /* give the appropriate response to the SER client */
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) /* SIP server */
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  /* Proxy Server */
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    // never reach this 
00729    return -1;     
00730 }
00731 
00732 
00733 /*
00734  * Create a response with given code and reason phrase
00735  * Optionally add new headers specified in _hdr
00736  */
00737 int send_resp(struct sip_msg* m, int code, str* reason,
00738                char* hdr, int hdr_len)
00739 {
00740    /* Add new headers if there are any */
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 

Generated on Thu May 17 12:00:25 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6