diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2011-04-28 06:19:58 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2011-04-28 06:19:58 +0000 |
commit | fa9d7b6082456caf8e490d50bc5d343277a2c67b (patch) | |
tree | 42fa8b593e554f30357234384779ee406d23e311 /usr.bin/aucat/sock.c | |
parent | 7c46124c1f9b4e99b5ca7e36469b292d77b6663f (diff) |
Implement a new authentication method allowing aucat and midicat to
work over TCP, for instance, to expose the sound card of one machine
with other machines of the network.
The first client generates a 128-bit random number (aka the
session cookie), saves it in $HOME/.aucat_cookie and sends it to the
server. Successive clients load the cookie from $HOME/.aucat_cookie
and send it to the server but the server accepts only clients whose
cookie matches the session cookie. When all clients are gone, the
session is over, and another cookie could start a new session, and so
on.
TCP is enabled on the server with the new -L option, and on the client
side hostnames are specified with a new optional component in the
device name.
hints from damien, dlg and deraadt, tweaks from jmc
Diffstat (limited to 'usr.bin/aucat/sock.c')
-rw-r--r-- | usr.bin/aucat/sock.c | 73 |
1 files changed, 47 insertions, 26 deletions
diff --git a/usr.bin/aucat/sock.c b/usr.bin/aucat/sock.c index a8db9ec6793..74a6a156953 100644 --- a/usr.bin/aucat/sock.c +++ b/usr.bin/aucat/sock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sock.c,v 1.56 2011/04/16 11:24:18 ratchov Exp $ */ +/* $OpenBSD: sock.c,v 1.57 2011/04/28 06:19:57 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -93,15 +93,16 @@ struct ctl_ops ctl_sockops = { sock_quitreq }; -unsigned sock_sesrefs = 0; /* connections to the session */ -uid_t sock_sesuid; /* owner of the session */ +unsigned sock_sesrefs = 0; /* connections to the session */ +uint8_t sock_sescookie[AMSG_COOKIELEN]; /* owner of the session */ void sock_close(struct file *arg) { struct sock *f = (struct sock *)arg; - sock_sesrefs--; + if (f->pstate != SOCK_AUTH) + sock_sesrefs--; pipe_close(&f->pipe.file); if (f->dev) { dev_unref(f->dev); @@ -322,34 +323,13 @@ sock_new(struct fileops *ops, int fd) { struct aproc *rproc, *wproc; struct sock *f; - uid_t uid, gid; - - /* - * ensure that all connections belong to the same user, - * for privacy reasons. - * - * XXX: is there a portable way of doing this ? - */ - if (getpeereid(fd, &uid, &gid) < 0) { - close(fd); - return NULL; - } - if (sock_sesrefs == 0) { - /* start a new session */ - sock_sesuid = uid; - } else if (uid != sock_sesuid) { - /* session owned by another user, drop connection */ - close(fd); - return NULL; - } - sock_sesrefs++; f = (struct sock *)pipe_new(ops, fd, "sock"); if (f == NULL) { close(fd); return NULL; } - f->pstate = SOCK_HELLO; + f->pstate = SOCK_AUTH; f->mode = 0; f->opt = NULL; f->dev = NULL; @@ -980,6 +960,23 @@ sock_midiattach(struct sock *f) } int +sock_auth(struct sock *f) +{ + struct amsg_auth *p = &f->rmsg.u.auth; + + if (sock_sesrefs == 0) { + /* start a new session */ + memcpy(sock_sescookie, p->cookie, AMSG_COOKIELEN); + } else if (memcmp(sock_sescookie, p->cookie, AMSG_COOKIELEN) != 0) { + /* another session is active, drop connection */ + return 0; + } + sock_sesrefs++; + f->pstate = SOCK_HELLO; + return 1; +} + +int sock_hello(struct sock *f) { struct amsg_hello *p = &f->rmsg.u.hello; @@ -1320,6 +1317,30 @@ sock_execmsg(struct sock *f) f->rtodo = sizeof(struct amsg); f->rstate = SOCK_RMSG; break; + case AMSG_AUTH: +#ifdef DEBUG + if (debug_level >= 3) { + sock_dbg(f); + dbg_puts(": AUTH message\n"); + } +#endif + if (f->pstate != SOCK_AUTH) { +#ifdef DEBUG + if (debug_level >= 1) { + sock_dbg(f); + dbg_puts(": AUTH, bad state\n"); + } +#endif + aproc_del(f->pipe.file.rproc); + return 0; + } + if (!sock_auth(f)) { + aproc_del(f->pipe.file.rproc); + return 0; + } + f->rstate = SOCK_RMSG; + f->rtodo = sizeof(struct amsg); + break; case AMSG_HELLO: #ifdef DEBUG if (debug_level >= 3) { |