dom0/qrexec: Add always allow option in qrexec confirmation dialog (#278)
This commit is contained in:
parent
810a59b6ce
commit
ede96353af
55
dom0/qvm-core/guihelpers.py
Normal file
55
dom0/qvm-core/guihelpers.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/python2
|
||||||
|
#
|
||||||
|
# The Qubes OS Project, http://www.qubes-os.org
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 Marek Marczykowski <marmarek@invisiblethingslab.com>
|
||||||
|
#
|
||||||
|
# This program 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 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from optparse import OptionParser
|
||||||
|
from PyQt4.QtCore import *
|
||||||
|
from PyQt4.QtGui import *
|
||||||
|
|
||||||
|
app = None
|
||||||
|
|
||||||
|
def prepare_app():
|
||||||
|
global app
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
app.setOrganizationName("The Qubes Project")
|
||||||
|
app.setOrganizationDomain("http://qubes-os.org")
|
||||||
|
app.setApplicationName("Qubes")
|
||||||
|
|
||||||
|
def ask(text, title="Question", yestoall=False):
|
||||||
|
global app
|
||||||
|
if app is None:
|
||||||
|
prepare_app()
|
||||||
|
|
||||||
|
buttons = QMessageBox.Yes | QMessageBox.No
|
||||||
|
if yestoall:
|
||||||
|
buttons |= QMessageBox.YesToAll
|
||||||
|
|
||||||
|
reply = QMessageBox.question(None, title, text, buttons)
|
||||||
|
if reply == QMessageBox.Yes:
|
||||||
|
return 0
|
||||||
|
elif reply == QMessageBox.No:
|
||||||
|
return 1
|
||||||
|
elif reply == QMessageBox.YesToAll:
|
||||||
|
return 2
|
||||||
|
else:
|
||||||
|
#?!
|
||||||
|
return 127
|
@ -4,10 +4,17 @@ import os
|
|||||||
import os.path
|
import os.path
|
||||||
import subprocess
|
import subprocess
|
||||||
import xen.lowlevel.xl
|
import xen.lowlevel.xl
|
||||||
|
import qubes.guihelpers
|
||||||
|
import fcntl
|
||||||
|
|
||||||
POLICY_FILE_DIR="/etc/qubes_rpc/policy"
|
POLICY_FILE_DIR="/etc/qubes_rpc/policy"
|
||||||
QREXEC_CLIENT="/usr/lib/qubes/qrexec_client"
|
QREXEC_CLIENT="/usr/lib/qubes/qrexec_client"
|
||||||
|
|
||||||
|
class UserChoice:
|
||||||
|
ALLOW=0
|
||||||
|
DENY=1
|
||||||
|
ALWAYS_ALLOW=2
|
||||||
|
|
||||||
def line_to_dict(line):
|
def line_to_dict(line):
|
||||||
tokens=line.split()
|
tokens=line.split()
|
||||||
if len(tokens) < 3:
|
if len(tokens) < 3:
|
||||||
@ -20,6 +27,7 @@ def line_to_dict(line):
|
|||||||
dict['source']=tokens[0]
|
dict['source']=tokens[0]
|
||||||
dict['dest']=tokens[1]
|
dict['dest']=tokens[1]
|
||||||
|
|
||||||
|
dict['full-action']=tokens[2]
|
||||||
action_list=tokens[2].split(',')
|
action_list=tokens[2].split(',')
|
||||||
dict['action']=action_list.pop(0)
|
dict['action']=action_list.pop(0)
|
||||||
|
|
||||||
@ -36,6 +44,7 @@ def read_policy_file(exec_index):
|
|||||||
return None
|
return None
|
||||||
policy_list=list()
|
policy_list=list()
|
||||||
f = open(policy_file)
|
f = open(policy_file)
|
||||||
|
fcntl.flock(f, fcntl.LOCK_SH)
|
||||||
for iter in f.readlines():
|
for iter in f.readlines():
|
||||||
dict = line_to_dict(iter)
|
dict = line_to_dict(iter)
|
||||||
if dict is not None:
|
if dict is not None:
|
||||||
@ -92,9 +101,23 @@ def do_execute(domain, target, user, exec_index, process_ident):
|
|||||||
|
|
||||||
def confirm_execution(domain, target, exec_index):
|
def confirm_execution(domain, target, exec_index):
|
||||||
text = "Do you allow domain \"" +domain + "\" to execute " + exec_index
|
text = "Do you allow domain \"" +domain + "\" to execute " + exec_index
|
||||||
text+= " operation on the domain \"" + target +"\"?"
|
text+= " operation on the domain \"" + target +"\"?<br>"
|
||||||
retcode = subprocess.call(["/usr/bin/zenity", "--question", "--text", text])
|
text+= " \"Yes to All\" option will automatically allow this operation in the future."
|
||||||
return retcode==0
|
return qubes.guihelpers.ask(text, yestoall=True)
|
||||||
|
|
||||||
|
def add_always_allow(domain, target, exec_index, options):
|
||||||
|
policy_file=POLICY_FILE_DIR+"/"+exec_index
|
||||||
|
if not os.path.isfile(policy_file):
|
||||||
|
return None
|
||||||
|
f = open(policy_file, 'r+')
|
||||||
|
fcntl.flock(f, fcntl.LOCK_EX)
|
||||||
|
lines = []
|
||||||
|
for l in f.readlines():
|
||||||
|
lines.append(l)
|
||||||
|
lines.insert(0, "%s\t%s\tallow%s\n" % (domain, target, options))
|
||||||
|
f.seek(0)
|
||||||
|
f.write("".join(lines))
|
||||||
|
f.close()
|
||||||
|
|
||||||
def policy_editor(domain, target, exec_index):
|
def policy_editor(domain, target, exec_index):
|
||||||
text = "Policy editor not yet implemented. Please add a line in the form \""
|
text = "Policy editor not yet implemented. Please add a line in the form \""
|
||||||
@ -118,7 +141,11 @@ def main():
|
|||||||
policy_dict=find_policy(policy_list, domain, target)
|
policy_dict=find_policy(policy_list, domain, target)
|
||||||
|
|
||||||
if policy_dict["action"] == "ask":
|
if policy_dict["action"] == "ask":
|
||||||
if confirm_execution(domain, target, exec_index):
|
user_choice = confirm_execution(domain, target, exec_index)
|
||||||
|
if user_choice == UserChoice.ALWAYS_ALLOW:
|
||||||
|
add_always_allow(domain, target, exec_index, policy_dict["full-action"].lstrip('ask'))
|
||||||
|
policy_dict["action"] = "allow"
|
||||||
|
elif user_choice == UserChoice.ALLOW:
|
||||||
policy_dict["action"] = "allow"
|
policy_dict["action"] = "allow"
|
||||||
else:
|
else:
|
||||||
policy_dict["action"] = "deny"
|
policy_dict["action"] = "deny"
|
||||||
@ -136,4 +163,3 @@ def main():
|
|||||||
os.execl(QREXEC_CLIENT, "qrexec_client", "-d", domain, "-l", "/bin/false", "-c", process_ident)
|
os.execl(QREXEC_CLIENT, "qrexec_client", "-d", domain, "-l", "/bin/false", "-c", process_ident)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
@ -82,6 +82,8 @@ cp qvm-core/qubes.py $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
|||||||
cp qvm-core/qubes.py[co] $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
cp qvm-core/qubes.py[co] $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
||||||
cp qvm-core/qubesutils.py $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
cp qvm-core/qubesutils.py $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
||||||
cp qvm-core/qubesutils.py[co] $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
cp qvm-core/qubesutils.py[co] $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
||||||
|
cp qvm-core/guihelpers.py $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
||||||
|
cp qvm-core/guihelpers.py[co] $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
||||||
cp qvm-core/__init__.py $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
cp qvm-core/__init__.py $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
||||||
cp qvm-core/__init__.py[co] $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
cp qvm-core/__init__.py[co] $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
||||||
cp qmemman/qmemman*py $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
cp qmemman/qmemman*py $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
||||||
@ -303,6 +305,9 @@ fi
|
|||||||
%{python_sitearch}/qubes/qubesutils.py
|
%{python_sitearch}/qubes/qubesutils.py
|
||||||
%{python_sitearch}/qubes/qubesutils.pyc
|
%{python_sitearch}/qubes/qubesutils.pyc
|
||||||
%{python_sitearch}/qubes/qubesutils.pyo
|
%{python_sitearch}/qubes/qubesutils.pyo
|
||||||
|
%{python_sitearch}/qubes/guihelpers.py
|
||||||
|
%{python_sitearch}/qubes/guihelpers.pyc
|
||||||
|
%{python_sitearch}/qubes/guihelpers.pyo
|
||||||
%{python_sitearch}/qubes/__init__.py
|
%{python_sitearch}/qubes/__init__.py
|
||||||
%{python_sitearch}/qubes/__init__.pyc
|
%{python_sitearch}/qubes/__init__.pyc
|
||||||
%{python_sitearch}/qubes/__init__.pyo
|
%{python_sitearch}/qubes/__init__.pyo
|
||||||
@ -358,11 +363,11 @@ fi
|
|||||||
/usr/lib/qubes/qubes_rpc_multiplexer
|
/usr/lib/qubes/qubes_rpc_multiplexer
|
||||||
/usr/lib/qubes/qrexec_policy
|
/usr/lib/qubes/qrexec_policy
|
||||||
%dir /etc/qubes_rpc/policy
|
%dir /etc/qubes_rpc/policy
|
||||||
/etc/qubes_rpc/policy/qubes.Filecopy
|
%attr(0664,root,qubes) /etc/qubes_rpc/policy/qubes.Filecopy
|
||||||
/etc/qubes_rpc/policy/qubes.OpenInVM
|
%attr(0664,root,qubes) /etc/qubes_rpc/policy/qubes.OpenInVM
|
||||||
/etc/qubes_rpc/policy/qubes.SyncAppMenus
|
%attr(0664,root,qubes) /etc/qubes_rpc/policy/qubes.SyncAppMenus
|
||||||
/etc/qubes_rpc/policy//qubes.ReceiveUpdates
|
%attr(0664,root,qubes) /etc/qubes_rpc/policy/qubes.ReceiveUpdates
|
||||||
/etc/qubes_rpc/policy/qubes.VMShell
|
%attr(0664,root,qubes) /etc/qubes_rpc/policy/qubes.VMShell
|
||||||
/etc/qubes_rpc/qubes.SyncAppMenus
|
/etc/qubes_rpc/qubes.SyncAppMenus
|
||||||
/etc/qubes_rpc/qubes.ReceiveUpdates
|
/etc/qubes_rpc/qubes.ReceiveUpdates
|
||||||
%attr(4750,root,qubes) /usr/lib/qubes/qrexec_daemon
|
%attr(4750,root,qubes) /usr/lib/qubes/qrexec_daemon
|
||||||
|
Loading…
Reference in New Issue
Block a user