Check TLS availability before using it on outgoing streams.

git-svn-id: http://voip.null.ro/svn/yate@3427 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2010-07-09 14:37:19 +00:00
parent fdd5b3e44b
commit 0549bfe554
5 changed files with 71 additions and 6 deletions

View File

@ -724,7 +724,7 @@ JBEngine::JBEngine(const char* name)
m_pingInterval(JB_PING_INTERVAL), m_pingTimeout(JB_PING_TIMEOUT),
m_idleTimeout(0),
m_streamReadBuffer(JB_STREAMBUF), m_maxIncompleteXml(XMPP_MAX_INCOMPLETEXML),
m_printXml(0), m_initialized(false)
m_hasClientTls(true), m_printXml(0), m_initialized(false)
{
debugName(name);
XDebug(this,DebugAll,"JBEngine [%p]",this);

View File

@ -1892,12 +1892,17 @@ bool JBStream::processFeaturesOut(XmlElement* xml, const JabberID& from,
if (!flag(StreamSecured)) {
XMPPFeature* tls = m_features.get(XMPPNamespace::Tls);
if (tls) {
TelEngine::destruct(xml);
XmlElement* x = XMPPUtils::createElement(XmlTag::Starttls,
XMPPNamespace::Tls);
return sendStreamXml(WaitTlsRsp,x);
if (m_engine->hasClientTls()) {
TelEngine::destruct(xml);
XmlElement* x = XMPPUtils::createElement(XmlTag::Starttls,
XMPPNamespace::Tls);
return sendStreamXml(WaitTlsRsp,x);
}
if (tls->required() || flag(TlsRequired))
return destroyDropXml(xml,XMPPError::Internal,
"required encryption not available");
}
if (flag(TlsRequired))
else if (flag(TlsRequired))
return destroyDropXml(xml,XMPPError::EncryptionRequired,
"required encryption not supported by remote");
setFlags(StreamSecured);

View File

@ -1690,6 +1690,13 @@ public:
XMPPError::Shutdown);
}
/**
* Check if TLS is available for outgoing streams
* @return True if TLS is available for outgoing streams
*/
inline bool hasClientTls() const
{ return m_hasClientTls; }
/**
* Find a remote domain definition. Return the default settings if not found.
* This method is not thread safe
@ -1933,6 +1940,7 @@ protected:
unsigned int m_idleTimeout; // Stream idle timeout (nothing sent or received)
unsigned int m_streamReadBuffer; // Stream read buffer length
unsigned int m_maxIncompleteXml; // Maximum length of an incomplete xml
bool m_hasClientTls; // True if TLS is available for outgoing streams
int m_printXml; // Print XML data to output
bool m_initialized; // True if already initialized

View File

@ -252,6 +252,8 @@ public:
bool handleMsgExecute(Message& msg, const String& line);
// Process 'user.login' messages
bool handleUserLogin(Message& msg, const String& line);
// Process 'engine.start' messages
void handleEngineStart(Message& msg);
// Handle 'presence' stanzas
// The given event is always valid and carry a valid stream and xml element
void processPresenceStanza(JBEvent* ev);
@ -314,6 +316,10 @@ class JBModule : public Module
{
friend class TcpListener; // Add/remove to/from list
public:
// Message relays
enum {
EngineStart = Private
};
JBModule();
virtual ~JBModule();
// Inherited methods
@ -1004,6 +1010,18 @@ bool YJBEngine::handleUserLogin(Message& msg, const String& line)
return ok;
}
// Process 'engine.start' messages
void YJBEngine::handleEngineStart(Message& msg)
{
// Check client TLS
Message m("socket.ssl");
m.addParam("test",String::boolText(true));
m.addParam("server",String::boolText(false));
m_hasClientTls = Engine::dispatch(m);
if (!m_hasClientTls)
Debug(this,DebugNote,"TLS not available for outgoing streams");
}
// Handle 'presence' stanzas
// The given event is always valid and carry a valid stream and xml element
void YJBEngine::processPresenceStanza(JBEvent* ev)
@ -1693,6 +1711,7 @@ void JBModule::initialize()
installRelay(Halt);
installRelay(Help);
installRelay(ImExecute);
installRelay(EngineStart,"engine.start");
s_jabber = new YJBEngine;
s_jabber->debugChain(this);
// Install handlers
@ -1769,6 +1788,8 @@ bool JBModule::received(Message& msg, int id)
}
if (id == Timer)
s_entityCaps.expire(msg.msgTime().msec());
else if (id == EngineStart)
s_jabber->handleEngineStart(msg);
return Module::received(msg,id);
}

View File

@ -207,6 +207,8 @@ public:
bool handleMsgExecute(Message& msg);
// Process 'jabber.item' messages
bool handleJabberItem(Message& msg);
// Process 'engine.start' messages
void handleEngineStart(Message& msg);
// Handle 'presence' stanzas
// s2s: Destination domain was already checked by the lower layer
// The given event is always valid and carry a valid stream and xml element
@ -446,6 +448,7 @@ public:
UserRoster = -3, // YJBEngine::handleUserRoster()
UserUpdate = -4, // YJBEngine::handleUserUpdate()
JabberItem = -5, // YJBEngine::handleJabberItem()
EngineStart = -6, // YJBEngine::handleEngineStart()
JabberIq = 150, // YJBEngine::handleJabberIq()
};
JBMessageHandler(int handler);
@ -534,6 +537,8 @@ public:
msg.addParam("module",name());
msg.addParam("protocol","jabber");
}
// Check if client/server TLS is available
bool checkTls(bool server, const String& domain = String::empty());
protected:
// Inherited methods
virtual bool received(Message& msg, int id);
@ -563,6 +568,7 @@ Mutex JBPendingWorker::s_mutex(false,"JBPendingWorker");
static bool s_s2sFeatures = true; // Offer RFC 3920 version=1 and stream features
// on incoming s2s streams
static bool s_dumpIq = false; // Dump 'iq' xml string in jabber.iq message
static bool s_engineStarted = false; // Engine started flag
INIT_PLUGIN(JBModule); // The module
static YJBEntityCapsList s_entityCaps;
static YJBEngine* s_jabber = 0;
@ -591,6 +597,7 @@ static const TokenDict s_msgHandler[] = {
{"user.update", JBMessageHandler::UserUpdate},
{"jabber.iq", JBMessageHandler::JabberIq},
{"jabber.item", JBMessageHandler::JabberItem},
{"engine.start", JBMessageHandler::EngineStart},
{0,0}
};
@ -1470,6 +1477,16 @@ bool YJBEngine::handleJabberItem(Message& msg)
return true;
}
// Process 'engine.start' messages
void YJBEngine::handleEngineStart(Message& msg)
{
s_engineStarted = true;
// Check client TLS
m_hasClientTls = __plugin.checkTls(false);
if (!m_hasClientTls)
Debug(this,DebugNote,"TLS not available for outgoing streams");
}
// Handle 'presence' stanzas
// s2s: Destination domain was already checked by the lower layer
// The given event is always valid and carry a valid stream and xml element
@ -3146,6 +3163,9 @@ bool JBMessageHandler::received(Message& msg)
return false;
case JabberItem:
return s_jabber->handleJabberItem(msg);
case EngineStart:
s_jabber->handleEngineStart(msg);
return false;
default:
DDebug(&__plugin,DebugStub,"JBMessageHandler(%s) not handled!",msg.c_str());
}
@ -3380,6 +3400,17 @@ void JBModule::cancelListener(const String& name)
Debug(this,DebugInfo,"Listener '%s' terminated",name.c_str());
}
// Check if client/server TLS is available
bool JBModule::checkTls(bool server, const String& domain)
{
Message m("socket.ssl");
m.addParam("test",String::boolText(true));
m.addParam("server",String::boolText(server));
if (server)
m.addParam("domain",domain,false);
return Engine::dispatch(m);
}
// Message handler
bool JBModule::received(Message& msg, int id)
{