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

Let server listen on + client connect to unix domain socket #4

Open
TauPan opened this issue Apr 5, 2013 · 9 comments
Open

Let server listen on + client connect to unix domain socket #4

TauPan opened this issue Apr 5, 2013 · 9 comments

Comments

@TauPan
Copy link

TauPan commented Apr 5, 2013

A possible solution to the "security issue" mentioned in the README:

Since unix domain sockets are protected via unix file permissions, there's no further security measures needed.

The server should create and listen on a socket file, that belongs to the user running the window manager and should be created with restrictive file permissions (i.e. set umask accordingly).

The client should connect to that socket.

To make the code portable to machines with non-local filesystems, there should be a list of paths that is tried for socket creation/connect:

  • some subdirectory of $HOME, might fail for some remote filesystems
  • /tmp/$USER/, must be created first and checked for permissions

Also socket creation might be vulnerable to a race condition, which must be prevented in the server code.

Rough draft, I might try my hand at this when/if I find the time. First step is to figure out how to use unix-domain-sockets in racket.

Drawback of this approach is of course that client connections won't work across the network any more, but a proper authentication scheme would be needed for this, which imho is overkill for a window manager client.

I dimly remember sawfish uses unix-domain sockets, too, but it's been a long time since I used it.

@Metaxal
Copy link
Owner

Metaxal commented Apr 5, 2013

Interesting, thanks for the idea!

I guess it may be a simple matter of using sync' on anopen-input-file'
port, along with make-temporary-file' andfile-or-directory-permissions'.
With proper filenames, like 'rwind-socket-1', it should be possible to have
multiple connections on different sockets.

For race conditions, we can restrict to one connection for now, I don't
think that's currently a big deal (though in some cases multiple
connections can clearly be useful).

For network connection, clients should probably use an ssh tunnel, so I
think that's not a real problem, and that's even probably the "right" way
to do it. Connections are currently only local anyway, and I don't believe
it's necessary to change that.

Laurent

On Fri, Apr 5, 2013 at 4:38 PM, TauPan [email protected] wrote:

A possible solution to the "security issue" mentioned in the README:

Since unix domain sockets are protected via unix file permissions, there's
no further security measures needed.

The server should create and listen on a socket file, that belongs to the
user running the window manager and should be created with restrictive file
permissions (i.e. set umask accordingly).

The client should connect to that socket.

To make the code portable to machines with non-local filesystems, there
should be a list of paths that is tried for socket creation/connect:

  • some subdirectory of $HOME, might fail for some remote filesystems
  • /tmp/$USER/, must be created first and checked for permissions

Also socket creation might be vulnerable to a race condition, which must
be prevented in the server code.

Rough draft, I might try my hand at this when/if I find the time. First
step is to figure out how to use unix-domain-sockets in racket.

Drawback of this approach is of course that client connections won't work
across the network any more, but a proper authentication scheme would be
needed for this, which imho is overkill for a window manager client.

I dimly remember sawfish uses unix-domain sockets, too, but it's been a
long time since I used it.


Reply to this email directly or view it on GitHubhttps://github.com//issues/4
.

@TauPan
Copy link
Author

TauPan commented Apr 8, 2013

Thanks for your pointers, as I'm more familiar with the posix-api than the particular way racket wraps it!

I've been using scsh for posix programming a couple of years ago and found it very convenient, but I have to read up on the relevant parts of the racket api first.

With "race condition" I referred to the situation that a malicious local user could create and control a socket file with the correct filename before we do and thus hijack the window manager. This just has to be done according to best practice.

@Metaxal
Copy link
Owner

Metaxal commented Apr 8, 2013

On Mon, Apr 8, 2013 at 1:49 PM, TauPan [email protected] wrote:

Thanks for your pointers, as I'm more familiar with the posix-api than the
particular way racket wraps it!

I've been using scsh for posix programming a couple of years ago and found
it very convenient, but I have to read up on the relevant parts of the
racket api first.

Actually, it seems that the racket FFI will be needed here (I'm not really
familiar with unix domain sockets, though now a bit more than 3 days ago).
The client side should be quite similar to:
https://github.com/plt/racket/blob/master/collects/unstable/socket.rkt
(note for the future: this collection is unstable, so the link to the file
may change in the near future).
The server side needs to be implemented though.

With "race condition" I referred to the situation that a malicious local
user could create and control a socket file with the correct filename
before we do and thus hijack the window manager. This just has to be done
according to best practice.

Oh, right, of course.
One possibility: If the client and the server verify that the socket file
access right are user rw only, right after connection, do you think there
could still be a race condition? Probably putting it in the user dir before
trying other temporary paths could not harm though.

Laurent

@TauPan
Copy link
Author

TauPan commented Apr 9, 2013

