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