Skip to content

Commit

Permalink
[sailfish-secrets] Add support for InteractionRequest. Contributes to…
Browse files Browse the repository at this point in the history
… JB#36797

Some client use cases require the capability to request user input
via a system-mediated UI where that input is NOT stored into the
secrets storage (for example, a daemon which wishes to use a transient
lock code for some functionality).

This commit adds support for an InteractionRequest where the user
is explicitly informed that the data they are entering should not
be considered "secure" in the secrets-storage sense.

Contributes to JB#36797
  • Loading branch information
Chris Adams committed Feb 22, 2018
1 parent 76c1104 commit f7073ef
Show file tree
Hide file tree
Showing 15 changed files with 434 additions and 22 deletions.
42 changes: 34 additions & 8 deletions daemon/SecretsImpl/secrets.cpp
Expand Up @@ -46,6 +46,28 @@ void Daemon::ApiImpl::SecretsDBusObject::getPluginInfo(
result);
}

// retrieve user input for the client (daemon)
void Daemon::ApiImpl::SecretsDBusObject::userInput(
const InteractionParameters &uiParams,
const QDBusMessage &message,
Result &result,
QByteArray &data)
{
Q_UNUSED(data); // outparam, set in handlePendingRequest / handleFinishedRequest
InteractionParameters modifiedParams(uiParams);
modifiedParams.setOperation(InteractionParameters::RequestUserData);
modifiedParams.setCollectionName(QString());
modifiedParams.setSecretName(QString());
modifiedParams.setPromptTrId(QString());
QList<QVariant> inParams;
inParams << QVariant::fromValue<InteractionParameters>(modifiedParams);
m_requestQueue->handleRequest(Daemon::ApiImpl::UserInputRequest,
inParams,
connection(),
message,
result);
}

