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 7006 - (show annotations) (download) (as text)
Mon Dec 18 11:06:09 2017 UTC (6 years, 3 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 184040 byte(s)
MAC 方式の管理を、暗号方式を表す値(hmac_type)から ssh2_macs 内のエントリへのポインタを使うように変更。

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