[GSoC] Qubes-MIME-Handlers Weekly Progress Report #7

84 views
Skip to first unread message

Andrew Morgan

unread,
Jul 24, 2017, 5:36:41 AM7/24/17
to qubes...@googlegroups.com
Hello everyone! After a lapse of a week, another progress report has
been completed for you all to read up on.

As always, the blog post with screenshots is here:
https://blog.amorgan.xyz/gsoc-weekly-progress-report-7.html

Otherwise text-only is below (with screenshots attached!):

---

Hello and welcome to another weekly report!

Since the last report a few exciting things have been completed. This
includes packaging of qvm-file-trust as an installable python package, a
functioning qubes-trust-daemon, and some strong headway on patching
Nautilus!

So without further ado, let's get into it:

## Pretty Python Packaging

`qvm-file-trust` has been moved from the project's root directory into
its own directory and its own python package. This has the benefit of
cleaning up the root folder a bit, but more importantly allowing for
proper importing into other python scripts.

Tests have been refactored to no longer use the hacky method of
importing `qvm-file-trust` and instead import the new `qubesfiletrust`
package directly.

Finally, installing the python package and all the other scripts can now
be achieved through the use of a Makefile. Simply `sudo make install`
and you're done!

## Daemon Challenges

Coming from python back to C++ took a moment of re-adjustment as I had
started to get used to the conveniences that python provides. There is
however no doubt that the tradeoff of what C and C++ offer in terms of
performance are worth the drop in comfort.

What was interesting was that even after deciding to switch
`qubes-trust-daemon` from C to C++, a majority of the code that went
into programming the daemon was C compatible. Low-level libraries like
`inotify` are written for C, and one must interact with them with C-like
components such as null-terminated character arrays as opposed to C++'s
std strings. In this sense, C++'s ability to handle nearly all C code is
thus incredibly useful.

After a few days I became comfortable working within these two
languages. C offers necessary power and speed, while C++ offers many
convenient classes and functions that I was able to make use of.

So after all that, here's the story on what is completed with
`qubes-trust-daemon` and what still needs to be done:

What's done:

* Grab a list of untrusted folders from the global and local list
* Place an inotify directory watch on those folders and subfolders and
listen to various file change events
* Act on events such as items being created or moved inside of untrusted
folders. Upon catching one of these events, we either watch the new
folder for further events, or if it is a file, mark that file as untrusted
* Handle files being deleted or moved out of watched directories

What's still to do:

* Proper error reporting
* Testing

Currently, the list of untrusted folders are grabbed and sorted by the
daemon directly and then passed to other functions. I am considering
adding the ability to export the list that `qvm-file-trust` creates as a
line-by-line list to stdout and having the daemon capturing that instead.

The upside to this is that there is only one implementation of parsing
and sorting the lists and it is written in a language where there are
less likely to be parsing errors by the programmer. The downside will be
that you must start up an instance of `qvm-file-trust` to perform this
action, but as it will only be done once per initialization of the
daemon, the cost is mostly negligible.

As it stands on my i7-4810MQ, only 6.7% of the VM's CPU (2 out of my 4
cores) is used as a couple tens of thousand files are being marked as
untrusted on startup and on moving a large folder in. That CPU usage is
well within reasonable levels, especially on such a large operation.
That is a win in my book.

## Nautilus

