-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

On Wed, Aug 09, 2017 at 07:28:21AM -0700, Andrew Morgan wrote:
> On 08/08/2017 03:38 AM, Andrew Morgan wrote:
> > Another report with some long-awaited news, enjoy!
> > 
> > Blog post with screenshots:
> > https://blog.amorgan.xyz/gsoc-weekly-progress-report-8.html
> > 
> > Otherwise text-only is below (with screenshots attached):
> > 
> > ---
> > 
> > Hey there, welcome to another report! Since the last one, you may
> > remember that I had finished setting up the build environment for
> > Nautilus inside of GNOME Builder and was just getting started on
> > properly doing the patch for supporting file trust attributes. Well, I'm
> > happy to report that the patch is now finished! Screenshots and details
> > below.
> > 
> > ## Working Demo
> > 
> > As screen recording in dom0 still isn't really doable yet, you'll have
> > to settle for some screenshots of it in action :)
> > 
> > ![Double-clicking a trusted file opens
> > normally...](images/open-trusted.png)
> > *Double-clicking a trusted file opens normally...*
> > 
> > ![Everyone knows gedit is the ultimate text
> > editor.](images/opened-gedit.png)
> > *Everyone knows gedit is the ultimate text editor.*
> > 
> > ![Whereas an untrusted file summons a DispVM!](images/open-untrusted.png)
> > *Whereas an untrusted file summons a DispVM!*
> > 
> > ![Virus free, yes-sir-ee!](images/opened-dispvm.png)
> > *Virus free, yes-sir-ee!*
> > 
> > This short demo makes use of a majority of all the different components
> > that have been worked on throughout the project. The now-patched
> > Nautilus makes a call to the patched NautilusPython which asks our
> > `qvm_trust` python extension to open a file, which it gives a response
> > based on what our cli tool, `qvm-file-trust`, says about it, and if it
> > is determined an untrusted file, `open-file-trust-based` will open it
> > securely in a DisposableVM. The contents of the file were never parsed
> > on the local machine!
> > 
> > The low-level part of this process was already working, but it took the
> > patch to Nautilus allowing us to set off the chain from the GUI to
> > really bring it all together. Let's talk about how that was done and how
> > it works.
> > 
> > ## Nautilus and NautilusPython
> > 
> > By default, Nautilus does not support extensions written in Python, but
> > rather only those written in C. To get around this, a _Nautilus C
> > extension called NautilusPython_ was created. This extension has the
> > ability to provide a bridging interface from Nautilus' extension
> > infastructure to Python, handling any calls Python programs make to
> > Nautilus and calling them from C. Arguments and return variables are all
> > passed along seamlessly.
> > 
> > This is a really nice feature, as writing extensions in Python are about
> > 90% less work than writing them in C, due to the large amount of
> > boiler-plate associated with setting up and tearing down an extension.
> > If you recall, the point of patching Nautilus was to allow extensions to
> > be able to be notified of when a file is being opened, and block that
> > request if necessary. I didn't want to subject myself or anyone else to
> > only being able to write an extension that made use of this new
> > functionality in C, thus patching NautilusPython as well as Nautilus
> > itself to add our new `file_open` function was necessary. So how was
> > each one done then?
> > 
> > Patching NautilusPython to add a new method was relatively simple, you
> > only need look at the existing methods that an extension can subclass,
> > find one that is functionally similar your own (I used
> > `update_file_info` as my guide), then insert your own method
> > (`file_open` in this case) at all the relevant points as well as create
> > the appropriate function bodies and set argument/return variables
> > appropriately.
> > 
> > So overall NautilusPython wasn't too bad really. The real time sink was
> > Nautilus itself.
> > 
> > ## Patching Nautilus
> > 
> > First of all, I almost immediately ditched GNOME Builder after my last
> > blog post. It's not that it was a bad IDE, far from it actually, I quite
> > liked the interface and the various tools it contained. The ability to
> > download a project from git, package and run it inside a Flatpak, and
> > then send patches upstream all from within the editor was quite
> > appealing! The first major showstopper however, was that the version of
> > Nautilus that Qubes makes use of (v3.22.3), doesn't support Flatpak.
> > While building and running from GNOME Builder without Flatpak seemed
> > possible, no matter what I tried I could not get extensions to function
> > properly with the GNOME Builder version.
> > 
> > After a lot of fiddling about, I settled on what I probably should have
> > been using since the very beginning:
> > [qubes-builder](https://github.com/qubesos/qubes-builder)!
> > 
> > Not only does it build the correct version (and supports extensions),
> > but I knew that whatever I did with this build system would be exactly
> > what users would be using when they built Qubes' templates or got them
> > from the build servers. So, unfortunately no Flatpak'd builds, but I do
> > have pre-packaged RPMs with debug-symbols! That's probably even better,
> > right?
> > 
> > I'll post them in a separate blog post with instructions on how to set
> > everything up soon.
> > 
> > qubes-builder worked very well and was quite easy to drill into and mess
> > about with, as it is mostly just a collection of various scripts. I
> > eventually built a script that ran in dom0 that would build Nautilus in
> > my development VM, transfer it to my testing VM, delete the old version
> > and install the new version.
> > 
> > The only downside to this process was that building Nautilus took quite
> > a while each time (2-3m) which made quick changes quite an agonizing
> > process. I believe this was due to both having to rebuild _every_ file
> > each time (as they were packaged in a .tar.xz before being built,
> > meaning all files were considered to be modified) as well as a call to
> > `dnf` to fetch any updates was made, _every time_. I found out the
> > latter when working without internet and realizing my could would not
> > build! Each of these things probably could have been worked out or
> > changed if I had felt the need to, but I just stuck with the loading
> > times and usually had internet, so it was not too terrible.
> > 
> > Was _was_ terrible and time-consuming were a couple of very strange
> > issues I had during the creation of the patch.
> > 
> > The first was the dreaded _provider issue_. You see, every time Nautilus
> > calls a method that is meant to be subclassed by a Nautilus extension,
> > you must _provide a provider_. This can be an `INFO` provider, `MENU`
> > provider, and so on. Each method only accepts one of each type,
> > typically corresponding to the category of method you were calling. For
> > the `file_open` method I decided to stick it under the `INFO` provider
> > category, as that had to do with information about files, which I felt
> > 'when they were opened' best fell into.
> > 
> > Well, these providers don't just pop out of nowhere. You have to create
> > them! You can do that by calling the intuitively-named
> > `nautilus_module_get_extensions_for_type` method, providing it the
> > `NAUTILUS_TYPE_INFO_PROVIDER` enum. It is then _supposed_ to return a
> > provider with a type that matches the one you gave it, but no matter
> > what I did it would always just return a `NULL` pointer! I spent _days_
> > on this problem, trying loads of different things. Every other call of
> > `nautilus_module_get_extensions_for_type` had no special setup or
> > initialization, leading me confused why my own calling of it brought
> > such different results.
> > 
> > After picking through many lines of code, talking with GNOME people over
> > IRC who were currently GUADEC'ing, and trying to understand the whole
> > GNOME development ecosystem, I eventually traced it all back to
> > NautilusPython not finding an extension that made use of a subclassed
> > method from the `INFO` method type. But wait, we _do_ have an extension
> > that does that with `qvm_trust`, so why doesn't it work??
> > 
> > Well I hit my head after this one folks. The version of NautilusPython
> > that Nautilus was loading in my test VM was the original, from-repo
> > version, not our modified version. **D'oh!**
> > 
> > "Well that's just a simple fix, I just have to build it and import it
> > into Nautilus in the testing VM!", I assumed, before realizing that
> > while my modified NautilusPython built, Nautilus _would not accept it_.
> > Nautilus would just _hang_ with little to no output.
> > 
> > After a few emails, Marek pointed me in the correct direction with the
> > `nautilus-3.0` branch of NautilusPython, which, while 6 years since the
> > last commit, worked with the latest version. Alright no problem. Rebase
> > my commits on that branch, rebuild, transfer the newly-built
> > shared-library over and bam, Nautilus runs again! And we have a provider
> > that's not NULL, hooray!
> > 
> > And then, ladies and gentlemen, problem #2 reared _its_ ugly head.
> > 
> > Here's the code to get a list (`GList*`) of providers to use with a
> > Nautilus extension:
> > 
> >     providers = nautilus_module_get_extensions_for_type
> > (NAUTILUS_TYPE_INFO_PROVIDER);
> > 
> > While we were getting a _non-null_ provider value, the value we received
> > was _different_ from the one returned by the method we called. "Wat?"
> > you say, and I too said the same. For some reason we were returning a
> > 64-bit `GList` pointer from `nautilus_module_get_extensions_for_type`,
> > but storing a 32-bit `GList` pointer in `providers`.
> > 
> > I tried all sorts of weird tricks to get this fixed. Nobody I talked to
> > seemed to have a solution, and after wrestling with it for a few days I
> > begrudingly settled on this very elegant workaround:
> > 
> >     // TODO: Providers ends up as 0x55f65ac0
> >     // when method is returning 0x555555f65ac0, very odd...
> >     providers = (GList*) (nautilus_module_get_extensions_for_type
> > (NAUTILUS_TYPE_INFO_PROVIDER) + 0x555500000000);
> > 
> > Yes I know this is terrible. It did work though, and I needed to stop
> > hitting this strange bug and get on with patching, so that's where it
> > currently sits. I'm still actively looking for a proper solution. If
> > anyone knows why a 64bit pointer might get truncated to a 32bit pointer
> > after a function call in C please do let me know! You can find the full
> > code
> > [here](https://github.com/anoadragon453/nautilus/blob/master/src/nautilus-mime-actions.c#L2496)
> > and the `type` method
> > [here](https://github.com/anoadragon453/nautilus/blob/master/src/nautilus-module.c#L269).
> > 
> > After this was out of the way, and a handful of more methods were
> > implemented, we finally had a working solution between the `qvm_trust`
> > extension and our patched Nautilus! It was beautiful, really.
> > 
> > ## Conclusion and going forward
> > 
> > My [email](https://amorgan.xyz/upstream-request.html) to the [Nautilus
> > mailing list](https://mail.gnome.org/archives/nautilus-list/) is still
> > awaiting moderation. GUADEC has now concluded, and with no update on the
> > situation it seems I need to do some more active poking of people to get
> > moderation approval. We'll see where that lands, the code still needs to
> > be cleaned up a bit before sending it upstream anyways, so I'm not too
> > worried.
> > 
> > At this point in the project, we essentially have the following tasks left:
> > 
> > * Patch KDE Dolphin to provide the same functionality as Nautilus now does
> > * Finish up some small tasks with the daemon like logging and some more
> > interfacing with the cli tool
> > * Code cleanup, linting, tests
> > * Integrate into main QubesOS repos
> > 
> > I'm going to prioritize the latter 3 bullet points at this point to
> > ensure we get a really solid core implementation down of the project. I
> > don't want to spend another couple weeks patching Dolphin only to run
> > out of time for a general cleanup and other polish. I will try to pour
> > through the Dolphin code and note down everything that one would need to
> > do with Dolphin to make it work with file trust attributes, so that in
> > the future either myself or someone else can give it a shot.
> > 
> > It may end up that Dolphin already has most of the functionality and the
> > patch will be very small, we'll see!
> > 
> > Anyways, for now I'm going to start on finishing the remaining small
> > tasks, and will post any questions regarding packaging and/or cleanup to
> > the qubes-devel mailing list.
> > 
> > As always, you can find the code
> > [here](https://github.com/anoadragon453/qubes-mime-types).
> > 
> > And as of now, you can also find the patched code for
> > [Nautilus](https://github.com/anoadragon453/nautilus) and
> > [NautilusPython](https://github.com/anoadragon453/nautilus-python/tree/nautilus-3.0)
> > on Github as well. Make sure that when you're inspecting the
> > NautilusPython code, you're looking at the `nautilus-3.0` branch. That's
> > where all the important commits are!
> > 
> > That's all for now, thanks for reading!
> > 
> 
> Marek,
> 
> The git commits for nautilus/python seem like a bit of a mess at the
> moment. Are you currently reviewing them individually or can I squash
> them into just a few and force push to the repo?

Feel free to squash them.

- -- 
Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQEcBAEBCAAGBQJZiyRaAAoJENuP0xzK19csug0H+wRi9RLWQWHmMBznsWUFquvL
qF4UOKrUpTd463fUGdzOIIWqlox9gciu7X3mOIsXBmoCTyt9ouq2dsHV80WSpku/
9Wn/smKf01jQNYgRq9ZJ80jOU3TjAZcTwMgG1KynHPTKOJHf4EBQmCsKIjZtyAVk
DbnkHIFxb0npUIFqUqr7qJF/f9Sx0WgTR3LlHrbmIIkXHPr01K9YN/SGqIJrw8Wh
JWV6m0mJHjQXSnJccG58FbLBdA0J/Mf0T20mV+5vQKj1QwH0bOci6+V7PMC9HKN2
xEGPR8dF14gQvwEq1EHWN8kdkjD00ttM1eTdzz4CAUzPyLGsAppP9lGwTsd2B84=
=92f+
-----END PGP SIGNATURE-----

-- 
You received this message because you are subscribed to the Google Groups 
"qubes-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to qubes-devel+unsubscr...@googlegroups.com.
To post to this group, send email to qubes-devel@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/qubes-devel/20170809150354.GM1145%40mail-itl.
For more options, visit https://groups.google.com/d/optout.

Reply via email to