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 5900 - (show annotations) (download) (as text)
Tue Jun 2 09:07:33 2015 UTC (8 years, 10 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 192010 byte(s)
DH-GEXで要求するgroupサイズの最小値を指定できるようにした。

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