1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)register.c 1.12 (Berkeley) 09/06/90"; 20 #endif /* not lint */ 21 22 #include <sys/types.h> 23 #include <sys/param.h> 24 #include <sys/time.h> 25 #include <sys/resource.h> 26 #include <sys/socket.h> 27 #include <sys/file.h> 28 #include <sys/signal.h> 29 #include <netinet/in.h> 30 #include <pwd.h> 31 #include <stdio.h> 32 #include <netdb.h> 33 #include <kerberosIV/des.h> 34 #include <kerberosIV/krb.h> 35 #include "pathnames.h" 36 #include "register_proto.h" 37 38 #define SERVICE "krbupdate" /* service to add to KDC's database */ 39 #define PROTO "tcp" 40 41 char realm[REALM_SZ]; 42 char krbhst[MAX_HSTNM]; 43 44 static char pname[ANAME_SZ]; 45 static char iname[INST_SZ]; 46 static char password[_PASSWORD_LEN]; 47 48 /* extern char *sys_errlist; */ 49 int die(); 50 void setup_key(), type_info(), cleanup(); 51 52 main(argc, argv) 53 int argc; 54 char **argv; 55 { 56 struct servent *se; 57 struct hostent *host; 58 struct sockaddr_in sin, local; 59 int rval; 60 int sock, llen; 61 u_char code; 62 static struct rlimit rl = { 0, 0 }; 63 64 signal(SIGPIPE, die); 65 66 if (setrlimit(RLIMIT_CORE, &rl) < 0) { 67 perror("rlimit"); 68 exit(1); 69 } 70 71 if ((se = getservbyname(SERVICE, PROTO)) == NULL) { 72 fprintf(stderr, "couldn't find entry for service %s\n", 73 SERVICE); 74 exit(1); 75 } 76 if ((rval = krb_get_lrealm(realm,0)) != KSUCCESS) { 77 fprintf(stderr, "couldn't get local Kerberos realm: %s\n", 78 krb_err_txt[rval]); 79 exit(1); 80 } 81 82 if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) { 83 fprintf(stderr, "couldn't get Kerberos host: %s\n", 84 krb_err_txt[rval]); 85 exit(1); 86 } 87 88 if ((host = gethostbyname(krbhst)) == NULL) { 89 fprintf(stderr, "couldn't get host entry for host %s\n", 90 krbhst); 91 exit(1); 92 } 93 94 sin.sin_family = host->h_addrtype; 95 (void)bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length); 96 sin.sin_port = se->s_port; 97 98 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 99 perror("socket"); 100 exit(1); 101 } 102 103 if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) { 104 perror("connect"); 105 (void)close(sock); 106 exit(1); 107 } 108 109 llen = sizeof(local); 110 if (getsockname(sock, (struct sockaddr *) &local, &llen) < 0) { 111 perror("getsockname"); 112 (void)close(sock); 113 exit(1); 114 } 115 116 setup_key(local); 117 118 type_info(); 119 120 if (!get_user_info()) { 121 code = ABORT; 122 (void)des_write(sock, &code, 1); 123 cleanup(); 124 exit(1); 125 } 126 127 code = APPEND_DB; 128 if (des_write(sock, &code, 1) != 1) { 129 perror("write 1"); 130 cleanup(); 131 exit(1); 132 } 133 134 if (des_write(sock, pname, ANAME_SZ) != ANAME_SZ) { 135 perror("write principal name"); 136 cleanup(); 137 exit(1); 138 } 139 140 if (des_write(sock, iname, INST_SZ) != INST_SZ) { 141 perror("write instance name"); 142 cleanup(); 143 exit(1); 144 } 145 146 if (des_write(sock, password, 255) != 255) { 147 perror("write password"); 148 cleanup(); 149 exit(1); 150 } 151 152 /* get return message */ 153 154 { 155 int cc; 156 char msgbuf[BUFSIZ]; 157 158 cc = read(sock, msgbuf, BUFSIZ); 159 if (cc <= 0) { 160 fprintf(stderr, "protocol error during key verification\n"); 161 cleanup(); 162 exit(1); 163 } 164 if (strncmp(msgbuf, GOTKEY_MSG, 6) != 0) { 165 fprintf(stderr, "%s: %s", krbhst, msgbuf); 166 cleanup(); 167 exit(1); 168 } 169 170 cc = des_read(sock, msgbuf, BUFSIZ); 171 if (cc <= 0) { 172 fprintf(stderr, "protocol error during read\n"); 173 cleanup(); 174 exit(1); 175 } else { 176 printf("%s: %s", krbhst, msgbuf); 177 } 178 } 179 180 cleanup(); 181 (void)close(sock); 182 } 183 184 void 185 cleanup() 186 { 187 bzero(password, 255); 188 } 189 190 extern char *crypt(); 191 extern char *getpass(); 192 193 int 194 get_user_info() 195 { 196 int uid = getuid(); 197 int valid = 0, i; 198 struct passwd *pw; 199 char *pas, *namep; 200 201 /* NB: we must run setuid-root to get at the real pw file */ 202 203 if ((pw = getpwuid(uid)) == NULL) { 204 fprintf(stderr, "Who are you?\n"); 205 return(0); 206 } 207 (void)seteuid(uid); 208 (void)strcpy(pname, pw->pw_name); /* principal name */ 209 210 for (i = 1; i < 3; i++) { 211 pas = getpass("login password:"); 212 namep = crypt(pas, pw->pw_passwd); 213 if (strcmp(namep, pw->pw_passwd)) { 214 fprintf(stderr, "Password incorrect\n"); 215 continue; 216 } else { 217 valid = 1; 218 break; 219 } 220 } 221 if (!valid) 222 return(0); 223 pas = getpass("Kerberos password (may be the same):"); 224 while (*pas == NULL) { 225 printf("<NULL> password not allowed\n"); 226 pas = getpass("Kerberos password (may be the same):"); 227 } 228 (void)strcpy(password, pas); /* password */ 229 pas = getpass("Retype Kerberos password:"); 230 if (strcmp(password, pas)) { 231 fprintf(stderr, "Password mismatch -- aborted\n"); 232 return(0); 233 } 234 235 iname[0] = NULL; /* null instance name */ 236 return(1); 237 } 238 239 void 240 setup_key(local) 241 struct sockaddr_in local; 242 { 243 static struct keyfile_data kdata; 244 static Key_schedule schedule; 245 int fd; 246 char namebuf[MAXPATHLEN]; 247 extern int errno; 248 249 (void) sprintf(namebuf, "%s%s", 250 CLIENT_KEYFILE, 251 inet_ntoa(local.sin_addr)); 252 253 fd = open(namebuf, O_RDONLY); 254 if (fd < 0) { 255 fprintf(stderr, "couldn't open key file %s for local host: ", 256 namebuf); 257 perror(""); 258 exit(1); 259 } 260 261 if (read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) { 262 fprintf(stderr,"size error reading key file for local host %s\n", 263 inet_ntoa(local.sin_addr)); 264 exit(1); 265 } 266 key_sched(kdata.kf_key, schedule); 267 des_set_key(kdata.kf_key, schedule); 268 return; 269 } 270 271 void 272 type_info() 273 { 274 printf("Kerberos user registration (realm %s)\n\n", realm); 275 printf("Please enter your login password followed by your new Kerberos password.\n"); 276 printf("The Kerberos password you enter now will be used in the future\n"); 277 printf("as your Kerberos password for all machines in the %s realm.\n", realm); 278 printf("You will only be allowed to perform this operation once, although you may run\n"); 279 printf("the %s program from now on to change your Kerberos password.\n\n", _PATH_KPASSWD); 280 } 281 282 int 283 die() 284 { 285 fprintf(stderr, "\nServer no longer listening\n"); 286 fflush(stderr); 287 cleanup(); 288 exit(1); 289 } 290