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 8086 - (show annotations) (download) (as text)
Sat Sep 7 12:18:28 2019 UTC (4 years, 7 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 174874 byte(s)
チケット38959
ユーザ認証ダイアログの表示タイミングをknown_hostsダイアログの後に変更した。

branches/ttssh_improvedからリビジョン8027をマージ:
ProxyやNAT経由でサーバに接続できない場合、すでに切断状態にも関わらず、
認証ダイアログが表示されたままとなる問題を修正した。



........

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