📄 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>#include "milenage.h"/* TAKEN from rcf2617.txt */#define HASHLEN 16typedef char HASH[HASHLEN];#define HASHHEXLEN 32typedef char HASHHEX[HASHHEXLEN + 1];#define IN#define OUT/* AKA */#define MAX_HEADER_LEN 2049#define KLEN 16typedef u_char K[KLEN];#define RANDLEN 16typedef u_char RAND[RANDLEN];#define AUTNLEN 16typedef u_char AUTN[AUTNLEN];#define AKLEN 6typedef u_char AK[AKLEN];#define AMFLEN 2typedef u_char AMF[AMFLEN];#define MACLEN 8typedef u_char MAC[MACLEN];#define CKLEN 16typedef u_char CK[CKLEN];#define IKLEN 16typedef u_char IK[IKLEN];#define SQNLEN 6typedef u_char SQN[SQNLEN];#define AUTSLEN 14typedef char AUTS[AUTSLEN];#define AUTS64LEN 21typedef char AUTS64[AUTS64LEN];#define RESLEN 8typedef unsigned char RES[RESLEN];#define RESHEXLEN 17typedef char RESHEX[RESHEXLEN];typedef char RESHEXAKA2[RESHEXLEN + IKLEN * 2 + CKLEN * 2];AMF amf = "\0\0";AMF amfstar = "\0\0";/* end AKA */extern 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 int Aka, IN const char *pszMethod, IN const char *pszDigestUri, IN HASHHEX HEntity, OUT HASHHEX Response);static void DigestCalcResponseAka (IN const char *pszPassword, IN const char *pszNonce, IN const char *pszCNonce, IN const char *pszQop, IN const char *pszMethod, IN const char *pszDigestUri, IN int version, 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){ osip_MD5_CTX Md5Ctx; HASH HA1; osip_MD5Init (&Md5Ctx); osip_MD5Update (&Md5Ctx, (unsigned char *) pszUserName, strlen (pszUserName)); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) pszRealm, strlen (pszRealm)); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) pszPassword, strlen (pszPassword)); osip_MD5Final ((unsigned char *) HA1, &Md5Ctx); if ((pszAlg != NULL) && osip_strcasecmp (pszAlg, "md5-sess") == 0) { osip_MD5Init (&Md5Ctx); osip_MD5Update (&Md5Ctx, (unsigned char *) HA1, HASHLEN); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) pszNonce, strlen (pszNonce)); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) pszCNonce, strlen (pszCNonce)); osip_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 int Aka, /* Calculating AKAv1-MD5 response */ 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 */ ){ osip_MD5_CTX Md5Ctx; HASH HA2; HASH RespHash; HASHHEX HA2Hex; /* calculate H(A2) */ osip_MD5Init (&Md5Ctx); osip_MD5Update (&Md5Ctx, (unsigned char *) pszMethod, strlen (pszMethod)); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) pszDigestUri, strlen (pszDigestUri)); if (pszQop == NULL) { goto auth_withoutqop; } else if (0 == osip_strcasecmp (pszQop, "auth-int")) { goto auth_withauth_int; } else if (0 == osip_strcasecmp (pszQop, "auth")) { goto auth_withauth; }auth_withoutqop: osip_MD5Final ((unsigned char *) HA2, &Md5Ctx); CvtHex (HA2, HA2Hex); /* calculate response */ osip_MD5Init (&Md5Ctx); osip_MD5Update (&Md5Ctx, (unsigned char *) HA1, HASHHEXLEN); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) pszNonce, strlen (pszNonce)); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); goto end;auth_withauth_int: osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) HEntity, HASHHEXLEN);auth_withauth: osip_MD5Final ((unsigned char *) HA2, &Md5Ctx); CvtHex (HA2, HA2Hex); /* calculate response */ osip_MD5Init (&Md5Ctx); osip_MD5Update (&Md5Ctx, (unsigned char *) HA1, HASHHEXLEN); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) pszNonce, strlen (pszNonce)); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); if (Aka == 0) { osip_MD5Update (&Md5Ctx, (unsigned char *) pszNonceCount, strlen (pszNonceCount)); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) pszCNonce, strlen (pszCNonce)); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) pszQop, strlen (pszQop)); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); }end: osip_MD5Update (&Md5Ctx, (unsigned char *) HA2Hex, HASHHEXLEN); osip_MD5Final ((unsigned char *) RespHash, &Md5Ctx); CvtHex (RespHash, Response);}/*"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";*/static intbase64_val (char x){ switch (x) { case '=': return -1; case 'A': return OSIP_SUCCESS; case 'B': return 1; case 'C': return 2; case 'D': return 3; case 'E': return 4; case 'F': return 5; case 'G': return 6; case 'H': return 7; case 'I': return 8; case 'J': return 9; case 'K': return 10; case 'L': return 11; case 'M': return 12; case 'N': return 13; case 'O': return 14; case 'P': return 15; case 'Q': return 16; case 'R': return 17; case 'S': return 18; case 'T': return 19; case 'U': return 20; case 'V': return 21; case 'W': return 22; case 'X': return 23; case 'Y': return 24; case 'Z': return 25; case 'a': return 26; case 'b': return 27; case 'c': return 28; case 'd': return 29; case 'e': return 30; case 'f': return 31; case 'g': return 32; case 'h': return 33; case 'i': return 34; case 'j': return 35; case 'k': return 36; case 'l': return 37; case 'm': return 38; case 'n': return 39; case 'o': return 40; case 'p': return 41; case 'q': return 42; case 'r': return 43; case 's': return 44; case 't': return 45; case 'u': return 46; case 'v': return 47; case 'w': return 48; case 'x': return 49; case 'y': return 50; case 'z': return 51; case '0': return 52; case '1': return 53; case '2': return 54; case '3': return 55; case '4': return 56; case '5': return 57; case '6': return 58; case '7': return 59; case '8': return 60; case '9': return 61; case '+': return 62; case '/': return 63; } return OSIP_SUCCESS;}static char *base64_decode_string (const char *buf, unsigned int len, int *newlen){ int i, j, x1, x2, x3, x4; char *out; out = (char *) osip_malloc ((len * 3 / 4) + 8); if (out == NULL) return NULL; for (i = 0, j = 0; i + 3 < len; i += 4) { x1 = base64_val (buf[i]); x2 = base64_val (buf[i + 1]); x3 = base64_val (buf[i + 2]); x4 = base64_val (buf[i + 3]); out[j++] = (x1 << 2) | ((x2 & 0x30) >> 4); out[j++] = ((x2 & 0x0F) << 4) | ((x3 & 0x3C) >> 2); out[j++] = ((x3 & 0x03) << 6) | (x4 & 0x3F); } if (i < len) { x1 = base64_val (buf[i]); if (i + 1 < len) x2 = base64_val (buf[i + 1]); else x2 = -1; if (i + 2 < len) x3 = base64_val (buf[i + 2]); else x3 = -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -