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