Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2835 - (show annotations) (download) (as text)
Fri Jul 15 14:58:04 2005 UTC (18 years, 9 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/auth.c
File MIME type: text/x-csrc
File size: 31193 byte(s)
SSH1接続で一度ユーザ認証に失敗すると、その後認証ができなくなるバグを修正。

1 /*
2 Copyright (c) 1998-2001, Robert O'Callahan
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8 Redistributions of source code must retain the above copyright notice, this list of
9 conditions and the following disclaimer.
10
11 Redistributions in binary form must reproduce the above copyright notice, this list
12 of conditions and the following disclaimer in the documentation and/or other materials
13 provided with the distribution.
14
15 The name of Robert O'Callahan may not be used to endorse or promote products derived from
16 this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "ttxssh.h"
30 #include "util.h"
31 #include "ssh.h"
32
33 #include <io.h>
34 #include <fcntl.h>
35 #include <stdlib.h>
36 #include <errno.h>
37
38 #include "resource.h"
39 #include "keyfiles.h"
40
41 #define AUTH_START_USER_AUTH_ON_ERROR_END 1
42
43 #define MAX_AUTH_CONTROL IDC_SSHUSETIS
44
45 static void destroy_malloced_string(char FAR * FAR * str)
46 {
47 if (*str != NULL) {
48 memset(*str, 0, strlen(*str));
49 free(*str);
50 *str = NULL;
51 }
52 }
53
54 static int auth_types_to_control_IDs[] = {
55 -1, IDC_SSHUSERHOSTS, IDC_SSHUSERSA, IDC_SSHUSEPASSWORD,
56 IDC_SSHUSERHOSTS, IDC_SSHUSETIS, -1
57 };
58
59 static LRESULT CALLBACK password_wnd_proc(HWND control, UINT msg,
60 WPARAM wParam, LPARAM lParam)
61 {
62 switch (msg) {
63 case WM_CHAR:
64 if ((GetKeyState(VK_CONTROL) & 0x8000) != 0) {
65 char chars[] = { (char) wParam, 0 };
66
67 SendMessage(control, EM_REPLACESEL, (WPARAM) TRUE,
68 (LPARAM) (char FAR *) chars);
69 return 0;
70 }
71 }
72
73 return CallWindowProc((WNDPROC) GetWindowLong(control, GWL_USERDATA),
74 control, msg, wParam, lParam);
75 }
76
77 static void init_password_control(HWND dlg)
78 {
79 HWND passwordControl = GetDlgItem(dlg, IDC_SSHPASSWORD);
80
81 SetWindowLong(passwordControl, GWL_USERDATA,
82 SetWindowLong(passwordControl, GWL_WNDPROC,
83 (LONG) password_wnd_proc));
84
85 SetFocus(passwordControl);
86 }
87
88 static void set_auth_options_status(HWND dlg, int controlID)
89 {
90 BOOL RSA_enabled = controlID == IDC_SSHUSERSA;
91 BOOL rhosts_enabled = controlID == IDC_SSHUSERHOSTS;
92 BOOL TIS_enabled = controlID == IDC_SSHUSETIS;
93 int i;
94
95 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL, controlID);
96
97 EnableWindow(GetDlgItem(dlg, IDC_SSHPASSWORDCAPTION), !TIS_enabled);
98 EnableWindow(GetDlgItem(dlg, IDC_SSHPASSWORD), !TIS_enabled);
99
100 for (i = IDC_CHOOSERSAFILE; i <= IDC_RSAFILENAME; i++) {
101 EnableWindow(GetDlgItem(dlg, i), RSA_enabled);
102 }
103
104 for (i = IDC_LOCALUSERNAMELABEL; i <= IDC_HOSTRSAFILENAME; i++) {
105 EnableWindow(GetDlgItem(dlg, i), rhosts_enabled);
106 }
107 }
108
109 static void init_auth_machine_banner(PTInstVar pvar, HWND dlg)
110 {
111 char buf[1024] = "Logging in to ";
112
113 if (strlen(buf) + strlen(SSH_get_host_name(pvar)) < sizeof(buf) - 2) {
114 strcat(buf, SSH_get_host_name(pvar));
115 }
116 SetDlgItemText(dlg, IDC_SSHAUTHBANNER, buf);
117 }
118
119 static void update_server_supported_types(PTInstVar pvar, HWND dlg)
120 {
121 int supported_methods = pvar->auth_state.supported_types;
122 int cur_control = -1;
123 int control;
124 HWND focus = GetFocus();
125
126 if (supported_methods == 0) {
127 return;
128 }
129
130 for (control = IDC_SSHUSEPASSWORD; control <= MAX_AUTH_CONTROL;
131 control++) {
132 BOOL enabled = FALSE;
133 int method;
134 HWND item = GetDlgItem(dlg, control);
135
136 if (item != NULL) {
137 for (method = 0; method <= SSH_AUTH_MAX; method++) {
138 if (auth_types_to_control_IDs[method] == control
139 && (supported_methods & (1 << method)) != 0) {
140 enabled = TRUE;
141 }
142 }
143
144 EnableWindow(item, enabled);
145
146 if (IsDlgButtonChecked(dlg, control)) {
147 cur_control = control;
148 }
149 }
150 }
151
152 if (cur_control >= 0) {
153 if (!IsWindowEnabled(GetDlgItem(dlg, cur_control))) {
154 do {
155 cur_control++;
156 if (cur_control > MAX_AUTH_CONTROL) {
157 cur_control = IDC_SSHUSEPASSWORD;
158 }
159 } while (!IsWindowEnabled(GetDlgItem(dlg, cur_control)));
160
161 set_auth_options_status(dlg, cur_control);
162
163 if (focus != NULL && !IsWindowEnabled(focus)) {
164 SetFocus(GetDlgItem(dlg, cur_control));
165 }
166 }
167 }
168 }
169
170 static void init_auth_dlg(PTInstVar pvar, HWND dlg)
171 {
172 int default_method = pvar->session_settings.DefaultAuthMethod;
173
174 init_auth_machine_banner(pvar, dlg);
175 init_password_control(dlg);
176
177 if (pvar->auth_state.failed_method != SSH_AUTH_NONE) {
178 /* must be retrying a failed attempt */
179 SetDlgItemText(dlg, IDC_SSHAUTHBANNER2,
180 "Authentication failed. Please retry.");
181 SetWindowText(dlg, "Retrying SSH Authentication");
182 default_method = pvar->auth_state.failed_method;
183 }
184
185 set_auth_options_status(dlg,
186 auth_types_to_control_IDs[default_method]);
187
188 if (default_method == SSH_AUTH_TIS) {
189 /* we disabled the password control, so fix the focus */
190 SetFocus(GetDlgItem(dlg, IDC_SSHUSETIS));
191 }
192
193 if (pvar->auth_state.user != NULL) {
194 SetDlgItemText(dlg, IDC_SSHUSERNAME, pvar->auth_state.user);
195 EnableWindow(GetDlgItem(dlg, IDC_SSHUSERNAME), FALSE);
196 EnableWindow(GetDlgItem(dlg, IDC_SSHUSERNAMELABEL), FALSE);
197 } else if (pvar->session_settings.DefaultUserName[0] != 0) {
198 SetDlgItemText(dlg, IDC_SSHUSERNAME,
199 pvar->session_settings.DefaultUserName);
200 } else {
201 SetFocus(GetDlgItem(dlg, IDC_SSHUSERNAME));
202 }
203
204 SetDlgItemText(dlg, IDC_RSAFILENAME,
205 pvar->session_settings.DefaultRSAPrivateKeyFile);
206 SetDlgItemText(dlg, IDC_HOSTRSAFILENAME,
207 pvar->session_settings.DefaultRhostsHostPrivateKeyFile);
208 SetDlgItemText(dlg, IDC_LOCALUSERNAME,
209 pvar->session_settings.DefaultRhostsLocalUserName);
210
211 update_server_supported_types(pvar, dlg);
212
213 // SSH2 autologin
214 // ���[�U�A�p�X���[�h�A�F�����\�b�h���������������A������������OK�{�^�������������B
215 //
216 // (2004.12.1 yutaka)
217 // (2005.1.26 yutaka) ���J���F���T�|�[�g
218 if (pvar->ssh2_autologin == 1) {
219 SetDlgItemText(dlg, IDC_SSHUSERNAME, pvar->ssh2_username);
220 EnableWindow(GetDlgItem(dlg, IDC_SSHUSERNAME), FALSE);
221 EnableWindow(GetDlgItem(dlg, IDC_SSHUSERNAMELABEL), FALSE);
222
223 SetDlgItemText(dlg, IDC_SSHPASSWORD, pvar->ssh2_password);
224 EnableWindow(GetDlgItem(dlg, IDC_SSHPASSWORD), FALSE);
225 EnableWindow(GetDlgItem(dlg, IDC_SSHPASSWORDCAPTION), FALSE);
226
227 if (pvar->ssh2_authmethod == SSH_AUTH_PASSWORD) {
228 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL, IDC_SSHUSEPASSWORD);
229
230 } else if (pvar->ssh2_authmethod == SSH_AUTH_RSA) {
231 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL, IDC_SSHUSERSA);
232
233 SetDlgItemText(dlg, IDC_RSAFILENAME, pvar->ssh2_keyfile);
234 EnableWindow(GetDlgItem(dlg, IDC_CHOOSERSAFILE), FALSE);
235 EnableWindow(GetDlgItem(dlg, IDC_RSAFILENAME), FALSE);
236
237 } else {
238 // TODO
239
240 }
241 }
242
243 #if 1
244 // �p�X���[�h�F���������O���Akeyboard-interactive���\�b�h�������������A���x������
245 // ���X�����B(2005.3.12 yutaka)
246 if (pvar->settings.ssh2_keyboard_interactive == 1) {
247 SetDlgItemText(dlg, IDC_SSHUSEPASSWORD, "Use p&lain password to log in (with keyboard-interactive)");
248 }
249
250 if (pvar->settings.ssh_protocol_version == 1) {
251 SetDlgItemText(dlg, IDC_SSHUSETIS, "Use challenge/response to log in(&TIS)");
252 } else {
253 SetDlgItemText(dlg, IDC_SSHUSETIS, "Use challenge/response to log in(&keyboard-interactive)");
254 }
255 #endif
256
257 }
258
259 static char FAR *alloc_control_text(HWND ctl)
260 {
261 int len = GetWindowTextLength(ctl);
262 char FAR *result = malloc(len + 1);
263
264 if (result != NULL) {
265 GetWindowText(ctl, result, len + 1);
266 result[len] = 0;
267 }
268
269 return result;
270 }
271
272 static int get_key_file_name(HWND parent, char FAR * buf, int bufsize)
273 {
274 #ifdef TERATERM32
275 OPENFILENAME params;
276 char fullname_buf[2048] = "identity";
277
278 ZeroMemory(&params, sizeof(params));
279 params.lStructSize = sizeof(OPENFILENAME);
280 params.hwndOwner = parent;
281 // �t�B���^������ (2004.12.19 yutaka)
282 // 3�t�@�C���t�B���^������ (2005.4.26 yutaka)
283 params.lpstrFilter = "identity files\0identity;id_rsa;id_dsa\0identity(RSA1)\0identity\0id_rsa(SSH2)\0id_rsa\0id_dsa(SSH2)\0id_dsa\0all(*.*)\0*.*\0\0";
284 params.lpstrCustomFilter = NULL;
285 params.nFilterIndex = 0;
286 buf[0] = 0;
287 params.lpstrFile = fullname_buf;
288 params.nMaxFile = sizeof(fullname_buf);
289 params.lpstrFileTitle = NULL;
290 params.lpstrInitialDir = NULL;
291 params.lpstrTitle = "Choose a file with the RSA/DSA private key";
292 params.Flags =
293 OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
294 params.lpstrDefExt = NULL;
295
296 if (GetOpenFileName(&params) != 0) {
297 copy_teraterm_dir_relative_path(buf, bufsize, fullname_buf);
298 return 1;
299 } else {
300 return 0;
301 }
302 #else
303 return 0;
304 #endif
305 }
306
307 static void choose_RSA_key_file(HWND dlg)
308 {
309 char buf[1024];
310
311 if (get_key_file_name(dlg, buf, sizeof(buf))) {
312 SetDlgItemText(dlg, IDC_RSAFILENAME, buf);
313 }
314 }
315
316 static void choose_host_RSA_key_file(HWND dlg)
317 {
318 char buf[1024];
319
320 if (get_key_file_name(dlg, buf, sizeof(buf))) {
321 SetDlgItemText(dlg, IDC_HOSTRSAFILENAME, buf);
322 }
323 }
324
325 static BOOL end_auth_dlg(PTInstVar pvar, HWND dlg)
326 {
327 int method = SSH_AUTH_PASSWORD;
328 char FAR *password =
329 alloc_control_text(GetDlgItem(dlg, IDC_SSHPASSWORD));
330 CRYPTKeyPair FAR *key_pair = NULL;
331
332 if (IsDlgButtonChecked(dlg, IDC_SSHUSERSA)) {
333 method = SSH_AUTH_RSA;
334 } else if (IsDlgButtonChecked(dlg, IDC_SSHUSERHOSTS)) {
335 if (GetWindowTextLength(GetDlgItem(dlg, IDC_HOSTRSAFILENAME)) > 0) {
336 method = SSH_AUTH_RHOSTS_RSA;
337 } else {
338 method = SSH_AUTH_RHOSTS;
339 }
340 } else if (IsDlgButtonChecked(dlg, IDC_SSHUSETIS)) {
341 method = SSH_AUTH_TIS;
342 }
343
344 if (method == SSH_AUTH_RSA || method == SSH_AUTH_RHOSTS_RSA) {
345 char buf[2048];
346 int file_ctl_ID =
347 method == SSH_AUTH_RSA ? IDC_RSAFILENAME : IDC_HOSTRSAFILENAME;
348
349 buf[0] = 0;
350 GetDlgItemText(dlg, file_ctl_ID, buf, sizeof(buf));
351 if (buf[0] == 0) {
352 notify_nonfatal_error(pvar,
353 "You must specify a file containing the RSA/DSA private key.");
354 SetFocus(GetDlgItem(dlg, file_ctl_ID));
355 destroy_malloced_string(&password);
356 return FALSE;
357 }
358
359 if (SSHv1(pvar)) {
360 BOOL invalid_passphrase = FALSE;
361
362 key_pair = KEYFILES_read_private_key(pvar, buf, password,
363 &invalid_passphrase,
364 FALSE);
365
366 if (key_pair == NULL) {
367 if (invalid_passphrase) {
368 HWND passwordCtl = GetDlgItem(dlg, IDC_SSHPASSWORD);
369
370 SetFocus(passwordCtl);
371 SendMessage(passwordCtl, EM_SETSEL, 0, -1);
372 } else {
373 SetFocus(GetDlgItem(dlg, file_ctl_ID));
374 }
375 destroy_malloced_string(&password);
376 return FALSE;
377 }
378
379 } else { // SSH2(yutaka)
380 BOOL invalid_passphrase = FALSE;
381 char errmsg[256];
382
383 memset(errmsg, 0, sizeof(errmsg));
384 //GetCurrentDirectory(sizeof(errmsg), errmsg);
385
386 key_pair = read_SSH2_private_key(pvar, buf, password,
387 &invalid_passphrase,
388 FALSE,
389 errmsg,
390 sizeof(errmsg)
391 );
392
393 if (key_pair == NULL) { // read error
394 char buf[1024];
395 _snprintf(buf, sizeof(buf), "read error SSH2 private key file\r\n%s", errmsg);
396 notify_nonfatal_error(pvar, buf);
397 destroy_malloced_string(&password);
398 return FALSE;
399 }
400
401 }
402
403 }
404
405 /* from here on, we cannot fail, so just munge cur_cred in place */
406 pvar->auth_state.cur_cred.method = method;
407 pvar->auth_state.cur_cred.key_pair = key_pair;
408 /* we can't change the user name once it's set. It may already have
409 been sent to the server, and it can only be sent once. */
410 if (pvar->auth_state.user == NULL) {
411 pvar->auth_state.user =
412 alloc_control_text(GetDlgItem(dlg, IDC_SSHUSERNAME));
413 }
414
415 // ���J���F���������A�Z�b�V�������������p�X���[�h���g�����������������������������������B
416 // (2005.4.8 yutaka)
417 if (method == SSH_AUTH_PASSWORD || method == SSH_AUTH_RSA) {
418 pvar->auth_state.cur_cred.password = password;
419 } else {
420 destroy_malloced_string(&password);
421 }
422 if (method == SSH_AUTH_RHOSTS || method == SSH_AUTH_RHOSTS_RSA) {
423 if (pvar->session_settings.DefaultAuthMethod != SSH_AUTH_RHOSTS) {
424 notify_nonfatal_error(pvar,
425 "Rhosts authentication will probably fail because it was not "
426 "the default authentication method.\n"
427 "To use Rhosts authentication "
428 "in TTSSH, you need to set it to be the default by restarting\n"
429 "TTSSH and selecting \"SSH Authentication...\" from the Setup menu"
430 "before connecting.");
431 }
432
433 pvar->auth_state.cur_cred.rhosts_client_user =
434 alloc_control_text(GetDlgItem(dlg, IDC_LOCALUSERNAME));
435 }
436 pvar->auth_state.auth_dialog = NULL;
437
438 GetDlgItemText(dlg, IDC_RSAFILENAME,
439 pvar->session_settings.DefaultRSAPrivateKeyFile,
440 sizeof(pvar->session_settings.
441 DefaultRSAPrivateKeyFile));
442 GetDlgItemText(dlg, IDC_HOSTRSAFILENAME,
443 pvar->session_settings.DefaultRhostsHostPrivateKeyFile,
444 sizeof(pvar->session_settings.
445 DefaultRhostsHostPrivateKeyFile));
446 GetDlgItemText(dlg, IDC_LOCALUSERNAME,
447 pvar->session_settings.DefaultRhostsLocalUserName,
448 sizeof(pvar->session_settings.
449 DefaultRhostsLocalUserName));
450
451 if (SSHv1(pvar)) {
452 SSH_notify_user_name(pvar);
453 SSH_notify_cred(pvar);
454 } else {
455 // for SSH2(yutaka)
456 do_SSH2_userauth(pvar);
457 }
458
459 EndDialog(dlg, 1);
460 return TRUE;
461 }
462
463 static BOOL CALLBACK auth_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
464 LPARAM lParam)
465 {
466 const int IDC_TIMER1 = 300;
467 const int autologin_timeout = 10; // �~���b
468 PTInstVar pvar;
469
470 switch (msg) {
471 case WM_INITDIALOG:
472 pvar = (PTInstVar) lParam;
473 pvar->auth_state.auth_dialog = dlg;
474 SetWindowLong(dlg, DWL_USER, lParam);
475
476 init_auth_dlg(pvar, dlg);
477
478 // SSH2 autologin���L�����������A�^�C�}���d�|�����B (2004.12.1 yutaka)
479 if (pvar->ssh2_autologin == 1) {
480 SetTimer(dlg, IDC_TIMER1, autologin_timeout, 0);
481 }
482 return FALSE; /* because we set the focus */
483
484 case WM_TIMER:
485 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
486 // �F�������������������A�F���f�[�^�����M�����B�����������A�������B(2004.12.16 yutaka)
487 if (!(pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME)) {
488 KillTimer(dlg, IDC_TIMER1);
489 SendMessage(dlg, WM_COMMAND, IDOK, 0);
490 }
491 return TRUE;
492
493 case WM_COMMAND:
494 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
495
496 switch (LOWORD(wParam)) {
497 case IDOK:
498 // �F�������������������A�F���f�[�^�����M�����B�����������A�������B(2001.1.25 yutaka)
499 if (pvar->userauth_retry_count == 0 && (pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME)) {
500 return FALSE;
501 }
502 return end_auth_dlg(pvar, dlg);
503
504 case IDCANCEL: /* kill the connection */
505 pvar->auth_state.auth_dialog = NULL;
506 notify_closed_connection(pvar);
507 EndDialog(dlg, 0);
508 return TRUE;
509
510 case IDC_SSHUSEPASSWORD:
511 case IDC_SSHUSERSA:
512 case IDC_SSHUSERHOSTS:
513 case IDC_SSHUSETIS:
514 set_auth_options_status(dlg, LOWORD(wParam));
515 return TRUE;
516
517 case IDC_CHOOSERSAFILE:
518 choose_RSA_key_file(dlg);
519 return TRUE;
520
521 case IDC_CHOOSEHOSTRSAFILE:
522 choose_host_RSA_key_file(dlg);
523 return TRUE;
524
525 default:
526 return FALSE;
527 }
528
529 default:
530 return FALSE;
531 }
532 }
533
534 char FAR *AUTH_get_user_name(PTInstVar pvar)
535 {
536 return pvar->auth_state.user;
537 }
538
539 int AUTH_set_supported_auth_types(PTInstVar pvar, int types)
540 {
541 char buf[1024];
542
543 _snprintf(buf, sizeof(buf),
544 "Server reports supported authentication method mask = %d",
545 types);
546 buf[sizeof(buf) - 1] = 0;
547 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
548
549 if (SSHv1(pvar)) {
550 types &= (1 << SSH_AUTH_PASSWORD) | (1 << SSH_AUTH_RSA)
551 | (1 << SSH_AUTH_RHOSTS_RSA) | (1 << SSH_AUTH_RHOSTS)
552 | (1 << SSH_AUTH_TIS);
553 } else {
554 // for SSH2(yutaka)
555 // types &= (1 << SSH_AUTH_PASSWORD);
556 // ���J���F�����L�������� (2004.12.18 yutaka)
557 // TIS�������BSSH2����keyboard-interactive�����������B(2005.3.12 yutaka)
558 types &= (1 << SSH_AUTH_PASSWORD) | (1 << SSH_AUTH_RSA)
559 | (1 << SSH_AUTH_DSA)
560 | (1 << SSH_AUTH_TIS);
561 }
562 pvar->auth_state.supported_types = types;
563
564 if (types == 0) {
565 notify_fatal_error(pvar,
566 "Server does not support any of the authentication options\n"
567 "provided by TTSSH. This connection will now close.");
568 return 0;
569 } else {
570 if (pvar->auth_state.auth_dialog != NULL) {
571 update_server_supported_types(pvar,
572 pvar->auth_state.auth_dialog);
573 }
574
575 return 1;
576 }
577 }
578
579 static void start_user_auth(PTInstVar pvar)
580 {
581 // �F���_�C�A���O���\�������� (2004.12.1 yutaka)
582 PostMessage(pvar->NotificationWindow, WM_COMMAND, (WPARAM) ID_SSHAUTH,
583 (LPARAM) NULL);
584 pvar->auth_state.cur_cred.method = SSH_AUTH_NONE;
585 }
586
587 static void try_default_auth(PTInstVar pvar)
588 {
589 if (pvar->session_settings.TryDefaultAuth) {
590 switch (pvar->session_settings.DefaultAuthMethod) {
591 case SSH_AUTH_RSA:{
592 BOOL invalid_passphrase;
593 char password[] = "";
594
595 pvar->auth_state.cur_cred.key_pair
596 =
597 KEYFILES_read_private_key(pvar,
598 pvar->session_settings.
599 DefaultRSAPrivateKeyFile,
600 password,
601 &invalid_passphrase, TRUE);
602 if (pvar->auth_state.cur_cred.key_pair == NULL) {
603 return;
604 } else {
605 pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
606 }
607 break;
608 }
609
610 case SSH_AUTH_RHOSTS:
611 if (pvar->session_settings.
612 DefaultRhostsHostPrivateKeyFile[0] != 0) {
613 BOOL invalid_passphrase;
614 char password[] = "";
615
616 pvar->auth_state.cur_cred.key_pair
617 =
618 KEYFILES_read_private_key(pvar,
619 pvar->session_settings.
620 DefaultRhostsHostPrivateKeyFile,
621 password,
622 &invalid_passphrase, TRUE);
623 if (pvar->auth_state.cur_cred.key_pair == NULL) {
624 return;
625 } else {
626 pvar->auth_state.cur_cred.method = SSH_AUTH_RHOSTS_RSA;
627 }
628 } else {
629 pvar->auth_state.cur_cred.method = SSH_AUTH_RHOSTS;
630 }
631
632 pvar->auth_state.cur_cred.rhosts_client_user =
633 _strdup(pvar->session_settings.DefaultRhostsLocalUserName);
634 break;
635
636 case SSH_AUTH_PASSWORD:
637 pvar->auth_state.cur_cred.password = _strdup("");
638 pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
639 break;
640
641 case SSH_AUTH_TIS:
642 default:
643 return;
644 }
645
646 pvar->auth_state.user =
647 _strdup(pvar->session_settings.DefaultUserName);
648 }
649 }
650
651 void AUTH_notify_end_error(PTInstVar pvar)
652 {
653 if ((pvar->auth_state.flags & AUTH_START_USER_AUTH_ON_ERROR_END) != 0) {
654 start_user_auth(pvar);
655 pvar->auth_state.flags &= ~AUTH_START_USER_AUTH_ON_ERROR_END;
656 }
657 }
658
659 void AUTH_advance_to_next_cred(PTInstVar pvar)
660 {
661 pvar->auth_state.failed_method = pvar->auth_state.cur_cred.method;
662
663 if (pvar->auth_state.cur_cred.method == SSH_AUTH_NONE) {
664 try_default_auth(pvar);
665
666 if (pvar->auth_state.cur_cred.method == SSH_AUTH_NONE) {
667 if (pvar->err_msg != NULL) {
668 pvar->auth_state.flags |=
669 AUTH_START_USER_AUTH_ON_ERROR_END;
670 } else {
671 // �������F���_�C�A���O���o�������� (2004.12.1 yutaka)
672 // �R�}���h���C���w������������
673 start_user_auth(pvar);
674 }
675 }
676 } else {
677 // �������F���_�C�A���O���o�������� (2004.12.1 yutaka)
678 // �R�}���h���C���w������(/auth=xxxx)������
679 start_user_auth(pvar);
680 }
681 }
682
683 static void init_TIS_dlg(PTInstVar pvar, HWND dlg)
684 {
685 init_auth_machine_banner(pvar, dlg);
686 init_password_control(dlg);
687
688 if (pvar->auth_state.TIS_prompt != NULL) {
689 if (strlen(pvar->auth_state.TIS_prompt) > 10000) {
690 pvar->auth_state.TIS_prompt[10000] = 0;
691 }
692 SetDlgItemText(dlg, IDC_SSHAUTHBANNER2,
693 pvar->auth_state.TIS_prompt);
694 destroy_malloced_string(&pvar->auth_state.TIS_prompt);
695 }
696 }
697
698 static BOOL end_TIS_dlg(PTInstVar pvar, HWND dlg)
699 {
700 char FAR *password =
701 alloc_control_text(GetDlgItem(dlg, IDC_SSHPASSWORD));
702
703 pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
704 pvar->auth_state.cur_cred.password = password;
705 pvar->auth_state.auth_dialog = NULL;
706
707 // add
708 if (SSHv2(pvar)) {
709 pvar->keyboard_interactive_password_input = 1;
710 handle_SSH2_userauth_inforeq(pvar);
711 }
712
713 SSH_notify_cred(pvar);
714
715 EndDialog(dlg, 1);
716 return TRUE;
717 }
718
719 static BOOL CALLBACK TIS_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
720 LPARAM lParam)
721 {
722 PTInstVar pvar;
723
724 switch (msg) {
725 case WM_INITDIALOG:
726 pvar = (PTInstVar) lParam;
727 pvar->auth_state.auth_dialog = dlg;
728 SetWindowLong(dlg, DWL_USER, lParam);
729
730 init_TIS_dlg(pvar, dlg);
731 return FALSE; /* because we set the focus */
732
733 case WM_COMMAND:
734 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
735
736 switch (LOWORD(wParam)) {
737 case IDOK:
738 return end_TIS_dlg(pvar, dlg);
739
740 case IDCANCEL: /* kill the connection */
741 pvar->auth_state.auth_dialog = NULL;
742 notify_closed_connection(pvar);
743 EndDialog(dlg, 0);
744 return TRUE;
745
746 default:
747 return FALSE;
748 }
749
750 default:
751 return FALSE;
752 }
753 }
754
755 void AUTH_do_cred_dialog(PTInstVar pvar)
756 {
757 if (pvar->auth_state.auth_dialog == NULL) {
758 HWND cur_active = GetActiveWindow();
759 DLGPROC dlg_proc;
760 LPCTSTR dialog_template;
761
762 switch (pvar->auth_state.mode) {
763 case TIS_AUTH_MODE:
764 dialog_template = MAKEINTRESOURCE(IDD_SSHTISAUTH);
765 dlg_proc = TIS_dlg_proc;
766 break;
767 case GENERIC_AUTH_MODE:
768 default:
769 dialog_template = MAKEINTRESOURCE(IDD_SSHAUTH);
770 dlg_proc = auth_dlg_proc;
771 }
772
773 if (!DialogBoxParam(hInst, dialog_template,
774 cur_active !=
775 NULL ? cur_active : pvar->NotificationWindow,
776 dlg_proc, (LPARAM) pvar) == -1) {
777 notify_fatal_error(pvar,
778 "Unable to display authentication dialog box.\n"
779 "Connection terminated.");
780 }
781 }
782 }
783
784 static void init_default_auth_dlg(PTInstVar pvar, HWND dlg)
785 {
786 switch (pvar->settings.DefaultAuthMethod) {
787 case SSH_AUTH_RSA:
788 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL,
789 IDC_SSHUSERSA);
790 break;
791 case SSH_AUTH_RHOSTS:
792 case SSH_AUTH_RHOSTS_RSA:
793 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL,
794 IDC_SSHUSERHOSTS);
795 break;
796 case SSH_AUTH_TIS:
797 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL,
798 IDC_SSHUSETIS);
799 break;
800 case SSH_AUTH_PASSWORD:
801 default:
802 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL,
803 IDC_SSHUSEPASSWORD);
804 }
805
806 SetDlgItemText(dlg, IDC_SSHUSERNAME, pvar->settings.DefaultUserName);
807 SetDlgItemText(dlg, IDC_RSAFILENAME,
808 pvar->settings.DefaultRSAPrivateKeyFile);
809 SetDlgItemText(dlg, IDC_HOSTRSAFILENAME,
810 pvar->settings.DefaultRhostsHostPrivateKeyFile);
811 SetDlgItemText(dlg, IDC_LOCALUSERNAME,
812 pvar->settings.DefaultRhostsLocalUserName);
813
814 // SSH2 keyboard-interactive method (2005.2.22 yutaka)
815 if (pvar->settings.ssh2_keyboard_interactive) {
816 SendMessage(GetDlgItem(dlg, IDC_KEYBOARD_INTERACTIVE_CHECK), BM_SETCHECK, BST_CHECKED, 0);
817 }
818
819 }
820
821 static BOOL end_default_auth_dlg(PTInstVar pvar, HWND dlg)
822 {
823 if (IsDlgButtonChecked(dlg, IDC_SSHUSERSA)) {
824 pvar->settings.DefaultAuthMethod = SSH_AUTH_RSA;
825 } else if (IsDlgButtonChecked(dlg, IDC_SSHUSERHOSTS)) {
826 if (GetWindowTextLength(GetDlgItem(dlg, IDC_HOSTRSAFILENAME)) > 0) {
827 pvar->settings.DefaultAuthMethod = SSH_AUTH_RHOSTS_RSA;
828 } else {
829 pvar->settings.DefaultAuthMethod = SSH_AUTH_RHOSTS;
830 }
831 } else if (IsDlgButtonChecked(dlg, IDC_SSHUSETIS)) {
832 pvar->settings.DefaultAuthMethod = SSH_AUTH_TIS;
833 } else {
834 pvar->settings.DefaultAuthMethod = SSH_AUTH_PASSWORD;
835 }
836
837 GetDlgItemText(dlg, IDC_SSHUSERNAME, pvar->settings.DefaultUserName,
838 sizeof(pvar->settings.DefaultUserName));
839 GetDlgItemText(dlg, IDC_RSAFILENAME,
840 pvar->settings.DefaultRSAPrivateKeyFile,
841 sizeof(pvar->settings.DefaultRSAPrivateKeyFile));
842 GetDlgItemText(dlg, IDC_HOSTRSAFILENAME,
843 pvar->settings.DefaultRhostsHostPrivateKeyFile,
844 sizeof(pvar->settings.DefaultRhostsHostPrivateKeyFile));
845 GetDlgItemText(dlg, IDC_LOCALUSERNAME,
846 pvar->settings.DefaultRhostsLocalUserName,
847 sizeof(pvar->settings.DefaultRhostsLocalUserName));
848
849 // SSH2 keyboard-interactive method (2005.2.22 yutaka)
850 {
851 LRESULT ret;
852 ret = SendMessage(GetDlgItem(dlg, IDC_KEYBOARD_INTERACTIVE_CHECK), BM_GETCHECK, 0, 0);
853 if (ret & BST_CHECKED) {
854 pvar->settings.ssh2_keyboard_interactive = 1;
855 } else {
856 pvar->settings.ssh2_keyboard_interactive = 0;
857 }
858 }
859
860 EndDialog(dlg, 1);
861 return TRUE;
862 }
863
864 static BOOL CALLBACK default_auth_dlg_proc(HWND dlg, UINT msg,
865 WPARAM wParam, LPARAM lParam)
866 {
867 PTInstVar pvar;
868
869 switch (msg) {
870 case WM_INITDIALOG:
871 pvar = (PTInstVar) lParam;
872 SetWindowLong(dlg, DWL_USER, lParam);
873
874 init_default_auth_dlg(pvar, dlg);
875 return TRUE; /* because we do not set the focus */
876
877 case WM_COMMAND:
878 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
879
880 switch (LOWORD(wParam)) {
881 case IDOK:
882 return end_default_auth_dlg(pvar, dlg);
883
884 case IDCANCEL:
885 EndDialog(dlg, 0);
886 return TRUE;
887
888 case IDC_CHOOSERSAFILE:
889 choose_RSA_key_file(dlg);
890 return TRUE;
891
892 case IDC_CHOOSEHOSTRSAFILE:
893 choose_host_RSA_key_file(dlg);
894 return TRUE;
895
896 default:
897 return FALSE;
898 }
899
900 default:
901 return FALSE;
902 }
903 }
904
905 void AUTH_init(PTInstVar pvar)
906 {
907 pvar->auth_state.failed_method = SSH_AUTH_NONE;
908 pvar->auth_state.auth_dialog = NULL;
909 pvar->auth_state.user = NULL;
910 pvar->auth_state.flags = 0;
911 pvar->auth_state.TIS_prompt = NULL;
912 pvar->auth_state.supported_types = 0;
913 pvar->auth_state.cur_cred.method = SSH_AUTH_NONE;
914 pvar->auth_state.cur_cred.password = NULL;
915 pvar->auth_state.cur_cred.rhosts_client_user = NULL;
916 pvar->auth_state.cur_cred.key_pair = NULL;
917 AUTH_set_generic_mode(pvar);
918 }
919
920 void AUTH_set_generic_mode(PTInstVar pvar)
921 {
922 pvar->auth_state.mode = GENERIC_AUTH_MODE;
923 destroy_malloced_string(&pvar->auth_state.TIS_prompt);
924 }
925
926 void AUTH_set_TIS_mode(PTInstVar pvar, char FAR * prompt, int len)
927 {
928 if (pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) {
929 pvar->auth_state.mode = TIS_AUTH_MODE;
930
931 destroy_malloced_string(&pvar->auth_state.TIS_prompt);
932 pvar->auth_state.TIS_prompt = malloc(len + 1);
933 memcpy(pvar->auth_state.TIS_prompt, prompt, len);
934 pvar->auth_state.TIS_prompt[len] = 0;
935 } else {
936 AUTH_set_generic_mode(pvar);
937 }
938 }
939
940 void AUTH_do_default_cred_dialog(PTInstVar pvar)
941 {
942 HWND cur_active = GetActiveWindow();
943
944 if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHAUTHSETUP),
945 cur_active !=
946 NULL ? cur_active : pvar->NotificationWindow,
947 default_auth_dlg_proc, (LPARAM) pvar) == -1) {
948 notify_nonfatal_error(pvar,
949 "Unable to display authentication setup dialog box.");
950 }
951 }
952
953 void AUTH_destroy_cur_cred(PTInstVar pvar)
954 {
955 destroy_malloced_string(&pvar->auth_state.cur_cred.password);
956 destroy_malloced_string(&pvar->auth_state.cur_cred.rhosts_client_user);
957 if (pvar->auth_state.cur_cred.key_pair != NULL) {
958 CRYPT_free_key_pair(pvar->auth_state.cur_cred.key_pair);
959 pvar->auth_state.cur_cred.key_pair = NULL;
960 }
961 }
962
963 static char FAR *get_auth_method_name(SSHAuthMethod auth)
964 {
965 switch (auth) {
966 case SSH_AUTH_PASSWORD:
967 return "password";
968 case SSH_AUTH_RSA:
969 return "RSA";
970 case SSH_AUTH_RHOSTS:
971 return "rhosts";
972 case SSH_AUTH_RHOSTS_RSA:
973 return "rhosts with RSA";
974 case SSH_AUTH_TIS:
975 return "challenge/response (TIS)";
976 default:
977 return "unknown method";
978 }
979 }
980
981 void AUTH_get_auth_info(PTInstVar pvar, char FAR * dest, int len)
982 {
983 char *method = "unknown";
984
985 if (pvar->auth_state.user == NULL) {
986 strncpy(dest, "None", len);
987 } else if (pvar->auth_state.cur_cred.method != SSH_AUTH_NONE) {
988 if (SSHv1(pvar)) {
989 _snprintf(dest, len, "User '%s', using %s", pvar->auth_state.user,
990 get_auth_method_name(pvar->auth_state.cur_cred.method));
991
992 } else {
993 // SSH2:�F�����\�b�h������ (2004.12.23 yutaka)
994 // keyboard-interactive���\�b�h������ (2005.3.12 yutaka)
995 if (pvar->auth_state.cur_cred.method == SSH_AUTH_PASSWORD ||
996 pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) {
997 // keyboard-interactive���\�b�h������ (2005.1.24 yutaka)
998 if (pvar->keyboard_interactive_done == 1 ||
999 pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) {
1000 method = "keyboard-interactive";
1001 } else {
1002 method = get_auth_method_name(pvar->auth_state.cur_cred.method);
1003 }
1004 _snprintf(dest, len, "User '%s', using %s", pvar->auth_state.user, method);
1005
1006 } else {
1007 if (pvar->auth_state.cur_cred.key_pair->RSA_key != NULL) {
1008 method = "RSA";
1009 } else if (pvar->auth_state.cur_cred.key_pair->DSA_key != NULL) {
1010 method = "DSA";
1011 }
1012 _snprintf(dest, len, "User '%s', using %s", pvar->auth_state.user, method);
1013 }
1014
1015 }
1016
1017 } else {
1018 _snprintf(dest, len, "User '%s', using %s", pvar->auth_state.user,
1019 get_auth_method_name(pvar->auth_state.failed_method));
1020 }
1021
1022 dest[len - 1] = 0;
1023 }
1024
1025 void AUTH_notify_disconnecting(PTInstVar pvar)
1026 {
1027 if (pvar->auth_state.auth_dialog != NULL) {
1028 PostMessage(pvar->auth_state.auth_dialog, WM_COMMAND, IDCANCEL, 0);
1029 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
1030 EnableWindow(pvar->NotificationWindow, TRUE);
1031 }
1032 }
1033
1034 void AUTH_end(PTInstVar pvar)
1035 {
1036 destroy_malloced_string(&pvar->auth_state.user);
1037 destroy_malloced_string(&pvar->auth_state.TIS_prompt);
1038
1039 AUTH_destroy_cur_cred(pvar);
1040 }
1041
1042 /*
1043 * $Log: not supported by cvs2svn $
1044 * Revision 1.14 2005/04/26 13:57:57 yutakakn
1045 * private key�t�@�C���_�C�A���O��3�t�@�C���t�B���^�����������B
1046 *
1047 * Revision 1.13 2005/04/08 14:55:03 yutakakn
1048 * "Duplicate session"��������SSH�������O�C�����s�������������B
1049 *
1050 * Revision 1.12 2005/03/23 12:39:35 yutakakn
1051 * SSH2�F���_�C�A���O�� Use challenge/response to log in ���A�N�Z�����[�^�L�[�������������B
1052 *
1053 * Revision 1.11 2005/03/12 15:07:33 yutakakn
1054 * SSH2 keyboard-interactive�F����TIS�_�C�A���O�����������B
1055 *
1056 * Revision 1.10 2005/03/12 12:08:05 yutakakn
1057 * �p�X���[�h�F�����O���s��keyboard-interactive���\�b�h���A�f�t�H���g�����l������(0)�������B
1058 * �����A�F���_�C�A���O�����x�������������L�����������X���������������B
1059 *
1060 * Revision 1.9 2005/02/22 08:48:11 yutakakn
1061 * TTSSH setup�_�C�A���O�� HeartBeat �����������B
1062 * TTSSH authentication setup�_�C�A���O�� keyboard-interactive �����������B
1063 *
1064 * Revision 1.8 2005/01/27 13:30:33 yutakakn
1065 * ���J���F���������O�C�����T�|�[�g�B
1066 * /auth=publickey, /keyfile �I�v�V�������V�K���������B
1067 * �����A�����������������T�|�[�g�B
1068 *
1069 * Revision 1.7 2005/01/25 13:38:22 yutakakn
1070 * SSH�F���_�C�A���O���ARhosts/TIS���O���[�������O���AEnter�L�[�������������A
1071 * �A�v���P�[�V�����G���[���������������������B
1072 *
1073 * Revision 1.6 2005/01/24 14:07:07 yutakakn
1074 * �Ekeyboard-interactive�F�����T�|�[�g�����B
1075 * �@�����������Ateraterm.ini�� "KeyboardInteractive" �G���g�������������B
1076 * �E�o�[�W�����_�C�A���O�� OpenSSL�o�[�W���� ������
1077 *
1078 * Revision 1.5 2004/12/27 14:35:41 yutakakn
1079 * SSH2�����������������s�����G���[���b�Z�[�W�����������B
1080 *
1081 * Revision 1.4 2004/12/22 17:28:14 yutakakn
1082 * SSH2���J���F��(RSA/DSA)���T�|�[�g�����B
1083 *
1084 * Revision 1.3 2004/12/16 13:01:09 yutakakn
1085 * SSH�������O�C�����A�v���P�[�V�����G���[�������������C�������B
1086 *
1087 * Revision 1.2 2004/12/01 15:37:49 yutakakn
1088 * SSH2�������O�C���@�\�������B
1089 * �����A�p�X���[�h�F�������������B
1090 * �E�R�}���h���C��
1091 * /ssh /auth=�F�����\�b�h /user=���[�U�� /passwd=�p�X���[�h
1092 *
1093 */

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26