修复rtsp basic鉴权相关bug: #2087

This commit is contained in:
ziyue 2022-11-15 20:52:27 +08:00
parent 87353534af
commit 034e29b25a
4 changed files with 32 additions and 45 deletions

View File

@ -245,23 +245,19 @@ public:
_printer << "a=rtpmap:" << payload_type << " " << getCodecName() << "/" << 90000 << "\r\n"; _printer << "a=rtpmap:" << payload_type << " " << getCodecName() << "/" << 90000 << "\r\n";
_printer << "a=fmtp:" << payload_type << " packetization-mode=1; profile-level-id="; _printer << "a=fmtp:" << payload_type << " packetization-mode=1; profile-level-id=";
char strTemp[1024];
uint32_t profile_level_id = 0; uint32_t profile_level_id = 0;
if (strSPS.length() >= 4) { // sanity check if (strSPS.length() >= 4) { // sanity check
profile_level_id = (uint8_t(strSPS[1]) << 16) | profile_level_id = (uint8_t(strSPS[1]) << 16) |
(uint8_t(strSPS[2]) << 8) | (uint8_t(strSPS[2]) << 8) |
(uint8_t(strSPS[3])); // profile_idc|constraint_setN_flag|level_idc (uint8_t(strSPS[3])); // profile_idc|constraint_setN_flag|level_idc
} }
memset(strTemp, 0, sizeof(strTemp));
snprintf(strTemp, sizeof(strTemp), "%06X", profile_level_id); char profile[8];
_printer << strTemp; snprintf(profile, sizeof(profile), "%06X", profile_level_id);
_printer << profile;
_printer << "; sprop-parameter-sets="; _printer << "; sprop-parameter-sets=";
memset(strTemp, 0, sizeof(strTemp)); _printer << encodeBase64(strSPS) << ",";
av_base64_encode(strTemp, sizeof(strTemp), (uint8_t *)strSPS.data(), (int)strSPS.size()); _printer << encodeBase64(strPPS) << "\r\n";
_printer << strTemp << ",";
memset(strTemp, 0, sizeof(strTemp));
av_base64_encode(strTemp, sizeof(strTemp), (uint8_t *)strPPS.data(), (int)strPPS.size());
_printer << strTemp << "\r\n";
_printer << "a=control:trackID=" << (int)TrackVideo << "\r\n"; _printer << "a=control:trackID=" << (int)TrackVideo << "\r\n";
} }

View File

@ -580,16 +580,16 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url, const std
void RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrCaseMap &header_const) { void RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrCaseMap &header_const) {
auto header = header_const; auto header = header_const;
header.emplace("CSeq",StrPrinter << _cseq_send++); header.emplace("CSeq", StrPrinter << _cseq_send++);
header.emplace("User-Agent",kServerName); header.emplace("User-Agent", kServerName);
if(!_session_id.empty()){ if (!_session_id.empty()) {
header.emplace("Session", _session_id); header.emplace("Session", _session_id);
} }
if(!_realm.empty() && !(*this)[Client::kRtspUser].empty()){ if (!_realm.empty() && !(*this)[Client::kRtspUser].empty()) {
if(!_md5_nonce.empty()){ if (!_md5_nonce.empty()) {
//MD5认证 // MD5认证
/* /*
response计算方法如下 response计算方法如下
RTSP客户端应该使用username + password并计算response如下: RTSP客户端应该使用username + password并计算response如下:
@ -599,7 +599,7 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrC
response= md5( md5(username:realm:password):nonce:md5(public_method:url) ); response= md5( md5(username:realm:password):nonce:md5(public_method:url) );
*/ */
string encrypted_pwd = (*this)[Client::kRtspPwd]; string encrypted_pwd = (*this)[Client::kRtspPwd];
if(!(*this)[Client::kRtspPwdIsMD5].as<bool>()){ if (!(*this)[Client::kRtspPwdIsMD5].as<bool>()) {
encrypted_pwd = MD5((*this)[Client::kRtspUser] + ":" + _realm + ":" + encrypted_pwd).hexdigest(); encrypted_pwd = MD5((*this)[Client::kRtspUser] + ":" + _realm + ":" + encrypted_pwd).hexdigest();
} }
auto response = MD5(encrypted_pwd + ":" + _md5_nonce + ":" + MD5(cmd + ":" + url).hexdigest()).hexdigest(); auto response = MD5(encrypted_pwd + ":" + _md5_nonce + ":" + MD5(cmd + ":" + url).hexdigest()).hexdigest();
@ -610,13 +610,11 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrC
printer << "nonce=\"" << _md5_nonce << "\", "; printer << "nonce=\"" << _md5_nonce << "\", ";
printer << "uri=\"" << url << "\", "; printer << "uri=\"" << url << "\", ";
printer << "response=\"" << response << "\""; printer << "response=\"" << response << "\"";
header.emplace("Authorization",printer); header.emplace("Authorization", printer);
}else if(!(*this)[Client::kRtspPwdIsMD5].as<bool>()){ } else if (!(*this)[Client::kRtspPwdIsMD5].as<bool>()) {
//base64认证 // base64认证
string authStr = StrPrinter << (*this)[Client::kRtspUser] << ":" << (*this)[Client::kRtspPwd]; auto authStrBase64 = encodeBase64((*this)[Client::kRtspUser] + ":" + (*this)[Client::kRtspPwd]);
char authStrBase64[1024] = {0}; header.emplace("Authorization", StrPrinter << "Basic " << authStrBase64);
av_base64_encode(authStrBase64, sizeof(authStrBase64), (uint8_t *) authStr.data(), (int) authStr.size());
header.emplace("Authorization",StrPrinter << "Basic " << authStrBase64 );
} }
} }

View File

@ -537,10 +537,8 @@ void RtspPusher::sendRtspRequest(const string &cmd, const string &url,const StrC
printer << "response=\"" << response << "\""; printer << "response=\"" << response << "\"";
header.emplace("Authorization", printer); header.emplace("Authorization", printer);
} else if (!(*this)[Client::kRtspPwdIsMD5].as<bool>()) { } else if (!(*this)[Client::kRtspPwdIsMD5].as<bool>()) {
//base64认证 // base64认证
string authStr = StrPrinter << (*this)[Client::kRtspUser] << ":" << (*this)[Client::kRtspPwd]; auto authStrBase64 = encodeBase64((*this)[Client::kRtspUser] + ":" + (*this)[Client::kRtspPwd]);
char authStrBase64[1024] = {0};
av_base64_encode(authStrBase64, sizeof(authStrBase64), (uint8_t *) authStr.data(), (int)authStr.size());
header.emplace("Authorization", StrPrinter << "Basic " << authStrBase64); header.emplace("Authorization", StrPrinter << "Basic " << authStrBase64);
} }
} }

