Fix over indented code blocks

This commit is contained in:
Marek Marczykowski-Górecki 2021-03-28 20:58:39 +02:00
parent 0824b2d196
commit 752f1d4ddc
No known key found for this signature in database
GPG Key ID: F32894BE9684938A
16 changed files with 530 additions and 492 deletions

View File

@ -113,7 +113,7 @@ And this should produce a shiny new ISO.
You can also build selected component separately. Eg. to compile only gui virtualization agent/daemon:
```shell
make gui-daemon
make gui-daemon
```
You can get a full list from make help.

View File

@ -157,14 +157,14 @@ Security coding guidelines
- Use `untrusted_` prefix for all variables that hold values read from untrusted party and which have not yet been verified to be decent, e.g.:
~~~
read_struct(untrusted_conf);
/* sanitize start */
if (untrusted_conf.width > MAX_WINDOW_WIDTH)
untrusted_conf.width = MAX_WINDOW_WIDTH;
if (untrusted_conf.height > MAX_WINDOW_HEIGHT)
untrusted_conf.height = MAX_WINDOW_HEIGHT;
width = untrusted_conf.width;
height = untrusted_conf.height;
read_struct(untrusted_conf);
/* sanitize start */
if (untrusted_conf.width > MAX_WINDOW_WIDTH)
untrusted_conf.width = MAX_WINDOW_WIDTH;
if (untrusted_conf.height > MAX_WINDOW_HEIGHT)
untrusted_conf.height = MAX_WINDOW_HEIGHT;
width = untrusted_conf.width;
height = untrusted_conf.height;
~~~
- Use others variables, without the `untrusted_` prefix to hold the sanitized values, as shown above.

View File

@ -47,70 +47,70 @@ Our test runner runs mostly the same as the standard one, but it has some nice a
You can use `python3 -m qubes.tests.run -h` to get usage information:
```
[user@dom0 ~]$ python3 -m qubes.tests.run -h
usage: run.py [-h] [--verbose] [--quiet] [--list] [--failfast] [--no-failfast]
[--do-not-clean] [--do-clean] [--loglevel LEVEL]
[--logfile FILE] [--syslog] [--no-syslog] [--kmsg] [--no-kmsg]
[TESTNAME [TESTNAME ...]]
[user@dom0 ~]$ python3 -m qubes.tests.run -h
usage: run.py [-h] [--verbose] [--quiet] [--list] [--failfast] [--no-failfast]
[--do-not-clean] [--do-clean] [--loglevel LEVEL]
[--logfile FILE] [--syslog] [--no-syslog] [--kmsg] [--no-kmsg]
[TESTNAME [TESTNAME ...]]
positional arguments:
TESTNAME list of tests to run named like in description
(default: run all tests)
positional arguments:
TESTNAME list of tests to run named like in description
(default: run all tests)
optional arguments:
-h, --help show this help message and exit
--verbose, -v increase console verbosity level
--quiet, -q decrease console verbosity level
--list, -l list all available tests and exit
--failfast, -f stop on the first fail, error or unexpected success
--no-failfast disable --failfast
--loglevel LEVEL, -L LEVEL
logging level for file and syslog forwarding (one of:
NOTSET, DEBUG, INFO, WARN, WARNING, ERROR, CRITICAL;
default: DEBUG)
--logfile FILE, -o FILE
if set, test run will be also logged to file
--syslog reenable logging to syslog
--no-syslog disable logging to syslog
--kmsg, --very-brave-or-very-stupid
log most important things to kernel ring-buffer
--no-kmsg, --i-am-smarter-than-kay-sievers
do not abuse kernel ring-buffer
--allow-running-along-qubesd
allow running in parallel with qubesd; this is
DANGEROUS and WILL RESULT IN INCONSISTENT SYSTEM STATE
--break-to-repl break to REPL after tests
optional arguments:
-h, --help show this help message and exit
--verbose, -v increase console verbosity level
--quiet, -q decrease console verbosity level
--list, -l list all available tests and exit
--failfast, -f stop on the first fail, error or unexpected success
--no-failfast disable --failfast
--loglevel LEVEL, -L LEVEL
logging level for file and syslog forwarding (one of:
NOTSET, DEBUG, INFO, WARN, WARNING, ERROR, CRITICAL;
default: DEBUG)
--logfile FILE, -o FILE
if set, test run will be also logged to file
--syslog reenable logging to syslog
--no-syslog disable logging to syslog
--kmsg, --very-brave-or-very-stupid
log most important things to kernel ring-buffer
--no-kmsg, --i-am-smarter-than-kay-sievers
do not abuse kernel ring-buffer
--allow-running-along-qubesd
allow running in parallel with qubesd; this is
DANGEROUS and WILL RESULT IN INCONSISTENT SYSTEM STATE
--break-to-repl break to REPL after tests
When running only specific tests, write their names like in log, in format:
MODULE+"/"+CLASS+"/"+FUNCTION. MODULE should omit initial "qubes.tests.".
Example: basic/TC_00_Basic/test_000_create
When running only specific tests, write their names like in log, in format:
MODULE+"/"+CLASS+"/"+FUNCTION. MODULE should omit initial "qubes.tests.".
Example: basic/TC_00_Basic/test_000_create
```
For instance, to run only the tests for the fedora-21 template, you can use the `-l` option, then filter the list:
```
[user@dom0 ~]$ python3 -m qubes.tests.run -l | grep fedora-21
network/VmNetworking_fedora-21/test_000_simple_networking
network/VmNetworking_fedora-21/test_010_simple_proxyvm
network/VmNetworking_fedora-21/test_020_simple_proxyvm_nm
network/VmNetworking_fedora-21/test_030_firewallvm_firewall
network/VmNetworking_fedora-21/test_040_inter_vm
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_000_start_shutdown
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_010_run_gui_app
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_050_qrexec_simple_eof
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_051_qrexec_simple_eof_reverse
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_052_qrexec_vm_service_eof
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_053_qrexec_vm_service_eof_reverse
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_060_qrexec_exit_code_dom0
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_065_qrexec_exit_code_vm
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_100_qrexec_filecopy
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_110_qrexec_filecopy_deny
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_120_qrexec_filecopy_self
vm_qrexec_gui/TC_20_DispVM_fedora-21/test_000_prepare_dvm
vm_qrexec_gui/TC_20_DispVM_fedora-21/test_010_simple_dvm_run
vm_qrexec_gui/TC_20_DispVM_fedora-21/test_020_gui_app
vm_qrexec_gui/TC_20_DispVM_fedora-21/test_030_edit_file
[user@dom0 ~]$ sudo -E python3 -m qubes.tests.run -v `python3 -m qubes.tests.run -l | grep fedora-21`
[user@dom0 ~]$ python3 -m qubes.tests.run -l | grep fedora-21
network/VmNetworking_fedora-21/test_000_simple_networking
network/VmNetworking_fedora-21/test_010_simple_proxyvm
network/VmNetworking_fedora-21/test_020_simple_proxyvm_nm
network/VmNetworking_fedora-21/test_030_firewallvm_firewall
network/VmNetworking_fedora-21/test_040_inter_vm
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_000_start_shutdown
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_010_run_gui_app
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_050_qrexec_simple_eof
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_051_qrexec_simple_eof_reverse
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_052_qrexec_vm_service_eof
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_053_qrexec_vm_service_eof_reverse
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_060_qrexec_exit_code_dom0
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_065_qrexec_exit_code_vm
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_100_qrexec_filecopy
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_110_qrexec_filecopy_deny
vm_qrexec_gui/TC_00_AppVM_fedora-21/test_120_qrexec_filecopy_self
vm_qrexec_gui/TC_20_DispVM_fedora-21/test_000_prepare_dvm
vm_qrexec_gui/TC_20_DispVM_fedora-21/test_010_simple_dvm_run
vm_qrexec_gui/TC_20_DispVM_fedora-21/test_020_gui_app
vm_qrexec_gui/TC_20_DispVM_fedora-21/test_030_edit_file
[user@dom0 ~]$ sudo -E python3 -m qubes.tests.run -v `python3 -m qubes.tests.run -l | grep fedora-21`
```
Example test run:
@ -120,7 +120,7 @@ Example test run:
Tests are also compatible with nose2 test runner, so you can use this instead:
```bash
sudo systemctl stop qubesd; sudo -E nose2 -v --plugin nose2.plugins.loader.loadtests qubes.tests; sudo systemctl start qubesd
sudo systemctl stop qubesd; sudo -E nose2 -v --plugin nose2.plugins.loader.loadtests qubes.tests; sudo systemctl start qubesd
```
This may be especially useful together with various nose2 plugins to store tests results (for example `nose2.plugins.junitxml`), to ease presenting results. This is what we use on [OpenQA].
@ -179,16 +179,16 @@ You'll also need to add your test at the bottom of the `__init__.py` file, in th
Again, given the hypothetical `example.py` test:
~~~python
for modname in (
'qubes.tests.basic',
'qubes.tests.dom0_update',
'qubes.tests.network',
'qubes.tests.vm_qrexec_gui',
'qubes.tests.backup',
'qubes.tests.backupcompatibility',
'qubes.tests.regressions',
'qubes.tests.example', # This is our newly added test
):
for modname in (
'qubes.tests.basic',
'qubes.tests.dom0_update',
'qubes.tests.network',
'qubes.tests.vm_qrexec_gui',
'qubes.tests.backup',
'qubes.tests.backupcompatibility',
'qubes.tests.regressions',
'qubes.tests.example', # This is our newly added test
):
~~~
### Testing PyQt applications

