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', ...@@ -65,5 +65,12 @@ deja_dup_appdata = custom_target('org.gnome.DejaDup.appdata.xml',
test('validate-appstream', appstream_util, test('validate-appstream', appstream_util,
args: ['--nonet', 'validate-relax', deja_dup_appdata.full_path()]) 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 message('You may need to recompile your gsettings schemas or regenerate
your icon cache after installation.') 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 "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "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" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
......
...@@ -106,10 +106,7 @@ internal class DuplicityInstance : Object ...@@ -106,10 +106,7 @@ internal class DuplicityInstance : Object
// Add logging argument // Add logging argument
if (as_root) { if (as_root) {
// Make log file // Make log file
int logfd = 0; logfile = File.new_tmp(Config.PACKAGE + "-XXXXXX", out logstream);
string logname;
logfd = FileUtils.open_tmp(Config.PACKAGE + "-XXXXXX", out logname);
logfile = File.new_for_path(logname);
argv.append("--log-file=%s".printf(logfile.get_path())); argv.append("--log-file=%s".printf(logfile.get_path()));
} }
else { else {
...@@ -136,38 +133,19 @@ internal class DuplicityInstance : Object ...@@ -136,38 +133,19 @@ internal class DuplicityInstance : Object
// Run as root if needed // Run as root if needed
if (as_root && if (as_root &&
Environment.find_program_in_path("pkexec") != null && Environment.find_program_in_path("pkexec") != null) {
Environment.find_program_in_path("sh") != null) { // Set environment variables for subprocess here because pkexec reserves
// 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
// the right to strip them. // the right to strip them.
StringBuilder args = new StringBuilder();
foreach (string env in envp_in) foreach (string env in envp_in)
args.append("export '%s'\n".printf(env)); args.append("%s\n".printf(env));
foreach (string a in argv) { IOStream iostream;
if (a == null) scriptfile = File.new_tmp(Config.PACKAGE + "-XXXXXX", out iostream);
break; yield iostream.get_output_stream().write_all_async(args.data, Priority.DEFAULT, null, null);
if (args.len == 0)
args.append(Shell.quote(a)); argv.prepend(scriptfile.get_path());
else argv.prepend(Path.build_filename(Config.PKG_LIBEXEC_DIR, "duplicity"));
args.append(" " + Shell.quote(a));
}
FileUtils.set_contents(scriptname, args.str);
argv = new List<string>(); // reset
argv.prepend(scriptname);
argv.prepend("sh");
argv.prepend("pkexec"); argv.prepend("pkexec");
} }
...@@ -235,6 +213,7 @@ internal class DuplicityInstance : Object ...@@ -235,6 +213,7 @@ internal class DuplicityInstance : Object
int[] pipes; int[] pipes;
DataInputStream reader; DataInputStream reader;
File logfile; File logfile;
IOStream logstream;
File scriptfile; File scriptfile;
bool process_done; bool process_done;
int status; int status;
...@@ -334,22 +313,15 @@ internal class DuplicityInstance : Object ...@@ -334,22 +313,15 @@ internal class DuplicityInstance : Object
* *
* Stream initiated either from log file or pipe * Stream initiated either from log file or pipe
*/ */
try { InputStream stream;
InputStream stream;
if (logstream != null)
if (logfile != null) stream = logstream.get_input_stream();
stream = yield logfile.read_async(Priority.DEFAULT, null); else
else stream = new UnixInputStream(pipes[0], true);
stream = new UnixInputStream(pipes[0], true);
reader = new DataInputStream(stream);
reader = new DataInputStream(stream);
}
catch (Error e) {
warning("%s\n", e.message);
done(false, false);
return;
}
// This loop goes on while rest of class is doing its work. We ref // 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. // it to make sure that the rest of the class doesn't drop from under us.
ref(); 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( ...@@ -35,3 +35,9 @@ configure_file(
input: 'duplicity.plugin', input: 'duplicity.plugin',
output: 'duplicity.plugin', output: 'duplicity.plugin',
install_dir: toolsdir) 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.appdata.xml.in
data/org.gnome.DejaDup.desktop data/org.gnome.DejaDup.desktop
data/org.gnome.DejaDup.gschema.xml data/org.gnome.DejaDup.gschema.xml
data/org.gnome.DejaDup.policy.in
deja-dup/monitor/deja-dup-monitor.desktop.in deja-dup/monitor/deja-dup-monitor.desktop.in
deja-dup/ui/help-overlay.ui deja-dup/ui/help-overlay.ui
deja-dup/ui/menus.ui deja-dup/ui/menus.ui
......
...@@ -8,7 +8,7 @@ msgid "" ...@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: deja-dup\n" "Project-Id-Version: deja-dup\n"
"Report-Msgid-Bugs-To: \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" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
...@@ -23,7 +23,7 @@ msgstr "" ...@@ -23,7 +23,7 @@ msgstr ""
#. context is itself a reference to both the underlying command line tool #. 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 #. "duplicity" and the act of duplicating data for backup. As a whole, the
#. phrase "Déjà Dup" may not be very translatable. #. 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 #: libdeja/CommonUtils.vala:145
msgid "Déjà Dup Backup Tool" msgid "Déjà Dup Backup Tool"
msgstr "" msgstr ""
...@@ -62,7 +62,7 @@ msgid "Integrates well into your GNOME desktop" ...@@ -62,7 +62,7 @@ msgid "Integrates well into your GNOME desktop"
msgstr "" msgstr ""
#. Translators: "Backups" is a noun #. 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 #: deja-dup/Prompt.vala:78
msgid "Backups" msgid "Backups"
msgstr "" msgstr ""
...@@ -432,6 +432,14 @@ msgid "" ...@@ -432,6 +432,14 @@ msgid ""
"If the backup location is on an external volume, this is the volume’s icon." "If the backup location is on an external volume, this is the volume’s icon."
msgstr "" 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 #. Translators: Monitor in this sense means something akin to 'watcher', not
#. a computer screen. This program acts like a daemon that kicks off #. a computer screen. This program acts like a daemon that kicks off
#. backups at scheduled times. #. backups at scheduled times.
...@@ -633,10 +641,6 @@ msgstr "" ...@@ -633,10 +641,6 @@ msgstr ""
msgid "Backup encryption password" msgid "Backup encryption password"
msgstr "" msgstr ""
#: deja-dup/AssistantRestore.vala:68
msgid "Restore"
msgstr ""
#: deja-dup/AssistantRestore.vala:69 #: deja-dup/AssistantRestore.vala:69
msgid "_Restore" msgid "_Restore"
msgstr "" msgstr ""
...@@ -819,47 +823,47 @@ msgstr "" ...@@ -819,47 +823,47 @@ msgstr ""
msgid "_Resume Later" msgid "_Resume Later"
msgstr "" 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" msgid "Show version"
msgstr "" msgstr ""
#: deja-dup/main.vala:31 #: deja-dup/main.vala:32
msgid "Restore given files" msgid "Restore given files"
msgstr "" msgstr ""
#: deja-dup/main.vala:32 #: deja-dup/main.vala:33
msgid "Immediately start a backup" msgid "Immediately start a backup"
msgstr "" msgstr ""
#: deja-dup/main.vala:34 #: deja-dup/main.vala:35
msgid "Restore deleted files" msgid "Restore deleted files"
msgstr "" 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" msgid "An operation is already in progress"
msgstr "" msgstr ""
#: deja-dup/main.vala:100 #: deja-dup/main.vala:101
msgid "No directory provided" msgid "No directory provided"
msgstr "" msgstr ""
#: deja-dup/main.vala:104 #: deja-dup/main.vala:105
msgid "Only one directory can be shown at once" msgid "Only one directory can be shown at once"
msgstr "" msgstr ""
#: deja-dup/main.vala:110 #: deja-dup/main.vala:111
msgid "Directory does not exist" msgid "Directory does not exist"
msgstr "" msgstr ""
#: deja-dup/main.vala:114 #: deja-dup/main.vala:115
msgid "You must provide a directory, not a file" msgid "You must provide a directory, not a file"
msgstr "" msgstr ""
#: deja-dup/main.vala:128 #: deja-dup/main.vala:129
msgid "Scheduled backup delayed" msgid "Scheduled backup delayed"
msgstr "" msgstr ""
#: deja-dup/main.vala:221 #: deja-dup/main.vala:230
msgid "translator-credits" msgid "translator-credits"
msgstr "" 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