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