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