From 9cc6050e7caaab96079ec9e1fa3b78c2650f3a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Tue, 12 May 2020 05:01:36 +0200 Subject: [PATCH 1/2] Convert default qrexec policy to the new format QubesOS/qubes-issues#4370 --- Makefile | 39 ++---- .../90-admin-default.policy.header | 22 +++ qubes-rpc-policy/90-default.policy | 127 ++++++++++++++++++ qubes-rpc-policy/admin-global-ro | 6 +- qubes-rpc-policy/admin-global-rwx | 5 +- qubes-rpc-policy/admin-local-ro | 7 +- qubes-rpc-policy/admin-local-rwx | 5 +- qubes-rpc-policy/generate-admin-policy | 48 +++---- rpm_spec/core-dom0.spec.in | 29 +--- 9 files changed, 192 insertions(+), 96 deletions(-) create mode 100644 qubes-rpc-policy/90-admin-default.policy.header create mode 100644 qubes-rpc-policy/90-default.policy diff --git a/Makefile b/Makefile index 8816a45f..8c692f9f 100644 --- a/Makefile +++ b/Makefile @@ -170,31 +170,11 @@ ifeq ($(BACKEND_VMM),xen) # Currently supported only on xen cp etc/qmemman.conf $(DESTDIR)/etc/qubes/ endif - mkdir -p $(DESTDIR)/etc/qubes-rpc/policy + mkdir -p $(DESTDIR)/etc/qubes-rpc + mkdir -p $(DESTDIR)/etc/qubes/policy.d mkdir -p $(DESTDIR)/usr/libexec/qubes - cp qubes-rpc-policy/qubes.FeaturesRequest.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.FeaturesRequest - cp qubes-rpc-policy/qubes.Filecopy.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.Filecopy - cp qubes-rpc-policy/qubes.OpenInVM.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.OpenInVM - cp qubes-rpc-policy/qubes.OpenURL.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.OpenURL - cp qubes-rpc-policy/qubes.VMShell.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMShell - cp qubes-rpc-policy/qubes.VMRootShell.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMRootShell - cp qubes-rpc-policy/qubes.VMExec.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMExec - cp qubes-rpc-policy/qubes.VMExecGUI.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMExecGUI - cp qubes-rpc-policy/qubes.NotifyUpdates.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyUpdates - cp qubes-rpc-policy/qubes.NotifyTools.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyTools - cp qubes-rpc-policy/qubes.GetImageRGBA.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.GetImageRGBA - cp qubes-rpc-policy/qubes.GetRandomizedTime.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.GetRandomizedTime - cp qubes-rpc-policy/qubes.NotifyTools.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyTools - cp qubes-rpc-policy/qubes.NotifyUpdates.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyUpdates - cp qubes-rpc-policy/qubes.OpenInVM.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.OpenInVM - cp qubes-rpc-policy/qubes.StartApp.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.StartApp - cp qubes-rpc-policy/qubes.UpdatesProxy.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.UpdatesProxy - cp qubes-rpc-policy/qubes.GetDate.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.GetDate - cp qubes-rpc-policy/qubes.ConnectTCP.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.ConnectTCP - cp qubes-rpc-policy/admin.vm.Console.policy $(DESTDIR)/etc/qubes-rpc/policy/admin.vm.Console - cp qubes-rpc-policy/admin.vm.volume.Import.policy $(DESTDIR)/etc/qubes-rpc/policy/admin.vm.volume.Import - cp qubes-rpc-policy/admin.vm.volume.ImportWithSize.policy $(DESTDIR)/etc/qubes-rpc/policy/admin.vm.volume.ImportWithSize - cp qubes-rpc-policy/policy.RegisterArgument.policy $(DESTDIR)/etc/qubes-rpc/policy/policy.RegisterArgument + install -m 0644 qubes-rpc-policy/90-default.policy \ + $(DESTDIR)/etc/qubes/policy.d/90-default.policy cp qubes-rpc/qubes.FeaturesRequest $(DESTDIR)/etc/qubes-rpc/ cp qubes-rpc/qubes.GetDate $(DESTDIR)/etc/qubes-rpc/ cp qubes-rpc/qubes.GetRandomizedTime $(DESTDIR)/etc/qubes-rpc/ @@ -214,7 +194,8 @@ endif ln -s admin.vm.volume.Import $(DESTDIR)/etc/qubes-rpc/admin.vm.volume.ImportWithSize install qubes-rpc/admin.vm.Console $(DESTDIR)/etc/qubes-rpc/ PYTHONPATH=.:test-packages qubes-rpc-policy/generate-admin-policy \ - --destdir=$(DESTDIR)/etc/qubes-rpc/policy \ + --dest=$(DESTDIR)/etc/qubes/policy.d/90-admin-default.policy \ + --header=qubes-rpc-policy/90-admin-default.policy.header \ --exclude admin.vm.Create.AdminVM \ admin.vm.CreateInPool.AdminVM \ admin.vm.device.testclass.Attach \ @@ -222,16 +203,12 @@ endif admin.vm.device.testclass.List \ admin.vm.device.testclass.Set.persistent \ admin.vm.device.testclass.Available - # sanity check - for method in $(DESTDIR)/etc/qubes-rpc/policy/admin.*; do \ - ls $(DESTDIR)/etc/qubes-rpc/$$(basename $$method) >/dev/null || exit 1; \ - done - install -d $(DESTDIR)/etc/qubes-rpc/policy/include + install -d $(DESTDIR)/etc/qubes/policy.d/include install -m 0644 qubes-rpc-policy/admin-local-ro \ qubes-rpc-policy/admin-local-rwx \ qubes-rpc-policy/admin-global-ro \ qubes-rpc-policy/admin-global-rwx \ - $(DESTDIR)/etc/qubes-rpc/policy/include/ + $(DESTDIR)/etc/qubes/policy.d/include/ mkdir -p "$(DESTDIR)$(FILESDIR)" cp -r templates "$(DESTDIR)$(FILESDIR)/templates" diff --git a/qubes-rpc-policy/90-admin-default.policy.header b/qubes-rpc-policy/90-admin-default.policy.header new file mode 100644 index 00000000..bd08451e --- /dev/null +++ b/qubes-rpc-policy/90-admin-default.policy.header @@ -0,0 +1,22 @@ +## Do not modify this file, create a new policy file with a lower number in the +## filename instead. For example `30-admin-user.policy`. + +### +### Default Admin API qrexec policy +### + +## WARNING: most qrexec services here allows a qube to control system +## configuration. It should be allowed only to trusted qubes. + +## Remember to add "target=dom0" option to any (allow/ask) entry you create. + +## For convenience of maintaining this policy, all services include one of: +## - include/admin-local-rwx (services to modify a specific qube configuration) +## - include/admin-local-ro (services to read a specific qube configuration) +## - include/admin-global-rwx (services to modify global parameters) +## - include/admin-global-ro (services to read global parameters) + +!include-service admin.vm.Console * include/admin-local-rwx +!include-service admin.vm.volume.Import * include/admin-local-rwx +!include-service admin.vm.volume.ImportWithSize * include/admin-local-rwx + diff --git a/qubes-rpc-policy/90-default.policy b/qubes-rpc-policy/90-default.policy new file mode 100644 index 00000000..1bd30fd8 --- /dev/null +++ b/qubes-rpc-policy/90-default.policy @@ -0,0 +1,127 @@ +## Do not modify this file, create a new policy file with a lower number in the +## filename instead. For example `30-user.policy`. + +### +### Default qrexec policy +### + +## File format: +## service-name|* +argument|* source destination action [options] + +## Note that policy parsing stops at the first match. + +# policy.RegisterArgument should be allowed only for specific arguments. +policy.RegisterArgument * @anyvm dom0 deny + +# WARNING: The qubes.ConnectTCP service is dangerous and allows any +# qube to access any other qube TCP port. It should be restricted +# only to restricted qubes. This is why the default policy is 'deny' + +# Example of policy: qubes.ConnectTCP +22 mytcp-client @default allow,target=mytcp-server +qubes.ConnectTCP * @anyvm @anyvm deny + +# VM advertise its supported features +qubes.FeaturesRequest * @anyvm dom0 allow + +# Windows VM advertise installed Qubes Windows Tools +qubes.NotifyTools * @anyvm dom0 allow + +# File copy/move +qubes.Filecopy * @anyvm @anyvm ask + +# Get current date/time +qubes.GetDate * @tag:anon-vm @anyvm deny +qubes.GetDate * @anyvm @anyvm allow target=dom0 + +# Get slightly randomized date/time +qubes.GetRandomizedTime * @anyvm dom0 allow + +# Convert image to a safe format, also, allows to get an image (icon) file from a VM +qubes.GetImageRGBA * @anyvm @dispvm allow +qubes.GetImageRGBA * @anyvm @anyvm ask + +# Notify about available updates +qubes.NotifyUpdates * @anyvm dom0 allow + +# Open a file in a VM +qubes.OpenInVM * @anyvm @dispvm allow +qubes.OpenInVM * @anyvm @anyvm ask + +# Open URL in a VM +qubes.OpenURL * @anyvm @dispvm allow +qubes.OpenURL * @anyvm @anyvm ask + +# Start application using its menu entry (only applications with menu entries +# are allowed, no arbitrary command). Argument is an application name (in case +# of Linux, basename of .desktop file from /usr/share/applications or similar +# location). +qubes.StartApp * @anyvm @dispvm allow +qubes.StartApp * @anyvm @anyvm ask + +# HTTP proxy for downloading updates +# Upgrade all TemplateVMs through sys-whonix. +#qubes.UpdatesProxy * @type:TemplateVM @default allow,target=sys-whonix +# Upgrade Whonix TemplateVMs through sys-whonix. +qubes.UpdatesProxy * @tag:whonix-updatevm @default allow target=sys-whonix +# Deny Whonix TemplateVMs using UpdatesProxy of any other VM. +qubes.UpdatesProxy * @tag:whonix-updatevm @anyvm deny +# Default rule for all TemplateVMs - direct the connection to sys-net +qubes.UpdatesProxy * @type:TemplateVM @default allow target=sys-net +qubes.UpdatesProxy * @anyvm @anyvm deny + +# WARNING: The qubes.VMShell service is dangerous and there are really few +# cases when it could be safely used. Especially when policy set to "ask" you +# have no way to know for sure what command(s) will be called. Compromissed +# source VM can substitute the command. Allowing one VM to execute +# qubes.VMShell over the other VM allows the former to TAKE FULL CONTROL over +# the later. In most cases this is not what we want! +# +# Instead we should be using task-specific qrexec services which provide +# assurance as to what program will be responding to the (untrusted) VM +# requests. +# +# It is, however, safe, in most cases, to allow ultimate control of the +# creating AppVM over the DisposableVM it creates as part of the qrexec service +# invocation. That's why by default we have "@anyvm @dispvm allow" rule. Note +# that it does _not_ allow any AppVM to execute qubes.VMShell service over any +# DispVM created in the system -- that would obviously be wrong. It only allows +# qubes.VMShell service access to the AppVM which creates the DispVM as part of +# this very service invocation. +# +# See e.g. this thread for some discussion: +# https://groups.google.com/d/msg/qubes-users/xnAByaL_bjI/3PjYdiTDW-0J +qubes.VMShell * @anyvm @dispvm allow +qubes.VMShell * @anyvm @anyvm deny + +# WARNING: qubes.VMRootShell has similar risks as qubes.VMExec +# Add "user=root" option to any ask or allow rules. +qubes.VMRootShell * @anyvm @anyvm deny + +# WARNING: The qubes.VMExec service is dangerous and there are really few +# cases when it could be safely used. Contrary to qubes.VMShell, when policy is +# set to "ask", the command to be executed is visible in the confirmation +# prompt. But once allowed, the source VM have full control over the command +# standard input/output. Allowing one VM to execute qubes.VMExec over the +# other VM allows the former to TAKE FULL CONTROL over the later. In most cases +# this is not what we want! +# +# Instead we should be using task-specific qrexec services which provide +# assurance as to what program will be responding to the (untrusted) VM +# requests. +# +# It is, however, safe, in most cases, to allow ultimate control of the +# creating AppVM over the DisposableVM it creates as part of the qrexec service +# invocation. That's why by default we have "@anyvm @dispvm allow" rule. Note +# that it does _not_ allow any AppVM to execute qubes.VMExec service over any +# DispVM created in the system -- that would obviously be wrong. It only allows +# qubes.VMExec service access to the AppVM which creates the DispVM as part of +# this very service invocation. +# +# See e.g. this thread for some discussion: +# https://groups.google.com/d/msg/qubes-users/xnAByaL_bjI/3PjYdiTDW-0J +qubes.VMExec * @anyvm @dispvm allow +qubes.VMExec * @anyvm @anyvm deny + +# WARNING: qubes.VMExecGUI has similar risks as qubes.VMExec +qubes.VMExecGUI * @anyvm @dispvm allow +qubes.VMExecGUI * @anyvm @anyvm deny diff --git a/qubes-rpc-policy/admin-global-ro b/qubes-rpc-policy/admin-global-ro index 48cf561a..d1b136ab 100644 --- a/qubes-rpc-policy/admin-global-ro +++ b/qubes-rpc-policy/admin-global-ro @@ -2,12 +2,12 @@ ## _in default configuration_. To allow only specific action, ## edit specific policy file. -## Note that policy parsing stops at the first match, +## Note that policy parsing stops at the first match. ## Please use a single # to start your custom comments ## Include all already having write access -$include:include/admin-global-rwx +!include include/admin-global-rwx -## Add your entries here, make sure to append ",target=dom0" to all allow/ask actions +## Add your entries here, make sure to append "target=dom0" to all allow/ask actions diff --git a/qubes-rpc-policy/admin-global-rwx b/qubes-rpc-policy/admin-global-rwx index 02c0a8d2..22f7c739 100644 --- a/qubes-rpc-policy/admin-global-rwx +++ b/qubes-rpc-policy/admin-global-rwx @@ -2,10 +2,9 @@ ## _in default configuration_. To allow only specific action, ## edit specific policy file. -## Note that policy parsing stops at the first match, -## so adding anything below "$anyvm $anyvm action" line will have no effect +## Note that policy parsing stops at the first match. ## Please use a single # to start your custom comments -## Add your entries here, make sure to append ",target=dom0" to all allow/ask actions +## Add your entries here, make sure to append "target=dom0" to all allow/ask actions diff --git a/qubes-rpc-policy/admin-local-ro b/qubes-rpc-policy/admin-local-ro index b16e9f5e..8dbfec54 100644 --- a/qubes-rpc-policy/admin-local-ro +++ b/qubes-rpc-policy/admin-local-ro @@ -2,13 +2,12 @@ ## _in default configuration_. To allow only specific action, ## edit specific policy file. -## Note that policy parsing stops at the first match, -## so adding anything below "$anyvm $anyvm action" line will have no effect +## Note that policy parsing stops at the first match. ## Please use a single # to start your custom comments ## Include all already having write access -$include:include/admin-local-rwx +!include include/admin-local-rwx -## Add your entries here, make sure to append ",target=dom0" to all allow/ask actions +## Add your entries here, make sure to append "target=dom0" to all allow/ask actions diff --git a/qubes-rpc-policy/admin-local-rwx b/qubes-rpc-policy/admin-local-rwx index 8c827af3..2fa944f8 100644 --- a/qubes-rpc-policy/admin-local-rwx +++ b/qubes-rpc-policy/admin-local-rwx @@ -2,10 +2,9 @@ ## _in default configuration_. To allow only specific action, ## edit specific policy file. -## Note that policy parsing stops at the first match, -## so adding anything below "$anyvm $anyvm action" line will have no effect +## Note that policy parsing stops at the first match. ## Please use a single # to start your custom comments -## Add your entries here, make sure to append ",target=dom0" to all allow/ask actions +## Add your entries here, make sure to append "target=dom0" to all allow/ask actions diff --git a/qubes-rpc-policy/generate-admin-policy b/qubes-rpc-policy/generate-admin-policy index f2805d81..a724a375 100755 --- a/qubes-rpc-policy/generate-admin-policy +++ b/qubes-rpc-policy/generate-admin-policy @@ -30,9 +30,12 @@ parser = argparse.ArgumentParser( parser.add_argument('--include-base', action='store', default='include', help='Base path for included paths (default: %(default)s)') -parser.add_argument('--destdir', action='store', - default='/etc/qubes-rpc/policy', - help='Directory where write output files to (default: %(default)s)') +parser.add_argument('--dest', action='store', + default='/etc/qubes/policy.d/90-admin-default.policy', + help='Path where write output file to (default: %(default)s)') +parser.add_argument('--header', action='store', + default='90-admin-default.policy.header', + help='File to prepend to the policy (default: %(default)s)') parser.add_argument('--verbose', action='store_true', default=False, help='Be verbose') parser.add_argument('--exclude', action='store', nargs='*', @@ -40,22 +43,7 @@ parser.add_argument('--exclude', action='store', nargs='*', parser.add_argument('service', nargs='*', action='store', help='Generate policy for those services (default: all)') -default_policy_header = '''\ -## Note that policy parsing stops at the first match. -## Anything not specifically allowed here (or in included file) will be denied. - -## Please use a single # to start your custom comments - -## Add your entries here, make sure to append ",target=dom0" to all allow/ask actions - -## Include a common file for all admin.* methods to ease setting up -## Management VM. -## To allow only specific actions, edit specific policy file, like this one. To -## allow all of them, edit appropriate /etc/qubes-rpc/include/admin-*. - -''' - -def write_default_policy(args, apiname, clasifiers): +def write_default_policy(args, apiname, clasifiers, f): ''' Write single default policy for given API call ''' assert 'scope' in clasifiers, \ 'Method {} lack scope classifier'.format(apiname) @@ -73,22 +61,24 @@ def write_default_policy(args, apiname, clasifiers): if args.verbose: print('Service {}: include {}'.format(apiname, file_to_include), file=sys.stderr) - with open(os.path.join(args.destdir, apiname), 'w') as f: - f.write(default_policy_header) - f.write('$include:{}\n'.format( - os.path.join(args.include_base, file_to_include))) + f.write('!include-service {} * {}\n'.format( + apiname, + os.path.join(args.include_base, file_to_include))) def main(args=None): ''' Main function of default-admin-policy tool''' args = parser.parse_args(args) - for func, apiname, _ in qubes.api.admin.QubesAdminAPI.list_methods(): - if args.service and apiname not in args.service: - continue - if args.exclude and apiname in args.exclude: - continue - write_default_policy(args, apiname, func.classifiers) + with open(os.path.join(args.dest), 'w') as f: + with open(args.header) as header_f: + f.write(header_f.read()) + for func, apiname, _ in qubes.api.admin.QubesAdminAPI.list_methods(): + if args.service and apiname not in args.service: + continue + if args.exclude and apiname in args.exclude: + continue + write_default_policy(args, apiname, func.classifiers, f) if __name__ == '__main__': diff --git a/rpm_spec/core-dom0.spec.in b/rpm_spec/core-dom0.spec.in index 64dbe2a5..09a8a767 100644 --- a/rpm_spec/core-dom0.spec.in +++ b/rpm_spec/core-dom0.spec.in @@ -383,29 +383,12 @@ fi /etc/xen/scripts/block-snapshot /etc/xen/scripts/block-origin /etc/xen/scripts/vif-route-qubes -%attr(2775,root,qubes) %dir /etc/qubes-rpc/policy -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/admin.* -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/include/admin-local-ro -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/include/admin-local-rwx -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/include/admin-global-ro -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/include/admin-global-rwx -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.ConnectTCP -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.FeaturesRequest -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.Filecopy -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.GetImageRGBA -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.GetRandomizedTime -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.NotifyTools -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.NotifyUpdates -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.OpenInVM -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.OpenURL -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.StartApp -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMShell -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMRootShell -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMExec -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMExecGUI -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.UpdatesProxy -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.GetDate -%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/policy.RegisterArgument +%attr(0664,root,qubes) %config(noreplace) /etc/qubes/policy.d/90-admin-default.policy +%attr(0664,root,qubes) %config(noreplace) /etc/qubes/policy.d/90-default.policy +%attr(0664,root,qubes) %config(noreplace) /etc/qubes/policy.d/include/admin-global-ro +%attr(0664,root,qubes) %config(noreplace) /etc/qubes/policy.d/include/admin-global-rwx +%attr(0664,root,qubes) %config(noreplace) /etc/qubes/policy.d/include/admin-local-ro +%attr(0664,root,qubes) %config(noreplace) /etc/qubes/policy.d/include/admin-local-rwx /etc/qubes-rpc/admin.* /etc/qubes-rpc/qubes.FeaturesRequest /etc/qubes-rpc/qubes.GetDate From 657b6e48062ab11ca322d2ff0c496ebd6f54872b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Fri, 15 May 2020 03:00:28 +0200 Subject: [PATCH 2/2] Avoid moving old, user-modified qrexec policy to .rpmsave files Keep it at original files, to still load it using compat rules. This way the update should not break user's policies. Note the unchanged policy files are still going to be removed - meaning those calls will use the new policy. QubesOS/qubes-issues#4370 --- rpm_spec/core-dom0.spec.in | 142 +++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/rpm_spec/core-dom0.spec.in b/rpm_spec/core-dom0.spec.in index 09a8a767..d1d40c28 100644 --- a/rpm_spec/core-dom0.spec.in +++ b/rpm_spec/core-dom0.spec.in @@ -190,6 +190,148 @@ if [ "$1" = 0 ] ; then groupdel qubes fi +%posttrans + +# Preserve user-modified legacy policy at original location, revert rpm adding +# .rpmsave suffix. This needs to be done in %%posttrans, to be run after +# uninstalling the old package. + +# List policy files explicitly, to not touch files from other packages. +SERVICES=" +admin.Events +admin.backup.Cancel +admin.backup.Execute +admin.backup.Info +admin.deviceclass.List +admin.label.Create +admin.label.Get +admin.label.Index +admin.label.List +admin.label.Remove +admin.pool.Add +admin.pool.Info +admin.pool.List +admin.pool.ListDrivers +admin.pool.Remove +admin.pool.Set.revisions_to_keep +admin.pool.UsageDetails +admin.pool.volume.List +admin.property.Get +admin.property.GetAll +admin.property.GetDefault +admin.property.Help +admin.property.List +admin.property.Reset +admin.property.Set +admin.vm.Console +admin.vm.Create.AppVM +admin.vm.Create.DispVM +admin.vm.Create.StandaloneVM +admin.vm.Create.TemplateVM +admin.vm.CreateDisposable +admin.vm.CreateInPool.AppVM +admin.vm.CreateInPool.DispVM +admin.vm.CreateInPool.StandaloneVM +admin.vm.CreateInPool.TemplateVM +admin.vm.CurrentState +admin.vm.Kill +admin.vm.List +admin.vm.Pause +admin.vm.Remove +admin.vm.Shutdown +admin.vm.Start +admin.vm.Stats +admin.vm.Unpause +admin.vm.device.block.Attach +admin.vm.device.block.Available +admin.vm.device.block.Detach +admin.vm.device.block.List +admin.vm.device.block.Set.persistent +admin.vm.device.pci.Attach +admin.vm.device.pci.Available +admin.vm.device.pci.Detach +admin.vm.device.pci.List +admin.vm.device.pci.Set.persistent +admin.vm.feature.CheckWithAdminVM +admin.vm.feature.CheckWithNetvm +admin.vm.feature.CheckWithTemplate +admin.vm.feature.CheckWithTemplateAndAdminVM +admin.vm.feature.Get +admin.vm.feature.List +admin.vm.feature.Remove +admin.vm.feature.Set +admin.vm.firewall.Get +admin.vm.firewall.Reload +admin.vm.firewall.Set +admin.vm.property.Get +admin.vm.property.GetAll +admin.vm.property.GetDefault +admin.vm.property.Help +admin.vm.property.List +admin.vm.property.Reset +admin.vm.property.Set +admin.vm.tag.Get +admin.vm.tag.List +admin.vm.tag.Remove +admin.vm.tag.Set +admin.vm.volume.CloneFrom +admin.vm.volume.CloneTo +admin.vm.volume.Import +admin.vm.volume.ImportWithSize +admin.vm.volume.Info +admin.vm.volume.List +admin.vm.volume.ListSnapshots +admin.vm.volume.Resize +admin.vm.volume.Revert +admin.vm.volume.Set.revisions_to_keep +admin.vm.volume.Set.rw +admin.vmclass.List +include/admin-global-ro +include/admin-global-rwx +include/admin-local-ro +include/admin-local-rwx +policy.RegisterArgument +qubes.ConnectTCP +qubes.FeaturesRequest +qubes.Filecopy +qubes.GetDate +qubes.GetImageRGBA +qubes.GetRandomizedTime +qubes.NotifyTools +qubes.NotifyUpdates +qubes.OpenInVM +qubes.OpenURL +qubes.StartApp +qubes.UpdatesProxy +qubes.VMExec +qubes.VMExecGUI +qubes.VMRootShell +qubes.VMShell +" + +for service in $SERVICES; do + if [ -f "/etc/qubes-rpc/policy/$service.rpmsave" ] && \ + ! [ -e "/etc/qubes-rpc/policy/$service" ]; then + mv -n "/etc/qubes-rpc/policy/$service.rpmsave" \ + "/etc/qubes-rpc/policy/$service" + fi +done + +# Take extra care about policy files in include/ - if any of them is gone +# (because unmodified) but user still reference them anywhere, the policy +# loading will be broken. Check for this case, and avoid the issue by creating +# a symlink to the new policy. + +INCLUDES="admin-global-ro admin-global-rwx admin-local-ro admin-local-rwx" + +for include in $INCLUDES; do + if grep -qr "include/$include" /etc/qubes-rpc && \ + ! [ -e "/etc/qubes-rpc/policy/include/$include" ]; then + ln -s "../../../qubes/policy.d/include/$include" \ + "/etc/qubes-rpc/policy/include/$include" + fi +done + %files %defattr(-,root,root,-) %config(noreplace) %attr(0664,root,qubes) %{_sysconfdir}/qubes/qmemman.conf