From 3454abdc43a54af3b16617f9c4e21e6420cf498a Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Mon, 29 Aug 2016 21:52:45 +0530 Subject: [PATCH] monkeysphere: Allow non-root cancel of publishing Implement killing the publish process from within the action. Don't let the killing be too generic to avoid potential security issues. Kill process only if it appears as expected. --- actions/monkeysphere | 26 ++++++++++++++++++++++++++ plinth/modules/monkeysphere/views.py | 3 ++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/actions/monkeysphere b/actions/monkeysphere index c5e6a87bc..3090cdd6d 100755 --- a/actions/monkeysphere +++ b/actions/monkeysphere @@ -24,7 +24,9 @@ import argparse import augeas import json import os +import psutil import re +import signal import subprocess @@ -50,6 +52,10 @@ def parse_arguments(): host_publish_key.add_argument( 'key_ids', nargs='*', help='Optional list of KEYIDs') + host_cancel_publish = subparsers.add_parser( + 'host-cancel-publish', help='Cancel a running publish operation') + host_cancel_publish.add_argument('pid', help='PID of the publish process') + return parser.parse_args() @@ -237,6 +243,26 @@ def subcommand_host_publish_key(arguments): print(output) +def subcommand_host_cancel_publish(arguments): + """Kill a running publish process.""" + process = psutil.Process(int(arguments.pid)) + + # Perform tight checks on the process before killing for security. + arguments = process.cmdline() + if not arguments: + # Process already completed + return + + # Remove the sudo prefix if present + while arguments[0] == 'sudo' or arguments[0].startswith('-'): + arguments = arguments[1:] + + if len(arguments) >= 2 and \ + arguments[0].split('/')[-1] == 'monkeysphere' and \ + arguments[1] == 'host-publish-key': + process.send_signal(signal.SIGTERM) + + def main(): """Parse arguments and perform all duties.""" arguments = parse_arguments() diff --git a/plinth/modules/monkeysphere/views.py b/plinth/modules/monkeysphere/views.py index 434bd4607..673ab9dc2 100644 --- a/plinth/modules/monkeysphere/views.py +++ b/plinth/modules/monkeysphere/views.py @@ -86,7 +86,8 @@ def cancel(request): """Cancel ongoing process.""" global publish_process if publish_process: - publish_process.terminate() + actions.superuser_run( + 'monkeysphere', ['host-cancel-publish', str(publish_process.pid)]) publish_process = None messages.info(request, _('Cancelled key publishing.'))