OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [librpc/] [src/] [rpc/] [key_call.c] - Blame information for rev 583

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3
 * unrestricted use provided that this legend is included on all tape
4
 * media and as a part of the software program in whole or part.  Users
5
 * may copy or modify Sun RPC without charge, but are not authorized
6
 * to license or distribute it to anyone else except as part of a product or
7
 * program developed by the user.
8
 *
9
 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10
 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11
 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12
 *
13
 * Sun RPC is provided with no support and without any obligation on the
14
 * part of Sun Microsystems, Inc. to assist in its use, correction,
15
 * modification or enhancement.
16
 *
17
 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18
 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19
 * OR ANY PART THEREOF.
20
 *
21
 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22
 * or profits or other special, indirect and consequential damages, even if
23
 * Sun has been advised of the possibility of such damages.
24
 *
25
 * Sun Microsystems, Inc.
26
 * 2550 Garcia Avenue
27
 * Mountain View, California  94043
28
 */
29
/*
30
 * Copyright (c) 1986-1991 by Sun Microsystems Inc.
31
 *
32
 * $FreeBSD: src/lib/libc/rpc/key_call.c,v 1.3 2000/01/27 23:06:39 jasone Exp $
33
 */
34
 
35
#ident  "@(#)key_call.c 1.25    94/04/24 SMI"
36
 
37
/*
38
 * key_call.c, Interface to keyserver
39
 *
40
 * setsecretkey(key) - set your secret key
41
 * encryptsessionkey(agent, deskey) - encrypt a session key to talk to agent
42
 * decryptsessionkey(agent, deskey) - decrypt ditto
43
 * gendeskey(deskey) - generate a secure des key
44
 */
45
 
46
#include <stdio.h>
47
#include <stdlib.h>
48
#include <unistd.h>
49
#include <errno.h>
50
#include <rpc/rpc.h>
51
#include <rpc/auth.h>
52
#include <rpc/auth_unix.h>
53
#include <rpc/key_prot.h>
54
#include <string.h>
55
#include <sys/utsname.h>
56
#include <stdlib.h>
57
#include <signal.h>
58
#include <sys/wait.h>
59
#include <sys/fcntl.h>
60
 
61
 
62
#define KEY_TIMEOUT     5       /* per-try timeout in seconds */
63
#define KEY_NRETRY      12      /* number of retries */
64
 
65
#ifdef DEBUG
66
#define debug(msg)      (void) fprintf(stderr, "%s\n", msg);
67
#else
68
#define debug(msg)
69
#endif /* DEBUG */
70
 
71
/*
72
 * Hack to allow the keyserver to use AUTH_DES (for authenticated
73
 * NIS+ calls, for example).  The only functions that get called
74
 * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
75
 *
76
 * The approach is to have the keyserver fill in pointers to local
77
 * implementations of these functions, and to call those in key_call().
78
 */
79
 
80
cryptkeyres *(*__key_encryptsession_pk_LOCAL)() = 0;
81
cryptkeyres *(*__key_decryptsession_pk_LOCAL)() = 0;
82
des_block *(*__key_gendes_LOCAL)() = 0;
83
 
84
static int key_call __P(( u_long, xdrproc_t, char *, xdrproc_t, char * ));
85
 
86
int
87
key_setsecret(secretkey)
88
        const char *secretkey;
89
{
90
        keystatus status;
91
 
92
        if (!key_call((u_long) KEY_SET, xdr_keybuf, (char *) secretkey,
93
                        xdr_keystatus, (char *)&status)) {
94
                return (-1);
95
        }
96
        if (status != KEY_SUCCESS) {
97
                debug("set status is nonzero");
98
                return (-1);
99
        }
100
        return (0);
101
}
102
 
103
 
104
/* key_secretkey_is_set() returns 1 if the keyserver has a secret key
105
 * stored for the caller's effective uid; it returns 0 otherwise
106
 *
107
 * N.B.:  The KEY_NET_GET key call is undocumented.  Applications shouldn't
108
 * be using it, because it allows them to get the user's secret key.
109
 */
110
 
111
int
112
key_secretkey_is_set(void)
113
{
114
        struct key_netstres     kres;
115
 
116
        memset((void*)&kres, 0, sizeof (kres));
117
        if (key_call((u_long) KEY_NET_GET, xdr_void, (char *)NULL,
118
                        xdr_key_netstres, (char *) &kres) &&
119
            (kres.status == KEY_SUCCESS) &&
120
            (kres.key_netstres_u.knet.st_priv_key[0] != 0)) {
121
                /* avoid leaving secret key in memory */
122
                memset(kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES);
123
                return (1);
124
        }
125
        return (0);
126
}
127
 
128
int
129
key_encryptsession_pk(remotename, remotekey, deskey)
130
        char *remotename;
131
        netobj *remotekey;
132
        des_block *deskey;
