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 5430 - (show annotations) (download) (as text)
Sat Nov 23 16:29:16 2013 UTC (10 years, 4 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 168238 byte(s)
OpenSSL バージョンの取得方法を変更した。

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