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 3631 - (show annotations) (download) (as text)
Sat Oct 3 15:52:58 2009 UTC (14 years, 6 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 138397 byte(s)
隠しオプション"/nosecuritywarning"を追加した。
known_hosts のチェックダイアログを出現させない。

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