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