diff options
author | Robert Ancell <robert.ancell@canonical.com> | 2011-11-30 13:39:56 +1100 |
---|---|---|
committer | Robert Ancell <robert.ancell@canonical.com> | 2011-11-30 13:39:56 +1100 |
commit | caa2b99d423b4af21c835f2443acab570e29e46e (patch) | |
tree | 9ad29bc7981f19805406ddb8973bf8c46dc845fa /liblightdm-qt/greeter.cpp | |
parent | c387eda5540025d0753cbc5f793c1e3dc2b49692 (diff) | |
parent | aeb8bedaf75b144dea7d12fedf9d5b5c18aefb9a (diff) | |
download | lightdm-caa2b99d423b4af21c835f2443acab570e29e46e.tar.gz |
Merge in liblightdm-qt-2 changes
Diffstat (limited to 'liblightdm-qt/greeter.cpp')
-rw-r--r-- | liblightdm-qt/greeter.cpp | 461 |
1 files changed, 95 insertions, 366 deletions
diff --git a/liblightdm-qt/greeter.cpp b/liblightdm-qt/greeter.cpp index bc8ec28a..8d6aaaff 100644 --- a/liblightdm-qt/greeter.cpp +++ b/liblightdm-qt/greeter.cpp @@ -10,482 +10,211 @@ * license. */ -#include "config.h" -#include "QLightDM/Greeter" +#include "QLightDM/greeter.h" -#include <security/pam_appl.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> - -/* 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.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; + 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(); -Greeter::~Greeter() -{ - delete d->readBuffer; - delete d; + 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); } -static int intLength() +void GreeterPrivate::cb_showPrompt(LightDMGreeter *greeter, const gchar *text, LightDMPromptType type, gpointer data) { - return 4; -} + Q_UNUSED(greeter); + + GreeterPrivate *that = static_cast<GreeterPrivate*>(data); + QString message = QString::fromLocal8Bit(text); + + //FIXME prompt type -static int stringLength(QString value) -{ - QByteArray a = value.toUtf8(); - return intLength() + a.size(); + Q_EMIT that->q_func()->showPrompt(message, Greeter::PromptTypeSecret); } -void Greeter::writeInt(int value) +void GreeterPrivate::cb_showMessage(LightDMGreeter *greeter, const gchar *text, LightDMMessageType type, gpointer data) { - char buffer[4]; - buffer[0] = value >> 24; - buffer[1] = (value >> 16) & 0xFF; - buffer[2] = (value >> 8) & 0xFF; - buffer[3] = value & 0xFF; - if (write(d->toServerFd, buffer, intLength()) != intLength()) { - qDebug() << "Error writing to server"; - } -} + Q_UNUSED(greeter); -void Greeter::writeString(QString value) -{ - QByteArray a = value.toUtf8(); - writeInt(a.size()); - if (write(d->toServerFd, a.data(), a.size()) != a.size()) { - qDebug() << "Error writing to server"; - } -} + GreeterPrivate *that = static_cast<GreeterPrivate*>(data); + QString message = QString::fromLocal8Bit(text); -void Greeter::writeHeader(int id, int length) -{ - writeInt(id); - writeInt(length); + //FIXME prompt type + + Q_EMIT that->q_func()->showMessage(message, Greeter::MessageTypeInfo); } -void Greeter::flush() +void GreeterPrivate::cb_authenticationComplete(LightDMGreeter *greeter, gpointer data) { - fsync(d->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..."; - writeHeader(GREETER_MESSAGE_CONNECT, stringLength(VERSION)); - writeString(VERSION); - flush(); - - int responseLength; - char *response = 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 << "..."; - writeHeader(GREETER_MESSAGE_AUTHENTICATE, intLength() + stringLength(username)); - d->authenticateSequenceNumber++; - writeInt(d->authenticateSequenceNumber); - writeString(username); - 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"; - writeHeader(GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, intLength()); - writeInt(d->authenticateSequenceNumber); - flush(); + Q_D(Greeter); + lightdm_greeter_authenticate_as_guest(d->ldmGreeter); + } void Greeter::respond(const QString &response) { - qDebug() << "Providing response to display manager"; - writeHeader(GREETER_MESSAGE_CONTINUE_AUTHENTICATION, intLength() + stringLength(response)); - // FIXME: Could be multiple response required - writeInt(1); - writeString(response); - flush(); + Q_D(Greeter); + lightdm_greeter_respond(d->ldmGreeter, response.toLocal8Bit().data()); } void Greeter::cancelAuthentication() { - qDebug() << "Cancelling authentication"; - d->cancellingAuthentication = true; - writeHeader(GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0); - 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); + return QString::fromLocal8Bit(lightdm_greeter_get_authentication_user(d->ldmGreeter)); } -void Greeter::setLanguage (QString language) +void Greeter::setLanguage (const QString &language) { - writeHeader(GREETER_MESSAGE_SET_LANGUAGE, stringLength(language)); - writeString (language); - flush(); + Q_D(Greeter); + lightdm_greeter_set_language(d->ldmGreeter, language.toLocal8Bit().constData()); } bool Greeter::startSessionSync(const QString &session) { - if (session == "") - qDebug() << "Starting default session"; - else - qDebug() << "Starting session " << session; - - writeHeader(GREETER_MESSAGE_START_SESSION, stringLength(session)); - writeString(session); - flush(); - - int responseLength; - char *response = 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; + Q_D(Greeter); + return lightdm_greeter_start_session_sync(d->ldmGreeter, session.toLocal8Bit().constData(), NULL); } -char *Greeter::readMessage(int *length, bool block) -{ - /* Read the header, or the whole message if we already have that */ - int nToRead = HEADER_SIZE; - if(d->nRead >= HEADER_SIZE) - nToRead += getMessageLength(d->readBuffer, d->nRead); - - do - { - ssize_t nRead = read(d->fromServerFd, d->readBuffer + d->nRead, nToRead - d->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"; - d->nRead += nRead; - } while(d->nRead < nToRead && block); - - /* Stop if haven't got all the data we want */ - if(d->nRead != nToRead) - return NULL; - - /* If have header, rerun for content */ - if(d->nRead == HEADER_SIZE) - { - nToRead = getMessageLength(d->readBuffer, d->nRead); - if(nToRead > 0) - { - d->readBuffer = (char *)realloc(d->readBuffer, HEADER_SIZE + nToRead); - return readMessage(length, block); - } - } - - char *buffer = d->readBuffer; - *length = d->nRead; - - d->readBuffer = (char *)malloc(d->nRead); - d->nRead = 0; - - return buffer; -} - -void Greeter::onRead(int fd) -{ - qDebug() << "Reading from server"; - - int messageLength; - char *message = 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, PROMPT_TYPE_SECRET); - break; - case PAM_PROMPT_ECHO_ON: - emit showPrompt(text, PROMPT_TYPE_QUESTION); - break; - case PAM_ERROR_MSG: - emit showMessage(text, MESSAGE_TYPE_ERROR); - break; - case PAM_TEXT_INFO: - emit showMessage(text, MESSAGE_TYPE_INFO); - 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(QString name) const +QString Greeter::getHint(const QString &name) const { - return d->hints.value (name); + Q_D(const Greeter); + return lightdm_greeter_get_hint(d->ldmGreeter, name.toLocal8Bit().constData()); } QString Greeter::defaultSessionHint() const { - return getHint ("default-session"); + Q_D(const Greeter); + return QString::fromLocal8Bit(lightdm_greeter_get_default_session_hint(d->ldmGreeter)); } bool Greeter::hideUsersHint() const { - return d->hints.value ("hide-users", "true") == "true"; + Q_D(const Greeter); + return lightdm_greeter_get_hide_users_hint(d->ldmGreeter); } bool Greeter::hasGuestAccountHint() const { - return d->hints.value ("has-guest-account", "false") == "true"; + Q_D(const Greeter); + return lightdm_greeter_get_has_guest_account_hint(d->ldmGreeter); } QString Greeter::selectUserHint() const { - return getHint ("select-user"); + Q_D(const Greeter); + return QString::fromLocal8Bit(lightdm_greeter_get_select_user_hint(d->ldmGreeter)); } bool Greeter::selectGuestHint() const { - return d->hints.value ("select-guest", "false") == "true"; + Q_D(const Greeter); + return lightdm_greeter_get_select_guest_hint(d->ldmGreeter); } QString Greeter::autologinUserHint() const { - return getHint ("autologin-user"); + Q_D(const Greeter); + return QString::fromLocal8Bit(lightdm_greeter_get_autologin_user_hint(d->ldmGreeter)); } bool Greeter::autologinGuestHint() const { - return d->hints.value ("autologin-guest", "false") == "true"; + Q_D(const Greeter); + return lightdm_greeter_get_autologin_guest_hint(d->ldmGreeter); } int Greeter::autologinTimeoutHint() const { - return d->hints.value ("autologin-timeout", "0").toInt (); + Q_D(const Greeter); + return lightdm_greeter_get_autologin_timeout_hint(d->ldmGreeter); } + +#include "greeter_moc.cpp" |