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