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