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 7363 - (show annotations) (download) (as text)
Tue Dec 25 05:46:12 2018 UTC (5 years, 3 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 184536 byte(s)
SSH 接続で、セッションを開かずに接続のみ出来るようにした。

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