Commit 102bfe59 authored by Michael Terry's avatar Michael Terry

Handle running pkexec better -- more safely write environment variables to...

Handle running pkexec better -- more safely write environment variables to disk and use a nice message instead of asking to run /bin/sh
parent ddcec718
......@@ -65,5 +65,12 @@ deja_dup_appdata = custom_target('org.gnome.DejaDup.appdata.xml',
test('validate-appstream', appstream_util,
args: ['--nonet', 'validate-relax', deja_dup_appdata.full_path()])
conf_data = configuration_data()
conf_data.set('pkglibexecdir', pkglibexecdir)
vars = configure_file(input: 'org.gnome.DejaDup.policy.in',
output: 'org.gnome.DejaDup.policy',
configuration: conf_data,
install_dir: join_paths(datadir, 'polkit-1', 'actions'))
message('You may need to recompile your gsettings schemas or regenerate
your icon cache after installation.')
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD polkit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/software/polkit/policyconfig-1.dtd">
<policyconfig>
<icon_name>deja-dup</icon_name>
<action id="org.gnome.DejaDup.duplicity">
<description gettext-domain="deja-dup">Restore</description>
<message gettext-domain="deja-dup">Privileges are required to restore files to system locations</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">@pkglibexecdir@/duplicity</annotate>
</action>
</policyconfig>
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2017-08-09 15:43-0400\n"
"POT-Creation-Date: 2017-08-10 01:31-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......
......@@ -106,10 +106,7 @@ internal class DuplicityInstance : Object
// Add logging argument
if (as_root) {
// Make log file
int logfd = 0;
string logname;
logfd = FileUtils.open_tmp(Config.PACKAGE + "-XXXXXX", out logname);
logfile = File.new_for_path(logname);
logfile = File.new_tmp(Config.PACKAGE + "-XXXXXX", out logstream);
argv.append("--log-file=%s".printf(logfile.get_path()));
}
else {
......@@ -136,38 +133,19 @@ internal class DuplicityInstance : Object
// Run as root if needed
if (as_root &&
Environment.find_program_in_path("pkexec") != null &&
Environment.find_program_in_path("sh") != null) {
// pkexec does not preserve environment variables, so we need to stuff
// the ones we care about in a shell script.
string scriptname;
var scriptfd = FileUtils.open_tmp(Config.PACKAGE + "-XXXXXX", out scriptname);
scriptfile = File.new_for_path(scriptname);
Posix.close(scriptfd);
// We have to wrap all current args into one string.
StringBuilder args = new StringBuilder();
// Set environment variables for subprocess here because sudo reserves
Environment.find_program_in_path("pkexec") != null) {
// Set environment variables for subprocess here because pkexec reserves
// the right to strip them.
StringBuilder args = new StringBuilder();
foreach (string env in envp_in)
args.append("export '%s'\n".printf(env));
args.append("%s\n".printf(env));
foreach (string a in argv) {
if (a == null)
break;
if (args.len == 0)
args.append(Shell.quote(a));
else
args.append(" " + Shell.quote(a));
}
FileUtils.set_contents(scriptname, args.str);
argv = new List<string>(); // reset
argv.prepend(scriptname);
argv.prepend("sh");
IOStream iostream;
scriptfile = File.new_tmp(Config.PACKAGE + "-XXXXXX", out iostream);
yield iostream.get_output_stream().write_all_async(args.data, Priority.DEFAULT, null, null);
argv.prepend(scriptfile.get_path());
argv.prepend(Path.build_filename(Config.PKG_LIBEXEC_DIR, "duplicity"));
argv.prepend("pkexec");
}
......@@ -235,6 +213,7 @@ internal class DuplicityInstance : Object
int[] pipes;
DataInputStream reader;
File logfile;
IOStream logstream;
File scriptfile;
bool process_done;
int status;
......@@ -334,22 +313,15 @@ internal class DuplicityInstance : Object
*
* Stream initiated either from log file or pipe
*/
try {
InputStream stream;
if (logfile != null)
stream = yield logfile.read_async(Priority.DEFAULT, null);
else
stream = new UnixInputStream(pipes[0], true);
reader = new DataInputStream(stream);
}
catch (Error e) {
warning("%s\n", e.message);
done(false, false);
return;
}
InputStream stream;
if (logstream != null)
stream = logstream.get_input_stream();
else
stream = new UnixInputStream(pipes[0], true);
reader = new DataInputStream(stream);
// This loop goes on while rest of class is doing its work. We ref
// it to make sure that the rest of the class doesn't drop from under us.
ref();
......
#!/bin/sh
# -*- Mode: sh; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-
#
# This file is part of Déjà Dup.
# For copyright information, see AUTHORS.
#
# Déjà Dup is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Déjà Dup is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
# This script *could* just be a symlink to '/bin/sh' and do the same thing.
# But since this script is meant to be called by pkexec to operate as root,
# it didn't seem smart to install a polkit action that gave /bin/sh an
# innocent description that could be called by other programs.
#
# However, we should be mindful of attacks here and quote everything carefully.
set -e
# The first argument is going to be a file to read and export some variables
# from. We do this in a file to avoid any environment variables being listed
# on the command line (and visible from 'ps') and because pkexec will strip
# our environment before we see them normally.
# The second argument is "duplicity"
# All other arguments are for duplicity.
while read line; do
case "$line" in
PASSPHRASE=*|AWS_*=*|CLOUDFILES_*=*|GS_*=*|SWIFT_*=*)
export "$line"
;;
*)
# Do not echo it here, else someone could read any file via this
echo "Invalid environment variable passed"
exit 1
esac
done < "$1"
shift
[ "$1" = "duplicity" ] || exit 1
# PATH should be made safe by pkexec, so let's find duplicity on system
exec "$@"
......@@ -35,3 +35,9 @@ configure_file(
input: 'duplicity.plugin',
output: 'duplicity.plugin',
install_dir: toolsdir)
# This is used when running duplicity as root.
# See data/org.gnome.DejaDup.policy.in and DuplicityInstance.vala for more details.
install_data('duplicity',
install_dir: pkglibexecdir,
install_mode: 'rwxr-xr-x')
data/org.gnome.DejaDup.appdata.xml.in
data/org.gnome.DejaDup.desktop
data/org.gnome.DejaDup.gschema.xml
data/org.gnome.DejaDup.policy.in
deja-dup/monitor/deja-dup-monitor.desktop.in
deja-dup/ui/help-overlay.ui
deja-dup/ui/menus.ui
......
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: deja-dup\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-08-09 15:43-0400\n"
"POT-Creation-Date: 2017-08-10 01:31-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......@@ -23,7 +23,7 @@ msgstr ""
#. context is itself a reference to both the underlying command line tool
#. "duplicity" and the act of duplicating data for backup. As a whole, the
#. phrase "Déjà Dup" may not be very translatable.
#: data/org.gnome.DejaDup.appdata.xml.in:7 deja-dup/main.vala:295
#: data/org.gnome.DejaDup.appdata.xml.in:7 deja-dup/main.vala:304
#: libdeja/CommonUtils.vala:145
msgid "Déjà Dup Backup Tool"
msgstr ""
......@@ -62,7 +62,7 @@ msgid "Integrates well into your GNOME desktop"
msgstr ""
#. Translators: "Backups" is a noun
#: data/org.gnome.DejaDup.desktop:5 deja-dup/main.vala:159
#: data/org.gnome.DejaDup.desktop:5 deja-dup/main.vala:160
#: deja-dup/Prompt.vala:78
msgid "Backups"
msgstr ""
......@@ -432,6 +432,14 @@ msgid ""
"If the backup location is on an external volume, this is the volume’s icon."
msgstr ""
#: data/org.gnome.DejaDup.policy.in:10 deja-dup/AssistantRestore.vala:68
msgid "Restore"
msgstr ""
#: data/org.gnome.DejaDup.policy.in:11
msgid "Privileges are required to restore files to system locations"
msgstr ""
#. Translators: Monitor in this sense means something akin to 'watcher', not
#. a computer screen. This program acts like a daemon that kicks off
#. backups at scheduled times.
......@@ -633,10 +641,6 @@ msgstr ""
msgid "Backup encryption password"
msgstr ""
#: deja-dup/AssistantRestore.vala:68
msgid "Restore"
msgstr ""
#: deja-dup/AssistantRestore.vala:69
msgid "_Restore"
msgstr ""
......@@ -819,47 +823,47 @@ msgstr ""
msgid "_Resume Later"
msgstr ""
#: deja-dup/main.vala:30 deja-dup/monitor/monitor.vala:34
#: deja-dup/main.vala:31 deja-dup/monitor/monitor.vala:34
msgid "Show version"
msgstr ""
#: deja-dup/main.vala:31
#: deja-dup/main.vala:32
msgid "Restore given files"
msgstr ""
#: deja-dup/main.vala:32
#: deja-dup/main.vala:33
msgid "Immediately start a backup"
msgstr ""
#: deja-dup/main.vala:34
#: deja-dup/main.vala:35
msgid "Restore deleted files"
msgstr ""
#: deja-dup/main.vala:80 deja-dup/main.vala:95 deja-dup/main.vala:121
#: deja-dup/main.vala:81 deja-dup/main.vala:96 deja-dup/main.vala:122
msgid "An operation is already in progress"
msgstr ""
#: deja-dup/main.vala:100
#: deja-dup/main.vala:101
msgid "No directory provided"
msgstr ""
#: deja-dup/main.vala:104
#: deja-dup/main.vala:105
msgid "Only one directory can be shown at once"
msgstr ""
#: deja-dup/main.vala:110
#: deja-dup/main.vala:111
msgid "Directory does not exist"
msgstr ""
#: deja-dup/main.vala:114
#: deja-dup/main.vala:115
msgid "You must provide a directory, not a file"
msgstr ""
#: deja-dup/main.vala:128
#: deja-dup/main.vala:129
msgid "Scheduled backup delayed"
msgstr ""
#: deja-dup/main.vala:221
#: deja-dup/main.vala:230
msgid "translator-credits"
msgstr ""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment