Commit Graph

65 Commits

Author SHA1 Message Date
Marek Marczykowski-Górecki
4c47ce139e
qrexec: fix infinite loop when multiple services are waiting for GUI
Reported by @ctrlaltdel
Fixes QubesOS/qubes-issues#3433
2017-12-28 17:31:06 +01:00
Marek Marczykowski-Górecki
57d43430e1
qrexec: setup process environment when not using fork server
If fork server is used, proper environment is inherited from the
session. But in other case (like non-default user), it needs to be
created by qrexec-agent itself. PAM provide some variables, but not the
most basic: HOME, SHELL, USER, LOGNAME. Also process should be started
in user home directory (if available).

Fixes QubesOS/qubes-issues#3416
2017-12-22 01:14:19 +01:00
Olivier MEDOC
0b15761d69 archlinux: ship pam.d/qrexec as a replacement of using su 2017-10-23 08:09:34 +02:00
Marek Marczykowski-Górecki
6bf395022a
qrexec: use user shell instead of hardcoded /bin/sh
Fixes QubesOS/qubes-issues#3139
2017-10-02 05:14:50 +02:00
Marek Marczykowski-Górecki
1497b3b05b
qrexec: code style fix - use spaces for indentation 2017-10-02 05:14:49 +02:00
Marek Marczykowski-Górecki
b42c1880b0
Few more shellcheck warnings fixes/ignores 2017-09-30 05:05:34 +02:00
Marek Marczykowski-Górecki
9c839d789f
qubes-rpc: fix issues found by shellcheck
Most of them are missing quotes, `` -> $(), and -o/-a usage in
conditions. Also add few directives disabling checks where were too
verbose.
2017-09-30 04:45:31 +02:00
Marek Marczykowski-Górecki
c8140375fa
qrexec: add configurable waiting for session before starting service
Some services require GUI access. Make qrexec-agent handling this, based
on per-service configuration, instead of forcing every caller to call
qubes.WaitForSession service first. This is especially important for
Disposable VMs, because those are destroyed after a single service call.

This needs to be done in qrexec-agent (instead of service script, or
qubes-rpc-multiplexer), because agent will behave differently depending
on GUI session being available or not. Namely, will use
qrexec-fork-server (so the process will be a child of session leader),
or will open new session.

Service configuration lives in /etc/qubes/rpc-config/SERVICE_NAME, can
can contain 'key=value' entries (no space around '=' allowed). Currently
the only settings supported is 'wait-for-session', with value either '0'
or '1'.

QubesOS/qubes-issues#2974
2017-08-09 00:58:48 +02:00
Marek Marczykowski-Górecki
89cb419d9c
qrexec: start process in a login shell
Prepend "-" to shell name, to instruct it being a login shell. This way
shell will initialize environment, load /etc/profile etc.

Fixes QubesOS/qubes-issues#2903
2017-07-11 23:52:55 +02:00
Marek Marczykowski-Górecki
5179cbc751
qrexec: ship pam configuration for debian
Debian have different base pam config files to include than Fedora.

Fixes QubesOS/qubes-issues#2903
2017-07-11 20:21:46 +02:00
Marek Marczykowski-Górecki
3af55c5cb3
qrexec: use PAM directly instead of calling su to setup the session
Instead of calling 'su' to switch the user, use own implementation of
this. Thanks to PAM it's pretty simple. The main reason is to have
control over process waiting for session termination (to call
pam_close_sesion/pam_end). Especially we don't want it to keep std* fds
open, which would prevent qrexec-agent from receiving EOF when one of
them will be closed.
Also, this will preserve QREXEC_AGENT_PID environment variable.

Fixes QubesOS/qubes-issues#2851
2017-07-05 02:17:43 +02:00
Vincent Penquerc'h
f49042211b
core-agent-linux: misc const fixups
(cherry picked from commit 475421b2e2)
Apparently some of this commit got reverted during cleanup before
Qubes 3.0 release.
2017-07-05 01:18:07 +02:00
Marek Marczykowski-Górecki
6bddcfcb52
qrexec: do not shutdown stdout socket inherited from parent
When qrexec-client-vm is started with socket on its stdout and no local
process requested, it will try to shutdown(SHUT_WR) this socket when
remote process exists. This is wrong, because this socket may be still
needed by other processes (for example shell from where qrexec-client-vm
was called).
In such a case, simple close() should be used.
2017-06-21 11:21:41 +02:00
Marek Marczykowski-Górecki
ea0cd0fdc3
qrexec: fix reporting exit code in qrexec-client-vm
1. If local process is started, report its exit code, instaed of remote
one. To get remote exit code, simply start qrexec-client-vm without
third argument (and connect its stdin/stdout with the other process some
other way).

2. Report process terminated by signal.
Don't pretend that process terminated by signal finished successfuly.
Copy shell behaviour of reporting it as 128+signum.

3. Do not wait() for any child process, just the one we expect. In case
of qrexec-client-vm the child process is started differently and
wait()ing on it inside main loop would break its exit code reporting.

