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 6117 - (show annotations) (download) (as text)
Wed Nov 11 22:38:30 2015 UTC (8 years, 5 months ago) by maya
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 194661 byte(s)
SSH key fingerprint の hex 形式の出力を関数に移動(OpenSSH と同じ)
ダイジェストの形式を引数に追加

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