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 3495 - (show annotations) (download) (as text)
Mon Jun 15 18:43:59 2009 UTC (14 years, 9 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 137912 byte(s)
ssh接続の時はLine at a timeモードを無効にするようにした。

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