Feature #15218

Iteration 1: Support unlocking VeraCrypt partitions in GVfs

Added by segfault 2018-01-22 17:53:18 . Updated 2018-06-11 13:23:04 .

Status:
Resolved
Priority:
Normal
Assignee:
Category:
Target version:
Start date:
2018-01-22
Due date:
% Done:

100%

Feature Branch:
Type of work:
Code
Blueprint:

Starter:
Affected tool:
Deliverable for:
299

Description

Development repository: https://github.com/segfault3/gvfs.git
Branch: support-tcrypt

The GVfs volume monitor is a daemon running in the background and monitoring volumes. It is responsible for the unlock dialog that opens once you plug in a storage device with a LUKS volume on it. We would like to have the same support for VeraCrypt volumes.


Files


Subtasks


Related issues

Blocked by Tails - Feature #15478: Revisit GVfs goals for iteration 1 Resolved 2018-03-30
Blocks Tails - Feature #15222: Iteration 1: Upstream unlocking VeraCrypt partitions in GVfs Resolved 2018-01-25 2018-07-30

History

#1 Updated by segfault 2018-01-23 01:32:39

  • Description updated
  • % Done changed from 0 to 10

The opening of the unlock dialog already works with a simple patch. The hard part will be to modify the unlock dialog to include the required options for VeraCrypt volumes (keyfiles, PIM, etc.).

This unlock dialog does not get created by GVfs directly, but by GtkMountOperation, which in turn calls org.gtk.MountOperationHandler.AskPassword, which is part of GNOME Shell. Then, finally, GNOME Shell creates the ShellMountPasswordDialog.

I will ask the GNOME developers how we should best proceed.

#2 Updated by segfault 2018-01-25 16:01:17

  • Subject changed from Support unlocking VeraCrypt partitions in GVfs to Iteration 1: Support unlocking VeraCrypt partitions in GVfs

#3 Updated by segfault 2018-02-26 15:23:52

segfault wrote:
> This unlock dialog does not get created by GVfs directly, but by GtkMountOperation, which in turn calls org.gtk.MountOperationHandler.AskPassword, which is part of GNOME Shell. Then, finally, GNOME Shell creates the ShellMountPasswordDialog.
>
> I will ask the GNOME developers how we should best proceed.

See the discussion on https://mail.gnome.org/archives/gtk-devel-list/2018-February/msg00003.html

#4 Updated by segfault 2018-03-30 10:27:08

I worked on this in the last weeks and made some progress. I successfully added an entry to the unlock dialog to enter a PIM (in addition to the password), which is then used to unlock the volume.

I had to patch glib, gvfs and gnome-shell for this. Additionally, gjs and gobject-introspection need to be rebuilt after installing the patched glib. And I assume that we also need to patch gtk in order to compile against the patched glib.

My work can be found here:
https://gitlab.com/segfault3/glib/commits/support-tcrypt
https://github.com/segfault3/gvfs/tree/support-tcrypt
https://gitlab.gnome.org/segfault3/gnome-shell/tree/gnome-3-26-support-tcrypt

Now, also adding the other properties to the dialog should not require a lot of additional work, because it should be basically the same as for the PIM (although I already spent hours unsuccessfully trying to make the “hidden volume” and “system volume” properties work). Except for the keyfiles, which will be more complicated, because we need to be able to add multiple keyfiles, and there is no FileChooserDialog available in javascript, so we need to call an external program (zenity might work).

Actually, at this point, I’m not sure if it makes sense to continue working on this. I would like to discuss this, and we should consider the following points:

  • A lot of projects need to be patched for this, which means a lot of upstream work, and a lot of patches we have to backport to Stretch (and maintain until Tails 4.0).
  • It’s a feature which will be annoying for users in case of false positives (volumes which are incorrectly detected as VeraCrypt volumes cause the unlock dialog to pop up).
  • It’s only a small part of the project, but requires an unproportional high amount of work.
  • I’m already way over what we budgeted for this.
  • The work is painful for me (it involves js and css, which I’m not used to; I have to rebuild 5 projects and restart gnome-shell everytime I want to test a change, …)

#5 Updated by intrigeri 2018-03-30 11:32:13

#6 Updated by intrigeri 2018-04-06 10:11:46

segfault wrote:
> * I’m already way over what we budgeted for this.

segfault checked and realized that’s incorrect: he has quite some time left on the VeraCrypt project; but of course lots of that time is needed for other parts of this project than this one.

