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