⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 auth_client.c

📁 Internet Phone, Chat, Conferencing
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//**@CFILE auth_client.c  Authenticators for SIP client * * @author Pekka Pessi <Pekka.Pessi@nokia.com> * * @date Created: Wed Feb 14 18:32:58 2001 ppessi */#include "config.h"#include <stddef.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <sofia-sip/su.h>#include <sofia-sip/su_md5.h>#include "sofia-sip/auth_client.h"#include <sofia-sip/msg_header.h>#include <sofia-sip/auth_digest.h>#include <sofia-sip/base64.h>#include <sofia-sip/su_uniqueid.h>#include <sofia-sip/su_debug.h>#if HAVE_SC_CRED_H#include <sc_creds.h>#endif#if HAVE_UICC_H#include <uicc.h>#endifstruct auth_client_s {  su_home_t     ca_home[1];  auth_client_t*ca_next;  msg_param_t   ca_scheme;  msg_param_t   ca_realm;  msg_param_t   ca_user;  msg_param_t   ca_pass;#if  0  msg_hclass_t *ca_challenge_class;  msg_auth_t   *ca_challenge;#endif  msg_hclass_t *ca_credential_class;  auth_challenge_t ca_ac[1];  int           ca_ncount;  char const   *ca_cnonce;  msg_header_t *(*ca_authorize)(auth_client_t *ca, 				su_home_t *h,				char const *method, 				url_t const *url, 				msg_payload_t const *body);};static auth_client_t *ca_create(su_home_t *home);static int ca_challenge(auth_client_t *ca, 			msg_auth_t const *auth, 			msg_hclass_t *credential_class,			msg_param_t scheme, 			msg_param_t realm);static int ca_credentials(auth_client_t *ca, 			  char const *scheme,			  char const *realm, 			  char const *user,			  char const *pass);static int ca_clear_credentials(auth_client_t *ca, 				char const *scheme,				char const *realm);static msg_header_t *auc_basic_authorization(auth_client_t *ca,					     su_home_t *h,					     char const *method, 					     url_t const *url, 					     msg_payload_t const *body);static msg_header_t *auc_digest_authorization(auth_client_t *ca, 					      su_home_t *h,					      char const *method, 					      url_t const *url, 					      msg_payload_t const *body);/** Allocate a dummy auth_client_t structure. */auth_client_t *ca_create(su_home_t *home){  auth_client_t *ca;  if ((ca = su_home_clone(home, sizeof(*ca)))) {    ca->ca_scheme = ca->ca_realm = "";  }  return ca;}void ca_destroy(su_home_t *home, auth_client_t *ca){  su_free(home, ca);}/** Initialize AKA authenticator. * * The function auc_with_uicc() initializes the AKA authenticator to the * list of authenticators @a auc_list. * * @param auc_list [in/out] list of authenticators to be updated * @param home     [in/out] memory home used for allocating authenticators * @param uicc     [in]     UICC object *  * @retval 0 when successful * @retval -1 upon an error */int auc_with_uicc(auth_client_t **auc_list,		  su_home_t *home, 		  struct uicc_s *uicc){#if HAVE_UICC_H  /* Xyzzy. */#endif  return -1;}/** Initialize authenticators. * * The function auc_challenge() merges the challenge @a ch to the list of * authenticators @a auc_list.   * * @param auc_list [in/out] list of authenticators to be updated * @param home     [in/out] memory home used for allocating authenticators * @param ch       [in] challenge to be processed * @param crcl     [in] credential class *  * @retval 1 when challenge was updated * @retval 0 when there was no new challenges * @retval -1 upon an error */int auc_challenge(auth_client_t **auc_list,		  su_home_t *home, 		  msg_auth_t const *ch,		  msg_hclass_t *crcl){  auth_client_t **cca;  int retval = 0;  for (; ch; ch = ch->au_next) {    char const *scheme = ch->au_scheme;    char const *realm = msg_header_find_param(ch->au_common, "realm=");    int updated = 0, updated0;    if (!scheme || !realm)      continue;    for (cca = auc_list; (*cca); cca = &(*cca)->ca_next) {      updated0 = ca_challenge((*cca), ch, crcl, scheme, realm);      if (updated0 < 0)	continue;      updated = 1;      retval = retval || updated0 > 0;    }    if (!updated) {      *cca = ca_create(home);      if (ca_challenge((*cca), ch, crcl, scheme, realm) != -1) {	updated = 1;      } else {	ca_destroy(home, *cca), *cca = NULL;	retval = -1;	break;      }     }    retval = retval || updated;  }  return retval;}staticint ca_challenge(auth_client_t *ca, 		 msg_auth_t const *ch,		 msg_hclass_t *credential_class,		 msg_param_t scheme, 		 msg_param_t realm){  su_home_t *home = ca->ca_home;  auth_challenge_t *ac = ca->ca_ac;  int existing = ca->ca_authorize != NULL;  assert(ca); assert(ch);  if (!ca || !ch)    return -1;  ca->ca_ac->ac_size = sizeof(ca->ca_ac);  if (ca->ca_scheme[0] && strcmp(ca->ca_scheme, scheme))    return -1;  if (ca->ca_realm[0] && strcmp(ca->ca_realm, realm))    return -1;  if (strcasecmp(scheme, "Basic") == 0) {    ca->ca_authorize = auc_basic_authorization;  }  else if (strcasecmp(scheme, "Digest") == 0) {    ca->ca_authorize = auc_digest_authorization;  }  else    return -1;#if 0  if (ca->ca_challenge_class &&       ca->ca_challenge_class != ch->au_common->h_class)    return -1;#endif  if (ca->ca_credential_class &&       ca->ca_credential_class != credential_class)    return -1;  ca->ca_credential_class = credential_class;#if 0  ca->ca_challenge = msg_header_dup(home, (msg_header_t *)ch)->sh_auth;  ca->ca_challenge_class = ca->ca_challenge->au_common->h_class;  ca->ca_scheme = ca->ca_challenge->au_scheme;  ca->ca_realm = msg_header_find_param(ca->ca_challenge->au_common, "realm=");#else  ca->ca_scheme = su_strdup(home, ch->au_scheme);  ca->ca_realm = su_strdup(home, 			   msg_header_find_param(ch->au_common, "realm"));#endif  if (auth_digest_challenge_get(home, ac, ch->au_params) < 0)    return -1;  /* Check that we can handle this */  if (!ac->ac_md5 && !ac->ac_md5sess)    return -1;  if (ac->ac_qop && !ac->ac_auth && !ac->ac_auth_int)    return -1;  if (ac->ac_qop && (ca->ca_cnonce == NULL || ac->ac_stale)) {    /* XXX - generate cnonce */    su_guid_t guid[1];    char *cnonce;    su_guid_generate(guid);    ca->ca_cnonce = cnonce = su_alloc(home, BASE64_SIZE(sizeof(guid)) + 1);    base64_e(cnonce, BASE64_SIZE(sizeof(guid)) + 1, guid, sizeof(guid));    ca->ca_ncount = 0;  }  return !existing || ac->ac_stale != NULL;}/**Feed authentication data to the authenticator. * * The function auc_credentials() is used to provide the authenticators in * with authentication data (user name, secret).  The authentication data * has format as follows: * * scheme:"realm":user:pass * * For instance, @c Basic:"nokia-proxy":ppessi:verysecret * * @todo The authentication data format sucks. * * @param auc_list [in/out] list of authenticators  * @param home     [in/out] memory home used for allocations * @param data     [in]     colon-separated authentication data *  * @retval 0 when successful * @retval -1 upon an error */int auc_credentials(auth_client_t **auc_list, su_home_t *home, 		    char const *data){  int retval = 0, match;  char *s0, *s;  char *scheme = NULL, *user = NULL, *pass = NULL, *realm = NULL;  s0 = s = su_strdup(NULL, data);  /* Parse authentication data */  /* Data is string like "Basic:\"agni\":user1:secret" */  if (s && (s = strchr(scheme = s, ':')))    *s++ = 0;  if (s && (s = strchr(realm = s, ':')))    *s++ = 0;  if (s && (s = strchr(user = s, ':')))    *s++ = 0;  if (s && (s = strchr(pass = s, ':')))    *s++ = 0;  if (scheme && realm && user && pass) {    for (; *auc_list; auc_list = &(*auc_list)->ca_next) {      match = ca_credentials(*auc_list, scheme, realm, user, pass);      if (match < 0) {	retval = -1;	break;      }      if (match) 	retval++;    }  }  su_free(NULL, s0);  return retval;}/**Feed authentication data to the authenticator. * * The function auc_credentials() is used to provide the authenticators in * with authentication tuple (scheme, realm, user name, secret).   * * scheme:"realm":user:pass * * @todo The authentication data format sucks. * * @param auc_list [in/out] list of authenticators  * @param scheme   [in]     scheme to use (NULL, if any) * @param realm    [in]     realm to use (NULL, if any) * @param user     [in]     username  * @param pass     [in]     password *  * @retval number of matching clients * @retval 0 when no matching client was found * @retval -1 upon an error */int auc_all_credentials(auth_client_t **auc_list, 			char const *scheme,			char const *realm, 			char const *user,			char const *pass){  int retval = 0, match;#if HAVE_SC_CRED_H  /* XXX: add */#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -