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