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