[asterisk-scf-commits] asterisk-scf/release/sip.git branch "authexten" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Fri Feb 11 17:07:17 CST 2011


branch "authexten" has been updated
       via  6913f102979144b1203fd032d1afffcf7cd8d09c (commit)
       via  5f9e9fd318c13fa5d58c30a6d2ab85d33fe59866 (commit)
       via  7837bf220f03f26090c509f427c003fc00deae76 (commit)
       via  0910249b0079177bd957635dd46286b16e769247 (commit)
      from  fbfa98d635f3cd6737585691cf82b4e65a0f1570 (commit)

Summary of changes:
 src/AuthHelper.cpp         |   27 ++++++++++++++++++----
 src/AuthHelper.h           |    6 ++++-
 src/PJSipModule.cpp        |   24 +++++++++++++++++++
 src/PJSipModule.h          |   24 ++-----------------
 src/PJSipSessionModule.cpp |   54 +++++++++++++++++++++++++++++++++++++++++--
 5 files changed, 105 insertions(+), 30 deletions(-)


- Log -----------------------------------------------------------------
commit 6913f102979144b1203fd032d1afffcf7cd8d09c
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Feb 11 16:24:28 2011 -0600

    Add giant note planning how to save and destroy AuthHelpers.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 07ff5c6..4375c83 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -462,8 +462,56 @@ bool PJSipSessionModule::checkAuth(pjsip_rx_data *rdata, pjsip_inv_session *inv,
             authHelper->addDigests(tdata, digests);
 
             pjsip_inv_send_msg(inv, tdata);
-            //XXX In this case, we need to put the authHelper
-            //somewhere we can retrieve it later.
+
+            // So here's the part that truly sucks about all this. Authentication
+            // is something whose lifetime is not governed by the lifetime of any other
+            // SIP element. The current transaction, dialog, and inv_session all end
+            // when we receive the ACK for the 401 we send. This means we can't stuff
+            // the AuthHelper into any of these structures. Instead, we have to store
+            // this in a container local to the module itself.
+            //
+            // Now, that leads to two further issues: identification and lifetime.
+            //
+            // When a new message comes in, how are we supposed to match up the new incoming
+            // request with our stored AuthHelper? If you read RFC 3261, it implies that
+            // a requester should regenerate his original request with auth info added and
+            // the CSeq incremented. So we SHOULD be able to use the call-id and from tag
+            // to figure out which AuthHelper to retrieve. Experimentation will be required
+            // to determine if this actually works in all cases.
+            //
+            // The lifetime of an AuthHelper is a bit hard to grasp. Let's say we send a 401
+            // response and then either a) never receive an ACK or b) receive an ACK but never
+            // receive a new request with proper auth info. In either case, we will never
+            // receive any sort of message that indicates to us that we should destroy the
+            // AuthHelper. Instead, what we have to do is periodically check to see if we
+            // have held onto an AuthHelper for longer than some prescribed period. While I'd
+            // think that a few seconds would be long enough to hold on, in practice this may
+            // cause issues. If we have to retransmit the 401 3 times and then the other endpoint
+            // has to retransmit its ACK 4 times, then the INVITE with the auth info has to
+            // be retransmitted 3 times, then that's a lot of time between when we created the
+            // AuthHelper and when we finally see auth info. So this means we have to wait
+            // a minute or two before we can safely claim that an AuthHelper isn't going to
+            // be used for anything.
+            //
+            // One thing we can be assured of is that the AuthHelper definitely only pertains
+            // to this particular PJSIP module. So it seems we can add a container to the PJSIP
+            // module and store our AuthHelpers in there. We can get away with using a vector
+            // pretty easily. So first, we need to modify the AuthHelper class to store the
+            // call-id and from tag of the request so that we can identify which to use when
+            // authenticating. We can modify the AuthHelper's constructor to take the pjsip_rdata
+            // to fill in these values. We can even be slick and define an operator== so that
+            // we can use std::find to find an appropriate match, but that's not entirely
+            // necessary atm.
+            //
+            // So how about the lifetime issue? Well PJSIP offers a handy function called
+            // pjsip_endpt_schedule_timer. We can schedule a callback to be called in the future,
+            // presumably when the AuthHelper can be determined to be no longer useful. This callback
+            // can find and remove the AuthHelper from the vector. Now of course, if we receive
+            // authentication from the requester, then we can destroy the AuthHelper and cancel
+            // the scheduled callback. This will require adding the pj_timer_entry to the AuthHelper.
+            // Unfortunately we can't schedule the operation from within a method of AuthHelper because
+            // the vector of AuthHelpers lives here in the module, not the AuthHelper. So instead, we'll
+            // need a method in the PJSipModule to schedule the operation instead. Easy-peasy.
             return true;
         }
     }

