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 3212 - (show annotations) (download) (as text)
Wed Feb 18 14:44:08 2009 UTC (15 years, 1 month ago) by maya
Original Path: ttssh2/trunk/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 128710 byte(s)
DoCover_IsDebuggerPresent() を WinMain, DllMain から呼ぶようにした。

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