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 5799 - (show annotations) (download) (as text)
Wed Feb 25 15:50:25 2015 UTC (9 years, 1 month ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 184815 byte(s)
X11転送の転送先指定方法を /ssh-X オプションに変更した。

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