Skip to content

Commit

Permalink
Update PJSUA2 docs on auth digest AKA callback (#4089)
Browse files Browse the repository at this point in the history
  • Loading branch information
nanangizz authored Sep 26, 2024
1 parent 6cb98ab commit 906f816
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 63 deletions.
95 changes: 50 additions & 45 deletions pjsip/include/pjsua2/endpoint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
};

Expand Down Expand Up @@ -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 <b>libmilenage</b>).
*
* 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, <b>libmilenage</b> 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 <b>libmilenage</b>.
*
* 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);

Expand Down
5 changes: 3 additions & 2 deletions pjsip/src/pjsua2/account.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) );
Expand Down
35 changes: 19 additions & 16 deletions pjsip/src/pjsua2/endpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
Expand Down

0 comments on commit 906f816

Please sign in to comment.