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;
};