// create a DeviceLock-protected collection
void Daemon::ApiImpl::SecretsDBusObject::createCollection(
const QString &collectionName,
Expand Down Expand Up @@ -856,8 +878,12 @@ void Daemon::ApiImpl::SecretsRequestQueue::handlePendingRequest(
// waiting for asynchronous flow to complete
*completed = false;
} else {
// This request type exists solely to implement Crypto API functionality.
asynchronousCryptoRequestCompleted(request->cryptoRequestId, result, QVariantList());
// failed, return error immediately
if (request->isSecretsCryptoRequest) {
asynchronousCryptoRequestCompleted(request->cryptoRequestId, result, QVariantList());
} else {
request->connection.send(request->message.createReply() << QVariant::fromValue<Result>(result));
}
*completed = true;
}
break;
Expand Down Expand Up @@ -1098,7 +1124,7 @@ void Daemon::ApiImpl::SecretsRequestQueue::handleFinishedRequest(
break;
}
case UserInputRequest: {
Result result = request->outParams.size()
const Result result = request->outParams.size()
? request->outParams.takeFirst().value<Result>()
: Result(Result::UnknownError,
QLatin1String("Unable to determine result of UserInputRequest request"));
Expand All @@ -1107,14 +1133,14 @@ void Daemon::ApiImpl::SecretsRequestQueue::handleFinishedRequest(
qCWarning(lcSailfishSecretsDaemon) << "UserInputRequest:" << request->requestId << "finished as pending!";
*completed = true;
} else {
const QByteArray userInput = request->outParams.size()
? request->outParams.takeFirst().value<QByteArray>()
: QByteArray();
if (request->isSecretsCryptoRequest) {
QByteArray userInput = request->outParams.size()
? request->outParams.takeFirst().value<QByteArray>()
: QByteArray();
asynchronousCryptoRequestCompleted(request->cryptoRequestId, result, QVariantList() << userInput);
} else {
// shouldn't happen!
qCWarning(lcSailfishSecretsDaemon) << "Error: UserInputRequest not a secrets crypto request!";
request->connection.send(request->message.createReply() << QVariant::fromValue<Result>(result)
<< QVariant::fromValue<QByteArray>(userInput));
}
*completed = true;
}
Expand Down
14 changes: 14 additions & 0 deletions daemon/SecretsImpl/secrets_p.h
Expand Up @@ -50,6 +50,13 @@ class SecretsDBusObject : public QObject, protected QDBusContext
" <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out3\" value=\"QVector<Sailfish::Secrets::EncryptedStoragePluginInfo>\" />\n"
" <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out4\" value=\"QVector<Sailfish::Secrets::AuthenticationPluginInfo>\" />\n"
" </method>\n"
" <method name=\"userInput\">\n"
" <arg name=\"uiParams\" type=\"(sss(i)sss(i)(i))\" direction=\"in\" />\n"
" <arg name=\"result\" type=\"(iis)\" direction=\"out\" />\n"
" <arg name=\"data\" type=\"ay\" direction=\"out\" />\n"
" <annotation name=\"org.qtproject.QtDBus.QtTypeName.In0\" value=\"Sailfish::Secrets::InteractionParameters\" />\n"
" <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"Sailfish::Secrets::Result\" />\n"
" </method>\n"
" <method name=\"createCollection\">\n"
" <arg name=\"collectionName\" type=\"s\" direction=\"in\" />\n"
" <arg name=\"storagePluginName\" type=\"s\" direction=\"in\" />\n"
Expand Down Expand Up @@ -182,6 +189,13 @@ public Q_SLOTS:
QVector<Sailfish::Secrets::EncryptedStoragePluginInfo> &encryptedStoragePlugins,
QVector<Sailfish::Secrets::AuthenticationPluginInfo> &authenticationPlugins);

// retrieve user input for the client (daemon)
void userInput(
const Sailfish::Secrets::InteractionParameters &uiParams,
const QDBusMessage &message,
Sailfish::Secrets::Result &result,
QByteArray &data);

// create a DeviceLock-protected collection
void createCollection(
const QString &collectionName,
Expand Down
9 changes: 9 additions & 0 deletions daemon/SecretsImpl/secretsrequestprocessor.cpp
Expand Up @@ -1160,6 +1160,15 @@ Daemon::ApiImpl::RequestProcessor::userInput(

InteractionParameters ikdRequest(uiParams);
ikdRequest.setApplicationId(callerApplicationId);
if (ikdRequest.collectionName().isEmpty() && ikdRequest.secretName().isEmpty()) {
// this is a request on behalf of a client application.
// the user needs to be warned that the data they enter cannot
// be considered to be "secure" in the secrets-storage sense.
const QString warningPromptText = QString::fromLatin1(
"An application is requesting input which will be returned to the application: %1")
.arg(ikdRequest.promptText());
ikdRequest.setPromptText(warningPromptText);
}
Result interactionResult = m_authenticationPlugins[userInputPlugin]->beginUserInputInteraction(
callerPid,
requestId,
Expand Down
13 changes: 8 additions & 5 deletions lib/Secrets/Secrets.pro
Expand Up @@ -18,16 +18,17 @@ PUBLIC_HEADERS += \
$$PWD/deletesecretrequest.h \
$$PWD/extensionplugins.h \
$$PWD/findsecretsrequest.h \
$$PWD/interactionparameters.h \
$$PWD/interactionrequest.h \
$$PWD/request.h \
$$PWD/result.h \
$$PWD/secret.h \
$$PWD/secretmanager.h \
$$PWD/secretsglobal.h \
$$PWD/storedsecretrequest.h \
$$PWD/storesecretrequest.h \
$$PWD/interactionparameters.h \
$$PWD/interactionresponse.h \
$$PWD/interactionrequestwatcher.h \
$$PWD/interactionresponse.h \
$$PWD/interactionview.h

INTERNAL_PUBLIC_HEADERS += \
Expand All @@ -40,11 +41,12 @@ PRIVATE_HEADERS += \
$$PWD/deletesecretrequest_p.h \
$$PWD/findsecretsrequest_p.h \
$$PWD/interactionparameters_p.h \
$$PWD/interactionresponse_p.h \
$$PWD/interactionrequest_p.h \
$$PWD/secretsdaemonconnection_p_p.h \
$$PWD/secretmanager_p.h \
$$PWD/storedsecretrequest_p.h \
$$PWD/storesecretrequest_p.h \
$$PWD/interactionresponse_p.h \
$$PWD/interactionservice_p.h

HEADERS += \
Expand All @@ -58,15 +60,16 @@ SOURCES += \
$$PWD/deletesecretrequest.cpp \
$$PWD/extensionplugins.cpp \
$$PWD/findsecretsrequest.cpp \
$$PWD/interactionparameters.cpp \
$$PWD/interactionrequest.cpp \
$$PWD/request.cpp \
$$PWD/secretsdaemonconnection.cpp \
$$PWD/secretmanager.cpp \
$$PWD/serialisation.cpp \
$$PWD/storedsecretrequest.cpp \
$$PWD/storesecretrequest.cpp \
$$PWD/interactionparameters.cpp \
$$PWD/interactionresponse.cpp \
$$PWD/interactionrequestwatcher.cpp \
$$PWD/interactionresponse.cpp \
$$PWD/interactionservice.cpp

develheaders.path = /usr/include/Sailfish/
Expand Down
2 changes: 2 additions & 0 deletions lib/Secrets/interactionparameters.cpp
Expand Up @@ -20,6 +20,7 @@ InteractionParametersPrivate::InteractionParametersPrivate(const InteractionPara
, m_collectionName(other.m_collectionName)
, m_applicationId(other.m_applicationId)
, m_operation(other.m_operation)
, m_authenticationPluginName(other.m_authenticationPluginName)
, m_promptText(other.m_promptText)
, m_promptTrId(other.m_promptTrId)
, m_inputType(other.m_inputType)
Expand Down Expand Up @@ -93,6 +94,7 @@ bool InteractionParameters::operator==(const InteractionParameters &other) const
&& operation() == other.operation()
&& authenticationPluginName() == other.authenticationPluginName()
&& promptText() == other.promptText()
&& promptTrId() == other.promptTrId()
&& inputType() == other.inputType()
&& echoMode() == other.echoMode();
}
Expand Down
6 changes: 3 additions & 3 deletions lib/Secrets/interactionparameters.h
Expand Up @@ -5,8 +5,8 @@
* BSD 3-Clause License, see LICENSE.
*/

#ifndef LIBSAILFISHSECRETS_INTERACTIONREQUEST_H
#define LIBSAILFISHSECRETS_INTERACTIONREQUEST_H
#ifndef LIBSAILFISHSECRETS_INTERACTIONPARAMETERS_H
#define LIBSAILFISHSECRETS_INTERACTIONPARAMETERS_H

#include "Secrets/secretsglobal.h"

Expand Down Expand Up @@ -149,4 +149,4 @@ inline bool operator<(const Sailfish::Secrets::InteractionParameters &/*lhs*/, c
return false;
}

#endif // LIBSAILFISHSECRETS_INTERACTIONREQUEST_H
#endif // LIBSAILFISHSECRETS_INTERACTIONPARAMETERS_H
6 changes: 3 additions & 3 deletions lib/Secrets/interactionparameters_p.h
Expand Up @@ -5,8 +5,8 @@
* BSD 3-Clause License, see LICENSE.
*/

#ifndef LIBSAILFISHSECRETS_INTERACTIONREQUEST_P_H
#define LIBSAILFISHSECRETS_INTERACTIONREQUEST_P_H
#ifndef LIBSAILFISHSECRETS_INTERACTIONPARAMETERS_P_H
#define LIBSAILFISHSECRETS_INTERACTIONPARAMETERS_P_H

#include "Secrets/interactionparameters.h"

Expand Down Expand Up @@ -38,4 +38,4 @@ class InteractionParametersPrivate : public QSharedData {

} // Sailfish

#endif // LIBSAILFISHSECRETS_INTERACTIONREQUEST_P_H
#endif // LIBSAILFISHSECRETS_INTERACTIONPARAMETERS_P_H

0 comments on commit f7073ef

Please sign in to comment.