Discussion:
Feature #5301 - Clone or Backup Persistent Volume
(too old to reply)
Andrew Gallagher
2015-12-03 12:51:54 UTC
Permalink
Raw Message
Hi, all.

I've written a tool to clone the contents of a mounted persistent volume
(or any other given directory tree) to a fresh or existing persistent
volume on another tails drive. It was done as part of a pet project, but
this functionality really belongs in tails itself.

It consists of two parts: a perl wrapper that handles user prompts for
passphrases etc. and a small setuid helper that performs the actual
work. The setuid helper will create a partition/filesystem if necessary
and then mounts, rsyncs and unmounts - this requires the passphrase to
be entered multiple times, so the perl wrapper prompts for one itself
and uses expect to supply it to the helper.

There are currently two main caveats. Firstly, the size of the tails
primary partition is hardcoded in the helper. It should be possible to
extract this instead from the output of parted, and is probably just a
matter of spending an hour or two on it. The other one is that the
wrapper depends on Term::Choose, which isn't packaged in either tails or
debian. I solved this by aliening a perl-term-choose deb but don't want
to be responsible for it, so the user interface really should be rebuilt
(suggestions welcome!). Of course it would probably be best if it could
be integrated into the tails installer instead... ;-)

You can find the code here:

https://github.com/andrewgdotcom/frith/tree/master/src/tcp-helper.c
https://github.com/andrewgdotcom/frith/tree/master/bin/tails-clone-persistent

perl-term-choose can be found here:

https://andrewg.com/debian/pool/main/p/perl-term-choose/perl-term-choose_1.202.0-2-abg2_all.deb

Let me know if you think it is useful.

Andrew.
Andrew Gallagher
2015-12-10 15:58:21 UTC
Permalink
Raw Message
Nobody interested?

To be clear, I'm willing to put in the work. I just don't want to spend
too much time on it if it isn't going to go anywhere.

Andrew.
Post by Andrew Gallagher
Hi, all.
I've written a tool to clone the contents of a mounted persistent volume
(or any other given directory tree) to a fresh or existing persistent
volume on another tails drive. It was done as part of a pet project, but
this functionality really belongs in tails itself.
It consists of two parts: a perl wrapper that handles user prompts for
passphrases etc. and a small setuid helper that performs the actual
work. The setuid helper will create a partition/filesystem if necessary
and then mounts, rsyncs and unmounts - this requires the passphrase to
be entered multiple times, so the perl wrapper prompts for one itself
and uses expect to supply it to the helper.
There are currently two main caveats. Firstly, the size of the tails
primary partition is hardcoded in the helper. It should be possible to
extract this instead from the output of parted, and is probably just a
matter of spending an hour or two on it. The other one is that the
wrapper depends on Term::Choose, which isn't packaged in either tails or
debian. I solved this by aliening a perl-term-choose deb but don't want
to be responsible for it, so the user interface really should be rebuilt
(suggestions welcome!). Of course it would probably be best if it could
be integrated into the tails installer instead... ;-)
https://github.com/andrewgdotcom/frith/tree/master/src/tcp-helper.c
https://github.com/andrewgdotcom/frith/tree/master/bin/tails-clone-persistent
https://andrewg.com/debian/pool/main/p/perl-term-choose/perl-term-choose_1.202.0-2-abg2_all.deb
Let me know if you think it is useful.
Andrew.
u
2015-12-10 19:16:32 UTC
Permalink
Raw Message
Hi Andrew,
Post by Andrew Gallagher
Nobody interested?
I guess most of us are simply quite busy atm - but yes, as we created
this ticket initially, we are interested in such a solution. Thank you
for working on this.

I had a quick view, but I am not knowledgeable in Perl and just saw that
you use rsync, as suggested also in our blueprint on the matter:
https://tails.boum.org/blueprint/backups/
Did you read it?

The Installer is written in Python and uses GTK so I suppose that a
backup that wants to get integrated into the installer should probably
use Python (correct me if that is totally wrong, please).

Cheers!
u.
sajolida
2015-12-11 10:57:36 UTC
Permalink
Raw Message
Post by u
Post by Andrew Gallagher
Nobody interested?
I guess most of us are simply quite busy atm - but yes, as we created
this ticket initially, we are interested in such a solution. Thank you
for working on this.
Hi Andrew, sorry for not answering earlier but as u said we're all too
busy right now. It's the end of the year and we have to finish many
projects.

We have "backup system for persistence" on our roadmap for 2016 [1][2]
and I'll be the one to work on the broad picture, UX design, etc. So I'm
definitely interested in your work but I wanted to test it before
answering (but couldn't find the time to do so), tough I won't be able
review your Perl code.

[1]: https://tails.boum.org/blueprint/roadmap_2016-2017/
[2]: https://labs.riseup.net/code/issues/5301
Post by u
I had a quick view, but I am not knowledgeable in Perl and just saw that
https://tails.boum.org/blueprint/backups/
Did you read it?
The Installer is written in Python and uses GTK so I suppose that a
backup that wants to get integrated into the installer should probably
use Python (correct me if that is totally wrong, please).
Right. At the moment I'm playing with Deja-Dup [3] for the backups of my
Tails. I really like the integration in the desktop but, as it's running
as the amnesia user, it can't create a perfect clone of the persistent
volume. So your approach is also something we've considered, see #8812 [4].

[3]:
https://wiki.gnome.org/action/show/Apps/DejaDup?action=show&redirect=DejaDup
[4]: https://labs.riseup.net/code/issues/8812
Andrew Gallagher
2015-12-11 12:14:34 UTC
Permalink
Raw Message
Post by sajolida
Hi Andrew, sorry for not answering earlier but as u said we're all too
busy right now. It's the end of the year and we have to finish many
projects.
Completely understandable! Sorry for nagging.
Post by sajolida
We have "backup system for persistence" on our roadmap for 2016 [1][2]
and I'll be the one to work on the broad picture, UX design, etc. So I'm
definitely interested in your work but I wanted to test it before
answering (but couldn't find the time to do so), tough I won't be able
review your Perl code.
That's fine, I can refactor it in python - although I'm not a python dev
so the first attempt may be a little ropey.
Post by sajolida
Right. At the moment I'm playing with Deja-Dup [3] for the backups of my
Tails. I really like the integration in the desktop but, as it's running
as the amnesia user, it can't create a perfect clone of the persistent
volume. So your approach is also something we've considered, see #8812 [4].
I saw you had been working on it, hence why I wanted to check before
spending too much time on potentially duplicated effort. I think there's
value in both methods - the bootable clone is more useful for me and I'm
sure I can't be alone.

So I'll work on and get back to you when I have something worth testing?

Thanks,
Andrew
sajolida
2015-12-13 17:46:50 UTC
Permalink
Raw Message
Post by Andrew Gallagher
Post by sajolida
We have "backup system for persistence" on our roadmap for 2016 [1][2]
and I'll be the one to work on the broad picture, UX design, etc. So I'm
definitely interested in your work but I wanted to test it before
answering (but couldn't find the time to do so), tough I won't be able
review your Perl code.
That's fine, I can refactor it in python - although I'm not a python dev
so the first attempt may be a little ropey.
I don't code seriously myself so I won't be able to review your Python
code either :) But as u pointed out, Tails Installer is written in
Python and if we ever want to propose a "clone everything" feature, I
think it should be integrated in Tails Installer.

If you're interested in plugging this in the current code [1] that would
be awesome. But as we haven't really finished the design decision around
the backup scenarios, I can't promise anything regarding it's official
acceptance yet.

[1]: https://git-tails.immerda.ch/liveusb-creator/
Post by Andrew Gallagher
Post by sajolida
Right. At the moment I'm playing with Deja-Dup [3] for the backups of my
Tails. I really like the integration in the desktop but, as it's running
as the amnesia user, it can't create a perfect clone of the persistent
volume. So your approach is also something we've considered, see #8812 [4].
I saw you had been working on it, hence why I wanted to check before
spending too much time on potentially duplicated effort. I think there's
value in both methods - the bootable clone is more useful for me and I'm
sure I can't be alone.
I also think there's value in both methods. But we also prefer having
one tool for one thing and avoid overlapping features. That's for me one
of the main issue regarding the design of the backup tool:

- "Clone everything" allows for a bootable backup of literally
everything in persistence, including files owed by root.
- Deja-Dup allows incremental and distant backups with a very good
integration on the desktop but only for the files owned by `amnesia`.

I wonder whether we could have to best of both worlds in a single tool,
but I haven't taken the time to investigate this in depth really. If
it's impossible, then I might propose to have both options.
Post by Andrew Gallagher
So I'll work on and get back to you when I have something worth testing?
Sure :)
Andrew Gallagher
2016-01-06 19:50:09 UTC
Permalink
Raw Message
Post by sajolida
If you're interested in plugging this in the current code [1] that would
be awesome. But as we haven't really finished the design decision around
the backup scenarios, I can't promise anything regarding it's official
acceptance yet.
I have a reasonably stable version of the code available here:

https://github.com/andrewgdotcom/tails-clone-persistent/releases/tag/v0.1.1-beta1

The easiest way to install it is to download the .deb, but it should(?)
build cleanly from the source. There's nothing particularly fancy in it.

Some notes/caveats:

1. The GUI half of the code is still perl, sorry. So it's not directly
pluggable into tails-installer (yet!). It works fine as a standalone
GTK2 app and invokes tails-installer as required. Working code >> proper
standards and all that. ;-)

2. The GUI is not particularly pretty.

3. My C++ string handling sucks. Please don't look at it. I'll tidy it
up later.

4. If you type in the wrong password when updating an existing
persistent partition, it will fail hard rather than reprompt.

5. I've been testing it against Tails 2.0beta. It used to work against
1.x also, but I might have broken that when I migrated to udisks2.
Haven't got around to checking it since.

Andrew.
sajolida
2016-01-07 14:16:22 UTC
Permalink
Raw Message
Post by Andrew Gallagher
Post by sajolida
If you're interested in plugging this in the current code [1] that would
be awesome. But as we haven't really finished the design decision around
the backup scenarios, I can't promise anything regarding it's official
acceptance yet.
https://github.com/andrewgdotcom/tails-clone-persistent/releases/tag/v0.1.1-beta1
Amazing!
Post by Andrew Gallagher
The easiest way to install it is to download the .deb, but it should(?)
build cleanly from the source. There's nothing particularly fancy in it.
I want to first have a look at what would be the user scenario for this
from a broader perspective in our plans regarding backups in Tails,
before looking at the code.

But we're definitely lacking people writing code in Tails as well,
especially Perl, so it's a good news in and off itself that you can
write Perl and do Debian packages!

I'm still way too busy with finishing deliverables to look at your tool
this week again, but I though maybe Emma Peel (in copy) could be
interested as she's been giving a workshop on Tails backups last week
and 32C3.
Post by Andrew Gallagher
1. The GUI half of the code is still perl, sorry. So it's not directly
pluggable into tails-installer (yet!). It works fine as a standalone
GTK2 app and invokes tails-installer as required. Working code >> proper
standards and all that. ;-)
2. The GUI is not particularly pretty.
3. My C++ string handling sucks. Please don't look at it. I'll tidy it
up later.
4. If you type in the wrong password when updating an existing
persistent partition, it will fail hard rather than reprompt.
5. I've been testing it against Tails 2.0beta. It used to work against
1.x also, but I might have broken that when I migrated to udisks2.
Haven't got around to checking it since.
Andrew Gallagher
2016-01-07 15:54:51 UTC
Permalink
Raw Message
Post by sajolida
But we're definitely lacking people writing code in Tails as well,
especially Perl, so it's a good news in and off itself that you can
write Perl and do Debian packages!
You may have to retract that after you read the code. ;-) I'm a sysadmin
more than a developer. Let's just say this has been a greater learning
experience than I first anticipated...

A
Spencer
2016-01-07 22:38:16 UTC
Permalink
Raw Message
Hi,
Post by sajolida
Emma Peel (in copy) could be
interested as she's been giving a workshop on Tails backups last week
and 32C3.
I found this [0] but no record of anything here [1]. Are there any
recordings of this workshop, or workshops in general, from this event?

Wordlife,
Spencer

[0]: https://events.ccc.de/congress/2015/wiki/Session:Tails_backup
[1]: https://events.ccc.de/congress/2015/Fahrplan/schedule/0.html
sajolida
2016-01-08 13:19:01 UTC
Permalink
Raw Message
Post by Spencer
Post by sajolida
Emma Peel (in copy) could be
interested as she's been giving a workshop on Tails backups last week
and 32C3.
I found this [0] but no record of anything here [1]. Are there any
recordings of this workshop, or workshops in general, from this event?
It was an ad-hoc session with no recording.
emmapeel
2016-01-10 08:40:29 UTC
Permalink
Raw Message
Post by sajolida
Emma Peel (in copy) could be
interested as she's been giving a workshop on Tails backups last week
and 32C3.
Ok, I didn't tried Andrew's script, but I can say that the 'permissions
issue' was for the users that attended the most difficult part to follow.

As in after backing up they lose the configurations,
live-additional-software, etc.
Andrew Gallagher
2016-01-10 12:32:42 UTC
Permalink
Raw Message
Andrew Gallagher
Post by emmapeel
Ok, I didn't tried Andrew's script, but I can say that the 'permissions
issue' was for the users that attended the most difficult part to follow.
As in after backing up they lose the configurations,
live-additional-software, etc.
Yes, the tool performs the equivalent of tails-fix-persistent-volume-permissions on the target partition after rsyncing. I had to code it separately as t-f-p-v-p hardcodes the location of the source partition.

Solving that was particularly urgent, as I use apt persistence to pull my custom software onto the tails drive for testing, which is much easier than rebuilding images.

(The only wrinkle that still trips me up is that persisting single files is not supported, so I have to persist the entire /etc/apt/sources.list.d directory, thus tails upgrades require manual intervention - but that's a separate issue)

A
Andrew Gallagher
2018-03-06 17:32:18 UTC
Permalink
Raw Message
Hi, all.

Sorry it has been so long since I've written.

I have just uploaded v0.2.0 of tails-clone-persistent[1], which is
memory-safe and relies entirely on polkit and sudoers to manage
privilege escalation.

There are still a couple of minor niggles, but I'm hoping someone on the
list can help with them.

Firstly, I had some trouble finding the correct polkit action for
unlocking the target crypted drive. As far as I can tell from the docs,
this should be `org.freedesktop.udisks2.encrypted-unlock-system` - but
this is already in the tails polkit configuration and seems to have no
effect. I got it to work by enabling `org.freedesktop.udisks2.*`, but
this is excessive.

Secondly, I have a subroutine that duplicates the functionality of
`tails-persistence-setup --step bootstrap --override-boot-drive <x>`,
but clumsily and less safely. Ideally, I would replace this by a call to
tails-persistence-setup itself, but I can't get `--override-boot-drive`
to work.

Any ideas or support would be most welcome. ;-)

[1] https://github.com/andrewgdotcom/tails-clone-persistent

Andrew.

anonym
2016-01-07 19:41:25 UTC
Permalink
Raw Message
Post by Andrew Gallagher
Post by sajolida
If you're interested in plugging this in the current code [1] that would
be awesome. But as we haven't really finished the design decision around
the backup scenarios, I can't promise anything regarding it's official
acceptance yet.
https://github.com/andrewgdotcom/tails-clone-persistent/releases/tag/v0.1.1-beta1
Cool! Thanks for your contribution!

I haven't tested it, but I did have a look at src/tcp-helper.c since the
necessity of memory unsafe code surprised me:

* It has the ".c" extension, but really is C++, so by convention it
should be ".cpp", no?

* BTW, regarding the name: for many of us "tcp" has other associations.
It completely threw me off for a few seconds ("What?! Does this do
TCP/IP networking?"), so I'd rather see something else. I'm a proponent
for less surprises and a super boring experience when dealing with code. :)

* The usage of `fgets()` makes me worried. Of course you use the magical
constant 1000 consistently, so we're ok, but still, using a constant
(`#define LINE_READ_BUFFER_SIZE 1000` or something) is good practice and
ensures consistency if we change the buffer size later. I'd say the same
for other magic constants are bad used in more than once place (for
those used in one place only, an obligatory comment explaining it is ok).

* Manual memory management is hard:

- `tails_free_start()` has a memory leak since you do not `free()` the
`line` variable before returning. Since it's fixed length and not
required to live after this function returns you should put it on the
stack like you did in e.g. `mount_device()`.

- Each use of your string-returning functions introduces a memory leak
since the returned string is not `free()`:d in the calling functions.

