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