1*7f2fe78bSCy Schubert /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2*7f2fe78bSCy Schubert /* lib/krb5/os/read_pwd.c */
3*7f2fe78bSCy Schubert /*
4*7f2fe78bSCy Schubert * Copyright 1990,1991 by the Massachusetts Institute of Technology.
5*7f2fe78bSCy Schubert * All Rights Reserved.
6*7f2fe78bSCy Schubert *
7*7f2fe78bSCy Schubert * Export of this software from the United States of America may
8*7f2fe78bSCy Schubert * require a specific license from the United States Government.
9*7f2fe78bSCy Schubert * It is the responsibility of any person or organization contemplating
10*7f2fe78bSCy Schubert * export to obtain such a license before exporting.
11*7f2fe78bSCy Schubert *
12*7f2fe78bSCy Schubert * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13*7f2fe78bSCy Schubert * distribute this software and its documentation for any purpose and
14*7f2fe78bSCy Schubert * without fee is hereby granted, provided that the above copyright
15*7f2fe78bSCy Schubert * notice appear in all copies and that both that copyright notice and
16*7f2fe78bSCy Schubert * this permission notice appear in supporting documentation, and that
17*7f2fe78bSCy Schubert * the name of M.I.T. not be used in advertising or publicity pertaining
18*7f2fe78bSCy Schubert * to distribution of the software without specific, written prior
19*7f2fe78bSCy Schubert * permission. Furthermore if you modify this software you must label
20*7f2fe78bSCy Schubert * your software as modified software and not distribute it in such a
21*7f2fe78bSCy Schubert * fashion that it might be confused with the original M.I.T. software.
22*7f2fe78bSCy Schubert * M.I.T. makes no representations about the suitability of
23*7f2fe78bSCy Schubert * this software for any purpose. It is provided "as is" without express
24*7f2fe78bSCy Schubert * or implied warranty.
25*7f2fe78bSCy Schubert */
26*7f2fe78bSCy Schubert
27*7f2fe78bSCy Schubert #include "k5-int.h"
28*7f2fe78bSCy Schubert
29*7f2fe78bSCy Schubert #if !defined(_WIN32)
30*7f2fe78bSCy Schubert #define DEFINED_KRB5_READ_PASSWORD
31*7f2fe78bSCy Schubert #include <stdio.h>
32*7f2fe78bSCy Schubert #include <errno.h>
33*7f2fe78bSCy Schubert #include <signal.h>
34*7f2fe78bSCy Schubert #include <setjmp.h>
35*7f2fe78bSCy Schubert
36*7f2fe78bSCy Schubert #ifndef ECHO_PASSWORD
37*7f2fe78bSCy Schubert #include <termios.h>
38*7f2fe78bSCy Schubert #endif /* ECHO_PASSWORD */
39*7f2fe78bSCy Schubert
40*7f2fe78bSCy Schubert krb5_error_code
krb5_read_password(krb5_context context,const char * prompt,const char * prompt2,char * return_pwd,unsigned int * size_return)41*7f2fe78bSCy Schubert krb5_read_password(krb5_context context,
42*7f2fe78bSCy Schubert const char *prompt, const char *prompt2,
43*7f2fe78bSCy Schubert char *return_pwd, unsigned int *size_return)
44*7f2fe78bSCy Schubert {
45*7f2fe78bSCy Schubert krb5_data reply_data, verify_data = empty_data();
46*7f2fe78bSCy Schubert krb5_prompt k5prompt, vprompt;
47*7f2fe78bSCy Schubert krb5_error_code retval;
48*7f2fe78bSCy Schubert
49*7f2fe78bSCy Schubert /* *size_return is the space available in the return buffer on input. */
50*7f2fe78bSCy Schubert reply_data = make_data(return_pwd, *size_return);
51*7f2fe78bSCy Schubert k5prompt.prompt = (char *)prompt;
52*7f2fe78bSCy Schubert k5prompt.hidden = 1;
53*7f2fe78bSCy Schubert k5prompt.reply = &reply_data;
54*7f2fe78bSCy Schubert retval = krb5_prompter_posix(NULL, NULL, NULL, NULL, 1, &k5prompt);
55*7f2fe78bSCy Schubert if (retval || prompt2 == NULL)
56*7f2fe78bSCy Schubert goto done;
57*7f2fe78bSCy Schubert
58*7f2fe78bSCy Schubert retval = alloc_data(&verify_data, *size_return);
59*7f2fe78bSCy Schubert if (retval)
60*7f2fe78bSCy Schubert goto done;
61*7f2fe78bSCy Schubert vprompt.prompt = (char *)prompt2;
62*7f2fe78bSCy Schubert vprompt.hidden = 1;
63*7f2fe78bSCy Schubert vprompt.reply = &verify_data;
64*7f2fe78bSCy Schubert retval = krb5_prompter_posix(NULL, NULL, NULL, NULL, 1, &vprompt);
65*7f2fe78bSCy Schubert if (retval)
66*7f2fe78bSCy Schubert goto done;
67*7f2fe78bSCy Schubert if (strncmp(return_pwd, verify_data.data, *size_return) != 0)
68*7f2fe78bSCy Schubert retval = KRB5_LIBOS_BADPWDMATCH;
69*7f2fe78bSCy Schubert
70*7f2fe78bSCy Schubert done:
71*7f2fe78bSCy Schubert zapfree(verify_data.data, verify_data.length);
72*7f2fe78bSCy Schubert if (!retval)
73*7f2fe78bSCy Schubert *size_return = k5prompt.reply->length;
74*7f2fe78bSCy Schubert else
75*7f2fe78bSCy Schubert zap(return_pwd, *size_return);
76*7f2fe78bSCy Schubert return retval;
77*7f2fe78bSCy Schubert }
78*7f2fe78bSCy Schubert #endif
79*7f2fe78bSCy Schubert
80*7f2fe78bSCy Schubert #if defined(_WIN32)
81*7f2fe78bSCy Schubert #define DEFINED_KRB5_READ_PASSWORD
82*7f2fe78bSCy Schubert
83*7f2fe78bSCy Schubert #include <io.h>
84*7f2fe78bSCy Schubert
85*7f2fe78bSCy Schubert typedef struct {
86*7f2fe78bSCy Schubert char *pwd_prompt;
87*7f2fe78bSCy Schubert char *pwd_prompt2;
88*7f2fe78bSCy Schubert char *pwd_return_pwd;
89*7f2fe78bSCy Schubert int *pwd_size_return;
90*7f2fe78bSCy Schubert } pwd_params;
91*7f2fe78bSCy Schubert
92*7f2fe78bSCy Schubert void
center_dialog(HWND hwnd)93*7f2fe78bSCy Schubert center_dialog(HWND hwnd)
94*7f2fe78bSCy Schubert {
95*7f2fe78bSCy Schubert int scrwidth, scrheight;
96*7f2fe78bSCy Schubert int dlgwidth, dlgheight;
97*7f2fe78bSCy Schubert RECT r;
98*7f2fe78bSCy Schubert HDC hdc;
99*7f2fe78bSCy Schubert
100*7f2fe78bSCy Schubert if (hwnd == NULL)
101*7f2fe78bSCy Schubert return;
102*7f2fe78bSCy Schubert
103*7f2fe78bSCy Schubert GetWindowRect(hwnd, &r);
104*7f2fe78bSCy Schubert dlgwidth = r.right - r.left;
105*7f2fe78bSCy Schubert dlgheight = r.bottom - r.top ;
106*7f2fe78bSCy Schubert hdc = GetDC(NULL);
107*7f2fe78bSCy Schubert scrwidth = GetDeviceCaps(hdc, HORZRES);
108*7f2fe78bSCy Schubert scrheight = GetDeviceCaps(hdc, VERTRES);
109*7f2fe78bSCy Schubert ReleaseDC(NULL, hdc);
110*7f2fe78bSCy Schubert r.left = (scrwidth - dlgwidth) / 2;
111*7f2fe78bSCy Schubert r.top = (scrheight - dlgheight) / 2;
112*7f2fe78bSCy Schubert MoveWindow(hwnd, r.left, r.top, dlgwidth, dlgheight, TRUE);
113*7f2fe78bSCy Schubert }
114*7f2fe78bSCy Schubert
115*7f2fe78bSCy Schubert #ifdef _WIN32
116*7f2fe78bSCy Schubert static krb5_error_code
read_console_password(krb5_context context,const char * prompt,const char * prompt2,char * password,int * pwsize)117*7f2fe78bSCy Schubert read_console_password(krb5_context context,
118*7f2fe78bSCy Schubert const char * prompt,
119*7f2fe78bSCy Schubert const char * prompt2,
120*7f2fe78bSCy Schubert char * password,
121*7f2fe78bSCy Schubert int * pwsize)
122*7f2fe78bSCy Schubert {
123*7f2fe78bSCy Schubert HANDLE handle;
124*7f2fe78bSCy Schubert DWORD old_mode, new_mode;
125*7f2fe78bSCy Schubert char *tmpstr = 0;
126*7f2fe78bSCy Schubert char *ptr;
127*7f2fe78bSCy Schubert int scratchchar;
128*7f2fe78bSCy Schubert krb5_error_code errcode = 0;
129*7f2fe78bSCy Schubert
130*7f2fe78bSCy Schubert handle = GetStdHandle(STD_INPUT_HANDLE);
131*7f2fe78bSCy Schubert if (handle == INVALID_HANDLE_VALUE)
132*7f2fe78bSCy Schubert return ENOTTY;
133*7f2fe78bSCy Schubert if (!GetConsoleMode(handle, &old_mode))
134*7f2fe78bSCy Schubert return ENOTTY;
135*7f2fe78bSCy Schubert
136*7f2fe78bSCy Schubert new_mode = old_mode;
137*7f2fe78bSCy Schubert new_mode |= ( ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT );
138*7f2fe78bSCy Schubert new_mode &= ~( ENABLE_ECHO_INPUT );
139*7f2fe78bSCy Schubert
140*7f2fe78bSCy Schubert if (!SetConsoleMode(handle, new_mode))
141*7f2fe78bSCy Schubert return ENOTTY;
142*7f2fe78bSCy Schubert
143*7f2fe78bSCy Schubert (void) fputs(prompt, stdout);
144*7f2fe78bSCy Schubert (void) fflush(stdout);
145*7f2fe78bSCy Schubert (void) memset(password, 0, *pwsize);
146*7f2fe78bSCy Schubert
147*7f2fe78bSCy Schubert if (fgets(password, *pwsize, stdin) == NULL) {
148*7f2fe78bSCy Schubert (void) putchar('\n');
149*7f2fe78bSCy Schubert errcode = KRB5_LIBOS_CANTREADPWD;
150*7f2fe78bSCy Schubert goto cleanup;
151*7f2fe78bSCy Schubert }
152*7f2fe78bSCy Schubert (void) putchar('\n');
153*7f2fe78bSCy Schubert
154*7f2fe78bSCy Schubert if ((ptr = strchr(password, '\n')))
155*7f2fe78bSCy Schubert *ptr = '\0';
156*7f2fe78bSCy Schubert else /* need to flush */
157*7f2fe78bSCy Schubert do {
158*7f2fe78bSCy Schubert scratchchar = getchar();
159*7f2fe78bSCy Schubert } while (scratchchar != EOF && scratchchar != '\n');
160*7f2fe78bSCy Schubert
161*7f2fe78bSCy Schubert if (prompt2) {
162*7f2fe78bSCy Schubert if (! (tmpstr = (char *)malloc(*pwsize))) {
163*7f2fe78bSCy Schubert errcode = ENOMEM;
164*7f2fe78bSCy Schubert goto cleanup;
165*7f2fe78bSCy Schubert }
166*7f2fe78bSCy Schubert (void) fputs(prompt2, stdout);
167*7f2fe78bSCy Schubert (void) fflush(stdout);
168*7f2fe78bSCy Schubert if (fgets(tmpstr, *pwsize, stdin) == NULL) {
169*7f2fe78bSCy Schubert (void) putchar('\n');
170*7f2fe78bSCy Schubert errcode = KRB5_LIBOS_CANTREADPWD;
171*7f2fe78bSCy Schubert goto cleanup;
172*7f2fe78bSCy Schubert }
173*7f2fe78bSCy Schubert (void) putchar('\n');
174*7f2fe78bSCy Schubert
175*7f2fe78bSCy Schubert if ((ptr = strchr(tmpstr, '\n')))
176*7f2fe78bSCy Schubert *ptr = '\0';
177*7f2fe78bSCy Schubert else /* need to flush */
178*7f2fe78bSCy Schubert do {
179*7f2fe78bSCy Schubert scratchchar = getchar();
180*7f2fe78bSCy Schubert } while (scratchchar != EOF && scratchchar != '\n');
181*7f2fe78bSCy Schubert
182*7f2fe78bSCy Schubert if (strncmp(password, tmpstr, *pwsize)) {
183*7f2fe78bSCy Schubert errcode = KRB5_LIBOS_BADPWDMATCH;
184*7f2fe78bSCy Schubert goto cleanup;
185*7f2fe78bSCy Schubert }
186*7f2fe78bSCy Schubert }
187*7f2fe78bSCy Schubert
188*7f2fe78bSCy Schubert cleanup:
189*7f2fe78bSCy Schubert (void) SetConsoleMode(handle, old_mode);
190*7f2fe78bSCy Schubert if (tmpstr) {
191*7f2fe78bSCy Schubert (void) memset(tmpstr, 0, *pwsize);
192*7f2fe78bSCy Schubert (void) free(tmpstr);
193*7f2fe78bSCy Schubert }
194*7f2fe78bSCy Schubert if (errcode)
195*7f2fe78bSCy Schubert (void) memset(password, 0, *pwsize);
196*7f2fe78bSCy Schubert else
197*7f2fe78bSCy Schubert *pwsize = strlen(password);
198*7f2fe78bSCy Schubert return errcode;
199*7f2fe78bSCy Schubert }
200*7f2fe78bSCy Schubert #endif
201*7f2fe78bSCy Schubert
202*7f2fe78bSCy Schubert static int CALLBACK
read_pwd_proc(HWND hdlg,UINT msg,WPARAM wParam,LPARAM lParam)203*7f2fe78bSCy Schubert read_pwd_proc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
204*7f2fe78bSCy Schubert {
205*7f2fe78bSCy Schubert pwd_params *dp;
206*7f2fe78bSCy Schubert
207*7f2fe78bSCy Schubert switch(msg) {
208*7f2fe78bSCy Schubert case WM_INITDIALOG:
209*7f2fe78bSCy Schubert dp = (pwd_params *) lParam;
210*7f2fe78bSCy Schubert SetWindowLongPtr(hdlg, DWLP_USER, lParam);
211*7f2fe78bSCy Schubert SetDlgItemText(hdlg, ID_READ_PWD_PROMPT, dp->pwd_prompt);
212*7f2fe78bSCy Schubert SetDlgItemText(hdlg, ID_READ_PWD_PROMPT2, dp->pwd_prompt2);
213*7f2fe78bSCy Schubert SetDlgItemText(hdlg, ID_READ_PWD_PWD, "");
214*7f2fe78bSCy Schubert center_dialog(hdlg);
215*7f2fe78bSCy Schubert return TRUE;
216*7f2fe78bSCy Schubert
217*7f2fe78bSCy Schubert case WM_COMMAND:
218*7f2fe78bSCy Schubert dp = (pwd_params *) GetWindowLongPtr(hdlg, DWLP_USER);
219*7f2fe78bSCy Schubert switch (wParam) {
220*7f2fe78bSCy Schubert case IDOK:
221*7f2fe78bSCy Schubert *(dp->pwd_size_return) =
222*7f2fe78bSCy Schubert GetDlgItemText(hdlg, ID_READ_PWD_PWD,
223*7f2fe78bSCy Schubert dp->pwd_return_pwd, *(dp->pwd_size_return));
224*7f2fe78bSCy Schubert EndDialog(hdlg, TRUE);
225*7f2fe78bSCy Schubert break;
226*7f2fe78bSCy Schubert
227*7f2fe78bSCy Schubert case IDCANCEL:
228*7f2fe78bSCy Schubert memset(dp->pwd_return_pwd, 0 , *(dp->pwd_size_return));
229*7f2fe78bSCy Schubert *(dp->pwd_size_return) = 0;
230*7f2fe78bSCy Schubert EndDialog(hdlg, FALSE);
231*7f2fe78bSCy Schubert break;
232*7f2fe78bSCy Schubert }
233*7f2fe78bSCy Schubert return TRUE;
234*7f2fe78bSCy Schubert
235*7f2fe78bSCy Schubert default:
236*7f2fe78bSCy Schubert return FALSE;
237*7f2fe78bSCy Schubert }
238*7f2fe78bSCy Schubert }
239*7f2fe78bSCy Schubert
240*7f2fe78bSCy Schubert krb5_error_code KRB5_CALLCONV
krb5_read_password(context,prompt,prompt2,return_pwd,size_return)241*7f2fe78bSCy Schubert krb5_read_password(context, prompt, prompt2, return_pwd, size_return)
242*7f2fe78bSCy Schubert krb5_context context;
243*7f2fe78bSCy Schubert const char *prompt;
244*7f2fe78bSCy Schubert const char *prompt2;
245*7f2fe78bSCy Schubert char *return_pwd;
246*7f2fe78bSCy Schubert int *size_return;
247*7f2fe78bSCy Schubert {
248*7f2fe78bSCy Schubert DLGPROC dlgproc;
249*7f2fe78bSCy Schubert HINSTANCE hinst;
250*7f2fe78bSCy Schubert pwd_params dps;
251*7f2fe78bSCy Schubert int rc;
252*7f2fe78bSCy Schubert
253*7f2fe78bSCy Schubert #ifdef _WIN32
254*7f2fe78bSCy Schubert if (_isatty(_fileno(stdin)))
255*7f2fe78bSCy Schubert return(read_console_password
256*7f2fe78bSCy Schubert (context, prompt, prompt2, return_pwd, size_return));
257*7f2fe78bSCy Schubert #endif
258*7f2fe78bSCy Schubert
259*7f2fe78bSCy Schubert dps.pwd_prompt = prompt;
260*7f2fe78bSCy Schubert dps.pwd_prompt2 = prompt2;
261*7f2fe78bSCy Schubert dps.pwd_return_pwd = return_pwd;
262*7f2fe78bSCy Schubert dps.pwd_size_return = size_return;
263*7f2fe78bSCy Schubert
264*7f2fe78bSCy Schubert hinst = get_lib_instance();
265*7f2fe78bSCy Schubert #ifdef _WIN32
266*7f2fe78bSCy Schubert dlgproc = read_pwd_proc;
267*7f2fe78bSCy Schubert #else
268*7f2fe78bSCy Schubert dlgproc = (FARPROC) MakeProcInstance(read_pwd_proc, hinst);
269*7f2fe78bSCy Schubert #endif
270*7f2fe78bSCy Schubert rc = DialogBoxParam(hinst, MAKEINTRESOURCE(ID_READ_PWD_DIALOG), 0,
271*7f2fe78bSCy Schubert dlgproc, (LPARAM) &dps);
272*7f2fe78bSCy Schubert #ifndef _WIN32
273*7f2fe78bSCy Schubert FreeProcInstance ((FARPROC) dlgproc);
274*7f2fe78bSCy Schubert #endif
275*7f2fe78bSCy Schubert return 0;
276*7f2fe78bSCy Schubert }
277*7f2fe78bSCy Schubert #endif
278*7f2fe78bSCy Schubert
279*7f2fe78bSCy Schubert #ifndef DEFINED_KRB5_READ_PASSWORD
280*7f2fe78bSCy Schubert #define DEFINED_KRB5_READ_PASSWORD
281*7f2fe78bSCy Schubert /*
282*7f2fe78bSCy Schubert * Don't expect to be called, just define it for sanity and the linker.
283*7f2fe78bSCy Schubert */
284*7f2fe78bSCy Schubert krb5_error_code KRB5_CALLCONV
krb5_read_password(context,prompt,prompt2,return_pwd,size_return)285*7f2fe78bSCy Schubert krb5_read_password(context, prompt, prompt2, return_pwd, size_return)
286*7f2fe78bSCy Schubert krb5_context context;
287*7f2fe78bSCy Schubert const char *prompt;
288*7f2fe78bSCy Schubert const char *prompt2;
289*7f2fe78bSCy Schubert char *return_pwd;
290*7f2fe78bSCy Schubert int *size_return;
291*7f2fe78bSCy Schubert {
292*7f2fe78bSCy Schubert *size_return = 0;
293*7f2fe78bSCy Schubert return KRB5_LIBOS_CANTREADPWD;
294*7f2fe78bSCy Schubert }
295*7f2fe78bSCy Schubert #endif
296