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 8087 - (show annotations) (download) (as text)
Sun Sep 8 02:29:51 2019 UTC (4 years, 7 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 175254 byte(s)
non-fatalおよびfatalメッセージボックスの表示に同一メッセージが複数含まれることがある問題を修正した。

branches/ttssh_improvedからリビジョン8053をマージ:
・non-fatalおよびfatal時のエラーメッセージを登録する際、同一メッセージがすでに
登録されていた場合は追加しないようにした。ユーザに同じメッセージを何回見せても
意味がない(むしろ心証がよくない)。
・メモリ確保できない場合の処理を追加した。

........

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