Re: Initial ideas on portals for file access



On Fri, 2015-03-06 at 21:34 +0100, Alexander Larsson wrote:
The xdg-app stuff for non-sandboxed apps is functioning pretty well 
now, and even if its not 100% there yet its time to start looking at 
making sandboxed application integrate with the system, the so 
called "portals".

I've been thinking a bit about file access in sandboxed apps. There 
are all sorts of files of course, some are the executables and data 
files require for the app to work, and others are internal things 
like save games and databases. These are really not all that hard, 
we already have the readonly files in the app, and per-app writable 
storage for internal files. The more interesting part is instead 
what I'd call documents. These are files that the user is aware of 
and that can be used by multiple applications. Typical examples of 
such files are images, videos, text files, audio files, office 
documents, pdf files.

There are a few ways such documents could be used by sandboxed 
applications:


Might have been easier if you numbered those possibilities ;)

* Application silos


1)


* Allow app access to parts of $HOME


2)


* Allow application access to files after interactive operation


3)


* Implicit permission grants from interactive operations


4)


So, what do we want to do here? I don't think the application silo 
model is a good fit, because its very unlike how desktop Linux works 
(users file are stored in $HOME), and we would be fighting both 
users and existing apps making this work. We could allow partial 
HOME access to some very trusted apps, but that doesn't really 
strikes me as a proper sandbox solution.

In my opinion the last model is the one we need to focus on. The 
question is what kind of implicit permissions are we talking
about. For example, in the case of an open file dialog, here are 
some permissions that could be granted to the app:

 * Ability to read file contents (clearly ok)
 * Access to an actual file descriptor for the file
 * Access to the same file at a later time (how much later?)

How do you tell that it's the "same file"? It has the same path? How 
would you end up pruning your whitelist of allowed apps for each path?

 * Access to a new version of the file at the same place
 * Ability to replace the file with a new version
 * Access other files in the same location (say video subtitles)

That sounds iffy. It would be better if the application calling the 
file chooser could ask for certain annex files, and the user could see 
that those files are related.

 * Knowledge about the file (filename, mimetype, mtime, etc)
 * Knowledge about the file environment (pathname, type of share, 
etc)
 * Ability to persist the file reference for later in e.g. "recent
files"
   (across app restart, and/or system restarts)
 * Ability to pass the cookie to another app

I don't think all of these are should be granted, but some
should. Clearly the open call has to returns some kind of (probably 
persistent) opaque cookie that refers to the file and has app
permission stored on it.

Michael mentioned the "save" use case, I'll mention the Camera 
application use case. I captured a screenshot/webcam/camera picture 
which will get stored in the "photos" store. I'd like to pass that 
picture to another application to get modified (say, GIMP) and have 
that application send it back when done.

Passing the same cookie as the original application will make it 
difficult to revoke the photo touchup application's permissions on 
that photo.

I could imagine whatever daemon running in the background acting as 
the broker for those apps.

                   Camera app (through user)
- I have this photo, I'd like to pass it to another app to get modified
                   Daemon
- Sure, there's your list of apps
                   Camera app (through user)
- This one, here's a read-only handle for the image
                   Photo touch-up app
- Here's some kittens and and bold text to put on top. All done, 
here's another read-only handle for another image, and the handle for 
the original image.
                   Daemon
- Let me check whether that matches. Yep, still ok with Camera app. 
Camera app, there's your modified image corresponding to this one you 
asked to modify.
                   Camera app
- Cheers. Storing that here. Or overwriting the original. What do you 
say user?

<snip>
Here are some assumptions I'm making on how document files will be 
used.  I believe these are realistic, and these limitations will 
help us design the APIs.

* A document instance would be read only (i.e. no in place 
replacement
  like databases or log files)
* A document can be replaced with a new version
* Document could be read/written as a stream, but they are also often
  done using seeks (for instance seek in videos, or back-patching
  file headers when saving).
* Documents can be large (videos)
* Applications will work on the files as if they were local, rather
  than as if they were doing a network operation. This implies a
  possible download/upload operation outside the app.
  If you need to do streaming from the network you should use an
  actual network protocol library instead.
* Documents can be local files, or from a network filesystem (smb,
  nfs) or from some kind of cloud service (google drive)

Given the above, here is a strawman proposal for how this could work:

There is a dbus service on a well known name on the session bus. All 
requests about documents goes through it, and all sandboxed apps can 
talk to it.

All references to documents are done via opaque cookies, which are 
stored on the host side, and contain per-app permissions for 
operations/information. These cookies are persisted by the dbus 
service, so an app can store them in they data.

Cookies are created by interactive requests, like open file dialogs, 
or save as dialogs, although we may allow an app to create a cookie 
for an already existing file belonging to itself without interaction.

Actually reading and writing files is done by passing a file
descriptor to the application. In the read case, a read-only one for 
the actual file (or a cached copy), and in the write case a read-
write one for a temporary file.

All operations are fully async, and have some kind of reference to a 
parent window so that they can do slow i/o and show interactive 
dialogs.

Here are some available operations:

Open() - open document dialog, then optional download dialog
  Input: document type filter
  Output: A cookie
  Permissions granted:
    Allow reading the current version forever
    Allow reading future versions forever (maybe?)
    Allow getting file metadata
    These permissions affect only this app, other (sandboxed) apps 
have
      no access, so you can't pass on the cookie

SaveAs() - save-as dialog, then optional upload dialog
  Input: Initial title (can be used as filename)
  Output: A cookie
          A fd to write the file data to
          A way to set preview and metadata on the new file
  Permissions granted:
    Allow Save() without UI until a new version of the document
    Allow reading the file until a new version of the document

Save() - save new version to existing cookie, optional upload dialog
  Input: Cookie
  Output: Shows dialog if not allowed:
             No auth at all: "app foo wants to save..."
             Auth on previous version: "The file has changed since 
last
              time, do you still want to save"
          Way to write the data as in SaveAs()
  Permissions granted:
    Allow save and read of the new versions (until new version)

We would also have to make up some new kind of url scheme so that we 
can persist these cookies to files, and so that we can pass then to 
apps when we open files (i.e. when you click on a file in the file 
manager).

There are some weaknesses i see here:

* The database for cookies risk growing forever, as its generally
  hard to know how to revoke some permission.
* In the save operation, I can't think of a good way to revoke access
  to the file once the app has finished writing and we're about to
  rename it over the old file. This means an app can modify a file
  that some other app is reading.
* In wayland we don't have a great way to "parent" dialogs between
  client, so we can't make the file selector seem to be owned by
  the window that requested the file operation without some form
  of compositor help.


I think that the file selection window should be owned by the 
compositor/shell, and should be unspoofable. It's a permission 
granting job after all. It could be populated by the application in 
some limited way for internal "sharing".

Anyway, this can be fleshed out more, but I'd love to hear some 
feedback on this first.

The Open/Save dialogues are kind of a special case of "Sharing". I 
would expect a way to open a URL, a Photo from the Photo library, etc. 
to be one of 2 mechanisms, the pull one.

I think that the majority of interactions would instead be push ones. 
Send this video file in my Mail to the video player, share the URL of 
this web page to Twitter, open this PDF from the web to my Documents.

This doesn't need cookies, at worst a receipt that the data has been 
received on the other end if you want to "move" it from one app to the 
other.

HTH


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]