commit 5f9e9fd318c13fa5d58c30a6d2ab85d33fe59866
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Feb 11 14:06:45 2011 -0600

    Move some logic from PJSipModule.h to PJSipModule.cpp

diff --git a/src/PJSipModule.cpp b/src/PJSipModule.cpp
index c53a60e..a2e9535 100644
--- a/src/PJSipModule.cpp
+++ b/src/PJSipModule.cpp
@@ -154,5 +154,29 @@ TransactionState PJSipTransactionModInfo::transactionStateTranslate(pjsip_tsx_st
     return retState;
 }
 
+void PJSipModule::addAuthHook(AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx hook, int priority, AsteriskSCF::SIP::ExtensionPoint::V1::RequestTypeSeq types)
+{
+    boost::shared_ptr<AuthHookData> hookData(new AuthHookData(priority, hook, types));
+    mAuthHooks.push_back(hookData);
+    std::stable_sort(mAuthHooks.begin(), mAuthHooks.end());
+}
+
+void PJSipModule::removeAuthHook(AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx hook)
+{
+    for (moduleHookVector::iterator iter = mAuthHooks.begin(); iter != mAuthHooks.end(); ++iter)
+    {
+        if ((*iter)->getHook() == hook)
+        {
+            mAuthHooks.erase(iter);
+            break;
+        }
+    }
+}
+
+void PJSipModule::clearAuthHooks()
+{
+    mAuthHooks.clear();
+}
+
 };
 };
diff --git a/src/PJSipModule.h b/src/PJSipModule.h
index 13d9a4e..6d8ac76 100644
--- a/src/PJSipModule.h
+++ b/src/PJSipModule.h
@@ -70,27 +70,9 @@ public:
     virtual pj_status_t on_tx_response(pjsip_tx_data *tdata) = 0;
     virtual void on_tsx_state(pjsip_transaction *tsx, pjsip_event *event) = 0;
     pjsip_module &getModule() { return mModule; };
-    void addAuthHook(AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx hook, int priority, AsteriskSCF::SIP::ExtensionPoint::V1::RequestTypeSeq types)
-    {
-        boost::shared_ptr<AuthHookData> hookData(new AuthHookData(priority, hook, types));
-        mAuthHooks.push_back(hookData);
-        std::stable_sort(mAuthHooks.begin(), mAuthHooks.end());
-    }
-    void removeAuthHook(AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx hook)
-    {
-        for (moduleHookVector::iterator iter = mAuthHooks.begin(); iter != mAuthHooks.end(); ++iter)
-        {
-            if ((*iter)->getHook() == hook)
-            {
-                mAuthHooks.erase(iter);
-                break;
-            }
-        }
-    }
-    void clearAuthHooks()
-    {
-        mAuthHooks.clear();
-    }
+    void addAuthHook(AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx hook, int priority, AsteriskSCF::SIP::ExtensionPoint::V1::RequestTypeSeq types);
+    void removeAuthHook(AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx hook);
+    void clearAuthHooks();
 protected:
     PJSipModule() { }
     virtual ~PJSipModule() { }

commit 7837bf220f03f26090c509f427c003fc00deae76
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Feb 11 14:05:52 2011 -0600

    Add qop string to outbound digest.