View File

@ -448,31 +448,26 @@ void RtspSession::onAuthSuccess() {
} }
void RtspSession::onAuthFailed(const string &realm,const string &why,bool close) { void RtspSession::onAuthFailed(const string &realm,const string &why,bool close) {
GET_CONFIG(bool,authBasic,Rtsp::kAuthBasic); GET_CONFIG(bool, authBasic, Rtsp::kAuthBasic);
if (!authBasic) { if (!authBasic) {
//我们需要客户端优先以md5方式认证 // 我们需要客户端优先以md5方式认证
_auth_nonce = makeRandStr(32); _auth_nonce = makeRandStr(32);
sendRtspResponse("401 Unauthorized", sendRtspResponse("401 Unauthorized", { "WWW-Authenticate", StrPrinter << "Digest realm=\"" << realm << "\",nonce=\"" << _auth_nonce << "\"" });
{"WWW-Authenticate", } else {
StrPrinter << "Digest realm=\"" << realm << "\",nonce=\"" << _auth_nonce << "\"" }); // 当然我们也支持base64认证,但是我们不建议这样做
}else { sendRtspResponse("401 Unauthorized", { "WWW-Authenticate", StrPrinter << "Basic realm=\"" << realm << "\"" });
//当然我们也支持base64认证,但是我们不建议这样做
sendRtspResponse("401 Unauthorized",
{"WWW-Authenticate",
StrPrinter << "Basic realm=\"" << realm << "\"" });
} }
if(close){ if (close) {
shutdown(SockException(Err_shutdown,StrPrinter << "401 Unauthorized:" << why)); shutdown(SockException(Err_shutdown, StrPrinter << "401 Unauthorized:" << why));
} }
} }
void RtspSession::onAuthBasic(const string &realm,const string &auth_base64){ void RtspSession::onAuthBasic(const string &realm, const string &auth_base64) {
//base64认证 //base64认证
char user_pwd_buf[512]; auto user_passwd = decodeBase64(auth_base64);
av_base64_decode((uint8_t *) user_pwd_buf, auth_base64.data(), (int)auth_base64.size()); auto user_pwd_vec = split(user_passwd, ":");
auto user_pwd_vec = split(user_pwd_buf, ":");
if (user_pwd_vec.size() < 2) { if (user_pwd_vec.size() < 2) {
//认证信息格式不合法回复401 Unauthorized // 认证信息格式不合法回复401 Unauthorized
onAuthFailed(realm, "can not find user and passwd when basic64 auth"); onAuthFailed(realm, "can not find user and passwd when basic64 auth");
return; return;
} }