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

📄 helper.cxx

📁 一个著名的SIP协议栈
💻 CXX
📖 第 1 页 / 共 5 页
字号:
         {
            return make_pair(BadlyFormed,username);
         }
      }
      return make_pair(BadlyFormed,username);
   }
   DebugLog (<< "No authentication headers. Failing request.");
   return make_pair(Failed,username);
}

// !jf! note that this only authenticates a ProxyAuthenticate header, need to
// add support for WWWAuthenticate as well!!
Helper::AuthResult
Helper::authenticateRequest(const SipMessage& request, 
                            const Data& realm,
                            const Data& password,
                            int expiresDelta)
{
   DebugLog(<< "Authenticating: realm=" << realm << " expires=" << expiresDelta);
   //DebugLog(<< request);
   
   if (request.exists(h_ProxyAuthorizations))
   {
      const ParserContainer<Auth>& auths = request.header(h_ProxyAuthorizations);
      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 BadlyFormed;
            }
            const char* anchor = pb.position();
            pb.skipToChar(Symbols::COLON[0]);

            if (pb.eof())
            {
               DebugLog(<< "Invalid nonce; expected timestamp terminator.");
               return BadlyFormed;
            }

            Data then;
            pb.data(then, anchor); */
 
            NonceHelper::Nonce x_nonce = getNonceHelper()->parseNonce(i->param(p_nonce));
            if(x_nonce.getCreationTime() == 0)
               return BadlyFormed;


            if (expiresDelta > 0)
            {
               UInt64 now = Timer::getTimeMs()/1000;
               if (x_nonce.getCreationTime() + expiresDelta < now)
               {
                  DebugLog(<< "Nonce has expired.");
                  return Expired;
               }
            }

   	        Data then(x_nonce.getCreationTime());
            if (i->param(p_nonce) != makeNonce(request, then))
            {
               InfoLog(<< "Not my nonce.");
               return Failed;
            }
         
            InfoLog (<< " username=" << (i->param(p_username))
                     << " password=" << password
                     << " realm=" << realm
                     << " method=" << getMethodName(request.header(h_RequestLine).getMethod())
                     << " uri=" << i->param(p_uri)
                     << " nonce=" << i->param(p_nonce));
            
            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) == makeResponseMD5(i->param(p_username), 
                                                               password,
                                                               realm, 
                                                               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())
                     {
                        return Authenticated;
                     }
                     else
                     {
                        return Failed;
                     }
                  }
               }
               else
               {
                  InfoLog (<< "Unsupported qop=" << i->param(p_qop));
                  return Failed;
               }
            }
            else if(i->exists(p_uri))
            {
            
               if (i->param(p_response) == makeResponseMD5(i->param(p_username), 
                                                               password,
                                                               realm, 
                                                               getMethodName(request.header(h_RequestLine).getMethod()),
                                                               i->param(p_uri),
                                                               i->param(p_nonce)))
               {
                  return Authenticated;
               }
               else
               {
                  return Failed;
               }
            }
         }
         else
         {
            return BadlyFormed;
         }
      }
      return BadlyFormed;
   }
   DebugLog (<< "No authentication headers. Failing request.");
   return Failed;
}

Helper::AuthResult
Helper::authenticateRequestWithA1(const SipMessage& request, 
                                  const Data& realm,
                                  const Data& hA1,
                                  int expiresDelta)
{
   DebugLog(<< "Authenticating with HA1: realm=" << realm << " expires=" << expiresDelta);
   //DebugLog(<< request);
   
   if (request.exists(h_ProxyAuthorizations))
   {
      const ParserContainer<Auth>& auths = request.header(h_ProxyAuthorizations);
      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 BadlyFormed;
            }
            const char* anchor = pb.position();
            pb.skipToChar(Symbols::COLON[0]);

            if (pb.eof())
            {
               DebugLog(<< "Invalid nonce; expected timestamp terminator.");
               return BadlyFormed;
            }

            Data then;
            pb.data(then, anchor); */
            NonceHelper::Nonce x_nonce = getNonceHelper()->parseNonce(i->param(p_nonce));
            if(x_nonce.getCreationTime() == 0)
               return BadlyFormed;


            if (expiresDelta > 0)
            {
               UInt64 now = Timer::getTimeMs()/1000;
               if (x_nonce.getCreationTime() + expiresDelta < now)
               {
                  DebugLog(<< "Nonce has expired.");
                  return Expired;
               }
            }

	        Data then(x_nonce.getCreationTime());
            if (i->param(p_nonce) != makeNonce(request, then))
            {
               InfoLog(<< "Not my nonce.");
               return Failed;
            }
         
            InfoLog (<< " username=" << (i->param(p_username))
                     << " H(A1)=" << hA1
                     << " realm=" << realm
                     << " method=" << getMethodName(request.header(h_RequestLine).getMethod())
                     << " uri=" << i->param(p_uri)
                     << " nonce=" << i->param(p_nonce));
            
            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(hA1, 
                                                                     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()))
                     {
                        return Authenticated;
                     }
                     else
                     {
                        return Failed;
                     }
                  }
               }
               else
               {
                  InfoLog (<< "Unsupported qop=" << i->param(p_qop));
                  return Failed;
               }
            }
            else if(i->exists(p_uri))
            {
               if (i->param(p_response) == makeResponseMD5WithA1(hA1,
                                                                     getMethodName(request.header(h_RequestLine).getMethod()),
                                                                     i->param(p_uri),
                                                                     i->param(p_nonce)))
               {
                  return Authenticated;
               }
               else
               {
                  return Failed;
               }
            }
         }
         else
         {
            return BadlyFormed;
         }
      }
      return BadlyFormed;
   }
   DebugLog (<< "No authentication headers. Failing request.");
   return Failed;
}

