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 5578 - (show annotations) (download) (as text)
Sun May 4 15:49:47 2014 UTC (9 years, 11 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 178028 byte(s)
バージョン情報のEdit Controlに、等幅フォントを指定できるようにした。
また、横スクロールバーを追加した。

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