📄 jauth.c
字号:
if (i + 3 < len) x4 = base64_val (buf[i + 3]); else x4 = -1; if (x2 != -1) { out[j++] = (x1 << 2) | ((x2 & 0x30) >> 4); if (x3 == -1) { out[j++] = ((x2 & 0x0F) << 4) | ((x3 & 0x3C) >> 2); if (x4 == -1) { out[j++] = ((x3 & 0x03) << 6) | (x4 & 0x3F); } } } } out[j++] = 0; *newlen = j; return out;}char base64[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";static char *base64_encode_string (const char *buf, unsigned int len, int *newlen){ int i, k; int triplets, rest; char *out, *ptr; triplets = len / 3; rest = len % 3; out = (char *) osip_malloc ((triplets * 4) + 8); if (out == NULL) return NULL; ptr = out; for (i = 0; i < triplets * 3; i += 3) { k = (((unsigned char) buf[i]) & 0xFC) >> 2; *ptr = base64[k]; ptr++; k = (((unsigned char) buf[i]) & 0x03) << 4; k |= (((unsigned char) buf[i + 1]) & 0xF0) >> 4; *ptr = base64[k]; ptr++; k = (((unsigned char) buf[i + 1]) & 0x0F) << 2; k |= (((unsigned char) buf[i + 2]) & 0xC0) >> 6; *ptr = base64[k]; ptr++; k = (((unsigned char) buf[i + 2]) & 0x3F); *ptr = base64[k]; ptr++; } i = triplets * 3; switch (rest) { case 0: break; case 1: k = (((unsigned char) buf[i]) & 0xFC) >> 2; *ptr = base64[k]; ptr++; k = (((unsigned char) buf[i]) & 0x03) << 4; *ptr = base64[k]; ptr++; *ptr = '='; ptr++; *ptr = '='; ptr++; break; case 2: k = (((unsigned char) buf[i]) & 0xFC) >> 2; *ptr = base64[k]; ptr++; k = (((unsigned char) buf[i]) & 0x03) << 4; k |= (((unsigned char) buf[i + 1]) & 0xF0) >> 4; *ptr = base64[k]; ptr++; k = (((unsigned char) buf[i + 1]) & 0x0F) << 2; *ptr = base64[k]; ptr++; *ptr = '='; ptr++; break; } *newlen = ptr - out; return out;}char hexa[16] = "0123456789abcdef";/* calculate AKA request-digest/response-digest as per HTTP Digest spec */voidDigestCalcResponseAka (IN const char *pszPassword, IN const char *pszNonce, /* nonce from server */ 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 int version, /* AKA version */ OUT RESHEXAKA2 resp_hex /* request-digest or response-digest */ ){ char tmp[MAX_HEADER_LEN]; /* static unsigned int mync = 1; */ /* int has_opaque = 0; */ char *nonce64, *nonce; int noncelen; RAND rnd; MAC mac, xmac; SQN sqn_he; K k; RES res; CK ck; IK ik; AK ak; int i, j; /* Compute the AKA response */ resp_hex[0] = 0; sprintf (tmp, "%s", pszNonce); nonce64 = tmp; nonce = base64_decode_string (nonce64, strlen (tmp), &noncelen); if (nonce == NULL) return; if (noncelen < RANDLEN + AUTNLEN) { /* Nonce is too short */ goto done; } memcpy (rnd, nonce, RANDLEN); /* memcpy(autn,nonce+RANDLEN,AUTNLEN); */ memcpy (sqn_he, nonce + RANDLEN, SQNLEN); memcpy (mac, nonce + RANDLEN + SQNLEN + AMFLEN, MACLEN); osip_free (nonce); j = strlen (pszPassword); memcpy (k, pszPassword, j); memset (k + j, 0, KLEN - j); /* compute XMAC */ f1 (k, rnd, sqn_he, amf, xmac); if (memcmp (mac, xmac, MACLEN) != 0) { /* createAuthHeaderAKAv1MD5 : MAC != eXpectedMAC -> Server might not know the secret (man-in-the-middle attack?) return OSIP_SUCCESS; */ } /* compute the response and keys */ f2345 (k, rnd, res, ck, ik, ak); /* no check for sqn is performed, so no AUTS synchronization performed */ /* Format data for output in the SIP message */ for (i = 0; i < RESLEN; i++) { resp_hex[2 * i] = hexa[(res[i] & 0xF0) >> 4]; resp_hex[2 * i + 1] = hexa[res[i] & 0x0F]; } resp_hex[RESHEXLEN - 1] = 0;done: switch (version) { case 1: /* AKA v1 */ /* Nothing to do */ break; case 2: /* AKA v2 */ resp_hex[RESHEXLEN + IKLEN * 2 + CKLEN * 2 - 1] = 0; for (i = 0; i < IKLEN; i++) { resp_hex[RESLEN * 2 + 2 * i] = hexa[(ik[i] & 0xF0) >> 4]; resp_hex[RESLEN * 2 + 2 * i + 1] = hexa[ik[i] & 0x0F]; } for (i = 0; i < CKLEN; i++) { resp_hex[RESLEN * 2 + IKLEN * 2 + 2 * i] = hexa[(ck[i] & 0xF0) >> 4]; resp_hex[RESLEN * 2 + IKLEN * 2 + 2 * i + 1] = hexa[ck[i] & 0x0F]; } break; }}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; char *Alg = "MD5"; int version = 0; int i; /* make some test */ if (passwd == NULL) return OSIP_BADPARAMETER; if (wa == NULL) return OSIP_BADPARAMETER; if (wa->auth_type == NULL || (wa->nonce == NULL)) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "www_authenticate header is not acceptable.\n")); return OSIP_SYNTAXERROR; } if (wa->realm == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "www_authenticate header contains an empty realm: contact your admin!\n")); } 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 OSIP_UNDEFINED_ERROR; } /* "MD5" is invalid, but some servers use it. */ if (wa->algorithm != NULL) { if (0 == osip_strcasecmp ("MD5", wa->algorithm) || 0 == osip_strcasecmp ("\"MD5\"", wa->algorithm)) { } else if (0 == osip_strcasecmp ("AKAv1-MD5", wa->algorithm) || 0 == osip_strcasecmp ("\"AKAv1-MD5\"", wa->algorithm)) { Alg = "AKAv1-MD5"; } else if (0 == osip_strcasecmp ("AKAv2-MD5", wa->algorithm) || 0 == osip_strcasecmp ("\"AKAv2-MD5\"", wa->algorithm)) { Alg = "AKAv2-MD5"; } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Authentication method not supported. (MD5, AKAv1-MD5, AKAv2-MD5)\n")); return OSIP_UNDEFINED_ERROR; } } i = osip_authorization_init (&aut); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "allocation with authorization_init failed.\n")); return i; } /* 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); if (aut->username == NULL) { osip_authorization_free (aut); return OSIP_NOMEM; } sprintf (aut->username, "\"%s\"", username); { char *tmp = osip_malloc (strlen (rquri) + 3); if (tmp == NULL) { osip_authorization_free (aut); return OSIP_NOMEM; } sprintf (tmp, "\"%s\"", rquri); osip_authorization_set_uri (aut, tmp); } osip_authorization_set_algorithm (aut, osip_strdup (Alg)); 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 = NULL; const char *pszPass = NULL; char *szNonceCount = NULL; const char *pszMethod = method; /* previous_answer->cseq->method; */ char *pszQop = NULL; const char *pszURI = rquri; HASHHEX HA1; HASHHEX HA2 = ""; HASHHEX Response; RESHEXAKA2 Response2; const char *pha1 = NULL; if (osip_authorization_get_realm (aut) == NULL) { pszRealm = osip_strdup (""); } else { pszRealm = osip_strdup_without_quote (osip_authorization_get_realm (aut)); } if (qop != NULL) { /* only accept qop="auth" */ pszQop = osip_strdup ("auth"); if (pszQop == NULL) { osip_authorization_free (aut); osip_free (pszNonce); osip_free (pszRealm); return OSIP_NOMEM; } szNonceCount = osip_malloc (10); if (szNonceCount == NULL) { osip_authorization_free (aut); osip_free (pszNonce); osip_free (pszRealm); osip_free (pszQop); return OSIP_NOMEM; } snprintf (szNonceCount, 9, "%.8i", iNonceCount); pszCNonce = osip_strdup (pCNonce); if (pszCNonce == NULL) { osip_authorization_free (aut); osip_free (pszNonce); osip_free (pszRealm); osip_free (pszQop); osip_free (szNonceCount); return OSIP_NOMEM; } osip_authorization_set_message_qop (aut, osip_strdup ("auth")); osip_authorization_set_nonce_count (aut, osip_strdup (szNonceCount)); { char *tmp = osip_malloc (strlen (pszCNonce) + 3); if (tmp == NULL) { osip_authorization_free (aut); osip_free (pszNonce); osip_free (pszCNonce); osip_free (pszRealm); osip_free (pszQop); osip_free (szNonceCount); return OSIP_NOMEM; } sprintf (tmp, "\"%s\"", pszCNonce); osip_authorization_set_cnonce (aut, tmp); } } pszPass = passwd; /* Depending on which algorithm the response will be calculated, MD5 or AKAv1-MD5 */ if (0 == osip_strcasecmp (Alg, "MD5")) { if (ha1 && ha1[0]) { /* Depending on algorithm=md5 */ pha1 = ha1; } else { DigestCalcHA1 ("MD5", pszUser, pszRealm, pszPass, pszNonce,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -