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 4392 - (show annotations) (download) (as text)
Tue Mar 22 00:05:50 2011 UTC (13 years ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 147459 byte(s)
最後の二つの暗号方式 (Blowfish-CTR, CAST128-CTR) が常に無効化されるのを修正。
# 暗号方式で 1, 4, 5 が欠番なので、デフォルトのリストに三つ分のダミーエントリーを追加

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