diff --git a/dbus/org.nemomobile.devicelock.AuthenticationInput.xml b/dbus/org.nemomobile.devicelock.AuthenticationInput.xml index 0f0d227..4d59e33 100644 --- a/dbus/org.nemomobile.devicelock.AuthenticationInput.xml +++ b/dbus/org.nemomobile.devicelock.AuthenticationInput.xml @@ -17,6 +17,9 @@ + + + diff --git a/dbus/org.nemomobile.devicelock.Authenticator.xml b/dbus/org.nemomobile.devicelock.Authenticator.xml index 8adb249..0ae27bd 100644 --- a/dbus/org.nemomobile.devicelock.Authenticator.xml +++ b/dbus/org.nemomobile.devicelock.Authenticator.xml @@ -8,6 +8,11 @@ + + + + + diff --git a/dbus/org.nemomobile.devicelock.Authorization.xml b/dbus/org.nemomobile.devicelock.Authorization.xml index dea26ff..0857211 100644 --- a/dbus/org.nemomobile.devicelock.Authorization.xml +++ b/dbus/org.nemomobile.devicelock.Authorization.xml @@ -4,6 +4,8 @@ + + diff --git a/dbus/org.nemomobile.devicelock.client.Authenticator.xml b/dbus/org.nemomobile.devicelock.client.Authenticator.xml index 0bf2964..f2ae38e 100644 --- a/dbus/org.nemomobile.devicelock.client.Authenticator.xml +++ b/dbus/org.nemomobile.devicelock.client.Authenticator.xml @@ -5,6 +5,9 @@ + + + diff --git a/rpm/nemo-qml-plugin-devicelock.spec b/rpm/nemo-qml-plugin-devicelock.spec index ea0f3a9..60c0b92 100644 --- a/rpm/nemo-qml-plugin-devicelock.spec +++ b/rpm/nemo-qml-plugin-devicelock.spec @@ -16,7 +16,6 @@ BuildRequires: pkgconfig(libsystemd-daemon) BuildRequires: pkgconfig(mce) BuildRequires: pkgconfig(nemodbus) Obsoletes: nemo-qml-plugin-devicelock-default < 0.2.0 -Requires: nemo-devicelock-daemon %description %{summary}. @@ -43,7 +42,6 @@ Requires: pkgconfig(nemodbus) Summary: Development libraries for device lock daemons Group: Development/Libraries Requires: %{name}-devel = %{version}-%{release} -Requires: nemo-devicelock-daemon-cli = %{version}-%{release} Requires: pkgconfig(keepalive) Requires: pkgconfig(libsystemd-daemon) Requires: pkgconfig(mce) diff --git a/src/nemo-devicelock/authenticationinput.cpp b/src/nemo-devicelock/authenticationinput.cpp index 0aa8807..224383b 100644 --- a/src/nemo-devicelock/authenticationinput.cpp +++ b/src/nemo-devicelock/authenticationinput.cpp @@ -434,6 +434,15 @@ void AuthenticationInput::requestSecurityCode() call(QStringLiteral("RequestSecurityCode"), m_localPath); } +/*! + Informs the security dialog that an action was authorized without authenticating. +*/ + +void AuthenticationInput::authorize() +{ + call(QStringLiteral("Authorize"), m_localPath); +} + /*! Sends a request to cancel authentication to the security daemon. */ diff --git a/src/nemo-devicelock/authenticationinput.h b/src/nemo-devicelock/authenticationinput.h index 43461e6..ac53f50 100644 --- a/src/nemo-devicelock/authenticationinput.h +++ b/src/nemo-devicelock/authenticationinput.h @@ -66,7 +66,7 @@ class NEMODEVICELOCK_EXPORT AuthenticationInput : public QObject, private Connec Q_OBJECT Q_PROPERTY(Authenticator::Methods utilizedMethods READ utilizedMethods NOTIFY utilizedMethodsChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged) - Q_PROPERTY(bool authenticatingProcess READ authenticatingPid NOTIFY authenticatingPidChanged) + Q_PROPERTY(int authenticatingProcess READ authenticatingPid NOTIFY authenticatingPidChanged) Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged) Q_PROPERTY(bool registered READ isRegistered WRITE setRegistered NOTIFY registeredChanged) Q_PROPERTY(int minimumCodeLength READ minimumCodeLength CONSTANT) @@ -76,6 +76,7 @@ class NEMODEVICELOCK_EXPORT AuthenticationInput : public QObject, private Connec Q_PROPERTY(CodeGeneration codeGeneration READ codeGeneration NOTIFY codeGenerationChanged) public: enum Feedback { + Authorize, EnterSecurityCode, EnterNewSecurityCode, RepeatNewSecurityCode, @@ -150,6 +151,7 @@ class NEMODEVICELOCK_EXPORT AuthenticationInput : public QObject, private Connec Q_INVOKABLE void enterSecurityCode(const QString &code); Q_INVOKABLE void requestSecurityCode(); + Q_INVOKABLE void authorize(); Q_INVOKABLE void cancel(); signals: @@ -164,7 +166,7 @@ class NEMODEVICELOCK_EXPORT AuthenticationInput : public QObject, private Connec void codeGenerationChanged(); void codeInputIsKeyboardChanged(); - void authenticationStarted(Feedback feedback, const QVariant &data); + void authenticationStarted(Feedback feedback, const QVariantMap &data); void authenticationUnavailable(Error error); void authenticationEvaluating(); void authenticationProgress(int current, int maximum); diff --git a/src/nemo-devicelock/authenticator.cpp b/src/nemo-devicelock/authenticator.cpp index e5e51f9..8b2520f 100644 --- a/src/nemo-devicelock/authenticator.cpp +++ b/src/nemo-devicelock/authenticator.cpp @@ -49,6 +49,11 @@ void AuthenticatorAdaptor::Authenticated(const QDBusVariant &authenticationToken m_authenticator->handleAuthentication(authenticationToken.variant()); } +void AuthenticatorAdaptor::PermissionGranted(uint method) +{ + m_authenticator->handlePermissionGranted(Authenticator::Method(method)); +} + void AuthenticatorAdaptor::Aborted() { m_authenticator->handleAborted(); @@ -142,6 +147,40 @@ void Authenticator::authenticate(const QVariant &challengeCode, Methods methods) emit authenticatingChanged(); } +/*! + Requests the user grant permission for an action described by \a message and \a properties + using one of the given authentication \a methods. + + The properties map may contain one of the following values: + + \table + \header + \li Key + \li Value + \row + \li authenticatingPid + \li The PID of the application permissions are being requested for. + \endtable +*/ + +void Authenticator::requestPermission( + const QString &message, const QVariantMap &properties, Methods methods) +{ + const auto response = call( + QStringLiteral("RequestPermission"), m_localPath, message, properties, uint(methods)); + + m_authenticating = true; + + response->onError([this](const QDBusError &) { + m_authenticating = false; + + emit aborted(); + emit authenticatingChanged(); + }); + + emit authenticatingChanged(); +} + /*! Cancels an active authentication request. */ @@ -174,6 +213,23 @@ void Authenticator::handleAuthentication(const QVariant &authenticationToken) } } +/*! + \signal NemoDeviceLock::Authenticator::permissionGranted(Method method) + + Signals that the user has successfully granted permission for the requested + action using the given authentication \a method. +*/ + +void Authenticator::handlePermissionGranted(Method method) +{ + if (m_authenticating) { + m_authenticating = false; + + emit permissionGranted(method); + emit authenticatingChanged(); + } +} + /*! \signal NemoDeviceLock::Authenticator::aborted() diff --git a/src/nemo-devicelock/authenticator.h b/src/nemo-devicelock/authenticator.h index 6f5ab46..9aac53e 100644 --- a/src/nemo-devicelock/authenticator.h +++ b/src/nemo-devicelock/authenticator.h @@ -52,6 +52,7 @@ class AuthenticatorAdaptor : public QDBusAbstractAdaptor public slots: Q_NOREPLY void Authenticated(const QDBusVariant &authenticationToken); + Q_NOREPLY void PermissionGranted(uint method); Q_NOREPLY void Aborted(); private: @@ -67,9 +68,11 @@ class NEMODEVICELOCK_EXPORT Authenticator : public QObject, private ConnectionCl Q_FLAGS(Methods) public: enum Method { - NoAuthentication = 0x00, - SecurityCode = 0x01, - Fingerprint = 0x02 + NoAuthentication = 0x000, + SecurityCode = 0x0001, + Fingerprint = 0x0002, + Confirmation = 0x1000, + AllAvailable = SecurityCode | Fingerprint | Confirmation }; Q_DECLARE_FLAGS(Methods, Method) @@ -81,7 +84,9 @@ class NEMODEVICELOCK_EXPORT Authenticator : public QObject, private ConnectionCl bool isAuthenticating() const; Q_INVOKABLE void authenticate( - const QVariant &challengeCode, Methods methods = Methods(SecurityCode | Fingerprint)); + const QVariant &challengeCode, Methods methods = AllAvailable); + Q_INVOKABLE void requestPermission( + const QString &message, const QVariantMap &properties, Methods methods = AllAvailable); Q_INVOKABLE void cancel(); signals: @@ -89,6 +94,7 @@ class NEMODEVICELOCK_EXPORT Authenticator : public QObject, private ConnectionCl void authenticatingChanged(); void authenticated(const QVariant &authenticationToken); + void permissionGranted(Method method); void aborted(); private: @@ -97,6 +103,7 @@ class NEMODEVICELOCK_EXPORT Authenticator : public QObject, private ConnectionCl inline void connected(); inline void handleAuthentication(const QVariant &authenticationToken); + inline void handlePermissionGranted(Method method); inline void handleAborted(); AuthenticatorAdaptor m_adaptor; diff --git a/src/nemo-devicelock/host/cli/cliauthenticator.cpp b/src/nemo-devicelock/host/cli/cliauthenticator.cpp index b81449b..73a76cb 100644 --- a/src/nemo-devicelock/host/cli/cliauthenticator.cpp +++ b/src/nemo-devicelock/host/cli/cliauthenticator.cpp @@ -103,7 +103,7 @@ void CliAuthenticator::enterSecurityCode(const QString &code) m_securityCode.clear(); } -QVariant CliAuthenticator::authenticateChallengeCode(const QVariant &) +QVariant CliAuthenticator::authenticateChallengeCode(const QVariant &, Authenticator::Method, uint) { return m_securityCode; } diff --git a/src/nemo-devicelock/host/cli/cliauthenticator.h b/src/nemo-devicelock/host/cli/cliauthenticator.h index 64c2de0..d4a6400 100644 --- a/src/nemo-devicelock/host/cli/cliauthenticator.h +++ b/src/nemo-devicelock/host/cli/cliauthenticator.h @@ -58,7 +58,8 @@ class CliAuthenticator : public HostAuthenticator bool clearCode(const QString &code) override; void enterSecurityCode(const QString &code); - QVariant authenticateChallengeCode(const QVariant &challengeCode); + QVariant authenticateChallengeCode( + const QVariant &challengeCode, Authenticator::Method method, uint authenticatingPid) override; private: QExplicitlySharedDataPointer m_watcher; diff --git a/src/nemo-devicelock/host/hostauthenticationinput.cpp b/src/nemo-devicelock/host/hostauthenticationinput.cpp index 9c00b39..cf266ac 100644 --- a/src/nemo-devicelock/host/hostauthenticationinput.cpp +++ b/src/nemo-devicelock/host/hostauthenticationinput.cpp @@ -73,12 +73,17 @@ void HostAuthenticationInputAdaptor::Cancel(const QDBusObjectPath &path) m_authenticationInput->handleCancel(path.path()); } +void HostAuthenticationInputAdaptor::Authorize(const QDBusObjectPath &path) +{ + m_authenticationInput->handleAuthorize(path.path()); +} + HostAuthenticationInput::HostAuthenticationInput( const QString &path, Authenticator::Methods supportedMethods, QObject *parent) : HostObject(path, parent) , m_adaptor(this) , m_settings(SettingsWatcher::instance()) - , m_supportedMethods(supportedMethods) + , m_supportedMethods(supportedMethods | Authenticator::Confirmation) // Basic yes/no confirmation is always supported. , m_activeMethods() , m_authenticating(false) { @@ -88,60 +93,81 @@ HostAuthenticationInput::~HostAuthenticationInput() { } +void HostAuthenticationInput::authorize() +{ +} + void HostAuthenticationInput::authenticationStarted( Authenticator::Methods methods, + uint authenticatingPid, AuthenticationInput::Feedback) { + Q_UNUSED(authenticatingPid); + qCDebug(daemon, "Authentication started"); m_authenticating = true; m_activeMethods = methods & m_supportedMethods; } +void HostAuthenticationInput::startAuthentication( + AuthenticationInput::Feedback feedback, + const QVariantMap &data, + Authenticator::Methods methods) +{ + const uint pid = connectionPid(QDBusContext::connection()); + if (pid != 0) { + startAuthentication(feedback, pid, data, methods); + } +} void HostAuthenticationInput::startAuthentication( AuthenticationInput::Feedback feedback, + uint authenticatingPid, const QVariantMap &data, Authenticator::Methods methods) { qCDebug(daemon, "Authentication started"); - const uint pid = connectionPid(QDBusContext::connection()); - - if (pid != 0 && !m_inputStack.isEmpty()) { - authenticationStarted(methods, feedback); + if (!m_inputStack.isEmpty()) { + authenticationStarted(methods, authenticatingPid, feedback); NemoDBus::send( m_inputStack.last().connection, m_inputStack.last().path, clientInterface, QStringLiteral("AuthenticationStarted"), - pid, + authenticatingPid, uint(m_activeMethods), uint(feedback), data); } } - void HostAuthenticationInput::authenticationUnavailable(AuthenticationInput::Error error) { - qCDebug(daemon, "Authentication unavailable"); - const uint pid = connectionPid(QDBusContext::connection()); + if (pid != 0) { + authenticationUnavailable(error, pid); + } +} - if (pid != 0 && !m_inputStack.isEmpty()) { +void HostAuthenticationInput::authenticationUnavailable( + AuthenticationInput::Error error, uint authenticatingPid) +{ + qCDebug(daemon, "Authentication unavailable"); + + if (!m_inputStack.isEmpty()) { NemoDBus::send( m_inputStack.last().connection, m_inputStack.last().path, clientInterface, QStringLiteral("AuthenticationUnavailable"), - pid, + authenticatingPid, uint(error)); } } - void HostAuthenticationInput::authenticationResumed( AuthenticationInput::Feedback feedback, const QVariantMap &data, @@ -213,6 +239,7 @@ void HostAuthenticationInput::authenticationEnded(bool confirmed) void HostAuthenticationInput::setRegistered(const QString &path, bool registered) { const auto pid = connectionPid(QDBusContext::connection()); + if (pid == 0 || !authorizeInput(pid)) { QDBusContext::sendErrorReply(QDBusError::AccessDenied); return; @@ -440,4 +467,14 @@ void HostAuthenticationInput::handleCancel(const QString &path) } } +void HostAuthenticationInput::handleAuthorize(const QString &path) +{ + const auto connection = QDBusContext::connection().name(); + if (!m_inputStack.isEmpty() + && m_inputStack.last().connection == connection + && m_inputStack.last().path == path) { + authorize(); + } +} + } diff --git a/src/nemo-devicelock/host/hostauthenticationinput.h b/src/nemo-devicelock/host/hostauthenticationinput.h index 04d9dc4..01875c3 100644 --- a/src/nemo-devicelock/host/hostauthenticationinput.h +++ b/src/nemo-devicelock/host/hostauthenticationinput.h @@ -56,6 +56,7 @@ public slots: void SetActive(const QDBusObjectPath &path, bool active); void EnterSecurityCode(const QDBusObjectPath &path, const QString &code); void RequestSecurityCode(const QDBusObjectPath &path); + void Authorize(const QDBusObjectPath &path); void Cancel(const QDBusObjectPath &path); private: @@ -110,17 +111,28 @@ class HostAuthenticationInput : public HostObject virtual void enterSecurityCode(const QString &code) = 0; virtual void requestSecurityCode() = 0; + virtual void authorize(); void cancel() override = 0; // Client + Authenticator::Methods activeMethods() const { return m_activeMethods; } + void startAuthentication( AuthenticationInput::Feedback feedback, const QVariantMap &data, Authenticator::Methods methods); + void startAuthentication( + AuthenticationInput::Feedback feedback, + uint authenticatingPid, + const QVariantMap &data, + Authenticator::Methods methods); + virtual void authenticationStarted( Authenticator::Methods methods, + uint authenticatingPid, AuthenticationInput::Feedback feedback = AuthenticationInput::EnterSecurityCode); void authenticationUnavailable(AuthenticationInput::Error error); + void authenticationUnavailable(AuthenticationInput::Error error, uint authenticatingPid); void authenticationResumed( AuthenticationInput::Feedback feedback, const QVariantMap &data = QVariantMap(), @@ -132,9 +144,9 @@ class HostAuthenticationInput : public HostObject virtual void authenticationActive(Authenticator::Methods methods); virtual void authenticationInactive(); - virtual void confirmAuthentication() = 0; + virtual void confirmAuthentication(Authenticator::Method method) = 0; virtual void abortAuthentication(AuthenticationInput::Error error); - +\ // Signals void feedback( AuthenticationInput::Feedback feedback, @@ -159,7 +171,7 @@ class HostAuthenticationInput : public HostObject struct Input { - Input() {} + Input() = default; Input(const QString &connection, const QString &path) : connection(connection), path(path) {} QString connection; @@ -169,6 +181,7 @@ class HostAuthenticationInput : public HostObject inline void handleEnterSecurityCode(const QString &client, const QString &code); inline void handleRequestSecurityCode(const QString &path); inline void handleCancel(const QString &client); + inline void handleAuthorize(const QString &client); inline void setRegistered(const QString &path, bool registered); inline void setActive(const QString &path, bool active); diff --git a/src/nemo-devicelock/host/hostauthenticator.cpp b/src/nemo-devicelock/host/hostauthenticator.cpp index e70a7bc..66d330b 100644 --- a/src/nemo-devicelock/host/hostauthenticator.cpp +++ b/src/nemo-devicelock/host/hostauthenticator.cpp @@ -34,6 +34,12 @@ #include "settingswatcher.h" +#include +#include +#include + +#include + namespace NemoDeviceLock { @@ -58,6 +64,12 @@ void HostAuthenticatorAdaptor::Authenticate( path.path(), challengeCode.variant(), Authenticator::Methods(methods)); } +void HostAuthenticatorAdaptor::RequestPermission( + const QDBusObjectPath &path, const QString &message, const QVariantMap &properties, uint methods) +{ + m_authenticator->requestPermission(path.path(), message, properties, Authenticator::Methods(methods)); +} + void HostAuthenticatorAdaptor::Cancel(const QDBusObjectPath &path) { m_authenticator->handleCancel(path.path()); @@ -99,6 +111,7 @@ HostAuthenticator::HostAuthenticator(Authenticator::Methods supportedMethods, QO , m_adaptor(this) , m_securityCodeAdaptor(this) , m_repeatsRequired(0) + , m_authenticatingPid(0) , m_state(Idle) { } @@ -135,15 +148,24 @@ void HostAuthenticator::authenticate( const auto availability = this->availability(); switch (availability) { case AuthenticationNotRequired: - qCDebug(daemon, "Authentication requested. Unsecured, authenticating immediately."); - confirmAuthentication(); + if (methods & Authenticator::Confirmation) { + qCDebug(daemon, "Authentication requested. Requesting simple confirmation."); + startAuthentication(AuthenticationInput::Authorize, QVariantMap(), Authenticator::Confirmation); + } else { + qCDebug(daemon, "Authentication requested. Unsecured, authenticating immediately."); + confirmAuthentication(Authenticator::NoAuthentication); + } break; case CanAuthenticateSecurityCode: - methods &= Authenticator::SecurityCode; + methods &= Authenticator::SecurityCode | Authenticator::Confirmation; // Fall through. case CanAuthenticate: qCDebug(daemon, "Authentication requested using methods %i.", int(methods)); - startAuthentication(AuthenticationInput::EnterSecurityCode, QVariantMap(), methods); + if (methods == Authenticator::Confirmation) { + startAuthentication(AuthenticationInput::Authorize, QVariantMap(), Authenticator::Confirmation); + } else { + startAuthentication(AuthenticationInput::EnterSecurityCode, QVariantMap(), methods); + } break; case SecurityCodeRequired: m_challengeCode.clear(); @@ -159,6 +181,55 @@ void HostAuthenticator::authenticate( } } + +void HostAuthenticator::requestPermission( + const QString &client, + const QString &message, + const QVariantMap &properties, + Authenticator::Methods methods) +{ + cancel(); + setActiveClient(client); + + m_state = RequestingPermission; + + const uint authenticatingPid = properties.value( + QStringLiteral("authenticatingPid"), + QVariant::fromValue(connectionPid(QDBusContext::connection()))).toUInt(); + + const QVariantMap data = { + { QStringLiteral("message"), message } + }; + + const auto availability = this->availability(); + switch (availability) { + case AuthenticationNotRequired: + qCDebug(daemon, "Authentication requested. Requesting simple confirmation."); + startAuthentication(AuthenticationInput::Authorize, authenticatingPid, data, Authenticator::Confirmation); + break; + case CanAuthenticateSecurityCode: + methods &= Authenticator::SecurityCode | Authenticator::Confirmation; + // Fall through. + case CanAuthenticate: + qCDebug(daemon, "Authentication requested using methods %i.", int(methods)); + if (methods == Authenticator::Confirmation) { + startAuthentication(AuthenticationInput::Authorize, authenticatingPid, data, methods); + } else { + startAuthentication(AuthenticationInput::EnterSecurityCode, authenticatingPid, data, methods); + } + break; + case SecurityCodeRequired: + authenticationUnavailable(AuthenticationInput::FunctionUnavailable, authenticatingPid); + break; + case CodeEntryLockedRecoverable: + case CodeEntryLockedPermanent: + case ManagerLockedRecoverable: + case ManagerLockedPermanent: + lockedOut(); + break; + } +} + void HostAuthenticator::handleChangeSecurityCode(const QString &client, const QVariant &challengeCode) { const auto pid = connectionPid(QDBusContext::connection()); @@ -233,11 +304,12 @@ void HostAuthenticator::enterSecurityCode(const QString &code) case Idle: return; case Authenticating: + case RequestingPermission: qCDebug(daemon, "Security code entered for authentication."); switch ((attempts = checkCode(code))) { case Success: case SecurityCodeExpired: - confirmAuthentication(); + confirmAuthentication(Authenticator::SecurityCode); return; case LockedOut: lockedOut(); @@ -342,6 +414,23 @@ void HostAuthenticator::requestSecurityCode() } } +void HostAuthenticator::authorize() +{ + switch (m_state) { + case Authenticating: + case RequestingPermission: + if (activeMethods() == Authenticator::Confirmation) { + qCDebug(daemon, "Action authorized without authentication."); + confirmAuthentication(Authenticator::Confirmation); + } else { + qCWarning(daemon, "Authorization requires authentication, rejecting."); + } + break; + default: + break; + } +} + void HostAuthenticator::setCodeFinished(int result) { switch (result) { @@ -349,7 +438,8 @@ void HostAuthenticator::setCodeFinished(int result) m_currentCode.clear(); qCDebug(daemon, "Security code changed."); - securityCodeChanged(authenticateChallengeCode(m_challengeCode)); + securityCodeChanged(authenticateChallengeCode( + m_challengeCode, Authenticator::SecurityCode, m_authenticatingPid)); break; case SecurityCodeInHistory: if (m_state == ChangeCanceled) { @@ -377,9 +467,14 @@ void HostAuthenticator::setCodeFinished(int result) } } -void HostAuthenticator::confirmAuthentication() +void HostAuthenticator::confirmAuthentication(Authenticator::Method method) { - authenticated(authenticateChallengeCode(m_challengeCode)); + if (m_state == RequestingPermission) { + sendToActiveClient(authenticatorInterface, QStringLiteral("PermissionGranted"), uint(method)); + authenticationEnded(true); + } else { + authenticated(authenticateChallengeCode(m_challengeCode, method, m_authenticatingPid)); + } } void HostAuthenticator::abortAuthentication(AuthenticationInput::Error error) @@ -388,6 +483,9 @@ void HostAuthenticator::abortAuthentication(AuthenticationInput::Error error) case Authenticating: m_state = AuthenticationError; break; + case RequestingPermission: + m_state = AuthenticationError; + break; case AuthenticatingForChange: case EnteringNewSecurityCode: case RepeatingNewSecurityCode: @@ -404,10 +502,19 @@ void HostAuthenticator::abortAuthentication(AuthenticationInput::Error error) HostAuthenticationInput::abortAuthentication(error); } +void HostAuthenticator::authenticationStarted( + Authenticator::Methods methods, uint authenticatingPid, AuthenticationInput::Feedback feedback) +{ + m_authenticatingPid = authenticatingPid; + + HostAuthenticationInput::authenticationStarted(methods, authenticatingPid, feedback); +} + void HostAuthenticator::authenticationEnded(bool confirmed) { clearActiveClient(); + m_authenticatingPid = 0; m_challengeCode.clear(); m_state = Idle; m_currentCode.clear(); @@ -421,6 +528,7 @@ void HostAuthenticator::cancel() switch (m_state) { case Authenticating: case AuthenticationError: + case RequestingPermission: aborted(); break; case AuthenticatingForChange: diff --git a/src/nemo-devicelock/host/hostauthenticator.h b/src/nemo-devicelock/host/hostauthenticator.h index 996443d..c3cd494 100644 --- a/src/nemo-devicelock/host/hostauthenticator.h +++ b/src/nemo-devicelock/host/hostauthenticator.h @@ -34,10 +34,11 @@ #define NEMODEVICELOCK_HOSTAUTHENTICATOR_H #include -#include +#include #include #include +#include #include #include @@ -61,6 +62,8 @@ class HostAuthenticatorAdaptor : public QDBusAbstractAdaptor public slots: void Authenticate(const QDBusObjectPath &client, const QDBusVariant &challengeCode, uint methods); + void RequestPermission( + const QDBusObjectPath &path, const QString &message, const QVariantMap &properties, uint methods); void Cancel(const QDBusObjectPath &client); private: @@ -102,7 +105,8 @@ class HostAuthenticator : public HostAuthenticationInput // Authenticator virtual Authenticator::Methods availableMethods() const = 0; - virtual QVariant authenticateChallengeCode(const QVariant &challengeCode) = 0; + virtual QVariant authenticateChallengeCode( + const QVariant &challengeCode, Authenticator::Method method, uint authenticatingPid) = 0; // SecurityCodeSettings virtual bool authorizeSecurityCodeSettings(unsigned long pid); @@ -116,10 +120,13 @@ class HostAuthenticator : public HostAuthenticationInput void enterSecurityCode(const QString &code) override; void requestSecurityCode() override; + void authorize() override; void cancel() override; - void confirmAuthentication() override; + void confirmAuthentication(Authenticator::Method method) override; void abortAuthentication(AuthenticationInput::Error error) override; + void authenticationStarted( + Authenticator::Methods methods, uint authenticatingPid, AuthenticationInput::Feedback feedback) override; void authenticationEnded(bool confirmed) override; void setCodeFinished(int result); @@ -143,6 +150,7 @@ class HostAuthenticator : public HostAuthenticationInput Authenticating, AuthenticationError, AuthenticatingForChange, + RequestingPermission, EnteringNewSecurityCode, RepeatingNewSecurityCode, ExpectingGeneratedSecurityCode, @@ -156,6 +164,11 @@ class HostAuthenticator : public HostAuthenticationInput inline bool isSecurityCodeSet() const; inline void authenticate( const QString &authenticator, const QVariant &challengeCode, Authenticator::Methods methods); + inline void requestPermission( + const QString &client, + const QString &message, + const QVariantMap &properties, + Authenticator::Methods methods); inline void handleChangeSecurityCode(const QString &client, const QVariant &challengeCode); inline void handleClearSecurityCode(const QString &client); inline void handleCancel(const QString &client); @@ -173,6 +186,7 @@ class HostAuthenticator : public HostAuthenticationInput QString m_newCode; QString m_generatedCode; int m_repeatsRequired; + int m_authenticatingPid; State m_state; }; diff --git a/src/nemo-devicelock/host/hostauthorization.cpp b/src/nemo-devicelock/host/hostauthorization.cpp index 66e02f8..5df440d 100644 --- a/src/nemo-devicelock/host/hostauthorization.cpp +++ b/src/nemo-devicelock/host/hostauthorization.cpp @@ -45,9 +45,10 @@ HostAuthorizationAdaptor::HostAuthorizationAdaptor(HostAuthorization *authorizat { } -void HostAuthorizationAdaptor::RequestChallenge(const QDBusObjectPath &path) +void HostAuthorizationAdaptor::RequestChallenge( + const QDBusObjectPath &path, uint requestedMethods, uint authenticatingPid) { - m_authorization->requestChallenge(path.path()); + m_authorization->requestChallenge(path.path(), Authenticator::Methods(requestedMethods), authenticatingPid); } void HostAuthorizationAdaptor::RelinquishChallenge(const QDBusObjectPath &path) @@ -67,13 +68,14 @@ HostAuthorization::~HostAuthorization() { } -void HostAuthorization::requestChallenge(const QString &) +void HostAuthorization::requestChallenge(const QString &, Authenticator::Methods requestedMethods, uint) { - if (m_allowedMethods) { + const auto methods = m_allowedMethods & requestedMethods; + if (methods) { QDBusContext::setDelayedReply(true); QDBusContext::connection().send(QDBusContext::message().createReply(NemoDBus::marshallArguments( - QVariant(0), uint(m_allowedMethods)))); + QVariant(0), uint(methods)))); } else { QDBusContext::sendErrorReply(QDBusError::NotSupported); } diff --git a/src/nemo-devicelock/host/hostauthorization.h b/src/nemo-devicelock/host/hostauthorization.h index 31b6d36..18d9c55 100644 --- a/src/nemo-devicelock/host/hostauthorization.h +++ b/src/nemo-devicelock/host/hostauthorization.h @@ -52,7 +52,7 @@ class HostAuthorizationAdaptor : public QDBusAbstractAdaptor explicit HostAuthorizationAdaptor(HostAuthorization *authorization); public slots: - void RequestChallenge(const QDBusObjectPath &path); + void RequestChallenge(const QDBusObjectPath &path, uint requestedMethods, uint authenticatingPid); void RelinquishChallenge(const QDBusObjectPath &path); private: @@ -68,7 +68,7 @@ class HostAuthorization : public HostObject ~HostAuthorization(); protected: - virtual void requestChallenge(const QString &client); + virtual void requestChallenge(const QString &client, Authenticator::Methods requestedMethods, uint authenticatingPid); virtual void relinquishChallenge(const QString &client); void challengeExpired(const QString &connection, const QString &client); diff --git a/src/nemo-devicelock/host/hostdevicelock.cpp b/src/nemo-devicelock/host/hostdevicelock.cpp index 555a4a9..e31d918 100644 --- a/src/nemo-devicelock/host/hostdevicelock.cpp +++ b/src/nemo-devicelock/host/hostdevicelock.cpp @@ -149,7 +149,7 @@ void HostDeviceLock::enterSecurityCode(const QString &code) case Authenticating: { switch (const int result = checkCode(code)) { case Success: - unlockFinished(unlockWithCode(code)); + unlockFinished(unlockWithCode(code), Authenticator::SecurityCode); break; case SecurityCodeExpired: m_state = EnteringNewSecurityCode; @@ -237,11 +237,11 @@ void HostDeviceLock::requestSecurityCode() } } -void HostDeviceLock::unlockFinished(int result) +void HostDeviceLock::unlockFinished(int result, Authenticator::Method method) { switch (result) { case Success: - confirmAuthentication(); + confirmAuthentication(method); break; case Evaluating: if (m_state == Authenticating) { @@ -274,7 +274,7 @@ void HostDeviceLock::setCodeFinished(int result) qCDebug(daemon, "Security code changed."); m_currentCode.clear(); if (m_state == ChangingSecurityCode || m_state == RepeatingNewSecurityCode) { - unlockFinished(unlockWithCode(m_newCode)); + unlockFinished(unlockWithCode(m_newCode), Authenticator::SecurityCode); } else if (m_state == Canceled) { m_state = Idle; @@ -329,7 +329,7 @@ void HostDeviceLock::cancel() } } -void HostDeviceLock::confirmAuthentication() +void HostDeviceLock::confirmAuthentication(Authenticator::Method) { m_state = Idle; diff --git a/src/nemo-devicelock/host/hostdevicelock.h b/src/nemo-devicelock/host/hostdevicelock.h index 97c5b69..2f583f1 100644 --- a/src/nemo-devicelock/host/hostdevicelock.h +++ b/src/nemo-devicelock/host/hostdevicelock.h @@ -94,7 +94,7 @@ class HostDeviceLock : public HostAuthenticationInput virtual bool isLocked() const = 0; virtual void setLocked(bool locked) = 0; - void confirmAuthentication() override; + void confirmAuthentication(Authenticator::Method method) override; void abortAuthentication(AuthenticationInput::Error error) override; void lockedChanged(); @@ -102,7 +102,7 @@ class HostDeviceLock : public HostAuthenticationInput virtual void automaticLockingChanged(); - void unlockFinished(int result); + void unlockFinished(int result, Authenticator::Method method); void setCodeFinished(int result); // Signals diff --git a/src/nemo-devicelock/host/hostservice.cpp b/src/nemo-devicelock/host/hostservice.cpp index d5a4622..4d2a4f8 100644 --- a/src/nemo-devicelock/host/hostservice.cpp +++ b/src/nemo-devicelock/host/hostservice.cpp @@ -110,15 +110,14 @@ HostService::HostService( HostFingerprintSensor *fingerprintSensor, HostFingerprintSettings *fingerprintSettings, QObject *parent) - : HostService( - QVector() - << authenticator - << deviceLock - << deviceLockSettings - << deviceReset - << encryptionSettings - << fingerprintSensor - << fingerprintSettings + : HostService({ + authenticator, + deviceLock, + deviceLockSettings, + deviceReset, + encryptionSettings, + fingerprintSensor, + fingerprintSettings } , parent) { } diff --git a/src/nemo-devicelock/private/clientauthorization.cpp b/src/nemo-devicelock/private/clientauthorization.cpp index a94f09e..4881cc3 100644 --- a/src/nemo-devicelock/private/clientauthorization.cpp +++ b/src/nemo-devicelock/private/clientauthorization.cpp @@ -32,6 +32,9 @@ #include "clientauthorization.h" + +#include + namespace NemoDeviceLock { @@ -56,6 +59,8 @@ ClientAuthorization::ClientAuthorization( QStringLiteral("org.nemomobile.devicelock.Authorization"), localPath) , m_allowedMethods() + , m_requestedMethods(Authenticator::AllAvailable) + , m_authenticatingPid(QCoreApplication::applicationPid()) , m_status(NoChallenge) { m_connection->onDisconnected(this, [this] { @@ -72,6 +77,26 @@ Authenticator::Methods ClientAuthorization::allowedMethods() const return m_allowedMethods; } +Authenticator::Methods ClientAuthorization::requestedMethods() const +{ + return m_requestedMethods; +} + +void ClientAuthorization::setRequestedMethods(Authenticator::Methods methods) +{ + m_requestedMethods = methods; +} + +int ClientAuthorization::authenticatingPid() const +{ + return m_authenticatingPid; +} + +void ClientAuthorization::setAuthenticatingPid(int pid) +{ + m_authenticatingPid = pid; +} + Authorization::Status ClientAuthorization::status() const { return m_status ; @@ -87,7 +112,11 @@ void ClientAuthorization::requestChallenge() if (m_status != RequestingChallenge) { m_status = RequestingChallenge; - const auto response = call(QStringLiteral("RequestChallenge"), m_localPath); + const auto response = call( + QStringLiteral("RequestChallenge"), + m_localPath, + uint(m_requestedMethods), + uint(m_authenticatingPid)); response->onFinished([this](const QVariant &challengeCode, uint allowedMethods) { if (m_status == NoChallenge) { diff --git a/src/nemo-devicelock/private/clientauthorization.h b/src/nemo-devicelock/private/clientauthorization.h index 8b7abf2..73ff17e 100644 --- a/src/nemo-devicelock/private/clientauthorization.h +++ b/src/nemo-devicelock/private/clientauthorization.h @@ -64,6 +64,12 @@ class ClientAuthorization : public Authorization, private ConnectionClient Authenticator::Methods allowedMethods() const override; + Authenticator::Methods requestedMethods() const; + void setRequestedMethods(Authenticator::Methods methods); + + int authenticatingPid() const; + void setAuthenticatingPid(int pid); + Status status() const override; QVariant challengeCode() const override; @@ -77,6 +83,8 @@ class ClientAuthorization : public Authorization, private ConnectionClient QVariant m_challengeCode; Authenticator::Methods m_allowedMethods; + Authenticator::Methods m_requestedMethods; + int m_authenticatingPid; Status m_status; };