diff --git a/pjsip/include/pjsua2/endpoint.hpp b/pjsip/include/pjsua2/endpoint.hpp index c446d04081..133159267d 100644 --- a/pjsip/include/pjsua2/endpoint.hpp +++ b/pjsip/include/pjsua2/endpoint.hpp @@ -546,57 +546,57 @@ struct DigestChallenge struct DigestCredential { /** - *Realm of the credential + * Realm of the credential */ std::string realm; /** - *Other parameters. + * Other parameters. */ StringToStringMap otherParam; /** - *Username parameter. + * Username parameter. */ std::string username; /** - *Nonce parameter. + * Nonce parameter. */ std::string nonce; /** - *URI parameter. + * URI parameter. */ std::string uri; /** - *Response digest. + * Response digest. */ std::string response; /** - *Algorithm. + * Algorithm. */ std::string algorithm; /** - *Cnonce. + * Cnonce. */ std::string cnonce; /** - *Opaque value. + * Opaque value. */ std::string opaque; /** - *Quality of protection. + * Quality of protection. */ std::string qop; /** - *Nonce count. + * Nonce count. */ std::string nc; @@ -613,20 +613,36 @@ struct DigestCredential /** - * Parameters for onCredAuth account method. + * Parameter of Endpoint::onCredAuth() callback. */ struct OnCredAuthParam { - /** Digest challenge */ + /** + * Digest challenge. + * The authentication challenge sent by server in 401 or 401 response, + * as either Proxy-Authenticate or WWW-Authenticate header. + */ DigestChallenge digestChallenge; - /** Credential info */ + /** + * Credential info. + */ AuthCredInfo credentialInfo; - /** Method */ + /** + * The request method. + */ std::string method; - /** Digest credential */ + /** + * The digest credential where the digest response will be placed to. + * + * Upon calling this function, the nonce, nc, cnonce, qop, uri, and realm + * fields of this structure must be set by the caller. + * + * Upon return, the callback must set the response in + * \a DigestCredential.response. + */ DigestCredential digestCredential; }; @@ -1928,35 +1944,24 @@ class Endpoint { PJ_UNUSED_ARG(prm); } /** - * Callback for computation of the digest credential. - * - * Usually, an application does not need to implement (overload) this callback. - * Use it, if your application needs to support Digest AKA authentication without - * the default digest computation back-end (i.e: using libmilenage). - * - * To use Digest AKA authentication, add \a PJSIP_CRED_DATA_EXT_AKA flag in the - * AuthCredInfo's \a dataType field of the AccountConfig, and fill up other - * AKA specific information in AuthCredInfo: - * - If PJSIP_HAS_DIGEST_AKA_AUTH is disabled, you have to overload this callback - * to provide your own digest computation back-end. - * - If PJSIP_HAS_DIGEST_AKA_AUTH is enabled, libmilenage library from - * \a third_party directory is linked, and this callback returns PJ_ENOTSUP, - * then the default digest computation back-end is used. - * - * @param prm.digestChallenge The authentication challenge sent by server in 401 - * or 401 response, as either Proxy-Authenticate or - * WWW-Authenticate header. - * @param prm.credentialInfo The credential to be used. - * @param method The request method. - * @param prm.digestCredential The digest credential where the digest response - * will be placed to. Upon calling this function, the - * nonce, nc, cnonce, qop, uri, and realm fields of - * this structure must have been set by caller. Upon - * return, the \a response field will be initialized - * by this function. - * - * @return PJ_ENOTSUP is the default. If you overload this callback, - * return PJ_SUCCESS on success. + * Callback for custom computation of the digest AKA response. + * + * Usually an application does not need to implement (overload) this + * callback because by default the response digest AKA is automatically + * computed using libmilenage. + * + * To use Digest AKA authentication, add \a PJSIP_CRED_DATA_EXT_AKA flag + * in the AuthCredInfo's \a dataType field of the AccountConfig, and + * fill up other AKA specific information in AuthCredInfo. + * Please see \ref PJSIP_AUTH_AKA_API for more information. + * + * @param prm Callback parameter. + * + * @return Return PJ_ENOTSUP to let the library compute + * the response digest automatically. + * Return PJ_SUCCESS if application does the computation + * and sets the response digest in + * \a prm.DigestCredential.response. */ virtual pj_status_t onCredAuth(OnCredAuthParam &prm); diff --git a/pjsip/src/pjsua2/account.cpp b/pjsip/src/pjsua2/account.cpp index 4db9214fe7..2558596fdd 100644 --- a/pjsip/src/pjsua2/account.cpp +++ b/pjsip/src/pjsua2/account.cpp @@ -992,8 +992,9 @@ void Account::create(const AccountConfig &acc_cfg, acc_cfg.toPj(pj_acc_cfg); for (unsigned i = 0; i < pj_acc_cfg.cred_count; ++i) { - pjsip_cred_info *dst = &pj_acc_cfg.cred_info[i]; - dst->ext.aka.cb = (pjsip_cred_cb)Endpoint::on_auth_create_aka_response_callback; + pjsip_cred_info *dst = &pj_acc_cfg.cred_info[i]; + dst->ext.aka.cb = (pjsip_cred_cb) + &Endpoint::on_auth_create_aka_response_callback; } pj_acc_cfg.user_data = (void*)this; PJSUA2_CHECK_EXPR( pjsua_acc_add(&pj_acc_cfg, make_default, &id) ); diff --git a/pjsip/src/pjsua2/endpoint.cpp b/pjsip/src/pjsua2/endpoint.cpp index b6fc1aed6d..829f70a300 100644 --- a/pjsip/src/pjsua2/endpoint.cpp +++ b/pjsip/src/pjsua2/endpoint.cpp @@ -2701,6 +2701,7 @@ pj_status_t Endpoint::on_auth_create_aka_response_callback(pj_pool_t *pool, pjsip_digest_credential *auth) { OnCredAuthParam prm; + prm.digestChallenge.fromPj(*chal); prm.credentialInfo.fromPj(*cred); prm.method = pj2Str(*method); @@ -2709,24 +2710,26 @@ pj_status_t Endpoint::on_auth_create_aka_response_callback(pj_pool_t *pool, pj_status_t status = Endpoint::instance().onCredAuth(prm); if (status == PJ_SUCCESS) { - pjsip_digest_credential auth_new = prm.digestCredential.toPj(); - // Duplicate in the pool, so that digestCredential - // is allowed to be destructed at the end of the method. - pj_strdup(pool, &auth->realm, &auth_new.realm); - pj_strdup(pool, &auth->username, &auth_new.username); - pj_strdup(pool, &auth->nonce, &auth_new.nonce); - pj_strdup(pool, &auth->uri, &auth_new.uri); - pj_strdup(pool, &auth->response, &auth_new.response); - pj_strdup(pool, &auth->algorithm, &auth_new.algorithm); - pj_strdup(pool, &auth->cnonce, &auth_new.cnonce); - pj_strdup(pool, &auth->opaque, &auth_new.opaque); - pj_strdup(pool, &auth->qop, &auth_new.qop); - pj_strdup(pool, &auth->nc, &auth_new.nc); - pjsip_param_clone(pool, &auth->other_param, &auth_new.other_param); + pjsip_digest_credential auth_new = prm.digestCredential.toPj(); + + // Duplicate in the pool, so that digestCredential + // is allowed to be destructed at the end of the method. + pj_strdup(pool, &auth->realm, &auth_new.realm); + pj_strdup(pool, &auth->username, &auth_new.username); + pj_strdup(pool, &auth->nonce, &auth_new.nonce); + pj_strdup(pool, &auth->uri, &auth_new.uri); + pj_strdup(pool, &auth->response, &auth_new.response); + pj_strdup(pool, &auth->algorithm, &auth_new.algorithm); + pj_strdup(pool, &auth->cnonce, &auth_new.cnonce); + pj_strdup(pool, &auth->opaque, &auth_new.opaque); + pj_strdup(pool, &auth->qop, &auth_new.qop); + pj_strdup(pool, &auth->nc, &auth_new.nc); + pjsip_param_clone(pool, &auth->other_param, &auth_new.other_param); } #if PJSIP_HAS_DIGEST_AKA_AUTH - else if (status == PJ_ENOTSUP) { - status = pjsip_auth_create_aka_response(pool, chal, cred, method, auth); + else if (status == PJ_ENOTSUP) { + status = pjsip_auth_create_aka_response(pool, chal, cred, method, + auth); } #endif return status;