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 8273 - (show annotations) (download) (as text)
Mon Oct 7 14:37:58 2019 UTC (4 years, 6 months ago) by zmatsuo
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 169102 byte(s)
ヘルプの表示をリクエストする側がヘルプIDを指定するようにした

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