import: make aan (-p flag) work in ``backwards mode'' (-B)

in backwards mode, the roles of the aan filters need to be
reversed. add "-n address" option to import to override the
announce address for the aan server part (default tcp!*!0).
This commit is contained in:
cinap_lenrek 2014-08-14 00:11:14 +02:00
parent d8d26c7001
commit a67d18ccf1
3 changed files with 119 additions and 66 deletions

View file

@ -123,6 +123,11 @@ Push the
filter onto the connection to protect against filter onto the connection to protect against
temporary network outages. temporary network outages.
.TP .TP
.B -n
Specify announce string for
.IR aan (8)
filter when run in ``backwards'' mode.
.TP
.B -s \fIname .B -s \fIname
Post the connection's mountable file descriptor as Post the connection's mountable file descriptor as
.BI /srv/ name\fR. .BI /srv/ name\fR.

View file

@ -42,7 +42,6 @@ int qidcnt;
int qfreecnt; int qfreecnt;
int ncollision; int ncollision;
int netfd; /* initially stdin */
int srvfd = -1; int srvfd = -1;
int nonone = 1; int nonone = 1;
char *filterp; char *filterp;
@ -57,7 +56,7 @@ static char *anstring = "tcp!*!0";
char *netdir = "", *local = "", *remote = ""; char *netdir = "", *local = "", *remote = "";
int filter(int, char *); void filter(int, char *, char *);
void void
usage(void) usage(void)
@ -175,7 +174,7 @@ main(int argc, char **argv)
}ARGEND }ARGEND
USED(argc, argv); USED(argc, argv);
if(doauth){ if(na == nil && doauth){
/* /*
* We use p9any so we don't have to visit this code again, with the * We use p9any so we don't have to visit this code again, with the
* cost that this code is incompatible with the old world, which * cost that this code is incompatible with the old world, which
@ -233,7 +232,7 @@ main(int argc, char **argv)
rfork(RFNOTEG|RFREND); rfork(RFNOTEG|RFREND);
if(messagesize == 0){ if(messagesize == 0){
messagesize = iounit(netfd); messagesize = iounit(0);
if(messagesize == 0) if(messagesize == 0)
messagesize = 8192+IOHDRSZ; messagesize = 8192+IOHDRSZ;
} }
@ -259,7 +258,7 @@ main(int argc, char **argv)
strncpy(buf, srv, sizeof buf); strncpy(buf, srv, sizeof buf);
} }
else { else {
noteconn(netfd); noteconn(0);
buf[0] = 0; buf[0] = 0;
n = read(0, buf, sizeof(buf)-1); n = read(0, buf, sizeof(buf)-1);
if(n < 0) { if(n < 0) {
@ -286,7 +285,7 @@ main(int argc, char **argv)
fatal("open ack write"); fatal("open ack write");
ini = initial; ini = initial;
n = readn(netfd, initial, sizeof(initial)); n = readn(0, initial, sizeof(initial));
if(n == 0) if(n == 0)
fatal(nil); /* port scan or spurious open/close on exported /srv file (unmount) */ fatal(nil); /* port scan or spurious open/close on exported /srv file (unmount) */
if(n < sizeof(initial)) if(n < sizeof(initial))
@ -298,7 +297,7 @@ main(int argc, char **argv)
ini = nil; ini = nil;
p = buf; p = buf;
for(;;){ for(;;){
if((n = read(netfd, p, 1)) < 0) if((n = read(0, p, 1)) < 0)
fatal("can't read impo arguments: %r"); fatal("can't read impo arguments: %r");
if(n == 0) if(n == 0)
fatal("connection closed while reading arguments"); fatal("connection closed while reading arguments");
@ -345,10 +344,10 @@ main(int argc, char **argv)
if(ini != nil) if(ini != nil)
fatal("Protocol botch: old import"); fatal("Protocol botch: old import");
if(readn(netfd, key, 4) != 4) if(readn(0, key, 4) != 4)
fatal("can't read key part; %r"); fatal("can't read key part; %r");
if(write(netfd, key+12, 4) != 4) if(write(0, key+12, 4) != 4)
fatal("can't write key part; %r"); fatal("can't write key part; %r");
/* scramble into two secrets */ /* scramble into two secrets */
@ -357,26 +356,29 @@ main(int argc, char **argv)
mksecret(fromserversecret, digest+10); mksecret(fromserversecret, digest+10);
if(filterp != nil) if(filterp != nil)
netfd = filter(netfd, filterp); filter(0, filterp, na);
switch(encproto) { switch(encproto) {
case Encssl: case Encssl:
netfd = pushssl(netfd, ealgs, fromserversecret, fd = pushssl(0, ealgs, fromserversecret, fromclientsecret, nil);
fromclientsecret, nil); if(fd < 0)
fatal("can't establish ssl connection: %r");
if(fd != 0){
dup(fd, 0);
close(fd);
}
break; break;
case Enctls: case Enctls:
default: default:
fatal("Unsupported encryption protocol"); fatal("Unsupported encryption protocol");
} }
if(netfd < 0)
fatal("can't establish ssl connection: %r");
} }
else if(filterp != nil) { else if(filterp != nil) {
if(ini != nil) if(ini != nil)
fatal("Protocol botch: don't know how to deal with this"); fatal("Protocol botch: don't know how to deal with this");
netfd = filter(netfd, filterp); filter(0, filterp, na);
} }
dup(0, 1);
if(ai != nil) if(ai != nil)
auth_freeAI(ai); auth_freeAI(ai);
@ -386,7 +388,7 @@ main(int argc, char **argv)
*/ */
for(;;) { for(;;) {
r = getsbuf(); r = getsbuf();
while((n = localread9pmsg(netfd, r->buf, messagesize, ini)) == 0) while((n = localread9pmsg(0, r->buf, messagesize, ini)) == 0)
; ;
if(n < 0) if(n < 0)
fatal(nil); fatal(nil);
@ -456,7 +458,7 @@ reply(Fcall *r, Fcall *t, char *err)
if(data == nil) if(data == nil)
fatal(Enomem); fatal(Enomem);
n = convS2M(t, data, messagesize); n = convS2M(t, data, messagesize);
if(write(netfd, data, n) != n){ if(write(0, data, n) != n){
/* not fatal, might have got a note due to flush */ /* not fatal, might have got a note due to flush */
fprint(2, "exportfs: short write in reply: %r\n"); fprint(2, "exportfs: short write in reply: %r\n");
} }
@ -867,18 +869,18 @@ estrdup(char *s)
return t; return t;
} }
/* Network on fd1, mount driver on fd0 */ void
int filter(int fd, char *cmd, char *host)
filter(int fd, char *cmd)
{ {
char buf[128], devdir[40], *s, *file, *argv[16]; char addr[128], buf[256], *s, *file, *argv[16];
int p[2], lfd, len, argc; int lfd, p[2], len, argc;
if(host == nil){
/* Get a free port and post it to the client. */ /* Get a free port and post it to the client. */
if (announce(anstring, devdir) < 0) if (announce(anstring, addr) < 0)
fatal("filter: Cannot announce %s: %r", anstring); fatal("filter: Cannot announce %s: %r", anstring);
snprint(buf, sizeof(buf), "%s/local", devdir); snprint(buf, sizeof(buf), "%s/local", addr);
if ((lfd = open(buf, OREAD)) < 0) if ((lfd = open(buf, OREAD)) < 0)
fatal("filter: Cannot open %s: %r", buf); fatal("filter: Cannot open %s: %r", buf);
if ((len = read(lfd, buf, sizeof buf - 1)) < 0) if ((len = read(lfd, buf, sizeof buf - 1)) < 0)
@ -889,24 +891,42 @@ filter(int fd, char *cmd)
len = s - buf; len = s - buf;
if (write(fd, buf, len) != len) if (write(fd, buf, len) != len)
fatal("filter: cannot write port; %r"); fatal("filter: cannot write port; %r");
} else {
/* Read address string from connection */
if ((len = read(fd, buf, sizeof buf - 1)) < 0)
sysfatal("filter: cannot write port; %r");
buf[len] = '\0';
if ((s = strrchr(buf, '!')) == nil)
sysfatal("filter: illegally formatted port %s", buf);
strecpy(addr, addr+sizeof(addr), netmkaddr(host, "tcp", s+1));
strecpy(strrchr(addr, '!'), addr+sizeof(addr), s);
}
DEBUG(DFD, "filter: %s\n", addr);
snprint(buf, sizeof(buf), "%s", cmd); snprint(buf, sizeof(buf), "%s", cmd);
argc = tokenize(buf, argv, nelem(argv)-2); argc = tokenize(buf, argv, nelem(argv)-3);
if (argc == 0) if (argc == 0)
fatal("filter: empty command"); sysfatal("filter: empty command");
argv[argc++] = devdir;
if(host != nil)
argv[argc++] = "-c";
argv[argc++] = addr;
argv[argc] = nil; argv[argc] = nil;
file = argv[0]; file = argv[0];
if (s = strrchr(argv[0], '/')) if((s = strrchr(argv[0], '/')) != nil)
argv[0] = s+1; argv[0] = s+1;
if(pipe(p) < 0) if(pipe(p) < 0)
fatal("filter: pipe; %r"); sysfatal("pipe: %r");
switch(rfork(RFNOWAIT|RFPROC|RFMEM|RFFDG|RFREND)) { switch(rfork(RFNOWAIT|RFPROC|RFMEM|RFFDG|RFREND)) {
case -1: case -1:
fatal("filter: rfork; %r\n"); fatal("filter: rfork; %r\n");
case 0: case 0:
close(fd);
if (dup(p[0], 1) < 0) if (dup(p[0], 1) < 0)
fatal("filter: Cannot dup to 1; %r"); fatal("filter: Cannot dup to 1; %r");
if (dup(p[0], 0) < 0) if (dup(p[0], 0) < 0)
@ -920,7 +940,6 @@ filter(int fd, char *cmd)
close(p[0]); close(p[0]);
close(p[1]); close(p[1]);
} }
return fd;
} }
static void static void

View file

@ -21,6 +21,7 @@ char *filterp;
char *ealgs = "rc4_256 sha1"; char *ealgs = "rc4_256 sha1";
int encproto = Encnone; int encproto = Encnone;
char *aan = "/bin/aan"; char *aan = "/bin/aan";
char *anstring = "tcp!*!0";
AuthInfo *ai; AuthInfo *ai;
int debug; int debug;
int doauth = 1; int doauth = 1;
@ -140,6 +141,9 @@ main(int argc, char **argv)
case 'p': case 'p':
filterp = aan; filterp = aan;
break; break;
case 'n':
anstring = EARGF(usage());
break;
case 's': case 's':
srvpost = EARGF(usage()); srvpost = EARGF(usage());
break; break;
@ -214,7 +218,7 @@ main(int argc, char **argv)
mksecret(fromserversecret, digest+10); mksecret(fromserversecret, digest+10);
if (filterp) if (filterp)
fd = filter(fd, filterp, argv[0]); fd = filter(fd, filterp, backwards ? nil : argv[0]);
/* set up encryption */ /* set up encryption */
procsetname("pushssl"); procsetname("pushssl");
@ -223,7 +227,7 @@ main(int argc, char **argv)
sysfatal("can't establish ssl connection: %r"); sysfatal("can't establish ssl connection: %r");
} }
else if (filterp) else if (filterp)
fd = filter(fd, filterp, argv[0]); fd = filter(fd, filterp, backwards ? nil : argv[0]);
if(ai) if(ai)
auth_freeAI(ai); auth_freeAI(ai);
@ -372,17 +376,34 @@ void
usage(void) usage(void)
{ {
fprint(2, "usage: import [-abcC] [-A] [-E clear|ssl|tls] " fprint(2, "usage: import [-abcC] [-A] [-E clear|ssl|tls] "
"[-e 'crypt auth'|clear] [-k keypattern] [-p] [-z] host remotefs [mountpoint]\n"); "[-e 'crypt auth'|clear] [-k keypattern] [-p] [-n address ] [-z] host remotefs [mountpoint]\n");
exits("usage"); exits("usage");
} }
/* Network on fd1, mount driver on fd0 */
int int
filter(int fd, char *cmd, char *host) filter(int fd, char *cmd, char *host)
{ {
char addr[128], buf[256], *s, *file, *argv[16]; char addr[128], buf[256], *s, *file, *argv[16];
int p[2], len, argc; int lfd, p[2], len, argc;
if(host == nil){
/* Get a free port and post it to the client. */
if (announce(anstring, addr) < 0)
sysfatal("filter: Cannot announce %s: %r", anstring);
snprint(buf, sizeof(buf), "%s/local", addr);
if ((lfd = open(buf, OREAD)) < 0)
sysfatal("filter: Cannot open %s: %r", buf);
if ((len = read(lfd, buf, sizeof buf - 1)) < 0)
sysfatal("filter: Cannot read %s: %r", buf);
close(lfd);
buf[len] = '\0';
if ((s = strchr(buf, '\n')) != nil)
len = s - buf;
if (write(fd, buf, len) != len)
sysfatal("filter: cannot write port; %r");
} else {
/* Read address string from connection */
if ((len = read(fd, buf, sizeof buf - 1)) < 0) if ((len = read(fd, buf, sizeof buf - 1)) < 0)
sysfatal("filter: cannot write port; %r"); sysfatal("filter: cannot write port; %r");
buf[len] = '\0'; buf[len] = '\0';
@ -391,39 +412,47 @@ filter(int fd, char *cmd, char *host)
sysfatal("filter: illegally formatted port %s", buf); sysfatal("filter: illegally formatted port %s", buf);
strecpy(addr, addr+sizeof(addr), netmkaddr(host, "tcp", s+1)); strecpy(addr, addr+sizeof(addr), netmkaddr(host, "tcp", s+1));
strecpy(strrchr(addr, '!'), addr+sizeof(addr), s); strecpy(strrchr(addr, '!'), addr+sizeof(addr), s);
}
if(debug) if(debug)
fprint(2, "filter: remote %s\n", addr); fprint(2, "filter: %s\n", addr);
snprint(buf, sizeof(buf), "%s", cmd); snprint(buf, sizeof(buf), "%s", cmd);
argc = tokenize(buf, argv, nelem(argv)-2); argc = tokenize(buf, argv, nelem(argv)-3);
if (argc == 0) if (argc == 0)
sysfatal("filter: empty command"); sysfatal("filter: empty command");
if(host != nil)
argv[argc++] = "-c"; argv[argc++] = "-c";
argv[argc++] = addr; argv[argc++] = addr;
argv[argc] = nil; argv[argc] = nil;
file = argv[0]; file = argv[0];
if (s = strrchr(argv[0], '/')) if((s = strrchr(argv[0], '/')) != nil)
argv[0] = s+1; argv[0] = s+1;
if(pipe(p) < 0) if(pipe(p) < 0)
sysfatal("pipe: %r"); sysfatal("pipe: %r");
switch(rfork(RFNOWAIT|RFPROC|RFMEM|RFFDG)) { switch(rfork(RFNOWAIT|RFPROC|RFMEM|RFFDG|RFREND)) {
case -1: case -1:
sysfatal("filter: rfork; %r"); sysfatal("filter: rfork; %r\n");
case 0: case 0:
dup(p[0], 1); close(fd);
dup(p[0], 0); if (dup(p[0], 1) < 0)
sysfatal("filter: Cannot dup to 1; %r");
if (dup(p[0], 0) < 0)
sysfatal("filter: Cannot dup to 0; %r");
close(p[0]); close(p[0]);
close(p[1]); close(p[1]);
exec(file, argv); exec(file, argv);
sysfatal("filter: exec; %r"); sysfatal("filter: exec; %r");
default: default:
close(fd); dup(p[1], fd);
close(p[0]); close(p[0]);
close(p[1]);
} }
return p[1]; return fd;
} }
static void static void