146666Sbostic /*-
2*60967Sbostic  * Copyright (c) 1989, 1993
3*60967Sbostic  *	The Regents of the University of California.  All rights reserved.
438046Skfall  *
546666Sbostic  * %sccs.include.redist.c%
638046Skfall  */
738046Skfall 
838046Skfall #ifndef lint
9*60967Sbostic static char copyright[] =
10*60967Sbostic "@(#) Copyright (c) 1989, 1993\n\
11*60967Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1238046Skfall #endif /* not lint */
1338046Skfall 
1446666Sbostic #ifndef lint
15*60967Sbostic static char sccsid[] = "@(#)register.c	8.1 (Berkeley) 06/01/93";
1646666Sbostic #endif /* not lint */
1746666Sbostic 
1836343Skfall #include <sys/types.h>
1943461Skfall #include <sys/param.h>
2036343Skfall #include <sys/time.h>
2136343Skfall #include <sys/resource.h>
2236343Skfall #include <sys/socket.h>
2343461Skfall #include <sys/file.h>
2443461Skfall #include <sys/signal.h>
2543461Skfall #include <netinet/in.h>
2643461Skfall #include <pwd.h>
2736343Skfall #include <stdio.h>
2836343Skfall #include <netdb.h>
2941764Skfall #include <kerberosIV/des.h>
3041764Skfall #include <kerberosIV/krb.h>
3138699Skfall #include "pathnames.h"
3236343Skfall #include "register_proto.h"
3336343Skfall 
3443461Skfall #define	SERVICE	"krbupdate"	/* service to add to KDC's database */
3536343Skfall #define	PROTO	"tcp"
3636343Skfall 
3736343Skfall char	realm[REALM_SZ];
3836343Skfall char	krbhst[MAX_HSTNM];
3936343Skfall 
4036343Skfall static	char	pname[ANAME_SZ];
4136343Skfall static	char	iname[INST_SZ];
4243461Skfall static	char	password[_PASSWORD_LEN];
4336343Skfall 
4443461Skfall /* extern char	*sys_errlist; */
4546666Sbostic void	die();
4643461Skfall void	setup_key(), type_info(), cleanup();
4736343Skfall 
main(argc,argv)4836343Skfall main(argc, argv)
4943461Skfall 	int	argc;
5043461Skfall 	char	**argv;
5136343Skfall {
5236343Skfall 	struct servent	*se;
5336343Skfall 	struct hostent	*host;
5436343Skfall 	struct sockaddr_in	sin, local;
5536343Skfall 	int		rval;
5636343Skfall 	int		sock, llen;
5736343Skfall 	u_char		code;
5836343Skfall 	static struct rlimit rl = { 0, 0 };
5936343Skfall 
6036348Skfall 	signal(SIGPIPE, die);
6136348Skfall 
6238046Skfall 	if (setrlimit(RLIMIT_CORE, &rl) < 0) {
6336343Skfall 		perror("rlimit");
6436343Skfall 		exit(1);
6536343Skfall 	}
6636343Skfall 
6738046Skfall 	if ((se = getservbyname(SERVICE, PROTO)) == NULL) {
6836343Skfall 		fprintf(stderr, "couldn't find entry for service %s\n",
6936343Skfall 			SERVICE);
7036343Skfall 		exit(1);
7136343Skfall 	}
7245213Skfall 	if ((rval = krb_get_lrealm(realm,0)) != KSUCCESS) {
7336343Skfall 		fprintf(stderr, "couldn't get local Kerberos realm: %s\n",
7436343Skfall 			krb_err_txt[rval]);
7536343Skfall 		exit(1);
7636343Skfall 	}
7736343Skfall 
7838046Skfall 	if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) {
7936343Skfall 		fprintf(stderr, "couldn't get Kerberos host: %s\n",
8036343Skfall 			krb_err_txt[rval]);
8136343Skfall 		exit(1);
8236343Skfall 	}
8336343Skfall 
8438046Skfall 	if ((host = gethostbyname(krbhst)) == NULL) {
8536343Skfall 		fprintf(stderr, "couldn't get host entry for host %s\n",
8636343Skfall 			krbhst);
8736343Skfall 		exit(1);
8836343Skfall 	}
8936343Skfall 
9036343Skfall 	sin.sin_family = host->h_addrtype;
9143461Skfall 	(void)bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length);
9236343Skfall 	sin.sin_port = se->s_port;
9336343Skfall 
9438046Skfall 	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
9536343Skfall 		perror("socket");
9636343Skfall 		exit(1);
9736343Skfall 	}
9836343Skfall 
9938046Skfall 	if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
10036343Skfall 		perror("connect");
10143461Skfall 		(void)close(sock);
10236343Skfall 		exit(1);
10336343Skfall 	}
10436343Skfall 
10536343Skfall 	llen = sizeof(local);
10638046Skfall 	if (getsockname(sock, (struct sockaddr *) &local, &llen) < 0) {
10736343Skfall 		perror("getsockname");
10843461Skfall 		(void)close(sock);
10936343Skfall 		exit(1);
11036343Skfall 	}
11136343Skfall 
11236343Skfall 	setup_key(local);
11336343Skfall 
11436343Skfall 	type_info();
11536343Skfall 
11638046Skfall 	if (!get_user_info()) {
11738046Skfall 		code = ABORT;
11838046Skfall 		(void)des_write(sock, &code, 1);
11938046Skfall 		cleanup();
12038046Skfall 		exit(1);
12138046Skfall 	}
12238046Skfall 
12336343Skfall 	code = APPEND_DB;
12438699Skfall 	if (des_write(sock, &code, 1) != 1) {
12536343Skfall 		perror("write 1");
12636343Skfall 		cleanup();
12736343Skfall 		exit(1);
12836343Skfall 	}
12936343Skfall 
13038699Skfall 	if (des_write(sock, pname, ANAME_SZ) != ANAME_SZ) {
13136343Skfall 		perror("write principal name");
13236343Skfall 		cleanup();
13336343Skfall 		exit(1);
13436343Skfall 	}
13536343Skfall 
13638699Skfall 	if (des_write(sock, iname, INST_SZ) != INST_SZ) {
13736343Skfall 		perror("write instance name");
13836343Skfall 		cleanup();
13936343Skfall 		exit(1);
14036343Skfall 	}
14136343Skfall 
14238699Skfall 	if (des_write(sock, password, 255) != 255) {
14336343Skfall 		perror("write password");
14436343Skfall 		cleanup();
14536343Skfall 		exit(1);
14636343Skfall 	}
14736343Skfall 
14836343Skfall 	/* get return message */
14936343Skfall 
15036343Skfall 	{
15136343Skfall 		int	cc;
15236343Skfall 		char	msgbuf[BUFSIZ];
15336343Skfall 
15437170Skfall 		cc = read(sock, msgbuf, BUFSIZ);
15537170Skfall 		if (cc <= 0) {
15637170Skfall 			fprintf(stderr, "protocol error during key verification\n");
15737170Skfall 			cleanup();
15837170Skfall 			exit(1);
15937170Skfall 		}
16038046Skfall 		if (strncmp(msgbuf, GOTKEY_MSG, 6) != 0) {
16137170Skfall 			fprintf(stderr, "%s: %s", krbhst, msgbuf);
16237170Skfall 			cleanup();
16337170Skfall 			exit(1);
16437170Skfall 		}
16537170Skfall 
16636343Skfall 		cc = des_read(sock, msgbuf, BUFSIZ);
16738699Skfall 		if (cc <= 0) {
16836343Skfall 			fprintf(stderr, "protocol error during read\n");
16936343Skfall 			cleanup();
17036343Skfall 			exit(1);
17136343Skfall 		} else {
17236343Skfall 			printf("%s: %s", krbhst, msgbuf);
17336343Skfall 		}
17436343Skfall 	}
17536343Skfall 
17636343Skfall 	cleanup();
17743461Skfall 	(void)close(sock);
17836343Skfall }
17936343Skfall 
18043461Skfall void
cleanup()18136343Skfall cleanup()
18236343Skfall {
18336343Skfall 	bzero(password, 255);
18436343Skfall }
18536343Skfall 
18636343Skfall extern	char	*crypt();
18736343Skfall extern	char	*getpass();
18838046Skfall 
18938046Skfall int
get_user_info()19036343Skfall get_user_info()
19136343Skfall {
19236343Skfall 	int	uid = getuid();
19336343Skfall 	int	valid = 0, i;
19436343Skfall 	struct	passwd	*pw;
19536343Skfall 	char	*pas, *namep;
19636343Skfall 
19743461Skfall 	/* NB: we must run setuid-root to get at the real pw file */
19843461Skfall 
19938699Skfall 	if ((pw = getpwuid(uid)) == NULL) {
20036343Skfall 		fprintf(stderr, "Who are you?\n");
20138046Skfall 		return(0);
20236343Skfall 	}
20343461Skfall 	(void)seteuid(uid);
20443461Skfall 	(void)strcpy(pname, pw->pw_name);	/* principal name */
20543461Skfall 
20643461Skfall 	for (i = 1; i < 3; i++) {
20736343Skfall 		pas = getpass("login password:");
20836343Skfall 		namep = crypt(pas, pw->pw_passwd);
20938699Skfall 		if (strcmp(namep, pw->pw_passwd)) {
21036343Skfall 			fprintf(stderr, "Password incorrect\n");
21136343Skfall 			continue;
21236343Skfall 		} else {
21336343Skfall 			valid = 1;
21436343Skfall 			break;
21536343Skfall 		}
21636343Skfall 	}
21738699Skfall 	if (!valid)
21838046Skfall 		return(0);
21936343Skfall 	pas = getpass("Kerberos password (may be the same):");
22043461Skfall 	while (*pas == NULL) {
22137170Skfall 		printf("<NULL> password not allowed\n");
22237170Skfall 		pas = getpass("Kerberos password (may be the same):");
22337170Skfall 	}
22443461Skfall 	(void)strcpy(password, pas);		/* password */
22536343Skfall 	pas = getpass("Retype Kerberos password:");
22638699Skfall 	if (strcmp(password, pas)) {
22736343Skfall 		fprintf(stderr, "Password mismatch -- aborted\n");
22838046Skfall 		return(0);
22936343Skfall 	}
23036343Skfall 
23136343Skfall 	iname[0] = NULL;	/* null instance name */
23238046Skfall 	return(1);
23336343Skfall }
23436343Skfall 
23543461Skfall void
setup_key(local)23636343Skfall setup_key(local)
23736343Skfall 	struct	sockaddr_in	local;
23836343Skfall {
23936343Skfall 	static	struct	keyfile_data	kdata;
24036343Skfall 	static  Key_schedule		schedule;
24136343Skfall 	int	fd;
24236343Skfall 	char	namebuf[MAXPATHLEN];
24336343Skfall 	extern int errno;
24436343Skfall 
24538703Skfall 	(void) sprintf(namebuf, "%s%s",
24638699Skfall 		CLIENT_KEYFILE,
24738699Skfall 		inet_ntoa(local.sin_addr));
24838699Skfall 
24936343Skfall 	fd = open(namebuf, O_RDONLY);
25038699Skfall 	if (fd < 0) {
25141768Skfall 		fprintf(stderr, "couldn't open key file %s for local host: ",
25241768Skfall 			namebuf);
25341768Skfall 		perror("");
25436343Skfall 		exit(1);
25536343Skfall 	}
25636343Skfall 
25738699Skfall 	if (read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) {
25836343Skfall 		fprintf(stderr,"size error reading key file for local host %s\n",
25936343Skfall 			inet_ntoa(local.sin_addr));
26036343Skfall 		exit(1);
26136343Skfall 	}
26236343Skfall 	key_sched(kdata.kf_key, schedule);
26336343Skfall 	des_set_key(kdata.kf_key, schedule);
26443461Skfall 	return;
26536343Skfall }
26636343Skfall 
26743461Skfall void
type_info()26836343Skfall type_info()
26936343Skfall {
27036343Skfall 	printf("Kerberos user registration (realm %s)\n\n", realm);
27136343Skfall 	printf("Please enter your login password followed by your new Kerberos password.\n");
27236343Skfall 	printf("The Kerberos password you enter now will be used in the future\n");
27337170Skfall 	printf("as your Kerberos password for all machines in the %s realm.\n", realm);
27436343Skfall 	printf("You will only be allowed to perform this operation once, although you may run\n");
27538699Skfall 	printf("the %s program from now on to change your Kerberos password.\n\n", _PATH_KPASSWD);
27636343Skfall }
27736348Skfall 
27846666Sbostic void
die()27936348Skfall die()
28036348Skfall {
28138699Skfall 	fprintf(stderr, "\nServer no longer listening\n");
28236348Skfall 	fflush(stderr);
28336348Skfall 	cleanup();
28436348Skfall 	exit(1);
28536348Skfall }
286