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 4621 - (show annotations) (download) (as text)
Mon Sep 5 09:01:55 2011 UTC (12 years, 7 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 163753 byte(s)
SSH 設定ダイアログに VerifyHostKeyDNS を追加

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