Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

Contents of /trunk/ttssh2/ttxssh/auth.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2811 - (show annotations) (download) (as text)
Fri Apr 8 14:55:03 2005 UTC (19 years, 2 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/auth.c
File MIME type: text/x-csrc
File size: 30837 byte(s)
"Duplicate session"においてSSH自動ログインを行うようにした。

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 params.lpstrFilter = "identity(RSA1)\0identity\0id_rsa(SSH2)\0id_rsa\0id_dsa(SSH2)\0id_dsa\0all(*.*)\0*.*\0\0";
283 params.lpstrCustomFilter = NULL;
284 params.nFilterIndex = 0;
285 buf[0] = 0;
286 params.lpstrFile = fullname_buf;
287 params.nMaxFile = sizeof(fullname_buf);
288 params.lpstrFileTitle = NULL;
289 params.lpstrInitialDir = NULL;
290 params.lpstrTitle = "Choose a file with the RSA private key";
291 params.Flags =
292 OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
293 params.lpstrDefExt = NULL;
294
295 if (GetOpenFileName(&params) != 0) {
296 copy_teraterm_dir_relative_path(buf, bufsize, fullname_buf);
297 return 1;
298 } else {
299 return 0;
300 }
301 #else
302 return 0;
303 #endif
304 }
305
306 static void choose_RSA_key_file(HWND dlg)
307 {
308 char buf[1024];
309
310 if (get_key_file_name(dlg, buf, sizeof(buf))) {
311 SetDlgItemText(dlg, IDC_RSAFILENAME, buf);
312 }
313 }
314
315 static void choose_host_RSA_key_file(HWND dlg)
316 {
317 char buf[1024];
318
319 if (get_key_file_name(dlg, buf, sizeof(buf))) {
320 SetDlgItemText(dlg, IDC_HOSTRSAFILENAME, buf);
321 }
322 }
323
324 static BOOL end_auth_dlg(PTInstVar pvar, HWND dlg)
325 {
326 int method = SSH_AUTH_PASSWORD;
327 char FAR *password =
328 alloc_control_text(GetDlgItem(dlg, IDC_SSHPASSWORD));
329 CRYPTKeyPair FAR *key_pair = NULL;
330
331 if (IsDlgButtonChecked(dlg, IDC_SSHUSERSA)) {
332 method = SSH_AUTH_RSA;
333 } else if (IsDlgButtonChecked(dlg, IDC_SSHUSERHOSTS)) {
334 if (GetWindowTextLength(GetDlgItem(dlg, IDC_HOSTRSAFILENAME)) > 0) {
335 method = SSH_AUTH_RHOSTS_RSA;
336 } else {
337 method = SSH_AUTH_RHOSTS;
338 }
339 } else if (IsDlgButtonChecked(dlg, IDC_SSHUSETIS)) {
340 method = SSH_AUTH_TIS;
341 }
342
343 if (method == SSH_AUTH_RSA || method == SSH_AUTH_RHOSTS_RSA) {
344 char buf[2048];
345 int file_ctl_ID =
346 method == SSH_AUTH_RSA ? IDC_RSAFILENAME : IDC_HOSTRSAFILENAME;
347
348 buf[0] = 0;
349 GetDlgItemText(dlg, file_ctl_ID, buf, sizeof(buf));
350 if (buf[0] == 0) {
351 notify_nonfatal_error(pvar,
352 "You must specify a file containing the RSA/DSA private key.");
353 SetFocus(GetDlgItem(dlg, file_ctl_ID));
354 destroy_malloced_string(&password);
355 return FALSE;
356 }
357
358 if (SSHv1(pvar)) {
359 BOOL invalid_passphrase = FALSE;
360
361 key_pair = KEYFILES_read_private_key(pvar, buf, password,
362 &invalid_passphrase,
363 FALSE);
364
365 if (key_pair == NULL) {
366 if (invalid_passphrase) {
367 HWND passwordCtl = GetDlgItem(dlg, IDC_SSHPASSWORD);
368
369 SetFocus(passwordCtl);
370 SendMessage(passwordCtl, EM_SETSEL, 0, -1);
371 } else {
372 SetFocus(GetDlgItem(dlg, file_ctl_ID));
373 }
374 destroy_malloced_string(&password);
375 return FALSE;
376 }
377
378 } else { // SSH2(yutaka)
379 BOOL invalid_passphrase = FALSE;
380 char errmsg[256];
381
382 memset(errmsg, 0, sizeof(errmsg));
383 //GetCurrentDirectory(sizeof(errmsg), errmsg);
384
385 key_pair = read_SSH2_private_key(pvar, buf, password,
386 &invalid_passphrase,
387 FALSE,
388 errmsg,
389 sizeof(errmsg)
390 );
391
392 if (key_pair == NULL) { // read error
393 char buf[1024];
394 _snprintf(buf, sizeof(buf), "read error SSH2 private key file\r\n%s", errmsg);
395 notify_nonfatal_error(pvar, buf);
396 destroy_malloced_string(&password);
397 return FALSE;
398 }
399
400 }
401
402 }
403
404 /* from here on, we cannot fail, so just munge cur_cred in place */
405 pvar->auth_state.cur_cred.method = method;
406 pvar->auth_state.cur_cred.key_pair = key_pair;
407 /* we can't change the user name once it's set. It may already have
408 been sent to the server, and it can only be sent once. */
409 if (pvar->auth_state.user == NULL) {
410 pvar->auth_state.user =
411 alloc_control_text(GetDlgItem(dlg, IDC_SSHUSERNAME));
412 }
413
414 // ���J���F���������A�Z�b�V�������������p�X���[�h���g�����������������������������������B
415 // (2005.4.8 yutaka)
416 if (method == SSH_AUTH_PASSWORD || method == SSH_AUTH_RSA) {
417 pvar->auth_state.cur_cred.password = password;
418 } else {
419 destroy_malloced_string(&password);
420 }
421 if (method == SSH_AUTH_RHOSTS || method == SSH_AUTH_RHOSTS_RSA) {
422 if (pvar->session_settings.DefaultAuthMethod != SSH_AUTH_RHOSTS) {
423 notify_nonfatal_error(pvar,
424 "Rhosts authentication will probably fail because it was not "
425 "the default authentication method.\n"
426 "To use Rhosts authentication "
427 "in TTSSH, you need to set it to be the default by restarting\n"
428 "TTSSH and selecting \"SSH Authentication...\" from the Setup menu"
429 "before connecting.");
430 }
431
432 pvar->auth_state.cur_cred.rhosts_client_user =
433 alloc_control_text(GetDlgItem(dlg, IDC_LOCALUSERNAME));
434 }
435 pvar->auth_state.auth_dialog = NULL;
436
437 GetDlgItemText(dlg, IDC_RSAFILENAME,
438 pvar->session_settings.DefaultRSAPrivateKeyFile,
439 sizeof(pvar->session_settings.
440 DefaultRSAPrivateKeyFile));
441 GetDlgItemText(dlg, IDC_HOSTRSAFILENAME,
442 pvar->session_settings.DefaultRhostsHostPrivateKeyFile,
443 sizeof(pvar->session_settings.
444 DefaultRhostsHostPrivateKeyFile));
445 GetDlgItemText(dlg, IDC_LOCALUSERNAME,
446 pvar->session_settings.DefaultRhostsLocalUserName,
447 sizeof(pvar->session_settings.
448 DefaultRhostsLocalUserName));
449
450 if (SSHv1(pvar)) {
451 SSH_notify_user_name(pvar);
452 SSH_notify_cred(pvar);
453 } else {
454 // for SSH2(yutaka)
455 do_SSH2_userauth(pvar);
456 }
457
458 EndDialog(dlg, 1);
459 return TRUE;
460 }
461
462 static BOOL CALLBACK auth_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
463 LPARAM lParam)
464 {
465 const int IDC_TIMER1 = 300;
466 const int autologin_timeout = 10; // �~���b
467 PTInstVar pvar;
468
469 switch (msg) {
470 case WM_INITDIALOG:
471 pvar = (PTInstVar) lParam;
472 pvar->auth_state.auth_dialog = dlg;
473 SetWindowLong(dlg, DWL_USER, lParam);
474
475 init_auth_dlg(pvar, dlg);
476
477 // SSH2 autologin���L�����������A�^�C�}���d�|�����B (2004.12.1 yutaka)
478 if (pvar->ssh2_autologin == 1) {
479 SetTimer(dlg, IDC_TIMER1, autologin_timeout, 0);
480 }
481 return FALSE; /* because we set the focus */
482
483 case WM_TIMER:
484 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
485 // �F�������������������A�F���f�[�^�����M�����B�����������A�������B(2004.12.16 yutaka)
486 if (!(pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME)) {
487 KillTimer(dlg, IDC_TIMER1);
488 SendMessage(dlg, WM_COMMAND, IDOK, 0);
489 }
490 return TRUE;
491
492 case WM_COMMAND:
493 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
494
495 switch (LOWORD(wParam)) {
496 case IDOK:
497 // �F�������������������A�F���f�[�^�����M�����B�����������A�������B(2001.1.25 yutaka)
498 if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME)) {
499 return FALSE;
500 }
501 return end_auth_dlg(pvar, dlg);
502
503 case IDCANCEL: /* kill the connection */
504 pvar->auth_state.auth_dialog = NULL;
505 notify_closed_connection(pvar);
506 EndDialog(dlg, 0);
507 return TRUE;
508
509 case IDC_SSHUSEPASSWORD:
510 case IDC_SSHUSERSA:
511 case IDC_SSHUSERHOSTS:
512 case IDC_SSHUSETIS:
513 set_auth_options_status(dlg, LOWORD(wParam));
514 return TRUE;
515
516 case IDC_CHOOSERSAFILE:
517 choose_RSA_key_file(dlg);
518 return TRUE;
519
520 case IDC_CHOOSEHOSTRSAFILE:
521 choose_host_RSA_key_file(dlg);
522 return TRUE;
523
524 default:
525 return FALSE;
526 }
527
528 default:
529 return FALSE;
530 }
531 }
532
533 char FAR *AUTH_get_user_name(PTInstVar pvar)
534 {
535 return pvar->auth_state.user;
536 }
537
538 int AUTH_set_supported_auth_types(PTInstVar pvar, int types)
539 {
540 char buf[1024];
541
542 _snprintf(buf, sizeof(buf),
543 "Server reports supported authentication method mask = %d",
544 types);
545 buf[sizeof(buf) - 1] = 0;
546 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
547
548 if (SSHv1(pvar)) {
549 types &= (1 << SSH_AUTH_PASSWORD) | (1 << SSH_AUTH_RSA)
550 | (1 << SSH_AUTH_RHOSTS_RSA) | (1 << SSH_AUTH_RHOSTS)
551 | (1 << SSH_AUTH_TIS);
552 } else {
553 // for SSH2(yutaka)
554 // types &= (1 << SSH_AUTH_PASSWORD);
555 // ���J���F�����L�������� (2004.12.18 yutaka)
556 // TIS�������BSSH2����keyboard-interactive�����������B(2005.3.12 yutaka)
557 types &= (1 << SSH_AUTH_PASSWORD) | (1 << SSH_AUTH_RSA)
558 | (1 << SSH_AUTH_DSA)
559 | (1 << SSH_AUTH_TIS);
560 }
561 pvar->auth_state.supported_types = types;
562
563 if (types == 0) {
564 notify_fatal_error(pvar,
565 "Server does not support any of the authentication options\n"
566 "provided by TTSSH. This connection will now close.");
567 return 0;
568 } else {
569 if (pvar->auth_state.auth_dialog != NULL) {
570 update_server_supported_types(pvar,
571 pvar->auth_state.auth_dialog);
572 }
573
574 return 1;
575 }
576 }
577
578 static void start_user_auth(PTInstVar pvar)
579 {
580 // �F���_�C�A���O���\�������� (2004.12.1 yutaka)
581 PostMessage(pvar->NotificationWindow, WM_COMMAND, (WPARAM) ID_SSHAUTH,
582 (LPARAM) NULL);
583 pvar->auth_state.cur_cred.method = SSH_AUTH_NONE;
584 }
585
586 static void try_default_auth(PTInstVar pvar)
587 {
588 if (pvar->session_settings.TryDefaultAuth) {
589 switch (pvar->session_settings.DefaultAuthMethod) {
590 case SSH_AUTH_RSA:{
591 BOOL invalid_passphrase;
592 char password[] = "";
593
594 pvar->auth_state.cur_cred.key_pair
595 =
596 KEYFILES_read_private_key(pvar,
597 pvar->session_settings.
598 DefaultRSAPrivateKeyFile,
599 password,
600 &invalid_passphrase, TRUE);
601 if (pvar->auth_state.cur_cred.key_pair == NULL) {
602 return;
603 } else {
604 pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
605 }
606 break;
607 }
608
609 case SSH_AUTH_RHOSTS:
610 if (pvar->session_settings.
611 DefaultRhostsHostPrivateKeyFile[0] != 0) {
612 BOOL invalid_passphrase;
613 char password[] = "";
614
615 pvar->auth_state.cur_cred.key_pair
616 =
617 KEYFILES_read_private_key(pvar,
618 pvar->session_settings.
619 DefaultRhostsHostPrivateKeyFile,
620 password,
621 &invalid_passphrase, TRUE);
622 if (pvar->auth_state.cur_cred.key_pair == NULL) {
623 return;
624 } else {
625 pvar->auth_state.cur_cred.method = SSH_AUTH_RHOSTS_RSA;
626 }
627 } else {
628 pvar->auth_state.cur_cred.method = SSH_AUTH_RHOSTS;
629 }
630
631 pvar->auth_state.cur_cred.rhosts_client_user =
632 _strdup(pvar->session_settings.DefaultRhostsLocalUserName);
633 break;
634
635 case SSH_AUTH_PASSWORD:
636 pvar->auth_state.cur_cred.password = _strdup("");
637 pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
638 break;
639
640 case SSH_AUTH_TIS:
641 default:
642 return;
643 }
644
645 pvar->auth_state.user =
646 _strdup(pvar->session_settings.DefaultUserName);
647 }
648 }
649
650 void AUTH_notify_end_error(PTInstVar pvar)
651 {
652 if ((pvar->auth_state.flags & AUTH_START_USER_AUTH_ON_ERROR_END) != 0) {
653 start_user_auth(pvar);
654 pvar->auth_state.flags &= ~AUTH_START_USER_AUTH_ON_ERROR_END;
655 }
656 }
657
658 void AUTH_advance_to_next_cred(PTInstVar pvar)
659 {
660 pvar->auth_state.failed_method = pvar->auth_state.cur_cred.method;
661
662 if (pvar->auth_state.cur_cred.method == SSH_AUTH_NONE) {
663 try_default_auth(pvar);
664
665 if (pvar->auth_state.cur_cred.method == SSH_AUTH_NONE) {
666 if (pvar->err_msg != NULL) {
667 pvar->auth_state.flags |=
668 AUTH_START_USER_AUTH_ON_ERROR_END;
669 } else {
670 // �������F���_�C�A���O���o�������� (2004.12.1 yutaka)
671 // �R�}���h���C���w������������
672 start_user_auth(pvar);
673 }
674 }
675 } else {
676 // �������F���_�C�A���O���o�������� (2004.12.1 yutaka)
677 // �R�}���h���C���w������(/auth=xxxx)������
678 start_user_auth(pvar);
679 }
680 }
681
682 static void init_TIS_dlg(PTInstVar pvar, HWND dlg)
683 {
684 init_auth_machine_banner(pvar, dlg);
685 init_password_control(dlg);
686
687 if (pvar->auth_state.TIS_prompt != NULL) {
688 if (strlen(pvar->auth_state.TIS_prompt) > 10000) {
689 pvar->auth_state.TIS_prompt[10000] = 0;
690 }
691 SetDlgItemText(dlg, IDC_SSHAUTHBANNER2,
692 pvar->auth_state.TIS_prompt);
693 destroy_malloced_string(&pvar->auth_state.TIS_prompt);
694 }
695 }
696
697 static BOOL end_TIS_dlg(PTInstVar pvar, HWND dlg)
698 {
699 char FAR *password =
700 alloc_control_text(GetDlgItem(dlg, IDC_SSHPASSWORD));
701
702 pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
703 pvar->auth_state.cur_cred.password = password;
704 pvar->auth_state.auth_dialog = NULL;
705
706 // add
707 if (SSHv2(pvar)) {
708 pvar->keyboard_interactive_password_input = 1;
709 handle_SSH2_userauth_inforeq(pvar);
710 }
711
712 SSH_notify_cred(pvar);
713
714 EndDialog(dlg, 1);
715 return TRUE;
716 }
717
718 static BOOL CALLBACK TIS_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
719 LPARAM lParam)
720 {
721 PTInstVar pvar;
722
723 switch (msg) {
724 case WM_INITDIALOG:
725 pvar = (PTInstVar) lParam;
726 pvar->auth_state.auth_dialog = dlg;
727 SetWindowLong(dlg, DWL_USER, lParam);
728
729 init_TIS_dlg(pvar, dlg);
730 return FALSE; /* because we set the focus */
731
732 case WM_COMMAND:
733 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
734
735 switch (LOWORD(wParam)) {
736 case IDOK:
737 return end_TIS_dlg(pvar, dlg);
738
739 case IDCANCEL: /* kill the connection */
740 pvar->auth_state.auth_dialog = NULL;
741 notify_closed_connection(pvar);
742 EndDialog(dlg, 0);
743 return TRUE;
744
745 default:
746 return FALSE;
747 }
748
749 default:
750 return FALSE;
751 }
752 }
753
754 void AUTH_do_cred_dialog(PTInstVar pvar)
755 {
756 if (pvar->auth_state.auth_dialog == NULL) {
757 HWND cur_active = GetActiveWindow();
758 DLGPROC dlg_proc;
759 LPCTSTR dialog_template;
760
761 switch (pvar->auth_state.mode) {
762 case TIS_AUTH_MODE:
763 dialog_template = MAKEINTRESOURCE(IDD_SSHTISAUTH);
764 dlg_proc = TIS_dlg_proc;
765 break;
766 case GENERIC_AUTH_MODE:
767 default:
768 dialog_template = MAKEINTRESOURCE(IDD_SSHAUTH);
769 dlg_proc = auth_dlg_proc;
770 }
771
772 if (!DialogBoxParam(hInst, dialog_template,
773 cur_active !=
774 NULL ? cur_active : pvar->NotificationWindow,
775 dlg_proc, (LPARAM) pvar) == -1) {
776 notify_fatal_error(pvar,
777 "Unable to display authentication dialog box.\n"
778 "Connection terminated.");
779 }
780 }
781 }
782
783 static void init_default_auth_dlg(PTInstVar pvar, HWND dlg)
784 {
785 switch (pvar->settings.DefaultAuthMethod) {
786 case SSH_AUTH_RSA:
787 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL,
788 IDC_SSHUSERSA);
789 break;
790 case SSH_AUTH_RHOSTS:
791 case SSH_AUTH_RHOSTS_RSA:
792 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL,
793 IDC_SSHUSERHOSTS);
794 break;
795 case SSH_AUTH_TIS:
796 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL,
797 IDC_SSHUSETIS);
798 break;
799 case SSH_AUTH_PASSWORD:
800 default:
801 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL,
802 IDC_SSHUSEPASSWORD);
803 }
804
805 SetDlgItemText(dlg, IDC_SSHUSERNAME, pvar->settings.DefaultUserName);
806 SetDlgItemText(dlg, IDC_RSAFILENAME,
807 pvar->settings.DefaultRSAPrivateKeyFile);
808 SetDlgItemText(dlg, IDC_HOSTRSAFILENAME,
809 pvar->settings.DefaultRhostsHostPrivateKeyFile);
810 SetDlgItemText(dlg, IDC_LOCALUSERNAME,
811 pvar->settings.DefaultRhostsLocalUserName);
812
813 // SSH2 keyboard-interactive method (2005.2.22 yutaka)
814 if (pvar->settings.ssh2_keyboard_interactive) {
815 SendMessage(GetDlgItem(dlg, IDC_KEYBOARD_INTERACTIVE_CHECK), BM_SETCHECK, BST_CHECKED, 0);
816 }
817
818 }
819
820 static BOOL end_default_auth_dlg(PTInstVar pvar, HWND dlg)
821 {
822 if (IsDlgButtonChecked(dlg, IDC_SSHUSERSA)) {
823 pvar->settings.DefaultAuthMethod = SSH_AUTH_RSA;
824 } else if (IsDlgButtonChecked(dlg, IDC_SSHUSERHOSTS)) {
825 if (GetWindowTextLength(GetDlgItem(dlg, IDC_HOSTRSAFILENAME)) > 0) {
826 pvar->settings.DefaultAuthMethod = SSH_AUTH_RHOSTS_RSA;
827 } else {
828 pvar->settings.DefaultAuthMethod = SSH_AUTH_RHOSTS;
829 }
830 } else if (IsDlgButtonChecked(dlg, IDC_SSHUSETIS)) {
831 pvar->settings.DefaultAuthMethod = SSH_AUTH_TIS;
832 } else {
833 pvar->settings.DefaultAuthMethod = SSH_AUTH_PASSWORD;
834 }
835
836 GetDlgItemText(dlg, IDC_SSHUSERNAME, pvar->settings.DefaultUserName,
837 sizeof(pvar->settings.DefaultUserName));
838 GetDlgItemText(dlg, IDC_RSAFILENAME,
839 pvar->settings.DefaultRSAPrivateKeyFile,
840 sizeof(pvar->settings.DefaultRSAPrivateKeyFile));
841 GetDlgItemText(dlg, IDC_HOSTRSAFILENAME,
842 pvar->settings.DefaultRhostsHostPrivateKeyFile,
843 sizeof(pvar->settings.DefaultRhostsHostPrivateKeyFile));
844 GetDlgItemText(dlg, IDC_LOCALUSERNAME,
845 pvar->settings.DefaultRhostsLocalUserName,
846 sizeof(pvar->settings.DefaultRhostsLocalUserName));
847
848 // SSH2 keyboard-interactive method (2005.2.22 yutaka)
849 {
850 LRESULT ret;
851 ret = SendMessage(GetDlgItem(dlg, IDC_KEYBOARD_INTERACTIVE_CHECK), BM_GETCHECK, 0, 0);
852 if (ret & BST_CHECKED) {
853 pvar->settings.ssh2_keyboard_interactive = 1;
854 } else {
855 pvar->settings.ssh2_keyboard_interactive = 0;
856 }
857 }
858
859 EndDialog(dlg, 1);
860 return TRUE;
861 }
862
863 static BOOL CALLBACK default_auth_dlg_proc(HWND dlg, UINT msg,
864 WPARAM wParam, LPARAM lParam)
865 {
866 PTInstVar pvar;
867
868 switch (msg) {
869 case WM_INITDIALOG:
870 pvar = (PTInstVar) lParam;
871 SetWindowLong(dlg, DWL_USER, lParam);
872
873 init_default_auth_dlg(pvar, dlg);
874 return TRUE; /* because we do not set the focus */
875
876 case WM_COMMAND:
877 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
878
879 switch (LOWORD(wParam)) {
880 case IDOK:
881 return end_default_auth_dlg(pvar, dlg);
882
883 case IDCANCEL:
884 EndDialog(dlg, 0);
885 return TRUE;
886
887 case IDC_CHOOSERSAFILE:
888 choose_RSA_key_file(dlg);
889 return TRUE;
890
891 case IDC_CHOOSEHOSTRSAFILE:
892 choose_host_RSA_key_file(dlg);
893 return TRUE;
894
895 default:
896 return FALSE;
897 }
898
899 default:
900 return FALSE;
901 }
902 }
903
904 void AUTH_init(PTInstVar pvar)
905 {
906 pvar->auth_state.failed_method = SSH_AUTH_NONE;
907 pvar->auth_state.auth_dialog = NULL;
908 pvar->auth_state.user = NULL;
909 pvar->auth_state.flags = 0;
910 pvar->auth_state.TIS_prompt = NULL;
911 pvar->auth_state.supported_types = 0;
912 pvar->auth_state.cur_cred.method = SSH_AUTH_NONE;
913 pvar->auth_state.cur_cred.password = NULL;
914 pvar->auth_state.cur_cred.rhosts_client_user = NULL;
915 pvar->auth_state.cur_cred.key_pair = NULL;
916 AUTH_set_generic_mode(pvar);
917 }
918
919 void AUTH_set_generic_mode(PTInstVar pvar)
920 {
921 pvar->auth_state.mode = GENERIC_AUTH_MODE;
922 destroy_malloced_string(&pvar->auth_state.TIS_prompt);
923 }
924
925 void AUTH_set_TIS_mode(PTInstVar pvar, char FAR * prompt, int len)
926 {
927 if (pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) {
928 pvar->auth_state.mode = TIS_AUTH_MODE;
929
930 destroy_malloced_string(&pvar->auth_state.TIS_prompt);
931 pvar->auth_state.TIS_prompt = malloc(len + 1);
932 memcpy(pvar->auth_state.TIS_prompt, prompt, len);
933 pvar->auth_state.TIS_prompt[len] = 0;
934 } else {
935 AUTH_set_generic_mode(pvar);
936 }
937 }
938
939 void AUTH_do_default_cred_dialog(PTInstVar pvar)
940 {
941 HWND cur_active = GetActiveWindow();
942
943 if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHAUTHSETUP),
944 cur_active !=
945 NULL ? cur_active : pvar->NotificationWindow,
946 default_auth_dlg_proc, (LPARAM) pvar) == -1) {
947 notify_nonfatal_error(pvar,
948 "Unable to display authentication setup dialog box.");
949 }
950 }
951
952 void AUTH_destroy_cur_cred(PTInstVar pvar)
953 {
954 destroy_malloced_string(&pvar->auth_state.cur_cred.password);
955 destroy_malloced_string(&pvar->auth_state.cur_cred.rhosts_client_user);
956 if (pvar->auth_state.cur_cred.key_pair != NULL) {
957 CRYPT_free_key_pair(pvar->auth_state.cur_cred.key_pair);
958 pvar->auth_state.cur_cred.key_pair = NULL;
959 }
960 }
961
962 static char FAR *get_auth_method_name(SSHAuthMethod auth)
963 {
964 switch (auth) {
965 case SSH_AUTH_PASSWORD:
966 return "password";
967 case SSH_AUTH_RSA:
968 return "RSA";
969 case SSH_AUTH_RHOSTS:
970 return "rhosts";
971 case SSH_AUTH_RHOSTS_RSA:
972 return "rhosts with RSA";
973 case SSH_AUTH_TIS:
974 return "challenge/response (TIS)";
975 default:
976 return "unknown method";
977 }
978 }
979
980 void AUTH_get_auth_info(PTInstVar pvar, char FAR * dest, int len)
981 {
982 char *method = "unknown";
983
984 if (pvar->auth_state.user == NULL) {
985 strncpy(dest, "None", len);
986 } else if (pvar->auth_state.cur_cred.method != SSH_AUTH_NONE) {
987 if (SSHv1(pvar)) {
988 _snprintf(dest, len, "User '%s', using %s", pvar->auth_state.user,
989 get_auth_method_name(pvar->auth_state.cur_cred.method));
990
991 } else {
992 // SSH2:�F�����\�b�h������ (2004.12.23 yutaka)
993 // keyboard-interactive���\�b�h������ (2005.3.12 yutaka)
994 if (pvar->auth_state.cur_cred.method == SSH_AUTH_PASSWORD ||
995 pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) {
996 // keyboard-interactive���\�b�h������ (2005.1.24 yutaka)
997 if (pvar->keyboard_interactive_done == 1 ||
998 pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) {
999 method = "keyboard-interactive";
1000 } else {
1001 method = get_auth_method_name(pvar->auth_state.cur_cred.method);
1002 }
1003 _snprintf(dest, len, "User '%s', using %s", pvar->auth_state.user, method);
1004
1005 } else {
1006 if (pvar->auth_state.cur_cred.key_pair->RSA_key != NULL) {
1007 method = "RSA";
1008 } else if (pvar->auth_state.cur_cred.key_pair->DSA_key != NULL) {
1009 method = "DSA";
1010 }
1011 _snprintf(dest, len, "User '%s', using %s", pvar->auth_state.user, method);
1012 }
1013
1014 }
1015
1016 } else {
1017 _snprintf(dest, len, "User '%s', using %s", pvar->auth_state.user,
1018 get_auth_method_name(pvar->auth_state.failed_method));
1019 }
1020
1021 dest[len - 1] = 0;
1022 }
1023
1024 void AUTH_notify_disconnecting(PTInstVar pvar)
1025 {
1026 if (pvar->auth_state.auth_dialog != NULL) {
1027 PostMessage(pvar->auth_state.auth_dialog, WM_COMMAND, IDCANCEL, 0);
1028 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
1029 EnableWindow(pvar->NotificationWindow, TRUE);
1030 }
1031 }
1032
1033 void AUTH_end(PTInstVar pvar)
1034 {
1035 destroy_malloced_string(&pvar->auth_state.user);
1036 destroy_malloced_string(&pvar->auth_state.TIS_prompt);
1037
1038 AUTH_destroy_cur_cred(pvar);
1039 }
1040
1041 /*
1042 * $Log: not supported by cvs2svn $
1043 * Revision 1.12 2005/03/23 12:39:35 yutakakn
1044 * SSH2�F���_�C�A���O�� Use challenge/response to log in ���A�N�Z�����[�^�L�[�������������B
1045 *
1046 * Revision 1.11 2005/03/12 15:07:33 yutakakn
1047 * SSH2 keyboard-interactive�F����TIS�_�C�A���O�����������B
1048 *
1049 * Revision 1.10 2005/03/12 12:08:05 yutakakn
1050 * �p�X���[�h�F�����O���s��keyboard-interactive���\�b�h���A�f�t�H���g�����l������(0)�������B
1051 * �����A�F���_�C�A���O�����x�������������L�����������X���������������B
1052 *
1053 * Revision 1.9 2005/02/22 08:48:11 yutakakn
1054 * TTSSH setup�_�C�A���O�� HeartBeat �����������B
1055 * TTSSH authentication setup�_�C�A���O�� keyboard-interactive �����������B
1056 *
1057 * Revision 1.8 2005/01/27 13:30:33 yutakakn
1058 * ���J���F���������O�C�����T�|�[�g�B
1059 * /auth=publickey, /keyfile �I�v�V�������V�K���������B
1060 * �����A�����������������T�|�[�g�B
1061 *
1062 * Revision 1.7 2005/01/25 13:38:22 yutakakn
1063 * SSH�F���_�C�A���O���ARhosts/TIS���O���[�������O���AEnter�L�[�������������A
1064 * �A�v���P�[�V�����G���[���������������������B
1065 *
1066 * Revision 1.6 2005/01/24 14:07:07 yutakakn
1067 * �Ekeyboard-interactive�F�����T�|�[�g�����B
1068 * �@�����������Ateraterm.ini�� "KeyboardInteractive" �G���g�������������B
1069 * �E�o�[�W�����_�C�A���O�� OpenSSL�o�[�W���� ������
1070 *
1071 * Revision 1.5 2004/12/27 14:35:41 yutakakn
1072 * SSH2�����������������s�����G���[���b�Z�[�W�����������B
1073 *
1074 * Revision 1.4 2004/12/22 17:28:14 yutakakn
1075 * SSH2���J���F��(RSA/DSA)���T�|�[�g�����B
1076 *
1077 * Revision 1.3 2004/12/16 13:01:09 yutakakn
1078 * SSH�������O�C�����A�v���P�[�V�����G���[�������������C�������B
1079 *
1080 * Revision 1.2 2004/12/01 15:37:49 yutakakn
1081 * SSH2�������O�C���@�\�������B
1082 * �����A�p�X���[�h�F�������������B
1083 * �E�R�}���h���C��
1084 * /ssh /auth=�F�����\�b�h /user=���[�U�� /passwd=�p�X���[�h
1085 *
1086 */

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