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 5793 - (show annotations) (download) (as text)
Sun Feb 22 13:04:28 2015 UTC (9 years, 1 month ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 184733 byte(s)
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 /* returns 1 if the option text must be deleted */
1640 static int parse_option(PTInstVar pvar, char FAR * option)
1641 {
1642 if ((option[0] == '-' || option[0] == '/')) {
1643 if (MATCH_STR(option + 1, "ssh") == 0) {
1644 if (option[4] == 0) {
1645 pvar->settings.Enabled = 1;
1646 } else if (MATCH_STR(option + 4, "-L") == 0 ||
1647 MATCH_STR(option + 4, "-R") == 0 ||
1648 _stricmp(option + 4, "-X") == 0) {
1649 if (pvar->settings.DefaultForwarding[0] == 0) {
1650 strncpy_s(pvar->settings.DefaultForwarding,
1651 sizeof(pvar->settings.DefaultForwarding),
1652 option + 5, _TRUNCATE);
1653 } else {
1654 strncat_s(pvar->settings.DefaultForwarding,
1655 sizeof(pvar->settings.DefaultForwarding),
1656 ";", _TRUNCATE);
1657 strncat_s(pvar->settings.DefaultForwarding,
1658 sizeof(pvar->settings.DefaultForwarding),
1659 option + 5, _TRUNCATE);
1660 }
1661 } else if (MATCH_STR(option + 4, "-display=") == 0) {
1662 strncpy_s(pvar->settings.X11Display,
1663 sizeof(pvar->settings.X11Display),
1664 option + 13, _TRUNCATE);
1665 } else if (MATCH_STR(option + 4, "-f=") == 0) {
1666 read_ssh_options_from_user_file(pvar, option + 7);
1667 } else if (MATCH_STR(option + 4, "-v") == 0) {
1668 pvar->settings.LogLevel = LOG_LEVEL_VERBOSE;
1669 } else if (_stricmp(option + 4, "-autologin") == 0 ||
1670 _stricmp(option + 4, "-autologon") == 0) {
1671 pvar->settings.TryDefaultAuth = TRUE;
1672 } else if (MATCH_STR_I(option + 4, "-agentconfirm=") == 0) {
1673 if ((_stricmp(option+18, "off") == 0) ||
1674 (_stricmp(option+18, "no") == 0) ||
1675 (_stricmp(option+18, "false") == 0) ||
1676 (_stricmp(option+18, "0") == 0) ||
1677 (_stricmp(option+18, "n") == 0)) {
1678 pvar->settings.ForwardAgentConfirm = 0;
1679 }
1680 else {
1681 pvar->settings.ForwardAgentConfirm = 1;
1682 }
1683
1684 // -axx������������������
1685 } else if (MATCH_STR(option + 4, "-a") == 0) {
1686 pvar->settings.ForwardAgent = FALSE;
1687 } else if (MATCH_STR(option + 4, "-A") == 0) {
1688 pvar->settings.ForwardAgent = TRUE;
1689
1690 } else if (MATCH_STR(option + 4, "-consume=") == 0) {
1691 read_ssh_options_from_user_file(pvar, option + 13);
1692 DeleteFile(option + 13);
1693
1694 } else if (MATCH_STR(option + 4, "-C=") == 0) {
1695 pvar->settings.CompressionLevel = atoi(option+7);
1696 if (pvar->settings.CompressionLevel < 0) {
1697 pvar->settings.CompressionLevel = 0;
1698 }
1699 else if (pvar->settings.CompressionLevel > 9) {
1700 pvar->settings.CompressionLevel = 9;
1701 }
1702 } else if (MATCH_STR(option + 4, "-C") == 0) {
1703 pvar->settings.CompressionLevel = 6;
1704 } else if (MATCH_STR(option + 4, "-c") == 0) {
1705 pvar->settings.CompressionLevel = 0;
1706 } else if (MATCH_STR_I(option + 4, "-icon=") == 0) {
1707 if ((_stricmp(option+10, "old") == 0) ||
1708 (_stricmp(option+10, "yellow") == 0) ||
1709 (_stricmp(option+10, "securett_yellow") == 0)) {
1710 pvar->settings.IconID = IDI_SECURETT_YELLOW;
1711 }
1712 else {
1713 pvar->settings.IconID = IDI_SECURETT;
1714 }
1715
1716 // /ssh1 �� /ssh2 �I�v�V�������V�K���� (2006.9.16 maya)
1717 } else if (MATCH_STR(option + 4, "1") == 0) {
1718 pvar->settings.Enabled = 1;
1719 pvar->settings.ssh_protocol_version = 1;
1720 } else if (MATCH_STR(option + 4, "2") == 0) {
1721 pvar->settings.Enabled = 1;
1722 pvar->settings.ssh_protocol_version = 2;
1723
1724 } else {
1725 char buf[1024];
1726
1727 UTIL_get_lang_msg("MSG_UNKNOWN_OPTION_ERROR", pvar,
1728 "Unrecognized command-line option: %s");
1729 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, option);
1730
1731 MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
1732 }
1733
1734 // ttermpro.exe �� /T= �w�������p�������A������������ (2006.10.19 maya)
1735 } else if (MATCH_STR_I(option + 1, "t=") == 0) {
1736 if (strcmp(option + 3, "2") == 0) {
1737 pvar->settings.Enabled = 1;
1738 return OPTION_CLEAR; // /t=2��ttssh�������g������������
1739 } else {
1740 pvar->settings.Enabled = 0;
1741 return OPTION_NONE; // Tera Term������������������������
1742 }
1743
1744 // ttermpro.exe �� /F= �w������ TTSSH ������������ (2006.10.11 maya)
1745 } else if (MATCH_STR_I(option + 1, "f=") == 0) {
1746 read_ssh_options_from_user_file(pvar, option + 3);
1747 return OPTION_NONE; // Tera Term���������������K�v������������������
1748
1749 // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
1750 } else if (MATCH_STR(option + 1, "1") == 0) {
1751 // command line: /ssh /1 is SSH1 only
1752 pvar->settings.ssh_protocol_version = 1;
1753
1754 } else if (MATCH_STR(option + 1, "2") == 0) {
1755 // command line: /ssh /2 is SSH2 & SSH1
1756 pvar->settings.ssh_protocol_version = 2;
1757
1758 } else if (MATCH_STR(option + 1, "nossh") == 0) {
1759 // '/nossh' �I�v�V�����������B
1760 // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
1761 // �����������������B(2004.10.11 yutaka)
1762 pvar->settings.Enabled = 0;
1763
1764 } else if (MATCH_STR(option + 1, "telnet") == 0) {
1765 // '/telnet' ���w�������������������� '/nossh' ��������
1766 // SSH������������ (2006.9.16 maya)
1767 pvar->settings.Enabled = 0;
1768 // Tera Term �� Telnet �t���O���t����
1769 pvar->ts->Telnet = 1;
1770
1771 } else if (MATCH_STR(option + 1, "auth") == 0) {
1772 // SSH2�������O�C���I�v�V����������
1773 //
1774 // SYNOPSIS: /ssh /auth=passowrd /user=���[�U�� /passwd=�p�X���[�h
1775 // /ssh /auth=publickey /user=���[�U�� /passwd=�p�X���[�h /keyfile=�p�X
1776 // EXAMPLE: /ssh /auth=password /user=nike /passwd=a@bc
1777 // /ssh /auth=publickey /user=foo /passwd=bar /keyfile=d:\tmp\id_rsa
1778 // NOTICE: �p�X���[�h���p�X�������������������A�u�����N���������� @ ���g�������B
1779 //
1780 // (2004.11.30 yutaka)
1781 // (2005.1.26 yutaka) ���������B���J���F���T�|�[�g�B
1782 //
1783 pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
1784
1785 if (MATCH_STR(option + 5, "=password") == 0) { // �p�X���[�h
1786 //pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
1787 pvar->ssh2_authmethod = SSH_AUTH_PASSWORD;
1788
1789 // /auth=challenge ������ (2007.10.5 maya)
1790 } else if (MATCH_STR(option + 5, "=challenge") == 0) { // keyboard-interactive�F��
1791 //pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
1792 pvar->ssh2_authmethod = SSH_AUTH_TIS;
1793
1794 } else if (MATCH_STR(option + 5, "=publickey") == 0) { // ���J���F��
1795 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1796 pvar->ssh2_authmethod = SSH_AUTH_RSA;
1797
1798 } else if (MATCH_STR(option + 5, "=pageant") == 0) { // ���J���F�� by Pageant
1799 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1800 pvar->ssh2_authmethod = SSH_AUTH_PAGEANT;
1801
1802 } else {
1803 // TODO:
1804
1805 }
1806
1807 } else if (MATCH_STR(option + 1, "user=") == 0) {
1808 #ifdef USE_ATCMDLINE
1809 replace_to_blank(option + 6, pvar->ssh2_username, sizeof(pvar->ssh2_username));
1810 //_snprintf(pvar->ssh2_username, sizeof(pvar->ssh2_username), "%s", option + 6);
1811
1812 #else
1813 _snprintf_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), _TRUNCATE, "%s", option + 6);
1814 #endif
1815
1816 } else if (MATCH_STR(option + 1, "passwd=") == 0) {
1817 #ifdef USE_ATCMDLINE
1818 replace_to_blank(option + 8, pvar->ssh2_password, sizeof(pvar->ssh2_password));
1819 //_snprintf(pvar->ssh2_password, sizeof(pvar->ssh2_password), "%s", option + 8);
1820 #else
1821 _snprintf_s(pvar->ssh2_password, sizeof(pvar->ssh2_password), _TRUNCATE, "%s", option + 8);
1822 #endif
1823
1824 } else if (MATCH_STR(option + 1, "keyfile=") == 0) {
1825 #ifdef USE_ATCMDLINE
1826 replace_to_blank(option + 9, pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile));
1827 #else
1828 _snprintf_s(pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile), _TRUNCATE, "%s", option + 9);
1829 #endif
1830
1831 } else if (MATCH_STR(option + 1, "ask4passwd") == 0) {
1832 // �p�X���[�h������ (2006.9.18 maya)
1833 pvar->ask4passwd = 1;
1834
1835 } else if (MATCH_STR(option + 1, "nosecuritywarning") == 0) {
1836 // known_hosts�`�F�b�N���������B���Y�I�v�V�������g�����A�Z�L�����e�B������������
1837 // �����A�B���I�v�V���������������B
1838 // (2009.10.4 yutaka)
1839 pvar->nocheck_known_hosts = TRUE;
1840
1841 }
1842 else { // Other (not ttssh) option
1843 return OPTION_NONE; // ttssh���I�v�V������������������������
1844 }
1845
1846 // �p�X���[�h�������������������O�C��������������
1847 // /auth ���F�����\�b�h���w�������������p������ (2006.9.18 maya)
1848 if (pvar->ask4passwd == 1) {
1849 pvar->ssh2_autologin = 0;
1850 }
1851 return OPTION_CLEAR;
1852
1853 }
1854 else if ((MATCH_STR_I(option, "ssh://") == 0) ||
1855 (MATCH_STR_I(option, "ssh1://") == 0) ||
1856 (MATCH_STR_I(option, "ssh2://") == 0) ||
1857 (MATCH_STR_I(option, "slogin://") == 0) ||
1858 (MATCH_STR_I(option, "slogin1://") == 0) ||
1859 (MATCH_STR_I(option, "slogin2://") == 0)) {
1860 //
1861 // ssh://user@host/ ����URL�`�����T�|�[�g
1862 // ���{�I�������� telnet:// URL��������
1863 //
1864 // �Q�l:
1865 // RFC3986: Uniform Resource Identifier (URI): Generic Syntax
1866 // RFC4248: The telnet URI Scheme
1867 //
1868 char *p, *p2, *p3;
1869 int optlen, hostlen;
1870
1871 optlen = strlen(option);
1872
1873 // ������':'���O�����������������������A������ssh�v���g�R���o�[�W������������
1874 p = _mbschr(option, ':');
1875 switch (*(p-1)) {
1876 case '1':
1877 pvar->settings.ssh_protocol_version = 1;
1878 break;
1879 case '2':
1880 pvar->settings.ssh_protocol_version = 2;
1881 break;
1882 }
1883
1884 // authority part �����|�C���^������
1885 p += 3;
1886
1887 // path part ������������
1888 if ((p2 = _mbschr(p, '/')) != NULL) {
1889 *p2 = 0;
1890 }
1891
1892 // '@'�������������A���������O�����[�U����
1893 if ((p2 = _mbschr(p, '@')) != NULL) {
1894 *p2 = 0;
1895 // ':'���~���p�X���[�h
1896 if ((p3 = _mbschr(p, ':')) != NULL) {
1897 *p3 = 0;
1898 percent_decode(pvar->ssh2_password, sizeof(pvar->ssh2_password), p3 + 1);
1899 }
1900 percent_decode(pvar->ssh2_username, sizeof(pvar->ssh2_username), p);
1901 // p �� host part ������('@'����������)����������������
1902 p = p2 + 1;
1903 }
1904
1905 // host part �� option �����������������Ascheme part ������
1906 // port�w����������������port���������������������m��������������
1907 hostlen = strlen(p);
1908 memmove_s(option, optlen, p, hostlen);
1909 option[hostlen] = 0;
1910
1911 // �|�[�g�w������������":22"������
1912 #ifndef NO_INET6
1913 if (option[0] == '[' && option[hostlen-1] == ']' || // IPv6 raw address without port
1914 option[0] != '[' && _mbschr(option, ':') == NULL) { // hostname or IPv4 raw address without port
1915 #else
1916 if (_mbschr(option, ':') == NULL) {
1917 #endif /* NO_INET6 */
1918 memcpy_s(option+hostlen, optlen-hostlen, ":22", 3);
1919 hostlen += 3;
1920 }
1921
1922 // �|�[�g�w�����������������X�y�[�X������
1923 memset(option+hostlen, ' ', optlen-hostlen);
1924
1925 pvar->settings.Enabled = 1;
1926
1927 return OPTION_REPLACE;
1928 }
1929 else if (_mbschr(option, '@') != NULL) {
1930 //
1931 // user@host �`�����T�|�[�g
1932 // ����������ssh�������T�|�[�g�����A���[�U����ttssh���������B
1933 // (ssh�������O -- ttssh�������W������������)
1934 // �����I��telnet authentication option���T�|�[�g��������
1935 // Tera Term�{�����������������������\���B
1936 //
1937 char *p;
1938 p = _mbschr(option, '@');
1939 *p = 0;
1940
1941 strncpy_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), option, _TRUNCATE);
1942
1943 // ���[�U���������X�y�[�X�������B
1944 // ������TTX��Tera Term�{�������������������X�y�[�X�����������������A
1945 // �z�X�g�����������l�����K�v�������B
1946 memset(option, ' ', p-option+1);
1947
1948 return OPTION_REPLACE;
1949 }
1950
1951 return OPTION_NONE;
1952 }
1953
1954 static void FAR PASCAL TTXParseParam(PCHAR param, PTTSet ts,
1955 PCHAR DDETopic)
1956 {
1957 #ifndef USE_ATCMDLINE
1958 int i;
1959 BOOL inParam = FALSE;
1960 BOOL inQuotes = FALSE;
1961 BOOL inEqual = FALSE;
1962 int param_len=strlen(param);
1963 PCHAR start = NULL;
1964 char *buf = (char *)calloc(param_len+1, sizeof(char));
1965 int buflen = 0;
1966
1967 if (pvar->hostdlg_activated) {
1968 pvar->settings.Enabled = pvar->hostdlg_Enabled;
1969 }
1970
1971 for (i = 0; i < param_len; i++) {
1972 if (inQuotes) {
1973 // �������u��"����
1974 if (param[i] == '"') {
1975 if (param[i+1] == '"') {
1976 buf[buflen] = param[i];
1977 buflen++;
1978 i++;
1979 }
1980 else {
1981 // �N�H�[�g���������������������I����
1982 // "��buf�����������������n��
1983 switch (parse_option(pvar, buf)) {
1984 case OPTION_CLEAR:
1985 memset(start, ' ', (param + i) - start + 1);
1986 break;
1987 case OPTION_REPLACE:
1988 memset(start, ' ', (param + i) - start + 1);
1989 buflen = strlen(buf);
1990 memcpy(start, buf, buflen);
1991 break;
1992 }
1993 inParam = FALSE;
1994 inEqual = FALSE;
1995 start = NULL;
1996 memset(buf, 0, param_len);
1997 buflen = 0;
1998 inQuotes = FALSE;
1999 }
2000 }
2001 else {
2002 buf[buflen] = param[i];
2003 buflen++;
2004 }
2005 }
2006 else {
2007 if (!inParam) {
2008 // �����p�����[�^������������
2009 if (param[i] == '"') {
2010 // " ���n����
2011 start = param + i;
2012 inParam = TRUE;
2013 inQuotes = TRUE;
2014 }
2015 else if (param[i] != ' ' && param[i] != '\t') {
2016 // �������n����
2017 buf[buflen] = param[i];
2018 buflen++;
2019 start = param + i;
2020 inParam = TRUE;
2021 }
2022 }
2023 else {
2024 // �������u���p�����[�^����
2025 if (param[i] == ' ' || param[i] == '\t') {
2026 // �N�H�[�g�����������������������I����
2027 switch (parse_option(pvar, buf)) {
2028 case OPTION_CLEAR:
2029 memset(start, ' ', (param + i) - start + 1);
2030 break;
2031 case OPTION_REPLACE:
2032 memset(start, ' ', (param + i) - start + 1);
2033 buflen = strlen(buf);
2034 memcpy(start, buf, buflen);
2035 break;
2036 }
2037 inParam = FALSE;
2038 inEqual = FALSE;
2039 start = NULL;
2040 memset(buf, 0, param_len);
2041 buflen = 0;
2042 }
2043 else {
2044 buf[buflen] = param[i];
2045 buflen++;
2046 if (!inEqual && param[i] == '=') {
2047 inEqual = TRUE;
2048 if (param[i+1] == '"') {
2049 inQuotes = TRUE;
2050 i++;
2051 }
2052 }
2053 }
2054 }
2055 }
2056 }
2057
2058 // buf ���c�����������������n��
2059 // +1������������'\0'�������������������A��������������������
2060 if (strlen(buf) > 0) {
2061 switch (parse_option(pvar, buf)) {
2062 case OPTION_CLEAR:
2063 memset(start, ' ', (param + i) - start);
2064 break;
2065 case OPTION_REPLACE:
2066 memset(start, ' ', (param + i) - start);
2067 buflen = strlen(buf);
2068 memcpy(start, buf, buflen);
2069 break;
2070 }
2071 }
2072 free(buf);
2073 #else
2074 // �X�y�[�X�������t�@�C�������F�������������C�� (2006.10.7 maya)
2075 int i, buflen;
2076 BOOL inParam = FALSE;
2077 BOOL inQuotes = FALSE;
2078 BOOL inFileParam = FALSE;
2079 PCHAR option = NULL;
2080
2081 if (pvar->hostdlg_activated) {
2082 pvar->settings.Enabled = pvar->hostdlg_Enabled;
2083 }
2084
2085 for (i = 0; param[i] != 0; i++) {
2086 if (inQuotes ? param[i] == '"'
2087 : (param[i] == ' ' || param[i] == '\t')) {
2088 if (option != NULL) {
2089 char ch = param[i];
2090 PCHAR Equal;
2091
2092 param[i] = 0;
2093 Equal = strchr(option, '=');
2094 if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
2095 int buf_len = strlen(option) * sizeof(char);
2096 char *buf = (char *)calloc(strlen(option), sizeof(char));
2097 char c = option[Equal - option + 1];
2098 option[Equal - option + 1] = 0;
2099 strncat_s(buf, buf_len, option, _TRUNCATE);
2100 option[Equal - option + 1] = c;
2101 strncat_s(buf, buf_len, Equal + 2, _TRUNCATE);
2102 switch (parse_option(pvar, *buf == '"' ? buf + 1 : buf)) {
2103 case OPTION_CLEAR:
2104 memset(option, ' ', i + 1 - (option - param));
2105 break;
2106 case OPTION_REPLACE:
2107 buflen = strlen(buf);
2108 memcpy(option, buf, buflen);
2109 memset(option + buflen, ' ', i + 1 - buflen - (option - param));
2110 break;
2111 default:
2112 param[i] = ch;
2113 }
2114 free(buf);
2115 }
2116 else {
2117 switch (parse_option(pvar, *option == '"' ? option + 1 : option)) {
2118 case OPTION_CLEAR:
2119 memset(option, ' ', i + 1 - (option - param));
2120 break;
2121 default:
2122 param[i] = ch;
2123 }
2124 }
2125 option = NULL;
2126 }
2127 inParam = FALSE;
2128 inQuotes = FALSE;
2129 inFileParam = FALSE;
2130 } else if (!inParam) {
2131 if (param[i] == '"') {
2132 inQuotes = TRUE;
2133 inParam = TRUE;
2134 option = param + i;
2135 } else if (param[i] != ' ' && param[i] != '\t') {
2136 inParam = TRUE;
2137 option = param + i;
2138 }
2139 } else {
2140 if (option == NULL) {
2141 continue;
2142 }
2143 if ((option[0] == '-' || option[0] == '/') &&
2144 (MATCH_STR(option + 1, "ssh-f=") == 0 || // ttssh option
2145 MATCH_STR(option + 1, "ssh-consume=") == 0 || // ttssh option
2146 MATCH_STR_I(option + 1, "f=") == 0 || // Tera Term option
2147 MATCH_STR_I(option + 1, "fd=") == 0 || // Tera Term option
2148 MATCH_STR_I(option + 1, "k=") == 0 || // Tera Term option
2149 MATCH_STR_I(option + 1, "l=") == 0 || // Tera Term option
2150 MATCH_STR_I(option + 1, "m=") == 0 || // Tera Term option
2151 MATCH_STR_I(option + 1, "r=") == 0 || // Tera Term option
2152 MATCH_STR_I(option + 1, "w=") == 0 || // Tera Term option
2153 MATCH_STR(option + 1, "keyfile=") == 0)) { // ttssh option
2154 if (param[i] == '"') {
2155 inQuotes = TRUE;
2156 }
2157 inFileParam = TRUE;
2158 }
2159 }
2160 }
2161
2162 if (option != NULL) {
2163 PCHAR Equal = strchr(option, '=');
2164 if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
2165 int buf_len = strlen(option) * sizeof(char);
2166 char *buf = (char *)calloc(strlen(option), sizeof(char));
2167 char c = option[Equal - option + 1];
2168 option[Equal - option + 1] = 0;
2169 strncat_s(buf, buf_len, option, _TRUNCATE);
2170 option[Equal - option + 1] = c;
2171 strncat_s(buf, buf_len, Equal + 2, _TRUNCATE);
2172 switch (parse_option(pvar, *buf == '"' ? buf + 1 : buf)) {
2173 case OPTION_CLEAR:
2174 memset(option, ' ', i + 1 - (option - param));
2175 break;
2176 case OPTION_REPLACE:
2177 strcpy_s(option, i - (param - option), buf);
2178 break;
2179 }
2180 free(buf);
2181 }
2182 else {
2183 switch (parse_option(pvar, option)) {
2184 case OPTION_CLEAR:
2185 memset(option, ' ', i - (option - param));
2186 break;
2187 }
2188 }
2189 }
2190 #endif
2191
2192 FWDUI_load_settings(pvar);
2193
2194 (pvar->ParseParam) (param, ts, DDETopic);
2195
2196 }
2197
2198 static void PASCAL FAR TTXGetSetupHooks(TTXSetupHooks FAR * hooks)
2199 {
2200 pvar->ReadIniFile = *hooks->ReadIniFile;
2201 pvar->WriteIniFile = *hooks->WriteIniFile;
2202 pvar->ParseParam = *hooks->ParseParam;
2203
2204 *hooks->ReadIniFile = TTXReadINIFile;
2205 *hooks->WriteIniFile = TTXWriteINIFile;
2206 *hooks->ParseParam = TTXParseParam;
2207 }
2208
2209 static void PASCAL FAR TTXSetWinSize(int rows, int cols)
2210 {
2211 SSH_notify_win_size(pvar, cols, rows);
2212 }
2213
2214 static void insertMenuBeforeItem(HMENU menu, WORD beforeItemID, WORD flags,
2215 WORD newItemID, char FAR * text)
2216 {
2217 int i, j;
2218
2219 for (i = GetMenuItemCount(menu) - 1; i >= 0; i--) {
2220 HMENU submenu = GetSubMenu(menu, i);
2221
2222 for (j = GetMenuItemCount(submenu) - 1; j >= 0; j--) {
2223 if (GetMenuItemID(submenu, j) == beforeItemID) {
2224 InsertMenu(submenu, j, MF_BYPOSITION | flags, newItemID, text);
2225 return;
2226 }
2227 }
2228 }
2229 }
2230
2231 #define GetFileMenu(menu) GetSubMenuByChildID(menu, 50110) // ID_FILE_NEWCONNECTION
2232 #define GetEditMenu(menu) GetSubMenuByChildID(menu, 50210) // ID_EDIT_COPY2
2233 #define GetSetupMenu(menu) GetSubMenuByChildID(menu, 50310) // ID_SETUP_TERMINAL
2234 #define GetControlMenu(menu) GetSubMenuByChildID(menu, 50410) // ID_CONTROL_RESETTERMINAL
2235 #define GetHelpMenu(menu) GetSubMenuByChildID(menu, 50990) // ID_HELP_ABOUT
2236
2237 HMENU GetSubMenuByChildID(HMENU menu, UINT id) {
2238 int i, j, items, subitems, cur_id;
2239 HMENU m;
2240
2241 items = GetMenuItemCount(menu);
2242
2243 for (i=0; i<items; i++) {
2244 if (m = GetSubMenu(menu, i)) {
2245 subitems = GetMenuItemCount(m);
2246 for (j=0; j<subitems; j++) {
2247 cur_id = GetMenuItemID(m, j);
2248 if (cur_id == id) {
2249 return m;
2250 }
2251 }
2252 }
2253 }
2254 return NULL;
2255 }
2256
2257 static void PASCAL FAR TTXModifyMenu(HMENU menu)
2258 {
2259 pvar->FileMenu = GetFileMenu(menu);
2260
2261 /* inserts before ID_HELP_ABOUT */
2262 UTIL_get_lang_msg("MENU_ABOUT", pvar, "About &TTSSH...");
2263 insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU, pvar->ts->UIMsg);
2264
2265 /* inserts before ID_SETUP_TCPIP */
2266 UTIL_get_lang_msg("MENU_SSH", pvar, "SS&H...");
2267 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU, pvar->ts->UIMsg);
2268 /* inserts before ID_SETUP_TCPIP */
2269 UTIL_get_lang_msg("MENU_SSH_AUTH", pvar, "SSH &Authentication...");
2270 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU, pvar->ts->UIMsg);
2271 /* inserts before ID_SETUP_TCPIP */
2272 UTIL_get_lang_msg("MENU_SSH_FORWARD", pvar, "SSH F&orwarding...");
2273 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU, pvar->ts->UIMsg);
2274 UTIL_get_lang_msg("MENU_SSH_KEYGEN", pvar, "SSH KeyGe&nerator...");
2275 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHKEYGENMENU, pvar->ts->UIMsg);
2276
2277 /* inserts before ID_FILE_CHANGEDIR */
2278 UTIL_get_lang_msg("MENU_SSH_SCP", pvar, "SS&H SCP...");
2279 insertMenuBeforeItem(menu, 50170, MF_GRAYED, ID_SSHSCPMENU, pvar->ts->UIMsg);
2280 }
2281
2282 static void PASCAL FAR TTXModifyPopupMenu(HMENU menu) {
2283 if (menu == pvar->FileMenu) {
2284 if (pvar->cv->Ready && pvar->settings.Enabled)
2285 EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_ENABLED);
2286 else
2287 EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_GRAYED);
2288 }
2289 }
2290
2291 static void append_about_text(HWND dlg, char FAR * prefix, char FAR * msg)
2292 {
2293 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
2294 (LPARAM) prefix);
2295 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0, (LPARAM) msg);
2296 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
2297 (LPARAM) (char FAR *) "\r\n");
2298 }
2299
2300 // ���s�t�@�C�������o�[�W�������������� (2005.2.28 yutaka)
2301 void get_file_version(char *exefile, int *major, int *minor, int *release, int *build)
2302 {
2303 typedef struct {
2304 WORD wLanguage;
2305 WORD wCodePage;
2306 } LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
2307 LPLANGANDCODEPAGE lplgcode;
2308 UINT unLen;
2309 DWORD size;
2310 char *buf = NULL;
2311 BOOL ret;
2312 int i;
2313 char fmt[80];
2314 char *pbuf;
2315
2316 size = GetFileVersionInfoSize(exefile, NULL);
2317 if (size == 0) {
2318 goto error;
2319 }
2320 buf = malloc(size);
2321 ZeroMemory(buf, size);
2322
2323 if (GetFileVersionInfo(exefile, 0, size, buf) == FALSE) {
2324 goto error;
2325 }
2326
2327 ret = VerQueryValue(buf,
2328 "\\VarFileInfo\\Translation",
2329 (LPVOID *)&lplgcode, &unLen);
2330 if (ret == FALSE)
2331 goto error;
2332
2333 for (i = 0 ; i < (int)(unLen / sizeof(LANGANDCODEPAGE)) ; i++) {
2334 _snprintf_s(fmt, sizeof(fmt), _TRUNCATE,
2335 "\\StringFileInfo\\%04x%04x\\FileVersion",
2336 lplgcode[i].wLanguage, lplgcode[i].wCodePage);
2337 VerQueryValue(buf, fmt, &pbuf, &unLen);
2338 if (unLen > 0) { // get success
2339 int n, a, b, c, d;
2340
2341 n = sscanf(pbuf, "%d, %d, %d, %d", &a, &b, &c, &d);
2342 if (n == 4) { // convert success
2343 *major = a;
2344 *minor = b;
2345 *release = c;
2346 *build = d;
2347 break;
2348 }
2349 }
2350 }
2351
2352 free(buf);
2353 return;
2354
2355 error:
2356 free(buf);
2357 *major = *minor = *release = *build = 0;
2358 }
2359
2360 static void init_about_dlg(PTInstVar pvar, HWND dlg)
2361 {
2362 char buf[1024];
2363 int a, b, c, d;
2364 char uimsg[MAX_UIMSG];
2365 char *fp = NULL;
2366
2367 GetWindowText(dlg, uimsg, sizeof(uimsg));
2368 UTIL_get_lang_msg("DLG_ABOUT_TITLE", pvar, uimsg);
2369 SetWindowText(dlg, pvar->ts->UIMsg);
2370 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2371 UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
2372 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2373
2374 // TTSSH���o�[�W�������������� (2005.2.28 yutaka)
2375 get_file_version("ttxssh.dll", &a, &b, &c, &d);
2376 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2377 "TTSSH\r\nTera Term Secure Shell extension, %d.%d", a, b);
2378 SendMessage(GetDlgItem(dlg, IDC_TTSSH_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2379
2380 // OpenSSL���o�[�W�������������� (2005.1.24 yutaka)
2381 // ���������� (2005.5.11 yutaka)
2382 // OPENSSL_VERSION_TEXT �}�N�����`���������A�������g�����o�[�W���������������B(2013.11.24 yutaka)
2383 SendMessage(GetDlgItem(dlg, IDC_OPENSSL_VERSION), WM_SETTEXT, 0, (LPARAM)SSLeay_version(SSLEAY_VERSION));
2384
2385 // zlib���o�[�W�������������� (2005.5.11 yutaka)
2386 #ifdef ZLIB_VERSION
2387 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "ZLib %s", ZLIB_VERSION);
2388 #else
2389 _snprintf(buf, sizeof(buf), "ZLib Unknown");
2390 #endif
2391 SendMessage(GetDlgItem(dlg, IDC_ZLIB_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2392
2393 // PuTTY���o�[�W�������������� (2011.7.26 yutaka)
2394 #ifdef PUTTYVERSION
2395 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "PuTTY %s", PUTTYVERSION);
2396 #else
2397 _snprintf(buf, sizeof(buf), "PuTTY Unknown");
2398 #endif
2399 SendMessage(GetDlgItem(dlg, IDC_PUTTY_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2400
2401 // TTSSH�_�C�A���O���\������SSH������������ (2004.10.30 yutaka)
2402 if (pvar->socket != INVALID_SOCKET) {
2403 if (SSHv1(pvar)) {
2404 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
2405 UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID:");
2406 append_about_text(dlg, pvar->ts->UIMsg, buf);
2407 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
2408 UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol:");
2409 append_about_text(dlg, pvar->ts->UIMsg, buf);
2410 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
2411 UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:");
2412 append_about_text(dlg, pvar->ts->UIMsg, buf);
2413 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
2414 UTIL_get_lang_msg("DLG_ABOUT_SERVERKEY", pvar, "Server keys:");
2415 append_about_text(dlg, pvar->ts->UIMsg, buf);
2416 AUTH_get_auth_info(pvar, buf, sizeof(buf));
2417 UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication:");
2418 append_about_text(dlg, pvar->ts->UIMsg, buf);
2419 SSH_get_compression_info(pvar, buf, sizeof(buf));
2420 UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression:");
2421 append_about_text(dlg, pvar->ts->UIMsg, buf);
2422
2423 } else { // SSH2
2424 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
2425 UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID:");
2426 append_about_text(dlg, pvar->ts->UIMsg, buf);
2427 UTIL_get_lang_msg("DLG_ABOUT_CLIENTID", pvar, "Client ID:");
2428 append_about_text(dlg, pvar->ts->UIMsg, pvar->client_version_string);
2429
2430 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
2431 UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol:");
2432 append_about_text(dlg, pvar->ts->UIMsg, buf);
2433
2434 append_about_text(dlg, "KEX:", get_kex_algorithm_name(pvar->kex_type));
2435
2436 strncpy_s(buf, sizeof(buf), get_ssh_keytype_name(pvar->hostkey_type), _TRUNCATE);
2437 UTIL_get_lang_msg("DLG_ABOUT_HOSTKEY", pvar, "Host Key:");
2438 append_about_text(dlg, pvar->ts->UIMsg, buf);
2439
2440 // add MAC algorithm (2004.12.17 yutaka)
2441 buf[0] = '\0';
2442 strncat_s(buf, sizeof(buf), get_ssh2_mac_name(pvar->ctos_hmac) , _TRUNCATE);
2443 UTIL_get_lang_msg("DLG_ABOUT_TOSERVER", pvar, " to server,");
2444 strncat_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2445 strncat_s(buf, sizeof(buf), get_ssh2_mac_name(pvar->stoc_hmac) , _TRUNCATE);
2446 UTIL_get_lang_msg("DLG_ABOUT_FROMSERVER", pvar, " from server");
2447 strncat_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2448 append_about_text(dlg, "MAC:", buf);
2449
2450 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
2451 UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:");
2452 append_about_text(dlg, pvar->ts->UIMsg, buf);
2453 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
2454 UTIL_get_lang_msg("DLG_ABOUT_KEXKEY", pvar, "Key exchange keys:");
2455 append_about_text(dlg, pvar->ts->UIMsg, buf);
2456
2457 AUTH_get_auth_info(pvar, buf, sizeof(buf));
2458 UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication:");
2459 append_about_text(dlg, pvar->ts->UIMsg, buf);
2460
2461 SSH_get_compression_info(pvar, buf, sizeof(buf));
2462 if (pvar->ctos_compression == COMP_DELAYED) { // �x���p�P�b�g���k������ (2006.6.23 yutaka)
2463 UTIL_get_lang_msg("DLG_ABOUT_COMPDELAY", pvar, "Delayed Compression:");
2464 append_about_text(dlg, pvar->ts->UIMsg, buf);
2465 } else {
2466 UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression:");
2467 append_about_text(dlg, pvar->ts->UIMsg, buf);
2468 }
2469 }
2470
2471 // �z�X�g���J����fingerprint���\�������B
2472 // Random art���\�������������������������B
2473 // (2014.5.1 yutaka)
2474 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX);
2475 UTIL_get_lang_msg("DLG_ABOUT_FINGERPRINT", pvar, "Host key's fingerprint:");
2476 append_about_text(dlg, pvar->ts->UIMsg, fp);
2477 free(fp);
2478
2479 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART);
2480 append_about_text(dlg, "", fp);
2481 free(fp);
2482 }
2483 }
2484
2485 // WM_MOUSEWHEEL �� winuser.h �w�b�_���������������������A#define _WIN32_WINNT 0x0400 ���������������������F�������������B
2486 #define WM_MOUSEWHEEL 0x020A
2487 #define WHEEL_DELTA 120
2488 #define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
2489 #define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam))
2490
2491 static WNDPROC g_defAboutDlgEditWndProc; // Edit Control���T�u�N���X���p
2492 static int g_deltaSumAboutDlg = 0; // �}�E�X�z�C�[����Delta�����p
2493
2494 static LRESULT CALLBACK AboutDlgEditWindowProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
2495 {
2496 WORD keys;
2497 short delta;
2498 BOOL page;
2499
2500 switch (msg) {
2501 case WM_KEYDOWN:
2502 // Edit control���� CTRL+A �������������A�e�L�X�g���S�I�������B
2503 if (wp == 'A' && GetKeyState(VK_CONTROL) < 0) {
2504 PostMessage(hWnd, EM_SETSEL, 0, -1);
2505 return 0;
2506 }
2507 break;
2508
2509 case WM_MOUSEWHEEL:
2510 // CTRLorSHIFT + �}�E�X�z�C�[���������A���X�N���[���������B
2511 keys = GET_KEYSTATE_WPARAM(wp);
2512 delta = GET_WHEEL_DELTA_WPARAM(wp);
2513 page = keys & (MK_CONTROL | MK_SHIFT);
2514
2515 if (page == 0)
2516 break;
2517
2518 g_deltaSumAboutDlg += delta;
2519
2520 if (g_deltaSumAboutDlg >= WHEEL_DELTA) {
2521 g_deltaSumAboutDlg -= WHEEL_DELTA;
2522 SendMessage(hWnd, WM_HSCROLL, SB_PAGELEFT , 0);
2523 } else if (g_deltaSumAboutDlg <= -WHEEL_DELTA) {
2524 g_deltaSumAboutDlg += WHEEL_DELTA;
2525 SendMessage(hWnd, WM_HSCROLL, SB_PAGERIGHT, 0);
2526 }
2527
2528 break;
2529 }
2530 return CallWindowProc(g_defAboutDlgEditWndProc, hWnd, msg, wp, lp);
2531 }
2532
2533 static BOOL CALLBACK TTXAboutDlg(HWND dlg, UINT msg, WPARAM wParam,
2534 LPARAM lParam)
2535 {
2536 LOGFONT logfont;
2537 HFONT font;
2538
2539 switch (msg) {
2540 case WM_INITDIALOG:
2541 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2542 GetObject(font, sizeof(LOGFONT), &logfont);
2543 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgAboutFont, pvar)) {
2544 SendDlgItemMessage(dlg, IDC_TTSSH_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2545 SendDlgItemMessage(dlg, IDC_SSHVERSIONS, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2546 SendDlgItemMessage(dlg, IDC_INCLUDES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2547 SendDlgItemMessage(dlg, IDC_OPENSSL_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2548 SendDlgItemMessage(dlg, IDC_ZLIB_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2549 SendDlgItemMessage(dlg, IDC_WEBSITES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2550 SendDlgItemMessage(dlg, IDC_CRYPTOGRAPHY, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2551 SendDlgItemMessage(dlg, IDC_CREDIT, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2552 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2553 }
2554 else {
2555 DlgAboutFont = NULL;
2556 }
2557
2558 // Edit control�������t�H���g���\�������������A���������������t�H���g���Z�b�g�����B
2559 // (2014.5.5. yutaka)
2560 if (UTIL_get_lang_font("DLG_ABOUT_FONT", dlg, &logfont, &DlgAboutTextFont, pvar)) {
2561 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, WM_SETFONT, (WPARAM)DlgAboutTextFont, MAKELPARAM(TRUE,0));
2562 } else {
2563 // ���������������������������t�H���g���w�������B
2564 // �G�f�B�b�g�R���g���[�����_�C�A���O�������t�H���g������������
2565 // �����t�H���g�������������B
2566 strncpy_s(logfont.lfFaceName, sizeof(logfont.lfFaceName), "Courier New", _TRUNCATE);
2567 logfont.lfCharSet = 0;
2568 logfont.lfHeight = MulDiv(8, GetDeviceCaps(GetDC(dlg),LOGPIXELSY) * -1, 72);
2569 logfont.lfWidth = 0;
2570 if ((DlgAboutTextFont = CreateFontIndirect(&logfont)) != NULL) {
2571 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, WM_SETFONT, (WPARAM)DlgAboutTextFont, MAKELPARAM(TRUE,0));
2572 }
2573 else {
2574 DlgAboutTextFont = NULL;
2575 }
2576 }
2577
2578 // �A�C�R�������I���Z�b�g
2579 {
2580 int fuLoad = LR_DEFAULTCOLOR;
2581 HICON hicon;
2582
2583 if (is_NT4()) {
2584 fuLoad = LR_VGACOLOR;
2585 }
2586
2587 hicon = LoadImage(hInst, MAKEINTRESOURCE(pvar->settings.IconID),
2588 IMAGE_ICON, 32, 32, fuLoad);
2589 SendDlgItemMessage(dlg, IDC_TTSSH_ICON, STM_SETICON, (WPARAM)hicon, 0);
2590 }
2591
2592 init_about_dlg((PTInstVar) lParam, dlg);
2593 SetFocus(GetDlgItem(dlg, IDOK));
2594
2595 // Edit control���T�u�N���X�������B
2596 g_deltaSumAboutDlg = 0;
2597 g_defAboutDlgEditWndProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(dlg, IDC_ABOUTTEXT), GWLP_WNDPROC, (LONG_PTR)AboutDlgEditWindowProc);
2598
2599 return FALSE;
2600
2601 case WM_COMMAND:
2602 switch (LOWORD(wParam)) {
2603 case IDOK:
2604 EndDialog(dlg, 1);
2605 if (DlgAboutFont != NULL) {
2606 DeleteObject(DlgAboutFont);
2607 }
2608 if (DlgAboutTextFont != NULL) {
2609 DeleteObject(DlgAboutTextFont);
2610 }
2611 return TRUE;
2612 case IDCANCEL: /* there isn't a cancel button, but other Windows
2613 UI things can send this message */
2614 EndDialog(dlg, 0);
2615 if (DlgAboutFont != NULL) {
2616 DeleteObject(DlgAboutFont);
2617 }
2618 if (DlgAboutTextFont != NULL) {
2619 DeleteObject(DlgAboutTextFont);
2620 }
2621 return TRUE;
2622 }
2623 break;
2624 }
2625
2626 return FALSE;
2627 }
2628
2629 static char FAR *get_cipher_name(int cipher)
2630 {
2631 switch (cipher) {
2632 case SSH_CIPHER_NONE:
2633 UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_BORDER", pvar,
2634 "<ciphers below this line are disabled>");
2635 return pvar->ts->UIMsg;
2636 case SSH_CIPHER_RC4:
2637 return "RC4(SSH1)";
2638 case SSH_CIPHER_3DES:
2639 return "3DES(SSH1)";
2640 case SSH_CIPHER_DES:
2641 return "DES(SSH1)";
2642 case SSH_CIPHER_IDEA:
2643 return "IDEA(SSH1)";
2644 case SSH_CIPHER_TSS:
2645 return "TSS(SSH1)";
2646 case SSH_CIPHER_BLOWFISH:
2647 return "Blowfish(SSH1)";
2648
2649 // for SSH2(yutaka)
2650 case SSH2_CIPHER_AES128_CBC:
2651 return "AES128-CBC(SSH2)";
2652 case SSH2_CIPHER_AES192_CBC:
2653 return "AES192-CBC(SSH2)";
2654 case SSH2_CIPHER_AES256_CBC:
2655 return "AES256-CBC(SSH2)";
2656 case SSH2_CIPHER_3DES_CBC:
2657 return "3DES-CBC(SSH2)";
2658 case SSH2_CIPHER_BLOWFISH_CBC:
2659 return "Blowfish-CBC(SSH2)";
2660 case SSH2_CIPHER_AES128_CTR:
2661 return "AES128-CTR(SSH2)";
2662 case SSH2_CIPHER_AES192_CTR:
2663 return "AES192-CTR(SSH2)";
2664 case SSH2_CIPHER_AES256_CTR:
2665 return "AES256-CTR(SSH2)";
2666 case SSH2_CIPHER_ARCFOUR:
2667 return "Arcfour(SSH2)";
2668 case SSH2_CIPHER_ARCFOUR128:
2669 return "Arcfour128(SSH2)";
2670 case SSH2_CIPHER_ARCFOUR256:
2671 return "Arcfour256(SSH2)";
2672 case SSH2_CIPHER_CAST128_CBC:
2673 return "CAST128-CBC(SSH2)";
2674 case SSH2_CIPHER_3DES_CTR:
2675 return "3DES-CTR(SSH2)";
2676 case SSH2_CIPHER_BLOWFISH_CTR:
2677 return "Blowfish-CTR(SSH2)";
2678 case SSH2_CIPHER_CAST128_CTR:
2679 return "CAST128-CTR(SSH2)";
2680 case SSH2_CIPHER_CAMELLIA128_CBC:
2681 return "Camellia128-CBC(SSH2)";
2682 case SSH2_CIPHER_CAMELLIA192_CBC:
2683 return "Camellia192-CBC(SSH2)";
2684 case SSH2_CIPHER_CAMELLIA256_CBC:
2685 return "Camellia256-CBC(SSH2)";
2686 case SSH2_CIPHER_CAMELLIA128_CTR:
2687 return "Camellia128-CTR(SSH2)";
2688 case SSH2_CIPHER_CAMELLIA192_CTR:
2689 return "Camellia192-CTR(SSH2)";
2690 case SSH2_CIPHER_CAMELLIA256_CTR:
2691 return "Camellia256-CTR(SSH2)";
2692
2693 default:
2694 return NULL;
2695 }
2696 }
2697
2698 static void set_move_button_status(HWND dlg, int type, int up, int down)
2699 {
2700 HWND cipherControl = GetDlgItem(dlg, type);
2701 int curPos = (int) SendMessage(cipherControl, LB_GETCURSEL, 0, 0);
2702 int maxPos = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0) - 1;
2703
2704 EnableWindow(GetDlgItem(dlg, up),
2705 curPos > 0 && curPos <= maxPos);
2706 EnableWindow(GetDlgItem(dlg, down),
2707 curPos >= 0 && curPos < maxPos);
2708 }
2709
2710 static void init_setup_dlg(PTInstVar pvar, HWND dlg)
2711 {
2712 HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
2713 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
2714 HWND kexControl = GetDlgItem(dlg, IDC_SSHKEX_LIST);
2715 HWND hostkeyControl = GetDlgItem(dlg, IDC_SSHHOST_KEY_LIST);
2716 HWND macControl = GetDlgItem(dlg, IDC_SSHMAC_LIST);
2717 HWND compControl = GetDlgItem(dlg, IDC_SSHCOMP_LIST);
2718 int i;
2719 int ch;
2720 char uimsg[MAX_UIMSG];
2721
2722 GetWindowText(dlg, uimsg, sizeof(uimsg));
2723 UTIL_get_lang_msg("DLG_SSHSETUP_TITLE", pvar, uimsg);
2724 SetWindowText(dlg, pvar->ts->UIMsg);
2725 GetDlgItemText(dlg, IDC_COMPRESSLABEL, uimsg, sizeof(uimsg));
2726 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS", pvar, uimsg);
2727 SetDlgItemText(dlg, IDC_COMPRESSLABEL, pvar->ts->UIMsg);
2728 GetDlgItemText(dlg, IDC_COMPRESSNONE, uimsg, sizeof(uimsg));
2729 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_NONE", pvar, uimsg);
2730 SetDlgItemText(dlg, IDC_COMPRESSNONE, pvar->ts->UIMsg);
2731 GetDlgItemText(dlg, IDC_COMPRESSHIGH, uimsg, sizeof(uimsg));
2732 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_HIGHEST", pvar, uimsg);
2733 SetDlgItemText(dlg, IDC_COMPRESSHIGH, pvar->ts->UIMsg);
2734 GetDlgItemText(dlg, IDC_COMPRESSNOTE, uimsg, sizeof(uimsg));
2735 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_NOTE", pvar, uimsg);
2736 SetDlgItemText(dlg, IDC_COMPRESSNOTE, pvar->ts->UIMsg);
2737
2738 GetDlgItemText(dlg, IDC_CIPHERORDER, uimsg, sizeof(uimsg));
2739 UTIL_get_lang_msg("DLG_SSHSETUP_CHIPER", pvar, uimsg);
2740 SetDlgItemText(dlg, IDC_CIPHERORDER, pvar->ts->UIMsg);
2741 GetDlgItemText(dlg, IDC_SSHMOVECIPHERUP, uimsg, sizeof(uimsg));
2742 UTIL_get_lang_msg("DLG_SSHSETUP_CHIPER_UP", pvar, uimsg);
2743 SetDlgItemText(dlg, IDC_SSHMOVECIPHERUP, pvar->ts->UIMsg);
2744 GetDlgItemText(dlg, IDC_SSHMOVECIPHERDOWN, uimsg, sizeof(uimsg));
2745 UTIL_get_lang_msg("DLG_SSHSETUP_CHIPER_DOWN", pvar, uimsg);
2746 SetDlgItemText(dlg, IDC_SSHMOVECIPHERDOWN, pvar->ts->UIMsg);
2747
2748 GetDlgItemText(dlg, IDC_KEX_ORDER, uimsg, sizeof(uimsg));
2749 UTIL_get_lang_msg("DLG_SSHSETUP_KEX", pvar, uimsg);
2750 SetDlgItemText(dlg, IDC_KEX_ORDER, pvar->ts->UIMsg);
2751 GetDlgItemText(dlg, IDC_SSHKEX_MOVEUP, uimsg, sizeof(uimsg));
2752 UTIL_get_lang_msg("DLG_SSHSETUP_KEX_UP", pvar, uimsg);
2753 SetDlgItemText(dlg, IDC_SSHKEX_MOVEUP, pvar->ts->UIMsg);
2754 GetDlgItemText(dlg, IDC_SSHKEX_MOVEDOWN, uimsg, sizeof(uimsg));
2755 UTIL_get_lang_msg("DLG_SSHSETUP_KEX_DOWN", pvar, uimsg);
2756 SetDlgItemText(dlg, IDC_SSHKEX_MOVEDOWN, pvar->ts->UIMsg);
2757
2758 GetDlgItemText(dlg, IDC_HOST_KEY_ORDER, uimsg, sizeof(uimsg));
2759 UTIL_get_lang_msg("DLG_SSHSETUP_HOST_KEY", pvar, uimsg);
2760 SetDlgItemText(dlg, IDC_HOST_KEY_ORDER, pvar->ts->UIMsg);
2761 GetDlgItemText(dlg, IDC_SSHHOST_KEY_MOVEUP, uimsg, sizeof(uimsg));
2762 UTIL_get_lang_msg("DLG_SSHSETUP_HOST_KEY_UP", pvar, uimsg);
2763 SetDlgItemText(dlg, IDC_SSHHOST_KEY_MOVEUP, pvar->ts->UIMsg);
2764 GetDlgItemText(dlg, IDC_SSHHOST_KEY_MOVEDOWN, uimsg, sizeof(uimsg));
2765 UTIL_get_lang_msg("DLG_SSHSETUP_HOST_KEY_DOWN", pvar, uimsg);
2766 SetDlgItemText(dlg, IDC_SSHHOST_KEY_MOVEDOWN, pvar->ts->UIMsg);
2767
2768 GetDlgItemText(dlg, IDC_MAC_ORDER, uimsg, sizeof(uimsg));
2769 UTIL_get_lang_msg("DLG_SSHSETUP_MAC", pvar, uimsg);
2770 SetDlgItemText(dlg, IDC_MAC_ORDER, pvar->ts->UIMsg);
2771 GetDlgItemText(dlg, IDC_SSHMAC_MOVEUP, uimsg, sizeof(uimsg));
2772 UTIL_get_lang_msg("DLG_SSHSETUP_MAC_UP", pvar, uimsg);
2773 SetDlgItemText(dlg, IDC_SSHMAC_MOVEUP, pvar->ts->UIMsg);
2774 GetDlgItemText(dlg, IDC_SSHMAC_MOVEDOWN, uimsg, sizeof(uimsg));
2775 UTIL_get_lang_msg("DLG_SSHSETUP_MAC_DOWN", pvar, uimsg);
2776 SetDlgItemText(dlg, IDC_SSHMAC_MOVEDOWN, pvar->ts->UIMsg);
2777
2778 GetDlgItemText(dlg, IDC_COMP_ORDER, uimsg, sizeof(uimsg));
2779 UTIL_get_lang_msg("DLG_SSHSETUP_COMP", pvar, uimsg);
2780 SetDlgItemText(dlg, IDC_COMP_ORDER, pvar->ts->UIMsg);
2781 GetDlgItemText(dlg, IDC_SSHCOMP_MOVEUP, uimsg, sizeof(uimsg));
2782 UTIL_get_lang_msg("DLG_SSHSETUP_COMP_UP", pvar, uimsg);
2783 SetDlgItemText(dlg, IDC_SSHCOMP_MOVEUP, pvar->ts->UIMsg);
2784 GetDlgItemText(dlg, IDC_SSHCOMP_MOVEDOWN, uimsg, sizeof(uimsg));
2785 UTIL_get_lang_msg("DLG_SSHSETUP_COMP_DOWN", pvar, uimsg);
2786 SetDlgItemText(dlg, IDC_SSHCOMP_MOVEDOWN, pvar->ts->UIMsg);
2787
2788 GetDlgItemText(dlg, IDC_KNOWNHOSTS, uimsg, sizeof(uimsg));
2789 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST", pvar, uimsg);
2790 SetDlgItemText(dlg, IDC_KNOWNHOSTS, pvar->ts->UIMsg);
2791 GetDlgItemText(dlg, IDC_CHOOSEREADWRITEFILE, uimsg, sizeof(uimsg));
2792 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST_RW", pvar, uimsg);
2793 SetDlgItemText(dlg, IDC_CHOOSEREADWRITEFILE, pvar->ts->UIMsg);
2794 GetDlgItemText(dlg, IDC_CHOOSEREADONLYFILE, uimsg, sizeof(uimsg));
2795 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST_RO", pvar, uimsg);
2796 SetDlgItemText(dlg, IDC_CHOOSEREADONLYFILE, pvar->ts->UIMsg);
2797 GetDlgItemText(dlg, IDC_HEARTBEATLABEL, uimsg, sizeof(uimsg));
2798 UTIL_get_lang_msg("DLG_SSHSETUP_HEARTBEAT", pvar, uimsg);
2799 SetDlgItemText(dlg, IDC_HEARTBEATLABEL, pvar->ts->UIMsg);
2800 GetDlgItemText(dlg, IDC_HEARTBEATLABEL2, uimsg, sizeof(uimsg));
2801 UTIL_get_lang_msg("DLG_SSHSETUP_HEARTBEAT_UNIT", pvar, uimsg);
2802 SetDlgItemText(dlg, IDC_HEARTBEATLABEL2, pvar->ts->UIMsg);
2803 GetDlgItemText(dlg, IDC_REMEMBERPASSWORD, uimsg, sizeof(uimsg));
2804 UTIL_get_lang_msg("DLG_SSHSETUP_PASSWORD", pvar, uimsg);
2805 SetDlgItemText(dlg, IDC_REMEMBERPASSWORD, pvar->ts->UIMsg);
2806 GetDlgItemText(dlg, IDC_FORWARDAGENT, uimsg, sizeof(uimsg));
2807 UTIL_get_lang_msg("DLG_SSHSETUP_FORWARDAGENT", pvar, uimsg);
2808 SetDlgItemText(dlg, IDC_FORWARDAGENT, pvar->ts->UIMsg);
2809 GetDlgItemText(dlg, IDC_FORWARDAGENTCONFIRM, uimsg, sizeof(uimsg));
2810 UTIL_get_lang_msg("DLG_SSHSETUP_FORWARDAGENTCONFIRM", pvar, uimsg);
2811 SetDlgItemText(dlg, IDC_FORWARDAGENTCONFIRM, pvar->ts->UIMsg);
2812 GetDlgItemText(dlg, IDC_VERIFYHOSTKEYDNS, uimsg, sizeof(uimsg));
2813 UTIL_get_lang_msg("DLG_SSHSETUP_VERIFYHOSTKEYDNS", pvar, uimsg);
2814 SetDlgItemText(dlg, IDC_VERIFYHOSTKEYDNS, pvar->ts->UIMsg);
2815 GetDlgItemText(dlg, IDC_NOTICEBANNER, uimsg, sizeof(uimsg));
2816 UTIL_get_lang_msg("DLG_SSHSETUP_NOTICE", pvar, uimsg);
2817 SetDlgItemText(dlg, IDC_NOTICEBANNER, pvar->ts->UIMsg);
2818 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2819 UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
2820 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2821 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2822 UTIL_get_lang_msg("BTN_CANCEL", pvar, uimsg);
2823 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2824
2825 SendMessage(compressionControl, TBM_SETRANGE, TRUE, MAKELONG(0, 9));
2826 SendMessage(compressionControl, TBM_SETPOS, TRUE,
2827 pvar->settings.CompressionLevel);
2828
2829 // Cipher order
2830 normalize_cipher_order(pvar->settings.CipherOrder);
2831
2832 for (i = 0; pvar->settings.CipherOrder[i] != 0; i++) {
2833 int cipher = pvar->settings.CipherOrder[i] - '0';
2834 char FAR *name = get_cipher_name(cipher);
2835
2836 if (name != NULL) {
2837 SendMessage(cipherControl, LB_ADDSTRING, 0, (LPARAM) name);
2838 }
2839 }
2840
2841 SendMessage(cipherControl, LB_SETCURSEL, 0, 0);
2842 set_move_button_status(dlg, IDC_SSHCIPHERPREFS, IDC_SSHMOVECIPHERUP, IDC_SSHMOVECIPHERDOWN);
2843
2844 // KEX order
2845 normalize_kex_order(pvar->settings.KexOrder);
2846 for (i = 0; pvar->settings.KexOrder[i] != 0; i++) {
2847 int index = pvar->settings.KexOrder[i] - '0';
2848 char FAR *name = NULL;
2849
2850 if (index == 0) {
2851 UTI