Make rxgen emit prototype for ExecuteRequest
[openafs.git] / src / rxkad / test / stress_s.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /* RX Authentication Stress test: server side code. */
11
12 #include <afsconfig.h>
13 #include <afs/param.h>
14
15
16 #include <afs/stds.h>
17 #include <stdio.h>
18 #include <fcntl.h>
19 #include <sys/types.h>
20 #ifdef AFS_NT40_ENV
21 #include <winsock2.h>
22 #else
23 #include <netinet/in.h>
24 #endif
25 #include <rx/rx_null.h>
26
27 #include <rx/rxkad.h>
28
29 #include <afs/keys.h>
30 #include <afs/cellconfig.h>
31
32 #include "stress.h"
33 #include "stress_internal.h"
34
35 struct ktc_encryptionKey serviceKey =
36     { 0x45, 0xe3, 0x3d, 0x16, 0x29, 0x64, 0x8a, 0x8f };
37 long serviceKeyVersion = 7;
38
39 static long
40 GetKey(rock, kvno, key)
41      IN char *rock;
42      IN long kvno;
43      OUT struct ktc_encryptionKey *key;
44 {
45     struct serverParms *parms = (struct serverParms *)rock;
46     struct afsconf_keys tstr;
47     afs_int32 code;
48     int fd;
49
50     fprintf(stderr, "GetKey called for kvno %d\n", kvno);
51     if (!parms->keyfile) {
52         memcpy(key, &serviceKey, sizeof(*key));
53         return 0;
54     }
55
56     /* the rest of this function borrows heavily from auth/cellconfig.c */
57     fd = open(parms->keyfile, O_RDONLY);
58     if (fd < 0) {
59         return AFSCONF_FAILURE;
60     }
61     code = read(fd, &tstr, sizeof(struct afsconf_keys));
62     close(fd);
63     if (code < sizeof(afs_int32)) {
64         return AFSCONF_FAILURE;
65     }
66
67     /* convert key structure to host order */
68     tstr.nkeys = ntohl(tstr.nkeys);
69     for (fd = 0; fd < tstr.nkeys; fd++) {
70         if (kvno == ntohl(tstr.key[fd].kvno)) {
71             memcpy(key, tstr.key[fd].key, sizeof(*key));
72             return 0;
73         }
74     }
75
76     return AFSCONF_NOTFOUND;
77 }
78
79 static int minAuth;
80
81 long
82 rxkst_StartServer(parms)
83      INOUT struct serverParms *parms;
84 {
85     extern int rx_stackSize;
86     struct rx_service *tservice;
87     struct rx_securityClass *sc[3];
88     rxkad_level minLevel;
89
90     minAuth = parms->authentication;
91     if (minAuth == -1)
92         minLevel = rxkad_clear;
93     else
94         minLevel = minAuth;
95
96     sc[0] = rxnull_NewServerSecurityObject();
97     sc[1] = 0;                  /* no rxvab anymore */
98     sc[2] = rxkad_NewServerSecurityObject(minLevel, (void *)parms, GetKey, 0);
99     tservice =
100         rx_NewService(htons(RXKST_SERVICEPORT), RXKST_SERVICEID,
101                       "stress test", sc, 3, RXKST_ExecuteRequest);
102     if (tservice == (struct rx_service *)0) {
103         fprintf(stderr, "Could not create stress test rx service\n");
104         exit(3);
105     }
106     rx_SetMinProcs(tservice, parms->threads);
107     rx_SetMaxProcs(tservice, parms->threads);
108     rx_SetStackSize(tservice, 10000);
109
110     rx_StartServer( /*donate me */ 1);  /* start handling req. of all types */
111     /* never reached */
112     return 0;
113 }
114
115 static char test_client_name[MAXKTCNAMELEN];
116 static char test_client_inst[MAXKTCNAMELEN];
117 static char test_client_cell[MAXKTCREALMLEN];
118 static int got_client_id = 0;
119 static long
120 CheckAuth(call)
121      IN struct rx_call *call;
122 {
123     long code;
124     int si;
125     rxkad_level level;
126     char name[MAXKTCNAMELEN];
127     char inst[MAXKTCNAMELEN];
128     char cell[MAXKTCREALMLEN];
129     long kvno;
130     u_long expiration;          /* checked by Security Module */
131
132     si = rx_SecurityClassOf(rx_ConnectionOf(call));
133     if (si == 1) {
134         printf("No support for VAB security module.\n");
135         return -1;
136     } else if (si == 0) {
137         if (minAuth > -1)
138             return RXKST_UNAUTH;
139         else
140             return 0;
141     } else if (si != 2) {
142         fprintf(stderr, "Unknown security index %d\n", si);
143         return -1;
144     }
145
146     code =
147         rxkad_GetServerInfo(rx_ConnectionOf(call), &level, &expiration, name,
148                             inst, cell, &kvno);
149     if (code)
150         return code;
151     if (minAuth > level)
152         return -1;
153     fprintf(stderr, "Test client is %s.%s@%s\n", name, inst, cell);
154     if (got_client_id) {
155         if (strcmp(name, test_client_name))
156             return RXKST_BADCLIENT;
157         if (strcmp(inst, test_client_inst))
158             return RXKST_BADCLIENT;
159         if (strcmp(cell, test_client_cell))
160             return RXKST_BADCLIENT;
161     } else {
162         strcpy(test_client_name, name);
163         strcpy(test_client_inst, inst);
164         strcpy(test_client_cell, cell);
165         got_client_id = 1;
166     }
167     return 0;
168 }
169
170 /* Stop the server.  There isn't a graceful way to do this so just exit. */
171
172 afs_int32
173 SRXKST_Kill(call)
174      IN struct rx_call *call;
175 {
176     long code;
177     code = CheckAuth(call);
178     if (code)
179         return code;
180
181     /* This is tricky, but since we're never going to return, we end the call
182      * here, then rx_Finalize should push out the response/ack. */
183     rx_EndCall(call, 0);
184     rx_Finalize();
185
186     printf("Server halted by RPC request.\n");
187     exit(0);
188     return 0;
189 }
190
191 afs_int32
192 SRXKST_Fast(call, n, inc_nP)
193      IN struct rx_call *call;
194      IN u_long n;
195      OUT u_long *inc_nP;
196 {
197     *inc_nP = n + 1;
198     return 0;
199 }
200
201 afs_int32
202 SRXKST_Slow(call, tag, nowP)
203      IN struct rx_call *call;
204      IN u_long tag;
205      OUT u_long *nowP;
206 {
207     long code;
208     code = CheckAuth(call);
209     if (code)
210         return code;
211 #ifdef AFS_PTHREAD_ENV
212     sleep(1);
213 #else
214     IOMGR_Sleep(1);
215 #endif
216     time(nowP);
217     return 0;
218 }
219
220 #define COPBUFSIZE 10000
221 static struct buflist {
222     struct buflist *next;
223 } *buflist = 0;
224 static int bufAllocs = 0;
225
226 static u_char *
227 GetBuffer()
228 {
229     u_char *ret;
230     if (buflist) {
231         ret = (u_char *) buflist;
232         buflist = buflist->next;
233     } else {
234         ret = (u_char *) osi_Alloc(COPBUFSIZE);
235         bufAllocs++;
236     }
237     return ret;
238 }
239
240 static void
241 PutBuffer(b)
242      IN u_char *b;
243 {
244     struct buflist *bl = (struct buflist *)b;
245     bl->next = buflist;
246     buflist = bl;
247 }
248
249 afs_int32
250 SRXKST_Copious(call, inlen, insum, outlen, outsum)
251      IN struct rx_call *call;
252      IN u_long inlen;
253      IN u_long insum;
254      IN u_long outlen;
255      OUT u_long *outsum;
256 {
257     long code;
258     long mysum;
259     u_char *buf;
260     int i;
261     long b;
262     long bytesTransfered;
263     long n;
264
265     code = CheckAuth(call);
266     if (code)
267         return code;
268     buf = GetBuffer();
269     mysum = 0;
270     bytesTransfered = 0;
271     while (bytesTransfered < inlen) {
272         u_long tlen;            /* how much more to do */
273         tlen = inlen - bytesTransfered;
274         if (tlen > COPBUFSIZE)
275             tlen = COPBUFSIZE;
276         n = rx_Read(call, buf, tlen);
277         if (n != tlen) {
278             if (n < 0)
279                 code = n;
280             else
281                 code = RXKST_READSHORT;
282             break;
283         }
284         for (i = 0; i < tlen; i++)
285             mysum += buf[i];
286         bytesTransfered += tlen;
287     }
288     if (code)
289         goto done;
290     if (mysum != insum) {
291         code = RXKST_BADINPUTSUM;
292         goto done;
293     }
294 #define BIG_PRIME 1257056893    /* 0x4AED2A7d */
295 #if 0
296 #define NextByte() ((b>24 ? ((seed = seed*BIG_PRIME + BIG_PRIME),b=0) : 0), \
297                     (b +=8), ((seed >> (b-8))&0xff))
298 #else
299 #define NextByte() (b+=3)
300 #endif
301     b = 32;
302
303     mysum = 0;
304     bytesTransfered = 0;
305     while (bytesTransfered < outlen) {
306         u_long tlen;            /* how much more to do */
307         tlen = outlen - bytesTransfered;
308         if (tlen > COPBUFSIZE)
309             tlen = COPBUFSIZE;
310         for (i = 0; i < tlen; i++)
311             mysum += (buf[i] = NextByte());
312         n = rx_Write(call, buf, tlen);
313         if (n != tlen) {
314             if (n < 0)
315                 code = n;
316             else
317                 code = RXKST_WRITESHORT;
318             break;
319         }
320         bytesTransfered += tlen;
321     }
322   done:
323     PutBuffer(buf);
324     if (code)
325         return code;
326     *outsum = mysum;
327     return 0;
328 }