28 namespace ubuntu = apparmor::ubuntu;
35 std::string authority;
43 Uri parse_uri(
const std::string& s)
48 const std::size_t scheme{2};
49 const std::size_t authority{4};
50 const std::size_t path{5};
51 const std::size_t query{7};
52 const std::size_t fragment{9};
55 static const std::regex regex{R
"delim(^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)delim"}; 58 if (not std::regex_match(s, match, regex))
throw std::runtime_error
60 "Not a valid URI: " + s
65 match.str(index.scheme),
66 match.str(index.authority),
67 match.str(index.path),
68 match.str(index.query),
69 match.str(index.fragment)
73 static constexpr std::size_t index_package{1};
74 static constexpr std::size_t index_app{2};
75 static const std::string unity_name{
"unity8-dash"};
79 bool process_context_name(
const std::string& s, std::smatch& out,
80 std::string& pkg_name)
83 static const std::regex short_re{
"(.*)_(.*)"};
84 static const std::regex full_re{
"(.*)_(.*)_(.*)"};
85 static const std::regex trust_store_re{
"(.*)-(.*)"};
87 if ((s ==
"messaging-app" or s == unity_name)
88 and std::regex_match(s, out, trust_store_re))
94 if (std::regex_match(s, out, full_re) or std::regex_match(s, out, short_re))
96 pkg_name = out[index_package];
104 apparmor::ubuntu::Context::Context(
const std::string& name)
106 unconfined_{
str() == ubuntu::unconfined},
107 unity_{name == unity_name},
108 has_package_name_{process_context_name(
str(), match_, pkg_name_)}
110 std::cout <<
"apparmor profile name: " << name;
114 throw std::logic_error
116 "apparmor::ubuntu::Context: Invalid profile name " +
str()
132 return has_package_name_;
142 return std::string{match_[index_package]} +
"-" + std::string{match_[index_app]};
150 const std::string& name,
162 return Result{
true,
"Client allowed access since it's unconfined"};
164 Uri parsed_uri = parse_uri(uri);
166 std::cout <<
"context.profile_name(): " << context.
profile_name() << std::endl;
167 std::cout <<
"parsed_uri.path: " << parsed_uri.path << std::endl;
170 if (parsed_uri.path.find(std::string(
".local/share/" + context.
package_name() +
"/")) != std::string::npos ||
171 parsed_uri.path.find(std::string(
".cache/" + context.
package_name() +
"/")) != std::string::npos)
182 (parsed_uri.path.find(std::string(
".local/share/com.ubuntu." + context.
profile_name() +
"/")) != std::string::npos ||
183 parsed_uri.path.find(std::string(
".cache/com.ubuntu." + context.
profile_name() +
"/")) != std::string::npos))
191 else if (parsed_uri.path.find(std::string(
"opt/click.ubuntu.com/")) != std::string::npos &&
192 parsed_uri.path.find(context.
package_name()) != std::string::npos)
194 return Result{
true,
"Client can access content in own opt directory"};
196 else if ((parsed_uri.path.find(std::string(
"/system/media/audio/ui/")) != std::string::npos ||
197 parsed_uri.path.find(std::string(
"/android/system/media/audio/ui/")) != std::string::npos) &&
200 return Result{
true,
"Camera app can access ui sounds"};
210 (parsed_uri.path.find(std::string(
"Music/")) != std::string::npos ||
211 parsed_uri.path.find(std::string(
"Videos/")) != std::string::npos ||
212 parsed_uri.path.find(std::string(
"/media")) != std::string::npos))
214 return Result{
true,
"Client can access content in ~/Music or ~/Videos"};
216 else if (parsed_uri.path.find(std::string(
"/usr/share/sounds")) != std::string::npos)
218 return Result{
true,
"Client can access content in /usr/share/sounds"};
220 else if (parsed_uri.scheme ==
"http" ||
221 parsed_uri.scheme ==
"https" ||
222 parsed_uri.scheme ==
"rtsp")
224 return Result{
true,
"Client can access streaming content"};
227 return Result{
false,
"Client is not allowed to access: " + uri};
233 return std::make_shared<apparmor::ubuntu::DBusDaemonRequestContextResolver>(es.
session);
239 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