214 lines
4.7 KiB
C
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
|