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 4425 - (show annotations) (download) (as text)
Fri Apr 8 08:31:26 2011 UTC (13 years ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 147646 byte(s)
hmac-sha2 サポート。ドラフトだし、動作確認もまだなので無効化中。
http://www.ietf.org/id/draft-dbider-sha2-mac-for-ssh-00.txt

# 気が早すぎ

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