📄 helper.cxx
字号:
int responseCode,
const Data& reason,
const Data& hostname,
const Data& warning)
{
// !bwc! Exception safety. Catch/rethrow is dicey because we can't rethrow
// resip::BaseException, since it is abstract.
std::auto_ptr<SipMessage> response(new SipMessage);
makeResponse(*response, request, responseCode, reason, hostname, warning);
return response.release();
}
void
Helper::getResponseCodeReason(int responseCode, Data& reason)
{
switch (responseCode)
{
case 100: reason = "Trying"; break;
case 180: reason = "Ringing"; break;
case 181: reason = "Call Is Being Forwarded"; break;
case 182: reason = "Queued"; break;
case 183: reason = "Session Progress"; break;
case 200: reason = "OK"; break;
case 202: reason = "Accepted"; break;
case 300: reason = "Multiple Choices"; break;
case 301: reason = "Moved Permanently"; break;
case 302: reason = "Moved Temporarily"; break;
case 305: reason = "Use Proxy"; break;
case 380: reason = "Alternative Service"; break;
case 400: reason = "Bad Request"; break;
case 401: reason = "Unauthorized"; break;
case 402: reason = "Payment Required"; break;
case 403: reason = "Forbidden"; break;
case 404: reason = "Not Found"; break;
case 405: reason = "Method Not Allowed"; break;
case 406: reason = "Not Acceptable"; break;
case 407: reason = "Proxy Authentication Required"; break;
case 408: reason = "Request Timeout"; break;
case 410: reason = "Gone"; break;
case 412: reason = "Precondition Failed"; break;
case 413: reason = "Request Entity Too Large"; break;
case 414: reason = "Request-URI Too Long"; break;
case 415: reason = "Unsupported Media Type"; break;
case 416: reason = "Unsupported URI Scheme"; break;
case 420: reason = "Bad Extension"; break;
case 421: reason = "Extension Required"; break;
case 422: reason = "Session Interval Too Small"; break;
case 423: reason = "Interval Too Brief"; break;
case 480: reason = "Temporarily Unavailable"; break;
case 481: reason = "Call/Transaction Does Not Exist"; break;
case 482: reason = "Loop Detected"; break;
case 483: reason = "Too Many Hops"; break;
case 484: reason = "Address Incomplete"; break;
case 485: reason = "Ambiguous"; break;
case 486: reason = "Busy Here"; break;
case 487: reason = "Request Terminated"; break;
case 488: reason = "Not Acceptable Here"; break;
case 489: reason = "Event Package Not Supported"; break;
case 491: reason = "Request Pending"; break;
case 493: reason = "Undecipherable"; break;
case 500: reason = "Server Internal Error"; break;
case 501: reason = "Not Implemented"; break;
case 502: reason = "Bad Gateway"; break;
case 503: reason = "Service Unavailable"; break;
case 504: reason = "Server Time-out"; break;
case 505: reason = "Version Not Supported"; break;
case 513: reason = "Message Too Large"; break;
case 600: reason = "Busy Everywhere"; break;
case 603: reason = "Decline"; break;
case 604: reason = "Does Not Exist Anywhere"; break;
case 606: reason = "Not Acceptable"; break;
}
}
SipMessage*
Helper::makeCancel(const SipMessage& request)
{
assert(request.isRequest());
assert(request.header(h_RequestLine).getMethod() == INVITE);
SipMessage* cancel = new SipMessage;
RequestLine rLine(CANCEL, request.header(h_RequestLine).getSipVersion());
rLine.uri() = request.header(h_RequestLine).uri();
cancel->header(h_RequestLine) = rLine;
cancel->header(h_To) = request.header(h_To);
cancel->header(h_From) = request.header(h_From);
cancel->header(h_CallId) = request.header(h_CallId);
if (request.exists(h_ProxyAuthorizations))
{
cancel->header(h_ProxyAuthorizations) = request.header(h_ProxyAuthorizations);
}
if (request.exists(h_Authorizations))
{
cancel->header(h_Authorizations) = request.header(h_Authorizations);
}
if (request.exists(h_Routes))
{
cancel->header(h_Routes) = request.header(h_Routes);
}
cancel->header(h_CSeq) = request.header(h_CSeq);
cancel->header(h_CSeq).method() = CANCEL;
cancel->header(h_Vias).push_back(request.header(h_Vias).front());
return cancel;
}
SipMessage*
Helper::makeFailureAck(const SipMessage& request, const SipMessage& response)
{
assert (request.header(h_Vias).size() >= 1);
assert (request.header(h_RequestLine).getMethod() == INVITE);
SipMessage* ack = new SipMessage;
RequestLine rLine(ACK, request.header(h_RequestLine).getSipVersion());
rLine.uri() = request.header(h_RequestLine).uri();
ack->header(h_RequestLine) = rLine;
ack->header(h_CallId) = request.header(h_CallId);
ack->header(h_From) = request.header(h_From);
ack->header(h_To) = response.header(h_To); // to get to-tag
ack->header(h_Vias).push_back(request.header(h_Vias).front());
ack->header(h_CSeq) = request.header(h_CSeq);
ack->header(h_CSeq).method() = ACK;
if (request.exists(h_Routes))
{
ack->header(h_Routes) = request.header(h_Routes);
}
return ack;
}
Data
Helper::computeUniqueBranch()
{
static const Data cookie("z9hG4bK"); // magic cookie per rfc2543bis-09
Data result(16, Data::Preallocate);
result += cookie;
result += Random::getRandomHex(4);
result += "C1";
result += Random::getRandomHex(2);
return result;
}
Data
Helper::computeCallId()
{
static Data hostname = DnsUtil::getLocalHostName();
Data hostAndSalt(hostname + Random::getRandomHex(8));
return hostAndSalt.md5().base64encode(true);
}
Data
Helper::computeTag(int numBytes)
{
return Random::getRandomHex(numBytes);
}
void
Helper::setNonceHelper(NonceHelper *nonceHelper)
{
mNonceHelperPtr.mNonceHelper = nonceHelper;
}
NonceHelper*
Helper::getNonceHelper()
{
if (mNonceHelperPtr.mNonceHelper == 0)
{
mNonceHelperPtr.mNonceHelper = new BasicNonceHelper();
}
return mNonceHelperPtr.mNonceHelper;
}
Data
Helper::makeNonce(const SipMessage& request, const Data& timestamp)
{
return getNonceHelper()->makeNonce(request, timestamp);
}
Data
Helper::makeResponseMD5WithA1(const Data& a1,
const Data& method, const Data& digestUri, const Data& nonce,
const Data& qop, const Data& cnonce, const Data& cnonceCount,
const Contents* entityBody)
{
MD5Stream a2;
a2 << method
<< Symbols::COLON
<< digestUri;
if (qop == Symbols::authInt)
{
if (entityBody)
{
MD5Stream eStream;
eStream << *entityBody;
a2 << Symbols::COLON << eStream.getHex();
}
else
{
static Data noBody = MD5Stream().getHex();
a2 << Symbols::COLON << noBody;
}
}
MD5Stream r;
r << a1
<< Symbols::COLON
<< nonce
<< Symbols::COLON;
if (!qop.empty())
{
r << cnonceCount
<< Symbols::COLON
<< cnonce
<< Symbols::COLON
<< qop
<< Symbols::COLON;
}
r << a2.getHex();
return r.getHex();
}
//RFC 2617 3.2.2.1
Data
Helper::makeResponseMD5(const Data& username, const Data& password, const Data& realm,
const Data& method, const Data& digestUri, const Data& nonce,
const Data& qop, const Data& cnonce, const Data& cnonceCount,
const Contents *entity)
{
MD5Stream a1;
a1 << username
<< Symbols::COLON
<< realm
<< Symbols::COLON
<< password;
//a1.flush(); // .slg. Not needed getHex now calls flush()
return makeResponseMD5WithA1(a1.getHex(), method, digestUri, nonce, qop,
cnonce, cnonceCount, entity);
}
std::pair<Helper::AuthResult,Data>
Helper::advancedAuthenticateRequest(const SipMessage& request,
const Data& realm,
const Data& a1,
int expiresDelta,
bool proxyAuthorization)
{
Data username;
DebugLog(<< "Authenticating: realm=" << realm << " expires=" << expiresDelta);
//DebugLog(<< request);
const ParserContainer<Auth>* auths = 0;
if(proxyAuthorization)
{
if(request.exists(h_ProxyAuthorizations))
{
auths = &request.header(h_ProxyAuthorizations);
}
}
else
{
if(request.exists(h_Authorizations))
{
auths = &request.header(h_Authorizations);
}
}
if (auths)
{
for (ParserContainer<Auth>::const_iterator i = auths->begin(); i != auths->end(); i++)
{
if (i->exists(p_realm) &&
i->exists(p_nonce) &&
i->exists(p_response) &&
i->param(p_realm) == realm)
{
static Data digest("digest");
if(!isEqualNoCase(i->scheme(),digest))
{
DebugLog(<< "Scheme must be Digest");
continue;
}
/* ParseBuffer pb(i->param(p_nonce).data(), i->param(p_nonce).size());
if (!pb.eof() && !isdigit(*pb.position()))
{
DebugLog(<< "Invalid nonce; expected timestamp.");
return make_pair(BadlyFormed,username);
}
const char* anchor = pb.position();
pb.skipToChar(Symbols::COLON[0]);
if (pb.eof())
{
DebugLog(<< "Invalid nonce; expected timestamp terminator.");
return make_pair(BadlyFormed,username);
}
Data then;
pb.data(then, anchor);
if (expiresDelta > 0)
{
unsigned int now = (unsigned int)(Timer::getTimeMs()/1000);
if ((unsigned int)then.convertUInt64() + expiresDelta < now)
{
DebugLog(<< "Nonce has expired.");
return make_pair(Expired,username);
}
} */
NonceHelper::Nonce x_nonce = getNonceHelper()->parseNonce(i->param(p_nonce));
if(x_nonce.getCreationTime() == 0)
return make_pair(BadlyFormed,username);
if (expiresDelta > 0)
{
UInt64 now = Timer::getTimeMs()/1000;
if (x_nonce.getCreationTime() + expiresDelta < now)
{
DebugLog(<< "Nonce has expired.");
return make_pair(Expired,username);
}
}
Data then(x_nonce.getCreationTime());
if (i->param(p_nonce) != makeNonce(request, then))
{
InfoLog(<< "Not my nonce. expected=" << makeNonce(request, then)
<< " received=" << i->param(p_nonce)
<< " then=" << then);
return make_pair(Failed,username);
}
if (i->exists(p_qop))
{
if (i->param(p_qop) == Symbols::auth || i->param(p_qop) == Symbols::authInt)
{
if(i->exists(p_uri) && i->exists(p_cnonce) && i->exists(p_nc))
{
if (i->param(p_response) == makeResponseMD5WithA1(a1,
getMethodName(request.header(h_RequestLine).getMethod()),
i->param(p_uri),
i->param(p_nonce),
i->param(p_qop),
i->param(p_cnonce),
i->param(p_nc),
request.getContents()))
{
if(i->exists(p_username))
{
username = i->param(p_username);
}
return make_pair(Authenticated,username);
}
else
{
return make_pair(Failed,username);
}
}
}
else
{
InfoLog (<< "Unsupported qop=" << i->param(p_qop));
return make_pair(Failed,username);
}
}
else if(i->exists(p_uri))
{
if (i->param(p_response) == makeResponseMD5WithA1(a1,
getMethodName(request.header(h_RequestLine).getMethod()),
i->param(p_uri),
i->param(p_nonce)))
{
if(i->exists(p_username))
{
username = i->param(p_username);
}
return make_pair(Authenticated,username);
}
else
{
return make_pair(Failed,username);
}
}
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -