auth_module.c
来自「sip协议栈」· C语言 代码 · 共 1,882 行 · 第 1/4 页
C
1,882 行
if (!(buffer = su_alloc(home, len + 2)) || fread(buffer, 1, len, f) != len) { SU_DEBUG_1(("%s: unable to read file (%s)\n", __func__, strerror(errno))); if (buffer) su_free(home, buffer); return -1; } if (add_trailing_lf) { /* Make sure that the buffer has trailing newline */ if (len == 0 || buffer[len - 1] != '\n') buffer[len++] = '\n'; } buffer[len] = '\0'; *contents = buffer; return len;}/* ====================================================================== *//* Helper functions *//** Check if request method is on always-allowed list. */int auth_allow_check(auth_mod_t *am, auth_status_t *as){ char const *method = as->as_method; int i; if (method && strcmp(method, "ACK") == 0) /* Hack */ return as->as_status = 0; if (!method || !am->am_allow) return 1; for (i = 0; am->am_allow[i]; i++) if (strcmp(am->am_allow[i], method) == 0) return as->as_status = 0; return 1;}/** Find a credential header with matching scheme and realm. */msg_auth_t *auth_mod_credentials(msg_auth_t *auth, char const *scheme, char const *realm){ char const *arealm; for (;auth; auth = auth->au_next) { if (strcasecmp(auth->au_scheme, scheme)) continue; if (!realm) return auth; arealm = msg_header_find_param(auth->au_common, "realm="); if (!arealm) continue; if (arealm[0] == '"') { /* Compare quoted arealm with unquoted realm */ int i, j; for (i = 1, j = 0; arealm[i] != 0; i++, j++) { if (arealm[i] == '"' && realm[j] == 0) return auth; if (arealm[i] == '\\' && arealm[i + 1] != '\0') i++; if (arealm[i] != realm[j]) break; } } else { if (strcmp(arealm, realm) == 0) return auth; } } return NULL;}/** Find a Digest credential header with matching realm and opaque. */msg_auth_t *auth_digest_credentials(msg_auth_t *auth, char const *realm, char const *opaque){ char const *arealm, *aopaque; for (;auth; auth = auth->au_next) { if (strcasecmp(auth->au_scheme, "Digest")) continue; if (realm) { int cmp = 1; arealm = msg_header_find_param(auth->au_common, "realm="); if (!arealm) continue; if (arealm[0] == '"') { /* Compare quoted arealm with unquoted realm */ int i, j; for (i = 1, j = 0, cmp = 1; arealm[i] != 0; i++, j++) { if (arealm[i] == '"' && realm[j] == 0) { cmp = 0; break; } if (arealm[i] == '\\' && arealm[i + 1] != '\0') i++; if (arealm[i] != realm[j]) break; } } else { cmp = strcmp(arealm, realm); } if (cmp) continue; } if (opaque) { int cmp = 1; aopaque = msg_header_find_param(auth->au_common, "opaque="); if (!aopaque) continue; if (aopaque[0] == '"') { /* Compare quoted aopaque with unquoted opaque */ int i, j; for (i = 1, j = 0, cmp = 1; aopaque[i] != 0; i++, j++) { if (aopaque[i] == '"' && opaque[j] == 0) { cmp = 0; break; } if (aopaque[i] == '\\' && aopaque[i + 1] != '\0') i++; if (aopaque[i] != opaque[j]) break; } } else { cmp = strcmp(aopaque, opaque); } if (cmp) continue; } return auth; } return NULL;}/** Generate nonce parameter. * * @param am pointer to authentication module object * @param buffer string buffer for nonce [OUT] * @param bsize size of buffer [IN] * @param nextnonce true if this is a "nextnonce" [IN] * @param now current time [IN] */int auth_generate_digest_nonce(auth_mod_t *am, char buffer[], size_t bsize, int nextnonce, msg_time_t now){ struct nonce nonce[1] = {{ 0 }}; su_md5_t md5[1]; am->am_count += 3730029547U; /* 3730029547 is a prime */ nonce->issued = now; nonce->count = am->am_count; nonce->nextnonce = nextnonce != 0; /* Calculate HMAC of nonce data */ auth_md5_hmac_init(am, md5); su_md5_update(md5, nonce, offsetof(struct nonce, digest)); auth_md5_hmac_digest(am, md5, nonce->digest, sizeof nonce->digest); return base64_e(buffer, bsize, nonce, sizeof(nonce));}/** Validate nonce parameter. * * @param am pointer to authentication module object * @param as authentication status structure [OUT] * @param ar decoded authentication response from client [IN] * @param now current time [IN] */int auth_validate_digest_nonce(auth_mod_t *am, auth_status_t *as, auth_response_t *ar, msg_time_t now){ struct nonce nonce[1] = {{ 0 }}; su_md5_t md5[1]; uint8_t hmac[sizeof nonce->digest]; unsigned expires; /* Check nonce */ if (!ar->ar_nonce) { SU_DEBUG_5(("auth_method_digest: no nonce\n")); return -1; } if (base64_d((void*)nonce, (sizeof nonce), ar->ar_nonce) != (sizeof nonce)) { SU_DEBUG_5(("auth_method_digest: too short nonce\n")); return -1; } /* Calculate HMAC over decoded nonce data */ auth_md5_hmac_init(am, md5); su_md5_update(md5, nonce, offsetof(struct nonce, digest)); auth_md5_hmac_digest(am, md5, hmac, sizeof hmac); if (memcmp(nonce->digest, hmac, sizeof nonce->digest)) { SU_DEBUG_5(("auth_method_digest: bad nonce\n")); return -1; } as->as_nonce_issued = nonce->issued; as->as_nextnonce = nonce->nextnonce != 0; expires = nonce->nextnonce ? am->am_next_exp : am->am_expires; if (nonce->issued > now || (expires && nonce->issued + expires < now)) { SU_DEBUG_5(("auth_method_digest: nonce expired %lu seconds ago " "(lifetime %u)\n", now - (nonce->issued + expires), expires)); as->as_stale = 1; } /* We should also check cnonce, nc... */ return 0;}#if HAVE_SOFIA_NTLM/** Find a NTLM credential header with matching realm and opaque. */msg_auth_t *auth_ntlm_credentials(msg_auth_t *auth, char const *realm, char const *opaque, char const *gssapidata, char const *targetname){ char const *arealm, *aopaque, *agssapidata, *atargetname; for (;auth; auth = auth->au_next) { if (strcasecmp(auth->au_scheme, "NTLM")) continue; if (realm) { int cmp = 1; arealm = msg_header_find_param(auth->au_common, "realm="); if (!arealm) continue; if (arealm[0] == '"') { /* Compare quoted arealm with unquoted realm */ int i, j; for (i = 1, j = 0, cmp = 1; arealm[i] != 0; i++, j++) { if (arealm[i] == '"' && realm[j] == 0) { cmp = 0; break; } if (arealm[i] == '\\' && arealm[i + 1] != '\0') i++; if (arealm[i] != realm[j]) break; } } else { cmp = strcmp(arealm, realm); } if (cmp) continue; } if (opaque) { int cmp = 1; aopaque = msg_header_find_param(auth->au_common, "opaque="); if (!aopaque) continue; if (aopaque[0] == '"') { /* Compare quoted aopaque with unquoted opaque */ int i, j; for (i = 1, j = 0, cmp = 1; aopaque[i] != 0; i++, j++) { if (aopaque[i] == '"' && opaque[j] == 0) { cmp = 0; break; } if (aopaque[i] == '\\' && aopaque[i + 1] != '\0') i++; if (aopaque[i] != opaque[j]) break; } } else { cmp = strcmp(aopaque, opaque); } if (cmp) continue; } if (gssapidata) { int cmp = 1; agssapidata = msg_header_find_param(auth->au_common, "gssapi-data="); if (!agssapidata) continue; if (agssapidata[0] == '"') { /* Compare quoted agssapi-data with unquoted gssapi-data */ int i, j; for (i = 1, j = 0, cmp = 1; agssapidata[i] != 0; i++, j++) { if (agssapidata[i] == '"' && gssapidata[j] == 0) { cmp = 0; break; } if (agssapidata[i] == '\\' && agssapidata[i + 1] != '\0') i++; if (agssapidata[i] != gssapidata[j]) break; } } else { cmp = strcmp(agssapidata, gssapidata); } if (cmp) continue; } if (targetname) { int cmp = 1; atargetname = msg_header_find_param(auth->au_common, "targetname="); if (!atargetname) continue; if (atargetname[0] == '"') { /* Compare quoted atargetname with unquoted targetname */ int i, j; for (i = 1, j = 0, cmp = 1; atargetname[i] != 0; i++, j++) { if (atargetname[i] == '"' && targetname[j] == 0) { cmp = 0; break; } if (atargetname[i] == '\\' && atargetname[i + 1] != '\0') i++; if (atargetname[i] != targetname[j]) break; } } else { cmp = strcmp(atargetname, targetname); } if (cmp) continue; } return auth; } return NULL;}#endif /* HAVE_SOFIA_NTLM *//* ====================================================================== *//* HMAC routines */staticvoid auth_md5_hmac_key(auth_mod_t *am){ int i; uint8_t ipad[SU_MD5_DIGEST_SIZE]; uint8_t opad[SU_MD5_DIGEST_SIZE]; assert(SU_MD5_DIGEST_SIZE == sizeof am->am_master_key); /* Derive HMAC ipad and opad from master key */ for (i = 0; i < sizeof am->am_master_key; i++) { ipad[i] = am->am_master_key[i] ^ 0x36; opad[i] = am->am_master_key[i] ^ 0x5C; } /* Pre-calculate sum of ipad */ su_md5_init(&am->am_hmac_ipad); su_md5_update(&am->am_hmac_ipad, ipad, sizeof ipad); /* Pre-calculate sum of opad */ su_md5_init(&am->am_hmac_opad); su_md5_update(&am->am_hmac_opad, opad, sizeof opad);}void auth_md5_hmac_init(auth_mod_t *am, struct su_md5_t *imd5){ *imd5 = am->am_hmac_ipad;}void auth_md5_hmac_digest(auth_mod_t *am, struct su_md5_t *imd5, void *hmac, size_t size){ uint8_t digest[SU_MD5_DIGEST_SIZE]; su_md5_t omd5[1]; /* inner sum */ su_md5_digest(imd5, digest); *omd5 = am->am_hmac_opad; su_md5_update(omd5, digest, sizeof *digest); /* outer sum */ if (size == sizeof digest) { su_md5_digest(omd5, hmac); } else { su_md5_digest(omd5, digest); if (size > sizeof digest) { memset((char *)hmac + (sizeof digest), 0, size - sizeof digest); size = sizeof digest; } memcpy(hmac, digest, size); }}/* ====================================================================== *//* Compatibility interface */void auth_mod_check_client(auth_mod_t *am, auth_status_t *as, msg_auth_t *credentials, auth_challenger_t const *ach){ auth_mod_method(am, as, credentials, ach);}void auth_mod_challenge_client(auth_mod_t *am, auth_status_t *as, auth_challenger_t const *ach){ auth_mod_challenge(am, as, ach);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?