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 2890 - (show annotations) (download) (as text)
Thu Aug 3 15:05:02 2006 UTC (17 years, 8 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/auth.c
File MIME type: text/x-csrc
File size: 32460 byte(s)
パスワードをメモリ上に保持するかどうかを決めるチェックボックスを認証ダイアログに追加した。

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->auth_state.cur_cred.remeber_password != 0) {
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->auth_state.cur_cred.remeber_password = 1; // �o��������
432 } else {
433 pvar->auth_state.cur_cred.remeber_password = 0; // ���������������Y����
434 }
435
436 // ���J���F���������A�Z�b�V�������������p�X���[�h���g�����������������������������������B
437 // (2005.4.8 yutaka)
438 if (method == SSH_AUTH_PASSWORD || method == SSH_AUTH_RSA) {
439 pvar->auth_state.cur_cred.password = password;
440 } else {
441 destroy_malloced_string(&password);
442 }
443 if (method == SSH_AUTH_RHOSTS || method == SSH_AUTH_RHOSTS_RSA) {
444 if (pvar->session_settings.DefaultAuthMethod != SSH_AUTH_RHOSTS) {
445 notify_nonfatal_error(pvar,
446 "Rhosts authentication will probably fail because it was not "
447 "the default authentication method.\n"
448 "To use Rhosts authentication "
449 "in TTSSH, you need to set it to be the default by restarting\n"
450 "TTSSH and selecting \"SSH Authentication...\" from the Setup menu"
451 "before connecting.");
452 }
453
454 pvar->auth_state.cur_cred.rhosts_client_user =
455 alloc_control_text(GetDlgItem(dlg, IDC_LOCALUSERNAME));
456 }
457 pvar->auth_state.auth_dialog = NULL;
458
459 GetDlgItemText(dlg, IDC_RSAFILENAME,
460 pvar->session_settings.DefaultRSAPrivateKeyFile,
461 sizeof(pvar->session_settings.
462 DefaultRSAPrivateKeyFile));
463 GetDlgItemText(dlg, IDC_HOSTRSAFILENAME,
464 pvar->session_settings.DefaultRhostsHostPrivateKeyFile,
465 sizeof(pvar->session_settings.
466 DefaultRhostsHostPrivateKeyFile));
467 GetDlgItemText(dlg, IDC_LOCALUSERNAME,
468 pvar->session_settings.DefaultRhostsLocalUserName,
469 sizeof(pvar->session_settings.
470 DefaultRhostsLocalUserName));
471
472 if (SSHv1(pvar)) {
473 SSH_notify_user_name(pvar);
474 SSH_notify_cred(pvar);
475 } else {
476 // for SSH2(yutaka)
477 do_SSH2_userauth(pvar);
478 }
479
480 EndDialog(dlg, 1);
481 return TRUE;
482 }
483
484 static BOOL CALLBACK auth_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
485 LPARAM lParam)
486 {
487 const int IDC_TIMER1 = 300;
488 const int autologin_timeout = 10; // �~���b
489 PTInstVar pvar;
490
491 switch (msg) {
492 case WM_INITDIALOG:
493 pvar = (PTInstVar) lParam;
494 pvar->auth_state.auth_dialog = dlg;
495 SetWindowLong(dlg, DWL_USER, lParam);
496
497 init_auth_dlg(pvar, dlg);
498
499 // SSH2 autologin���L�����������A�^�C�}���d�|�����B (2004.12.1 yutaka)
500 if (pvar->ssh2_autologin == 1) {
501 SetTimer(dlg, IDC_TIMER1, autologin_timeout, 0);
502 }
503 return FALSE; /* because we set the focus */
504
505 case WM_TIMER:
506 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
507 // �F�������������������A�F���f�[�^�����M�����B�����������A�������B(2004.12.16 yutaka)
508 if (!(pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME)) {
509 KillTimer(dlg, IDC_TIMER1);
510 SendMessage(dlg, WM_COMMAND, IDOK, 0);
511 }
512 return TRUE;
513
514 case WM_COMMAND:
515 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
516
517 switch (LOWORD(wParam)) {
518 case IDOK:
519 // �F�������������������A�F���f�[�^�����M�����B�����������A�������B(2001.1.25 yutaka)
520 if (pvar->userauth_retry_count == 0 && (pvar->ssh_state.status_flags & STATUS_DONT_SEND_USER_NAME)) {
521 return FALSE;
522 }
523 return end_auth_dlg(pvar, dlg);
524
525 case IDCANCEL: /* kill the connection */
526 pvar->auth_state.auth_dialog = NULL;
527 notify_closed_connection(pvar);
528 EndDialog(dlg, 0);
529 return TRUE;
530
531 case IDC_SSHUSEPASSWORD:
532 case IDC_SSHUSERSA:
533 case IDC_SSHUSERHOSTS:
534 case IDC_SSHUSETIS:
535 set_auth_options_status(dlg, LOWORD(wParam));
536 return TRUE;
537
538 case IDC_CHOOSERSAFILE:
539 choose_RSA_key_file(dlg);
540 return TRUE;
541
542 case IDC_CHOOSEHOSTRSAFILE:
543 choose_host_RSA_key_file(dlg);
544 return TRUE;
545
546 default:
547 return FALSE;
548 }
549
550 default:
551 return FALSE;
552 }
553 }
554
555 char FAR *AUTH_get_user_name(PTInstVar pvar)
556 {
557 return pvar->auth_state.user;
558 }
559
560 int AUTH_set_supported_auth_types(PTInstVar pvar, int types)
561 {
562 char buf[1024];
563
564 _snprintf(buf, sizeof(buf),
565 "Server reports supported authentication method mask = %d",
566 types);
567 buf[sizeof(buf) - 1] = 0;
568 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
569
570 if (SSHv1(pvar)) {
571 types &= (1 << SSH_AUTH_PASSWORD) | (1 << SSH_AUTH_RSA)
572 | (1 << SSH_AUTH_RHOSTS_RSA) | (1 << SSH_AUTH_RHOSTS)
573 | (1 << SSH_AUTH_TIS);
574 } else {
575 // for SSH2(yutaka)
576 // types &= (1 << SSH_AUTH_PASSWORD);
577 // ���J���F�����L�������� (2004.12.18 yutaka)
578 // TIS�������BSSH2����keyboard-interactive�����������B(2005.3.12 yutaka)
579 types &= (1 << SSH_AUTH_PASSWORD) | (1 << SSH_AUTH_RSA)
580 | (1 << SSH_AUTH_DSA)
581 | (1 << SSH_AUTH_TIS);
582 }
583 pvar->auth_state.supported_types = types;
584
585 if (types == 0) {
586 notify_fatal_error(pvar,
587 "Server does not support any of the authentication options\n"
588 "provided by TTSSH. This connection will now close.");
589 return 0;
590 } else {
591 if (pvar->auth_state.auth_dialog != NULL) {
592 update_server_supported_types(pvar,
593 pvar->auth_state.auth_dialog);
594 }
595
596 return 1;
597 }
598 }
599
600 static void start_user_auth(PTInstVar pvar)
601 {
602 // �F���_�C�A���O���\�������� (2004.12.1 yutaka)
603 PostMessage(pvar->NotificationWindow, WM_COMMAND, (WPARAM) ID_SSHAUTH,
604 (LPARAM) NULL);
605 pvar->auth_state.cur_cred.method = SSH_AUTH_NONE;
606 }
607
608 static void try_default_auth(PTInstVar pvar)
609 {
610 if (pvar->session_settings.TryDefaultAuth) {
611 switch (pvar->session_settings.DefaultAuthMethod) {
612 case SSH_AUTH_RSA:{
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 DefaultRSAPrivateKeyFile,
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_RSA;
627 }
628 break;
629 }
630
631 case SSH_AUTH_RHOSTS:
632 if (pvar->session_settings.
633 DefaultRhostsHostPrivateKeyFile[0] != 0) {
634 BOOL invalid_passphrase;
635 char password[] = "";
636
637 pvar->auth_state.cur_cred.key_pair
638 =
639 KEYFILES_read_private_key(pvar,
640 pvar->session_settings.
641 DefaultRhostsHostPrivateKeyFile,
642 password,
643 &invalid_passphrase, TRUE);
644 if (pvar->auth_state.cur_cred.key_pair == NULL) {
645 return;
646 } else {
647 pvar->auth_state.cur_cred.method = SSH_AUTH_RHOSTS_RSA;
648 }
649 } else {
650 pvar->auth_state.cur_cred.method = SSH_AUTH_RHOSTS;
651 }
652
653 pvar->auth_state.cur_cred.rhosts_client_user =
654 _strdup(pvar->session_settings.DefaultRhostsLocalUserName);
655 break;
656
657 case SSH_AUTH_PASSWORD:
658 pvar->auth_state.cur_cred.password = _strdup("");
659 pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
660 break;
661
662 case SSH_AUTH_TIS:
663 default:
664 return;
665 }
666
667 pvar->auth_state.user =
668 _strdup(pvar->session_settings.DefaultUserName);
669 }
670 }
671
672 void AUTH_notify_end_error(PTInstVar pvar)
673 {
674 if ((pvar->auth_state.flags & AUTH_START_USER_AUTH_ON_ERROR_END) != 0) {
675 start_user_auth(pvar);
676 pvar->auth_state.flags &= ~AUTH_START_USER_AUTH_ON_ERROR_END;
677 }
678 }
679
680 void AUTH_advance_to_next_cred(PTInstVar pvar)
681 {
682 pvar->auth_state.failed_method = pvar->auth_state.cur_cred.method;
683
684 if (pvar->auth_state.cur_cred.method == SSH_AUTH_NONE) {
685 try_default_auth(pvar);
686
687 if (pvar->auth_state.cur_cred.method == SSH_AUTH_NONE) {
688 if (pvar->err_msg != NULL) {
689 pvar->auth_state.flags |=
690 AUTH_START_USER_AUTH_ON_ERROR_END;
691 } else {
692 // �������F���_�C�A���O���o�������� (2004.12.1 yutaka)
693 // �R�}���h���C���w������������
694 start_user_auth(pvar);
695 }
696 }
697 } else {
698 // �������F���_�C�A���O���o�������� (2004.12.1 yutaka)
699 // �R�}���h���C���w������(/auth=xxxx)������
700 start_user_auth(pvar);
701 }
702 }
703
704 static void init_TIS_dlg(PTInstVar pvar, HWND dlg)
705 {
706 init_auth_machine_banner(pvar, dlg);
707 init_password_control(dlg);
708
709 if (pvar->auth_state.TIS_prompt != NULL) {
710 if (strlen(pvar->auth_state.TIS_prompt) > 10000) {
711 pvar->auth_state.TIS_prompt[10000] = 0;
712 }
713 SetDlgItemText(dlg, IDC_SSHAUTHBANNER2,
714 pvar->auth_state.TIS_prompt);
715 destroy_malloced_string(&pvar->auth_state.TIS_prompt);
716 }
717 }
718
719 static BOOL end_TIS_dlg(PTInstVar pvar, HWND dlg)
720 {
721 char FAR *password =
722 alloc_control_text(GetDlgItem(dlg, IDC_SSHPASSWORD));
723
724 pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
725 pvar->auth_state.cur_cred.password = password;
726 pvar->auth_state.auth_dialog = NULL;
727
728 // add
729 if (SSHv2(pvar)) {
730 pvar->keyboard_interactive_password_input = 1;
731 handle_SSH2_userauth_inforeq(pvar);
732 }
733
734 SSH_notify_cred(pvar);
735
736 EndDialog(dlg, 1);
737 return TRUE;
738 }
739
740 static BOOL CALLBACK TIS_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
741 LPARAM lParam)
742 {
743 PTInstVar pvar;
744
745 switch (msg) {
746 case WM_INITDIALOG:
747 pvar = (PTInstVar) lParam;
748 pvar->auth_state.auth_dialog = dlg;
749 SetWindowLong(dlg, DWL_USER, lParam);
750
751 init_TIS_dlg(pvar, dlg);
752 return FALSE; /* because we set the focus */
753
754 case WM_COMMAND:
755 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
756
757 switch (LOWORD(wParam)) {
758 case IDOK:
759 return end_TIS_dlg(pvar, dlg);
760
761 case IDCANCEL: /* kill the connection */
762 pvar->auth_state.auth_dialog = NULL;
763 notify_closed_connection(pvar);
764 EndDialog(dlg, 0);
765 return TRUE;
766
767 default:
768 return FALSE;
769 }
770
771 default:
772 return FALSE;
773 }
774 }
775
776 void AUTH_do_cred_dialog(PTInstVar pvar)
777 {
778 if (pvar->auth_state.auth_dialog == NULL) {
779 HWND cur_active = GetActiveWindow();
780 DLGPROC dlg_proc;
781 LPCTSTR dialog_template;
782
783 switch (pvar->auth_state.mode) {
784 case TIS_AUTH_MODE:
785 dialog_template = MAKEINTRESOURCE(IDD_SSHTISAUTH);
786 dlg_proc = TIS_dlg_proc;
787 break;
788 case GENERIC_AUTH_MODE:
789 default:
790 dialog_template = MAKEINTRESOURCE(IDD_SSHAUTH);
791 dlg_proc = auth_dlg_proc;
792 }
793
794 if (!DialogBoxParam(hInst, dialog_template,
795 cur_active !=
796 NULL ? cur_active : pvar->NotificationWindow,
797 dlg_proc, (LPARAM) pvar) == -1) {
798 notify_fatal_error(pvar,
799 "Unable to display authentication dialog box.\n"
800 "Connection terminated.");
801 }
802 }
803 }
804
805 static void init_default_auth_dlg(PTInstVar pvar, HWND dlg)
806 {
807 switch (pvar->settings.DefaultAuthMethod) {
808 case SSH_AUTH_RSA:
809 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL,
810 IDC_SSHUSERSA);
811 break;
812 case SSH_AUTH_RHOSTS:
813 case SSH_AUTH_RHOSTS_RSA:
814 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL,
815 IDC_SSHUSERHOSTS);
816 break;
817 case SSH_AUTH_TIS:
818 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL,
819 IDC_SSHUSETIS);
820 break;
821 case SSH_AUTH_PASSWORD:
822 default:
823 CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL,
824 IDC_SSHUSEPASSWORD);
825 }
826
827 SetDlgItemText(dlg, IDC_SSHUSERNAME, pvar->settings.DefaultUserName);
828 SetDlgItemText(dlg, IDC_RSAFILENAME,
829 pvar->settings.DefaultRSAPrivateKeyFile);
830 SetDlgItemText(dlg, IDC_HOSTRSAFILENAME,
831 pvar->settings.DefaultRhostsHostPrivateKeyFile);
832 SetDlgItemText(dlg, IDC_LOCALUSERNAME,
833 pvar->settings.DefaultRhostsLocalUserName);
834
835 // SSH2 keyboard-interactive method (2005.2.22 yutaka)
836 if (pvar->settings.ssh2_keyboard_interactive) {
837 SendMessage(GetDlgItem(dlg, IDC_KEYBOARD_INTERACTIVE_CHECK), BM_SETCHECK, BST_CHECKED, 0);
838 }
839
840 }
841
842 static BOOL end_default_auth_dlg(PTInstVar pvar, HWND dlg)
843 {
844 if (IsDlgButtonChecked(dlg, IDC_SSHUSERSA)) {
845 pvar->settings.DefaultAuthMethod = SSH_AUTH_RSA;
846 } else if (IsDlgButtonChecked(dlg, IDC_SSHUSERHOSTS)) {
847 if (GetWindowTextLength(GetDlgItem(dlg, IDC_HOSTRSAFILENAME)) > 0) {
848 pvar->settings.DefaultAuthMethod = SSH_AUTH_RHOSTS_RSA;
849 } else {
850 pvar->settings.DefaultAuthMethod = SSH_AUTH_RHOSTS;
851 }
852 } else if (IsDlgButtonChecked(dlg, IDC_SSHUSETIS)) {
853 pvar->settings.DefaultAuthMethod = SSH_AUTH_TIS;
854 } else {
855 pvar->settings.DefaultAuthMethod = SSH_AUTH_PASSWORD;
856 }
857
858 GetDlgItemText(dlg, IDC_SSHUSERNAME, pvar->settings.DefaultUserName,
859 sizeof(pvar->settings.DefaultUserName));
860 GetDlgItemText(dlg, IDC_RSAFILENAME,
861 pvar->settings.DefaultRSAPrivateKeyFile,
862 sizeof(pvar->settings.DefaultRSAPrivateKeyFile));
863 GetDlgItemText(dlg, IDC_HOSTRSAFILENAME,
864 pvar->settings.DefaultRhostsHostPrivateKeyFile,
865 sizeof(pvar->settings.DefaultRhostsHostPrivateKeyFile));
866 GetDlgItemText(dlg, IDC_LOCALUSERNAME,
867 pvar->settings.DefaultRhostsLocalUserName,
868 sizeof(pvar->settings.DefaultRhostsLocalUserName));
869
870 // SSH2 keyboard-interactive method (2005.2.22 yutaka)
871 {
872 LRESULT ret;
873 ret = SendMessage(GetDlgItem(dlg, IDC_KEYBOARD_INTERACTIVE_CHECK), BM_GETCHECK, 0, 0);
874 if (ret & BST_CHECKED) {
875 pvar->settings.ssh2_keyboard_interactive = 1;
876 } else {
877 pvar->settings.ssh2_keyboard_interactive = 0;
878 }
879 }
880
881 EndDialog(dlg, 1);
882 return TRUE;
883 }
884
885 static BOOL CALLBACK default_auth_dlg_proc(HWND dlg, UINT msg,
886 WPARAM wParam, LPARAM lParam)
887 {
888 PTInstVar pvar;
889
890 switch (msg) {
891 case WM_INITDIALOG:
892 pvar = (PTInstVar) lParam;
893 SetWindowLong(dlg, DWL_USER, lParam);
894
895 init_default_auth_dlg(pvar, dlg);
896 return TRUE; /* because we do not set the focus */
897
898 case WM_COMMAND:
899 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
900
901 switch (LOWORD(wParam)) {
902 case IDOK:
903 return end_default_auth_dlg(pvar, dlg);
904
905 case IDCANCEL:
906 EndDialog(dlg, 0);
907 return TRUE;
908
909 case IDC_CHOOSERSAFILE:
910 choose_RSA_key_file(dlg);
911 return TRUE;
912
913 case IDC_CHOOSEHOSTRSAFILE:
914 choose_host_RSA_key_file(dlg);
915 return TRUE;
916
917 default:
918 return FALSE;
919 }
920
921 default:
922 return FALSE;
923 }
924 }
925
926 void AUTH_init(PTInstVar pvar)
927 {
928 pvar->auth_state.failed_method = SSH_AUTH_NONE;
929 pvar->auth_state.auth_dialog = NULL;
930 pvar->auth_state.user = NULL;
931 pvar->auth_state.flags = 0;
932 pvar->auth_state.TIS_prompt = NULL;
933 pvar->auth_state.supported_types = 0;
934 pvar->auth_state.cur_cred.method = SSH_AUTH_NONE;
935 pvar->auth_state.cur_cred.password = NULL;
936 pvar->auth_state.cur_cred.rhosts_client_user = NULL;
937 pvar->auth_state.cur_cred.key_pair = NULL;
938 pvar->auth_state.cur_cred.remeber_password = 1; // �p�X���[�h���o���� (2006.8.3 yutaka)
939 AUTH_set_generic_mode(pvar);
940 }
941
942 void AUTH_set_generic_mode(PTInstVar pvar)
943 {
944 pvar->auth_state.mode = GENERIC_AUTH_MODE;
945 destroy_malloced_string(&pvar->auth_state.TIS_prompt);
946 }
947
948 void AUTH_set_TIS_mode(PTInstVar pvar, char FAR * prompt, int len)
949 {
950 if (pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) {
951 pvar->auth_state.mode = TIS_AUTH_MODE;
952
953 destroy_malloced_string(&pvar->auth_state.TIS_prompt);
954 pvar->auth_state.TIS_prompt = malloc(len + 1);
955 memcpy(pvar->auth_state.TIS_prompt, prompt, len);
956 pvar->auth_state.TIS_prompt[len] = 0;
957 } else {
958 AUTH_set_generic_mode(pvar);
959 }
960 }
961
962 void AUTH_do_default_cred_dialog(PTInstVar pvar)
963 {
964 HWND cur_active = GetActiveWindow();
965
966 if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHAUTHSETUP),
967 cur_active !=
968 NULL ? cur_active : pvar->NotificationWindow,
969 default_auth_dlg_proc, (LPARAM) pvar) == -1) {
970 notify_nonfatal_error(pvar,
971 "Unable to display authentication setup dialog box.");
972 }
973 }
974
975 void AUTH_destroy_cur_cred(PTInstVar pvar)
976 {
977 destroy_malloced_string(&pvar->auth_state.cur_cred.password);
978 destroy_malloced_string(&pvar->auth_state.cur_cred.rhosts_client_user);
979 if (pvar->auth_state.cur_cred.key_pair != NULL) {
980 CRYPT_free_key_pair(pvar->auth_state.cur_cred.key_pair);
981 pvar->auth_state.cur_cred.key_pair = NULL;
982 }
983 }
984
985 static char FAR *get_auth_method_name(SSHAuthMethod auth)
986 {
987 switch (auth) {
988 case SSH_AUTH_PASSWORD:
989 return "password";
990 case SSH_AUTH_RSA:
991 return "RSA";
992 case SSH_AUTH_RHOSTS:
993 return "rhosts";
994 case SSH_AUTH_RHOSTS_RSA:
995 return "rhosts with RSA";
996 case SSH_AUTH_TIS:
997 return "challenge/response (TIS)";
998 default:
999 return "unknown method";
1000 }
1001 }
1002
1003 void AUTH_get_auth_info(PTInstVar pvar, char FAR * dest, int len)
1004 {
1005 char *method = "unknown";
1006
1007 if (pvar->auth_state.user == NULL) {
1008 strncpy(dest, "None", len);
1009 } else if (pvar->auth_state.cur_cred.method != SSH_AUTH_NONE) {
1010 if (SSHv1(pvar)) {
1011 _snprintf(dest, len, "User '%s', using %s", pvar->auth_state.user,
1012 get_auth_method_name(pvar->auth_state.cur_cred.method));
1013
1014 } else {
1015 // SSH2:�F�����\�b�h������ (2004.12.23 yutaka)
1016 // keyboard-interactive���\�b�h������ (2005.3.12 yutaka)
1017 if (pvar->auth_state.cur_cred.method == SSH_AUTH_PASSWORD ||
1018 pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) {
1019 // keyboard-interactive���\�b�h������ (2005.1.24 yutaka)
1020 if (pvar->keyboard_interactive_done == 1 ||
1021 pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) {
1022 method = "keyboard-interactive";
1023 } else {
1024 method = get_auth_method_name(pvar->auth_state.cur_cred.method);
1025 }
1026 _snprintf(dest, len, "User '%s', using %s", pvar->auth_state.user, method);
1027
1028 } else {
1029 if (pvar->auth_state.cur_cred.key_pair->RSA_key != NULL) {
1030 method = "RSA";
1031 } else if (pvar->auth_state.cur_cred.key_pair->DSA_key != NULL) {
1032 method = "DSA";
1033 }
1034 _snprintf(dest, len, "User '%s', using %s", pvar->auth_state.user, method);
1035 }
1036
1037 }
1038
1039 } else {
1040 _snprintf(dest, len, "User '%s', using %s", pvar->auth_state.user,
1041 get_auth_method_name(pvar->auth_state.failed_method));
1042 }
1043
1044 dest[len - 1] = 0;
1045 }
1046
1047 void AUTH_notify_disconnecting(PTInstVar pvar)
1048 {
1049 if (pvar->auth_state.auth_dialog != NULL) {
1050 PostMessage(pvar->auth_state.auth_dialog, WM_COMMAND, IDCANCEL, 0);
1051 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
1052 EnableWindow(pvar->NotificationWindow, TRUE);
1053 }
1054 }
1055
1056 void AUTH_end(PTInstVar pvar)
1057 {
1058 destroy_malloced_string(&pvar->auth_state.user);
1059 destroy_malloced_string(&pvar->auth_state.TIS_prompt);
1060
1061 AUTH_destroy_cur_cred(pvar);
1062 }
1063
1064 /*
1065 * $Log: not supported by cvs2svn $
1066 * Revision 1.17 2005/09/05 10:46:22 yutakakn
1067 * '/I' �w�����������������F���_�C�A���O�����������������������B
1068 *
1069 * Revision 1.16 2005/08/26 16:26:02 yutakakn
1070 * �������O�C������SSH�F���_�C�A���O�����������������������B
1071 *
1072 * Revision 1.15 2005/07/15 14:58:04 yutakakn
1073 * SSH1���������x���[�U�F�������s�������A�������F�����������������o�O���C���B
1074 *
1075 * Revision 1.14 2005/04/26 13:57:57 yutakakn
1076 * private key�t�@�C���_�C�A���O��3�t�@�C���t�B���^�����������B
1077 *
1078 * Revision 1.13 2005/04/08 14:55:03 yutakakn
1079 * "Duplicate session"��������SSH�������O�C�����s�������������B
1080 *
1081 * Revision 1.12 2005/03/23 12:39:35 yutakakn
1082 * SSH2�F���_�C�A���O�� Use challenge/response to log in ���A�N�Z�����[�^�L�[�������������B
1083 *
1084 * Revision 1.11 2005/03/12 15:07:33 yutakakn
1085 * SSH2 keyboard-interactive�F����TIS�_�C�A���O�����������B
1086 *
1087 * Revision 1.10 2005/03/12 12:08:05 yutakakn
1088 * �p�X���[�h�F�����O���s��keyboard-interactive���\�b�h���A�f�t�H���g�����l������(0)�������B
1089 * �����A�F���_�C�A���O�����x�������������L�����������X���������������B
1090 *
1091 * Revision 1.9 2005/02/22 08:48:11 yutakakn
1092 * TTSSH setup�_�C�A���O�� HeartBeat �����������B
1093 * TTSSH authentication setup�_�C�A���O�� keyboard-interactive �����������B
1094 *
1095 * Revision 1.8 2005/01/27 13:30:33 yutakakn
1096 * ���J���F���������O�C�����T�|�[�g�B
1097 * /auth=publickey, /keyfile �I�v�V�������V�K���������B
1098 * �����A�����������������T�|�[�g�B
1099 *
1100 * Revision 1.7 2005/01/25 13:38:22 yutakakn
1101 * SSH�F���_�C�A���O���ARhosts/TIS���O���[�������O���AEnter�L�[�������������A
1102 * �A�v���P�[�V�����G���[���������������������B
1103 *
1104 * Revision 1.6 2005/01/24 14:07:07 yutakakn
1105 * �Ekeyboard-interactive�F�����T�|�[�g�����B
1106 * �@�����������Ateraterm.ini�� "KeyboardInteractive" �G���g�������������B
1107 * �E�o�[�W�����_�C�A���O�� OpenSSL�o�[�W���� ������
1108 *
1109 * Revision 1.5 2004/12/27 14:35:41 yutakakn
1110 * SSH2�����������������s�����G���[���b�Z�[�W�����������B
1111 *
1112 * Revision 1.4 2004/12/22 17:28:14 yutakakn
1113 * SSH2���J���F��(RSA/DSA)���T�|�[�g�����B
1114 *
1115 * Revision 1.3 2004/12/16 13:01:09 yutakakn
1116 * SSH�������O�C�����A�v���P�[�V�����G���[�������������C�������B
1117 *
1118 * Revision 1.2 2004/12/01 15:37:49 yutakakn
1119 * SSH2�������O�C���@�\�������B
1120 * �����A�p�X���[�h�F�������������B
1121 * �E�R�}���h���C��
1122 * /ssh /auth=�F�����\�b�h /user=���[�U�� /passwd=�p�X���[�h
1123 *
1124 */

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