151251b2bSBill Paul /* 251251b2bSBill Paul * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 351251b2bSBill Paul * unrestricted use provided that this legend is included on all tape 451251b2bSBill Paul * media and as a part of the software program in whole or part. Users 551251b2bSBill Paul * may copy or modify Sun RPC without charge, but are not authorized 651251b2bSBill Paul * to license or distribute it to anyone else except as part of a product or 751251b2bSBill Paul * program developed by the user. 851251b2bSBill Paul * 951251b2bSBill Paul * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1051251b2bSBill Paul * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1151251b2bSBill Paul * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1251251b2bSBill Paul * 1351251b2bSBill Paul * Sun RPC is provided with no support and without any obligation on the 1451251b2bSBill Paul * part of Sun Microsystems, Inc. to assist in its use, correction, 1551251b2bSBill Paul * modification or enhancement. 1651251b2bSBill Paul * 1751251b2bSBill Paul * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 1851251b2bSBill Paul * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 1951251b2bSBill Paul * OR ANY PART THEREOF. 2051251b2bSBill Paul * 2151251b2bSBill Paul * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2251251b2bSBill Paul * or profits or other special, indirect and consequential damages, even if 2351251b2bSBill Paul * Sun has been advised of the possibility of such damages. 2451251b2bSBill Paul * 2551251b2bSBill Paul * Sun Microsystems, Inc. 2651251b2bSBill Paul * 2550 Garcia Avenue 2751251b2bSBill Paul * Mountain View, California 94043 2851251b2bSBill Paul */ 2951251b2bSBill Paul 30ecdf56e7SPhilippe Charnier #ifndef lint 31ecdf56e7SPhilippe Charnier #if 0 32ecdf56e7SPhilippe Charnier static char sccsid[] = "@(#)keyserv.c 1.15 94/04/25 SMI"; 33ecdf56e7SPhilippe Charnier #endif 34ecdf56e7SPhilippe Charnier static const char rcsid[] = 3597d92980SPeter Wemm "$FreeBSD$"; 36ecdf56e7SPhilippe Charnier #endif /* not lint */ 3751251b2bSBill Paul 3851251b2bSBill Paul /* 3951251b2bSBill Paul * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. 4051251b2bSBill Paul */ 4151251b2bSBill Paul 4251251b2bSBill Paul /* 4351251b2bSBill Paul * Keyserver 4451251b2bSBill Paul * Store secret keys per uid. Do public key encryption and decryption 4551251b2bSBill Paul * operations. Generate "random" keys. 4651251b2bSBill Paul * Do not talk to anything but a local root 4751251b2bSBill Paul * process on the local transport only 4851251b2bSBill Paul */ 4951251b2bSBill Paul 50ecdf56e7SPhilippe Charnier #include <err.h> 51ecdf56e7SPhilippe Charnier #include <pwd.h> 5251251b2bSBill Paul #include <stdio.h> 5351251b2bSBill Paul #include <stdlib.h> 5451251b2bSBill Paul #include <string.h> 55ecdf56e7SPhilippe Charnier #include <unistd.h> 5651251b2bSBill Paul #include <sys/stat.h> 5751251b2bSBill Paul #include <sys/types.h> 5851251b2bSBill Paul #include <rpc/rpc.h> 5951251b2bSBill Paul #include <sys/param.h> 6051251b2bSBill Paul #include <sys/file.h> 6151251b2bSBill Paul #include <rpc/des_crypt.h> 6251251b2bSBill Paul #include <rpc/des.h> 6351251b2bSBill Paul #include <rpc/key_prot.h> 6451251b2bSBill Paul #include <rpcsvc/crypt.h> 6551251b2bSBill Paul #include "keyserv.h" 6651251b2bSBill Paul 6751251b2bSBill Paul #ifndef NGROUPS 6851251b2bSBill Paul #define NGROUPS 16 6951251b2bSBill Paul #endif 7051251b2bSBill Paul 7151251b2bSBill Paul #ifndef KEYSERVSOCK 7251251b2bSBill Paul #define KEYSERVSOCK "/var/run/keyservsock" 7351251b2bSBill Paul #endif 7451251b2bSBill Paul 7551251b2bSBill Paul static void randomize __P(( des_block * )); 7651251b2bSBill Paul static void usage __P(( void )); 7751251b2bSBill Paul static int getrootkey __P(( des_block *, int )); 7851251b2bSBill Paul static int root_auth __P(( SVCXPRT *, struct svc_req * )); 7951251b2bSBill Paul 8051251b2bSBill Paul #ifdef DEBUG 8151251b2bSBill Paul static int debugging = 1; 8251251b2bSBill Paul #else 8351251b2bSBill Paul static int debugging = 0; 8451251b2bSBill Paul #endif 8551251b2bSBill Paul 8651251b2bSBill Paul static void keyprogram(); 8751251b2bSBill Paul static des_block masterkey; 8851251b2bSBill Paul char *getenv(); 8951251b2bSBill Paul static char ROOTKEY[] = "/etc/.rootkey"; 9051251b2bSBill Paul 9151251b2bSBill Paul /* 9251251b2bSBill Paul * Hack to allow the keyserver to use AUTH_DES (for authenticated 9351251b2bSBill Paul * NIS+ calls, for example). The only functions that get called 9451251b2bSBill Paul * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes. 9551251b2bSBill Paul * 9651251b2bSBill Paul * The approach is to have the keyserver fill in pointers to local 9751251b2bSBill Paul * implementations of these functions, and to call those in key_call(). 9851251b2bSBill Paul */ 9951251b2bSBill Paul 10051251b2bSBill Paul extern cryptkeyres *(*__key_encryptsession_pk_LOCAL)(); 10151251b2bSBill Paul extern cryptkeyres *(*__key_decryptsession_pk_LOCAL)(); 10251251b2bSBill Paul extern des_block *(*__key_gendes_LOCAL)(); 10351251b2bSBill Paul extern int (*__des_crypt_LOCAL)(); 10451251b2bSBill Paul 10551251b2bSBill Paul cryptkeyres *key_encrypt_pk_2_svc_prog __P(( uid_t, cryptkeyarg2 * )); 10651251b2bSBill Paul cryptkeyres *key_decrypt_pk_2_svc_prog __P(( uid_t, cryptkeyarg2 * )); 10751251b2bSBill Paul des_block *key_gen_1_svc_prog __P(( void *, struct svc_req * )); 10851251b2bSBill Paul 10951251b2bSBill Paul int 11051251b2bSBill Paul main(argc, argv) 11151251b2bSBill Paul int argc; 11251251b2bSBill Paul char *argv[]; 11351251b2bSBill Paul { 11451251b2bSBill Paul int nflag = 0; 11551251b2bSBill Paul int c; 11651251b2bSBill Paul int warn = 0; 11751251b2bSBill Paul char *path = NULL; 11898fb6503SAlfred Perlstein void *localhandle; 11998fb6503SAlfred Perlstein register SVCXPRT *transp; 12098fb6503SAlfred Perlstein struct netconfig *nconf = NULL; 12151251b2bSBill Paul 12251251b2bSBill Paul __key_encryptsession_pk_LOCAL = &key_encrypt_pk_2_svc_prog; 12351251b2bSBill Paul __key_decryptsession_pk_LOCAL = &key_decrypt_pk_2_svc_prog; 12451251b2bSBill Paul __key_gendes_LOCAL = &key_gen_1_svc_prog; 12551251b2bSBill Paul 12651251b2bSBill Paul while ((c = getopt(argc, argv, "ndDvp:")) != -1) 12751251b2bSBill Paul switch (c) { 12851251b2bSBill Paul case 'n': 12951251b2bSBill Paul nflag++; 13051251b2bSBill Paul break; 13151251b2bSBill Paul case 'd': 13251251b2bSBill Paul pk_nodefaultkeys(); 13351251b2bSBill Paul break; 13451251b2bSBill Paul case 'D': 13551251b2bSBill Paul debugging = 1; 13651251b2bSBill Paul break; 13751251b2bSBill Paul case 'v': 13851251b2bSBill Paul warn = 1; 13951251b2bSBill Paul break; 14051251b2bSBill Paul case 'p': 14151251b2bSBill Paul path = optarg; 14251251b2bSBill Paul break; 14351251b2bSBill Paul default: 14451251b2bSBill Paul usage(); 14551251b2bSBill Paul } 14651251b2bSBill Paul 14751251b2bSBill Paul load_des(warn, path); 14851251b2bSBill Paul __des_crypt_LOCAL = _my_crypt; 149ecdf56e7SPhilippe Charnier if (svc_auth_reg(AUTH_DES, _svcauth_des) == -1) 150ecdf56e7SPhilippe Charnier errx(1, "failed to register AUTH_DES authenticator"); 15151251b2bSBill Paul 15251251b2bSBill Paul if (optind != argc) { 15351251b2bSBill Paul usage(); 15451251b2bSBill Paul } 15551251b2bSBill Paul 15651251b2bSBill Paul /* 15751251b2bSBill Paul * Initialize 15851251b2bSBill Paul */ 15998fb6503SAlfred Perlstein (void) umask(S_IXUSR|S_IXGRP|S_IXOTH); 160ecdf56e7SPhilippe Charnier if (geteuid() != 0) 161ecdf56e7SPhilippe Charnier errx(1, "keyserv must be run as root"); 16251251b2bSBill Paul setmodulus(HEXMODULUS); 16351251b2bSBill Paul getrootkey(&masterkey, nflag); 16451251b2bSBill Paul 16598fb6503SAlfred Perlstein rpcb_unset(KEY_PROG, KEY_VERS, NULL); 16698fb6503SAlfred Perlstein rpcb_unset(KEY_PROG, KEY_VERS2, NULL); 16798fb6503SAlfred Perlstein 1688360efbdSAlfred Perlstein if (svc_create(keyprogram, KEY_PROG, KEY_VERS, 1698360efbdSAlfred Perlstein "netpath") == 0) { 1708360efbdSAlfred Perlstein (void) fprintf(stderr, 1718360efbdSAlfred Perlstein "%s: unable to create service\n", argv[0]); 1728360efbdSAlfred Perlstein exit(1); 1738360efbdSAlfred Perlstein } 17451251b2bSBill Paul 1758360efbdSAlfred Perlstein if (svc_create(keyprogram, KEY_PROG, KEY_VERS2, 1768360efbdSAlfred Perlstein "netpath") == 0) { 1778360efbdSAlfred Perlstein (void) fprintf(stderr, 1788360efbdSAlfred Perlstein "%s: unable to create service\n", argv[0]); 1798360efbdSAlfred Perlstein exit(1); 1808360efbdSAlfred Perlstein } 18151251b2bSBill Paul 18298fb6503SAlfred Perlstein localhandle = setnetconfig(); 18398fb6503SAlfred Perlstein while ((nconf = getnetconfig(localhandle)) != NULL) { 18498fb6503SAlfred Perlstein if (nconf->nc_protofmly != NULL && 18598fb6503SAlfred Perlstein strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) 18698fb6503SAlfred Perlstein break; 18798fb6503SAlfred Perlstein } 18898fb6503SAlfred Perlstein 18998fb6503SAlfred Perlstein if (nconf == NULL) 19098fb6503SAlfred Perlstein errx(1, "getnetconfig: %s", nc_sperror()); 19198fb6503SAlfred Perlstein 19298fb6503SAlfred Perlstein unlink(KEYSERVSOCK); 19398fb6503SAlfred Perlstein rpcb_unset(CRYPT_PROG, CRYPT_VERS, nconf); 19498fb6503SAlfred Perlstein transp = svcunix_create(RPC_ANYSOCK, 0, 0, KEYSERVSOCK); 19598fb6503SAlfred Perlstein if (transp == NULL) 19698fb6503SAlfred Perlstein errx(1, "cannot create AF_LOCAL service"); 19798fb6503SAlfred Perlstein if (!svc_reg(transp, KEY_PROG, KEY_VERS, keyprogram, nconf)) 19898fb6503SAlfred Perlstein errx(1, "unable to register (KEY_PROG, KEY_VERS, unix)"); 19998fb6503SAlfred Perlstein if (!svc_reg(transp, KEY_PROG, KEY_VERS2, keyprogram, nconf)) 20098fb6503SAlfred Perlstein errx(1, "unable to register (KEY_PROG, KEY_VERS2, unix)"); 20198fb6503SAlfred Perlstein if (!svc_reg(transp, CRYPT_PROG, CRYPT_VERS, crypt_prog_1, nconf)) 20298fb6503SAlfred Perlstein errx(1, "unable to register (CRYPT_PROG, CRYPT_VERS, unix)"); 20398fb6503SAlfred Perlstein 20498fb6503SAlfred Perlstein endnetconfig(localhandle); 20598fb6503SAlfred Perlstein 20698fb6503SAlfred Perlstein (void) umask(066); /* paranoia */ 20798fb6503SAlfred Perlstein 20851251b2bSBill Paul if (!debugging) { 20951251b2bSBill Paul daemon(0,0); 21051251b2bSBill Paul } 21151251b2bSBill Paul 21298fb6503SAlfred Perlstein signal(SIGPIPE, SIG_IGN); 21398fb6503SAlfred Perlstein 21451251b2bSBill Paul svc_run(); 21551251b2bSBill Paul abort(); 21651251b2bSBill Paul /* NOTREACHED */ 21751251b2bSBill Paul } 21851251b2bSBill Paul 21951251b2bSBill Paul /* 22051251b2bSBill Paul * In the event that we don't get a root password, we try to 22151251b2bSBill Paul * randomize the master key the best we can 22251251b2bSBill Paul */ 22351251b2bSBill Paul static void 22451251b2bSBill Paul randomize(master) 22551251b2bSBill Paul des_block *master; 22651251b2bSBill Paul { 22751251b2bSBill Paul int i; 22851251b2bSBill Paul int seed; 22951251b2bSBill Paul struct timeval tv; 23051251b2bSBill Paul int shift; 23151251b2bSBill Paul 23251251b2bSBill Paul seed = 0; 23351251b2bSBill Paul for (i = 0; i < 1024; i++) { 23451251b2bSBill Paul (void) gettimeofday(&tv, (struct timezone *) NULL); 23551251b2bSBill Paul shift = i % 8 * sizeof (int); 23651251b2bSBill Paul seed ^= (tv.tv_usec << shift) | (tv.tv_usec >> (32 - shift)); 23751251b2bSBill Paul } 23851251b2bSBill Paul #ifdef KEYSERV_RANDOM 23951251b2bSBill Paul srandom(seed); 24051251b2bSBill Paul master->key.low = random(); 24151251b2bSBill Paul master->key.high = random(); 24251251b2bSBill Paul srandom(seed); 24351251b2bSBill Paul #else 24451251b2bSBill Paul /* use stupid dangerous bad rand() */ 24551251b2bSBill Paul srand(seed); 24651251b2bSBill Paul master->key.low = rand(); 24751251b2bSBill Paul master->key.high = rand(); 24851251b2bSBill Paul srand(seed); 24951251b2bSBill Paul #endif 25051251b2bSBill Paul } 25151251b2bSBill Paul 25251251b2bSBill Paul /* 25351251b2bSBill Paul * Try to get root's secret key, by prompting if terminal is a tty, else trying 25451251b2bSBill Paul * from standard input. 25551251b2bSBill Paul * Returns 1 on success. 25651251b2bSBill Paul */ 25751251b2bSBill Paul static int 25851251b2bSBill Paul getrootkey(master, prompt) 25951251b2bSBill Paul des_block *master; 26051251b2bSBill Paul int prompt; 26151251b2bSBill Paul { 26251251b2bSBill Paul char *passwd; 26351251b2bSBill Paul char name[MAXNETNAMELEN + 1]; 26451251b2bSBill Paul char secret[HEXKEYBYTES]; 26551251b2bSBill Paul key_netstarg netstore; 26651251b2bSBill Paul int fd; 26751251b2bSBill Paul 26851251b2bSBill Paul if (!prompt) { 26951251b2bSBill Paul /* 27051251b2bSBill Paul * Read secret key out of ROOTKEY 27151251b2bSBill Paul */ 27251251b2bSBill Paul fd = open(ROOTKEY, O_RDONLY, 0); 27351251b2bSBill Paul if (fd < 0) { 27451251b2bSBill Paul randomize(master); 27551251b2bSBill Paul return (0); 27651251b2bSBill Paul } 27751251b2bSBill Paul if (read(fd, secret, HEXKEYBYTES) < HEXKEYBYTES) { 278ecdf56e7SPhilippe Charnier warnx("the key read from %s was too short", ROOTKEY); 27951251b2bSBill Paul (void) close(fd); 28051251b2bSBill Paul return (0); 28151251b2bSBill Paul } 28251251b2bSBill Paul (void) close(fd); 28351251b2bSBill Paul if (!getnetname(name)) { 284ecdf56e7SPhilippe Charnier warnx( 285ecdf56e7SPhilippe Charnier "failed to generate host's netname when establishing root's key"); 28651251b2bSBill Paul return (0); 28751251b2bSBill Paul } 28851251b2bSBill Paul memcpy(netstore.st_priv_key, secret, HEXKEYBYTES); 28951251b2bSBill Paul memset(netstore.st_pub_key, 0, HEXKEYBYTES); 29051251b2bSBill Paul netstore.st_netname = name; 29151251b2bSBill Paul if (pk_netput(0, &netstore) != KEY_SUCCESS) { 292ecdf56e7SPhilippe Charnier warnx("could not set root's key and netname"); 29351251b2bSBill Paul return (0); 29451251b2bSBill Paul } 29551251b2bSBill Paul return (1); 29651251b2bSBill Paul } 29751251b2bSBill Paul /* 29851251b2bSBill Paul * Decrypt yellow pages publickey entry to get secret key 29951251b2bSBill Paul */ 30051251b2bSBill Paul passwd = getpass("root password:"); 30151251b2bSBill Paul passwd2des(passwd, (char *)master); 30251251b2bSBill Paul getnetname(name); 30351251b2bSBill Paul if (!getsecretkey(name, secret, passwd)) { 304ecdf56e7SPhilippe Charnier warnx("can't find %s's secret key", name); 30551251b2bSBill Paul return (0); 30651251b2bSBill Paul } 30751251b2bSBill Paul if (secret[0] == 0) { 308ecdf56e7SPhilippe Charnier warnx("password does not decrypt secret key for %s", name); 30951251b2bSBill Paul return (0); 31051251b2bSBill Paul } 31151251b2bSBill Paul (void) pk_setkey(0, secret); 31251251b2bSBill Paul /* 31351251b2bSBill Paul * Store it for future use in $ROOTKEY, if possible 31451251b2bSBill Paul */ 31551251b2bSBill Paul fd = open(ROOTKEY, O_WRONLY|O_TRUNC|O_CREAT, 0); 31651251b2bSBill Paul if (fd > 0) { 31751251b2bSBill Paul char newline = '\n'; 31851251b2bSBill Paul 31951251b2bSBill Paul write(fd, secret, strlen(secret)); 32051251b2bSBill Paul write(fd, &newline, sizeof (newline)); 32151251b2bSBill Paul close(fd); 32251251b2bSBill Paul } 32351251b2bSBill Paul return (1); 32451251b2bSBill Paul } 32551251b2bSBill Paul 32651251b2bSBill Paul /* 32751251b2bSBill Paul * Procedures to implement RPC service 32851251b2bSBill Paul */ 32951251b2bSBill Paul char * 33051251b2bSBill Paul strstatus(status) 33151251b2bSBill Paul keystatus status; 33251251b2bSBill Paul { 33351251b2bSBill Paul switch (status) { 33451251b2bSBill Paul case KEY_SUCCESS: 33551251b2bSBill Paul return ("KEY_SUCCESS"); 33651251b2bSBill Paul case KEY_NOSECRET: 33751251b2bSBill Paul return ("KEY_NOSECRET"); 33851251b2bSBill Paul case KEY_UNKNOWN: 33951251b2bSBill Paul return ("KEY_UNKNOWN"); 34051251b2bSBill Paul case KEY_SYSTEMERR: 34151251b2bSBill Paul return ("KEY_SYSTEMERR"); 34251251b2bSBill Paul default: 34351251b2bSBill Paul return ("(bad result code)"); 34451251b2bSBill Paul } 34551251b2bSBill Paul } 34651251b2bSBill Paul 34751251b2bSBill Paul keystatus * 34851251b2bSBill Paul key_set_1_svc_prog(uid, key) 34951251b2bSBill Paul uid_t uid; 35051251b2bSBill Paul keybuf key; 35151251b2bSBill Paul { 35251251b2bSBill Paul static keystatus status; 35351251b2bSBill Paul 35451251b2bSBill Paul if (debugging) { 35551251b2bSBill Paul (void) fprintf(stderr, "set(%ld, %.*s) = ", uid, 35651251b2bSBill Paul (int) sizeof (keybuf), key); 35751251b2bSBill Paul } 35851251b2bSBill Paul status = pk_setkey(uid, key); 35951251b2bSBill Paul if (debugging) { 36051251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(status)); 36151251b2bSBill Paul (void) fflush(stderr); 36251251b2bSBill Paul } 36351251b2bSBill Paul return (&status); 36451251b2bSBill Paul } 36551251b2bSBill Paul 36651251b2bSBill Paul cryptkeyres * 36751251b2bSBill Paul key_encrypt_pk_2_svc_prog(uid, arg) 36851251b2bSBill Paul uid_t uid; 36951251b2bSBill Paul cryptkeyarg2 *arg; 37051251b2bSBill Paul { 37151251b2bSBill Paul static cryptkeyres res; 37251251b2bSBill Paul 37351251b2bSBill Paul if (debugging) { 37451251b2bSBill Paul (void) fprintf(stderr, "encrypt(%ld, %s, %08x%08x) = ", uid, 37551251b2bSBill Paul arg->remotename, arg->deskey.key.high, 37651251b2bSBill Paul arg->deskey.key.low); 37751251b2bSBill Paul } 37851251b2bSBill Paul res.cryptkeyres_u.deskey = arg->deskey; 37951251b2bSBill Paul res.status = pk_encrypt(uid, arg->remotename, &(arg->remotekey), 38051251b2bSBill Paul &res.cryptkeyres_u.deskey); 38151251b2bSBill Paul if (debugging) { 38251251b2bSBill Paul if (res.status == KEY_SUCCESS) { 38351251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 38451251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 38551251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 38651251b2bSBill Paul } else { 38751251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 38851251b2bSBill Paul } 38951251b2bSBill Paul (void) fflush(stderr); 39051251b2bSBill Paul } 39151251b2bSBill Paul return (&res); 39251251b2bSBill Paul } 39351251b2bSBill Paul 39451251b2bSBill Paul cryptkeyres * 39551251b2bSBill Paul key_decrypt_pk_2_svc_prog(uid, arg) 39651251b2bSBill Paul uid_t uid; 39751251b2bSBill Paul cryptkeyarg2 *arg; 39851251b2bSBill Paul { 39951251b2bSBill Paul static cryptkeyres res; 40051251b2bSBill Paul 40151251b2bSBill Paul if (debugging) { 40251251b2bSBill Paul (void) fprintf(stderr, "decrypt(%ld, %s, %08x%08x) = ", uid, 40351251b2bSBill Paul arg->remotename, arg->deskey.key.high, 40451251b2bSBill Paul arg->deskey.key.low); 40551251b2bSBill Paul } 40651251b2bSBill Paul res.cryptkeyres_u.deskey = arg->deskey; 40751251b2bSBill Paul res.status = pk_decrypt(uid, arg->remotename, &(arg->remotekey), 40851251b2bSBill Paul &res.cryptkeyres_u.deskey); 40951251b2bSBill Paul if (debugging) { 41051251b2bSBill Paul if (res.status == KEY_SUCCESS) { 41151251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 41251251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 41351251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 41451251b2bSBill Paul } else { 41551251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 41651251b2bSBill Paul } 41751251b2bSBill Paul (void) fflush(stderr); 41851251b2bSBill Paul } 41951251b2bSBill Paul return (&res); 42051251b2bSBill Paul } 42151251b2bSBill Paul 42251251b2bSBill Paul keystatus * 42351251b2bSBill Paul key_net_put_2_svc_prog(uid, arg) 42451251b2bSBill Paul uid_t uid; 42551251b2bSBill Paul key_netstarg *arg; 42651251b2bSBill Paul { 42751251b2bSBill Paul static keystatus status; 42851251b2bSBill Paul 42951251b2bSBill Paul if (debugging) { 43051251b2bSBill Paul (void) fprintf(stderr, "net_put(%s, %.*s, %.*s) = ", 43151251b2bSBill Paul arg->st_netname, (int)sizeof (arg->st_pub_key), 43251251b2bSBill Paul arg->st_pub_key, (int)sizeof (arg->st_priv_key), 43351251b2bSBill Paul arg->st_priv_key); 43451251b2bSBill Paul }; 43551251b2bSBill Paul 43651251b2bSBill Paul status = pk_netput(uid, arg); 43751251b2bSBill Paul 43851251b2bSBill Paul if (debugging) { 43951251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(status)); 44051251b2bSBill Paul (void) fflush(stderr); 44151251b2bSBill Paul } 44251251b2bSBill Paul 44351251b2bSBill Paul return (&status); 44451251b2bSBill Paul } 44551251b2bSBill Paul 44651251b2bSBill Paul key_netstres * 44751251b2bSBill Paul key_net_get_2_svc_prog(uid, arg) 44851251b2bSBill Paul uid_t uid; 44951251b2bSBill Paul void *arg; 45051251b2bSBill Paul { 45151251b2bSBill Paul static key_netstres keynetname; 45251251b2bSBill Paul 45351251b2bSBill Paul if (debugging) 45451251b2bSBill Paul (void) fprintf(stderr, "net_get(%ld) = ", uid); 45551251b2bSBill Paul 45651251b2bSBill Paul keynetname.status = pk_netget(uid, &keynetname.key_netstres_u.knet); 45751251b2bSBill Paul if (debugging) { 45851251b2bSBill Paul if (keynetname.status == KEY_SUCCESS) { 45951251b2bSBill Paul fprintf(stderr, "<%s, %.*s, %.*s>\n", 46051251b2bSBill Paul keynetname.key_netstres_u.knet.st_netname, 46151251b2bSBill Paul (int)sizeof (keynetname.key_netstres_u.knet.st_pub_key), 46251251b2bSBill Paul keynetname.key_netstres_u.knet.st_pub_key, 46351251b2bSBill Paul (int)sizeof (keynetname.key_netstres_u.knet.st_priv_key), 46451251b2bSBill Paul keynetname.key_netstres_u.knet.st_priv_key); 46551251b2bSBill Paul } else { 46651251b2bSBill Paul (void) fprintf(stderr, "NOT FOUND\n"); 46751251b2bSBill Paul } 46851251b2bSBill Paul (void) fflush(stderr); 46951251b2bSBill Paul } 47051251b2bSBill Paul 47151251b2bSBill Paul return (&keynetname); 47251251b2bSBill Paul 47351251b2bSBill Paul } 47451251b2bSBill Paul 47551251b2bSBill Paul cryptkeyres * 47651251b2bSBill Paul key_get_conv_2_svc_prog(uid, arg) 47751251b2bSBill Paul uid_t uid; 47851251b2bSBill Paul keybuf arg; 47951251b2bSBill Paul { 48051251b2bSBill Paul static cryptkeyres res; 48151251b2bSBill Paul 48251251b2bSBill Paul if (debugging) 48351251b2bSBill Paul (void) fprintf(stderr, "get_conv(%ld, %.*s) = ", uid, 48451251b2bSBill Paul (int)sizeof (arg), arg); 48551251b2bSBill Paul 48651251b2bSBill Paul 48751251b2bSBill Paul res.status = pk_get_conv_key(uid, arg, &res); 48851251b2bSBill Paul 48951251b2bSBill Paul if (debugging) { 49051251b2bSBill Paul if (res.status == KEY_SUCCESS) { 49151251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 49251251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 49351251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 49451251b2bSBill Paul } else { 49551251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 49651251b2bSBill Paul } 49751251b2bSBill Paul (void) fflush(stderr); 49851251b2bSBill Paul } 49951251b2bSBill Paul return (&res); 50051251b2bSBill Paul } 50151251b2bSBill Paul 50251251b2bSBill Paul 50351251b2bSBill Paul cryptkeyres * 50451251b2bSBill Paul key_encrypt_1_svc_prog(uid, arg) 50551251b2bSBill Paul uid_t uid; 50651251b2bSBill Paul cryptkeyarg *arg; 50751251b2bSBill Paul { 50851251b2bSBill Paul static cryptkeyres res; 50951251b2bSBill Paul 51051251b2bSBill Paul if (debugging) { 51151251b2bSBill Paul (void) fprintf(stderr, "encrypt(%ld, %s, %08x%08x) = ", uid, 51251251b2bSBill Paul arg->remotename, arg->deskey.key.high, 51351251b2bSBill Paul arg->deskey.key.low); 51451251b2bSBill Paul } 51551251b2bSBill Paul res.cryptkeyres_u.deskey = arg->deskey; 51651251b2bSBill Paul res.status = pk_encrypt(uid, arg->remotename, NULL, 51751251b2bSBill Paul &res.cryptkeyres_u.deskey); 51851251b2bSBill Paul if (debugging) { 51951251b2bSBill Paul if (res.status == KEY_SUCCESS) { 52051251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 52151251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 52251251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 52351251b2bSBill Paul } else { 52451251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 52551251b2bSBill Paul } 52651251b2bSBill Paul (void) fflush(stderr); 52751251b2bSBill Paul } 52851251b2bSBill Paul return (&res); 52951251b2bSBill Paul } 53051251b2bSBill Paul 53151251b2bSBill Paul cryptkeyres * 53251251b2bSBill Paul key_decrypt_1_svc_prog(uid, arg) 53351251b2bSBill Paul uid_t uid; 53451251b2bSBill Paul cryptkeyarg *arg; 53551251b2bSBill Paul { 53651251b2bSBill Paul static cryptkeyres res; 53751251b2bSBill Paul 53851251b2bSBill Paul if (debugging) { 53951251b2bSBill Paul (void) fprintf(stderr, "decrypt(%ld, %s, %08x%08x) = ", uid, 54051251b2bSBill Paul arg->remotename, arg->deskey.key.high, 54151251b2bSBill Paul arg->deskey.key.low); 54251251b2bSBill Paul } 54351251b2bSBill Paul res.cryptkeyres_u.deskey = arg->deskey; 54451251b2bSBill Paul res.status = pk_decrypt(uid, arg->remotename, NULL, 54551251b2bSBill Paul &res.cryptkeyres_u.deskey); 54651251b2bSBill Paul if (debugging) { 54751251b2bSBill Paul if (res.status == KEY_SUCCESS) { 54851251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 54951251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 55051251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 55151251b2bSBill Paul } else { 55251251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 55351251b2bSBill Paul } 55451251b2bSBill Paul (void) fflush(stderr); 55551251b2bSBill Paul } 55651251b2bSBill Paul return (&res); 55751251b2bSBill Paul } 55851251b2bSBill Paul 55951251b2bSBill Paul /* ARGSUSED */ 56051251b2bSBill Paul des_block * 56151251b2bSBill Paul key_gen_1_svc_prog(v, s) 56251251b2bSBill Paul void *v; 56351251b2bSBill Paul struct svc_req *s; 56451251b2bSBill Paul { 56551251b2bSBill Paul struct timeval time; 56651251b2bSBill Paul static des_block keygen; 56751251b2bSBill Paul static des_block key; 56851251b2bSBill Paul 56951251b2bSBill Paul (void) gettimeofday(&time, (struct timezone *) NULL); 57051251b2bSBill Paul keygen.key.high += (time.tv_sec ^ time.tv_usec); 57151251b2bSBill Paul keygen.key.low += (time.tv_sec ^ time.tv_usec); 57251251b2bSBill Paul ecb_crypt((char *)&masterkey, (char *)&keygen, sizeof (keygen), 57351251b2bSBill Paul DES_ENCRYPT | DES_HW); 57451251b2bSBill Paul key = keygen; 57551251b2bSBill Paul des_setparity((char *)&key); 57651251b2bSBill Paul if (debugging) { 57751251b2bSBill Paul (void) fprintf(stderr, "gen() = %08x%08x\n", key.key.high, 57851251b2bSBill Paul key.key.low); 57951251b2bSBill Paul (void) fflush(stderr); 58051251b2bSBill Paul } 58151251b2bSBill Paul return (&key); 58251251b2bSBill Paul } 58351251b2bSBill Paul 58451251b2bSBill Paul getcredres * 58551251b2bSBill Paul key_getcred_1_svc_prog(uid, name) 58651251b2bSBill Paul uid_t uid; 58751251b2bSBill Paul netnamestr *name; 58851251b2bSBill Paul { 58951251b2bSBill Paul static getcredres res; 59051251b2bSBill Paul static u_int gids[NGROUPS]; 59151251b2bSBill Paul struct unixcred *cred; 59251251b2bSBill Paul 59351251b2bSBill Paul cred = &res.getcredres_u.cred; 59451251b2bSBill Paul cred->gids.gids_val = gids; 59551251b2bSBill Paul if (!netname2user(*name, (uid_t *) &cred->uid, (gid_t *) &cred->gid, 59651251b2bSBill Paul (int *)&cred->gids.gids_len, (gid_t *)gids)) { 59751251b2bSBill Paul res.status = KEY_UNKNOWN; 59851251b2bSBill Paul } else { 59951251b2bSBill Paul res.status = KEY_SUCCESS; 60051251b2bSBill Paul } 60151251b2bSBill Paul if (debugging) { 60251251b2bSBill Paul (void) fprintf(stderr, "getcred(%s) = ", *name); 60351251b2bSBill Paul if (res.status == KEY_SUCCESS) { 60451251b2bSBill Paul (void) fprintf(stderr, "uid=%d, gid=%d, grouplen=%d\n", 60551251b2bSBill Paul cred->uid, cred->gid, cred->gids.gids_len); 60651251b2bSBill Paul } else { 60751251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 60851251b2bSBill Paul } 60951251b2bSBill Paul (void) fflush(stderr); 61051251b2bSBill Paul } 61151251b2bSBill Paul return (&res); 61251251b2bSBill Paul } 61351251b2bSBill Paul 61451251b2bSBill Paul /* 61551251b2bSBill Paul * RPC boilerplate 61651251b2bSBill Paul */ 61751251b2bSBill Paul static void 61851251b2bSBill Paul keyprogram(rqstp, transp) 61951251b2bSBill Paul struct svc_req *rqstp; 62051251b2bSBill Paul SVCXPRT *transp; 62151251b2bSBill Paul { 62251251b2bSBill Paul union { 62351251b2bSBill Paul keybuf key_set_1_arg; 62451251b2bSBill Paul cryptkeyarg key_encrypt_1_arg; 62551251b2bSBill Paul cryptkeyarg key_decrypt_1_arg; 62651251b2bSBill Paul netnamestr key_getcred_1_arg; 62751251b2bSBill Paul cryptkeyarg key_encrypt_2_arg; 62851251b2bSBill Paul cryptkeyarg key_decrypt_2_arg; 62951251b2bSBill Paul netnamestr key_getcred_2_arg; 63051251b2bSBill Paul cryptkeyarg2 key_encrypt_pk_2_arg; 63151251b2bSBill Paul cryptkeyarg2 key_decrypt_pk_2_arg; 63251251b2bSBill Paul key_netstarg key_net_put_2_arg; 63351251b2bSBill Paul netobj key_get_conv_2_arg; 63451251b2bSBill Paul } argument; 63551251b2bSBill Paul char *result; 63651251b2bSBill Paul bool_t(*xdr_argument)(), (*xdr_result)(); 63751251b2bSBill Paul char *(*local) (); 63851251b2bSBill Paul uid_t uid = -1; 63951251b2bSBill Paul int check_auth; 64051251b2bSBill Paul 64151251b2bSBill Paul switch (rqstp->rq_proc) { 64251251b2bSBill Paul case NULLPROC: 64351251b2bSBill Paul svc_sendreply(transp, xdr_void, (char *)NULL); 64451251b2bSBill Paul return; 64551251b2bSBill Paul 64651251b2bSBill Paul case KEY_SET: 64751251b2bSBill Paul xdr_argument = xdr_keybuf; 64851251b2bSBill Paul xdr_result = xdr_int; 64951251b2bSBill Paul local = (char *(*)()) key_set_1_svc_prog; 65051251b2bSBill Paul check_auth = 1; 65151251b2bSBill Paul break; 65251251b2bSBill Paul 65351251b2bSBill Paul case KEY_ENCRYPT: 65451251b2bSBill Paul xdr_argument = xdr_cryptkeyarg; 65551251b2bSBill Paul xdr_result = xdr_cryptkeyres; 65651251b2bSBill Paul local = (char *(*)()) key_encrypt_1_svc_prog; 65751251b2bSBill Paul check_auth = 1; 65851251b2bSBill Paul break; 65951251b2bSBill Paul 66051251b2bSBill Paul case KEY_DECRYPT: 66151251b2bSBill Paul xdr_argument = xdr_cryptkeyarg; 66251251b2bSBill Paul xdr_result = xdr_cryptkeyres; 66351251b2bSBill Paul local = (char *(*)()) key_decrypt_1_svc_prog; 66451251b2bSBill Paul check_auth = 1; 66551251b2bSBill Paul break; 66651251b2bSBill Paul 66751251b2bSBill Paul case KEY_GEN: 66851251b2bSBill Paul xdr_argument = xdr_void; 66951251b2bSBill Paul xdr_result = xdr_des_block; 67051251b2bSBill Paul local = (char *(*)()) key_gen_1_svc_prog; 67151251b2bSBill Paul check_auth = 0; 67251251b2bSBill Paul break; 67351251b2bSBill Paul 67451251b2bSBill Paul case KEY_GETCRED: 67551251b2bSBill Paul xdr_argument = xdr_netnamestr; 67651251b2bSBill Paul xdr_result = xdr_getcredres; 67751251b2bSBill Paul local = (char *(*)()) key_getcred_1_svc_prog; 67851251b2bSBill Paul check_auth = 0; 67951251b2bSBill Paul break; 68051251b2bSBill Paul 68151251b2bSBill Paul case KEY_ENCRYPT_PK: 68251251b2bSBill Paul xdr_argument = xdr_cryptkeyarg2; 68351251b2bSBill Paul xdr_result = xdr_cryptkeyres; 68451251b2bSBill Paul local = (char *(*)()) key_encrypt_pk_2_svc_prog; 68551251b2bSBill Paul check_auth = 1; 68651251b2bSBill Paul break; 68751251b2bSBill Paul 68851251b2bSBill Paul case KEY_DECRYPT_PK: 68951251b2bSBill Paul xdr_argument = xdr_cryptkeyarg2; 69051251b2bSBill Paul xdr_result = xdr_cryptkeyres; 69151251b2bSBill Paul local = (char *(*)()) key_decrypt_pk_2_svc_prog; 69251251b2bSBill Paul check_auth = 1; 69351251b2bSBill Paul break; 69451251b2bSBill Paul 69551251b2bSBill Paul 69651251b2bSBill Paul case KEY_NET_PUT: 69751251b2bSBill Paul xdr_argument = xdr_key_netstarg; 69851251b2bSBill Paul xdr_result = xdr_keystatus; 69951251b2bSBill Paul local = (char *(*)()) key_net_put_2_svc_prog; 70051251b2bSBill Paul check_auth = 1; 70151251b2bSBill Paul break; 70251251b2bSBill Paul 70351251b2bSBill Paul case KEY_NET_GET: 70451251b2bSBill Paul xdr_argument = (xdrproc_t) xdr_void; 70551251b2bSBill Paul xdr_result = xdr_key_netstres; 70651251b2bSBill Paul local = (char *(*)()) key_net_get_2_svc_prog; 70751251b2bSBill Paul check_auth = 1; 70851251b2bSBill Paul break; 70951251b2bSBill Paul 71051251b2bSBill Paul case KEY_GET_CONV: 71151251b2bSBill Paul xdr_argument = (xdrproc_t) xdr_keybuf; 71251251b2bSBill Paul xdr_result = xdr_cryptkeyres; 71351251b2bSBill Paul local = (char *(*)()) key_get_conv_2_svc_prog; 71451251b2bSBill Paul check_auth = 1; 71551251b2bSBill Paul break; 71651251b2bSBill Paul 71751251b2bSBill Paul default: 71851251b2bSBill Paul svcerr_noproc(transp); 71951251b2bSBill Paul return; 72051251b2bSBill Paul } 72151251b2bSBill Paul if (check_auth) { 72251251b2bSBill Paul if (root_auth(transp, rqstp) == 0) { 72351251b2bSBill Paul if (debugging) { 72451251b2bSBill Paul (void) fprintf(stderr, 72551251b2bSBill Paul "not local privileged process\n"); 72651251b2bSBill Paul } 72751251b2bSBill Paul svcerr_weakauth(transp); 72851251b2bSBill Paul return; 72951251b2bSBill Paul } 73051251b2bSBill Paul if (rqstp->rq_cred.oa_flavor != AUTH_SYS) { 73151251b2bSBill Paul if (debugging) { 73251251b2bSBill Paul (void) fprintf(stderr, 73351251b2bSBill Paul "not unix authentication\n"); 73451251b2bSBill Paul } 73551251b2bSBill Paul svcerr_weakauth(transp); 73651251b2bSBill Paul return; 73751251b2bSBill Paul } 73851251b2bSBill Paul uid = ((struct authsys_parms *)rqstp->rq_clntcred)->aup_uid; 73951251b2bSBill Paul } 74051251b2bSBill Paul 74151251b2bSBill Paul memset((char *) &argument, 0, sizeof (argument)); 74251251b2bSBill Paul if (!svc_getargs(transp, xdr_argument, (caddr_t)&argument)) { 74351251b2bSBill Paul svcerr_decode(transp); 74451251b2bSBill Paul return; 74551251b2bSBill Paul } 74651251b2bSBill Paul result = (*local) (uid, &argument); 74751251b2bSBill Paul if (!svc_sendreply(transp, xdr_result, (char *) result)) { 74851251b2bSBill Paul if (debugging) 74951251b2bSBill Paul (void) fprintf(stderr, "unable to reply\n"); 75051251b2bSBill Paul svcerr_systemerr(transp); 75151251b2bSBill Paul } 75251251b2bSBill Paul if (!svc_freeargs(transp, xdr_argument, (caddr_t)&argument)) { 75351251b2bSBill Paul if (debugging) 75451251b2bSBill Paul (void) fprintf(stderr, 75551251b2bSBill Paul "unable to free arguments\n"); 75651251b2bSBill Paul exit(1); 75751251b2bSBill Paul } 75851251b2bSBill Paul return; 75951251b2bSBill Paul } 76051251b2bSBill Paul 76151251b2bSBill Paul static int 76251251b2bSBill Paul root_auth(trans, rqstp) 76351251b2bSBill Paul SVCXPRT *trans; 76451251b2bSBill Paul struct svc_req *rqstp; 76551251b2bSBill Paul { 76651251b2bSBill Paul uid_t uid; 76751251b2bSBill Paul struct sockaddr_in *remote; 76851251b2bSBill Paul 76951251b2bSBill Paul remote = svc_getcaller(trans); 77051251b2bSBill Paul if (remote->sin_family == AF_INET) { 77151251b2bSBill Paul if (debugging) 77251251b2bSBill Paul fprintf(stderr, "client didn't use AF_UNIX\n"); 77351251b2bSBill Paul return (0); 77451251b2bSBill Paul } 77551251b2bSBill Paul 7764ed6d634SAlfred Perlstein if (__rpc_get_local_uid(trans, &uid) < 0) { 77751251b2bSBill Paul if (debugging) 77851251b2bSBill Paul fprintf(stderr, "__rpc_get_local_uid failed\n"); 77951251b2bSBill Paul return (0); 78051251b2bSBill Paul } 78151251b2bSBill Paul 78251251b2bSBill Paul if (debugging) 78351251b2bSBill Paul fprintf(stderr, "local_uid %ld\n", uid); 78451251b2bSBill Paul if (uid == 0) 78551251b2bSBill Paul return (1); 78651251b2bSBill Paul if (rqstp->rq_cred.oa_flavor == AUTH_SYS) { 78751251b2bSBill Paul if (((uid_t) ((struct authunix_parms *) 78851251b2bSBill Paul rqstp->rq_clntcred)->aup_uid) 78951251b2bSBill Paul == uid) { 79051251b2bSBill Paul return (1); 79151251b2bSBill Paul } else { 79251251b2bSBill Paul if (debugging) 79351251b2bSBill Paul fprintf(stderr, 79451251b2bSBill Paul "local_uid %ld mismatches auth %ld\n", uid, 79551251b2bSBill Paul ((uid_t) ((struct authunix_parms *)rqstp->rq_clntcred)->aup_uid)); 79651251b2bSBill Paul return (0); 79751251b2bSBill Paul } 79851251b2bSBill Paul } else { 79951251b2bSBill Paul if (debugging) 80051251b2bSBill Paul fprintf(stderr, "Not auth sys\n"); 80151251b2bSBill Paul return (0); 80251251b2bSBill Paul } 80351251b2bSBill Paul } 80451251b2bSBill Paul 80551251b2bSBill Paul static void 80651251b2bSBill Paul usage() 80751251b2bSBill Paul { 80851251b2bSBill Paul (void) fprintf(stderr, 80951251b2bSBill Paul "usage: keyserv [-n] [-D] [-d] [-v] [-p path]\n"); 81051251b2bSBill Paul (void) fprintf(stderr, "-d disables the use of default keys\n"); 81151251b2bSBill Paul exit(1); 81251251b2bSBill Paul } 813