1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mp.h>
#include <libsec.h>
#include <auth.h>
int debug, auth;
char *keyspec = "";
char *remotesys = "";
char *logfile = nil;
static int
reporter(char *fmt, ...)
{
va_list ap;
char buf[2000];
va_start(ap, fmt);
if(logfile){
vsnprint(buf, sizeof buf, fmt, ap);
syslog(0, logfile, "%s tls reports %s", remotesys, buf);
}else{
fprint(2, "%s: %s tls reports ", argv0, remotesys);
vfprint(2, fmt, ap);
fprint(2, "\n");
}
va_end(ap);
return 0;
}
void
usage(void)
{
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");
}
void
main(int argc, char *argv[])
{
TLSconn *conn;
char *cert;
int fd;
cert = 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;
case 'l':
logfile = EARGF(usage());
break;
case 'r':
remotesys = EARGF(usage());
break;
default:
usage();
}ARGEND
if(*argv == nil)
usage();
conn = (TLSconn*)mallocz(sizeof *conn, 1);
if(conn == nil)
sysfatal("out of memory");
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;
fd = tlsServer(0, conn);
if(fd < 0){
reporter("failed: %r");
exits(0);
}
if(debug)
reporter("open");
dup(fd, 0);
dup(fd, 1);
if(fd > 1)
close(fd);
exec(*argv, argv);
reporter("can't exec %s: %r", *argv);
exits("exec");
}
|