~cjwatson/trust-store/tests-dep

« back to all changes in this revision

Viewing changes to src/core/trust/mir/agent.h

  • Committer: thomas-voss
  • Date: 2014-07-18 09:41:24 UTC
  • mfrom: (21 trust-store)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: thomas.voss@canonical.com-20140718094124-502cgmnt9bh4wi7m
[ Ubuntu daily release ]
* debian/*symbols: auto-update new symbols to released version
[ thomas-voss ]
* Provide an agent implementation that leverages Mir's trusted
  prompting API. Introduce a default prompt provider using Qt/QML.
  Provide a test harness around the core::trust::mir::Agent
  implementation and the prompt provider. Add a convenience function
  for processing incoming requests.
[ thomas-voss ]
* Remove obsolete data/session.conf and data/system.conf files. Adjust
  directory creation default mode to 0755. (LP: #1338587)
[ Ubuntu daily release ]
* New rebuild forced

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2014 Canonical Ltd.
 
3
 *
 
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.
 
7
 *
 
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.
 
12
 *
 
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/>.
 
15
 *
 
16
 * Authored by: Thomas Voß <thomas.voss@canonical.com>
 
17
 */
 
18
 
 
19
#ifndef CORE_TRUST_MIR_MIR_AGENT_H_
 
20
#define CORE_TRUST_MIR_MIR_AGENT_H_
 
21
 
 
22
#include <core/trust/agent.h>
 
23
 
 
24
#include <core/posix/child_process.h>
 
25
#include <core/posix/exec.h>
 
26
 
 
27
#include <mirclient/mir_toolkit/mir_client_library.h>
 
28
#include <mirclient/mir_toolkit/mir_prompt_session.h>
 
29
 
 
30
#include <condition_variable>
 
31
#include <functional>
 
32
#include <mutex>
 
33
 
 
34
namespace core
 
35
{
 
36
namespace trust
 
37
{
 
38
namespace mir
 
39
{
 
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
 
43
{
 
44
    // Just a convenience typedef
 
45
    typedef std::shared_ptr<PromptSessionVirtualTable> Ptr;
 
46
 
 
47
    // Just a helper struct to be passed to client_fd_callbacks.
 
48
    struct Context
 
49
    {
 
50
        // Marks the value of an invalid fd.
 
51
        static constexpr const int invalid_fd{-1};
 
52
        // The fd contained within this context instance.
 
53
        int fd{invalid_fd};
 
54
    };
 
55
 
 
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);
 
58
 
 
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;
 
64
 
 
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();
 
68
 
 
69
    // Finalizes and releases the given prompt session instance.
 
70
    virtual void release_sync();
 
71
 
 
72
    // The underlying prompt session instance.
 
73
    MirPromptSession* prompt_session;
 
74
};
 
75
 
 
76
struct CORE_TRUST_DLL_PUBLIC ConnectionVirtualTable
 
77
{
 
78
    // Just a convenience typedef
 
79
    typedef std::shared_ptr<ConnectionVirtualTable> Ptr;
 
80
 
 
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;
 
87
 
 
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
 
91
            pid_t app_pid,
 
92
            // Callback handling prompt session state changes.
 
93
            mir_prompt_session_state_change_callback cb,
 
94
            // Callback context
 
95
            void* context);
 
96
 
 
97
    // We do not take over ownership of the connection object.
 
98
    MirConnection* connection;
 
99
};
 
100
 
 
101
// Abstracts common functionality required for running external helpers.
 
102
struct CORE_TRUST_DLL_PUBLIC PromptProviderHelper
 
103
{
 
104
    // Just a convenience typedef.
 
105
    typedef std::shared_ptr<PromptProviderHelper> Ptr;
 
106
 
 
107
    // Creation-time arguments.
 
108
    struct CreationArguments
 
109
    {
 
110
        // Path to the helper executable that provides the prompting UI.
 
111
        std::string path_to_helper_executable;
 
112
    };
 
113
 
 
114
    // Invocation arguments for exec_prompt_provider_with_arguments
 
115
    struct InvocationArguments
 
116
    {
 
117
        // The pre-authenticated fd that the helper
 
118
        // should use for connecting to Mir.
 
119
        int fd;
 
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;
 
124
    };
 
125
 
 
126
    PromptProviderHelper(const CreationArguments& args);
 
127
    virtual ~PromptProviderHelper() = default;
 
128
 
 
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);
 
132
 
 
133
    // We store all arguments passed at construction.
 
134
    CreationArguments creation_arguments;
 
135
};
 
136
 
 
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
 
141
{
 
142
    // Convenience typedef
 
143
    typedef std::shared_ptr<Agent> Ptr;
 
144
 
 
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
 
148
    {
 
149
        // The process that provides the prompting UI.
 
150
        core::posix::ChildProcess prompt_provider_process;
 
151
    };
 
152
 
 
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.
 
161
            void* context);
 
162
 
 
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();
 
167
 
 
168
    // Creates a new MirAgent instance with the given MirConnectionVirtualTable instance.
 
169
    Agent(
 
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);
 
177
 
 
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;
 
182
 
 
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;
 
189
};
 
190
 
 
191
CORE_TRUST_DLL_PUBLIC bool operator==(const PromptProviderHelper::InvocationArguments&, const PromptProviderHelper::InvocationArguments&);
 
192
}
 
193
}
 
194
}
 
195
 
 
196
#endif // CORE_TRUST_MIR_MIR_AGENT_H_