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