Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <auth.h>
4
#include <authsrv.h>
5
#include "authlocal.h"
6
 
7
Chalstate*
8
auth_challenge(char *fmt, ...)
9
{
10
	char *p;
11
	va_list arg;
12
	Chalstate *c;
13
 
14
	quotefmtinstall();	/* just in case */
15
	va_start(arg, fmt);
16
	p = vsmprint(fmt, arg);
17
	va_end(arg);
18
	if(p == nil)
19
		return nil;
20
 
21
	c = mallocz(sizeof(*c), 1);
22
	if(c == nil){
23
		free(p);
24
		return nil;
25
	}
26
 
27
	if((c->afd = open("/mnt/factotum/rpc", ORDWR)) < 0){
28
	Error:
29
		auth_freechal(c);
30
		free(p);
31
		return nil;
32
	}
33
 
34
	if((c->rpc=auth_allocrpc(c->afd)) == nil
35
	|| auth_rpc(c->rpc, "start", p, strlen(p)) != ARok
36
	|| auth_rpc(c->rpc, "read", nil, 0) != ARok)
37
		goto Error;
38
 
39
	if(c->rpc->narg > sizeof(c->chal)-1){
40
		werrstr("buffer too small for challenge");
41
		goto Error;
42
	}
43
	memmove(c->chal, c->rpc->arg, c->rpc->narg);
44
	c->nchal = c->rpc->narg;
45
	free(p);
46
	return c;
47
}
48
 
49
AuthInfo*
50
auth_response(Chalstate *c)
51
{
52
	int ret;
53
	AuthInfo *ai;
54
 
55
	ai = nil;
56
	if(c->afd < 0){
57
		werrstr("auth_response: connection not open");
58
		return nil;
59
	}
60
	if(c->resp == nil){
61
		werrstr("auth_response: nil response");
62
		return nil;
63
	}
64
	if(c->nresp == 0){
65
		werrstr("auth_response: unspecified response length");
66
		return nil;
67
	}
68
 
69
	if(c->user){
70
		if(auth_rpc(c->rpc, "write", c->user, strlen(c->user)) != ARok){
71
			/*
72
			 * if this fails we're out of phase with factotum.
73
			 * give up.
74
			 */
75
			goto Out;
76
		}
77
	}
78
 
79
	if(auth_rpc(c->rpc, "write", c->resp, c->nresp) != ARok){
80
		/*
81
		 * don't close the connection -- maybe we'll try again.
82
		 */
83
		return nil;
84
	}
85
 
86
	switch(ret = auth_rpc(c->rpc, "read", nil, 0)){
87
	case ARok:
88
	default:
89
		werrstr("factotum protocol botch %d %s", ret, c->rpc->ibuf);
90
		break;
91
	case ARdone:
92
		ai = auth_getinfo(c->rpc);
93
		break;
94
	}
95
 
96
Out:
97
	close(c->afd);
98
	auth_freerpc(c->rpc);
99
	c->afd = -1;
100
	c->rpc = nil;
101
	return ai;
102
}
103
 
104
void
105
auth_freechal(Chalstate *c)
106
{
107
	if(c == nil)
108
		return;
109
 
110
	if(c->afd >= 0)
111
		close(c->afd);
112
	if(c->rpc != nil)
113
		auth_freerpc(c->rpc);
114
 
115
	memset(c, 0xBB, sizeof(*c));
116
	free(c);
117
}