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 6031 - (show annotations) (download) (as text)
Fri Sep 25 02:27:17 2015 UTC (8 years, 6 months ago) by maya
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 194323 byte(s)
TERATERM.INI の設定値に現れない鍵交換・ホスト鍵・暗号化・MAC・圧縮方式の追加位置を変更
  https://osdn.jp/ticket/browse.php?group_id=1412&tid=35201

  末尾に追加
  ↓
  デフォルトで有効な方式...使用される方式の末尾に追加
  デフォルトで無効な方式...使用されない方式の末尾に追加
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 static void PASCAL FAR TTXOpenTCP(TTXSockHooks FAR * hooks)
966 {
967 if (pvar->settings.Enabled) {
968 // TCPLocalEcho/TCPCRSend ������������ (maya 2007.4.25)
969 pvar->origDisableTCPEchoCR = pvar->ts->DisableTCPEchoCR;
970 pvar->ts->DisableTCPEchoCR = TRUE;
971
972 pvar->session_settings = pvar->settings;
973
974 notify_verbose_message(pvar, "---------------------------------------------------------------------", LOG_LEVEL_VERBOSE);
975 notify_verbose_message(pvar, "Initiating SSH session", LOG_LEVEL_VERBOSE);
976
977 FWDUI_load_settings(pvar);
978
979 pvar->cv->TelAutoDetect = FALSE;
980 /* This next line should not be needed because Tera Term's
981 CommLib should find ts->Telnet == 0 ... but we'll do this
982 just to be on the safe side. */
983 pvar->cv->TelFlag = FALSE;
984 pvar->cv->TelLineMode = FALSE;
985
986 pvar->Precv = *hooks->Precv;
987 pvar->Psend = *hooks->Psend;
988 pvar->PWSAAsyncSelect = *hooks->PWSAAsyncSelect;
989 pvar->Pconnect = *hooks->Pconnect;
990 pvar->PWSAGetLastError = *hooks->PWSAGetLastError;
991
992 *hooks->Precv = TTXrecv;
993 *hooks->Psend = TTXsend;
994 *hooks->PWSAAsyncSelect = TTXWSAAsyncSelect;
995 *hooks->Pconnect = TTXconnect;
996
997 SSH_open(pvar);
998 HOSTS_open(pvar);
999 FWDUI_open(pvar);
1000
1001 // ������ myproposal �����f���������A�������O�����������B (2006.6.26 maya)
1002 SSH2_update_cipher_myproposal(pvar);
1003 SSH2_update_kex_myproposal(pvar);
1004 SSH2_update_host_key_myproposal(pvar);
1005 SSH2_update_hmac_myproposal(pvar);
1006 SSH2_update_compression_myproposal(pvar);
1007 }
1008 }
1009
1010 static void PASCAL FAR TTXCloseTCP(TTXSockHooks FAR * hooks)
1011 {
1012 if (pvar->session_settings.Enabled) {
1013 pvar->socket = INVALID_SOCKET;
1014
1015 notify_verbose_message(pvar, "Terminating SSH session...",
1016 LOG_LEVEL_VERBOSE);
1017
1018 *hooks->Precv = pvar->Precv;
1019 *hooks->Psend = pvar->Psend;
1020 *hooks->PWSAAsyncSelect = pvar->PWSAAsyncSelect;
1021 *hooks->Pconnect = pvar->Pconnect;
1022
1023 pvar->ts->DisableTCPEchoCR = pvar->origDisableTCPEchoCR;
1024 }
1025
1026 uninit_TTSSH(pvar);
1027 init_TTSSH(pvar);
1028 }
1029
1030 static void enable_dlg_items(HWND dlg, int from, int to, BOOL enabled)
1031 {
1032 for (; from <= to; from++) {
1033 EnableWindow(GetDlgItem(dlg, from), enabled);
1034 }
1035 }
1036
1037 // C-p/C-n/C-b/C-f/C-a/C-e ���T�|�[�g (2007.9.5 maya)
1038 // C-d/C-k ���T�|�[�g (2007.10.3 yutaka)
1039 // �h���b�v�_�E���������G�f�B�b�g�R���g���[����
1040 // �T�u�N���X�������������E�C���h�E�v���V�[�W��
1041 WNDPROC OrigHostnameEditProc; // Original window procedure
1042 LRESULT CALLBACK HostnameEditProc(HWND dlg, UINT msg,
1043 WPARAM wParam, LPARAM lParam)
1044 {
1045 HWND parent;
1046 int max, select, len;
1047 char *str, *orgstr;
1048
1049 switch (msg) {
1050 // �L�[�����������������m����
1051 case WM_KEYDOWN:
1052 if (GetKeyState(VK_CONTROL) < 0) {
1053 switch (wParam) {
1054 case 0x50: // Ctrl+p ... up
1055 parent = GetParent(dlg);
1056 select = SendMessage(parent, CB_GETCURSEL, 0, 0);
1057 if (select > 0) {
1058 PostMessage(parent, CB_SETCURSEL, select - 1, 0);
1059 }
1060 return 0;
1061 case 0x4e: // Ctrl+n ... down
1062 parent = GetParent(dlg);
1063 max = SendMessage(parent, CB_GETCOUNT, 0, 0);
1064 select = SendMessage(parent, CB_GETCURSEL, 0, 0);
1065 if (select < max - 1) {
1066 PostMessage(parent, CB_SETCURSEL, select + 1, 0);
1067 }
1068 return 0;
1069 case 0x42: // Ctrl+b ... left
1070 SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1071 PostMessage(dlg, EM_SETSEL, select-1, select-1);
1072 return 0;
1073 case 0x46: // Ctrl+f ... right
1074 SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1075 max = GetWindowTextLength(dlg) ;
1076 PostMessage(dlg, EM_SETSEL, select+1, select+1);
1077 return 0;
1078 case 0x41: // Ctrl+a ... home
1079 PostMessage(dlg, EM_SETSEL, 0, 0);
1080 return 0;
1081 case 0x45: // Ctrl+e ... end
1082 max = GetWindowTextLength(dlg) ;
1083 PostMessage(dlg, EM_SETSEL, max, max);
1084 return 0;
1085
1086 case 0x44: // Ctrl+d
1087 case 0x4b: // Ctrl+k
1088 case 0x55: // Ctrl+u
1089 SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1090 max = GetWindowTextLength(dlg);
1091 max++; // '\0'
1092 orgstr = str = malloc(max);
1093 if (str != NULL) {
1094 len = GetWindowText(dlg, str, max);
1095 if (select >= 0 && select < len) {
1096 if (wParam == 0x44) { // �J�[�\���z����������������������
1097 memmove(&str[select], &str[select + 1], len - select - 1);
1098 str[len - 1] = '\0';
1099
1100 } else if (wParam == 0x4b) { // �J�[�\�������s��������������
1101 str[select] = '\0';
1102
1103 }
1104 }
1105
1106 if (wParam == 0x55) { // �J�[�\����������������������
1107 if (select >= len) {
1108 str[0] = '\0';
1109 } else {
1110 str = &str[select];
1111 }
1112 select = 0;
1113 }
1114
1115 SetWindowText(dlg, str);
1116 SendMessage(dlg, EM_SETSEL, select, select);
1117 free(orgstr);
1118 return 0;
1119 }
1120 break;
1121 }
1122 }
1123 break;
1124
1125 // �����L�[��������������������������������������������
1126 case WM_CHAR:
1127 switch (wParam) {
1128 case 0x01:
1129 case 0x02:
1130 case 0x04:
1131 case 0x05:
1132 case 0x06:
1133 case 0x0b:
1134 case 0x0e:
1135 case 0x10:
1136 case 0x15:
1137 return 0;
1138 }
1139 }
1140
1141 return CallWindowProc(OrigHostnameEditProc, dlg, msg, wParam, lParam);
1142 }
1143
1144 static BOOL CALLBACK TTXHostDlg(HWND dlg, UINT msg, WPARAM wParam,
1145 LPARAM lParam)
1146 {
1147 static char *ssh_version[] = {"SSH1", "SSH2", NULL};
1148 PGetHNRec GetHNRec;
1149 char EntName[128];
1150 char TempHost[HostNameMaxLength + 1];
1151 WORD i, j, w;
1152 WORD ComPortTable[MAXCOMPORT];
1153 static char *ComPortDesc[MAXCOMPORT];
1154 int comports;
1155 BOOL Ok;
1156 LOGFONT logfont;
1157 HFONT font;
1158 char uimsg[MAX_UIMSG];
1159 static HWND hwndHostname = NULL; // HOSTNAME dropdown
1160 static HWND hwndHostnameEdit = NULL; // Edit control on HOSTNAME dropdown
1161
1162 switch (msg) {
1163 case WM_INITDIALOG:
1164 GetHNRec = (PGetHNRec) lParam;
1165 SetWindowLong(dlg, DWL_USER, lParam);
1166
1167 GetWindowText(dlg, uimsg, sizeof(uimsg));
1168 UTIL_get_lang_msg("DLG_HOST_TITLE", pvar, uimsg);
1169 SetWindowText(dlg, pvar->ts->UIMsg);
1170 GetDlgItemText(dlg, IDC_HOSTNAMELABEL, uimsg, sizeof(uimsg));
1171 UTIL_get_lang_msg("DLG_HOST_TCPIPHOST", pvar, uimsg);
1172 SetDlgItemText(dlg, IDC_HOSTNAMELABEL, pvar->ts->UIMsg);
1173 GetDlgItemText(dlg, IDC_HISTORY, uimsg, sizeof(uimsg));
1174 UTIL_get_lang_msg("DLG_HOST_TCPIPHISTORY", pvar, uimsg);
1175 SetDlgItemText(dlg, IDC_HISTORY, pvar->ts->UIMsg);
1176 GetDlgItemText(dlg, IDC_SERVICELABEL, uimsg, sizeof(uimsg));
1177 UTIL_get_lang_msg("DLG_HOST_TCPIPSERVICE", pvar, uimsg);
1178 SetDlgItemText(dlg, IDC_SERVICELABEL, pvar->ts->UIMsg);
1179 GetDlgItemText(dlg, IDC_HOSTOTHER, uimsg, sizeof(uimsg));
1180 UTIL_get_lang_msg("DLG_HOST_TCPIPOTHER", pvar, uimsg);
1181 SetDlgItemText(dlg, IDC_HOSTOTHER, pvar->ts->UIMsg);
1182 GetDlgItemText(dlg, IDC_HOSTTCPPORTLABEL, uimsg, sizeof(uimsg));
1183 UTIL_get_lang_msg("DLG_HOST_TCPIPPORT", pvar, uimsg);
1184 SetDlgItemText(dlg, IDC_HOSTTCPPORTLABEL, pvar->ts->UIMsg);
1185 GetDlgItemText(dlg, IDC_SSH_VERSION_LABEL, uimsg, sizeof(uimsg));
1186 UTIL_get_lang_msg("DLG_HOST_TCPIPSSHVERSION", pvar, uimsg);
1187 SetDlgItemText(dlg, IDC_SSH_VERSION_LABEL, pvar->ts->UIMsg);
1188 GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOLLABEL, uimsg, sizeof(uimsg));
1189 UTIL_get_lang_msg("DLG_HOST_TCPIPPROTOCOL", pvar, uimsg);
1190 SetDlgItemText(dlg, IDC_HOSTTCPPROTOCOLLABEL, pvar->ts->UIMsg);
1191 GetDlgItemText(dlg, IDC_HOSTSERIAL, uimsg, sizeof(uimsg));
1192 UTIL_get_lang_msg("DLG_HOST_SERIAL", pvar, uimsg);
1193 SetDlgItemText(dlg, IDC_HOSTSERIAL, pvar->ts->UIMsg);
1194 GetDlgItemText(dlg, IDC_HOSTCOMLABEL, uimsg, sizeof(uimsg));
1195 UTIL_get_lang_msg("DLG_HOST_SERIALPORT", pvar, uimsg);
1196 SetDlgItemText(dlg, IDC_HOSTCOMLABEL, pvar->ts->UIMsg);
1197 GetDlgItemText(dlg, IDC_HOSTHELP, uimsg, sizeof(uimsg));
1198 UTIL_get_lang_msg("DLG_HOST_HELP", pvar, uimsg);
1199 SetDlgItemText(dlg, IDC_HOSTHELP, pvar->ts->UIMsg);
1200 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
1201 UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
1202 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
1203 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1204 UTIL_get_lang_msg("BTN_CANCEL", pvar, uimsg);
1205 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1206
1207 // �z�X�g�q�X�g�����`�F�b�N�{�b�N�X������ (2005.10.21 yutaka)
1208 if (pvar->ts->HistoryList > 0) {
1209 SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_SETCHECK, BST_CHECKED, 0);
1210 } else {
1211 SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_SETCHECK, BST_UNCHECKED, 0);
1212 }
1213
1214 // �t�@�C�����������O�t���p�C�v�������ATCP/IP�����������B
1215 if (GetHNRec->PortType == IdFile ||
1216 GetHNRec->PortType == IdNamedPipe
1217 )
1218 GetHNRec->PortType = IdTCPIP;
1219
1220 strncpy_s(EntName, sizeof(EntName), "Host", _TRUNCATE);
1221
1222 i = 1;
1223 do {
1224 _snprintf_s(&EntName[4], sizeof(EntName)-4, _TRUNCATE, "%d", i);
1225 GetPrivateProfileString("Hosts", EntName, "",
1226 TempHost, sizeof(TempHost),
1227 GetHNRec->SetupFN);
1228 if (strlen(TempHost) > 0)
1229 SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_ADDSTRING,
1230 0, (LPARAM) TempHost);
1231 i++;
1232 } while (i <= MAXHOSTLIST);
1233
1234 SendDlgItemMessage(dlg, IDC_HOSTNAME, EM_LIMITTEXT,
1235 HostNameMaxLength - 1, 0);
1236
1237 SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_SETCURSEL, 0, 0);
1238
1239 // C-n/C-p ���������T�u�N���X�� (2007.9.4 maya)
1240 hwndHostname = GetDlgItem(dlg, IDC_HOSTNAME);
1241 hwndHostnameEdit = GetWindow(hwndHostname, GW_CHILD);
1242 OrigHostnameEditProc = (WNDPROC)GetWindowLong(hwndHostnameEdit, GWL_WNDPROC);
1243 SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)HostnameEditProc);
1244
1245 CheckRadioButton(dlg, IDC_HOSTTELNET, IDC_HOSTOTHER,
1246 pvar->settings.Enabled ? IDC_HOSTSSH : GetHNRec->
1247 Telnet ? IDC_HOSTTELNET : IDC_HOSTOTHER);
1248 SendDlgItemMessage(dlg, IDC_HOSTTCPPORT, EM_LIMITTEXT, 5, 0);
1249 SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TCPPort, FALSE);
1250 #ifndef NO_INET6
1251 for (i = 0; ProtocolFamilyList[i]; ++i) {
1252 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_ADDSTRING,
1253 0, (LPARAM) ProtocolFamilyList[i]);
1254 }
1255 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, EM_LIMITTEXT,
1256 ProtocolFamilyMaxLength - 1, 0);
1257 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_SETCURSEL, 0, 0);
1258 #endif /* NO_INET6 */
1259
1260 /////// SSH version
1261 for (i = 0; ssh_version[i]; ++i) {
1262 SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_ADDSTRING,
1263 0, (LPARAM) ssh_version[i]);
1264 }
1265 SendDlgItemMessage(dlg, IDC_SSH_VERSION, EM_LIMITTEXT,
1266 NUM_ELEM(ssh_version) - 1, 0);
1267
1268 if (pvar->settings.ssh_protocol_version == 1) {
1269 SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 0, 0); // SSH1
1270 } else {
1271 SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 1, 0); // SSH2
1272 }
1273
1274 if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1275 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE); // enabled
1276 } else {
1277 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1278 }
1279 /////// SSH version
1280
1281
1282 j = 0;
1283 w = 1;
1284 if ((comports=DetectComPorts(ComPortTable, GetHNRec->MaxComPort, ComPortDesc)) >= 0) {
1285 for (i=0; i<comports; i++) {
1286 // MaxComPort ���z�����|�[�g���\��������
1287 if (ComPortTable[i] > GetHNRec->MaxComPort) {
1288 continue;
1289 }
1290
1291 // �g�p�����|�[�g���\��������
1292 if (CheckCOMFlag(ComPortTable[i]) == 1) {
1293 continue;
1294 }
1295
1296 _snprintf_s(EntName, sizeof(EntName), _TRUNCATE, "COM%d", ComPortTable[i]);
1297 if (ComPortDesc[i] != NULL) {
1298 strncat_s(EntName, sizeof(EntName), ": ", _TRUNCATE);
1299 strncat_s(EntName, sizeof(EntName), ComPortDesc[i], _TRUNCATE);
1300 }
1301 SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_ADDSTRING,
1302 0, (LPARAM)EntName);
1303 j++;
1304 if (GetHNRec->ComPort == ComPortTable[i])
1305 w = j;
1306 }
1307
1308 } else {
1309 for (i = 1; i <= GetHNRec->MaxComPort; i++) {
1310 // �g�p�����|�[�g���\��������
1311 if (CheckCOMFlag(i) == 1) {
1312 continue;
1313 }
1314
1315 _snprintf_s(EntName, sizeof(EntName), _TRUNCATE, "COM%d", i);
1316 SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_ADDSTRING,
1317 0, (LPARAM) EntName);
1318 j++;
1319 if (GetHNRec->ComPort == i)
1320 w = j;
1321 }
1322 }
1323
1324 if (j > 0)
1325 SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_SETCURSEL, w - 1, 0);
1326 else { /* All com ports are already used */
1327 GetHNRec->PortType = IdTCPIP;
1328 enable_dlg_items(dlg, IDC_HOSTSERIAL, IDC_HOSTSERIAL, FALSE);
1329 }
1330
1331 CheckRadioButton(dlg, IDC_HOSTTCPIP, IDC_HOSTSERIAL,
1332 IDC_HOSTTCPIP + GetHNRec->PortType - 1);
1333
1334 if (GetHNRec->PortType == IdTCPIP) {
1335 enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
1336
1337 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE);
1338 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE);
1339
1340 enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, TRUE); // enabled
1341 }
1342 #ifndef NO_INET6
1343 else {
1344 enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1345 FALSE);
1346 enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1347 IDC_HOSTTCPPROTOCOL, FALSE);
1348
1349 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1350 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1351
1352 enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, FALSE); // disabled
1353 }
1354 #else
1355 else
1356 enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1357 FALSE);
1358 #endif /* NO_INET6 */
1359
1360 // Host dialog���t�H�[�J�X�������� (2004.10.2 yutaka)
1361 if (GetHNRec->PortType == IdTCPIP) {
1362 HWND hwnd = GetDlgItem(dlg, IDC_HOSTNAME);
1363 SetFocus(hwnd);
1364 } else {
1365 HWND hwnd = GetDlgItem(dlg, IDC_HOSTCOM);
1366 SetFocus(hwnd);
1367 }
1368
1369 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1370 GetObject(font, sizeof(LOGFONT), &logfont);
1371 if (UTIL_get_lang_font("DLG_SYSTEM_FONT", dlg, &logfont, &DlgHostFont, pvar)) {
1372 SendDlgItemMessage(dlg, IDC_HOSTTCPIP, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1373 SendDlgItemMessage(dlg, IDC_HOSTNAMELABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1374 SendDlgItemMessage(dlg, IDC_HOSTNAME, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1375 SendDlgItemMessage(dlg, IDC_HISTORY, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1376 SendDlgItemMessage(dlg, IDC_SERVICELABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1377 SendDlgItemMessage(dlg, IDC_HOSTTELNET, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1378 SendDlgItemMessage(dlg, IDC_HOSTSSH, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1379 SendDlgItemMessage(dlg, IDC_HOSTOTHER, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1380 SendDlgItemMessage(dlg, IDC_HOSTTCPPORTLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1381 SendDlgItemMessage(dlg, IDC_HOSTTCPPORT, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1382 SendDlgItemMessage(dlg, IDC_SSH_VERSION_LABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1383 SendDlgItemMessage(dlg, IDC_SSH_VERSION, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1384 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOLLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1385 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1386 SendDlgItemMessage(dlg, IDC_HOSTSERIAL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1387 SendDlgItemMessage(dlg, IDC_HOSTCOMLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1388 SendDlgItemMessage(dlg, IDC_HOSTCOM, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1389 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1390 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1391 SendDlgItemMessage(dlg, IDC_HOSTHELP, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1392 }
1393 else {
1394 DlgHostFont = NULL;
1395 }
1396
1397 // SetFocus()���t�H�[�J�X���������������AFALSE�������K�v�������B
1398 // TRUE���������ATABSTOP�������������������R���g���[�����I�������B
1399 // (2004.11.23 yutaka)
1400 return FALSE;
1401 //return TRUE;
1402
1403 case WM_COMMAND:
1404 switch (LOWORD(wParam)) {
1405 case IDOK:
1406 GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1407 if (GetHNRec != NULL) {
1408 if (IsDlgButtonChecked(dlg, IDC_HOSTTCPIP)) {
1409 #ifndef NO_INET6
1410 char afstr[BUFSIZ];
1411 #endif /* NO_INET6 */
1412 i = GetDlgItemInt(dlg, IDC_HOSTTCPPORT, &Ok, FALSE);
1413 if (Ok) {
1414 GetHNRec->TCPPort = i;
1415 } else {
1416 UTIL_get_lang_msg("MSG_TCPPORT_NAN_ERROR", pvar,
1417 "The TCP port must be a number.");
1418 MessageBox(dlg, pvar->ts->UIMsg,
1419 "Tera Term", MB_OK | MB_ICONEXCLAMATION);
1420 return TRUE;
1421 }
1422 #ifndef NO_INET6
1423 #define getaf(str) \
1424 ((strcmp((str), "IPv6") == 0) ? AF_INET6 : \
1425 ((strcmp((str), "IPv4") == 0) ? AF_INET : AF_UNSPEC))
1426 memset(afstr, 0, sizeof(afstr));
1427 GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOL, afstr,
1428 sizeof(afstr));
1429 GetHNRec->ProtocolFamily = getaf(afstr);
1430 #endif /* NO_INET6 */
1431 GetHNRec->PortType = IdTCPIP;
1432 GetDlgItemText(dlg, IDC_HOSTNAME, GetHNRec->HostName,
1433 HostNameMaxLength);
1434 pvar->hostdlg_activated = TRUE;
1435 pvar->hostdlg_Enabled = FALSE;
1436 if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1437 GetHNRec->Telnet = TRUE;
1438 } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1439 pvar->hostdlg_Enabled = TRUE;
1440
1441 // check SSH protocol version
1442 memset(afstr, 0, sizeof(afstr));
1443 GetDlgItemText(dlg, IDC_SSH_VERSION, afstr, sizeof(afstr));
1444 if (_stricmp(afstr, "SSH1") == 0) {
1445 pvar->settings.ssh_protocol_version = 1;
1446 } else {
1447 pvar->settings.ssh_protocol_version = 2;
1448 }
1449 }
1450 else { // IDC_HOSTOTHER
1451 GetHNRec->Telnet = FALSE;
1452 }
1453
1454 // host history check button
1455 if (SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_GETCHECK, 0, 0) == BST_CHECKED) {
1456 pvar->ts->HistoryList = 1;
1457 } else {
1458 pvar->ts->HistoryList = 0;
1459 }
1460
1461 } else {
1462 GetHNRec->PortType = IdSerial;
1463 GetHNRec->HostName[0] = 0;
1464 memset(EntName, 0, sizeof(EntName));
1465 GetDlgItemText(dlg, IDC_HOSTCOM, EntName,
1466 sizeof(EntName) - 1);
1467 if (strncmp(EntName, "COM", 3) == 0 && EntName[3] != '\0') {
1468 #if 0
1469 GetHNRec->ComPort = (BYTE) (EntName[3]) - 0x30;
1470 if (strlen(EntName) > 4)
1471 GetHNRec->ComPort =
1472 GetHNRec->ComPort * 10 + (BYTE) (EntName[4]) -
1473 0x30;
1474 #else
1475 GetHNRec->ComPort = atoi(&EntName[3]);
1476 #endif
1477 if (GetHNRec->ComPort > GetHNRec->MaxComPort)
1478 GetHNRec->ComPort = 1;
1479 } else {
1480 GetHNRec->ComPort = 1;
1481 }
1482 }
1483 }
1484 SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)OrigHostnameEditProc);
1485 EndDialog(dlg, 1);
1486
1487 if (DlgHostFont != NULL) {
1488 DeleteObject(DlgHostFont);
1489 }
1490
1491 return TRUE;
1492
1493 case IDCANCEL:
1494 SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)OrigHostnameEditProc);
1495 EndDialog(dlg, 0);
1496
1497 if (DlgHostFont != NULL) {
1498 DeleteObject(DlgHostFont);
1499 }
1500
1501 return TRUE;
1502
1503 case IDC_HOSTTCPIP:
1504 enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1505 TRUE);
1506 #ifndef NO_INET6
1507 enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1508 IDC_HOSTTCPPROTOCOL, TRUE);
1509 #endif /* NO_INET6 */
1510 enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
1511
1512 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE); // disabled (2004.11.23 yutaka)
1513 if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1514 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE);
1515 } else {
1516 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1517 }
1518
1519 enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, TRUE); // disabled
1520
1521 return TRUE;
1522
1523 case IDC_HOSTSERIAL:
1524 enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, TRUE);
1525 enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1526 FALSE);
1527 #ifndef NO_INET6
1528 enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1529 IDC_HOSTTCPPROTOCOL, FALSE);
1530 #endif /* NO_INET6 */
1531 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1532 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1533
1534 enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, FALSE); // disabled
1535
1536 return TRUE;
1537
1538 case IDC_HOSTSSH:
1539 enable_dlg_items(dlg, IDC_SSH_VERSION,
1540 IDC_SSH_VERSION, TRUE);
1541 goto hostssh_enabled;
1542
1543 case IDC_HOSTTELNET:
1544 case IDC_HOSTOTHER:
1545 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1546 hostssh_enabled:
1547
1548 GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1549
1550 if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1551 if (GetHNRec != NULL)
1552 SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TelPort,
1553 FALSE);
1554 } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1555 SetDlgItemInt(dlg, IDC_HOSTTCPPORT, 22, FALSE);
1556 }
1557 return TRUE;
1558
1559 case IDC_HOSTCOM:
1560 if(HIWORD(wParam) == CBN_DROPDOWN) {
1561 HWND hostcom = GetDlgItem(dlg, IDC_HOSTCOM);
1562 int count = SendMessage(hostcom, CB_GETCOUNT, 0, 0);
1563 int i, len, max_len = 0;
1564 char *lbl;
1565 HDC TmpDC = GetDC(hostcom);
1566 SIZE s;
1567 for (i=0; i<count; i++) {
1568 len = SendMessage(hostcom, CB_GETLBTEXTLEN, i, 0);
1569 lbl = (char *)calloc(len+1, sizeof(char));
1570 SendMessage(hostcom, CB_GETLBTEXT, i, (LPARAM)lbl);
1571 GetTextExtentPoint32(TmpDC, lbl, len, &s);
1572 if (s.cx > max_len)
1573 max_len = s.cx;
1574 free(lbl);
1575 }
1576 SendMessage(hostcom, CB_SETDROPPEDWIDTH,
1577 max_len + GetSystemMetrics(SM_CXVSCROLL), 0);
1578 }
1579 break;
1580
1581 case IDC_HOSTHELP:
1582 PostMessage(GetParent(dlg), WM_USER_DLGHELP2, 0, 0);
1583 }
1584 }
1585 return FALSE;
1586 }
1587
1588 static BOOL FAR PASCAL TTXGetHostName(HWND parent, PGetHNRec rec)
1589 {
1590 return (BOOL) DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HOSTDLG),
1591 parent, TTXHostDlg, (LONG) rec);
1592 }
1593
1594 static void PASCAL FAR TTXGetUIHooks(TTXUIHooks FAR * hooks)
1595 {
1596 *hooks->GetHostName = TTXGetHostName;
1597 }
1598
1599 static void FAR PASCAL TTXReadINIFile(PCHAR fileName, PTTSet ts)
1600 {
1601 (pvar->ReadIniFile) (fileName, ts);
1602 read_ssh_options(pvar, fileName);
1603 pvar->settings = *pvar->ts_SSH;
1604 notify_verbose_message(pvar, "Reading INI file", LOG_LEVEL_VERBOSE);
1605 FWDUI_load_settings(pvar);
1606 }
1607
1608 static void FAR PASCAL TTXWriteINIFile(PCHAR fileName, PTTSet ts)
1609 {
1610 (pvar->WriteIniFile) (fileName, ts);
1611 *pvar->ts_SSH = pvar->settings;
1612 clear_local_settings(pvar);
1613 notify_verbose_message(pvar, "Writing INI file", LOG_LEVEL_VERBOSE);
1614 write_ssh_options(pvar, fileName, pvar->ts_SSH, TRUE);
1615 }
1616
1617 static void read_ssh_options_from_user_file(PTInstVar pvar,
1618 char FAR * user_file_name)
1619 {
1620 if (user_file_name[0] == '.') {
1621 read_ssh_options(pvar, user_file_name);
1622 } else {
1623 char buf[1024];
1624
1625 get_teraterm_dir_relative_name(buf, sizeof(buf), user_file_name);
1626 read_ssh_options(pvar, buf);
1627 }
1628
1629 pvar->settings = *pvar->ts_SSH;
1630 FWDUI_load_settings(pvar);
1631 }
1632
1633 // Percent-encode������������src���f�R�[�h����dst���R�s�[�����B
1634 // dstlen��dst���T�C�Y�B�����������������������A�����������������������B
1635 static void percent_decode(char *dst, int dstlen, char *src) {
1636 if (src == NULL || dst == NULL || dstlen < 1) {
1637 return;
1638 }
1639
1640 while (*src != 0 && dstlen > 1) {
1641 if (*src == '%' && isxdigit(*(src+1)) && isxdigit(*(src+2))) {
1642 src++; *dst = (isalpha(*src) ? (*src|0x20) - 'a' + 10 : *src - '0') << 4;
1643 src++; *dst |= (isalpha(*src) ? (*src|0x20) - 'a' + 10 : *src - '0');
1644 src++; dst++;
1645 }
1646 else {
1647 *dst++ = *src++;
1648 }
1649 dstlen--;
1650 }
1651 *dst = 0;
1652 return;
1653 }
1654
1655 void add_forward_param(PTInstVar pvar, char *param)
1656 {
1657 if (pvar->settings.DefaultForwarding[0] == 0) {
1658 strncpy_s(pvar->settings.DefaultForwarding,
1659 sizeof(pvar->settings.DefaultForwarding),
1660 param, _TRUNCATE);
1661 } else {
1662 strncat_s(pvar->settings.DefaultForwarding,
1663 sizeof(pvar->settings.DefaultForwarding),
1664 ";", _TRUNCATE);
1665 strncat_s(pvar->settings.DefaultForwarding,
1666 sizeof(pvar->settings.DefaultForwarding),
1667 param, _TRUNCATE);
1668 }
1669 }
1670
1671 #if 1
1672 static void FAR PASCAL TTXParseParam(PCHAR param, PTTSet ts, PCHAR DDETopic) {
1673 int param_len=strlen(param);
1674 int opt_len = param_len+1;
1675 char *option = (char *)calloc(opt_len, sizeof(char));
1676 char *option2 = (char *)calloc(opt_len, sizeof(char));
1677 int action;
1678 PCHAR start, cur, next;
1679 size_t i;
1680
1681 if (pvar->hostdlg_activated) {
1682 pvar->settings.Enabled = pvar->hostdlg_Enabled;
1683 }
1684
1685 /* the first term shuld be executable filename of Tera Term */
1686 start = GetParam(option, opt_len, param);
1687
1688 cur = start;
1689 while (next = GetParam(option, opt_len, cur)) {
1690 action = OPTION_NONE;
1691
1692 if ((option[0] == '-' || option[0] == '/')) {
1693 if (MATCH_STR(option + 1, "ssh") == 0) {
1694 if (MATCH_STR(option + 4, "-f=") == 0) {
1695 DequoteParam(option2, opt_len, option + 7);
1696 read_ssh_options_from_user_file(pvar, option2);
1697 action = OPTION_CLEAR;
1698 } else if (MATCH_STR(option + 4, "-consume=") == 0) {
1699 DequoteParam(option2, opt_len, option + 13);
1700 read_ssh_options_from_user_file(pvar, option2);
1701 DeleteFile(option2);
1702 action = OPTION_CLEAR;
1703 }
1704
1705 // ttermpro.exe �� /F= �w������ TTSSH ������������ (2006.10.11 maya)
1706 } else if (MATCH_STR_I(option + 1, "f=") == 0) {
1707 DequoteParam(option2, opt_len, option + 3);
1708 read_ssh_options_from_user_file(pvar, option2);
1709 // Tera Term���������������K�v������������������
1710 }
1711 }
1712
1713 switch (action) {
1714 case OPTION_CLEAR:
1715 memset(cur, ' ', next-cur);
1716 break;
1717 case OPTION_REPLACE:
1718 memset(cur, ' ', next-cur);
1719 memcpy(cur+1, option, strlen(option));
1720 break;
1721 }
1722
1723 cur = next;
1724 }
1725
1726 cur = start;
1727 while (next = GetParam(option, opt_len, cur)) {
1728 action = OPTION_NONE;
1729
1730 if ((option[0] == '-' || option[0] == '/')) {
1731 action = OPTION_CLEAR;
1732 if (MATCH_STR(option + 1, "ssh") == 0) {
1733 if (option[4] == 0) {
1734 pvar->settings.Enabled = 1;
1735 } else if (MATCH_STR(option + 4, "-L") == 0 ||
1736 MATCH_STR(option + 4, "-R") == 0) {
1737 char *p = option + 5;
1738 option2[0] = *p;
1739 i = 1;
1740 while (*++p) {
1741 if (*p == ';' || *p == ',') {
1742 option2[i] = 0;
1743 add_forward_param(pvar, option2);
1744 i = 1;
1745 }
1746 else {
1747 option2[i++] = *p;
1748 }
1749 }
1750 if (i > 1) {
1751 option2[i] = 0;
1752 add_forward_param(pvar, option2);
1753 }
1754 } else if (MATCH_STR(option + 4, "-X") == 0) {
1755 add_forward_param(pvar, "X");
1756 if (option+6 != 0) {
1757 strncpy_s(pvar->settings.X11Display,
1758 sizeof(pvar->settings.X11Display),
1759 option + 6, _TRUNCATE);
1760 }
1761 } else if (MATCH_STR(option + 4, "-v") == 0) {
1762 pvar->settings.LogLevel = LOG_LEVEL_VERBOSE;
1763 } else if (_stricmp(option + 4, "-autologin") == 0 ||
1764 _stricmp(option + 4, "-autologon") == 0) {
1765 pvar->settings.TryDefaultAuth = TRUE;
1766 } else if (MATCH_STR_I(option + 4, "-agentconfirm=") == 0) {
1767 if ((_stricmp(option+18, "off") == 0) ||
1768 (_stricmp(option+18, "no") == 0) ||
1769 (_stricmp(option+18, "false") == 0) ||
1770 (_stricmp(option+18, "0") == 0) ||
1771 (_stricmp(option+18, "n") == 0)) {
1772 pvar->settings.ForwardAgentConfirm = 0;
1773 }
1774 else {
1775 pvar->settings.ForwardAgentConfirm = 1;
1776 }
1777
1778 // -axx������������������
1779 } else if (MATCH_STR(option + 4, "-a") == 0) {
1780 pvar->settings.ForwardAgent = FALSE;
1781 } else if (MATCH_STR(option + 4, "-A") == 0) {
1782 pvar->settings.ForwardAgent = TRUE;
1783
1784 } else if (MATCH_STR(option + 4, "-C=") == 0) {
1785 pvar->settings.CompressionLevel = atoi(option+7);
1786 if (pvar->settings.CompressionLevel < 0) {
1787 pvar->settings.CompressionLevel = 0;
1788 }
1789 else if (pvar->settings.CompressionLevel > 9) {
1790 pvar->settings.CompressionLevel = 9;
1791 }
1792 } else if (MATCH_STR(option + 4, "-C") == 0) {
1793 pvar->settings.CompressionLevel = 6;
1794 } else if (MATCH_STR(option + 4, "-c") == 0) {
1795 pvar->settings.CompressionLevel = 0;
1796 } else if (MATCH_STR_I(option + 4, "-icon=") == 0) {
1797 if ((_stricmp(option+10, "old") == 0) ||
1798 (_stricmp(option+10, "yellow") == 0) ||
1799 (_stricmp(option+10, "securett_yellow") == 0)) {
1800 pvar->settings.IconID = IDI_SECURETT_YELLOW;
1801 }
1802 else {
1803 pvar->settings.IconID = IDI_SECURETT;
1804 }
1805
1806 // /ssh1 �� /ssh2 �I�v�V�������V�K���� (2006.9.16 maya)
1807 } else if (MATCH_STR(option + 4, "1") == 0) {
1808 pvar->settings.Enabled = 1;
1809 pvar->settings.ssh_protocol_version = 1;
1810 } else if (MATCH_STR(option + 4, "2") == 0) {
1811 pvar->settings.Enabled = 1;
1812 pvar->settings.ssh_protocol_version = 2;
1813
1814 } else {
1815 char buf[1024];
1816
1817 UTIL_get_lang_msg("MSG_UNKNOWN_OPTION_ERROR", pvar,
1818 "Unrecognized command-line option: %s");
1819 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, option);
1820
1821 MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
1822 }
1823
1824 // ttermpro.exe �� /T= �w�������p�������A������������ (2006.10.19 maya)
1825 } else if (MATCH_STR_I(option + 1, "t=") == 0) {
1826 if (strcmp(option + 3, "2") == 0) {
1827 pvar->settings.Enabled = 1;
1828 // /t=2��ttssh�������g������������
1829 } else {
1830 pvar->settings.Enabled = 0;
1831 action = OPTION_NONE; // Tera Term������������������������
1832 }
1833
1834 // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
1835 } else if (MATCH_STR(option + 1, "1") == 0) {
1836 // command line: /ssh /1 is SSH1 only
1837 pvar->settings.ssh_protocol_version = 1;
1838
1839 } else if (MATCH_STR(option + 1, "2") == 0) {
1840 // command line: /ssh /2 is SSH2 & SSH1
1841 pvar->settings.ssh_protocol_version = 2;
1842
1843 } else if (MATCH_STR(option + 1, "nossh") == 0) {
1844 // '/nossh' �I�v�V�����������B
1845 // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
1846 // �����������������B(2004.10.11 yutaka)
1847 pvar->settings.Enabled = 0;
1848
1849 } else if (MATCH_STR(option + 1, "telnet") == 0) {
1850 // '/telnet' ���w�������������������� '/nossh' ��������
1851 // SSH������������ (2006.9.16 maya)
1852 pvar->settings.Enabled = 0;
1853 // Tera Term �� Telnet �t���O���t����
1854 pvar->ts->Telnet = 1;
1855
1856 } else if (MATCH_STR(option + 1, "auth") == 0) {
1857 // SSH2�������O�C���I�v�V����������
1858 //
1859 // SYNOPSIS: /ssh /auth=passowrd /user=���[�U�� /passwd=�p�X���[�h
1860 // /ssh /auth=publickey /user=���[�U�� /passwd=�p�X���[�h /keyfile=�p�X
1861 // EXAMPLE: /ssh /auth=password /user=nike /passwd=a@bc
1862 // /ssh /auth=publickey /user=foo /passwd=bar /keyfile=d:\tmp\id_rsa
1863 // NOTICE: �p�X���[�h���p�X�������������������A�u�����N���������� @ ���g�������B
1864 //
1865 // (2004.11.30 yutaka)
1866 // (2005.1.26 yutaka) ���������B���J���F���T�|�[�g�B
1867 //
1868 pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
1869
1870 if (MATCH_STR(option + 5, "=password") == 0) { // �p�X���[�h
1871 //pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
1872 pvar->ssh2_authmethod = SSH_AUTH_PASSWORD;
1873
1874 // /auth=challenge ������ (2007.10.5 maya)
1875 } else if (MATCH_STR(option + 5, "=challenge") == 0) { // keyboard-interactive�F��
1876 //pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
1877 pvar->ssh2_authmethod = SSH_AUTH_TIS;
1878
1879 } else if (MATCH_STR(option + 5, "=publickey") == 0) { // ���J���F��
1880 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1881 pvar->ssh2_authmethod = SSH_AUTH_RSA;
1882
1883 } else if (MATCH_STR(option + 5, "=pageant") == 0) { // ���J���F�� by Pageant
1884 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1885 pvar->ssh2_authmethod = SSH_AUTH_PAGEANT;
1886
1887 } else {
1888 // TODO:
1889
1890 }
1891
1892 } else if (MATCH_STR(option + 1, "user=") == 0) {
1893 DequoteParam(option2, opt_len, option + 6);
1894 _snprintf_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), _TRUNCATE, "%s", option2);
1895
1896 } else if (MATCH_STR(option + 1, "passwd=") == 0) {
1897 DequoteParam(option2, opt_len, option + 8);
1898 _snprintf_s(pvar->ssh2_password, sizeof(pvar->ssh2_password), _TRUNCATE, "%s", option2);
1899
1900 } else if (MATCH_STR(option + 1, "keyfile=") == 0) {
1901 DequoteParam(option2, opt_len, option + 9);
1902 _snprintf_s(pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile), _TRUNCATE, "%s", option2);
1903
1904 } else if (MATCH_STR(option + 1, "ask4passwd") == 0) {
1905 // �p�X���[�h������ (2006.9.18 maya)
1906 pvar->ask4passwd = 1;
1907
1908 } else if (MATCH_STR(option + 1, "nosecuritywarning") == 0) {
1909 // known_hosts�`�F�b�N���������B���Y�I�v�V�������g�����A�Z�L�����e�B������������
1910 // �����A�B���I�v�V���������������B
1911 // (2009.10.4 yutaka)
1912 pvar->nocheck_known_hosts = TRUE;
1913
1914 }
1915 else { // Other (not ttssh) option
1916 action = OPTION_NONE; // ttssh���I�v�V������������������������
1917 }
1918
1919 // �p�X���[�h�������������������O�C��������������
1920 // /auth ���F�����\�b�h���w�������������p������ (2006.9.18 maya)
1921 if (pvar->ask4passwd == 1) {
1922 pvar->ssh2_autologin = 0;
1923 }
1924
1925 }
1926 else if ((MATCH_STR_I(option, "ssh://") == 0) ||
1927 (MATCH_STR_I(option, "ssh1://") == 0) ||
1928 (MATCH_STR_I(option, "ssh2://") == 0) ||
1929 (MATCH_STR_I(option, "slogin://") == 0) ||
1930 (MATCH_STR_I(option, "slogin1://") == 0) ||
1931 (MATCH_STR_I(option, "slogin2://") == 0)) {
1932 //
1933 // ssh://user@host/ ����URL�`�����T�|�[�g
1934 // ���{�I�������� telnet:// URL��������
1935 //
1936 // �Q�l:
1937 // RFC3986: Uniform Resource Identifier (URI): Generic Syntax
1938 // RFC4248: The telnet URI Scheme
1939 //
1940 char *p, *p2, *p3;
1941 int optlen, hostlen;
1942
1943 optlen = strlen(option);
1944
1945 // ������':'���O�����������������������A������ssh�v���g�R���o�[�W������������
1946 p = _mbschr(option, ':');
1947 switch (*(p-1)) {
1948 case '1':
1949 pvar->settings.ssh_protocol_version = 1;
1950 break;
1951 case '2':
1952 pvar->settings.ssh_protocol_version = 2;
1953 break;
1954 }
1955
1956 // authority part �����|�C���^������
1957 p += 3;
1958
1959 // path part ������������
1960 if ((p2 = _mbschr(p, '/')) != NULL) {
1961 *p2 = 0;
1962 }
1963
1964 // '@'�������������A���������O�����[�U����
1965 if ((p2 = _mbschr(p, '@')) != NULL) {
1966 *p2 = 0;
1967 // ':'���~���p�X���[�h
1968 if ((p3 = _mbschr(p, ':')) != NULL) {
1969 *p3 = 0;
1970 percent_decode(pvar->ssh2_password, sizeof(pvar->ssh2_password), p3 + 1);
1971 }
1972 percent_decode(pvar->ssh2_username, sizeof(pvar->ssh2_username), p);
1973 // p �� host part ������('@'����������)����������������
1974 p = p2 + 1;
1975 }
1976
1977 // host part �� option �����������������Ascheme part ������
1978 // port�w����������������port���������������������m��������������
1979 hostlen = strlen(p);
1980 memmove_s(option, optlen, p, hostlen);
1981 option[hostlen] = 0;
1982
1983 // �|�[�g�w������������":22"������
1984 #ifndef NO_INET6
1985 if (option[0] == '[' && option[hostlen-1] == ']' || // IPv6 raw address without port
1986 option[0] != '[' && _mbschr(option, ':') == NULL) { // hostname or IPv4 raw address without port
1987 #else
1988 if (_mbschr(option, ':') == NULL) {
1989 #endif /* NO_INET6 */
1990 memcpy_s(option+hostlen, optlen-hostlen, ":22", 3);
1991 hostlen += 3;
1992 }
1993
1994 // �|�[�g�w�����������������X�y�[�X������
1995 memset(option+hostlen, ' ', optlen-hostlen);
1996
1997 pvar->settings.Enabled = 1;
1998
1999 action = OPTION_REPLACE;
2000 }
2001 else if (_mbschr(option, '@') != NULL) {
2002 //
2003 // user@host �`�����T�|�[�g
2004 // ����������ssh�������T�|�[�g�����A���[�U����ttssh���������B
2005 // (ssh�������O -- ttssh�������W������������)
2006 // �����I��telnet authentication option���T�|�[�g��������
2007 // Tera Term�{�����������������������\���B
2008 //
2009 char *p;
2010 p = _mbschr(option, '@');
2011 *p = 0;
2012
2013 strncpy_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), option, _TRUNCATE);
2014
2015 // ���[�U���������X�y�[�X�������B
2016 // ������TTX��Tera Term�{�������������������X�y�[�X�����������������A
2017 // �z�X�g�����������l�����K�v�������B
2018 memset(option, ' ', p-option+1);
2019
2020 action = OPTION_REPLACE;
2021 }
2022
2023
2024 switch (action) {
2025 case OPTION_CLEAR:
2026 memset(cur, ' ', next-cur);
2027 break;
2028 case OPTION_REPLACE:
2029 memset(cur, ' ', next-cur);
2030 memcpy(cur+1, option, strlen(option));
2031 break;
2032 }
2033
2034 cur = next;
2035 }
2036
2037 free(option);
2038
2039 FWDUI_load_settings(pvar);
2040
2041 (pvar->ParseParam) (param, ts, DDETopic);
2042 }
2043 #else
2044 /* returns 1 if the option text must be deleted */
2045 static int parse_option(PTInstVar pvar, char FAR * option)
2046 {
2047 if ((option[0] == '-' || option[0] == '/')) {
2048 if (MATCH_STR(option + 1, "ssh") == 0) {
2049 if (option[4] == 0) {
2050 pvar->settings.Enabled = 1;
2051 } else if (MATCH_STR(option + 4, "-L") == 0 ||
2052 MATCH_STR(option + 4, "-R") == 0 ||
2053 _stricmp(option + 4, "-X") == 0) {
2054 add_forward_param(pvar, option+5);
2055 } else if (MATCH_STR(option + 4, "-X") == 0) {
2056 add_forward_param(pvar, "X");
2057 strncpy_s(pvar->settings.X11Display,
2058 sizeof(pvar->settings.X11Display),
2059 option + 6, _TRUNCATE);
2060 } else if (MATCH_STR(option + 4, "-f=") == 0) {
2061 read_ssh_options_from_user_file(pvar, option + 7);
2062 } else if (MATCH_STR(option + 4, "-v") == 0) {
2063 pvar->settings.LogLevel = LOG_LEVEL_VERBOSE;
2064 } else if (_stricmp(option + 4, "-autologin") == 0 ||
2065 _stricmp(option + 4, "-autologon") == 0) {
2066 pvar->settings.TryDefaultAuth = TRUE;
2067 } else if (MATCH_STR_I(option + 4, "-agentconfirm=") == 0) {
2068 if ((_stricmp(option+18, "off") == 0) ||
2069 (_stricmp(option+18, "no") == 0) ||
2070 (_stricmp(option+18, "false") == 0) ||
2071 (_stricmp(option+18, "0") == 0) ||
2072 (_stricmp(option+18, "n") == 0)) {
2073 pvar->settings.ForwardAgentConfirm = 0;
2074 }
2075 else {
2076 pvar->settings.ForwardAgentConfirm = 1;
2077 }
2078
2079 // -axx������������������
2080 } else if (MATCH_STR(option + 4, "-a") == 0) {
2081 pvar->settings.ForwardAgent = FALSE;
2082 } else if (MATCH_STR(option + 4, "-A") == 0) {
2083 pvar->settings.ForwardAgent = TRUE;
2084
2085 } else if (MATCH_STR(option + 4, "-consume=") == 0) {
2086 read_ssh_options_from_user_file(pvar, option + 13);
2087 DeleteFile(option + 13);
2088
2089 } else if (MATCH_STR(option + 4, "-C=") == 0) {
2090 pvar->settings.CompressionLevel = atoi(option+7);
2091 if (pvar->settings.CompressionLevel < 0) {
2092 pvar->settings.CompressionLevel = 0;
2093 }
2094 else if (pvar->settings.CompressionLevel > 9) {
2095 pvar->settings.CompressionLevel = 9;
2096 }
2097 } else if (MATCH_STR(option + 4, "-C") == 0) {
2098 pvar->settings.CompressionLevel = 6;
2099 } else if (MATCH_STR(option + 4, "-c") == 0) {
2100 pvar->settings.CompressionLevel = 0;
2101 } else if (MATCH_STR_I(option + 4, "-icon=") == 0) {
2102 if ((_stricmp(option+10, "old") == 0) ||
2103 (_stricmp(option+10, "yellow") == 0) ||
2104 (_stricmp(option+10, "securett_yellow") == 0)) {
2105 pvar->settings.IconID = IDI_SECURETT_YELLOW;
2106 }
2107 else {
2108 pvar->settings.IconID = IDI_SECURETT;
2109 }
2110
2111 // /ssh1 �� /ssh2 �I�v�V�������V�K���� (2006.9.16 maya)
2112 } else if (MATCH_STR(option + 4, "1") == 0) {
2113 pvar->settings.Enabled = 1;
2114 pvar->settings.ssh_protocol_version = 1;
2115 } else if (MATCH_STR(option + 4, "2") == 0) {
2116 pvar->settings.Enabled = 1;
2117 pvar->settings.ssh_protocol_version = 2;
2118
2119 } else {
2120 char buf[1024];
2121
2122 UTIL_get_lang_msg("MSG_UNKNOWN_OPTION_ERROR", pvar,
2123 "Unrecognized command-line option: %s");
2124 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, option);
2125
2126 MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
2127 }
2128
2129 // ttermpro.exe �� /T= �w�������p�������A������������ (2006.10.19 maya)
2130 } else if (MATCH_STR_I(option + 1, "t=") == 0) {
2131 if (strcmp(option + 3, "2") == 0) {
2132 pvar->settings.Enabled = 1;
2133 return OPTION_CLEAR; // /t=2��ttssh�������g������������
2134 } else {
2135 pvar->settings.Enabled = 0;
2136 return OPTION_NONE; // Tera Term������������������������
2137 }
2138
2139 // ttermpro.exe �� /F= �w������ TTSSH ������������ (2006.10.11 maya)
2140 } else if (MATCH_STR_I(option + 1, "f=") == 0) {
2141 read_ssh_options_from_user_file(pvar, option + 3);
2142 return OPTION_NONE; // Tera Term���������������K�v������������������
2143
2144 // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
2145 } else if (MATCH_STR(option + 1, "1") == 0) {
2146 // command line: /ssh /1 is SSH1 only
2147 pvar->settings.ssh_protocol_version = 1;
2148
2149 } else if (MATCH_STR(option + 1, "2") == 0) {
2150 // command line: /ssh /2 is SSH2 & SSH1
2151 pvar->settings.ssh_protocol_version = 2;
2152
2153 } else if (MATCH_STR(option + 1, "nossh") == 0) {
2154 // '/nossh' �I�v�V�����������B
2155 // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
2156 // �����������������B(2004.10.11 yutaka)
2157 pvar->settings.Enabled = 0;
2158
2159 } else if (MATCH_STR(option + 1, "telnet") == 0) {
2160 // '/telnet' ���w�������������������� '/nossh' ��������
2161 // SSH������������ (2006.9.16 maya)
2162 pvar->settings.Enabled = 0;
2163 // Tera Term �� Telnet �t���O���t����
2164 pvar->ts->Telnet = 1;
2165
2166 } else if (MATCH_STR(option + 1, "auth") == 0) {
2167 // SSH2�������O�C���I�v�V����������
2168 //
2169 // SYNOPSIS: /ssh /auth=passowrd /user=���[�U�� /passwd=�p�X���[�h
2170 // /ssh /auth=publickey /user=���[�U�� /passwd=�p�X���[�h /keyfile=�p�X
2171 // EXAMPLE: /ssh /auth=password /user=nike /passwd=a@bc
2172 // /ssh /auth=publickey /user=foo /passwd=bar /keyfile=d:\tmp\id_rsa
2173 // NOTICE: �p�X���[�h���p�X�������������������A�u�����N���������� @ ���g�������B
2174 //
2175 // (2004.11.30 yutaka)
2176 // (2005.1.26 yutaka) ���������B���J���F���T�|�[�g�B
2177 //
2178 pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
2179
2180 if (MATCH_STR(option + 5, "=password") == 0) { // �p�X���[�h
2181 //pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
2182 pvar->ssh2_authmethod = SSH_AUTH_PASSWORD;
2183
2184 // /auth=challenge ������ (2007.10.5 maya)
2185 } else if (MATCH_STR(option + 5, "=challenge") == 0) { // keyboard-interactive�F��
2186 //pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
2187 pvar->ssh2_authmethod = SSH_AUTH_TIS;
2188
2189 } else if (MATCH_STR(option + 5, "=publickey") == 0) { // ���J���F��
2190 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
2191 pvar->ssh2_authmethod = SSH_AUTH_RSA;
2192
2193 } else if (MATCH_STR(option + 5, "=pageant") == 0) { // ���J���F�� by Pageant
2194 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
2195 pvar->ssh2_authmethod = SSH_AUTH_PAGEANT;
2196
2197 } else {
2198 // TODO:
2199
2200 }
2201
2202 } else if (MATCH_STR(option + 1, "user=") == 0) {
2203 _snprintf_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), _TRUNCATE, "%s", option + 6);
2204
2205 } else if (MATCH_STR(option + 1, "passwd=") == 0) {
2206 _snprintf_s(pvar->ssh2_password, sizeof(pvar->ssh2_password), _TRUNCATE, "%s", option + 8);
2207
2208 } else if (MATCH_STR(option + 1, "keyfile=") == 0) {
2209 _snprintf_s(pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile), _TRUNCATE, "%s", option + 9);
2210
2211 } else if (MATCH_STR(option + 1, "ask4passwd") == 0) {
2212 // �p�X���[�h������ (2006.9.18 maya)
2213 pvar->ask4passwd = 1;
2214
2215 } else if (MATCH_STR(option + 1, "nosecuritywarning") == 0) {
2216 // known_hosts�`�F�b�N���������B���Y�I�v�V�������g�����A�Z�L�����e�B������������
2217 // �����A�B���I�v�V���������������B
2218 // (2009.10.4 yutaka)
2219 pvar->nocheck_known_hosts = TRUE;
2220
2221 }
2222 else { // Other (not ttssh) option
2223 return OPTION_NONE; // ttssh���I�v�V������������������������
2224 }
2225
2226 // �p�X���[�h�������������������O�C��������������
2227 // /auth ���F�����\�b�h���w�������������p������ (2006.9.18 maya)
2228 if (pvar->ask4passwd == 1) {
2229 pvar->ssh2_autologin = 0;
2230 }
2231 return OPTION_CLEAR;
2232
2233 }
2234 else if ((MATCH_STR_I(option, "ssh://") == 0) ||
2235 (MATCH_STR_I(option, "ssh1://") == 0) ||
2236 (MATCH_STR_I(option, "ssh2://") == 0) ||
2237 (MATCH_STR_I(option, "slogin://") == 0) ||
2238 (MATCH_STR_I(option, "slogin1://") == 0) ||
2239 (MATCH_STR_I(option, "slogin2://") == 0)) {
2240 //
2241 // ssh://user@host/ ����URL�`�����T�|�[�g
2242 // ���{�I�������� telnet:// URL��������
2243 //
2244 // �Q�l:
2245 // RFC3986: Uniform Resource Identifier (URI): Generic Syntax
2246 // RFC4248: The telnet URI Scheme
2247 //
2248 char *p, *p2, *p3;
2249 int optlen, hostlen;
2250
2251 optlen = strlen(option);
2252
2253 // ������':'���O�����������������������A������ssh�v���g�R���o�[�W������������
2254 p = _mbschr(option, ':');
2255 switch (*(p-1)) {
2256 case '1':
2257 pvar->settings.ssh_protocol_version = 1;
2258 break;
2259 case '2':
2260 pvar->settings.ssh_protocol_version = 2;
2261 break;
2262 }
2263
2264 // authority part �����|�C���^������
2265 p += 3;
2266
2267 // path part ������������
2268 if ((p2 = _mbschr(p, '/')) != NULL) {
2269 *p2 = 0;
2270 }
2271
2272 // '@'�������������A���������O�����[�U����
2273 if ((p2 = _mbschr(p, '@')) != NULL) {
2274 *p2 = 0;
2275 // ':'���~���p�X���[�h
2276 if ((p3 = _mbschr(p, ':')) != NULL) {
2277 *p3 = 0;
2278 percent_decode(pvar->ssh2_password, sizeof(pvar->ssh2_password), p3 + 1);
2279 }
2280 percent_decode(pvar->ssh2_username, sizeof(pvar->ssh2_username), p);
2281 // p �� host part ������('@'����������)����������������
2282 p = p2 + 1;
2283 }
2284
2285 // host part �� option �����������������Ascheme part ������
2286 // port�w����������������port���������������������m��������������
2287 hostlen = strlen(p);
2288 memmove_s(option, optlen, p, hostlen);
2289 option[hostlen] = 0;
2290
2291 // �|�[�g�w������������":22"������
2292 #ifndef NO_INET6
2293 if (option[0] == '[' && option[hostlen-1] == ']' || // IPv6 raw address without port
2294 option[0] != '[' && _mbschr(option, ':') == NULL) { // hostname or IPv4 raw address without port
2295 #else
2296 if (_mbschr(option, ':') == NULL) {
2297 #endif /* NO_INET6 */
2298 memcpy_s(option+hostlen, optlen-hostlen, ":22", 3);
2299 hostlen += 3;
2300 }
2301
2302 // �|�[�g�w�����������������X�y�[�X������
2303 memset(option+hostlen, ' ', optlen-hostlen);
2304
2305 pvar->settings.Enabled = 1;
2306
2307 return OPTION_REPLACE;
2308 }
2309 else if (_mbschr(option, '@') != NULL) {
2310 //
2311 // user@host �`�����T�|�[�g
2312 // ����������ssh�������T�|�[�g�����A���[�U����ttssh���������B
2313 // (ssh�������O -- ttssh�������W������������)
2314 // �����I��telnet authentication option���T�|�[�g��������
2315 // Tera Term�{�����������������������\���B
2316 //
2317 char *p;
2318 p = _mbschr(option, '@');
2319 *p = 0;
2320
2321 strncpy_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), option, _TRUNCATE);
2322
2323 // ���[�U���������X�y�[�X�������B
2324 // ������TTX��Tera Term�{�������������������X�y�[�X�����������������A
2325 // �z�X�g�����������l�����K�v�������B
2326 memset(option, ' ', p-option+1);
2327
2328 return OPTION_REPLACE;
2329 }
2330
2331 return OPTION_NONE;
2332 }
2333
2334 static void FAR PASCAL TTXParseParam(PCHAR param, PTTSet ts,
2335 PCHAR DDETopic)
2336 {
2337 int i;
2338 BOOL inParam = FALSE;
2339 BOOL inQuotes = FALSE;
2340 BOOL inEqual = FALSE;
2341 int param_len=strlen(param);
2342 PCHAR start = NULL;
2343 char *buf = (char *)calloc(param_len+1, sizeof(char));
2344 int buflen = 0;
2345
2346 if (pvar->hostdlg_activated) {
2347 pvar->settings.Enabled = pvar->hostdlg_Enabled;
2348 }
2349
2350 for (i = 0; i < param_len; i++) {
2351 if (inQuotes) {
2352 // �������u��"����
2353 if (param[i] == '"') {
2354 if (param[i+1] == '"') {
2355 buf[buflen] = param[i];
2356 buflen++;
2357 i++;
2358 }
2359 else {
2360 // �N�H�[�g���������������������I����
2361 // "��buf�����������������n��
2362 switch (parse_option(pvar, buf)) {
2363 case OPTION_CLEAR:
2364 memset(start, ' ', (param + i) - start + 1);
2365 break;
2366 case OPTION_REPLACE:
2367 memset(start, ' ', (param + i) - start + 1);
2368 buflen = strlen(buf);
2369 memcpy(start, buf, buflen);
2370 break;
2371 }
2372 inParam = FALSE;
2373 inEqual = FALSE;
2374 start = NULL;
2375 memset(buf, 0, param_len);
2376 buflen = 0;
2377 inQuotes = FALSE;
2378 }
2379 }
2380 else {
2381 buf[buflen] = param[i];
2382 buflen++;
2383 }
2384 }
2385 else {
2386 if (!inParam) {
2387 // �����p�����[�^������������
2388 if (param[i] == '"') {
2389 // " ���n����
2390 start = param + i;
2391 inParam = TRUE;
2392 inQuotes = TRUE;
2393 }
2394 else if (param[i] != ' ' && param[i] != '\t') {
2395 // �������n����
2396 buf[buflen] = param[i];
2397 buflen++;
2398 start = param + i;
2399 inParam = TRUE;
2400 }
2401 }
2402 else {
2403 // �������u���p�����[�^����
2404 if (param[i] == ' ' || param[i] == '\t') {
2405 // �N�H�[�g�����������������������I����
2406 switch (parse_option(pvar, buf)) {
2407 case OPTION_CLEAR:
2408 memset(start, ' ', (param + i) - start + 1);
2409 break;
2410 case OPTION_REPLACE:
2411 memset(start, ' ', (param + i) - start + 1);
2412 buflen = strlen(buf);
2413 memcpy(start, buf, buflen);
2414 break;
2415 }
2416 inParam = FALSE;
2417 inEqual = FALSE;
2418 start = NULL;
2419 memset(buf, 0, param_len);
2420 buflen = 0;
2421 }
2422 else {
2423 buf[buflen] = param[i];
2424 buflen++;
2425 if (!inEqual && param[i] == '=') {
2426 inEqual = TRUE;
2427 if (param[i+1] == '"') {
2428 inQuotes = TRUE;
2429 i++;
2430 }
2431 }
2432 }
2433 }
2434 }
2435 }
2436
2437 // buf ���c�����������������n��
2438 // +1������������'\0'�������������������A��������������������
2439 if (strlen(buf) > 0) {
2440 switch (parse_option(pvar, buf)) {
2441 case OPTION_CLEAR:
2442 memset(start, ' ', (param + i) - start);
2443 break;
2444 case OPTION_REPLACE:
2445 memset(start, ' ', (param + i) - start);
2446 buflen = strlen(buf);
2447 memcpy(start, buf, buflen);
2448 break;
2449 }
2450 }
2451 free(buf);
2452
2453 FWDUI_load_settings(pvar);
2454
2455 (pvar->ParseParam) (param, ts, DDETopic);
2456
2457 }
2458 #endif
2459
2460 static void PASCAL FAR TTXGetSetupHooks(TTXSetupHooks FAR * hooks)
2461 {
2462 pvar->ReadIniFile = *hooks->ReadIniFile;
2463 pvar->WriteIniFile = *hooks->WriteIniFile;
2464 pvar->ParseParam = *hooks->ParseParam;
2465
2466 *hooks->ReadIniFile = TTXReadINIFile;
2467 *hooks->WriteIniFile = TTXWriteINIFile;
2468 *hooks->ParseParam = TTXParseParam;
2469 }
2470
2471 static void PASCAL FAR TTXSetWinSize(int rows, int cols)
2472 {
2473 SSH_notify_win_size(pvar, cols, rows);
2474 }
2475
2476 static void insertMenuBeforeItem(HMENU menu, WORD beforeItemID, WORD flags,
2477 WORD newItemID, char FAR * text)
2478 {
2479 int i, j;
2480
2481 for (i = GetMenuItemCount(menu) - 1; i >= 0; i--) {
2482 HMENU submenu = GetSubMenu(menu, i);
2483
2484 for (j = GetMenuItemCount(submenu) - 1; j >= 0; j--) {
2485 if (GetMenuItemID(submenu, j) == beforeItemID) {
2486 InsertMenu(submenu, j, MF_BYPOSITION | flags, newItemID, text);
2487 return;
2488 }
2489 }
2490 }
2491 }
2492
2493 #define GetFileMenu(menu) GetSubMenuByChildID(menu, 50110) // ID_FILE_NEWCONNECTION
2494 #define GetEditMenu(menu) GetSubMenuByChildID(menu, 50210) // ID_EDIT_COPY2
2495 #define GetSetupMenu(menu) GetSubMenuByChildID(menu, 50310) // ID_SETUP_TERMINAL
2496 #define GetControlMenu(menu) GetSubMenuByChildID(menu, 50410) // ID_CONTROL_RESETTERMINAL
2497 #define GetHelpMenu(menu) GetSubMenuByChildID(menu, 50990) // ID_HELP_ABOUT
2498
2499 HMENU GetSubMenuByChildID(HMENU menu, UINT id) {
2500 int i, j, items, subitems, cur_id;
2501 HMENU m;
2502
2503 items = GetMenuItemCount(menu);
2504
2505 for (i=0; i<items; i++) {
2506 if (m = GetSubMenu(menu, i)) {
2507 subitems = GetMenuItemCount(m);
2508 for (j=0; j<subitems; j++) {
2509 cur_id = GetMenuItemID(m, j);
2510 if (cur_id == id) {
2511 return m;
2512 }
2513 }
2514 }
2515 }
2516 return NULL;
2517 }
2518
2519 static void PASCAL FAR TTXModifyMenu(HMENU menu)
2520 {
2521 pvar->FileMenu = GetFileMenu(menu);
2522
2523 /* inserts before ID_HELP_ABOUT */
2524 UTIL_get_lang_msg("MENU_ABOUT", pvar, "About &TTSSH...");
2525 insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU, pvar->ts->UIMsg);
2526
2527 /* inserts before ID_SETUP_TCPIP */
2528 UTIL_get_lang_msg("MENU_SSH", pvar, "SS&H...");
2529 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU, pvar->ts->UIMsg);
2530 /* inserts before ID_SETUP_TCPIP */
2531 UTIL_get_lang_msg("MENU_SSH_AUTH", pvar, "SSH &Authentication...");
2532 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU, pvar->ts->UIMsg);
2533 /* inserts before ID_SETUP_TCPIP */
2534 UTIL_get_lang_msg("MENU_SSH_FORWARD", pvar, "SSH F&orwarding...");
2535 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU, pvar->ts->UIMsg);
2536 UTIL_get_lang_msg("MENU_SSH_KEYGEN", pvar, "SSH KeyGe&nerator...");
2537 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHKEYGENMENU, pvar->ts->UIMsg);
2538
2539 /* inserts before ID_FILE_CHANGEDIR */
2540 UTIL_get_lang_msg("MENU_SSH_SCP", pvar, "SS&H SCP...");
2541 insertMenuBeforeItem(menu, 50170, MF_GRAYED, ID_SSHSCPMENU, pvar->ts->UIMsg);
2542 }
2543
2544 static void PASCAL FAR TTXModifyPopupMenu(HMENU menu) {
2545 if (menu == pvar->FileMenu) {
2546 if (pvar->cv->Ready && pvar->settings.Enabled)
2547 EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_ENABLED);
2548 else
2549 EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_GRAYED);
2550 }
2551 }
2552
2553 static void append_about_text(HWND dlg, char FAR * prefix, char FAR * msg)
2554 {
2555 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
2556 (LPARAM) prefix);
2557 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0, (LPARAM) msg);
2558 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
2559 (LPARAM) (char FAR *) "\r\n");
2560 }
2561
2562 // ���s�t�@�C�������o�[�W�������������� (2005.2.28 yutaka)
2563 void get_file_version(char *exefile, int *major, int *minor, int *release, int *build)
2564 {
2565 typedef struct {
2566 WORD wLanguage;
2567 WORD wCodePage;
2568 } LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
2569 LPLANGANDCODEPAGE lplgcode;
2570 UINT unLen;
2571 DWORD size;
2572 char *buf = NULL;
2573 BOOL ret;
2574 int i;
2575 char fmt[80];
2576 char *pbuf;
2577
2578 size = GetFileVersionInfoSize(exefile, NULL);
2579 if (size == 0) {
2580 goto error;
2581 }
2582 buf = malloc(size);
2583 ZeroMemory(buf, size);
2584
2585 if (GetFileVersionInfo(exefile, 0, size, buf) == FALSE) {
2586 goto error;
2587 }
2588
2589 ret = VerQueryValue(buf,
2590 "\\VarFileInfo\\Translation",
2591 (LPVOID *)&lplgcode, &unLen);
2592 if (ret == FALSE)
2593 goto error;
2594
2595 for (i = 0 ; i < (int)(unLen / sizeof(LANGANDCODEPAGE)) ; i++) {
2596 _snprintf_s(fmt, sizeof(fmt), _TRUNCATE,
2597 "\\StringFileInfo\\%04x%04x\\FileVersion",
2598 lplgcode[i].wLanguage, lplgcode[i].wCodePage);
2599 VerQueryValue(buf, fmt, &pbuf, &unLen);
2600 if (unLen > 0) { // get success
2601 int n, a, b, c, d;
2602
2603 n = sscanf(pbuf, "%d, %d, %d, %d", &a, &b, &c, &d);
2604 if (n == 4) { // convert success
2605 *major = a;
2606 *minor = b;
2607 *release = c;
2608 *build = d;
2609 break;
2610 }
2611 }
2612 }
2613
2614 free(buf);
2615 return;
2616
2617 error:
2618 free(buf);
2619 *major = *minor = *release = *build = 0;
2620 }
2621
2622 static void init_about_dlg(PTInstVar pvar, HWND dlg)
2623 {
2624 char buf[1024];
2625 int a, b, c, d;
2626 char uimsg[MAX_UIMSG];
2627 char *fp = NULL;
2628
2629 GetWindowText(dlg, uimsg, sizeof(uimsg));
2630 UTIL_get_lang_msg("DLG_ABOUT_TITLE", pvar, uimsg);
2631 SetWindowText(dlg, pvar->ts->UIMsg);
2632 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2633 UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
2634 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2635
2636 // TTSSH���o�[�W�������������� (2005.2.28 yutaka)
2637 get_file_version("ttxssh.dll", &a, &b, &c, &d);
2638 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2639 "TTSSH\r\nTera Term Secure Shell extension, %d.%d", a, b);
2640 SendMessage(GetDlgItem(dlg, IDC_TTSSH_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2641
2642 // OpenSSL���o�[�W�������������� (2005.1.24 yutaka)
2643 // ���������� (2005.5.11 yutaka)
2644 // OPENSSL_VERSION_TEXT �}�N�����`���������A�������g�����o�[�W���������������B(2013.11.24 yutaka)
2645 SendMessage(GetDlgItem(dlg, IDC_OPENSSL_VERSION), WM_SETTEXT, 0, (LPARAM)SSLeay_version(SSLEAY_VERSION));
2646
2647 // zlib���o�[�W�������������� (2005.5.11 yutaka)
2648 #ifdef ZLIB_VERSION
2649 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "ZLib %s", ZLIB_VERSION);
2650 #else
2651 _snprintf(buf, sizeof(buf), "ZLib Unknown");
2652 #endif
2653 SendMessage(GetDlgItem(dlg, IDC_ZLIB_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2654
2655 // PuTTY���o�[�W�������������� (2011.7.26 yutaka)
2656 #ifdef PUTTYVERSION
2657 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "PuTTY %s", PUTTYVERSION);
2658 #else
2659 _snprintf(buf, sizeof(buf), "PuTTY Unknown");
2660 #endif
2661 SendMessage(GetDlgItem(dlg, IDC_PUTTY_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2662
2663 // TTSSH�_�C�A���O���\������SSH������������ (2004.10.30 yutaka)
2664 if (pvar->socket != INVALID_SOCKET) {
2665 if (SSHv1(pvar)) {
2666 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
2667 UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID:");
2668 append_about_text(dlg, pvar->ts->UIMsg, buf);
2669 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
2670 UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol:");
2671 append_about_text(dlg, pvar->ts->UIMsg, buf);
2672 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
2673 UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:");
2674 append_about_text(dlg, pvar->ts->UIMsg, buf);
2675 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
2676 UTIL_get_lang_msg("DLG_ABOUT_SERVERKEY", pvar, "Server keys:");
2677 append_about_text(dlg, pvar->ts->UIMsg, buf);
2678 AUTH_get_auth_info(pvar, buf, sizeof(buf));
2679 UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication:");
2680 append_about_text(dlg, pvar->ts->UIMsg, buf);
2681 SSH_get_compression_info(pvar, buf, sizeof(buf));
2682 UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression:");
2683 append_about_text(dlg, pvar->ts->UIMsg, buf);
2684
2685 } else { // SSH2
2686 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
2687 UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID:");
2688 append_about_text(dlg, pvar->ts->UIMsg, buf);
2689 UTIL_get_lang_msg("DLG_ABOUT_CLIENTID", pvar, "Client ID:");
2690 append_about_text(dlg, pvar->ts->UIMsg, pvar->client_version_string);
2691
2692 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
2693 UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol:");
2694 append_about_text(dlg, pvar->ts->UIMsg, buf);
2695
2696 append_about_text(dlg, "KEX:", get_kex_algorithm_name(pvar->kex_type));
2697
2698 strncpy_s(buf, sizeof(buf), get_ssh_keytype_name(pvar->hostkey_type), _TRUNCATE);
2699 UTIL_get_lang_msg("DLG_ABOUT_HOSTKEY", pvar, "Host Key:");
2700 append_about_text(dlg, pvar->ts->UIMsg, buf);
2701
2702 // add MAC algorithm (2004.12.17 yutaka)
2703 buf[0] = '\0';
2704 strncat_s(buf, sizeof(buf), get_ssh2_mac_name(pvar->ctos_hmac) , _TRUNCATE);
2705 UTIL_get_lang_msg("DLG_ABOUT_TOSERVER", pvar, " to server,");
2706 strncat_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2707 strncat_s(buf, sizeof(buf), get_ssh2_mac_name(pvar->stoc_hmac) , _TRUNCATE);
2708 UTIL_get_lang_msg("DLG_ABOUT_FROMSERVER", pvar, " from server");
2709 strncat_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2710 append_about_text(dlg, "MAC:", buf);
2711
2712 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
2713 UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:");
2714 append_about_text(dlg, pvar->ts->UIMsg, buf);
2715 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
2716 UTIL_get_lang_msg("DLG_ABOUT_KEXKEY", pvar, "Key exchange keys:");
2717 append_about_text(dlg, pvar->ts->UIMsg, buf);
2718
2719 AUTH_get_auth_info(pvar, buf, sizeof(buf));
2720 UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication:");
2721 append_about_text(dlg, pvar->ts->UIMsg, buf);
2722
2723 SSH_get_compression_info(pvar, buf, sizeof(buf));
2724 if (pvar->ctos_compression == COMP_DELAYED) { // �x���p�P�b�g���k������ (2006.6.23 yutaka)
2725 UTIL_get_lang_msg("DLG_ABOUT_COMPDELAY", pvar, "Delayed Compression:");
2726 append_about_text(dlg, pvar->ts->UIMsg, buf);
2727 } else {
2728 UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression:");
2729 append_about_text(dlg, pvar->ts->UIMsg, buf);
2730 }
2731 }
2732
2733 // �z�X�g���J����fingerprint���\�������B
2734 // Random art���\�������������������������B
2735 // (2014.5.1 yutaka)
2736 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX);
2737 UTIL_get_lang_msg("DLG_ABOUT_FINGERPRINT", pvar, "Host key's fingerprint:");
2738 append_about_text(dlg, pvar->ts->UIMsg, fp);
2739 free(fp);
2740
2741 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART);
2742 append_about_text(dlg, "", fp);
2743 free(fp);
2744 }
2745 }
2746
2747 // WM_MOUSEWHEEL �� winuser.h �w�b�_���������������������A#define _WIN32_WINNT 0x0400 ���������������������F�������������B
2748 #define WM_MOUSEWHEEL 0x020A
2749 #define WHEEL_DELTA 120
2750 #define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
2751 #define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam))
2752
2753 static WNDPROC g_defAboutDlgEditWndProc; // Edit Control���T�u�N���X���p
2754 static int g_deltaSumAboutDlg = 0; // �}�E�X�z�C�[����Delta�����p
2755
2756 static LRESULT CALLBACK AboutDlgEditWindowProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
2757 {
2758 WORD keys;
2759 short delta;
2760 BOOL page;
2761
2762 switch (msg) {
2763 case WM_KEYDOWN:
2764 // Edit control���� CTRL+A �������������A�e�L�X�g���S�I�������B
2765 if (wp == 'A' && GetKeyState(VK_CONTROL) < 0) {
2766 PostMessage(hWnd, EM_SETSEL, 0, -1);
2767 return 0;
2768 }
2769 break;
2770
2771 case WM_MOUSEWHEEL:
2772 // CTRLorSHIFT + �}�E�X�z�C�[���������A���X�N���[���������B
2773 keys = GET_KEYSTATE_WPARAM(wp);
2774 delta = GET_WHEEL_DELTA_WPARAM(wp);
2775 page = keys & (MK_CONTROL | MK_SHIFT);
2776
2777 if (page == 0)
2778 break;
2779
2780 g_deltaSumAboutDlg += delta;
2781
2782 if (g_deltaSumAboutDlg >= WHEEL_DELTA) {
2783 g_deltaSumAboutDlg -= WHEEL_DELTA;
2784 SendMessage(hWnd, WM_HSCROLL, SB_PAGELEFT , 0);
2785 } else if (g_deltaSumAboutDlg <= -WHEEL_DELTA) {
2786 g_deltaSumAboutDlg += WHEEL_DELTA;
2787 SendMessage(hWnd, WM_HSCROLL, SB_PAGERIGHT, 0);
2788 }
2789
2790 break;
2791 }
2792 return CallWindowProc(g_defAboutDlgEditWndProc, hWnd, msg, wp, lp);
2793 }
2794
2795 static BOOL CALLBACK TTXAboutDlg(HWND dlg, UINT msg, WPARAM wParam,
2796 LPARAM lParam)
2797 {
2798 LOGFONT logfont;
2799 HFONT font;
2800
2801 switch (msg) {
2802 case WM_INITDIALOG:
2803 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2804 GetObject(font, sizeof(LOGFONT), &logfont);
2805 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgAboutFont, pvar)) {
2806 SendDlgItemMessage(dlg, IDC_TTSSH_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2807 SendDlgItemMessage(dlg, IDC_SSHVERSIONS, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2808 SendDlgItemMessage(dlg, IDC_INCLUDES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2809 SendDlgItemMessage(dlg, IDC_OPENSSL_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2810 SendDlgItemMessage(dlg, IDC_ZLIB_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2811 SendDlgItemMessage(dlg, IDC_WEBSITES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2812 SendDlgItemMessage(dlg, IDC_CRYPTOGRAPHY, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2813 SendDlgItemMessage(dlg, IDC_CREDIT, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2814 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2815 }
2816 else {
2817 DlgAboutFont = NULL;
2818 }
2819
2820 // Edit control�������t�H���g���\�������������A���������������t�H���g���Z�b�g�����B
2821 // (2014.5.5. yutaka)
2822 if (UTIL_get_lang_font("DLG_ABOUT_FONT", dlg, &logfont, &DlgAboutTextFont, pvar)) {
2823 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, WM_SETFONT, (WPARAM)DlgAboutTextFont, MAKELPARAM(TRUE,0));
2824 } else {
2825 // ���������������������������t�H���g���w�������B
2826 // �G�f�B�b�g�R���g���[�����_�C�A���O�������t�H���g������������
2827 // �����t�H���g�������������B
2828 strncpy_s(logfont.lfFaceName, sizeof(logfont.lfFaceName), "Courier New", _TRUNCATE);
2829 logfont.lfCharSet = 0;
2830 logfont.lfHeight = MulDiv(8, GetDeviceCaps(GetDC(dlg),LOGPIXELSY) * -1, 72);
2831 logfont.lfWidth = 0;
2832 if ((DlgAboutTextFont = CreateFontIndirect(&logfont)) != NULL) {
2833 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, WM_SETFONT, (WPARAM)DlgAboutTextFont, MAKELPARAM(TRUE,0));
2834 }
2835 else {
2836 DlgAboutTextFont = NULL;
2837 }
2838 }
2839
2840 // �A�C�R�������I���Z�b�g
2841 {
2842 int fuLoad = LR_DEFAULTCOLOR;
2843 HICON hicon;
2844
2845 if (is_NT4()) {
2846 fuLoad = LR_VGACOLOR;
2847 }
2848
2849 hicon = LoadImage(hInst, MAKEINTRESOURCE(pvar->settings.IconID),
2850 IMAGE_ICON, 32, 32, fuLoad);
2851 SendDlgItemMessage(dlg, IDC_TTSSH_ICON, STM_SETICON, (WPARAM)hicon, 0);
2852 }
2853
2854 init_about_dlg((PTInstVar) lParam, dlg);
2855 SetFocus(GetDlgItem(dlg, IDOK));
2856
2857 // Edit control���T�u�N���X�������B
2858 g_deltaSumAboutDlg = 0;
2859 g_defAboutDlgEditWndProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(dlg, IDC_ABOUTTEXT), GWLP_WNDPROC, (LONG_PTR)AboutDlgEditWindowProc);
2860
2861 return FALSE;
2862
2863 case WM_COMMAND:
2864 switch (LOWORD(wParam)) {
2865 case IDOK:
2866 EndDialog(dlg, 1);
2867 if (DlgAboutFont != NULL) {
2868 DeleteObject(DlgAboutFont);
2869 }
2870 if (DlgAboutTextFont != NULL) {
2871 DeleteObject(DlgAboutTextFont);
2872 }
2873 return TRUE;
2874 case IDCANCEL: /* there isn't a cancel button, but other Windows
2875 UI things can send this message */
2876 EndDialog(dlg, 0);
2877 if (DlgAboutFont != NULL) {
2878 DeleteObject(DlgAboutFont);
2879 }
2880 if (DlgAboutTextFont != NULL)