xref: /original-bsd/old/athena/register/register.c (revision e8cf8951)
1 /*
2  * Copyright (c) 1989 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)register.c	1.5 (Berkeley) 05/17/89";
20 #endif /* not lint */
21 
22 #include <sys/types.h>
23 #include <sys/time.h>
24 #include <sys/resource.h>
25 #include <sys/socket.h>
26 #include <stdio.h>
27 #include <netdb.h>
28 #include <netinet/in.h>
29 #include <kerberos/krb.h>
30 #include <sys/param.h>
31 #include <sys/file.h>
32 #include <sys/signal.h>
33 #include "register_proto.h"
34 
35 #define	SERVICE	"krbupdate"
36 #define	PROTO	"tcp"
37 #define	KFILE	"/.update.key%s"
38 #define	KPASSWD	"/usr/athena/kpasswd"
39 
40 char	realm[REALM_SZ];
41 char	krbhst[MAX_HSTNM];
42 
43 static	char	pname[ANAME_SZ];
44 static	char	iname[INST_SZ];
45 static	char	password[255];
46 
47 extern char	*sys_errlist;
48 int	die();
49 
main(argc,argv)50 main(argc, argv)
51 int	argc;
52 char	**argv;
53 {
54 	struct servent	*se;
55 	struct hostent	*host;
56 	struct sockaddr_in	sin, local;
57 	int		rval;
58 	int		sock, llen;
59 	u_char		code;
60 	static struct rlimit rl = { 0, 0 };
61 
62 	signal(SIGPIPE, die);
63 
64 	if (setrlimit(RLIMIT_CORE, &rl) < 0) {
65 		perror("rlimit");
66 		exit(1);
67 	}
68 
69 	if ((se = getservbyname(SERVICE, PROTO)) == NULL) {
70 		fprintf(stderr, "couldn't find entry for service %s\n",
71 			SERVICE);
72 		exit(1);
73 	}
74 	if ((rval = krb_get_lrealm(realm,1)) != KSUCCESS) {
75 		fprintf(stderr, "couldn't get local Kerberos realm: %s\n",
76 			krb_err_txt[rval]);
77 		exit(1);
78 	}
79 
80 	if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) {
81 		fprintf(stderr, "couldn't get Kerberos host: %s\n",
82 			krb_err_txt[rval]);
83 		exit(1);
84 	}
85 
86 	if ((host = gethostbyname(krbhst)) == NULL) {
87 		fprintf(stderr, "couldn't get host entry for host %s\n",
88 			krbhst);
89 		exit(1);
90 	}
91 
92 	sin.sin_family = host->h_addrtype;
93 	bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length);
94 	sin.sin_port = se->s_port;
95 
96 	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
97 		perror("socket");
98 		exit(1);
99 	}
100 
101 	if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
102 		perror("connect");
103 		close(sock);
104 		exit(1);
105 	}
106 
107 	llen = sizeof(local);
108 	if (getsockname(sock, (struct sockaddr *) &local, &llen) < 0) {
109 		perror("getsockname");
110 		close(sock);
111 		exit(1);
112 	}
113 
114 	setup_key(local);
115 
116 	type_info();
117 
118 	if (!get_user_info()) {
119 		code = ABORT;
120 		(void)des_write(sock, &code, 1);
121 		cleanup();
122 		exit(1);
123 	}
124 
125 	code = APPEND_DB;
126 	if(des_write(sock, &code, 1) != 1) {
127 		perror("write 1");
128 		cleanup();
129 		exit(1);
130 	}
131 
132 	if(des_write(sock, pname, ANAME_SZ) != ANAME_SZ) {
133 		perror("write principal name");
134 		cleanup();
135 		exit(1);
136 	}
137 
138 	if(des_write(sock, iname, INST_SZ) != INST_SZ) {
139 		perror("write instance name");
140 		cleanup();
141 		exit(1);
142 	}
143 
144 	if(des_write(sock, password, 255) != 255) {
145 		perror("write password");
146 		cleanup();
147 		exit(1);
148 	}
149 
150 	/* get return message */
151 
152 	{
153 		int	cc;
154 		char	msgbuf[BUFSIZ];
155 
156 		cc = read(sock, msgbuf, BUFSIZ);
157 		if (cc <= 0) {
158 			fprintf(stderr, "protocol error during key verification\n");
159 			cleanup();
160 			exit(1);
161 		}
162 		if (strncmp(msgbuf, GOTKEY_MSG, 6) != 0) {
163 			fprintf(stderr, "%s: %s", krbhst, msgbuf);
164 			cleanup();
165 			exit(1);
166 		}
167 
168 		cc = des_read(sock, msgbuf, BUFSIZ);
169 		if(cc <= 0) {
170 			fprintf(stderr, "protocol error during read\n");
171 			cleanup();
172 			exit(1);
173 		} else {
174 			printf("%s: %s", krbhst, msgbuf);
175 		}
176 	}
177 
178 	cleanup();
179 	close(sock);
180 }
181 
cleanup()182 cleanup()
183 {
184 	bzero(password, 255);
185 }
186 
187 #include <pwd.h>
188 
189 extern	char	*crypt();
190 extern	char	*getpass();
191 
192 int
get_user_info()193 get_user_info()
194 {
195 	int	uid = getuid();
196 	int	valid = 0, i;
197 	struct	passwd	*pw;
198 	char	*pas, *namep;
199 
200 	if((pw = getpwuid(uid)) == NULL) {
201 		fprintf(stderr, "Who are you?\n");
202 		return(0);
203 	}
204 	seteuid(uid);
205 	strcpy(pname, pw->pw_name);	/* principal name */
206 	for(i = 1; i < 3; i++) {
207 		pas = getpass("login password:");
208 		namep = crypt(pas, pw->pw_passwd);
209 		if(strcmp(namep, pw->pw_passwd)) {
210 			fprintf(stderr, "Password incorrect\n");
211 			continue;
212 		} else {
213 			valid = 1;
214 			break;
215 		}
216 	}
217 	if(!valid)
218 		return(0);
219 	pas = getpass("Kerberos password (may be the same):");
220 	while(*pas == NULL) {
221 		printf("<NULL> password not allowed\n");
222 		pas = getpass("Kerberos password (may be the same):");
223 	}
224 	strcpy(password, pas);		/* password */
225 	pas = getpass("Retype Kerberos password:");
226 	if(strcmp(password, pas)) {
227 		fprintf(stderr, "Password mismatch -- aborted\n");
228 		return(0);
229 	}
230 
231 	iname[0] = NULL;	/* null instance name */
232 	return(1);
233 }
234 
235 setup_key(local)
236 	struct	sockaddr_in	local;
237 {
238 	static	struct	keyfile_data	kdata;
239 	static  Key_schedule		schedule;
240 	int	fd;
241 	char	namebuf[MAXPATHLEN];
242 	extern int errno;
243 
244 	sprintf(namebuf, KFILE, inet_ntoa(local.sin_addr));
245 	fd = open(namebuf, O_RDONLY);
246 	if(fd < 0) {
247 		fprintf(stderr, "couldn't open key file for local host %s\n",
248 			inet_ntoa(local.sin_addr));
249 		perror("open");
250 		exit(1);
251 	}
252 
253 	if(read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) {
254 		fprintf(stderr,"size error reading key file for local host %s\n",
255 			inet_ntoa(local.sin_addr));
256 		exit(1);
257 	}
258 	key_sched(kdata.kf_key, schedule);
259 	des_set_key(kdata.kf_key, schedule);
260 }
261 
type_info()262 type_info()
263 {
264 	printf("Kerberos user registration (realm %s)\n\n", realm);
265 	printf("Please enter your login password followed by your new Kerberos password.\n");
266 	printf("The Kerberos password you enter now will be used in the future\n");
267 	printf("as your Kerberos password for all machines in the %s realm.\n", realm);
268 	printf("You will only be allowed to perform this operation once, although you may run\n");
269 	printf("the %s program from now on to change your Kerberos password.\n\n", KPASSWD);
270 }
271 
die()272 die()
273 {
274 	fprintf(stderr, "\nServer no longer listeninga\n");
275 	fflush(stderr);
276 	cleanup();
277 	exit(1);
278 }
279