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 7706 - (show annotations) (download) (as text)
Tue May 21 15:20:52 2019 UTC (4 years, 10 months ago) by zmatsuo
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 174100 byte(s)
ダイアログフォントの設定をメモリに持つようにした

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