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