user_in.c

Go to the documentation of this file.
00001 /*
00002  * $Id: user_in.c 5340 2008-12-13 13:07:21Z klaus_darilion $
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  *  
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 /* 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 
00055 /* headers defined by this module */
00056 #include "diameter_msg.h"
00057 #include "auth_diameter.h"
00058 #include "defs.h"
00059 #include "tcp_comm.h"
00060 
00061 
00062 /* Get To header field URI */
00063 static inline int get_to_uri(struct sip_msg* m, str* u)
00064 {
00065      // check that the header field is there and is parsed
00066    if (!m->to && ((parse_headers(m, HDR_TO_F, 0) == -1)|| (!m->to))) 
00067    {
00068       LM_ERR("can't get To header field\n");
00069       return -1;
00070    }
00071    
00072    u->s   = ((struct to_body*)m->to->parsed)->uri.s;
00073    u->len = ((struct to_body*)m->to->parsed)->uri.len;
00074    
00075    return 0;
00076 }
00077 
00078 
00079 /* Get From header field URI */
00080 static inline int get_from_uri(struct sip_msg* m, str* u)
00081 {
00082      // check that the header field is there and is parsed
00083    if (parse_from_header(m) < 0) {
00084       LM_ERR("failed to parse From body\n");
00085       return -1;
00086    }
00087    
00088    u->s   = ((struct to_body*)m->from->parsed)->uri.s;
00089    u->len = ((struct to_body*)m->from->parsed)->uri.len;
00090 
00091    return 0;
00092 }
00093 
00094 /* it checks if a user is member of a group */
00095 int diameter_is_user_in(struct sip_msg* _m, char* _hf, char* _group)
00096 {
00097    str *grp, user_name, user, domain, uri;
00098    dig_cred_t* cred = 0;
00099    int hf_type;
00100    struct hdr_field* h;
00101    struct sip_uri puri;
00102    AAAMessage *req;
00103    AAA_AVP *avp; 
00104    int ret;
00105    unsigned int tmp;
00106 
00107    grp = (str*)_group; /* via fixup */
00108 
00109    hf_type = (int)(long)_hf;
00110 
00111    uri.s = 0;
00112    uri.len = 0;
00113 
00114    /* extract the uri according with the _hf parameter */
00115    switch(hf_type) 
00116    {
00117       case 1: /* Request-URI */
00118          uri = *(GET_RURI(_m));
00119       break;
00120 
00121       case 2: /* To */
00122          if (get_to_uri(_m, &uri) < 0) 
00123          {
00124             LM_ERR("failed to extract To\n");
00125             return -2;
00126          }
00127          break;
00128 
00129       case 3: /* From */
00130          if (get_from_uri(_m, &uri) < 0) 
00131          {
00132             LM_ERR("failed to extract From URI\n");
00133             return -3;
00134          }
00135          break;
00136 
00137       case 4: /* Credentials */
00138          get_authorized_cred(_m->authorization, &h);
00139          if (!h)  
00140          {
00141             get_authorized_cred(_m->proxy_auth, &h);
00142             if (!h) 
00143             {
00144                LM_ERR("no authorized credentials found "
00145                      "(error in scripts)\n");
00146                return -4;
00147             }
00148          }
00149          cred = &((auth_body_t*)(h->parsed))->digest;
00150          break;
00151    }
00152 
00153    if (hf_type != 4) 
00154    {
00155       if (parse_uri(uri.s, uri.len, &puri) < 0) 
00156       {
00157          LM_ERR("failed to parse URI\n");
00158          return -5;
00159       }
00160       user = puri.user;
00161       domain = puri.host;
00162    } 
00163    else
00164    {
00165       user = cred->username.user;
00166       domain = cred->realm;
00167    }
00168    
00169    /* user@domain mode */
00170    if (use_domain)
00171    {
00172       user_name.s = 0;
00173       user_name.len = user.len + domain.len;
00174       if(user_name.len>0)
00175       {
00176          user_name.len++;
00177          user_name.s = (char*)pkg_malloc(user_name.len);
00178          if (!user_name.s) 
00179          {
00180             LM_ERR("no pkg memory left\n");
00181             return -6;
00182          }
00183       
00184          memcpy(user_name.s, user.s, user.len);
00185          if(user.len>0)
00186          {
00187             user_name.s[user.len] = '@';
00188             memcpy(user_name.s + user.len + 1, domain.s, domain.len);
00189          }
00190          else
00191             memcpy(user_name.s, domain.s, domain.len);
00192       }
00193    } 
00194    else 
00195       user_name = user;
00196    
00197    
00198    if ( (req=AAAInMessage(AA_REQUEST, AAA_APP_NASREQ))==NULL)
00199    {
00200       LM_ERR("can't create new AAA message!\n");
00201       return -1;
00202    }
00203    
00204    /* Username AVP */
00205    if( (avp=AAACreateAVP(AVP_User_Name, 0, 0, user_name.s,
00206             user_name.len, AVP_DUPLICATE_DATA)) == 0)
00207    {
00208       LM_ERR("no more pkg memory!\n");
00209       goto error;
00210    }
00211    if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
00212    {
00213       LM_ERR("avp not added \n");
00214       goto error1;
00215    }
00216 
00217    /* Usergroup AVP */
00218    if( (avp=AAACreateAVP(AVP_User_Group, 0, 0, grp->s,
00219             grp->len, AVP_DUPLICATE_DATA)) == 0)
00220    {
00221       LM_ERR("no more pkg memory!\n");
00222       goto error;
00223    }
00224    if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
00225    {
00226       LM_ERR("avp not added \n");
00227       goto error1;
00228    }
00229 
00230    /* SIP_MSGID AVP */
00231    LM_DBG("******* m_id=%d\n", _m->id);
00232    tmp = _m->id;
00233    if( (avp=AAACreateAVP(AVP_SIP_MSGID, 0, 0, (char*)(&tmp), 
00234             sizeof(tmp), AVP_DUPLICATE_DATA)) == 0)
00235    {
00236       LM_ERR("no more pkg memory!\n");
00237       goto error;
00238    }
00239    if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
00240    {
00241       LM_ERR("avp not added \n");
00242       goto error1;
00243    }
00244 
00245    
00246    /* ServiceType AVP */
00247    if( (avp=AAACreateAVP(AVP_Service_Type, 0, 0, SIP_GROUP_CHECK, 
00248             SERVICE_LEN, AVP_DUPLICATE_DATA)) == 0)
00249    {
00250       LM_ERR("no more pkg memory!\n");
00251       goto error;
00252    }
00253    if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
00254    {
00255       LM_ERR("avp not added \n");
00256       goto error1;
00257    }
00258    
00259 
00260    /* Destination-Realm AVP */
00261    uri = *(GET_RURI(_m));
00262    parse_uri(uri.s, uri.len, &puri);
00263    if( (avp=AAACreateAVP(AVP_Destination_Realm, 0, 0, puri.host.s,
00264                   puri.host.len, AVP_DUPLICATE_DATA)) == 0)
00265    {
00266       LM_ERR("no more pkg memory!\n");
00267       goto error;
00268    }
00269    
00270    if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS)
00271    {
00272       LM_ERR("avp not added \n");
00273       goto error1;
00274    }
00275    
00276 #ifdef DEBUG
00277    AAAPrintMessage(req);
00278 #endif
00279 
00280    /* build a AAA message buffer */
00281    if(AAABuildMsgBuffer(req) != AAA_ERR_SUCCESS)
00282    {
00283       LM_ERR("message buffer not created\n");
00284       goto error;
00285    }
00286 
00287    if(sockfd==AAA_NO_CONNECTION)
00288    {
00289       sockfd = init_mytcp(diameter_client_host, diameter_client_port);
00290       if(sockfd==AAA_NO_CONNECTION)
00291       {
00292          LM_ERR("failed to reconnect to Diameter client\n");
00293          goto error;
00294       }
00295    }
00296 
00297    ret =tcp_send_recv(sockfd, req->buf.s, req->buf.len, rb, _m->id);
00298 
00299    if(ret == AAA_CONN_CLOSED)
00300    {
00301       LM_NOTICE("connection to Diameter client closed."
00302             "It will be reopened by the next request\n");
00303       close(sockfd);
00304       sockfd = AAA_NO_CONNECTION;
00305       goto error;
00306    }
00307    if(ret != AAA_USER_IN_GROUP)
00308    {
00309       LM_ERR("message sending to the DIAMETER backend authorization server"
00310             "failed or user is not in group\n");
00311       goto error;
00312    }
00313    
00314    AAAFreeMessage(&req);
00315    return 1;
00316 
00317 error1:
00318    AAAFreeAVP(&avp);
00319 error:
00320    AAAFreeMessage(&req);
00321    return -1;
00322 
00323 }
00324 

Generated on Thu May 24 22:00:35 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6