#7 Updated by segfault 2018-04-06 10:23:40

intrigeri wrote:
> segfault wrote:
> > * I’m already way over what we budgeted for this.
>
> segfault checked and realized that’s incorrect: he has quite some time left on the VeraCrypt project; but of course lots of that time is needed for other parts of this project than this one.

What I meant is that I’m over what we budgeted for this part (i.e. what we called “integration into GNOME Files”).

#8 Updated by segfault 2018-04-26 17:04:42

  • Assignee changed from segfault to anonym
  • QA Check set to Ready for QA

I finally got everything to build reliably! This now allows to unlock VC/TC containers using hidden/system flag and PIM via the GNOME Shell unlock dialog. So the only thing that’s missing is the keyfiles property.

I find the keyfiles hard to implement - not only because we can’t open a GtkFileChooserDialog from GNOME Shell, but also because the properties are all added to a struct in gio/gmountoperation.c in glib, which is passed from gnome-shell to gvfs. The only way I see to support multiple keyfiles is to increase the size of this struct by MAX_PATH_LENGTH * MAX_NUM_KEYFILES. I’m not sure if that is the best solution, and whether upstream would happily merge this. Do you see a better way, anonym?

The code lives in the following repositories:
https://gitlab.com/segfault3/debian-glib
https://gitlab.com/segfault3/debian-gvfs
https://gitlab.com/segfault3/debian-gnome-shell

Additionally, gobject-introspection needs to be rebuilt in order for the code to work (to include the TCRYPT properties added to glib):
https://gitlab.com/segfault3/debian-gobject-introspection

Here are the steps to test it:

# libblockdev
sudo apt build-dep libblockdev
git clone https://gitlab.com/segfault3/debian-libblockdev
cd debian-libblockdev
gbp buildpackage --git-debian-branch=2.16-2-support-tcrypt
cd .. && sudo dpkg -i *.deb

# udisks2
sudo apt build-dep udisks2
git clone https://gitlab.com/segfault3/debian-udisks2
cd debian-udisks2
gbp buildpackage --git-debian-branch=2.7.6-2-support-tcrypt
cd .. && sudo dpkg -i *.deb

# glib
sudo apt build-dep libglib2.0-0
git clone https://gitlab.com/segfault3/debian-glib
cd debian-glib
gbp buildpackage --git-debian-branch=2.56.1-2-support-tcrypt
cd .. && sudo dpkg -i *.deb

# gvfs
sudo apt build-dep libglib2.0-0
git clone https://gitlab.com/segfault3/debian-gvfs
cd debian-gvfs
gbp buildpackage --git-debian-branch=1.36.1-1-support-tcrypt
cd .. && sudo dpkg -i *.deb
killall gvfs-udisks2-volume-monitor && /usr/lib/gvfs/gvfs-udisks2-volume-monitor

# gobject-introspection
sudo apt build-dep gobject-introspection
git clone https://gitlab.com/segfault3/debian-gobject-introspection
cd debian-gobject-introspection
gbp buildpackage --git-debian-branch=1.56.0-2.tcrypt
cd .. && sudo dpkg -i *.deb

# gnome-shell
sudo apt build-dep gnome-shell
git clone https://gitlab.com/segfault3/debian-gnome-shell
cd debian-gnome-shell
gbp buildpackage --git-debian-branch=3.28.0-1-support-tcrypt
cd .. && sudo dpkg -i *.deb

#9 Updated by anonym 2018-04-27 16:19:14

  • Status changed from Confirmed to In Progress
  • Assignee changed from anonym to segfault
  • QA Check changed from Ready for QA to Info Needed

segfault wrote:
> I finally got everything to build reliably! This now allows to unlock VC/TC containers using hidden/system flag and PIM via the GNOME Shell unlock dialog. So the only thing that’s missing is the keyfiles property.

Oh yeah, congrats!

> I find the keyfiles hard to implement - not only because we can’t open a GtkFileChooserDialog from GNOME Shell, but also because the properties are all added to a struct in gio/gmountoperation.c in glib, which is passed from gnome-shell to gvfs. The only way I see to support multiple keyfiles is to increase the size of this struct by MAX_PATH_LENGTH * MAX_NUM_KEYFILES. I’m not sure if that is the best solution, and whether upstream would happily merge this. Do you see a better way, anonym?

