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