⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 helper.cxx

📁 一个著名的SIP协议栈
💻 CXX
📖 第 1 页 / 共 5 页
字号:
                     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 + -