Perhaps I am missing something, but why is that (indeed, unacceptable) solution the only one? For instance, what makes the following approach impossible (interpret as unified diff):

 struct _GMountOperationPrivate {
   char *password;
   char *user;
   char *domain;
   gboolean anonymous;
   GPasswordSave password_save;
   int choice;
+  size_t num_keys;
+  char *keys[];
 };

> The code lives in the following repositories:
> https://gitlab.com/segfault3/debian-glib
> https://gitlab.com/segfault3/debian-gvfs
> https://gitlab.com/segfault3/debian-gnome-shell
>
> Additionally, gobject-introspection needs to be rebuilt in order for the code to work (to include the TCRYPT properties added to glib):
> https://gitlab.com/segfault3/debian-gobject-introspection
>
> Here are the steps to test it:
> […]

Cool! So, what am I actually supposed to review beside the packaging? I did verify that they build, at least. :)

So far I have these comments:

  • It seems you are not using dch to manipulate debian/changelog, cause one of your entries are wrong. I you insist on editing them manually (which is extremely error prone, just saying) please also manually verify that the entry you added is fine with dpkg-parsechangelog.
  • Regarding the version numbering, I suggest we just add +tcryptN, where N is an integer starting from 0 (why? it is more consistent with how we do it elsewhere, and having a number to increment is nice). Luckily .tcrypt < +tcrypt0 according to version sort, so next time I suggest just releasing as ${DEBIAN_VERSION}+tcrypt0.

BTW, I couldn’t really use your snippets since I don’t want to mess with my system, and your repos are not complete for usage with gbp (no pristine-tar branch). I had a similar “pipeline” for a series of other source packages, so I adjusted it as follows (and I added some annotations in case you want to understand what’s going on). I guess it could be useful for Feature #15524.

