Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement request_service and some attendant changes #35

Closed
wants to merge 6 commits into from

Conversation

yomimono
Copy link
Contributor

This change implements a request_service function, which lets users request that a service run on their behalf on another VM. I believe it fixes #23 .

It requires some minor API-breaking changes in the Flow interface, which previously assumed that users would be operating in the client context only.

The signature for request_service may be a bit controversial as I don't see result types used elsewhere in the library; I'm happy to rework it to fit in better with other functions here if there's a specific signature that seems more sensible.

@linse and I implemented this to allow a unikernel to request dom0 to run a service on its behalf, and we've tested it only in that context. The protocol also allows domY to request a service run on domX (where X is not 0), and while this should work, we haven't tested it.

yomimono and others added 6 commits April 26, 2019 16:05
Co-authored-by: linse <sschirme@gmail.com>
Co-authored-by: linse <sschirme@gmail.com>
Co-authored-by: linse <sschirme@gmail.com>
Co-authored-by: linse <sschirme@gmail.com>
`request_service` implements the message flow described at
https://www.qubes-os.org/doc/qrexec3/#domy-invoke-execution-of-qubes-service-qubessomerpc-in-domx-and-pass-stdinstdout .
It allows applications to request that other VMs (including dom0) invoke
services on behalf of the application and provides functionality for
interacting with the remote service via the handler function.

Co-authored-by: linse <sschirme@gmail.com>
Previously, the Flow module assumed that the application using the RExec
module would be the client executing code on behalf of a remote server,
and therefore would always want to write to and read from the
same streams.  In the case where the RExec-using application has requested
that a service start, the application will instead be the server, so the
streams can no longer be assumed to be stdin/stdout as in the client
case.

This patch attempts to provide an interface for interacting with flows
on whichever stream is appropriate, for the use of both client and
server applications.

Co-authored-by: linse <sschirme@gmail.com>
@talex5
Copy link
Collaborator

talex5 commented Apr 27, 2019

This API doesn't make much sense to me. I may be misunderstanding the API or the protocol, but it seems to be trying to use the same API for both clients and servers. As I understand it, these roles are different.

A server can:

  • Read bytes from stdin.
  • Write bytes to stdout.
  • Write bytes to stderr.
  • Send an exit status.

A client can:

  • Write bytes to stdin.
  • Read tagged stdout/stderr values.
  • Read an exit status.

For the server-side API, we currently provide something similar to a normal Mirage FLOW, but extended with the ability to write to stderr.

For a client, we need something different. It can't just be a normal bidirectional flow extended to read stderr, because we can't control whether we receive data from stdout or stderr. It looks like this PR just throws an exception if you try to read stdout but the remote end sends stderr. It would be possible to provide a bi-directional flow that just sends stderr values to the log, but it's probably better to let the caller handle that.

The PR replaces the old server FLOW with 3 FLOWs (each with the same type): stdin, stdout and stderr. I don't believe this is useful. The point of a FLOW is that you can pass it to something that needs to read and write, but these flows are really unidirectional. e.g. a client can write to its stdin, but it would be an error to try to read from it.

It also tries to reuse the handler type for the client and server, but then has to provide a meaningless value for the user argument and ignore the return value.

I think it would make more sense to leave the existing RExec module as it is and create a new RExec_client with its own API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement doing qrexec calls
2 participants