diff options
Diffstat (limited to 'liblightdm-qt')
-rw-r--r-- | liblightdm-qt/QLightDM/greeter.h | 13 | ||||
-rw-r--r-- | liblightdm-qt/greeter.cpp | 446 |
2 files changed, 77 insertions, 382 deletions
diff --git a/liblightdm-qt/QLightDM/greeter.h b/liblightdm-qt/QLightDM/greeter.h index c0b89b41..dea521d2 100644 --- a/liblightdm-qt/QLightDM/greeter.h +++ b/liblightdm-qt/QLightDM/greeter.h @@ -16,16 +16,15 @@ #include <QtCore/QObject> #include <QtCore/QVariant> -class GreeterPrivate; namespace QLightDM { + class GreeterPrivate; class Q_DECL_EXPORT Greeter : public QObject { Q_OBJECT public: - enum PromptType { PromptTypeQuestion, PromptTypeSecret @@ -65,16 +64,14 @@ public slots: bool startSessionSync(const QString &session=QString()); signals: - void showMessage(QString text, Greeter::MessageType type); - void showPrompt(QString text, Greeter::PromptType type); + void showMessage(QString text, QLightDM::Greeter::MessageType type); + void showPrompt(QString text, QLightDM::Greeter::PromptType type); void authenticationComplete(); void autologinTimerExpired(); -private slots: - void onRead(int fd); - private: - GreeterPrivate *d; + GreeterPrivate *d_ptr; + Q_DECLARE_PRIVATE(Greeter); }; }; diff --git a/liblightdm-qt/greeter.cpp b/liblightdm-qt/greeter.cpp index 9a6b3c2d..f8eca222 100644 --- a/liblightdm-qt/greeter.cpp +++ b/liblightdm-qt/greeter.cpp @@ -13,492 +13,190 @@ #include "QLightDM/greeter.h" -#include "config.h" - #include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QVariant> #include <QtCore/QSettings> -#include <QtCore/QUrl> -#include <QtCore/QFile> -#include <QtCore/QHash> -#include <QtCore/QSocketNotifier> -#include <QtDBus/QDBusPendingReply> -#include <QtDBus/QDBusInterface> -#include <QtDBus/QDBusReply> - -#include <security/pam_appl.h> - -/* Messages from the greeter to the server */ -typedef enum -{ - GREETER_MESSAGE_CONNECT = 0, - GREETER_MESSAGE_AUTHENTICATE, - GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, - GREETER_MESSAGE_CONTINUE_AUTHENTICATION, - GREETER_MESSAGE_START_SESSION, - GREETER_MESSAGE_CANCEL_AUTHENTICATION, - GREETER_MESSAGE_SET_LANGUAGE -} GreeterMessage; - -/* Messages from the server to the greeter */ -typedef enum -{ - SERVER_MESSAGE_CONNECTED = 0, - SERVER_MESSAGE_PROMPT_AUTHENTICATION, - SERVER_MESSAGE_END_AUTHENTICATION, - SERVER_MESSAGE_SESSION_RESULT -} ServerMessage; - -#define HEADER_SIZE 8 +#include <lightdm-gobject-1/lightdm.h> using namespace QLightDM; -class GreeterPrivate +class QLightDM::GreeterPrivate { public: - QHash<QString, QString> hints; - int toServerFd; - int fromServerFd; - QSocketNotifier *n; - char *readBuffer; - int nRead; - bool inAuthentication; - bool isAuthenticated; - QString authenticationUser; - int authenticateSequenceNumber; - bool cancellingAuthentication; - - void writeInt(int value); - void writeString(QString value); - void writeHeader(int id, int length); - void flush(); - char *readMessage(int *length, bool block); + GreeterPrivate(Greeter *parent); + LightDMGreeter *ldmGreeter; +protected: + Greeter* q_ptr; + + static void cb_showPrompt(LightDMGreeter *greeter, const gchar *text, LightDMPromptType type, gpointer data); + static void cb_showMessage(LightDMGreeter *greeter, const gchar *text, LightDMMessageType type, gpointer data); + static void cb_authenticationComplete(LightDMGreeter *greeter, gpointer data); + static void cb_autoLoginExpired(LightDMGreeter *greeter, gpointer data); + +private: + Q_DECLARE_PUBLIC(Greeter) }; -Greeter::Greeter(QObject *parent) : - QObject(parent), - d(new GreeterPrivate) +GreeterPrivate::GreeterPrivate(Greeter *parent) : + q_ptr(parent) { - d->readBuffer = (char *)malloc(HEADER_SIZE); - d->nRead = 0; - d->authenticateSequenceNumber = 0; + g_type_init(); + ldmGreeter = lightdm_greeter_new(); + + g_signal_connect (ldmGreeter, "show-prompt", G_CALLBACK (cb_showPrompt), this); + g_signal_connect (ldmGreeter, "show-message", G_CALLBACK (cb_showMessage), this); + g_signal_connect (ldmGreeter, "authentication-complete", G_CALLBACK (cb_authenticationComplete), this); + g_signal_connect (ldmGreeter, "autologin-timer-expired", G_CALLBACK (cb_autoLoginExpired), this); } -Greeter::~Greeter() +void GreeterPrivate::cb_showPrompt(LightDMGreeter *greeter, const gchar *text, LightDMPromptType type, gpointer data) { - delete d->readBuffer; - delete d; -} + Q_UNUSED(greeter); + + GreeterPrivate *that = static_cast<GreeterPrivate*>(data); + QString message = QString::fromLocal8Bit(text); + + //FIXME prompt type -static int intLength() -{ - return 4; + Q_EMIT that->q_func()->showPrompt(message, Greeter::PromptTypeSecret); } -static int stringLength(QString value) +void GreeterPrivate::cb_showMessage(LightDMGreeter *greeter, const gchar *text, LightDMMessageType type, gpointer data) { - QByteArray a = value.toUtf8(); - return intLength() + a.size(); -} + Q_UNUSED(greeter); -void GreeterPrivate::writeInt(int value) -{ - char buffer[4]; - buffer[0] = value >> 24; - buffer[1] = (value >> 16) & 0xFF; - buffer[2] = (value >> 8) & 0xFF; - buffer[3] = value & 0xFF; - if (write(toServerFd, buffer, intLength()) != intLength()) { - qDebug() << "Error writing to server"; - } -} + GreeterPrivate *that = static_cast<GreeterPrivate*>(data); + QString message = QString::fromLocal8Bit(text); -void GreeterPrivate::writeString(QString value) -{ - QByteArray a = value.toUtf8(); - writeInt(a.size()); - if (write(toServerFd, a.data(), a.size()) != a.size()) { - qDebug() << "Error writing to server"; - } -} + //FIXME prompt type -void GreeterPrivate::writeHeader(int id, int length) -{ - writeInt(id); - writeInt(length); + Q_EMIT that->q_func()->showMessage(message, Greeter::MessageTypeInfo); } -void GreeterPrivate::flush() +void GreeterPrivate::cb_authenticationComplete(LightDMGreeter *greeter, gpointer data) { - fsync(toServerFd); + Q_UNUSED(greeter); + GreeterPrivate *that = static_cast<GreeterPrivate*>(data); + Q_EMIT that->q_func()->authenticationComplete(); } -static int readInt(char *message, int messageLength, int *offset) +void GreeterPrivate::cb_autoLoginExpired(LightDMGreeter *greeter, gpointer data) { - if(messageLength - *offset < intLength()) { - qDebug() << "Not enough space for int, need " << intLength() << ", got " << (messageLength - *offset); - return 0; - } - - char *buffer = message + *offset; - int value = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; - *offset += intLength(); - return value; + Q_UNUSED(greeter); + GreeterPrivate *that = static_cast<GreeterPrivate*>(data); + Q_EMIT that->q_func()->autologinTimerExpired(); } -static int getMessageLength(char *message, int messageLength) +Greeter::Greeter(QObject *parent) : + QObject(parent), + d_ptr(new GreeterPrivate(this)) { - int offset = intLength(); - return readInt(message, messageLength, &offset); } -static QString readString(char *message, int messageLength, int *offset) +Greeter::~Greeter() { - int length = readInt(message, messageLength, offset); - if(messageLength - *offset < length) { - qDebug() << "Not enough space for string, need " << length << ", got " << (messageLength - *offset); - return ""; - } - char *start = message + *offset; - *offset += length; - return QString::fromUtf8(start, length); + delete d_ptr; } + bool Greeter::connectSync() { - QDBusConnection busType = QDBusConnection::systemBus(); - QString ldmBus(qgetenv("LIGHTDM_BUS")); - if(ldmBus == QLatin1String("SESSION")) { - busType = QDBusConnection::sessionBus(); - } - - char* fd = getenv("LIGHTDM_TO_SERVER_FD"); - if(!fd) { - qDebug() << "No LIGHTDM_TO_SERVER_FD environment variable"; - return false; - } - d->toServerFd = atoi(fd); - - qDebug() << "***connecting to server"; - QFile toServer; - qDebug() << toServer.open(d->toServerFd, QIODevice::WriteOnly); - - fd = getenv("LIGHTDM_FROM_SERVER_FD"); - if(!fd) { - qDebug() << "No LIGHTDM_FROM_SERVER_FD environment variable"; - return false; - } - d->fromServerFd = atoi(fd); - - d->n = new QSocketNotifier(d->fromServerFd, QSocketNotifier::Read); - connect(d->n, SIGNAL(activated(int)), this, SLOT(onRead(int))); - - qDebug() << "Connecting to display manager..."; - d->writeHeader(GREETER_MESSAGE_CONNECT, stringLength(VERSION)); - d->writeString(VERSION); - d->flush(); - - int responseLength; - char *response = d->readMessage(&responseLength, false); - if (!response) - return false; - - int offset = 0; - int id = readInt(response, responseLength, &offset); - int length = readInt(response, responseLength, &offset); - bool connected = false; - if (id == SERVER_MESSAGE_CONNECTED) - { - QString version = readString(response, responseLength, &offset); - QString hintString = ""; - while (offset < length) - { - QString name = readString(response, responseLength, &offset); - QString value = readString(response, responseLength, &offset); - hintString.append (" "); - hintString.append (name); - hintString.append ("="); - hintString.append (value); - } - - qDebug() << "Connected version=" << version << hintString; - connected = true; - } - else - qDebug() << "Expected CONNECTED message, got " << id; - free(response); - - return connected; + Q_D(Greeter); + return lightdm_greeter_connect_sync(d->ldmGreeter, NULL); } void Greeter::authenticate(const QString &username) { - d->inAuthentication = true; - d->isAuthenticated = false; - d->cancellingAuthentication = false; - d->authenticationUser = username; - qDebug() << "Starting authentication for user " << username << "..."; - d->writeHeader(GREETER_MESSAGE_AUTHENTICATE, intLength() + stringLength(username)); - d->authenticateSequenceNumber++; - d->writeInt(d->authenticateSequenceNumber); - d->writeString(username); - d->flush(); + Q_D(Greeter); + lightdm_greeter_authenticate(d->ldmGreeter, username.toLocal8Bit().data()); } void Greeter::authenticateAsGuest() { - d->authenticateSequenceNumber++; - d->inAuthentication = true; - d->isAuthenticated = false; - d->cancellingAuthentication = false; - d->authenticationUser = ""; - qDebug() << "Starting authentication for guest account"; - d->writeHeader(GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, intLength()); - d->writeInt(d->authenticateSequenceNumber); - d->flush(); + Q_D(Greeter); + lightdm_greeter_authenticate_as_guest(d->ldmGreeter); + } void Greeter::respond(const QString &response) { - qDebug() << "Providing response to display manager"; - d->writeHeader(GREETER_MESSAGE_CONTINUE_AUTHENTICATION, intLength() + stringLength(response)); - // FIXME: Could be multiple response required - d->writeInt(1); - d->writeString(response); - d->flush(); + Q_D(Greeter); + lightdm_greeter_respond(d->ldmGreeter, response.toLocal8Bit().data()); } void Greeter::cancelAuthentication() { - qDebug() << "Cancelling authentication"; - d->cancellingAuthentication = true; - d->writeHeader(GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0); - d->flush(); + Q_D(Greeter); + lightdm_greeter_cancel_authentication(d->ldmGreeter); } bool Greeter::inAuthentication() const { - return d->inAuthentication; + Q_D(const Greeter); + return lightdm_greeter_get_in_authentication(d->ldmGreeter); } bool Greeter::isAuthenticated() const { - return d->isAuthenticated; + Q_D(const Greeter); + return lightdm_greeter_get_is_authenticated(d->ldmGreeter); } QString Greeter::authenticationUser() const { - return d->authenticationUser; + Q_D(const Greeter); + const gchar* string = lightdm_greeter_get_authentication_user(d->ldmGreeter); + QString authenticationUser = QString::fromLocal8Bit(string); + return authenticationUser; } void Greeter::setLanguage (const QString &language) { - d->writeHeader(GREETER_MESSAGE_SET_LANGUAGE, stringLength(language)); - d->writeString (language); - d->flush(); } bool Greeter::startSessionSync(const QString &session) { - if (session.isEmpty()) { - qDebug() << "Starting default session"; - } - else { - qDebug() << "Starting session " << session; - } - - d->writeHeader(GREETER_MESSAGE_START_SESSION, stringLength(session)); - d->writeString(session); - d->flush(); - - int responseLength; - char *response = d->readMessage(&responseLength, false); - if (!response) { - return false; - } - - int offset = 0; - int id = readInt(response, responseLength, &offset); - readInt(response, responseLength, &offset); - int returnCode = -1; - if (id == SERVER_MESSAGE_SESSION_RESULT) { - returnCode = readInt(response, responseLength, &offset); - } - else { - qDebug() << "Expected SESSION_RESULT message, got " << id; - } - free(response); - - return returnCode == 0; -} - -char* GreeterPrivate::readMessage(int *length, bool block) -{ - /* Read the header, or the whole message if we already have that */ - int nToRead = HEADER_SIZE; - if(nRead >= HEADER_SIZE) { - nToRead += getMessageLength(readBuffer, nRead); - } - - do { - ssize_t nRead = read(fromServerFd, readBuffer + nRead, nToRead - nRead); - if(nRead < 0) { - qDebug() << "Error reading from server"; - return NULL; - } - - if (nRead == 0) { - qDebug() << "EOF reading from server"; - return NULL; - } - - qDebug() << "Read " << nRead << " octets from daemon"; - nRead += nRead; - } while(nRead < nToRead && block); - - /* Stop if haven't got all the data we want */ - if(nRead != nToRead) { - return NULL; - } - - /* If have header, rerun for content */ - if(nRead == HEADER_SIZE) { - nToRead = getMessageLength(readBuffer, nRead); - if(nToRead > 0) { - readBuffer = (char *)realloc(readBuffer, HEADER_SIZE + nToRead); - return readMessage(length, block); - } - } - - char *buffer = readBuffer; - *length = nRead; - - readBuffer = (char *)malloc(nRead); - nRead = 0; - - return buffer; + Q_D(Greeter); + return lightdm_greeter_start_session_sync(d->ldmGreeter, session.toLocal8Bit().constData(), NULL); } -void Greeter::onRead(int fd) -{ - qDebug() << "Reading from server"; - - int messageLength; - char *message = d->readMessage(&messageLength, false); - if (!message) { - return; - } - - int offset = 0; - int id = readInt(message, messageLength, &offset); - int length = readInt(message, messageLength, &offset); - int nMessages, sequenceNumber, returnCode; - QString version, username; - switch(id) { - case SERVER_MESSAGE_PROMPT_AUTHENTICATION: - sequenceNumber = readInt(message, messageLength, &offset); - username = readString(message, messageLength, &offset); - - d->authenticationUser = username; - - if (sequenceNumber == d->authenticateSequenceNumber && - !d->cancellingAuthentication) - { - nMessages = readInt(message, messageLength, &offset); - qDebug() << "Prompt user with " << nMessages << " message(s)"; - for(int i = 0; i < nMessages; i++) - { - int style = readInt(message, messageLength, &offset); - QString text = readString(message, messageLength, &offset); - - // FIXME: Should stop on prompts? - switch (style) - { - case PAM_PROMPT_ECHO_OFF: - emit showPrompt(text, Greeter::PromptTypeSecret); - break; - case PAM_PROMPT_ECHO_ON: - emit showPrompt(text, Greeter::PromptTypeQuestion); - break; - case PAM_ERROR_MSG: - emit showMessage(text, Greeter::MessageTypeError); - break; - case PAM_TEXT_INFO: - emit showMessage(text, Greeter::MessageTypeInfo); - break; - } - } - } - break; - case SERVER_MESSAGE_END_AUTHENTICATION: - sequenceNumber = readInt(message, messageLength, &offset); - username = readString(message, messageLength, &offset); - returnCode = readInt(message, messageLength, &offset); - - if (sequenceNumber == d->authenticateSequenceNumber) - { - qDebug() << "Authentication complete with return code " << returnCode; - - d->cancellingAuthentication = false; - d->isAuthenticated = (returnCode == 0); - d->authenticationUser = username; - d->inAuthentication = false; - emit authenticationComplete(); - } - else - qDebug () << "Ignoring end authentication with invalid sequence number " << sequenceNumber; - break; - default: - qDebug() << "Unknown message from server: " << id; - } - free(message); -} QString Greeter::getHint(const QString &name) const { - return d->hints.value (name); } QString Greeter::defaultSessionHint() const { - return getHint ("default-session"); } bool Greeter::hideUsersHint() const { - return d->hints.value ("hide-users", "true") == "true"; } bool Greeter::hasGuestAccountHint() const { - return d->hints.value ("has-guest-account", "false") == "true"; } QString Greeter::selectUserHint() const { - return getHint ("select-user"); } bool Greeter::selectGuestHint() const { - return d->hints.value ("select-guest", "false") == "true"; } QString Greeter::autologinUserHint() const { - return getHint ("autologin-user"); } bool Greeter::autologinGuestHint() const { - return d->hints.value ("autologin-guest", "false") == "true"; } int Greeter::autologinTimeoutHint() const { - return d->hints.value ("autologin-timeout", "0").toInt (); } #include "greeter_moc.cpp" |