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