MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), m_preferences(new Preferences), m_xmppClient(new QXmppClient(this)), m_loginWidget(new LoginWidget(this)) { ui->setupUi(this); initialize(); ui->treeWidget->setClient(m_xmppClient); // xmpp client connect(m_xmppClient, SIGNAL(connected()), this, SLOT(clientConnected())); connect(m_xmppClient, SIGNAL(disconnected()), this, SLOT(clientDisconnected()) ); connect(m_xmppClient, SIGNAL(error(QXmppClient::Error)), this, SLOT(clientError(QXmppClient::Error))); bool check = connect(m_xmppClient, SIGNAL(messageReceived(QXmppMessage)), this, SLOT(messageReceived(QXmppMessage))); Q_ASSERT(check); // qApp connect( qApp, SIGNAL(lastWindowClosed()), this, SLOT(quit()) ); // login connect(m_loginWidget, SIGNAL(login()), this, SLOT(login())); connect(m_loginWidget, SIGNAL(cancelLogin()), this, SLOT(cancelLogin())); }
void LoginHandler::prepareToSendIdentity() { if(m_mustAuth || m_needUserPassword) { dialogs::LoginDialog *logindlg = new dialogs::LoginDialog(_widgetParent); logindlg->setWindowModality(Qt::WindowModal); logindlg->setAttribute(Qt::WA_DeleteOnClose); logindlg->setWindowTitle(m_address.host()); logindlg->setUsername(m_address.userName(), true); if(m_mustAuth) logindlg->setIntroText(tr("This server does not allow guest logins")); else logindlg->setIntroText(tr("Password needed to log in as \"%1\"").arg(m_address.userName())); connect(logindlg, SIGNAL(rejected()), this, SLOT(cancelLogin())); connect(logindlg, SIGNAL(login(QString,QString)), this, SLOT(selectIdentity(QString,QString))); m_state = WAIT_FOR_LOGIN_PASSWORD; logindlg->show(); } else { sendIdentity(); } }
void LoginHandler::showPasswordDialog(const QString &title, const QString &text) { Q_ASSERT(_passwordDialog.isNull()); if(_selectorDialog) _selectorDialog->hide(); _passwordDialog = new dialogs::LoginDialog(_widgetParent); _passwordDialog->setWindowModality(Qt::WindowModal); _passwordDialog->setWindowTitle(title); _passwordDialog->setIntroText(text); _passwordDialog->setUsername(m_address.userName(), false); connect(_passwordDialog, SIGNAL(login(QString,QString)), this, SLOT(passwordSet(QString))); connect(_passwordDialog, SIGNAL(rejected()), this, SLOT(cancelLogin())); _passwordDialog->show(); }
void LoginHandler::expectIdentified(const protocol::ServerReply &msg) { if(msg.reply["state"] == "needPass") { // Looks like guest logins are not possible m_needUserPassword = true; prepareToSendIdentity(); return; } if(msg.reply["state"] != "identOk") { qWarning() << "Expected identOk state, got" << msg.reply["state"]; failLogin(tr("Invalid state")); return; } //bool isGuest = msg.reply["guest"].toBool(); QJsonArray flags = msg.reply["flags"].toArray(); if(m_mode == HOST) { m_state = EXPECT_SESSIONLIST_TO_HOST; // Query host password if needed if(m_mode == HOST && m_needHostPassword && !flags.contains("HOST")) { showPasswordDialog(tr("Password is needed to host a session"), tr("Enter hosting password")); } } else { // Show session selector if in multisession mode if(m_multisession) { _selectorDialog = new dialogs::SelectSessionDialog(m_sessions, _widgetParent); _selectorDialog->setWindowModality(Qt::WindowModal); _selectorDialog->setAttribute(Qt::WA_DeleteOnClose); connect(_selectorDialog, SIGNAL(selected(QString,bool)), this, SLOT(joinSelectedSession(QString,bool))); connect(_selectorDialog, SIGNAL(rejected()), this, SLOT(cancelLogin())); _selectorDialog->show(); } m_state = EXPECT_SESSIONLIST_TO_JOIN; } }
void LoginHandler::tlsStarted() { QSslCertificate cert = m_server->hostCertificate(); QString hostname = m_address.host(); // Check if this is a trusted certificate QFileInfo trustedCertFile = getCertFile(TRUSTED_HOSTS, hostname); if(trustedCertFile.exists()) { QList<QSslCertificate> trustedcerts = QSslCertificate::fromPath(trustedCertFile.absoluteFilePath()); if(trustedcerts.isEmpty() || trustedcerts.at(0).isNull()) { failLogin(tr("Invalid SSL certificate for host %1").arg(hostname)); } else if(trustedcerts.at(0) != cert) { failLogin(tr("Certificate of a trusted server has changed!")); } else { // Certificate matches explicitly trusted one, proceed with login m_server->_securityLevel = Server::TRUSTED_HOST; tlsAccepted(); } return; } // Check if we have seen this host certificate before QFileInfo certFile = getCertFile(KNOWN_HOSTS, hostname); if(certFile.exists()) { QList<QSslCertificate> knowncerts = QSslCertificate::fromPath(certFile.absoluteFilePath()); if(knowncerts.isEmpty() || knowncerts.at(0).isNull()) { failLogin(tr("Invalid SSL certificate for host %1").arg(hostname)); return; } if(knowncerts.at(0) != cert) { // Certificate mismatch! if(_selectorDialog) _selectorDialog->hide(); _certDialog = new QMessageBox(_widgetParent); _certDialog->setWindowTitle(hostname); _certDialog->setWindowModality(Qt::WindowModal); _certDialog->setIcon(QMessageBox::Warning); _certDialog->setText(tr("The certificate of this server has changed!")); QAbstractButton *continueBtn = _certDialog->addButton(tr("Continue"), QMessageBox::AcceptRole); _certDialog->addButton(QMessageBox::Cancel); // WTF, accepted() and rejected() signals do not work correctly: // http://qt-project.org/forums/viewthread/21172 // https://bugreports.qt-project.org/browse/QTBUG-23967 connect(_certDialog.data(), &QMessageBox::finished, [this, cert, certFile, continueBtn]() { if(_certDialog->clickedButton() == continueBtn) { saveCert(certFile, cert); tlsAccepted(); } else { cancelLogin(); } }); _certDialog->show(); m_server->_securityLevel = TcpServer::NEW_HOST; return; } else { m_server->_securityLevel = TcpServer::KNOWN_HOST; } } else { // Host not encountered yet: rember the certificate for next time saveCert(certFile, cert); m_server->_securityLevel = TcpServer::NEW_HOST; } // Certificate is acceptable tlsAccepted(); }