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