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