tlssrv: fix this mess (thanks burnzez for reporting the issue)

tlsServer() closes the passed in fd, in our case fd=1 leaving it
with no std output which got occupied by pipe() filedescriptor
which it then closed after duping... a classic.

delete all this mess. theres no reason to fork() and copy traffic
on a pipe at all as tlsServer() gives us a perfectly valid filedescriptor.
just dup() and exec() and we'r done.
This commit is contained in:
cinap_lenrek 2015-02-17 06:54:19 +01:00
parent d99a4ed1b8
commit a55c2b2b81

View file

@ -4,84 +4,9 @@
#include <mp.h> #include <mp.h>
#include <libsec.h> #include <libsec.h>
enum{ BufSize = 8192 }; char *remotesys = "";
char *logfile = nil;
char *remotesys, *logfile; int debug = 0;
int debug, p[2];
void
death(void *, char *)
{
int pid;
close(0);
close(1);
close(p[1]);
pid = getpid();
postnote(PNGROUP, pid, "die");
postnote(PNGROUP, pid, "die");
postnote(PNGROUP, pid, "die");
_exits(0);
}
static void
dump(int fd, uchar *buf, int n, char *label)
{
Biobuf bout;
int i;
Binit(&bout, fd, OWRITE);
Bprint(&bout, "%s<%d>: ", label, n);
if(n > 64)
n = 64;
for(i = 0; i < n; i++)
Bprint(&bout, "%2.2x ", buf[i]);
Bprint(&bout, "\n");
Bterm(&bout);
}
static void
xfer(int from, int to, int cfd, char *label)
{
uchar buf[BufSize];
int n;
if(fork() == 0)
return;
close(cfd);
for(;;){
n = read(from, buf, sizeof(buf));
if(n <= 0){
fprint(2, "%s EOF\n", label);
close(to);
close(from);
death(nil, nil);
}
dump(2, buf, n, label);
n = write(to, buf, n);
if(n < 0){
fprint(2, "%s write err\n", label);
close(to);
close(from);
death(nil, nil);
}
}
}
static int
dumper(int fd)
{
int p[2];
if(pipe(p) < 0)
sysfatal("can't make pipe: %r");
xfer(fd, p[0], p[1], "read");
xfer(p[0], fd, p[1], "write");
close(p[0]);
return p[1];
}
static int static int
reporter(char *fmt, ...) reporter(char *fmt, ...)
@ -114,14 +39,10 @@ void
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
TLSconn *conn; TLSconn *conn;
uchar buf[BufSize];
char *cert; char *cert;
int n, fd, clearfd; int fd;
debug = 0;
remotesys = nil;
cert = nil; cert = nil;
logfile = nil;
ARGBEGIN{ ARGBEGIN{
case 'D': case 'D':
debug++; debug++;
@ -141,76 +62,33 @@ main(int argc, char *argv[])
if(cert == nil) if(cert == nil)
sysfatal("no certificate specified"); sysfatal("no certificate specified");
if(remotesys == nil)
remotesys = "";
conn = (TLSconn*)mallocz(sizeof *conn, 1); conn = (TLSconn*)mallocz(sizeof *conn, 1);
if(conn == nil) if(conn == nil)
sysfatal("out of memory"); sysfatal("out of memory");
conn->chain = readcertchain(cert); conn->chain = readcertchain(cert);
if(conn->chain == nil) if(conn->chain == nil)
sysfatal("can't read certificate"); sysfatal("can't read certificate %s", cert);
conn->cert = conn->chain->pem; conn->cert = conn->chain->pem;
conn->certlen = conn->chain->pemlen; conn->certlen = conn->chain->pemlen;
conn->chain = conn->chain->next; conn->chain = conn->chain->next;
if(debug) if(debug)
conn->trace = reporter; conn->trace = reporter;
clearfd = 0; fd = tlsServer(1, conn);
fd = 1;
if(debug > 1)
fd = dumper(fd);
fd = tlsServer(fd, conn);
if(fd < 0){ if(fd < 0){
reporter("failed: %r"); reporter("failed: %r");
exits(0); exits(0);
} }
reporter("open"); if(debug)
reporter("open");
if(argc > 0){ dup(fd, 0);
if(pipe(p) < 0) dup(fd, 1);
exits("pipe");
switch(fork()){
case 0:
close(fd);
dup(p[0], 0);
dup(p[0], 1);
close(p[1]);
close(p[0]);
exec(argv[0], argv);
reporter("can't exec %s: %r", argv[0]);
_exits("exec");
case -1:
exits("fork");
default:
close(p[0]);
clearfd = p[1];
break;
}
}
rfork(RFNOTEG); if(*argv == nil)
notify(death); *--argv = "/bin/cat";
switch(rfork(RFPROC)){
case -1: exec(*argv, argv);
sysfatal("can't fork"); reporter("can't exec %s: %r", *argv);
case 0: exits("exec");
for(;;){
n = read(clearfd, buf, BufSize);
if(n <= 0)
break;
if(write(fd, buf, n) != n)
break;
}
break;
default:
for(;;){
n = read(fd, buf, BufSize);
if(n <= 0)
break;
if(write(clearfd, buf, n) != n)
break;
}
break;
}
death(nil, nil);
} }