Fixed registration bug.
git-svn-id: http://yate.null.ro/svn/yate/trunk@1075 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
1618048429
commit
c87c32f5d0
|
@ -230,10 +230,11 @@ public:
|
|||
* @param transTimeout Timeout (in seconds) on remote request of transactions belonging to this engine
|
||||
* @param maxFullFrameDataLen Max full frame IE list (buffer) length
|
||||
* @param trunkSendInterval Send trunk meta frame interval
|
||||
* @param authRequired Automatically challenge all clients for authentication
|
||||
*/
|
||||
YIAXEngine(const char* iface, int port, u_int16_t transListCount, u_int16_t retransCount, u_int16_t retransInterval,
|
||||
u_int16_t authTimeout, u_int16_t transTimeout,
|
||||
u_int16_t maxFullFrameDataLen, u_int32_t trunkSendInterval);
|
||||
u_int16_t maxFullFrameDataLen, u_int32_t trunkSendInterval, bool authRequired);
|
||||
|
||||
virtual ~YIAXEngine()
|
||||
{}
|
||||
|
@ -286,8 +287,11 @@ protected:
|
|||
|
||||
/*
|
||||
* Event handler for incoming registration transactions.
|
||||
* @param event The event.
|
||||
* @param first True if this is the first request.
|
||||
* False if it is a response to an authentication request.
|
||||
*/
|
||||
void processRemoteReg(IAXEvent* event);
|
||||
void processRemoteReg(IAXEvent* event,bool first);
|
||||
|
||||
/*
|
||||
* Send Register/Unregister messages to Engine
|
||||
|
@ -345,6 +349,15 @@ public:
|
|||
// @return False if formtas is not 0 and the result is 0 (no intersection)
|
||||
bool updateCodecsFromRoute(u_int32_t& codecs, const char* formats);
|
||||
|
||||
// Dispatch user.auth
|
||||
// @tr The IAX transaction
|
||||
// @param response True if it is a response.
|
||||
// @param requestAuth True on exit: the caller should request authentication
|
||||
// @param invalidAuth True on exit: authentication response is incorrect
|
||||
// @return False if not authenticated
|
||||
bool userAuth(IAXTransaction* tr, bool response, bool& requestAuth,
|
||||
bool& invalidAuth);
|
||||
|
||||
protected:
|
||||
YIAXEngine* m_iaxEngine;
|
||||
u_int32_t m_defaultCodec;
|
||||
|
@ -785,10 +798,13 @@ void YIAXTrunking::run()
|
|||
/**
|
||||
* YIAXEngine
|
||||
*/
|
||||
YIAXEngine::YIAXEngine(const char* iface, int port, u_int16_t transListCount, u_int16_t retransCount, u_int16_t retransInterval,
|
||||
u_int16_t authTimeout, u_int16_t transTimeout, u_int16_t maxFullFrameDataLen, u_int32_t trunkSendInterval)
|
||||
: IAXEngine(iface,port,transListCount,retransCount,retransInterval,authTimeout,transTimeout,
|
||||
maxFullFrameDataLen,iplugin.defaultCodec(),iplugin.codecs(),trunkSendInterval),
|
||||
YIAXEngine::YIAXEngine(const char* iface, int port, u_int16_t transListCount,
|
||||
u_int16_t retransCount, u_int16_t retransInterval, u_int16_t authTimeout,
|
||||
u_int16_t transTimeout, u_int16_t maxFullFrameDataLen,
|
||||
u_int32_t trunkSendInterval, bool authRequired)
|
||||
: IAXEngine(iface,port,transListCount,retransCount,retransInterval,authTimeout,
|
||||
transTimeout,maxFullFrameDataLen,iplugin.defaultCodec(),iplugin.codecs(),
|
||||
trunkSendInterval,authRequired),
|
||||
m_threadsCreated(false)
|
||||
{
|
||||
}
|
||||
|
@ -914,8 +930,8 @@ void YIAXEngine::processEvent(IAXEvent* event)
|
|||
break;
|
||||
case IAXTransaction::RegReq:
|
||||
case IAXTransaction::RegRel:
|
||||
if (event->type() == IAXEvent::New)
|
||||
processRemoteReg(event);
|
||||
if (event->type() == IAXEvent::New || event->type() == IAXEvent::AuthRep)
|
||||
processRemoteReg(event,(event->type() == IAXEvent::New));
|
||||
else
|
||||
if (event->getTransaction()->getUserData())
|
||||
s_lines.handleEvent(event);
|
||||
|
@ -926,38 +942,44 @@ void YIAXEngine::processEvent(IAXEvent* event)
|
|||
}
|
||||
|
||||
// Process events for remote users registering to us
|
||||
void YIAXEngine::processRemoteReg(IAXEvent* event)
|
||||
void YIAXEngine::processRemoteReg(IAXEvent* event, bool first)
|
||||
{
|
||||
IAXTransaction* tr = event->getTransaction();
|
||||
|
||||
Debug(this,DebugAll,"processRemoteReg: %s username: '%s'",
|
||||
tr->type() == IAXTransaction::RegReq?"Register":"Unregister",tr->username().c_str());
|
||||
Message msg("user.auth");
|
||||
msg.addParam("username",tr->username());
|
||||
msg.addParam("ip_host",tr->remoteAddr().host());
|
||||
msg.addParam("ip_port",String(tr->remoteAddr().port()));
|
||||
if (!Engine::dispatch(msg)) {
|
||||
// Not authenticated
|
||||
Debug(this,DebugAll,"processRemoteReg. Not authenticated. Reject");
|
||||
tr->sendReject();
|
||||
// Check for automatomatically authentication request if it's the first request
|
||||
if (first && iplugin.getEngine()->authRequired()) {
|
||||
Debug(this,DebugAll,"processRemoteReg. Request authentication");
|
||||
tr->sendAuth();
|
||||
return;
|
||||
}
|
||||
String password = msg.retValue();
|
||||
if (password.null()) {
|
||||
// Authenticated, no password. Try to (un)register
|
||||
// Authenticated: register/unregister
|
||||
bool requestAuth = false, invalidAuth = false;
|
||||
if (iplugin.userAuth(tr,!first,requestAuth,invalidAuth)) {
|
||||
// Authenticated. Try to (un)register
|
||||
if (userreg(tr,event->subclass() == IAXControl::RegRel)) {
|
||||
Debug(this,DebugAll,"processRemoteReg. Authenticated and (un)registered. Ack");
|
||||
tr->sendAccept();
|
||||
}
|
||||
else {
|
||||
Debug(this,DebugAll,"processRemoteReg. Authenticated but not (un)registered. Reject");
|
||||
tr->sendReject();
|
||||
tr->sendReject("not registered");
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Authenticated, password required
|
||||
Debug(this,DebugAll,"processRemoteReg. Request authentication");
|
||||
tr->sendAuth(password);
|
||||
// First request: check if we should request auth
|
||||
const char* reason = 0;
|
||||
if (first && requestAuth) {
|
||||
Debug(this,DebugAll,"processRemoteReg. Request authentication");
|
||||
tr->sendAuth();
|
||||
return;
|
||||
}
|
||||
else if (invalidAuth)
|
||||
reason = IAXTransaction::s_iax_modInvalidAuth;
|
||||
if (!reason)
|
||||
reason = "not authenticated";
|
||||
Debug(this,DebugAll,"processRemoteReg. Not authenticated ('%s'). Reject",reason);
|
||||
tr->sendReject(reason);
|
||||
}
|
||||
|
||||
// Build and dispatch the user.(un)register message
|
||||
|
@ -1044,6 +1066,7 @@ void YIAXDriver::initialize()
|
|||
// Port and interface
|
||||
m_port = s_cfg.getIntValue("general","port",4569);
|
||||
String iface = s_cfg.getValue("general","addr");
|
||||
bool authReq = s_cfg.getBoolValue("registrar","auth_required",true);
|
||||
unlock();
|
||||
setup();
|
||||
// We need channels to be dropped on shutdown
|
||||
|
@ -1060,7 +1083,7 @@ void YIAXDriver::initialize()
|
|||
if (!m_iaxEngine) {
|
||||
Engine::install(new YIAXRegDataHandler);
|
||||
m_iaxEngine = new YIAXEngine(iface,m_port,transListCount,retransCount,retransInterval,authTimeout,
|
||||
transTimeout,maxFullFrameDataLen,trunkSendInterval);
|
||||
transTimeout,maxFullFrameDataLen,trunkSendInterval,authReq);
|
||||
m_iaxEngine->debugChain(this);
|
||||
int tos = s_cfg.getIntValue("general","tos",dict_tos,0);
|
||||
if (tos) {
|
||||
|
@ -1193,6 +1216,42 @@ bool YIAXDriver::updateCodecsFromRoute(u_int32_t& codecs, const char* formats)
|
|||
return codecs != 0;
|
||||
}
|
||||
|
||||
bool YIAXDriver::userAuth(IAXTransaction* tr, bool response, bool& requestAuth,
|
||||
bool& invalidAuth)
|
||||
{
|
||||
requestAuth = invalidAuth = false;
|
||||
// Create and dispatch user.auth
|
||||
Message msg("user.auth");
|
||||
msg.addParam("protocol","iax");
|
||||
msg.addParam("username",tr->username());
|
||||
msg.addParam("called",tr->calledNo());
|
||||
msg.addParam("caller",tr->callingNo());
|
||||
msg.addParam("callername",tr->callingName());
|
||||
msg.addParam("ip_host",tr->remoteAddr().host());
|
||||
msg.addParam("ip_port",String(tr->remoteAddr().port()));
|
||||
if (response) {
|
||||
msg.addParam("nonce",tr->challenge());
|
||||
msg.addParam("response",tr->authdata());
|
||||
}
|
||||
if (!Engine::dispatch(msg))
|
||||
return false;
|
||||
String pwd = msg.retValue();
|
||||
// We have a password
|
||||
if (pwd) {
|
||||
// Not a response: request authentication
|
||||
if (!response) {
|
||||
requestAuth = true;
|
||||
return false;
|
||||
}
|
||||
// Check response
|
||||
if (!IAXEngine::isMD5ChallengeCorrect(tr->authdata(),tr->challenge(),pwd)) {
|
||||
invalidAuth = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* IAXConsumer
|
||||
*/
|
||||
|
@ -1293,14 +1352,13 @@ void YIAXConnection::callRejected(const char* error, const char* reason, const M
|
|||
reason = error;
|
||||
DDebug(this,DebugInfo,"callRejected [%p]. Error: '%s'",this,error);
|
||||
String s(error);
|
||||
m_mutexTrans.lock();
|
||||
Lock lock(m_mutexTrans);
|
||||
if (m_transaction && (s == "noauth") && safeRefIncrease()) {
|
||||
Debug(this,DebugAll,"callRejected [%p]. Requesting authentication",this);
|
||||
m_transaction->sendAuth(m_password);
|
||||
m_mutexTrans.unlock();
|
||||
Debug(this,DebugAll,"callRejected [%p]. Request authentication",this);
|
||||
m_transaction->sendAuth();
|
||||
return;
|
||||
}
|
||||
m_mutexTrans.unlock();
|
||||
lock.drop();
|
||||
hangup(reason,true);
|
||||
}
|
||||
|
||||
|
@ -1556,29 +1614,15 @@ void YIAXConnection::startAudioOut()
|
|||
void YIAXConnection::evAuthRep(IAXEvent* event)
|
||||
{
|
||||
DDebug(this,DebugAll,"YIAXConnection - AUTHREP");
|
||||
IAXTransaction* tr = event->getTransaction();
|
||||
// Try to obtain a password from Engine
|
||||
Message msg("user.auth");
|
||||
msg.addParam("username",tr->username());
|
||||
if (!Engine::dispatch(msg)) {
|
||||
// NOT Authenticated
|
||||
hangup(event,"",true);
|
||||
bool requestAuth, invalidAuth;
|
||||
if (iplugin.userAuth(event->getTransaction(),true,requestAuth,invalidAuth)) {
|
||||
// Authenticated. Route the user.
|
||||
route(true);
|
||||
return;
|
||||
}
|
||||
String pwd = msg.retValue();
|
||||
if (pwd.null()) {
|
||||
// Authenticated
|
||||
tr->sendAccept();
|
||||
return;
|
||||
}
|
||||
if (!IAXEngine::isMD5ChallengeCorrect(tr->authdata(),tr->challenge(),pwd)) {
|
||||
// Incorrect data received
|
||||
DDebug(this,DebugAll,"AUTHREP - Incorrect MD5 answer. Reject.");
|
||||
hangup(event,IAXTransaction::s_iax_modInvalidAuth,true);
|
||||
return;
|
||||
}
|
||||
// Password is correct. Route the user.
|
||||
route(true);
|
||||
const char* reason = invalidAuth ? IAXTransaction::s_iax_modInvalidAuth : "not authenticated";
|
||||
DDebug(this,DebugAll,"Not authenticated. Reason: '%s'. Reject.",reason);
|
||||
hangup(event,reason,true);
|
||||
}
|
||||
|
||||
// Get rid of the extra reference
|
||||
|
|
Loading…
Reference in New Issue