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