📄 helper.cxx
字号:
else { response.setFromExternal(); } if (reason.size()) { response.header(h_StatusLine).reason() = reason; } else { getResponseCodeReason(responseCode, response.header(h_StatusLine).reason()); }}SipMessage*Helper::makeResponse(const SipMessage& request, int responseCode, const NameAddr& myContact, 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); // in general, this should not create a Contact header since only requests // that create a dialog (or REGISTER requests) should produce a response with // a contact(s). response->header(h_Contacts).clear(); response->header(h_Contacts).push_back(myContact); return response.release();}SipMessage*Helper::makeResponse(const SipMessage& request, 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_MaxForwards).value() = 70; 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_MaxForwards).value() = 70; 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;}DataHelper::computeCallId(){ static Data hostname = DnsUtil::getLocalHostName(); Data hostAndSalt(hostname + Random::getRandomHex(16));#ifndef USE_SSL // .bwc. None of this is neccessary if we're using openssl#if defined(__linux__) || defined(__APPLE__) pid_t pid = getpid(); hostAndSalt.append((char*)&pid,sizeof(pid));#endif#ifdef __APPLE__ pthread_t thread = pthread_self(); hostAndSalt.append((char*)&thread,sizeof(thread));#endif#ifdef WIN32 DWORD proccessId = ::GetCurrentProcessId(); DWORD threadId = ::GetCurrentThreadId(); hostAndSalt.append((char*)&proccessId,sizeof(proccessId)); hostAndSalt.append((char*)&threadId,sizeof(threadId));#endif#endif // of USE_SSL return hostAndSalt.md5().base64encode(true);}DataHelper::computeTag(int numBytes){ return Random::getRandomHex(numBytes);}voidHelper::setNonceHelper(NonceHelper *nonceHelper){ mNonceHelperPtr.mNonceHelper = nonceHelper;}NonceHelper* Helper::getNonceHelper(){ if (mNonceHelperPtr.mNonceHelper == 0) { mNonceHelperPtr.mNonceHelper = new BasicNonceHelper(); } return mNonceHelperPtr.mNonceHelper;}DataHelper::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.1Data 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; 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::getTimeSecs(); 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(BadlyFormed,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); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -