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