The patch for Nautilus is finally getting going! After some hiccups with
Nautilus' build process, I've now switched to [GNOME
Builder](https://wiki.gnome.org/Apps/Builder) for the compilation and
run management of Nautilus. Builder provides a much cleaner experience
when building and compiling, and after only hearing about it here and
there, it was exciting to finally download and try it out.

After a couple hiccups with importing the Nautilus code and checking out
the correct branch (gnome-3-22 in this case) with the help of some fine
folks on #gnome-builder, Nautilus was building and launching as expected:

![Nautilus built and running from
Builder](images/nautilus-gnome-builder.png)
*Nautilus built and running from Builder*

The other advantage GNOME Builder holds is its ability to build all
projects as flatpaks. This makes it much easier to share testing builds
of Nautilus without asking people to install Nautilus' [horrible list of
dependencies](https://ubuntuforums.org/showthread.php?t=1678656&p=10426119#post10426119),
and instead just run a single command to start it up!

In addition to Nautilus, GNOME Builder is also helping me with patching
[nautilus-python](https://wiki.gnome.org/Projects/NautilusPython/),
which are the python bindings that allow extensions written in python to
interact with Nautilus' C API.

[This
folder](https://git.gnome.org/browse/nautilus-python/tree/src/nautilus-python-object.c)
houses the definitions of functions that can be referenced in
`nautilus-python` extensions. Nautilus' maintainer, Carlos Soriano, also
kindly pointed out where these methods connect to Nautilus itself, which
turns out to be
[here](https://git.gnome.org/browse/nautilus/tree/libnautilus-extension).

The typical workflow in a `nautilus-python` extension is to define a
function that corresponds to the data or action you desire, then return
some data based on some logic you have in your extension. My plan is to
create another function here that will be called when a file is
determined to be opened. The file will then be opened depending on
whether the extension returns a `True` or a `False`.

A new DisposableVM with the file in question can be launched from within
the extension, so there is no need for any Qubes-specific code to go
into this patch.

## User UX

In other news, in addition to the [Dolphin Folder
Color](https://github.com/audoban/dolphin-folder-color) that allows you
to set the color of a folder from an extension, I have now come across a
similar offering for Nautilus, titled simply [Folder
Color](https://foldercolor.tuxfamily.org/)
([code here](https://code.launchpad.net/~costales/folder-color/trunk)).

With the ability to now mark untrusted folders with a color (likely
red), and with Nautilus and Dolphin _already_ adding an icon for
untrusted files (due to their unreadable nature), I no longer see any
reason to add additional icons on top of this. After a few rounds of
testing, seeing many 'warning' and 'lock' icons on files got a bit
repetitive anyways :)

## Conclusion

Phew, that was quite a few things to talk about. At this point I'm going
to be devoting the majority of my time to get Nautilus' patch
functional. Once we have a complete GUI + cli tool + daemon working
together we can more easily get a picture of how to test and tweak the
overall flow of the tool.

I'll also be providing flatpak's of Nautilus for easier testing, which
will most certainly be appreciated once they are available!

Anyways, that is all for now. As always, you can find the code
[here](https://github.com/anoadragon453/qubes-mime-types).

Have a wonderful day!

Andrew Morgan
nautilus-gnome-builder.png
signature.asc

Andrew Morgan

unread,
Jul 25, 2017, 8:53:15 PM7/25/17
to qubes...@googlegroups.com
To clarify on this after some digging today, Nautilus officially only
supports extensions written in C. There are a few extensions that are
included in Nautilus' source tree (such as the sendto extension), but
all one needs to do to install an extension is to place the extension
library in `/usr/lib(64)/nautilus/extensions-3.0/`, restart Nautilus and
it should be installed.

NautilusPython is a Nautilus C extension. It's purpose is just to read
python scripts that perform extension actions and translate those into
the C actions Nautilus is used to. It's a completely separate
compatibility layer.

This is all fine and dandy, and means that if needed, really only
Nautilus (not NautilusPython) would have to be patched to include new
bindings for file open events, and a C Nautilus extension could be
written to make use of it.

I'm going to strive to have NautilusPython be compatible with the new
bindings though, since writing extensions in C is a heck of a lot more
work and setup then their Python counterparts.

One blocker I'm having at the moment is getting the gnome-builder
version of Nautilus to recognize extensions. The 'gnome-3-22' branch
version, to my knowledge, does not support building with Flatpak (or at
least there was no manifest defined, even though it could be built and
ran from gnome-builder).

The version that was built couldn't find installed extensions however,
which lead me to think it was packaged as a Flatpak, with a policy that
prevented reading it from the extensions directory. (Though I could
navigate to the extensions directory in Nautilus, so presumably you can
access it??)

Checking out the master branch did reveal a Flatpak manifest
(org.gnome.Nautilus.json), however I am unable to build the latest
version due to a dependency on glibc v2.51.2 on Fedora 25 (v2.50.3 is
installed).

Also not even sure if the latest version is compatible with Qubes since
we use 3.22 Nautilus at the moment..

Anyways, that's where I stand with all that. IRC has been helpful with
some answers, but I still have a lot of questions :)

Andrew Morgan

signature.asc

Marek Marczykowski-Górecki

unread,
Jul 25, 2017, 9:23:10 PM7/25/17
to Andrew Morgan, qubes...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
+1

> One blocker I'm having at the moment is getting the gnome-builder
> version of Nautilus to recognize extensions. The 'gnome-3-22' branch
> version, to my knowledge, does not support building with Flatpak (or at
> least there was no manifest defined, even though it could be built and
> ran from gnome-builder).

I'm not really sure if you need to spend time on getting Flatpak build
working. If you build the same (or similar) Nautilus version as is
already installed in the template, all dependencies should be already in
place, so it should be still easy.

> The version that was built couldn't find installed extensions however,
> which lead me to think it was packaged as a Flatpak, with a policy that
> prevented reading it from the extensions directory. (Though I could
> navigate to the extensions directory in Nautilus, so presumably you can
> access it??)
>
> Checking out the master branch did reveal a Flatpak manifest
> (org.gnome.Nautilus.json), however I am unable to build the latest
> version due to a dependency on glibc v2.51.2 on Fedora 25 (v2.50.3 is
> installed).
>
> Also not even sure if the latest version is compatible with Qubes since
> we use 3.22 Nautilus at the moment..
>
> Anyways, that's where I stand with all that. IRC has been helpful with
> some answers, but I still have a lot of questions :)

Maybe, just guessing, it looks for extensions somewhere else? Like /lib
instead of /usr/lib or such. I'd check ./configure (or equivalent)
options. And if still nothing, use strace to check where it really looks
(log to a file, then grep for "extensions" or some similar phrase). See
"-s ..." and "-v" options if paths are truncated in log.

- --
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

iQEcBAEBCAAGBQJZd+74AAoJENuP0xzK19csyRwH/1yODam87a7KootM/SY3M+0Y
AAy9pDRvJ3vCh1VAQ6bd6hJ7XtwdPDLgbVGXRfvwIt9AcOf0hZGcEGwyQGwbfp+p
JDuLwBl+GYcjXbq3jidnCKF0Ds5LAzbjDIH+PXBfCXUza5tGLi7d8CGy4gdfBKW6
0UAjExpAEI4Iayw8kugNw3ddYh9usAcW9qs7J0TlmKOEK9V8OfzwNuH4BJymt/WE
fGhn6fJOYwP35evYprZX7WOiOzPqy6SNWAhTamCrHubVGfK76lmleSryepMz7tws
GE2wF9MntoXr/C1TGmmoWDeS/fIU4gqwJEc4ij7qUBtmqunbs91+Cpw4H+upULA=
=pVw7
-----END PGP SIGNATURE-----

Andrew Morgan

unread,
Jul 25, 2017, 11:55:15 PM7/25/17
to qubes...@googlegroups.com
Is it possible to build just Nautilus with qubes-builder? That may make
things much closer to what we want.

>
>> The version that was built couldn't find installed extensions however,
>> which lead me to think it was packaged as a Flatpak, with a policy that
>> prevented reading it from the extensions directory. (Though I could
>> navigate to the extensions directory in Nautilus, so presumably you can
>> access it??)
>
>> Checking out the master branch did reveal a Flatpak manifest
>> (org.gnome.Nautilus.json), however I am unable to build the latest
>> version due to a dependency on glibc v2.51.2 on Fedora 25 (v2.50.3 is
>> installed).
>
>> Also not even sure if the latest version is compatible with Qubes since
>> we use 3.22 Nautilus at the moment..
>
>> Anyways, that's where I stand with all that. IRC has been helpful with
>> some answers, but I still have a lot of questions :)
>
> Maybe, just guessing, it looks for extensions somewhere else? Like /lib
> instead of /usr/lib or such. I'd check ./configure (or equivalent)
> options. And if still nothing, use strace to check where it really looks
> (log to a file, then grep for "extensions" or some similar phrase). See
> "-s ..." and "-v" options if paths are truncated in log.
>
>

Yeah ran an strace on it though it's a little tricky as I can only start
the builder version from builder itself. Extensions are likely loaded as
soon as Nautilus starts up, thus I'm not sure how to strace the PID
before I start the program from Builder. Builder's profiling tools are
also lacking the ability to check what files are accessed.

That said, if qubes-builder can build Nautilus then we shouldn't have to
worry about any of that.

File sandboxing a File Manager seems like a silly thing to do anyways :)

Andrew Morgan

signature.asc

Marek Marczykowski-Górecki

unread,
Jul 26, 2017, 4:29:51 AM7/26/17
to Andrew Morgan, qubes...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

You'll need source package (.spec for rpm for example). You can start
with upstream source package:
- dnf download --source nautilus && rpmdev-extract nautilus*src.rpm
- apt-get source nautilus

Then place resulting files in a subdirectory of qubes-src and add
Makefile.builder with either (or both):
RPM_SPEC_FILES = relative/path/to/spec
DEBIAN_BUILD_DIRS = debian (actually, a path to a directory with "control" file)

For RPM, qubes-builder will handle unpacking sources, for Debian, you
need to add commands to do it into Makefile.builder, something like:

ifneq ($(filter $(DISTRIBUTION), debian qubuntu),)
SOURCE_COPY_IN = debian-source-copy-in
endif

debian-source-copy-in: SRC_FILE = "$(CHROOT_DIR)/$(DIST_SRC)/nautilus-x.y.z.tar.gz"
tar xf $(SRC_FILE) -C $(CHROOT_DIR)/$(DIST_SRC) --strip-components=1

Some more details here:
https://github.com/QubesOS/qubes-builder/blob/master/doc/ComponentConfiguration.md

- --
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

iQEcBAEBCAAGBQJZeFL5AAoJENuP0xzK19csyYAH/1Q0l1QMm5/MH5YlRb7zdKAL
EKvl4u45vxAEWxblyqr7Iuw8JBkmkfwXzwSRN3o/+rmCJNg7zHWwiG54C2KUE/pF
G33nqrcE62udnmFVfvwGkyUI+g95Bvu1qCeA7Q8Bep7CwJKCQ9qri4GqjkfK3oWx
vqVG37M1sBqpdT/PWWpOjd/lww7X2XPqn2pSHXRZA2cK/fSPXIJGyuWGf8Lpjk9F
QvOglJqRBrFV6PhkabOWC8cI8axN3AuAAMpx5Dqfm1Wbam2WygWSNsiCG9Bm6GjV
jfS86onxZY4RqtzStDVWcwS+Wjalgp9NL7foetR54FnEQUqFYoU9Zaa+gV/s1v0=
=FZqG
-----END PGP SIGNATURE-----

Andrew Morgan

unread,
Jul 27, 2017, 10:01:48 PM7/27/17
to qubes...@googlegroups.com
Hey Marek,

I was able to build an entire f25-minimal template. Is there any way to
build just the app or perhaps just build a new copy of Nautilus for an
existing template?

Thanks,
Andrew Morgan

signature.asc

Marek Marczykowski-Górecki

unread,
Jul 28, 2017, 4:21:44 AM7/28/17
to Andrew Morgan, qubes...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Yes, I recommend "make help" ;)
In short: "make component-name", like "make core-agent-linux". It will
print list of built packages at the end - you need to copy them into
appropriate (Template)VM and install using rpm or dnf.

To build nautilus (which is by default downloaded from upstream
repositories as binary package), you need to add new component,
according to instruction above.

Also, other builder documentation
https://www.qubes-os.org/doc/qubes-builder/

- --
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

iQEcBAEBCAAGBQJZevQSAAoJENuP0xzK19csPLAH/0hgqeQiwMSGPeeqaB17F/l3
3tqUa9zAttAHHDdMcic0w2v0AB6hAQl8bfXMq+CTLfO/wRBKc0fMKkXmFeLby21y
ds78yuJvOKn14yjZdAWy7WRg55u2NdAySROeI2tr749lK6Bj8JU8svwY+NLtN9+m
pomuhEUTYvDYbAK9gTKZtqV3Ckl4MkGMFY4U9EBBTeyFXfcK/qIpnGoYAC3fBoLH
c+uh/T7XNd8P86697cSJwj1HFZv0w/bPHU7md3ZLD0ZZNg1pFMpuslrJopUxZeib
0E024cyPasWIM1gPL2bFH45Wy69ldudS0cGTSGHCZNjqN87JoHh12Td7oIC7EVY=
=Ueos
-----END PGP SIGNATURE-----

Andrew Morgan

unread,
Jul 28, 2017, 11:47:27 PM7/28/17
to qubes...@googlegroups.com
Thanks Marek, I've managed to get it working and all automated with a
dom0 script.

I'll also make sure to update you guys more often on my progress going
forward ;)

Thanks,
Andrew Morgan

signature.asc

Andrew Morgan

unread,
Jul 29, 2017, 11:43:41 PM7/29/17
to qubes...@googlegroups.com
Quick progress update:

I've created the following repos to hold progress of the nautilus patch:

https://github.com/anoadragon453/nautilus
https://github.com/anoadragon453/nautilus-python

The nautilus repo doesn't have commit history as checking out the
gnome-3-22 branch from upstream produces a tree that's slightly
different from the source package from Fedora repo. Mostly just build stuff.

Commits made on there should still be applicable to the upstream branch
once finished.

Notes/what I've found so far:

NautilusPython creates a Python interface to Nautilus' C extensions. It
is itself a Nautilus C extension. Nautilus extensions are in fact shared
libraries and thus are loaded in at run-time.

There are three main areas across the different codebases to worry about:
NautilusPython: nautilus-python-object.c
Nautilus: nautilus-info-provider.c
Nautilus: Wherever a file open call is invoked

There are a few different categories of methods that can be called by a
nautilus extension. nautilus-info-provider is for getting information
about and dealing with files and file data. There exists a method inside
already called update_file_info, which is called every time a file is to
be displayed on screen, once per file.

If an extension subclasses this method, it will be able to alter file
properties (such as add an emblem) to each file based on that file's
information. Once finished, the extension can return an object that
Nautilus' extension infrastructure can use (what is returns is used for
determining whether Nautilus should block the main thread's execution
until the extension is finished or continue and wait for the extension
to tell it when it's finished, but that is irrelevant here).

Essentially we also want to define a method that can return a value, in
this case a True/False, whenever a file is opened which will tell
nautilus whether to open the file or not.

Thus I've created a new method, file_open, to do just this. All it
should pass to the extension is a NautilusFileInfo object (plus some
other boilerplate), which the extension can then use to get the file
path, pass that to qvm-file-trust, and return a False if the file is
untrusted. The extension should've already began to open the file in a
disposableVM, so Nautilus doing nothing at this point is desired.

I've created some basic structures for the new method in both nautilus
and nautilus-python. I still need to determine where a file is opened
and restructure that to be blockable by an extension (I assume have a
method that just returns True, that can be overridden by an extension to
return false). I'm not sure exactly how Nautilus handles two extensions
updating information about the same file, but presumably it does it in
some sort of mergable way. This implementation will be easier as we can
just take a blocker by any extension to not open the file.

Documentation for both of these project is kind of lackluster, and some
can only be found through the Wayback Machine. Here are the relevant
links which I've found helpful thus far:

Creating Nautilus extensions:
https://web.archive.org/web/20090418175132/http://www.campd.org/stuff/docs/extending-nautilus/NautilusExtensions.html

Nautilus extension API:
https://developer.gnome.org/libnautilus-extension/stable/

NautilusPython docs:
https://projects-old.gnome.org/nautilus-python/documentation/html/index.html

Old NautilusPython docs (has better descriptions for some methods):
https://web.archive.org/web/*/http://projects.gnome.org:80/nautilus-python/documentation/*

Andrew Morgan

signature.asc

Marek Marczykowski-Górecki

unread,
Jul 30, 2017, 5:42:58 AM7/30/17
to Andrew Morgan, qubes...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

For working directly with sources, this is the most convenient way. But
for building and maintaining the package later, it would be better to
have source package + patches. Then for example rebasing it later would
be much easier, and will not mess the git history that much. See here
for example:
https://github.com/QubesOS/qubes-linux-scrypt
or here:
https://github.com/QubesOS/qubes-core-libvirt/

In fact the second example is maintained in a local git repository
(clone of upstream), and patches.qubes directory is result of `git
format-patch ...`. To reconstruct that local repository, you can clone
upstream repo, then `git am patches.qubes/*`.

So, for now your repos are ok. But when finished, you'll need to extract
those patches to:
1) send them upstream
2) create package in maintainable way
Sounds good.

