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 9211 - (show annotations) (download) (as text)
Sat Apr 17 09:52:01 2021 UTC (2 years, 11 months ago) by nmaya
File MIME type: text/x-csrc
File size: 160768 byte(s)
cipher_init_SSH2() に渡すのを EVP_CIPHER_CTX から sshcipher_ctx に変更

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