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 { 227bd344e96SAndrey A. Chernov #ifndef __FreeBSD__ 22851251b2bSBill Paul int i; 22951251b2bSBill Paul int seed; 23051251b2bSBill Paul struct timeval tv; 23151251b2bSBill Paul int shift; 23251251b2bSBill Paul 23351251b2bSBill Paul seed = 0; 23451251b2bSBill Paul for (i = 0; i < 1024; i++) { 23551251b2bSBill Paul (void) gettimeofday(&tv, (struct timezone *) NULL); 23651251b2bSBill Paul shift = i % 8 * sizeof (int); 23751251b2bSBill Paul seed ^= (tv.tv_usec << shift) | (tv.tv_usec >> (32 - shift)); 23851251b2bSBill Paul } 239bd344e96SAndrey A. Chernov #endif 24051251b2bSBill Paul #ifdef KEYSERV_RANDOM 241bd344e96SAndrey A. Chernov #ifdef __FreeBSD__ 2426cf217b2SKris Kennaway master->key.low = arc4random(); 2436cf217b2SKris Kennaway master->key.high = arc4random(); 244bd344e96SAndrey A. Chernov #else 24551251b2bSBill Paul srandom(seed); 24651251b2bSBill Paul master->key.low = random(); 24751251b2bSBill Paul master->key.high = random(); 2486cf217b2SKris Kennaway #endif 24951251b2bSBill Paul #else 25051251b2bSBill Paul /* use stupid dangerous bad rand() */ 251bd344e96SAndrey A. Chernov #ifdef __FreeBSD__ 252bd344e96SAndrey A. Chernov sranddev(); 253bd344e96SAndrey A. Chernov #else 25451251b2bSBill Paul srand(seed); 255bd344e96SAndrey A. Chernov #endif 25651251b2bSBill Paul master->key.low = rand(); 25751251b2bSBill Paul master->key.high = rand(); 25851251b2bSBill Paul #endif 25951251b2bSBill Paul } 26051251b2bSBill Paul 26151251b2bSBill Paul /* 26251251b2bSBill Paul * Try to get root's secret key, by prompting if terminal is a tty, else trying 26351251b2bSBill Paul * from standard input. 26451251b2bSBill Paul * Returns 1 on success. 26551251b2bSBill Paul */ 26651251b2bSBill Paul static int 26751251b2bSBill Paul getrootkey(master, prompt) 26851251b2bSBill Paul des_block *master; 26951251b2bSBill Paul int prompt; 27051251b2bSBill Paul { 27151251b2bSBill Paul char *passwd; 27251251b2bSBill Paul char name[MAXNETNAMELEN + 1]; 27351251b2bSBill Paul char secret[HEXKEYBYTES]; 27451251b2bSBill Paul key_netstarg netstore; 27551251b2bSBill Paul int fd; 27651251b2bSBill Paul 27751251b2bSBill Paul if (!prompt) { 27851251b2bSBill Paul /* 27951251b2bSBill Paul * Read secret key out of ROOTKEY 28051251b2bSBill Paul */ 28151251b2bSBill Paul fd = open(ROOTKEY, O_RDONLY, 0); 28251251b2bSBill Paul if (fd < 0) { 28351251b2bSBill Paul randomize(master); 28451251b2bSBill Paul return (0); 28551251b2bSBill Paul } 28651251b2bSBill Paul if (read(fd, secret, HEXKEYBYTES) < HEXKEYBYTES) { 287ecdf56e7SPhilippe Charnier warnx("the key read from %s was too short", ROOTKEY); 28851251b2bSBill Paul (void) close(fd); 28951251b2bSBill Paul return (0); 29051251b2bSBill Paul } 29151251b2bSBill Paul (void) close(fd); 29251251b2bSBill Paul if (!getnetname(name)) { 293ecdf56e7SPhilippe Charnier warnx( 294ecdf56e7SPhilippe Charnier "failed to generate host's netname when establishing root's key"); 29551251b2bSBill Paul return (0); 29651251b2bSBill Paul } 29751251b2bSBill Paul memcpy(netstore.st_priv_key, secret, HEXKEYBYTES); 29851251b2bSBill Paul memset(netstore.st_pub_key, 0, HEXKEYBYTES); 29951251b2bSBill Paul netstore.st_netname = name; 30051251b2bSBill Paul if (pk_netput(0, &netstore) != KEY_SUCCESS) { 301ecdf56e7SPhilippe Charnier warnx("could not set root's key and netname"); 30251251b2bSBill Paul return (0); 30351251b2bSBill Paul } 30451251b2bSBill Paul return (1); 30551251b2bSBill Paul } 30651251b2bSBill Paul /* 30751251b2bSBill Paul * Decrypt yellow pages publickey entry to get secret key 30851251b2bSBill Paul */ 30951251b2bSBill Paul passwd = getpass("root password:"); 31051251b2bSBill Paul passwd2des(passwd, (char *)master); 31151251b2bSBill Paul getnetname(name); 31251251b2bSBill Paul if (!getsecretkey(name, secret, passwd)) { 313ecdf56e7SPhilippe Charnier warnx("can't find %s's secret key", name); 31451251b2bSBill Paul return (0); 31551251b2bSBill Paul } 31651251b2bSBill Paul if (secret[0] == 0) { 317ecdf56e7SPhilippe Charnier warnx("password does not decrypt secret key for %s", name); 31851251b2bSBill Paul return (0); 31951251b2bSBill Paul } 32051251b2bSBill Paul (void) pk_setkey(0, secret); 32151251b2bSBill Paul /* 32251251b2bSBill Paul * Store it for future use in $ROOTKEY, if possible 32351251b2bSBill Paul */ 32451251b2bSBill Paul fd = open(ROOTKEY, O_WRONLY|O_TRUNC|O_CREAT, 0); 32551251b2bSBill Paul if (fd > 0) { 32651251b2bSBill Paul char newline = '\n'; 32751251b2bSBill Paul 32851251b2bSBill Paul write(fd, secret, strlen(secret)); 32951251b2bSBill Paul write(fd, &newline, sizeof (newline)); 33051251b2bSBill Paul close(fd); 33151251b2bSBill Paul } 33251251b2bSBill Paul return (1); 33351251b2bSBill Paul } 33451251b2bSBill Paul 33551251b2bSBill Paul /* 33651251b2bSBill Paul * Procedures to implement RPC service 33751251b2bSBill Paul */ 33851251b2bSBill Paul char * 33951251b2bSBill Paul strstatus(status) 34051251b2bSBill Paul keystatus status; 34151251b2bSBill Paul { 34251251b2bSBill Paul switch (status) { 34351251b2bSBill Paul case KEY_SUCCESS: 34451251b2bSBill Paul return ("KEY_SUCCESS"); 34551251b2bSBill Paul case KEY_NOSECRET: 34651251b2bSBill Paul return ("KEY_NOSECRET"); 34751251b2bSBill Paul case KEY_UNKNOWN: 34851251b2bSBill Paul return ("KEY_UNKNOWN"); 34951251b2bSBill Paul case KEY_SYSTEMERR: 35051251b2bSBill Paul return ("KEY_SYSTEMERR"); 35151251b2bSBill Paul default: 35251251b2bSBill Paul return ("(bad result code)"); 35351251b2bSBill Paul } 35451251b2bSBill Paul } 35551251b2bSBill Paul 35651251b2bSBill Paul keystatus * 35751251b2bSBill Paul key_set_1_svc_prog(uid, key) 35851251b2bSBill Paul uid_t uid; 35951251b2bSBill Paul keybuf key; 36051251b2bSBill Paul { 36151251b2bSBill Paul static keystatus status; 36251251b2bSBill Paul 36351251b2bSBill Paul if (debugging) { 36451251b2bSBill Paul (void) fprintf(stderr, "set(%ld, %.*s) = ", uid, 36551251b2bSBill Paul (int) sizeof (keybuf), key); 36651251b2bSBill Paul } 36751251b2bSBill Paul status = pk_setkey(uid, key); 36851251b2bSBill Paul if (debugging) { 36951251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(status)); 37051251b2bSBill Paul (void) fflush(stderr); 37151251b2bSBill Paul } 37251251b2bSBill Paul return (&status); 37351251b2bSBill Paul } 37451251b2bSBill Paul 37551251b2bSBill Paul cryptkeyres * 37651251b2bSBill Paul key_encrypt_pk_2_svc_prog(uid, arg) 37751251b2bSBill Paul uid_t uid; 37851251b2bSBill Paul cryptkeyarg2 *arg; 37951251b2bSBill Paul { 38051251b2bSBill Paul static cryptkeyres res; 38151251b2bSBill Paul 38251251b2bSBill Paul if (debugging) { 38351251b2bSBill Paul (void) fprintf(stderr, "encrypt(%ld, %s, %08x%08x) = ", uid, 38451251b2bSBill Paul arg->remotename, arg->deskey.key.high, 38551251b2bSBill Paul arg->deskey.key.low); 38651251b2bSBill Paul } 38751251b2bSBill Paul res.cryptkeyres_u.deskey = arg->deskey; 38851251b2bSBill Paul res.status = pk_encrypt(uid, arg->remotename, &(arg->remotekey), 38951251b2bSBill Paul &res.cryptkeyres_u.deskey); 39051251b2bSBill Paul if (debugging) { 39151251b2bSBill Paul if (res.status == KEY_SUCCESS) { 39251251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 39351251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 39451251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 39551251b2bSBill Paul } else { 39651251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 39751251b2bSBill Paul } 39851251b2bSBill Paul (void) fflush(stderr); 39951251b2bSBill Paul } 40051251b2bSBill Paul return (&res); 40151251b2bSBill Paul } 40251251b2bSBill Paul 40351251b2bSBill Paul cryptkeyres * 40451251b2bSBill Paul key_decrypt_pk_2_svc_prog(uid, arg) 40551251b2bSBill Paul uid_t uid; 40651251b2bSBill Paul cryptkeyarg2 *arg; 40751251b2bSBill Paul { 40851251b2bSBill Paul static cryptkeyres res; 40951251b2bSBill Paul 41051251b2bSBill Paul if (debugging) { 41151251b2bSBill Paul (void) fprintf(stderr, "decrypt(%ld, %s, %08x%08x) = ", uid, 41251251b2bSBill Paul arg->remotename, arg->deskey.key.high, 41351251b2bSBill Paul arg->deskey.key.low); 41451251b2bSBill Paul } 41551251b2bSBill Paul res.cryptkeyres_u.deskey = arg->deskey; 41651251b2bSBill Paul res.status = pk_decrypt(uid, arg->remotename, &(arg->remotekey), 41751251b2bSBill Paul &res.cryptkeyres_u.deskey); 41851251b2bSBill Paul if (debugging) { 41951251b2bSBill Paul if (res.status == KEY_SUCCESS) { 42051251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 42151251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 42251251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 42351251b2bSBill Paul } else { 42451251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 42551251b2bSBill Paul } 42651251b2bSBill Paul (void) fflush(stderr); 42751251b2bSBill Paul } 42851251b2bSBill Paul return (&res); 42951251b2bSBill Paul } 43051251b2bSBill Paul 43151251b2bSBill Paul keystatus * 43251251b2bSBill Paul key_net_put_2_svc_prog(uid, arg) 43351251b2bSBill Paul uid_t uid; 43451251b2bSBill Paul key_netstarg *arg; 43551251b2bSBill Paul { 43651251b2bSBill Paul static keystatus status; 43751251b2bSBill Paul 43851251b2bSBill Paul if (debugging) { 43951251b2bSBill Paul (void) fprintf(stderr, "net_put(%s, %.*s, %.*s) = ", 44051251b2bSBill Paul arg->st_netname, (int)sizeof (arg->st_pub_key), 44151251b2bSBill Paul arg->st_pub_key, (int)sizeof (arg->st_priv_key), 44251251b2bSBill Paul arg->st_priv_key); 44351251b2bSBill Paul }; 44451251b2bSBill Paul 44551251b2bSBill Paul status = pk_netput(uid, arg); 44651251b2bSBill Paul 44751251b2bSBill Paul if (debugging) { 44851251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(status)); 44951251b2bSBill Paul (void) fflush(stderr); 45051251b2bSBill Paul } 45151251b2bSBill Paul 45251251b2bSBill Paul return (&status); 45351251b2bSBill Paul } 45451251b2bSBill Paul 45551251b2bSBill Paul key_netstres * 45651251b2bSBill Paul key_net_get_2_svc_prog(uid, arg) 45751251b2bSBill Paul uid_t uid; 45851251b2bSBill Paul void *arg; 45951251b2bSBill Paul { 46051251b2bSBill Paul static key_netstres keynetname; 46151251b2bSBill Paul 46251251b2bSBill Paul if (debugging) 46351251b2bSBill Paul (void) fprintf(stderr, "net_get(%ld) = ", uid); 46451251b2bSBill Paul 46551251b2bSBill Paul keynetname.status = pk_netget(uid, &keynetname.key_netstres_u.knet); 46651251b2bSBill Paul if (debugging) { 46751251b2bSBill Paul if (keynetname.status == KEY_SUCCESS) { 46851251b2bSBill Paul fprintf(stderr, "<%s, %.*s, %.*s>\n", 46951251b2bSBill Paul keynetname.key_netstres_u.knet.st_netname, 47051251b2bSBill Paul (int)sizeof (keynetname.key_netstres_u.knet.st_pub_key), 47151251b2bSBill Paul keynetname.key_netstres_u.knet.st_pub_key, 47251251b2bSBill Paul (int)sizeof (keynetname.key_netstres_u.knet.st_priv_key), 47351251b2bSBill Paul keynetname.key_netstres_u.knet.st_priv_key); 47451251b2bSBill Paul } else { 47551251b2bSBill Paul (void) fprintf(stderr, "NOT FOUND\n"); 47651251b2bSBill Paul } 47751251b2bSBill Paul (void) fflush(stderr); 47851251b2bSBill Paul } 47951251b2bSBill Paul 48051251b2bSBill Paul return (&keynetname); 48151251b2bSBill Paul 48251251b2bSBill Paul } 48351251b2bSBill Paul 48451251b2bSBill Paul cryptkeyres * 48551251b2bSBill Paul key_get_conv_2_svc_prog(uid, arg) 48651251b2bSBill Paul uid_t uid; 48751251b2bSBill Paul keybuf arg; 48851251b2bSBill Paul { 48951251b2bSBill Paul static cryptkeyres res; 49051251b2bSBill Paul 49151251b2bSBill Paul if (debugging) 49251251b2bSBill Paul (void) fprintf(stderr, "get_conv(%ld, %.*s) = ", uid, 49351251b2bSBill Paul (int)sizeof (arg), arg); 49451251b2bSBill Paul 49551251b2bSBill Paul 49651251b2bSBill Paul res.status = pk_get_conv_key(uid, arg, &res); 49751251b2bSBill Paul 49851251b2bSBill Paul if (debugging) { 49951251b2bSBill Paul if (res.status == KEY_SUCCESS) { 50051251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 50151251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 50251251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 50351251b2bSBill Paul } else { 50451251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 50551251b2bSBill Paul } 50651251b2bSBill Paul (void) fflush(stderr); 50751251b2bSBill Paul } 50851251b2bSBill Paul return (&res); 50951251b2bSBill Paul } 51051251b2bSBill Paul 51151251b2bSBill Paul 51251251b2bSBill Paul cryptkeyres * 51351251b2bSBill Paul key_encrypt_1_svc_prog(uid, arg) 51451251b2bSBill Paul uid_t uid; 51551251b2bSBill Paul cryptkeyarg *arg; 51651251b2bSBill Paul { 51751251b2bSBill Paul static cryptkeyres res; 51851251b2bSBill Paul 51951251b2bSBill Paul if (debugging) { 52051251b2bSBill Paul (void) fprintf(stderr, "encrypt(%ld, %s, %08x%08x) = ", uid, 52151251b2bSBill Paul arg->remotename, arg->deskey.key.high, 52251251b2bSBill Paul arg->deskey.key.low); 52351251b2bSBill Paul } 52451251b2bSBill Paul res.cryptkeyres_u.deskey = arg->deskey; 52551251b2bSBill Paul res.status = pk_encrypt(uid, arg->remotename, NULL, 52651251b2bSBill Paul &res.cryptkeyres_u.deskey); 52751251b2bSBill Paul if (debugging) { 52851251b2bSBill Paul if (res.status == KEY_SUCCESS) { 52951251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 53051251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 53151251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 53251251b2bSBill Paul } else { 53351251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 53451251b2bSBill Paul } 53551251b2bSBill Paul (void) fflush(stderr); 53651251b2bSBill Paul } 53751251b2bSBill Paul return (&res); 53851251b2bSBill Paul } 53951251b2bSBill Paul 54051251b2bSBill Paul cryptkeyres * 54151251b2bSBill Paul key_decrypt_1_svc_prog(uid, arg) 54251251b2bSBill Paul uid_t uid; 54351251b2bSBill Paul cryptkeyarg *arg; 54451251b2bSBill Paul { 54551251b2bSBill Paul static cryptkeyres res; 54651251b2bSBill Paul 54751251b2bSBill Paul if (debugging) { 54851251b2bSBill Paul (void) fprintf(stderr, "decrypt(%ld, %s, %08x%08x) = ", uid, 54951251b2bSBill Paul arg->remotename, arg->deskey.key.high, 55051251b2bSBill Paul arg->deskey.key.low); 55151251b2bSBill Paul } 55251251b2bSBill Paul res.cryptkeyres_u.deskey = arg->deskey; 55351251b2bSBill Paul res.status = pk_decrypt(uid, arg->remotename, NULL, 55451251b2bSBill Paul &res.cryptkeyres_u.deskey); 55551251b2bSBill Paul if (debugging) { 55651251b2bSBill Paul if (res.status == KEY_SUCCESS) { 55751251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 55851251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 55951251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 56051251b2bSBill Paul } else { 56151251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 56251251b2bSBill Paul } 56351251b2bSBill Paul (void) fflush(stderr); 56451251b2bSBill Paul } 56551251b2bSBill Paul return (&res); 56651251b2bSBill Paul } 56751251b2bSBill Paul 56851251b2bSBill Paul /* ARGSUSED */ 56951251b2bSBill Paul des_block * 57051251b2bSBill Paul key_gen_1_svc_prog(v, s) 57151251b2bSBill Paul void *v; 57251251b2bSBill Paul struct svc_req *s; 57351251b2bSBill Paul { 57451251b2bSBill Paul struct timeval time; 57551251b2bSBill Paul static des_block keygen; 57651251b2bSBill Paul static des_block key; 57751251b2bSBill Paul 57851251b2bSBill Paul (void) gettimeofday(&time, (struct timezone *) NULL); 57951251b2bSBill Paul keygen.key.high += (time.tv_sec ^ time.tv_usec); 58051251b2bSBill Paul keygen.key.low += (time.tv_sec ^ time.tv_usec); 58151251b2bSBill Paul ecb_crypt((char *)&masterkey, (char *)&keygen, sizeof (keygen), 58251251b2bSBill Paul DES_ENCRYPT | DES_HW); 58351251b2bSBill Paul key = keygen; 58451251b2bSBill Paul des_setparity((char *)&key); 58551251b2bSBill Paul if (debugging) { 58651251b2bSBill Paul (void) fprintf(stderr, "gen() = %08x%08x\n", key.key.high, 58751251b2bSBill Paul key.key.low); 58851251b2bSBill Paul (void) fflush(stderr); 58951251b2bSBill Paul } 59051251b2bSBill Paul return (&key); 59151251b2bSBill Paul } 59251251b2bSBill Paul 59351251b2bSBill Paul getcredres * 59451251b2bSBill Paul key_getcred_1_svc_prog(uid, name) 59551251b2bSBill Paul uid_t uid; 59651251b2bSBill Paul netnamestr *name; 59751251b2bSBill Paul { 59851251b2bSBill Paul static getcredres res; 59951251b2bSBill Paul static u_int gids[NGROUPS]; 60051251b2bSBill Paul struct unixcred *cred; 60151251b2bSBill Paul 60251251b2bSBill Paul cred = &res.getcredres_u.cred; 60351251b2bSBill Paul cred->gids.gids_val = gids; 60451251b2bSBill Paul if (!netname2user(*name, (uid_t *) &cred->uid, (gid_t *) &cred->gid, 60551251b2bSBill Paul (int *)&cred->gids.gids_len, (gid_t *)gids)) { 60651251b2bSBill Paul res.status = KEY_UNKNOWN; 60751251b2bSBill Paul } else { 60851251b2bSBill Paul res.status = KEY_SUCCESS; 60951251b2bSBill Paul } 61051251b2bSBill Paul if (debugging) { 61151251b2bSBill Paul (void) fprintf(stderr, "getcred(%s) = ", *name); 61251251b2bSBill Paul if (res.status == KEY_SUCCESS) { 61351251b2bSBill Paul (void) fprintf(stderr, "uid=%d, gid=%d, grouplen=%d\n", 61451251b2bSBill Paul cred->uid, cred->gid, cred->gids.gids_len); 61551251b2bSBill Paul } else { 61651251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 61751251b2bSBill Paul } 61851251b2bSBill Paul (void) fflush(stderr); 61951251b2bSBill Paul } 62051251b2bSBill Paul return (&res); 62151251b2bSBill Paul } 62251251b2bSBill Paul 62351251b2bSBill Paul /* 62451251b2bSBill Paul * RPC boilerplate 62551251b2bSBill Paul */ 62651251b2bSBill Paul static void 62751251b2bSBill Paul keyprogram(rqstp, transp) 62851251b2bSBill Paul struct svc_req *rqstp; 62951251b2bSBill Paul SVCXPRT *transp; 63051251b2bSBill Paul { 63151251b2bSBill Paul union { 63251251b2bSBill Paul keybuf key_set_1_arg; 63351251b2bSBill Paul cryptkeyarg key_encrypt_1_arg; 63451251b2bSBill Paul cryptkeyarg key_decrypt_1_arg; 63551251b2bSBill Paul netnamestr key_getcred_1_arg; 63651251b2bSBill Paul cryptkeyarg key_encrypt_2_arg; 63751251b2bSBill Paul cryptkeyarg key_decrypt_2_arg; 63851251b2bSBill Paul netnamestr key_getcred_2_arg; 63951251b2bSBill Paul cryptkeyarg2 key_encrypt_pk_2_arg; 64051251b2bSBill Paul cryptkeyarg2 key_decrypt_pk_2_arg; 64151251b2bSBill Paul key_netstarg key_net_put_2_arg; 64251251b2bSBill Paul netobj key_get_conv_2_arg; 64351251b2bSBill Paul } argument; 64451251b2bSBill Paul char *result; 645f249dbccSDag-Erling Smørgrav xdrproc_t xdr_argument, xdr_result; 64651251b2bSBill Paul char *(*local) (); 64751251b2bSBill Paul uid_t uid = -1; 64851251b2bSBill Paul int check_auth; 64951251b2bSBill Paul 65051251b2bSBill Paul switch (rqstp->rq_proc) { 65151251b2bSBill Paul case NULLPROC: 652f249dbccSDag-Erling Smørgrav svc_sendreply(transp, (xdrproc_t)xdr_void, NULL); 65351251b2bSBill Paul return; 65451251b2bSBill Paul 65551251b2bSBill Paul case KEY_SET: 656f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_keybuf; 657f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_int; 65851251b2bSBill Paul local = (char *(*)()) key_set_1_svc_prog; 65951251b2bSBill Paul check_auth = 1; 66051251b2bSBill Paul break; 66151251b2bSBill Paul 66251251b2bSBill Paul case KEY_ENCRYPT: 663f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_cryptkeyarg; 664f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_cryptkeyres; 66551251b2bSBill Paul local = (char *(*)()) key_encrypt_1_svc_prog; 66651251b2bSBill Paul check_auth = 1; 66751251b2bSBill Paul break; 66851251b2bSBill Paul 66951251b2bSBill Paul case KEY_DECRYPT: 670f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_cryptkeyarg; 671f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_cryptkeyres; 67251251b2bSBill Paul local = (char *(*)()) key_decrypt_1_svc_prog; 67351251b2bSBill Paul check_auth = 1; 67451251b2bSBill Paul break; 67551251b2bSBill Paul 67651251b2bSBill Paul case KEY_GEN: 677f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_void; 678f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_des_block; 67951251b2bSBill Paul local = (char *(*)()) key_gen_1_svc_prog; 68051251b2bSBill Paul check_auth = 0; 68151251b2bSBill Paul break; 68251251b2bSBill Paul 68351251b2bSBill Paul case KEY_GETCRED: 684f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_netnamestr; 685f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_getcredres; 68651251b2bSBill Paul local = (char *(*)()) key_getcred_1_svc_prog; 68751251b2bSBill Paul check_auth = 0; 68851251b2bSBill Paul break; 68951251b2bSBill Paul 69051251b2bSBill Paul case KEY_ENCRYPT_PK: 691f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_cryptkeyarg2; 692f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_cryptkeyres; 69351251b2bSBill Paul local = (char *(*)()) key_encrypt_pk_2_svc_prog; 69451251b2bSBill Paul check_auth = 1; 69551251b2bSBill Paul break; 69651251b2bSBill Paul 69751251b2bSBill Paul case KEY_DECRYPT_PK: 698f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_cryptkeyarg2; 699f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_cryptkeyres; 70051251b2bSBill Paul local = (char *(*)()) key_decrypt_pk_2_svc_prog; 70151251b2bSBill Paul check_auth = 1; 70251251b2bSBill Paul break; 70351251b2bSBill Paul 70451251b2bSBill Paul 70551251b2bSBill Paul case KEY_NET_PUT: 706f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_key_netstarg; 707f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_keystatus; 70851251b2bSBill Paul local = (char *(*)()) key_net_put_2_svc_prog; 70951251b2bSBill Paul check_auth = 1; 71051251b2bSBill Paul break; 71151251b2bSBill Paul 71251251b2bSBill Paul case KEY_NET_GET: 71351251b2bSBill Paul xdr_argument = (xdrproc_t) xdr_void; 714f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_key_netstres; 71551251b2bSBill Paul local = (char *(*)()) key_net_get_2_svc_prog; 71651251b2bSBill Paul check_auth = 1; 71751251b2bSBill Paul break; 71851251b2bSBill Paul 71951251b2bSBill Paul case KEY_GET_CONV: 72051251b2bSBill Paul xdr_argument = (xdrproc_t) xdr_keybuf; 721f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_cryptkeyres; 72251251b2bSBill Paul local = (char *(*)()) key_get_conv_2_svc_prog; 72351251b2bSBill Paul check_auth = 1; 72451251b2bSBill Paul break; 72551251b2bSBill Paul 72651251b2bSBill Paul default: 72751251b2bSBill Paul svcerr_noproc(transp); 72851251b2bSBill Paul return; 72951251b2bSBill Paul } 73051251b2bSBill Paul if (check_auth) { 73151251b2bSBill Paul if (root_auth(transp, rqstp) == 0) { 73251251b2bSBill Paul if (debugging) { 73351251b2bSBill Paul (void) fprintf(stderr, 73451251b2bSBill Paul "not local privileged process\n"); 73551251b2bSBill Paul } 73651251b2bSBill Paul svcerr_weakauth(transp); 73751251b2bSBill Paul return; 73851251b2bSBill Paul } 73951251b2bSBill Paul if (rqstp->rq_cred.oa_flavor != AUTH_SYS) { 74051251b2bSBill Paul if (debugging) { 74151251b2bSBill Paul (void) fprintf(stderr, 74251251b2bSBill Paul "not unix authentication\n"); 74351251b2bSBill Paul } 74451251b2bSBill Paul svcerr_weakauth(transp); 74551251b2bSBill Paul return; 74651251b2bSBill Paul } 74751251b2bSBill Paul uid = ((struct authsys_parms *)rqstp->rq_clntcred)->aup_uid; 74851251b2bSBill Paul } 74951251b2bSBill Paul 750f249dbccSDag-Erling Smørgrav memset(&argument, 0, sizeof (argument)); 751f249dbccSDag-Erling Smørgrav if (!svc_getargs(transp, xdr_argument, &argument)) { 75251251b2bSBill Paul svcerr_decode(transp); 75351251b2bSBill Paul return; 75451251b2bSBill Paul } 75551251b2bSBill Paul result = (*local) (uid, &argument); 756f249dbccSDag-Erling Smørgrav if (!svc_sendreply(transp, xdr_result, result)) { 75751251b2bSBill Paul if (debugging) 75851251b2bSBill Paul (void) fprintf(stderr, "unable to reply\n"); 75951251b2bSBill Paul svcerr_systemerr(transp); 76051251b2bSBill Paul } 761f249dbccSDag-Erling Smørgrav if (!svc_freeargs(transp, xdr_argument, &argument)) { 76251251b2bSBill Paul if (debugging) 76351251b2bSBill Paul (void) fprintf(stderr, 76451251b2bSBill Paul "unable to free arguments\n"); 76551251b2bSBill Paul exit(1); 76651251b2bSBill Paul } 76751251b2bSBill Paul return; 76851251b2bSBill Paul } 76951251b2bSBill Paul 77051251b2bSBill Paul static int 77151251b2bSBill Paul root_auth(trans, rqstp) 77251251b2bSBill Paul SVCXPRT *trans; 77351251b2bSBill Paul struct svc_req *rqstp; 77451251b2bSBill Paul { 77551251b2bSBill Paul uid_t uid; 776af37179bSAlfred Perlstein struct sockaddr *remote; 77751251b2bSBill Paul 778af37179bSAlfred Perlstein remote = svc_getrpccaller(trans)->buf; 779af37179bSAlfred Perlstein if (remote->sa_family != AF_UNIX) { 78051251b2bSBill Paul if (debugging) 78151251b2bSBill Paul fprintf(stderr, "client didn't use AF_UNIX\n"); 78251251b2bSBill Paul return (0); 78351251b2bSBill Paul } 78451251b2bSBill Paul 7854ed6d634SAlfred Perlstein if (__rpc_get_local_uid(trans, &uid) < 0) { 78651251b2bSBill Paul if (debugging) 78751251b2bSBill Paul fprintf(stderr, "__rpc_get_local_uid failed\n"); 78851251b2bSBill Paul return (0); 78951251b2bSBill Paul } 79051251b2bSBill Paul 79151251b2bSBill Paul if (debugging) 79251251b2bSBill Paul fprintf(stderr, "local_uid %ld\n", uid); 79351251b2bSBill Paul if (uid == 0) 79451251b2bSBill Paul return (1); 79551251b2bSBill Paul if (rqstp->rq_cred.oa_flavor == AUTH_SYS) { 79651251b2bSBill Paul if (((uid_t) ((struct authunix_parms *) 79751251b2bSBill Paul rqstp->rq_clntcred)->aup_uid) 79851251b2bSBill Paul == uid) { 79951251b2bSBill Paul return (1); 80051251b2bSBill Paul } else { 80151251b2bSBill Paul if (debugging) 80251251b2bSBill Paul fprintf(stderr, 80351251b2bSBill Paul "local_uid %ld mismatches auth %ld\n", uid, 80451251b2bSBill Paul ((uid_t) ((struct authunix_parms *)rqstp->rq_clntcred)->aup_uid)); 80551251b2bSBill Paul return (0); 80651251b2bSBill Paul } 80751251b2bSBill Paul } else { 80851251b2bSBill Paul if (debugging) 80951251b2bSBill Paul fprintf(stderr, "Not auth sys\n"); 81051251b2bSBill Paul return (0); 81151251b2bSBill Paul } 81251251b2bSBill Paul } 81351251b2bSBill Paul 81451251b2bSBill Paul static void 81551251b2bSBill Paul usage() 81651251b2bSBill Paul { 81751251b2bSBill Paul (void) fprintf(stderr, 81851251b2bSBill Paul "usage: keyserv [-n] [-D] [-d] [-v] [-p path]\n"); 81951251b2bSBill Paul (void) fprintf(stderr, "-d disables the use of default keys\n"); 82051251b2bSBill Paul exit(1); 82151251b2bSBill Paul } 822