add Berkeley headers
[unix-history] / usr / src / old / athena / kpasswd / kpasswd.c
CommitLineData
5dc00f89
KF
1
2/*
3 * Copyright (c) 1989 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms are permitted
7 * provided that the above copyright notice and this paragraph are
8 * duplicated in all such forms and that any documentation,
9 * advertising materials, and other materials related to such
10 * distribution and use acknowledge that the software was developed
11 * by the University of California, Berkeley. The name of the
12 * University may not be used to endorse or promote products derived
13 * from this software without specific prior written permission.
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 */
18
19#ifndef lint
20static char sccsid[] = "@(#)kpasswd.c 1.2 (Berkeley) %G%";
21#endif /* not lint */
22
24788cb9 23/*
5dc00f89 24 * kpasswd - client program to update Kerberos password
24788cb9
KF
25 *
26 * K. Fall
27 * 12-Dec-88
28 */
29
30#include <stdio.h>
31#include <sys/types.h>
32#include <sys/time.h>
33#include <sys/resource.h>
34#include <sys/socket.h>
35#include <sys/signal.h>
36#include <netinet/in.h>
37#include <netdb.h>
38#include <kerberos/krb.h>
39#include "kpasswd_proto.h"
40
41KTEXT_ST ticket;
42long authopts = 0L;
43Key_schedule random_schedule;
44char realm[REALM_SZ], krbhst[MAX_HSTNM];
45static struct kpasswd_data proto_data;
46static C_Block okey;
47static Key_schedule osched;
48static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0 };
49int sock;
50char *getpass();
51int sock;
52
53int finish();
54
55#define PROTO "tcp"
56
57main(argc, argv)
58int argc;
59char **argv;
60{
61 struct servent *se;
62 struct hostent *host;
63 struct sockaddr_in sin;
64 int rval;
65 char password[255], *pass;
66 fd_set readfds;
67
68 static struct rlimit rl = { 0, 0 };
69
70 signal(SIGHUP, SIG_IGN);
71 signal(SIGINT, SIG_IGN);
72 signal(SIGTSTP, SIG_IGN);
73
74 if(setrlimit(RLIMIT_CORE, &rl) < 0) {
75 perror("setrlimit");
76 exit(1);
77 }
78
79 if((se = getservbyname(SERVICE, PROTO)) == NULL) {
80 fprintf(stderr, "couldn't find entry for service %s/%s\n",
81 SERVICE, PROTO);
82 exit(1);
83 }
5dc00f89 84 if((rval = krb_get_lrealm(realm,1)) != KSUCCESS) {
24788cb9
KF
85 fprintf(stderr, "couldn't get local Kerberos realm: %s\n",
86 krb_err_txt[rval]);
87 exit(1);
88 }
89
5dc00f89 90 if((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) {
24788cb9
KF
91 fprintf(stderr, "couldn't get Kerberos host: %s\n",
92 krb_err_txt[rval]);
93 exit(1);
94 }
95
96 if((host = gethostbyname(krbhst)) == NULL) {
97 fprintf(stderr, "couldn't get host entry for host %s\n",
98 krbhst);
99 exit(1);
100 }
101
102 sin.sin_family = host->h_addrtype;
103 bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length);
104 sin.sin_port = se->s_port;
105
106 if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
107 perror("socket");
108 exit(1);
109 }
110
111 if(connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
112 perror("connect");
113 close(sock);
114 exit(1);
115 }
116
117 rval = krb_sendauth(
118 authopts, /* NOT mutual */
119 sock,
120 &ticket, /* (filled in) */
121 SERVICE,
122 krbhst, /* instance (krbhst) */
123 realm, /* dest realm */
124 (u_long) getpid(), /* checksum */
125 NULL, /* msg data */
126 NULL, /* credentials */
127 NULL, /* schedule */
128 NULL, /* local addr */
129 NULL, /* foreign addr */
130 "KPWDV0.1"
131 );
132
133 if(rval != KSUCCESS) {
134 fprintf(stderr, "Kerberos sendauth error: %s\n",
135 krb_err_txt[rval]);
136 exit(1);
137 }
138
139 pass = getpass("Old Kerberos password:");
140 string_to_key(pass, okey);
141 key_sched(okey, osched);
142 des_set_key(okey, osched);
143
144 /* wait on the verification string */
145
146 FD_ZERO(&readfds);
147 FD_SET(sock, &readfds);
148
149 rval =
150 select(sock + 1, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout);
151 if((rval < 1) || !FD_ISSET(sock, &readfds)) {
152 if(rval == 0) {
153 fprintf(stderr, "Timed out\n");
154 cleanup();
155 exit(1);
156 }
157 fprintf(stderr, "select failed\n");
158 cleanup();
159 exit(1);
160 }
161
162 /* read verification string */
163
164 if(des_read(sock, &proto_data, sizeof(proto_data)) != sizeof(proto_data)) {
165 fprintf(stderr,
166 "%s: couldn't read verification string (aborted)\n",
167 argv[0]
168 );
169
170 cleanup();
171 exit(1);
172 }
173
174 signal(SIGHUP, finish);
175 signal(SIGINT, finish);
176
177 if(strcmp(SECURE_STRING, proto_data.secure_msg)) {
178 cleanup();
179 fprintf(stderr, "Sorry.\n");
180 exit(1);
181 }
182 key_sched(proto_data.random_key, random_schedule);
183 des_set_key(proto_data.random_key, random_schedule);
184 pass = getpass("New Kerberos password:");
185 strcpy(password, pass);
186 pass = getpass("Retype new Kerberos password:");
187 if(strcmp(password, pass)) {
188 fprintf(stderr, "Password mismatch (aborted)\n");
189 cleanup();
190 exit(1);
191 }
192 send_update(sock, password, SECURE_STRING);
193
194 /* wait for ACK */
195
196 FD_ZERO(&readfds);
197 FD_SET(sock, &readfds);
198
199 rval =
200 select(sock + 1, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout);
201 if((rval < 1) || !FD_ISSET(sock, &readfds)) {
202 if(rval == 0) {
203 fprintf(stderr, "Timed out reading ACK\n");
204 cleanup();
205 exit(1);
206 }
207 fprintf(stderr, "select failed\n");
208 cleanup();
209 exit(1);
210 }
211
212 recv_ack(sock);
213 cleanup();
214 exit(0);
215}
216
217send_update(dest, pwd, str)
218 int dest;
219 char *pwd, *str;
220{
221 static struct update_data ud;
222 strncpy(ud.secure_msg, str, MSGSIZE);
223 strncpy(ud.pw, pwd, sizeof(ud.pw));
224 if(des_write(dest, &ud, sizeof(ud)) != sizeof(ud)) {
225 fprintf(stderr, "couldn't write pw update (abort)\n");
226 bzero(ud, sizeof(ud));
227 cleanup();
228 exit(1);
229 }
230}
231
232recv_ack(remote)
233 int remote;
234{
235 int cc;
236 char buf[BUFSIZ];
237 cc = des_read(remote, buf, sizeof(buf));
238 if(cc <= 0) {
239 fprintf(stderr, "error reading acknowledgement\n");
240 cleanup();
241 exit(1);
242 }
243 printf("%s", buf);
244}
245
246cleanup()
247{
248 bzero(&proto_data, sizeof(proto_data));
249 bzero(okey, sizeof(okey));
250 bzero(osched, sizeof(osched));
251 bzero(random_schedule, sizeof(random_schedule));
252}
253
254finish()
255{
256 close(sock);
257 exit(1);
258}