Fixes QubesOS/qubes-issues#2861
2017-06-21 11:21:40 +02:00
Marek Marczykowski-Górecki
d2aa21625c
qrexec: exit with code 126 when service request was refused
Exit code 1 is very common in all kind of programs, including qrexec
services, so it is hard to distinguish remote failure from service call
refusal. Use something from top of the range here (but not 127, as it is
commonly used to report "Command not found")

QubesOS/qubes-issues#2861
2017-06-21 11:21:40 +02:00
Marek Marczykowski-Górecki
6e8f0e1a61
qrexec: add service argument support
Fixes QubesOS/qubes-issues#1876
2016-03-27 04:30:44 +02:00
Marek Marczykowski-Górecki
73beddf78e
qrexec: unify service environment preparation
Always set QREXEC_AGENT_PID variable, setup SIGUSR1 handler. And do that
before starting child process to avoid race conditions.

Required for QubesOS/qubes-issues#
Fixes QubesOS/qubes-issues#1863
2016-03-21 13:23:34 +01:00
Marek Marczykowski-Górecki
b267e5c305
qrexec: write service stderr to both syslog and caller
In case of some services it makes much sense for caller to receive also
stderr in addition to stdout. For example:
 - qubes.VMShell (stderr required for salt-ssh over qrexec)
 - qubes.OpenInVM - especially when called to DispVM - otherwise
 diagnosing errors can be hard

And generally all sort of error reporting (the purpose of stderr). It
would ease debugging - instead of message "error occurred, check here and
there for more details", it could be "error occurred: the reason".

Fixes QubesOS/qubes-issues#1808
2016-03-05 12:51:07 +01:00
Marek Marczykowski-Górecki
823954c7f6
qrexec: use #define for protocol-specified strings
And optimize strlen() calls.
Those defines are in qrexec.h (as the rest of qrexec protocol).
2015-11-08 22:06:54 +01:00
Marek Marczykowski-Górecki
b6d4f5afbf
qrexec: add some comments, minor improvement in readability 2015-11-08 21:59:30 +01:00
Marek Marczykowski-Górecki
97a3793345
qrexec: implement buffered write to a child stdin
Implement one of TODOs left in the code. Without this buffering, it may
happen that qrexec-agent will hang waiting on write(2) to the child
process, while that child will do the same (try to write something to
the qrexec-agent), without reading its stdin. This would end up in a
deadlock.

Fixes QubesOS/qubes-issues#1347
2015-10-24 20:35:36 +02:00
Marek Marczykowski-Górecki
51e2d6d356
qrexec: make sure that all the pipes/sockets are closed on cleanup
This will ensure that the child process will receive info that the
connection is closed. Otherwise it could hang on write() or in some
cases read() - on its stdin/stdout.

Thanks @adrelanos for help with debugging.
2015-08-08 01:52:59 +02:00
Marek Marczykowski-Górecki
cc83b8d344
qrexec: fix exit code from qrexec-client-vm
It should be remote process exit code, not the local one.
Also do not 'return' from the middle of the look, just use 'break' to
execute common cleanup code (which will be introduced in next commit).
2015-08-07 21:36:49 +02:00
Marek Marczykowski-Górecki
52a1fee533 qrexec: do not show message about missing fork-sever - it isn't an error 2015-05-24 20:47:34 +02:00
Marek Marczykowski-Górecki
23a9512402 qrexec: prefer VM-local service file (if present) over default one
This will allow a service to be overridden per-VM.
2015-05-13 23:21:01 +02:00
Marek Marczykowski-Górecki
731ee3e09a qrexec: do not reset umask to 077 for every started process
This umask will be inherited by any process started directly by qrexec
(i.e. without help of fork-server).
2015-04-10 18:07:32 +02:00
Marek Marczykowski-Górecki
5c3ab559c6 Merge branch 'master' of git://github.com/woju/qubes-core-agent-linux 2015-03-31 22:25:23 +02:00
Marek Marczykowski-Górecki
74490b0b94 qrexec: try to recover from fork-server communication error
Simply forget about that connection, instead of waiting for further
messages. If that connection is no longer available, select would return
EBADF, which would cause qrexec-agent termination.
2015-03-29 15:43:21 +02:00
Wojtek Porczyk
6c0e567929 qubes-rpc-multiplexer: deprecate /etc/qubes_rpc, allow /usr/local
/usr/local resides in private.img, so it is possible to define per-appvm RPC

