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 4151 - (show annotations) (download) (as text)
Wed Nov 10 06:20:21 2010 UTC (13 years, 5 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 138993 byte(s)
圧縮を有効/無効にするオプション、/ssh-C, /ssh-c を追加。

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