begin standardizing markdown lineation of qrexec3 docs

This commit is contained in:
pierwill 2019-08-08 12:00:38 -05:00
parent cc0d62e2d4
commit bdffd0fa59

View File

@ -18,92 +18,68 @@ redirect_from:
# Command execution in VMs # # Command execution in VMs #
(*This page is about qrexec v3. For qrexec v2, see (*This page is about qrexec v3. For qrexec v2, see [here](/doc/qrexec2/).*)
[here](/doc/qrexec2/).*)
The **qrexec** framework is used by core Qubes components to implement The **qrexec** framework is used by core Qubes components to implement communication between domains.
communication between domains. Qubes domains are isolated by design, but Qubes domains are isolated by design, but there is a need for a mechanism to allow the administrative domain (dom0) to force command execution in another domain (VM).
there is a need for a mechanism to allow the administrative domain (dom0) to For instance, when user selects an application from the KDE menu, it should be started in the selected VM.
force command execution in another domain (VM). For instance, when user Also, it is often useful to be able to pass stdin/stdout/stderr from an application running in a VM to dom0 (and the other way around).
selects an application from the KDE menu, it should be started in the selected In specific circumstances, Qubes allows VMs to be initiators of such communications (so, for example, a VM can notify dom0 that there are updates available for it).
VM. Also, it is often useful to be able to pass stdin/stdout/stderr from an
application running in a VM to dom0 (and the other way around). In specific
circumstances, Qubes allows VMs to be initiators of such communications (so,
for example, a VM can notify dom0 that there are updates available for it).
## Qrexec basics ## ## Qrexec basics ##
Qrexec is built on top of vchan (a library providing data links between Qrexec is built on top of vchan (a library providing data links between VMs).
VMs). During domain creation a process named `qrexec-daemon` is started During domain creation a process named `qrexec-daemon` is started in dom0, and a process named `qrexec-agent` is started in the VM.
in dom0, and a process named `qrexec-agent` is started in the VM. They are They are connected over **vchan** channel.
connected over **vchan** channel. `qrexec-daemon` listens for connections `qrexec-daemon` listens for connections from dom0 utility named `qrexec-client`.
from dom0 utility named `qrexec-client`. Typically, the first thing that a Typically, the first thing that a `qrexec-client` instance does is to send a request to `qrexec-daemon` to start a process (let's name it `VMprocess`) with a given command line in a specified VM (`someVM`).
`qrexec-client` instance does is to send a request to `qrexec-daemon` to `qrexec-daemon` assigns unique vchan connection details and sends them both to `qrexec-client` (in dom0) and `qrexec-agent` (in `someVM`).
start a process (let's name it `VMprocess`) with a given command line in `qrexec-client` starts a vchan server which `qrexec-agent` connects to.
a specified VM (`someVM`). `qrexec-daemon` assigns unique vchan connection Since then, stdin/stdout/stderr from the VMprocess is passed via vchan between `qrexec-agent` and the `qrexec-client` process.
details and sends them both to `qrexec-client` (in dom0) and `qrexec-agent`
(in `someVM`). `qrexec-client` starts a vchan server which `qrexec-agent`
connects to. Since then, stdin/stdout/stderr from the VMprocess is passed
via vchan between `qrexec-agent` and the `qrexec-client` process.
So, for example, executing in dom0: So, for example, executing in dom0:
qrexec-client -d someVM user:bash qrexec-client -d someVM user:bash
allows to work with the remote shell. The string before the first allows to work with the remote shell.
semicolon specifies what user to run the command as. Adding `-e` on the The string before the first semicolon specifies what user to run the command as.
`qrexec-client` command line results in mere command execution (no data Adding `-e` on the `qrexec-client` command line results in mere command execution (no data passing), and `qrexec-client` exits immediately after sending the execution request and receiving status code from `qrexec-agent` (whether the process creation succeeded).
passing), and `qrexec-client` exits immediately after sending the execution There is also the `-l local_program` flag -- with it, `qrexec-client` passes stdin/stdout of the remote process to the (spawned for this purpose) `local_program`, not to its own stdin/stdout.
request and receiving status code from `qrexec-agent` (whether the process
creation succeeded). There is also the `-l local_program` flag -- with it,
`qrexec-client` passes stdin/stdout of the remote process to the (spawned
for this purpose) `local_program`, not to its own stdin/stdout.
The `qvm-run` command is heavily based on `qrexec-client`. It also takes care The `qvm-run` command is heavily based on `qrexec-client`.
of additional activities, e.g. starting the domain if it is not up yet and It also takes care of additional activities, e.g. starting the domain if it is not up yet and starting the GUI daemon.
starting the GUI daemon. Thus, it is usually more convenient to use `qvm-run`. Thus, it is usually more convenient to use `qvm-run`.
There can be almost arbitrary number of `qrexec-client` processes for a There can be almost arbitrary number of `qrexec-client` processes for a domain (so, connected to the same `qrexec-daemon`, same domain) -- their data is multiplexed independently.
domain (so, connected to the same `qrexec-daemon`, same domain) -- their Number of available vchan channels is the limiting factor here, it depends on the underlying hypervisor.
data is multiplexed independently. Number of available vchan channels is
the limiting factor here, it depends on the underlying hypervisor.
## Qubes RPC services ## ## Qubes RPC services ##
Some tasks (like inter-vm file copy) share the same rpc-like structure: Some tasks (like inter-vm file copy) share the same rpc-like structure: a process in one VM (say, file sender) needs to invoke and send/receive data to some process in other VM (say, file receiver).
a process in one VM (say, file sender) needs to invoke and send/receive Thus, the Qubes RPC framework was created, facilitating such actions.
data to some process in other VM (say, file receiver). Thus, the Qubes RPC
framework was created, facilitating such actions.
Obviously, inter-VM communication must be tightly controlled to prevent one Obviously, inter-VM communication must be tightly controlled to prevent one VM from taking control over other, possibly more privileged, VM.
VM from taking control over other, possibly more privileged, VM. Therefore Therefore the design decision was made to pass all control communication via dom0, that can enforce proper authorization.
the design decision was made to pass all control communication via dom0, Then, it is natural to reuse the already-existing qrexec framework.
that can enforce proper authorization. Then, it is natural to reuse the
already-existing qrexec framework.
Also, note that bare qrexec provides `VM <-> dom0` connectivity, but the Also, note that bare qrexec provides `VM <-> dom0` connectivity, but the command execution is always initiated by dom0.
command execution is always initiated by dom0. There are cases when VM needs There are cases when VM needs to invoke and send data to a command in dom0 (e.g. to pass information on newly installed `.desktop` files).
to invoke and send data to a command in dom0 (e.g. to pass information on Thus, the framework allows dom0 to be the rpc target as well.
newly installed `.desktop` files). Thus, the framework allows dom0 to be
the rpc target as well.
Thanks to the framework, RPC programs are very simple -- both rpc client Thanks to the framework, RPC programs are very simple -- both rpc client and server just use their stdin/stdout to pass data.
and server just use their stdin/stdout to pass data. The framework does all The framework does all the inner work to connect these processes to each other via `qrexec-daemon` and `qrexec-agent`.
the inner work to connect these processes to each other via `qrexec-daemon` Additionally, disposable VMs are tightly integrated -- rpc to a DisposableVM is identical to rpc to a normal domain, all one needs is to pass `$dispvm` as the remote domain name.
and `qrexec-agent`. Additionally, disposable VMs are tightly integrated --
rpc to a DisposableVM is identical to rpc to a normal domain, all one needs
is to pass `$dispvm` as the remote domain name.
## Qubes RPC administration ## ## Qubes RPC administration ##
(*TODO: fix for non-linux dom0*) (*TODO: fix for non-linux dom0*)
In dom0, there is a bunch of files in `/etc/qubes-rpc/policy` directory, In dom0, there is a bunch of files in `/etc/qubes-rpc/policy` directory, whose names describe the available rpc actions.
whose names describe the available rpc actions. Their content is the rpc Their content is the rpc access policy database.
access policy database. Currently defined actions are: Currently defined actions are:
qubes.ClipboardPaste qubes.ClipboardPaste
qubes.Filecopy qubes.Filecopy
@ -128,47 +104,31 @@ 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`, `$dispvm`, You can specify srcvm and destvm by name, or by one of `$anyvm`, `$dispvm`, `dom0` reserved keywords (note string `dom0` does not match the `$anyvm` pattern; all other names do).
`dom0` reserved keywords (note string `dom0` does not match the `$anyvm` Only `$anyvm` keyword makes sense in srcvm field (service calls from dom0 are currently always allowed, `$dispvm` means "new VM created for this particular request," so it is never a source of request).
pattern; all other names do). Only `$anyvm` keyword makes sense in srcvm Currently there is no way to specify source VM by type.
field (service calls from dom0 are currently always allowed, `$dispvm` Whenever a rpc request for action X is received, the first line in `/etc/qubes-rpc/policy/X` that match srcvm/destvm is consulted to determine whether to allow rpc, what user account the program should run in target VM under, and what VM to redirect the execution to.
means "new VM created for this particular request," so it is never a Note that if the request is redirected (`target=` parameter), policy action remains the same - even if there is another rule which would otherwise deny such request.
source of request). Currently there is no way to specify source VM by If the policy file does not exist, user is prompted to create one; if still there is no policy file after prompting, the action is denied.
type. Whenever a rpc request for action X is received, the first line in
`/etc/qubes-rpc/policy/X` that match srcvm/destvm is consulted to determine
whether to allow rpc, what user account the program should run in target VM
under, and what VM to redirect the execution to. Note that if the request is
redirected (`target=` parameter), policy action remains the same - even if
there is another rule which would otherwise deny such request. If the policy
file does not exist, user is prompted to create one; if still there is no
policy file after prompting, the action is denied.
In the target VM, the `/etc/qubes-rpc/RPC_ACTION_NAME` must exist, containing In the target VM, the `/etc/qubes-rpc/RPC_ACTION_NAME` must exist, containing the file name of the program that will be invoked, or being that program itself - in which case it must have executable permission set (`chmod +x`).
the file name of the program that will be invoked, or being that program itself
- in which case it must have executable permission set (`chmod +x`).
In the src VM, one should invoke the client via: In the src VM, one should invoke the client via:
/usr/lib/qubes/qrexec-client-vm target_vm_name RPC_ACTION_NAME rpc_client_path client arguments /usr/lib/qubes/qrexec-client-vm target_vm_name RPC_ACTION_NAME rpc_client_path client arguments
Note that only stdin/stdout is passed between rpc server and client -- Note that only stdin/stdout is passed between rpc server and client -- notably, no command line arguments are passed.
notably, no command line arguments are passed. Source VM name is specified by Source VM name is specified by `QREXEC_REMOTE_DOMAIN` environment variable.
`QREXEC_REMOTE_DOMAIN` environment variable. By default, stderr of client By default, stderr of client and server is logged to respective `/var/log/qubes/qrexec.XID` files.
and server is logged to respective `/var/log/qubes/qrexec.XID` files. It is also possible to call service without specific client program - in which case server stdin/out will be connected with the terminal:
It is also possible to call service without specific client program - in which
case server stdin/out will be connected with the terminal:
/usr/lib/qubes/qrexec-client-vm target_vm_name RPC_ACTION_NAME /usr/lib/qubes/qrexec-client-vm target_vm_name RPC_ACTION_NAME
Be very careful when coding and adding a new rpc service. Unless the Be very careful when coding and adding a new rpc service.
offered functionality equals full control over the target (it is the case Unless the offered functionality equals full control over the target (it is the case with e.g. `qubes.VMShell` action), any vulnerability in an rpc server can be fatal to Qubes security.
with e.g. `qubes.VMShell` action), any vulnerability in an rpc server can On the other hand, this mechanism allows to delegate processing of untrusted input to less privileged (or disposable) AppVMs, thus wise usage of it increases security.
be fatal to Qubes security. On the other hand, this mechanism allows to
delegate processing of untrusted input to less privileged (or disposable)
AppVMs, thus wise usage of it increases security.
For example, this command will run the `firefox` command in a DisposableVM based For example, this command will run the `firefox` command in a DisposableVM based on `work`:
on `work`:
``` ```
$ qvm-run --dispvm=work firefox $ qvm-run --dispvm=work firefox
@ -180,133 +140,95 @@ By contrast, consider this command:
$ qvm-run --dispvm=work --service qubes.StartApp+firefox $ qvm-run --dispvm=work --service qubes.StartApp+firefox
``` ```
This will look for a `firefox.desktop` file in a standard location in a This will look for a `firefox.desktop` file in a standard location in a DisposableVM based on `work`, then launch the application described by that file.
DisposableVM based on `work`, then launch the application described by that The practical difference is that the bare `qvm-run` command uses the `qubes.VMShell` service, which allows you to run an arbitrary command with arbitrary arguments, essentially providing full control over the target VM.
file. The practical difference is that the bare `qvm-run` command uses the By contrast, the `qubes.StartApp` service allows you to run only applications that are advertised in `/usr/share/applications` (or other standard locations) *without* control over the arguments, so giving a VM access to `qubes.StartApp` is much safer.
`qubes.VMShell` service, which allows you to run an arbitrary command with While there isn't much practical difference between the two commands above when starting an application from dom0 in Qubes 4.0, there is a significant security risk when launching applications from a domU (e.g., from a separate GUI domain).
arbitrary arguments, essentially providing full control over the target VM. By This is why `qubes.StartApp` uses our standard `qrexec` argument grammar to strictly filter the permissible grammar of the `Exec=` lines in `.desktop` files that are passed from untrusted domUs to dom0, thereby protecting dom0 from command injection by maliciously-crafted `.desktop` files.
contrast, the `qubes.StartApp` service allows you to run only applications that
are advertised in `/usr/share/applications` (or other standard locations)
*without* control over the arguments, so giving a VM access to `qubes.StartApp`
is much safer. While there isn't much practical difference between the two
commands above when starting an application from dom0 in Qubes 4.0, there is a
significant security risk when launching applications from a domU (e.g., from
a separate GUI domain). This is why `qubes.StartApp` uses our standard `qrexec`
argument grammar to strictly filter the permissible grammar of the `Exec=` lines
in `.desktop` files that are passed from untrusted domUs to dom0, thereby
protecting dom0 from command injection by maliciously-crafted `.desktop` files.
### Extra keywords available in Qubes 4.0 and later ### Extra keywords available in Qubes 4.0 and later
**This section is about a not-yet-released version, some details may change** **This section is about a not-yet-released version, some details may change**
In Qubes 4.0, target VM can be specified also as `$dispvm:DISP_VM`, which is In Qubes 4.0, target VM can be specified also as `$dispvm:DISP_VM`, which is very similar to `$dispvm` but forces using a particular VM (`DISP_VM`) as a base VM to be started as DisposableVM.
very similar to `$dispvm` but forces using a particular VM (`DISP_VM`) as a base For example:
VM to be started as DisposableVM. For example:
anon-whonix $dispvm:anon-whonix-dvm allow anon-whonix $dispvm:anon-whonix-dvm allow
Adding such policy itself will not force usage of this particular `DISP_VM` - Adding such policy itself will not force usage of this particular `DISP_VM` - it will only allow it when specified by the caller.
it will only allow it when specified by the caller. But `$dispvm:DISP_VM` can But `$dispvm:DISP_VM` can also be used as target in request redirection, so _it is possible_ to force particular `DISP_VM` usage, when caller didn't specify it:
also be used as target in request redirection, so _it is possible_ to force
particular `DISP_VM` usage, when caller didn't specify it:
anon-whonix $dispvm allow,target=$dispvm:anon-whonix-dvm anon-whonix $dispvm allow,target=$dispvm:anon-whonix-dvm
Note that without redirection, this rule would allow using default Disposable Note that without redirection, this rule would allow using default Disposable VM (`default_dispvm` VM property, which itself defaults to global `default_dispvm` property).
VM (`default_dispvm` VM property, which itself defaults to global Also note that the request will be allowed (`allow` action) even if there is no second rule allowing calls to `$dispvm:anon-whonix-dvm`, or even if there is a rule explicitly denying it.
`default_dispvm` property). This is because the redirection happens _after_ considering the action.
Also note that the request will be allowed (`allow` action) even if there is no
second rule allowing calls to `$dispvm:anon-whonix-dvm`, or even if
there is a rule explicitly denying it. This is because the redirection happens
_after_ considering the action.
In Qubes 4.0 there are also additional methods to specify source/target VM: In Qubes 4.0 there are also additional methods to specify source/target VM:
* `$tag:some-tag` - meaning a VM with tag `some-tag` * `$tag:some-tag` - meaning a VM with tag `some-tag`
* `$type:type` - meaning a VM of `type` (like `AppVM`, `TemplateVM` etc) * `$type:type` - meaning a VM of `type` (like `AppVM`, `TemplateVM` etc)
Target VM can be also specified as `$default`, which matches the case when Target VM can be also specified as `$default`, which matches the case when calling VM didn't specified any particular target (either by using `$default` target, or empty target).
calling VM didn't specified any particular target (either by using `$default`
target, or empty target).
In Qubes 4.0 policy confirmation dialog (`ask` action) allow the user to In Qubes 4.0 policy confirmation dialog (`ask` action) allow the user to specify target VM.
specify target VM. User can choose from VMs that, according to policy, would User can choose from VMs that, according to policy, would lead to `ask` or `allow` actions.
lead to `ask` or `allow` actions. It is not possible to select VM that policy It is not possible to select VM that policy would deny.
would deny. By default no VM is selected, even if the caller provided some, but By default no VM is selected, even if the caller provided some, but policy can specify default value using `default_target=` parameter.
policy can specify default value using `default_target=` parameter. For For example:
example:
work-mail work-archive allow work-mail work-archive allow
work-mail $tag:work ask,default_target=work-files work-mail $tag:work ask,default_target=work-files
work-mail $default ask,default_target=work-files work-mail $default ask,default_target=work-files
The first rule allow call from `work-mail` to `work-archive`, without any The first rule allow call from `work-mail` to `work-archive`, without any confirmation.
confirmation. The second rule will ask the user about calls from `work-mail` VM to any VM with tag `work`.
The second rule will ask the user about calls from `work-mail` VM to any VM with And the confirmation dialog will have `work-files` VM chosen by default, regardless of the VM specified by the caller (`work-mail` VM).
tag `work`. And the confirmation dialog will have `work-files` VM chosen by The third rule allow the caller to not specify target VM at all and let the user choose, still - from VMs with tag `work` (and `work-archive`, regardless of tag), and with `work-files` as default.
default, regardless of the VM specified by the caller (`work-mail` VM). The
third rule allow the caller to not specify target VM at all and let the user
choose, still - from VMs with tag `work` (and `work-archive`, regardless of
tag), and with `work-files` as default.
### Service argument in policy ### Service argument in policy
Sometimes just service name isn't enough to make reasonable qrexec policy. One Sometimes just service name isn't enough to make reasonable qrexec policy.
example of such a situation is [qrexec-based USB One example of such a situation is [qrexec-based USB passthrough](https://github.com/qubesos/qubes-issues/issues/531) - using just service name isn't possible to express the policy "allow access to device X and deny to others".
passthrough](https://github.com/qubesos/qubes-issues/issues/531) - using just It also isn't feasible to create a separate service for every device...
service name isn't possible to express the policy "allow access to device X and
deny to others". It also isn't feasible to create a separate service for every
device...
For this reason, starting with Qubes 3.2, it is possible to specify a service For this reason, starting with Qubes 3.2, it is possible to specify a service argument, which will be subject to policy.
argument, which will be subject to policy. Besides the above example of USB Besides the above example of USB passthrough, a service argument can make many service policies more fine-grained and easier to write precise policy with "allow" and "deny" actions, instead of "ask" (offloading additional decisions to the user).
passthrough, a service argument can make many service policies more fine-grained And generally the less choices the user must make, the lower the chance to make a mistake.
and easier to write precise policy with "allow" and "deny" actions, instead of
"ask" (offloading additional decisions to the user). And generally the less
choices the user must make, the lower the chance to make a mistake.
The syntax is simple: when calling a service, add an argument to the service name The syntax is simple: when calling a service, add an argument to the service name separated with `+` sign, for example:
separated with `+` sign, for example:
/usr/lib/qubes/qrexec-client-vm target_vm_name RPC_ACTION_NAME+ARGUMENT /usr/lib/qubes/qrexec-client-vm target_vm_name RPC_ACTION_NAME+ARGUMENT
Then create a policy as usual, including the argument Then create a policy as usual, including the argument (`/etc/qubes-rpc/policy/RPC_ACTION_NAME+ARGUMENT`).
(`/etc/qubes-rpc/policy/RPC_ACTION_NAME+ARGUMENT`). If the policy for the specific If the policy for the specific argument is not set (file does not exist), then the default policy for this service is loaded (`/etc/qubes-rpc/policy/RPC_ACTION_NAME`).
argument is not set (file does not exist), then the default policy for this service
is loaded (`/etc/qubes-rpc/policy/RPC_ACTION_NAME`).
In target VM (when the call is allowed) the service file will searched as: In target VM (when the call is allowed) the service file will searched as:
- `/etc/qubes-rpc/RPC_ACTION_NAME+ARGUMENT` - `/etc/qubes-rpc/RPC_ACTION_NAME+ARGUMENT`
- `/etc/qubes-rpc/RPC_ACTION_NAME` - `/etc/qubes-rpc/RPC_ACTION_NAME`
In any case, the script will receive `ARGUMENT` as its argument and additionally as In any case, the script will receive `ARGUMENT` as its argument and additionally as `QREXEC_SERVICE_ARGUMENT` environment variable.
`QREXEC_SERVICE_ARGUMENT` environment variable. This means it is also possible This means it is also possible to install a different script for a particular service argument.
to install a different script for a particular service argument.
See below for an example service using an argument. See below for an example service using an argument.
### Revoking "Yes to All" authorization ### ### Revoking "Yes to All" authorization ###
Qubes RPC policy supports "ask" action. This will prompt the user whether given Qubes RPC policy supports "ask" action.
RPC call should be allowed. That prompt window also has a "Yes to All" option, This will prompt the user whether given RPC call should be allowed.
which will allow the action and add a new entry to the policy file, which will That prompt window also has a "Yes to All" option, which will allow the action and add a new entry to the policy file, which will unconditionally allow further calls for the given service-srcVM-dstVM tuple.
unconditionally allow further calls for the given service-srcVM-dstVM tuple.
In order to remove such authorization, issue this command from a dom0 terminal In order to remove such authorization, issue this command from a dom0 terminal (for `qubes.Filecopy` service):
(for `qubes.Filecopy` service):
sudo nano /etc/qubes-rpc/policy/qubes.Filecopy sudo nano /etc/qubes-rpc/policy/qubes.Filecopy
and then remove the first line(s) (before the first `##` comment) which are and then remove the first line(s) (before the first `##` comment) which are the "Yes to All" results.
the "Yes to All" results.
### Qubes RPC example ### ### Qubes RPC example ###
We will show the necessary files to create an rpc call that adds two integers We will show the necessary files to create an rpc call that adds two integers on the target and returns back the result to the invoker.
on the target and returns back the result to the invoker.
* rpc client code (`/usr/bin/our_test_add_client`): * rpc client code (`/usr/bin/our_test_add_client`):
@ -334,17 +256,14 @@ on the target and returns back the result to the invoker.
and we should get "3" as answer, after dom0 allows it. and we should get "3" as answer, after dom0 allows it.
**Note:** For a real world example of writing a qrexec service, see this **Note:** For a real world example of writing a qrexec service, see this [blog post](https://blog.invisiblethings.org/2013/02/21/converting-untrusted-pdfs-into-trusted.html).
[blog post](https://blog.invisiblethings.org/2013/02/21/converting-untrusted-pdfs-into-trusted.html).
### Qubes RPC example - with argument usage ### ### Qubes RPC example - with argument usage ###
We will show the necessary files to create an rpc call that reads a specific file We will show the necessary files to create an rpc call that reads a specific file from a predefined directory on the target.
from a predefined directory on the target. Besides really naive storage, it may Besides really naive storage, it may be a very simple password manager.
be a very simple password manager. Additionally, in this example a simplified workflow will be used - server code placed directly in the service definition file (in `/etc/qubes-rpc` directory).
Additionally, in this example a simplified workflow will be used - server code And no separate client script will be used.
placed directly in the service definition file (in `/etc/qubes-rpc` directory). And
no separate client script will be used.
* rpc server code (*/etc/qubes-rpc/test.File*) * rpc server code (*/etc/qubes-rpc/test.File*)
@ -385,13 +304,11 @@ no separate client script will be used.
# Qubes RPC internals # # Qubes RPC internals #
(*This is about the implementation of qrexec v3. For the implementation of (*This is about the implementation of qrexec v3.
qrexec v2, see [here](/doc/qrexec2/#qubes-rpc-internals).*) For the implementation of qrexec v2, see [here](/doc/qrexec2/#qubes-rpc-internals).*)
Qrexec framework consists of a number of processes communicating with each Qrexec framework consists of a number of processes communicating with each other using common IPC protocol (described in detail below).
other using common IPC protocol (described in detail below). Components Components residing in the same domain (`qrexec-client-vm` to `qrexec-agent`, `qrexec-client` to `qrexec-daemon`) use pipes as the underlying transport medium, while components in separate domains (`qrexec-daemon` to `qrexec-agent`, data channel between `qrexec-agent`s) use vchan link.
residing in the same domain (`qrexec-client-vm` to `qrexec-agent`, `qrexec-client` to `qrexec-daemon`) use pipes as the underlying transport medium,
while components in separate domains (`qrexec-daemon` to `qrexec-agent`, data channel between `qrexec-agent`s) use vchan link.
Because of [vchan limitation](https://github.com/qubesos/qubes-issues/issues/951), it is not possible to establish qrexec connection back to the source domain. Because of [vchan limitation](https://github.com/qubesos/qubes-issues/issues/951), it is not possible to establish qrexec connection back to the source domain.
@ -457,16 +374,15 @@ by an optional data packet.
uint32_t len; /* data length */ uint32_t len; /* data length */
}; };
When two peers establish connection, the server sends `MSG_HELLO` followed by When two peers establish connection, the server sends `MSG_HELLO` followed by `peer_info` struct:
`peer_info` struct:
struct peer_info { struct peer_info {
uint32_t version; /* qrexec protocol version */ uint32_t version; /* qrexec protocol version */
}; };
The client then should reply with its own `MSG_HELLO` and `peer_info`. The The client then should reply with its own `MSG_HELLO` and `peer_info`.
lower of two versions define protocol used for this connection. If either side The lower of two versions define protocol used for this connection.
does not support this version, the connection is closed. If either side does not support this version, the connection is closed.
Details of all possible use cases and the messages involved are described below. Details of all possible use cases and the messages involved are described below.