> Documentation for both of these project is kind of lackluster, and some
> can only be found through the Wayback Machine. Here are the relevant
> links which I've found helpful thus far:
>
> Creating Nautilus extensions:
> https://web.archive.org/web/20090418175132/http://www.campd.org/stuff/docs/extending-nautilus/NautilusExtensions.html
>
> Nautilus extension API:
> https://developer.gnome.org/libnautilus-extension/stable/
>
> NautilusPython docs:
> https://projects-old.gnome.org/nautilus-python/documentation/html/index.html
>
> Old NautilusPython docs (has better descriptions for some methods):
> https://web.archive.org/web/*/http://projects.gnome.org:80/nautilus-python/documentation/*
>
> Andrew Morgan
>




- --
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

iQEcBAEBCAAGBQJZfaocAAoJENuP0xzK19csbI4H/RBAsaSJUXyYJI0fhmY5qjB8
qLGLSSn9Y+D2wotwlgxYsOhB5Se+gkQxwoomOaXdr+9QTEDQH3EO7uayBgGDrUv8
9zmv1ePSDWfl/wJ8JkYOhPA6fEsnIYG2Ul9VN7gI7ZDxcIjwyWQt6D7dF2Y9a29a
orNBhoJnGwWWZxTsD0UxZ9tfIJuwHlS+OuOCAvpO9qKN5M4k8Ve5vFlD3HnyJQNF
RRRccDsjFTa5x6mmZUlSPgZn01mQCpXKVbTSGd5hOjyZlUiZzCynGgRRRKfmnNl/
SvBmNuOWMZzhB7thEu5DA0wWIVZEEbgBFejcKr/z4/En+X88G/Q84cPdrMJQCdQ=
=ImZW
-----END PGP SIGNATURE-----

Andrew Morgan

unread,
Jul 31, 2017, 2:49:11 AM7/31/17
to qubes...@googlegroups.com
Quick update for tonight.

I've found where the most likely choke point for opening files is. [1]
Ideally one would just make a call to extensions through
libnautilus-extension through there, wait for responses, then return if
any extension returns a False. I'm unsure if anything in Nautilus on the
UX side needs to happen after that (such as showing a loading icon or
something...) but that's currently outside the scope of this patchset.

I've been talking to and getting help from people on GIMPnet/#nautilus.
After explaining the whole idea to a few people, I've been prompted to
post on the mailing list. I have now done so with a RFC of sorts on the
idea and whether or not they'd be prone to accepting it upstream once
it's ready.

The post is currently awaiting moderation approval, but I'll link it
once it goes up so people can keep up with the discussion.

Andrew Morgan

[1]:
https://github.com/GNOME/nautilus/blob/master/src/nautilus-mime-actions.c#L2421

signature.asc

Marek Marczykowski-Górecki

unread,
Jul 31, 2017, 6:17:15 AM7/31/17
to Andrew Morgan, qubes...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

On Sun, Jul 30, 2017 at 11:48:48PM -0700, Andrew Morgan wrote:
> Quick update for tonight.
>
> I've found where the most likely choke point for opening files is. [1]
> Ideally one would just make a call to extensions through
> libnautilus-extension through there, wait for responses, then return if
> any extension returns a False. I'm unsure if anything in Nautilus on the
> UX side needs to happen after that (such as showing a loading icon or
> something...) but that's currently outside the scope of this patchset.
>
> I've been talking to and getting help from people on GIMPnet/#nautilus.
> After explaining the whole idea to a few people, I've been prompted to
> post on the mailing list. I have now done so with a RFC of sorts on the
> idea and whether or not they'd be prone to accepting it upstream once
> it's ready.
>
> The post is currently awaiting moderation approval, but I'll link it
> once it goes up so people can keep up with the discussion.

