Skip to content

Commit

Permalink
[devicelock] Add a way to reset an in-progress authentication to the …
Browse files Browse the repository at this point in the history
…beginning. Contributes to JB#18948
  • Loading branch information
adenexter committed May 24, 2017
1 parent 1fbbe60 commit 037889d
Show file tree
Hide file tree
Showing 9 changed files with 240 additions and 61 deletions.
3 changes: 3 additions & 0 deletions dbus/org.nemomobile.devicelock.AuthenticationInput.xml
Expand Up @@ -17,6 +17,9 @@
<method name="RequestSecurityCode">
<arg name="client" type="o" direction="in"/>
</method>
<method name="Reset">
<arg name="client" type="o" direction="in"/>
</method>
<method name="Cancel">
<arg name="client" type="o" direction="in"/>
</method>
Expand Down
13 changes: 13 additions & 0 deletions src/nemo-devicelock/authenticationinput.cpp
Expand Up @@ -434,6 +434,19 @@ void AuthenticationInput::requestSecurityCode()
call(QStringLiteral("RequestSecurityCode"), m_localPath);
}

/*!
Sends a request to reset authentication to the beginning to the security daemon.
*/

void AuthenticationInput::reset()
{
if (m_status != Idle) {
qCDebug(devicelock, "Reset authentication");

call(QStringLiteral("Reset"), m_localPath);
}
}

/*!
Sends a request to cancel authentication to the security daemon.
*/
Expand Down
1 change: 1 addition & 0 deletions src/nemo-devicelock/authenticationinput.h
Expand Up @@ -150,6 +150,7 @@ class NEMODEVICELOCK_EXPORT AuthenticationInput : public QObject, private Connec

Q_INVOKABLE void enterSecurityCode(const QString &code);
Q_INVOKABLE void requestSecurityCode();
Q_INVOKABLE void reset();
Q_INVOKABLE void cancel();

signals:
Expand Down
20 changes: 17 additions & 3 deletions src/nemo-devicelock/host/hostauthenticationinput.cpp
Expand Up @@ -68,6 +68,11 @@ void HostAuthenticationInputAdaptor::RequestSecurityCode(const QDBusObjectPath &
m_authenticationInput->handleRequestSecurityCode(path.path());
}

void HostAuthenticationInputAdaptor::Reset(const QDBusObjectPath &path)
{
m_authenticationInput->handleReset(path.path());
}

void HostAuthenticationInputAdaptor::Cancel(const QDBusObjectPath &path)
{
m_authenticationInput->handleCancel(path.path());
Expand Down Expand Up @@ -347,9 +352,7 @@ void HostAuthenticationInput::lockedOut()
lockedOut(availability(), &HostAuthenticationInput::abortAuthentication);
}

void HostAuthenticationInput::lockedOut(
Availability availability,
void (HostAuthenticationInput::*errorFunction)(AuthenticationInput::Error error))
void HostAuthenticationInput::lockedOut(Availability availability, ErrorFunction errorFunction)
{
switch (availability) {
case CodeEntryLockedRecoverable:
Expand Down Expand Up @@ -430,6 +433,17 @@ void HostAuthenticationInput::handleRequestSecurityCode(const QString &path)
}
}

void HostAuthenticationInput::handleReset(const QString &path)
{
qCDebug(daemon) << "Received reset request";
const auto connection = QDBusContext::connection().name();
if (!m_inputStack.isEmpty()
&& m_inputStack.last().connection == connection
&& m_inputStack.last().path == path) {
reset();
}
}

