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