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 7048 - (show annotations) (download) (as text)
Wed Feb 21 03:02:02 2018 UTC (6 years, 1 month ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 184249 byte(s)
設定で SSH_MSG_USERAUTH_BANNER の表示方法を設定できるようにした

[TTSSH]
; Authentication Banner
;  0 ... ignore
;  1 ... display in VT window
;  2 ... display by popup message box
;  3 ... display by balloon tip
AuthBanner=1

また、メッセージボックスでの表示にも対応した。

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