📄 jauth.c
字号:
/* eXosip - This is the eXtended osip library. Copyright (C) 2002,2003,2004,2005,2006,2007 Aymeric MOIZARD - jack@atosc.org eXosip is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. eXosip 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#ifdef ENABLE_MPATROL#include <mpatrol.h>#endif#include "eXosip2.h"#include <eXosip2/eXosip.h>#include <osip2/osip_mt.h>#include <osip2/osip_condv.h>/* #include <osip2/global.h> */#include <osipparser2/osip_md5.h>/* TAKEN from rcf2617.txt */#define HASHLEN 16typedef char HASH[HASHLEN];#define HASHHEXLEN 32typedef char HASHHEX[HASHHEXLEN + 1];#define IN#define OUTextern eXosip_t eXosip;/* Private functions */void CvtHex (IN HASH Bin, OUT HASHHEX Hex);static void DigestCalcHA1 (IN const char *pszAlg, IN const char *pszUserName, IN const char *pszRealm, IN const char *pszPassword, IN const char *pszNonce, IN const char *pszCNonce, OUT HASHHEX SessionKey);static void DigestCalcResponse (IN HASHHEX HA1, IN const char *pszNonce, IN const char *pszNonceCount, IN const char *pszCNonce, IN const char *pszQop, IN const char *pszMethod, IN const char *pszDigestUri, IN HASHHEX HEntity, OUT HASHHEX Response);voidCvtHex (IN HASH Bin, OUT HASHHEX Hex){ unsigned short i; unsigned char j; for (i = 0; i < HASHLEN; i++) { j = (Bin[i] >> 4) & 0xf; if (j <= 9) Hex[i * 2] = (j + '0'); else Hex[i * 2] = (j + 'a' - 10); j = Bin[i] & 0xf; if (j <= 9) Hex[i * 2 + 1] = (j + '0'); else Hex[i * 2 + 1] = (j + 'a' - 10); }; Hex[HASHHEXLEN] = '\0';}/* calculate H(A1) as per spec */static voidDigestCalcHA1 (IN const char *pszAlg, IN const char *pszUserName, IN const char *pszRealm, IN const char *pszPassword, IN const char *pszNonce, IN const char *pszCNonce, OUT HASHHEX SessionKey){ MD5_CTX Md5Ctx; HASH HA1; MD5Init (&Md5Ctx); MD5Update (&Md5Ctx, (unsigned char *) pszUserName, strlen (pszUserName)); MD5Update (&Md5Ctx, (unsigned char *) ":", 1); MD5Update (&Md5Ctx, (unsigned char *) pszRealm, strlen (pszRealm)); MD5Update (&Md5Ctx, (unsigned char *) ":", 1); MD5Update (&Md5Ctx, (unsigned char *) pszPassword, strlen (pszPassword)); MD5Final ((unsigned char *) HA1, &Md5Ctx); if ((pszAlg != NULL) && osip_strcasecmp (pszAlg, "md5-sess") == 0) { MD5Init (&Md5Ctx); MD5Update (&Md5Ctx, (unsigned char *) HA1, HASHLEN); MD5Update (&Md5Ctx, (unsigned char *) ":", 1); MD5Update (&Md5Ctx, (unsigned char *) pszNonce, strlen (pszNonce)); MD5Update (&Md5Ctx, (unsigned char *) ":", 1); MD5Update (&Md5Ctx, (unsigned char *) pszCNonce, strlen (pszCNonce)); MD5Final ((unsigned char *) HA1, &Md5Ctx); } CvtHex (HA1, SessionKey);}/* calculate request-digest/response-digest as per HTTP Digest spec */static voidDigestCalcResponse (IN HASHHEX HA1, /* H(A1) */ IN const char *pszNonce, /* nonce from server */ IN const char *pszNonceCount, /* 8 hex digits */ IN const char *pszCNonce, /* client nonce */ IN const char *pszQop, /* qop-value: "", "auth", "auth-int" */ IN const char *pszMethod, /* method from the request */ IN const char *pszDigestUri, /* requested URL */ IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ OUT HASHHEX Response /* request-digest or response-digest */ ){ MD5_CTX Md5Ctx; HASH HA2; HASH RespHash; HASHHEX HA2Hex; /* calculate H(A2) */ MD5Init (&Md5Ctx); MD5Update (&Md5Ctx, (unsigned char *) pszMethod, strlen (pszMethod)); MD5Update (&Md5Ctx, (unsigned char *) ":", 1); MD5Update (&Md5Ctx, (unsigned char *) pszDigestUri, strlen (pszDigestUri)); if (pszQop == NULL) { goto auth_withoutqop; } else if (0 == strcmp (pszQop, "auth-int")) { goto auth_withauth_int; } else if (0 == strcmp (pszQop, "auth")) { goto auth_withauth; }auth_withoutqop: MD5Final ((unsigned char *) HA2, &Md5Ctx); CvtHex (HA2, HA2Hex); /* calculate response */ MD5Init (&Md5Ctx); MD5Update (&Md5Ctx, (unsigned char *) HA1, HASHHEXLEN); MD5Update (&Md5Ctx, (unsigned char *) ":", 1); MD5Update (&Md5Ctx, (unsigned char *) pszNonce, strlen (pszNonce)); MD5Update (&Md5Ctx, (unsigned char *) ":", 1); goto end;auth_withauth_int: MD5Update (&Md5Ctx, (unsigned char *) ":", 1); MD5Update (&Md5Ctx, (unsigned char *) HEntity, HASHHEXLEN);auth_withauth: MD5Final ((unsigned char *) HA2, &Md5Ctx); CvtHex (HA2, HA2Hex); /* calculate response */ MD5Init (&Md5Ctx); MD5Update (&Md5Ctx, (unsigned char *) HA1, HASHHEXLEN); MD5Update (&Md5Ctx, (unsigned char *) ":", 1); MD5Update (&Md5Ctx, (unsigned char *) pszNonce, strlen (pszNonce)); MD5Update (&Md5Ctx, (unsigned char *) ":", 1); MD5Update (&Md5Ctx, (unsigned char *) pszNonceCount, strlen (pszNonceCount)); MD5Update (&Md5Ctx, (unsigned char *) ":", 1); MD5Update (&Md5Ctx, (unsigned char *) pszCNonce, strlen (pszCNonce)); MD5Update (&Md5Ctx, (unsigned char *) ":", 1); MD5Update (&Md5Ctx, (unsigned char *) pszQop, strlen (pszQop)); MD5Update (&Md5Ctx, (unsigned char *) ":", 1);end: MD5Update (&Md5Ctx, (unsigned char *) HA2Hex, HASHHEXLEN); MD5Final ((unsigned char *) RespHash, &Md5Ctx); CvtHex (RespHash, Response);}int__eXosip_create_authorization_header (osip_www_authenticate_t *wa, const char *rquri, const char *username, const char *passwd, const char *ha1, osip_authorization_t ** auth, const char *method, const char *pCNonce, int iNonceCount){ osip_authorization_t *aut; char *qop=NULL; /* make some test */ if (passwd == NULL) return -1; if (wa == NULL || wa->auth_type == NULL || (wa->realm == NULL) || (wa->nonce == NULL)) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "www_authenticate header is not acceptable.\n")); return -1; } if (0 != osip_strcasecmp ("Digest", wa->auth_type)) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Authentication method not supported. (Digest only).\n")); return -1; } /* "MD5" is invalid, but some servers use it. */ if (wa->algorithm != NULL && 0 != osip_strcasecmp ("MD5", wa->algorithm) && 0 != osip_strcasecmp ("\"MD5\"", wa->algorithm)) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Authentication method not supported. (Digest only).\n")); return -1; } if (0 != osip_authorization_init (&aut)) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "allocation with authorization_init failed.\n")); return -1; } /* just copy some feilds from response to new request */ osip_authorization_set_auth_type (aut, osip_strdup ("Digest")); osip_authorization_set_realm (aut, osip_strdup (osip_www_authenticate_get_realm (wa))); osip_authorization_set_nonce (aut, osip_strdup (osip_www_authenticate_get_nonce (wa))); if (osip_www_authenticate_get_opaque (wa) != NULL) osip_authorization_set_opaque (aut, osip_strdup (osip_www_authenticate_get_opaque (wa))); /* copy the username field in new request */ aut->username = osip_malloc (strlen (username) + 3); sprintf (aut->username, "\"%s\"", username); { char *tmp = osip_malloc (strlen (rquri) + 3); sprintf (tmp, "\"%s\"", rquri); osip_authorization_set_uri (aut, tmp); } osip_authorization_set_algorithm (aut, osip_strdup ("MD5")); qop = osip_www_authenticate_get_qop_options (wa); if (qop==NULL || qop[0]=='\0' || strlen(qop)<4) qop=NULL; { char *pszNonce = osip_strdup_without_quote (osip_www_authenticate_get_nonce (wa)); char *pszCNonce = NULL; const char *pszUser = username; char *pszRealm = osip_strdup_without_quote (osip_authorization_get_realm (aut)); const char *pszPass = NULL; char *pszAlg = osip_strdup ("MD5"); char *szNonceCount = NULL; const char *pszMethod = method; /* previous_answer->cseq->method; */ char *pszQop = NULL; const char *pszURI = rquri; HASHHEX HA1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -