Annotation of src/usr.bin/passwd/krb_passwd.c, Revision 1.6
1.6 ! deraadt 1: /* $OpenBSD: krb_passwd.c,v 1.5 1997/03/27 00:30:52 weingart Exp $ */
1.4 deraadt 2:
1.1 deraadt 3: /*-
4: * Copyright (c) 1990 The Regents of the University of California.
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by the University of
18: * California, Berkeley and its contributors.
19: * 4. Neither the name of the University nor the names of its contributors
20: * may be used to endorse or promote products derived from this software
21: * without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33: * SUCH DAMAGE.
34: */
35:
36: #ifndef lint
37: /*static char sccsid[] = "from: @(#)krb_passwd.c 5.4 (Berkeley) 3/1/91";*/
1.6 ! deraadt 38: static char rcsid[] = "$OpenBSD: krb_passwd.c,v 1.5 1997/03/27 00:30:52 weingart Exp $";
1.1 deraadt 39: #endif /* not lint */
40:
41: #ifdef KERBEROS
42:
43: #include <sys/types.h>
44: #include <sys/socket.h>
45: #include <sys/time.h>
46: #include <sys/resource.h>
47: #include <netinet/in.h>
48: #include <kerberosIV/des.h>
49: #include <kerberosIV/krb.h>
50: #include <netdb.h>
51: #include <signal.h>
52: #include <pwd.h>
1.5 weingart 53: #include <err.h>
1.1 deraadt 54: #include <errno.h>
55: #include <stdio.h>
56: #include "kpasswd_proto.h"
57: #include <string.h>
58: #include <stdlib.h>
1.5 weingart 59: #include <unistd.h>
1.1 deraadt 60:
61: #define PROTO "tcp"
62:
63: static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0 };
64: static struct kpasswd_data proto_data;
65: static des_cblock okey;
66: static Key_schedule osched;
67: KTEXT_ST ticket;
68: Key_schedule random_schedule;
69: long authopts;
70: char realm[REALM_SZ], krbhst[MAX_HSTNM];
71: int sock;
72:
73: krb_passwd()
74: {
75: struct servent *se;
76: struct hostent *host;
77: struct sockaddr_in sin;
78: CREDENTIALS cred;
1.6 ! deraadt 79: int fdsn;
! 80: fd_set *fdsp;
1.1 deraadt 81: int rval;
82: char pass[_PASSWORD_LEN], password[_PASSWORD_LEN];
83: static void finish();
84:
85: static struct rlimit rl = { 0, 0 };
86:
87: (void)signal(SIGHUP, SIG_IGN);
88: (void)signal(SIGINT, SIG_IGN);
89: (void)signal(SIGTSTP, SIG_IGN);
90:
91: if (setrlimit(RLIMIT_CORE, &rl) < 0) {
1.5 weingart 92: warn("setrlimit");
1.1 deraadt 93: return(1);
94: }
95:
96: if ((se = getservbyname(SERVICE, PROTO)) == NULL) {
1.5 weingart 97: warnx("couldn't find entry for service %s/%s", SERVICE, PROTO);
1.1 deraadt 98: return(1);
99: }
100:
101: if ((rval = krb_get_lrealm(realm,1)) != KSUCCESS) {
1.5 weingart 102: warnx("couldn't get local Kerberos realm: %s", krb_err_txt[rval]);
1.1 deraadt 103: return(1);
104: }
105:
106: if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) {
1.5 weingart 107: warnx("couldn't get Kerberos host: %s", krb_err_txt[rval]);
1.1 deraadt 108: return(1);
109: }
110:
111: if ((host = gethostbyname(krbhst)) == NULL) {
1.5 weingart 112: warnx("couldn't get host entry for krb host %s", krbhst);
1.1 deraadt 113: return(1);
114: }
115:
116: sin.sin_family = host->h_addrtype;
117: bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length);
118: sin.sin_port = se->s_port;
119:
120: if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
1.5 weingart 121: warn("socket");
1.1 deraadt 122: return(1);
123: }
124:
125: if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
1.5 weingart 126: warn("connect");
1.1 deraadt 127: (void)close(sock);
128: return(1);
129: }
130:
131: rval = krb_sendauth(
132: authopts, /* NOT mutual */
133: sock,
134: &ticket, /* (filled in) */
135: SERVICE,
136: krbhst, /* instance (krbhst) */
137: realm, /* dest realm */
138: (u_long) getpid(), /* checksum */
139: NULL, /* msg data */
140: NULL, /* credentials */
141: NULL, /* schedule */
142: NULL, /* local addr */
143: NULL, /* foreign addr */
144: "KPWDV0.1"
145: );
146:
147: if (rval != KSUCCESS) {
1.5 weingart 148: warnx("Kerberos sendauth error: %s", krb_err_txt[rval]);
1.1 deraadt 149: return(1);
150: }
151:
152: krb_get_cred("krbtgt", realm, realm, &cred);
153:
154: (void)printf("Changing Kerberos password for %s.%s@%s.\n",
155: cred.pname, cred.pinst, realm);
156:
157: if (des_read_pw_string(pass,
158: sizeof(pass)-1, "Old Kerberos password:", 0)) {
1.5 weingart 159: warnx("error reading old Kerberos password");
1.1 deraadt 160: return(1);
161: }
162:
1.2 tholo 163: (void)des_string_to_key(pass, &okey);
164: (void)des_key_sched(&okey, osched);
1.3 tholo 165: (void)desrw_set_key(&okey, osched);
1.1 deraadt 166:
167: /* wait on the verification string */
168:
1.6 ! deraadt 169: fdsn = howmany(sock+1, NFDBITS) * sizeof(fd_mask);
! 170: if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
! 171: err(1, "malloc");
! 172: memset(fdsp, 0, fdsn);
! 173: FD_SET(sock, fdsp);
1.1 deraadt 174:
175: rval =
1.6 ! deraadt 176: select(sock + 1, fdsp, (fd_set *) 0, (fd_set *) 0, &timeout);
1.1 deraadt 177:
1.6 ! deraadt 178: if ((rval < 1) || !FD_ISSET(sock, fdsp)) {
! 179: free(fdsp);
1.1 deraadt 180: if(rval == 0) {
1.5 weingart 181: warnx("timed out (aborted)");
1.1 deraadt 182: cleanup();
183: return(1);
184: }
1.5 weingart 185: warnx("select failed (aborted)");
1.1 deraadt 186: cleanup();
187: return(1);
188: }
1.6 ! deraadt 189: free(fdsp);
1.1 deraadt 190:
191: /* read verification string */
192:
193: if (des_read(sock, &proto_data, sizeof(proto_data)) !=
194: sizeof(proto_data)) {
1.5 weingart 195: warnx("couldn't read verification string (aborted)");
1.1 deraadt 196: cleanup();
197: return(1);
198: }
199:
200: (void)signal(SIGHUP, finish);
201: (void)signal(SIGINT, finish);
202:
203: if (strcmp(SECURE_STRING, proto_data.secure_msg) != 0) {
204: cleanup();
205: /* don't complain loud if user just hit return */
206: if (pass == NULL || (!*pass))
207: return(0);
1.5 weingart 208: warnx("Sorry");
1.1 deraadt 209: return(1);
210: }
211:
1.2 tholo 212: (void)des_key_sched(&proto_data.random_key, random_schedule);
1.3 tholo 213: (void)desrw_set_key(&proto_data.random_key, random_schedule);
1.1 deraadt 214: (void)bzero(pass, sizeof(pass));
215:
216: if (des_read_pw_string(pass,
217: sizeof(pass)-1, "New Kerberos password:", 0)) {
1.5 weingart 218: warnx("error reading new Kerberos password (aborted)");
1.1 deraadt 219: cleanup();
220: return(1);
221: }
222:
223: if (des_read_pw_string(password,
224: sizeof(password)-1, "Retype new Kerberos password:", 0)) {
1.5 weingart 225: warnx("error reading new Kerberos password (aborted)");
1.1 deraadt 226: cleanup();
227: return(1);
228: }
229:
230: if (strcmp(password, pass) != 0) {
1.5 weingart 231: warnx("password mismatch (aborted)");
1.1 deraadt 232: cleanup();
233: return(1);
234: }
235:
236: if (strlen(pass) == 0)
237: (void)printf("using NULL password\n");
238:
239: send_update(sock, password, SECURE_STRING);
240:
241: /* wait for ACK */
242:
1.6 ! deraadt 243: fdsn = howmany(sock+1, NFDBITS) * sizeof(fd_mask);
! 244: if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
! 245: err(1, "malloc");
! 246: memset(fdsp, 0, fdsn);
! 247: FD_SET(sock, fdsp);
1.1 deraadt 248:
249: rval =
1.6 ! deraadt 250: select(sock + 1, fdsp, (fd_set *) 0, (fd_set *) 0, &timeout);
! 251: if ((rval < 1) || !FD_ISSET(sock, fdsp)) {
! 252: free(fdsp);
1.1 deraadt 253: if(rval == 0) {
1.5 weingart 254: warnx("timed out reading ACK (aborted)");
1.1 deraadt 255: cleanup();
256: exit(1);
257: }
1.5 weingart 258: warnx("select failed (aborted)");
1.1 deraadt 259: cleanup();
260: exit(1);
261: }
1.6 ! deraadt 262: free(fdsp);
1.1 deraadt 263: recv_ack(sock);
264: cleanup();
265: exit(0);
266: }
267:
268: send_update(dest, pwd, str)
269: int dest;
270: char *pwd, *str;
271: {
272: static struct update_data ud;
273:
274: (void)strncpy(ud.secure_msg, str, _PASSWORD_LEN);
275: (void)strncpy(ud.pw, pwd, sizeof(ud.pw));
276: if (des_write(dest, &ud, sizeof(ud)) != sizeof(ud)) {
1.5 weingart 277: warnx("couldn't write pw update (abort)");
1.1 deraadt 278: bzero((char *)&ud, sizeof(ud));
279: cleanup();
280: exit(1);
281: }
282: }
283:
284: recv_ack(remote)
285: int remote;
286: {
287: int cc;
288: char buf[BUFSIZ];
289:
290: cc = des_read(remote, buf, sizeof(buf));
291: if (cc <= 0) {
1.5 weingart 292: warnx("error reading acknowledgement (aborted)");
1.1 deraadt 293: cleanup();
294: exit(1);
295: }
296: (void)printf("%s", buf);
297: }
298:
299: cleanup()
300: {
301: (void)bzero((char *)&proto_data, sizeof(proto_data));
302: (void)bzero((char *)okey, sizeof(okey));
303: (void)bzero((char *)osched, sizeof(osched));
304: (void)bzero((char *)random_schedule, sizeof(random_schedule));
305: }
306:
307: static void
308: finish()
309: {
310: (void)close(sock);
311: exit(1);
312: }
313:
314: #endif /* KERBEROS */