user_in.c

00001 /*
00002  * $Id$
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