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 7454 - (show annotations) (download) (as text)
Fri Mar 1 10:20:15 2019 UTC (5 years, 1 month ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 184632 byte(s)
TERATERM.INI の保存時に CipherOrder/MacOrder の末尾にゴミが入るのを修正 #39001

使っていない方式(SSH_CIPHER_IDEA等)のダミーエントリを書き込んでいた。
ダミーエントリは disabled_line のエントリと同じ値なので、通常は既に
存在するとして無視されるが、設定に disabled_line のエントリが含まれて
いない場合にダミーエントリがすべて設定に追加されていた。

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