Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
68 7u83 1
#include <sys/param.h>
2
#include <sys/systm.h>
3
#include <sys/socket.h>
4
#include <sys/socketvar.h>
5
#include <sys/protosw.h>
6
#include <sys/malloc.h>
7
#include <sys/mbuf.h>
8
#include <sys/uio.h>
9
 
10
#include <9fs/9p.h>
11
#include <9fs/9auth.h>
12
 
13
#define	N2HCHAR(x)		x = *p++
14
#define	N2HSHORT(x)	x = (p[0] | (p[1]<<8)); p += 2
15
#define	N2HLONG(x)		x = (p[0] | (p[1]<<8) |\
16
				(p[2]<<16) | (p[3]<<24)); p += 4
17
#define	N2HQUAD(x)	x = (u_int64_t)(p[0] | (p[1]<<8) |\
18
					(p[2]<<16) | (p[3]<<24)) |\
19
				((u_int64_t)(p[4] | (p[5]<<8) |\
20
					(p[6]<<16) | (p[7]<<24)) << 32); p += 8
21
#define	N2HSTRING(x,n)	bcopy(p, x, n); p += n
22
 
23
#define	H2NCHAR(x)	*p++ = x
24
#define	H2NSHORT(x)	p[0]=x; p[1]=x>>8; p += 2
25
#define	H2NLONG(x)		p[0]=x; p[1]=x>>8; p[2]=x>>16; p[3]=x>>24; p += 4
26
#define	H2NQUAD(x)	p[0]=x;	p[1]=x>>8;\
27
			p[2]=x>>16;	p[3]=x>>24;\
28
			p[4]=x>>32;	p[5]=x>>40;\
29
			p[6]=x>>48;	p[7]=x>>56;\
30
			p += 8
31
#define	H2NSTRING(x,n)	bcopy(x, p, n); p += n
32
 
33
static int u9auth_send __P((struct socket *so, struct mbuf *top, struct proc *p));
34
static int u9auth_recv __P((struct socket *so, struct mbuf **mp, struct proc *p));
35
 
36
static int u9auth_count = 0;
37
 
38
static int u9auth_tr2m(struct u9auth_ticketreq *f, char *ap)
39
{
40
	int n;
41
	u_char *p;
42
 
43
	p = (u_char*)ap;
44
        H2NCHAR(f->type);
45
	H2NSTRING(f->authid, U9FS_NAMELEN);
46
	H2NSTRING(f->authdom, U9FS_DOMLEN);
47
	H2NSTRING(f->chal, U9FS_CHALLEN);
48
	H2NSTRING(f->hostid, U9FS_NAMELEN);
49
	H2NSTRING(f->uid, U9FS_NAMELEN);
50
	n = p - (u_char*)ap;
51
	return n;
52
}
53
 
54
static struct mbuf * u9auth_m_tr2m(struct u9auth_ticketreq * tktq)
55
{
56
  register struct mbuf *m;
57
  char * ap;
58
  int sz = 141;
59
 
60
  MGETHDR(m, M_WAIT, MT_DATA);
61
  if( sz > MHLEN )
62
    MCLGET(m, M_WAIT);
63
  m->m_len = 0;
64
 
65
  if ( M_TRAILINGSPACE(m) < sz )
66
    panic("u9auth_m_tr2m");
67
 
68
  ap = mtod(m, char *);
69
  m->m_len = u9auth_tr2m(tktq, ap);
70
  m->m_pkthdr.len = m->m_len;
71
 
72
  return (m);
73
}
74
 
75
static int
76
u9auth_send(so, top, p)
77
	register struct socket *so;
78
	register struct mbuf *top;
79
	register struct proc *p;
80
 
81
{
82
  int error, soflags, flags;
83
 
84
  soflags = so->so_proto->pr_flags;
85
  if (so->so_type == SOCK_SEQPACKET)
86
    flags = MSG_EOR;
87
  else
88
    flags = 0;
89
 
90
  error = so->so_proto->pr_usrreqs->pru_sosend(so, 0, 0, top, 0, flags, p);
91
 
92
  return (error);
93
}
94
 
95
static int
96
u9auth_recv(so, mp, p)	
97
     register struct socket * so;
98
     register struct mbuf **mp;
99
     struct proc *p;