Great, thanks for the update!
- --
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

iQEcBAEBCAAGBQJZfwOlAAoJENuP0xzK19cs2sEH/1a9J6AHnSTulLdvxd934G8m
SQlIRhwdjnIY71MKVwY4OfpbcMWFeDgVj8fPZMhPw7CvtZNK3pM6cWUOGJol+hWZ
TSQzbMjTKNJ6zWhoBMOvfPRdy0BTHvn3kerL7XIoyBzPMP4kYq54OzIRnzGs6tGo
mYEnNxoe98Jba6UwLCFLsz1VdS4wrBxANwC24eP1jlhqXrTprtvlNdOogv1HWvbK
qmuCQBVHAX7OgkULOvw6cqD2lN/BWSGYmvC+rAzUM+Ha0UxQ9yKGarVWIg7kTlM0
tM68M1sHjLe7OxX35lpkKU1OxKpcL7lpxL1+5cK92fvKAwHg6Cfgx0bdYGXCer4=
=upFI
-----END PGP SIGNATURE-----

Andrew Morgan

unread,
Aug 1, 2017, 3:59:32 AM8/1/17
to qubes...@googlegroups.com
On 07/31/2017 03:17 AM, Marek Marczykowski-Górecki wrote:
> On Sun, Jul 30, 2017 at 11:48:48PM -0700, Andrew Morgan wrote:
>> Quick update for tonight.
>
>> I've found where the most likely choke point for opening files is. [1]
>> Ideally one would just make a call to extensions through
>> libnautilus-extension through there, wait for responses, then return if
>> any extension returns a False. I'm unsure if anything in Nautilus on the
>> UX side needs to happen after that (such as showing a loading icon or
>> something...) but that's currently outside the scope of this patchset.
>
>> I've been talking to and getting help from people on GIMPnet/#nautilus.
>> After explaining the whole idea to a few people, I've been prompted to
>> post on the mailing list. I have now done so with a RFC of sorts on the
>> idea and whether or not they'd be prone to accepting it upstream once
>> it's ready.
>
>> The post is currently awaiting moderation approval, but I'll link it
>> once it goes up so people can keep up with the discussion.
>
> Great, thanks for the update!
>
>> Andrew Morgan
>
>> [1]:
>> https://github.com/GNOME/nautilus/blob/master/src/nautilus-mime-actions.c#L2421

Another update,

The mailing list post still hasn't been approved. I messaged on GIMPnet
about it not too long ago so hopefully the appropriate people will get
pinged eventually. The team is currently busy with GUADEC so it's
understandable they may be running behind on moderating posts on a not
too traffic heavy mailing list[1] :)

In terms of the patch, I've inserted the necessary code into all the
accompanying files and Nautilus builds successfully. During my testing I
threw a return statement in there and confirmed it blocked all file open
attempts silently, which is intended behavior.

I've stuck the WIP code up on Github, currently it segfaults but the
cause is known. I'll be modifying the qvm_trust.py NautilusPython
extension to make use of this method soon, and once it all works out
I'll provide some pre-made .RPMs for testing.

Thanks
Andrew Morgan

signature.asc

Marek Marczykowski-Górecki