133
{
134
        cryptkeyarg2 arg;
135
        cryptkeyres res;
136
 
137
        arg.remotename = remotename;
138
        arg.remotekey = *remotekey;
139
        arg.deskey = *deskey;
140
        if (!key_call((u_long)KEY_ENCRYPT_PK, xdr_cryptkeyarg2, (char *)&arg,
141
                        xdr_cryptkeyres, (char *)&res)) {
142
                return (-1);
143
        }
144
        if (res.status != KEY_SUCCESS) {
145
                debug("encrypt status is nonzero");
146
                return (-1);
147
        }
148
        *deskey = res.cryptkeyres_u.deskey;
149
        return (0);
150
}
151
 
152
int
153
key_decryptsession_pk(remotename, remotekey, deskey)
154
        char *remotename;
155
        netobj *remotekey;
156
        des_block *deskey;
157
{
158
        cryptkeyarg2 arg;
159
        cryptkeyres res;
160
 
161
        arg.remotename = remotename;
162
        arg.remotekey = *remotekey;
163
        arg.deskey = *deskey;
164
        if (!key_call((u_long)KEY_DECRYPT_PK, xdr_cryptkeyarg2, (char *)&arg,
165
                        xdr_cryptkeyres, (char *)&res)) {
166
                return (-1);
167
        }
168
        if (res.status != KEY_SUCCESS) {
169
                debug("decrypt status is nonzero");
170
                return (-1);
171
        }
172
        *deskey = res.cryptkeyres_u.deskey;
173
        return (0);
174
}
175
 
176
int
177
key_encryptsession(remotename, deskey)
178
        const char *remotename;
179
        des_block *deskey;
180
{
181
        cryptkeyarg arg;
182
        cryptkeyres res;
183
 
184
        arg.remotename = (char *) remotename;
185
        arg.deskey = *deskey;
186
        if (!key_call((u_long)KEY_ENCRYPT, xdr_cryptkeyarg, (char *)&arg,
187
                        xdr_cryptkeyres, (char *)&res)) {
188
                return (-1);
189
        }
190
        if (res.status != KEY_SUCCESS) {
191
                debug("encrypt status is nonzero");
192
                return (-1);
193
        }
194
        *deskey = res.cryptkeyres_u.deskey;
195
        return (0);
196
}
197
 
198
int
199
key_decryptsession(remotename, deskey)
200
        const char *remotename;
201
        des_block *deskey;
202
{
203
        cryptkeyarg arg;
204
        cryptkeyres res;
205
 
206
        arg.remotename = (char *) remotename;
207
        arg.deskey = *deskey;
208
        if (!key_call((u_long)KEY_DECRYPT, xdr_cryptkeyarg, (char *)&arg,
209
                        xdr_cryptkeyres, (char *)&res)) {
210
                return (-1);
211
        }
212
        if (res.status != KEY_SUCCESS) {
213
                debug("decrypt status is nonzero");
214
                return (-1);
215
        }
216
        *deskey = res.cryptkeyres_u.deskey;
217
        return (0);
218
}
219
 
220
int
221
key_gendes(key)
222
        des_block *key;
223
{
224
        if (!key_call((u_long)KEY_GEN, xdr_void, (char *)NULL,
225
                        xdr_des_block, (char *)key)) {
226
                return (-1);
227
        }
228
        return (0);
229
}
230
 
231
int
232
key_setnet(arg)
233
struct netstarg *arg;
234
{
235
        keystatus status;
236
 
237
 
238
        if (!key_call((u_long) KEY_NET_PUT, xdr_key_netstarg, (char *) arg,
239
                xdr_keystatus, (char *) &status)){
240
                return (-1);
241
        }
242
 
243
        if (status != KEY_SUCCESS) {
244
                debug("key_setnet status is nonzero");
245
                return (-1);
246
        }
247
        return (1);
248
}
249
 
250
 
251
int
252
key_get_conv(pkey, deskey)
253
        char *pkey;
254
        des_block *deskey;
255
{
256
        cryptkeyres res;
257
 
258
        if (!key_call((u_long) KEY_GET_CONV, xdr_keybuf, pkey,
259
                xdr_cryptkeyres, (char *)&res)) {
260
                return (-1);
261
        }
262
        if (res.status != KEY_SUCCESS) {
263
                debug("get_conv status is nonzero");
264
                return (-1);
265
        }
266
        *deskey = res.cryptkeyres_u.deskey;
267
        return (0);
268
}
269
 
270
struct  key_call_private {
271
        CLIENT  *client;        /* Client handle */
272
        pid_t   pid;            /* process-id at moment of creation */
273
        uid_t   uid;            /* user-id at last authorization */
274
};
275
static struct key_call_private *key_call_private_main = NULL;
276
 
277
#ifdef foo
278
static void
279
key_call_destroy(void *vp)
280
{
281
        register struct key_call_private *kcp = (struct key_call_private *)vp;
282
 
283
        if (kcp) {
284
                if (kcp->client)
285
                        clnt_destroy(kcp->client);
286
                free(kcp);
287
        }
288
}
289
#endif
290
 
291
/*
292
 * Keep the handle cached.  This call may be made quite often.
293
 */
