freebsd-dev/lib/librpc/secure_rpc/keyserv/keyenvoy.c
1994-05-27 05:00:24 +00:00

214 lines
4.7 KiB
C

#ifndef lint
static char sccsid[] = "@(#)keyenvoy.c 2.2 88/08/10 4.0 RPCSRC";
#endif
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (C) 1986, Sun Microsystems, Inc.
*/
#include <stdio.h>
#include <rpc/rpc.h>
#include <rpc/key_prot.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <fcntl.h>
/*
* Talk to the keyserver on a privileged port on the part of a calling program.
*
* Protocol is for caller to send through stdin the procedure number
* to call followed by the argument data. We call the keyserver, and
* send the results back to the caller through stdout.
* Non-zero exit status means something went wrong.
*/
#ifndef DEBUG
#define debug(msg)
#endif
#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */
#define TOTAL_TRIES 10 /* Number of tries */
/*
* Opaque data that we send and receive
*/
#define MAXOPAQUE 256
struct opaqn {
u_int len;
u_int data[MAXOPAQUE];
};
bool_t xdr_opaqn();
main(argc,argv)
int argc;
char *argv[];
{
XDR xdrs_args;
XDR xdrs_rslt;
int proc;
struct opaqn args, rslt;
if (isatty(0)) {
fprintf(stderr,
"This program cannot be used interactively.\n");
exit(1);
}
#ifdef DEBUG
close(2);
open("/dev/console", O_WRONLY, 0);
#endif
xdrstdio_create(&xdrs_args, stdin, XDR_DECODE);
xdrstdio_create(&xdrs_rslt, stdout, XDR_ENCODE);
if ( ! xdr_u_long(&xdrs_args, &proc)) {
debug("no proc");
exit(1);
}
if (! xdr_opaqn(&xdrs_args, &args)) {
debug("recving args failed");
exit(1);
}
if (! callkeyserver(proc, xdr_opaqn, &args, xdr_opaqn, &rslt)) {
debug("rpc_call failed");
exit(1);
}
if (! xdr_opaqn(&xdrs_rslt, &rslt)) {
debug("sending args failed");
exit(1);
}
exit(0);
}
callkeyserver(proc, xdr_args, args, xdr_rslt, rslt)
u_long proc;
bool_t (*xdr_args)();
void *args;
bool_t (*xdr_rslt)();
void *rslt;
{
struct sockaddr_in remote;
int port;
struct timeval wait;
enum clnt_stat stat;
CLIENT *client;
int sd;
/*
* set up the remote address
* and create client
*/
remote.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
remote.sin_family = AF_INET;
remote.sin_port = 0;
wait.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES; wait.tv_usec = 0;
sd = RPC_ANYSOCK;
client = clntudp_create(&remote, KEY_PROG, KEY_VERS, wait, &sd);
if (client == NULL) {
debug("no client");
return (0);
}
/*
* Check that server is bound to a reserved port, so
* that noone can masquerade as the keyserver.
*/
if (ntohs(remote.sin_port) >= IPPORT_RESERVED) {
debug("insecure port");
return (0);
}
/*
* Create authentication
* All we care about really is sending the real uid
*/
client->cl_auth = authunix_create("", getuid(), 0, 0, NULL);
if (client->cl_auth == NULL) {
debug("no auth");
return (0);
}
wait.tv_sec = TOTAL_TIMEOUT; wait.tv_usec = 0;
stat = clnt_call(client, proc, xdr_args, args, xdr_rslt, rslt, wait);
if (stat != RPC_SUCCESS) {
debug("clnt_call failed");
}
return (stat == RPC_SUCCESS);
}
/*
* XDR opaque data
* Don't know the length on decode, so just keep receiving until failure.
*/
bool_t
xdr_opaqn(xdrs, objp)
XDR *xdrs;
struct opaqn *objp;
{
int i;
switch (xdrs->x_op) {
case XDR_FREE:
break;
case XDR_DECODE:
for (i = 0; i < MAXOPAQUE && xdr_int(xdrs, &objp->data[i]); i++) {
}
if (i == MAXOPAQUE) {
return (FALSE);
}
objp->len = i;
break;
case XDR_ENCODE:
for (i = 0; i < objp->len; i++) {
if (! xdr_int(xdrs, &objp->data[i])) {
return (FALSE);
}
}
break;
}
return (TRUE);
}
#ifdef DEBUG
debug(msg)
char *msg;
{
fprintf(stderr, "%s\n", msg);
}
#endif