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 6969 - (show annotations) (download) (as text)
Thu Nov 2 11:37:41 2017 UTC (6 years, 5 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 183855 byte(s)
OpenSSH の EtM 方式の MAC に対応。#31495

以下の MAC 方式に対応。
  ・hmac-sha2-256-etm@openssh.comhmac-sha2-512-etm@openssh.comhmac-sha1-etm@openssh.comhmac-md5-etm@openssh.com (*1)
  ・hmac-ripemd160-etm@openssh.com (*1, *2)
  ・hmac-sha1-96-etm@openssh.com (*1, *3)
  ・hmac-md5-96-etm@openssh.com (*1, *3)

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