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 3179 - (show annotations) (download) (as text)
Tue Dec 2 15:49:12 2008 UTC (15 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 121469 byte(s)
/ssh-a オプションを追加

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