newkey.c revision 50477
1/* 2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 3 * unrestricted use provided that this legend is included on all tape 4 * media and as a part of the software program in whole or part. Users 5 * may copy or modify Sun RPC without charge, but are not authorized 6 * to license or distribute it to anyone else except as part of a product or 7 * program developed by the user or with the express written consent of 8 * Sun Microsystems, Inc. 9 * 10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13 * 14 * Sun RPC is provided with no support and without any obligation on the 15 * part of Sun Microsystems, Inc. to assist in its use, correction, 16 * modification or enhancement. 17 * 18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20 * OR ANY PART THEREOF. 21 * 22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23 * or profits or other special, indirect and consequential damages, even if 24 * Sun has been advised of the possibility of such damages. 25 * 26 * Sun Microsystems, Inc. 27 * 2550 Garcia Avenue 28 * Mountain View, California 94043 29 */ 30#if !defined(lint) && defined(SCCSIDS) 31#if 0 32static char sccsid[] = "@(#)newkey.c 1.8 91/03/11 Copyr 1986 Sun Micro"; 33#endif 34static const char rcsid[] = 35 "$FreeBSD: head/usr.bin/newkey/newkey.c 50477 1999-08-28 01:08:13Z peter $"; 36#endif 37 38/* 39 * Copyright (C) 1986, Sun Microsystems, Inc. 40 */ 41 42/* 43 * Administrative tool to add a new user to the publickey database 44 */ 45#include <err.h> 46#include <stdio.h> 47#include <rpc/rpc.h> 48#include <rpc/key_prot.h> 49#ifdef YP 50#include <rpcsvc/yp_prot.h> 51#include <rpcsvc/ypclnt.h> 52#include <sys/wait.h> 53#include <netdb.h> 54#endif /* YP */ 55#include <pwd.h> 56#include <string.h> 57#include <unistd.h> 58#include <sys/resource.h> 59 60#ifdef YP 61#define MAXMAPNAMELEN 256 62#else 63#define YPOP_CHANGE 1 /* change, do not add */ 64#define YPOP_INSERT 2 /* add, do not change */ 65#define YPOP_DELETE 3 /* delete this entry */ 66#define YPOP_STORE 4 /* add, or change */ 67#define ERR_ACCESS 1 68#define ERR_MALLOC 2 69#define ERR_READ 3 70#define ERR_WRITE 4 71#define ERR_DBASE 5 72#define ERR_KEY 6 73#endif 74 75#ifdef YP 76static char *basename(); 77static char SHELL[] = "/bin/sh"; 78static char YPDBPATH[]="/var/yp"; 79static char PKMAP[] = "publickey.byname"; 80static char UPDATEFILE[] = "updaters"; 81#else 82static char PKFILE[] = "/etc/publickey"; 83static char *err_string(); 84#endif /* YP */ 85 86static void usage __P((void)); 87 88int 89main(argc, argv) 90 int argc; 91 char *argv[]; 92{ 93 char name[MAXNETNAMELEN + 1]; 94 char public[HEXKEYBYTES + 1]; 95 char secret[HEXKEYBYTES + 1]; 96 char crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE + 1]; 97 char crypt2[HEXKEYBYTES + KEYCHECKSUMSIZE + 1]; 98 int status; 99 char *pass; 100 struct passwd *pw; 101#ifdef undef 102 struct hostent *h; 103#endif 104 105 if (argc != 3 || !(strcmp(argv[1], "-u") == 0 || 106 strcmp(argv[1], "-h") == 0)) { 107 usage(); 108 } 109 if (geteuid() != 0) 110 errx(1, "must be superuser"); 111 112#ifdef YP 113 if (chdir(YPDBPATH) < 0) 114 warn("cannot chdir to %s", YPDBPATH); 115#endif /* YP */ 116 if (strcmp(argv[1], "-u") == 0) { 117 pw = getpwnam(argv[2]); 118 if (pw == NULL) 119 errx(1, "unknown user: %s", argv[2]); 120 (void)user2netname(name, (int)pw->pw_uid, (char *)NULL); 121 } else { 122#ifdef undef 123 h = gethostbyname(argv[2]); 124 if (h == NULL) 125 errx(1, "unknown host: %s", argv[1]); 126 (void)host2netname(name, h->h_name, (char *)NULL); 127#else 128 (void)host2netname(name, argv[2], (char *)NULL); 129#endif 130 } 131 132 (void)printf("Adding new key for %s.\n", name); 133 pass = getpass("New password:"); 134 genkeys(public, secret, pass); 135 136 memcpy(crypt1, secret, HEXKEYBYTES); 137 memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE); 138 crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0; 139 xencrypt(crypt1, pass); 140 141 memcpy(crypt2, crypt1, HEXKEYBYTES + KEYCHECKSUMSIZE + 1); 142 xdecrypt(crypt2, getpass("Retype password:")); 143 if (memcmp(crypt2, crypt2 + HEXKEYBYTES, KEYCHECKSUMSIZE) != 0 || 144 memcmp(crypt2, secret, HEXKEYBYTES) != 0) 145 errx(1, "password incorrect"); 146 147#ifdef YP 148 (void)printf("Please wait for the database to get updated...\n"); 149#endif 150 if ((status = setpublicmap(name, public, crypt1))) { 151#ifdef YP 152 errx(1, "unable to update NIS database (%u): %s", 153 status, yperr_string(status)); 154#else 155 errx(1, "unable to update publickey database (%u): %s", 156 status, err_string(status)); 157#endif 158 } 159 (void)printf("Your new key has been successfully stored away.\n"); 160 exit(0); 161 /* NOTREACHED */ 162} 163 164static void 165usage() 166{ 167 (void)fprintf(stderr, "%s\n%s\n", 168 "usage: newkey [-u username]", 169 " newkey [-h hostname]"); 170 exit(1); 171} 172 173/* 174 * Set the entry in the public key file 175 */ 176setpublicmap(name, public, secret) 177 char *name; 178 char *public; 179 char *secret; 180{ 181 char pkent[1024]; 182 183 (void)sprintf(pkent, "%s:%s", public, secret); 184#ifdef YP 185 return (mapupdate(name, PKMAP, YPOP_STORE, 186 strlen(name), name, strlen(pkent), pkent)); 187#else 188 return (localupdate(name, PKFILE, YPOP_STORE, 189 strlen(name), name, strlen(pkent), pkent)); 190#endif 191 } 192 193#ifndef YP 194 /* 195 * This returns a pointer to an error message string appropriate 196 * to an input error code. An input value of zero will return 197 * a success message. 198 */ 199static char * 200err_string(code) 201 int code; 202{ 203 char *pmesg; 204 205 switch (code) { 206 case 0: 207 pmesg = "update operation succeeded"; 208 break; 209 case ERR_KEY: 210 pmesg = "no such key in file"; 211 break; 212 case ERR_READ: 213 pmesg = "cannot read the database"; 214 break; 215 case ERR_WRITE: 216 pmesg = "cannot write to the database"; 217 break; 218 case ERR_DBASE: 219 pmesg = "cannot update database"; 220 break; 221 case ERR_ACCESS: 222 pmesg = "permission denied"; 223 break; 224 case ERR_MALLOC: 225 pmesg = "malloc failed"; 226 break; 227 default: 228 pmesg = "unknown error"; 229 break; 230 } 231 return (pmesg); 232} 233#endif 234