#include <bio.h>
#include <mp.h>
#include <libsec.h>
+#include <auth.h>
-enum{ BufSize = 8192 };
-
-char *remotesys, *logfile;
-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];
-}
+int debug, auth;
+char *keyspec = "";
+char *remotesys = "";
+char *logfile = nil;
static int
reporter(char *fmt, ...)
void
usage(void)
{
- fprint(2, "usage: tlssrv -c cert [-D] [-l logfile] [-r remotesys] [cmd args...]\n");
+ fprint(2, "usage: tlssrv [-D] -[aA] [-k keyspec]] [-c cert] [-l logfile] [-r remotesys] cmd [args...]\n");
fprint(2, " after auth/secretpem key.pem > /mnt/factotum/ctl\n");
exits("usage");
}
main(int argc, char *argv[])
{
TLSconn *conn;
- uchar buf[BufSize];
char *cert;
- int n, fd, clearfd;
+ int fd;
- debug = 0;
- remotesys = nil;
cert = nil;
- logfile = nil;
ARGBEGIN{
case 'D':
debug++;
break;
+ case 'a':
+ auth = 1;
+ break;
+ case 'A':
+ auth = -1; /* authenticate, but dont change user */
+ break;
+ case 'k':
+ keyspec = EARGF(usage());
+ break;
case 'c':
cert = EARGF(usage());
break;
usage();
}ARGEND
- if(cert == nil)
- sysfatal("no certificate specified");
- if(remotesys == nil)
- remotesys = "";
+ if(*argv == nil)
+ usage();
+
conn = (TLSconn*)mallocz(sizeof *conn, 1);
if(conn == nil)
sysfatal("out of memory");
- conn->chain = readcertchain(cert);
- if (conn->chain == nil)
- sysfatal("can't read certificate");
- conn->cert = conn->chain->pem;
- conn->certlen = conn->chain->pemlen;
- conn->chain = conn->chain->next;
+
+ if(auth){
+ AuthInfo *ai;
+
+ ai = auth_proxy(0, nil, "proto=p9any role=server %s", keyspec);
+ if(ai == nil)
+ sysfatal("auth_proxy: %r");
+
+ if(auth == 1)
+ if(auth_chuid(ai, nil) < 0)
+ sysfatal("auth_chuid: %r");
+
+ conn->pskID = "p9secret";
+ conn->psk = ai->secret;
+ conn->psklen = ai->nsecret;
+ }
+
+ if(cert){
+ conn->chain = readcertchain(cert);
+ if(conn->chain == nil)
+ sysfatal("%r");
+ conn->cert = conn->chain->pem;
+ conn->certlen = conn->chain->pemlen;
+ conn->chain = conn->chain->next;
+ }
+
+ if(conn->cert == nil && conn->psklen == 0)
+ sysfatal("no certificate or shared secret");
+
if(debug)
conn->trace = reporter;
- clearfd = 0;
- fd = 1;
- if(debug > 1)
- fd = dumper(fd);
- fd = tlsServer(fd, conn);
+ fd = tlsServer(0, conn);
if(fd < 0){
reporter("failed: %r");
exits(0);
}
- reporter("open");
-
- if(argc > 0){
- if(pipe(p) < 0)
- 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;
- }
- }
+ if(debug)
+ reporter("open");
- rfork(RFNOTEG);
- notify(death);
- switch(rfork(RFPROC)){
- case -1:
- sysfatal("can't fork");
- case 0:
- 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);
+ dup(fd, 0);
+ dup(fd, 1);
+ if(fd > 1)
+ close(fd);
+
+ exec(*argv, argv);
+ reporter("can't exec %s: %r", *argv);
+ exits("exec");
}