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 6712 - (show annotations) (download) (as text)
Fri May 12 12:41:35 2017 UTC (6 years, 11 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 188521 byte(s)
SSH 設定ダイアログを開いた時にエージェント転送が無効の場合はエージェント通知をグレーアウトするようにした。

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