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 6841 - (show annotations) (download) (as text)
Tue Jul 4 15:02:28 2017 UTC (6 years, 9 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 183660 byte(s)
TeraTerm Project としてのライセンス表記を追加

・Tera Term 本体分を横 80 桁に収まるように改行位置を調整
・ttssh 関連の分を追加
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 char *p = option + 5;
1793 option2[0] = *p;
1794 i = 1;
1795 while (*++p) {
1796 if (*p == ';' || *p == ',') {
1797 option2[i] = 0;
1798 add_forward_param(pvar, option2);
1799 i = 1;
1800 }
1801 else {
1802 option2[i++] = *p;
1803 }
1804 }
1805 if (i > 1) {
1806 option2[i] = 0;
1807 add_forward_param(pvar, option2);
1808 }
1809 } else if (MATCH_STR(option + 4, "-X") == 0) {
1810 add_forward_param(pvar, "X");
1811 if (option+6 != 0) {
1812 strncpy_s(pvar->settings.X11Display,
1813 sizeof(pvar->settings.X11Display),
1814 option + 6, _TRUNCATE);
1815 }
1816 } else if (strcmp(option + 4, "-v") == 0) {
1817 pvar->settings.LogLevel = LOG_LEVEL_VERBOSE;
1818 } else if (_stricmp(option + 4, "-autologin") == 0 ||
1819 _stricmp(option + 4, "-autologon") == 0) {
1820 pvar->settings.TryDefaultAuth = TRUE;
1821 } else if (MATCH_STR_I(option + 4, "-agentconfirm=") == 0) {
1822 if ((_stricmp(option+18, "off") == 0) ||
1823 (_stricmp(option+18, "no") == 0) ||
1824 (_stricmp(option+18, "false") == 0) ||
1825 (_stricmp(option+18, "0") == 0) ||
1826 (_stricmp(option+18, "n") == 0)) {
1827 pvar->settings.ForwardAgentConfirm = 0;
1828 }
1829 else {
1830 pvar->settings.ForwardAgentConfirm = 1;
1831 }
1832 } else if (strcmp(option + 4, "-a") == 0) {
1833 pvar->settings.ForwardAgent = FALSE;
1834 } else if (strcmp(option + 4, "-A") == 0) {
1835 pvar->settings.ForwardAgent = TRUE;
1836
1837 } else if (MATCH_STR(option + 4, "-C=") == 0) {
1838 pvar->settings.CompressionLevel = atoi(option+7);
1839 if (pvar->settings.CompressionLevel < 0) {
1840 pvar->settings.CompressionLevel = 0;
1841 }
1842 else if (pvar->settings.CompressionLevel > 9) {
1843 pvar->settings.CompressionLevel = 9;
1844 }
1845 } else if (strcmp(option + 4, "-C") == 0) {
1846 pvar->settings.CompressionLevel = 6;
1847 } else if (strcmp(option + 4, "-c") == 0) {
1848 pvar->settings.CompressionLevel = 0;
1849 } else if (MATCH_STR_I(option + 4, "-icon=") == 0) {
1850 if ((_stricmp(option+10, "old") == 0) ||
1851 (_stricmp(option+10, "yellow") == 0) ||
1852 (_stricmp(option+10, "securett_yellow") == 0)) {
1853 pvar->settings.IconID = IDI_SECURETT_YELLOW;
1854 }
1855 else if ((_stricmp(option+10, "green") == 0) ||
1856 (_stricmp(option+10, "securett_green") == 0)) {
1857 pvar->settings.IconID = IDI_SECURETT_GREEN;
1858 }
1859 else {
1860 pvar->settings.IconID = IDI_SECURETT;
1861 }
1862 } else if (MATCH_STR(option + 4, "-subsystem=") == 0) {
1863 pvar->use_subsystem = TRUE;
1864 strncpy_s(pvar->subsystem_name,
1865 sizeof(pvar->subsystem_name),
1866 option + 15, _TRUNCATE);
1867
1868 // /ssh1 �� /ssh2 �I�v�V�������V�K���� (2006.9.16 maya)
1869 } else if (strcmp(option + 4, "1") == 0) {
1870 pvar->settings.Enabled = 1;
1871 pvar->settings.ssh_protocol_version = 1;
1872 } else if (strcmp(option + 4, "2") == 0) {
1873 pvar->settings.Enabled = 1;
1874 pvar->settings.ssh_protocol_version = 2;
1875
1876 } else {
1877 char buf[1024];
1878
1879 UTIL_get_lang_msg("MSG_UNKNOWN_OPTION_ERROR", pvar,
1880 "Unrecognized command-line option: %s");
1881 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, option);
1882
1883 MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
1884 }
1885
1886 // ttermpro.exe �� /T= �w�������p�������A������������ (2006.10.19 maya)
1887 } else if (MATCH_STR_I(option + 1, "t=") == 0) {
1888 if (strcmp(option + 3, "2") == 0) {
1889 pvar->settings.Enabled = 1;
1890 // /t=2��ttssh�������g������������
1891 } else {
1892 pvar->settings.Enabled = 0;
1893 action = OPTION_NONE; // Tera Term������������������������
1894 }
1895
1896 // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
1897 } else if (strcmp(option + 1, "1") == 0) {
1898 // command line: /ssh /1 is SSH1 only
1899 pvar->settings.ssh_protocol_version = 1;
1900
1901 } else if (strcmp(option + 1, "2") == 0) {
1902 // command line: /ssh /2 is SSH2 & SSH1
1903 pvar->settings.ssh_protocol_version = 2;
1904
1905 } else if (strcmp(option + 1, "nossh") == 0) {
1906 // '/nossh' �I�v�V�����������B
1907 // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
1908 // �����������������B(2004.10.11 yutaka)
1909 pvar->settings.Enabled = 0;
1910
1911 } else if (strcmp(option + 1, "telnet") == 0) {
1912 // '/telnet' ���w�������������������� '/nossh' ��������
1913 // SSH������������ (2006.9.16 maya)
1914 pvar->settings.Enabled = 0;
1915 // Tera Term �� Telnet �t���O���t����
1916 pvar->ts->Telnet = 1;
1917
1918 } else if (MATCH_STR(option + 1, "auth=") == 0) {
1919 // SSH2�������O�C���I�v�V����������
1920 //
1921 // SYNOPSIS: /ssh /auth=passowrd /user=���[�U�� /passwd=�p�X���[�h
1922 // /ssh /auth=publickey /user=���[�U�� /passwd=�p�X���[�h /keyfile=�p�X
1923 // EXAMPLE: /ssh /auth=password /user=nike /passwd="a b""c" ; �p�X���[�h: �ua b"c�v
1924 // /ssh /auth=publickey /user=foo /passwd=bar /keyfile=d:\tmp\id_rsa
1925 // NOTICE: �p�X���[�h���p�X���������Z�~�R���������������������_�u���N�H�[�g " ������
1926 // �p�X���[�h���_�u���N�H�[�g�����������������A�������_�u���N�H�[�g "" ���u��������
1927 //
1928 pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
1929
1930 if (_stricmp(option + 6, "password") == 0) { // �p�X���[�h
1931 //pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
1932 pvar->ssh2_authmethod = SSH_AUTH_PASSWORD;
1933
1934 // /auth=challenge ������ (2007.10.5 maya)
1935 } else if (_stricmp(option + 6, "challenge") == 0) { // keyboard-interactive�F��
1936 //pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
1937 pvar->ssh2_authmethod = SSH_AUTH_TIS;
1938
1939 } else if (_stricmp(option + 6, "publickey") == 0) { // ���J���F��
1940 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1941 pvar->ssh2_authmethod = SSH_AUTH_RSA;
1942
1943 } else if (_stricmp(option + 6, "pageant") == 0) { // ���J���F�� by Pageant
1944 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1945 pvar->ssh2_authmethod = SSH_AUTH_PAGEANT;
1946
1947 } else {
1948 // TODO:
1949 }
1950
1951 } else if (MATCH_STR(option + 1, "user=") == 0) {
1952 _snprintf_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), _TRUNCATE, "%s", option+6);
1953
1954 } else if (MATCH_STR(option + 1, "passwd=") == 0) {
1955 _snprintf_s(pvar->ssh2_password, sizeof(pvar->ssh2_password), _TRUNCATE, "%s", option+8);
1956
1957 } else if (MATCH_STR(option + 1, "keyfile=") == 0) {
1958 _snprintf_s(pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile), _TRUNCATE, "%s", option+9);
1959
1960 } else if (strcmp(option + 1, "ask4passwd") == 0) {
1961 // �p�X���[�h������ (2006.9.18 maya)
1962 pvar->ask4passwd = 1;
1963
1964 } else if (strcmp(option + 1, "nosecuritywarning") == 0) {
1965 // known_hosts�`�F�b�N���������B���Y�I�v�V�������g�����A�Z�L�����e�B������������
1966 // �����A�B���I�v�V���������������B
1967 // (2009.10.4 yutaka)
1968 pvar->nocheck_known_hosts = TRUE;
1969
1970 }
1971 else { // Other (not ttssh) option
1972 action = OPTION_NONE; // ttssh���I�v�V������������������������
1973 }
1974
1975 // �p�X���[�h�������������������O�C��������������
1976 // /auth ���F�����\�b�h���w�������������p������ (2006.9.18 maya)
1977 if (pvar->ask4passwd == 1) {
1978 pvar->ssh2_autologin = 0;
1979 }
1980
1981 }
1982 else if ((MATCH_STR_I(option, "ssh://") == 0) ||
1983 (MATCH_STR_I(option, "ssh1://") == 0) ||
1984 (MATCH_STR_I(option, "ssh2://") == 0) ||
1985 (MATCH_STR_I(option, "slogin://") == 0) ||
1986 (MATCH_STR_I(option, "slogin1://") == 0) ||
1987 (MATCH_STR_I(option, "slogin2://") == 0)) {
1988 //
1989 // ssh://user@host/ ����URL�`�����T�|�[�g
1990 // ���{�I�������� telnet:// URL��������
1991 //
1992 // �Q�l:
1993 // RFC3986: Uniform Resource Identifier (URI): Generic Syntax
1994 // RFC4248: The telnet URI Scheme
1995 //
1996 char *p, *p2, *p3;
1997 int optlen, hostlen;
1998
1999 optlen = strlen(option);
2000
2001 // ������':'���O�����������������������A������ssh�v���g�R���o�[�W������������
2002 p = _mbschr(option, ':');
2003 switch (*(p-1)) {
2004 case '1':
2005 pvar->settings.ssh_protocol_version = 1;
2006 break;
2007 case '2':
2008 pvar->settings.ssh_protocol_version = 2;
2009 break;
2010 }
2011
2012 // authority part �����|�C���^������
2013 p += 3;
2014
2015 // path part ������������
2016 if ((p2 = _mbschr(p, '/')) != NULL) {
2017 *p2 = 0;
2018 }
2019
2020 // '@'�������������A���������O�����[�U����
2021 if ((p2 = _mbschr(p, '@')) != NULL) {
2022 *p2 = 0;
2023 // ':'���~���p�X���[�h
2024 if ((p3 = _mbschr(p, ':')) != NULL) {
2025 *p3 = 0;
2026 percent_decode(pvar->ssh2_password, sizeof(pvar->ssh2_password), p3 + 1);
2027 }
2028 percent_decode(pvar->ssh2_username, sizeof(pvar->ssh2_username), p);
2029 // p �� host part ������('@'����������)����������������
2030 p = p2 + 1;
2031 }
2032
2033 // host part �� option �����������������Ascheme part ������
2034 // port�w����������������port���������������������m��������������
2035 hostlen = strlen(p);
2036 memmove_s(option, optlen, p, hostlen);
2037 option[hostlen] = 0;
2038
2039 // �|�[�g�w������������":22"������
2040 if (option[0] == '[' && option[hostlen-1] == ']' || // IPv6 raw address without port
2041 option[0] != '[' && _mbschr(option, ':') == NULL) { // hostname or IPv4 raw address without port
2042 memcpy_s(option+hostlen, optlen-hostlen, ":22", 3);
2043 hostlen += 3;
2044 }
2045
2046 // �|�[�g�w�����������������X�y�[�X������
2047 memset(option+hostlen, ' ', optlen-hostlen);
2048
2049 pvar->settings.Enabled = 1;
2050
2051 action = OPTION_REPLACE;
2052 }
2053 else if (_mbschr(option, '@') != NULL) {
2054 //
2055 // user@host �`�����T�|�[�g
2056 // ����������ssh�������T�|�[�g�����A���[�U����ttssh���������B
2057 // (ssh�������O -- ttssh�������W������������)
2058 // �����I��telnet authentication option���T�|�[�g��������
2059 // Tera Term�{�����������������������\���B
2060 //
2061 char *p;
2062 p = _mbschr(option, '@');
2063 *p = 0;
2064
2065 strncpy_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), option, _TRUNCATE);
2066
2067 // ���[�U���������X�y�[�X�������B
2068 // ������TTX��Tera Term�{�������������������X�y�[�X�����������������A
2069 // �z�X�g�����������l�����K�v�������B
2070 memset(option, ' ', p-option+1);
2071
2072 action = OPTION_REPLACE;
2073 }
2074
2075
2076 switch (action) {
2077 case OPTION_CLEAR:
2078 memset(cur, ' ', next-cur);
2079 break;
2080 case OPTION_REPLACE:
2081 memset(cur, ' ', next-cur);
2082 memcpy(cur+1, option, strlen(option));
2083 break;
2084 }
2085
2086 cur = next;
2087 }
2088
2089 free(option);
2090
2091 FWDUI_load_settings(pvar);
2092
2093 (pvar->ParseParam) (param, ts, DDETopic);
2094 }
2095
2096 static void PASCAL TTXGetSetupHooks(TTXSetupHooks *hooks)
2097 {
2098 pvar->ReadIniFile = *hooks->ReadIniFile;
2099 pvar->WriteIniFile = *hooks->WriteIniFile;
2100 pvar->ParseParam = *hooks->ParseParam;
2101
2102 *hooks->ReadIniFile = TTXReadINIFile;
2103 *hooks->WriteIniFile = TTXWriteINIFile;
2104 *hooks->ParseParam = TTXParseParam;
2105 }
2106
2107 static void PASCAL TTXSetWinSize(int rows, int cols)
2108 {
2109 SSH_notify_win_size(pvar, cols, rows);
2110 }
2111
2112 static void insertMenuBeforeItem(HMENU menu, WORD beforeItemID, WORD flags,
2113 WORD newItemID, char *text)
2114 {
2115 int i, j;
2116
2117 for (i = GetMenuItemCount(menu) - 1; i >= 0; i--) {
2118 HMENU submenu = GetSubMenu(menu, i);
2119
2120 for (j = GetMenuItemCount(submenu) - 1; j >= 0; j--) {
2121 if (GetMenuItemID(submenu, j) == beforeItemID) {
2122 InsertMenu(submenu, j, MF_BYPOSITION | flags, newItemID, text);
2123 return;
2124 }
2125 }
2126 }
2127 }
2128
2129 #define GetFileMenu(menu) GetSubMenuByChildID(menu, 50110) // ID_FILE_NEWCONNECTION
2130 #define GetEditMenu(menu) GetSubMenuByChildID(menu, 50210) // ID_EDIT_COPY2
2131 #define GetSetupMenu(menu) GetSubMenuByChildID(menu, 50310) // ID_SETUP_TERMINAL
2132 #define GetControlMenu(menu) GetSubMenuByChildID(menu, 50410) // ID_CONTROL_RESETTERMINAL
2133 #define GetHelpMenu(menu) GetSubMenuByChildID(menu, 50990) // ID_HELP_ABOUT
2134
2135 HMENU GetSubMenuByChildID(HMENU menu, UINT id) {
2136 int i, j, items, subitems, cur_id;
2137 HMENU m;
2138
2139 items = GetMenuItemCount(menu);
2140
2141 for (i=0; i<items; i++) {
2142 if (m = GetSubMenu(menu, i)) {
2143 subitems = GetMenuItemCount(m);
2144 for (j=0; j<subitems; j++) {
2145 cur_id = GetMenuItemID(m, j);
2146 if (cur_id == id) {
2147 return m;
2148 }
2149 }
2150 }
2151 }
2152 return NULL;
2153 }
2154
2155 static void PASCAL TTXModifyMenu(HMENU menu)
2156 {
2157 pvar->FileMenu = GetFileMenu(menu);
2158
2159 /* inserts before ID_HELP_ABOUT */
2160 UTIL_get_lang_msg("MENU_ABOUT", pvar, "About &TTSSH...");
2161 insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU, pvar->ts->UIMsg);
2162
2163 /* inserts before ID_SETUP_TCPIP */
2164 UTIL_get_lang_msg("MENU_SSH", pvar, "SS&H...");
2165 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU, pvar->ts->UIMsg);
2166 /* inserts before ID_SETUP_TCPIP */
2167 UTIL_get_lang_msg("MENU_SSH_AUTH", pvar, "SSH &Authentication...");
2168 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU, pvar->ts->UIMsg);
2169 /* inserts before ID_SETUP_TCPIP */
2170 UTIL_get_lang_msg("MENU_SSH_FORWARD", pvar, "SSH F&orwarding...");
2171 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU, pvar->ts->UIMsg);
2172 UTIL_get_lang_msg("MENU_SSH_KEYGEN", pvar, "SSH KeyGe&nerator...");
2173 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHKEYGENMENU, pvar->ts->UIMsg);
2174
2175 /* inserts before ID_FILE_CHANGEDIR */
2176 UTIL_get_lang_msg("MENU_SSH_SCP", pvar, "SS&H SCP...");
2177 insertMenuBeforeItem(menu, 50170, MF_GRAYED, ID_SSHSCPMENU, pvar->ts->UIMsg);
2178 }
2179
2180 static void PASCAL TTXModifyPopupMenu(HMENU menu) {
2181 if (menu == pvar->FileMenu) {
2182 if (pvar->cv->Ready && pvar->settings.Enabled)
2183 EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_ENABLED);
2184 else
2185 EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_GRAYED);
2186 }
2187 }
2188
2189 static void about_dlg_set_abouttext(PTInstVar pvar, HWND dlg, digest_algorithm dgst_alg)
2190 {
2191 char buf[1024], buf2[2048];
2192 char *fp = NULL;
2193
2194 // TTSSH�_�C�A���O���\������SSH������������ (2004.10.30 yutaka)
2195 if (pvar->socket != INVALID_SOCKET) {
2196 buf2[0] = '\0';
2197
2198 if (SSHv1(pvar)) {
2199 UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID:");
2200 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2201 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2202 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
2203 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2204 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2205
2206 UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol:");
2207 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2208 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2209 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
2210 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2211 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2212
2213 UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:");
2214 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2215 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2216 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
2217 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2218 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2219
2220 UTIL_get_lang_msg("DLG_ABOUT_SERVERKEY", pvar, "Server keys:");
2221 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2222 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2223 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
2224 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2225 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2226
2227 UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication:");
2228 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2229 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2230 AUTH_get_auth_info(pvar, buf, sizeof(buf));
2231 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2232 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2233
2234 UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression:");
2235 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2236 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2237 SSH_get_compression_info(pvar, buf, sizeof(buf));
2238 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2239 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2240
2241 } else { // SSH2
2242 UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID:");
2243 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2244 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2245 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
2246 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2247 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2248
2249 UTIL_get_lang_msg("DLG_ABOUT_CLIENTID", pvar, "Client ID:");
2250 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2251 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2252 strncat_s(buf2, sizeof(buf2), pvar->client_version_string, _TRUNCATE);
2253 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2254
2255 UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol:");
2256 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2257 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2258 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
2259 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2260 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2261
2262 UTIL_get_lang_msg("DLG_ABOUT_KEX", pvar, "Key exchange algorithm:");
2263 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2264 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2265 strncat_s(buf2, sizeof(buf2), get_kex_algorithm_name(pvar->kex_type), _TRUNCATE);
2266 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2267
2268 UTIL_get_lang_msg("DLG_ABOUT_HOSTKEY", pvar, "Host Key:");
2269 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2270 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2271 strncat_s(buf2, sizeof(buf2), get_ssh_keytype_name(pvar->hostkey_type), _TRUNCATE);
2272 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2273
2274 UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:");
2275 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2276 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2277 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
2278 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2279 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2280
2281 UTIL_get_lang_msg("DLG_ABOUT_MAC", pvar, "MAC algorithm:");
2282 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2283 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2284 SSH_get_mac_info(pvar, buf, sizeof(buf));
2285 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2286 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2287
2288 if (pvar->ctos_compression == COMP_DELAYED) { // �x���p�P�b�g���k������ (2006.6.23 yutaka)
2289 UTIL_get_lang_msg("DLG_ABOUT_COMPDELAY", pvar, "Delayed Compression:");
2290 }
2291 else {
2292 UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression:");
2293 }
2294 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2295 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2296 SSH_get_compression_info(pvar, buf, sizeof(buf));
2297 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2298 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2299
2300 UTIL_get_lang_msg("DLG_ABOUT_KEXKEY", pvar, "Key exchange keys:");
2301 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2302 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2303 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
2304 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2305 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2306
2307 UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication:");
2308 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2309 strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
2310 AUTH_get_auth_info(pvar, buf, sizeof(buf));
2311 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2312 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2313 }
2314
2315 // �z�X�g���J����fingerprint���\�������B
2316 // (2014.5.1 yutaka)
2317 UTIL_get_lang_msg("DLG_ABOUT_FINGERPRINT", pvar, "Host key's fingerprint:");
2318 strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
2319 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2320
2321 switch (dgst_alg) {
2322 case SSH_DIGEST_MD5:
2323 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX, dgst_alg);
2324 strncat_s(buf2, sizeof(buf2), fp, _TRUNCATE);
2325 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2326 free(fp);
2327 break;
2328 case SSH_DIGEST_SHA256:
2329 default:
2330 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_BASE64, SSH_DIGEST_SHA256);
2331 if (fp != NULL) {
2332 strncat_s(buf2, sizeof(buf2), fp, _TRUNCATE);
2333 free(fp);
2334 }
2335 strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
2336 break;
2337 }
2338
2339 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART, dgst_alg);
2340 strncat_s(buf2, sizeof(buf2), fp, _TRUNCATE);
2341 free(fp);
2342
2343 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, WM_SETTEXT, 0, (LPARAM)(char *)buf2);
2344 }
2345 }
2346
2347 static void init_about_dlg(PTInstVar pvar, HWND dlg)
2348 {
2349 char buf[1024];
2350 char uimsg[MAX_UIMSG];
2351
2352 GetWindowText(dlg, uimsg, sizeof(uimsg));
2353 UTIL_get_lang_msg("DLG_ABOUT_TITLE", pvar, uimsg);
2354 SetWindowText(dlg, pvar->ts->UIMsg);
2355 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2356 UTIL_get_lang_msg("DLG_ABOUT_FP_HASH_ALGORITHM", pvar, uimsg);
2357 SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2358 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2359 UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
2360 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2361
2362 // TTSSH���o�[�W�������������� (2005.2.28 yutaka)
2363 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2364 "TTSSH\r\nTera Term Secure Shell extension, %d.%d", TTSSH_VERSION_MAJOR, TTSSH_VERSION_MINOR);
2365 SendMessage(GetDlgItem(dlg, IDC_TTSSH_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2366
2367 // OpenSSL���o�[�W�������������� (2005.1.24 yutaka)
2368 // ���������� (2005.5.11 yutaka)
2369 // OPENSSL_VERSION_TEXT �}�N�����`���������A�������g�����o�[�W���������������B(2013.11.24 yutaka)
2370 SendMessage(GetDlgItem(dlg, IDC_OPENSSL_VERSION), WM_SETTEXT, 0, (LPARAM)SSLeay_version(SSLEAY_VERSION));
2371
2372 // zlib���o�[�W�������������� (2005.5.11 yutaka)
2373 #ifdef ZLIB_VERSION
2374 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "ZLib %s", ZLIB_VERSION);
2375 #else
2376 _snprintf(buf, sizeof(buf), "ZLib Unknown");
2377 #endif
2378 SendMessage(GetDlgItem(dlg, IDC_ZLIB_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2379
2380 // PuTTY���o�[�W�������������� (2011.7.26 yutaka)
2381 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "PuTTY %s", putty_get_version());
2382 SendMessage(GetDlgItem(dlg, IDC_PUTTY_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2383 }
2384
2385 // WM_MOUSEWHEEL �� winuser.h �w�b�_���������������������A#define _WIN32_WINNT 0x0400 ���������������������F�������������B
2386 #define WM_MOUSEWHEEL 0x020A
2387 #define WHEEL_DELTA 120
2388 #define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
2389 #define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam))
2390
2391 static WNDPROC g_defAboutDlgEditWndProc; // Edit Control���T�u�N���X���p
2392 static int g_deltaSumAboutDlg = 0; // �}�E�X�z�C�[����Delta�����p
2393
2394 static LRESULT CALLBACK AboutDlgEditWindowProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
2395 {
2396 WORD keys;
2397 short delta;
2398 BOOL page;
2399
2400 switch (msg) {
2401 case WM_KEYDOWN:
2402 // Edit control���� CTRL+A �������������A�e�L�X�g���S�I�������B
2403 if (wp == 'A' && GetKeyState(VK_CONTROL) < 0) {
2404 PostMessage(hWnd, EM_SETSEL, 0, -1);
2405 return 0;
2406 }
2407 break;
2408
2409 case WM_MOUSEWHEEL:
2410 // CTRLorSHIFT + �}�E�X�z�C�[���������A���X�N���[���������B
2411 keys = GET_KEYSTATE_WPARAM(wp);
2412 delta = GET_WHEEL_DELTA_WPARAM(wp);
2413 page = keys & (MK_CONTROL | MK_SHIFT);
2414
2415 if (page == 0)
2416 break;
2417
2418 g_deltaSumAboutDlg += delta;
2419
2420 if (g_deltaSumAboutDlg >= WHEEL_DELTA) {
2421 g_deltaSumAboutDlg -= WHEEL_DELTA;
2422 SendMessage(hWnd, WM_HSCROLL, SB_PAGELEFT , 0);
2423 } else if (g_deltaSumAboutDlg <= -WHEEL_DELTA) {
2424 g_deltaSumAboutDlg += WHEEL_DELTA;
2425 SendMessage(hWnd, WM_HSCROLL, SB_PAGERIGHT, 0);
2426 }
2427
2428 break;
2429 }
2430 return CallWindowProc(g_defAboutDlgEditWndProc, hWnd, msg, wp, lp);
2431 }
2432
2433 static BOOL CALLBACK TTXAboutDlg(HWND dlg, UINT msg, WPARAM wParam,
2434 LPARAM lParam)
2435 {
2436 LOGFONT logfont;
2437 HFONT font;
2438
2439 switch (msg) {
2440 case WM_INITDIALOG:
2441 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2442 GetObject(font, sizeof(LOGFONT), &logfont);
2443 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgAboutFont, pvar)) {
2444 SendDlgItemMessage(dlg, IDC_TTSSH_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2445 SendDlgItemMessage(dlg, IDC_SSHVERSIONS, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2446 SendDlgItemMessage(dlg, IDC_INCLUDES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2447 SendDlgItemMessage(dlg, IDC_OPENSSL_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2448 SendDlgItemMessage(dlg, IDC_ZLIB_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2449 SendDlgItemMessage(dlg, IDC_PUTTY_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE, 0));
2450 SendDlgItemMessage(dlg, IDC_WEBSITES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE, 0));
2451 SendDlgItemMessage(dlg, IDC_CRYPTOGRAPHY, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2452 SendDlgItemMessage(dlg, IDC_CREDIT, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2453 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE, 0));
2454 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE, 0));
2455 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE, 0));
2456 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2457 }
2458 else {
2459 DlgAboutFont = NULL;
2460 }
2461
2462 // Edit control�������t�H���g���\�������������A���������������t�H���g���Z�b�g�����B
2463 // (2014.5.5. yutaka)
2464 if (UTIL_get_lang_font("DLG_ABOUT_FONT", dlg, &logfont, &DlgAboutTextFont, pvar)) {
2465 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, WM_SETFONT, (WPARAM)DlgAboutTextFont, MAKELPARAM(TRUE,0));
2466 } else {
2467 // ���������������������������t�H���g���w�������B
2468 // �G�f�B�b�g�R���g���[�����_�C�A���O�������t�H���g������������
2469 // �����t�H���g�������������B
2470 strncpy_s(logfont.lfFaceName, sizeof(logfont.lfFaceName), "Courier New", _TRUNCATE);
2471 logfont.lfCharSet = 0;
2472 logfont.lfHeight = MulDiv(8, GetDeviceCaps(GetDC(dlg),LOGPIXELSY) * -1, 72);
2473 logfont.lfWidth = 0;
2474 if ((DlgAboutTextFont = CreateFontIndirect(&logfont)) != NULL) {
2475 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, WM_SETFONT, (WPARAM)DlgAboutTextFont, MAKELPARAM(TRUE,0));
2476 }
2477 else {
2478 DlgAboutTextFont = NULL;
2479 }
2480 }
2481
2482 // �A�C�R�������I���Z�b�g
2483 {
2484 int fuLoad = LR_DEFAULTCOLOR;
2485 HICON hicon;
2486
2487 if (IsWindowsNT4()) {
2488 fuLoad = LR_VGACOLOR;
2489 }
2490
2491 hicon = LoadImage(hInst, MAKEINTRESOURCE(pvar->settings.IconID),
2492 IMAGE_ICON, 32, 32, fuLoad);
2493 SendDlgItemMessage(dlg, IDC_TTSSH_ICON, STM_SETICON, (WPARAM)hicon, 0);
2494 }
2495
2496 init_about_dlg(pvar, dlg);
2497 CheckDlgButton(dlg, IDC_FP_HASH_ALG_SHA256, TRUE);
2498 about_dlg_set_abouttext(pvar, dlg, SSH_DIGEST_SHA256);
2499 SetFocus(GetDlgItem(dlg, IDOK));
2500
2501 // Edit control���T�u�N���X�������B
2502 g_deltaSumAboutDlg = 0;
2503 g_defAboutDlgEditWndProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(dlg, IDC_ABOUTTEXT), GWLP_WNDPROC, (LONG_PTR)AboutDlgEditWindowProc);
2504
2505 return FALSE;
2506
2507 case WM_COMMAND:
2508 switch (LOWORD(wParam)) {
2509 case IDOK:
2510 EndDialog(dlg, 1);
2511 if (DlgAboutFont != NULL) {
2512 DeleteObject(DlgAboutFont);
2513 }
2514 if (DlgAboutTextFont != NULL) {
2515 DeleteObject(DlgAboutTextFont);
2516 }
2517 return TRUE;
2518 case IDCANCEL: /* there isn't a cancel button, but other Windows
2519 UI things can send this message */
2520 EndDialog(dlg, 0);
2521 if (DlgAboutFont != NULL) {
2522 DeleteObject(DlgAboutFont);
2523 }
2524 if (DlgAboutTextFont != NULL) {
2525 DeleteObject(DlgAboutTextFont);
2526 }
2527 return TRUE;
2528 case IDC_FP_HASH_ALG_MD5:
2529 about_dlg_set_abouttext(pvar, dlg, SSH_DIGEST_MD5);
2530 return TRUE;
2531 case IDC_FP_HASH_ALG_SHA256:
2532 about_dlg_set_abouttext(pvar, dlg, SSH_DIGEST_SHA256);
2533 return TRUE;
2534 }
2535 break;
2536 }
2537
2538 return FALSE;
2539 }
2540
2541 static char *get_cipher_name(int cipher)
2542 {
2543 switch (cipher) {
2544 case SSH_CIPHER_NONE:
2545 UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_BORDER", pvar,
2546 "<ciphers below this line are disabled>");
2547 return pvar->ts->UIMsg;
2548 case SSH_CIPHER_3DES:
2549 return "3DES(SSH1)";
2550 case SSH_CIPHER_DES:
2551 return "DES(SSH1)";
2552 case SSH_CIPHER_BLOWFISH:
2553 return "Blowfish(SSH1)";
2554
2555 // for SSH2(yutaka)
2556 case SSH2_CIPHER_AES128_CBC:
2557 return "AES128-CBC(SSH2)";
2558 case SSH2_CIPHER_AES192_CBC:
2559 return "AES192-CBC(SSH2)";
2560 case SSH2_CIPHER_AES256_CBC:
2561 return "AES256-CBC(SSH2)";
2562 case SSH2_CIPHER_3DES_CBC:
2563 return "3DES-CBC(SSH2)";
2564 case SSH2_CIPHER_BLOWFISH_CBC:
2565 return "Blowfish-CBC(SSH2)";
2566 case SSH2_CIPHER_AES128_CTR:
2567 return "AES128-CTR(SSH2)";
2568 case SSH2_CIPHER_AES192_CTR:
2569 return "AES192-CTR(SSH2)";
2570 case SSH2_CIPHER_AES256_CTR:
2571 return "AES256-CTR(SSH2)";
2572 case SSH2_CIPHER_ARCFOUR:
2573 return "Arcfour(SSH2)";
2574 case SSH2_CIPHER_ARCFOUR128:
2575 return "Arcfour128(SSH2)";
2576 case SSH2_CIPHER_ARCFOUR256:
2577 return "Arcfour256(SSH2)";
2578 case SSH2_CIPHER_CAST128_CBC:
2579 return "CAST128-CBC(SSH2)";
2580 case SSH2_CIPHER_3DES_CTR:
2581 return "3DES-CTR(SSH2)";
2582 case SSH2_CIPHER_BLOWFISH_CTR:
2583 return "Blowfish-CTR(SSH2)";
2584 case SSH2_CIPHER_CAST128_CTR:
2585 return "CAST128-CTR(SSH2)";
2586 case SSH2_CIPHER_CAMELLIA128_CBC:
2587 return "Camellia128-CBC(SSH2)";
2588 case SSH2_CIPHER_CAMELLIA192_CBC:
2589 return "Camellia192-CBC(SSH2)";
2590 case SSH2_CIPHER_CAMELLIA256_CBC:
2591 return "Camellia256-CBC(SSH2)";
2592 case SSH2_CIPHER_CAMELLIA128_CTR:
2593 return "Camellia128-CTR(SSH2)";
2594 case SSH2_CIPHER_CAMELLIA192_CTR:
2595 return "Camellia192-CTR(SSH2)";
2596 case SSH2_CIPHER_CAMELLIA256_CTR:
2597 return "Camellia256-CTR(SSH2)";
2598
2599 default:
2600 return NULL;
2601 }
2602 }
2603
2604 static void set_move_button_status(HWND dlg, int type, int up, int down)
2605 {
2606 HWND cipherControl = GetDlgItem(dlg, type);
2607 int curPos = (int) SendMessage(cipherControl, LB_GETCURSEL, 0, 0);
2608 int maxPos = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0) - 1;
2609
2610 EnableWindow(GetDlgItem(dlg, up),
2611 curPos > 0 && curPos <= maxPos);
2612 EnableWindow(GetDlgItem(dlg, down),
2613 curPos >= 0 && curPos < maxPos);
2614 }
2615
2616 static void init_setup_dlg(PTInstVar pvar, HWND dlg)
2617 {
2618 HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
2619 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
2620 HWND kexControl = GetDlgItem(dlg, IDC_SSHKEX_LIST);
2621 HWND hostkeyControl = GetDlgItem(dlg, IDC_SSHHOST_KEY_LIST);
2622 HWND macControl = GetDlgItem(dlg, IDC_SSHMAC_LIST);
2623 HWND compControl = GetDlgItem(dlg, IDC_SSHCOMP_LIST);
2624 HWND hostkeyRotationControl = GetDlgItem(dlg, IDC_HOSTKEY_ROTATION_STATIC);
2625 HWND hostkeyRotationControlList = GetDlgItem(dlg, IDC_HOSTKEY_ROTATION_COMBO);
2626 int i;
2627 int ch;
2628 char uimsg[MAX_UIMSG];
2629 char *rotationItem[SSH_UPDATE_HOSTKEYS_MAX] = {
2630 "No",
2631 "Yes",
2632 "Ask",
2633 };
2634 char *rotationItemKey[SSH_UPDATE_HOSTKEYS_MAX] = {
2635 "DLG_SSHSETUP_HOSTKEY_ROTATION_NO",
2636 "DLG_SSHSETUP_HOSTKEY_ROTATION_YES",
2637 "DLG_SSHSETUP_HOSTKEY_ROTATION_ASK",
2638 };
2639
2640 GetWindowText(dlg, uimsg, sizeof(uimsg));
2641 UTIL_get_lang_msg("DLG_SSHSETUP_TITLE", pvar, uimsg);
2642 SetWindowText(dlg, pvar->ts->UIMsg);
2643 GetDlgItemText(dlg, IDC_COMPRESSLABEL, uimsg, sizeof(uimsg));
2644 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS", pvar, uimsg);
2645 SetDlgItemText(dlg, IDC_COMPRESSLABEL, pvar->ts->UIMsg);
2646 GetDlgItemText(dlg, IDC_COMPRESSNONE, uimsg, sizeof(uimsg));
2647 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_NONE", pvar, uimsg);
2648 SetDlgItemText(dlg, IDC_COMPRESSNONE, pvar->ts->UIMsg);
2649 GetDlgItemText(dlg, IDC_COMPRESSHIGH, uimsg, sizeof(uimsg));
2650 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_HIGHEST", pvar, uimsg);
2651 SetDlgItemText(dlg, IDC_COMPRESSHIGH, pvar->ts->UIMsg);
2652 GetDlgItemText(dlg, IDC_COMPRESSNOTE, uimsg, sizeof(uimsg));
2653 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_NOTE", pvar, uimsg);
2654 SetDlgItemText(dlg, IDC_COMPRESSNOTE, pvar->ts->UIMsg);
2655
2656 GetDlgItemText(dlg, IDC_CIPHERORDER, uimsg, sizeof(uimsg));
2657 UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER", pvar, uimsg);
2658 SetDlgItemText(dlg, IDC_CIPHERORDER, pvar->ts->UIMsg);
2659 GetDlgItemText(dlg, IDC_SSHMOVECIPHERUP, uimsg, sizeof(uimsg));
2660 UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_UP", pvar, uimsg);
2661 SetDlgItemText(dlg, IDC_SSHMOVECIPHERUP, pvar->ts->UIMsg);
2662 GetDlgItemText(dlg, IDC_SSHMOVECIPHERDOWN, uimsg, sizeof(uimsg));
2663 UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_DOWN", pvar, uimsg);
2664 SetDlgItemText(dlg, IDC_SSHMOVECIPHERDOWN, pvar->ts->UIMsg);
2665
2666 GetDlgItemText(dlg, IDC_KEX_ORDER, uimsg, sizeof(uimsg));
2667 UTIL_get_lang_msg("DLG_SSHSETUP_KEX", pvar, uimsg);
2668 SetDlgItemText(dlg, IDC_KEX_ORDER, pvar->ts->UIMsg);
2669 GetDlgItemText(dlg, IDC_SSHKEX_MOVEUP, uimsg, sizeof(uimsg));
2670 UTIL_get_lang_msg("DLG_SSHSETUP_KEX_UP", pvar, uimsg);
2671 SetDlgItemText(dlg, IDC_SSHKEX_MOVEUP, pvar->ts->UIMsg);
2672 GetDlgItemText(dlg, IDC_SSHKEX_MOVEDOWN, uimsg, sizeof(uimsg));
2673 UTIL_get_lang_msg("DLG_SSHSETUP_KEX_DOWN", pvar, uimsg);
2674 SetDlgItemText(dlg, IDC_SSHKEX_MOVEDOWN, pvar->ts->UIMsg);
2675
2676 GetDlgItemText(dlg, IDC_HOST_KEY_ORDER, uimsg, sizeof(uimsg));
2677 UTIL_get_lang_msg("DLG_SSHSETUP_HOST_KEY", pvar, uimsg);
2678 SetDlgItemText(dlg, IDC_HOST_KEY_ORDER, pvar->ts->UIMsg);
2679 GetDlgItemText(dlg, IDC_SSHHOST_KEY_MOVEUP, uimsg, sizeof(uimsg));
2680 UTIL_get_lang_msg("DLG_SSHSETUP_HOST_KEY_UP", pvar, uimsg);
2681 SetDlgItemText(dlg, IDC_SSHHOST_KEY_MOVEUP, pvar->ts->UIMsg);
2682 GetDlgItemText(dlg, IDC_SSHHOST_KEY_MOVEDOWN, uimsg, sizeof(uimsg));
2683 UTIL_get_lang_msg("DLG_SSHSETUP_HOST_KEY_DOWN", pvar, uimsg);
2684 SetDlgItemText(dlg, IDC_SSHHOST_KEY_MOVEDOWN, pvar->ts->UIMsg);
2685
2686 GetDlgItemText(dlg, IDC_MAC_ORDER, uimsg, sizeof(uimsg));
2687 UTIL_get_lang_msg("DLG_SSHSETUP_MAC", pvar, uimsg);
2688 SetDlgItemText(dlg, IDC_MAC_ORDER, pvar->ts->UIMsg);
2689 GetDlgItemText(dlg, IDC_SSHMAC_MOVEUP, uimsg, sizeof(uimsg));
2690 UTIL_get_lang_msg("DLG_SSHSETUP_MAC_UP", pvar, uimsg);
2691 SetDlgItemText(dlg, IDC_SSHMAC_MOVEUP, pvar->ts->UIMsg);
2692 GetDlgItemText(dlg, IDC_SSHMAC_MOVEDOWN, uimsg, sizeof(uimsg));
2693 UTIL_get_lang_msg("DLG_SSHSETUP_MAC_DOWN", pvar, uimsg);
2694 SetDlgItemText(dlg, IDC_SSHMAC_MOVEDOWN, pvar->ts->UIMsg);
2695
2696 GetDlgItemText(dlg, IDC_COMP_ORDER, uimsg, sizeof(uimsg));
2697 UTIL_get_lang_msg("DLG_SSHSETUP_COMP", pvar, uimsg);
2698 SetDlgItemText(dlg, IDC_COMP_ORDER, pvar->ts->UIMsg);
2699 GetDlgItemText(dlg, IDC_SSHCOMP_MOVEUP, uimsg, sizeof(uimsg));
2700 UTIL_get_lang_msg("DLG_SSHSETUP_COMP_UP", pvar, uimsg);
2701 SetDlgItemText(dlg, IDC_SSHCOMP_MOVEUP, pvar->ts->UIMsg);
2702 GetDlgItemText(dlg, IDC_SSHCOMP_MOVEDOWN, uimsg, sizeof(uimsg));
2703 UTIL_get_lang_msg("DLG_SSHSETUP_COMP_DOWN", pvar, uimsg);
2704 SetDlgItemText(dlg, IDC_SSHCOMP_MOVEDOWN, pvar->ts->UIMsg);
2705
2706 GetDlgItemText(dlg, IDC_KNOWNHOSTS, uimsg, sizeof(uimsg));
2707 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST", pvar, uimsg);
2708 SetDlgItemText(dlg, IDC_KNOWNHOSTS, pvar->ts->UIMsg);
2709 GetDlgItemText(dlg, IDC_CHOOSEREADWRITEFILE, uimsg, sizeof(uimsg));
2710 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST_RW", pvar, uimsg);
2711 SetDlgItemText(dlg, IDC_CHOOSEREADWRITEFILE, pvar->ts->UIMsg);
2712 GetDlgItemText(dlg, IDC_CHOOSEREADONLYFILE, uimsg, sizeof(uimsg));
2713 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST_RO", pvar, uimsg);
2714 SetDlgItemText(dlg, IDC_CHOOSEREADONLYFILE, pvar->ts->UIMsg);
2715 GetDlgItemText(dlg, IDC_HEARTBEATLABEL, uimsg, sizeof(uimsg));
2716 UTIL_get_lang_msg("DLG_SSHSETUP_HEARTBEAT", pvar, uimsg);
2717 SetDlgItemText(dlg, IDC_HEARTBEATLABEL, pvar->ts->UIMsg);
2718 GetDlgItemText(dlg, IDC_HEARTBEATLABEL2, uimsg, sizeof(uimsg));
2719 UTIL_get_lang_msg("DLG_SSHSETUP_HEARTBEAT_UNIT", pvar, uimsg);
2720 SetDlgItemText(dlg, IDC_HEARTBEATLABEL2, pvar->ts->UIMsg);
2721 GetDlgItemText(dlg, IDC_REMEMBERPASSWORD, uimsg, sizeof(uimsg));
2722 UTIL_get_lang_msg("DLG_SSHSETUP_PASSWORD", pvar, uimsg);
2723 SetDlgItemText(dlg, IDC_REMEMBERPASSWORD, pvar->ts->UIMsg);
2724 GetDlgItemText(dlg, IDC_FORWARDAGENT, uimsg, sizeof(uimsg));
2725 UTIL_get_lang_msg("DLG_SSHSETUP_FORWARDAGENT", pvar, uimsg);
2726 SetDlgItemText(dlg, IDC_FORWARDAGENT, pvar->ts->UIMsg);
2727 GetDlgItemText(dlg, IDC_FORWARDAGENTCONFIRM, uimsg, sizeof(uimsg));
2728 UTIL_get_lang_msg("DLG_SSHSETUP_FORWARDAGENTCONFIRM", pvar, uimsg);
2729 SetDlgItemText(dlg, IDC_FORWARDAGENTCONFIRM, pvar->ts->UIMsg);
2730 GetDlgItemText(dlg, IDC_FORWARDAGENTNOTIFY, uimsg, sizeof(uimsg));
2731 UTIL_get_lang_msg("DLG_SSHSETUP_FORWARDAGENTNOTIFY", pvar, uimsg);
2732 SetDlgItemText(dlg, IDC_FORWARDAGENTNOTIFY, pvar->ts->UIMsg);
2733 GetDlgItemText(dlg, IDC_VERIFYHOSTKEYDNS, uimsg, sizeof(uimsg));
2734 UTIL_get_lang_msg("DLG_SSHSETUP_VERIFYHOSTKEYDNS", pvar, uimsg);
2735 SetDlgItemText(dlg, IDC_VERIFYHOSTKEYDNS, pvar->ts->UIMsg);
2736 GetDlgItemText(dlg, IDC_NOTICEBANNER, uimsg, sizeof(uimsg));
2737 UTIL_get_lang_msg("DLG_SSHSETUP_NOTICE", pvar, uimsg);
2738 SetDlgItemText(dlg, IDC_NOTICEBANNER, pvar->ts->UIMsg);
2739 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2740 UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
2741 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2742 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2743 UTIL_get_lang_msg("BTN_CANCEL", pvar, uimsg);
2744 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2745
2746 GetDlgItemText(dlg, IDC_HOSTKEY_ROTATION_STATIC, uimsg, sizeof(uimsg));
2747 UTIL_get_lang_msg("DLG_SSHSETUP_HOSTKEY_ROTATION", pvar, uimsg);
2748 SetDlgItemText(dlg, IDC_HOSTKEY_ROTATION_STATIC, pvar->ts->UIMsg);
2749
2750 SendMessage(compressionControl, TBM_SETRANGE, TRUE, MAKELONG(0, 9));
2751 SendMessage(compressionControl, TBM_SETPOS, TRUE,
2752 pvar->settings.CompressionLevel);
2753
2754 // Cipher order
2755 normalize_cipher_order(pvar->settings.CipherOrder);
2756
2757 for (i = 0; pvar->settings.CipherOrder[i] != 0; i++) {
2758 int cipher = pvar->settings.CipherOrder[i] - '0';
2759 char *name = get_cipher_name(cipher);
2760
2761 if (name != NULL) {
2762 SendMessage(cipherControl, LB_ADDSTRING, 0, (LPARAM) name);
2763 }
2764 }
2765
2766 SendMessage(cipherControl, LB_SETCURSEL, 0, 0);
2767 set_move_button_status(dlg, IDC_SSHCIPHERPREFS, IDC_SSHMOVECIPHERUP, IDC_SSHMOVECIPHERDOWN);
2768
2769 // KEX order
2770 normalize_kex_order(pvar->settings.KexOrder);
2771 for (i = 0; pvar->settings.KexOrder[i] != 0; i++) {
2772 int index = pvar->settings.KexOrder[i] - '0';
2773 char *name = NULL;
2774
2775 if (index == 0) {
2776 UTIL_get_lang_msg("DLG_SSHSETUP_KEX_BORDER", pvar,
2777 "<KEXs below this line are disabled>");
2778 name = pvar->ts->UIMsg;
2779 } else {
2780 name = get_kex_algorithm_name(index);
2781 }
2782
2783 if (name != NULL) {
2784 SendMessage(kexControl, LB_ADDSTRING, 0, (LPARAM) name);
2785 }
2786 }
2787 SendMessage(kexControl, LB_SETCURSEL, 0, 0);
2788 set_move_button_status(dlg, IDC_SSHKEX_LIST, IDC_SSHKEX_MOVEUP, IDC_SSHKEX_MOVEDOWN);
2789
2790 // Host Key order
2791 normalize_host_key_order(pvar->settings.HostKeyOrder);
2792 for (i = 0; pvar->settings.HostKeyOrder[i] != 0; i++) {
2793 int index = pvar->settings.HostKeyOrder[i] - '0';
2794 char *name = NULL;
2795
2796 if (index == 0) {
2797 UTIL_get_lang_msg("DLG_SSHSETUP_HOST_KEY_BORDER", pvar,
2798 "<Host Keys below this line are disabled>");
2799 name = pvar->ts->UIMsg;
2800 } else {
2801 name = get_ssh_keytype_name(index);
2802 }
2803
2804 if (name != NULL) {
2805 SendMessage(hostkeyControl, LB_ADDSTRING, 0, (LPARAM) name);
2806 }
2807 }
2808 SendMessage(hostkeyControl, LB_SETCURSEL, 0, 0);
2809 set_move_button_status(dlg, IDC_SSHHOST_KEY_LIST, IDC_SSHHOST_KEY_MOVEUP, IDC_SSHHOST_KEY_MOVEDOWN);
2810