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 6846 - (show annotations) (download) (as text)
Tue Jul 4 15:03:01 2017 UTC (6 years, 9 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 183712 byte(s)
Dynamic Forwarding (SOCKS Proxy) に対応。

/ssh-D1080 でポート 1080 で SOCKS の待ち受けを行う

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