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 4531 - (show annotations) (download) (as text)
Tue Jul 26 08:50:11 2011 UTC (12 years, 8 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 163914 byte(s)
RFC 4255 "Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints" 対応の準備
http://tools.ietf.org/html/rfc4255

VerifyHostKeyDNS = 1 にすると、ホスト鍵の検証を行う。
検証するだけで検証結果は使ってないけれど。

DNSSEC 未対応の問題が有るので、その部分について検討中。
解決する目途が立っていないので、もしかするとお蔵入りするかも。

Windows95/98/Me/NT4 では動かないかも。

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