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