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 3579 - (show annotations) (download) (as text)
Mon Jul 6 02:56:52 2009 UTC (14 years, 9 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 138141 byte(s)
ssh接続後の接続で、TCPLocalEcho,TCPCRSendの設定が使われないのを修正した。
https://sourceforge.jp/ticket/browse.php?group_id=1412&tid=17592

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