Also, with the upcoming 3.0 release support for old (R1) paths is
removed.
2015-03-21 01:48:06 +01:00
Marek Marczykowski-Górecki
c33565b001 qrexec: enable compiler optimization
Besides obvious profits, it also enables some additional compiler
warnings.
2015-03-20 12:06:33 +01:00
Marek Marczykowski-Górecki
b718747c09 qrexec: do not wait for local process if no one exists 2015-03-20 12:05:48 +01:00
Marek Marczykowski-Górecki
9fe45aeae5 qrexec: fix compile warning 2015-03-20 03:05:05 +01:00
Marek Marczykowski-Górecki
9a7b161c37 qrexec: move qrexec-client-vm to /usr/bin 2015-03-17 23:11:47 +01:00
Marek Marczykowski-Górecki
4b451ef680 qrexec: execute RPC service directly (without a shell) if it has executable bit set
This will allow to use some different shell/language for a service (for
example python).
2015-03-17 14:47:29 +01:00
Marek Marczykowski-Górecki
0f75603d6d qrexec: do not leak FDs to logger process
This would prevent qrexec from detecting EOF.
2015-03-17 14:46:53 +01:00
Marek Marczykowski-Górecki
a86d980ff4 qrexec: add option to use real stdin/out of qrexec-client-vm 2015-03-17 14:17:01 +01:00
Marek Marczykowski-Górecki
8f00bdb4a6 qrexec: process vchan data queue (esp MSG_EXIT_CODE) before sending anything
In case of remote process exit even when some messages are still
waiting, vchan connection can be already closed. If we try to send some
data in this case (for example stdout of local process), there will be
an error, which will terminate qrexec-client-vm/qrexec-agent child. So
first check vchan data (where could be MSG_EXIT_CODE queued) , then
local process.

There is still some race condition in this code - remote process could
exit just after we check vchan, but before we send some data. But this
is much less probable and in the worst case we only loose remote process
exit code.
2015-03-17 12:39:30 +01:00
Marek Marczykowski-Górecki
16c27fc409 qrexec: minor readability fix 2015-03-16 21:41:36 +01:00
Marek Marczykowski-Górecki
55e040cbef qrexec: do not break connection on duplicated SIGUSR1
Child process can request to use single socket for both stdin and
stdout by sending SIGUSR1 signal. If it does so twice or more, previous
code broke the connection by closing the socket.
2015-03-16 21:39:34 +01:00
Marek Marczykowski-Górecki
23fc3599e8 qrexec: better handle remote process termination
If remote end terminates without proper protocol finish
(MSG_DATA_EXIT_CODE), terminate also local part instead of waiting
indefinitely.
2015-03-16 21:37:59 +01:00
Marek Marczykowski-Górecki
4eb1d72aee qrexec: return remote process status as qrexec-client-vm exit code
This doesn't cover all the cases, because local process could want to
receive that value (currently it cant), but I can't think of any simple,
*compatible* way to pass it there.
2015-03-16 21:32:34 +01:00
Marek Marczykowski-Górecki
1aa05ebc36 qrexec: handle data vchan directly from qrexec-client-vm
This way qrexec-client-vm will have much more information, at least:
 - will know whether the service call was accepted or refused
 - potentially will know remote process exit code
This commit implements the first point - the local process will not be
started if service call was refused.
2015-03-16 21:10:25 +01:00
Marek Marczykowski-Górecki
203691fae0 qrexec: simplify makefile 2015-03-16 20:51:28 +01:00
Marek Marczykowski-Górecki
29f5709c53 qrexec: fork into background after setting up qrexec-fork-server socket
This allows qubes-session signalling dom0 when session is really ready.
2015-02-22 03:12:54 +01:00
Marek Marczykowski-Górecki
e43c43f7b5 qrexec: fix compile warning 2015-02-17 14:09:36 +01:00
Marek Marczykowski-Górecki
700c240d37 qrexec: add simple "fork server" to spawn new processes inside user session
This process should be started from user session (most likely
qubes-session). New processes (of that user) will be created as
children of that session making logind and such crap happy. This should
also solve problems with EOF transmission (no additional "su" process)
and prevent loading all the environment multiple times.
2015-02-17 04:18:34 +01:00
Marek Marczykowski-Górecki
4b5960daa3 qrexec: reorganise code for upcoming change
Move (qrexec-agent version of) do_exec to qrexec-agent.c, move
handle_handshake to qrexec-agent-data.c (common to all agent binaries).
Fix indentation (tabs -> spaces).
2015-02-17 04:06:19 +01:00
Marek Marczykowski-Górecki
c1cb78e0e8 qrexec: use sockets instead of pipes to communicate with child process
The main advantage is possible use of single socket for both stdin and
stdout. This is strictly required for using USBIP over qrexec.

For compatibility qrexec still creates three socket pairs (instead of
pipes) for stdin/out/err respectively. When qrexec-agent receives
SIGUSR1, it will close stdout socket and use stdin socket for both
directions.

Some additional work is needed here to actually allow child process to
send that signal - qrexec is running as root, but child as "user" in
most cases.
2015-02-17 01:36:09 +01:00
Marek Marczykowski-Górecki
48685938ff qrexec: register exec function
Update for shared libqrexec.so API (instead of statically linked one).
2014-11-19 15:34:34 +01:00
Marek Marczykowski-Górecki
b13844afe1 qrexec: new protocol - direct data vchan connections 2014-11-19 15:34:34 +01:00