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 6263 - (show annotations) (download) (as text)
Mon Jan 18 09:24:32 2016 UTC (8 years, 2 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 196813 byte(s)
diffie-hellman-group{14,15,16}-sha256 鍵交換方式に対応
https://osdn.jp/ticket/browse.php?group_id=1412&tid=35921

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