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 8316 - (show annotations) (download) (as text)
Wed Oct 16 13:19:25 2019 UTC (4 years, 5 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 170981 byte(s)
- TTSSHとTTProxyを OpenSSL 1.1.1 に対応した。
  ※OpenSSL 1.0.2ではビルドできません
- Win32 APIのWindows依存チェックツール(installer/checksymbol)を追加した。

branches/openssl_1_1_1_v3からリビジョン8258をマージ:
/branches/openssl_1_1_1_v2 ブランチの r7785 - r8256 をマージした。


........

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