mirror of
https://github.com/QubesOS/qubes-doc.git
synced 2025-05-02 23:05:19 -04:00
Fix over indented code blocks
This commit is contained in:
parent
0824b2d196
commit
752f1d4ddc
16 changed files with 530 additions and 492 deletions
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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`).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue