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 3850 - (show annotations) (download) (as text)
Mon Apr 12 08:29:53 2010 UTC (14 years ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 138242 byte(s)
3DES-CTR, BLOWFISH-CTR, CAST128-CTR 共通鍵暗号方式をサポート。

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 // /ssh1 �� /ssh2 �I�v�V�������V�K���� (2006.9.16 maya)
1533 } else if (MATCH_STR(option + 4, "1") == 0) {
1534 pvar->settings.Enabled = 1;
1535 pvar->settings.ssh_protocol_version = 1;
1536 } else if (MATCH_STR(option + 4, "2") == 0) {
1537 pvar->settings.Enabled = 1;
1538 pvar->settings.ssh_protocol_version = 2;
1539
1540 } else {
1541 char buf[1024];
1542
1543 UTIL_get_lang_msg("MSG_UNKNOWN_OPTION_ERROR", pvar,
1544 "Unrecognized command-line option: %s");
1545 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, option);
1546
1547 MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
1548 }
1549
1550 // ttermpro.exe �� /T= �w�������p�������A������������ (2006.10.19 maya)
1551 } else if (MATCH_STR_I(option + 1, "t=") == 0) {
1552 if (strcmp(option + 3, "2") == 0) {
1553 pvar->settings.Enabled = 1;
1554 return OPTION_CLEAR; // /t=2��ttssh�������g������������
1555 } else {
1556 pvar->settings.Enabled = 0;
1557 return OPTION_NONE; // Tera Term������������������������
1558 }
1559
1560 // ttermpro.exe �� /F= �w������ TTSSH ������������ (2006.10.11 maya)
1561 } else if (MATCH_STR_I(option + 1, "f=") == 0) {
1562 read_ssh_options_from_user_file(pvar, option + 3);
1563 return OPTION_NONE; // Tera Term���������������K�v������������������
1564
1565 // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
1566 } else if (MATCH_STR(option + 1, "1") == 0) {
1567 // command line: /ssh /1 is SSH1 only
1568 pvar->settings.ssh_protocol_version = 1;
1569
1570 } else if (MATCH_STR(option + 1, "2") == 0) {
1571 // command line: /ssh /2 is SSH2 & SSH1
1572 pvar->settings.ssh_protocol_version = 2;
1573
1574 } else if (MATCH_STR(option + 1, "nossh") == 0) {
1575 // '/nossh' �I�v�V�����������B
1576 // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
1577 // �����������������B(2004.10.11 yutaka)
1578 pvar->settings.Enabled = 0;
1579
1580 } else if (MATCH_STR(option + 1, "telnet") == 0) {
1581 // '/telnet' ���w�������������������� '/nossh' ��������
1582 // SSH������������ (2006.9.16 maya)
1583 pvar->settings.Enabled = 0;
1584 // Tera Term �� Telnet �t���O���t����
1585 pvar->ts->Telnet = 1;
1586
1587 } else if (MATCH_STR(option + 1, "auth") == 0) {
1588 // SSH2�������O�C���I�v�V����������
1589 //
1590 // SYNOPSIS: /ssh /auth=passowrd /user=���[�U�� /passwd=�p�X���[�h
1591 // /ssh /auth=publickey /user=���[�U�� /passwd=�p�X���[�h /keyfile=�p�X
1592 // EXAMPLE: /ssh /auth=password /user=nike /passwd=a@bc
1593 // /ssh /auth=publickey /user=foo /passwd=bar /keyfile=d:\tmp\id_rsa
1594 // NOTICE: �p�X���[�h���p�X�������������������A�u�����N���������� @ ���g�������B
1595 //
1596 // (2004.11.30 yutaka)
1597 // (2005.1.26 yutaka) ���������B���J���F���T�|�[�g�B
1598 //
1599 pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
1600
1601 if (MATCH_STR(option + 5, "=password") == 0) { // �p�X���[�h
1602 //pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
1603 pvar->ssh2_authmethod = SSH_AUTH_PASSWORD;
1604
1605 // /auth=challenge ������ (2007.10.5 maya)
1606 } else if (MATCH_STR(option + 5, "=challenge") == 0) { // keyboard-interactive�F��
1607 //pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
1608 pvar->ssh2_authmethod = SSH_AUTH_TIS;
1609
1610 } else if (MATCH_STR(option + 5, "=publickey") == 0) { // ���J���F��
1611 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1612 pvar->ssh2_authmethod = SSH_AUTH_RSA;
1613
1614 } else if (MATCH_STR(option + 5, "=pageant") == 0) { // ���J���F�� by Pageant
1615 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1616 pvar->ssh2_authmethod = SSH_AUTH_PAGEANT;
1617
1618 } else {
1619 // TODO:
1620
1621 }
1622
1623 } else if (MATCH_STR(option + 1, "user=") == 0) {
1624 #ifdef USE_ATCMDLINE
1625 replace_to_blank(option + 6, pvar->ssh2_username, sizeof(pvar->ssh2_username));
1626 //_snprintf(pvar->ssh2_username, sizeof(pvar->ssh2_username), "%s", option + 6);
1627
1628 #else
1629 _snprintf_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), _TRUNCATE, "%s", option + 6);
1630 #endif
1631
1632 } else if (MATCH_STR(option + 1, "passwd=") == 0) {
1633 #ifdef USE_ATCMDLINE
1634 replace_to_blank(option + 8, pvar->ssh2_password, sizeof(pvar->ssh2_password));
1635 //_snprintf(pvar->ssh2_password, sizeof(pvar->ssh2_password), "%s", option + 8);
1636 #else
1637 _snprintf_s(pvar->ssh2_password, sizeof(pvar->ssh2_password), _TRUNCATE, "%s", option + 8);
1638 #endif
1639
1640 } else if (MATCH_STR(option + 1, "keyfile=") == 0) {
1641 #ifdef USE_ATCMDLINE
1642 replace_to_blank(option + 9, pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile));
1643 #else
1644 _snprintf_s(pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile), _TRUNCATE, "%s", option + 9);
1645 #endif
1646
1647 } else if (MATCH_STR(option + 1, "ask4passwd") == 0) {
1648 // �p�X���[�h������ (2006.9.18 maya)
1649 pvar->ask4passwd = 1;
1650
1651 } else if (MATCH_STR(option + 1, "nosecuritywarning") == 0) {
1652 // known_hosts�`�F�b�N���������B���Y�I�v�V�������g�����A�Z�L�����e�B������������
1653 // �����A�B���I�v�V���������������B
1654 // (2009.10.4 yutaka)
1655 pvar->nocheck_known_hosts = TRUE;
1656
1657 }
1658 else { // Other (not ttssh) option
1659 return OPTION_NONE; // ttssh���I�v�V������������������������
1660 }
1661
1662 // �p�X���[�h�������������������O�C��������������
1663 // /auth ���F�����\�b�h���w�������������p������ (2006.9.18 maya)
1664 if (pvar->ask4passwd == 1) {
1665 pvar->ssh2_autologin = 0;
1666 }
1667 return OPTION_CLEAR;
1668
1669 }
1670 else if ((MATCH_STR_I(option, "ssh://") == 0) ||
1671 (MATCH_STR_I(option, "ssh1://") == 0) ||
1672 (MATCH_STR_I(option, "ssh2://") == 0) ||
1673 (MATCH_STR_I(option, "slogin://") == 0) ||
1674 (MATCH_STR_I(option, "slogin1://") == 0) ||
1675 (MATCH_STR_I(option, "slogin2://") == 0)) {
1676 //
1677 // ssh://user@host/ ����URL�`�����T�|�[�g
1678 // ���{�I�������� telnet:// URL��������
1679 //
1680 // �Q�l:
1681 // RFC3986: Uniform Resource Identifier (URI): Generic Syntax
1682 // RFC4248: The telnet URI Scheme
1683 //
1684 char *p, *p2, *p3;
1685 int optlen, hostlen;
1686
1687 optlen = strlen(option);
1688
1689 // ������':'���O�����������������������A������ssh�v���g�R���o�[�W������������
1690 p = _mbschr(option, ':');
1691 switch (*(p-1)) {
1692 case '1':
1693 pvar->settings.ssh_protocol_version = 1;
1694 break;
1695 case '2':
1696 pvar->settings.ssh_protocol_version = 2;
1697 break;
1698 }
1699
1700 // authority part �����|�C���^������
1701 p += 3;
1702
1703 // path part ������������
1704 if ((p2 = _mbschr(p, '/')) != NULL) {
1705 *p2 = 0;
1706 }
1707
1708 // '@'�������������A���������O�����[�U����
1709 if ((p2 = _mbschr(p, '@')) != NULL) {
1710 *p2 = 0;
1711 // ':'���~���p�X���[�h
1712 if ((p3 = _mbschr(p, ':')) != NULL) {
1713 *p3 = 0;
1714 percent_decode(pvar->ssh2_password, sizeof(pvar->ssh2_password), p3 + 1);
1715 }
1716 percent_decode(pvar->ssh2_username, sizeof(pvar->ssh2_username), p);
1717 // p �� host part ������('@'����������)����������������
1718 p = p2 + 1;
1719 }
1720
1721 // host part �� option �����������������Ascheme part ������
1722 // port�w����������������port���������������������m��������������
1723 hostlen = strlen(p);
1724 memmove_s(option, optlen, p, hostlen);
1725 option[hostlen] = 0;
1726
1727 // �|�[�g�w������������":22"������
1728 #ifndef NO_INET6
1729 if (option[0] == '[' && option[hostlen-1] == ']' || // IPv6 raw address without port
1730 option[0] != '[' && _mbschr(option, ':') == NULL) { // hostname or IPv4 raw address without port
1731 #else
1732 if (_mbschr(option, ':') == NULL) {
1733 #endif /* NO_INET6 */
1734 memcpy_s(option+hostlen, optlen-hostlen, ":22", 3);
1735 hostlen += 3;
1736 }
1737
1738 // �|�[�g�w�����������������X�y�[�X������
1739 memset(option+hostlen, ' ', optlen-hostlen);
1740
1741 pvar->settings.Enabled = 1;
1742
1743 return OPTION_REPLACE;
1744 }
1745 else if (_mbschr(option, '@') != NULL) {
1746 //
1747 // user@host �`�����T�|�[�g
1748 // ����������ssh�������T�|�[�g�����A���[�U����ttssh���������B
1749 // (ssh�������O -- ttssh�������W������������)
1750 // �����I��telnet authentication option���T�|�[�g��������
1751 // Tera Term�{�����������������������\���B
1752 //
1753 char *p;
1754 p = _mbschr(option, '@');
1755 *p = 0;
1756
1757 strncpy_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), option, _TRUNCATE);
1758
1759 // ���[�U���������X�y�[�X�������B
1760 // ������TTX��Tera Term�{�������������������X�y�[�X�����������������A
1761 // �z�X�g�����������l�����K�v�������B
1762 memset(option, ' ', p-option+1);
1763
1764 return OPTION_REPLACE;
1765 }
1766
1767 return OPTION_NONE;
1768 }
1769
1770 static void FAR PASCAL TTXParseParam(PCHAR param, PTTSet ts,
1771 PCHAR DDETopic)
1772 {
1773 #ifndef USE_ATCMDLINE
1774 int i;
1775 BOOL inParam = FALSE;
1776 BOOL inQuotes = FALSE;
1777 BOOL inEqual = FALSE;
1778 int param_len=strlen(param);
1779 PCHAR start = NULL;
1780 char *buf = (char *)calloc(param_len+1, sizeof(char));
1781 int buflen = 0;
1782
1783 if (pvar->hostdlg_activated) {
1784 pvar->settings.Enabled = pvar->hostdlg_Enabled;
1785 }
1786
1787 for (i = 0; i < param_len; i++) {
1788 if (inQuotes) {
1789 // �������u��"����
1790 if (param[i] == '"') {
1791 if (param[i+1] == '"') {
1792 buf[buflen] = param[i];
1793 buflen++;
1794 i++;
1795 }
1796 else {
1797 // �N�H�[�g���������������������I����
1798 // "��buf�����������������n��
1799 switch (parse_option(pvar, buf)) {
1800 case OPTION_CLEAR:
1801 memset(start, ' ', (param + i) - start + 1);
1802 break;
1803 case OPTION_REPLACE:
1804 memset(start, ' ', (param + i) - start + 1);
1805 buflen = strlen(buf);
1806 memcpy(start, buf, buflen);
1807 break;
1808 }
1809 inParam = FALSE;
1810 inEqual = FALSE;
1811 start = NULL;
1812 memset(buf, 0, param_len);
1813 buflen = 0;
1814 inQuotes = FALSE;
1815 }
1816 }
1817 else {
1818 buf[buflen] = param[i];
1819 buflen++;
1820 }
1821 }
1822 else {
1823 if (!inParam) {
1824 // �����p�����[�^������������
1825 if (param[i] == '"') {
1826 // " ���n����
1827 start = param + i;
1828 inParam = TRUE;
1829 inQuotes = TRUE;
1830 }
1831 else if (param[i] != ' ' && param[i] != '\t') {
1832 // �������n����
1833 buf[buflen] = param[i];
1834 buflen++;
1835 start = param + i;
1836 inParam = TRUE;
1837 }
1838 }
1839 else {
1840 // �������u���p�����[�^����
1841 if (param[i] == ' ' || param[i] == '\t') {
1842 // �N�H�[�g�����������������������I����
1843 switch (parse_option(pvar, buf)) {
1844 case OPTION_CLEAR:
1845 memset(start, ' ', (param + i) - start + 1);
1846 break;
1847 case OPTION_REPLACE:
1848 memset(start, ' ', (param + i) - start + 1);
1849 buflen = strlen(buf);
1850 memcpy(start, buf, buflen);
1851 break;
1852 }
1853 inParam = FALSE;
1854 inEqual = FALSE;
1855 start = NULL;
1856 memset(buf, 0, param_len);
1857 buflen = 0;
1858 }
1859 else {
1860 buf[buflen] = param[i];
1861 buflen++;
1862 if (!inEqual && param[i] == '=') {
1863 inEqual = TRUE;
1864 if (param[i+1] == '"') {
1865 inQuotes = TRUE;
1866 i++;
1867 }
1868 }
1869 }
1870 }
1871 }
1872 }
1873
1874 // buf ���c�����������������n��
1875 // +1������������'\0'�������������������A��������������������
1876 if (strlen(buf) > 0) {
1877 switch (parse_option(pvar, buf)) {
1878 case OPTION_CLEAR:
1879 memset(start, ' ', (param + i) - start);
1880 break;
1881 case OPTION_REPLACE:
1882 memset(start, ' ', (param + i) - start);
1883 buflen = strlen(buf);
1884 memcpy(start, buf, buflen);
1885 break;
1886 }
1887 }
1888 free(buf);
1889 #else
1890 // �X�y�[�X�������t�@�C�������F�������������C�� (2006.10.7 maya)
1891 int i, buflen;
1892 BOOL inParam = FALSE;
1893 BOOL inQuotes = FALSE;
1894 BOOL inFileParam = FALSE;
1895 PCHAR option = NULL;
1896
1897 if (pvar->hostdlg_activated) {
1898 pvar->settings.Enabled = pvar->hostdlg_Enabled;
1899 }
1900
1901 for (i = 0; param[i] != 0; i++) {
1902 if (inQuotes ? param[i] == '"'
1903 : (param[i] == ' ' || param[i] == '\t')) {
1904 if (option != NULL) {
1905 char ch = param[i];
1906 PCHAR Equal;
1907
1908 param[i] = 0;
1909 Equal = strchr(option, '=');
1910 if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
1911 int buf_len = strlen(option) * sizeof(char);
1912 char *buf = (char *)calloc(strlen(option), sizeof(char));
1913 char c = option[Equal - option + 1];
1914 option[Equal - option + 1] = 0;
1915 strncat_s(buf, buf_len, option, _TRUNCATE);
1916 option[Equal - option + 1] = c;
1917 strncat_s(buf, buf_len, Equal + 2, _TRUNCATE);
1918 switch (parse_option(pvar, *buf == '"' ? buf + 1 : buf)) {
1919 case OPTION_CLEAR:
1920 memset(option, ' ', i + 1 - (option - param));
1921 break;
1922 case OPTION_REPLACE:
1923 buflen = strlen(buf);
1924 memcpy(option, buf, buflen);
1925 memset(option + buflen, ' ', i + 1 - buflen - (option - param));
1926 break;
1927 default:
1928 param[i] = ch;
1929 }
1930 free(buf);
1931 }
1932 else {
1933 switch (parse_option(pvar, *option == '"' ? option + 1 : option)) {
1934 case OPTION_CLEAR:
1935 memset(option, ' ', i + 1 - (option - param));
1936 break;
1937 default:
1938 param[i] = ch;
1939 }
1940 }
1941 option = NULL;
1942 }
1943 inParam = FALSE;
1944 inQuotes = FALSE;
1945 inFileParam = FALSE;
1946 } else if (!inParam) {
1947 if (param[i] == '"') {
1948 inQuotes = TRUE;
1949 inParam = TRUE;
1950 option = param + i;
1951 } else if (param[i] != ' ' && param[i] != '\t') {
1952 inParam = TRUE;
1953 option = param + i;
1954 }
1955 } else {
1956 if (option == NULL) {
1957 continue;
1958 }
1959 if ((option[0] == '-' || option[0] == '/') &&
1960 (MATCH_STR(option + 1, "ssh-f=") == 0 || // ttssh option
1961 MATCH_STR(option + 1, "ssh-consume=") == 0 || // ttssh option
1962 MATCH_STR_I(option + 1, "f=") == 0 || // Tera Term option
1963 MATCH_STR_I(option + 1, "fd=") == 0 || // Tera Term option
1964 MATCH_STR_I(option + 1, "k=") == 0 || // Tera Term option
1965 MATCH_STR_I(option + 1, "l=") == 0 || // Tera Term option
1966 MATCH_STR_I(option + 1, "m=") == 0 || // Tera Term option
1967 MATCH_STR_I(option + 1, "r=") == 0 || // Tera Term option
1968 MATCH_STR_I(option + 1, "w=") == 0 || // Tera Term option
1969 MATCH_STR(option + 1, "keyfile=") == 0)) { // ttssh option
1970 if (param[i] == '"') {
1971 inQuotes = TRUE;
1972 }
1973 inFileParam = TRUE;
1974 }
1975 }
1976 }
1977
1978 if (option != NULL) {
1979 PCHAR Equal = strchr(option, '=');
1980 if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
1981 int buf_len = strlen(option) * sizeof(char);
1982 char *buf = (char *)calloc(strlen(option), sizeof(char));
1983 char c = option[Equal - option + 1];
1984 option[Equal - option + 1] = 0;
1985 strncat_s(buf, buf_len, option, _TRUNCATE);
1986 option[Equal - option + 1] = c;
1987 strncat_s(buf, buf_len, Equal + 2, _TRUNCATE);
1988 switch (parse_option(pvar, *buf == '"' ? buf + 1 : buf)) {
1989 case OPTION_CLEAR:
1990 memset(option, ' ', i + 1 - (option - param));
1991 break;
1992 case OPTION_REPLACE:
1993 strcpy_s(option, i - (param - option), buf);
1994 break;
1995 }
1996 free(buf);
1997 }
1998 else {
1999 switch (parse_option(pvar, option)) {
2000 case OPTION_CLEAR:
2001 memset(option, ' ', i - (option - param));
2002 break;
2003 }
2004 }
2005 }
2006 #endif
2007
2008 FWDUI_load_settings(pvar);
2009
2010 (pvar->ParseParam) (param, ts, DDETopic);
2011
2012 }
2013
2014 static void PASCAL FAR TTXGetSetupHooks(TTXSetupHooks FAR * hooks)
2015 {
2016 pvar->ReadIniFile = *hooks->ReadIniFile;
2017 pvar->WriteIniFile = *hooks->WriteIniFile;
2018 pvar->ParseParam = *hooks->ParseParam;
2019
2020 *hooks->ReadIniFile = TTXReadINIFile;
2021 *hooks->WriteIniFile = TTXWriteINIFile;
2022 *hooks->ParseParam = TTXParseParam;
2023 }
2024
2025 static void PASCAL FAR TTXSetWinSize(int rows, int cols)
2026 {
2027 SSH_notify_win_size(pvar, cols, rows);
2028 }
2029
2030 static void insertMenuBeforeItem(HMENU menu, WORD beforeItemID, WORD flags,
2031 WORD newItemID, char FAR * text)
2032 {
2033 int i, j;
2034
2035 for (i = GetMenuItemCount(menu) - 1; i >= 0; i--) {
2036 HMENU submenu = GetSubMenu(menu, i);
2037
2038 for (j = GetMenuItemCount(submenu) - 1; j >= 0; j--) {
2039 if (GetMenuItemID(submenu, j) == beforeItemID) {
2040 InsertMenu(submenu, j, MF_BYPOSITION | flags, newItemID, text);
2041 return;
2042 }
2043 }
2044 }
2045 }
2046
2047 static void PASCAL FAR TTXModifyMenu(HMENU menu)
2048 {
2049 /* inserts before ID_HELP_ABOUT */
2050 UTIL_get_lang_msg("MENU_ABOUT", pvar, "About &TTSSH...");
2051 insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU, pvar->ts->UIMsg);
2052
2053 /* inserts before ID_SETUP_TCPIP */
2054 UTIL_get_lang_msg("MENU_SSH", pvar, "SS&H...");
2055 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU, pvar->ts->UIMsg);
2056 /* inserts before ID_SETUP_TCPIP */
2057 UTIL_get_lang_msg("MENU_SSH_AUTH", pvar, "SSH &Authentication...");
2058 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU, pvar->ts->UIMsg);
2059 /* inserts before ID_SETUP_TCPIP */
2060 UTIL_get_lang_msg("MENU_SSH_FORWARD", pvar, "SSH F&orwarding...");
2061 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU, pvar->ts->UIMsg);
2062 UTIL_get_lang_msg("MENU_SSH_KEYGEN", pvar, "SSH KeyGe&nerator...");
2063 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHKEYGENMENU, pvar->ts->UIMsg);
2064
2065 /* inserts before ID_FILE_CHANGEDIR */
2066 UTIL_get_lang_msg("MENU_SSH_SCP", pvar, "SS&H SCP...");
2067 insertMenuBeforeItem(menu, 50170, MF_ENABLED, ID_SSHSCPMENU, pvar->ts->UIMsg);
2068 }
2069
2070 static void append_about_text(HWND dlg, char FAR * prefix, char FAR * msg)
2071 {
2072 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
2073 (LPARAM) prefix);
2074 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0, (LPARAM) msg);
2075 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
2076 (LPARAM) (char FAR *) "\r\n");
2077 }
2078
2079 // ���s�t�@�C�������o�[�W�������������� (2005.2.28 yutaka)
2080 void get_file_version(char *exefile, int *major, int *minor, int *release, int *build)
2081 {
2082 typedef struct {
2083 WORD wLanguage;
2084 WORD wCodePage;
2085 } LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
2086 LPLANGANDCODEPAGE lplgcode;
2087 UINT unLen;
2088 DWORD size;
2089 char *buf = NULL;
2090 BOOL ret;
2091 int i;
2092 char fmt[80];
2093 char *pbuf;
2094
2095 size = GetFileVersionInfoSize(exefile, NULL);
2096 if (size == 0) {
2097 goto error;
2098 }
2099 buf = malloc(size);
2100 ZeroMemory(buf, size);
2101
2102 if (GetFileVersionInfo(exefile, 0, size, buf) == FALSE) {
2103 goto error;
2104 }
2105
2106 ret = VerQueryValue(buf,
2107 "\\VarFileInfo\\Translation",
2108 (LPVOID *)&lplgcode, &unLen);
2109 if (ret == FALSE)
2110 goto error;
2111
2112 for (i = 0 ; i < (int)(unLen / sizeof(LANGANDCODEPAGE)) ; i++) {
2113 _snprintf_s(fmt, sizeof(fmt), _TRUNCATE,
2114 "\\StringFileInfo\\%04x%04x\\FileVersion",
2115 lplgcode[i].wLanguage, lplgcode[i].wCodePage);
2116 VerQueryValue(buf, fmt, &pbuf, &unLen);
2117 if (unLen > 0) { // get success
2118 int n, a, b, c, d;
2119
2120 n = sscanf(pbuf, "%d, %d, %d, %d", &a, &b, &c, &d);
2121 if (n == 4) { // convert success
2122 *major = a;
2123 *minor = b;
2124 *release = c;
2125 *build = d;
2126 break;
2127 }
2128 }
2129 }
2130
2131 free(buf);
2132 return;
2133
2134 error:
2135 free(buf);
2136 *major = *minor = *release = *build = 0;
2137 }
2138
2139 static void init_about_dlg(PTInstVar pvar, HWND dlg)
2140 {
2141 char buf[1024];
2142 int a, b, c, d;
2143 char uimsg[MAX_UIMSG];
2144
2145 GetWindowText(dlg, uimsg, sizeof(uimsg));
2146 UTIL_get_lang_msg("DLG_ABOUT_TITLE", pvar, uimsg);
2147 SetWindowText(dlg, pvar->ts->UIMsg);
2148 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2149 UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
2150 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2151
2152 // TTSSH���o�[�W�������������� (2005.2.28 yutaka)
2153 get_file_version("ttxssh.dll", &a, &b, &c, &d);
2154 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2155 "TTSSH\r\nTera Term Secure Shell extension, %d.%d", a, b);
2156 SendMessage(GetDlgItem(dlg, IDC_TTSSH_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2157
2158 // OpenSSL���o�[�W�������������� (2005.1.24 yutaka)
2159 // ���������� (2005.5.11 yutaka)
2160 #ifdef OPENSSL_VERSION_TEXT
2161 SendMessage(GetDlgItem(dlg, IDC_OPENSSL_VERSION), WM_SETTEXT, 0, (LPARAM)OPENSSL_VERSION_TEXT);
2162 #else
2163 SendMessage(GetDlgItem(dlg, IDC_OPENSSL_VERSION), WM_SETTEXT, 0, (LPARAM)"Unknown");
2164 #endif
2165
2166 // zlib���o�[�W�������������� (2005.5.11 yutaka)
2167 #ifdef ZLIB_VERSION
2168 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "ZLib %s", ZLIB_VERSION);
2169 #else
2170 _snprintf(buf, sizeof(buf), "ZLib Unknown");
2171 #endif
2172 SendMessage(GetDlgItem(dlg, IDC_ZLIB_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2173
2174
2175 // TTSSH�_�C�A���O���\������SSH������������ (2004.10.30 yutaka)
2176 if (pvar->socket != INVALID_SOCKET) {
2177 if (SSHv1(pvar)) {
2178 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
2179 UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID:");
2180 append_about_text(dlg, pvar->ts->UIMsg, buf);
2181 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
2182 UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol:");
2183 append_about_text(dlg, pvar->ts->UIMsg, buf);
2184 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
2185 UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:");
2186 append_about_text(dlg, pvar->ts->UIMsg, buf);
2187 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
2188 UTIL_get_lang_msg("DLG_ABOUT_SERVERKEY", pvar, "Server keys:");
2189 append_about_text(dlg, pvar->ts->UIMsg, buf);
2190 AUTH_get_auth_info(pvar, buf, sizeof(buf));
2191 UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication:");
2192 append_about_text(dlg, pvar->ts->UIMsg, buf);
2193 SSH_get_compression_info(pvar, buf, sizeof(buf));
2194 UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression:");
2195 append_about_text(dlg, pvar->ts->UIMsg, buf);
2196
2197 } else { // SSH2
2198 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
2199 UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID:");
2200 append_about_text(dlg, pvar->ts->UIMsg, buf);
2201 UTIL_get_lang_msg("DLG_ABOUT_CLIENTID", pvar, "Client ID:");
2202 append_about_text(dlg, pvar->ts->UIMsg, pvar->client_version_string);
2203
2204 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
2205 UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol:");
2206 append_about_text(dlg, pvar->ts->UIMsg, buf);
2207
2208 if (pvar->kex_type == KEX_DH_GRP1_SHA1) {
2209 strncpy_s(buf, sizeof(buf), KEX_DH1, _TRUNCATE);
2210 } else if (pvar->kex_type == KEX_DH_GRP14_SHA1) {
2211 strncpy_s(buf, sizeof(buf), KEX_DH14, _TRUNCATE);
2212 } else {
2213 strncpy_s(buf, sizeof(buf), KEX_DHGEX, _TRUNCATE);
2214 }
2215 append_about_text(dlg, "KEX:", buf);
2216
2217 if (pvar->hostkey_type == KEY_DSA) {
2218 strncpy_s(buf, sizeof(buf), "ssh-dss", _TRUNCATE);
2219 } else {
2220 strncpy_s(buf, sizeof(buf), "ssh-rsa", _TRUNCATE);
2221 }
2222 UTIL_get_lang_msg("DLG_ABOUT_HOSTKEY", pvar, "Host Key:");
2223 append_about_text(dlg, pvar->ts->UIMsg, buf);
2224
2225 // add HMAC algorithm (2004.12.17 yutaka)
2226 buf[0] = '\0';
2227 if (pvar->ctos_hmac == HMAC_SHA1) {
2228 strncat_s(buf, sizeof(buf), "hmac-sha1", _TRUNCATE);
2229 } else if (pvar->ctos_hmac == HMAC_MD5) {
2230 strncat_s(buf, sizeof(buf), "hmac-md5", _TRUNCATE);
2231 }
2232 UTIL_get_lang_msg("DLG_ABOUT_TOSERVER", pvar, " to server,");
2233 strncat_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2234 if (pvar->stoc_hmac == HMAC_SHA1) {
2235 strncat_s(buf, sizeof(buf), "hmac-sha1", _TRUNCATE);
2236 } else if (pvar->stoc_hmac == HMAC_MD5) {
2237 strncat_s(buf, sizeof(buf), "hmac-md5", _TRUNCATE);
2238 }
2239 UTIL_get_lang_msg("DLG_ABOUT_FROMSERVER", pvar, " from server");
2240 strncat_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2241 append_about_text(dlg, "HMAC:", buf);
2242
2243 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
2244 UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:");
2245 append_about_text(dlg, pvar->ts->UIMsg, buf);
2246 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
2247 UTIL_get_lang_msg("DLG_ABOUT_SERVERKEY", pvar, "Server keys:");
2248 append_about_text(dlg, pvar->ts->UIMsg, buf);
2249
2250 AUTH_get_auth_info(pvar, buf, sizeof(buf));
2251 UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication:");
2252 append_about_text(dlg, pvar->ts->UIMsg, buf);
2253
2254 SSH_get_compression_info(pvar, buf, sizeof(buf));
2255 if (pvar->ctos_compression == COMP_DELAYED) { // �x���p�P�b�g���k������ (2006.6.23 yutaka)
2256 UTIL_get_lang_msg("DLG_ABOUT_COMPDELAY", pvar, "Delayed Compression:");
2257 append_about_text(dlg, pvar->ts->UIMsg, buf);
2258 } else {
2259 UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression:");
2260 append_about_text(dlg, pvar->ts->UIMsg, buf);
2261 }
2262 }
2263 }
2264 }
2265
2266 static BOOL CALLBACK TTXAboutDlg(HWND dlg, UINT msg, WPARAM wParam,
2267 LPARAM lParam)
2268 {
2269 LOGFONT logfont;
2270 HFONT font;
2271
2272 switch (msg) {
2273 case WM_INITDIALOG:
2274 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2275 GetObject(font, sizeof(LOGFONT), &logfont);
2276 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgAboutFont, pvar)) {
2277 SendDlgItemMessage(dlg, IDC_TTSSH_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2278 SendDlgItemMessage(dlg, IDC_SSHVERSIONS, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2279 SendDlgItemMessage(dlg, IDC_INCLUDES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2280 SendDlgItemMessage(dlg, IDC_OPENSSL_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2281 SendDlgItemMessage(dlg, IDC_ZLIB_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2282 SendDlgItemMessage(dlg, IDC_WEBSITES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2283 SendDlgItemMessage(dlg, IDC_CRYPTOGRAPHY, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2284 SendDlgItemMessage(dlg, IDC_CREDIT, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2285 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2286 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2287 }
2288 else {
2289 DlgAboutFont = NULL;
2290 }
2291
2292 // �A�C�R�������I���Z�b�g
2293 {
2294 int fuLoad = LR_DEFAULTCOLOR;
2295 HICON hicon;
2296
2297 if (is_NT4()) {
2298 fuLoad = LR_VGACOLOR;
2299 }
2300
2301 hicon = LoadImage(hInst, MAKEINTRESOURCE(IDI_SECURETT),
2302 IMAGE_ICON, 32, 32, fuLoad);
2303 SendDlgItemMessage(dlg, IDC_TTSSH_ICON, STM_SETICON, (WPARAM)hicon, 0);
2304 }
2305
2306 init_about_dlg((PTInstVar) lParam, dlg);
2307 return TRUE;
2308 case WM_COMMAND:
2309 switch (LOWORD(wParam)) {
2310 case IDOK:
2311 EndDialog(dlg, 1);
2312 if (DlgAboutFont != NULL) {
2313 DeleteObject(DlgAboutFont);
2314 }
2315 return TRUE;
2316 case IDCANCEL: /* there isn't a cancel button, but other Windows
2317 UI things can send this message */
2318 EndDialog(dlg, 0);
2319 if (DlgAboutFont != NULL) {
2320 DeleteObject(DlgAboutFont);
2321 }
2322 return TRUE;
2323 }
2324 break;
2325 }
2326
2327 return FALSE;
2328 }
2329
2330 static char FAR *get_cipher_name(int cipher)
2331 {
2332 switch (cipher) {
2333 case SSH_CIPHER_NONE:
2334 UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_BORDER", pvar,
2335 "<ciphers below this line are disabled>");
2336 return pvar->ts->UIMsg;
2337 case SSH_CIPHER_RC4:
2338 return "RC4(SSH1)";
2339 case SSH_CIPHER_3DES:
2340 return "3DES(SSH1)";
2341 case SSH_CIPHER_DES:
2342 return "DES(SSH1)";
2343 case SSH_CIPHER_IDEA:
2344 return "IDEA(SSH1)";
2345 case SSH_CIPHER_TSS:
2346 return "TSS(SSH1)";
2347 case SSH_CIPHER_BLOWFISH:
2348 return "Blowfish(SSH1)";
2349
2350 // for SSH2(yutaka)
2351 case SSH2_CIPHER_AES128_CBC:
2352 return "AES128-CBC(SSH2)";
2353 case SSH2_CIPHER_AES192_CBC:
2354 return "AES192-CBC(SSH2)";
2355 case SSH2_CIPHER_AES256_CBC:
2356 return "AES256-CBC(SSH2)";
2357 case SSH2_CIPHER_3DES_CBC:
2358 return "3DES-CBC(SSH2)";
2359 case SSH2_CIPHER_BLOWFISH_CBC:
2360 return "Blowfish-CBC(SSH2)";
2361 case SSH2_CIPHER_AES128_CTR:
2362 return "AES128-CTR(SSH2)";
2363 case SSH2_CIPHER_AES192_CTR:
2364 return "AES192-CTR(SSH2)";
2365 case SSH2_CIPHER_AES256_CTR:
2366 return "AES256-CTR(SSH2)";
2367 case SSH2_CIPHER_ARCFOUR:
2368 return "Arcfour(SSH2)";
2369 case SSH2_CIPHER_ARCFOUR128:
2370 return "Arcfour128(SSH2)";
2371 case SSH2_CIPHER_ARCFOUR256:
2372 return "Arcfour256(SSH2)";
2373 case SSH2_CIPHER_CAST128_CBC:
2374 return "CAST128-CBC(SSH2)";
2375 case SSH2_CIPHER_3DES_CTR:
2376 return "3DES-CTR(SSH2)";
2377 case SSH2_CIPHER_BLOWFISH_CTR:
2378 return "Blowfish-CTR(SSH2)";
2379 case SSH2_CIPHER_CAST128_CTR:
2380 return "CAST128-CTR(SSH2)";
2381
2382 default:
2383 return NULL;
2384 }
2385 }
2386
2387 static void set_move_button_status(HWND dlg)
2388 {
2389 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
2390 int curPos = (int) SendMessage(cipherControl, LB_GETCURSEL, 0, 0);
2391 int maxPos = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0) - 1;
2392
2393 EnableWindow(GetDlgItem(dlg, IDC_SSHMOVECIPHERUP),
2394 curPos > 0 && curPos <= maxPos);
2395 EnableWindow(GetDlgItem(dlg, IDC_SSHMOVECIPHERDOWN),
2396 curPos >= 0 && curPos < maxPos);
2397 }
2398
2399 static void init_setup_dlg(PTInstVar pvar, HWND dlg)
2400 {
2401 HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
2402 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
2403 int i;
2404 int ch;
2405 char uimsg[MAX_UIMSG];
2406
2407 GetWindowText(dlg, uimsg, sizeof(uimsg));
2408 UTIL_get_lang_msg("DLG_SSHSETUP_TITLE", pvar, uimsg);
2409 SetWindowText(dlg, pvar->ts->UIMsg);
2410 GetDlgItemText(dlg, IDC_COMPRESSLABEL, uimsg, sizeof(uimsg));
2411 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS", pvar, uimsg);
2412 SetDlgItemText(dlg, IDC_COMPRESSLABEL, pvar->ts->UIMsg);
2413 GetDlgItemText(dlg, IDC_COMPRESSNONE, uimsg, sizeof(uimsg));
2414 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_NONE", pvar, uimsg);
2415 SetDlgItemText(dlg, IDC_COMPRESSNONE, pvar->ts->UIMsg);
2416 GetDlgItemText(dlg, IDC_COMPRESSHIGH, uimsg, sizeof(uimsg));
2417 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_HIGHEST", pvar, uimsg);
2418 SetDlgItemText(dlg, IDC_COMPRESSHIGH, pvar->ts->UIMsg);
2419 GetDlgItemText(dlg, IDC_CIPHERORDER, uimsg, sizeof(uimsg));
2420 UTIL_get_lang_msg("DLG_SSHSETUP_CHIPER", pvar, uimsg);
2421 SetDlgItemText(dlg, IDC_CIPHERORDER, pvar->ts->UIMsg);
2422 GetDlgItemText(dlg, IDC_SSHMOVECIPHERUP, uimsg, sizeof(uimsg));
2423 UTIL_get_lang_msg("DLG_SSHSETUP_CHIPER_UP", pvar, uimsg);
2424 SetDlgItemText(dlg, IDC_SSHMOVECIPHERUP, pvar->ts->UIMsg);
2425 GetDlgItemText(dlg, IDC_SSHMOVECIPHERDOWN, uimsg, sizeof(uimsg));
2426 UTIL_get_lang_msg("DLG_SSHSETUP_CHIPER_DOWN", pvar, uimsg);
2427 SetDlgItemText(dlg, IDC_SSHMOVECIPHERDOWN, pvar->ts->UIMsg);
2428 GetDlgItemText(dlg, IDC_KNOWNHOSTS, uimsg, sizeof(uimsg));
2429 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST", pvar, uimsg);
2430 SetDlgItemText(dlg, IDC_KNOWNHOSTS, pvar->ts->UIMsg);
2431 GetDlgItemText(dlg, IDC_CHOOSEREADWRITEFILE, uimsg, sizeof(uimsg));
2432 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST_RW", pvar, uimsg);
2433 SetDlgItemText(dlg, IDC_CHOOSEREADWRITEFILE, pvar->ts->UIMsg);
2434 GetDlgItemText(dlg, IDC_CHOOSEREADONLYFILE, uimsg, sizeof(uimsg));
2435 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST_RO", pvar, uimsg);
2436 SetDlgItemText(dlg, IDC_CHOOSEREADONLYFILE, pvar->ts->UIMsg);
2437 GetDlgItemText(dlg, IDC_HEARTBEATLABEL, uimsg, sizeof(uimsg));
2438 UTIL_get_lang_msg("DLG_SSHSETUP_HEARTBEAT", pvar, uimsg);
2439 SetDlgItemText(dlg, IDC_HEARTBEATLABEL, pvar->ts->UIMsg);
2440 GetDlgItemText(dlg, IDC_HEARTBEATLABEL2, uimsg, sizeof(uimsg));
2441 UTIL_get_lang_msg("DLG_SSHSETUP_HEARTBEAT_UNIT", pvar, uimsg);
2442 SetDlgItemText(dlg, IDC_HEARTBEATLABEL2, pvar->ts->UIMsg);
2443 GetDlgItemText(dlg, IDC_REMEMBERPASSWORD, uimsg, sizeof(uimsg));
2444 UTIL_get_lang_msg("DLG_SSHSETUP_PASSWORD", pvar, uimsg);
2445 SetDlgItemText(dlg, IDC_REMEMBERPASSWORD, pvar->ts->UIMsg);
2446 GetDlgItemText(dlg, IDC_FORWARDAGENT, uimsg, sizeof(uimsg));
2447 UTIL_get_lang_msg("DLG_SSHSETUP_FORWARDAGENT", pvar, uimsg);
2448 SetDlgItemText(dlg, IDC_FORWARDAGENT, pvar->ts->UIMsg);
2449 GetDlgItemText(dlg, IDC_NOTICEBANNER, uimsg, sizeof(uimsg));
2450 UTIL_get_lang_msg("DLG_SSHSETUP_NOTICE", pvar, uimsg);
2451 SetDlgItemText(dlg, IDC_NOTICEBANNER, pvar->ts->UIMsg);
2452 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2453 UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
2454 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2455 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2456 UTIL_get_lang_msg("BTN_CANCEL", pvar, uimsg);
2457 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2458
2459 SendMessage(compressionControl, TBM_SETRANGE, TRUE, MAKELONG(0, 9));
2460 SendMessage(compressionControl, TBM_SETPOS, TRUE,
2461 pvar->settings.CompressionLevel);
2462
2463 normalize_cipher_order(pvar->settings.CipherOrder);
2464
2465 for (i = 0; pvar->settings.CipherOrder[i] != 0; i++) {
2466 int cipher = pvar->settings.CipherOrder[i] - '0';
2467 char FAR *name = get_cipher_name(cipher);
2468
2469 if (name != NULL) {
2470 SendMessage(cipherControl, LB_ADDSTRING, 0, (LPARAM) name);
2471 }
2472 }
2473
2474 SendMessage(cipherControl, LB_SETCURSEL, 0, 0);
2475 set_move_button_status(dlg);
2476
2477 for (i = 0; (ch = pvar->settings.KnownHostsFiles[i]) != 0 && ch != ';';
2478 i++) {
2479 }
2480 if (ch != 0) {
2481 pvar->settings.KnownHostsFiles[i] = 0;
2482 SetDlgItemText(dlg, IDC_READWRITEFILENAME,
2483 pvar->settings.KnownHostsFiles);
2484 pvar->settings.KnownHostsFiles[i] = ch;
2485 SetDlgItemText(dlg, IDC_READONLYFILENAME,
2486 pvar->settings.KnownHostsFiles + i + 1);
2487 } else {
2488 SetDlgItemText(dlg, IDC_READWRITEFILENAME,
2489 pvar->settings.KnownHostsFiles);
2490 }
2491
2492 // SSH2 HeartBeat(keep-alive)������ (2005.2.22 yutaka)
2493 {
2494 char buf[10];
2495 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2496 "%d", pvar->settings.ssh_heartbeat_overtime);
2497 SetDlgItemText(dlg, IDC_HEARTBEAT_EDIT, buf);
2498 }
2499
2500 if (pvar->settings.remember_password) {
2501 CheckDlgButton(dlg, IDC_REMEMBERPASSWORD, TRUE);
2502 }
2503 if (pvar->settings.ForwardAgent) {
2504 CheckDlgButton(dlg, IDC_FORWARDAGENT, TRUE);
2505 }
2506 }
2507
2508 void get_teraterm_dir_relative_name(char FAR * buf, int bufsize,
2509 char FAR * basename)
2510 {
2511 int filename_start = 0;
2512 int i;
2513 int ch;
2514
2515 if (basename[0] == '\\' || basename[0] == '/'
2516 || (basename[0] != 0 && basename[1] == ':')) {
2517 strncpy_s(buf, bufsize, basename, _TRUNCATE);
2518 return;
2519 }
2520
2521 GetModuleFileName(NULL, buf, bufsize);
2522 for (i = 0; (ch = buf[i]) != 0; i++) {
2523 if (ch == '\\' || ch == '/' || ch == ':') {
2524 filename_start = i + 1;
2525 }
2526 }
2527
2528 if (bufsize > filename_start) {
2529 strncpy_s(buf + filename_start, bufsize - filename_start, basename, _TRUNCATE);
2530 }
2531 }
2532
2533 int copy_teraterm_dir_relative_path(char FAR * dest, int destsize,
2534 char FAR * basename)
2535 {
2536 char buf[1024];
2537 int filename_start = 0;
2538 int i;
2539 int ch, ch2;
2540
2541 if (basename[0] != '\\' && basename[0] != '/'
2542 && (basename[0] == 0 || basename[1] != ':')) {
2543 strncpy_s(dest, destsize, basename, _TRUNCATE);
2544 return strlen(dest);
2545 }
2546
2547 GetModuleFileName(NULL, buf, sizeof(buf));
2548 for (i = 0; (ch = buf[i]) != 0; i++) {
2549 if (ch == '\\' || ch == '/' || ch == ':') {
2550 filename_start = i + 1;
2551 }
2552 }
2553
2554 for (i = 0; i < filename_start; i++) {
2555 ch = toupper(buf[i]);
2556 ch2 = toupper(basename[i]);
2557
2558 if (ch == ch2 ||
2559 ((ch == '\\' || ch == '/') && (ch2 == '\\' || ch2 == '/'))) {
2560 } else {
2561 break;
2562 }
2563 }
2564
2565 if (i == filename_start) {
2566 strncpy_s(dest, destsize, basename + i, _TRUNCATE);
2567 } else {
2568 strncpy_s(dest, destsize, basename, _TRUNCATE);
2569 }
2570 return strlen(dest);
2571 }
2572
2573 static void complete_setup_dlg(PTInstVar pvar, HWND dlg)
2574 {
2575 char buf[4096];
2576 char buf2[1024];
2577 HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
2578 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
2579 int i, j, buf2index, bufindex;
2580 int count = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0);
2581
2582 pvar->settings.CompressionLevel =
2583 (int) SendMessage(compressionControl, TBM_GETPOS, 0, 0);
2584
2585 buf2index = 0;
2586 for (i = 0; i < count; i++) {
2587 int len = SendMessage(cipherControl, LB_GETTEXTLEN, i, 0);
2588
2589 if (len > 0 && len < sizeof(buf)) { /* should always be true */
2590 buf[0] = 0;
2591 SendMessage(cipherControl, LB_GETTEXT, i, (LPARAM) buf);
2592 for (j = 0;
2593 j <= SSH_CIPHER_MAX
2594 && strcmp(buf, get_cipher_name(j)) != 0; j++) {
2595 }
2596 if (j <= SSH_CIPHER_MAX) {
2597 buf2[buf2index] = '0' + j;
2598 buf2index++;
2599 }
2600 }
2601 }
2602 buf2[buf2index] = 0;
2603 normalize_cipher_order(buf2);
2604 strncpy_s(pvar->settings.CipherOrder, sizeof(pvar->settings.CipherOrder), buf2, _TRUNCATE);
2605
2606 buf[0] = 0;
2607 GetDlgItemText(dlg, IDC_READWRITEFILENAME, buf, sizeof(buf));
2608 j = copy_teraterm_dir_relative_path(pvar->settings.KnownHostsFiles,
2609 sizeof(pvar->settings.KnownHostsFiles),
2610 buf);
2611 buf[0] = 0;
2612 bufindex = 0;
2613 GetDlgItemText(dlg, IDC_READONLYFILENAME, buf, sizeof(buf));
2614 for (i = 0; buf[i] != 0; i++) {
2615 if (buf[i] == ';') {
2616 buf[i] = 0;
2617 if (j < sizeof(pvar->settings.KnownHostsFiles) - 1) {
2618 pvar->settings.KnownHostsFiles[j] = ';';
2619 j++;
2620 j += copy_teraterm_dir_relative_path(pvar->settings.
2621 KnownHostsFiles + j,
2622 sizeof(pvar->settings.
2623 KnownHostsFiles)
2624 - j, buf + bufindex);
2625 }
2626 bufindex = i + 1;
2627 }
2628 }
2629 if (bufindex < i && j < sizeof(pvar->settings.KnownHostsFiles) - 1) {
2630 pvar->settings.KnownHostsFiles[j] = ';';
2631 j++;
2632 copy_teraterm_dir_relative_path(pvar->settings.KnownHostsFiles + j,
2633 sizeof(pvar->settings. KnownHostsFiles) - j,
2634 buf + bufindex);
2635 }
2636
2637 // get SSH HeartBeat(keep-alive)
2638 SendMessage(GetDlgItem(dlg, IDC_HEARTBEAT_EDIT), WM_GETTEXT, sizeof(buf), (LPARAM)buf);
2639 i = atoi(buf);
2640 if (i < 0)
2641 i = 60;
2642 pvar->settings.ssh_heartbeat_overtime = i;
2643
2644 pvar->settings.remember_password = IsDlgButtonChecked(dlg, IDC_REMEMBERPASSWORD);
2645 pvar->settings.ForwardAgent = IsDlgButtonChecked(dlg, IDC_FORWARDAGENT);
2646 }
2647
2648 static void move_cur_sel_delta(HWND listbox, int delta)
2649 {
2650 int curPos = (int) SendMessage(listbox, LB_GETCURSEL, 0, 0);
2651 int maxPos = (int) SendMessage(listbox, LB_GETCOUNT, 0, 0) - 1;
2652 int newPos = curPos + delta;
2653 char buf[1024];
2654
2655 if (curPos >= 0 && newPos >= 0 && newPos <= maxPos) {
2656 int len = SendMessage(listbox, LB_GETTEXTLEN, curPos, 0);
2657
2658 if (len > 0 && len < sizeof(buf)) { /* should always be true */
2659 buf[0] = 0;
2660 SendMessage(listbox, LB_GETTEXT, curPos, (LPARAM) buf);
2661 SendMessage(listbox, LB_DELETESTRING, curPos, 0);
2662 SendMessage(listbox, LB_INSERTSTRING, newPos,
2663 (LPARAM) (char FAR *) buf);
2664 SendMessage(listbox, LB_SETCURSEL, newPos, 0);
2665 }
2666 }
2667 }
2668
2669 static int get_keys_file_name(HWND parent, char FAR * buf, int bufsize,
2670 int readonly)
2671 {
2672 OPENFILENAME params;
2673 char fullname_buf[2048] = "ssh_known_hosts";
2674
2675 params.lStructSize = sizeof(OPENFILENAME);
2676 params.hwndOwner = parent;
2677 params.lpstrFilter = NULL;
2678 params.lpstrCustomFilter = NULL;
2679 params.nFilterIndex = 0;
2680 buf[0] = 0;
2681 params.lpstrFile = fullname_buf;
2682 params.nMaxFile = sizeof(fullname_buf);
2683 params.lpstrFileTitle = NULL;
2684 params.lpstrInitialDir = NULL;
2685 if (readonly) {
2686 UTIL_get_lang_msg("MSG_OPEN_KNOWNHOSTS_RO_TITLE", pvar,
2687 "Choose a read-only known-hosts file to add");
2688 }
2689 else {
2690 UTIL_get_lang_msg("MSG_OPEN_KNOWNHOSTS_RW_TITLE", pvar,
2691 "Choose a read/write known-hosts file");
2692 }
2693 params.lpstrTitle = pvar->ts->UIMsg;
2694 params.Flags = (readonly ? OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST : 0)
2695 | OFN_HIDEREADONLY | (!readonly ? OFN_NOREADONLYRETURN : 0);
2696 params.lpstrDefExt = NULL;
2697
2698 if (GetOpenFileName(&params) != 0) {
2699 copy_teraterm_dir_relative_path(buf, bufsize, fullname_buf);
2700 return 1;
2701 } else {
2702 int err = CommDlgExtendedError();
2703
2704 if (err != 0) {
2705 char buf[1024];
2706 UTIL_get_lang_msg("MSG_OPEN_FILEDLG_KNOWNHOSTS_ERROR", pvar,
2707 "Unable to display file dialog box: error %d");
2708 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, err);
2709 MessageBox(parent, buf, "TTSSH Error",
2710 MB_OK | MB_ICONEXCLAMATION);
2711 }
2712
2713 return 0;
2714 }
2715 }
2716
2717 static void choose_read_write_file(HWND dlg)
2718 {
2719 char buf[1024];
2720
2721 if (get_keys_file_name(dlg, buf, sizeof(buf), 0)) {
2722 SetDlgItemText(dlg, IDC_READWRITEFILENAME, buf);
2723 }
2724 }
2725
2726 static void choose_read_only_file(HWND dlg)
2727 {
2728 char buf[1024];
2729 char buf2[4096];
2730
2731 if (get_keys_file_name(dlg, buf, sizeof(buf), 1)) {
2732 buf2[0] = 0;
2733 GetDlgItemText(dlg, IDC_READONLYFILENAME, buf2, sizeof(buf2));
2734 if (buf2[0] != 0 && buf2[strlen(buf2) - 1] != ';') {
2735 strncat_s(buf2, sizeof(buf2), ";", _TRUNCATE);
2736 }
2737 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2738 SetDlgItemText(dlg, IDC_READONLYFILENAME, buf2);
2739 }
2740 }
2741
2742 static BOOL CALLBACK TTXSetupDlg(HWND dlg, UINT msg, WPARAM wParam,
2743 LPARAM lParam)
2744 {
2745 LOGFONT logfont;
2746 HFONT font;
2747
2748 switch (msg) {
2749 case WM_INITDIALOG:
2750 SetWindowLong(dlg, DWL_USER, lParam);
2751 init_setup_dlg((PTInstVar) lParam, dlg);
2752
2753 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2754 GetObject(font, sizeof(LOGFONT), &logfont);
2755 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgSetupFont, pvar)) {
2756 SendDlgItemMessage(dlg, IDC_COMPRESSLABEL, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2757 SendDlgItemMessage(dlg, IDC_CIPHERORDER, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2758 SendDlgItemMessage(dlg, IDC_SSHCIPHERPREFS, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2759 SendDlgItemMessage(dlg, IDC_SSHMOVECIPHERUP, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2760 SendDlgItemMessage(dlg, IDC_SSHMOVECIPHERDOWN, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2761 SendDlgItemMessage(dlg, IDC_CHOOSEREADWRITEFILE, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2762 SendDlgItemMessage(dlg, IDC_READWRITEFILENAME, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2763 SendDlgItemMessage(dlg, IDC_CHOOSEREADONLYFILE, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2764 SendDlgItemMessage(dlg, IDC_READONLYFILENAME, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2765 SendDlgItemMessage(dlg, IDC_COMPRESSNONE, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2766 SendDlgItemMessage(dlg, IDC_COMPRESSHIGH, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2767 SendDlgItemMessage(dlg, IDC_NOTICEBANNER, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2768 SendDlgItemMessage(dlg, IDC_KNOWNHOSTS, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2769 SendDlgItemMessage(dlg, IDC_HEARTBEATLABEL, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2770 SendDlgItemMessage(dlg, IDC_HEARTBEAT_EDIT, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2771 SendDlgItemMessage(dlg, IDC_HEARTBEATLABEL2, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2772 SendDlgItemMessage(dlg, IDC_REMEMBERPASSWORD, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2773 SendDlgItemMessage(dlg, IDC_FORWARDAGENT, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2774 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2775 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2776 }
2777 else {
2778 DlgSetupFont = NULL;
2779 }
2780
2781 return TRUE;
2782 case WM_COMMAND:
2783 switch (LOWORD(wParam)) {
2784 case IDOK:
2785 complete_setup_dlg((PTInstVar) GetWindowLong(dlg, DWL_USER), dlg);
2786 EndDialog(dlg, 1);
2787 if (DlgSetupFont != NULL) {
2788 DeleteObject(DlgSetupFont);
2789 }
2790 return TRUE;
2791 case IDCANCEL: /* there isn't a cancel button, but other Windows
2792 UI things can send this message */
2793 EndDialog(dlg, 0);
2794 if (DlgSetupFont != NULL) {
2795 DeleteObject(DlgSetupFont);
2796 }
2797 return TRUE;
2798 case IDC_SSHMOVECIPHERUP:
2799 move_cur_sel_delta(GetDlgItem(dlg, IDC_SSHCIPHERPREFS), -1);
2800 set_move_button_status(dlg);
2801 SetFocus(GetDlgItem(dlg, IDC_SSHCIPHERPREFS));
2802 return TRUE;
2803 case IDC_SSHMOVECIPHERDOWN:
2804 move_cur_sel_delta(GetDlgItem(dlg, IDC_SSHCIPHERPREFS), 1);
2805 set_move_button_status(dlg);
2806 SetFocus(GetDlgItem(dlg, IDC_SSHCIPHERPREFS));
2807 return TRUE;
2808 case IDC_SSHCIPHERPREFS:
2809 set_move_button_status(dlg);
2810 return TRUE;
2811 case IDC_CHOOSEREADWRITEFILE:
2812 choose_read_write_file(dlg);
2813 return TRUE;
2814 case IDC_CHOOSEREADONLYFILE:
2815 choose_read_only_file(dlg);
2816 return TRUE;
2817 }
2818 break;
2819 }
2820
2821 return FALSE;
2822