resiprocate 之repro注册

repro为resiprocate 提供的代理服务,可以直接运行,我们可以参考他,来实现自己的sip服务,下面分析一下repro关于digest流程的处理。

找到工程reprolib的ReproServerAuthManager 类,处理digest认证再此类完成。

首先进入,这里返回true 表示digest 认证

ServerAuthManager::AsyncBool
ReproServerAuthManager::requiresChallenge(const SipMessage& msg)
{
   resip_assert(msg.isRequest());
   if(!mAclDb.isRequestTrusted(msg))
   {
      return ServerAuthManager::requiresChallenge(msg);
   }
   else
   {
      return False;
   }
}

然后进入requestCredential函数

void 
ReproServerAuthManager::requestCredential(const Data& user, 
                                          const Data& realm, 
                                          const SipMessage& msg,
                                          const Auth& auth,
                                          const Data& transactionId )
{
   // Build a UserAuthInfo object and pass to UserAuthGrabber to have a1 password filled in
   UserAuthInfo* async = new UserAuthInfo(user,realm,transactionId,&mDum);
   std::auto_ptr app(async);
   mAuthRequestDispatcher->post(app);
}

这个函数的作用是获取A1值,A1说明如下

 

采用MD5算法:
    A1=(user):(realm):(password)

我们自己开发服务的时候,可以直接在这里获取A1的值,反馈给dum,

repro 在UserAuthGrabber::process函数获取A1的值,其实就是从数据库里面把A1的值拿出来。

UserAuthGrabber::process(resip::ApplicationMessage* msg)
{
   repro::UserInfoMessage* uinf = dynamic_cast(msg);    // auth for repro's DigestAuthenticator
   if (uinf)
   {
      uinf->mRec.passwordHash = mUserStore.getUserAuthInfo(uinf->user(), uinf->realm());
      uinf->setMode(resip::UserAuthInfo::RetrievedA1);
      DebugLog(<< "Grabbed user info for " << uinf->user() << "@" << uinf->realm() << " : " << uinf->A1());
      return true;
   }

   resip::UserAuthInfo* uainf = dynamic_cast(msg);  // auth for DUM's ServerAuthManager
   if (uainf)
   {
      uainf->setA1(mUserStore.getUserAuthInfo(uainf->getUser(), uainf->getRealm()));
      if (uainf->getA1().empty())
      {
         uainf->setMode(resip::UserAuthInfo::UserUnknown);
      }
      DebugLog(<< "Grabbed user info for " << uainf->getUser() << "@" << uainf->getRealm() << " : " << uainf->getA1());
      return true;
   }

   repro::PresenceUserExists* pue = dynamic_cast(msg);  // user exists query for Presence server
   if (pue)
   {
      pue->setUserExists(!mUserStore.getUserInfo(UserStore::buildKey(pue->getUser(), pue->getDomain())).user.empty());
      DebugLog(<< "Checking existence for " << pue->getUser() << "@" << pue->getDomain() << " : user " << (pue->getUserExists() ? "exists" : "does not exist"));
      return true;
   }

   WarningLog(<< "Did not recognize message type...");
   return false;
}

获取A1值之后调用

mStack->post

投递给协议栈,即可完成注册流程的服务端开发。

queueToStack = mWorker->process(msg);

            if(queueToStack && mStack)
            {
               StackLog(<<"async work done, posting to stack");
               // Post to stack instead of directly to TU, since stack does
               // some safety checks to ensure the TU still exists before posting
               mStack->post(std::auto_ptr(msg));
            }


****************-------我是风格线--------****************************

 

用海康摄像机,测试注册功能,如下图,发现一个大问题,当sip用户名和sip用户认证ID填写一样时,可以认证通过

 

但是当这两者不一样时,认证失败,抓包显示未知用户。

resiprocate 之repro注册_第1张图片

通过阅读源码,发现在校验结束后,还校验了from字段的用户名和认证用户名是否一样,强制修改为return true后,认证通过。

为什么一定要from字段的用户名和认证用户名一样呢?不得而知。

bool
ServerAuthManager::authorizedForThisIdentity(const resip::Data &user, 
                                               const resip::Data &realm, 
                                                resip::Uri &fromUri)
{
   // !rwm! good enough for now.  TODO eventually consult a database to see what
   // combinations of user/realm combos are authorized for an identity

   // First try the form where the username parameter in the auth
   // header is just the username component of the fromUri
   //
   if ((fromUri.user() == user) && (fromUri.host() == realm))
      return true;

   // Now try the form where the username parameter in the auth
   // header is the full fromUri, e.g.
   //    Proxy-Authorization: Digest username="user@domain" ...
   //
   if (fromUri.getAorNoPort() == user)
      return true;

   // catch-all: access denied
   return true;
}

附上抓包截图

resiprocate 之repro注册_第2张图片

 

*****************************************resip注册处理流程******************************************

今天遇到了sip注册发生了405的错误

查明原因,注册管理,需要设置RegistrationPersistenceManager类,由于我没有设置,所以返回405失败。

resiprocate 之repro注册_第3张图片

增加RegistrationPersistenceManager属性

	InMemorySyncRegDb* pRegDB = new InMemorySyncRegDb(0);
	mDum->setRegistrationPersistenceManager(pRegDB);

另外发现一个调试的好方法:找到错误码的对应类,打上断点,基本上就可以处理基本的错误。

resiprocate 之repro注册_第4张图片

 

 

你可能感兴趣的:(GB28181)