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 5027 - (show annotations) (download) (as text)
Sat Sep 29 14:10:29 2012 UTC (11 years, 6 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 167198 byte(s)
DSA 鍵の生成で、鍵長を 1024 ビットに固定した。

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