From 888073df05877d2e669f4f70ed982529765ea62f Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Sat, 8 Dec 2018 20:43:36 -0500 Subject: [PATCH 01/10] Add admin.repos.* qrexec services This is a prerequisite for QubesOS/qubes-issues#4550. --- qubes-rpc-policy/admin.repos.Disable | 7 +++++++ qubes-rpc-policy/admin.repos.Enable | 7 +++++++ qubes-rpc-policy/admin.repos.List | 7 +++++++ qubes-rpc/admin.repos.Disable | 24 ++++++++++++++++++++++++ qubes-rpc/admin.repos.Enable | 24 ++++++++++++++++++++++++ qubes-rpc/admin.repos.List | 11 +++++++++++ 6 files changed, 80 insertions(+) create mode 100644 qubes-rpc-policy/admin.repos.Disable create mode 100644 qubes-rpc-policy/admin.repos.Enable create mode 100644 qubes-rpc-policy/admin.repos.List create mode 100755 qubes-rpc/admin.repos.Disable create mode 100755 qubes-rpc/admin.repos.Enable create mode 100755 qubes-rpc/admin.repos.List diff --git a/qubes-rpc-policy/admin.repos.Disable b/qubes-rpc-policy/admin.repos.Disable new file mode 100644 index 0000000..c829d5a --- /dev/null +++ b/qubes-rpc-policy/admin.repos.Disable @@ -0,0 +1,7 @@ +## Note that policy parsing stops at the first match, +## so adding anything below "$anyvm $anyvm action" line will have no effect + +## Please use a single # to start your custom comments + +dom0 dom0 allow +$anyvm $anyvm deny diff --git a/qubes-rpc-policy/admin.repos.Enable b/qubes-rpc-policy/admin.repos.Enable new file mode 100644 index 0000000..c829d5a --- /dev/null +++ b/qubes-rpc-policy/admin.repos.Enable @@ -0,0 +1,7 @@ +## Note that policy parsing stops at the first match, +## so adding anything below "$anyvm $anyvm action" line will have no effect + +## Please use a single # to start your custom comments + +dom0 dom0 allow +$anyvm $anyvm deny diff --git a/qubes-rpc-policy/admin.repos.List b/qubes-rpc-policy/admin.repos.List new file mode 100644 index 0000000..c829d5a --- /dev/null +++ b/qubes-rpc-policy/admin.repos.List @@ -0,0 +1,7 @@ +## Note that policy parsing stops at the first match, +## so adding anything below "$anyvm $anyvm action" line will have no effect + +## Please use a single # to start your custom comments + +dom0 dom0 allow +$anyvm $anyvm deny diff --git a/qubes-rpc/admin.repos.Disable b/qubes-rpc/admin.repos.Disable new file mode 100755 index 0000000..8c7b12f --- /dev/null +++ b/qubes-rpc/admin.repos.Disable @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +# Empty output indicates success; any input indicates error (probably an exception) + +import dnf +import iniparse +import sys + +base = dnf.Base() + +base.read_all_repos() + +reponame = sys.stdin.readline() +repo = base.repos[reponame] + +# Loosely based on write_raw_configfile() from DNF source code, +# because that method was introduced in DNF 2.0 but Qubes dom0 has DNF 1.x. +with open(repo.repofile) as fp: + ini = iniparse.INIConfig(fp) + +ini[reponame]['enabled'] = 0 + +with open(repo.repofile, 'w') as fp: + fp.write(str(ini)) diff --git a/qubes-rpc/admin.repos.Enable b/qubes-rpc/admin.repos.Enable new file mode 100755 index 0000000..7cce2a8 --- /dev/null +++ b/qubes-rpc/admin.repos.Enable @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +# Empty output indicates success; any input indicates error (probably an exception) + +import dnf +import iniparse +import sys + +base = dnf.Base() + +base.read_all_repos() + +reponame = sys.stdin.readline() +repo = base.repos[reponame] + +# Loosely based on write_raw_configfile() from DNF source code, +# because that method was introduced in DNF 2.0 but Qubes dom0 has DNF 1.x. +with open(repo.repofile) as fp: + ini = iniparse.INIConfig(fp) + +ini[reponame]['enabled'] = 1 + +with open(repo.repofile, 'w') as fp: + fp.write(str(ini)) diff --git a/qubes-rpc/admin.repos.List b/qubes-rpc/admin.repos.List new file mode 100755 index 0000000..a347d53 --- /dev/null +++ b/qubes-rpc/admin.repos.List @@ -0,0 +1,11 @@ +#!/usr/bin/python3 + +import dnf + +base = dnf.Base() + +base.read_all_repos() + +for repo in base.repos.all(): + l = [repo.id, repo.name, 'enabled' if repo.enabled else 'disabled'] + print('\0'.join(l)) From ce702093100c94ea63a7cac248bcae976dd2a8bd Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Sun, 9 Dec 2018 01:38:07 -0500 Subject: [PATCH 02/10] Rename admin.repos.* to qubes.repos.* --- qubes-rpc-policy/{admin.repos.Disable => qubes.repos.Disable} | 0 qubes-rpc-policy/{admin.repos.Enable => qubes.repos.Enable} | 0 qubes-rpc-policy/{admin.repos.List => qubes.repos.List} | 0 qubes-rpc/{admin.repos.Disable => qubes.repos.Disable} | 0 qubes-rpc/{admin.repos.Enable => qubes.repos.Enable} | 0 qubes-rpc/{admin.repos.List => qubes.repos.List} | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename qubes-rpc-policy/{admin.repos.Disable => qubes.repos.Disable} (100%) rename qubes-rpc-policy/{admin.repos.Enable => qubes.repos.Enable} (100%) rename qubes-rpc-policy/{admin.repos.List => qubes.repos.List} (100%) rename qubes-rpc/{admin.repos.Disable => qubes.repos.Disable} (100%) rename qubes-rpc/{admin.repos.Enable => qubes.repos.Enable} (100%) rename qubes-rpc/{admin.repos.List => qubes.repos.List} (100%) diff --git a/qubes-rpc-policy/admin.repos.Disable b/qubes-rpc-policy/qubes.repos.Disable similarity index 100% rename from qubes-rpc-policy/admin.repos.Disable rename to qubes-rpc-policy/qubes.repos.Disable diff --git a/qubes-rpc-policy/admin.repos.Enable b/qubes-rpc-policy/qubes.repos.Enable similarity index 100% rename from qubes-rpc-policy/admin.repos.Enable rename to qubes-rpc-policy/qubes.repos.Enable diff --git a/qubes-rpc-policy/admin.repos.List b/qubes-rpc-policy/qubes.repos.List similarity index 100% rename from qubes-rpc-policy/admin.repos.List rename to qubes-rpc-policy/qubes.repos.List diff --git a/qubes-rpc/admin.repos.Disable b/qubes-rpc/qubes.repos.Disable similarity index 100% rename from qubes-rpc/admin.repos.Disable rename to qubes-rpc/qubes.repos.Disable diff --git a/qubes-rpc/admin.repos.Enable b/qubes-rpc/qubes.repos.Enable similarity index 100% rename from qubes-rpc/admin.repos.Enable rename to qubes-rpc/qubes.repos.Enable diff --git a/qubes-rpc/admin.repos.List b/qubes-rpc/qubes.repos.List similarity index 100% rename from qubes-rpc/admin.repos.List rename to qubes-rpc/qubes.repos.List From 529f5a1cd049e21cecb7b498deed2791607fcd9b Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Sun, 9 Dec 2018 01:42:46 -0500 Subject: [PATCH 03/10] Use Python whitespace conventions --- qubes-rpc/qubes.repos.Disable | 4 ++-- qubes-rpc/qubes.repos.Enable | 4 ++-- qubes-rpc/qubes.repos.List | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/qubes-rpc/qubes.repos.Disable b/qubes-rpc/qubes.repos.Disable index 8c7b12f..6c07971 100755 --- a/qubes-rpc/qubes.repos.Disable +++ b/qubes-rpc/qubes.repos.Disable @@ -16,9 +16,9 @@ repo = base.repos[reponame] # Loosely based on write_raw_configfile() from DNF source code, # because that method was introduced in DNF 2.0 but Qubes dom0 has DNF 1.x. with open(repo.repofile) as fp: - ini = iniparse.INIConfig(fp) + ini = iniparse.INIConfig(fp) ini[reponame]['enabled'] = 0 with open(repo.repofile, 'w') as fp: - fp.write(str(ini)) + fp.write(str(ini)) diff --git a/qubes-rpc/qubes.repos.Enable b/qubes-rpc/qubes.repos.Enable index 7cce2a8..d013c74 100755 --- a/qubes-rpc/qubes.repos.Enable +++ b/qubes-rpc/qubes.repos.Enable @@ -16,9 +16,9 @@ repo = base.repos[reponame] # Loosely based on write_raw_configfile() from DNF source code, # because that method was introduced in DNF 2.0 but Qubes dom0 has DNF 1.x. with open(repo.repofile) as fp: - ini = iniparse.INIConfig(fp) + ini = iniparse.INIConfig(fp) ini[reponame]['enabled'] = 1 with open(repo.repofile, 'w') as fp: - fp.write(str(ini)) + fp.write(str(ini)) diff --git a/qubes-rpc/qubes.repos.List b/qubes-rpc/qubes.repos.List index a347d53..e462d7e 100755 --- a/qubes-rpc/qubes.repos.List +++ b/qubes-rpc/qubes.repos.List @@ -7,5 +7,5 @@ base = dnf.Base() base.read_all_repos() for repo in base.repos.all(): - l = [repo.id, repo.name, 'enabled' if repo.enabled else 'disabled'] - print('\0'.join(l)) + l = [repo.id, repo.name, 'enabled' if repo.enabled else 'disabled'] + print('\0'.join(l)) From 0af2769acab3b647ac41e97a1e79953d3c0bbcbf Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Sun, 9 Dec 2018 01:46:38 -0500 Subject: [PATCH 04/10] Enable/disable repos atomically --- qubes-rpc/qubes.repos.Disable | 5 ++++- qubes-rpc/qubes.repos.Enable | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/qubes-rpc/qubes.repos.Disable b/qubes-rpc/qubes.repos.Disable index 6c07971..e340c60 100755 --- a/qubes-rpc/qubes.repos.Disable +++ b/qubes-rpc/qubes.repos.Disable @@ -4,6 +4,7 @@ import dnf import iniparse +import os import sys base = dnf.Base() @@ -20,5 +21,7 @@ with open(repo.repofile) as fp: ini[reponame]['enabled'] = 0 -with open(repo.repofile, 'w') as fp: +with open(repo.repofile + '.new', 'w') as fp: fp.write(str(ini)) + +os.rename(repo.repofile + '.new', repo.repofile) diff --git a/qubes-rpc/qubes.repos.Enable b/qubes-rpc/qubes.repos.Enable index d013c74..a832c4e 100755 --- a/qubes-rpc/qubes.repos.Enable +++ b/qubes-rpc/qubes.repos.Enable @@ -4,6 +4,7 @@ import dnf import iniparse +import os import sys base = dnf.Base() @@ -20,5 +21,7 @@ with open(repo.repofile) as fp: ini[reponame]['enabled'] = 1 -with open(repo.repofile, 'w') as fp: +with open(repo.repofile + '.new', 'w') as fp: fp.write(str(ini)) + +os.rename(repo.repofile + '.new', repo.repofile) From 05658f08503681c5d6df0c302650073fb9c8c7dd Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Sun, 9 Dec 2018 02:03:17 -0500 Subject: [PATCH 05/10] Properly set the umask for repo files --- qubes-rpc/qubes.repos.Disable | 2 ++ qubes-rpc/qubes.repos.Enable | 2 ++ 2 files changed, 4 insertions(+) diff --git a/qubes-rpc/qubes.repos.Disable b/qubes-rpc/qubes.repos.Disable index e340c60..0f35c4a 100755 --- a/qubes-rpc/qubes.repos.Disable +++ b/qubes-rpc/qubes.repos.Disable @@ -7,6 +7,8 @@ import iniparse import os import sys +os.umask(0o022) + base = dnf.Base() base.read_all_repos() diff --git a/qubes-rpc/qubes.repos.Enable b/qubes-rpc/qubes.repos.Enable index a832c4e..3ba25bf 100755 --- a/qubes-rpc/qubes.repos.Enable +++ b/qubes-rpc/qubes.repos.Enable @@ -7,6 +7,8 @@ import iniparse import os import sys +os.umask(0o022) + base = dnf.Base() base.read_all_repos() From 00c37b0b5b8d2dd97ccb6237aa1783b8b5c72f57 Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Sun, 9 Dec 2018 02:09:46 -0500 Subject: [PATCH 06/10] Use qrexec service arguments --- qubes-rpc/qubes.repos.Disable | 2 +- qubes-rpc/qubes.repos.Enable | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qubes-rpc/qubes.repos.Disable b/qubes-rpc/qubes.repos.Disable index 0f35c4a..afac982 100755 --- a/qubes-rpc/qubes.repos.Disable +++ b/qubes-rpc/qubes.repos.Disable @@ -13,7 +13,7 @@ base = dnf.Base() base.read_all_repos() -reponame = sys.stdin.readline() +reponame = sys.argv[1] repo = base.repos[reponame] # Loosely based on write_raw_configfile() from DNF source code, diff --git a/qubes-rpc/qubes.repos.Enable b/qubes-rpc/qubes.repos.Enable index 3ba25bf..62c8a01 100755 --- a/qubes-rpc/qubes.repos.Enable +++ b/qubes-rpc/qubes.repos.Enable @@ -13,7 +13,7 @@ base = dnf.Base() base.read_all_repos() -reponame = sys.stdin.readline() +reponame = sys.argv[1] repo = base.repos[reponame] # Loosely based on write_raw_configfile() from DNF source code, From 2283af8ce5d1729f2bd99770162c9bd429df3533 Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Mon, 31 Dec 2018 18:04:15 -0500 Subject: [PATCH 07/10] Print `ok` for repo enable/disable success --- qubes-rpc/qubes.repos.Disable | 9 ++++++--- qubes-rpc/qubes.repos.Enable | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/qubes-rpc/qubes.repos.Disable b/qubes-rpc/qubes.repos.Disable index afac982..3d62b79 100755 --- a/qubes-rpc/qubes.repos.Disable +++ b/qubes-rpc/qubes.repos.Disable @@ -1,6 +1,7 @@ #!/usr/bin/python3 -# Empty output indicates success; any input indicates error (probably an exception) +# `ok` on stdout indicates success; any stderr output indicates an error +# (probably an exception) import dnf import iniparse @@ -16,8 +17,8 @@ base.read_all_repos() reponame = sys.argv[1] repo = base.repos[reponame] -# Loosely based on write_raw_configfile() from DNF source code, -# because that method was introduced in DNF 2.0 but Qubes dom0 has DNF 1.x. +# Loosely based on write_raw_configfile() from DNF source code, because +# that method was introduced in DNF 2.0 but Qubes dom0 has DNF 1.x. with open(repo.repofile) as fp: ini = iniparse.INIConfig(fp) @@ -27,3 +28,5 @@ with open(repo.repofile + '.new', 'w') as fp: fp.write(str(ini)) os.rename(repo.repofile + '.new', repo.repofile) + +print('ok') diff --git a/qubes-rpc/qubes.repos.Enable b/qubes-rpc/qubes.repos.Enable index 62c8a01..ed24484 100755 --- a/qubes-rpc/qubes.repos.Enable +++ b/qubes-rpc/qubes.repos.Enable @@ -1,6 +1,7 @@ #!/usr/bin/python3 -# Empty output indicates success; any input indicates error (probably an exception) +# `ok` on stdout indicates success; any stderr output indicates an error +# (probably an exception) import dnf import iniparse @@ -16,8 +17,8 @@ base.read_all_repos() reponame = sys.argv[1] repo = base.repos[reponame] -# Loosely based on write_raw_configfile() from DNF source code, -# because that method was introduced in DNF 2.0 but Qubes dom0 has DNF 1.x. +# Loosely based on write_raw_configfile() from DNF source code, because +# that method was introduced in DNF 2.0 but Qubes dom0 has DNF 1.x. with open(repo.repofile) as fp: ini = iniparse.INIConfig(fp) @@ -27,3 +28,5 @@ with open(repo.repofile + '.new', 'w') as fp: fp.write(str(ini)) os.rename(repo.repofile + '.new', repo.repofile) + +print('ok') From 75faa22dff970acc1664d4b3d403f374c2fcf0b1 Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Mon, 31 Dec 2018 18:27:20 -0500 Subject: [PATCH 08/10] Add qubes.repos.* services to the RPMs --- rpm_spec/core-dom0-linux.spec.in | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rpm_spec/core-dom0-linux.spec.in b/rpm_spec/core-dom0-linux.spec.in index 097d37f..dba79f7 100644 --- a/rpm_spec/core-dom0-linux.spec.in +++ b/rpm_spec/core-dom0-linux.spec.in @@ -106,6 +106,12 @@ ln -s ../../bin/qrexec-client $RPM_BUILD_ROOT/usr/lib/qubes/qrexec-client ln -s ../../sbin/qrexec-daemon $RPM_BUILD_ROOT/usr/lib/qubes/qrexec-daemon cp qrexec/qubes-rpc-multiplexer $RPM_BUILD_ROOT/usr/lib/qubes +# Qrexec services +mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes/qubes-rpc $RPM_BUILD_ROOT/etc/qubes-rpc/policy +cp qubes-rpc/* $RPM_BUILD_ROOT/usr/lib/qubes/qubes-rpc/ +for i in qubes-rpc/*; do ln -s ../../usr/lib/qubes/$i $RPM_BUILD_ROOT/etc/qubes-rpc/$(basename $i); done +cp qubes-rpc-policy/* $RPM_BUILD_ROOT/etc/qubes-rpc/policy/ + ### pm-utils mkdir -p $RPM_BUILD_ROOT/usr/lib64/pm-utils/sleep.d cp pm-utils/52qubes-pause-vms $RPM_BUILD_ROOT/usr/lib64/pm-utils/sleep.d/ @@ -207,6 +213,12 @@ chmod -x /etc/grub.d/10_linux /etc/qubes-rpc/qubes.ReceiveUpdates %attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.ReceiveUpdates %attr(0770,root,qubes) %dir /var/lib/qubes/updates +# Qrexec services +/etc/qubes-rpc/qubes.repos.* +/usr/lib/qubes/qubes-rpc/qubes.repos.* +%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.repos.List +%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.repos.Enable +%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.repos.Disable # Dracut module /etc/dracut.conf.d/* %dir %{_dracutmoddir}/90qubes-pciback From 3786197ab23847895d6518d7b91e4178b00253cd Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Mon, 8 Apr 2019 03:41:45 -0400 Subject: [PATCH 09/10] Don't write a trailing newline in qubes.repos.List This makes it annoying to parse. --- qubes-rpc/qubes.repos.List | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qubes-rpc/qubes.repos.List b/qubes-rpc/qubes.repos.List index e462d7e..ffdfd04 100755 --- a/qubes-rpc/qubes.repos.List +++ b/qubes-rpc/qubes.repos.List @@ -6,6 +6,9 @@ base = dnf.Base() base.read_all_repos() +first = True for repo in base.repos.all(): l = [repo.id, repo.name, 'enabled' if repo.enabled else 'disabled'] - print('\0'.join(l)) + if not first: print() + first = False + print('\0'.join(l), end='') From 82806b53e22d4358685d0a59c40cbd6cbe5c111a Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Mon, 8 Apr 2019 03:46:28 -0400 Subject: [PATCH 10/10] Add some comments to qubes.repos.List --- qubes-rpc/qubes.repos.List | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qubes-rpc/qubes.repos.List b/qubes-rpc/qubes.repos.List index ffdfd04..d16f4d4 100755 --- a/qubes-rpc/qubes.repos.List +++ b/qubes-rpc/qubes.repos.List @@ -1,5 +1,8 @@ #!/usr/bin/python3 +# Records in the output are separated by newlines; fields are separated by \0 +# Each record is unique_id:pretty_name:enabled + import dnf base = dnf.Base()