void HostAuthenticationInput::handleCancel(const QString &path)
{
const auto connection = QDBusContext::connection().name();
Expand Down
8 changes: 5 additions & 3 deletions src/nemo-devicelock/host/hostauthenticationinput.h
Expand Up @@ -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 Reset(const QDBusObjectPath &path);
void Cancel(const QDBusObjectPath &path);

private:
Expand Down Expand Up @@ -88,6 +89,7 @@ class HostAuthenticationInput : public HostObject

typedef void (HostAuthenticationInput::*FeedbackFunction)(
AuthenticationInput::Feedback, const QVariantMap &, Authenticator::Methods);
typedef void (HostAuthenticationInput::*ErrorFunction)(AuthenticationInput::Error error);

explicit HostAuthenticationInput(
const QString &path,
Expand All @@ -110,6 +112,7 @@ class HostAuthenticationInput : public HostObject

virtual void enterSecurityCode(const QString &code) = 0;
virtual void requestSecurityCode() = 0;
virtual void reset() = 0;
void cancel() override = 0;

// Client
Expand Down Expand Up @@ -150,9 +153,7 @@ class HostAuthenticationInput : public HostObject

protected:
void lockedOut();
void lockedOut(
Availability availability,
void (HostAuthenticationInput::*errorFunction)(AuthenticationInput::Error error));
void lockedOut(Availability availability, ErrorFunction error);

private:
friend class HostAuthenticationInputAdaptor;
Expand All @@ -168,6 +169,7 @@ class HostAuthenticationInput : public HostObject

inline void handleEnterSecurityCode(const QString &client, const QString &code);
inline void handleRequestSecurityCode(const QString &path);
inline void handleReset(const QString &client);
inline void handleCancel(const QString &client);

inline void setRegistered(const QString &path, bool registered);
Expand Down
116 changes: 103 additions & 13 deletions src/nemo-devicelock/host/hostauthenticator.cpp
Expand Up @@ -127,9 +127,20 @@ void HostAuthenticator::authenticate(
cancel();
setActiveClient(client);

m_state = Authenticating;
m_challengeCode = challengeCode;

beginAuthentication(
&HostAuthenticationInput::startAuthentication,
&HostAuthenticationInput::authenticationUnavailable,
methods);

}

void HostAuthenticator::beginAuthentication(
FeedbackFunction feedback, ErrorFunction error, Authenticator::Methods methods)
{
m_state = Authenticating;

const auto availability = this->availability();
switch (availability) {
case AuthenticationNotRequired:
Expand All @@ -141,18 +152,18 @@ void HostAuthenticator::authenticate(
// Fall through.
case CanAuthenticate:
qCDebug(daemon, "Authentication requested using methods %i.", int(methods));
startAuthentication(AuthenticationInput::EnterSecurityCode, QVariantMap(), methods);
(this->*feedback)(AuthenticationInput::EnterSecurityCode, QVariantMap(), methods);
break;
case SecurityCodeRequired:
m_challengeCode.clear();
authenticationUnavailable(AuthenticationInput::FunctionUnavailable);
(this->*error)(AuthenticationInput::FunctionUnavailable);
break;
case CodeEntryLockedRecoverable:
case CodeEntryLockedPermanent:
case ManagerLockedRecoverable:
case ManagerLockedPermanent:
m_challengeCode.clear();
lockedOut(availability, &HostAuthenticationInput::authenticationUnavailable);
lockedOut(availability, error);
break;
}
}
Expand All @@ -168,24 +179,33 @@ void HostAuthenticator::handleChangeSecurityCode(const QString &client, const QV
cancel();
setActiveClient(client);

m_state = AuthenticatingForChange;
m_challengeCode = challengeCode;

beginChangeSecurityCode(
&HostAuthenticationInput::startAuthentication,
&HostAuthenticationInput::authenticationUnavailable);
}

void HostAuthenticator::beginChangeSecurityCode(FeedbackFunction feedback, ErrorFunction error)
{
m_state = AuthenticatingForChange;

switch (availability()) {
case AuthenticationNotRequired:
case SecurityCodeRequired:
enterCodeChangeState(&HostAuthenticationInput::startAuthentication, Authenticator::SecurityCode);
enterCodeChangeState(feedback, Authenticator::SecurityCode);
break;
case CanAuthenticateSecurityCode:
case CanAuthenticate:
startAuthentication(AuthenticationInput::EnterSecurityCode, QVariantMap(), Authenticator::SecurityCode);
(this->*feedback)(
AuthenticationInput::EnterSecurityCode, QVariantMap(), Authenticator::SecurityCode);
break;
case CodeEntryLockedRecoverable:
case CodeEntryLockedPermanent:
case ManagerLockedRecoverable:
case ManagerLockedPermanent:
m_challengeCode.clear();
authenticationUnavailable(AuthenticationInput::FunctionUnavailable);
(this->*error)(AuthenticationInput::FunctionUnavailable);
break;
}
}
Expand All @@ -201,24 +221,31 @@ void HostAuthenticator::handleClearSecurityCode(const QString &client)
cancel();
setActiveClient(client);

beginClearSecurityCode(
&HostAuthenticator::startAuthentication, &HostAuthenticator::authenticationUnavailable);
}

void HostAuthenticator::beginClearSecurityCode(FeedbackFunction feedback, ErrorFunction error)
{
m_state = AuthenticatingForClear;

switch (availability()) {
case AuthenticationNotRequired:
m_state = Idle;
QDBusContext::sendErrorReply(QDBusError::InvalidArgs);
(this->*error)(AuthenticationInput::SoftwareError);
break;
case CanAuthenticateSecurityCode:
case CanAuthenticate:
startAuthentication(
(this->*feedback)(
AuthenticationInput::EnterSecurityCode, QVariantMap(), Authenticator::SecurityCode);
break;
case SecurityCodeRequired:
case CodeEntryLockedRecoverable:
case CodeEntryLockedPermanent:
case ManagerLockedRecoverable:
case ManagerLockedPermanent:
authenticationUnavailable(AuthenticationInput::FunctionUnavailable);
m_state = Idle;
(this->*error)(AuthenticationInput::FunctionUnavailable);
break;
}
}
Expand All @@ -229,6 +256,7 @@ void HostAuthenticator::enterSecurityCode(const QString &code)

switch (m_state) {
case Idle:
case ChangeReset:
return;
case Authenticating:
qCDebug(daemon, "Lock code entered for authentication.");
Expand Down Expand Up @@ -351,6 +379,10 @@ void HostAuthenticator::setCodeFinished(int result)
case SecurityCodeInHistory:
if (m_state == ChangeCanceled) {
securityCodeChangeAborted();
} else if (m_state == ChangeReset) {
beginChangeSecurityCode(
&HostAuthenticationInput::feedback,
&HostAuthenticationInput::abortAuthentication);
} else {
qCDebug(daemon, "Security code disallowed.");
feedback(AuthenticationInput::SecurityCodeInHistory, -1);
Expand All @@ -368,8 +400,15 @@ void HostAuthenticator::setCodeFinished(int result)
default:
m_currentCode.clear();
qCDebug(daemon, "Lock code change failed.");

abortAuthentication(AuthenticationInput::SoftwareError);
if (m_state == ChangeCanceled) {
securityCodeChangeAborted();
} else if (m_state == ChangeReset) {
beginChangeSecurityCode(
&HostAuthenticationInput::feedback,
&HostAuthenticationInput::abortAuthentication);
} else {
abortAuthentication(AuthenticationInput::SoftwareError);
}
break;
}
}
Expand All @@ -394,6 +433,9 @@ void HostAuthenticator::abortAuthentication(AuthenticationInput::Error error)
case AuthenticatingForClear:
m_state = ClearError;
break;
case ChangeReset:
m_state = ChangeCanceled;
break;
default:
break;
}
Expand All @@ -413,6 +455,54 @@ void HostAuthenticator::authenticationEnded(bool confirmed)
HostAuthenticationInput::authenticationEnded(confirmed);
}

void HostAuthenticator::reset()
{
switch (m_state) {
case Idle:
break;
case Authenticating:
beginAuthentication(
&HostAuthenticationInput::feedback,
&HostAuthenticationInput::abortAuthentication);
break;
case AuthenticationError:
beginAuthentication(
&HostAuthenticationInput::authenticationResumed,
&HostAuthenticationInput::abortAuthentication);
break;
case AuthenticatingForChange:
case EnteringNewSecurityCode:
case RepeatingNewSecurityCode:
case ExpectingGeneratedSecurityCode:
beginChangeSecurityCode(
&HostAuthenticationInput::feedback,
&HostAuthenticationInput::abortAuthentication);
break;
case Changing:
m_state = ChangeReset;
break;
case ChangeError:
beginChangeSecurityCode(
&HostAuthenticationInput::authenticationResumed,
&HostAuthenticationInput::abortAuthentication);
break;
case ChangeCanceled:
break;
case ChangeReset:
break;
case AuthenticatingForClear:
beginClearSecurityCode(
&HostAuthenticationInput::feedback,
&HostAuthenticationInput::abortAuthentication);
break;
case ClearError:
beginClearSecurityCode(
&HostAuthenticationInput::authenticationResumed,
&HostAuthenticationInput::abortAuthentication);
break;
}
}

void HostAuthenticator::cancel()
{
switch (m_state) {
Expand Down
12 changes: 11 additions & 1 deletion src/nemo-devicelock/host/hostauthenticator.h
Expand Up @@ -116,6 +116,7 @@ class HostAuthenticator : public HostAuthenticationInput

void enterSecurityCode(const QString &code) override;
void requestSecurityCode() override;
void reset() override;
void cancel() override;

void confirmAuthentication() override;
Expand Down Expand Up @@ -149,15 +150,24 @@ class HostAuthenticator : public HostAuthenticationInput
Changing,
ChangeError,
ChangeCanceled,
ChangeReset,
AuthenticatingForClear,
ClearError,
};

inline bool isSecurityCodeSet() const;
inline void authenticate(
const QString &authenticator, const QVariant &challengeCode, Authenticator::Methods methods);
const QString &authenticator,
const QVariant &challengeCode,
Authenticator::Methods methods = Authenticator::Methods());
inline void beginAuthentication(
FeedbackFunction feedback,
ErrorFunction error,
Authenticator::Methods methods = Authenticator::Methods());
inline void handleChangeSecurityCode(const QString &client, const QVariant &challengeCode);
inline void beginChangeSecurityCode(FeedbackFunction feedback, ErrorFunction error);
inline void handleClearSecurityCode(const QString &client);
inline void beginClearSecurityCode(FeedbackFunction feedback, ErrorFunction error);
inline void handleCancel(const QString &client);
inline QVariantMap generatedCodeData();
inline void enterCodeChangeState(
Expand Down

0 comments on commit 037889d

Please sign in to comment.