294
static CLIENT *
295
getkeyserv_handle(vers)
296
int     vers;
297
{
298
        struct key_call_private *kcp = key_call_private_main;
299
        struct timeval wait_time;
300
        int fd;
301
        struct sockaddr_un name;
302
        int namelen = sizeof(struct sockaddr_un);
303
 
304
#define TOTAL_TIMEOUT   30      /* total timeout talking to keyserver */
305
#define TOTAL_TRIES     5       /* Number of tries */
306
 
307
        if (kcp == (struct key_call_private *)NULL) {
308
                kcp = (struct key_call_private *)malloc(sizeof (*kcp));
309
                if (kcp == (struct key_call_private *)NULL) {
310
                        return ((CLIENT *) NULL);
311
                }
312
                key_call_private_main = kcp;
313
                kcp->client = NULL;
314
        }
315
 
316
        /* if pid has changed, destroy client and rebuild */
317
        if (kcp->client != NULL && kcp->pid != getpid()) {
318
                clnt_destroy(kcp->client);
319
                kcp->client = NULL;
320
        }
321
 
322
        if (kcp->client != NULL) {
323
                /* if other side closed socket, build handle again */
324
                clnt_control(kcp->client, CLGET_FD, (char *)&fd);
325
                if (getpeername(fd,(struct sockaddr *)&name,&namelen) == -1) {
326
                        auth_destroy(kcp->client->cl_auth);
327
                        clnt_destroy(kcp->client);
328
                        kcp->client = NULL;
329
                }
330
        }
331
 
332
        if (kcp->client != NULL) {
333
                /* if uid has changed, build client handle again */
334
                if (kcp->uid != geteuid()) {
335
                        kcp->uid = geteuid();
336
                        auth_destroy(kcp->client->cl_auth);
337
                        kcp->client->cl_auth =
338
                                authsys_create("", kcp->uid, 0, 0, NULL);
339
                        if (kcp->client->cl_auth == NULL) {
340
                                clnt_destroy(kcp->client);
341
                                kcp->client = NULL;
342
                                return ((CLIENT *) NULL);
343
                        }
344
                }
345
                /* Change the version number to the new one */
346
                clnt_control(kcp->client, CLSET_VERS, (void *)&vers);
347
                return (kcp->client);
348
        }
349
 
350
        if ((kcp->client == (CLIENT *) NULL))
351
                /* Use the AF_UNIX transport */
352
                kcp->client = clnt_create("/var/run/keyservsock", KEY_PROG,
353
                                                        vers, "unix");
354
 
355
        if (kcp->client == (CLIENT *) NULL) {
356
                return ((CLIENT *) NULL);
357
        }
358
        kcp->uid = geteuid();
359
        kcp->pid = getpid();
360
        kcp->client->cl_auth = authsys_create("", kcp->uid, 0, 0, NULL);
361
        if (kcp->client->cl_auth == NULL) {
362
                clnt_destroy(kcp->client);
363
                kcp->client = NULL;
364
                return ((CLIENT *) NULL);
365
        }
366
 
367
        wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES;
368
        wait_time.tv_usec = 0;
369
        (void) clnt_control(kcp->client, CLSET_RETRY_TIMEOUT,
370
                (char *)&wait_time);
371
        if (clnt_control(kcp->client, CLGET_FD, (char *)&fd))
372
                _fcntl(fd, F_SETFD, 1); /* make it "close on exec" */
373
 
374
        return (kcp->client);
375
}
376
 
377
/* returns  0 on failure, 1 on success */
378
 
379
static int
380
key_call(proc, xdr_arg, arg, xdr_rslt, rslt)
381
        u_long proc;
382
        xdrproc_t xdr_arg;
383
        char *arg;
384
        xdrproc_t xdr_rslt;
385
        char *rslt;
386
{
387
        CLIENT *clnt;
388
        struct timeval wait_time;
389
 
390
        if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL) {
391
                cryptkeyres *res;
392
                res = (*__key_encryptsession_pk_LOCAL)(geteuid(), arg);
393
                *(cryptkeyres*)rslt = *res;
394
                return (1);
395
        } else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL) {
396
                cryptkeyres *res;
397
                res = (*__key_decryptsession_pk_LOCAL)(geteuid(), arg);
398
                *(cryptkeyres*)rslt = *res;
399
                return (1);
400
        } else if (proc == KEY_GEN && __key_gendes_LOCAL) {
401
                des_block *res;
402
                res = (*__key_gendes_LOCAL)(geteuid(), 0);
403
                *(des_block*)rslt = *res;
404
                return (1);
405
        }
406
 
407
        if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) ||
408
            (proc == KEY_NET_GET) || (proc == KEY_NET_PUT) ||
409
            (proc == KEY_GET_CONV))
410
                clnt = getkeyserv_handle(2); /* talk to version 2 */
411
        else
412
                clnt = getkeyserv_handle(1); /* talk to version 1 */
413
 
414
        if (clnt == NULL) {
415
                return (0);
416
        }
417
 
418
        wait_time.tv_sec = TOTAL_TIMEOUT;
419
        wait_time.tv_usec = 0;
420
 
421
        if (clnt_call(clnt, proc, xdr_arg, arg, xdr_rslt, rslt,
422
                wait_time) == RPC_SUCCESS) {
423
                return (1);
424
        } else {
425
                return (0);
426
        }
427
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.