unread,
Aug 1, 2017, 5:53:06 AM8/1/17
to Andrew Morgan, qubes...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Does subscribing to the list workaround the issue? Some times moderator
is set to just one, busy, person...

> In terms of the patch, I've inserted the necessary code into all the
> accompanying files and Nautilus builds successfully. During my testing I
> threw a return statement in there and confirmed it blocked all file open
> attempts silently, which is intended behavior.
>
> I've stuck the WIP code up on Github, currently it segfaults but the
> cause is known. I'll be modifying the qvm_trust.py NautilusPython
> extension to make use of this method soon, and once it all works out
> I'll provide some pre-made .RPMs for testing.

Ok :)

- --
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

iQEcBAEBCAAGBQJZgE99AAoJENuP0xzK19csaokH/RnttNKLqHZdVWCgs95Aw7No
oh9Ay0aYlpThTX3pQKti2oUImrGWguUvOZyaHH0phIkr6Te7TEAwCjKmeiOwCRVA
QF4H+C86tetmk62wPLjGRtCSSP2v5LFnBZc8ISPUvaY40kTvAUqzEnZA1kGtFZPM
e0LJnxUDyAPG67jq1TN+JPTg3GMY2VxJI+c2XGxD4M8YTNA4xSoPRMhS1rS4XMeN
3hnmnwUtc8eTeomIzIFuyaep+JqC6ZxVRNTi88q8bPBEKvk43r1HFXcUJ091TqJ1
1xk9eXAxLFV/EUMspHxvdfe6vPRxJiK6v8Aq6US/B1sk+127riKc2NYor3YPxW0=
=nNh+
-----END PGP SIGNATURE-----

Andrew Morgan

unread,
Aug 1, 2017, 5:54:49 AM8/1/17
to qubes...@googlegroups.com
I presume that's probably the case, yeah. I subscribed before I posted,
didn't seem to make a difference :)
signature.asc

Andrew Morgan

unread,
Aug 2, 2017, 7:34:15 AM8/2/17
to qubes...@googlegroups.com
Another status update for today.

As I said mostly everything's in place, however I'm currently stuck on
trying to provide the correct arguments to a function that calls the
subclassed methods in nautilus extensions.

Here is an example of calling a function subclassed by extensions:
https://github.com/anoadragon453/nautilus/blob/master/src/nautilus-directory-async.c#L4647

The update_complete and &handle arguments are not necessary for our
purposes, but the provider and file args are.

Here I am calling our new method, that asks extensions whether we should
open a particular file or not:
https://github.com/anoadragon453/nautilus/blob/master/src/nautilus-mime-actions.c#L2500

However the provider object is NULL. That
nautilus_module_get_extensions_for_type method is defined here:
https://github.com/anoadragon453/nautilus/blob/master/src/nautilus-module.c#L268

That G_TYPE_CHECK_INSTANCE_TYPE always fails, so we never get any data
prepended. G_TYPE_CHECK_INSTANCE_TYPE doesn't seem to be defined in this
codebase either, which makes it a bit tricky to figure out why we're
getting a negative value back from it.

Talking to people about it on IRC has brought mixed results, it seems
the extension interface hasn't been changed in a while, so most don't
remember too much about it. I'll keep asking though, hoping someone in
the know pops in.

That's where I'm at currently, any help or clues are appreciated.

Thanks,
Andrew Morgan

signature.asc

Marek Marczykowski-Górecki

unread,
Aug 2, 2017, 10:59:55 AM8/2/17
to Andrew Morgan, qubes...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

See this search results:
https://github.com/search?q=org%3AGNOME+NAUTILUS_TYPE_INFO_PROVIDER&type=Code

Especially this one:
https://github.com/GNOME/gnome-system-tools/blob/50f92695648a1d6340416c8db6eff7c38a7b3bbd/src/shares/nautilus/nautilus-shares.c#L349-L352


- --
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

iQEcBAEBCAAGBQJZgejjAAoJENuP0xzK19cslRgH/32Iv0SNvw6BNI+K3/IvEcgT
4kLuNRAJeE9lB6eDSH9SFE1fvkyXW9/5eh71sqRK4gpOU2GUiTAbnakGQFQGNvB/
X8MlBpYVE0cTPx2Pz5jSJlzTEcIsnHzhn309cqmWbnk+6AmnQ1C/wGB66EI257mt
P2KSL5ZpVPEhHXA6CjmG4gxgJ0MVL95Xdq4GddbQX2ktG+j/VrLdD9LZhzB2nNAi
v6IC0qhbPan62Lt0MeHjGiWHAdyunGvgMd3rnmm8B2aNQs80uPb1j9iLxmbEW81g
G4KSPFCdnoPfd9nZRLsQNE9HkBailw3hptNSjKs1I1vrN3KXaM/f7gPCXyfU3aI=
=+nK2
-----END PGP SIGNATURE-----

Andrew Morgan

unread,
Aug 4, 2017, 6:51:48 AM8/4/17
to qubes...@googlegroups.com
Alright well I've been at this for a bit again with varying success.

The issue is that this if statement here fails:
https://github.com/anoadragon453/nautilus/blob/master/src/nautilus-module.c#L290

This is due to none of the modules in module_objects being of type
NAUTILUS_TYPE_INFO_PROVIDER. I tried the method suggested
(g_type_module_add_interface) but am unsure of how to get access to the
correct module to add our NAUTILUS_TYPE_INFO_PROVIDER type to.

Looking at nautilus-sendto-module.c (part of the included sendto
extension) it gets a module from Nautilus, then calls a method that
registers the NAUTILUS_TYPE_MENU_PROVIDER with that module:

