1 2 /* 3 * Copyright (c) 1989 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms are permitted 7 * provided that the above copyright notice and this paragraph are 8 * duplicated in all such forms and that any documentation, 9 * advertising materials, and other materials related to such 10 * distribution and use acknowledge that the software was developed 11 * by the University of California, Berkeley. The name of the 12 * University may not be used to endorse or promote products derived 13 * from this software without specific prior written permission. 14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 17 */ 18 19 #ifndef lint 20 static char sccsid[] = "@(#)registerd.c 1.7 (Berkeley) 05/11/90"; 21 #endif /* not lint */ 22 23 #include <sys/types.h> 24 #include <sys/time.h> 25 #include <sys/signal.h> 26 #include <sys/resource.h> 27 #include <sys/param.h> 28 #include <sys/file.h> 29 #include <netinet/in.h> 30 #include <stdio.h> 31 #include <syslog.h> 32 #include <kerberosIV/des.h> 33 #include <kerberosIV/krb.h> 34 #include <kerberosIV/krb_db.h> 35 #include "pathnames.h" 36 #include "register_proto.h" 37 38 #define KBUFSIZ (sizeof(struct keyfile_data)) 39 #define CRYPT 0x00 40 #define CLEAR 0x01 41 42 char *progname; 43 struct sockaddr_in sin; 44 char msgbuf[BUFSIZ]; 45 46 int die(); 47 48 main(argc, argv) 49 char **argv; 50 { 51 int kf; 52 char keyfile[MAXPATHLEN]; 53 static Key_schedule schedule; 54 u_char code; 55 char keybuf[KBUFSIZ]; 56 int retval, sval; 57 struct keyfile_data *kfile; 58 static struct rlimit rl = { 0, 0 }; 59 60 openlog("registerd", LOG_PID, LOG_AUTH); 61 62 progname = argv[0]; 63 64 signal(SIGHUP, SIG_IGN); 65 signal(SIGINT, SIG_IGN); 66 signal(SIGTSTP, SIG_IGN); 67 signal(SIGPIPE, die); 68 if (setrlimit(RLIMIT_CORE, &rl) < 0) { 69 syslog(LOG_ERR, "setrlimit: %m"); 70 exit(1); 71 } 72 73 74 /* figure out who we are talking to */ 75 76 sval = sizeof(sin); 77 if (getpeername(0, (struct sockaddr *) &sin, &sval) < 0) { 78 syslog(LOG_ERR, "getpeername: %m"); 79 exit(1); 80 } 81 82 /* get encryption key */ 83 84 (void) sprintf(keyfile, "%s%s%s", 85 SERVER_KEYDIR, 86 CLIENT_KEYFILE, 87 inet_ntoa(sin.sin_addr)); 88 89 if ((kf = open(keyfile, O_RDONLY)) < 0) { 90 syslog(LOG_ERR, 91 "error opening Kerberos update keyfile (%s): %m", keyfile); 92 (void) sprintf(msgbuf, 93 "couldn't open session keyfile for your host"); 94 send_packet(msgbuf, CLEAR); 95 exit(1); 96 } 97 98 if (read(kf, keybuf, KBUFSIZ) != KBUFSIZ) { 99 syslog(LOG_ERR, "wrong read size of Kerberos update keyfile"); 100 (void) sprintf(msgbuf, 101 "couldn't read session key from your host's keyfile"); 102 send_packet(msgbuf, CLEAR); 103 exit(1); 104 } 105 (void) sprintf(msgbuf, GOTKEY_MSG); 106 send_packet(msgbuf, CLEAR); 107 kfile = (struct keyfile_data *) keybuf; 108 key_sched(kfile->kf_key, schedule); 109 des_set_key(kfile->kf_key, schedule); 110 111 /* read the command code byte */ 112 113 if (des_read(0, &code, 1) == 1) { 114 115 switch(code) { 116 case APPEND_DB: 117 retval = do_append(); 118 break; 119 case ABORT: 120 cleanup(); 121 close(0); 122 exit(0); 123 default: 124 retval = KFAILURE; 125 syslog(LOG_NOTICE, 126 "invalid command code on db update (0x%x)", 127 code); 128 } 129 130 } else { 131 retval = KFAILURE; 132 syslog(LOG_ERR, "couldn't read command code on Kerberos update"); 133 } 134 135 code = (u_char) retval; 136 if (code != KSUCCESS) { 137 (void) sprintf(msgbuf, "%s", krb_err_txt[code]); 138 send_packet(msgbuf, CRYPT); 139 } else { 140 (void) sprintf(msgbuf, "Update complete."); 141 send_packet(msgbuf, CRYPT); 142 } 143 cleanup(); 144 close(0); 145 exit(0); 146 } 147 148 #define MAX_PRINCIPAL 10 149 static Principal principal_data[MAX_PRINCIPAL]; 150 static C_Block key, master_key; 151 static Key_schedule master_key_schedule; 152 int 153 do_append() 154 { 155 Principal default_princ; 156 char input_name[ANAME_SZ]; 157 char input_instance[INST_SZ]; 158 int j,n, more; 159 long mkeyversion; 160 161 162 163 /* get master key from MKEYFILE */ 164 if (kdb_get_master_key(0, master_key, master_key_schedule) != 0) { 165 syslog(LOG_ERR, "couldn't get master key"); 166 return(KFAILURE); 167 } 168 169 mkeyversion = kdb_verify_master_key(master_key, master_key_schedule, NULL); 170 if (mkeyversion < 0) { 171 syslog(LOG_ERR, "couldn't validate master key"); 172 return(KFAILURE); 173 } 174 175 n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, 176 &default_princ, 1, &more); 177 178 if (n != 1) { 179 syslog(LOG_ERR, "couldn't get default principal"); 180 return(KFAILURE); 181 } 182 183 /* 184 * get principal name, instance, and password from network. 185 * convert password to key and store it 186 */ 187 188 if (net_get_principal(input_name, input_instance, key) != 0) { 189 return(KFAILURE); 190 } 191 192 193 j = kerb_get_principal( 194 input_name, 195 input_instance, 196 principal_data, 197 MAX_PRINCIPAL, 198 &more 199 ); 200 201 if (j != 0) { 202 /* already in database, no update */ 203 syslog(LOG_NOTICE, 204 "attempt to add duplicate entry for principal %s.%s", 205 input_name, input_instance); 206 return(KDC_PR_N_UNIQUE); 207 } 208 209 /* 210 * set up principal's name, instance 211 */ 212 213 strcpy(principal_data[0].name, input_name); 214 strcpy(principal_data[0].instance, input_instance); 215 principal_data[0].old = NULL; 216 217 218 /* and the expiration date and version #s */ 219 220 principal_data[0].exp_date = default_princ.exp_date; 221 strcpy(principal_data[0].exp_date_txt, default_princ.exp_date_txt); 222 principal_data[0].max_life = default_princ.max_life; 223 principal_data[0].attributes = default_princ.attributes; 224 principal_data[0].kdc_key_ver = default_princ.kdc_key_ver; 225 226 227 /* and the key */ 228 229 kdb_encrypt_key(key, key, master_key, master_key_schedule, 230 ENCRYPT); 231 bcopy(key, &principal_data[0].key_low, 4); 232 bcopy(((long *) key) + 1, &principal_data[0].key_high,4); 233 bzero(key, sizeof(key)); 234 235 principal_data[0].key_version = 1; /* 1st entry */ 236 237 /* and write it to the database */ 238 239 if (kerb_put_principal(&principal_data[0], 1)) { 240 syslog(LOG_INFO, "Kerberos update failure: put_principal failed"); 241 return(KFAILURE); 242 } 243 244 syslog(LOG_NOTICE, "Kerberos update: wrote new record for %s.%s from %s", 245 principal_data[0].name, 246 principal_data[0].instance, 247 inet_ntoa(sin.sin_addr) 248 ); 249 250 return(KSUCCESS); 251 252 } 253 254 send_packet(msg,flag) 255 char *msg; 256 int flag; 257 { 258 int len = strlen(msg); 259 msg[len++] = '\n'; 260 msg[len] = '\0'; 261 if (len > sizeof(msgbuf)) { 262 syslog(LOG_ERR, "send_packet: invalid msg size"); 263 return; 264 } 265 if (flag == CRYPT) { 266 if (des_write(0, msg, len) != len) 267 syslog(LOG_ERR, "couldn't write reply message"); 268 } else if (flag == CLEAR) { 269 if (write(0, msg, len) != len) 270 syslog(LOG_ERR, "couldn't write reply message"); 271 } else 272 syslog(LOG_ERR, "send_packet: invalid flag (%d)", flag); 273 274 } 275 276 net_get_principal(pname, iname, keyp) 277 char *pname, *iname; 278 C_Block *keyp; 279 { 280 int cc; 281 static char password[255]; 282 283 cc = des_read(0, pname, ANAME_SZ); 284 if (cc != ANAME_SZ) { 285 syslog(LOG_ERR, "couldn't get principal name"); 286 return(-1); 287 } 288 289 cc = des_read(0, iname, INST_SZ); 290 if (cc != INST_SZ) { 291 syslog(LOG_ERR, "couldn't get instance name"); 292 return(-1); 293 } 294 295 cc = des_read(0, password, 255); 296 if (cc != 255) { 297 syslog(LOG_ERR, "couldn't get password"); 298 bzero(password, 255); 299 return(-1); 300 } 301 302 string_to_key(password, *keyp); 303 bzero(password, 255); 304 return(0); 305 } 306 307 cleanup() 308 { 309 bzero(master_key, sizeof(master_key)); 310 bzero(key, sizeof(key)); 311 bzero(master_key_schedule, sizeof(master_key_schedule)); 312 } 313 314 die() 315 { 316 syslog(LOG_ERR, "remote end died (SIGPIPE)"); 317 cleanup(); 318 exit(1); 319 } 320