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 4463 - (show annotations) (download) (as text)
Thu Apr 28 06:27:03 2011 UTC (12 years, 11 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 163591 byte(s)
SSH 接続時以外は "SSH SCP" メニューをグレイアウトするようにした。

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