c++ - pjsip 应用程序无法注册帐户,并出现 Invalid/unsupported digest algorithm 错误
问题描述
我尝试使用库运行这个示例 C++ 应用程序pjsip
,但是当我运行该应用程序时,我遇到了这个错误:
06:56:50.480 sip_auth_client.c ...Unsupported digest algorithm "SHA-256"
06:56:50.480 pjsua_acc.c ....SIP registration error: Invalid/unsupported digest algorithm (PJSIP_EINVALIDALGORITHM) [status=171102]
但是当我检查来自服务器的 SIP 响应时,我注意到它包含两个WWW-Authenticate
标头:
WWW-Authenticate: Digest realm="sip.linphone.org", nonce="ImEX4gAAAAC73QlWAAC9corBNkwAAAAA", opaque="+GNywA==", algorithm=SHA-256, qop="auth"
WWW-Authenticate: Digest realm="sip.linphone.org", nonce="ImEX4gAAAAC73QlWAAC9corBNkwAAAAA", opaque="+GNywA==", algorithm=MD5, qop="auth"
所以问题是,如果pjsip
不支持sha-256
算法,为什么不使用md5
第二个标题中提到的算法?
示例代码是:
#include <pjsua2.hpp>
#include <iostream>
using namespace pj;
// Subclass to extend the Account and get notifications etc.
class MyAccount : public Account {
public:
virtual void onRegState(OnRegStateParam &prm) {
AccountInfo ai = getInfo();
std::cout << (ai.regIsActive? "*** Register:" : "*** Unregister:")
<< " code=" << prm.code << std::endl;
}
};
int main()
{
Endpoint ep;
ep.libCreate();
// Initialize endpoint
EpConfig ep_cfg;
ep.libInit( ep_cfg );
// Create SIP transport. Error handling sample is shown
TransportConfig tcfg;
tcfg.port = 5060;
try {
ep.transportCreate(PJSIP_TRANSPORT_UDP, tcfg);
} catch (Error &err) {
std::cout << err.info() << std::endl;
return 1;
}
// Start the library (worker threads etc)
ep.libStart();
std::cout << "*** PJSUA2 STARTED ***" << std::endl;
// Configure an AccountConfig
AccountConfig acfg;
acfg.idUri = "sip:test@pjsip.org";
acfg.regConfig.registrarUri = "sip:pjsip.org";
AuthCredInfo cred("digest", "*", "test", 0, "secret");
acfg.sipConfig.authCreds.push_back( cred );
// Create the account
MyAccount *acc = new MyAccount;
acc->create(acfg);
// Here we don't have anything else to do..
pj_thread_sleep(10000);
// Delete the account. This will unregister from server
delete acc;
// This will implicitly shutdown the library
return 0;
}
解决方案
我自己也为此苦苦挣扎。显然,PJSIP 只评估第一个 WWW-Authenticate 标头,即使服务器提供了多个标头。
为了克服这个问题,我在源代码中更改了以下内容:
在文件中/pjsip/src/pjsip/sip_auth_client.c
找到为 WWW-Authenticate 标头生成响应的代码块。它应该在 1220 行附近。
/* Create authorization header for this challenge, and update
* authorization session.
*/
status = process_auth(tdata->pool, hchal, tdata->msg->line.req.uri,
tdata, sess, cached_auth, &hauth);
if (status != PJ_SUCCESS)
return status;
if (pj_pool_get_used_size(cached_auth->pool) >
PJSIP_AUTH_CACHED_POOL_MAX_SIZE)
{
recreate_cached_auth_pool(sess->endpt, cached_auth);
}
/* Add to the message. */
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);
/* Process next header. */
hdr = hdr->next;
并将其替换为
/* Create authorization header for this challenge, and update
* authorization session.
*/
status = process_auth(tdata->pool, hchal, tdata->msg->line.req.uri,
tdata, sess, cached_auth, &hauth);
if (status != PJ_SUCCESS){
// Previously, pjsip analysed one www-auth header, and if it failed (due to unsupported sha-256 digest for example), it returned and did not consider the next www-auth header.
PJ_LOG(4,(THIS_FILE, "Invalid response, moving to next"));
//return status;
hdr = hdr->next;
}else{
if (pj_pool_get_used_size(cached_auth->pool) >
PJSIP_AUTH_CACHED_POOL_MAX_SIZE)
{
recreate_cached_auth_pool(sess->endpt, cached_auth);
}
/* Add to the message. */
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);
/* Process next header. */
hdr = hdr->next;
}
然后重新编译源代码(按照这些说明How to install pjsua2 packages for python?)
请注意,虽然这解决了 linphone 的问题,但我没有针对其他情况进行测试(例如,当服务器发送多个有效算法或根本不发送时)。
推荐阅读
- swift - 将 UI 与逻辑 Swift 连接时出现关闭错误
- javascript - Javascript scrollTop 错误
- python - TypeError:“DeferredAttribute”对象不可迭代
- python - 如何计算具有重复元素的列表的混乱(排列)
- python - 将 result_type 与 pandas 应用函数一起使用
- c++ - massif 可视化工具和 ms_print 之间的大小差异
- html - 如何更改我的 wordpress 网站上图像和文本的对齐方式?
- php - Wordpress 视频嵌入和缩略图生成器将视频中的缩略图添加到帖子
- python - 如何在 ml 引擎中构建用于对象检测预测的 uint8 numpy 数组输入张量
- android - 访问 Virdi AC 7000 指纹终端的日志文件