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