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.5 (Berkeley) 05/17/89"; 20 #endif /* not lint */ 21 22 #include <sys/types.h> 23 #include <sys/time.h> 24 #include <sys/resource.h> 25 #include <sys/socket.h> 26 #include <stdio.h> 27 #include <netdb.h> 28 #include <netinet/in.h> 29 #include <kerberos/krb.h> 30 #include <sys/param.h> 31 #include <sys/file.h> 32 #include <sys/signal.h> 33 #include "register_proto.h" 34 35 #define SERVICE "krbupdate" 36 #define PROTO "tcp" 37 #define KFILE "/.update.key%s" 38 #define KPASSWD "/usr/athena/kpasswd" 39 40 char realm[REALM_SZ]; 41 char krbhst[MAX_HSTNM]; 42 43 static char pname[ANAME_SZ]; 44 static char iname[INST_SZ]; 45 static char password[255]; 46 47 extern char *sys_errlist; 48 int die(); 49 50 main(argc, argv) 51 int argc; 52 char **argv; 53 { 54 struct servent *se; 55 struct hostent *host; 56 struct sockaddr_in sin, local; 57 int rval; 58 int sock, llen; 59 u_char code; 60 static struct rlimit rl = { 0, 0 }; 61 62 signal(SIGPIPE, die); 63 64 if (setrlimit(RLIMIT_CORE, &rl) < 0) { 65 perror("rlimit"); 66 exit(1); 67 } 68 69 if ((se = getservbyname(SERVICE, PROTO)) == NULL) { 70 fprintf(stderr, "couldn't find entry for service %s\n", 71 SERVICE); 72 exit(1); 73 } 74 if ((rval = krb_get_lrealm(realm,1)) != KSUCCESS) { 75 fprintf(stderr, "couldn't get local Kerberos realm: %s\n", 76 krb_err_txt[rval]); 77 exit(1); 78 } 79 80 if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) { 81 fprintf(stderr, "couldn't get Kerberos host: %s\n", 82 krb_err_txt[rval]); 83 exit(1); 84 } 85 86 if ((host = gethostbyname(krbhst)) == NULL) { 87 fprintf(stderr, "couldn't get host entry for host %s\n", 88 krbhst); 89 exit(1); 90 } 91 92 sin.sin_family = host->h_addrtype; 93 bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length); 94 sin.sin_port = se->s_port; 95 96 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 97 perror("socket"); 98 exit(1); 99 } 100 101 if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) { 102 perror("connect"); 103 close(sock); 104 exit(1); 105 } 106 107 llen = sizeof(local); 108 if (getsockname(sock, (struct sockaddr *) &local, &llen) < 0) { 109 perror("getsockname"); 110 close(sock); 111 exit(1); 112 } 113 114 setup_key(local); 115 116 type_info(); 117 118 if (!get_user_info()) { 119 code = ABORT; 120 (void)des_write(sock, &code, 1); 121 cleanup(); 122 exit(1); 123 } 124 125 code = APPEND_DB; 126 if(des_write(sock, &code, 1) != 1) { 127 perror("write 1"); 128 cleanup(); 129 exit(1); 130 } 131 132 if(des_write(sock, pname, ANAME_SZ) != ANAME_SZ) { 133 perror("write principal name"); 134 cleanup(); 135 exit(1); 136 } 137 138 if(des_write(sock, iname, INST_SZ) != INST_SZ) { 139 perror("write instance name"); 140 cleanup(); 141 exit(1); 142 } 143 144 if(des_write(sock, password, 255) != 255) { 145 perror("write password"); 146 cleanup(); 147 exit(1); 148 } 149 150 /* get return message */ 151 152 { 153 int cc; 154 char msgbuf[BUFSIZ]; 155 156 cc = read(sock, msgbuf, BUFSIZ); 157 if (cc <= 0) { 158 fprintf(stderr, "protocol error during key verification\n"); 159 cleanup(); 160 exit(1); 161 } 162 if (strncmp(msgbuf, GOTKEY_MSG, 6) != 0) { 163 fprintf(stderr, "%s: %s", krbhst, msgbuf); 164 cleanup(); 165 exit(1); 166 } 167 168 cc = des_read(sock, msgbuf, BUFSIZ); 169 if(cc <= 0) { 170 fprintf(stderr, "protocol error during read\n"); 171 cleanup(); 172 exit(1); 173 } else { 174 printf("%s: %s", krbhst, msgbuf); 175 } 176 } 177 178 cleanup(); 179 close(sock); 180 } 181 182 cleanup() 183 { 184 bzero(password, 255); 185 } 186 187 #include <pwd.h> 188 189 extern char *crypt(); 190 extern char *getpass(); 191 192 int 193 get_user_info() 194 { 195 int uid = getuid(); 196 int valid = 0, i; 197 struct passwd *pw; 198 char *pas, *namep; 199 200 if((pw = getpwuid(uid)) == NULL) { 201 fprintf(stderr, "Who are you?\n"); 202 return(0); 203 } 204 seteuid(uid); 205 strcpy(pname, pw->pw_name); /* principal name */ 206 for(i = 1; i < 3; i++) { 207 pas = getpass("login password:"); 208 namep = crypt(pas, pw->pw_passwd); 209 if(strcmp(namep, pw->pw_passwd)) { 210 fprintf(stderr, "Password incorrect\n"); 211 continue; 212 } else { 213 valid = 1; 214 break; 215 } 216 } 217 if(!valid) 218 return(0); 219 pas = getpass("Kerberos password (may be the same):"); 220 while(*pas == NULL) { 221 printf("<NULL> password not allowed\n"); 222 pas = getpass("Kerberos password (may be the same):"); 223 } 224 strcpy(password, pas); /* password */ 225 pas = getpass("Retype Kerberos password:"); 226 if(strcmp(password, pas)) { 227 fprintf(stderr, "Password mismatch -- aborted\n"); 228 return(0); 229 } 230 231 iname[0] = NULL; /* null instance name */ 232 return(1); 233 } 234 235 setup_key(local) 236 struct sockaddr_in local; 237 { 238 static struct keyfile_data kdata; 239 static Key_schedule schedule; 240 int fd; 241 char namebuf[MAXPATHLEN]; 242 extern int errno; 243 244 sprintf(namebuf, KFILE, inet_ntoa(local.sin_addr)); 245 fd = open(namebuf, O_RDONLY); 246 if(fd < 0) { 247 fprintf(stderr, "couldn't open key file for local host %s\n", 248 inet_ntoa(local.sin_addr)); 249 perror("open"); 250 exit(1); 251 } 252 253 if(read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) { 254 fprintf(stderr,"size error reading key file for local host %s\n", 255 inet_ntoa(local.sin_addr)); 256 exit(1); 257 } 258 key_sched(kdata.kf_key, schedule); 259 des_set_key(kdata.kf_key, schedule); 260 } 261 262 type_info() 263 { 264 printf("Kerberos user registration (realm %s)\n\n", realm); 265 printf("Please enter your login password followed by your new Kerberos password.\n"); 266 printf("The Kerberos password you enter now will be used in the future\n"); 267 printf("as your Kerberos password for all machines in the %s realm.\n", realm); 268 printf("You will only be allowed to perform this operation once, although you may run\n"); 269 printf("the %s program from now on to change your Kerberos password.\n\n", KPASSWD); 270 } 271 272 die() 273 { 274 fprintf(stderr, "\nServer no longer listeninga\n"); 275 fflush(stderr); 276 cleanup(); 277 exit(1); 278 } 279