auth_radius/authorize.c

Go to the documentation of this file.
00001 /*
00002  * $Id: authorize.c 4518 2008-07-28 15:39:28Z henningw $
00003  *
00004  * Digest Authentication - Radius 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-03-09: Based on authorize.c from radius_auth (janakj)
00027  * 2006-03-01: pseudo variables support for domain name (bogdan)
00028  */
00029 
00030 
00031 #include <string.h>
00032 #include <stdlib.h>
00033 #include "../../mem/mem.h"
00034 #include "../../str.h"
00035 #include "../../parser/hf.h"
00036 #include "../../parser/digest/digest.h"
00037 #include "../../parser/parse_uri.h"
00038 #include "../../parser/parse_from.h"
00039 #include "../../parser/parse_to.h"
00040 #include "../../dprint.h"
00041 #include "../../ut.h"
00042 #include "../../pvar.h"
00043 #include "../auth/api.h"
00044 #include "authorize.h"
00045 #include "sterman.h"
00046 #include "authrad_mod.h"
00047 
00048 
00049 /* 
00050  * Extract URI depending on the request from To or From header 
00051  */
00052 static inline int get_uri_user(struct sip_msg* _m, str** _uri_user)
00053 {
00054     struct sip_uri *puri;
00055 
00056     if ((REQ_LINE(_m).method.len == 8) && 
00057    (memcmp(REQ_LINE(_m).method.s, "REGISTER", 8) == 0)) {
00058    if ((puri=parse_to_uri(_m))==NULL) {
00059        LM_ERR("failed to parse To header\n");
00060        return -1;
00061    }
00062     } else {
00063    if ((puri=parse_from_uri(_m))==NULL) {
00064        LM_ERR("parsing From header\n");
00065        return -1;
00066    }
00067     }
00068 
00069     *_uri_user = &(puri->user);
00070 
00071     return 0;
00072 }
00073 
00074 
00075 /*
00076  * Authorize digest credentials
00077  */
00078 static inline int authorize(struct sip_msg* _msg, pv_elem_t* _realm,
00079              pv_spec_t * _uri_user, int _hftype)
00080 {
00081     int res;
00082     auth_result_t ret;
00083     struct hdr_field* h;
00084     auth_body_t* cred;
00085     str *uri_user;
00086     str user, domain;
00087     pv_value_t pv_val;
00088 
00089     /* get pre_auth domain from _realm pvar (if exists) */
00090     if (_realm) {
00091    if (pv_printf_s(_msg, _realm, &domain)!=0) {
00092        LM_ERR("pv_printf_s failed\n");
00093        return AUTH_ERROR;
00094    }
00095     } else {
00096    /* get pre_auth domain from To/From header */
00097    domain.len = 0;
00098    domain.s = 0;
00099     }
00100 
00101     ret = auth_api.pre_auth(_msg, &domain, _hftype, &h);
00102 
00103     if (ret != DO_AUTHORIZATION)
00104    return ret;
00105 
00106     cred = (auth_body_t*)h->parsed;
00107 
00108     /* get uri_user from _uri_user pvap (if exists) or
00109        from To/From URI */
00110     if (_uri_user) {
00111    if (pv_get_spec_value(_msg, _uri_user, &pv_val) == 0) {
00112        if (pv_val.flags & PV_VAL_STR) {
00113       res = radius_authorize_sterman(_msg, &cred->digest, 
00114                       &_msg->first_line.u.request.method,
00115                       &pv_val.rs);
00116        } else {
00117       LM_ERR("uri_user pvar value is not string\n");
00118       return AUTH_ERROR;
00119        }
00120    } else {
00121        LM_ERR("cannot get uri_user pvar value\n");
00122        return AUTH_ERROR;
00123    }
00124     } else {
00125    if (get_uri_user(_msg, &uri_user) < 0) {
00126        LM_ERR("To/From URI not found\n");
00127        return AUTH_ERROR;
00128    }
00129    user.s = (char *)pkg_malloc(uri_user->len);
00130    if (user.s == NULL) {
00131        LM_ERR("no pkg memory left for user\n");
00132        return AUTH_ERROR;
00133    }
00134    un_escape(uri_user, &user);
00135    res = radius_authorize_sterman(_msg, &cred->digest, 
00136                    &_msg->first_line.u.request.method,
00137                    &user);
00138    pkg_free(user.s);
00139     }
00140 
00141     if (res == 1) {
00142    ret = auth_api.post_auth(_msg, h);
00143    return ret;
00144     }
00145 
00146     return AUTH_ERROR;
00147 }
00148 
00149 
00150 /*
00151  * Authorize using Proxy-Authorize header field (no URI user parameter given)
00152  */
00153 int radius_proxy_authorize_1(struct sip_msg* _msg, char* _realm, char* _s2)
00154 {
00155    /* realm parameter is converted in fixup */
00156    return authorize(_msg, (pv_elem_t*)_realm, (pv_spec_t *)0,
00157       HDR_PROXYAUTH_T);
00158 }
00159 
00160 
00161 /*
00162  * Authorize using Proxy-Authorize header field (URI user parameter given)
00163  */
00164 int radius_proxy_authorize_2(struct sip_msg* _msg, char* _realm,
00165                                           char* _uri_user)
00166 {
00167    return authorize(_msg, (pv_elem_t*)_realm, (pv_spec_t *)_uri_user,
00168       HDR_PROXYAUTH_T);
00169 }
00170 
00171 
00172 /*
00173  * Authorize using WWW-Authorize header field
00174  */
00175 int radius_www_authorize(struct sip_msg* _msg, char* _realm, char* _s2)
00176 {
00177    return authorize(_msg, (pv_elem_t*)_realm, (pv_spec_t *)0,
00178           HDR_AUTHORIZATION_T);
00179 }

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