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 5959 - (show annotations) (download) (as text)
Tue Aug 25 09:17:18 2015 UTC (8 years, 7 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 194364 byte(s)
/ssh-L, /ssh-R で複数の転送を受け付ける形式を /ssh-L8080:remote:80,2525:remote2:25 に変更する。
/ssh-L8080:remote:80,R8888:localhost:80 のようなローカル/リモート混在を使えなくする。

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