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 5839 - (show annotations) (download) (as text)
Wed Apr 29 16:23:18 2015 UTC (8 years, 11 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 185457 byte(s)
チケット #35047 SSH サーバホスト公開鍵の自動更新

known_hosts ファイルの更新の実施有無を設定できるようにした。
TERATERM.INI の [TTSSH] セクションに"UpdateHostkeys"エントリを追加した。
デフォルトは、OpenSSH 6.8(oUpdateHostkeys)に合わせて「オフ」とする。

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