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 7714 - (show annotations) (download) (as text)
Mon May 27 13:23:19 2019 UTC (4 years, 10 months ago) by zmatsuo
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 173929 byte(s)
ttssh2、ビジュアル化fingerprintの表示に等幅フォントを設定する

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