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