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