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 75784bddbcSKevin Lo static void randomize( des_block * ); 76784bddbcSKevin Lo static void usage( void ); 77784bddbcSKevin Lo static int getrootkey( des_block *, int ); 78784bddbcSKevin Lo static int root_auth( 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 8635a624c5SJohn Baldwin static void keyprogram(struct svc_req *rqstp, SVCXPRT *transp); 8751251b2bSBill Paul static des_block masterkey; 8851251b2bSBill Paul static char ROOTKEY[] = "/etc/.rootkey"; 8951251b2bSBill Paul 9051251b2bSBill Paul /* 9151251b2bSBill Paul * Hack to allow the keyserver to use AUTH_DES (for authenticated 9251251b2bSBill Paul * NIS+ calls, for example). The only functions that get called 9351251b2bSBill Paul * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes. 9451251b2bSBill Paul * 9551251b2bSBill Paul * The approach is to have the keyserver fill in pointers to local 9651251b2bSBill Paul * implementations of these functions, and to call those in key_call(). 9751251b2bSBill Paul */ 9851251b2bSBill Paul 9951251b2bSBill Paul extern cryptkeyres *(*__key_encryptsession_pk_LOCAL)(); 10051251b2bSBill Paul extern cryptkeyres *(*__key_decryptsession_pk_LOCAL)(); 10151251b2bSBill Paul extern des_block *(*__key_gendes_LOCAL)(); 10251251b2bSBill Paul extern int (*__des_crypt_LOCAL)(); 10351251b2bSBill Paul 104784bddbcSKevin Lo cryptkeyres *key_encrypt_pk_2_svc_prog( uid_t, cryptkeyarg2 * ); 105784bddbcSKevin Lo cryptkeyres *key_decrypt_pk_2_svc_prog( uid_t, cryptkeyarg2 * ); 106784bddbcSKevin Lo des_block *key_gen_1_svc_prog( void *, struct svc_req * ); 10751251b2bSBill Paul 10851251b2bSBill Paul int 10935a624c5SJohn Baldwin main(int argc, char *argv[]) 11051251b2bSBill Paul { 11151251b2bSBill Paul int nflag = 0; 11251251b2bSBill Paul int c; 11351251b2bSBill Paul int warn = 0; 11451251b2bSBill Paul char *path = NULL; 11598fb6503SAlfred Perlstein void *localhandle; 11698fb6503SAlfred Perlstein register SVCXPRT *transp; 11798fb6503SAlfred Perlstein struct netconfig *nconf = NULL; 11851251b2bSBill Paul 11951251b2bSBill Paul __key_encryptsession_pk_LOCAL = &key_encrypt_pk_2_svc_prog; 12051251b2bSBill Paul __key_decryptsession_pk_LOCAL = &key_decrypt_pk_2_svc_prog; 12151251b2bSBill Paul __key_gendes_LOCAL = &key_gen_1_svc_prog; 12251251b2bSBill Paul 12351251b2bSBill Paul while ((c = getopt(argc, argv, "ndDvp:")) != -1) 12451251b2bSBill Paul switch (c) { 12551251b2bSBill Paul case 'n': 12651251b2bSBill Paul nflag++; 12751251b2bSBill Paul break; 12851251b2bSBill Paul case 'd': 12951251b2bSBill Paul pk_nodefaultkeys(); 13051251b2bSBill Paul break; 13151251b2bSBill Paul case 'D': 13251251b2bSBill Paul debugging = 1; 13351251b2bSBill Paul break; 13451251b2bSBill Paul case 'v': 13551251b2bSBill Paul warn = 1; 13651251b2bSBill Paul break; 13751251b2bSBill Paul case 'p': 13851251b2bSBill Paul path = optarg; 13951251b2bSBill Paul break; 14051251b2bSBill Paul default: 14151251b2bSBill Paul usage(); 14251251b2bSBill Paul } 14351251b2bSBill Paul 14451251b2bSBill Paul load_des(warn, path); 14551251b2bSBill Paul __des_crypt_LOCAL = _my_crypt; 146ecdf56e7SPhilippe Charnier if (svc_auth_reg(AUTH_DES, _svcauth_des) == -1) 147ecdf56e7SPhilippe Charnier errx(1, "failed to register AUTH_DES authenticator"); 14851251b2bSBill Paul 14951251b2bSBill Paul if (optind != argc) { 15051251b2bSBill Paul usage(); 15151251b2bSBill Paul } 15251251b2bSBill Paul 15351251b2bSBill Paul /* 15451251b2bSBill Paul * Initialize 15551251b2bSBill Paul */ 15698fb6503SAlfred Perlstein (void) umask(S_IXUSR|S_IXGRP|S_IXOTH); 157ecdf56e7SPhilippe Charnier if (geteuid() != 0) 158ecdf56e7SPhilippe Charnier errx(1, "keyserv must be run as root"); 15951251b2bSBill Paul setmodulus(HEXMODULUS); 16051251b2bSBill Paul getrootkey(&masterkey, nflag); 16151251b2bSBill Paul 16298fb6503SAlfred Perlstein rpcb_unset(KEY_PROG, KEY_VERS, NULL); 16398fb6503SAlfred Perlstein rpcb_unset(KEY_PROG, KEY_VERS2, NULL); 16498fb6503SAlfred Perlstein 1658360efbdSAlfred Perlstein if (svc_create(keyprogram, KEY_PROG, KEY_VERS, 1668360efbdSAlfred Perlstein "netpath") == 0) { 1678360efbdSAlfred Perlstein (void) fprintf(stderr, 1688360efbdSAlfred Perlstein "%s: unable to create service\n", argv[0]); 1698360efbdSAlfred Perlstein exit(1); 1708360efbdSAlfred Perlstein } 17151251b2bSBill Paul 1728360efbdSAlfred Perlstein if (svc_create(keyprogram, KEY_PROG, KEY_VERS2, 1738360efbdSAlfred Perlstein "netpath") == 0) { 1748360efbdSAlfred Perlstein (void) fprintf(stderr, 1758360efbdSAlfred Perlstein "%s: unable to create service\n", argv[0]); 1768360efbdSAlfred Perlstein exit(1); 1778360efbdSAlfred Perlstein } 17851251b2bSBill Paul 17998fb6503SAlfred Perlstein localhandle = setnetconfig(); 18098fb6503SAlfred Perlstein while ((nconf = getnetconfig(localhandle)) != NULL) { 18198fb6503SAlfred Perlstein if (nconf->nc_protofmly != NULL && 18298fb6503SAlfred Perlstein strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) 18398fb6503SAlfred Perlstein break; 18498fb6503SAlfred Perlstein } 18598fb6503SAlfred Perlstein 18698fb6503SAlfred Perlstein if (nconf == NULL) 18798fb6503SAlfred Perlstein errx(1, "getnetconfig: %s", nc_sperror()); 18898fb6503SAlfred Perlstein 18998fb6503SAlfred Perlstein unlink(KEYSERVSOCK); 19098fb6503SAlfred Perlstein rpcb_unset(CRYPT_PROG, CRYPT_VERS, nconf); 19198fb6503SAlfred Perlstein transp = svcunix_create(RPC_ANYSOCK, 0, 0, KEYSERVSOCK); 19298fb6503SAlfred Perlstein if (transp == NULL) 19398fb6503SAlfred Perlstein errx(1, "cannot create AF_LOCAL service"); 19498fb6503SAlfred Perlstein if (!svc_reg(transp, KEY_PROG, KEY_VERS, keyprogram, nconf)) 19598fb6503SAlfred Perlstein errx(1, "unable to register (KEY_PROG, KEY_VERS, unix)"); 19698fb6503SAlfred Perlstein if (!svc_reg(transp, KEY_PROG, KEY_VERS2, keyprogram, nconf)) 19798fb6503SAlfred Perlstein errx(1, "unable to register (KEY_PROG, KEY_VERS2, unix)"); 19898fb6503SAlfred Perlstein if (!svc_reg(transp, CRYPT_PROG, CRYPT_VERS, crypt_prog_1, nconf)) 19998fb6503SAlfred Perlstein errx(1, "unable to register (CRYPT_PROG, CRYPT_VERS, unix)"); 20098fb6503SAlfred Perlstein 20198fb6503SAlfred Perlstein endnetconfig(localhandle); 20298fb6503SAlfred Perlstein 20398fb6503SAlfred Perlstein (void) umask(066); /* paranoia */ 20498fb6503SAlfred Perlstein 20551251b2bSBill Paul if (!debugging) { 20651251b2bSBill Paul daemon(0,0); 20751251b2bSBill Paul } 20851251b2bSBill Paul 20998fb6503SAlfred Perlstein signal(SIGPIPE, SIG_IGN); 21098fb6503SAlfred Perlstein 21151251b2bSBill Paul svc_run(); 21251251b2bSBill Paul abort(); 21351251b2bSBill Paul /* NOTREACHED */ 21451251b2bSBill Paul } 21551251b2bSBill Paul 21651251b2bSBill Paul /* 21751251b2bSBill Paul * In the event that we don't get a root password, we try to 21851251b2bSBill Paul * randomize the master key the best we can 21951251b2bSBill Paul */ 22051251b2bSBill Paul static void 22135a624c5SJohn Baldwin randomize(des_block *master) 22251251b2bSBill Paul { 2236cf217b2SKris Kennaway master->key.low = arc4random(); 2246cf217b2SKris Kennaway master->key.high = arc4random(); 22551251b2bSBill Paul } 22651251b2bSBill Paul 22751251b2bSBill Paul /* 22851251b2bSBill Paul * Try to get root's secret key, by prompting if terminal is a tty, else trying 22951251b2bSBill Paul * from standard input. 23051251b2bSBill Paul * Returns 1 on success. 23151251b2bSBill Paul */ 23251251b2bSBill Paul static int 23335a624c5SJohn Baldwin getrootkey(des_block *master, int prompt) 23451251b2bSBill Paul { 23551251b2bSBill Paul char *passwd; 23651251b2bSBill Paul char name[MAXNETNAMELEN + 1]; 23751251b2bSBill Paul char secret[HEXKEYBYTES]; 23851251b2bSBill Paul key_netstarg netstore; 23951251b2bSBill Paul int fd; 24051251b2bSBill Paul 24151251b2bSBill Paul if (!prompt) { 24251251b2bSBill Paul /* 24351251b2bSBill Paul * Read secret key out of ROOTKEY 24451251b2bSBill Paul */ 24551251b2bSBill Paul fd = open(ROOTKEY, O_RDONLY, 0); 24651251b2bSBill Paul if (fd < 0) { 24751251b2bSBill Paul randomize(master); 24851251b2bSBill Paul return (0); 24951251b2bSBill Paul } 25051251b2bSBill Paul if (read(fd, secret, HEXKEYBYTES) < HEXKEYBYTES) { 251ecdf56e7SPhilippe Charnier warnx("the key read from %s was too short", ROOTKEY); 25251251b2bSBill Paul (void) close(fd); 25351251b2bSBill Paul return (0); 25451251b2bSBill Paul } 25551251b2bSBill Paul (void) close(fd); 25651251b2bSBill Paul if (!getnetname(name)) { 257ecdf56e7SPhilippe Charnier warnx( 258ecdf56e7SPhilippe Charnier "failed to generate host's netname when establishing root's key"); 25951251b2bSBill Paul return (0); 26051251b2bSBill Paul } 26151251b2bSBill Paul memcpy(netstore.st_priv_key, secret, HEXKEYBYTES); 26251251b2bSBill Paul memset(netstore.st_pub_key, 0, HEXKEYBYTES); 26351251b2bSBill Paul netstore.st_netname = name; 26451251b2bSBill Paul if (pk_netput(0, &netstore) != KEY_SUCCESS) { 265ecdf56e7SPhilippe Charnier warnx("could not set root's key and netname"); 26651251b2bSBill Paul return (0); 26751251b2bSBill Paul } 26851251b2bSBill Paul return (1); 26951251b2bSBill Paul } 27051251b2bSBill Paul /* 27151251b2bSBill Paul * Decrypt yellow pages publickey entry to get secret key 27251251b2bSBill Paul */ 27351251b2bSBill Paul passwd = getpass("root password:"); 27451251b2bSBill Paul passwd2des(passwd, (char *)master); 27551251b2bSBill Paul getnetname(name); 27651251b2bSBill Paul if (!getsecretkey(name, secret, passwd)) { 277ecdf56e7SPhilippe Charnier warnx("can't find %s's secret key", name); 27851251b2bSBill Paul return (0); 27951251b2bSBill Paul } 28051251b2bSBill Paul if (secret[0] == 0) { 281ecdf56e7SPhilippe Charnier warnx("password does not decrypt secret key for %s", name); 28251251b2bSBill Paul return (0); 28351251b2bSBill Paul } 28451251b2bSBill Paul (void) pk_setkey(0, secret); 28551251b2bSBill Paul /* 28651251b2bSBill Paul * Store it for future use in $ROOTKEY, if possible 28751251b2bSBill Paul */ 28851251b2bSBill Paul fd = open(ROOTKEY, O_WRONLY|O_TRUNC|O_CREAT, 0); 28951251b2bSBill Paul if (fd > 0) { 29051251b2bSBill Paul char newline = '\n'; 29151251b2bSBill Paul 29251251b2bSBill Paul write(fd, secret, strlen(secret)); 29351251b2bSBill Paul write(fd, &newline, sizeof (newline)); 29451251b2bSBill Paul close(fd); 29551251b2bSBill Paul } 29651251b2bSBill Paul return (1); 29751251b2bSBill Paul } 29851251b2bSBill Paul 29951251b2bSBill Paul /* 30051251b2bSBill Paul * Procedures to implement RPC service 30151251b2bSBill Paul */ 30251251b2bSBill Paul char * 30335a624c5SJohn Baldwin strstatus(keystatus status) 30451251b2bSBill Paul { 30551251b2bSBill Paul switch (status) { 30651251b2bSBill Paul case KEY_SUCCESS: 30751251b2bSBill Paul return ("KEY_SUCCESS"); 30851251b2bSBill Paul case KEY_NOSECRET: 30951251b2bSBill Paul return ("KEY_NOSECRET"); 31051251b2bSBill Paul case KEY_UNKNOWN: 31151251b2bSBill Paul return ("KEY_UNKNOWN"); 31251251b2bSBill Paul case KEY_SYSTEMERR: 31351251b2bSBill Paul return ("KEY_SYSTEMERR"); 31451251b2bSBill Paul default: 31551251b2bSBill Paul return ("(bad result code)"); 31651251b2bSBill Paul } 31751251b2bSBill Paul } 31851251b2bSBill Paul 31951251b2bSBill Paul keystatus * 32035a624c5SJohn Baldwin key_set_1_svc_prog(uid_t uid, keybuf key) 32151251b2bSBill Paul { 32251251b2bSBill Paul static keystatus status; 32351251b2bSBill Paul 32451251b2bSBill Paul if (debugging) { 32574088581SDimitry Andric (void) fprintf(stderr, "set(%u, %.*s) = ", uid, 32651251b2bSBill Paul (int) sizeof (keybuf), key); 32751251b2bSBill Paul } 32851251b2bSBill Paul status = pk_setkey(uid, key); 32951251b2bSBill Paul if (debugging) { 33051251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(status)); 33151251b2bSBill Paul (void) fflush(stderr); 33251251b2bSBill Paul } 33351251b2bSBill Paul return (&status); 33451251b2bSBill Paul } 33551251b2bSBill Paul 33651251b2bSBill Paul cryptkeyres * 33735a624c5SJohn Baldwin key_encrypt_pk_2_svc_prog(uid_t uid, cryptkeyarg2 *arg) 33851251b2bSBill Paul { 33951251b2bSBill Paul static cryptkeyres res; 34051251b2bSBill Paul 34151251b2bSBill Paul if (debugging) { 34274088581SDimitry Andric (void) fprintf(stderr, "encrypt(%u, %s, %08x%08x) = ", uid, 34351251b2bSBill Paul arg->remotename, arg->deskey.key.high, 34451251b2bSBill Paul arg->deskey.key.low); 34551251b2bSBill Paul } 34651251b2bSBill Paul res.cryptkeyres_u.deskey = arg->deskey; 34751251b2bSBill Paul res.status = pk_encrypt(uid, arg->remotename, &(arg->remotekey), 34851251b2bSBill Paul &res.cryptkeyres_u.deskey); 34951251b2bSBill Paul if (debugging) { 35051251b2bSBill Paul if (res.status == KEY_SUCCESS) { 35151251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 35251251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 35351251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 35451251b2bSBill Paul } else { 35551251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 35651251b2bSBill Paul } 35751251b2bSBill Paul (void) fflush(stderr); 35851251b2bSBill Paul } 35951251b2bSBill Paul return (&res); 36051251b2bSBill Paul } 36151251b2bSBill Paul 36251251b2bSBill Paul cryptkeyres * 36335a624c5SJohn Baldwin key_decrypt_pk_2_svc_prog(uid_t uid, cryptkeyarg2 *arg) 36451251b2bSBill Paul { 36551251b2bSBill Paul static cryptkeyres res; 36651251b2bSBill Paul 36751251b2bSBill Paul if (debugging) { 36874088581SDimitry Andric (void) fprintf(stderr, "decrypt(%u, %s, %08x%08x) = ", uid, 36951251b2bSBill Paul arg->remotename, arg->deskey.key.high, 37051251b2bSBill Paul arg->deskey.key.low); 37151251b2bSBill Paul } 37251251b2bSBill Paul res.cryptkeyres_u.deskey = arg->deskey; 37351251b2bSBill Paul res.status = pk_decrypt(uid, arg->remotename, &(arg->remotekey), 37451251b2bSBill Paul &res.cryptkeyres_u.deskey); 37551251b2bSBill Paul if (debugging) { 37651251b2bSBill Paul if (res.status == KEY_SUCCESS) { 37751251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 37851251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 37951251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 38051251b2bSBill Paul } else { 38151251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 38251251b2bSBill Paul } 38351251b2bSBill Paul (void) fflush(stderr); 38451251b2bSBill Paul } 38551251b2bSBill Paul return (&res); 38651251b2bSBill Paul } 38751251b2bSBill Paul 38851251b2bSBill Paul keystatus * 38935a624c5SJohn Baldwin key_net_put_2_svc_prog(uid_t uid, key_netstarg *arg) 39051251b2bSBill Paul { 39151251b2bSBill Paul static keystatus status; 39251251b2bSBill Paul 39351251b2bSBill Paul if (debugging) { 39451251b2bSBill Paul (void) fprintf(stderr, "net_put(%s, %.*s, %.*s) = ", 39551251b2bSBill Paul arg->st_netname, (int)sizeof (arg->st_pub_key), 39651251b2bSBill Paul arg->st_pub_key, (int)sizeof (arg->st_priv_key), 39751251b2bSBill Paul arg->st_priv_key); 39880c7cc1cSPedro F. Giffuni } 39951251b2bSBill Paul 40051251b2bSBill Paul status = pk_netput(uid, arg); 40151251b2bSBill Paul 40251251b2bSBill Paul if (debugging) { 40351251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(status)); 40451251b2bSBill Paul (void) fflush(stderr); 40551251b2bSBill Paul } 40651251b2bSBill Paul 40751251b2bSBill Paul return (&status); 40851251b2bSBill Paul } 40951251b2bSBill Paul 41051251b2bSBill Paul key_netstres * 41135a624c5SJohn Baldwin key_net_get_2_svc_prog(uid_t uid, void *arg) 41251251b2bSBill Paul { 41351251b2bSBill Paul static key_netstres keynetname; 41451251b2bSBill Paul 41551251b2bSBill Paul if (debugging) 41674088581SDimitry Andric (void) fprintf(stderr, "net_get(%u) = ", uid); 41751251b2bSBill Paul 41851251b2bSBill Paul keynetname.status = pk_netget(uid, &keynetname.key_netstres_u.knet); 41951251b2bSBill Paul if (debugging) { 42051251b2bSBill Paul if (keynetname.status == KEY_SUCCESS) { 42151251b2bSBill Paul fprintf(stderr, "<%s, %.*s, %.*s>\n", 42251251b2bSBill Paul keynetname.key_netstres_u.knet.st_netname, 42351251b2bSBill Paul (int)sizeof (keynetname.key_netstres_u.knet.st_pub_key), 42451251b2bSBill Paul keynetname.key_netstres_u.knet.st_pub_key, 42551251b2bSBill Paul (int)sizeof (keynetname.key_netstres_u.knet.st_priv_key), 42651251b2bSBill Paul keynetname.key_netstres_u.knet.st_priv_key); 42751251b2bSBill Paul } else { 42851251b2bSBill Paul (void) fprintf(stderr, "NOT FOUND\n"); 42951251b2bSBill Paul } 43051251b2bSBill Paul (void) fflush(stderr); 43151251b2bSBill Paul } 43251251b2bSBill Paul 43351251b2bSBill Paul return (&keynetname); 43451251b2bSBill Paul 43551251b2bSBill Paul } 43651251b2bSBill Paul 43751251b2bSBill Paul cryptkeyres * 43835a624c5SJohn Baldwin key_get_conv_2_svc_prog(uid_t uid, keybuf arg) 43951251b2bSBill Paul { 44051251b2bSBill Paul static cryptkeyres res; 44151251b2bSBill Paul 44251251b2bSBill Paul if (debugging) 44374088581SDimitry Andric (void) fprintf(stderr, "get_conv(%u, %.*s) = ", uid, 44474088581SDimitry Andric (int)sizeof (keybuf), arg); 44551251b2bSBill Paul 44651251b2bSBill Paul 44751251b2bSBill Paul res.status = pk_get_conv_key(uid, arg, &res); 44851251b2bSBill Paul 44951251b2bSBill Paul if (debugging) { 45051251b2bSBill Paul if (res.status == KEY_SUCCESS) { 45151251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 45251251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 45351251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 45451251b2bSBill Paul } else { 45551251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 45651251b2bSBill Paul } 45751251b2bSBill Paul (void) fflush(stderr); 45851251b2bSBill Paul } 45951251b2bSBill Paul return (&res); 46051251b2bSBill Paul } 46151251b2bSBill Paul 46251251b2bSBill Paul 46351251b2bSBill Paul cryptkeyres * 46435a624c5SJohn Baldwin key_encrypt_1_svc_prog(uid_t uid, cryptkeyarg *arg) 46551251b2bSBill Paul { 46651251b2bSBill Paul static cryptkeyres res; 46751251b2bSBill Paul 46851251b2bSBill Paul if (debugging) { 46974088581SDimitry Andric (void) fprintf(stderr, "encrypt(%u, %s, %08x%08x) = ", uid, 47051251b2bSBill Paul arg->remotename, arg->deskey.key.high, 47151251b2bSBill Paul arg->deskey.key.low); 47251251b2bSBill Paul } 47351251b2bSBill Paul res.cryptkeyres_u.deskey = arg->deskey; 47451251b2bSBill Paul res.status = pk_encrypt(uid, arg->remotename, NULL, 47551251b2bSBill Paul &res.cryptkeyres_u.deskey); 47651251b2bSBill Paul if (debugging) { 47751251b2bSBill Paul if (res.status == KEY_SUCCESS) { 47851251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 47951251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 48051251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 48151251b2bSBill Paul } else { 48251251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 48351251b2bSBill Paul } 48451251b2bSBill Paul (void) fflush(stderr); 48551251b2bSBill Paul } 48651251b2bSBill Paul return (&res); 48751251b2bSBill Paul } 48851251b2bSBill Paul 48951251b2bSBill Paul cryptkeyres * 49035a624c5SJohn Baldwin key_decrypt_1_svc_prog(uid_t uid, cryptkeyarg *arg) 49151251b2bSBill Paul { 49251251b2bSBill Paul static cryptkeyres res; 49351251b2bSBill Paul 49451251b2bSBill Paul if (debugging) { 49574088581SDimitry Andric (void) fprintf(stderr, "decrypt(%u, %s, %08x%08x) = ", uid, 49651251b2bSBill Paul arg->remotename, arg->deskey.key.high, 49751251b2bSBill Paul arg->deskey.key.low); 49851251b2bSBill Paul } 49951251b2bSBill Paul res.cryptkeyres_u.deskey = arg->deskey; 50051251b2bSBill Paul res.status = pk_decrypt(uid, arg->remotename, NULL, 50151251b2bSBill Paul &res.cryptkeyres_u.deskey); 50251251b2bSBill Paul if (debugging) { 50351251b2bSBill Paul if (res.status == KEY_SUCCESS) { 50451251b2bSBill Paul (void) fprintf(stderr, "%08x%08x\n", 50551251b2bSBill Paul res.cryptkeyres_u.deskey.key.high, 50651251b2bSBill Paul res.cryptkeyres_u.deskey.key.low); 50751251b2bSBill Paul } else { 50851251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 50951251b2bSBill Paul } 51051251b2bSBill Paul (void) fflush(stderr); 51151251b2bSBill Paul } 51251251b2bSBill Paul return (&res); 51351251b2bSBill Paul } 51451251b2bSBill Paul 51551251b2bSBill Paul /* ARGSUSED */ 51651251b2bSBill Paul des_block * 51735a624c5SJohn Baldwin key_gen_1_svc_prog(void *v, struct svc_req *s) 51851251b2bSBill Paul { 51951251b2bSBill Paul struct timeval time; 52051251b2bSBill Paul static des_block keygen; 52151251b2bSBill Paul static des_block key; 52251251b2bSBill Paul 523902d9eafSEd Schouten (void)gettimeofday(&time, NULL); 52451251b2bSBill Paul keygen.key.high += (time.tv_sec ^ time.tv_usec); 52551251b2bSBill Paul keygen.key.low += (time.tv_sec ^ time.tv_usec); 52651251b2bSBill Paul ecb_crypt((char *)&masterkey, (char *)&keygen, sizeof (keygen), 52751251b2bSBill Paul DES_ENCRYPT | DES_HW); 52851251b2bSBill Paul key = keygen; 52951251b2bSBill Paul des_setparity((char *)&key); 53051251b2bSBill Paul if (debugging) { 53151251b2bSBill Paul (void) fprintf(stderr, "gen() = %08x%08x\n", key.key.high, 53251251b2bSBill Paul key.key.low); 53351251b2bSBill Paul (void) fflush(stderr); 53451251b2bSBill Paul } 53551251b2bSBill Paul return (&key); 53651251b2bSBill Paul } 53751251b2bSBill Paul 53851251b2bSBill Paul getcredres * 53935a624c5SJohn Baldwin key_getcred_1_svc_prog(uid_t uid, netnamestr *name) 54051251b2bSBill Paul { 54151251b2bSBill Paul static getcredres res; 54251251b2bSBill Paul static u_int gids[NGROUPS]; 54351251b2bSBill Paul struct unixcred *cred; 54451251b2bSBill Paul 54551251b2bSBill Paul cred = &res.getcredres_u.cred; 54651251b2bSBill Paul cred->gids.gids_val = gids; 54751251b2bSBill Paul if (!netname2user(*name, (uid_t *) &cred->uid, (gid_t *) &cred->gid, 54851251b2bSBill Paul (int *)&cred->gids.gids_len, (gid_t *)gids)) { 54951251b2bSBill Paul res.status = KEY_UNKNOWN; 55051251b2bSBill Paul } else { 55151251b2bSBill Paul res.status = KEY_SUCCESS; 55251251b2bSBill Paul } 55351251b2bSBill Paul if (debugging) { 55451251b2bSBill Paul (void) fprintf(stderr, "getcred(%s) = ", *name); 55551251b2bSBill Paul if (res.status == KEY_SUCCESS) { 55651251b2bSBill Paul (void) fprintf(stderr, "uid=%d, gid=%d, grouplen=%d\n", 55751251b2bSBill Paul cred->uid, cred->gid, cred->gids.gids_len); 55851251b2bSBill Paul } else { 55951251b2bSBill Paul (void) fprintf(stderr, "%s\n", strstatus(res.status)); 56051251b2bSBill Paul } 56151251b2bSBill Paul (void) fflush(stderr); 56251251b2bSBill Paul } 56351251b2bSBill Paul return (&res); 56451251b2bSBill Paul } 56551251b2bSBill Paul 56651251b2bSBill Paul /* 56751251b2bSBill Paul * RPC boilerplate 56851251b2bSBill Paul */ 56951251b2bSBill Paul static void 57035a624c5SJohn Baldwin keyprogram(struct svc_req *rqstp, SVCXPRT *transp) 57151251b2bSBill Paul { 57251251b2bSBill Paul union { 57351251b2bSBill Paul keybuf key_set_1_arg; 57451251b2bSBill Paul cryptkeyarg key_encrypt_1_arg; 57551251b2bSBill Paul cryptkeyarg key_decrypt_1_arg; 57651251b2bSBill Paul netnamestr key_getcred_1_arg; 57751251b2bSBill Paul cryptkeyarg key_encrypt_2_arg; 57851251b2bSBill Paul cryptkeyarg key_decrypt_2_arg; 57951251b2bSBill Paul netnamestr key_getcred_2_arg; 58051251b2bSBill Paul cryptkeyarg2 key_encrypt_pk_2_arg; 58151251b2bSBill Paul cryptkeyarg2 key_decrypt_pk_2_arg; 58251251b2bSBill Paul key_netstarg key_net_put_2_arg; 58351251b2bSBill Paul netobj key_get_conv_2_arg; 58451251b2bSBill Paul } argument; 58551251b2bSBill Paul char *result; 586f249dbccSDag-Erling Smørgrav xdrproc_t xdr_argument, xdr_result; 58735a624c5SJohn Baldwin typedef void *(svc_cb)(uid_t uid, void *arg); 58835a624c5SJohn Baldwin svc_cb *local; 58951251b2bSBill Paul uid_t uid = -1; 59051251b2bSBill Paul int check_auth; 59151251b2bSBill Paul 59251251b2bSBill Paul switch (rqstp->rq_proc) { 59351251b2bSBill Paul case NULLPROC: 594f249dbccSDag-Erling Smørgrav svc_sendreply(transp, (xdrproc_t)xdr_void, NULL); 59551251b2bSBill Paul return; 59651251b2bSBill Paul 59751251b2bSBill Paul case KEY_SET: 598f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_keybuf; 599f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_int; 60035a624c5SJohn Baldwin local = (svc_cb *)key_set_1_svc_prog; 60151251b2bSBill Paul check_auth = 1; 60251251b2bSBill Paul break; 60351251b2bSBill Paul 60451251b2bSBill Paul case KEY_ENCRYPT: 605f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_cryptkeyarg; 606f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_cryptkeyres; 60735a624c5SJohn Baldwin local = (svc_cb *)key_encrypt_1_svc_prog; 60851251b2bSBill Paul check_auth = 1; 60951251b2bSBill Paul break; 61051251b2bSBill Paul 61151251b2bSBill Paul case KEY_DECRYPT: 612f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_cryptkeyarg; 613f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_cryptkeyres; 61435a624c5SJohn Baldwin local = (svc_cb *)key_decrypt_1_svc_prog; 61551251b2bSBill Paul check_auth = 1; 61651251b2bSBill Paul break; 61751251b2bSBill Paul 61851251b2bSBill Paul case KEY_GEN: 619f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_void; 620f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_des_block; 62135a624c5SJohn Baldwin local = (svc_cb *)key_gen_1_svc_prog; 62251251b2bSBill Paul check_auth = 0; 62351251b2bSBill Paul break; 62451251b2bSBill Paul 62551251b2bSBill Paul case KEY_GETCRED: 626f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_netnamestr; 627f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_getcredres; 62835a624c5SJohn Baldwin local = (svc_cb *)key_getcred_1_svc_prog; 62951251b2bSBill Paul check_auth = 0; 63051251b2bSBill Paul break; 63151251b2bSBill Paul 63251251b2bSBill Paul case KEY_ENCRYPT_PK: 633f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_cryptkeyarg2; 634f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_cryptkeyres; 63535a624c5SJohn Baldwin local = (svc_cb *)key_encrypt_pk_2_svc_prog; 63651251b2bSBill Paul check_auth = 1; 63751251b2bSBill Paul break; 63851251b2bSBill Paul 63951251b2bSBill Paul case KEY_DECRYPT_PK: 640f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_cryptkeyarg2; 641f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_cryptkeyres; 64235a624c5SJohn Baldwin local = (svc_cb *)key_decrypt_pk_2_svc_prog; 64351251b2bSBill Paul check_auth = 1; 64451251b2bSBill Paul break; 64551251b2bSBill Paul 64651251b2bSBill Paul 64751251b2bSBill Paul case KEY_NET_PUT: 648f249dbccSDag-Erling Smørgrav xdr_argument = (xdrproc_t)xdr_key_netstarg; 649f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_keystatus; 65035a624c5SJohn Baldwin local = (svc_cb *)key_net_put_2_svc_prog; 65151251b2bSBill Paul check_auth = 1; 65251251b2bSBill Paul break; 65351251b2bSBill Paul 65451251b2bSBill Paul case KEY_NET_GET: 65551251b2bSBill Paul xdr_argument = (xdrproc_t) xdr_void; 656f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_key_netstres; 65735a624c5SJohn Baldwin local = (svc_cb *)key_net_get_2_svc_prog; 65851251b2bSBill Paul check_auth = 1; 65951251b2bSBill Paul break; 66051251b2bSBill Paul 66151251b2bSBill Paul case KEY_GET_CONV: 66251251b2bSBill Paul xdr_argument = (xdrproc_t) xdr_keybuf; 663f249dbccSDag-Erling Smørgrav xdr_result = (xdrproc_t)xdr_cryptkeyres; 66435a624c5SJohn Baldwin local = (svc_cb *)key_get_conv_2_svc_prog; 66551251b2bSBill Paul check_auth = 1; 66651251b2bSBill Paul break; 66751251b2bSBill Paul 66851251b2bSBill Paul default: 66951251b2bSBill Paul svcerr_noproc(transp); 67051251b2bSBill Paul return; 67151251b2bSBill Paul } 67251251b2bSBill Paul if (check_auth) { 67351251b2bSBill Paul if (root_auth(transp, rqstp) == 0) { 67451251b2bSBill Paul if (debugging) { 67551251b2bSBill Paul (void) fprintf(stderr, 67651251b2bSBill Paul "not local privileged process\n"); 67751251b2bSBill Paul } 67851251b2bSBill Paul svcerr_weakauth(transp); 67951251b2bSBill Paul return; 68051251b2bSBill Paul } 68151251b2bSBill Paul if (rqstp->rq_cred.oa_flavor != AUTH_SYS) { 68251251b2bSBill Paul if (debugging) { 68351251b2bSBill Paul (void) fprintf(stderr, 68451251b2bSBill Paul "not unix authentication\n"); 68551251b2bSBill Paul } 68651251b2bSBill Paul svcerr_weakauth(transp); 68751251b2bSBill Paul return; 68851251b2bSBill Paul } 68951251b2bSBill Paul uid = ((struct authsys_parms *)rqstp->rq_clntcred)->aup_uid; 69051251b2bSBill Paul } 69151251b2bSBill Paul 692f249dbccSDag-Erling Smørgrav memset(&argument, 0, sizeof (argument)); 693f249dbccSDag-Erling Smørgrav if (!svc_getargs(transp, xdr_argument, &argument)) { 69451251b2bSBill Paul svcerr_decode(transp); 69551251b2bSBill Paul return; 69651251b2bSBill Paul } 69751251b2bSBill Paul result = (*local) (uid, &argument); 698f249dbccSDag-Erling Smørgrav if (!svc_sendreply(transp, xdr_result, result)) { 69951251b2bSBill Paul if (debugging) 70051251b2bSBill Paul (void) fprintf(stderr, "unable to reply\n"); 70151251b2bSBill Paul svcerr_systemerr(transp); 70251251b2bSBill Paul } 703f249dbccSDag-Erling Smørgrav if (!svc_freeargs(transp, xdr_argument, &argument)) { 70451251b2bSBill Paul if (debugging) 70551251b2bSBill Paul (void) fprintf(stderr, 70651251b2bSBill Paul "unable to free arguments\n"); 70751251b2bSBill Paul exit(1); 70851251b2bSBill Paul } 70951251b2bSBill Paul return; 71051251b2bSBill Paul } 71151251b2bSBill Paul 71251251b2bSBill Paul static int 71335a624c5SJohn Baldwin root_auth(SVCXPRT *trans, struct svc_req *rqstp) 71451251b2bSBill Paul { 71551251b2bSBill Paul uid_t uid; 716af37179bSAlfred Perlstein struct sockaddr *remote; 71751251b2bSBill Paul 718af37179bSAlfred Perlstein remote = svc_getrpccaller(trans)->buf; 719af37179bSAlfred Perlstein if (remote->sa_family != AF_UNIX) { 72051251b2bSBill Paul if (debugging) 72151251b2bSBill Paul fprintf(stderr, "client didn't use AF_UNIX\n"); 72251251b2bSBill Paul return (0); 72351251b2bSBill Paul } 72451251b2bSBill Paul 7254ed6d634SAlfred Perlstein if (__rpc_get_local_uid(trans, &uid) < 0) { 72651251b2bSBill Paul if (debugging) 72751251b2bSBill Paul fprintf(stderr, "__rpc_get_local_uid failed\n"); 72851251b2bSBill Paul return (0); 72951251b2bSBill Paul } 73051251b2bSBill Paul 73151251b2bSBill Paul if (debugging) 73274088581SDimitry Andric fprintf(stderr, "local_uid %u\n", uid); 73351251b2bSBill Paul if (uid == 0) 73451251b2bSBill Paul return (1); 73551251b2bSBill Paul if (rqstp->rq_cred.oa_flavor == AUTH_SYS) { 73651251b2bSBill Paul if (((uid_t) ((struct authunix_parms *) 73751251b2bSBill Paul rqstp->rq_clntcred)->aup_uid) 73851251b2bSBill Paul == uid) { 73951251b2bSBill Paul return (1); 74051251b2bSBill Paul } else { 74151251b2bSBill Paul if (debugging) 74251251b2bSBill Paul fprintf(stderr, 74374088581SDimitry Andric "local_uid %u mismatches auth %u\n", uid, 74451251b2bSBill Paul ((uid_t) ((struct authunix_parms *)rqstp->rq_clntcred)->aup_uid)); 74551251b2bSBill Paul return (0); 74651251b2bSBill Paul } 74751251b2bSBill Paul } else { 74851251b2bSBill Paul if (debugging) 74951251b2bSBill Paul fprintf(stderr, "Not auth sys\n"); 75051251b2bSBill Paul return (0); 75151251b2bSBill Paul } 75251251b2bSBill Paul } 75351251b2bSBill Paul 75451251b2bSBill Paul static void 75535a624c5SJohn Baldwin usage(void) 75651251b2bSBill Paul { 75751251b2bSBill Paul (void) fprintf(stderr, 75851251b2bSBill Paul "usage: keyserv [-n] [-D] [-d] [-v] [-p path]\n"); 75951251b2bSBill Paul (void) fprintf(stderr, "-d disables the use of default keys\n"); 76051251b2bSBill Paul exit(1); 76151251b2bSBill Paul } 762