xref: /plan9-contrib/sys/src/cmd/unix/drawterm/cpu.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier /*
2*8ccd4a63SDavid du Colombier  * cpu.c - Make a connection to a cpu server
3*8ccd4a63SDavid du Colombier  *
4*8ccd4a63SDavid du Colombier  *	   Invoked by listen as 'cpu -R | -N service net netdir'
5*8ccd4a63SDavid du Colombier  *	    	   by users  as 'cpu [-h system] [-c cmd args ...]'
6*8ccd4a63SDavid du Colombier  */
7*8ccd4a63SDavid du Colombier 
8*8ccd4a63SDavid du Colombier #include <u.h>
9*8ccd4a63SDavid du Colombier #include <libc.h>
10*8ccd4a63SDavid du Colombier #include <auth.h>
11*8ccd4a63SDavid du Colombier #include <fcall.h>
12*8ccd4a63SDavid du Colombier #include <authsrv.h>
13*8ccd4a63SDavid du Colombier #include <libsec.h>
14*8ccd4a63SDavid du Colombier #include "args.h"
15*8ccd4a63SDavid du Colombier #include "drawterm.h"
16*8ccd4a63SDavid du Colombier 
17*8ccd4a63SDavid du Colombier #define Maxfdata 8192
18*8ccd4a63SDavid du Colombier #define MaxStr 128
19*8ccd4a63SDavid du Colombier 
20*8ccd4a63SDavid du Colombier static void	fatal(int, char*, ...);
21*8ccd4a63SDavid du Colombier static void	usage(void);
22*8ccd4a63SDavid du Colombier static void	writestr(int, char*, char*, int);
23*8ccd4a63SDavid du Colombier static int	readstr(int, char*, int);
24*8ccd4a63SDavid du Colombier static char	*rexcall(int*, char*, char*);
25*8ccd4a63SDavid du Colombier static char *keyspec = "";
26*8ccd4a63SDavid du Colombier static AuthInfo *p9any(int);
27*8ccd4a63SDavid du Colombier 
28*8ccd4a63SDavid du Colombier #define system csystem
29*8ccd4a63SDavid du Colombier static char	*system;
30*8ccd4a63SDavid du Colombier static int	cflag;
31*8ccd4a63SDavid du Colombier extern int	dbg;
32*8ccd4a63SDavid du Colombier 
33*8ccd4a63SDavid du Colombier static char	*srvname = "ncpu";
34*8ccd4a63SDavid du Colombier static char	*ealgs = "rc4_256 sha1";
35*8ccd4a63SDavid du Colombier 
36*8ccd4a63SDavid du Colombier /* message size for exportfs; may be larger so we can do big graphics in CPU window */
37*8ccd4a63SDavid du Colombier static int	msgsize = Maxfdata+IOHDRSZ;
38*8ccd4a63SDavid du Colombier 
39*8ccd4a63SDavid du Colombier /* authentication mechanisms */
40*8ccd4a63SDavid du Colombier static int	netkeyauth(int);
41*8ccd4a63SDavid du Colombier static int	netkeysrvauth(int, char*);
42*8ccd4a63SDavid du Colombier static int	p9auth(int);
43*8ccd4a63SDavid du Colombier static int	srvp9auth(int, char*);
44*8ccd4a63SDavid du Colombier 
45*8ccd4a63SDavid du Colombier char *authserver;
46*8ccd4a63SDavid du Colombier 
47*8ccd4a63SDavid du Colombier typedef struct AuthMethod AuthMethod;
48*8ccd4a63SDavid du Colombier struct AuthMethod {
49*8ccd4a63SDavid du Colombier 	char	*name;			/* name of method */
50*8ccd4a63SDavid du Colombier 	int	(*cf)(int);		/* client side authentication */
51*8ccd4a63SDavid du Colombier 	int	(*sf)(int, char*);	/* server side authentication */
52*8ccd4a63SDavid du Colombier } authmethod[] =
53*8ccd4a63SDavid du Colombier {
54*8ccd4a63SDavid du Colombier 	{ "p9",		p9auth,		srvp9auth,},
55*8ccd4a63SDavid du Colombier 	{ "netkey",	netkeyauth,	netkeysrvauth,},
56*8ccd4a63SDavid du Colombier //	{ "none",	noauth,		srvnoauth,},
57*8ccd4a63SDavid du Colombier 	{ nil,	nil}
58*8ccd4a63SDavid du Colombier };
59*8ccd4a63SDavid du Colombier AuthMethod *am = authmethod;	/* default is p9 */
60*8ccd4a63SDavid du Colombier 
61*8ccd4a63SDavid du Colombier char *p9authproto = "p9any";
62*8ccd4a63SDavid du Colombier 
63*8ccd4a63SDavid du Colombier int setam(char*);
64*8ccd4a63SDavid du Colombier 
65*8ccd4a63SDavid du Colombier void
66*8ccd4a63SDavid du Colombier exits(char *s)
67*8ccd4a63SDavid du Colombier {
68*8ccd4a63SDavid du Colombier 	print("\ngoodbye\n");
69*8ccd4a63SDavid du Colombier 	for(;;) osyield();
70*8ccd4a63SDavid du Colombier }
71*8ccd4a63SDavid du Colombier 
72*8ccd4a63SDavid du Colombier void
73*8ccd4a63SDavid du Colombier usage(void)
74*8ccd4a63SDavid du Colombier {
75*8ccd4a63SDavid du Colombier 	fprint(2, "usage: drawterm [-a authserver] [-c cpuserver] [-s secstore] [-u user]\n");
76*8ccd4a63SDavid du Colombier 	exits("usage");
77*8ccd4a63SDavid du Colombier }
78*8ccd4a63SDavid du Colombier int fdd;
79*8ccd4a63SDavid du Colombier 
80*8ccd4a63SDavid du Colombier int
81*8ccd4a63SDavid du Colombier mountfactotum(void)
82*8ccd4a63SDavid du Colombier {
83*8ccd4a63SDavid du Colombier 	int fd;
84*8ccd4a63SDavid du Colombier 
85*8ccd4a63SDavid du Colombier 	if((fd = dialfactotum()) < 0)
86*8ccd4a63SDavid du Colombier 		return -1;
87*8ccd4a63SDavid du Colombier 	if(sysmount(fd, -1, "/mnt/factotum", MREPL, "") < 0){
88*8ccd4a63SDavid du Colombier 		fprint(2, "mount factotum: %r\n");
89*8ccd4a63SDavid du Colombier 		return -1;
90*8ccd4a63SDavid du Colombier 	}
91*8ccd4a63SDavid du Colombier 	if((fd = open("/mnt/factotum/ctl", OREAD)) < 0){
92*8ccd4a63SDavid du Colombier 		fprint(2, "open /mnt/factotum/ctl: %r\n");
93*8ccd4a63SDavid du Colombier 		return -1;
94*8ccd4a63SDavid du Colombier 	}
95*8ccd4a63SDavid du Colombier 	close(fd);
96*8ccd4a63SDavid du Colombier 	return 0;
97*8ccd4a63SDavid du Colombier }
98*8ccd4a63SDavid du Colombier 
99*8ccd4a63SDavid du Colombier void
100*8ccd4a63SDavid du Colombier cpumain(int argc, char **argv)
101*8ccd4a63SDavid du Colombier {
102*8ccd4a63SDavid du Colombier 	char dat[MaxStr], buf[MaxStr], cmd[MaxStr], *err, *secstoreserver, *p, *s;
103*8ccd4a63SDavid du Colombier 	int fd, ms, data;
104*8ccd4a63SDavid du Colombier 
105*8ccd4a63SDavid du Colombier 	/* see if we should use a larger message size */
106*8ccd4a63SDavid du Colombier 	fd = open("/dev/draw", OREAD);
107*8ccd4a63SDavid du Colombier 	if(fd > 0){
108*8ccd4a63SDavid du Colombier 		ms = iounit(fd);
109*8ccd4a63SDavid du Colombier 		if(msgsize < ms+IOHDRSZ)
110*8ccd4a63SDavid du Colombier 			msgsize = ms+IOHDRSZ;
111*8ccd4a63SDavid du Colombier 		close(fd);
112*8ccd4a63SDavid du Colombier 	}
113*8ccd4a63SDavid du Colombier 
114*8ccd4a63SDavid du Colombier         user = getenv("USER");
115*8ccd4a63SDavid du Colombier         if(user == nil)
116*8ccd4a63SDavid du Colombier         	user = readcons("user", nil, 0);
117*8ccd4a63SDavid du Colombier 	secstoreserver = nil;
118*8ccd4a63SDavid du Colombier 	authserver = getenv("auth");
119*8ccd4a63SDavid du Colombier 	if(authserver == nil)
120*8ccd4a63SDavid du Colombier 		authserver = "auth";
121*8ccd4a63SDavid du Colombier 	system = getenv("cpu");
122*8ccd4a63SDavid du Colombier 	if(system == nil)
123*8ccd4a63SDavid du Colombier 		system = "cpu";
124*8ccd4a63SDavid du Colombier 	ARGBEGIN{
125*8ccd4a63SDavid du Colombier 	case 'a':
126*8ccd4a63SDavid du Colombier 		authserver = EARGF(usage());
127*8ccd4a63SDavid du Colombier 		break;
128*8ccd4a63SDavid du Colombier 	case 'c':
129*8ccd4a63SDavid du Colombier 		system = EARGF(usage());
130*8ccd4a63SDavid du Colombier 		break;
131*8ccd4a63SDavid du Colombier 	case 'd':
132*8ccd4a63SDavid du Colombier 		dbg++;
133*8ccd4a63SDavid du Colombier 		break;
134*8ccd4a63SDavid du Colombier 	case 'e':
135*8ccd4a63SDavid du Colombier 		ealgs = EARGF(usage());
136*8ccd4a63SDavid du Colombier 		if(*ealgs == 0 || strcmp(ealgs, "clear") == 0)
137*8ccd4a63SDavid du Colombier 			ealgs = nil;
138*8ccd4a63SDavid du Colombier 		break;
139*8ccd4a63SDavid du Colombier 	case 'C':
140*8ccd4a63SDavid du Colombier 		cflag++;
141*8ccd4a63SDavid du Colombier 		cmd[0] = '!';
142*8ccd4a63SDavid du Colombier 		cmd[1] = '\0';
143*8ccd4a63SDavid du Colombier 		while((p = ARGF()) != nil) {
144*8ccd4a63SDavid du Colombier 			strcat(cmd, " ");
145*8ccd4a63SDavid du Colombier 			strcat(cmd, p);
146*8ccd4a63SDavid du Colombier 		}
147*8ccd4a63SDavid du Colombier 		break;
148*8ccd4a63SDavid du Colombier 	case 'k':
149*8ccd4a63SDavid du Colombier 		keyspec = EARGF(usage());
150*8ccd4a63SDavid du Colombier 		break;
151*8ccd4a63SDavid du Colombier 	case 'u':
152*8ccd4a63SDavid du Colombier 		user = EARGF(usage());
153*8ccd4a63SDavid du Colombier 		break;
154*8ccd4a63SDavid du Colombier 	case 's':
155*8ccd4a63SDavid du Colombier 		secstoreserver = EARGF(usage());
156*8ccd4a63SDavid du Colombier 		break;
157*8ccd4a63SDavid du Colombier 	default:
158*8ccd4a63SDavid du Colombier 		usage();
159*8ccd4a63SDavid du Colombier 	}ARGEND;
160*8ccd4a63SDavid du Colombier 
161*8ccd4a63SDavid du Colombier 	if(argc != 0)
162*8ccd4a63SDavid du Colombier 		usage();
163*8ccd4a63SDavid du Colombier 
164*8ccd4a63SDavid du Colombier 	if(mountfactotum() < 0){
165*8ccd4a63SDavid du Colombier 		if(secstoreserver == nil)
166*8ccd4a63SDavid du Colombier 			secstoreserver = authserver;
167*8ccd4a63SDavid du Colombier 	        if(havesecstore(secstoreserver, user)){
168*8ccd4a63SDavid du Colombier 	                s = secstorefetch(secstoreserver, user, nil);
169*8ccd4a63SDavid du Colombier 	                if(s){
170*8ccd4a63SDavid du Colombier 	                        if(strlen(s) >= sizeof secstorebuf)
171*8ccd4a63SDavid du Colombier 	                                sysfatal("secstore data too big");
172*8ccd4a63SDavid du Colombier 	                        strcpy(secstorebuf, s);
173*8ccd4a63SDavid du Colombier 	                }
174*8ccd4a63SDavid du Colombier 	        }
175*8ccd4a63SDavid du Colombier 	}
176*8ccd4a63SDavid du Colombier 
177*8ccd4a63SDavid du Colombier 	if((err = rexcall(&data, system, srvname)))
178*8ccd4a63SDavid du Colombier 		fatal(1, "%s: %s", err, system);
179*8ccd4a63SDavid du Colombier 
180*8ccd4a63SDavid du Colombier 	/* Tell the remote side the command to execute and where our working directory is */
181*8ccd4a63SDavid du Colombier 	if(cflag)
182*8ccd4a63SDavid du Colombier 		writestr(data, cmd, "command", 0);
183*8ccd4a63SDavid du Colombier 	if(getcwd(dat, sizeof(dat)) == 0)
184*8ccd4a63SDavid du Colombier 		writestr(data, "NO", "dir", 0);
185*8ccd4a63SDavid du Colombier 	else
186*8ccd4a63SDavid du Colombier 		writestr(data, dat, "dir", 0);
187*8ccd4a63SDavid du Colombier 
188*8ccd4a63SDavid du Colombier 	/*
189*8ccd4a63SDavid du Colombier 	 *  Wait for the other end to execute and start our file service
190*8ccd4a63SDavid du Colombier 	 *  of /mnt/term
191*8ccd4a63SDavid du Colombier 	 */
192*8ccd4a63SDavid du Colombier 	if(readstr(data, buf, sizeof(buf)) < 0)
193*8ccd4a63SDavid du Colombier 		fatal(1, "waiting for FS: %r");
194*8ccd4a63SDavid du Colombier 	if(strncmp("FS", buf, 2) != 0) {
195*8ccd4a63SDavid du Colombier 		print("remote cpu: %s", buf);
196*8ccd4a63SDavid du Colombier 		exits(buf);
197*8ccd4a63SDavid du Colombier 	}
198*8ccd4a63SDavid du Colombier 
199*8ccd4a63SDavid du Colombier 	if(readstr(data, buf, sizeof buf) < 0)
200*8ccd4a63SDavid du Colombier 		fatal(1, "waiting for remote export: %r");
201*8ccd4a63SDavid du Colombier 	if(strcmp(buf, "/") != 0){
202*8ccd4a63SDavid du Colombier 		print("remote cpu: %s" , buf);
203*8ccd4a63SDavid du Colombier 		exits(buf);
204*8ccd4a63SDavid du Colombier 	}
205*8ccd4a63SDavid du Colombier 	write(data, "OK", 2);
206*8ccd4a63SDavid du Colombier 
207*8ccd4a63SDavid du Colombier 	/* Begin serving the gnot namespace */
208*8ccd4a63SDavid du Colombier 	exportfs(data, msgsize);
209*8ccd4a63SDavid du Colombier 	fatal(1, "starting exportfs");
210*8ccd4a63SDavid du Colombier }
211*8ccd4a63SDavid du Colombier 
212*8ccd4a63SDavid du Colombier void
213*8ccd4a63SDavid du Colombier fatal(int syserr, char *fmt, ...)
214*8ccd4a63SDavid du Colombier {
215*8ccd4a63SDavid du Colombier 	Fmt f;
216*8ccd4a63SDavid du Colombier 	char *str;
217*8ccd4a63SDavid du Colombier 	va_list arg;
218*8ccd4a63SDavid du Colombier 
219*8ccd4a63SDavid du Colombier 	fmtstrinit(&f);
220*8ccd4a63SDavid du Colombier 	fmtprint(&f, "cpu: ");
221*8ccd4a63SDavid du Colombier 	va_start(arg, fmt);
222*8ccd4a63SDavid du Colombier 	fmtvprint(&f, fmt, arg);
223*8ccd4a63SDavid du Colombier 	va_end(arg);
224*8ccd4a63SDavid du Colombier 	if(syserr)
225*8ccd4a63SDavid du Colombier 		fmtprint(&f, ": %r");
226*8ccd4a63SDavid du Colombier 	fmtprint(&f, "\n");
227*8ccd4a63SDavid du Colombier 	str = fmtstrflush(&f);
228*8ccd4a63SDavid du Colombier 	write(2, str, strlen(str));
229*8ccd4a63SDavid du Colombier 	exits(str);
230*8ccd4a63SDavid du Colombier }
231*8ccd4a63SDavid du Colombier 
232*8ccd4a63SDavid du Colombier char *negstr = "negotiating authentication method";
233*8ccd4a63SDavid du Colombier 
234*8ccd4a63SDavid du Colombier char bug[256];
235*8ccd4a63SDavid du Colombier 
236*8ccd4a63SDavid du Colombier char*
237*8ccd4a63SDavid du Colombier rexcall(int *fd, char *host, char *service)
238*8ccd4a63SDavid du Colombier {
239*8ccd4a63SDavid du Colombier 	char *na;
240*8ccd4a63SDavid du Colombier 	char dir[MaxStr];
241*8ccd4a63SDavid du Colombier 	char err[ERRMAX];
242*8ccd4a63SDavid du Colombier 	char msg[MaxStr];
243*8ccd4a63SDavid du Colombier 	int n;
244*8ccd4a63SDavid du Colombier 
245*8ccd4a63SDavid du Colombier 	na = netmkaddr(host, "tcp", "17010");
246*8ccd4a63SDavid du Colombier 	if((*fd = dial(na, 0, dir, 0)) < 0)
247*8ccd4a63SDavid du Colombier 		return "can't dial";
248*8ccd4a63SDavid du Colombier 
249*8ccd4a63SDavid du Colombier 	/* negotiate authentication mechanism */
250*8ccd4a63SDavid du Colombier 	if(ealgs != nil)
251*8ccd4a63SDavid du Colombier 		snprint(msg, sizeof(msg), "%s %s", am->name, ealgs);
252*8ccd4a63SDavid du Colombier 	else
253*8ccd4a63SDavid du Colombier 		snprint(msg, sizeof(msg), "%s", am->name);
254*8ccd4a63SDavid du Colombier 	writestr(*fd, msg, negstr, 0);
255*8ccd4a63SDavid du Colombier 	n = readstr(*fd, err, sizeof err);
256*8ccd4a63SDavid du Colombier 	if(n < 0)
257*8ccd4a63SDavid du Colombier 		return negstr;
258*8ccd4a63SDavid du Colombier 	if(*err){
259*8ccd4a63SDavid du Colombier 		werrstr(err);
260*8ccd4a63SDavid du Colombier 		return negstr;
261*8ccd4a63SDavid du Colombier 	}
262*8ccd4a63SDavid du Colombier 
263*8ccd4a63SDavid du Colombier 	/* authenticate */
264*8ccd4a63SDavid du Colombier 	*fd = (*am->cf)(*fd);
265*8ccd4a63SDavid du Colombier 	if(*fd < 0)
266*8ccd4a63SDavid du Colombier 		return "can't authenticate";
267*8ccd4a63SDavid du Colombier 	return 0;
268*8ccd4a63SDavid du Colombier }
269*8ccd4a63SDavid du Colombier 
270*8ccd4a63SDavid du Colombier void
271*8ccd4a63SDavid du Colombier writestr(int fd, char *str, char *thing, int ignore)
272*8ccd4a63SDavid du Colombier {
273*8ccd4a63SDavid du Colombier 	int l, n;
274*8ccd4a63SDavid du Colombier 
275*8ccd4a63SDavid du Colombier 	l = strlen(str);
276*8ccd4a63SDavid du Colombier 	n = write(fd, str, l+1);
277*8ccd4a63SDavid du Colombier 	if(!ignore && n < 0)
278*8ccd4a63SDavid du Colombier 		fatal(1, "writing network: %s", thing);
279*8ccd4a63SDavid du Colombier }
280*8ccd4a63SDavid du Colombier 
281*8ccd4a63SDavid du Colombier int
282*8ccd4a63SDavid du Colombier readstr(int fd, char *str, int len)
283*8ccd4a63SDavid du Colombier {
284*8ccd4a63SDavid du Colombier 	int n;
285*8ccd4a63SDavid du Colombier 
286*8ccd4a63SDavid du Colombier 	while(len) {
287*8ccd4a63SDavid du Colombier 		n = read(fd, str, 1);
288*8ccd4a63SDavid du Colombier 		if(n < 0)
289*8ccd4a63SDavid du Colombier 			return -1;
290*8ccd4a63SDavid du Colombier 		if(*str == '\0')
291*8ccd4a63SDavid du Colombier 			return 0;
292*8ccd4a63SDavid du Colombier 		str++;
293*8ccd4a63SDavid du Colombier 		len--;
294*8ccd4a63SDavid du Colombier 	}
295*8ccd4a63SDavid du Colombier 	return -1;
296*8ccd4a63SDavid du Colombier }
297*8ccd4a63SDavid du Colombier 
298*8ccd4a63SDavid du Colombier static int
299*8ccd4a63SDavid du Colombier readln(char *buf, int n)
300*8ccd4a63SDavid du Colombier {
301*8ccd4a63SDavid du Colombier 	int i;
302*8ccd4a63SDavid du Colombier 	char *p;
303*8ccd4a63SDavid du Colombier 
304*8ccd4a63SDavid du Colombier 	n--;	/* room for \0 */
305*8ccd4a63SDavid du Colombier 	p = buf;
306*8ccd4a63SDavid du Colombier 	for(i=0; i<n; i++){
307*8ccd4a63SDavid du Colombier 		if(read(0, p, 1) != 1)
308*8ccd4a63SDavid du Colombier 			break;
309*8ccd4a63SDavid du Colombier 		if(*p == '\n' || *p == '\r')
310*8ccd4a63SDavid du Colombier 			break;
311*8ccd4a63SDavid du Colombier 		p++;
312*8ccd4a63SDavid du Colombier 	}
313*8ccd4a63SDavid du Colombier 	*p = '\0';
314*8ccd4a63SDavid du Colombier 	return p-buf;
315*8ccd4a63SDavid du Colombier }
316*8ccd4a63SDavid du Colombier 
317*8ccd4a63SDavid du Colombier /*
318*8ccd4a63SDavid du Colombier  *  user level challenge/response
319*8ccd4a63SDavid du Colombier  */
320*8ccd4a63SDavid du Colombier static int
321*8ccd4a63SDavid du Colombier netkeyauth(int fd)
322*8ccd4a63SDavid du Colombier {
323*8ccd4a63SDavid du Colombier 	char chall[32];
324*8ccd4a63SDavid du Colombier 	char resp[32];
325*8ccd4a63SDavid du Colombier 
326*8ccd4a63SDavid du Colombier 	strecpy(chall, chall+sizeof chall, getuser());
327*8ccd4a63SDavid du Colombier 	print("user[%s]: ", chall);
328*8ccd4a63SDavid du Colombier 	if(readln(resp, sizeof(resp)) < 0)
329*8ccd4a63SDavid du Colombier 		return -1;
330*8ccd4a63SDavid du Colombier 	if(*resp != 0)
331*8ccd4a63SDavid du Colombier 		strcpy(chall, resp);
332*8ccd4a63SDavid du Colombier 	writestr(fd, chall, "challenge/response", 1);
333*8ccd4a63SDavid du Colombier 
334*8ccd4a63SDavid du Colombier 	for(;;){
335*8ccd4a63SDavid du Colombier 		if(readstr(fd, chall, sizeof chall) < 0)
336*8ccd4a63SDavid du Colombier 			break;
337*8ccd4a63SDavid du Colombier 		if(*chall == 0)
338*8ccd4a63SDavid du Colombier 			return fd;
339*8ccd4a63SDavid du Colombier 		print("challenge: %s\nresponse: ", chall);
340*8ccd4a63SDavid du Colombier 		if(readln(resp, sizeof(resp)) < 0)
341*8ccd4a63SDavid du Colombier 			break;
342*8ccd4a63SDavid du Colombier 		writestr(fd, resp, "challenge/response", 1);
343*8ccd4a63SDavid du Colombier 	}
344*8ccd4a63SDavid du Colombier 	return -1;
345*8ccd4a63SDavid du Colombier }
346*8ccd4a63SDavid du Colombier 
347*8ccd4a63SDavid du Colombier static int
348*8ccd4a63SDavid du Colombier netkeysrvauth(int fd, char *user)
349*8ccd4a63SDavid du Colombier {
350*8ccd4a63SDavid du Colombier 	return -1;
351*8ccd4a63SDavid du Colombier }
352*8ccd4a63SDavid du Colombier 
353*8ccd4a63SDavid du Colombier static void
354*8ccd4a63SDavid du Colombier mksecret(char *t, uchar *f)
355*8ccd4a63SDavid du Colombier {
356*8ccd4a63SDavid du Colombier 	sprint(t, "%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux",
357*8ccd4a63SDavid du Colombier 		f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7], f[8], f[9]);
358*8ccd4a63SDavid du Colombier }
359*8ccd4a63SDavid du Colombier 
360*8ccd4a63SDavid du Colombier /*
361*8ccd4a63SDavid du Colombier  *  plan9 authentication followed by rc4 encryption
362*8ccd4a63SDavid du Colombier  */
363*8ccd4a63SDavid du Colombier static int
364*8ccd4a63SDavid du Colombier p9auth(int fd)
365*8ccd4a63SDavid du Colombier {
366*8ccd4a63SDavid du Colombier 	uchar key[16];
367*8ccd4a63SDavid du Colombier 	uchar digest[SHA1dlen];
368*8ccd4a63SDavid du Colombier 	char fromclientsecret[21];
369*8ccd4a63SDavid du Colombier 	char fromserversecret[21];
370*8ccd4a63SDavid du Colombier 	int i;
371*8ccd4a63SDavid du Colombier 	AuthInfo *ai;
372*8ccd4a63SDavid du Colombier 
373*8ccd4a63SDavid du Colombier 	ai = p9any(fd);
374*8ccd4a63SDavid du Colombier 	if(ai == nil)
375*8ccd4a63SDavid du Colombier 		return -1;
376*8ccd4a63SDavid du Colombier 	memmove(key+4, ai->secret, ai->nsecret);
377*8ccd4a63SDavid du Colombier 	if(ealgs == nil)
378*8ccd4a63SDavid du Colombier 		return fd;
379*8ccd4a63SDavid du Colombier 
380*8ccd4a63SDavid du Colombier 	/* exchange random numbers */
381*8ccd4a63SDavid du Colombier 	for(i = 0; i < 4; i++)
382*8ccd4a63SDavid du Colombier 		key[i] = fastrand();
383*8ccd4a63SDavid du Colombier 	if(write(fd, key, 4) != 4)
384*8ccd4a63SDavid du Colombier 		return -1;
385*8ccd4a63SDavid du Colombier 	if(readn(fd, key+12, 4) != 4)
386*8ccd4a63SDavid du Colombier 		return -1;
387*8ccd4a63SDavid du Colombier 
388*8ccd4a63SDavid du Colombier 	/* scramble into two secrets */
389*8ccd4a63SDavid du Colombier 	sha1(key, sizeof(key), digest, nil);
390*8ccd4a63SDavid du Colombier 	mksecret(fromclientsecret, digest);
391*8ccd4a63SDavid du Colombier 	mksecret(fromserversecret, digest+10);
392*8ccd4a63SDavid du Colombier 
393*8ccd4a63SDavid du Colombier 	/* set up encryption */
394*8ccd4a63SDavid du Colombier 	i = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil);
395*8ccd4a63SDavid du Colombier 	if(i < 0)
396*8ccd4a63SDavid du Colombier 		werrstr("can't establish ssl connection: %r");
397*8ccd4a63SDavid du Colombier 	return i;
398*8ccd4a63SDavid du Colombier }
399*8ccd4a63SDavid du Colombier 
400*8ccd4a63SDavid du Colombier int
401*8ccd4a63SDavid du Colombier authdial(char *net, char *dom)
402*8ccd4a63SDavid du Colombier {
403*8ccd4a63SDavid du Colombier 	int fd;
404*8ccd4a63SDavid du Colombier 	fd = dial(netmkaddr(authserver, "tcp", "567"), 0, 0, 0);
405*8ccd4a63SDavid du Colombier 	//print("authdial %d\n", fd);
406*8ccd4a63SDavid du Colombier 	return fd;
407*8ccd4a63SDavid du Colombier }
408*8ccd4a63SDavid du Colombier 
409*8ccd4a63SDavid du Colombier static int
410*8ccd4a63SDavid du Colombier getastickets(Ticketreq *tr, char *trbuf, char *tbuf)
411*8ccd4a63SDavid du Colombier {
412*8ccd4a63SDavid du Colombier 	int asfd, rv;
413*8ccd4a63SDavid du Colombier 	char *dom;
414*8ccd4a63SDavid du Colombier 
415*8ccd4a63SDavid du Colombier 	dom = tr->authdom;
416*8ccd4a63SDavid du Colombier 	asfd = authdial(nil, dom);
417*8ccd4a63SDavid du Colombier 	if(asfd < 0)
418*8ccd4a63SDavid du Colombier 		return -1;
419*8ccd4a63SDavid du Colombier 	rv = _asgetticket(asfd, trbuf, tbuf);
420*8ccd4a63SDavid du Colombier 	close(asfd);
421*8ccd4a63SDavid du Colombier 	return rv;
422*8ccd4a63SDavid du Colombier }
423*8ccd4a63SDavid du Colombier 
424*8ccd4a63SDavid du Colombier static int
425*8ccd4a63SDavid du Colombier mkserverticket(Ticketreq *tr, char *authkey, char *tbuf)
426*8ccd4a63SDavid du Colombier {
427*8ccd4a63SDavid du Colombier 	int i;
428*8ccd4a63SDavid du Colombier 	Ticket t;
429*8ccd4a63SDavid du Colombier 
430*8ccd4a63SDavid du Colombier 	if(strcmp(tr->authid, tr->hostid) != 0)
431*8ccd4a63SDavid du Colombier 		return -1;
432*8ccd4a63SDavid du Colombier 	memset(&t, 0, sizeof(t));
433*8ccd4a63SDavid du Colombier 	memmove(t.chal, tr->chal, CHALLEN);
434*8ccd4a63SDavid du Colombier 	strcpy(t.cuid, tr->uid);
435*8ccd4a63SDavid du Colombier 	strcpy(t.suid, tr->uid);
436*8ccd4a63SDavid du Colombier 	for(i=0; i<DESKEYLEN; i++)
437*8ccd4a63SDavid du Colombier 		t.key[i] = fastrand();
438*8ccd4a63SDavid du Colombier 	t.num = AuthTc;
439*8ccd4a63SDavid du Colombier 	convT2M(&t, tbuf, authkey);
440*8ccd4a63SDavid du Colombier 	t.num = AuthTs;
441*8ccd4a63SDavid du Colombier 	convT2M(&t, tbuf+TICKETLEN, authkey);
442*8ccd4a63SDavid du Colombier 	return 0;
443*8ccd4a63SDavid du Colombier }
444*8ccd4a63SDavid du Colombier 
445*8ccd4a63SDavid du Colombier static int
446*8ccd4a63SDavid du Colombier gettickets(Ticketreq *tr, char *key, char *trbuf, char *tbuf)
447*8ccd4a63SDavid du Colombier {
448*8ccd4a63SDavid du Colombier 	if(getastickets(tr, trbuf, tbuf) >= 0)
449*8ccd4a63SDavid du Colombier 		return 0;
450*8ccd4a63SDavid du Colombier 	return mkserverticket(tr, key, tbuf);
451*8ccd4a63SDavid du Colombier }
452*8ccd4a63SDavid du Colombier 
453*8ccd4a63SDavid du Colombier /*
454*8ccd4a63SDavid du Colombier  *  prompt user for a key.  don't care about memory leaks, runs standalone
455*8ccd4a63SDavid du Colombier  */
456*8ccd4a63SDavid du Colombier static Attr*
457*8ccd4a63SDavid du Colombier promptforkey(char *params)
458*8ccd4a63SDavid du Colombier {
459*8ccd4a63SDavid du Colombier 	char *v;
460*8ccd4a63SDavid du Colombier 	int fd;
461*8ccd4a63SDavid du Colombier 	Attr *a, *attr;
462*8ccd4a63SDavid du Colombier 	char *def;
463*8ccd4a63SDavid du Colombier 
464*8ccd4a63SDavid du Colombier 	fd = open("/dev/cons", ORDWR);
465*8ccd4a63SDavid du Colombier 	if(fd < 0)
466*8ccd4a63SDavid du Colombier 		sysfatal("opening /dev/cons: %r");
467*8ccd4a63SDavid du Colombier 
468*8ccd4a63SDavid du Colombier 	attr = _parseattr(params);
469*8ccd4a63SDavid du Colombier 	fprint(fd, "\n!Adding key:");
470*8ccd4a63SDavid du Colombier 	for(a=attr; a; a=a->next)
471*8ccd4a63SDavid du Colombier 		if(a->type != AttrQuery && a->name[0] != '!')
472*8ccd4a63SDavid du Colombier 			fprint(fd, " %q=%q", a->name, a->val);
473*8ccd4a63SDavid du Colombier 	fprint(fd, "\n");
474*8ccd4a63SDavid du Colombier 
475*8ccd4a63SDavid du Colombier 	for(a=attr; a; a=a->next){
476*8ccd4a63SDavid du Colombier 		v = a->name;
477*8ccd4a63SDavid du Colombier 		if(a->type != AttrQuery || v[0]=='!')
478*8ccd4a63SDavid du Colombier 			continue;
479*8ccd4a63SDavid du Colombier 		def = nil;
480*8ccd4a63SDavid du Colombier 		if(strcmp(v, "user") == 0)
481*8ccd4a63SDavid du Colombier 			def = getuser();
482*8ccd4a63SDavid du Colombier 		a->val = readcons(v, def, 0);
483*8ccd4a63SDavid du Colombier 		if(a->val == nil)
484*8ccd4a63SDavid du Colombier 			sysfatal("user terminated key input");
485*8ccd4a63SDavid du Colombier 		a->type = AttrNameval;
486*8ccd4a63SDavid du Colombier 	}
487*8ccd4a63SDavid du Colombier 	for(a=attr; a; a=a->next){
488*8ccd4a63SDavid du Colombier 		v = a->name;
489*8ccd4a63SDavid du Colombier 		if(a->type != AttrQuery || v[0]!='!')
490*8ccd4a63SDavid du Colombier 			continue;
491*8ccd4a63SDavid du Colombier 		def = nil;
492*8ccd4a63SDavid du Colombier 		if(strcmp(v+1, "user") == 0)
493*8ccd4a63SDavid du Colombier 			def = getuser();
494*8ccd4a63SDavid du Colombier 		a->val = readcons(v+1, def, 1);
495*8ccd4a63SDavid du Colombier 		if(a->val == nil)
496*8ccd4a63SDavid du Colombier 			sysfatal("user terminated key input");
497*8ccd4a63SDavid du Colombier 		a->type = AttrNameval;
498*8ccd4a63SDavid du Colombier 	}
499*8ccd4a63SDavid du Colombier 	fprint(fd, "!\n");
500*8ccd4a63SDavid du Colombier 	close(fd);
501*8ccd4a63SDavid du Colombier 	return attr;
502*8ccd4a63SDavid du Colombier }
503*8ccd4a63SDavid du Colombier 
504*8ccd4a63SDavid du Colombier /*
505*8ccd4a63SDavid du Colombier  *  send a key to the mounted factotum
506*8ccd4a63SDavid du Colombier  */
507*8ccd4a63SDavid du Colombier static int
508*8ccd4a63SDavid du Colombier sendkey(Attr *attr)
509*8ccd4a63SDavid du Colombier {
510*8ccd4a63SDavid du Colombier 	int fd, rv;
511*8ccd4a63SDavid du Colombier 	char buf[1024];
512*8ccd4a63SDavid du Colombier 
513*8ccd4a63SDavid du Colombier 	fd = open("/mnt/factotum/ctl", ORDWR);
514*8ccd4a63SDavid du Colombier 	if(fd < 0)
515*8ccd4a63SDavid du Colombier 		sysfatal("opening /mnt/factotum/ctl: %r");
516*8ccd4a63SDavid du Colombier 	rv = fprint(fd, "key %A\n", attr);
517*8ccd4a63SDavid du Colombier 	read(fd, buf, sizeof buf);
518*8ccd4a63SDavid du Colombier 	close(fd);
519*8ccd4a63SDavid du Colombier 	return rv;
520*8ccd4a63SDavid du Colombier }
521*8ccd4a63SDavid du Colombier 
522*8ccd4a63SDavid du Colombier int
523*8ccd4a63SDavid du Colombier askuser(char *params)
524*8ccd4a63SDavid du Colombier {
525*8ccd4a63SDavid du Colombier 	Attr *attr;
526*8ccd4a63SDavid du Colombier 
527*8ccd4a63SDavid du Colombier 	fmtinstall('A', _attrfmt);
528*8ccd4a63SDavid du Colombier 
529*8ccd4a63SDavid du Colombier 	attr = promptforkey(params);
530*8ccd4a63SDavid du Colombier 	if(attr == nil)
531*8ccd4a63SDavid du Colombier 		sysfatal("no key supplied");
532*8ccd4a63SDavid du Colombier 	if(sendkey(attr) < 0)
533*8ccd4a63SDavid du Colombier 		sysfatal("sending key to factotum: %r");
534*8ccd4a63SDavid du Colombier 	return 0;
535*8ccd4a63SDavid du Colombier }
536*8ccd4a63SDavid du Colombier 
537*8ccd4a63SDavid du Colombier AuthInfo*
538*8ccd4a63SDavid du Colombier p9anyfactotum(int fd, int afd)
539*8ccd4a63SDavid du Colombier {
540*8ccd4a63SDavid du Colombier 	return auth_proxy(fd, askuser, "proto=p9any role=client %s", keyspec);
541*8ccd4a63SDavid du Colombier }
542*8ccd4a63SDavid du Colombier 
543*8ccd4a63SDavid du Colombier AuthInfo*
544*8ccd4a63SDavid du Colombier p9any(int fd)
545*8ccd4a63SDavid du Colombier {
546*8ccd4a63SDavid du Colombier 	char buf[1024], buf2[1024], cchal[CHALLEN], *bbuf, *p, *dom, *u;
547*8ccd4a63SDavid du Colombier 	char *pass;
548*8ccd4a63SDavid du Colombier 	char tbuf[TICKETLEN+TICKETLEN+AUTHENTLEN], trbuf[TICKREQLEN];
549*8ccd4a63SDavid du Colombier 	char authkey[DESKEYLEN];
550*8ccd4a63SDavid du Colombier 	Authenticator auth;
551*8ccd4a63SDavid du Colombier 	int afd, i, v2;
552*8ccd4a63SDavid du Colombier 	Ticketreq tr;
553*8ccd4a63SDavid du Colombier 	Ticket t;
554*8ccd4a63SDavid du Colombier 	AuthInfo *ai;
555*8ccd4a63SDavid du Colombier 
556*8ccd4a63SDavid du Colombier 	if((afd = open("/mnt/factotum/ctl", ORDWR)) >= 0)
557*8ccd4a63SDavid du Colombier 		return p9anyfactotum(fd, afd);
558*8ccd4a63SDavid du Colombier 
559*8ccd4a63SDavid du Colombier 	if(readstr(fd, buf, sizeof buf) < 0)
560*8ccd4a63SDavid du Colombier 		fatal(1, "cannot read p9any negotiation");
561*8ccd4a63SDavid du Colombier 	bbuf = buf;
562*8ccd4a63SDavid du Colombier 	v2 = 0;
563*8ccd4a63SDavid du Colombier 	if(strncmp(buf, "v.2 ", 4) == 0){
564*8ccd4a63SDavid du Colombier 		v2 = 1;
565*8ccd4a63SDavid du Colombier 		bbuf += 4;
566*8ccd4a63SDavid du Colombier 	}
567*8ccd4a63SDavid du Colombier 	if((p = strchr(bbuf, ' ')))
568*8ccd4a63SDavid du Colombier 		*p = 0;
569*8ccd4a63SDavid du Colombier 	p = bbuf;
570*8ccd4a63SDavid du Colombier 	if((dom = strchr(p, '@')) == nil)
571*8ccd4a63SDavid du Colombier 		fatal(1, "bad p9any domain");
572*8ccd4a63SDavid du Colombier 	*dom++ = 0;
573*8ccd4a63SDavid du Colombier 	if(strcmp(p, "p9sk1") != 0)
574*8ccd4a63SDavid du Colombier 		fatal(1, "server did not offer p9sk1");
575*8ccd4a63SDavid du Colombier 
576*8ccd4a63SDavid du Colombier 	sprint(buf2, "%s %s", p, dom);
577*8ccd4a63SDavid du Colombier 	if(write(fd, buf2, strlen(buf2)+1) != strlen(buf2)+1)
578*8ccd4a63SDavid du Colombier 		fatal(1, "cannot write user/domain choice in p9any");
579*8ccd4a63SDavid du Colombier 	if(v2){
580*8ccd4a63SDavid du Colombier 		if(readstr(fd, buf, sizeof buf) != 3)
581*8ccd4a63SDavid du Colombier 			fatal(1, "cannot read OK in p9any");
582*8ccd4a63SDavid du Colombier 		if(memcmp(buf, "OK\0", 3) != 0)
583*8ccd4a63SDavid du Colombier 			fatal(1, "did not get OK in p9any");
584*8ccd4a63SDavid du Colombier 	}
585*8ccd4a63SDavid du Colombier 	for(i=0; i<CHALLEN; i++)
586*8ccd4a63SDavid du Colombier 		cchal[i] = fastrand();
587*8ccd4a63SDavid du Colombier 	if(write(fd, cchal, 8) != 8)
588*8ccd4a63SDavid du Colombier 		fatal(1, "cannot write p9sk1 challenge");
589*8ccd4a63SDavid du Colombier 
590*8ccd4a63SDavid du Colombier 	if(readn(fd, trbuf, TICKREQLEN) != TICKREQLEN)
591*8ccd4a63SDavid du Colombier 		fatal(1, "cannot read ticket request in p9sk1");
592*8ccd4a63SDavid du Colombier 
593*8ccd4a63SDavid du Colombier 
594*8ccd4a63SDavid du Colombier 	convM2TR(trbuf, &tr);
595*8ccd4a63SDavid du Colombier 	u = user;
596*8ccd4a63SDavid du Colombier 	pass = findkey(&u, tr.authdom);
597*8ccd4a63SDavid du Colombier 	if(pass == nil)
598*8ccd4a63SDavid du Colombier 	again:
599*8ccd4a63SDavid du Colombier 		pass = getkey(u, tr.authdom);
600*8ccd4a63SDavid du Colombier 	if(pass == nil)
601*8ccd4a63SDavid du Colombier 		fatal(1, "no password");
602*8ccd4a63SDavid du Colombier 
603*8ccd4a63SDavid du Colombier 	passtokey(authkey, pass);
604*8ccd4a63SDavid du Colombier 	memset(pass, 0, strlen(pass));
605*8ccd4a63SDavid du Colombier 
606*8ccd4a63SDavid du Colombier 	tr.type = AuthTreq;
607*8ccd4a63SDavid du Colombier 	strecpy(tr.hostid, tr.hostid+sizeof tr.hostid, u);
608*8ccd4a63SDavid du Colombier 	strecpy(tr.uid, tr.uid+sizeof tr.uid, u);
609*8ccd4a63SDavid du Colombier 	convTR2M(&tr, trbuf);
610*8ccd4a63SDavid du Colombier 
611*8ccd4a63SDavid du Colombier 	if(gettickets(&tr, authkey, trbuf, tbuf) < 0)
612*8ccd4a63SDavid du Colombier 		fatal(1, "cannot get auth tickets in p9sk1");
613*8ccd4a63SDavid du Colombier 
614*8ccd4a63SDavid du Colombier 	convM2T(tbuf, &t, authkey);
615*8ccd4a63SDavid du Colombier 	if(t.num != AuthTc){
616*8ccd4a63SDavid du Colombier 		print("?password mismatch with auth server\n");
617*8ccd4a63SDavid du Colombier 		goto again;
618*8ccd4a63SDavid du Colombier 	}
619*8ccd4a63SDavid du Colombier 	memmove(tbuf, tbuf+TICKETLEN, TICKETLEN);
620*8ccd4a63SDavid du Colombier 
621*8ccd4a63SDavid du Colombier 	auth.num = AuthAc;
622*8ccd4a63SDavid du Colombier 	memmove(auth.chal, tr.chal, CHALLEN);
623*8ccd4a63SDavid du Colombier 	auth.id = 0;
624*8ccd4a63SDavid du Colombier 	convA2M(&auth, tbuf+TICKETLEN, t.key);
625*8ccd4a63SDavid du Colombier 
626*8ccd4a63SDavid du Colombier 	if(write(fd, tbuf, TICKETLEN+AUTHENTLEN) != TICKETLEN+AUTHENTLEN)
627*8ccd4a63SDavid du Colombier 		fatal(1, "cannot send ticket and authenticator back in p9sk1");
628*8ccd4a63SDavid du Colombier 
629*8ccd4a63SDavid du Colombier 	if(readn(fd, tbuf, AUTHENTLEN) != AUTHENTLEN)
630*8ccd4a63SDavid du Colombier 		fatal(1, "cannot read authenticator in p9sk1");
631*8ccd4a63SDavid du Colombier 
632*8ccd4a63SDavid du Colombier 	convM2A(tbuf, &auth, t.key);
633*8ccd4a63SDavid du Colombier 	if(auth.num != AuthAs
634*8ccd4a63SDavid du Colombier 	|| memcmp(auth.chal, cchal, CHALLEN) != 0
635*8ccd4a63SDavid du Colombier 	|| auth.id != 0){
636*8ccd4a63SDavid du Colombier 		print("?you and auth server agree about password.\n");
637*8ccd4a63SDavid du Colombier 		print("?server is confused.\n");
638*8ccd4a63SDavid du Colombier 		fatal(1, "server lies got %llux.%d want %llux.%d", *(vlong*)auth.chal, auth.id, *(vlong*)cchal, 0);
639*8ccd4a63SDavid du Colombier 	}
640*8ccd4a63SDavid du Colombier 	//print("i am %s there.\n", t.suid);
641*8ccd4a63SDavid du Colombier 	ai = mallocz(sizeof(AuthInfo), 1);
642*8ccd4a63SDavid du Colombier 	ai->secret = mallocz(8, 1);
643*8ccd4a63SDavid du Colombier 	des56to64((uchar*)t.key, ai->secret);
644*8ccd4a63SDavid du Colombier 	ai->nsecret = 8;
645*8ccd4a63SDavid du Colombier 	ai->suid = strdup(t.suid);
646*8ccd4a63SDavid du Colombier 	ai->cuid = strdup(t.cuid);
647*8ccd4a63SDavid du Colombier 	memset(authkey, 0, sizeof authkey);
648*8ccd4a63SDavid du Colombier 	return ai;
649*8ccd4a63SDavid du Colombier }
650*8ccd4a63SDavid du Colombier 
651*8ccd4a63SDavid du Colombier /*
652*8ccd4a63SDavid du Colombier static int
653*8ccd4a63SDavid du Colombier noauth(int fd)
654*8ccd4a63SDavid du Colombier {
655*8ccd4a63SDavid du Colombier 	ealgs = nil;
656*8ccd4a63SDavid du Colombier 	return fd;
657*8ccd4a63SDavid du Colombier }
658*8ccd4a63SDavid du Colombier 
659*8ccd4a63SDavid du Colombier static int
660*8ccd4a63SDavid du Colombier srvnoauth(int fd, char *user)
661*8ccd4a63SDavid du Colombier {
662*8ccd4a63SDavid du Colombier 	strecpy(user, user+MaxStr, getuser());
663*8ccd4a63SDavid du Colombier 	ealgs = nil;
664*8ccd4a63SDavid du Colombier 	return fd;
665*8ccd4a63SDavid du Colombier }
666*8ccd4a63SDavid du Colombier */
667*8ccd4a63SDavid du Colombier 
668*8ccd4a63SDavid du Colombier void
669*8ccd4a63SDavid du Colombier loghex(uchar *p, int n)
670*8ccd4a63SDavid du Colombier {
671*8ccd4a63SDavid du Colombier 	char buf[100];
672*8ccd4a63SDavid du Colombier 	int i;
673*8ccd4a63SDavid du Colombier 
674*8ccd4a63SDavid du Colombier 	for(i = 0; i < n; i++)
675*8ccd4a63SDavid du Colombier 		sprint(buf+2*i, "%2.2ux", p[i]);
676*8ccd4a63SDavid du Colombier //	syslog(0, "cpu", buf);
677*8ccd4a63SDavid du Colombier }
678*8ccd4a63SDavid du Colombier 
679*8ccd4a63SDavid du Colombier static int
680*8ccd4a63SDavid du Colombier srvp9auth(int fd, char *user)
681*8ccd4a63SDavid du Colombier {
682*8ccd4a63SDavid du Colombier 	return -1;
683*8ccd4a63SDavid du Colombier }
684*8ccd4a63SDavid du Colombier 
685*8ccd4a63SDavid du Colombier /*
686*8ccd4a63SDavid du Colombier  *  set authentication mechanism
687*8ccd4a63SDavid du Colombier  */
688*8ccd4a63SDavid du Colombier int
689*8ccd4a63SDavid du Colombier setam(char *name)
690*8ccd4a63SDavid du Colombier {
691*8ccd4a63SDavid du Colombier 	for(am = authmethod; am->name != nil; am++)
692*8ccd4a63SDavid du Colombier 		if(strcmp(am->name, name) == 0)
693*8ccd4a63SDavid du Colombier 			return 0;
694*8ccd4a63SDavid du Colombier 	am = authmethod;
695*8ccd4a63SDavid du Colombier 	return -1;
696*8ccd4a63SDavid du Colombier }
697*8ccd4a63SDavid du Colombier 
698*8ccd4a63SDavid du Colombier /*
699*8ccd4a63SDavid du Colombier  *  set authentication mechanism and encryption/hash algs
700*8ccd4a63SDavid du Colombier  *
701*8ccd4a63SDavid du Colombier int
702*8ccd4a63SDavid du Colombier setamalg(char *s)
703*8ccd4a63SDavid du Colombier {
704*8ccd4a63SDavid du Colombier 	ealgs = strchr(s, ' ');
705*8ccd4a63SDavid du Colombier 	if(ealgs != nil)
706*8ccd4a63SDavid du Colombier 		*ealgs++ = 0;
707*8ccd4a63SDavid du Colombier 	return setam(s);
708*8ccd4a63SDavid du Colombier }
709*8ccd4a63SDavid du Colombier 
710*8ccd4a63SDavid du Colombier */
711