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