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 4533 - (show annotations) (download) (as text)
Tue Jul 26 15:07:33 2011 UTC (12 years, 8 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 164228 byte(s)
TTSSHのバージョンダイアログに、PuTTYバージョンを表記するようにした。

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