https://github.com/anoadragon453/nautilus/blob/master/nautilus-sendto-extension/nautilus-sendto-module.c#L33

https://github.com/anoadragon453/nautilus/blob/master/nautilus-sendto-extension/nautilus-nste.c#L190

So, nautilus-python is flexible and will do this for you given that your
extensions asks for one of the variable provider types:

https://github.com/anoadragon453/nautilus-python/blob/master/src/nautilus-python-object.c#L651

So while writing this it seems that unless the new method (or any
extension) is integrated into nautilus-python, it won't work to call it
from nautilus. That wouldn't be such a big deal... if nautilus-python
would work when I build and installed it. For that I'm having the
following issue:

[user@dev-fedora nautilus-python]$ nautilus
/usr/lib64/python2.7/site-packages/gtk-2.0/gtk/__init__.py:40: Warning:
specified class size for type 'PyGtkGenericCellRenderer' is smaller than
the parent type's 'GtkCellRenderer' class size
from gtk import _gtk
/usr/lib64/python2.7/site-packages/gtk-2.0/gtk/__init__.py:40: Warning:
g_type_get_qdata: assertion 'node != NULL' failed
from gtk import _gtk
^CSegmentation fault (core dumped)
[user@dev-fedora nautilus-python]$

This happens with both my patched nautilus-python and the version
directly from source. Some research online says that it has to do with
importing both PyGObject and PyGTK libraries at the same time[1], which
is interesting as both libraries are a requirement to build
NautilusPython. This crash occurs with patched nautilus and nautilus
from the repos, so it's definitely an issue with building NautilusPython
in some form or another, even though the build completes successfully.

The process of building it is as follows, simply:

./autogen
make

Then one copies the produced src/.libs/libnautilus-python.so to
/usr/lib64/nautilus/extensions-3.0/ and nautilus will load it on startup.

You can grab the source code from here: git clone
git://git.gnome.org/nautilus-python

And all the dependencies on Fedora: sudo dnf install gnome-common
gtk-doc python-devel gnome-python2-devel

And getting an error related to get_toolbar_items is normal, I just
comment out that line. I don't believe it to be related to the segfault.

So! Apologies for the wall of text. I assume just building
nautilus-python correctly will at least solve some of my issues. Not
getting too much help on IRC at this point so pretty much left to dance
in circles.

Thanks
Andrew Morgan

[1]: https://askubuntu.com/questions/215068/gtk-problem-in-ubuntu-12-04

signature.asc

Marek Marczykowski-Górecki

unread,
Aug 4, 2017, 8:17:31 AM8/4/17
to Andrew Morgan, qubes...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

I get identical behavior.
Then switched to nautilus-3.0 branch and this one do not crash.

I get this at startup:

Traceback (most recent call last):
File "/usr/lib64/python2.7/site-packages/gi/__init__.py", line 39, in <module>
raise ImportError(_static_binding_error)
ImportError: When using gi.repository you must not import static modules like "gobject". Please change all occurrences of "import gobject" to "from gi.repository import GObject". See: https://bugzilla.gnome.org/show_bug.cgi?id=709183

(nautilus:1168): Nautilus-Python-WARNING **: nautilus_python_init_python failed

Not sure if failing nautilus_python_init_python prevent the SEGV, or
previously it didn't got that far.

BTW that SEGV was infinite recursion like this:

#39684 0x00007fffcb7d42d2 in pyg_type_get_bases () at /usr/lib64/python2.7/site-packages/gobject/_gobject.so
#39685 0x00007fffcb7d4672 in pygobject_new_with_interfaces () at /usr/lib64/python2.7/site-packages/gobject/_gobject.so
#39686 0x00007fffcb7d4285 in pygobject_lookup_class () at /usr/lib64/python2.7/site-packages/gobject/_gobject.so
#39687 0x00007fffcb7d42d2 in pyg_type_get_bases () at /usr/lib64/python2.7/site-packages/gobject/_gobject.so
#39688 0x00007fffcb7d4672 in pygobject_new_with_interfaces () at /usr/lib64/python2.7/site-packages/gobject/_gobject.so


- --
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

iQEcBAEBCAAGBQJZhGXVAAoJENuP0xzK19csKCYH/0mpm/6X2IuS4dmD5A7fxrjs
jYQ35ud3cO7bD6fErPUDO27+xs22knvdFwNGDGyvbZsDpLIvAnQoPotrrpvuXNXr
vqeh/HJBhIKMi9h+6ZgAshTWyv03hzGo0S3FH7mvnmQhE5DF75di71ZXg/cVhw3X
ksDSWAy//lAKNd790jAQfEILcT5snCg5EKUNMCMif1sgSrls+lCRNJ0ZQ3mfa4UC
nIP+1L3x7h3wZRn/8DZnE4pwINdttezK7RFh3EQ9moUCttayaV0sJrUax/hEk558
sMTyZepwF39RJ1nKLTf6WhZzzPkkoCooV2c6nO0fZPSp2S/B7dlSDjq2MQAHqrM=
=wrDY
-----END PGP SIGNATURE-----

Andrew Morgan

unread,
Aug 4, 2017, 8:36:25 PM8/4/17
to qubes...@googlegroups.com
Wow, did not notice that branch. Yes that seems to be compatible with
the latest Nautilus code.

