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 2891 - (show annotations) (download) (as text)
Sat Aug 5 03:47:49 2006 UTC (17 years, 8 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/auth.c
File MIME type: text/x-csrc
File size: 32557 byte(s)
パスワードをメモリ上に覚えておくかどうかの設定は teraterm.ini に反映させるようにした。

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

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