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.2 (Berkeley) 05/16/93"; 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 char *progname, msgbuf[BUFSIZ]; 38 39 main(argc, argv) 40 int argc; 41 char **argv; 42 { 43 static Key_schedule schedule; 44 static struct rlimit rl = { 0, 0 }; 45 struct keyfile_data *kfile; 46 u_char code; 47 int kf, retval, sval; 48 struct sockaddr_in sin; 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(&sin); 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(sinp) 148 struct sockaddr_in *sinp; 149 { 150 Principal default_princ; 151 char input_name[ANAME_SZ]; 152 char input_instance[INST_SZ]; 153 int j,n, more; 154 long mkeyversion; 155 156 157 158 /* get master key from MKEYFILE */ 159 if (kdb_get_master_key(0, master_key, master_key_schedule) != 0) { 160 syslog(LOG_ERR, "couldn't get master key"); 161 return(KFAILURE); 162 } 163 164 mkeyversion = kdb_verify_master_key(master_key, master_key_schedule, NULL); 165 if (mkeyversion < 0) { 166 syslog(LOG_ERR, "couldn't validate master key"); 167 return(KFAILURE); 168 } 169 170 n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, 171 &default_princ, 1, &more); 172 173 if (n != 1) { 174 syslog(LOG_ERR, "couldn't get default principal"); 175 return(KFAILURE); 176 } 177 178 /* 179 * get principal name, instance, and password from network. 180 * convert password to key and store it 181 */ 182 183 if (net_get_principal(input_name, input_instance, key) != 0) { 184 return(KFAILURE); 185 } 186 187 188 j = kerb_get_principal( 189 input_name, 190 input_instance, 191 principal_data, 192 MAX_PRINCIPAL, 193 &more 194 ); 195 196 if (j != 0) { 197 /* already in database, no update */ 198 syslog(LOG_NOTICE, 199 "attempt to add duplicate entry for principal %s.%s", 200 input_name, input_instance); 201 return(KDC_PR_N_UNIQUE); 202 } 203 204 /* 205 * set up principal's name, instance 206 */ 207 208 strcpy(principal_data[0].name, input_name); 209 strcpy(principal_data[0].instance, input_instance); 210 principal_data[0].old = NULL; 211 212 213 /* and the expiration date and version #s */ 214 215 principal_data[0].exp_date = default_princ.exp_date; 216 strcpy(principal_data[0].exp_date_txt, default_princ.exp_date_txt); 217 principal_data[0].max_life = default_princ.max_life; 218 principal_data[0].attributes = default_princ.attributes; 219 principal_data[0].kdc_key_ver = default_princ.kdc_key_ver; 220 221 222 /* and the key */ 223 224 kdb_encrypt_key(key, key, master_key, master_key_schedule, 225 ENCRYPT); 226 bcopy(key, &principal_data[0].key_low, 4); 227 bcopy(((long *) key) + 1, &principal_data[0].key_high,4); 228 bzero(key, sizeof(key)); 229 230 principal_data[0].key_version = 1; /* 1st entry */ 231 232 /* and write it to the database */ 233 234 if (kerb_put_principal(&principal_data[0], 1)) { 235 syslog(LOG_INFO, "Kerberos update failure: put_principal failed"); 236 return(KFAILURE); 237 } 238 239 syslog(LOG_NOTICE, "Kerberos update: wrote new record for %s.%s from %s", 240 principal_data[0].name, 241 principal_data[0].instance, 242 inet_ntoa(sinp->sin_addr) 243 ); 244 245 return(KSUCCESS); 246 247 } 248 249 send_packet(msg,flag) 250 char *msg; 251 int flag; 252 { 253 int len = strlen(msg); 254 msg[len++] = '\n'; 255 msg[len] = '\0'; 256 if (len > sizeof(msgbuf)) { 257 syslog(LOG_ERR, "send_packet: invalid msg size"); 258 return; 259 } 260 if (flag == RCRYPT) { 261 if (des_write(0, msg, len) != len) 262 syslog(LOG_ERR, "couldn't write reply message"); 263 } else if (flag == CLEAR) { 264 if (write(0, msg, len) != len) 265 syslog(LOG_ERR, "couldn't write reply message"); 266 } else 267 syslog(LOG_ERR, "send_packet: invalid flag (%d)", flag); 268 269 } 270 271 net_get_principal(pname, iname, keyp) 272 char *pname, *iname; 273 C_Block *keyp; 274 { 275 int cc; 276 static char password[255]; 277 278 cc = des_read(0, pname, ANAME_SZ); 279 if (cc != ANAME_SZ) { 280 syslog(LOG_ERR, "couldn't get principal name"); 281 return(-1); 282 } 283 284 cc = des_read(0, iname, INST_SZ); 285 if (cc != INST_SZ) { 286 syslog(LOG_ERR, "couldn't get instance name"); 287 return(-1); 288 } 289 290 cc = des_read(0, password, 255); 291 if (cc != 255) { 292 syslog(LOG_ERR, "couldn't get password"); 293 bzero(password, 255); 294 return(-1); 295 } 296 297 string_to_key(password, *keyp); 298 bzero(password, 255); 299 return(0); 300 } 301 302 cleanup() 303 { 304 bzero(master_key, sizeof(master_key)); 305 bzero(key, sizeof(key)); 306 bzero(master_key_schedule, sizeof(master_key_schedule)); 307 } 308 309 void 310 die() 311 { 312 syslog(LOG_ERR, "remote end died (SIGPIPE)"); 313 cleanup(); 314 exit(1); 315 } 316