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