- You take the following precaution to use the notoriously dangerous
`strncpy()` safely (well, to ensure that the resulting buffer is a
well-formed C string -- you do nothing to ensure that the last byte that
is overwritten isn't anything important, however):

strncpy(buffer, line+offset, len);
// make double sure it's properly null terminated
buffer[len]='\0';

However,

char ... buffer[100];
...
offset=temp.find("End ")
len=temp.find("Size ")-offset

and AFAICT nothing guarantees that `len` < 100 (= the size of
`buffer`) so you may write a null outside of the buffer, causing
undefined behaviour. In practice, perhaps this shouldn't happen because
of the format of what is being parsed (but what about corruption?), but
I do not feel convinced without a comment arguing for that, and note
safe without a conditional check or assertion.

* This conditional worries me a lot:

if((offset=temp.find("End ")) &&
(len=temp.find("Size ")-offset)) { ...

So in C/C++, everything non-zero is treated as "true", so if we fail
the first `find()` (=> return value std::string::npos = -1, but I guess
since it's a size_t and hence unsigned it will wrap around and become
MAX_INT_32 - 1) the first operand to `&&` is true, which cannot be what
you intend. Essentially, it means that we only treat the `find()` as
failing if we happened to find "End " at the exact beginning of the
buffer. Clearly this is not what you intent.

And now it gets really interesting. The second operand is false if we
manage to calculate the length 0, and given that we cannot find "End"
and "Size" at the same position, it can happens if and only if we find
neither "End" nor "Size", since -1 - -1 = 0. Incidentally, this is
actually what makes sense for this whole conditional, but we definitely
didn't reach there by intention or sound reasoning, right? :)

So this conditional is scaring me because it works by coincidence --
you actually want to explicitly make sure that both `find()`:s found
something, i.e. neither returned `std::string::npos`. In addition, you
also want to check that `len` makes sense by checking that the first
found position is smaller than the second. This is probably what you want:

size_t end_pos = temp.find("End ");
size_t size_pos = temp.find("Size ");
if(end_pos != std::string::npos &&
size_pos != std::string::npos &&
end_pos < size_pos) {
len = end_pos - size_pos;
offset = end_pos;
...

Regarding style, assignments in conditionals is often a good way to
ask for subtle bugs and annoy code reviewers, except for a few common,
well-understood patterns, imho.

* The usage of `system()` and `popen()` is dangerous since they invoke
the shell in all its command injection-prone glory. For instance, let's
look at this part of `do_copy()`:

system((_STR + "/usr/bin/rsync -a --delete
--exclude=gnupg/random_seed --exclude=lost+found " + source_location +
"/ " + mount_point).c_str());

Here `source_location` will be the first parameter sent to the
executable, so if I set it to "; rm -rf /;" the command `rm -rf /` will
be executed in the shell as root. Woo! Well, actually I see that you do
enough input sanitation to prevent shell exploitation but imho that is
the wrong approach. For instance, you disallow perfectly fine path
characters like, for example, ö (and everything else non-ascii), space,
asterisk and backspace (ok, I'm not _so_ sad about the last two). :)
Best practice is to drop the input sanitation and pick alternatives to
`system()`/`popen()` that avoids invoking the shell and calls `exec()`
or similar. I'm too ignorant of C/C++ to recommend you anything.


From what I gather your program is essentially a wrapper around a few
executables (e.g. cryptsetup, mount, rsync) except that it does some
minor file parsing (`tails_free_start()` reads the block device). While
using complex, memory unsafe languages like C/C++ sometimes is
warranted, I fail to see it in this instance. Above it may seem that I
am excessive in my criticism, but I really want to make it clear how
hard it is to write correct C/C++ code. I would never consider doing it
myself since I don't have 10+ years of day-to-day experience doing it
(wow, isn't that a catch-22! :)). I really do not want to introduce more
C/C++ code into production unless there are really good reasons.

So, I personally would not include this program. Hence I recommend you
to rewriting it in the same scripting language you end up using for the
GUI, so Python 3, it seems. This will ease the integration as well as be
safer (memory wise), a lot shorter and more readable, supporting unicode
path characters (FWIW), architecture independent (and no Makefile
complexity) and *much* easier for us to maintain. Also, you can find
libraries (udisks) for dealing with disk partitioning that can be of
better service to you than `parted`, so you do not need hacks like
`tails_free_start()`. Similarly, there are nice cryptsetup/rsync/fs
formatting/mount handling/etc interfaces through libraries, so you can
probably drop most of your ad-hoc command output parsing too.

Cheers!
Andrew Gallagher
2016-01-08 14:48:42 UTC
Permalink
Raw Message
Post by anonym
I haven't tested it, but I did have a look at src/tcp-helper.c since the
For the record, I never intended to use C. It was originally written in
perl (like the GUI wrapper), but setuidperl is no longer supported and I
needed to drop any requirement for sudo. The perl documentation suggests
writing a setuid C wrapper that does (more or less)
"setreuid(0,0); system(MY_PROGRAM);"
and then lists all the reasons why you shouldn't.

So I reluctantly rewrote the helper in C, and after getting angry with C
I gave in and #included <string> (forgetting to rename the source
accordingly). Much of my time since has been spent trying to extricate
myself from the inevitable foot-shooting. ;-)

Rest of your comments fully understood, hands in the air bang to rights guv.
Post by anonym
Best practice is to drop the input sanitation and pick alternatives to
`system()`/`popen()` that avoids invoking the shell and calls `exec()`
or similar. I'm too ignorant of C/C++ to recommend you anything.
Yes, these were originally perl system(,,,) and open(,,,) calls, which
are safe as they don't invoke a shell. C has no simple equivalent that I
am aware of, so I cheated by adding the overkill input sanitation
(bearing in mind that in normal use the input parameters will in 99.9%
of cases be "/live/persistence/TailsData_unlocked" and "/dev/sd[a-z]").
Post by anonym
So, I personally would not include this program. Hence I recommend you
to rewriting it in the same scripting language you end up using for the
GUI, so Python 3, it seems.
I'd pay good money to have setuidperl back, but upstream had their reasons.

Thanks for the thorough criticism, sincerely. So I have a few questions
for the list:

1. is it worth spending any more time fixing the dodgy C++, or is it
just throwing good effort after bad?

2. is the general structure of userspace GUI + setuid helper still the
way to go?

3. Since tails-installer-invoker and tails-installer remain distinct
programs (and tails-installer closely tracks liveusb-creator), is it
necessary/desirable to merge persistence cloning into either of them, or
should/could it remain a separate (linked) executable? In other words,
do I really need to learn Python? ;-)

A
anonym
2016-01-08 17:43:04 UTC
Permalink
Raw Message
Post by Andrew Gallagher
Post by anonym
I haven't tested it, but I did have a look at src/tcp-helper.c since the
For the record, I never intended to use C. It was originally written in
perl (like the GUI wrapper), but setuidperl is no longer supported and I
needed to drop any requirement for sudo. The perl documentation suggests
writing a setuid C wrapper that does (more or less)
"setreuid(0,0); system(MY_PROGRAM);"
and then lists all the reasons why you shouldn't.
Ok. I'm not entirely sure why you'd need setuid.
Post by Andrew Gallagher
So I reluctantly rewrote the helper in C, and after getting angry with C
I gave in and #included <string> (forgetting to rename the source
accordingly). Much of my time since has been spent trying to extricate
myself from the inevitable foot-shooting. ;-)
Ack!
Post by Andrew Gallagher
Rest of your comments fully understood,
:)
Post by Andrew Gallagher
hands in the air bang to rights guv.
What does this mean? I'm not a native English speaker, which possibly
explains it.
Post by Andrew Gallagher
Post by anonym
Best practice is to drop the input sanitation and pick alternatives to
`system()`/`popen()` that avoids invoking the shell and calls `exec()`
or similar. I'm too ignorant of C/C++ to recommend you anything.
Yes, these were originally perl system(,,,) and open(,,,) calls, which
are safe as they don't invoke a shell.
Ok. Still, I'm confused by the need for setuid and going C(++). For the
record, Python's subprocess module would do the same job:

https://docs.python.org/3/library/subprocess.html
Post by Andrew Gallagher
C has no simple equivalent that I
am aware of,
I guess that'd be a combo of fork() + exec() + IPC to get the results
(return code, stdout/err) back to the parent. :) Or, preferably, using
some existing library which makes this easier.
Post by Andrew Gallagher
so I cheated by adding the overkill input sanitation
(bearing in mind that in normal use the input parameters will in 99.9%
of cases be "/live/persistence/TailsData_unlocked" and "/dev/sd[a-z]").
Understood.
Post by Andrew Gallagher
1. is it worth spending any more time fixing the dodgy C++, or is it
just throwing good effort after bad?
It's not worth the effort. Sorry, but let's drop the C/C++.
Post by Andrew Gallagher
2. is the general structure of userspace GUI + setuid helper still the
way to go?
3. Since tails-installer-invoker and tails-installer remain distinct
programs (and tails-installer closely tracks liveusb-creator), is it
necessary/desirable to merge persistence cloning into either of them, or
should/could it remain a separate (linked) executable? In other words,
do I really need to learn Python? ;-)
I mainly threw myself in the discussion to avert us from adding any
C/C++ code. I leave it to sajolida and u to decide on how the backup
tool should integrate into the installer (or if it should be separate),
and for u and intrigeri to clarify the privileges separation situation
in the installer (I think it's run as a normal users, and udisks is used
to partition, format, luksOpen etc without any risky setuid business).
All this will influence the answers to these questions.