diff --git a/src/AuthHelper.cpp b/src/AuthHelper.cpp
index d17738f..c657dab 100644
--- a/src/AuthHelper.cpp
+++ b/src/AuthHelper.cpp
@@ -129,6 +129,8 @@ static pj_status_t lookup_cred(pj_pool_t *pool, const pj_str_t *realm, const pj_
 
 void AuthHelper::addDigests(pjsip_tx_data *tdata, DigestChallengeSeq digests)
 {
+    static char qop[] = "auth";
+    pj_str_t pjqop = pj_str(qop);
     for (DigestChallengeSeq::iterator digest = digests.begin(); digest != digests.end(); ++digest)
     {
         pjsip_auth_srv *authServer = PJ_POOL_ZALLOC_T(mImpl->pool, pjsip_auth_srv);
@@ -146,7 +148,7 @@ void AuthHelper::addDigests(pjsip_tx_data *tdata, DigestChallengeSeq digests)
             pj_cstr(&nonce, (*digest)->nonce.front().c_str());
             noncePtr = &nonce;
         }
-        pjsip_auth_srv_challenge(authServer, NULL, noncePtr, opaquePtr, PJ_FALSE, tdata);
+        pjsip_auth_srv_challenge(authServer, &pjqop, noncePtr, opaquePtr, PJ_FALSE, tdata);
         mImpl->authServers.push_back(authServer);
     }
 }

commit 0910249b0079177bd957635dd46286b16e769247
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Feb 11 12:33:03 2011 -0600

    Add logger to the AuthHelper so that messages can be logged and stuff.

diff --git a/src/AuthHelper.cpp b/src/AuthHelper.cpp
index da8047d..d17738f 100644
--- a/src/AuthHelper.cpp
+++ b/src/AuthHelper.cpp
@@ -18,6 +18,7 @@
 
 using namespace AsteriskSCF::SIP::ExtensionPoint::V1;
 using namespace AsteriskSCF::System::Hook::V1;
+using namespace AsteriskSCF::System::Logging;
 
 namespace AsteriskSCF
 {
@@ -28,8 +29,8 @@ namespace SipSessionManager
 class AuthHelperPriv
 {
 public:
-    AuthHelperPriv(moduleHookVector moduleHooks, RequestType type, pjsip_endpoint *endpt)
-        : mEndpoint(endpt), pool(pjsip_endpt_create_pool(endpt, "auth%p", 1200, 512))
+    AuthHelperPriv(moduleHookVector moduleHooks, RequestType type, pjsip_endpoint *endpt, const Logger &logger)
+        : mEndpoint(endpt), pool(pjsip_endpt_create_pool(endpt, "auth%p", 1200, 512)), mLogger(logger)
     {
         if (moduleHooks.empty())
         {
@@ -96,10 +97,11 @@ public:
     std::vector<pjsip_auth_srv *> authServers;
     pjsip_endpoint *mEndpoint;
     pj_pool_t *pool;
+    Logger mLogger;
 };
 
-AuthHelper::AuthHelper(moduleHookVector hooks, RequestType type, pjsip_endpoint *endpt)
-        : mImpl(new AuthHelperPriv(hooks, type, endpt)) { }
+AuthHelper::AuthHelper(moduleHookVector hooks, RequestType type, pjsip_endpoint *endpt, const Logger &logger)
+        : mImpl(new AuthHelperPriv(hooks, type, endpt, logger)) { }
 
 std::vector<AuthHookPrx> AuthHelper::getHooks()
 {
@@ -157,11 +159,15 @@ void AuthHelper::fillInRequestInfo(pjsip_rx_data *rdata, RequestInfoPtr info)
     pjsip_name_addr *from = (pjsip_name_addr *)rdata->msg_info.from->uri;
     info->fromName = std::string(pj_strbuf(&from->display), pj_strlen(&from->display));
 
+    mImpl->mLogger(Debug) << "from name is " << info->fromName;
+
     pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, from->uri, buf, sizeof(buf));
     std::string fromURI(buf, strlen(buf));
     pos = fromURI.find_first_of(';');
     info->fromURI = fromURI.substr(0, pos);
 
+    mImpl->mLogger(Debug) << "from uri is " << info->fromURI;
+
     if (pos != std::string::npos)
     {
         mImpl->getURIParams(from->uri, info->fromParams);
@@ -170,11 +176,15 @@ void AuthHelper::fillInRequestInfo(pjsip_rx_data *rdata, RequestInfoPtr info)
     pjsip_name_addr *to = (pjsip_name_addr *)rdata->msg_info.to->uri;
     info->toName = std::string(pj_strbuf(&to->display), pj_strlen(&to->display));
 
+    mImpl->mLogger(Debug) << "to name is " << info->toName;
+
     pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, to->uri, buf, sizeof(buf));
     std::string toURI(buf, strlen(buf));
     pos = toURI.find_first_of(';');
     info->toURI = toURI.substr(0, pos);
 
+    mImpl->mLogger(Debug) << "to uri is " << info->toURI;
+
     if (pos != std::string::npos)
     {
         mImpl->getURIParams(to->uri, info->toParams);
@@ -186,6 +196,8 @@ void AuthHelper::fillInRequestInfo(pjsip_rx_data *rdata, RequestInfoPtr info)
     pos = rURIStr.find_first_of(';');
     info->requestURI = rURIStr.substr(0, pos);
 
+    mImpl->mLogger(Debug) << "ruri is " << info->requestURI;
+
     if (pos != std::string::npos)
     {
         mImpl->getURIParams(rURI, info->requestURIParams);
@@ -197,14 +209,17 @@ void AuthHelper::fillInRequestInfo(pjsip_rx_data *rdata, RequestInfoPtr info)
     if (transport == "tcp")
     {
         info->transport = AsteriskSCF::SIP::ExtensionPoint::V1::TCP;
+        mImpl->mLogger(Debug) << "Set transport to TCP";
     }
     else if (transport == "tls")
     {
         info->transport = AsteriskSCF::SIP::ExtensionPoint::V1::TLS;
+        mImpl->mLogger(Debug) << "Set transport to TLS";
     }
     else if (transport == "udp")
     {
         info->transport = AsteriskSCF::SIP::ExtensionPoint::V1::UDP;
+        mImpl->mLogger(Debug) << "Set transport to UDP";
     }
 }
 
diff --git a/src/AuthHelper.h b/src/AuthHelper.h
index 1e4fe5b..9d87494 100644
--- a/src/AuthHelper.h
+++ b/src/AuthHelper.h
@@ -22,6 +22,7 @@
 
 #include <AsteriskSCF/System/Hook/HookIf.h>
 #include <AsteriskSCF/SIP/SIPExtensionPointIf.h>
+#include <AsteriskSCF/logger.h>
 
 #include "PJSipModule.h"
 
@@ -36,7 +37,10 @@ class AuthHelperPriv;
 class AuthHelper
 {
 public:
-    AuthHelper(moduleHookVector hooks, AsteriskSCF::SIP::ExtensionPoint::V1::RequestType type, pjsip_endpoint *endpt);
+    AuthHelper(moduleHookVector hooks,
+            AsteriskSCF::SIP::ExtensionPoint::V1::RequestType type,
+            pjsip_endpoint *endpt,
+            const AsteriskSCF::System::Logging::Logger &logger);
     std::vector<AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx> getHooks();
     void fillInRequestInfo(pjsip_rx_data *rdata, AsteriskSCF::SIP::ExtensionPoint::V1::RequestInfoPtr info);
     void addDigests(pjsip_tx_data *tdata, AsteriskSCF::SIP::ExtensionPoint::V1::DigestChallengeSeq digests);
diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 82c1a9c..07ff5c6 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -428,7 +428,7 @@ pj_status_t PJSipSessionModule::unload()
 
 bool PJSipSessionModule::checkAuth(pjsip_rx_data *rdata, pjsip_inv_session *inv, RequestType type, pjsip_endpoint *endpt)
 {
-    boost::shared_ptr<AuthHelper> authHelper(new AuthHelper(mAuthHooks, type, endpt));
+    boost::shared_ptr<AuthHelper> authHelper(new AuthHelper(mAuthHooks, type, endpt, lg));
     
     std::vector<AuthHookPrx> hooks = authHelper->getHooks();
     if (hooks.empty())

-----------------------------------------------------------------------


-- 
asterisk-scf/release/sip.git



More information about the asterisk-scf-commits mailing list