auth_api.c

Go to the documentation of this file.
00001 /*
00002  * $Id: auth_api.c 2 2006-11-14 22:37:20Z vingarzan $
00003  *
00004  * Digest Authentication Module 
00005  * 
00006  * Just the credential finding routines
00007  *
00008  * Copyright (C) 2001-2003 FhG Fokus
00009  *
00010  * This file is part of ser, a free SIP server.
00011  *
00012  * ser is free software; you can redistribute it and/or modify
00013  * it under the terms of the GNU General Public License as published by
00014  * the Free Software Foundation; either version 2 of the License, or
00015  * (at your option) any later version
00016  *
00017  * For a license to use the ser software under conditions
00018  * other than those described here, or to purchase support for this
00019  * software, please contact iptel.org by e-mail at the following addresses:
00020  *    info@iptel.org
00021  *
00022  * ser is distributed in the hope that it will be useful,
00023  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00024  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025  * GNU General Public License for more details.
00026  *
00027  * You should have received a copy of the GNU General Public License 
00028  * along with this program; if not, write to the Free Software 
00029  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00030  */
00031   
00041 #include <string.h>
00042 #include "auth_api.h"
00043 #include "../../dprint.h"
00044 #include "../../parser/digest/digest.h"
00045 #include "../../sr_module.h"
00046 
00047 
00048 
00058 inline int find_credentials(struct sip_msg* _m, str* _realm,
00059                                     hdr_types_t _hftype, struct hdr_field** _h)
00060 {
00061     struct hdr_field** hook, *ptr, *prev;
00062     hdr_flags_t hdr_flags;
00063     int res;
00064     str* r;
00065 
00066          /*
00067           * Determine if we should use WWW-Authorization or
00068           * Proxy-Authorization header fields, this parameter
00069           * is set in www_authorize and proxy_authorize
00070           */
00071     switch(_hftype) {
00072     case HDR_AUTHORIZATION_T: 
00073                             hook = &(_m->authorization);
00074                             hdr_flags=HDR_AUTHORIZATION_F;
00075                             break;
00076     case HDR_PROXYAUTH_T:
00077                             hook = &(_m->proxy_auth);
00078                             hdr_flags=HDR_PROXYAUTH_F;
00079                             break;
00080     default:                
00081                             hook = &(_m->authorization);
00082                             hdr_flags=HDR_T2F(_hftype);
00083                             break;
00084     }
00085 
00086          /*
00087           * If the credentials haven't been parsed yet, do it now
00088           */
00089     if (*hook == 0) {
00090              /* No credentials parsed yet */
00091         if (parse_headers(_m, hdr_flags, 0) == -1) {
00092             LOG(L_ERR, "find_credentials(): Error while parsing headers\n");
00093             return -1;
00094         }
00095     }
00096 
00097     ptr = *hook;
00098 
00099          /*
00100           * Iterate through the credentials in the message and
00101           * find credentials with given realm
00102           */
00103     while(ptr) {
00104         res = parse_credentials(ptr);
00105         ptr->type = HDR_AUTHORIZATION_T;
00106         if (res < 0) {
00107             LOG(L_ERR, "find_credentials(): Error while parsing credentials\n");
00108             return (res == -1) ? -2 : -3;
00109         } else if (res == 0) {
00110             if (_realm->len) {
00111                 r = &(((auth_body_t*)(ptr->parsed))->digest.realm);
00112     
00113                 if (r->len == _realm->len) {
00114                     if (!strncasecmp(_realm->s, r->s, r->len)) {
00115                         *_h = ptr;
00116                         return 0;
00117                     }
00118                 }
00119             }
00120             else {
00121                 *_h = ptr;
00122                 return 0;
00123             }
00124             
00125         }
00126 
00127         prev = ptr;
00128         if (parse_headers(_m, hdr_flags, 1) == -1) {
00129             LOG(L_ERR, "find_credentials(): Error while parsing headers\n");
00130             return -4;
00131         } else {
00132             if (prev != _m->last_header) {
00133                 if (_m->last_header->type == _hftype) ptr = _m->last_header;
00134                 else break;
00135             } else break;
00136         }
00137     }
00138     
00139          /*
00140           * Credentials with given realm not found
00141           */
00142     return 1;
00143 }
00144 
00145 static str realm_par={"realm=\"",7};
00158 inline int find_credentials_noparse(struct sip_msg* _m, str* realm,
00159                                     hdr_types_t _hftype, struct hdr_field** _h)
00160 {
00161     struct hdr_field** hook, *ptr, *prev;
00162     hdr_flags_t hdr_flags;
00163     int i,k;
00164 
00165          /*
00166           * Determine if we should use WWW-Authorization or
00167           * Proxy-Authorization header fields, this parameter
00168           * is set in www_authorize and proxy_authorize
00169           */
00170     switch(_hftype) {
00171     case HDR_AUTHORIZATION_T: 
00172                             hook = &(_m->authorization);
00173                             hdr_flags=HDR_AUTHORIZATION_F;
00174                             break;
00175     case HDR_PROXYAUTH_T:
00176                             hook = &(_m->proxy_auth);
00177                             hdr_flags=HDR_PROXYAUTH_F;
00178                             break;
00179     default:                
00180                             hook = &(_m->authorization);
00181                             hdr_flags=HDR_T2F(_hftype);
00182                             break;
00183     }
00184 
00185          /*
00186           * If the credentials haven't been parsed yet, do it now
00187           */
00188     if (*hook == 0) {
00189              /* No credentials parsed yet */
00190         if (parse_headers(_m, hdr_flags, 0) == -1) {
00191             LOG(L_ERR, "find_credentials(): Error while parsing headers\n");
00192             return -1;
00193         }
00194     }
00195 
00196     ptr = *hook;
00197 
00198          /*
00199           * Iterate through the credentials in the message and
00200           * find credentials with given realm
00201           */
00202     while(ptr) {
00203         k = ptr->body.len - realm_par.len - realm->len;
00204         for(i=0;i<k;i++)
00205          if (strncasecmp(ptr->body.s+i,realm_par.s,realm_par.len)==0){
00206             if (strncasecmp(ptr->body.s+i+realm_par.len,realm->s,realm->len)==0){
00207                 *_h = ptr;
00208                 return 0;       
00209             } 
00210             else 
00211                 break;      
00212          }
00213             
00214         
00215         prev = ptr;
00216         if (parse_headers(_m, hdr_flags, 1) == -1) {
00217             LOG(L_ERR, "find_credentials(): Error while parsing headers\n");
00218             return -4;
00219         } else {
00220             if (prev != _m->last_header) {
00221                 if (_m->last_header->type == _hftype) ptr = _m->last_header;
00222                 else break;
00223             } else break;
00224         }
00225     }
00226     
00227          /*
00228           * Credentials with given realm not found
00229           */
00230     return 1;
00231 }

Generated on Thu Oct 23 04:14:37 2008 for Open IMS Core CSCFs by  doxygen 1.5.2