1
/****************************************************************************
5
** Copyright © 2011 Ruslan Nigmatullin <euroelessar@yandex.ru>
6
** Copyright © 2011 Aleksey Sidorov <gorthauer87@yandex.ru>
8
*****************************************************************************
10
** $JREEN_BEGIN_LICENSE$
11
** This program is free software: you can redistribute it and/or modify
12
** it under the terms of the GNU General Public License as published by
13
** the Free Software Foundation, either version 2 of the License, or
14
** (at your option) any later version.
16
** This program is distributed in the hope that it will be useful,
17
** but WITHOUT ANY WARRANTY; without even the implied warranty of
18
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19
** See the GNU General Public License for more details.
21
** You should have received a copy of the GNU General Public License
22
** along with this program. If not, see http://www.gnu.org/licenses/.
23
** $JREEN_END_LICENSE$
25
****************************************************************************/
27
#include "tlsfeature_p.h"
28
#include "tlsdatastream_p.h"
30
#include <QXmlStreamWriter>
32
#include <QCoreApplication>
34
#define NS_TLS QLatin1String("urn:ietf:params:xml:ns:xmpp-tls")
39
TLSFeature::TLSFeature() : StreamFeature(SecurityLayer)
42
QCA::setAppName(QCoreApplication::applicationName());
45
m_hasTls = QCA::isSupported("tls");
47
Logger::warning() << "Jreen: TLS is not provided by QCA";
50
void TLSFeature::init()
54
m_tls.reset(new QCA::TLS(this));
55
m_tls->setTrustedCertificates(QCA::systemStore());
56
connect(m_tls.data(), SIGNAL(handshaken()), SLOT(onHandshaken()));
57
connect(m_tls.data(), SIGNAL(closed()), SLOT(onClosed()));
58
connect(m_tls.data(), SIGNAL(error()), SLOT(onError()));
61
void TLSFeature::setStreamInfo(StreamInfo *info)
64
m_client->disconnect(this);
65
StreamFeature::setStreamInfo(info);
66
connect(m_client, SIGNAL(disconnected(Jreen::Client::DisconnectReason)),
67
SLOT(onDisconnected()));
70
void TLSFeature::reset()
76
bool TLSFeature::canParse(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes)
78
// All other methods shouldn't be called is canParse returnes false
84
Logger::debug() << Q_FUNC_INFO << name << uri;
88
void TLSFeature::handleStartElement(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes)
92
if (name == QLatin1String("starttls"))
94
else if (name == QLatin1String("required"))
98
// Logger::debug() << Q_FUNC_INFO << m_depth << name;
99
// if (m_depth == 1) {
100
// if (name == QLatin1String("mechanisms")) {
101
// m_state = AtMechanisms;
103
// } else if (name == QLatin1String("challenge")) {
104
// m_state = AtChallenge;
106
// } else if (m_depth == 2 && name == QLatin1String("mechanism")) {
107
// m_state = AtMechanism;
111
void TLSFeature::handleEndElement(const QStringRef &name, const QStringRef &uri)
114
if (name == QLatin1String("proceed")) {
115
Logger::debug() << Q_FUNC_INFO;
116
m_info->addDataStream(new TLSDataStream(m_tls.data()));
117
m_tls->startClient(m_info->jid().domain());
119
// if (m_depth == 2 && m_state == AtMechanism)
120
// m_state = AtMechanisms;
121
// else if (m_depth == 1) {
122
// Logger::debug() << Q_FUNC_INFO << m_mechs;
123
// m_state = AtStart;
124
// if (name == QLatin1String("success"))
125
// m_info->completed(StreamInfo::Authorized);
130
void TLSFeature::handleCharacterData(const QStringRef &text)
133
// if (m_state == AtMechanism) {
134
// Logger::debug() << Q_FUNC_INFO << "mechanism" << text;
135
// m_mechs.append(text.toString());
136
// } else if (m_state == AtChallenge) {
137
// Logger::debug() << Q_FUNC_INFO << "challenge" << text;
138
// // if (m_firstStep)
139
// // m_tls->putServerFirstStep("DIGEST-MD5");
140
// m_tls->putStep(QByteArray::fromBase64(text.toString().toLatin1()));
141
// m_firstStep = false;
145
bool TLSFeature::isActivatable()
147
return m_hasTls && m_available;
150
bool TLSFeature::activate()
153
QXmlStreamWriter *writer = m_info->writer();
154
writer->writeEmptyElement(QLatin1String("starttls"));
155
writer->writeDefaultNamespace(NS_TLS);
156
writer->writeCharacters(QString());
157
// Logger::debug() << Q_FUNC_INFO << m_info->password();
158
// m_tls->setPassword(QCA::SecureArray(m_info->password().toUtf8()));
159
// m_tls->setUsername(m_info->jid().node());
160
// m_tls->setRealm(m_info->jid().domain());
161
// m_tls->setAuthzid(m_info->jid().bare());
162
// m_tls->startClient("xmpp", QUrl::toAce(m_info->jid().domain()), m_mechs, QCA::TLS::AllowClientSendFirst);
166
void TLSFeature::onHandshaken()
168
Logger::debug() << Q_FUNC_INFO;
169
m_tls->continueAfterStep();
173
void TLSFeature::onClosed()
175
Logger::debug() << Q_FUNC_INFO;
179
void TLSFeature::onError()
181
Logger::debug() << Q_FUNC_INFO;
183
m_client->disconnectFromServer(true);
186
void TLSFeature::onDisconnected()
189
Logger::debug() << Q_FUNC_INFO;