1*38048Skfall
2*38048Skfall /*
3*38048Skfall * Copyright (c) 1989 The Regents of the University of California.
4*38048Skfall * All rights reserved.
5*38048Skfall *
6*38048Skfall * Redistribution and use in source and binary forms are permitted
7*38048Skfall * provided that the above copyright notice and this paragraph are
8*38048Skfall * duplicated in all such forms and that any documentation,
9*38048Skfall * advertising materials, and other materials related to such
10*38048Skfall * distribution and use acknowledge that the software was developed
11*38048Skfall * by the University of California, Berkeley. The name of the
12*38048Skfall * University may not be used to endorse or promote products derived
13*38048Skfall * from this software without specific prior written permission.
14*38048Skfall * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15*38048Skfall * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16*38048Skfall * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17*38048Skfall */
18*38048Skfall
19*38048Skfall #ifndef lint
20*38048Skfall static char sccsid[] = "@(#)registerd.c 1.4 (Berkeley) 05/17/89";
21*38048Skfall #endif /* not lint */
22*38048Skfall
2336346Skfall #include <sys/types.h>
2436346Skfall #include <sys/time.h>
2536350Skfall #include <sys/signal.h>
2636346Skfall #include <sys/resource.h>
2736346Skfall #include <sys/param.h>
2836346Skfall #include <sys/file.h>
2936346Skfall #include <netinet/in.h>
3036346Skfall #include <stdio.h>
3136346Skfall #include <syslog.h>
3236346Skfall #include <kerberos/krb.h>
3336346Skfall #include <kerberos/krb_db.h>
3436346Skfall #include "register_proto.h"
3536346Skfall
3636346Skfall #define SKEYFILE "/kerberos/update.key%s"
3736346Skfall #define KBUFSIZ (sizeof(struct keyfile_data))
3837171Skfall #define CRYPT 0x00
3937171Skfall #define CLEAR 0x01
4036346Skfall
4136346Skfall char *progname;
4236346Skfall struct sockaddr_in sin;
4337171Skfall char msgbuf[BUFSIZ];
4436346Skfall
4536350Skfall int die();
4636350Skfall
main(argc,argv)4736346Skfall main(argc, argv)
4836346Skfall char **argv;
4936346Skfall {
5036346Skfall int kf;
5136346Skfall char keyfile[MAXPATHLEN];
5236346Skfall static Key_schedule schedule;
5336346Skfall u_char code;
5436346Skfall char keybuf[KBUFSIZ];
5536346Skfall int retval, sval;
5636346Skfall struct keyfile_data *kfile;
5736346Skfall static struct rlimit rl = { 0, 0 };
5836346Skfall
5937171Skfall openlog("registerd", LOG_PID, LOG_AUTH);
6036346Skfall
6136346Skfall progname = argv[0];
6236346Skfall
6336346Skfall signal(SIGHUP, SIG_IGN);
6436346Skfall signal(SIGINT, SIG_IGN);
6536346Skfall signal(SIGTSTP, SIG_IGN);
6636350Skfall signal(SIGPIPE, die);
6736346Skfall if(setrlimit(RLIMIT_CORE, &rl) < 0) {
6836346Skfall syslog(LOG_ERR, "setrlimit: %m");
6936346Skfall exit(1);
7036346Skfall }
7136346Skfall
7236346Skfall
7336346Skfall /* figure out who we are talking to */
7436346Skfall
7536346Skfall sval = sizeof(sin);
7636346Skfall if(getpeername(0, (struct sockaddr *) &sin, &sval) < 0) {
7736346Skfall syslog(LOG_ERR, "getpeername: %m");
7836346Skfall exit(1);
7936346Skfall }
8036346Skfall
8136346Skfall /* get encryption key */
8236346Skfall
8336346Skfall (void) sprintf(keyfile, SKEYFILE, inet_ntoa(sin.sin_addr));
8436346Skfall if((kf = open(keyfile, O_RDONLY)) < 0) {
8536346Skfall syslog(LOG_ERR, "error opening Kerberos update keyfile (%s): %m", keyfile);
8637171Skfall (void) sprintf(msgbuf, "couldn't open session keyfile for your host");
8737171Skfall send_packet(msgbuf, CLEAR);
8836346Skfall exit(1);
8936346Skfall }
9036346Skfall
9136346Skfall if(read(kf, keybuf, KBUFSIZ) != KBUFSIZ) {
9236346Skfall syslog(LOG_ERR, "wrong read size of Kerberos update keyfile");
93*38048Skfall (void) sprintf(msgbuf,
94*38048Skfall "couldn't read session key from your host's keyfile");
9537171Skfall send_packet(msgbuf, CLEAR);
9636346Skfall exit(1);
9736346Skfall }
98*38048Skfall (void) sprintf(msgbuf, GOTKEY_MSG);
9937171Skfall send_packet(msgbuf, CLEAR);
10036346Skfall kfile = (struct keyfile_data *) keybuf;
10136346Skfall key_sched(kfile->kf_key, schedule);
10236346Skfall des_set_key(kfile->kf_key, schedule);
10336346Skfall
10436346Skfall /* read the command code byte */
10536346Skfall
10636346Skfall if(des_read(0, &code, 1) == 1) {
10736346Skfall
10836346Skfall switch(code) {
10936346Skfall case APPEND_DB:
11036346Skfall retval = do_append();
11136346Skfall break;
112*38048Skfall case ABORT:
113*38048Skfall cleanup();
114*38048Skfall close(0);
115*38048Skfall exit(0);
11636346Skfall default:
11736346Skfall retval = KFAILURE;
118*38048Skfall syslog(LOG_NOTICE,
119*38048Skfall "invalid command code on db update (0x%x)", code);
12036346Skfall }
12136346Skfall
12236346Skfall } else {
12336346Skfall retval = KFAILURE;
12436346Skfall syslog(LOG_ERR, "couldn't read command code on Kerberos update");
12536346Skfall }
12636346Skfall
12737171Skfall code = (u_char) retval;
12837171Skfall if(code != KSUCCESS) {
12937171Skfall (void) sprintf(msgbuf, "%s", krb_err_txt[code]);
13037171Skfall send_packet(msgbuf,CRYPT);
13137171Skfall } else {
13237171Skfall (void) sprintf(msgbuf, "Update complete.");
13337171Skfall send_packet(msgbuf, CRYPT);
13437171Skfall }
13536346Skfall cleanup();
13636346Skfall close(0);
13736346Skfall exit(0);
13836346Skfall }
13936346Skfall
14036346Skfall #define MAX_PRINCIPAL 10
14136346Skfall static Principal principal_data[MAX_PRINCIPAL];
14236346Skfall static C_Block key, master_key;
14336346Skfall static Key_schedule master_key_schedule;
14436346Skfall int
do_append()14536346Skfall do_append()
14636346Skfall {
14736346Skfall Principal default_princ;
14836346Skfall char input_name[ANAME_SZ];
14936346Skfall char input_instance[INST_SZ];
15036346Skfall int j,n, more;
15136346Skfall long mkeyversion;
15236346Skfall
15336346Skfall
15436346Skfall
15536346Skfall /* get master key from MKEYFILE */
15636346Skfall if(kdb_get_master_key(0, master_key, master_key_schedule) != 0) {
15736346Skfall syslog(LOG_ERR, "couldn't get master key");
15836346Skfall return(KFAILURE);
15936346Skfall }
16036346Skfall
16136346Skfall mkeyversion = kdb_verify_master_key(master_key, master_key_schedule, NULL);
16236346Skfall if(mkeyversion < 0) {
16336346Skfall syslog(LOG_ERR, "couldn't validate master key");
16436346Skfall return(KFAILURE);
16536346Skfall }
16636346Skfall
16736346Skfall n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
16836346Skfall &default_princ, 1, &more);
16936346Skfall
17036346Skfall if(n != 1) {
17136346Skfall syslog(LOG_ERR, "couldn't get default principal");
17236346Skfall return(KFAILURE);
17336346Skfall }
17436346Skfall
17536346Skfall /*
17636346Skfall * get principal name, instance, and password from network.
17736346Skfall * convert password to key and store it
17836346Skfall */
17936346Skfall
18036346Skfall if(net_get_principal(input_name, input_instance, key) != 0) {
18136346Skfall return(KFAILURE);
18236346Skfall }
18336346Skfall
18436346Skfall
18536346Skfall j = kerb_get_principal(
18636346Skfall input_name,
18736346Skfall input_instance,
18836346Skfall principal_data,
18936346Skfall MAX_PRINCIPAL,
19036346Skfall &more
19136346Skfall );
19236346Skfall
19336346Skfall if(j != 0) {
19436346Skfall /* already in database, no update */
19536346Skfall syslog(LOG_NOTICE, "attempt to add duplicate entry for principal %s.%s",
19636346Skfall input_name, input_instance);
19736346Skfall return(KDC_PR_N_UNIQUE);
19836346Skfall }
19936346Skfall
20036346Skfall /*
20136346Skfall * set up principal's name, instance
20236346Skfall */
20336346Skfall
20436346Skfall strcpy(principal_data[0].name, input_name);
20536346Skfall strcpy(principal_data[0].instance, input_instance);
20636346Skfall principal_data[0].old = NULL;
20736346Skfall
20836346Skfall
20936346Skfall /* and the expiration date and version #s */
21036346Skfall
21136346Skfall principal_data[0].exp_date = default_princ.exp_date;
21236346Skfall strcpy(principal_data[0].exp_date_txt, default_princ.exp_date_txt);
21336346Skfall principal_data[0].max_life = default_princ.max_life;
21436346Skfall principal_data[0].attributes = default_princ.attributes;
21536346Skfall principal_data[0].kdc_key_ver = default_princ.kdc_key_ver;
21636346Skfall
21736346Skfall
21836346Skfall /* and the key */
21936346Skfall
22036346Skfall kdb_encrypt_key(key, key, master_key, master_key_schedule,
22136346Skfall ENCRYPT);
22236346Skfall bcopy(key, &principal_data[0].key_low, 4);
22336346Skfall bcopy(((long *) key) + 1, &principal_data[0].key_high,4);
22436346Skfall bzero(key, sizeof(key));
22536346Skfall
22636346Skfall principal_data[0].key_version = 1; /* 1st entry */
22736346Skfall if(kerb_put_principal(&principal_data[0], 1)) {
22836346Skfall syslog(LOG_INFO, "Kerberos update failure: put_principal failed");
22936346Skfall return(KFAILURE);
23036346Skfall }
23136346Skfall
23236346Skfall syslog(LOG_NOTICE, "Kerberos update: wrote new record for %s.%s from %s",
23336346Skfall principal_data[0].name,
23436346Skfall principal_data[0].instance,
23536346Skfall inet_ntoa(sin.sin_addr)
23636346Skfall );
23736346Skfall
23836346Skfall return(KSUCCESS);
23936346Skfall
24036346Skfall }
24136346Skfall
send_packet(msg,flag)24237171Skfall send_packet(msg,flag)
24336346Skfall char *msg;
24437171Skfall int flag;
24536346Skfall {
24636346Skfall int len = strlen(msg);
24736346Skfall msg[len++] = '\n';
24836346Skfall msg[len] = '\0';
24937171Skfall if (len > sizeof(msgbuf)) {
25037171Skfall syslog(LOG_ERR, "send_packet: invalid msg size");
25137171Skfall return;
25237171Skfall }
25337171Skfall if (flag == CRYPT) {
25437171Skfall if (des_write(0, msg, len) != len)
25537171Skfall syslog(LOG_ERR, "couldn't write reply message");
25637171Skfall } else if (flag == CLEAR) {
25737171Skfall if (write(0, msg, len) != len)
25837171Skfall syslog(LOG_ERR, "couldn't write reply message");
25937171Skfall } else
26037171Skfall syslog(LOG_ERR, "send_packet: invalid flag (%d)", flag);
26137171Skfall
26236346Skfall }
26336346Skfall
net_get_principal(pname,iname,keyp)26436346Skfall net_get_principal(pname, iname, keyp)
26536346Skfall char *pname, *iname;
26636346Skfall C_Block *keyp;
26736346Skfall {
26836346Skfall int cc;
26936346Skfall static char password[255];
27036346Skfall
27136346Skfall cc = des_read(0, pname, ANAME_SZ);
27236346Skfall if(cc != ANAME_SZ) {
27336346Skfall syslog(LOG_ERR, "couldn't get principal name");
27436346Skfall return(-1);
27536346Skfall }
27636346Skfall
27736346Skfall cc = des_read(0, iname, INST_SZ);
27836346Skfall if(cc != INST_SZ) {
27936346Skfall syslog(LOG_ERR, "couldn't get instance name");
28036346Skfall return(-1);
28136346Skfall }
28236346Skfall
28336346Skfall cc = des_read(0, password, 255);
28436346Skfall if(cc != 255) {
28536346Skfall syslog(LOG_ERR, "couldn't get password");
28636346Skfall bzero(password, 255);
28736346Skfall return(-1);
28836346Skfall }
28936346Skfall
29036346Skfall string_to_key(password, *keyp);
29136346Skfall bzero(password, 255);
29236346Skfall return(0);
29336346Skfall }
29436346Skfall
cleanup()29536346Skfall cleanup()
29636346Skfall {
29736346Skfall bzero(master_key, sizeof(master_key));
29836346Skfall bzero(key, sizeof(key));
29936346Skfall bzero(master_key_schedule, sizeof(master_key_schedule));
30036346Skfall }
30136350Skfall
die()30236350Skfall die()
30336350Skfall {
30436350Skfall syslog(LOG_ERR, "remote end died (SIGPIPE)");
30536350Skfall cleanup();
30636350Skfall exit(1);
30736350Skfall }
308