SipMessage*
Helper::make405(const SipMessage& request,
                const int* allowedMethods,
                int len )
{
    SipMessage* resp = Helper::makeResponse(request, 405);

    if (len < 0)
    {
        int upperBound = static_cast<int>(MAX_METHODS);

        // The UNKNOWN method name is the first in the enum
        for (int i = 1 ; i < upperBound; i ++)
        {
            int last = 0;

            // ENUMS must be contiguous in order for this to work.
            assert( i - last <= 1);
            Token t;
            t.value() = getMethodName(static_cast<resip::MethodTypes>(i));
            resp->header(h_Allows).push_back(t);
            last = i;
        }
    }
    else
    {
        // use user's list
        for ( int i = 0 ; i < len ; i++)
        {
            Token t;
            t.value() = getMethodName(static_cast<resip::MethodTypes>(allowedMethods[i]));
            resp->header(h_Allows).push_back(t);
        }
    }
    return resp;
}


SipMessage*
Helper::makeProxyChallenge(const SipMessage& request, const Data& realm, bool useAuth, bool stale)
{
   return makeChallenge(request, realm, useAuth, stale, true);
}

SipMessage*
Helper::makeChallenge(const SipMessage& request, const Data& realm, bool useAuth, bool stale, bool proxy)
{
   Auth auth;
   auth.scheme() = "Digest";
   Data timestamp(Timer::getTimeMs()/1000);
   auth.param(p_nonce) = makeNonce(request, timestamp);
   auth.param(p_algorithm) = "MD5";
   auth.param(p_realm) = realm;
   if (useAuth)
   {
      auth.param(p_qopOptions) = "auth,auth-int";
   }
   if (stale)
   {
      auth.param(p_stale) = "true";
   }
   SipMessage *response;
   if(proxy)
   {
      response = Helper::makeResponse(request, 407);
      response->header(h_ProxyAuthenticates).push_back(auth);
   }
   else
   {
      response = Helper::makeResponse(request, 401);
      response->header(h_WWWAuthenticates).push_back(auth);
   }
   return response;
}

void updateNonceCount(unsigned int& nonceCount, Data& nonceCountString)
{
   if (!nonceCountString.empty())
   {
      return;
   }
   nonceCount++;
   {
      DataStream s(nonceCountString);
      
      s << std::setw(8) << std::setfill('0') << std::hex << nonceCount;
   }
   DebugLog(<< "nonceCount is now: [" << nonceCountString << "]");
}


Auth 
Helper::makeChallengeResponseAuth(SipMessage& request,
                                  const Data& username,
                                  const Data& password,
                                  const Auth& challenge,
                                  const Data& cnonce,
                                  unsigned int& nonceCount,
                                  Data& nonceCountString)
{
   Auth auth;
   auth.scheme() = "Digest";
   auth.param(p_username) = username;
   assert(challenge.exists(p_realm));
   auth.param(p_realm) = challenge.param(p_realm);
   assert(challenge.exists(p_nonce));
   auth.param(p_nonce) = challenge.param(p_nonce);
   Data digestUri;
   {
      DataStream s(digestUri);
      //s << request.header(h_RequestLine).uri().host(); // wrong 
      s << request.header(h_RequestLine).uri(); // right 
   }
   auth.param(p_uri) = digestUri;

   Data authQop = qopOption(challenge);
   if (!authQop.empty())
   {
      updateNonceCount(nonceCount, nonceCountString);
      auth.param(p_response) = Helper::makeResponseMD5(username, 
                                                       password,
                                                       challenge.param(p_realm), 
                                                       getMethodName(request.header(h_RequestLine).getMethod()), 
                                                       digestUri, 
                                                       challenge.param(p_nonce),
                                                       authQop,
                                                       cnonce,
                                                       nonceCountString,
                                                       request.getContents());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -