Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add a generic validator type which third parties can use to authentic…
…ate using the device lock.

This includes additional provisions for verifying an allowed
authentication method was used by the expected application.
  • Loading branch information
adenexter committed Dec 20, 2017
1 parent 82172d2 commit 8f6cc53
Show file tree
Hide file tree
Showing 28 changed files with 604 additions and 43 deletions.
2 changes: 2 additions & 0 deletions dbus/org.nemomobile.devicelock.Authorization.xml
Expand Up @@ -4,6 +4,8 @@
<interface name="org.nemomobile.devicelock.Authorization">
<method name="RequestChallenge">
<arg name="client" type="o" direction="in"/>
<arg name="requested_methods" type="u" direction="in"/>
<arg name="authenticating_pid" type="u" direction="in"/>
<arg name="challenge_code" type="v" direction="out"/>
<arg name="allowed_methods" type="u" direction="out"/>
</method>
Expand Down
2 changes: 0 additions & 2 deletions rpm/nemo-qml-plugin-devicelock.spec
Expand Up @@ -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}.
Expand All @@ -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)
Expand Down
5 changes: 4 additions & 1 deletion src/daemon/main.cpp
Expand Up @@ -35,6 +35,7 @@
#include <clidevicelocksettings.h>
#include <clidevicereset.h>
#include <cliencryptionsettings.h>
#include <clivalidator.h>
#include <hostfingerprintsensor.h>
#include <hostfingerprintsettings.h>
#include <hostservice.h>
Expand All @@ -50,6 +51,7 @@ int main(int argc, char *argv[])
NemoDeviceLock::CliDeviceLockSettings deviceLockSettings;
NemoDeviceLock::CliDeviceReset deviceReset;
NemoDeviceLock::CliEncryptionSettings encryptionSettings;
NemoDeviceLock::CliValidator validator;
NemoDeviceLock::HostFingerprintSensor fingerprintSensor;
NemoDeviceLock::HostFingerprintSettings fingerprintSettings;

Expand All @@ -60,7 +62,8 @@ int main(int argc, char *argv[])
&deviceReset,
&encryptionSettings,
&fingerprintSensor,
&fingerprintSettings);
&fingerprintSettings,
&validator);

return application.exec();
}
2 changes: 1 addition & 1 deletion src/nemo-devicelock/authenticationinput.h
Expand Up @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions src/nemo-devicelock/authenticator.h
Expand Up @@ -69,7 +69,8 @@ class NEMODEVICELOCK_EXPORT Authenticator : public QObject, private ConnectionCl
enum Method {
NoAuthentication = 0x00,
SecurityCode = 0x01,
Fingerprint = 0x02
Fingerprint = 0x02,
AllAvailable = SecurityCode | Fingerprint
};

Q_DECLARE_FLAGS(Methods, Method)
Expand All @@ -81,7 +82,7 @@ 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 cancel();

signals:
Expand Down
2 changes: 2 additions & 0 deletions src/nemo-devicelock/host/cli/cli.pri
Expand Up @@ -6,6 +6,7 @@ PUBLIC_HEADERS += \
$$PWD/clidevicelock.h \
$$PWD/clidevicelocksettings.h \
$$PWD/clidevicereset.h \
$$PWD/clivalidator.h \
$$PWD/cliencryptionsettings.h

HEADERS += \
Expand All @@ -17,4 +18,5 @@ SOURCES += \
$$PWD/clidevicelocksettings.cpp \
$$PWD/clidevicereset.cpp \
$$PWD/cliencryptionsettings.cpp \
$$PWD/clivalidator.cpp \
$$PWD/lockcodewatcher.cpp
2 changes: 1 addition & 1 deletion src/nemo-devicelock/host/cli/cliauthenticator.cpp
Expand Up @@ -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;
}
Expand Down
3 changes: 2 additions & 1 deletion src/nemo-devicelock/host/cli/cliauthenticator.h
Expand Up @@ -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<LockCodeWatcher> m_watcher;
Expand Down
60 changes: 60 additions & 0 deletions src/nemo-devicelock/host/cli/clivalidator.cpp
@@ -0,0 +1,60 @@
/*
* Copyright (C) 2016 Jolla Ltd
* Contact: Andrew den Exter <andrew.den.exter@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* "Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Nemo Mobile nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
*/

#include "clivalidator.h"
#include <hostauthenticationinput.h>


#include "lockcodewatcher.h"

namespace NemoDeviceLock
{

CliValidator::CliValidator(QObject *parent)
: HostValidator(parent)
, m_watcher(LockCodeWatcher::instance())
{
}

CliValidator::~CliValidator()
{
}

void CliValidator::verifyToken(const QString &, const QVariant &authenticationToken)
{

if (m_watcher->runPlugin({ QStringLiteral("--check-code"), authenticationToken.toString() }) != HostAuthenticationInput::Success) {
QDBusContext::sendErrorReply(QDBusError::InternalError);
}
}

}
59 changes: 59 additions & 0 deletions src/nemo-devicelock/host/cli/clivalidator.h
@@ -0,0 +1,59 @@
/*
* Copyright (C) 2016 Jolla Ltd
* Contact: Andrew den Exter <andrew.den.exter@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* "Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Nemo Mobile nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
*/

