2
* Copyright © 2014 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU Lesser General Public License version 3,
6
* as published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Authored by: Thomas Voß <thomas.voss@canonical.com>
19
#ifndef CORE_TRUST_MIR_MIR_AGENT_H_
20
#define CORE_TRUST_MIR_MIR_AGENT_H_
22
#include <core/trust/agent.h>
24
#include <core/posix/child_process.h>
25
#include <core/posix/exec.h>
27
#include <mirclient/mir_toolkit/mir_client_library.h>
28
#include <mirclient/mir_toolkit/mir_prompt_session.h>
30
#include <condition_variable>
40
// We wrap the Mir prompt session API into a struct to
41
// ease with testing and mocking.
42
struct CORE_TRUST_DLL_PUBLIC PromptSessionVirtualTable
44
// Just a convenience typedef
45
typedef std::shared_ptr<PromptSessionVirtualTable> Ptr;
47
// Just a helper struct to be passed to client_fd_callbacks.
50
// Marks the value of an invalid fd.
51
static constexpr const int invalid_fd{-1};
52
// The fd contained within this context instance.
56
// Invoked whenever a request for creation of pre-authenticated fds succeeds.
57
static void mir_client_fd_callback(MirPromptSession */*prompt_session*/, size_t count, int const* fds, void* context);
59
// Create a MirPromptSessionVirtualTable for a given prompt session instance.
60
// Please note that no change of ownwership is happening here. Instead, we expect
61
// the calling code to handle object lifetimes.
62
PromptSessionVirtualTable(MirPromptSession* prompt_session);
63
virtual ~PromptSessionVirtualTable() = default;
65
// Requests a new, pre-authenticated fd for associating prompt providers.
66
// Returns the fd or throws std::runtime_error.
67
virtual int new_fd_for_prompt_provider();
69
// Finalizes and releases the given prompt session instance.
70
virtual void release_sync();
72
// The underlying prompt session instance.
73
MirPromptSession* prompt_session;
76
struct CORE_TRUST_DLL_PUBLIC ConnectionVirtualTable
78
// Just a convenience typedef
79
typedef std::shared_ptr<ConnectionVirtualTable> Ptr;
81
// Create a new instance of MirConnectionVirtualTable
82
// using a pre-existing connection to Mir. Please note
83
// that we do not take ownership of the MirConnection but
84
// expect the calling code to coordinate object lifetimes.
85
ConnectionVirtualTable(MirConnection* connection);
86
virtual ~ConnectionVirtualTable() = default;
88
// Creates a new trusted prompt session instance synchronously.
89
virtual PromptSessionVirtualTable::Ptr create_prompt_session_sync(
90
// The process id of the requesting app/service
92
// Callback handling prompt session state changes.
93
mir_prompt_session_state_change_callback cb,
97
// We do not take over ownership of the connection object.
98
MirConnection* connection;
101
// Abstracts common functionality required for running external helpers.
102
struct CORE_TRUST_DLL_PUBLIC PromptProviderHelper
104
// Just a convenience typedef.
105
typedef std::shared_ptr<PromptProviderHelper> Ptr;
107
// Creation-time arguments.
108
struct CreationArguments
110
// Path to the helper executable that provides the prompting UI.
111
std::string path_to_helper_executable;
114
// Invocation arguments for exec_prompt_provider_with_arguments
115
struct InvocationArguments
117
// The pre-authenticated fd that the helper
118
// should use for connecting to Mir.
120
// The application id of the requesting app.
121
std::string application_id;
122
// The extended description that should be presented to the user.
123
std::string description;
126
PromptProviderHelper(const CreationArguments& args);
127
virtual ~PromptProviderHelper() = default;
129
// Execs the executable provided at construction time for the arguments and
130
// returns the corresponding child process.
131
virtual core::posix::ChildProcess exec_prompt_provider_with_arguments(const InvocationArguments& args);
133
// We store all arguments passed at construction.
134
CreationArguments creation_arguments;
137
// Implements the trust::Agent interface and dispatches calls to a helper
138
// prompt provider, tying it together with the requesting service and app
139
// by leveraging Mir's trusted session/prompting support.
140
struct CORE_TRUST_DLL_PUBLIC Agent : public core::trust::Agent
142
// Convenience typedef
143
typedef std::shared_ptr<Agent> Ptr;
145
// Helper struct for injecting state into on_trust_changed_state_state callbacks.
146
// Used in prompt_user_for_request to wait for the trust session to be stopped.
147
struct OnTrustSessionStateChangedCallbackContext
149
// The process that provides the prompting UI.
150
core::posix::ChildProcess prompt_provider_process;
153
// Handles state changes of trust sessions and sigkills the child process
154
// provided in context (of type OnTrustSessionStateChangedCallbackContext).
155
static void on_trust_session_changed_state(
156
// The prompt session instance that just changed state.
157
MirPromptSession* prompt_provider,
158
// The new state of the prompt session instance.
159
MirPromptSessionState state,
160
// The context of type context.
163
// Returns a wait result -> trust::Request::Answer translator that only returns Answer::granted if
164
// the prompt provider child process exits cleanly with status success.
165
// Throws std::logic_error if the process did not exit but was signaled.
166
static std::function<core::trust::Request::Answer(const core::posix::wait::Result&)> translator_only_accepting_exit_status_success();
168
// Creates a new MirAgent instance with the given MirConnectionVirtualTable instance.
170
// VTable object providing access to Mir's trusted prompting functionality.
171
const ConnectionVirtualTable::Ptr& connection_vtable,
172
// Exec helper for starting up prompt provider child processes with the correct setup
173
// of command line arguments and environment variables.
174
const PromptProviderHelper::Ptr& exec_helper,
175
// A translator function for mapping child process exit states to trust::Request answers.
176
const std::function<core::trust::Request::Answer(const core::posix::wait::Result&)>& translator);
178
// From core::trust::Agent:
179
// Throws a std::logic_error if anything unforeseen happens during execution, thus
180
// indicating that no conclusive answer could be obtained from the user.
181
core::trust::Request::Answer prompt_user_for_request(pid_t app_pid, const std::string& app_id, const std::string& description) override;
183
// The connection VTable used for creating trusted prompting sessions.
184
ConnectionVirtualTable::Ptr connection_vtable;
185
// Execution helper for firing up prompt provider executables.
186
PromptProviderHelper::Ptr exec_helper;
187
// Translator instance.
188
std::function<core::trust::Request::Answer(const core::posix::wait::Result&)> translator;
191
CORE_TRUST_DLL_PUBLIC bool operator==(const PromptProviderHelper::InvocationArguments&, const PromptProviderHelper::InvocationArguments&);
196
#endif // CORE_TRUST_MIR_MIR_AGENT_H_