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 9210 - (show annotations) (download) (as text)
Sat Apr 17 08:36:59 2021 UTC (2 years, 11 months ago) by nmaya
File MIME type: text/x-csrc
File size: 160775 byte(s)
ファイルを分割・コードを移動・関数名を整理・新しい OpenSSH からインポート

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