xref: /illumos-gate/usr/src/lib/gss_mechs/mech_krb5/krb5/os/read_pwd.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 #pragma ident	"%Z%%M%	%I%	%E% SMI"
7 
8 /*
9  * lib/krb5/os/read_pwd.c
10  *
11  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
12  * All Rights Reserved.
13  *
14  * Export of this software from the United States of America may
15  *   require a specific license from the United States Government.
16  *   It is the responsibility of any person or organization contemplating
17  *   export to obtain such a license before exporting.
18  *
19  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
20  * distribute this software and its documentation for any purpose and
21  * without fee is hereby granted, provided that the above copyright
22  * notice appear in all copies and that both that copyright notice and
23  * this permission notice appear in supporting documentation, and that
24  * the name of M.I.T. not be used in advertising or publicity pertaining
25  * to distribution of the software without specific, written prior
26  * permission.  Furthermore if you modify this software you must label
27  * your software as modified software and not distribute it in such a
28  * fashion that it might be confused with the original M.I.T. software.
29  * M.I.T. makes no representations about the suitability of
30  * this software for any purpose.  It is provided "as is" without express
31  * or implied warranty.
32  *
33  *
34  * libos: krb5_read_password for BSD 4.3
35  */
36 
37 #include <k5-int.h>
38 
39 #if !defined(_MSDOS) && !defined(_WIN32) && !defined(macintosh)
40 #define DEFINED_KRB5_READ_PASSWORD
41 #include <stdio.h>
42 #include <errno.h>
43 #include <signal.h>
44 #include <setjmp.h>
45 /*
46  * Solaris kerberos:  include this for internationalization
47  */
48 #include <libintl.h>
49 
50 #ifndef ECHO_PASSWORD
51 #include <termios.h>
52 #endif /* ECHO_PASSWORD */
53 
54 static jmp_buf pwd_jump;
55 
56 /*ARGSUSED*/
57 static krb5_sigtype
58 intr_routine(signo)
59     int signo;
60 {
61     longjmp(pwd_jump, 1);
62     /*NOTREACHED*/
63 }
64 
65 /*ARGSUSED*/
66 krb5_error_code
67 krb5_read_password(context, prompt, prompt2, return_pwd, size_return)
68     krb5_context context;
69     const char *prompt;
70     const char *prompt2;
71     char *return_pwd;
72     unsigned int *size_return;
73 {
74     /* adapted from Kerberos v4 des/read_password.c */
75     /* readin_string is used after a longjmp, so must be volatile */
76     char *volatile readin_string = 0;
77     register char *ptr;
78     int scratchchar;
79     krb5_sigtype (*volatile ointrfunc)();
80     krb5_error_code errcode;
81 #ifndef ECHO_PASSWORD
82     struct termios echo_control, save_control;
83     int fd;
84 
85     /* get the file descriptor associated with stdin */
86     fd=fileno(stdin);
87 
88     if (tcgetattr(fd, &echo_control) == -1)
89 	return errno;
90 
91     save_control = echo_control;
92     echo_control.c_lflag &= ~(ECHO|ECHONL);
93 
94     if (tcsetattr(fd, TCSANOW, &echo_control) == -1)
95 	return errno;
96 #endif /* ECHO_PASSWORD */
97 
98     if (setjmp(pwd_jump)) {
99 	errcode = KRB5_LIBOS_PWDINTR; 	/* we were interrupted... */
100 	goto cleanup;
101     }
102     /* save intrfunc */
103     ointrfunc = signal(SIGINT, intr_routine);
104 
105     /* put out the prompt */
106     (void) fputs(dgettext(TEXT_DOMAIN, prompt), stdout);
107     (void) fflush(stdout);
108     (void) memset(return_pwd, 0, *size_return);
109 
110     if (fgets(return_pwd, *size_return, stdin) == NULL) {
111 	(void) putchar('\n');
112 	errcode = KRB5_LIBOS_CANTREADPWD;
113 	goto cleanup;
114     }
115     (void) putchar('\n');
116     /* fgets always null-terminates the returned string */
117 
118     /* replace newline with null */
119     if ((ptr = strchr(return_pwd, '\n')))
120 	*ptr = '\0';
121     else /* flush rest of input line */
122 	do {
123 	    scratchchar = getchar();
124 	} while (scratchchar != EOF && scratchchar != '\n');
125 
126     if (prompt2) {
127 	/* put out the prompt */
128 	(void) fputs(dgettext(TEXT_DOMAIN, prompt2), stdout);
129 	(void) fflush(stdout);
130 	readin_string = malloc(*size_return);
131 	if (!readin_string) {
132 	    errcode = ENOMEM;
133 	    goto cleanup;
134 	}
135 	(void) memset((char *)readin_string, 0, *size_return);
136 	if (fgets((char *)readin_string, *size_return, stdin) == NULL) {
137 	    (void) putchar('\n');
138 	    errcode = KRB5_LIBOS_CANTREADPWD;
139 	    goto cleanup;
140 	}
141 	(void) putchar('\n');
142 
143 	if ((ptr = strchr((char *)readin_string, '\n')))
144 	    *ptr = '\0';
145         else /* need to flush */
146 	    do {
147 		scratchchar = getchar();
148 	    } while (scratchchar != EOF && scratchchar != '\n');
149 
150 	/* compare */
151 	if (strncmp(return_pwd, (char *)readin_string, *size_return)) {
152 	    errcode = KRB5_LIBOS_BADPWDMATCH;
153 	    goto cleanup;
154 	}
155     }
156 
157     errcode = 0;
158 
159 cleanup:
160     (void) signal(SIGINT, ointrfunc);
161 #ifndef ECHO_PASSWORD
162     if ((tcsetattr(fd, TCSANOW, &save_control) == -1) &&
163 	errcode == 0)
164 	    return errno;
165 #endif
166     if (readin_string) {
167 	    memset((char *)readin_string, 0, *size_return);
168 	    krb5_xfree(readin_string);
169     }
170     if (errcode)
171 	    memset(return_pwd, 0, *size_return);
172     else
173 	    *size_return = strlen(return_pwd);
174     return errcode;
175 }
176 #else /* MSDOS */
177 
178 #ifndef DEFINED_KRB5_READ_PASSWORD
179 #define DEFINED_KRB5_READ_PASSWORD
180 /*
181  * Don't expect to be called, just define it for sanity and the linker.
182  */
183 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
184 krb5_read_password(context, prompt, prompt2, return_pwd, size_return)
185     krb5_context context;
186     const char *prompt;
187     const char *prompt2;
188     char *return_pwd;
189     int *size_return;
190 {
191    *size_return = 0;
192    return KRB5_LIBOS_CANTREADPWD;
193 }
194 #endif /* DEFINED_KRB5_READ_PASSWORD */
195 
196 #endif /* MSDOS */
197