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