ref: 673e3de9a2f59dbac9a845b2f28363b2bb9f0041
parent: b52598178143b1c4a154caec87037c3a717c3ddd
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Mar 7 16:01:28 EST 2016
implement aan support for rcpu
--- a/Makefile
+++ b/Makefile
@@ -5,6 +5,7 @@
OFILES=\
main.$O\
cpu.$O\
+ aan.$O\
readcons.$O\
secstore.$O\
latin1.$O\
--- /dev/null
+++ b/aan.c
@@ -1,0 +1,204 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include "drawterm.h"
+
+enum {
+ Hdrsz = 3*4,
+ Bufsize = 8*1024,
+};
+
+typedef struct Hdr Hdr;
+typedef struct Buf Buf;
+typedef struct Client Client;
+
+struct Hdr {
+ uchar nb[4]; // Number of data bytes in this message
+ uchar msg[4]; // Message number
+ uchar acked[4]; // Number of messages acked
+};
+
+struct Buf {
+ Hdr hdr;
+ uchar buf[Bufsize];
+
+ Buf *next;
+};
+
+struct Client {
+ QLock lk;
+
+ char *addr;
+ int netfd;
+ int pipefd;
+
+ int reader;
+ int writer;
+ int syncer;
+
+ long inmsg;
+ long outmsg;
+
+ Buf *unackedhead;
+ Buf **unackedtail;
+};
+
+static void
+reconnect(Client *c)
+{
+ Buf *b;
+ int n;
+
+ qlock(&c->lk);
+Again:
+ for(;;){
+ if(c->netfd >= 0){
+ close(c->netfd);
+ c->netfd = -1;
+ }
+ if((c->netfd = dial(c->addr,nil,nil,nil)) >= 0)
+ break;
+ sleep(1000);
+ }
+ for(b = c->unackedhead; b != nil; b = b->next){
+ n = GBIT32(b->hdr.nb);
+ PBIT32(b->hdr.acked, c->inmsg);
+ if(write(c->netfd, &b->hdr, Hdrsz) != Hdrsz
+ || write(c->netfd, b->buf, n) != n){
+ print("write error: %r\n");
+ goto Again;
+ }
+ }
+ qunlock(&c->lk);
+}
+
+static void
+aanwriter(void *arg)
+{
+ Client *c = (Client*)arg;
+ Buf *b;
+ int n;
+ long m;
+
+ for(;;){
+ b = malloc(sizeof(Buf));
+ if(b == nil)
+ break;
+ if((n = read(c->pipefd, b->buf, Bufsize)) < 0){
+ free(b);
+ break;
+ }
+
+ qlock(&c->lk);
+ m = c->outmsg++;
+ PBIT32(b->hdr.nb, n);
+ PBIT32(b->hdr.msg, m);
+ PBIT32(b->hdr.acked, c->inmsg);
+
+ b->next = nil;
+ if(c->unackedhead == nil)
+ c->unackedtail = &c->unackedhead;
+ *c->unackedtail = b;
+ c->unackedtail = &b->next;
+
+ if(c->netfd < 0
+ || write(c->netfd, &b->hdr, Hdrsz) != Hdrsz
+ || write(c->netfd, b->buf, n) != n){
+ qunlock(&c->lk);
+ break;
+ }
+ qunlock(&c->lk);
+
+ if(n == 0)
+ break;
+ }
+ close(c->pipefd);
+ c->pipefd = -1;
+}
+
+static void
+aansyncer(void *arg)
+{
+ Client *c = (Client*)arg;
+ Hdr hdr;
+
+ for(;;){
+ sleep(4000);
+ qlock(&c->lk);
+ if(c->netfd >= 0){
+ PBIT32(hdr.nb, 0);
+ PBIT32(hdr.acked, c->inmsg);
+ PBIT32(hdr.msg, -1);
+ write(c->netfd, &hdr, Hdrsz);
+ }
+ qunlock(&c->lk);
+ }
+}
+
+static void
+aanreader(void *arg)
+{
+ Client *c = (Client*)arg;
+ Buf *b, *x, **l;
+ long a, m;
+ int n;
+
+Restart:
+ b = mallocz(sizeof(Buf), 1);
+ for(;;){
+ if(readn(c->netfd, &b->hdr, Hdrsz) != Hdrsz)
+ break;
+ a = GBIT32(b->hdr.acked);
+ m = GBIT32(b->hdr.msg);
+ n = GBIT32(b->hdr.nb);
+ if(n > Bufsize)
+ break;
+
+ qlock(&c->lk);
+ l = &c->unackedhead;
+ for(x = c->unackedhead; x != nil; x = *l){
+ if(a >= GBIT32(x->hdr.msg)){
+ if((*l = x->next) == nil)
+ c->unackedtail = l;
+ free(x);
+ } else {
+ l = &x->next;
+ }
+ }
+ qunlock(&c->lk);
+
+ if(readn(c->netfd, b->buf, n) != n)
+ break;
+ if(m < c->inmsg)
+ continue;
+ c->inmsg++;
+ if(c->pipefd < 0)
+ return;
+ write(c->pipefd, b->buf, n);
+ }
+ free(b);
+ reconnect(c);
+ goto Restart;
+}
+
+int
+aanclient(char *addr)
+{
+ Client *c;
+ int pfd[2];
+
+ if(pipe(pfd) < 0)
+ sysfatal("pipe: %r");
+
+ c = mallocz(sizeof(Client), 1);
+ c->addr = addr;
+ c->netfd = -1;
+ c->pipefd = pfd[1];
+ c->inmsg = 0;
+ c->outmsg = 0;
+ reconnect(c);
+ c->writer = kproc("aanwriter", aanwriter, c);
+ c->reader = kproc("aanreader", aanreader, c);
+ c->syncer = kproc("aansyncer", aansyncer, c);
+ return pfd[0];
+}
--- a/cpu.c
+++ b/cpu.c
@@ -40,6 +40,7 @@
static int p9auth(int);
char *authserver;
+int aanfilter;
void
exits(char *s)
@@ -75,6 +76,79 @@
return 0;
}
+/*
+ * p9any authentication followed by tls-psk encryption
+ */
+static int
+p9authtls(int fd)
+{
+ AuthInfo *ai;
+ TLSconn *conn;
+
+ ai = p9any(fd);
+ if(ai == nil)
+ fatal(1, "can't authenticate");
+
+ conn = mallocz(sizeof(TLSconn), 1);
+ conn->pskID = "p9secret";
+ conn->psk = ai->secret;
+ conn->psklen = ai->nsecret;
+
+ fd = tlsClient(fd, conn);
+ if(fd < 0)
+ fatal(1, "tlsClient");
+
+ auth_freeAI(ai);
+ free(conn->sessionID);
+ free(conn);
+
+ return fd;
+}
+
+static int
+startaan(char *host, int fd)
+{
+ static char script[] =
+"~ $#netdir 1 || netdir=/net/tcp/clone\n"
+"netdir=`{basename -d $netdir} || exit\n"
+"<>$netdir/clone {\n"
+" netdir=$netdir/`{read} || exit\n"
+" >[3] $netdir/ctl {\n"
+" echo -n 'announce *!0' >[1=3]\n"
+" echo `{cat $netdir/local} || exit\n"
+" bind '#|' /mnt/aan || exit\n"
+" exec aan $netdir <>/mnt/aan/data1 >[1=0] >[2]/dev/null &\n"
+" }\n"
+"}\n"
+"<>/mnt/aan/data >[1=0] >[2]/dev/null {\n"
+" rfork n\n"
+" fn server {\n"
+" echo -n aanserver $netdir >/proc/$pid/args\n"
+" . <{n=`{read} && ! ~ $#n 0 && read -c $n} >[2=1]\n"
+" }\n"
+" rm -f /env/^'fn#aanserver'\n"
+" exec tlssrv -A /bin/rc -c server\n"
+" exit\n"
+"}\n";
+ char buf[128], *p, *na;
+ int n;
+
+ if(fprint(fd, "%7ld\n%s", strlen(script), script) < 0)
+ fatal(1, "sending aan script");
+ n = read(fd, buf, sizeof(buf)-1);
+ close(fd);
+
+ while(n > 0 && buf[n-1] == '\n') n--;
+ if(n <= 0) return -1;
+ buf[n] = 0;
+ if((p = strrchr(buf, '!')) != nil)
+ na = strdup(netmkaddr(host, "tcp", p+1));
+ else
+ na = strdup(buf);
+
+ return aanclient(na);
+}
+
void
rcpu(char *host)
{
@@ -84,13 +158,11 @@
"</dev/cons >/dev/cons >[2=1] aux/kbdfs -dq -m /mnt/term/dev\n"
"bind -q /mnt/term/dev/cons /dev/cons\n"
"</dev/cons >/dev/cons >[2=1] service=cpu exec rc -li\n";
- AuthInfo *ai;
- TLSconn *conn;
char *na;
int fd;
na = netmkaddr(host, "tcp", "17019");
- if((fd = dial(na, 0, 0, 0)) < 0)
+ if((fd = dial(na, nil, nil, nil)) < 0)
return;
/* provide /dev/kbd for kbdfs */
@@ -97,21 +169,15 @@
if(bind("#b", "/dev", MAFTER) < 0)
panic("bind #b: %r");
- ai = p9any(fd);
- if(ai == nil)
- fatal(1, "can't authenticate");
+ fd = p9authtls(fd);
+ if(aanfilter){
+ fd = startaan(host, fd);
+ if(fd < 0)
+ fatal(1, "startaan");
+ fd = p9authtls(fd);
+ }
+ memset(secstorebuf, 0, sizeof(secstorebuf)); /* forget secstore secrets */
- conn = mallocz(sizeof(TLSconn), 1);
- conn->pskID = "p9secret";
- conn->psk = ai->secret;
- conn->psklen = ai->nsecret;
-
- fd = tlsClient(fd, conn);
- if(fd < 0)
- fatal(1, "tlsClient");
-
- auth_freeAI(ai);
-
if(fprint(fd, "%7ld\n%s", strlen(script), script) < 0)
fatal(1, "sending script");
@@ -140,6 +206,9 @@
authserver = getenv("auth");
system = getenv("cpu");
ARGBEGIN{
+ case 'p':
+ aanfilter = 1;
+ break;
case 'a':
authserver = EARGF(usage());
break;
@@ -353,6 +422,7 @@
AuthInfo *ai;
ai = p9any(fd);
+ memset(secstorebuf, 0, sizeof(secstorebuf)); /* forget secstore secrets */
if(ai == nil)
return -1;
if(ealgs == nil)
@@ -628,8 +698,6 @@
u = user;
pass = findkey(&u, tr.authdom, proto);
- memset(secstorebuf, 0, sizeof(secstorebuf)); /* forget secstore secrets */
-
if(pass == nil)
again:
pass = getkey(u, tr.authdom, proto);
--- a/drawterm.h
+++ b/drawterm.h
@@ -12,3 +12,4 @@
extern char *getuser(void);
extern void cpumain(int, char**);
extern char *estrdup(char*);
+extern int aanclient(char*);
--- a/kern/devpipe.c
+++ b/kern/devpipe.c
@@ -313,8 +313,6 @@
Pipe *p;
USED(offset);
- if(!islo())
- print("pipewrite hi %lux\n", getcallerpc(&c));
if(waserror()) {
/* avoid notes when pipe is a mounted queue */
--- a/main.c
+++ b/main.c
@@ -73,10 +73,14 @@
char*
getkey(char *user, char *dom, char *proto)
{
- char buf[1024];
+ char buf[1024], *key;
snprint(buf, sizeof buf, "%s@%s %s password", user, dom, proto);
- return readcons(buf, nil, 1);
+ key = readcons(buf, nil, 1);
+ if(key != nil)
+ snprint(secstorebuf, sizeof(secstorebuf), "key proto=%q dom=%q user=%q !password=%q\n",
+ proto, dom, user, key);
+ return key;
}
char*