b/f: add authentication header to in-dialog requests

sayer/1.4-spce2.6
Stefan Sayer 15 years ago
parent 7d02db22c3
commit 88194bfaab

@ -42,6 +42,8 @@ using std::string;
#define SIP_FLAGS_VERBATIM 1 // send request verbatim,
// i.e. modify as little as possible
#define SIP_FLAGS_NOAUTH 1<<1 // don't add authentication header
class AmSipTimeoutEvent;
/** \brief SIP transaction representation */

@ -149,10 +149,10 @@ bool UACAuth::onSipReply(const AmSipReply& reply, int old_dlg_status, const stri
getHeader(reply.hdrs, SIP_HDR_PROXY_AUTHENTICATE, true) :
getHeader(reply.hdrs, SIP_HDR_WWW_AUTHENTICATE, true);
string result;
string auth_uri;
auth_uri = dlg->remote_uri;
if (do_auth(reply.code, auth_hdr,
ri->second.method,
auth_uri, ri->second.body, result)) {
@ -187,7 +187,7 @@ bool UACAuth::onSipReply(const AmSipReply& reply, int old_dlg_status, const stri
if (dlg->sendRequest(ri->second.method,
ri->second.content_type,
ri->second.body,
hdrs, SIP_FLAGS_VERBATIM) == 0) {
hdrs, SIP_FLAGS_VERBATIM | SIP_FLAGS_NOAUTH) == 0) {
processed = true;
DBG("authenticated request successfully sent.\n");
// undo SIP dialog status change
@ -213,6 +213,20 @@ bool UACAuth::onSendRequest(const string& method,
int flags,
unsigned int cseq)
{
// add authentication header if nonce is already there
string result;
if (!(flags & SIP_FLAGS_NOAUTH) &&
!challenge.nonce.empty() &&
do_auth(challenge, challenge_code,
method,
dlg->remote_uri, body, result)) {
// add headers
if (hdrs == "\r\n" || hdrs == "\r" || hdrs == "\n")
hdrs = result;
else
hdrs += result;
}
DBG("adding %d to list of sent requests.\n", cseq);
sent_requests[cseq] = SIPRequestInfo(method,
content_type,
@ -279,20 +293,30 @@ bool UACAuth::parse_header(const string& auth_hdr, UACAuthDigestChallenge& chall
}
bool UACAuth::do_auth(const unsigned int code, const string& auth_hdr,
const string& method, const string& uri,
const string& body, string& result)
const string& method, const string& uri,
const string& body, string& result)
{
if (!auth_hdr.length()) {
ERROR("empty auth header.\n");
return false;
}
UACAuthDigestChallenge challenge;
if (!parse_header(auth_hdr, challenge)) {
ERROR("error parsing auth header '%s'\n", auth_hdr.c_str());
return false;
}
challenge_code = code;
return do_auth(challenge, code, method, uri, body, result);
}
bool UACAuth::do_auth(const UACAuthDigestChallenge& challenge,
const unsigned int code,
const string& method, const string& uri,
const string& body, string& result)
{
if ((challenge.algorithm.length()) && (challenge.algorithm != "MD5")) {
DBG("unsupported algorithm: '%s'\n", challenge.algorithm.c_str());
return false;
@ -404,7 +428,7 @@ static inline void cvt_hex(HASH bin, HASHHEX hex)
/*
* calculate H(A1)
*/
void UACAuth::uac_calc_HA1(UACAuthDigestChallenge& challenge,
void UACAuth::uac_calc_HA1(const UACAuthDigestChallenge& challenge,
string cnonce,
HASHHEX sess_key)
{
@ -439,7 +463,7 @@ void UACAuth::uac_calc_HA1(UACAuthDigestChallenge& challenge,
* calculate H(A2)
*/
void UACAuth::uac_calc_HA2( const string& method, const string& uri,
UACAuthDigestChallenge& challenge,
const UACAuthDigestChallenge& challenge,
HASHHEX hentity,
HASHHEX HA2Hex )
{
@ -480,9 +504,9 @@ void UACAuth::uac_calc_hentity( const string& body, HASHHEX hentity )
/*
* calculate request-digest/response-digest as per HTTP Digest spec
*/
void UACAuth::uac_calc_response( HASHHEX ha1, HASHHEX ha2,
UACAuthDigestChallenge& challenge, const string& cnonce,
const string& qop_value, HASHHEX response)
void UACAuth::uac_calc_response(HASHHEX ha1, HASHHEX ha2,
const UACAuthDigestChallenge& challenge, const string& cnonce,
const string& qop_value, HASHHEX response)
{
unsigned char hc[1]; hc[0]=':';
MD5_CTX Md5Ctx;

@ -105,35 +105,47 @@ class UACAuth : public AmSessionEventHandler
UACAuthCred* credential;
AmSipDialog* dlg;
UACAuthDigestChallenge challenge;
unsigned int challenge_code;
string nonce; // last nonce received from server
unsigned int nonce_count;
std::string find_attribute(const std::string& name, const std::string& header);
bool parse_header(const std::string& auth_hdr, UACAuthDigestChallenge& challenge);
void uac_calc_HA1(UACAuthDigestChallenge& challenge,
void uac_calc_HA1(const UACAuthDigestChallenge& challenge,
std::string cnonce,
HASHHEX sess_key);
void uac_calc_HA2( const std::string& method, const std::string& uri,
UACAuthDigestChallenge& challenge,
const UACAuthDigestChallenge& challenge,
HASHHEX hentity,
HASHHEX HA2Hex );
void uac_calc_hentity( const std::string& body, HASHHEX hentity );
void uac_calc_response( HASHHEX ha1, HASHHEX ha2,
UACAuthDigestChallenge& challenge,
const UACAuthDigestChallenge& challenge,
const std::string& cnonce, const string& qop_value,
HASHHEX response);
/**
* do auth on cmd with nonce in auth_hdr if possible
* @return true if successful
/**
* do auth on cmd with nonce in auth_hdr if possible
* @return true if successful
*/
bool do_auth(const unsigned int code, const string& auth_hdr,
const string& method, const string& uri,
const string& body, string& result);
/**
* do auth on cmd with saved challenge
* @return true if successful
*/
bool do_auth(const UACAuthDigestChallenge& challenge,
const unsigned int code,
const string& method, const string& uri,
const string& body, string& result);
public:

Loading…
Cancel
Save