#ifndef NEMODEVICELOCK_CLIHOSTVALIDATOR_H
#define NEMODEVICELOCK_CLIHOSTVALIDATOR_H

#include <nemo-devicelock/host/hostvalidator.h>

#include <QSharedDataPointer>

namespace NemoDeviceLock
{

class LockCodeWatcher;

class CliValidator : public HostValidator
{
public:
explicit CliValidator(QObject *parent = nullptr);
~CliValidator();

void verifyToken(const QString &requestor, const QVariant &authenticationToken) override;

private:
QExplicitlySharedDataPointer<LockCodeWatcher> m_watcher;
};

}

#endif
2 changes: 2 additions & 0 deletions src/nemo-devicelock/host/host.pro
Expand Up @@ -33,6 +33,7 @@ PUBLIC_HEADERS += \
$$PWD/hostfingerprintsettings.h \
$$PWD/hostobject.h \
$$PWD/hostservice.h \
$$PWD/hostvalidator.h \
$$PWD/mcedevicelock.h

SOURCES += \
Expand All @@ -47,6 +48,7 @@ SOURCES += \
$$PWD/hostfingerprintsettings.cpp \
$$PWD/hostobject.cpp \
$$PWD/hostservice.cpp \
$$PWD/hostvalidator.cpp \
$$PWD/mcedevicelock.cpp

include (cli/cli.pri)
Expand Down
5 changes: 4 additions & 1 deletion src/nemo-devicelock/host/hostauthenticationinput.cpp
Expand Up @@ -90,8 +90,11 @@ HostAuthenticationInput::~HostAuthenticationInput()

void HostAuthenticationInput::authenticationStarted(
Authenticator::Methods methods,
uint authenticatingPid,
AuthenticationInput::Feedback)
{
Q_UNUSED(authenticatingPid);

qCDebug(daemon, "Authentication started");

m_authenticating = true;
Expand All @@ -109,7 +112,7 @@ void HostAuthenticationInput::startAuthentication(
const uint pid = connectionPid(QDBusContext::connection());

if (pid != 0 && !m_inputStack.isEmpty()) {
authenticationStarted(methods, feedback);
authenticationStarted(methods, pid, feedback);

NemoDBus::send(
m_inputStack.last().connection,
Expand Down
3 changes: 2 additions & 1 deletion src/nemo-devicelock/host/hostauthenticationinput.h
Expand Up @@ -119,6 +119,7 @@ class HostAuthenticationInput : public HostObject
Authenticator::Methods methods);
virtual void authenticationStarted(
Authenticator::Methods methods,
uint authenticatingPid,
AuthenticationInput::Feedback feedback = AuthenticationInput::EnterSecurityCode);
void authenticationUnavailable(AuthenticationInput::Error error);
void authenticationResumed(
Expand All @@ -132,7 +133,7 @@ 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
Expand Down
21 changes: 16 additions & 5 deletions src/nemo-devicelock/host/hostauthenticator.cpp
Expand Up @@ -99,6 +99,7 @@ HostAuthenticator::HostAuthenticator(Authenticator::Methods supportedMethods, QO
, m_adaptor(this)
, m_securityCodeAdaptor(this)
, m_repeatsRequired(0)
, m_authenticatingPid(0)
, m_state(Idle)
{
}
Expand Down Expand Up @@ -136,7 +137,7 @@ void HostAuthenticator::authenticate(
switch (availability) {
case AuthenticationNotRequired:
qCDebug(daemon, "Authentication requested. Unsecured, authenticating immediately.");
confirmAuthentication();
confirmAuthentication(Authenticator::SecurityCode);
break;
case CanAuthenticateSecurityCode:
methods &= Authenticator::SecurityCode;
Expand Down Expand Up @@ -237,7 +238,7 @@ void HostAuthenticator::enterSecurityCode(const QString &code)
switch ((attempts = checkCode(code))) {
case Success:
case SecurityCodeExpired:
confirmAuthentication();
confirmAuthentication(Authenticator::SecurityCode);
return;
case LockedOut:
lockedOut();
Expand Down Expand Up @@ -349,7 +350,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) {
Expand Down Expand Up @@ -377,9 +379,9 @@ void HostAuthenticator::setCodeFinished(int result)
}
}

void HostAuthenticator::confirmAuthentication()
void HostAuthenticator::confirmAuthentication(Authenticator::Method method)
{
authenticated(authenticateChallengeCode(m_challengeCode));
authenticated(authenticateChallengeCode(m_challengeCode, method, m_authenticatingPid));
}

void HostAuthenticator::abortAuthentication(AuthenticationInput::Error error)
Expand All @@ -404,10 +406,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();
Expand Down
8 changes: 6 additions & 2 deletions src/nemo-devicelock/host/hostauthenticator.h
Expand Up @@ -102,7 +102,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);
Expand All @@ -118,8 +119,10 @@ class HostAuthenticator : public HostAuthenticationInput
void requestSecurityCode() 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);
Expand Down Expand Up @@ -173,6 +176,7 @@ class HostAuthenticator : public HostAuthenticationInput
QString m_newCode;
QString m_generatedCode;
int m_repeatsRequired;
int m_authenticatingPid;
State m_state;
};

Expand Down

0 comments on commit 8f6cc53

Please sign in to comment.