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