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