mkdir -p hooks
rm -fr hooks/*
# This hook will be run inside pbuilder's chroot just before the
# build; it upgrades any packages to the versions we built by sharing
# them over a bind-mount (see invocation of `gbp buildpackage` below).
cat > hooks/A00-upgrade-to-locally-built-debs.sh <<EOF
#!/bin/sh
echo "deb [ trusted=1 ] file:/deps ./" >> /etc/apt/sources.list
apt-get update
apt-get upgrade --yes
EOF
chmod a+x hooks/*

#   PACKAGE                BRANCH
echo "\
    libblockdev            2.16-2-support-tcrypt
    udisks2                2.7.6-2-support-tcrypt
    glib2.0                2.56.1-2-support-tcrypt
    gvfs                   1.36.1-1-support-tcrypt
    gobject-introspection  1.56.0-2.tcrypt
    gnome-shell            3.28.0-1-support-tcrypt
" | \
(
    summary=
    while read pkg branch; do
        [ -n "${pkg}" ] || continue
        # Update the Packages list of the .deb:s in this directory;
        # this way it can be used as a local APT repo. For details,
        # see the entry for "file" in the "URI SPECIFICATION" section
        # of sources.list(5).
        dpkg-scanpackages . > Packages
        # We need the pristine-tar branch for gbp to obtain the
        # upstream source code ("tar" refers to source TARballs).
        [ -d "${pkg}" ] || debcheckout --git-track=pristine-tar "${pkg}"
        cd "${pkg}"
        git fetch
        git checkout pristine-tar
        git reset --hard "origin/${branch}"
        # I have to workaround that you renamed 'glib2.0' to 'glib'
        [ "${pkg}" = glib2.0 ] && pkg=glib
        git remote add segfault "https://gitlab.com/segfault3/debian-${pkg}" || :
        git fetch segfault
        git checkout "${branch}"
        git reset --hard "segfault/${branch}"
        # Now all the magic comes together: the directory where
        # previous iterations' build results are stored is shared into
        # the chroot via a bind-mount, and a pre-build hook adds it as
        # a local APT repo and upgrades to those versions (provided
        # their version is higher than sid's version).
        gbp buildpackage --git-debian-branch="${branch}" --git-pbuilder --git-pbuilder-options="--bindmounts ..:/deps --hookdir ../hooks"
        status="$([ "${?}" = 0 ] && echo SUCCESS || echo FAILURE)"
        summary="${summary}${pkg} ${status}\n"
        cd ..
    done
    /bin/echo -en "\n\nSUMMARY\n=======\n${summary}"
)

To set pbuilder up, I think all you need is:

sudo apt-get install pbuilder
sudo pbuilder --create --architecture amd64 --distribution sid --basetgz /var/cache/pbuilder/base-sid-amd64.tgz
export BUILDER=pbuilder
export ARCH=amd64
export DIST=sid

#10 Updated by segfault 2018-04-27 17:42:56

anonym wrote:
> Perhaps I am missing something, but why is that (indeed, unacceptable) solution the only one? For instance, what makes the following approach impossible (interpret as unified diff):
> […]

I don’t think we can use pointers here, because the struct is passed from the gnome-shell process to the gvfs process via D-Bus.

> Cool! So, what am I actually supposed to review beside the packaging? I did verify that they build, at least. :)

I guess my patches in the default branches of these repositories should be reviewed (at least that is what I intend to upstream):

https://gitlab.com/segfault3/debian-glib
https://gitlab.com/segfault3/debian-gvfs
https://gitlab.com/segfault3/debian-gnome-shell

> So far I have these comments:
>
> * It seems you are not using dch to manipulate debian/changelog, cause one of your entries are wrong. I you insist on editing them manually (which is extremely error prone, just saying) please also manually verify that the entry you added is fine with dpkg-parsechangelog.

I did use debchange -i in (almost?) all cases to edit debian/changelog. But good to know about dpkg-parsechangelog.

> * Regarding the version numbering, I suggest we just add +tcryptN, where N is an integer starting from 0 (why? it is more consistent with how we do it elsewhere, and having a number to increment is nice). Luckily .tcrypt < +tcrypt0 according to version sort, so next time I suggest just releasing as ${DEBIAN_VERSION}+tcrypt0.

Ack.

> BTW, I couldn’t really use your snippets since I don’t want to mess with my system, and your repos are not complete for usage with gbp (no pristine-tar branch).

Right, I’m using the pristine-tar branches from the upstream repos, but didn’t push them to my repos. Should I do that?

> I had a similar “pipeline” for a series of other source packages, so I adjusted it as follows (and I added some annotations in case you want to understand what’s going on). I guess it could be useful for Feature #15524.

Ok, I will look at that later.

#11 Updated by segfault 2018-04-27 17:43:12

  • Assignee changed from segfault to anonym
  • QA Check changed from Info Needed to Ready for QA

#12 Updated by segfault 2018-05-04 18:45:40

  • % Done changed from 10 to 20

I cleaned up, rebased and squashed some commits. I think these branches are now ready to be upstreamed, which I would like to do ASAP:

https://gitlab.gnome.org/segfault3/gnome-shell/commits/support-tcrypt
https://github.com/segfault3/gvfs/commits/support-file-containers
https://gitlab.com/segfault3/glib/commits/support-tcrypt

This branch is not ready yet, because there are substantial merge conflicts with upstream/master which I still have to resolve:
https://github.com/segfault3/gvfs/commits/support-tcrypt

#13 Updated by intrigeri 2018-05-07 14:06:03

  • Target version changed from Tails_3.7 to Tails_3.8

#14 Updated by intrigeri 2018-05-21 14:06:25

  • Assignee changed from anonym to segfault
  • QA Check changed from Ready for QA to Dev Needed

I think you should go ahead and propose your work upstream.

#15 Updated by intrigeri 2018-06-03 12:46:04

  • blocks Feature #15222: Iteration 1: Upstream unlocking VeraCrypt partitions in GVfs added

#16 Updated by intrigeri 2018-06-03 12:47:47

segfault wrote:
> I cleaned up, rebased and squashed some commits. I think these branches are now ready to be upstreamed, which I would like to do ASAP:
>
> https://gitlab.gnome.org/segfault3/gnome-shell/commits/support-tcrypt
> https://github.com/segfault3/gvfs/commits/support-file-containers
> https://gitlab.com/segfault3/glib/commits/support-tcrypt

Great!

> This branch is not ready yet, because there are substantial merge conflicts with upstream/master which I still have to resolve:
> https://github.com/segfault3/gvfs/commits/support-tcrypt

Any status update here? I think that’s the only blocker left before we can close this ticket and switch to Feature #15222.

#17 Updated by segfault 2018-06-04 14:01:54

Currently the message of the dialog doesn’t make it clear that the volume might not be encrypted (see screenshot 1). I tried something to make it more similar to the message we display in Disks (see screenshot 2). sajolida, what do you think?

#18 Updated by sajolida 2018-06-04 16:19:41

  • Assignee changed from sajolida to segfault

Yes, “screenshot 2” is great. Good catch!

#19 Updated by intrigeri 2018-06-11 13:23:04

  • Status changed from In Progress to Resolved
  • Assignee deleted (segfault)
  • % Done changed from 20 to 100