📄 auth_client.c
字号:
if (user && pass) { for (; *auc_list; auc_list = &(*auc_list)->ca_next) { match = ca_credentials(*auc_list, scheme, realm, user, pass); if (match < 0) return -1; if (match) retval++; } } return retval;}int ca_credentials(auth_client_t *ca, char const *scheme, char const *realm, char const *user, char const *pass){ assert(ca); if (!ca || !ca->ca_scheme || !ca->ca_realm) return -1; if ((scheme != NULL && strcasecmp(scheme, ca->ca_scheme)) || (realm != NULL && strcmp(realm, ca->ca_realm))) return -1; ca->ca_user = su_strdup(ca->ca_home, user); ca->ca_pass = su_strdup(ca->ca_home, pass); if (!ca->ca_user || !ca->ca_pass) return -1; return 1;}/**Clear authentication data from the authenticator. * * The function auc_clear_credentials() is used to remove the credentials * from the authenticators. * * @param auc_list [in/out] list of authenticators * @param scheme [in] scheme (if non-null, remove only matching credentials) * @param realm [in] realm (if non-null, remove only matching credentials) * * @retval 0 when successful * @retval -1 upon an error */int auc_clear_credentials(auth_client_t **auc_list, char const *scheme, char const *realm){ int retval = 0; for (; *auc_list; auc_list = &(*auc_list)->ca_next) { int match = ca_clear_credentials(*auc_list, scheme, realm); if (match < 0) { retval = -1; break; } if (match) retval++; } return retval;}staticint ca_clear_credentials(auth_client_t *ca, char const *scheme, char const *realm){ assert(ca); if (!ca || !ca->ca_scheme || !ca->ca_realm) return -1; if ((scheme != NULL && strcasecmp(scheme, ca->ca_scheme)) || (realm != NULL && strcmp(realm, ca->ca_realm))) return -1; su_free(ca->ca_home, (void *)ca->ca_user), ca->ca_user = NULL; su_free(ca->ca_home, (void *)ca->ca_pass), ca->ca_pass = NULL; return 1;}/**Authorize a request. * * The function auc_authorization() is used to add correct authentication * headers to a request. The authentication headers will contain the * credentials generated by the list of authenticators. * * @param auc_list [in/out] list of authenticators * @param msg [out] message to be authenticated * @param pub [out] headers of the message * @param method [in] request method * @param url [in] request URI * @param body [in] message body (NULL if empty) * * @retval 1 when successful * @retval 0 when there is not enough credentials * @retval -1 upon an error */int auc_authorization(auth_client_t **auc_list, msg_t *msg, msg_pub_t *pub, char const *method, url_t const *url, msg_payload_t const *body){ auth_client_t *ca; msg_mclass_t const *mc = msg_mclass(msg); /* Make sure every challenge has credentials */ for (ca = *auc_list; ca; ca = ca->ca_next) { if (!ca->ca_user || !ca->ca_pass || !ca->ca_authorize) return 0; } /* Remove existing credentials */ for (ca = *auc_list; ca; ca = ca->ca_next) { msg_header_t **hh = msg_hclass_offset(mc, pub, ca->ca_credential_class); while (hh && *hh) msg_header_remove(msg, pub, *hh); } /* Insert new credentials */ for (; *auc_list; auc_list = &(*auc_list)->ca_next) { msg_header_t *h; h = (*auc_list)->ca_authorize(*auc_list, msg_home(msg), method, url, body); if (!h || msg_header_insert(msg, pub, h) < 0) return 0; } return 1;}/**Generate headers authorizing a request. * * The function auc_authorization_headers() is used to generate * authentication headers for a request. The list of authentication headers * will contain the credentials generated by the list of authenticators. * * @param auc_list [in/out] list of authenticators * @param home [in] memory home used to allocate headers * @param method [in] request method * @param url [in] request URI * @param body [in] message body (NULL if empty) * @param return_headers [out] authorization headers * * @retval 1 when successful * @retval 0 when there is not enough credentials * @retval -1 upon an error */int auc_authorization_headers(auth_client_t **auc_list, su_home_t *home, char const *method, url_t const *url, msg_payload_t const *body, msg_header_t **return_headers){ auth_client_t *ca; /* Make sure every challenge has credentials */ for (ca = *auc_list; ca; ca = ca->ca_next) { if (!ca->ca_user || !ca->ca_pass || !ca->ca_authorize) return 0; } /* Insert new credentials */ for (; *auc_list; auc_list = &(*auc_list)->ca_next) { msg_header_t *h; h = (*auc_list)->ca_authorize(*auc_list, home, method, url, body); if (!h) return -1; *return_headers = h; return_headers = &h->sh_next; } return 1;}/**Create a basic authorization header. * * The function auc_basic_authorization() creates a basic authorization * header from username @a user and password @a pass. The authorization * header type is determined by @a hc - it can be sip_authorization_class, * sip_proxy_authorization_class, http_authorization_class, or * http_proxy_authorization_class, for instance. * * @param home memory home used to allocate memory for the new header * @param hc header class for the header to be created * @param user user name * @param pass password * * @return * The function auc_basic_authorization() returns a pointer to newly created * authorization header, or NULL upon an error. */msg_header_t *auc_basic_authorization(auth_client_t *ca, su_home_t *home, char const *method, url_t const *url, msg_payload_t const *body){ char userpass[49]; /* "reasonable" maximum */ char base64[65]; msg_hclass_t *hc = ca->ca_credential_class; char const *user = ca->ca_user; char const *pass = ca->ca_pass; userpass[sizeof(userpass) - 1] = 0; base64[sizeof(base64) - 1] = 0; /* * Basic authentication consists of username and password separated by * colon and then base64 encoded. */ snprintf(userpass, sizeof(userpass) - 1, "%s:%s", user, pass); base64_e(base64, sizeof(base64), userpass, strlen(userpass)); return msg_header_format(home, hc, "Basic %s", base64);}/**Create a digest authorization header. * * The function auc_digest_authorization() creates a digest authorization * header from username @a user and password @a pass, client nonce @a * cnonce, client nonce count @a nc, request method @a method, request URI * @a uri and message body @a data. The authorization header type is * determined by @a hc - it can be either sip_authorization_class or * sip_proxy_authorization_class, as well as http_authorization_class or * http_proxy_authorization_class. * * @param home memory home used to allocate memory for the new header * @param hc header class for the header to be created * @param user user name * @param pass password * @param ac challenge structure * @param cnonce client nonce * @param nc client nonce count * @param method request method * @param uri request uri * @param data message body * @param dlen length of message body * * @return * The function auc_digest_authorization() returns a pointer to newly created * authorization header, or NULL upon an error. */msg_header_t *auc_digest_authorization(auth_client_t *ca, su_home_t *home, char const *method, url_t const *url, msg_payload_t const *body){ msg_hclass_t *hc = ca->ca_credential_class; char const *user = ca->ca_user; char const *pass = ca->ca_pass; auth_challenge_t const *ac = ca->ca_ac; char const *cnonce = ca->ca_cnonce; char *uri = url_as_string(home, url); void const *data = body ? body->pl_data : ""; int dlen = body ? body->pl_len : 0; msg_header_t *h; auth_hexmd5_t sessionkey, response; auth_response_t ar[1] = {{ 0 }}; char ncount[17]; ar->ar_size = sizeof(ar); ar->ar_username = user; ar->ar_realm = ac->ac_realm; ar->ar_nonce = ac->ac_nonce; ar->ar_algorithm = NULL; ar->ar_md5 = ac->ac_md5; ar->ar_md5sess = ac->ac_md5sess; ar->ar_opaque = ac->ac_opaque; ar->ar_qop = NULL; ar->ar_auth = ac->ac_auth; ar->ar_auth_int = ac->ac_auth_int; ar->ar_uri = uri; /* If there is no qop, we MUST NOT include cnonce or nc */ if (!ar->ar_auth && !ar->ar_auth_int) cnonce = NULL; if (cnonce) { snprintf(ncount, sizeof(ncount), "%08x", ++ca->ca_ncount); ar->ar_cnonce = cnonce; ar->ar_nc = ncount; } auth_digest_sessionkey(ar, sessionkey, pass); auth_digest_response(ar, response, sessionkey, method, data, dlen); h = msg_header_format(home, hc, "Digest " "username=\"%s\", " "realm=\"%s\", " "nonce=\"%s" "%s%s" "%s%s" "%s%s, " "uri=\"%s\", " "response=\"%s\"" "%s%s" "%s%s", ar->ar_username, ar->ar_realm, ar->ar_nonce, cnonce ? "\", cnonce=\"" : "", cnonce ? cnonce : "", ar->ar_opaque ? "\", opaque=\"" : "", ar->ar_opaque ? ar->ar_opaque : "", ar->ar_algorithm ? "\", algorithm=" : "", ar->ar_algorithm ? ar->ar_algorithm : "", ar->ar_uri, response, ar->ar_auth || ar->ar_auth_int ? ", qop=" : "", ar->ar_auth_int ? "auth-int" : (ar->ar_auth ? "auth" : ""), cnonce ? ", nc=" : "", cnonce ? ncount : ""); su_free(home, uri); return h;}#if HAVE_SOFIA_SIP#include <sofia-sip/sip.h>/**Authorize a SIP request. * * The function auc_authorize() is used to add correct authentication * headers to a SIP request. The authentication headers will contain the * credentials generated by the list of authenticators. * * @param auc_list [in/out] list of authenticators * @param msg [in/out] message to be authenticated * @param sip [in/out] sip headers of the message * * @retval 1 when successful * @retval 0 when there is not enough credentials * @retval -1 upon an error */int auc_authorize(auth_client_t **auc_list, msg_t *msg, sip_t *sip){ sip_request_t *rq = sip->sip_request; return auc_authorization(auc_list, msg, (msg_pub_t *)sip, rq->rq_method_name, /* XXX - why this was needed? rq->rq_method == sip_method_register ? sip->sip_to->a_url : */ rq->rq_url, sip->sip_payload);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -