[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