Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7605 - (show annotations) (download) (as text)
Mon Apr 22 16:18:08 2019 UTC (4 years, 11 months ago) by zmatsuo
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 185380 byte(s)
ttssh の passphrase edit control の tooltip を i18n化
auth dialog,Key generator dialogで使用
1 /*
2 * Copyright (c) 1998-2001, Robert O'Callahan
3 * (C) 2004-2019 TeraTerm Project
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /* Tera Term extension mechanism
31 Robert O'Callahan (roc+tt@cs.cmu.edu)
32
33 Tera Term by Takashi Teranishi (teranishi@rikaxp.riken.go.jp)
34 */
35
36 #include "teraterm_conf.h"
37 #include "ttxssh.h"
38 #include "fwdui.h"
39 #include "util.h"
40 #include "ssh.h"
41 #include "ttcommon.h"
42 #include "ttlib.h"
43 #include "keyfiles.h"
44 #include "arc4random.h"
45 #include "auth.h"
46
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <string.h>
50 #include <io.h>
51 #include <fcntl.h>
52 #include <sys/stat.h>
53 #include <time.h>
54 #include <mbstring.h>
55
56 #include "resource.h"
57 #include <commctrl.h>
58 #include <commdlg.h>
59 #include <winsock2.h>
60 static char *ProtocolFamilyList[] = { "UNSPEC", "IPv6", "IPv4", NULL };
61
62 #include <lmcons.h>
63
64 // include OpenSSL header file
65 #include <openssl/evp.h>
66 #include <openssl/rsa.h>
67 #include <openssl/dsa.h>
68 #include <openssl/bn.h>
69 #include <openssl/pem.h>
70 #include <openssl/rand.h>
71 #include <openssl/rc4.h>
72 #include <openssl/md5.h>
73
74 // include ZLib header file
75 #include <zlib.h>
76
77 #include "buffer.h"
78 #include "cipher.h"
79 #include "key.h"
80 #include "dlglib.h"
81
82 #include "sftp.h"
83
84 #include "compat_w95.h"
85 #include "compat_win.h"
86
87 #include "libputty.h"
88
89 #undef DialogBoxParam
90 #define DialogBoxParam(p1,p2,p3,p4,p5) \
91 TTDialogBoxParam(p1,p2,p3,p4,p5)
92 #undef EndDialog
93 #define EndDialog(p1,p2) \
94 TTEndDialog(p1, p2)
95
96 #define MATCH_STR(s, o) strncmp((s), (o), NUM_ELEM(o) - 1)
97 #define MATCH_STR_I(s, o) _strnicmp((s), (o), NUM_ELEM(o) - 1)
98
99 /* This extension implements SSH, so we choose a load order in the
100 "protocols" range. */
101 #define ORDER 2500
102
103 static HICON SecureLargeIcon = NULL;
104 static HICON SecureSmallIcon = NULL;
105 static HICON SecureNotifyIcon = NULL;
106 static HICON OldNotifyIcon = NULL;
107
108 //static HFONT DlgHostFont;
109 //static HFONT DlgAboutFont;
110 static HFONT DlgAboutTextFont;
111 //static HFONT DlgSetupFont;
112 //static HFONT DlgKeygenFont;
113
114 static TInstVar *pvar;
115
116 typedef struct {
117 int cnt;
118 HWND dlg;
119 ssh_keytype type;
120 } cbarg_t;
121
122 /* WIN32 allows multiple instances of a DLL */
123 static TInstVar InstVar;
124
125 /*
126 This code makes lots of assumptions about the order in which Tera Term
127 does things, and how. A key assumption is that the Notification window
128 passed into WSAAsyncSelect is the main terminal window. We also assume
129 that the socket used in the first WSAconnect is the main session socket.
130 */
131
132 static void init_TTSSH(PTInstVar pvar)
133 {
134 pvar->socket = INVALID_SOCKET;
135 pvar->OldLargeIcon = NULL;
136 pvar->OldSmallIcon = NULL;
137 pvar->NotificationWindow = NULL;
138 pvar->hostdlg_activated = FALSE;
139 pvar->socket = INVALID_SOCKET;
140 pvar->NotificationWindow = NULL;
141 pvar->protocol_major = 0;
142 pvar->protocol_minor = 0;
143
144 PKT_init(pvar);
145 SSH_init(pvar);
146 CRYPT_init(pvar);
147 AUTH_init(pvar);
148 HOSTS_init(pvar);
149 FWD_init(pvar);
150 FWDUI_init(pvar);
151
152 ssh_heartbeat_lock_initialize();
153 }
154
155 static void uninit_TTSSH(PTInstVar pvar)
156 {
157 halt_ssh_heartbeat_thread(pvar);
158
159 ssh2_channel_free();
160
161 SSH_end(pvar);
162 PKT_end(pvar);
163 AUTH_end(pvar);
164 CRYPT_end(pvar);
165 HOSTS_end(pvar);
166 FWD_end(pvar);
167 FWDUI_end(pvar);
168
169 if (pvar->OldLargeIcon != NULL) {
170 PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_BIG,
171 (LPARAM) pvar->OldLargeIcon);
172 pvar->OldLargeIcon = NULL;
173 }
174 if (pvar->OldSmallIcon != NULL) {
175 PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_SMALL,
176 (LPARAM) pvar->OldSmallIcon);
177 pvar->OldSmallIcon = NULL;
178 }
179 if (OldNotifyIcon) {
180 SetCustomNotifyIcon(OldNotifyIcon);
181 }
182
183 ssh_heartbeat_lock_finalize();
184 }
185
186 static void PASCAL TTXInit(PTTSet ts, PComVar cv)
187 {
188 pvar->settings = *pvar->ts_SSH;
189 pvar->ts = ts;
190 pvar->cv = cv;
191 pvar->fatal_error = FALSE;
192 pvar->showing_err = FALSE;
193 pvar->err_msg = NULL;
194
195 init_TTSSH(pvar);
196 }
197
198 static void normalize_generic_order(char *buf, char default_strings[], int default_strings_len)
199 {
200 char listed[max(KEX_DH_MAX,max(SSH_CIPHER_MAX,max(KEY_MAX,max(HMAC_MAX,COMP_MAX)))) + 1];
201 char allowed[max(KEX_DH_MAX,max(SSH_CIPHER_MAX,max(KEY_MAX,max(HMAC_MAX,COMP_MAX)))) + 1];
202 int i, j, k=-1;
203
204 memset(listed, 0, sizeof(listed));
205 memset(allowed, 0, sizeof(allowed));
206
207 // �����������������������X�g�������B
208 for (i = 0; i < default_strings_len ; i++) {
209 allowed[default_strings[i]] = 1;
210 }
211
212 // �w�����������������������A���������������������A�d���������������������B
213 //
214 // ex. (i=5 ����������������)
215 // i=012345
216 // >:=9<87;A@?B3026(\0)
217 // i+1
218 // <------------>
219 // ��
220 // >:=9<7;A@?B3026(\0)
221 //
222 for (i = 0; buf[i] != 0; i++) {
223 int num = buf[i] - '0';
224
225 if (num < 0 || num > default_strings_len
226 || !allowed[num]
227 || listed[num]) {
228 memmove(buf + i, buf + i + 1, strlen(buf + i + 1) + 1);
229 i--;
230 } else {
231 listed[num] = 1;
232 }
233
234 // disabled line���������A���u���o���������B
235 if (num == 0) {
236 k = i;
237 }
238 }
239
240 // �w���������������������������Adisabled line�����O���}�������B
241 //
242 // ex. (Z���}������)
243 // k
244 // >:=9<87;A@?B3026(\0)
245 // k+1
246 // <---->
247 // �� k
248 // >:=9<87;A@?B30026(\0)
249 // �� k
250 // >:=9<87;A@?B3Z026(\0)
251 //
252 for (j = 0; j < default_strings_len && default_strings[j] != 0; j++) {
253 int num = default_strings[j];
254
255 if (!listed[num] && k >= 0) {
256 int copylen = strlen(buf + k + 1) + 1;
257
258 memmove(buf + k + 1, buf + k, copylen);
259 buf[k + 1 + copylen] = '\0'; // �I�[���Y�������t�����B
260 buf[k] = num + '0';
261 k++;
262 i++;
263 }
264 }
265 if (k < 0) {
266 j = 0;
267 }
268 else {
269 j++;
270 }
271
272 // disabled line�������������������A�����������������������B
273 for (; j < default_strings_len ; j++) {
274 int num = default_strings[j];
275
276 if (!listed[num]) {
277 buf[i] = num + '0';
278 listed[num] = 1;
279 i++;
280 }
281 }
282
283 buf[i] = 0;
284 }
285
286 /*
287 * Remove unsupported cipher or duplicated cipher.
288 * Add unspecified ciphers at the end of list.
289 */
290 static void normalize_cipher_order(char *buf)
291 {
292 /* SSH_CIPHER_NONE means that all ciphers below that one are disabled.
293 We *never* allow no encryption. */
294 static char default_strings[] = {
295 SSH2_CIPHER_AES256_GCM,
296 SSH2_CIPHER_CAMELLIA256_CTR,
297 SSH2_CIPHER_AES256_CTR,
298 SSH2_CIPHER_CAMELLIA256_CBC,
299 SSH2_CIPHER_AES256_CBC,
300 SSH2_CIPHER_CAMELLIA192_CTR,
301 SSH2_CIPHER_AES192_CTR,
302 SSH2_CIPHER_CAMELLIA192_CBC,
303 SSH2_CIPHER_AES192_CBC,
304 SSH2_CIPHER_AES128_GCM,
305 SSH2_CIPHER_CAMELLIA128_CTR,
306 SSH2_CIPHER_AES128_CTR,
307 SSH2_CIPHER_CAMELLIA128_CBC,
308 SSH2_CIPHER_AES128_CBC,
309 SSH2_CIPHER_3DES_CTR,
310 SSH2_CIPHER_3DES_CBC,
311 SSH2_CIPHER_BLOWFISH_CTR,
312 SSH2_CIPHER_BLOWFISH_CBC,
313 SSH2_CIPHER_CAST128_CTR,
314 SSH2_CIPHER_CAST128_CBC,
315 SSH_CIPHER_3DES,
316 SSH_CIPHER_NONE,
317 SSH2_CIPHER_ARCFOUR256,
318 SSH2_CIPHER_ARCFOUR128,
319 SSH2_CIPHER_ARCFOUR,
320 SSH_CIPHER_BLOWFISH,
321 SSH_CIPHER_DES,
322 0, 0, 0 // Dummy for SSH_CIPHER_IDEA, SSH_CIPHER_TSS, SSH_CIPHER_RC4
323 };
324
325 normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
326 }
327
328 static void normalize_kex_order(char *buf)
329 {
330 static char default_strings[] = {
331 KEX_ECDH_SHA2_256,
332 KEX_ECDH_SHA2_384,
333 KEX_ECDH_SHA2_521,
334 KEX_DH_GRP18_SHA512,
335 KEX_DH_GRP16_SHA512,
336 KEX_DH_GRP14_SHA256,
337 KEX_DH_GEX_SHA256,
338 KEX_DH_GEX_SHA1,
339 KEX_DH_GRP14_SHA1,
340 KEX_DH_GRP1_SHA1,
341 KEX_DH_NONE,
342 };
343
344 normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
345 }
346
347 static void normalize_host_key_order(char *buf)
348 {
349 static char default_strings[] = {
350 KEY_ECDSA256,
351 KEY_ECDSA384,
352 KEY_ECDSA521,
353 KEY_ED25519,
354 KEY_RSA,
355 KEY_DSA,
356 KEY_NONE,
357 };
358
359 normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
360 }
361
362 static void normalize_mac_order(char *buf)
363 {
364 static char default_strings[] = {
365 HMAC_SHA2_512_EtM,
366 HMAC_SHA2_256_EtM,
367 HMAC_SHA1_EtM,
368 HMAC_SHA2_512,
369 HMAC_SHA2_256,
370 HMAC_SHA1,
371 HMAC_RIPEMD160_EtM,
372 HMAC_RIPEMD160,
373 HMAC_MD5_EtM,
374 HMAC_MD5,
375 HMAC_NONE,
376 HMAC_SHA1_96_EtM,
377 HMAC_MD5_96_EtM,
378 HMAC_SHA1_96,
379 HMAC_MD5_96,
380 0, // Dummy for HMAC_SHA2_512_96,
381 0, // Dummy for HMAC_SHA2_256_96,
382 };
383
384 normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
385 }
386
387 static void normalize_comp_order(char *buf)
388 {
389 static char default_strings[] = {
390 COMP_DELAYED,
391 COMP_ZLIB,
392 COMP_NOCOMP,
393 COMP_NONE,
394 };
395
396 normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
397 }
398
399
400 /* Remove local settings from the shared memory block. */
401 static void clear_local_settings(PTInstVar pvar)
402 {
403 pvar->ts_SSH->TryDefaultAuth = FALSE;
404 }
405
406 static BOOL read_BOOL_option(PCHAR fileName, char *keyName, BOOL def)
407 {
408 char buf[1024];
409
410 buf[0] = 0;
411 GetPrivateProfileString("TTSSH", keyName, "", buf, sizeof(buf),
412 fileName);
413 if (buf[0] == 0) {
414 return def;
415 } else {
416 return atoi(buf) != 0 ||
417 _stricmp(buf, "yes") == 0 ||
418 _stricmp(buf, "y") == 0;
419 }
420 }
421
422 static void read_string_option(PCHAR fileName, char *keyName,
423 char *def, char *buf, int bufSize)
424 {
425
426 buf[0] = 0;
427 GetPrivateProfileString("TTSSH", keyName, def, buf, bufSize, fileName);
428 }
429
430 static void read_ssh_options(PTInstVar pvar, PCHAR fileName)
431 {
432 char buf[1024];
433 TS_SSH *settings = pvar->ts_SSH;
434
435 #define READ_STD_STRING_OPTION(name) \
436 read_string_option(fileName, #name, "", settings->name, sizeof(settings->name))
437
438 settings->Enabled = read_BOOL_option(fileName, "Enabled", FALSE);
439
440 buf[0] = 0;
441 GetPrivateProfileString("TTSSH", "Compression", "", buf, sizeof(buf),
442 fileName);
443 settings->CompressionLevel = atoi(buf);
444 if (settings->CompressionLevel < 0 || settings->CompressionLevel > 9) {
445 settings->CompressionLevel = 0;
446 }
447
448 READ_STD_STRING_OPTION(DefaultUserName);
449 READ_STD_STRING_OPTION(DefaultForwarding);
450 READ_STD_STRING_OPTION(DefaultRhostsLocalUserName);
451 READ_STD_STRING_OPTION(DefaultRhostsHostPrivateKeyFile);
452 READ_STD_STRING_OPTION(DefaultRSAPrivateKeyFile);
453
454 READ_STD_STRING_OPTION(CipherOrder);
455 normalize_cipher_order(settings->CipherOrder);
456
457 // KEX order
458 READ_STD_STRING_OPTION(KexOrder);
459 normalize_kex_order(settings->KexOrder);
460 // Host Key algorithm order
461 READ_STD_STRING_OPTION(HostKeyOrder);
462 normalize_host_key_order(settings->HostKeyOrder);
463 // HMAC order
464 READ_STD_STRING_OPTION(MacOrder);
465 normalize_mac_order(settings->MacOrder);
466 // Compression algorithm order
467 READ_STD_STRING_OPTION(CompOrder);
468 normalize_comp_order(settings->CompOrder);
469
470 read_string_option(fileName, "KnownHostsFiles", "ssh_known_hosts",
471 settings->KnownHostsFiles,
472 sizeof(settings->KnownHostsFiles));
473
474 buf[0] = 0;
475 GetPrivateProfileString("TTSSH", "DefaultAuthMethod", "", buf,
476 sizeof(buf), fileName);
477 settings->DefaultAuthMethod = atoi(buf);
478 if (settings->DefaultAuthMethod != SSH_AUTH_PASSWORD
479 && settings->DefaultAuthMethod != SSH_AUTH_RSA
480 && settings->DefaultAuthMethod != SSH_AUTH_TIS // add (2005.3.12 yutaka)
481 && settings->DefaultAuthMethod != SSH_AUTH_RHOSTS
482 && settings->DefaultAuthMethod != SSH_AUTH_PAGEANT) {
483 /* this default can never be SSH_AUTH_RHOSTS_RSA because that is not a
484 selection in the dialog box; SSH_AUTH_RHOSTS_RSA is automatically chosen
485 when the dialog box has rhosts selected and an host private key file
486 is supplied. */
487 settings->DefaultAuthMethod = SSH_AUTH_PASSWORD;
488 }
489
490 buf[0] = 0;
491 GetPrivateProfileString("TTSSH", "LogLevel", "", buf, sizeof(buf),
492 fileName);
493 settings->LogLevel = atoi(buf);
494
495 buf[0] = 0;
496 GetPrivateProfileString("TTSSH", "WriteBufferSize", "", buf,
497 sizeof(buf), fileName);
498 settings->WriteBufferSize = atoi(buf);
499 if (settings->WriteBufferSize <= 0) {
500 settings->WriteBufferSize = (PACKET_MAX_SIZE / 2); // 2MB
501 }
502
503 // SSH protocol version (2004.10.11 yutaka)
504 // default is SSH2 (2004.11.30 yutaka)
505 settings->ssh_protocol_version = GetPrivateProfileInt("TTSSH", "ProtocolVersion", 2, fileName);
506
507 // SSH heartbeat time(second) (2004.12.11 yutaka)
508 settings->ssh_heartbeat_overtime = GetPrivateProfileInt("TTSSH", "HeartBeat", 60, fileName);
509
510 // �p�X���[�h�F�����������J���F�����g���p�X���[�h����������������������������������
511 // �\���B(2006.8.5 yutaka)
512 settings->remember_password = GetPrivateProfileInt("TTSSH", "RememberPassword", 1, fileName);
513
514 // �������F���_�C�A���O���T�|�[�g�������������\�b�h���`�F�b�N���A
515 // ���������\�b�h���O���C�A�E�g���� (2007.9.24 maya)
516 settings->CheckAuthListFirst = read_BOOL_option(fileName, "CheckAuthListFirst", FALSE);
517
518 // 768bit ������ RSA ���������T�[�o�����������L�������� (2008.9.11 maya)
519 settings->EnableRsaShortKeyServer = read_BOOL_option(fileName, "EnableRsaShortKeyServer", FALSE);
520
521 // agent forward ���L�������� (2008.11.25 maya)
522 settings->ForwardAgent = read_BOOL_option(fileName, "ForwardAgent", FALSE);
523
524 // agent forward �m�F���L��������
525 settings->ForwardAgentConfirm = read_BOOL_option(fileName, "ForwardAgentConfirm", TRUE);
526
527 // agent forward �m�F���L��������
528 settings->ForwardAgentNotify = read_BOOL_option(fileName, "ForwardAgentNotify", TRUE);
529
530 // �z�X�g���� DNS �����`�F�b�N (RFC 4255)
531 settings->VerifyHostKeyDNS = read_BOOL_option(fileName, "VerifyHostKeyDNS", TRUE);
532
533 // icon
534 GetPrivateProfileString("TTSSH", "SSHIcon", "", buf, sizeof(buf), fileName);
535 if ((_stricmp(buf, "old") == 0) ||
536 (_stricmp(buf, "yellow") == 0) ||
537 (_stricmp(buf, "securett_yellow") == 0)) {
538 settings->IconID = IDI_SECURETT_YELLOW;
539 }
540 else if ((_stricmp(buf, "green") == 0) ||
541 (_stricmp(buf, "securett_green") == 0)) {
542 settings->IconID = IDI_SECURETT_GREEN;
543 }
544 else {
545 settings->IconID = IDI_SECURETT;
546 }
547
548 // �G���[�������x�������|�b�v�A�b�v���b�Z�[�W���}�~���� (2014.6.26 yutaka)
549 settings->DisablePopupMessage = GetPrivateProfileInt("TTSSH", "DisablePopupMessage", 0, fileName);
550
551 READ_STD_STRING_OPTION(X11Display);
552
553 settings->UpdateHostkeys = GetPrivateProfileInt("TTSSH", "UpdateHostkeys", 0, fileName);
554
555 settings->GexMinimalGroupSize = GetPrivateProfileInt("TTSSH", "GexMinimalGroupSize", 0, fileName);
556
557 settings->AuthBanner = GetPrivateProfileInt("TTSSH", "AuthBanner", 1, fileName);
558
559 clear_local_settings(pvar);
560 }
561
562 static void write_ssh_options(PTInstVar pvar, PCHAR fileName,
563 TS_SSH *settings, BOOL copy_forward)
564 {
565 char buf[1024];
566
567 WritePrivateProfileString("TTSSH", "Enabled",
568 settings->Enabled ? "1" : "0", fileName);
569
570 _itoa(settings->CompressionLevel, buf, 10);
571 WritePrivateProfileString("TTSSH", "Compression", buf, fileName);
572
573 WritePrivateProfileString("TTSSH", "DefaultUserName",
574 settings->DefaultUserName, fileName);
575
576 if (copy_forward) {
577 WritePrivateProfileString("TTSSH", "DefaultForwarding",
578 settings->DefaultForwarding, fileName);
579 }
580
581 WritePrivateProfileString("TTSSH", "CipherOrder",
582 settings->CipherOrder, fileName);
583
584 WritePrivateProfileString("TTSSH", "KexOrder",
585 settings->KexOrder, fileName);
586
587 WritePrivateProfileString("TTSSH", "HostKeyOrder",
588 settings->HostKeyOrder, fileName);
589
590 WritePrivateProfileString("TTSSH", "MacOrder",
591 settings->MacOrder, fileName);
592
593 WritePrivateProfileString("TTSSH", "CompOrder",
594 settings->CompOrder, fileName);
595
596 WritePrivateProfileString("TTSSH", "KnownHostsFiles",
597 settings->KnownHostsFiles, fileName);
598
599 WritePrivateProfileString("TTSSH", "DefaultRhostsLocalUserName",
600 settings->DefaultRhostsLocalUserName,
601 fileName);
602
603 WritePrivateProfileString("TTSSH", "DefaultRhostsHostPrivateKeyFile",
604 settings->DefaultRhostsHostPrivateKeyFile,
605 fileName);
606
607 WritePrivateProfileString("TTSSH", "DefaultRSAPrivateKeyFile",
608 settings->DefaultRSAPrivateKeyFile,
609 fileName);
610
611 _itoa(settings->DefaultAuthMethod, buf, 10);
612 WritePrivateProfileString("TTSSH", "DefaultAuthMethod", buf, fileName);
613
614 _itoa(settings->LogLevel, buf, 10);
615 WritePrivateProfileString("TTSSH", "LogLevel", buf, fileName);
616
617 _itoa(settings->WriteBufferSize, buf, 10);
618 WritePrivateProfileString("TTSSH", "WriteBufferSize", buf, fileName);
619
620 // SSH protocol version (2004.10.11 yutaka)
621 WritePrivateProfileString("TTSSH", "ProtocolVersion",
622 settings->ssh_protocol_version==2 ? "2" : "1",
623 fileName);
624
625 // SSH heartbeat time(second) (2004.12.11 yutaka)
626 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
627 "%d", settings->ssh_heartbeat_overtime);
628 WritePrivateProfileString("TTSSH", "HeartBeat", buf, fileName);
629
630 // Remember password (2006.8.5 yutaka)
631 WritePrivateProfileString("TTSSH", "RememberPassword",
632 settings->remember_password ? "1" : "0",
633 fileName);
634
635 // �������F���_�C�A���O���T�|�[�g�������������\�b�h���`�F�b�N���A
636 // ���������\�b�h���O���C�A�E�g���� (2007.9.24 maya)
637 WritePrivateProfileString("TTSSH", "CheckAuthListFirst",
638 settings->CheckAuthListFirst ? "1" : "0", fileName);
639
640 // 768bit ������ RSA ���������T�[�o�����������L�������� (2008.9.11 maya)
641 WritePrivateProfileString("TTSSH", "EnableRsaShortKeyServer",
642 settings->EnableRsaShortKeyServer ? "1" : "0", fileName);
643
644 // agent forward ���L�������� (2008.11.25 maya)
645 WritePrivateProfileString("TTSSH", "ForwardAgent",
646 settings->ForwardAgent ? "1" : "0", fileName);
647
648 // agent forward �m�F���L��������
649 WritePrivateProfileString("TTSSH", "ForwardAgentConfirm",
650 settings->ForwardAgentConfirm ? "1" : "0", fileName);
651
652 // agent forward ���m���L��������
653 WritePrivateProfileString("TTSSH", "ForwardAgentNotify",
654 settings->ForwardAgentNotify ? "1" : "0", fileName);
655
656 // �z�X�g���� DNS �����`�F�b�N (RFC 4255)
657 WritePrivateProfileString("TTSSH", "VerifyHostKeyDNS",
658 settings->VerifyHostKeyDNS ? "1" : "0", fileName);
659
660 // SSH �A�C�R��
661 if (settings->IconID==IDI_SECURETT_YELLOW) {
662 WritePrivateProfileString("TTSSH", "SSHIcon", "yellow", fileName);
663 }
664 else if (settings->IconID==IDI_SECURETT_GREEN) {
665 WritePrivateProfileString("TTSSH", "SSHIcon", "green", fileName);
666 }
667 else {
668 WritePrivateProfileString("TTSSH", "SSHIcon", "Default", fileName);
669 }
670
671 _itoa(settings->DisablePopupMessage, buf, 10);
672 WritePrivateProfileString("TTSSH", "DisablePopupMessage", buf, fileName);
673
674 WritePrivateProfileString("TTSSH", "X11Display", settings->X11Display, fileName);
675
676 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
677 "%d", settings->UpdateHostkeys);
678 WritePrivateProfileString("TTSSH", "UpdateHostkeys", buf, fileName);
679
680 _itoa_s(settings->GexMinimalGroupSize, buf, sizeof(buf), 10);
681 WritePrivateProfileString("TTSSH", "GexMinimalGroupSize", buf, fileName);
682
683 _itoa_s(settings->AuthBanner, buf, sizeof(buf), 10);
684 WritePrivateProfileString("TTSSH", "AuthBanner", buf, fileName);
685 }
686
687
688 /* find free port in all protocol family */
689 static unsigned short find_local_port(PTInstVar pvar)
690 {
691 int tries;
692 SOCKET connecter;
693 struct addrinfo hints;
694 struct addrinfo *res;
695 struct addrinfo *res0;
696 unsigned short port;
697 char pname[NI_MAXHOST];
698
699 if (pvar->session_settings.DefaultAuthMethod != SSH_AUTH_RHOSTS) {
700 return 0;
701 }
702
703 /* The random numbers here are only used to try to get fresh
704 ports across runs (dangling ports can cause bind errors
705 if we're unlucky). They do not need to be (and are not)
706 cryptographically strong.
707 */
708 srand((unsigned) GetTickCount());
709
710 for (tries = 20; tries > 0; tries--) {
711 memset(&hints, 0, sizeof(hints));
712 hints.ai_family = pvar->ts->ProtocolFamily;
713 hints.ai_flags = AI_PASSIVE;
714 hints.ai_socktype = SOCK_STREAM;
715 port = (unsigned) rand() % 512 + 512;
716 _snprintf_s(pname, sizeof(pname), _TRUNCATE, "%d", (int) port);
717 if (getaddrinfo(NULL, pname, &hints, &res0)) {
718 return 0;
719 /* NOT REACHED */
720 }
721
722 for (res = res0; res; res = res->ai_next) {
723 if (res->ai_family == AF_INET || res->ai_family == AF_INET6)
724 continue;
725
726 connecter =
727 socket(res->ai_family, res->ai_socktype, res->ai_protocol);
728 if (connecter == INVALID_SOCKET) {
729 freeaddrinfo(res0);
730 return 0;
731 }
732
733 if (bind(connecter, res->ai_addr, res->ai_addrlen) !=
734 SOCKET_ERROR) {
735 return port;
736 freeaddrinfo(res0);
737 closesocket(connecter);
738 } else if (WSAGetLastError() != WSAEADDRINUSE) {
739 closesocket(connecter);
740 freeaddrinfo(res0);
741 return 0;
742 }
743
744 closesocket(connecter);
745 }
746 freeaddrinfo(res0);
747 }
748
749 return 0;
750 }
751
752 static int PASCAL TTXconnect(SOCKET s,
753 const struct sockaddr *name,
754 int namelen)
755 {
756 if (pvar->socket == INVALID_SOCKET || pvar->socket != s) {
757 struct sockaddr_storage ss;
758 int len;
759
760 pvar->socket = s;
761
762 memset(&ss, 0, sizeof(ss));
763 switch (pvar->ts->ProtocolFamily) {
764 case AF_INET:
765 len = sizeof(struct sockaddr_in);
766 ((struct sockaddr_in *) &ss)->sin_family = AF_INET;
767 ((struct sockaddr_in *) &ss)->sin_addr.s_addr = INADDR_ANY;
768 ((struct sockaddr_in *) &ss)->sin_port =
769 htons(find_local_port(pvar));
770 break;
771 case AF_INET6:
772 len = sizeof(struct sockaddr_in6);
773 ((struct sockaddr_in6 *) &ss)->sin6_family = AF_INET6;
774 ((struct sockaddr_in6 *) &ss)->sin6_addr = in6addr_any;
775 ((struct sockaddr_in6 *) &ss)->sin6_port =
776 htons(find_local_port(pvar));
777 break;
778 default:
779 /* UNSPEC */
780 len = sizeof(ss);
781 ss.ss_family = AF_UNSPEC;
782 break;
783 }
784
785 bind(s, (struct sockaddr *) &ss, len);
786 }
787
788 return (pvar->Pconnect) (s, name, namelen);
789 }
790
791 static int PASCAL TTXWSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,
792 long lEvent)
793 {
794 if (s == pvar->socket) {
795 pvar->notification_events = lEvent;
796 pvar->notification_msg = wMsg;
797
798 if (pvar->NotificationWindow == NULL) {
799 pvar->NotificationWindow = hWnd;
800 AUTH_advance_to_next_cred(pvar);
801 }
802 }
803
804 return (pvar->PWSAAsyncSelect) (s, hWnd, wMsg, lEvent);
805 }
806
807 static int PASCAL TTXrecv(SOCKET s, char *buf, int len, int flags)
808 {
809 if (s == pvar->socket) {
810 int ret;
811
812 ssh_heartbeat_lock();
813 ret = PKT_recv(pvar, buf, len);
814 ssh_heartbeat_unlock();
815 return (ret);
816
817 } else {
818 return (pvar->Precv) (s, buf, len, flags);
819 }
820 }
821
822 static int PASCAL TTXsend(SOCKET s, char const *buf, int len,
823 int flags)
824 {
825 if (s == pvar->socket) {
826 ssh_heartbeat_lock();
827 SSH_send(pvar, buf, len);
828 ssh_heartbeat_unlock();
829 return len;
830 } else {
831 return (pvar->Psend) (s, buf, len, flags);
832 }
833 }
834
835 void notify_established_secure_connection(PTInstVar pvar)
836 {
837 int fuLoad = LR_DEFAULTCOLOR;
838
839 if (IsWindowsNT4()) {
840 fuLoad = LR_VGACOLOR;
841 }
842
843 // LoadIcon �������� LoadImage ���g�����������A
844 // 16x16 ���A�C�R���������I�������������������� (2006.8.9 maya)
845 if (SecureLargeIcon == NULL) {
846 SecureLargeIcon = LoadImage(hInst, MAKEINTRESOURCE(pvar->settings.IconID),
847 IMAGE_ICON, 0, 0, fuLoad);
848 }
849 if (SecureSmallIcon == NULL) {
850 SecureSmallIcon = LoadImage(hInst, MAKEINTRESOURCE(pvar->settings.IconID),
851 IMAGE_ICON, 16, 16, fuLoad);
852 }
853
854 if (SecureLargeIcon != NULL && SecureSmallIcon != NULL) {
855 pvar->OldLargeIcon =
856 (HICON) SendMessage(pvar->NotificationWindow, WM_GETICON,
857 ICON_BIG, 0);
858 pvar->OldSmallIcon =
859 (HICON) SendMessage(pvar->NotificationWindow, WM_GETICON,
860 ICON_SMALL, 0);
861
862 PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_BIG,
863 (LPARAM) SecureLargeIcon);
864 PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_SMALL,
865 (LPARAM) SecureSmallIcon);
866 }
867
868 if (IsWindows2000()) {
869 if (SecureNotifyIcon == NULL) {
870 SecureNotifyIcon = LoadImage(hInst, MAKEINTRESOURCE(pvar->settings.IconID),
871 IMAGE_ICON, 0, 0, LR_VGACOLOR | LR_SHARED);
872 }
873 OldNotifyIcon = GetCustomNotifyIcon();
874 SetCustomNotifyIcon(SecureNotifyIcon);
875 }
876
877 logputs(LOG_LEVEL_VERBOSE, "Entering secure mode");
878 }
879
880 void notify_closed_connection(PTInstVar pvar, char *send_msg)
881 {
882 SSH_notify_disconnecting(pvar, send_msg);
883 AUTH_notify_disconnecting(pvar);
884 HOSTS_notify_disconnecting(pvar);
885
886 PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,
887 pvar->socket, MAKELPARAM(FD_CLOSE, 0));
888 }
889
890 static void add_err_msg(PTInstVar pvar, char *msg)
891 {
892 if (pvar->err_msg != NULL) {
893 int buf_len = strlen(pvar->err_msg) + 3 + strlen(msg);
894 char *buf = (char *) malloc(buf_len);
895
896 strncpy_s(buf, buf_len, pvar->err_msg, _TRUNCATE);
897 strncat_s(buf, buf_len, "\n\n", _TRUNCATE);
898 strncat_s(buf, buf_len, msg, _TRUNCATE);
899 free(pvar->err_msg);
900 pvar->err_msg = buf;
901 } else {
902 pvar->err_msg = _strdup(msg);
903 }
904 }
905
906 void notify_nonfatal_error(PTInstVar pvar, char *msg)
907 {
908 if (!pvar->showing_err) {
909 // �������������������m���E�B���h�E�����������A�f�X�N�g�b�v���I�[�i�[������
910 // ���b�Z�[�W�{�b�N�X���o���������B(2006.6.11 yutaka)
911 if (pvar->NotificationWindow == NULL) {
912 UTIL_get_lang_msg("MSG_NONFATAL_ERROR", pvar,
913 "Tera Term: not fatal error");
914 MessageBox(NULL, msg, pvar->ts->UIMsg, MB_OK|MB_ICONINFORMATION);
915 msg[0] = '\0';
916
917 } else {
918 PostMessage(pvar->NotificationWindow, WM_COMMAND,
919 ID_SSHASYNCMESSAGEBOX, 0);
920 }
921 }
922 if (msg[0] != 0) {
923 logputs(LOG_LEVEL_ERROR, msg);
924 add_err_msg(pvar, msg);
925 }
926 }
927
928 void notify_fatal_error(PTInstVar pvar, char *msg, BOOL send_disconnect)
929 {
930 if (msg[0] != 0) {
931 logputs(LOG_LEVEL_FATAL, msg);
932 add_err_msg(pvar, msg);
933 }
934
935 if (!pvar->fatal_error) {
936 pvar->fatal_error = TRUE;
937
938 if (send_disconnect) {
939 SSH_notify_disconnecting(pvar, msg);
940 }
941 AUTH_notify_disconnecting(pvar);
942 HOSTS_notify_disconnecting(pvar);
943
944 PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,
945 pvar->socket, MAKELPARAM(FD_CLOSE,
946 (pvar->PWSAGetLastError) ()));
947 }
948 }
949
950 void logputs(int level, char *msg)
951 {
952 if (level <= pvar->settings.LogLevel) {
953 char buf[4096];
954 int file;
955
956 get_teraterm_dir_relative_name(buf, NUM_ELEM(buf), "TTSSH.LOG");
957 file = _open(buf, _O_RDWR | _O_APPEND | _O_CREAT | _O_TEXT,
958 _S_IREAD | _S_IWRITE);
959
960 if (file >= 0) {
961 char *strtime = mctimelocal("%Y-%m-%d %H:%M:%S.%NZ", TRUE);
962 DWORD processid;
963 char tmp[26];
964
965 _write(file, strtime, strlen(strtime));
966 GetWindowThreadProcessId(pvar->cv->HWin, &processid);
967 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, " [%lu] ",processid);
968 _write(file, tmp, strlen(tmp));
969 _write(file, msg, strlen(msg));
970 _write(file, "\n", 1);
971 _close(file);
972 }
973 }
974 }
975
976 void logprintf(int level, char *fmt, ...)
977 {
978 char buff[4096];
979 va_list params;
980
981 if (level <= pvar->settings.LogLevel) {
982 va_start(params, fmt);
983 vsnprintf_s(buff, sizeof(buff), _TRUNCATE, fmt, params);
984 va_end(params);
985
986 logputs(level, buff);
987 }
988 }
989
990 static void format_line_hexdump(char *buf, int buflen, int addr, int *bytes, int byte_cnt)
991 {
992 int i, c;
993 char tmp[128];
994
995 buf[0] = 0;
996
997 /* �������A�h���X�\�� */
998 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, "%08X : ", addr);
999 strncat_s(buf, buflen, tmp, _TRUNCATE);
1000
1001 /* �o�C�i���\���i4�o�C�g�������������}���j*/
1002 for (i = 0; i < byte_cnt; i++) {
1003 if (i > 0 && i % 4 == 0) {
1004 strncat_s(buf, buflen, " ", _TRUNCATE);
1005 }
1006
1007 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, "%02X", bytes[i]);
1008 strncat_s(buf, buflen, tmp, _TRUNCATE);
1009 }
1010
1011 /* ASCII�\���������������������� */
1012 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, " %*s%*s", (16 - byte_cnt) * 2 + 1, " ", (16 - byte_cnt + 3) / 4, " ");
1013 strncat_s(buf, buflen, tmp, _TRUNCATE);
1014
1015 /* ASCII�\�� */
1016 for (i = 0; i < byte_cnt; i++) {
1017 c = bytes[i];
1018 if (isprint(c)) {
1019 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, "%c", c);
1020 strncat_s(buf, buflen, tmp, _TRUNCATE);
1021 }
1022 else {
1023 strncat_s(buf, buflen, ".", _TRUNCATE);
1024 }
1025 }
1026
1027 //strncat_s(buf, buflen, "\n", _TRUNCATE);
1028 }
1029
1030 void logprintf_hexdump(int level, char *data, int len, char *fmt, ...)
1031 {
1032 char buff[4096];
1033 va_list params;
1034 int c, addr;
1035 int bytes[16], *ptr;
1036 int byte_cnt;
1037 int i;
1038
1039 if (level <= pvar->settings.LogLevel) {
1040 va_start(params, fmt);
1041 vsnprintf_s(buff, sizeof(buff), _TRUNCATE, fmt, params);
1042 va_end(params);
1043
1044 logputs(level, buff);
1045
1046 addr = 0;
1047 byte_cnt = 0;
1048 ptr = bytes;
1049 for (i = 0; i < len; i++) {
1050 c = data[i];
1051 *ptr++ = c & 0xff;
1052 byte_cnt++;
1053
1054 if (byte_cnt == 16) {
1055 format_line_hexdump(buff, sizeof(buff), addr, bytes, byte_cnt);
1056 logputs(level, buff);
1057
1058 addr += 16;
1059 byte_cnt = 0;
1060 ptr = bytes;
1061 }
1062 }
1063
1064 if (byte_cnt > 0) {
1065 format_line_hexdump(buff, sizeof(buff), addr, bytes, byte_cnt);
1066 logputs(level, buff);
1067 }
1068 }
1069 }
1070
1071 static void PASCAL TTXOpenTCP(TTXSockHooks *hooks)
1072 {
1073 if (pvar->settings.Enabled) {
1074 // TCPLocalEcho/TCPCRSend ������������ (maya 2007.4.25)
1075 pvar->origDisableTCPEchoCR = pvar->ts->DisableTCPEchoCR;
1076 pvar->ts->DisableTCPEchoCR = TRUE;
1077
1078 pvar->session_settings = pvar->settings;
1079
1080 logputs(LOG_LEVEL_VERBOSE, "---------------------------------------------------------------------");
1081 logputs(LOG_LEVEL_VERBOSE, "Initiating SSH session");
1082
1083 FWDUI_load_settings(pvar);
1084
1085 pvar->cv->TelAutoDetect = FALSE;
1086 /* This next line should not be needed because Tera Term's
1087 CommLib should find ts->Telnet == 0 ... but we'll do this
1088 just to be on the safe side. */
1089 pvar->cv->TelFlag = FALSE;
1090 pvar->cv->TelLineMode = FALSE;
1091
1092 pvar->Precv = *hooks->Precv;
1093 pvar->Psend = *hooks->Psend;
1094 pvar->PWSAAsyncSelect = *hooks->PWSAAsyncSelect;
1095 pvar->Pconnect = *hooks->Pconnect;
1096 pvar->PWSAGetLastError = *hooks->PWSAGetLastError;
1097
1098 *hooks->Precv = TTXrecv;
1099 *hooks->Psend = TTXsend;
1100 *hooks->PWSAAsyncSelect = TTXWSAAsyncSelect;
1101 *hooks->Pconnect = TTXconnect;
1102
1103 SSH_open(pvar);
1104 HOSTS_open(pvar);
1105 FWDUI_open(pvar);
1106
1107 // ������ myproposal �����f���������A�������O�����������B (2006.6.26 maya)
1108 SSH2_update_cipher_myproposal(pvar);
1109 SSH2_update_kex_myproposal(pvar);
1110 SSH2_update_host_key_myproposal(pvar);
1111 SSH2_update_hmac_myproposal(pvar);
1112 SSH2_update_compression_myproposal(pvar);
1113 }
1114 }
1115
1116 static void PASCAL TTXCloseTCP(TTXSockHooks *hooks)
1117 {
1118 if (pvar->session_settings.Enabled) {
1119 pvar->socket = INVALID_SOCKET;
1120
1121 logputs(LOG_LEVEL_VERBOSE, "Terminating SSH session...");
1122
1123 *hooks->Precv = pvar->Precv;
1124 *hooks->Psend = pvar->Psend;
1125 *hooks->PWSAAsyncSelect = pvar->PWSAAsyncSelect;
1126 *hooks->Pconnect = pvar->Pconnect;
1127
1128 pvar->ts->DisableTCPEchoCR = pvar->origDisableTCPEchoCR;
1129 }
1130
1131 uninit_TTSSH(pvar);
1132 init_TTSSH(pvar);
1133 }
1134
1135 static void enable_dlg_items(HWND dlg, int from, int to, BOOL enabled)
1136 {
1137 for (; from <= to; from++) {
1138 EnableWindow(GetDlgItem(dlg, from), enabled);
1139 }
1140 }
1141
1142 // C-p/C-n/C-b/C-f/C-a/C-e ���T�|�[�g (2007.9.5 maya)
1143 // C-d/C-k ���T�|�[�g (2007.10.3 yutaka)
1144 // �h���b�v�_�E���������G�f�B�b�g�R���g���[����
1145 // �T�u�N���X�������������E�C���h�E�v���V�[�W��
1146 WNDPROC OrigHostnameEditProc; // Original window procedure
1147 LRESULT CALLBACK HostnameEditProc(HWND dlg, UINT msg,
1148 WPARAM wParam, LPARAM lParam)
1149 {
1150 HWND parent;
1151 int max, select, len;
1152 char *str, *orgstr;
1153
1154 switch (msg) {
1155 // �L�[�����������������m����
1156 case WM_KEYDOWN:
1157 if (GetKeyState(VK_CONTROL) < 0) {
1158 switch (wParam) {
1159 case 0x50: // Ctrl+p ... up
1160 parent = GetParent(dlg);
1161 select = SendMessage(parent, CB_GETCURSEL, 0, 0);
1162 if (select > 0) {
1163 PostMessage(parent, CB_SETCURSEL, select - 1, 0);
1164 }
1165 return 0;
1166 case 0x4e: // Ctrl+n ... down
1167 parent = GetParent(dlg);
1168 max = SendMessage(parent, CB_GETCOUNT, 0, 0);
1169 select = SendMessage(parent, CB_GETCURSEL, 0, 0);
1170 if (select < max - 1) {
1171 PostMessage(parent, CB_SETCURSEL, select + 1, 0);
1172 }
1173 return 0;
1174 case 0x42: // Ctrl+b ... left
1175 SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1176 PostMessage(dlg, EM_SETSEL, select-1, select-1);
1177 return 0;
1178 case 0x46: // Ctrl+f ... right
1179 SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1180 max = GetWindowTextLength(dlg) ;
1181 PostMessage(dlg, EM_SETSEL, select+1, select+1);
1182 return 0;
1183 case 0x41: // Ctrl+a ... home
1184 PostMessage(dlg, EM_SETSEL, 0, 0);
1185 return 0;
1186 case 0x45: // Ctrl+e ... end
1187 max = GetWindowTextLength(dlg) ;
1188 PostMessage(dlg, EM_SETSEL, max, max);
1189 return 0;
1190
1191 case 0x44: // Ctrl+d
1192 case 0x4b: // Ctrl+k
1193 case 0x55: // Ctrl+u
1194 SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1195 max = GetWindowTextLength(dlg);
1196 max++; // '\0'
1197 orgstr = str = malloc(max);
1198 if (str != NULL) {
1199 len = GetWindowText(dlg, str, max);
1200 if (select >= 0 && select < len) {
1201 if (wParam == 0x44) { // �J�[�\���z����������������������
1202 memmove(&str[select], &str[select + 1], len - select - 1);
1203 str[len - 1] = '\0';
1204
1205 } else if (wParam == 0x4b) { // �J�[�\�������s��������������
1206 str[select] = '\0';
1207
1208 }
1209 }
1210
1211 if (wParam == 0x55) { // �J�[�\����������������������
1212 if (select >= len) {
1213 str[0] = '\0';
1214 } else {
1215 str = &str[select];
1216 }
1217 select = 0;
1218 }
1219
1220 SetWindowText(dlg, str);
1221 SendMessage(dlg, EM_SETSEL, select, select);
1222 free(orgstr);
1223 return 0;
1224 }
1225 break;
1226 }
1227 }
1228 break;
1229
1230 // �����L�[��������������������������������������������
1231 case WM_CHAR:
1232 switch (wParam) {
1233 case 0x01:
1234 case 0x02:
1235 case 0x04:
1236 case 0x05:
1237 case 0x06:
1238 case 0x0b:
1239 case 0x0e:
1240 case 0x10:
1241 case 0x15:
1242 return 0;
1243 }
1244 }
1245
1246 return CallWindowProc(OrigHostnameEditProc, dlg, msg, wParam, lParam);
1247 }
1248
1249 static BOOL CALLBACK TTXHostDlg(HWND dlg, UINT msg, WPARAM wParam,
1250 LPARAM lParam)
1251 {
1252 static char *ssh_version[] = {"SSH1", "SSH2", NULL};
1253 PGetHNRec GetHNRec;
1254 char EntName[128];
1255 char TempHost[HostNameMaxLength + 1];
1256 WORD i, j, w;
1257 WORD ComPortTable[MAXCOMPORT];
1258 static char *ComPortDesc[MAXCOMPORT];
1259 int comports;
1260 BOOL Ok;
1261 // LOGFONT logfont;
1262 // HFONT font;
1263 char uimsg[MAX_UIMSG];
1264 static HWND hwndHostname = NULL; // HOSTNAME dropdown
1265 static HWND hwndHostnameEdit = NULL; // Edit control on HOSTNAME dropdown
1266
1267 switch (msg) {
1268 case WM_INITDIALOG:
1269 GetHNRec = (PGetHNRec) lParam;
1270 SetWindowLong(dlg, DWL_USER, lParam);
1271
1272 GetWindowText(dlg, uimsg, sizeof(uimsg));
1273 UTIL_get_lang_msg("DLG_HOST_TITLE", pvar, uimsg);
1274 SetWindowText(dlg, pvar->ts->UIMsg);
1275 GetDlgItemText(dlg, IDC_HOSTNAMELABEL, uimsg, sizeof(uimsg));
1276 UTIL_get_lang_msg("DLG_HOST_TCPIPHOST", pvar, uimsg);
1277 SetDlgItemText(dlg, IDC_HOSTNAMELABEL, pvar->ts->UIMsg);
1278 GetDlgItemText(dlg, IDC_HISTORY, uimsg, sizeof(uimsg));
1279 UTIL_get_lang_msg("DLG_HOST_TCPIPHISTORY", pvar, uimsg);
1280 SetDlgItemText(dlg, IDC_HISTORY, pvar->ts->UIMsg);
1281 GetDlgItemText(dlg, IDC_SERVICELABEL, uimsg, sizeof(uimsg));
1282 UTIL_get_lang_msg("DLG_HOST_TCPIPSERVICE", pvar, uimsg);
1283 SetDlgItemText(dlg, IDC_SERVICELABEL, pvar->ts->UIMsg);
1284 GetDlgItemText(dlg, IDC_HOSTOTHER, uimsg, sizeof(uimsg));
1285 UTIL_get_lang_msg("DLG_HOST_TCPIPOTHER", pvar, uimsg);
1286 SetDlgItemText(dlg, IDC_HOSTOTHER, pvar->ts->UIMsg);
1287 GetDlgItemText(dlg, IDC_HOSTTCPPORTLABEL, uimsg, sizeof(uimsg));
1288 UTIL_get_lang_msg("DLG_HOST_TCPIPPORT", pvar, uimsg);
1289 SetDlgItemText(dlg, IDC_HOSTTCPPORTLABEL, pvar->ts->UIMsg);
1290 GetDlgItemText(dlg, IDC_SSH_VERSION_LABEL, uimsg, sizeof(uimsg));
1291 UTIL_get_lang_msg("DLG_HOST_TCPIPSSHVERSION", pvar, uimsg);
1292 SetDlgItemText(dlg, IDC_SSH_VERSION_LABEL, pvar->ts->UIMsg);
1293 GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOLLABEL, uimsg, sizeof(uimsg));
1294 UTIL_get_lang_msg("DLG_HOST_TCPIPPROTOCOL", pvar, uimsg);
1295 SetDlgItemText(dlg, IDC_HOSTTCPPROTOCOLLABEL, pvar->ts->UIMsg);
1296 GetDlgItemText(dlg, IDC_HOSTSERIAL, uimsg, sizeof(uimsg));
1297 UTIL_get_lang_msg("DLG_HOST_SERIAL", pvar, uimsg);
1298 SetDlgItemText(dlg, IDC_HOSTSERIAL, pvar->ts->UIMsg);
1299 GetDlgItemText(dlg, IDC_HOSTCOMLABEL, uimsg, sizeof(uimsg));
1300 UTIL_get_lang_msg("DLG_HOST_SERIALPORT", pvar, uimsg);
1301 SetDlgItemText(dlg, IDC_HOSTCOMLABEL, pvar->ts->UIMsg);
1302 GetDlgItemText(dlg, IDC_HOSTHELP, uimsg, sizeof(uimsg));
1303 UTIL_get_lang_msg("DLG_HOST_HELP", pvar, uimsg);
1304 SetDlgItemText(dlg, IDC_HOSTHELP, pvar->ts->UIMsg);
1305 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
1306 UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
1307 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
1308 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1309 UTIL_get_lang_msg("BTN_CANCEL", pvar, uimsg);
1310 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1311
1312 // �z�X�g�q�X�g�����`�F�b�N�{�b�N�X������ (2005.10.21 yutaka)
1313 if (pvar->ts->HistoryList > 0) {
1314 SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_SETCHECK, BST_CHECKED, 0);
1315 } else {
1316 SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_SETCHECK, BST_UNCHECKED, 0);
1317 }
1318
1319 // �t�@�C�����������O�t���p�C�v�������ATCP/IP�����������B
1320 if (GetHNRec->PortType == IdFile ||
1321 GetHNRec->PortType == IdNamedPipe
1322 )
1323 GetHNRec->PortType = IdTCPIP;
1324
1325 strncpy_s(EntName, sizeof(EntName), "Host", _TRUNCATE);
1326
1327 i = 1;
1328 do {
1329 _snprintf_s(&EntName[4], sizeof(EntName)-4, _TRUNCATE, "%d", i);
1330 GetPrivateProfileString("Hosts", EntName, "",
1331 TempHost, sizeof(TempHost),
1332 GetHNRec->SetupFN);
1333 if (strlen(TempHost) > 0)
1334 SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_ADDSTRING,
1335 0, (LPARAM) TempHost);
1336 i++;
1337 } while (i <= MAXHOSTLIST);
1338
1339 SendDlgItemMessage(dlg, IDC_HOSTNAME, EM_LIMITTEXT,
1340 HostNameMaxLength - 1, 0);
1341
1342 SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_SETCURSEL, 0, 0);
1343
1344 // C-n/C-p ���������T�u�N���X�� (2007.9.4 maya)
1345 hwndHostname = GetDlgItem(dlg, IDC_HOSTNAME);
1346 hwndHostnameEdit = GetWindow(hwndHostname, GW_CHILD);
1347 OrigHostnameEditProc = (WNDPROC)GetWindowLong(hwndHostnameEdit, GWL_WNDPROC);
1348 SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)HostnameEditProc);
1349
1350 CheckRadioButton(dlg, IDC_HOSTTELNET, IDC_HOSTOTHER,
1351 pvar->settings.Enabled ? IDC_HOSTSSH : GetHNRec->
1352 Telnet ? IDC_HOSTTELNET : IDC_HOSTOTHER);
1353 SendDlgItemMessage(dlg, IDC_HOSTTCPPORT, EM_LIMITTEXT, 5, 0);
1354 SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TCPPort, FALSE);
1355 for (i = 0; ProtocolFamilyList[i]; ++i) {
1356 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_ADDSTRING,
1357 0, (LPARAM) ProtocolFamilyList[i]);
1358 }
1359 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, EM_LIMITTEXT,
1360 ProtocolFamilyMaxLength - 1, 0);
1361 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_SETCURSEL, 0, 0);
1362
1363 /////// SSH version
1364 for (i = 0; ssh_version[i]; ++i) {
1365 SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_ADDSTRING,
1366 0, (LPARAM) ssh_version[i]);
1367 }
1368 SendDlgItemMessage(dlg, IDC_SSH_VERSION, EM_LIMITTEXT,
1369 NUM_ELEM(ssh_version) - 1, 0);
1370
1371 if (pvar->settings.ssh_protocol_version == 1) {
1372 SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 0, 0); // SSH1
1373 } else {
1374 SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 1, 0); // SSH2
1375 }
1376
1377 if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1378 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE); // enabled
1379 } else {
1380 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1381 }
1382 /////// SSH version
1383
1384
1385 j = 0;
1386 w = 1;
1387 if ((comports=DetectComPorts(ComPortTable, GetHNRec->MaxComPort, ComPortDesc)) >= 0) {
1388 for (i=0; i<comports; i++) {
1389 // MaxComPort ���z�����|�[�g���\��������
1390 if (ComPortTable[i] > GetHNRec->MaxComPort) {
1391 continue;
1392 }
1393
1394 // �g�p�����|�[�g���\��������
1395 if (CheckCOMFlag(ComPortTable[i]) == 1) {
1396 continue;
1397 }
1398
1399 _snprintf_s(EntName, sizeof(EntName), _TRUNCATE, "COM%d", ComPortTable[i]);
1400 if (ComPortDesc[i] != NULL) {
1401 strncat_s(EntName, sizeof(EntName), ": ", _TRUNCATE);
1402 strncat_s(EntName, sizeof(EntName), ComPortDesc[i], _TRUNCATE);
1403 }
1404 SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_ADDSTRING,
1405 0, (LPARAM)EntName);
1406 j++;
1407 if (GetHNRec->ComPort == ComPortTable[i])
1408 w = j;
1409 }
1410
1411 } else {
1412 for (i = 1; i <= GetHNRec->MaxComPort; i++) {
1413 // �g�p�����|�[�g���\��������
1414 if (CheckCOMFlag(i) == 1) {
1415 continue;
1416 }
1417
1418 _snprintf_s(EntName, sizeof(EntName), _TRUNCATE, "COM%d", i);
1419 SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_ADDSTRING,
1420 0, (LPARAM) EntName);
1421 j++;
1422 if (GetHNRec->ComPort == i)
1423 w = j;
1424 }
1425 }
1426
1427 if (j > 0)
1428 SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_SETCURSEL, w - 1, 0);
1429 else { /* All com ports are already used */
1430 GetHNRec->PortType = IdTCPIP;
1431 enable_dlg_items(dlg, IDC_HOSTSERIAL, IDC_HOSTSERIAL, FALSE);
1432 }
1433
1434 CheckRadioButton(dlg, IDC_HOSTTCPIP, IDC_HOSTSERIAL,
1435 IDC_HOSTTCPIP + GetHNRec->PortType - 1);
1436
1437 if (GetHNRec->PortType == IdTCPIP) {
1438 enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
1439
1440 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE);
1441 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE);
1442
1443 enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, TRUE); // enabled
1444 }
1445 else {
1446 enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1447 FALSE);
1448 enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1449 IDC_HOSTTCPPROTOCOL, FALSE);
1450
1451 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1452 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1453
1454 enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, FALSE); // disabled
1455 }
1456
1457 // Host dialog���t�H�[�J�X�������� (2004.10.2 yutaka)
1458 if (GetHNRec->PortType == IdTCPIP) {
1459 HWND hwnd = GetDlgItem(dlg, IDC_HOSTNAME);
1460 SetFocus(hwnd);
1461 } else {
1462 HWND hwnd = GetDlgItem(dlg, IDC_HOSTCOM);
1463 SetFocus(hwnd);
1464 }
1465
1466 #if 0
1467 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1468 GetObject(font, sizeof(LOGFONT), &logfont);
1469 if (UTIL_get_lang_font("DLG_SYSTEM_FONT", dlg, &logfont, &DlgHostFont, pvar)) {
1470 SendDlgItemMessage(dlg, IDC_HOSTTCPIP, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1471 SendDlgItemMessage(dlg, IDC_HOSTNAMELABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1472 SendDlgItemMessage(dlg, IDC_HOSTNAME, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1473 SendDlgItemMessage(dlg, IDC_HISTORY, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1474 SendDlgItemMessage(dlg, IDC_SERVICELABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1475 SendDlgItemMessage(dlg, IDC_HOSTTELNET, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1476 SendDlgItemMessage(dlg, IDC_HOSTSSH, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1477 SendDlgItemMessage(dlg, IDC_HOSTOTHER, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1478 SendDlgItemMessage(dlg, IDC_HOSTTCPPORTLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1479 SendDlgItemMessage(dlg, IDC_HOSTTCPPORT, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1480 SendDlgItemMessage(dlg, IDC_SSH_VERSION_LABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1481 SendDlgItemMessage(dlg, IDC_SSH_VERSION, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1482 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOLLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1483 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1484 SendDlgItemMessage(dlg, IDC_HOSTSERIAL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1485 SendDlgItemMessage(dlg, IDC_HOSTCOMLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1486 SendDlgItemMessage(dlg, IDC_HOSTCOM, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1487 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1488 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1489 SendDlgItemMessage(dlg, IDC_HOSTHELP, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1490 }
1491 else {
1492 DlgHostFont = NULL;
1493 }
1494 #endif
1495
1496 CenterWindow(dlg, GetParent(dlg));
1497
1498 // SetFocus()���t�H�[�J�X���������������AFALSE�������K�v�������B
1499 // TRUE���������ATABSTOP�������������������R���g���[�����I�������B
1500 // (2004.11.23 yutaka)
1501 return FALSE;
1502 //return TRUE;
1503
1504 case WM_COMMAND:
1505 switch (LOWORD(wParam)) {
1506 case IDOK:
1507 GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1508 if (GetHNRec != NULL) {
1509 if (IsDlgButtonChecked(dlg, IDC_HOSTTCPIP)) {
1510 char afstr[BUFSIZ];
1511 i = GetDlgItemInt(dlg, IDC_HOSTTCPPORT, &Ok, FALSE);
1512 if (Ok) {
1513 GetHNRec->TCPPort = i;
1514 } else {
1515 UTIL_get_lang_msg("MSG_TCPPORT_NAN_ERROR", pvar,
1516 "The TCP port must be a number.");
1517 MessageBox(dlg, pvar->ts->UIMsg,
1518 "Tera Term", MB_OK | MB_ICONEXCLAMATION);
1519 return TRUE;
1520 }
1521 #define getaf(str) \
1522 ((strcmp((str), "IPv6") == 0) ? AF_INET6 : \
1523 ((strcmp((str), "IPv4") == 0) ? AF_INET : AF_UNSPEC))
1524 memset(afstr, 0, sizeof(afstr));
1525 GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOL, afstr,
1526 sizeof(afstr));
1527 GetHNRec->ProtocolFamily = getaf(afstr);
1528 GetHNRec->PortType = IdTCPIP;
1529 GetDlgItemText(dlg, IDC_HOSTNAME, GetHNRec->HostName,
1530 HostNameMaxLength);
1531 pvar->hostdlg_activated = TRUE;
1532 pvar->hostdlg_Enabled = FALSE;
1533 if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1534 GetHNRec->Telnet = TRUE;
1535 } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1536 pvar->hostdlg_Enabled = TRUE;
1537
1538 // check SSH protocol version
1539 memset(afstr, 0, sizeof(afstr));
1540 GetDlgItemText(dlg, IDC_SSH_VERSION, afstr, sizeof(afstr));
1541 if (_stricmp(afstr, "SSH1") == 0) {
1542 pvar->settings.ssh_protocol_version = 1;
1543 } else {
1544 pvar->settings.ssh_protocol_version = 2;
1545 }
1546 }
1547 else { // IDC_HOSTOTHER
1548 GetHNRec->Telnet = FALSE;
1549 }
1550
1551 // host history check button
1552 if (SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_GETCHECK, 0, 0) == BST_CHECKED) {
1553 pvar->ts->HistoryList = 1;
1554 } else {
1555 pvar->ts->HistoryList = 0;
1556 }
1557
1558 } else {
1559 GetHNRec->PortType = IdSerial;
1560 GetHNRec->HostName[0] = 0;
1561 memset(EntName, 0, sizeof(EntName));
1562 GetDlgItemText(dlg, IDC_HOSTCOM, EntName,
1563 sizeof(EntName) - 1);
1564 if (strncmp(EntName, "COM", 3) == 0 && EntName[3] != '\0') {
1565 GetHNRec->ComPort = atoi(&EntName[3]);
1566 if (GetHNRec->ComPort > GetHNRec->MaxComPort)
1567 GetHNRec->ComPort = 1;
1568 } else {
1569 GetHNRec->ComPort = 1;
1570 }
1571 }
1572 }
1573 SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)OrigHostnameEditProc);
1574 EndDialog(dlg, 1);
1575 #if 0
1576 if (DlgHostFont != NULL) {
1577 DeleteObject(DlgHostFont);
1578 }
1579 #endif
1580 return TRUE;
1581
1582 case IDCANCEL:
1583 SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)OrigHostnameEditProc);
1584 EndDialog(dlg, 0);
1585 #if 0
1586 if (DlgHostFont != NULL) {
1587 DeleteObject(DlgHostFont);
1588 }
1589 #endif
1590 return TRUE;
1591
1592 case IDC_HOSTTCPIP:
1593 enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1594 TRUE);
1595 enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1596 IDC_HOSTTCPPROTOCOL, TRUE);
1597 enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
1598
1599 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE); // disabled (2004.11.23 yutaka)
1600 if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1601 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE);
1602 } else {
1603 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1604 }
1605
1606 enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, TRUE); // disabled
1607
1608 return TRUE;
1609
1610 case IDC_HOSTSERIAL:
1611 enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, TRUE);
1612 enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1613 FALSE);
1614 enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1615 IDC_HOSTTCPPROTOCOL, FALSE);
1616 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1617 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1618
1619 enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, FALSE); // disabled
1620
1621 return TRUE;
1622
1623 case IDC_HOSTSSH:
1624 enable_dlg_items(dlg, IDC_SSH_VERSION,
1625 IDC_SSH_VERSION, TRUE);
1626 goto hostssh_enabled;
1627
1628 case IDC_HOSTTELNET:
1629 case IDC_HOSTOTHER:
1630 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1631 hostssh_enabled:
1632
1633 GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1634
1635 if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1636 if (GetHNRec != NULL)
1637 SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TelPort,
1638 FALSE);
1639 } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1640 SetDlgItemInt(dlg, IDC_HOSTTCPPORT, 22, FALSE);
1641 }
1642 return TRUE;
1643
1644 case IDC_HOSTCOM:
1645 if(HIWORD(wParam) == CBN_DROPDOWN) {
1646 HWND hostcom = GetDlgItem(dlg, IDC_HOSTCOM);
1647 int count = SendMessage(hostcom, CB_GETCOUNT, 0, 0);
1648 int i, len, max_len = 0;
1649 char *lbl;
1650 HDC TmpDC = GetDC(hostcom);
1651 SIZE s;
1652 for (i=0; i<count; i++) {
1653 len = SendMessage(hostcom, CB_GETLBTEXTLEN, i, 0);
1654 lbl = (char *)calloc(len+1, sizeof(char));
1655 SendMessage(hostcom, CB_GETLBTEXT, i, (LPARAM)lbl);
1656 GetTextExtentPoint32(TmpDC, lbl, len, &s);
1657 if (s.cx > max_len)
1658 max_len = s.cx;
1659 free(lbl);
1660 }
1661 SendMessage(hostcom, CB_SETDROPPEDWIDTH,
1662 max_len + GetSystemMetrics(SM_CXVSCROLL), 0);
1663 }
1664 break;
1665
1666 case IDC_HOSTHELP:
1667 PostMessage(GetParent(dlg), WM_USER_DLGHELP2, 0, 0);
1668 }
1669 }
1670 return FALSE;
1671 }
1672
1673 static void UTIL_SetDialogFont()
1674 {
1675 SetDialogFont(pvar->ts->SetupFName, pvar->ts->UILanguageFile, "TTSSH", "DLG_TAHOMA_FONT");
1676 }
1677
1678 static BOOL PASCAL TTXGetHostName(HWND parent, PGetHNRec rec)
1679 {
1680 SetDialogFont(pvar->ts->SetupFName,
1681 pvar->ts->UILanguageFile, "TTSSH", "DLG_SYSTEM_FONT");
1682 return (BOOL) DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HOSTDLG),
1683 parent, TTXHostDlg, (LPARAM)rec);
1684 }
1685
1686 static void PASCAL TTXGetUIHooks(TTXUIHooks *hooks)
1687 {
1688 *hooks->GetHostName = TTXGetHostName;
1689 }
1690
1691 static void PASCAL TTXReadINIFile(PCHAR fileName, PTTSet ts)
1692 {
1693 (pvar->ReadIniFile) (fileName, ts);
1694 read_ssh_options(pvar, fileName);
1695 pvar->settings = *pvar->ts_SSH;
1696 logputs(LOG_LEVEL_VERBOSE, "Reading INI file");
1697 FWDUI_load_settings(pvar);
1698 }
1699
1700 static void PASCAL TTXWriteINIFile(PCHAR fileName, PTTSet ts)
1701 {
1702 (pvar->WriteIniFile) (fileName, ts);
1703 *pvar->ts_SSH = pvar->settings;
1704 clear_local_settings(pvar);
1705 logputs(LOG_LEVEL_VERBOSE, "Writing INI file");
1706 write_ssh_options(pvar, fileName, pvar->ts_SSH, TRUE);
1707 }
1708
1709 static void read_ssh_options_from_user_file(PTInstVar pvar,
1710 char *user_file_name)
1711 {
1712 if (user_file_name[0] == '.') {
1713 read_ssh_options(pvar, user_file_name);
1714 } else {
1715 char buf[1024];
1716
1717 get_teraterm_dir_relative_name(buf, sizeof(buf), user_file_name);
1718 read_ssh_options(pvar, buf);
1719 }
1720
1721 pvar->settings = *pvar->ts_SSH;
1722 FWDUI_load_settings(pvar);
1723 }
1724
1725 // Percent-encode������������src���f�R�[�h����dst���R�s�[�����B
1726 // dstlen��dst���T�C�Y�B�����������������������A�����������������������B
1727 static void percent_decode(char *dst, int dstlen, char *src) {
1728 if (src == NULL || dst == NULL || dstlen < 1) {
1729 return;
1730 }
1731
1732 while (*src != 0 && dstlen > 1) {
1733 if (*src == '%' && isxdigit(*(src+1)) && isxdigit(*(src+2))) {
1734 src++; *dst = (isalpha(*src) ? (*src|0x20) - 'a' + 10 : *src - '0') << 4;
1735 src++; *dst |= (isalpha(*src) ? (*src|0x20) - 'a' + 10 : *src - '0');
1736 src++; dst++;
1737 }
1738 else {
1739 *dst++ = *src++;
1740 }
1741 dstlen--;
1742 }
1743 *dst = 0;
1744 return;
1745 }
1746
1747 void add_forward_param(PTInstVar pvar, char *param)
1748 {
1749 if (pvar->settings.DefaultForwarding[0] == 0) {
1750 strncpy_s(pvar->settings.DefaultForwarding,
1751 sizeof(pvar->settings.DefaultForwarding),
1752 param, _TRUNCATE);
1753 } else {
1754 strncat_s(pvar->settings.DefaultForwarding,
1755 sizeof(pvar->settings.DefaultForwarding),
1756 ";", _TRUNCATE);
1757 strncat_s(pvar->settings.DefaultForwarding,
1758 sizeof(pvar->settings.DefaultForwarding),
1759 param, _TRUNCATE);
1760 }
1761 }
1762
1763 static void PASCAL TTXParseParam(PCHAR param, PTTSet ts, PCHAR DDETopic) {
1764 int param_len=strlen(param);
1765 int opt_len = param_len+1;
1766 char *option = (char *)calloc(opt_len, sizeof(char));
1767 char *option2 = (char *)calloc(opt_len, sizeof(char));
1768 int action;
1769 PCHAR start, cur, next;
1770 size_t i;
1771
1772 if (pvar->hostdlg_activated) {
1773 pvar->settings.Enabled = pvar->hostdlg_Enabled;
1774 }
1775
1776 /* the first term shuld be executable filename of Tera Term */
1777 start = GetParam(option, opt_len, param);
1778
1779 cur = start;
1780 while (next = GetParam(option, opt_len, cur)) {
1781 DequoteParam(option, opt_len, option);
1782 action = OPTION_NONE;
1783
1784 if ((option[0] == '-' || option[0] == '/')) {
1785 if (MATCH_STR(option + 1, "ssh") == 0) {
1786 if (MATCH_STR(option + 4, "-f=") == 0) {
1787 strncpy_s(option2, opt_len, option + 7, _TRUNCATE);
1788 read_ssh_options_from_user_file(pvar, option2);
1789 action = OPTION_CLEAR;
1790 } else if (MATCH_STR(option + 4, "-consume=") == 0) {
1791 strncpy_s(option2, opt_len, option + 13, _TRUNCATE);
1792 read_ssh_options_from_user_file(pvar, option2);
1793 DeleteFile(option2);
1794 action = OPTION_CLEAR;
1795 }
1796
1797 // ttermpro.exe �� /F= �w������ TTSSH ������������ (2006.10.11 maya)
1798 } else if (MATCH_STR_I(option + 1, "f=") == 0) {
1799 strncpy_s(option2, opt_len, option + 3, _TRUNCATE);
1800 read_ssh_options_from_user_file(pvar, option2);
1801 // Tera Term���������������K�v������������������
1802 }
1803 }
1804
1805 switch (action) {
1806 case OPTION_CLEAR:
1807 memset(cur, ' ', next-cur);
1808 break;
1809 case OPTION_REPLACE:
1810 memset(cur, ' ', next-cur);
1811 memcpy(cur+1, option, strlen(option));
1812 break;
1813 }
1814
1815 cur = next;
1816 }
1817
1818 cur = start;
1819 while (next = GetParam(option, opt_len, cur)) {
1820 DequoteParam(option, opt_len, option);
1821 action = OPTION_NONE;
1822
1823 if ((option[0] == '-' || option[0] == '/')) {
1824 action = OPTION_CLEAR;
1825 if (MATCH_STR(option + 1, "ssh") == 0) {
1826 if (option[4] == 0) {
1827 pvar->settings.Enabled = 1;
1828 } else if (MATCH_STR(option + 4, "-L") == 0 ||
1829 MATCH_STR(option + 4, "-R") == 0 ||
1830 MATCH_STR(option + 4, "-D") == 0) {
1831 char *p = option + 5;
1832 option2[0] = *p;
1833 i = 1;
1834 while (*++p) {
1835 if (*p == ';' || *p == ',') {
1836 option2[i] = 0;
1837 add_forward_param(pvar, option2);
1838 i = 1;
1839 }
1840 else {
1841 option2[i++] = *p;
1842 }
1843 }
1844 if (i > 1) {
1845 option2[i] = 0;
1846 add_forward_param(pvar, option2);
1847 }
1848 } else if (MATCH_STR(option + 4, "-X") == 0) {
1849 add_forward_param(pvar, "X");
1850 if (option+6 != 0) {
1851 strncpy_s(pvar->settings.X11Display,
1852 sizeof(pvar->settings.X11Display),
1853 option + 6, _TRUNCATE);
1854 }
1855 } else if (strcmp(option + 4, "-v") == 0) {
1856 pvar->settings.LogLevel = LOG_LEVEL_VERBOSE;
1857 } else if (_stricmp(option + 4, "-autologin") == 0 ||
1858 _stricmp(option + 4, "-autologon") == 0) {
1859 pvar->settings.TryDefaultAuth = TRUE;
1860 } else if (MATCH_STR_I(option + 4, "-agentconfirm=") == 0) {
1861 if ((_stricmp(option+18, "off") == 0) ||
1862 (_stricmp(option+18, "no") == 0) ||
1863 (_stricmp(option+18, "false") == 0) ||
1864 (_stricmp(option+18, "0") == 0) ||
1865 (_stricmp(option+18, "n") == 0)) {
1866 pvar->settings.ForwardAgentConfirm = 0;
1867 }
1868 else {
1869 pvar->settings.ForwardAgentConfirm = 1;
1870 }
1871 } else if (strcmp(option + 4, "-a") == 0) {
1872 pvar->settings.ForwardAgent = FALSE;
1873 } else if (strcmp(option + 4, "-A") == 0) {
1874 pvar->settings.ForwardAgent = TRUE;
1875
1876 } else if (MATCH_STR(option + 4, "-C=") == 0) {
1877 pvar->settings.CompressionLevel = atoi(option+7);
1878 if (pvar->settings.CompressionLevel < 0) {
1879 pvar->settings.CompressionLevel = 0;
1880 }
1881 else if (pvar->settings.CompressionLevel > 9) {
1882 pvar->settings.CompressionLevel = 9;
1883 }
1884 } else if (strcmp(option + 4, "-C") == 0) {
1885 pvar->settings.CompressionLevel = 6;
1886 } else if (strcmp(option + 4, "-c") == 0) {
1887 pvar->settings.CompressionLevel = 0;
1888 } else if (MATCH_STR_I(option + 4, "-icon=") == 0) {
1889 if ((_stricmp(option+10, "old") == 0) ||
1890 (_stricmp(option+10, "yellow") == 0) ||
1891 (_stricmp(option+10, "securett_yellow") == 0)) {
1892 pvar->settings.IconID = IDI_SECURETT_YELLOW;
1893 }
1894 else if ((_stricmp(option+10, "green") == 0) ||
1895 (_stricmp(option+10, "securett_green") == 0)) {
1896 pvar->settings.IconID = IDI_SECURETT_GREEN;
1897 }
1898 else {
1899 pvar->settings.IconID = IDI_SECURETT;
1900 }
1901 } else if (MATCH_STR(option + 4, "-subsystem=") == 0) {
1902 pvar->use_subsystem = TRUE;
1903 strncpy_s(pvar->subsystem_name,
1904 sizeof(pvar->subsystem_name),
1905 option + 15, _TRUNCATE);
1906 } else if (strcmp(option + 4, "-N") == 0) {
1907 pvar->nosession = TRUE;
1908
1909 // /ssh1 �� /ssh2 �I�v�V�������V�K���� (2006.9.16 maya)
1910 } else if (strcmp(option + 4, "1") == 0) {
1911 pvar->settings.Enabled = 1;
1912 pvar->settings.ssh_protocol_version = 1;
1913 } else if (strcmp(option + 4, "2") == 0) {
1914 pvar->settings.Enabled = 1;
1915 pvar->settings.ssh_protocol_version = 2;
1916
1917 } else {
1918 char buf[1024];
1919
1920 UTIL_get_lang_msg("MSG_UNKNOWN_OPTION_ERROR", pvar,
1921 "Unrecognized command-line option: %s");
1922 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, option);
1923
1924 MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
1925 }
1926
1927 // ttermpro.exe �� /T= �w�������p�������A������������ (2006.10.19 maya)
1928 } else if (MATCH_STR_I(option + 1, "t=") == 0) {
1929 if (strcmp(option + 3, "2") == 0) {
1930 pvar->settings.Enabled = 1;
1931 // /t=2��ttssh�������g������������
1932 } else {
1933 pvar->settings.Enabled = 0;
1934 action = OPTION_NONE; // Tera Term������������������������
1935 }
1936
1937 // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
1938 } else if (strcmp(option + 1, "1") == 0) {
1939 // command line: /ssh /1 is SSH1 only
1940 pvar->settings.ssh_protocol_version = 1;
1941
1942 } else if (strcmp(option + 1, "2") == 0) {
1943 // command line: /ssh /2 is SSH2 & SSH1
1944 pvar->settings.ssh_protocol_version = 2;
1945
1946 } else if (strcmp(option + 1, "nossh") == 0) {
1947 // '/nossh' �I�v�V�����������B
1948 // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
1949 // �����������������B(2004.10.11 yutaka)
1950 pvar->settings.Enabled = 0;
1951
1952 } else if (strcmp(option + 1, "telnet") == 0) {
1953 // '/telnet' ���w�������������������� '/nossh' ��������
1954 // SSH������������ (2006.9.16 maya)
1955 pvar->settings.Enabled = 0;
1956 // Tera Term �� Telnet �t���O���t����
1957 pvar->ts->Telnet = 1;
1958
1959 } else if (MATCH_STR(option + 1, "auth=") == 0) {
1960 // SSH2�������O�C���I�v�V����������
1961 //
1962 // SYNOPSIS: /ssh /auth=passowrd /user=���[�U�� /passwd=�p�X���[�h
1963 // /ssh /auth=publickey /user=���[�U�� /passwd=�p�X���[�h /keyfile=�p�X
1964 // EXAMPLE: /ssh /auth=password /user=nike /passwd="a b""c" ; �p�X���[�h: �ua b"c�v
1965 // /ssh /auth=publickey /user=foo /passwd=bar /keyfile=d:\tmp\id_rsa
1966 // NOTICE: �p�X���[�h���p�X���������Z�~�R���������������������_�u���N�H�[�g " ������
1967 // �p�X���[�h���_�u���N�H�[�g�����������������A�������_�u���N�H�[�g "" ���u��������
1968 //
1969 pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
1970
1971 if (_stricmp(option + 6, "password") == 0) { // �p�X���[�h
1972 //pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
1973 pvar->ssh2_authmethod = SSH_AUTH_PASSWORD;
1974
1975 } else if (_stricmp(option + 6, "keyboard-interactive") == 0) { // keyboard-interactive�F��
1976 //pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
1977 pvar->ssh2_authmethod = SSH_AUTH_TIS;
1978
1979 } else if (_stricmp(option + 6, "challenge") == 0) { // keyboard-interactive�F��
1980 //pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
1981 pvar->ssh2_authmethod = SSH_AUTH_TIS;
1982
1983 } else if (_stricmp(option + 6, "publickey") == 0) { // ���J���F��
1984 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1985 pvar->ssh2_authmethod = SSH_AUTH_RSA;
1986
1987 } else if (_stricmp(option + 6, "pageant") == 0) { // ���J���F�� by Pageant
1988 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1989 pvar->ssh2_authmethod = SSH_AUTH_PAGEANT;
1990
1991 } else {
1992 // TODO:
1993 }
1994
1995 } else if (MATCH_STR(option + 1, "user=") == 0) {
1996 _snprintf_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), _TRUNCATE, "%s", option+6);
1997
1998 } else if (MATCH_STR(option + 1, "passwd=") == 0) {
1999 _snprintf_s(pvar->ssh2_password, sizeof(pvar->ssh2_password), _TRUNCATE, "%s", option+8);
2000
2001 } else if (MATCH_STR(option + 1, "keyfile=") == 0) {
2002 _snprintf_s(pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile), _TRUNCATE, "%s", option+9);
2003
2004 } else if (strcmp(option + 1, "ask4passwd") == 0) {
2005 // �p�X���[�h������ (2006.9.18 maya)
2006 pvar->ask4passwd = 1;
2007
2008 } else if (strcmp(option + 1, "nosecuritywarning") == 0) {
2009 // known_hosts�`�F�b�N���������B���Y�I�v�V�������g�����A�Z�L�����e�B������������
2010 // �����A�B���I�v�V���������������B
2011 // (2009.10.4 yutaka)
2012 pvar->nocheck_known_hosts = TRUE;
2013
2014 }
2015 else { // Other (not ttssh) option
2016 action = OPTION_NONE; // ttssh���I�v�V������������������������
2017 }
2018
2019 // �p�X���[�h�������������������O�C��������������
2020 // /auth ���F�����\�b�h���w�������������p������ (2006.9.18 maya)
2021 if (pvar->ask4passwd == 1) {
2022 pvar->ssh2_autologin = 0;
2023 }
2024
2025 }
2026 else if ((MATCH_STR_I(option, "ssh://") == 0) ||
2027 (MATCH_STR_I(option, "ssh1://") == 0) ||
2028 (MATCH_STR_I(option, "ssh2://") == 0) ||
2029 (MATCH_STR_I(option, "slogin://") == 0) ||
2030 (MATCH_STR_I(option, "slogin1://") == 0) ||
2031 (MATCH_STR_I(option, "slogin2://") == 0)) {
2032 //
2033 // ssh://user@host/ ����URL�`�����T�|�[�g
2034 // ���{�I�������� telnet:// URL��������
2035 //
2036 // �Q�l:
2037 // RFC3986: Uniform Resource Identifier (URI): Generic Syntax
2038 // RFC4248: The telnet URI Scheme
2039 //
2040 char *p, *p2, *p3;
2041 int optlen, hostlen;
2042
2043 optlen = strlen(option);
2044
2045 // ������':'���O�����������������������A������ssh�v���g�R���o�[�W������������
2046 p = _mbschr(option, ':');
2047 switch (*(p-1)) {
2048 case '1':
2049 pvar->settings.ssh_protocol_version = 1;
2050 break;
2051 case '2':
2052 pvar->settings.ssh_protocol_version = 2;
2053 break;
2054 }
2055
2056 // authority part �����|�C���^������
2057 p += 3;
2058
2059 // path part ������������
2060 if ((p2 = _mbschr(p, '/')) != NULL) {
2061 *p2 = 0;
2062 }
2063
2064 // '@'�������������A���������O�����[�U����
2065 if ((p2 = _mbschr(p, '@')) != NULL) {
2066 *p2 = 0;
2067 // ':'���~���p�X���[�h
2068 if ((p3 = _mbschr(p, ':')) != NULL) {
2069 *p3 = 0;
2070 percent_decode(pvar->ssh2_password, sizeof(pvar->ssh2_password), p3 + 1);
2071 }
2072 percent_decode(pvar->ssh2_username, sizeof(pvar->ssh2_username), p);
2073 // p �� host part ������('@'����������)����������������
2074 p = p2 + 1;
2075 }
2076
2077 // host part �� option �����������������Ascheme part ������
2078 // port�w����������������port���������������������m��������������
2079 hostlen = strlen(p);
2080 memmove_s(option, optlen, p, hostlen);
2081 option[hostlen] = 0;
2082
2083 // �|�[�g�w������������":22"������
2084 if (option[0] == '[' && option[hostlen-1] == ']' || // IPv6 raw address without port
2085 option[0] != '[' && _mbschr(option, ':') == NULL) { // hostname or IPv4 raw address without port
2086 memcpy_s(option+hostlen, optlen-hostlen, ":22", 3);
2087 hostlen += 3;
2088 }
2089
2090 // �|�[�g�w�����������������X�y�[�X������
2091 memset(option+hostlen, ' ', optlen-hostlen);
2092
2093 pvar->settings.Enabled = 1;
2094
2095 action = OPTION_REPLACE;
2096 }
2097 else if (_mbschr(option, '@') != NULL) {
2098 //
2099 // user@host �`�����T�|�[�g
2100 // ����������ssh�������T�|�[�g�����A���[�U����ttssh���������B
2101 // (ssh�������O -- ttssh�������W������������)
2102 // �����I��telnet authentication option���T�|�[�g��������
2103 // Tera Term�{�����������������������\���B
2104 //
2105 char *p;
2106 p = _mbschr(option, '@');
2107 *p = 0;
2108
2109 strncpy_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), option, _TRUNCATE);
2110
2111 // ���[�U���������X�y�[�X�������B
2112 // ������TTX��Tera Term�{�������������������X�y�[�X�����������������A
2113 // �z�X�g�����������l�����K�v�������B
2114 memset(option, ' ', p-option+1);
2115
2116 action = OPTION_REPLACE;
2117 }
2118
2119
2120 switch (action) {
2121 case OPTION_CLEAR:
2122 memset(cur, ' ', next-cur);
2123 break;
2124 case OPTION_REPLACE:
2125 memset(cur, ' ', next-cur);
2126 memcpy(cur+1, option, strlen(option));
2127 break;
2128 }
2129
2130 cur = next;
2131 }
2132
2133 free(option);
2134
2135 FWDUI_load_settings(pvar);
2136
2137 (pvar->ParseParam) (param, ts, DDETopic);
2138 }
2139
2140 static void PASCAL TTXGetSetupHooks(TTXSetupHooks *hooks)
2141 {
2142 pvar->ReadIniFile = *hooks->ReadIniFile;
2143 pvar->WriteIniFile = *hooks->WriteIniFile;
2144 pvar->ParseParam = *hooks->ParseParam;
2145
2146 *hooks->ReadIniFile = TTXReadINIFile;
2147 *hooks->WriteIniFile = TTXWriteINIFile;
2148 *hooks->ParseParam = TTXParseParam;
2149 }
2150
2151 static void PASCAL TTXSetWinSize(int rows, int cols)
2152 {
2153 SSH_notify_win_size(pvar, cols, rows);
2154 }
2155
2156 static void insertMenuBeforeItem(HMENU menu, WORD beforeItemID, WORD flags,
2157 WORD newItemID, char *text)
2158 {
2159 int i, j;
2160
2161 for (i = GetMenuItemCount(menu) - 1; i >= 0; i--) {
2162 HMENU submenu = GetSubMenu(menu, i);
2163
2164 for (j = GetMenuItemCount(submenu) - 1; j >= 0; j--) {
2165 if (GetMenuItemID(submenu, j) == beforeItemID) {
2166 InsertMenu(submenu, j, MF_BYPOSITION | flags, newItemID, text);
2167 return;
2168 }
2169 }
2170 }
2171 }
2172
2173 #define GetFileMenu(menu) GetSubMenuByChildID(menu, 50110) // ID_FILE_NEWCONNECTION
2174 #define GetEditMenu(menu) GetSubMenuByChildID(menu, 50210) // ID_EDIT_COPY2
2175 #define GetSetupMenu(menu) GetSubMenuByChildID(menu, 50310) // ID_SETUP_TERMINAL
2176 #define GetControlMenu(menu) GetSubMenuByChildID(menu, 50410) // ID_CONTROL_RESETTERMINAL
2177 #define GetHelpMenu(menu) GetSubMenuByChildID(menu, 50990) // ID_HELP_ABOUT
2178
2179 HMENU GetSubMenuByChildID(HMENU menu, UINT id) {
2180 int i, j, items, subitems, cur_id;
2181 HMENU m;
2182
2183 items = GetMenuItemCount(menu);
2184
2185 for (i=0; i<items; i++) {
2186 if (m = GetSubMenu(menu, i)) {
2187 subitems = GetMenuItemCount(m);
2188 for (j=0; j<subitems; j++) {
2189 cur_id = GetMenuItemID(m, j);
2190 if (cur_id == id) {
2191 return m;
2192 }
2193 }
2194 }
2195 }
2196 return NULL;
2197 }
2198
2199 static void PASCAL TTXModifyMenu(HMENU menu)
2200 {
2201 pvar->FileMenu = GetFileMenu(menu);
2202
2203 /* inserts before ID_HELP_ABOUT */
2204 UTIL_get_lang_msg("MENU_ABOUT", pvar, "About &TTSSH...");
2205 insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU, pvar->ts->UIMsg);
2206
2207 /* inserts before ID_SETUP_TCPIP */
2208 UTIL_get_lang_msg("MENU_SSH", pvar, "SS&H...");
2209 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU, pvar->ts->UIMsg);
2210 /* inserts before ID_SETUP_TCPIP */
2211 UTIL_get_lang_msg("MENU_SSH_AUTH", pvar, "SSH &Authentication...");
2212 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU, pvar->ts->UIMsg);
2213 /* inserts before ID_SETUP_TCPIP */
2214 UTIL_get_lang_msg("MENU_SSH_FORWARD", pvar, "SSH F&orwarding...");
2215 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU, pvar->ts->UIMsg);
2216 UTIL_get_lang_msg("MENU_SSH_KEYGEN", pvar, "SSH KeyGe&nerator...");
2217 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHKEYGENMENU, pvar->ts->UIMsg);
2218
2219 /* inserts before ID_FILE_CHANGEDIR */
2220 UTIL_get_lang_msg("MENU_SSH_SCP", pvar, "SS&H SCP...");
2221 insertMenuBeforeItem(menu, 50170, MF_GRAYED, ID_SSHSCPMENU, pvar->ts->UIMsg);
2222 }
2223
2224 static void PASCAL TTXModifyPopupMenu(HMENU menu) {
2225 if (menu == pvar->FileMenu) {
2226 if (pvar->cv->Ready && pvar->socket != INVALID_SOCKET)
2227 EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_ENABLED);
2228 else
2229 EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_GRAYED);
2230 }
2231 }
2232
2233 static void about_dlg_set_abouttext(PTInstVar pvar, HWND dlg, digest_algorithm dgst_alg)
2234 {
2235 char buf[1024], buf2[2048];
2236 char *fp = NULL;
2237
2238 // TTSSH�_�C�A���O���\������SSH������������ (2004.10.30 yutaka)
2239 if (pvar->socket != INVALID_SOCKET) {
2240 buf2[0] = '\0';
2241
2242 if (SSHv1(pvar)) {
2243 UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID:");
2244 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2245 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2246 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
2247 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2248 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2249
2250 UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol:");
2251 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2252 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2253 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
2254 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2255 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2256
2257 UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:");
2258 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2259 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2260 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
2261 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2262 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2263
2264 UTIL_get_lang_msg("DLG_ABOUT_SERVERKEY", pvar, "Server keys:");
2265 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2266 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2267 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
2268 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2269 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2270
2271 UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication:");
2272 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2273 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2274 AUTH_get_auth_info(pvar, buf, sizeof(buf));
2275 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2276 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2277
2278 UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression:");
2279 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2280 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2281 SSH_get_compression_info(pvar, buf, sizeof(buf));
2282 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2283 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2284
2285 } else { // SSH2
2286 UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID:");
2287 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2288 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2289 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
2290 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2291 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2292
2293 UTIL_get_lang_msg("DLG_ABOUT_CLIENTID", pvar, "Client ID:");
2294 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2295 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2296 strncat_s(buf2, sizeof(buf2), pvar->client_version_string, _TRUNCATE);
2297 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2298
2299 UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol:");
2300 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2301 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2302 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
2303 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2304 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2305
2306 UTIL_get_lang_msg("DLG_ABOUT_KEX", pvar, "Key exchange algorithm:");
2307 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2308 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2309 strncat_s(buf2, sizeof(buf2), get_kex_algorithm_name(pvar->kex_type), _TRUNCATE);
2310 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2311
2312 UTIL_get_lang_msg("DLG_ABOUT_HOSTKEY", pvar, "Host Key:");
2313 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2314 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2315 strncat_s(buf2, sizeof(buf2), get_ssh_keytype_name(pvar->hostkey_type), _TRUNCATE);
2316 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2317
2318 UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:");
2319 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2320 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2321 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
2322 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2323 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2324
2325 UTIL_get_lang_msg("DLG_ABOUT_MAC", pvar, "MAC algorithm:");
2326 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2327 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2328 SSH_get_mac_info(pvar, buf, sizeof(buf));
2329 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2330 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2331
2332 if (pvar->ctos_compression == COMP_DELAYED) { // �x���p�P�b�g���k������ (2006.6.23 yutaka)
2333 UTIL_get_lang_msg("DLG_ABOUT_COMPDELAY", pvar, "Delayed Compression:");
2334 }
2335 else {
2336 UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression:");
2337 }
2338 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2339 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2340 SSH_get_compression_info(pvar, buf, sizeof(buf));
2341 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2342 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2343
2344 UTIL_get_lang_msg("DLG_ABOUT_KEXKEY", pvar, "Key exchange keys:");
2345 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2346 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2347 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
2348 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2349 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2350
2351 UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication:");
2352 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2353 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2354 AUTH_get_auth_info(pvar, buf, sizeof(buf));
2355 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2356 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2357 }
2358
2359 // �z�X�g���J����fingerprint���\�������B
2360 // (2014.5.1 yutaka)
2361 UTIL_get_lang_msg("DLG_ABOUT_FINGERPRINT", pvar, "Host key's fingerprint:");
2362 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2363 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2364
2365 switch (dgst_alg) {
2366 case SSH_DIGEST_MD5:
2367 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX, dgst_alg);
2368 strncat_s(buf2, sizeof(buf2), fp, _TRUNCATE);
2369 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2370 free(fp);
2371 break;
2372 case SSH_DIGEST_SHA256:
2373 default:
2374 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_BASE64, SSH_DIGEST_SHA256);
2375 if (fp != NULL) {
2376 strncat_s(buf2, sizeof(buf2), fp, _TRUNCATE);
2377 free(fp);
2378 }
2379 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2380 break;
2381 }
2382
2383 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART, dgst_alg);
2384 strncat_s(buf2, sizeof(buf2), fp, _TRUNCATE);
2385 free(fp);
2386
2387 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, WM_SETTEXT, 0, (LPARAM)(char *)buf2);
2388 }
2389 }
2390
2391 static void init_about_dlg(PTInstVar pvar, HWND dlg)
2392 {
2393 char buf[1024];
2394 char uimsg[MAX_UIMSG];
2395
2396 GetWindowText(dlg, uimsg, sizeof(uimsg));
2397 UTIL_get_lang_msg("DLG_ABOUT_TITLE", pvar, uimsg);
2398 SetWindowText(dlg, pvar->ts->UIMsg);
2399 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2400 UTIL_get_lang_msg("DLG_ABOUT_FP_HASH_ALGORITHM", pvar, uimsg);
2401 SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2402 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2403 UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
2404 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2405
2406 // TTSSH���o�[�W�������������� (2005.2.28 yutaka)
2407 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2408 "TTSSH\r\nTera Term Secure Shell extension, %d.%d", TTSSH_VERSION_MAJOR, TTSSH_VERSION_MINOR);
2409 SendMessage(GetDlgItem(dlg, IDC_TTSSH_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2410
2411 // OpenSSL���o�[�W�������������� (2005.1.24 yutaka)
2412 // ���������� (2005.5.11 yutaka)
2413 // OPENSSL_VERSION_TEXT �}�N�����`���������A�������g�����o�[�W���������������B(2013.11.24 yutaka)
2414 SendMessage(GetDlgItem(dlg, IDC_OPENSSL_VERSION), WM_SETTEXT, 0, (LPARAM)SSLeay_version(SSLEAY_VERSION));
2415
2416 // zlib���o�[�W�������������� (2005.5.11 yutaka)
2417 #ifdef ZLIB_VERSION
2418 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "ZLib %s", ZLIB_VERSION);
2419 #else
2420 _snprintf(buf, sizeof(buf), "ZLib Unknown");
2421 #endif
2422 SendMessage(GetDlgItem(dlg, IDC_ZLIB_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2423
2424 // PuTTY���o�[�W�������������� (2011.7.26 yutaka)
2425 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "PuTTY %s", putty_get_version());
2426 SendMessage(GetDlgItem(dlg, IDC_PUTTY_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2427 }
2428
2429 #if 0
2430 // WM_MOUSEWHEEL �� winuser.h �w�b�_���������������������A#define _WIN32_WINNT 0x0400 ���������������������F�������������B
2431 #define WM_MOUSEWHEEL 0x020A1
2432 #define WHEEL_DELTA 120
2433 #define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
2434 #define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam))
2435 #endif
2436
2437 static WNDPROC g_defAboutDlgEditWndProc; // Edit Control���T�u�N���X���p
2438 static int g_deltaSumAboutDlg = 0; // �}�E�X�z�C�[����Delta�����p
2439
2440 static LRESULT CALLBACK AboutDlgEditWindowProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
2441 {
2442 WORD keys;
2443 short delta;
2444 BOOL page;
2445
2446 switch (msg) {
2447 case WM_KEYDOWN:
2448 // Edit control���� CTRL+A �������������A�e�L�X�g���S�I�������B
2449 if (wp == 'A' && GetKeyState(VK_CONTROL) < 0) {
2450 PostMessage(hWnd, EM_SETSEL, 0, -1);
2451 return 0;
2452 }
2453 break;
2454
2455 case WM_MOUSEWHEEL:
2456 // CTRLorSHIFT + �}�E�X�z�C�[���������A���X�N���[���������B
2457 keys = GET_KEYSTATE_WPARAM(wp);
2458 delta = GET_WHEEL_DELTA_WPARAM(wp);
2459 page = keys & (MK_CONTROL | MK_SHIFT);
2460
2461 if (page == 0)
2462 break;
2463
2464 g_deltaSumAboutDlg += delta;
2465
2466 if (g_deltaSumAboutDlg >= WHEEL_DELTA) {
2467 g_deltaSumAboutDlg -= WHEEL_DELTA;
2468 SendMessage(hWnd, WM_HSCROLL, SB_PAGELEFT , 0);
2469 } else if (g_deltaSumAboutDlg <= -WHEEL_DELTA) {
2470 g_deltaSumAboutDlg += WHEEL_DELTA;
2471 SendMessage(hWnd, WM_HSCROLL, SB_PAGERIGHT, 0);
2472 }
2473
2474 break;
2475 }
2476 return CallWindowProc(g_defAboutDlgEditWndProc, hWnd, msg, wp, lp);
2477 }
2478
2479 static BOOL CALLBACK TTXAboutDlg(HWND dlg, UINT msg, WPARAM wParam,
2480 LPARAM lParam)
2481 {
2482 // LOGFONTA logfont;
2483 // HFONT font;
2484
2485 switch (msg) {
2486 case WM_INITDIALOG:
2487 #if 0
2488 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2489 GetObject(font, sizeof(LOGFONT), &logfont);
2490 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgAboutFont, pvar)) {
2491 SendDlgItemMessage(dlg, IDC_TTSSH_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2492 SendDlgItemMessage(dlg, IDC_SSHVERSIONS, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2493 SendDlgItemMessage(dlg, IDC_INCLUDES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2494 SendDlgItemMessage(dlg, IDC_OPENSSL_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2495 SendDlgItemMessage(dlg, IDC_ZLIB_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2496 SendDlgItemMessage(dlg, IDC_PUTTY_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE, 0));
2497 SendDlgItemMessage(dlg, IDC_WEBSITES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE, 0));
2498 SendDlgItemMessage(dlg, IDC_CRYPTOGRAPHY, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2499 SendDlgItemMessage(dlg, IDC_CREDIT, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2500 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE, 0));
2501 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE, 0));
2502 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE, 0));
2503 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2504 }
2505 else {
2506 DlgAboutFont = NULL;
2507 }
2508 #endif
2509
2510 // Edit control�������t�H���g���\�������������A���������������t�H���g���Z�b�g�����B
2511 // (2014.5.5. yutaka)
2512 if (!UTIL_get_lang_font("DLG_ABOUT_FONT", dlg, NULL, &DlgAboutTextFont, pvar)) {
2513 // ���������������������������t�H���g���w�������B
2514 // �G�f�B�b�g�R���g���[�����_�C�A���O�������t�H���g������������
2515 // �����t�H���g�������������B
2516 LOGFONTA logfont = {0};
2517 strncpy_s(logfont.lfFaceName, sizeof(logfont.lfFaceName), "Courier New", _TRUNCATE);
2518 logfont.lfCharSet = 0;
2519 logfont.lfHeight = MulDiv(8, GetDeviceCaps(GetDC(dlg),LOGPIXELSY) * -1, 72);
2520 logfont.lfWidth = 0;
2521 DlgAboutTextFont = CreateFontIndirect(&logfont); // �G���[�� NULL
2522 }
2523 if (DlgAboutTextFont != NULL) {
2524 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, WM_SETFONT, (WPARAM)DlgAboutTextFont, MAKELPARAM(TRUE,0));
2525 }
2526
2527 // �A�C�R�������I���Z�b�g
2528 {
2529 int fuLoad = LR_DEFAULTCOLOR;
2530 HICON hicon;
2531
2532 if (IsWindowsNT4()) {
2533 fuLoad = LR_VGACOLOR;
2534 }
2535
2536 hicon = LoadImage(hInst, MAKEINTRESOURCE(pvar->settings.IconID),
2537 IMAGE_ICON, 32, 32, fuLoad);
2538 SendDlgItemMessage(dlg, IDC_TTSSH_ICON, STM_SETICON, (WPARAM)hicon, 0);
2539 }
2540
2541 init_about_dlg(pvar, dlg);
2542 CheckDlgButton(dlg, IDC_FP_HASH_ALG_SHA256, TRUE);
2543 about_dlg_set_abouttext(pvar, dlg, SSH_DIGEST_SHA256);
2544 SetFocus(GetDlgItem(dlg, IDOK));
2545
2546 // Edit control���T�u�N���X�������B
2547 g_deltaSumAboutDlg = 0;
2548 g_defAboutDlgEditWndProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(dlg, IDC_ABOUTTEXT), GWLP_WNDPROC, (LONG_PTR)AboutDlgEditWindowProc);
2549
2550 CenterWindow(dlg, GetParent(dlg));
2551
2552 return FALSE;
2553
2554 case WM_COMMAND:
2555 switch (LOWORD(wParam)) {
2556 case IDOK:
2557 EndDialog(dlg, 1);
2558 #if 0
2559 if (DlgAboutFont != NULL) {
2560 DeleteObject(DlgAboutFont);
2561 }
2562 #endif
2563 if (DlgAboutTextFont != NULL) {
2564 DeleteObject(DlgAboutTextFont);
2565 }
2566 return TRUE;
2567 case IDCANCEL: /* there isn't a cancel button, but other Windows
2568 UI things can send this message */
2569 EndDialog(dlg, 0);
2570 #if 0
2571 if (DlgAboutFont != NULL) {
2572 DeleteObject(DlgAboutFont);
2573 }
2574 #endif
2575 if (DlgAboutTextFont != NULL) {
2576 DeleteObject(DlgAboutTextFont);
2577 }
2578 return TRUE;
2579 case IDC_FP_HASH_ALG_MD5:
2580 about_dlg_set_abouttext(pvar, dlg, SSH_DIGEST_MD5);
2581 return TRUE;
2582 case IDC_FP_HASH_ALG_SHA256:
2583 about_dlg_set_abouttext(pvar, dlg, SSH_DIGEST_SHA256);
2584 return TRUE;
2585 }
2586 break;
2587 }
2588
2589 return FALSE;
2590 }
2591
2592 static char *get_cipher_name(int cipher)
2593 {
2594 switch (cipher) {
2595 case SSH_CIPHER_NONE:
2596 UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_BORDER", pvar,
2597 "<ciphers below this line are disabled>");
2598 return pvar->ts->UIMsg;
2599 case SSH_CIPHER_3DES:
2600 return "3DES(SSH1)";
2601 case SSH_CIPHER_DES:
2602 return "DES(SSH1)";
2603 case SSH_CIPHER_BLOWFISH:
2604 return "Blowfish(SSH1)";
2605
2606 // for SSH2(yutaka)
2607 case SSH2_CIPHER_AES128_CBC:
2608 return "aes128-cbc(SSH2)";
2609 case SSH2_CIPHER_AES192_CBC:
2610 return "aes192-cbc(SSH2)";
2611 case SSH2_CIPHER_AES256_CBC:
2612 return "aes256-cbc(SSH2)";
2613 case SSH2_CIPHER_3DES_CBC:
2614 return "3des-cbc(SSH2)";
2615 case SSH2_CIPHER_BLOWFISH_CBC:
2616 return "blowfish-cbc(SSH2)";
2617 case SSH2_CIPHER_AES128_CTR:
2618 return "aes128-ctr(SSH2)";
2619 case SSH2_CIPHER_AES192_CTR:
2620 return "aes192-ctr(SSH2)";
2621 case SSH2_CIPHER_AES256_CTR:
2622 return "aes256-ctr(SSH2)";
2623 case SSH2_CIPHER_ARCFOUR:
2624 return "arcfour(SSH2)";
2625 case SSH2_CIPHER_ARCFOUR128:
2626 return "arcfour128(SSH2)";
2627 case SSH2_CIPHER_ARCFOUR256:
2628 return "arcfour256(SSH2)";
2629 case SSH2_CIPHER_CAST128_CBC:
2630 return "cast128-cbc(SSH2)";
2631 case SSH2_CIPHER_3DES_CTR:
2632 return "3des-ctr(SSH2)";
2633 case SSH2_CIPHER_BLOWFISH_CTR:
2634 return "blowfish-ctr(SSH2)";
2635 case SSH2_CIPHER_CAST128_CTR:
2636 return "cast128-ctr(SSH2)";
2637 case SSH2_CIPHER_CAMELLIA128_CBC:
2638 return "camellia128-cbc(SSH2)";
2639 case SSH2_CIPHER_CAMELLIA192_CBC:
2640 return "camellia192-cbc(SSH2)";
2641 case SSH2_CIPHER_CAMELLIA256_CBC:
2642 return "camellia256-cbc(SSH2)";
2643 case SSH2_CIPHER_CAMELLIA128_CTR:
2644 return "camellia128-ctr(SSH2)";
2645 case SSH2_CIPHER_CAMELLIA192_CTR:
2646 return "camellia192-ctr(SSH2)";
2647 case SSH2_CIPHER_CAMELLIA256_CTR:
2648 return "camellia256-ctr(SSH2)";
2649 case SSH2_CIPHER_AES128_GCM:
2650 return "aes128-gcm@openssh.com(SSH2)";
2651 case SSH2_CIPHER_AES256_GCM:
2652 return "aes256-gcm@openssh.com(SSH2)";
2653
2654 default:
2655 return NULL;
2656 }
2657 }
2658
2659 static void set_move_button_status(HWND dlg, int type, int up, int down)
2660 {
2661 HWND cipherControl = GetDlgItem(dlg, type);
2662 int curPos = (int) SendMessage(cipherControl, LB_GETCURSEL, 0, 0);
2663 int maxPos = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0) - 1;
2664
2665 EnableWindow(GetDlgItem(dlg, up),
2666 curPos > 0 && curPos <= maxPos);
2667 EnableWindow(GetDlgItem(dlg, down),
2668 curPos >= 0 && curPos < maxPos);
2669 }
2670
2671 static void init_setup_dlg(PTInstVar pvar, HWND dlg)
2672 {
2673 HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
2674 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
2675 HWND kexControl = GetDlgItem(dlg, IDC_SSHKEX_LIST);
2676 HWND hostkeyControl = GetDlgItem(dlg, IDC_SSHHOST_KEY_LIST);
2677 HWND macControl = GetDlgItem(dlg, IDC_SSHMAC_LIST);
2678 HWND compControl = GetDlgItem(dlg, IDC_SSHCOMP_LIST);
2679 HWND hostkeyRotationControl = GetDlgItem(dlg, IDC_HOSTKEY_ROTATION_STATIC);
2680 HWND hostkeyRotationControlList = GetDlgItem(dlg, IDC_HOSTKEY_ROTATION_COMBO);
2681 int i;
2682 int ch;
2683 char uimsg[MAX_UIMSG];
2684 char *rotationItem[SSH_UPDATE_HOSTKEYS_MAX] = {
2685 "No",
2686 "Yes",
2687 "Ask",
2688 };
2689 char *rotationItemKey[SSH_UPDATE_HOSTKEYS_MAX] = {
2690 "DLG_SSHSETUP_HOSTKEY_ROTATION_NO",
2691 "DLG_SSHSETUP_HOSTKEY_ROTATION_YES",
2692 "DLG_SSHSETUP_HOSTKEY_ROTATION_ASK",
2693 };
2694
2695 GetWindowText(dlg, uimsg, sizeof(uimsg));
2696 UTIL_get_lang_msg("DLG_SSHSETUP_TITLE", pvar, uimsg);
2697 SetWindowText(dlg, pvar->ts->UIMsg);
2698 GetDlgItemText(dlg, IDC_COMPRESSLABEL, uimsg, sizeof(uimsg));
2699 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS", pvar, uimsg);
2700 SetDlgItemText(dlg, IDC_COMPRESSLABEL, pvar->ts->UIMsg);
2701 GetDlgItemText(dlg, IDC_COMPRESSNONE, uimsg, sizeof(uimsg));
2702 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_NONE", pvar, uimsg);
2703 SetDlgItemText(dlg, IDC_COMPRESSNONE, pvar->ts->UIMsg);
2704 GetDlgItemText(dlg, IDC_COMPRESSHIGH, uimsg, sizeof(uimsg));
2705 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_HIGHEST", pvar, uimsg);
2706 SetDlgItemText(dlg, IDC_COMPRESSHIGH, pvar->ts->UIMsg);
2707 GetDlgItemText(dlg, IDC_COMPRESSNOTE, uimsg, sizeof(uimsg));
2708 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_NOTE", pvar, uimsg);
2709 SetDlgItemText(dlg, IDC_COMPRESSNOTE, pvar->ts->UIMsg);
2710
2711 GetDlgItemText(dlg, IDC_CIPHERORDER, uimsg, sizeof(uimsg));
2712 UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER", pvar, uimsg);
2713 SetDlgItemText(dlg, IDC_CIPHERORDER, pvar->ts->UIMsg);
2714 GetDlgItemText(dlg, IDC_SSHMOVECIPHERUP, uimsg, sizeof(uimsg));
2715 UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_UP", pvar, uimsg);
2716 SetDlgItemText(dlg, IDC_SSHMOVECIPHERUP, pvar->ts->UIMsg);
2717 GetDlgItemText(dlg, IDC_SSHMOVECIPHERDOWN, uimsg, sizeof(uimsg));
2718 UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_DOWN", pvar, uimsg);
2719 SetDlgItemText(dlg, IDC_SSHMOVECIPHERDOWN, pvar->ts->UIMsg);
2720
2721 GetDlgItemText(dlg, IDC_KEX_ORDER, uimsg, sizeof(uimsg));
2722 UTIL_get_lang_msg("DLG_SSHSETUP_KEX", pvar, uimsg);
2723 SetDlgItemText(dlg, IDC_KEX_ORDER, pvar->ts->UIMsg);
2724 GetDlgItemText(dlg, IDC_SSHKEX_MOVEUP, uimsg, sizeof(uimsg));
2725 UTIL_get_lang_msg("DLG_SSHSETUP_KEX_UP", pvar, uimsg);
2726 SetDlgItemText(dlg, IDC_SSHKEX_MOVEUP, pvar->ts->UIMsg);
2727 GetDlgItemText(dlg, IDC_SSHKEX_MOVEDOWN, uimsg, sizeof(uimsg));
2728 UTIL_get_lang_msg("DLG_SSHSETUP_KEX_DOWN", pvar, uimsg);
2729 SetDlgItemText(dlg, IDC_SSHKEX_MOVEDOWN, pvar->ts->UIMsg);
2730
2731 GetDlgItemText(dlg, IDC_HOST_KEY_ORDER, uimsg, sizeof(uimsg));
2732 UTIL_get_lang_msg("DLG_SSHSETUP_HOST_KEY", pvar, uimsg);
2733 SetDlgItemText(dlg, IDC_HOST_KEY_ORDER, pvar->ts->UIMsg);
2734 GetDlgItemText(dlg, IDC_SSHHOST_KEY_MOVEUP, uimsg, sizeof(uimsg));
2735 UTIL_get_lang_msg("DLG_SSHSETUP_HOST_KEY_UP", pvar, uimsg);
2736 SetDlgItemText(dlg, IDC_SSHHOST_KEY_MOVEUP, pvar->ts->UIMsg);
2737 GetDlgItemText(dlg, IDC_SSHHOST_KEY_MOVEDOWN, uimsg, sizeof(uimsg));
2738 UTIL_get_lang_msg("DLG_SSHSETUP_HOST_KEY_DOWN", pvar, uimsg);
2739 SetDlgItemText(dlg, IDC_SSHHOST_KEY_MOVEDOWN, pvar->ts->UIMsg);
2740
2741 GetDlgItemText(dlg, IDC_MAC_ORDER, uimsg, sizeof(uimsg));
2742 UTIL_get_lang_msg("DLG_SSHSETUP_MAC", pvar, uimsg);
2743 SetDlgItemText(dlg, IDC_MAC_ORDER, pvar->ts->UIMsg);
2744 GetDlgItemText(dlg, IDC_SSHMAC_MOVEUP, uimsg, sizeof(uimsg));
2745 UTIL_get_lang_msg("DLG_SSHSETUP_MAC_UP", pvar, uimsg);
2746 SetDlgItemText(dlg, IDC_SSHMAC_MOVEUP, pvar->ts->UIMsg);
2747 GetDlgItemText(dlg, IDC_SSHMAC_MOVEDOWN, uimsg, sizeof(uimsg));
2748 UTIL_get_lang_msg("DLG_SSHSETUP_MAC_DOWN", pvar, uimsg);
2749 SetDlgItemText(dlg, IDC_SSHMAC_MOVEDOWN, pvar->ts->UIMsg);
2750
2751 GetDlgItemText(dlg, IDC_COMP_ORDER, uimsg, sizeof(uimsg));
2752 UTIL_get_lang_msg("DLG_SSHSETUP_COMP", pvar, uimsg);
2753 SetDlgItemText(dlg, IDC_COMP_ORDER, pvar->ts->UIMsg);
2754 GetDlgItemText(dlg, IDC_SSHCOMP_MOVEUP, uimsg, sizeof(uimsg));
2755 UTIL_get_lang_msg("DLG_SSHSETUP_COMP_UP", pvar, uimsg);
2756 SetDlgItemText(dlg, IDC_SSHCOMP_MOVEUP, pvar->ts->UIMsg);
2757 GetDlgItemText(dlg, IDC_SSHCOMP_MOVEDOWN, uimsg, sizeof(uimsg));
2758 UTIL_get_lang_msg("DLG_SSHSETUP_COMP_DOWN", pvar, uimsg);
2759 SetDlgItemText(dlg, IDC_SSHCOMP_MOVEDOWN, pvar->ts->UIMsg);
2760
2761 GetDlgItemText(dlg, IDC_KNOWNHOSTS, uimsg, sizeof(uimsg));
2762 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST", pvar, uimsg);
2763 SetDlgItemText(dlg, IDC_KNOWNHOSTS, pvar->ts->UIMsg);
2764 GetDlgItemText(dlg, IDC_CHOOSEREADWRITEFILE, uimsg, sizeof(uimsg));
2765 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST_RW", pvar, uimsg);
2766 SetDlgItemText(dlg, IDC_CHOOSEREADWRITEFILE, pvar->ts->UIMsg);
2767 GetDlgItemText(dlg, IDC_CHOOSEREADONLYFILE, uimsg, sizeof(uimsg));
2768 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST_RO", pvar, uimsg);
2769 SetDlgItemText(dlg, IDC_CHOOSEREADONLYFILE, pvar->ts->UIMsg);
2770 GetDlgItemText(dlg, IDC_HEARTBEATLABEL, uimsg, sizeof(uimsg));
2771 UTIL_get_lang_msg("DLG_SSHSETUP_HEARTBEAT", pvar, uimsg);
2772 SetDlgItemText(dlg, IDC_HEARTBEATLABEL, pvar->ts->UIMsg);
2773 GetDlgItemText(dlg, IDC_HEARTBEATLABEL2, uimsg, sizeof(uimsg));
2774 UTIL_get_lang_msg("DLG_SSHSETUP_HEARTBEAT_UNIT", pvar, uimsg);
2775 SetDlgItemText(dlg, IDC_HEARTBEATLABEL2, pvar->ts->UIMsg);
2776 GetDlgItemText(dlg, IDC_REMEMBERPASSWORD, uimsg, sizeof(uimsg));
2777 UTIL_get_lang_msg("DLG_SSHSETUP_PASSWORD", pvar, uimsg);
2778 SetDlgItemText(dlg, IDC_REMEMBERPASSWORD, pvar->ts->UIMsg);
2779 GetDlgItemText(dlg, IDC_FORWARDAGENT, uimsg, sizeof(uimsg));
2780 UTIL_get_lang_msg("DLG_SSHSETUP_FORWARDAGENT", pvar, uimsg);
2781 SetDlgItemText(dlg, IDC_FORWARDAGENT, pvar->ts->UIMsg);
2782 GetDlgItemText(dlg, IDC_FORWARDAGENTCONFIRM, uimsg, sizeof(uimsg));
2783 UTIL_get_lang_msg("DLG_SSHSETUP_FORWARDAGENTCONFIRM", pvar, uimsg);
2784 SetDlgItemText(dlg, IDC_FORWARDAGENTCONFIRM, pvar->ts->UIMsg);
2785 GetDlgItemText(dlg, IDC_FORWARDAGENTNOTIFY, uimsg, sizeof(uimsg));
2786 UTIL_get_lang_msg("DLG_SSHSETUP_FORWARDAGENTNOTIFY", pvar, uimsg);
2787 SetDlgItemText(dlg, IDC_FORWARDAGENTNOTIFY, pvar->ts->UIMsg);
2788 GetDlgItemText(dlg, IDC_VERIFYHOSTKEYDNS, uimsg, sizeof(uimsg));
2789 UTIL_get_lang_msg("DLG_SSHSETUP_VERIFYHOSTKEYDNS", pvar, uimsg);
2790 SetDlgItemText(dlg, IDC_VERIFYHOSTKEYDNS, pvar->ts->UIMsg);
2791 GetDlgItemText(dlg, IDC_NOTICEBANNER, uimsg, sizeof(uimsg));
2792 UTIL_get_lang_msg("DLG_SSHSETUP_NOTICE", pvar, uimsg);
2793 SetDlgItemText(dlg, IDC_NOTICEBANNER, pvar->ts->UIMsg);
2794 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2795 UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
2796 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2797 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2798 UTIL_get_lang_msg("BTN_CANCEL", pvar, uimsg);
2799 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2800
2801 GetDlgItemText(dlg, IDC_HOSTKEY_ROTATION_STATIC, uimsg, sizeof(uimsg));
2802 UTIL_get_lang_msg("DLG_SSHSETUP_HOSTKEY_ROTATION", pvar, uimsg);
2803 SetDlgItemText(dlg, IDC_HOSTKEY_ROTATION_STATIC, pvar->ts->UIMsg);
2804
2805 SendMessage(compressionControl, TBM_SETRANGE, TRUE, MAKELONG(0, 9));
2806 SendMessage(compressionControl, TBM_SETPOS, TRUE,
2807 pvar->settings.CompressionLevel);
2808
2809 // Cipher order
2810 normalize_cipher_order(pvar->settings.CipherOrder);
2811
2812 for (i = 0; pvar->settings.CipherOrder[i] != 0; i++) {
2813 int cipher = pvar->settings.CipherOrder[i] - '0';
2814 char *name = get_cipher_name(cipher);
2815
2816 if (name != NULL) {
2817 SendMessage(cipherControl, LB_ADDSTRING, 0, (LPARAM) name);
2818 }
2819 }
2820
2821 SendMessage(cipherControl, LB_SETCURSEL, 0, 0);
2822 set_move_button_status(dlg, IDC_SSHCIPHERPREFS, IDC_SSHMOVECIPHERUP, IDC_SSHMOVECIPHERDOWN);
2823
2824 // KEX order
2825 normalize_kex_order(pvar->settings.KexOrder);
2826 for (i = 0; pvar->settings.KexOrder[i] != 0; i++) {
2827 int index = pvar->settings.KexOrder[i] - '0';
2828 char *name = NULL;
2829
2830 if (index == 0) {
2831 UTIL_get_lang_msg("DLG_SSHSETUP_KEX_BORDER", pvar,
2832 "<KEXs below this line are disabled>");
2833 name = pvar->ts->UIMsg;
2834 } else {
2835 name = get_kex_algorithm_name(index);
2836 }
2837
2838 if (name != NULL) {
2839 SendMessage(kexControl, LB_ADDSTRING, 0, (LPARAM) name);
2840 }
2841 }
2842 SendMessage(kexControl, LB_SETCURSEL, 0, 0);
2843 set_move_button_status(dlg, IDC_SSHKEX_LIST, IDC_SSHKEX_MOVEUP, IDC_SSHKEX_MOVEDOWN);
2844
2845 // Host Key order
2846 normalize_host_key_order(pvar->settings.HostKeyOrder);
2847 for (i = 0; pvar->settings.HostKeyOrder[i] != 0; i++) {
2848 int index = pvar->settings.HostKeyOrder[i] - '0';
2849 char *name = NULL;
2850
2851 if (index == 0) {
2852 UTIL_get_lang_msg("DLG_SSHSETUP_HOST_KEY_BORDER", pvar,
2853 "<Host Keys below this line are disabled>");
2854 name = pvar->ts->UIMsg;
2855 } else {
2856 name = get_ssh_keytype_name(index);
2857 }
2858
2859 if (name != NULL) {
2860 SendMessage(hostkeyControl, LB_ADDSTRING, 0, (LPARAM) name);
2861 }
2862 }
2863 SendMessage(hostkeyControl, LB_SETCURSEL, 0, 0);
2864 set_move_button_status(dlg, IDC_SSHHOST_KEY_LIST, IDC_SSHHOST_KEY_MOVEUP, IDC_SSHHOST_KEY_MOVEDOWN);
2865
2866 // MAC order
2867 normalize_mac_order(pvar->settings.MacOrder);
2868 for (i = 0; pvar->settings.MacOrder[i] != 0; i++) {
2869 int index = pvar->settings.MacOrder[i] - '0';
2870 char *name = NULL;
2871
2872 if (index == 0) {
2873 UTIL_get_lang_msg("DLG_SSHSETUP_MAC_BORDER", pvar,
2874 "<MACs below this line are disabled>");
2875 name = pvar->ts->UIMsg;
2876 } else {
2877 name = get_ssh2_mac_name_by_id(index);
2878 }
2879