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