Ok, I'll look into that collection you mentioned, should be helpful. (Sorry, I can't seem to reply quoted with this browser here.)

A little research (web + manual pages) seems to indicate that it's sufficient to create the socket file via bind(2) in a directory where only the user has write-access. So putting it somewhere inside $HOME is a good suggestion for most cases. (Is there XDG_VARDIR or something?).

Since some network filesystems (AFS, which I happen to use in one installation) don't support sockets, I'd like an RWIND_SOCKET variable in the environment as a workaround for those (rare) cases. (Similar to RXVT_SOCKET, see the rxvt manpage.)

Sounds sane and simple enough.

@Metaxal
Copy link
Owner

Metaxal commented Apr 17, 2013

Are you the one that just uploaded the racket-unix-sockets package on PLaneT?
http://planet.racket-lang.org/display.ss?package=racket-unix-sockets.plt&owner=shawnpresser

Anyway, it's just what we need.

For the environment variable, would it be not as good if this goes instead in a config file? (i.e., the rwind user's config file)

@TauPan
Copy link
Author

TauPan commented Apr 20, 2013

Are you the one that just uploaded the racket-unix-sockets package on > PLaneT?
http://planet.racket-lang.org/display.ss?package=racket-unix-sockets.plt&owner=shawnpresser

nope

Anyway, it's just what we need.

Cool, I was afraid that my first try at something like this would involve hacking at racket itself ;)

For the environment variable, would it be not as good if this goes instead in a config file? (i.e., the rwind user's config file)

Sure, if you prefer it that way.

I have some free time this weekend but this is competing with a couple other projects, so still don't hold your breath waiting for contributions.

@Metaxal
Copy link
Owner

Metaxal commented Apr 20, 2013

If it can be of any help, here's a gist to test the package in
client/mono-server style :
https://gist.github.com/Metaxal/5426707

The main problem here is that the server uses the accept function which
will not allow for breaks (see the comments in server.rkt).

I'm not sure then what to do next for that issue.

Laurent

On Sat, Apr 20, 2013 at 11:41 AM, TauPan [email protected] wrote:

Are you the one that just uploaded the racket-unix-sockets package on >
PLaneT?

http://planet.racket-lang.org/display.ss?package=racket-unix-sockets.plt&owner=shawnpresser

nope

Anyway, it's just what we need.

Cool, I was afraid that my first try at something like this would involve
hacking at racket itself ;)

For the environment variable, would it be not as good if this goes instead
in a config file? (i.e., the rwind user's config file)

Sure, if you prefer it that way.

I have some free time this weekend but this is competing with a couple
other projects, so still don't hold your breath waiting for contributions.


Reply to this email directly or view it on GitHubhttps://github.com//issues/4#issuecomment-16701409
.

@Metaxal
Copy link
Owner

Metaxal commented Apr 23, 2013

See also the discussion here:
https://groups.google.com/forum/#!msg/racket-users/LIXBfMlFPCY/3f2IpJi5TZsJ

In particular the use of scheme_fd_to_semaphore.
(and its documentation in raw format here:
https://github.com/plt/racket/blob/master/collects/scribblings/inside/ports.scrbl#L791
)

Just one thing remains: the double check in atomic mode that there is a
client to accept.

Laurent

On Sat, Apr 20, 2013 at 7:18 PM, Laurent [email protected] wrote:

If it can be of any help, here's a gist to test the package in
client/mono-server style :
https://gist.github.com/Metaxal/5426707

The main problem here is that the server uses the accept function which
will not allow for breaks (see the comments in server.rkt).

I'm not sure then what to do next for that issue.

Laurent

On Sat, Apr 20, 2013 at 11:41 AM, TauPan [email protected] wrote:

Are you the one that just uploaded the racket-unix-sockets package on >
PLaneT?

http://planet.racket-lang.org/display.ss?package=racket-unix-sockets.plt&owner=shawnpresser

nope

Anyway, it's just what we need.

Cool, I was afraid that my first try at something like this would involve
hacking at racket itself ;)

For the environment variable, would it be not as good if this goes
instead in a config file? (i.e., the rwind user's config file)

Sure, if you prefer it that way.

I have some free time this weekend but this is competing with a couple
other projects, so still don't hold your breath waiting for contributions.


Reply to this email directly or view it on GitHubhttps://github.com//issues/4#issuecomment-16701409
.

@TauPan
Copy link
Author

TauPan commented Apr 24, 2013

Ah... I was about to suggest that the filedescriptor was used in a non-blocking way (i.e. not via accept()), with the equivalent of select(3). It seems that scheme_fd_to_semaphore provides an appropriate scheme-y abstraction for that. (Again, I'm way more familiar with the underlying posix semantics than the customary way to encapsulate these things in scheme-implementations, if we can call still call racket an implementation of scheme.)

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

No branches or pull requests

2 participants