145459Sbostic /*-
2*60969Sbostic * Copyright (c) 1990, 1993
3*60969Sbostic * The Regents of the University of California. All rights reserved.
438048Skfall *
545459Sbostic * %sccs.include.redist.c%
638048Skfall */
738048Skfall
838048Skfall #ifndef lint
9*60969Sbostic static char copyright[] =
10*60969Sbostic "@(#) Copyright (c) 1990, 1993\n\
11*60969Sbostic The Regents of the University of California. All rights reserved.\n";
1238048Skfall #endif /* not lint */
1338048Skfall
1445459Sbostic #ifndef lint
15*60969Sbostic static char sccsid[] = "@(#)registerd.c 8.1 (Berkeley) 06/01/93";
1645459Sbostic #endif /* not lint */
1745459Sbostic
1836346Skfall #include <sys/types.h>
1936346Skfall #include <sys/time.h>
2036350Skfall #include <sys/signal.h>
2136346Skfall #include <sys/resource.h>
2236346Skfall #include <sys/param.h>
2336346Skfall #include <sys/file.h>
2436346Skfall #include <netinet/in.h>
2536346Skfall #include <syslog.h>
2641769Skfall #include <kerberosIV/des.h>
2741769Skfall #include <kerberosIV/krb.h>
2841769Skfall #include <kerberosIV/krb_db.h>
2945459Sbostic #include <stdio.h>
3045459Sbostic #include "register_proto.h"
3138699Skfall #include "pathnames.h"
3236346Skfall
3336346Skfall #define KBUFSIZ (sizeof(struct keyfile_data))
3445459Sbostic #define RCRYPT 0x00
3537171Skfall #define CLEAR 0x01
3636346Skfall
3745459Sbostic char *progname, msgbuf[BUFSIZ];
3836346Skfall
main(argc,argv)3936346Skfall main(argc, argv)
4045459Sbostic int argc;
4145459Sbostic char **argv;
4236346Skfall {
4336346Skfall static Key_schedule schedule;
4445459Sbostic static struct rlimit rl = { 0, 0 };
4545459Sbostic struct keyfile_data *kfile;
4636346Skfall u_char code;
4745459Sbostic int kf, retval, sval;
4860032Storek struct sockaddr_in sin;
4945459Sbostic char keyfile[MAXPATHLEN], keybuf[KBUFSIZ];
5045459Sbostic void die();
5136346Skfall
5245459Sbostic progname = argv[0]; /* for the library routines */
5345459Sbostic
5437171Skfall openlog("registerd", LOG_PID, LOG_AUTH);
5536346Skfall
5645459Sbostic (void)signal(SIGHUP, SIG_IGN);
5745459Sbostic (void)signal(SIGINT, SIG_IGN);
5845459Sbostic (void)signal(SIGTSTP, SIG_IGN);
5945459Sbostic (void)signal(SIGPIPE, die);
6036346Skfall
6138699Skfall if (setrlimit(RLIMIT_CORE, &rl) < 0) {
6236346Skfall syslog(LOG_ERR, "setrlimit: %m");
6336346Skfall exit(1);
6436346Skfall }
6536346Skfall
6636346Skfall
6736346Skfall /* figure out who we are talking to */
6836346Skfall
6936346Skfall sval = sizeof(sin);
7038699Skfall if (getpeername(0, (struct sockaddr *) &sin, &sval) < 0) {
7136346Skfall syslog(LOG_ERR, "getpeername: %m");
7236346Skfall exit(1);
7336346Skfall }
7436346Skfall
7536346Skfall /* get encryption key */
7636346Skfall
7738703Skfall (void) sprintf(keyfile, "%s%s%s",
7838699Skfall SERVER_KEYDIR,
7938699Skfall CLIENT_KEYFILE,
8038699Skfall inet_ntoa(sin.sin_addr));
8138699Skfall
8238699Skfall if ((kf = open(keyfile, O_RDONLY)) < 0) {
8338699Skfall syslog(LOG_ERR,
8438699Skfall "error opening Kerberos update keyfile (%s): %m", keyfile);
8538699Skfall (void) sprintf(msgbuf,
8638699Skfall "couldn't open session keyfile for your host");
8737171Skfall send_packet(msgbuf, CLEAR);
8836346Skfall exit(1);
8936346Skfall }
9036346Skfall
9138699Skfall if (read(kf, keybuf, KBUFSIZ) != KBUFSIZ) {
9236346Skfall syslog(LOG_ERR, "wrong read size of Kerberos update keyfile");
9338048Skfall (void) sprintf(msgbuf,
9438048Skfall "couldn't read session key from your host's keyfile");
9537171Skfall send_packet(msgbuf, CLEAR);
9636346Skfall exit(1);
9736346Skfall }
9838048Skfall (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
10638699Skfall if (des_read(0, &code, 1) == 1) {
10736346Skfall
10836346Skfall switch(code) {
10936346Skfall case APPEND_DB:
11060032Storek retval = do_append(&sin);
11136346Skfall break;
11238048Skfall case ABORT:
11338048Skfall cleanup();
11438048Skfall close(0);
11538048Skfall exit(0);
11636346Skfall default:
11736346Skfall retval = KFAILURE;
11838048Skfall syslog(LOG_NOTICE,
11938699Skfall "invalid command code on db update (0x%x)",
12038699Skfall code);
12136346Skfall }
12236346Skfall
12336346Skfall } else {
12436346Skfall retval = KFAILURE;
12545459Sbostic syslog(LOG_ERR,
12645459Sbostic "couldn't read command code on Kerberos update");
12736346Skfall }
12836346Skfall
12937171Skfall code = (u_char) retval;
13038699Skfall if (code != KSUCCESS) {
13137171Skfall (void) sprintf(msgbuf, "%s", krb_err_txt[code]);
13245459Sbostic send_packet(msgbuf, RCRYPT);
13337171Skfall } else {
13437171Skfall (void) sprintf(msgbuf, "Update complete.");
13545459Sbostic send_packet(msgbuf, RCRYPT);
13637171Skfall }
13736346Skfall cleanup();
13836346Skfall close(0);
13936346Skfall exit(0);
14036346Skfall }
14136346Skfall
14236346Skfall #define MAX_PRINCIPAL 10
14336346Skfall static Principal principal_data[MAX_PRINCIPAL];
14436346Skfall static C_Block key, master_key;
14536346Skfall static Key_schedule master_key_schedule;
14636346Skfall int
do_append(sinp)14760032Storek do_append(sinp)
14860032Storek struct sockaddr_in *sinp;
14936346Skfall {
15036346Skfall Principal default_princ;
15136346Skfall char input_name[ANAME_SZ];
15236346Skfall char input_instance[INST_SZ];
15336346Skfall int j,n, more;
15436346Skfall long mkeyversion;
15536346Skfall
15636346Skfall
15736346Skfall
15836346Skfall /* get master key from MKEYFILE */
15938699Skfall if (kdb_get_master_key(0, master_key, master_key_schedule) != 0) {
16036346Skfall syslog(LOG_ERR, "couldn't get master key");
16136346Skfall return(KFAILURE);
16236346Skfall }
16336346Skfall
16436346Skfall mkeyversion = kdb_verify_master_key(master_key, master_key_schedule, NULL);
16538699Skfall if (mkeyversion < 0) {
16636346Skfall syslog(LOG_ERR, "couldn't validate master key");
16736346Skfall return(KFAILURE);
16836346Skfall }
16936346Skfall
17036346Skfall n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
17136346Skfall &default_princ, 1, &more);
17236346Skfall
17338699Skfall if (n != 1) {
17436346Skfall syslog(LOG_ERR, "couldn't get default principal");
17536346Skfall return(KFAILURE);
17636346Skfall }
17736346Skfall
17836346Skfall /*
17936346Skfall * get principal name, instance, and password from network.
18036346Skfall * convert password to key and store it
18136346Skfall */
18236346Skfall
18338699Skfall if (net_get_principal(input_name, input_instance, key) != 0) {
18436346Skfall return(KFAILURE);
18536346Skfall }
18636346Skfall
18736346Skfall
18836346Skfall j = kerb_get_principal(
18936346Skfall input_name,
19036346Skfall input_instance,
19136346Skfall principal_data,
19236346Skfall MAX_PRINCIPAL,
19336346Skfall &more
19436346Skfall );
19536346Skfall
19638699Skfall if (j != 0) {
19736346Skfall /* already in database, no update */
19838699Skfall syslog(LOG_NOTICE,
19938699Skfall "attempt to add duplicate entry for principal %s.%s",
20036346Skfall input_name, input_instance);
20136346Skfall return(KDC_PR_N_UNIQUE);
20236346Skfall }
20336346Skfall
20436346Skfall /*
20536346Skfall * set up principal's name, instance
20636346Skfall */
20736346Skfall
20836346Skfall strcpy(principal_data[0].name, input_name);
20936346Skfall strcpy(principal_data[0].instance, input_instance);
21036346Skfall principal_data[0].old = NULL;
21136346Skfall
21236346Skfall
21336346Skfall /* and the expiration date and version #s */
21436346Skfall
21536346Skfall principal_data[0].exp_date = default_princ.exp_date;
21636346Skfall strcpy(principal_data[0].exp_date_txt, default_princ.exp_date_txt);
21736346Skfall principal_data[0].max_life = default_princ.max_life;
21836346Skfall principal_data[0].attributes = default_princ.attributes;
21936346Skfall principal_data[0].kdc_key_ver = default_princ.kdc_key_ver;
22036346Skfall
22136346Skfall
22236346Skfall /* and the key */
22336346Skfall
22436346Skfall kdb_encrypt_key(key, key, master_key, master_key_schedule,
22536346Skfall ENCRYPT);
22636346Skfall bcopy(key, &principal_data[0].key_low, 4);
22736346Skfall bcopy(((long *) key) + 1, &principal_data[0].key_high,4);
22836346Skfall bzero(key, sizeof(key));
22936346Skfall
23036346Skfall principal_data[0].key_version = 1; /* 1st entry */
23138699Skfall
23238699Skfall /* and write it to the database */
23338699Skfall
23438699Skfall if (kerb_put_principal(&principal_data[0], 1)) {
23536346Skfall syslog(LOG_INFO, "Kerberos update failure: put_principal failed");
23636346Skfall return(KFAILURE);
23736346Skfall }
23836346Skfall
23936346Skfall syslog(LOG_NOTICE, "Kerberos update: wrote new record for %s.%s from %s",
24036346Skfall principal_data[0].name,
24136346Skfall principal_data[0].instance,
24260032Storek inet_ntoa(sinp->sin_addr)
24336346Skfall );
24436346Skfall
24536346Skfall return(KSUCCESS);
24636346Skfall
24736346Skfall }
24836346Skfall
send_packet(msg,flag)24937171Skfall send_packet(msg,flag)
25036346Skfall char *msg;
25137171Skfall int flag;
25236346Skfall {
25336346Skfall int len = strlen(msg);
25436346Skfall msg[len++] = '\n';
25536346Skfall msg[len] = '\0';
25637171Skfall if (len > sizeof(msgbuf)) {
25737171Skfall syslog(LOG_ERR, "send_packet: invalid msg size");
25837171Skfall return;
25937171Skfall }
26045459Sbostic if (flag == RCRYPT) {
26137171Skfall if (des_write(0, msg, len) != len)
26237171Skfall syslog(LOG_ERR, "couldn't write reply message");
26337171Skfall } else if (flag == CLEAR) {
26437171Skfall if (write(0, msg, len) != len)
26537171Skfall syslog(LOG_ERR, "couldn't write reply message");
26637171Skfall } else
26737171Skfall syslog(LOG_ERR, "send_packet: invalid flag (%d)", flag);
26837171Skfall
26936346Skfall }
27036346Skfall
net_get_principal(pname,iname,keyp)27136346Skfall net_get_principal(pname, iname, keyp)
27236346Skfall char *pname, *iname;
27336346Skfall C_Block *keyp;
27436346Skfall {
27536346Skfall int cc;
27636346Skfall static char password[255];
27736346Skfall
27836346Skfall cc = des_read(0, pname, ANAME_SZ);
27938699Skfall if (cc != ANAME_SZ) {
28036346Skfall syslog(LOG_ERR, "couldn't get principal name");
28136346Skfall return(-1);
28236346Skfall }
28336346Skfall
28436346Skfall cc = des_read(0, iname, INST_SZ);
28538699Skfall if (cc != INST_SZ) {
28636346Skfall syslog(LOG_ERR, "couldn't get instance name");
28736346Skfall return(-1);
28836346Skfall }
28936346Skfall
29036346Skfall cc = des_read(0, password, 255);
29138699Skfall if (cc != 255) {
29236346Skfall syslog(LOG_ERR, "couldn't get password");
29336346Skfall bzero(password, 255);
29436346Skfall return(-1);
29536346Skfall }
29636346Skfall
29736346Skfall string_to_key(password, *keyp);
29836346Skfall bzero(password, 255);
29936346Skfall return(0);
30036346Skfall }
30136346Skfall
cleanup()30236346Skfall cleanup()
30336346Skfall {
30436346Skfall bzero(master_key, sizeof(master_key));
30536346Skfall bzero(key, sizeof(key));
30636346Skfall bzero(master_key_schedule, sizeof(master_key_schedule));
30736346Skfall }
30836350Skfall
30945459Sbostic void
die()31036350Skfall die()
31136350Skfall {
31236350Skfall syslog(LOG_ERR, "remote end died (SIGPIPE)");
31336350Skfall cleanup();
31436350Skfall exit(1);
31536350Skfall }
316