100
{
101
  struct uio auio;
102
  u_int32_t len;
103
  int error = 0, sotype, rcvflg;
104
 
105
  *mp = 0;
106
  sotype = so->so_type;
107
 
108
  /*
109
   * For reliable protocols, lock against other senders/receivers
110
   * in case a reconnect is necessary.
111
   * For SOCK_STREAM, first get the Record Mark to find out how much
112
   * more there is to get.
113
   * We must lock the socket against other receivers
114
   * until we have an entire rpc request/reply.
115
   */
116
  if (sotype == SOCK_SEQPACKET ) {
117
    if( (so->so_state & SS_ISCONNECTED) == 0 )
118
      return (EACCES);
119
		auio.uio_resid = len = 1000000;
120
		auio.uio_procp = p;
121
		do {
122
			rcvflg = 0;
123
			error =  so->so_proto->pr_usrreqs->pru_soreceive
124
				(so, 0, &auio, mp,
125
				(struct mbuf **)0, &rcvflg);
126
		} while (error == EWOULDBLOCK);
127
		len -= auio.uio_resid;    
128
  }
129
  if (error) {
130
    m_freem(*mp);
131
    *mp = 0;
132
  }
133
  return (error);  
134
}
135
 
136
static void
137
u9auth_m2t(char *ap, struct u9auth_ticket *f, char *key)
138
{
139
	u_char *p;
140
 
141
	if(key)
142
		decrypt9(key, ap, U9AUTH_TICKETLEN);
143
	p = (u_char*)ap;
144
	N2HCHAR(f->num);
145
	N2HSTRING(f->chal, U9FS_CHALLEN);
146
	N2HSTRING(f->cuid, U9FS_NAMELEN);
147
	f->cuid[U9FS_NAMELEN-1] = 0;
148
	N2HSTRING(f->suid, U9FS_NAMELEN);
149
	f->suid[U9FS_NAMELEN-1] = 0;
150
	N2HSTRING(f->key, U9AUTH_DESKEYLEN);
151
};
152
 
153
static int 
154
u9auth_a2m(struct u9auth_authenticator *f, char *ap, char *key)
155
{
156
	int n;
157
	u_char *p;
158
 
159
	p = (u_char*)ap;
160
	H2NCHAR(f->num);
161
	H2NSTRING(f->chal, U9FS_CHALLEN);
162
	H2NLONG(f->id);
163
	n = p - (u_char*)ap;
164
	if(key)
165
		encrypt9(key, ap, n);
166
	return n;
167
}
168
 
169
void u9auth_genchal (char * chal)
170
{
171
  u_long * lp = (u_long *)chal;
172
 
173
  *lp++ = random();
174
  *lp = random();
175
}
176
 
177
int u9auth_gettickets (struct socket * so, struct u9fsreq * rep,
178
			   char * user, char * ckey, char * ts, char * authc,
179
		       struct proc *p)
180
{
181
  char * cp;
182
  struct u9auth_ticketreq tktq;
183
  struct u9auth_ticket tc;
184
  struct u9auth_authenticator auth;
185
  struct mbuf * m;
186
  int error, len;
187
 
188
  bzero(&tktq, sizeof(tktq));
189
  tktq.type = AuthTreq;
190
  bcopy(rep->r_authid, tktq.authid, U9FS_NAMELEN);
191
  bcopy(rep->r_authdom, tktq.authdom, U9FS_DOMLEN);
192
  bcopy(rep->r_chal, tktq.chal, U9FS_CHALLEN);
193
  strncpy(tktq.hostid, user, U9FS_NAMELEN);
194
  strncpy(tktq.uid, user, U9FS_NAMELEN);
195
 
196
  m = u9auth_m_tr2m(&tktq);
197
  error = u9auth_send(so, m, p);
198
  if( error ) 
199
    goto bad;
200
  error = u9auth_recv(so, &m, p);
201
  if( error )
202
    goto bad;
203
 
204
  len = U9AUTH_TICKETLEN+1;
205
  if( m->m_len < len && (m = m_pullup(m, len)) == 0 )
206
    goto bad;
207
 
208
  cp = mtod(m, char *);
209
  switch( cp[0] ) {
210
  case AuthOK:
211
    u9auth_m2t(&cp[1], & tc, ckey);
212
    bzero(&auth, sizeof(auth));
213
    auth.num = AuthAc;
214
    bcopy(tc.chal, auth.chal, sizeof(auth.chal));
215
    auth.id = u9auth_count++;
216
 
217
    m->m_len -= len;
218
    m->m_data += len;
219
 
220
    len = U9AUTH_TICKETLEN;
221
    if( m->m_len < len && (m = m_pullup(m, len)) == 0 )
222
      goto bad;
223
    cp = mtod(m, char *);
224
    bcopy(cp, ts, len);
225
    break;
226
  case AuthErr:
227
  case AuthOKvar:
228
    m_freem(m);
229
    goto bad;
230
    break;
231
  }
232
 
233
  u9auth_a2m(&auth, authc, tc.key);
234
  return 0;
235
 bad:
236
  return error;
237
}
238