コード例 #1
0
void SipImpliedSubscriptions::authenticate( const SipMessage& registerMessage
                                           ,SipMessage& subscribeRequest
                                           ,UtlString&  callId
                                           ,UtlString&  fromTag
                                           ,UtlString&  fromUri
                                           )
{
   // Construct authentication that the status server will accept
   // We need the user credentials, and a signed nonce like the one
   //    the status server would have generated to challenge this phone.
   UtlString user;
   UtlString realm;
   UtlString registrationNonce;
   UtlString opaque;
   UtlString response;
   UtlString authUri;

   // extract the identity from the authorization of the registration
   if ( registerMessage.getDigestAuthorizationData( &user, &realm       // the identity
                                                   ,NULL // request nonce not used
                                                   ,&opaque // passed through to aid debugging
                                                   ,NULL, NULL // response & authUri not used
                                                   ,HttpMessage::SERVER, 0
                                                   )
       )
   {
      Url subscribeUser;
      UtlString passToken;
      UtlString authType;

      if (CredentialDB::getInstance()->getCredential( user, realm, subscribeUser
                                                     ,passToken, authType
                                                     )
          )
      {
         // Construct a nonce
         UtlString serverNonce;
         UtlString clientNonce;
         SipNonceDb* nonceDb = SharedNonceDb::get();

         nonceDb->createNewNonce( callId, fromTag, realm ,serverNonce );

         // generate a client nonce - doesn't matter what it is, really
         //   because the server doesn't validate this one;
         //   but change an input so that the two won't be the same
         //              UtlString dummyFromTag("different value");
         //              mRegistrarNonceDb.createNewNonce( callId, dummyFromTag, fromUri
         //                                               ,clientNonce
         //                               );

         // Sign the message
         UtlString responseHash;
         HttpMessage::buildMd5Digest(passToken.data(),
                                     HTTP_MD5_ALGORITHM,
                                     serverNonce.data(),
                                     NULL, // client nonce
                                     1, // nonce count
                                     "",
                                     SIP_SUBSCRIBE_METHOD,
                                     fromUri.data(),
                                     NULL,
                                     &responseHash
                                     );

         subscribeRequest.removeHeader( HTTP_AUTHORIZATION_FIELD, 0);
         subscribeRequest.setDigestAuthorizationData(user.data(),
                                                     realm.data(),
                                                     serverNonce.data(),
                                                     fromUri.data(),
                                                     responseHash.data(),
                                                     HTTP_MD5_ALGORITHM,
                                                     NULL,//clientNonce.data(),
                                                     opaque.data(),
                                                     HTTP_QOP_AUTH,
                                                     1, // nonce count
                                                     HttpMessage::SERVER
                                                     );

      }
      else
      {
         OsSysLog::add( FAC_SIP, PRI_WARNING,
                       "%s implied subscription request not authenticated:\n"
                       "   no credentials found for \"%s\"",
                       mLogName.data(), user.data());
      }
   }
   else
   {
      OsSysLog::add( FAC_SIP, PRI_WARNING,
                    "%s implied subscription request not authenticated:\n"
                    "   no credentials in registration",
                    mLogName.data()
                    );
   }
}
コード例 #2
0
void SipImpliedSubscriptions::addAuthorization( const SipMessage& registerMessage
                                                ,SipMessage& subscribeRequest
                                                ,UtlString&  callId
                                                ,UtlString&  fromTag
                                                ,UtlString&  fromUri
                                                )
{
   // Construct authentication that the status server will accept
   // We need the user credentials, and a signed nonce like the one
   //    the status server would have generated to challenge this phone.
   UtlString user;
   UtlString userBase;
   UtlString realm;
   UtlString registrationNonce;
   UtlString opaque;
   UtlString response;
   UtlString authUri;
   UtlString qop;
   UtlString qopType;

   // Did Register have Authorization header?
   UtlBoolean registerHasAuth = registerMessage.getDigestAuthorizationData( &user, 
                                                                            &realm       // the identity
                                                                            ,NULL // request nonce not used
                                                                            ,&opaque // passed through to aid debugging
                                                                            ,NULL, NULL // response & authUri not used
                                                                            ,NULL  // cnonce not used
                                                                            ,NULL  // nonceCount not used
                                                                            ,&qop  // what kind of Auth?
                                                                            ,HttpMessage::SERVER, 0
                                                                            ,&userBase);
   // We only support no qop or with qop="auth"
   HttpMessage::AuthQopValues qopValue = registerMessage.parseQopValue(&qop, qopType);

   if( registerHasAuth && qopValue < HttpMessage::AUTH_QOP_NOT_SUPPORTED)
   {
      Url subscribeUser;
      UtlString passToken;
      UtlString authType;

      if (dataStore().entityDB().getCredential( userBase, realm, subscribeUser
                                                     ,passToken, authType))
      {
         // Construct a nonce
         UtlString serverNonce;
         UtlString clientNonce;
         UtlString cnonce;
         UtlString nonceCount;

         SipNonceDb* nonceDb = SharedNonceDb::get();

         nonceDb->createNewNonce( callId, fromTag, realm ,serverNonce );

         // Add support for "qop=auth" if requested (eg. cnonce, nonce-count)
         if (qopValue == HttpMessage::AUTH_QOP_HAS_AUTH)
         {
             // Use a random number, anything more adds no value
             UtlString cnonce;
             CallId::getNewTag( cnonce );

             // We always generate a new nonce, so it's ok to have fixed nonce count
             nonceCount.append("00000001");

         }

         // Construct A1
         UtlString a1Buffer;
         UtlString encodedA1;
         a1Buffer.append(user);
         a1Buffer.append(':');
         a1Buffer.append(realm);
         a1Buffer.append(':');
         a1Buffer.append(passToken);
         NetMd5Codec::encode(a1Buffer.data(), encodedA1);

         // Sign the message
         UtlString responseHash;
         HttpMessage::buildMd5Digest(encodedA1.data(),
                                     HTTP_MD5_ALGORITHM,
                                     serverNonce.data(),
                                     cnonce.data(), // client nonce
                                     nonceCount.data(),
                                     qopType.data(), 
                                     SIP_SUBSCRIBE_METHOD,
                                     fromUri.data(),
                                     NULL,
                                     &responseHash
                                     );

         subscribeRequest.removeHeader( HTTP_AUTHORIZATION_FIELD, 0);

         subscribeRequest.setDigestAuthorizationData(user.data(),
                                                     realm.data(),
                                                     serverNonce.data(),
                                                     fromUri.data(),
                                                     responseHash.data(),
                                                     HTTP_MD5_ALGORITHM,
                                                     cnonce.data(),
                                                     opaque.data(),
                                                     qopType.data(),
                                                     nonceCount.data(), 
                                                     HttpMessage::SERVER
                                                     );

      }
      else
      {
         Os::Logger::instance().log( FAC_SIP, PRI_WARNING,
                       "%s implied subscription request not authenticated:\n"
                       "   no credentials found for \"%s\"",
                       mLogName.data(), userBase.data());
      }
   }
   else
   {
      Os::Logger::instance().log( FAC_SIP, PRI_WARNING,
                    "%s implied subscription request not authenticated:\n"
                    "   no credentials in registration",
                    mLogName.data()
                    );
   }
}