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