29 namespace ubuntu = apparmor::ubuntu;
36 std::string authority;
44 Uri parse_uri(
const std::string& s)
49 const std::size_t scheme{2};
50 const std::size_t authority{4};
51 const std::size_t path{5};
52 const std::size_t query{7};
53 const std::size_t fragment{9};
56 static const std::regex regex{R
"delim(^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)delim"}; 59 if (not std::regex_match(s, match, regex))
throw std::runtime_error
61 "Not a valid URI: " + s
66 match.str(index.scheme),
67 match.str(index.authority),
68 match.str(index.path),
69 match.str(index.query),
70 match.str(index.fragment)
74 static constexpr std::size_t index_package{1};
75 static constexpr std::size_t index_app{2};
76 static const std::string unity_name{
"unity8-dash"};
80 bool process_context_name(
const std::string& s, std::smatch& out,
81 std::string& pkg_name)
84 static const std::regex short_re{
"(.*)_(.*)"};
85 static const std::regex full_re{
"(.*)_(.*)_(.*)"};
86 static const std::regex trust_store_re{
"(.*)-(.*)"};
88 if ((s ==
"messaging-app" or s == unity_name)
89 and std::regex_match(s, out, trust_store_re))
95 if (std::regex_match(s, out, full_re) or std::regex_match(s, out, short_re))
97 pkg_name = out[index_package];
105 apparmor::ubuntu::Context::Context(
const std::string& name)
107 unconfined_{
str() == ubuntu::unconfined},
108 unity_{name == unity_name},
109 has_package_name_{process_context_name(
str(), match_, pkg_name_)}
111 MH_DEBUG(
"apparmor profile name: %s", name);
115 throw std::logic_error
117 "apparmor::ubuntu::Context: Invalid profile name " +
str()
133 return has_package_name_;
143 return std::string{match_[index_package]} +
"-" + std::string{match_[index_app]};
151 const std::string& name,
163 return Result{
true,
"Client allowed access since it's unconfined"};
165 Uri parsed_uri = parse_uri(uri);
168 MH_DEBUG(
"parsed_uri.path: %s", parsed_uri.path);
171 if (parsed_uri.path.find(std::string(
".local/share/" + context.
package_name() +
"/")) != std::string::npos ||
172 parsed_uri.path.find(std::string(
".cache/" + context.
package_name() +
"/")) != std::string::npos)
183 (parsed_uri.path.find(std::string(
".local/share/com.ubuntu." + context.
profile_name() +
"/")) != std::string::npos ||
184 parsed_uri.path.find(std::string(
".cache/com.ubuntu." + context.
profile_name() +
"/")) != std::string::npos))
192 else if (parsed_uri.path.find(std::string(
"opt/click.ubuntu.com/")) != std::string::npos &&
193 parsed_uri.path.find(context.
package_name()) != std::string::npos)
195 return Result{
true,
"Client can access content in own opt directory"};
197 else if ((parsed_uri.path.find(std::string(
"/system/media/audio/ui/")) != std::string::npos ||
198 parsed_uri.path.find(std::string(
"/android/system/media/audio/ui/")) != std::string::npos) &&
201 return Result{
true,
"Camera app can access ui sounds"};
211 (parsed_uri.path.find(std::string(
"Music/")) != std::string::npos ||
212 parsed_uri.path.find(std::string(
"Videos/")) != std::string::npos ||
213 parsed_uri.path.find(std::string(
"/media")) != std::string::npos))
215 return Result{
true,
"Client can access content in ~/Music or ~/Videos"};
217 else if (parsed_uri.path.find(std::string(
"/usr/share/sounds")) != std::string::npos)
219 return Result{
true,
"Client can access content in /usr/share/sounds"};
221 else if (parsed_uri.scheme ==
"http" ||
222 parsed_uri.scheme ==
"https" ||
223 parsed_uri.scheme ==
"rtsp")
225 return Result{
true,
"Client can access streaming content"};
228 return Result{
false,
"Client is not allowed to access: " + uri};
234 return std::make_shared<apparmor::ubuntu::DBusDaemonRequestContextResolver>(es.
session);
240 return std::make_shared<apparmor::ubuntu::ExistingAuthenticator>();
DBusDaemonRequestContextResolver(const core::dbus::Bus::Ptr &)
virtual bool is_unity() const
virtual bool has_package_name() const
std::shared_ptr< RequestContextResolver > Ptr
virtual std::string profile_name() const
virtual bool is_unconfined() const
void resolve_context_for_dbus_name_async(const std::string &name, ResolveCallback) override
void get_connection_app_armor_security_async(const std::string &name, std::function< void(const std::string &)> handler)
std::function< void(const Context &)> ResolveCallback
virtual std::string package_name() const
const std::string & str() const