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 5575 - (show annotations) (download) (as text)
Thu May 1 14:09:18 2014 UTC (9 years, 11 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 177597 byte(s)
#33743: ホスト鍵のfingerprint

TTSSHのバージョン情報に、ホストの公開鍵の指紋(fingerprint)およびランダムアートを表示する。

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