I can't explain it, but for some reason I do not get that error on my
fedora-25-minimal VM (where I'm doing my testing), however I do get it
on my fedora-25 VM. Instead, I get the following:

[user@fedora-25-minimal np3]$ nautilus
sys:1: PyGIWarning: Nautilus was imported without specifying a version
first. Use gi.require_version('Nautilus', '3.0') before import to ensure
that the right version gets loaded.

** (nautilus:11881): WARNING **: Unable to get contents of the bookmarks
file: Error opening file /home/user/.gtk-bookmarks: No such file or
directory
update_file_info_full
Traceback (most recent call last):
File
"/usr/share/nautilus-python/extensions/update-file-info-async.py", line
9, in update_file_info_full
gobject.timeout_add_seconds(3, self.update_cb, provider, handle,
closure)
NameError: global name 'gobject' is not defined
update_file_info_full

However python extensions still seem to work fine, so I'll just continue
on with this VM for now.

Andrew Morgan

signature.asc

Andrew Morgan

unread,
Aug 4, 2017, 8:40:15 PM8/4/17
to qubes...@googlegroups.com
Yeah that error is for an extension that came from the old branch, so no
need to worry about it. Still confused why it works on this branch
though, I'm running Nautilus 3.22.3 on it...

Andrew Morgan

signature.asc

Andrew Morgan

unread,
Aug 4, 2017, 10:40:35 PM8/4/17
to qubes...@googlegroups.com
On 08/04/2017 05:36 PM, Andrew Morgan wrote:
Alright, I've managed to narrow down the issue to a single line which is
baffling me and probably has something to do with 32-bit vs. 64-bit
system (I'm on 64-bit of course).

https://github.com/anoadragon453/nautilus/blob/master/src/nautilus-mime-actions.c#L2489

So providers here (a GList *) is ending up as a different pointer than
what is being returned (another GList *), but instead of something
completely different, it's the same pointer but truncated 4 hex values
at the front.

Here we can see that without the truncation, we get a valid pointer
destination.

(gdb) print providers
$7 = 0x55f65ac0 = {Cannot access memory at address 0x55f65ac0
(gdb) print 0x555555f65ac0
$8 = 93825002789568
(gdb) Quit
(gdb)

So we're getting a 32-bit pointer instead of a 64-bit pointer, but I
can't see why as they're both GList *'s. As far as I know getting data
from this method works fine in other parts of the program, i.e. here:

https://github.com/anoadragon453/nautilus/blob/master/src/nautilus-files-view.c#L4577

Andrew Morgan

signature.asc

Andrew Morgan

unread,
Aug 4, 2017, 10:46:43 PM8/4/17
to qubes...@googlegroups.com
On 08/04/2017 05:36 PM, Andrew Morgan wrote:
(gdb) print providers
$2 = 0x55aaeb20 = {Cannot access memory at address 0x55aaeb20
(gdb) print 0x55aaeb20
$3 = 1437264672
(gdb)

Ok now I'm very confused.

Andrew Morgan

signature.asc

Marek Marczykowski-Górecki

unread,
Aug 5, 2017, 3:59:16 AM8/5/17
to Andrew Morgan, qubes...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Try:

print (GList*)0x555555f65ac0

Have you tried make clean after switching branch? I've got some problems
without that (like still old version reporting).

- --
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

iQEcBAEBCAAGBQJZhXrOAAoJENuP0xzK19csGh8H/RJ1qY8ILecqBcjDZtY7WVcC
sDJi0Eh3flWNAu3rPtIyZKYTNoYeP2pqLLLtmwOpbTNvAEfgY/kuKHVWblyHhqRo
n+Vvc5BlZSC92AbFUMXwce8/6cYn1CwNmKq5s3pUisFZlTAL5DIat8dfbQHTlgRn
cMJYxlJ61z1zJ/qF7ZWsPInbATsvx9ivfib7FkPILf71enNTDGfrY4MzOA+ta/v7
jBAO6BCQxYTKrCbsu2U+DQ4NsOGaU/VbAbXJszEv51ldciT43WyDHbtYRPOVwPA6
7wwbMAzRpRx3vRKYQeTXPRGG8No3hwzdY1VFznA3oPdYgA6xQ6OjsLzHfDwkUrs=
=weJ0
-----END PGP SIGNATURE-----

Andrew Morgan

unread,
Aug 6, 2017, 5:25:17 AM8/6/17
to qubes...@googlegroups.com
NautilusPython (which switching branches on fixed) is working swimmingly
now, though I did try to do a make clean and make to see if that had any
effect on this pointer nonsense but it didn't seem to. It's definitely a
problem contained within nautilus itself.

Doing a sizeof on both the returning GList* and the GList* we're storing
the data in both report 8 bytes, which is the correct size for a 64bit
pointer, so I have no idea why it's being truncated somewhere.

Doing the print statement you mentioned above does confirm that using
the correct address results in the correct data, while doing it on the
truncated address results in garbage data:

ret is 0x555555ab3d00, size: 8
providers is 0x55ab3d00, size: 8

Thread 1 "nautilus" received signal SIGSEGV, Segmentation fault.
0x00005555555fa960 in nautilus_mime_activate_files (parent_window=
2505 provider = NAUTILUS_INFO_PROVIDER (p->data);
(gdb) print (GList*) 0x555555ab3d00
$1 = 0x555555ab3d00 = {0x555555908e40}
(gdb) print ((GList*) 0x555555ab3d00)[0]
$2 = {data=0x555555908e40, next=0x0, prev=0x0}
(gdb) print (GList*) 0x55ab3d00
$3 = 0x55ab3d00 = {Cannot access memory at address 0x55ab3d00
(gdb)

As a workaround I've managed to get the correct address back again by
adding the truncated amount to the address, as well as setting the GList
to a static variable. Nautilus no longer crashes.

I'll leave a big TODO in there for now, but at least I'll be able to get
on with other things.

Andrew Morgan

signature.asc
Reply all
Reply to author
Forward
0 new messages