|
|
1.1 ! root 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.4 (Berkeley) 5/17/89"; ! 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 <kerberos/krb.h> ! 33: #include <kerberos/krb_db.h> ! 34: #include "register_proto.h" ! 35: ! 36: #define SKEYFILE "/kerberos/update.key%s" ! 37: #define KBUFSIZ (sizeof(struct keyfile_data)) ! 38: #define CRYPT 0x00 ! 39: #define CLEAR 0x01 ! 40: ! 41: char *progname; ! 42: struct sockaddr_in sin; ! 43: char msgbuf[BUFSIZ]; ! 44: ! 45: int die(); ! 46: ! 47: main(argc, argv) ! 48: char **argv; ! 49: { ! 50: int kf; ! 51: char keyfile[MAXPATHLEN]; ! 52: static Key_schedule schedule; ! 53: u_char code; ! 54: char keybuf[KBUFSIZ]; ! 55: int retval, sval; ! 56: struct keyfile_data *kfile; ! 57: static struct rlimit rl = { 0, 0 }; ! 58: ! 59: openlog("registerd", LOG_PID, LOG_AUTH); ! 60: ! 61: progname = argv[0]; ! 62: ! 63: signal(SIGHUP, SIG_IGN); ! 64: signal(SIGINT, SIG_IGN); ! 65: signal(SIGTSTP, SIG_IGN); ! 66: signal(SIGPIPE, die); ! 67: if(setrlimit(RLIMIT_CORE, &rl) < 0) { ! 68: syslog(LOG_ERR, "setrlimit: %m"); ! 69: exit(1); ! 70: } ! 71: ! 72: ! 73: /* figure out who we are talking to */ ! 74: ! 75: sval = sizeof(sin); ! 76: if(getpeername(0, (struct sockaddr *) &sin, &sval) < 0) { ! 77: syslog(LOG_ERR, "getpeername: %m"); ! 78: exit(1); ! 79: } ! 80: ! 81: /* get encryption key */ ! 82: ! 83: (void) sprintf(keyfile, SKEYFILE, inet_ntoa(sin.sin_addr)); ! 84: if((kf = open(keyfile, O_RDONLY)) < 0) { ! 85: syslog(LOG_ERR, "error opening Kerberos update keyfile (%s): %m", keyfile); ! 86: (void) sprintf(msgbuf, "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)", code); ! 120: } ! 121: ! 122: } else { ! 123: retval = KFAILURE; ! 124: syslog(LOG_ERR, "couldn't read command code on Kerberos update"); ! 125: } ! 126: ! 127: code = (u_char) retval; ! 128: if(code != KSUCCESS) { ! 129: (void) sprintf(msgbuf, "%s", krb_err_txt[code]); ! 130: send_packet(msgbuf,CRYPT); ! 131: } else { ! 132: (void) sprintf(msgbuf, "Update complete."); ! 133: send_packet(msgbuf, CRYPT); ! 134: } ! 135: cleanup(); ! 136: close(0); ! 137: exit(0); ! 138: } ! 139: ! 140: #define MAX_PRINCIPAL 10 ! 141: static Principal principal_data[MAX_PRINCIPAL]; ! 142: static C_Block key, master_key; ! 143: static Key_schedule master_key_schedule; ! 144: int ! 145: do_append() ! 146: { ! 147: Principal default_princ; ! 148: char input_name[ANAME_SZ]; ! 149: char input_instance[INST_SZ]; ! 150: int j,n, more; ! 151: long mkeyversion; ! 152: ! 153: ! 154: ! 155: /* get master key from MKEYFILE */ ! 156: if(kdb_get_master_key(0, master_key, master_key_schedule) != 0) { ! 157: syslog(LOG_ERR, "couldn't get master key"); ! 158: return(KFAILURE); ! 159: } ! 160: ! 161: mkeyversion = kdb_verify_master_key(master_key, master_key_schedule, NULL); ! 162: if(mkeyversion < 0) { ! 163: syslog(LOG_ERR, "couldn't validate master key"); ! 164: return(KFAILURE); ! 165: } ! 166: ! 167: n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, ! 168: &default_princ, 1, &more); ! 169: ! 170: if(n != 1) { ! 171: syslog(LOG_ERR, "couldn't get default principal"); ! 172: return(KFAILURE); ! 173: } ! 174: ! 175: /* ! 176: * get principal name, instance, and password from network. ! 177: * convert password to key and store it ! 178: */ ! 179: ! 180: if(net_get_principal(input_name, input_instance, key) != 0) { ! 181: return(KFAILURE); ! 182: } ! 183: ! 184: ! 185: j = kerb_get_principal( ! 186: input_name, ! 187: input_instance, ! 188: principal_data, ! 189: MAX_PRINCIPAL, ! 190: &more ! 191: ); ! 192: ! 193: if(j != 0) { ! 194: /* already in database, no update */ ! 195: syslog(LOG_NOTICE, "attempt to add duplicate entry for principal %s.%s", ! 196: input_name, input_instance); ! 197: return(KDC_PR_N_UNIQUE); ! 198: } ! 199: ! 200: /* ! 201: * set up principal's name, instance ! 202: */ ! 203: ! 204: strcpy(principal_data[0].name, input_name); ! 205: strcpy(principal_data[0].instance, input_instance); ! 206: principal_data[0].old = NULL; ! 207: ! 208: ! 209: /* and the expiration date and version #s */ ! 210: ! 211: principal_data[0].exp_date = default_princ.exp_date; ! 212: strcpy(principal_data[0].exp_date_txt, default_princ.exp_date_txt); ! 213: principal_data[0].max_life = default_princ.max_life; ! 214: principal_data[0].attributes = default_princ.attributes; ! 215: principal_data[0].kdc_key_ver = default_princ.kdc_key_ver; ! 216: ! 217: ! 218: /* and the key */ ! 219: ! 220: kdb_encrypt_key(key, key, master_key, master_key_schedule, ! 221: ENCRYPT); ! 222: bcopy(key, &principal_data[0].key_low, 4); ! 223: bcopy(((long *) key) + 1, &principal_data[0].key_high,4); ! 224: bzero(key, sizeof(key)); ! 225: ! 226: principal_data[0].key_version = 1; /* 1st entry */ ! 227: if(kerb_put_principal(&principal_data[0], 1)) { ! 228: syslog(LOG_INFO, "Kerberos update failure: put_principal failed"); ! 229: return(KFAILURE); ! 230: } ! 231: ! 232: syslog(LOG_NOTICE, "Kerberos update: wrote new record for %s.%s from %s", ! 233: principal_data[0].name, ! 234: principal_data[0].instance, ! 235: inet_ntoa(sin.sin_addr) ! 236: ); ! 237: ! 238: return(KSUCCESS); ! 239: ! 240: } ! 241: ! 242: send_packet(msg,flag) ! 243: char *msg; ! 244: int flag; ! 245: { ! 246: int len = strlen(msg); ! 247: msg[len++] = '\n'; ! 248: msg[len] = '\0'; ! 249: if (len > sizeof(msgbuf)) { ! 250: syslog(LOG_ERR, "send_packet: invalid msg size"); ! 251: return; ! 252: } ! 253: if (flag == CRYPT) { ! 254: if (des_write(0, msg, len) != len) ! 255: syslog(LOG_ERR, "couldn't write reply message"); ! 256: } else if (flag == CLEAR) { ! 257: if (write(0, msg, len) != len) ! 258: syslog(LOG_ERR, "couldn't write reply message"); ! 259: } else ! 260: syslog(LOG_ERR, "send_packet: invalid flag (%d)", flag); ! 261: ! 262: } ! 263: ! 264: net_get_principal(pname, iname, keyp) ! 265: char *pname, *iname; ! 266: C_Block *keyp; ! 267: { ! 268: int cc; ! 269: static char password[255]; ! 270: ! 271: cc = des_read(0, pname, ANAME_SZ); ! 272: if(cc != ANAME_SZ) { ! 273: syslog(LOG_ERR, "couldn't get principal name"); ! 274: return(-1); ! 275: } ! 276: ! 277: cc = des_read(0, iname, INST_SZ); ! 278: if(cc != INST_SZ) { ! 279: syslog(LOG_ERR, "couldn't get instance name"); ! 280: return(-1); ! 281: } ! 282: ! 283: cc = des_read(0, password, 255); ! 284: if(cc != 255) { ! 285: syslog(LOG_ERR, "couldn't get password"); ! 286: bzero(password, 255); ! 287: return(-1); ! 288: } ! 289: ! 290: string_to_key(password, *keyp); ! 291: bzero(password, 255); ! 292: return(0); ! 293: } ! 294: ! 295: cleanup() ! 296: { ! 297: bzero(master_key, sizeof(master_key)); ! 298: bzero(key, sizeof(key)); ! 299: bzero(master_key_schedule, sizeof(master_key_schedule)); ! 300: } ! 301: ! 302: die() ! 303: { ! 304: syslog(LOG_ERR, "remote end died (SIGPIPE)"); ! 305: cleanup(); ! 306: exit(1); ! 307: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.