View File

@ -43,19 +43,19 @@ You have to select the area in which you suspect less than optimal performance.
Replace
```python
def foo(self, bar):
# function content
def foo(self, bar):
# function content
```
with
```python
def foo(self, *args, **kwargs):
profile.runctx('self.real_foo(*args, **kwargs)', globals(), locals(),
time.strftime('/home/user/profiling/foo-%Y%m%d-%H%M%S.pstats'))
def foo(self, *args, **kwargs):
profile.runctx('self.real_foo(*args, **kwargs)', globals(), locals(),
time.strftime('/home/user/profiling/foo-%Y%m%d-%H%M%S.pstats'))
def real_foo(self, bar):
# function content
def real_foo(self, bar):
# function content
```
### Run application

View File

@ -23,37 +23,37 @@ First, do a clean install from ISO you built or grabbed elsewhere.
You have to fix network, because it is intentionally broken. This script should reenable your network card without depending on anything else.
```bash
#!/bin/sh
#!/bin/sh
# adjust this for your NIC (run lspci)
BDF=0000:02:00.0
# adjust this for your NIC (run lspci)
BDF=0000:02:00.0
prog=$(basename $0)
prog=$(basename $0)
pciunbind() {
local path
path=/sys/bus/pci/devices/${1}/driver/unbind
if ! [ -w ${path} ]; then
echo "${prog}: Device ${1} not bound"
return 1
fi
echo -n ${1} >${path}
}
pciunbind() {
local path
path=/sys/bus/pci/devices/${1}/driver/unbind
if ! [ -w ${path} ]; then
echo "${prog}: Device ${1} not bound"
return 1
fi
echo -n ${1} >${path}
}
pcibind() {
local path
path=/sys/bus/pci/drivers/${2}/bind
if ! [ -w ${path} ]; then
echo "${prog}: Driver ${2} not found"
return 1
fi
echo ${1} >${path}
}
pcibind() {
local path
path=/sys/bus/pci/drivers/${2}/bind
if ! [ -w ${path} ]; then
echo "${prog}: Driver ${2} not found"
return 1
fi
echo ${1} >${path}
}
pciunbind ${BDF}
pcibind ${BDF} e1000e
pciunbind ${BDF}
pcibind ${BDF} e1000e
dhclient
dhclient
```
TODO: describe how to run this at every startup
@ -97,51 +97,51 @@ This step is optional, but very helpful. Put these scripts somewhere in your `${
`qtb-runtests`:
```bash
#!/bin/sh
#!/bin/sh
ssh testbench python -m qubes.tests.run
ssh testbench python -m qubes.tests.run
```
`qtb-install`:
```bash
#!/bin/sh
#!/bin/sh
TMPDIR=/tmp/qtb-rpms
TMPDIR=/tmp/qtb-rpms
if [ $# -eq 0 ]; then
echo "usage: $(basename $0) <rpmfile> ..."
exit 2
fi
if [ $# -eq 0 ]; then
echo "usage: $(basename $0) <rpmfile> ..."
exit 2
fi
set -e
set -e
ssh testbench mkdir -p "${TMPDIR}"
scp "${@}" testbench:"${TMPDIR}"
ssh testbench mkdir -p "${TMPDIR}"
scp "${@}" testbench:"${TMPDIR}"
while [ $# -gt 0 ]; do
ssh testbench sudo rpm -i --replacepkgs --replacefiles "${TMPDIR}/$(basename ${1})"
shift
done
while [ $# -gt 0 ]; do
ssh testbench sudo rpm -i --replacepkgs --replacefiles "${TMPDIR}/$(basename ${1})"
shift
done
```
`qtb-iterate`:
```bash
#!/bin/sh
#!/bin/sh
set -e
set -e
# substitute path to your builder installation
pushd ${HOME}/builder >/dev/null
# substitute path to your builder installation
pushd ${HOME}/builder >/dev/null
# the following are needed only if you have sources outside builder
#rm -rf qubes-src/core-admin
#make COMPONENTS=core-admin get-sources
# the following are needed only if you have sources outside builder
#rm -rf qubes-src/core-admin
#make COMPONENTS=core-admin get-sources
make core-admin
qtb-install qubes-src/core-admin/rpm/x86_64/qubes-core-dom0-*.rpm
qtb-runtests
make core-admin
qtb-install qubes-src/core-admin/rpm/x86_64/qubes-core-dom0-*.rpm
qtb-runtests
```
### Hooking git
@ -151,17 +151,17 @@ I (woju) have those two git hooks. They ensure tests are passing (or are marked
`core-admin/.git/hooks/pre-commit`: (you may retain also the default hook, here omitted for readability)
```bash
#!/bin/sh
#!/bin/sh
set -e
set -e
python -c "import sys, qubes.tests.run; sys.exit(not qubes.tests.run.main())"
python -c "import sys, qubes.tests.run; sys.exit(not qubes.tests.run.main())"
```
`core-admin/.git/hooks/pre-push`:
```bash
#!/bin/sh
#!/bin/sh
exec qtb-iterate
exec qtb-iterate
```

View File

@ -25,11 +25,11 @@ Things get complicated if you need to perform kernel debugging or troubleshoot p
- To determine which dom0 pty corresponds to VM's serial port you need to read xenstore, example script below:
```bash
#!/bin/sh
#!/bin/sh
id1=$(xl domid "$1-dm")
tty1=$(xenstore-read /local/domain/${id1}/device/console/3/tty)
echo $tty1
id1=$(xl domid "$1-dm")
tty1=$(xenstore-read /local/domain/${id1}/device/console/3/tty)
echo $tty1
```
Pass it a running VM name and it will output the corresponding pty name.
@ -37,13 +37,13 @@ Pass it a running VM name and it will output the corresponding pty name.
- To connect both ptys you can use [socat](http://www.dest-unreach.org/socat/) like that:
```bash
#!/bin/sh
#!/bin/sh
id1=$(xl domid "$1-dm")
id2=$(xl domid "$2-dm")
tty1=$(xenstore-read /local/domain/${id1}/device/console/3/tty)
tty2=$(xenstore-read /local/domain/${id2}/device/console/3/tty)
socat $tty1,raw $tty2,raw
id1=$(xl domid "$1-dm")
id2=$(xl domid "$2-dm")
tty1=$(xenstore-read /local/domain/${id1}/device/console/3/tty)
tty2=$(xenstore-read /local/domain/${id2}/device/console/3/tty)
socat $tty1,raw $tty2,raw
```
...but there is a catch. Xen seems to process the traffic that goes through serial ports and changes all **0x0a** bytes into **0x0d, 0x0a** pairs (newline conversion). I didn't find a way to turn that off (setting ptys to raw mode didn't change anything) and it's not mentioned anywhere on the Internet, so maybe it's something on my system. If the above script works for you then you don't need anything more in dom0.
@ -79,115 +79,115 @@ Pass it a running VM name and it will output the corresponding pty name.
...then you're most likely a victim of the CRLF issue mentioned above. To get around it I wrote a small utility that basically does what socat would do and additionally corrects those replaced bytes in the stream. It's not pretty but it works:
```c
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
int fd1, fd2;
char mark = ' ';
int fd1, fd2;
char mark = ' ';
void out(unsigned char c)
void out(unsigned char c)
{
static int count = 0;
static unsigned char buf[17] = {0};
// relay to ouptput port
write(fd2, &c, 1);
fprintf(stderr, "%c", mark);
/* dump all data going over the line
if (count == 0)
fprintf(stderr, "%c", mark);
fprintf(stderr, "%02x ", c);
if (c >= 0x20 && c < 0x80)
buf[count] = c;
else
buf[count] = '.';
count++;
if (count == 0x10)
{
count = 0;
fprintf(stderr, " %s\n", buf);
}
*/
}
int main(int argc, char* argv[])
{
unsigned char c = 0;
struct termios tio;
ssize_t size;
if (argc < 3)
{
fprintf(stderr, "Usage: %s pty1 pty2 [mark character]\n", argv[0]);
return EINVAL;
}
fd1 = open(argv[1], O_RDONLY | O_NOCTTY);
if (fd1 <= 0)
{
perror("open fd1");
return errno;
}
fd2 = open(argv[2], O_WRONLY | O_NOCTTY);
if (fd2 <= 0)
{
perror("open fd2");
return errno;
}
/*
// This doesn't make any difference which supports the theory
// that it's Xen who corrupts the byte stream.
cfmakeraw(&tio);
if (tcsetattr(fd1, TCSANOW, &tio) < 0)
{
perror("tcsetattr 1");
return errno;
}
if (tcsetattr(fd2, TCSANOW, &tio) < 0)
{
perror("tcsetattr 2");
return errno;
}
*/
if (argc == 4)
mark = argv[3][0];
while (1)
{
size = read(fd1, &c, 1);
if (size <= 0)
break;
parse:
if (c == 0x0d)
{
static int count = 0;
static unsigned char buf[17] = {0};
// relay to ouptput port
write(fd2, &c, 1);
fprintf(stderr, "%c", mark);
/* dump all data going over the line
if (count == 0)
fprintf(stderr, "%c", mark);
fprintf(stderr, "%02x ", c);
if (c >= 0x20 && c < 0x80)
buf[count] = c;
size = read(fd1, &c, 1);
if (size <= 0)
{
out(0x0d);
break;
}
if (c == 0x0a)
{
out(0x0a);
}
else
buf[count] = '.';
count++;
if (count == 0x10)
{
count = 0;
fprintf(stderr, " %s\n", buf);
out(0x0d);
goto parse;
}
*/
}
else
out(c);
}
int main(int argc, char* argv[])
{
unsigned char c = 0;
struct termios tio;
ssize_t size;
if (argc < 3)
{
fprintf(stderr, "Usage: %s pty1 pty2 [mark character]\n", argv[0]);
return EINVAL;
}
fd1 = open(argv[1], O_RDONLY | O_NOCTTY);
if (fd1 <= 0)
{
perror("open fd1");
return errno;
}
fd2 = open(argv[2], O_WRONLY | O_NOCTTY);
if (fd2 <= 0)
{
perror("open fd2");
return errno;
}
/*
// This doesn't make any difference which supports the theory
// that it's Xen who corrupts the byte stream.
cfmakeraw(&tio);
if (tcsetattr(fd1, TCSANOW, &tio) < 0)
{
perror("tcsetattr 1");
return errno;
}
if (tcsetattr(fd2, TCSANOW, &tio) < 0)
{
perror("tcsetattr 2");
return errno;
}
*/
if (argc == 4)
mark = argv[3][0];
while (1)
{
size = read(fd1, &c, 1);
if (size <= 0)
break;
parse:
if (c == 0x0d)
{
size = read(fd1, &c, 1);
if (size <= 0)
{
out(0x0d);
break;
}
if (c == 0x0a)
{
out(0x0a);
}
else
{
out(0x0d);
goto parse;
}
}
else
out(c);
}
close(fd1);
close(fd2);
return 0;
}
close(fd1);
close(fd2);
return 0;
}
```
> This utility is a unidirectional relay so you need to run two instances to get duplex communication, like:

View File

@ -49,7 +49,9 @@ Security Notes
2. Select `Terminal Emulator`.
3. In the window that opens, enter this command:
sudo nano /etc/yum.repos.d/qubes-dom0.repo
```
sudo nano /etc/yum.repos.d/qubes-dom0.repo
```
4. This opens the nano text editor. Change all four instances of `http` to `https`.
5. Press `CTRL+X`, then `Y`, then `ENTER` to save changes and exit.
@ -61,8 +63,10 @@ Security Notes
2. Select `Template: fedora-26`, then `fedora-26: Terminal`.
3. In the window that opens, enter the command for your version:
[Qubes 3.2] sudo gedit /etc/yum.repos.d/qubes-r3.repo
[Qubes 4.0] sudo gedit /etc/yum.repos.d/qubes-r4.repo
```
[Qubes 3.2] sudo gedit /etc/yum.repos.d/qubes-r3.repo
[Qubes 4.0] sudo gedit /etc/yum.repos.d/qubes-r4.repo
```
4. This opens the gedit text editor in a window. Change all four instances of `http` to `https`.
5. Click the "Save" button in the top-right corner of the window.

View File

@ -23,13 +23,13 @@ Before passing user input, the socket service will receive a null-terminated ser
When running in a VM, this is:
```
<service_name> <source>\0
<service_name> <source>\0
```
When running in dom0, it is:
```
<service_name> <source> <target_type> <target>\0
<service_name> <source> <target_type> <target>\0
```
(The target type can be `name`, in which case target is a domain name, or `keyword`, in which the target is a keyword like `@dispvm`).

View File

@ -33,7 +33,7 @@ the stdin/stdout/stderr from this remote process will be passed to the
E.g., to start a primitive shell in a VM type the following in Dom0 console:
```shell_session
[user@dom0 ~]$ /usr/lib/qubes/qrexec-client -d <vm name> user:bash
[user@dom0 ~]$ /usr/lib/qubes/qrexec-client -d <vm name> user:bash
```
The string before first semicolon specifies what user to run the command as.
@ -102,21 +102,21 @@ whose names describe the available RPC actions; their content is the RPC
access policy database. Some example of the default services in Qubes are:
```
qubes.Filecopy
qubes.OpenInVM
qubes.ReceiveUpdates
qubes.SyncAppMenus
qubes.VMShell
qubes.ClipboardPaste
qubes.Gpg
qubes.NotifyUpdates
qubes.PdfConvert
qubes.Filecopy
qubes.OpenInVM
qubes.ReceiveUpdates
qubes.SyncAppMenus
qubes.VMShell
qubes.ClipboardPaste
qubes.Gpg
qubes.NotifyUpdates
qubes.PdfConvert
```
These files contain lines with the following format:
```
srcvm destvm (allow|deny|ask)[,user=user_to_run_as][,target=VM_to_redirect_to]
srcvm destvm (allow|deny|ask)[,user=user_to_run_as][,target=VM_to_redirect_to]
```
You can specify `srcvm` and `destvm` by name, or by one of `$anyvm`,
@ -142,7 +142,7 @@ name of the program that will be invoked.
In a src VM, one should invoke the qrexec client via the following command:
```
/usr/lib/qubes/qrexec-client-vm <target vm name> <service name> <local program path> [local program arguments]
/usr/lib/qubes/qrexec-client-vm <target vm name> <service name> <local program path> [local program arguments]
```
Note that only stdin/stdout is passed between RPC server and client --
@ -176,7 +176,7 @@ In order to remove such authorization, issue this command from a Dom0 terminal
(example below for `qubes.Filecopy` service):
```shell_session
sudo nano /etc/qubes-rpc/policy/qubes.Filecopy
sudo nano /etc/qubes-rpc/policy/qubes.Filecopy
```
and then remove any line(s) ending in "allow" (before the first `##` comment)
@ -193,37 +193,37 @@ integers on the target VM and returns back the result to the invoking VM.
* Client code on source VM (`/usr/bin/our_test_add_client`)
```bash
#!/bin/sh
echo $1 $2 # pass data to rpc server
exec cat >&$SAVED_FD_1 # print result to the original stdout, not to the other rpc endpoint
```
```bash
#!/bin/sh
echo $1 $2 # pass data to rpc server
exec cat >&$SAVED_FD_1 # print result to the original stdout, not to the other rpc endpoint
```
* Server code on target VM (`/usr/bin/our_test_add_server`)
```bash
#!/bin/sh
read arg1 arg2 # read from stdin, which is received from the rpc client
echo $(($arg1+$arg2)) # print to stdout - so, pass to the rpc client
```
```bash
#!/bin/sh
read arg1 arg2 # read from stdin, which is received from the rpc client
echo $(($arg1+$arg2)) # print to stdout - so, pass to the rpc client
```
* Policy file in dom0 (`/etc/qubes-rpc/policy/test.Add`)
```shell_session
$anyvm $anyvm ask
```
```shell_session
$anyvm $anyvm ask
```
* Server path definition on target VM (`/etc/qubes-rpc/test.Add`)
```
/usr/bin/our_test_add_server
```
```
/usr/bin/our_test_add_server
```
* To test this service, run the following in the source VM:
```
/usr/lib/qubes/qrexec-client-vm <target VM> test.Add /usr/bin/our_test_add_client 1 2
```
```
/usr/lib/qubes/qrexec-client-vm <target VM> test.Add /usr/bin/our_test_add_client 1 2
```
and we should get "3" as answer, provided dom0 policy allows the call to pass
through, which would happen after we click "Yes" in the popup that should

View File

@ -119,14 +119,14 @@ Each message starts with the following header:
```c
struct msghdr {
uint32_t type;
uint32_t window;
/* This field is intended for use by gui_agents to skip unknown
* messages from the (trusted) guid. Guid, on the other hand,
* should never rely on this field to calculate the actual len of
* message to be read, as the (untrusted) agent can put here
* whatever it wants! */
uint32_t untrusted_len;
uint32_t type;
uint32_t window;
/* This field is intended for use by gui_agents to skip unknown
* messages from the (trusted) guid. Guid, on the other hand,
* should never rely on this field to calculate the actual len of
* message to be read, as the (untrusted) agent can put here
* whatever it wants! */
uint32_t untrusted_len;
};
```
@ -412,8 +412,8 @@ struct msg_focus {
<td>MSG_WINDOW_FLAGS</td>
<td><pre>
struct msg_window_flags {
uint32_t flags_set;
uint32_t flags_unset;
uint32_t flags_set;
uint32_t flags_unset;
};
</pre> </td>
<td>Window state change confirmation</td>

View File

@ -46,13 +46,13 @@ The feature can be enabled on any network-providing qube, and will be propagated
To enable the `ipv6` feature use `qvm-features` tool and set the value to `1`. For example to enable it on `sys-net`, execute in dom0:
```
qvm-features sys-net ipv6 1
qvm-features sys-net ipv6 1
```
It is also possible to explicitly disable IPv6 support for some qubes, even if it is connected to IPv6-providing one. This can be done by setting `ipv6` feature to empty value:
```
qvm-features ipv4-only-qube ipv6 ''
qvm-features ipv4-only-qube ipv6 ''
```
This configuration is presented below - green qubes have IPv6 access, red one does not.

View File

@ -42,91 +42,91 @@ rationale in an
to the Qubes mailing lists:
```
Hello,
Hello,
A new Qubes Security Bulletin has been just released and is available here:
A new Qubes Security Bulletin has been just released and is available here:
https://github.com/QubesOS/qubes-secpack/blob/master/QSBs/qsb-013-2015.txt
https://github.com/QubesOS/qubes-secpack/blob/master/QSBs/qsb-013-2015.txt
As per the previous discussions about recent problems with verifying
digital signatures on messages sent to Google Groups (thanks to
automatic footer addition by Google), we have decided to change the way
we publish Qubes Security Bulletins, as well as other security-related
info pertinent to the Qubes Project.
As per the previous discussions about recent problems with verifying
digital signatures on messages sent to Google Groups (thanks to
automatic footer addition by Google), we have decided to change the way
we publish Qubes Security Bulletins, as well as other security-related
info pertinent to the Qubes Project.
Starting today, we will be maintain a Git repository -- "Qubes Security
Pack" -- which will contain all the QSBs released so far, all the keys,
warrant canaries [1], and potentially some additional info or
announcements (e.g. key revocations). The whole repo can be found here:
Starting today, we will be maintain a Git repository -- "Qubes Security
Pack" -- which will contain all the QSBs released so far, all the keys,
warrant canaries [1], and potentially some additional info or
announcements (e.g. key revocations). The whole repo can be found here:
https://github.com/QubesOS/qubes-secpack
https://github.com/QubesOS/qubes-secpack
Note that all the keys distributed there should be signed by Qubes
Master Key. The Master Key is also attached in the repo, but should
really be obtained/verified using a different channel.
Note that all the keys distributed there should be signed by Qubes
Master Key. The Master Key is also attached in the repo, but should
really be obtained/verified using a different channel.
Additionally, most of the files are signed by core Qubes
developers (currently by Marek and myself) via detached signatures as
well as git tag signatures.
Additionally, most of the files are signed by core Qubes
developers (currently by Marek and myself) via detached signatures as
well as git tag signatures.
The are several advantages of using Git to distribute all these information:
The are several advantages of using Git to distribute all these information:
1) Git repo is a collection of files, some of which can be detached GPG
signatures for other files and we can ensure all these files are
distributed together.
1) Git repo is a collection of files, some of which can be detached GPG
signatures for other files and we can ensure all these files are
distributed together.
2) Git makes it easy for people to clone and redistribute these
collection of files, as well as to easily host them and view on the Web.
2) Git makes it easy for people to clone and redistribute these
collection of files, as well as to easily host them and view on the Web.
3) Git provides for signed tags mechanisms which is another mean we
utilize to ensure integrity of the distributed files.
3) Git provides for signed tags mechanisms which is another mean we
utilize to ensure integrity of the distributed files.
A few words about the Warrant Canary which we've just introduced today,
and which can be seen here:
A few words about the Warrant Canary which we've just introduced today,
and which can be seen here:
https://github.com/QubesOS/qubes-secpack/blob/master/canaries/canary-001-2015.txt
https://github.com/QubesOS/qubes-secpack/blob/master/canaries/canary-001-2015.txt
Even though we're not providing any kind of services (such as e.g. email
hosting), that could be searched or tapped by authorities, there are
other possibilities that worry us [2], in the light of various recent
law "developments", such as those that might be coercing people to hand
over their private keys to authorities.
Even though we're not providing any kind of services (such as e.g. email
hosting), that could be searched or tapped by authorities, there are
other possibilities that worry us [2], in the light of various recent
law "developments", such as those that might be coercing people to hand
over their private keys to authorities.
Until we fully decentralize the root of trust for Qubes, something that
requires the move to deterministic builds [3], and so won't happen
very soon, the possibility of having to disclose any of the Qubes
signing keys to anybody might have pretty serious consequences for those
who decided to entrust Qubes with anything serious. And we would like to
somehow minimize these consequences with this canary thing.
Until we fully decentralize the root of trust for Qubes, something that
requires the move to deterministic builds [3], and so won't happen
very soon, the possibility of having to disclose any of the Qubes
signing keys to anybody might have pretty serious consequences for those
who decided to entrust Qubes with anything serious. And we would like to
somehow minimize these consequences with this canary thing.
Additionally the canary is a nice way of ensuring "freshness" of our
messaging to the community.
Additionally the canary is a nice way of ensuring "freshness" of our
messaging to the community.
Of course the canary doesn't solve all the problems. E.g. if my signing
keys were somehow stolen without our knowledge, it wouldn't help.
Neither it could help in case me being or becoming a miscreant. And
probably it doesn't address many other potential problems, which could
only be solved one day with a multi-signature scheme. But anyway, until
that time, this is the best we can do, I think.
Of course the canary doesn't solve all the problems. E.g. if my signing
keys were somehow stolen without our knowledge, it wouldn't help.
Neither it could help in case me being or becoming a miscreant. And
probably it doesn't address many other potential problems, which could
only be solved one day with a multi-signature scheme. But anyway, until
that time, this is the best we can do, I think.
And congrats to Jann for the very interesting clipboard attack (even
though mostly theoretical, still very cool)!
And congrats to Jann for the very interesting clipboard attack (even
though mostly theoretical, still very cool)!
Thanks,
joanna.
Thanks,
joanna.
--
The Qubes Security Team
https://www.qubes-os.org/doc/SecurityPage
--
The Qubes Security Team
https://www.qubes-os.org/doc/SecurityPage
[1] http://en.wikipedia.org/wiki/Warrant_canary
[1] http://en.wikipedia.org/wiki/Warrant_canary
[2] Especially myself, because I'm currently the Root Of Trust for all
Qubes binaries :/
[2] Especially myself, because I'm currently the Root Of Trust for all
Qubes binaries :/
[3] Deterministic builds are required because it's the only way we can
implement multiple signature scheme for distributed binaries.
[3] Deterministic builds are required because it's the only way we can
implement multiple signature scheme for distributed binaries.
```

View File

@ -32,13 +32,17 @@ Inside the TemplateBasedVM.
1. Make sure folder `/rw/config/qubes-bind-dirs.d` exists.
sudo mkdir -p /rw/config/qubes-bind-dirs.d
```
sudo mkdir -p /rw/config/qubes-bind-dirs.d
```
2. Create a file `/rw/config/qubes-bind-dirs.d/50_user.conf` with root rights.
3. Edit the file 50_user.conf to append a folder or file name to the `binds` variable.
binds+=( '/var/lib/tor' )
```
binds+=( '/var/lib/tor' )
```
4. Save.

View File

@ -73,9 +73,11 @@ state of the system with the administrator's configuration/desires.
The smallest unit of configuration is a state.
A state is written in YAML and looks like this:
stateid:
cmd.run: #this is the execution module. in this case it will execute a command on the shell
- name: echo 'hello world' #this is a parameter of the state.
```
stateid:
cmd.run: #this is the execution module. in this case it will execute a command on the shell
- name: echo 'hello world' #this is a parameter of the state.
```
The stateid has to be unique throughout all states running for a minion and can
be used to order the execution of the references state.
@ -96,24 +98,26 @@ With these three states you can define most of the configuration of a VM.
You can also [order the execution][salt-doc-states-order] of your states:
D:
cmd.run:
- name: echo 1
- order: last
C:
cmd.run:
- name: echo 1
B:
cmd.run:
- name: echo 1
- require:
- cmd: A
- require_in:
- cmd:C
A:
cmd.run:
- name: echo 1
- order: 1
```
D:
cmd.run:
- name: echo 1
- order: last
C:
cmd.run:
- name: echo 1
B:
cmd.run:
- name: echo 1
- require:
- cmd: A
- require_in:
- cmd:C
A:
cmd.run:
- name: echo 1
- order: 1
```
The order of execution will be `A, B, C, D`.
The official documentation has more details on the
@ -132,10 +136,12 @@ After you have several state files, you need something to assign them to a VM.
This is done by `*.top` files ([official documentation][salt-doc-top]).
Their structure looks like this:
environment:
target_matching_clause:
- statefile1
- folder2.statefile2
```
environment:
target_matching_clause:
- statefile1
- folder2.statefile2
```
In most cases, the environment will be called `base`.
The `target_matching_clause` will be used to select your minions (VMs).
@ -143,10 +149,12 @@ It can be either the name of a VM or a regular expression.
If you are using a regular expressions, you need to give Salt a hint you are
doing so:
environment:
^app-(work|(?!mail).*)$:
- match: pcre
- statefile
```
environment:
^app-(work|(?!mail).*)$:
- match: pcre
- statefile
```
For each target you can write a list of state files.
Each line is a path to a state file (without the `.sls` extension) relative to
@ -220,23 +228,25 @@ You can also use the `qubes` pillar module to select VMs with a particular
property (see below).
If you do so, then you need to pass additional arguments to the `qubesctl` tool:
usage: qubesctl [-h] [--show-output] [--force-color] [--skip-dom0]
[--targets TARGETS | --templates | --app | --all]
...
```
usage: qubesctl [-h] [--show-output] [--force-color] [--skip-dom0]
[--targets TARGETS | --templates | --app | --all]
...
positional arguments:
command Salt command to execute (e.g., state.highstate)
positional arguments:
command Salt command to execute (e.g., state.highstate)
optional arguments:
-h, --help show this help message and exit
--show-output Show output of management commands
--force-color Force color output, allow control characters from VM,
UNSAFE
--skip-dom0 Skip dom0 configuration (VM creation etc)
--targets TARGETS Coma separated list of VMs to target
--templates Target all templates
--app Target all AppVMs
--all Target all non-disposable VMs (TemplateVMs and AppVMs)
optional arguments:
-h, --help show this help message and exit
--show-output Show output of management commands
--force-color Force color output, allow control characters from VM,
UNSAFE
--skip-dom0 Skip dom0 configuration (VM creation etc)
--targets TARGETS Coma separated list of VMs to target
--templates Target all templates
--app Target all AppVMs
--all Target all non-disposable VMs (TemplateVMs and AppVMs)
```
To apply a state to all templates, call `qubesctl --templates state.highstate`.
@ -269,15 +279,17 @@ Beginning with Qubes 4.0 and after [QSB #45], we implemented two changes:
Let's start with a quick example:
my new and shiny VM:
qvm.present:
- name: salt-test # can be omitted when same as ID
- template: fedora-21
- label: yellow
- mem: 2000
- vcpus: 4
- flags:
- proxy
```
my new and shiny VM:
qvm.present:
- name: salt-test # can be omitted when same as ID
- template: fedora-21
- label: yellow
- mem: 2000
- vcpus: 4
- flags:
- proxy
```
It uses the Qubes-specific `qvm.present` state, which ensures that the domain is
present (if not, it creates it).
@ -297,9 +309,11 @@ As you will notice, the options are the same (or very similar) to those used in
This should be put in `/srv/salt/my-new-vm.sls` or another `.sls` file.
A separate `*.top` file should be also written:
base:
dom0:
- my-new-vm
```
base:
dom0:
- my-new-vm
```
**Note** The third line should contain the name of the previous state file,
without the `.sls` extension.
@ -322,15 +336,19 @@ Lets make sure that the `mc` package is installed in all templates.
Similar to the previous example, you need to create a state file
(`/srv/salt/mc-everywhere.sls`):
mc:
pkg.installed: []
```
mc:
pkg.installed: []
```
Then the appropriate top file (`/srv/salt/mc-everywhere.top`):
base:
qubes:type:template:
- match: pillar
- mc-everywhere
```
base:
qubes:type:template:
- match: pillar
- mc-everywhere
```
Now you need to enable the top file:
@ -354,27 +372,31 @@ As in the example above, it creates a domain and sets its properties.
You can set properties of an existing domain:
my preferences:
qvm.prefs:
- name: salt-test2
- netvm: sys-firewall
```
my preferences:
qvm.prefs:
- name: salt-test2
- netvm: sys-firewall
```
***Note*** The `name:` option will not change the name of a domain, it will only
be used to match a domain to apply the configurations to it.
### `qvm.service`
services in my domain:
qvm.service:
- name: salt-test3
- enable:
- service1
- service2
- disable:
- service3
- service4
- default:
- service5
```
services in my domain:
qvm.service:
- name: salt-test3
- enable:
- service1
- service2
- disable:
- service3
- service4
- default:
- service5
```
This enables, disables, or sets to default, services as in `qvm-service`.
@ -382,9 +404,11 @@ This enables, disables, or sets to default, services as in `qvm-service`.
Ensures the specified domain is running:
domain is running:
qvm.running:
- name: salt-test4
```
domain is running:
qvm.running:
- name: salt-test4
```
## Virtual Machine Formulae
@ -567,9 +591,11 @@ Having the `-p` flag is important when using a state with `cmd.run`.
If you install multiple templates you may encounter this error.
The solution is to shut down the updateVM between each install:
install template and shutdown updateVM:
cmd.run:
- name: sudo qubes-dom0-update -y fedora-24; qvm-shutdown {% raw %}{{ salt.cmd.run(qubes-prefs updateVM) }}{% endraw %}
```
install template and shutdown updateVM:
cmd.run:
- name: sudo qubes-dom0-update -y fedora-24; qvm-shutdown {% raw %}{{ salt.cmd.run(qubes-prefs updateVM) }}{% endraw %}
```
## Further Reading

View File

@ -30,10 +30,12 @@ When backing up dom0 using the Qubes backup tool (explained below), only the hom
Therefore, if there are files outside of the home directory you wish to save, you should copy them into the home directory prior to creating a backup.
Here is an example of how to back up Qubes config files and RPC policies:
$ mkdir -p ~/backup/etc/qubes/
$ cp -a /etc/qubes/* ~/backup/etc/qubes/
$ mkdir ~/backup/etc/qubes-rpc/
$ cp -a /etc/qubes-rpc/* ~/systemfiles/etc/qubes-rpc/
```
$ mkdir -p ~/backup/etc/qubes/
$ cp -a /etc/qubes/* ~/backup/etc/qubes/
$ mkdir ~/backup/etc/qubes-rpc/
$ cp -a /etc/qubes-rpc/* ~/systemfiles/etc/qubes-rpc/
```
To restore these files, move them from the restored directory in dom0's home back to their appropriate locations in `/etc/`.
Please note that any packages installed via the package manager in dom0 will not be backed up.

View File

@ -15,51 +15,53 @@ Passwordless Root Access in VMs
Background (`/etc/sudoers.d/qubes` in VM):
user ALL=(ALL) NOPASSWD: ALL
```
user ALL=(ALL) NOPASSWD: ALL
# WTF?! Have you lost your mind?!
#
# In Qubes VMs there is no point in isolating the root account from
# the user account. This is because all the user data is already
# accessible from the user account, so there is no direct benefit for
# the attacker if she could escalate to root (there is even no benefit
# in trying to install some persistent rootkits, as the VM's root
# filesystem modifications are lost upon each start of a VM).
#
# One might argue that some hypothetical attacks against the
# hypervisor or the few daemons/backends in Dom0 (so VM escape
# attacks) most likely would require root access in the VM to trigger
# the attack.
#
# That's true, but mere existence of such a bug in the hypervisor or
# Dom0 that could be exploited by a malicious VM, no matter whether
# requiring user, root, or even kernel access in the VM, would be
# FATAL. In such situation (if there was such a bug in Xen) there
# really is no comforting that: "oh, but the mitigating factor was
# that the attacker needed root in VM!" We're not M$, and we're not
# gonna BS our users that there are mitigating factors in that case,
# and for sure, root/user isolation is not a mitigating factor.
#
# Because, really, if somebody could find and exploit a bug in the Xen
# hypervisor -- as of 2016, there have been only three publicly disclosed
# exploitable bugs in the Xen hypervisor from a VM -- then it would be
# highly unlikely if that person couldn't also found a user-to-root
# escalation in VM (which as we know from history of UNIX/Linux
# happens all the time).
#
# At the same time allowing for easy user-to-root escalation in a VM
# is simply convenient for users, especially for update installation.
#
# Currently this still doesn't work as expected, because some idotic
# piece of software called PolKit uses own set of policies. We're
# planning to address this in Beta 2. (Why PolKit is an idiocy? Do a
# simple experiment: start 'xinput test' in one xterm, running as
# user, then open some app that uses PolKit and asks for root
# password, e.g. gpk-update-viewer -- observe how all the keystrokes
# with root password you enter into the "secure" PolKit dialog box can
# be seen by the xinput program...)
#
# joanna.
# WTF?! Have you lost your mind?!
#
# In Qubes VMs there is no point in isolating the root account from
# the user account. This is because all the user data is already
# accessible from the user account, so there is no direct benefit for
# the attacker if she could escalate to root (there is even no benefit
# in trying to install some persistent rootkits, as the VM's root
# filesystem modifications are lost upon each start of a VM).
#
# One might argue that some hypothetical attacks against the
# hypervisor or the few daemons/backends in Dom0 (so VM escape
# attacks) most likely would require root access in the VM to trigger
# the attack.
#
# That's true, but mere existence of such a bug in the hypervisor or
# Dom0 that could be exploited by a malicious VM, no matter whether
# requiring user, root, or even kernel access in the VM, would be
# FATAL. In such situation (if there was such a bug in Xen) there
# really is no comforting that: "oh, but the mitigating factor was
# that the attacker needed root in VM!" We're not M$, and we're not
# gonna BS our users that there are mitigating factors in that case,
# and for sure, root/user isolation is not a mitigating factor.
#
# Because, really, if somebody could find and exploit a bug in the Xen
# hypervisor -- as of 2016, there have been only three publicly disclosed
# exploitable bugs in the Xen hypervisor from a VM -- then it would be
# highly unlikely if that person couldn't also found a user-to-root
# escalation in VM (which as we know from history of UNIX/Linux
# happens all the time).
#
# At the same time allowing for easy user-to-root escalation in a VM
# is simply convenient for users, especially for update installation.
#
# Currently this still doesn't work as expected, because some idotic
# piece of software called PolKit uses own set of policies. We're
# planning to address this in Beta 2. (Why PolKit is an idiocy? Do a
# simple experiment: start 'xinput test' in one xterm, running as
# user, then open some app that uses PolKit and asks for root
# password, e.g. gpk-update-viewer -- observe how all the keystrokes
# with root password you enter into the "secure" PolKit dialog box can
# be seen by the xinput program...)
#
# joanna.
```
Below is a complete list of configuration made according to the above statement, with (not necessary complete) list of mechanisms depending on each of them: