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 8093 - (show annotations) (download) (as text)
Sun Sep 8 10:16:41 2019 UTC (4 years, 7 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 177170 byte(s)
・known_hostsダイアログおよびユーザ認証ダイアログの表示中に、SSHサーバ側からネットワーク切断された場合、ダイアログを自動で閉じるようにした。
・known_hostsダイアログの表示中にSSHサーバ側からネットワーク切断されると、アプリがクラッシュすることがある問題を修正した。
・SSH1: /nosecuritywarningオプションが機能していなかった問題を修正した。
・/nosecuritywarningオプションに関する注意事項を追記した。

branches/ttssh_improvedからリビジョン8036をマージ:
SSHサーバと認証中にネットワーク切断された場合、認証ダイアログが残ったままとならないようにした。

........
branches/ttssh_improvedからリビジョン8044をマージ:
r8036でダイアログの処理追加漏れ。
SSHサーバと認証中にネットワーク切断された場合、認証ダイアログが残ったままとならないようにした。

........

branches/ttssh_improvedからリビジョン8063をマージ:
known_hostsダイアログが表示されている状態で、サーバから切断を行うと、
TTXCloseTCPが呼び出され、TTSSHのリソースが解放されてしまう。
SSHハンドラの延長でknown_hostsダイアログを出して止まっているため、
ダイアログを閉じて、処理再開すると、SSHの内部情報が壊れる。
その状態で再度SSH接続しようとすると100%アプリが落ちる。

上記問題に対して、まずは SSH1 に処置した。

........

branches/ttssh_improvedからリビジョン8081をマージ:
known_hostsダイアログが表示されている状態で、サーバから切断を行うと、
TTXCloseTCPが呼び出され、TTSSHのリソースが解放されてしまう。
SSHハンドラの延長でknown_hostsダイアログを出して止まっているため、
ダイアログを閉じて、処理再開すると、SSHの内部情報が壊れる。
その状態で再度SSH接続しようとすると100%アプリが落ちる。

上記問題に対して、SSH2 に対応した。

パケット受信時のSSHハンドラのコンテキストで known_hosts ダイアログを表示
させていたが、TTXCloseTCPの非同期呼び出しに対処できないため、
TTSSH1で使われていたknown_hosts ダイアログの非同期呼び出しに
実装を変更した。
これにより、比較的大きくロジックの修正を行っている。

........

branches/ttssh_improvedからリビジョン8085をマージ:
前回のオプション指定(/nosecuritywarning)が残らないように初期化する。
........


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