X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;f=src%2Fcore%2Fcore.cpp;h=b2e3ee431c10aa74d590ce5bf95571120ec3abe6;hb=eb3bfb3d7909160b3b34995d074d0bacb7ae77c0;hp=542d425031f9c7e591965af661e4246529505835;hpb=9bf0c85ec4cc3b2b52a17465e2991ee5ea73f396;p=quassel.git diff --git a/src/core/core.cpp b/src/core/core.cpp index 542d4250..b2e3ee43 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -40,6 +40,22 @@ # include #endif /* Q_OS_WIN32 */ +// ============================== +// Custom Events +// ============================== +const int Core::AddClientEventId = QEvent::registerEventType(); + +class AddClientEvent : public QEvent { +public: + AddClientEvent(QTcpSocket *socket, UserId uid) : QEvent(QEvent::Type(Core::AddClientEventId)), socket(socket), userId(uid) {} + QTcpSocket *socket; + UserId userId; +}; + + +// ============================== +// Core +// ============================== Core *Core::instanceptr = 0; Core *Core::instance() { @@ -151,11 +167,6 @@ void Core::init() { exit(0); } - if(Quassel::isOptionSet("add-user")) { - createUser(); - exit(0); - } - if(!_configured) { if(!_storageBackends.count()) { qWarning() << qPrintable(tr("Could not initialize any storage backend! Exiting...")); @@ -167,6 +178,16 @@ void Core::init() { qWarning() << "Core is currently not configured! Please connect with a Quassel Client for basic setup."; } + if(Quassel::isOptionSet("add-user")) { + createUser(); + exit(0); + } + + if(Quassel::isOptionSet("change-userpass")) { + changeUserPass(Quassel::optionValue("change-userpass")); + exit(0); + } + connect(&_server, SIGNAL(newConnection()), this, SLOT(incomingConnection())); connect(&_v6server, SIGNAL(newConnection()), this, SLOT(incomingConnection())); if(!startListening()) exit(1); // TODO make this less brutal @@ -542,6 +563,7 @@ void Core::processClientMessage(QTcpSocket *socket, const QVariantMap &msg) { clientInfo[socket] = msg; // store for future reference reply["MsgType"] = "ClientInitAck"; SignalProxy::writeDataToDevice(socket, reply); + socket->flush(); // ensure that the write cache is flushed before we switch to ssl #ifdef HAVE_SSL // after we told the client that we are ssl capable we switch to ssl mode @@ -642,19 +664,48 @@ void Core::clientDisconnected() { } void Core::setupClientSession(QTcpSocket *socket, UserId uid) { - // Find or create session for validated user - SessionThread *sess; - if(sessions.contains(uid)) sess = sessions[uid]; - else sess = createSession(uid); - // Hand over socket, session then sends state itself + // From now on everything is handled by the client session disconnect(socket, 0, this, 0); + socket->flush(); blocksizes.remove(socket); clientInfo.remove(socket); - if(!sess) { - qWarning() << qPrintable(tr("Could not initialize session for client:")) << qPrintable(socket->peerAddress().toString()); + + // Find or create session for validated user + SessionThread *session; + if(sessions.contains(uid)) { + session = sessions[uid]; + } else { + session = createSession(uid); + if(!session) { + qWarning() << qPrintable(tr("Could not initialize session for client:")) << qPrintable(socket->peerAddress().toString()); + socket->close(); + return; + } + } + + // as we are currently handling an event triggered by incoming data on this socket + // it is unsafe to directly move the socket to the client thread. + QCoreApplication::postEvent(this, new AddClientEvent(socket, uid)); +} + +void Core::customEvent(QEvent *event) { + if(event->type() == AddClientEventId) { + AddClientEvent *addClientEvent = static_cast(event); + addClientHelper(addClientEvent->socket, addClientEvent->userId); + return; + } +} + +void Core::addClientHelper(QTcpSocket *socket, UserId uid) { + // Find or create session for validated user + if(!sessions.contains(uid)) { + qWarning() << qPrintable(tr("Could not find a session for client:")) << qPrintable(socket->peerAddress().toString()); socket->close(); + return; } - sess->addClient(socket); + + SessionThread *session = sessions[uid]; + session->addClient(socket); } void Core::setupInternalClientSession(SignalProxy *proxy) { @@ -663,7 +714,13 @@ void Core::setupInternalClientSession(SignalProxy *proxy) { setupCoreForInternalUsage(); } - UserId uid = _storage->internalUser(); + UserId uid; + if(_storage) { + uid = _storage->internalUser(); + } else { + qWarning() << "Core::setupInternalClientSession(): You're trying to run monolithic Quassel with an unusable Backend! Go fix it!"; + return; + } // Find or create session for validated user SessionThread *sess; @@ -808,6 +865,44 @@ void Core::createUser() { } } +void Core::changeUserPass(const QString &username) { + QTextStream out(stdout); + QTextStream in(stdin); + UserId userId = _storage->getUserId(username); + if(!userId.isValid()) { + out << "User " << username << " does not exist." << endl; + return; + } + + out << "Change password for user: " << username << endl; + + disableStdInEcho(); + out << "New Password: "; + out.flush(); + QString password = in.readLine().trimmed(); + out << endl; + out << "Repeat Password: "; + out.flush(); + QString password2 = in.readLine().trimmed(); + out << endl; + enableStdInEcho(); + + if(password != password2) { + qWarning() << "Passwords don't match!"; + return; + } + if(password.isEmpty()) { + qWarning() << "Password is empty!"; + return; + } + + if(_storage->updateUser(userId, password)) { + out << "Password changed successfuly!" << endl; + } else { + qWarning() << "Failed to change password!"; + } +} + AbstractSqlMigrationReader *Core::getMigrationReader(Storage *storage) { if(!storage) return 0;