Cheers!
intrigeri
2016-01-10 00:01:17 UTC
Permalink
Raw Message
I leave it to sajolida and u to decide on how the backup tool should
integrate into the installer (or if it should be separate),
Same here.
and for u and intrigeri to clarify the privileges separation situation
in the installer (I think it's run as a normal users, and udisks is used
to partition, format, luksOpen etc without any risky setuid business).
This is correct. There's no luksOpen involved since Tails Installer
does not handle encrypted partitions, though.

In Tails, we also directly access the block device as the amnesia
user, since
/etc/udev/rules.d/99-make-removable-devices-user-writable.rules allows
us to do that.

On Debian/Ubuntu, we are more limited so we use some operations that
require administrator credentials:

* opening the block device with udisks2, to get a filehandle for
writing the MBR;
* running syslinux as root, using pkexec.

Cheers!
--
intrigeri
Andrew Gallagher
2016-01-10 01:38:20 UTC
Permalink
Raw Message
Post by intrigeri
In Tails, we also directly access the block device as the amnesia
user, since
/etc/udev/rules.d/99-make-removable-devices-user-writable.rules allows
us to do that.
Ah, this could be the game changer. I'll look into that and see if it gives me the powers I need to avoid setuid (which is the source of all the problems).
Post by intrigeri
On Debian/Ubuntu, we are more limited so we use some operations that
* opening the block device with udisks2, to get a filehandle for
writing the MBR;
* running syslinux as root, using pkexec.
From what little I know of policykit, the same security caveats as setuid would usually apply...?

Thanks!

A
intrigeri
2016-02-04 11:18:45 UTC
Permalink
Raw Message
Post by Andrew Gallagher
Post by intrigeri
In Tails, we also directly access the block device as the amnesia
user, since
/etc/udev/rules.d/99-make-removable-devices-user-writable.rules allows
us to do that.
Ah, this could be the game changer. I'll look into that and see if it gives me the
powers I need to avoid setuid (which is the source of all the problems).
Cool :)
Post by Andrew Gallagher
Post by intrigeri
On Debian/Ubuntu, we are more limited so we use some operations that
* opening the block device with udisks2, to get a filehandle for
writing the MBR;
* running syslinux as root, using pkexec.
From what little I know of policykit, the same security caveats as setuid would usually apply...?
polkit has some minor security advantages, such as allowing us to
grant the privileges we need to the active session user only, and
requiring user consent in a way that's integrated in the desktop.

Cheers,
--
intrigeri
Andrew Gallagher
2015-12-11 12:03:06 UTC
Permalink
Raw Message
Post by u
Hi Andrew,
Post by Andrew Gallagher
Nobody interested?
I guess most of us are simply quite busy atm - but yes, as we created
this ticket initially, we are interested in such a solution. Thank you
for working on this.
Sorry, that may have come out more sarcastic than I intended! I saw the
ticket had been around for a while and someone did appear to be working
on it so I wanted to check before duplicating effort.
Post by u
I had a quick view, but I am not knowledgeable in Perl and just saw that
https://tails.boum.org/blueprint/backups/
Did you read it?
Yes, the "Clone everything" option is sufficient for my needs, so I
coded only for it.
Post by u
The Installer is written in Python and uses GTK so I suppose that a
backup that wants to get integrated into the installer should probably
use Python (correct me if that is totally wrong, please).
I'm assuming that also. I wrote it in perl because that's what I'm most
comfortable with - and I initially discounted the likelihood of
integrating it into the official code.

Andrew.
Loading...