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 3176 - (show annotations) (download) (as text)
Sun Nov 30 16:14:41 2008 UTC (15 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 119802 byte(s)
SSH agent forwarding をサポートした。
  SSH1 の channel 内部処理が port forward しか想定していなかったため、
  local_channel_num に固定値を強引に割り当てている。

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 (MATCH_STR(option + 4, "-A") == 0) {
1481 pvar->settings.ForwardAgent = TRUE;
1482
1483 } else if (_stricmp(option + 4, "-acceptall") == 0) {
1484 pvar->settings.LocalForwardingIdentityCheck = FALSE;
1485
1486 } else if (MATCH_STR(option + 4, "-consume=") == 0) {
1487 read_ssh_options_from_user_file(pvar, option + 13);
1488 DeleteFile(option + 13);
1489
1490 // /ssh1 �� /ssh2 �I�v�V�������V�K���� (2006.9.16 maya)
1491 } else if (MATCH_STR(option + 4, "1") == 0) {
1492 pvar->settings.Enabled = 1;
1493 pvar->settings.ssh_protocol_version = 1;
1494 } else if (MATCH_STR(option + 4, "2") == 0) {
1495 pvar->settings.Enabled = 1;
1496 pvar->settings.ssh_protocol_version = 2;
1497
1498 } else {
1499 char buf[1024];
1500
1501 UTIL_get_lang_msg("MSG_UNKNOWN_OPTION_ERROR", pvar,
1502 "Unrecognized command-line option: %s");
1503 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, option);
1504
1505 MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
1506 }
1507
1508 return 1;
1509
1510 // ttermpro.exe �� /T= �w�������p�������A������������ (2006.10.19 maya)
1511 } else if (MATCH_STR_I(option + 1, "t=") == 0) {
1512 if (strcmp(option + 3, "2") == 0) {
1513 pvar->settings.Enabled = 1;
1514 return 1;
1515 } else {
1516 pvar->settings.Enabled = 0;
1517 }
1518
1519 // ttermpro.exe �� /F= �w������ TTSSH ������������ (2006.10.11 maya)
1520 } else if (MATCH_STR_I(option + 1, "f=") == 0) {
1521 read_ssh_options_from_user_file(pvar, option + 3);
1522
1523 // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
1524 } else if (MATCH_STR(option + 1, "1") == 0) {
1525 // command line: /ssh /1 is SSH1 only
1526 pvar->settings.ssh_protocol_version = 1;
1527
1528 } else if (MATCH_STR(option + 1, "2") == 0) {
1529 // command line: /ssh /2 is SSH2 & SSH1
1530 pvar->settings.ssh_protocol_version = 2;
1531
1532 } else if (MATCH_STR(option + 1, "nossh") == 0) {
1533 // '/nossh' �I�v�V�����������B
1534 // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
1535 // �����������������B(2004.10.11 yutaka)
1536 pvar->settings.Enabled = 0;
1537
1538 } else if (MATCH_STR(option + 1, "telnet") == 0) {
1539 // '/telnet' ���w�������������������� '/nossh' ��������
1540 // SSH������������ (2006.9.16 maya)
1541 pvar->settings.Enabled = 0;
1542
1543 } else if (MATCH_STR(option + 1, "auth") == 0) {
1544 // SSH2�������O�C���I�v�V����������
1545 //
1546 // SYNOPSIS: /ssh /auth=passowrd /user=���[�U�� /passwd=�p�X���[�h
1547 // /ssh /auth=publickey /user=���[�U�� /passwd=�p�X���[�h /keyfile=�p�X
1548 // EXAMPLE: /ssh /auth=password /user=nike /passwd=a@bc
1549 // /ssh /auth=publickey /user=foo /passwd=bar /keyfile=d:\tmp\id_rsa
1550 // NOTICE: �p�X���[�h���p�X�������������������A�u�����N���������� @ ���g�������B
1551 //
1552 // (2004.11.30 yutaka)
1553 // (2005.1.26 yutaka) ���������B���J���F���T�|�[�g�B
1554 //
1555 pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
1556
1557 if (MATCH_STR(option + 5, "=password") == 0) { // �p�X���[�h
1558 //pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
1559 pvar->ssh2_authmethod = SSH_AUTH_PASSWORD;
1560
1561 // /auth=challenge ������ (2007.10.5 maya)
1562 } else if (MATCH_STR(option + 5, "=challenge") == 0) { // keyboard-interactive�F��
1563 //pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
1564 pvar->ssh2_authmethod = SSH_AUTH_TIS;
1565
1566 } else if (MATCH_STR(option + 5, "=publickey") == 0) { // ���J���F��
1567 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1568 pvar->ssh2_authmethod = SSH_AUTH_RSA;
1569
1570 } else if (MATCH_STR(option + 5, "=pageant") == 0) { // ���J���F�� by Pageant
1571 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1572 pvar->ssh2_authmethod = SSH_AUTH_PAGEANT;
1573
1574 } else {
1575 // TODO:
1576
1577 }
1578
1579 } else if (MATCH_STR(option + 1, "user=") == 0) {
1580 replace_to_blank(option + 6, pvar->ssh2_username, sizeof(pvar->ssh2_username));
1581 //_snprintf(pvar->ssh2_username, sizeof(pvar->ssh2_username), "%s", option + 6);
1582
1583 } else if (MATCH_STR(option + 1, "passwd=") == 0) {
1584 replace_to_blank(option + 8, pvar->ssh2_password, sizeof(pvar->ssh2_password));
1585 //_snprintf(pvar->ssh2_password, sizeof(pvar->ssh2_password), "%s", option + 8);
1586
1587 } else if (MATCH_STR(option + 1, "keyfile=") == 0) {
1588 replace_to_blank(option + 9, pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile));
1589
1590 } else if (MATCH_STR(option + 1, "ask4passwd") == 0) {
1591 // �p�X���[�h������ (2006.9.18 maya)
1592 pvar->ask4passwd = 1;
1593
1594 }
1595
1596 // �p�X���[�h�������������������O�C��������������
1597 // /auth ���F�����\�b�h���w�������������p������ (2006.9.18 maya)
1598 if (pvar->ask4passwd == 1) {
1599 pvar->ssh2_autologin = 0;
1600 }
1601
1602 }
1603
1604 return 0;
1605 }
1606
1607 static void FAR PASCAL TTXParseParam(PCHAR param, PTTSet ts,
1608 PCHAR DDETopic)
1609 {
1610 // �X�y�[�X�������t�@�C�������F�������������C�� (2006.10.7 maya)
1611 int i;
1612 BOOL inParam = FALSE;
1613 BOOL inQuotes = FALSE;
1614 BOOL inFileParam = FALSE;
1615 PCHAR option = NULL;
1616
1617 if (pvar->hostdlg_activated) {
1618 pvar->settings.Enabled = pvar->hostdlg_Enabled;
1619 }
1620
1621 for (i = 0; param[i] != 0; i++) {
1622 if (inQuotes ? param[i] == '"'
1623 : (param[i] == ' ' || param[i] == '\t')) {
1624 if (option != NULL) {
1625 char ch = param[i];
1626 PCHAR Equal;
1627
1628 param[i] = 0;
1629 Equal = strchr(option, '=');
1630 if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
1631 int buf_len = strlen(option) * sizeof(char);
1632 char *buf = (char *)calloc(strlen(option), sizeof(char));
1633 char c = option[Equal - option + 1];
1634 option[Equal - option + 1] = 0;
1635 strncat_s(buf, buf_len, option, _TRUNCATE);
1636 option[Equal - option + 1] = c;
1637 strncat_s(buf, buf_len, Equal + 2, _TRUNCATE);
1638 if (parse_option(pvar, *buf == '"' ? buf + 1 : buf)) {
1639 memset(option, ' ', i + 1 - (option - param));
1640 } else {
1641 param[i] = ch;
1642 }
1643 free(buf);
1644 }
1645 else {
1646 if (parse_option(pvar, *option == '"' ? option + 1 : option)) {
1647 memset(option, ' ', i + 1 - (option - param));
1648 } else {
1649 param[i] = ch;
1650 }
1651 }
1652 option = NULL;
1653 }
1654 inParam = FALSE;
1655 inQuotes = FALSE;
1656 inFileParam = FALSE;
1657 } else if (!inParam) {
1658 if (param[i] == '"') {
1659 inQuotes = TRUE;
1660 inParam = TRUE;
1661 option = param + i;
1662 } else if (param[i] != ' ' && param[i] != '\t') {
1663 inParam = TRUE;
1664 option = param + i;
1665 }
1666 } else {
1667 if (option == NULL) {
1668 continue;
1669 }
1670 if ((option[0] == '-' || option[0] == '/') &&
1671 (MATCH_STR(option + 1, "ssh-f=") == 0 ||
1672 MATCH_STR(option + 1, "ssh-consume=") == 0 ||
1673 MATCH_STR_I(option + 1, "f=") == 0 ||
1674 MATCH_STR(option + 1, "keyfile=") == 0)) {
1675 if (param[i] == '"') {
1676 inQuotes = TRUE;
1677 }
1678 inFileParam = TRUE;
1679 }
1680 }
1681 }
1682
1683 if (option != NULL) {
1684 PCHAR Equal = strchr(option, '=');
1685 if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
1686 int buf_len = strlen(option) * sizeof(char);
1687 char *buf = (char *)calloc(strlen(option), sizeof(char));
1688 char c = option[Equal - option + 1];
1689 option[Equal - option + 1] = 0;
1690 strncat_s(buf, buf_len, option, _TRUNCATE);
1691 option[Equal - option + 1] = c;
1692 strncat_s(buf, buf_len, Equal + 2, _TRUNCATE);
1693 if (parse_option(pvar, *buf == '"' ? buf + 1 : buf)) {
1694 memset(option, ' ', i + 1 - (option - param));
1695 }
1696 free(buf);
1697 }
1698 else {
1699 if (parse_option(pvar, option)) {
1700 memset(option, ' ', i - (option - param));
1701 }
1702 }
1703 }
1704
1705 FWDUI_load_settings(pvar);
1706
1707 (pvar->ParseParam) (param, ts, DDETopic);
1708
1709 }
1710
1711 static void PASCAL FAR TTXGetSetupHooks(TTXSetupHooks FAR * hooks)
1712 {
1713 pvar->ReadIniFile = *hooks->ReadIniFile;
1714 pvar->WriteIniFile = *hooks->WriteIniFile;
1715 pvar->ParseParam = *hooks->ParseParam;
1716
1717 *hooks->ReadIniFile = TTXReadINIFile;
1718 *hooks->WriteIniFile = TTXWriteINIFile;
1719 *hooks->ParseParam = TTXParseParam;
1720 }
1721
1722 static void PASCAL FAR TTXSetWinSize(int rows, int cols)
1723 {
1724 SSH_notify_win_size(pvar, cols, rows);
1725 }
1726
1727 static void insertMenuBeforeItem(HMENU menu, WORD beforeItemID, WORD flags,
1728 WORD newItemID, char FAR * text)
1729 {
1730 int i, j;
1731
1732 for (i = GetMenuItemCount(menu) - 1; i >= 0; i--) {
1733 HMENU submenu = GetSubMenu(menu, i);
1734
1735 for (j = GetMenuItemCount(submenu) - 1; j >= 0; j--) {
1736 if (GetMenuItemID(submenu, j) == beforeItemID) {
1737 InsertMenu(submenu, j, MF_BYPOSITION | flags, newItemID, text);
1738 return;
1739 }
1740 }
1741 }
1742 }
1743
1744 static void PASCAL FAR TTXModifyMenu(HMENU menu)
1745 {
1746 /* inserts before ID_HELP_ABOUT */
1747 UTIL_get_lang_msg("MENU_ABOUT", pvar, "About &TTSSH...");
1748 insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU, pvar->ts->UIMsg);
1749
1750 /* inserts before ID_SETUP_TCPIP */
1751 UTIL_get_lang_msg("MENU_SSH", pvar, "SS&H...");
1752 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU, pvar->ts->UIMsg);
1753 /* inserts before ID_SETUP_TCPIP */
1754 UTIL_get_lang_msg("MENU_SSH_AUTH", pvar, "SSH &Authentication...");
1755 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU, pvar->ts->UIMsg);
1756 /* inserts before ID_SETUP_TCPIP */
1757 UTIL_get_lang_msg("MENU_SSH_FORWARD", pvar, "SSH F&orwarding...");
1758 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU, pvar->ts->UIMsg);
1759 UTIL_get_lang_msg("MENU_SSH_KEYGEN", pvar, "SSH KeyGe&nerator...");
1760 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHKEYGENMENU, pvar->ts->UIMsg);
1761
1762 /* inserts before ID_FILE_CHANGEDIR */
1763 UTIL_get_lang_msg("MENU_SSH_SCP", pvar, "SSH SCP...");
1764 insertMenuBeforeItem(menu, 50170, MF_ENABLED, ID_SSHSCPMENU, pvar->ts->UIMsg);
1765 }
1766
1767 static void append_about_text(HWND dlg, char FAR * prefix, char FAR * msg)
1768 {
1769 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
1770 (LPARAM) prefix);
1771 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0, (LPARAM) msg);
1772 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
1773 (LPARAM) (char FAR *) "\r\n");
1774 }
1775
1776 // ���s�t�@�C�������o�[�W�������������� (2005.2.28 yutaka)
1777 void get_file_version(char *exefile, int *major, int *minor, int *release, int *build)
1778 {
1779 typedef struct {
1780 WORD wLanguage;
1781 WORD wCodePage;
1782 } LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
1783 LPLANGANDCODEPAGE lplgcode;
1784 UINT unLen;
1785 DWORD size;
1786 char *buf = NULL;
1787 BOOL ret;
1788 int i;
1789 char fmt[80];
1790 char *pbuf;
1791
1792 size = GetFileVersionInfoSize(exefile, NULL);
1793 if (size == 0) {
1794 goto error;
1795 }
1796 buf = malloc(size);
1797 ZeroMemory(buf, size);
1798
1799 if (GetFileVersionInfo(exefile, 0, size, buf) == FALSE) {
1800 goto error;
1801 }
1802
1803 ret = VerQueryValue(buf,
1804 "\\VarFileInfo\\Translation",
1805 (LPVOID *)&lplgcode, &unLen);
1806 if (ret == FALSE)
1807 goto error;
1808
1809 for (i = 0 ; i < (int)(unLen / sizeof(LANGANDCODEPAGE)) ; i++) {
1810 _snprintf_s(fmt, sizeof(fmt), _TRUNCATE,
1811 "\\StringFileInfo\\%04x%04x\\FileVersion",
1812 lplgcode[i].wLanguage, lplgcode[i].wCodePage);
1813 VerQueryValue(buf, fmt, &pbuf, &unLen);
1814 if (unLen > 0) { // get success
1815 int n, a, b, c, d;
1816
1817 n = sscanf(pbuf, "%d, %d, %d, %d", &a, &b, &c, &d);
1818 if (n == 4) { // convert success
1819 *major = a;
1820 *minor = b;
1821 *release = c;
1822 *build = d;
1823 break;
1824 }
1825 }
1826 }
1827
1828 free(buf);
1829 return;
1830
1831 error:
1832 free(buf);
1833 *major = *minor = *release = *build = 0;
1834 }
1835
1836 static void init_about_dlg(PTInstVar pvar, HWND dlg)
1837 {
1838 char buf[1024];
1839 int a, b, c, d;
1840 char uimsg[MAX_UIMSG];
1841
1842 GetWindowText(dlg, uimsg, sizeof(uimsg));
1843 UTIL_get_lang_msg("DLG_ABOUT_TITLE", pvar, uimsg);
1844 SetWindowText(dlg, pvar->ts->UIMsg);
1845 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
1846 UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
1847 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
1848
1849 // TTSSH���o�[�W�������������� (2005.2.28 yutaka)
1850 get_file_version("ttxssh.dll", &a, &b, &c, &d);
1851 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
1852 "TTSSH\r\nTera Term Secure Shell extension, %d.%d", a, b);
1853 SendMessage(GetDlgItem(dlg, IDC_TTSSH_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
1854
1855 // OpenSSL���o�[�W�������������� (2005.1.24 yutaka)
1856 // ���������� (2005.5.11 yutaka)
1857 #ifdef OPENSSL_VERSION_TEXT
1858 SendMessage(GetDlgItem(dlg, IDC_OPENSSL_VERSION), WM_SETTEXT, 0, (LPARAM)OPENSSL_VERSION_TEXT);
1859 #else
1860 SendMessage(GetDlgItem(dlg, IDC_OPENSSL_VERSION), WM_SETTEXT, 0, (LPARAM)"Unknown");
1861 #endif
1862
1863 // zlib���o�[�W�������������� (2005.5.11 yutaka)
1864 #ifdef ZLIB_VERSION
1865 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "ZLib %s", ZLIB_VERSION);
1866 #else
1867 _snprintf(buf, sizeof(buf), "ZLib Unknown");
1868 #endif
1869 SendMessage(GetDlgItem(dlg, IDC_ZLIB_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
1870
1871
1872 // TTSSH�_�C�A���O���\������SSH������������ (2004.10.30 yutaka)
1873 if (pvar->socket != INVALID_SOCKET) {
1874 if (SSHv1(pvar)) {
1875 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
1876 UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID: ");
1877 append_about_text(dlg, pvar->ts->UIMsg, buf);
1878 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
1879 UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol: ");
1880 append_about_text(dlg, pvar->ts->UIMsg, buf);
1881 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
1882 UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption: ");
1883 append_about_text(dlg, pvar->ts->UIMsg, buf);
1884 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
1885 UTIL_get_lang_msg("DLG_ABOUT_SERVERKEY", pvar, "Server keys: ");
1886 append_about_text(dlg, pvar->ts->UIMsg, buf);
1887 AUTH_get_auth_info(pvar, buf, sizeof(buf));
1888 UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication: ");
1889 append_about_text(dlg, pvar->ts->UIMsg, buf);
1890 SSH_get_compression_info(pvar, buf, sizeof(buf));
1891 UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression: ");
1892 append_about_text(dlg, pvar->ts->UIMsg, buf);
1893
1894 } else { // SSH2
1895 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
1896 UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID: ");
1897 append_about_text(dlg, pvar->ts->UIMsg, buf);
1898 UTIL_get_lang_msg("DLG_ABOUT_CLIENTID", pvar, "Client ID: ");
1899 append_about_text(dlg, pvar->ts->UIMsg, pvar->client_version_string);
1900
1901 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
1902 UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol: ");
1903 append_about_text(dlg, pvar->ts->UIMsg, buf);
1904
1905 if (pvar->kex_type == KEX_DH_GRP1_SHA1) {
1906 strncpy_s(buf, sizeof(buf), KEX_DH1, _TRUNCATE);
1907 } else if (pvar->kex_type == KEX_DH_GRP14_SHA1) {
1908 strncpy_s(buf, sizeof(buf), KEX_DH14, _TRUNCATE);
1909 } else {
1910 strncpy_s(buf, sizeof(buf), KEX_DHGEX, _TRUNCATE);
1911 }
1912 append_about_text(dlg, "KEX: ", buf);
1913
1914 if (pvar->hostkey_type == KEY_DSA) {
1915 strncpy_s(buf, sizeof(buf), "ssh-dss", _TRUNCATE);
1916 } else {
1917 strncpy_s(buf, sizeof(buf), "ssh-rsa", _TRUNCATE);
1918 }
1919 UTIL_get_lang_msg("DLG_ABOUT_HOSTKEY", pvar, "Host Key: ");
1920 append_about_text(dlg, pvar->ts->UIMsg, buf);
1921
1922 // add HMAC algorithm (2004.12.17 yutaka)
1923 buf[0] = '\0';
1924 if (pvar->ctos_hmac == HMAC_SHA1) {
1925 strncat_s(buf, sizeof(buf), "hmac-sha1", _TRUNCATE);
1926 } else if (pvar->ctos_hmac == HMAC_MD5) {
1927 strncat_s(buf, sizeof(buf), "hmac-md5", _TRUNCATE);
1928 }
1929 UTIL_get_lang_msg("DLG_ABOUT_TOSERVER", pvar, " to server, ");
1930 strncat_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
1931 if (pvar->stoc_hmac == HMAC_SHA1) {
1932 strncat_s(buf, sizeof(buf), "hmac-sha1", _TRUNCATE);
1933 } else if (pvar->stoc_hmac == HMAC_MD5) {
1934 strncat_s(buf, sizeof(buf), "hmac-md5", _TRUNCATE);
1935 }
1936 UTIL_get_lang_msg("DLG_ABOUT_FROMSERVER", pvar, " from server");
1937 strncat_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
1938 append_about_text(dlg, "HMAC: ", buf);
1939
1940 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
1941 UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption: ");
1942 append_about_text(dlg, pvar->ts->UIMsg, buf);
1943 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
1944 UTIL_get_lang_msg("DLG_ABOUT_SERVERKEY", pvar, "Server keys: ");
1945 append_about_text(dlg, pvar->ts->UIMsg, buf);
1946
1947 AUTH_get_auth_info(pvar, buf, sizeof(buf));
1948 UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication: ");
1949 append_about_text(dlg, pvar->ts->UIMsg, buf);
1950
1951 SSH_get_compression_info(pvar, buf, sizeof(buf));
1952 if (pvar->ctos_compression == COMP_DELAYED) { // �x���p�P�b�g���k������ (2006.6.23 yutaka)
1953 UTIL_get_lang_msg("DLG_ABOUT_COMPDELAY", pvar, "Delayed Compression: ");
1954 append_about_text(dlg, pvar->ts->UIMsg, buf);
1955 } else {
1956 UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression: ");
1957 append_about_text(dlg, pvar->ts->UIMsg, buf);
1958 }
1959 }
1960 }
1961 }
1962
1963 static BOOL CALLBACK TTXAboutDlg(HWND dlg, UINT msg, WPARAM wParam,
1964 LPARAM lParam)
1965 {
1966 LOGFONT logfont;
1967 HFONT font;
1968
1969 switch (msg) {
1970 case WM_INITDIALOG:
1971 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1972 GetObject(font, sizeof(LOGFONT), &logfont);
1973 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgAboutFont, pvar)) {
1974 SendDlgItemMessage(dlg, IDC_TTSSH_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1975 SendDlgItemMessage(dlg, IDC_SSHVERSIONS, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1976 SendDlgItemMessage(dlg, IDC_INCLUDES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1977 SendDlgItemMessage(dlg, IDC_OPENSSL_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1978 SendDlgItemMessage(dlg, IDC_ZLIB_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1979 SendDlgItemMessage(dlg, IDC_WEBSITES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1980 SendDlgItemMessage(dlg, IDC_CRYPTOGRAPHY, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1981 SendDlgItemMessage(dlg, IDC_CREDIT, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1982 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1983 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1984 }
1985 else {
1986 DlgAboutFont = NULL;
1987 }
1988
1989 // �A�C�R�������I���Z�b�g
1990 {
1991 int fuLoad = LR_DEFAULTCOLOR;
1992 HICON hicon;
1993
1994 if (is_NT4()) {
1995 fuLoad = LR_VGACOLOR;
1996 }
1997
1998 hicon = LoadImage(hInst, MAKEINTRESOURCE(IDI_SECURETT),
1999 IMAGE_ICON, 32, 32, fuLoad);
2000 SendDlgItemMessage(dlg, IDC_TTSSH_ICON, STM_SETICON, (WPARAM)hicon, 0);
2001 }
2002
2003 init_about_dlg((PTInstVar) lParam, dlg);
2004 return TRUE;
2005 case WM_COMMAND:
2006 switch (LOWORD(wParam)) {
2007 case IDOK:
2008 EndDialog(dlg, 1);
2009 if (DlgAboutFont != NULL) {
2010 DeleteObject(DlgAboutFont);
2011 }
2012 return TRUE;
2013 case IDCANCEL: /* there isn't a cancel button, but other Windows
2014 UI things can send this message */
2015 EndDialog(dlg, 0);
2016 if (DlgAboutFont != NULL) {
2017 DeleteObject(DlgAboutFont);
2018 }
2019 return TRUE;
2020 }
2021 break;
2022 }
2023
2024 return FALSE;
2025 }
2026
2027 static char FAR *get_cipher_name(int cipher)
2028 {
2029 switch (cipher) {
2030 case SSH_CIPHER_NONE:
2031 UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_BORDER", pvar,
2032 "<ciphers below this line are disabled>");
2033 return pvar->ts->UIMsg;
2034 case SSH_CIPHER_RC4:
2035 return "RC4(SSH1)";
2036 case SSH_CIPHER_3DES:
2037 return "3DES(SSH1)";
2038 case SSH_CIPHER_DES:
2039 return "DES(SSH1)";
2040 case SSH_CIPHER_IDEA:
2041 return "IDEA(SSH1)";
2042 case SSH_CIPHER_TSS:
2043 return "TSS(SSH1)";
2044 case SSH_CIPHER_BLOWFISH:
2045 return "Blowfish(SSH1)";
2046
2047 // for SSH2(yutaka)
2048 case SSH2_CIPHER_AES128_CBC:
2049 return "AES128-CBC(SSH2)";
2050 case SSH2_CIPHER_AES192_CBC:
2051 return "AES192-CBC(SSH2)";
2052 case SSH2_CIPHER_AES256_CBC:
2053 return "AES256-CBC(SSH2)";
2054 case SSH2_CIPHER_3DES_CBC:
2055 return "3DES-CBC(SSH2)";
2056 case SSH2_CIPHER_BLOWFISH_CBC:
2057 return "Blowfish-CBC(SSH2)";
2058 case SSH2_CIPHER_AES128_CTR:
2059 return "AES128-CTR(SSH2)";
2060 case SSH2_CIPHER_AES192_CTR:
2061 return "AES192-CTR(SSH2)";
2062 case SSH2_CIPHER_AES256_CTR:
2063 return "AES256-CTR(SSH2)";
2064 case SSH2_CIPHER_ARCFOUR:
2065 return "Arcfour(SSH2)";
2066 case SSH2_CIPHER_ARCFOUR128:
2067 return "Arcfour128(SSH2)";
2068 case SSH2_CIPHER_ARCFOUR256:
2069 return "Arcfour256(SSH2)";
2070 case SSH2_CIPHER_CAST128_CBC:
2071 return "CAST128-CBC(SSH2)";
2072
2073 default:
2074 return NULL;
2075 }
2076 }
2077
2078 static void set_move_button_status(HWND dlg)
2079 {
2080 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
2081 int curPos = (int) SendMessage(cipherControl, LB_GETCURSEL, 0, 0);
2082 int maxPos = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0) - 1;
2083
2084 EnableWindow(GetDlgItem(dlg, IDC_SSHMOVECIPHERUP),
2085 curPos > 0 && curPos <= maxPos);
2086 EnableWindow(GetDlgItem(dlg, IDC_SSHMOVECIPHERDOWN),
2087 curPos >= 0 && curPos < maxPos);
2088 }
2089
2090 static void init_setup_dlg(PTInstVar pvar, HWND dlg)
2091 {
2092 HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
2093 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
2094 int i;
2095 int ch;
2096 char uimsg[MAX_UIMSG];
2097
2098 GetWindowText(dlg, uimsg, sizeof(uimsg));
2099 UTIL_get_lang_msg("DLG_SSHSETUP_TITLE", pvar, uimsg);
2100 SetWindowText(dlg, pvar->ts->UIMsg);
2101 GetDlgItemText(dlg, IDC_COMPRESSLABEL, uimsg, sizeof(uimsg));
2102 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS", pvar, uimsg);
2103 SetDlgItemText(dlg, IDC_COMPRESSLABEL, pvar->ts->UIMsg);
2104 GetDlgItemText(dlg, IDC_COMPRESSNONE, uimsg, sizeof(uimsg));
2105 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_NONE", pvar, uimsg);
2106 SetDlgItemText(dlg, IDC_COMPRESSNONE, pvar->ts->UIMsg);
2107 GetDlgItemText(dlg, IDC_COMPRESSHIGH, uimsg, sizeof(uimsg));
2108 UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_HIGHEST", pvar, uimsg);
2109 SetDlgItemText(dlg, IDC_COMPRESSHIGH, pvar->ts->UIMsg);
2110 GetDlgItemText(dlg, IDC_CIPHERORDER, uimsg, sizeof(uimsg));
2111 UTIL_get_lang_msg("DLG_SSHSETUP_CHIPER", pvar, uimsg);
2112 SetDlgItemText(dlg, IDC_CIPHERORDER, pvar->ts->UIMsg);
2113 GetDlgItemText(dlg, IDC_SSHMOVECIPHERUP, uimsg, sizeof(uimsg));
2114 UTIL_get_lang_msg("DLG_SSHSETUP_CHIPER_UP", pvar, uimsg);
2115 SetDlgItemText(dlg, IDC_SSHMOVECIPHERUP, pvar->ts->UIMsg);
2116 GetDlgItemText(dlg, IDC_SSHMOVECIPHERDOWN, uimsg, sizeof(uimsg));
2117 UTIL_get_lang_msg("DLG_SSHSETUP_CHIPER_DOWN", pvar, uimsg);
2118 SetDlgItemText(dlg, IDC_SSHMOVECIPHERDOWN, pvar->ts->UIMsg);
2119 GetDlgItemText(dlg, IDC_KNOWNHOSTS, uimsg, sizeof(uimsg));
2120 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST", pvar, uimsg);
2121 SetDlgItemText(dlg, IDC_KNOWNHOSTS, pvar->ts->UIMsg);
2122 GetDlgItemText(dlg, IDC_CHOOSEREADWRITEFILE, uimsg, sizeof(uimsg));
2123 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST_RW", pvar, uimsg);
2124 SetDlgItemText(dlg, IDC_CHOOSEREADWRITEFILE, pvar->ts->UIMsg);
2125 GetDlgItemText(dlg, IDC_CHOOSEREADONLYFILE, uimsg, sizeof(uimsg));
2126 UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST_RO", pvar, uimsg);
2127 SetDlgItemText(dlg, IDC_CHOOSEREADONLYFILE, pvar->ts->UIMsg);
2128 GetDlgItemText(dlg, IDC_HEARTBEATLABEL, uimsg, sizeof(uimsg));
2129 UTIL_get_lang_msg("DLG_SSHSETUP_HEARTBEAT", pvar, uimsg);
2130 SetDlgItemText(dlg, IDC_HEARTBEATLABEL, pvar->ts->UIMsg);
2131 GetDlgItemText(dlg, IDC_HEARTBEATLABEL2, uimsg, sizeof(uimsg));
2132 UTIL_get_lang_msg("DLG_SSHSETUP_HEARTBEAT_UNIT", pvar, uimsg);
2133 SetDlgItemText(dlg, IDC_HEARTBEATLABEL2, pvar->ts->UIMsg);
2134 GetDlgItemText(dlg, IDC_FORWARDAGENT, uimsg, sizeof(uimsg));
2135 UTIL_get_lang_msg("DLG_SSHSETUP_FORWARDAGENT", pvar, uimsg);
2136 SetDlgItemText(dlg, IDC_FORWARDAGENT, pvar->ts->UIMsg);
2137 GetDlgItemText(dlg, IDC_NOTICEBANNER, uimsg, sizeof(uimsg));
2138 UTIL_get_lang_msg("DLG_SSHSETUP_NOTICE", pvar, uimsg);
2139 SetDlgItemText(dlg, IDC_NOTICEBANNER, pvar->ts->UIMsg);
2140 GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2141 UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
2142 SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2143 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2144 UTIL_get_lang_msg("BTN_CANCEL", pvar, uimsg);
2145 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2146
2147 SendMessage(compressionControl, TBM_SETRANGE, TRUE, MAKELONG(0, 9));
2148 SendMessage(compressionControl, TBM_SETPOS, TRUE,
2149 pvar->settings.CompressionLevel);
2150
2151 normalize_cipher_order(pvar->settings.CipherOrder);
2152
2153 for (i = 0; pvar->settings.CipherOrder[i] != 0; i++) {
2154 int cipher = pvar->settings.CipherOrder[i] - '0';
2155 char FAR *name = get_cipher_name(cipher);
2156
2157 if (name != NULL) {
2158 SendMessage(cipherControl, LB_ADDSTRING, 0, (LPARAM) name);
2159 }
2160 }
2161
2162 SendMessage(cipherControl, LB_SETCURSEL, 0, 0);
2163 set_move_button_status(dlg);
2164
2165 for (i = 0; (ch = pvar->settings.KnownHostsFiles[i]) != 0 && ch != ';';
2166 i++) {
2167 }
2168 if (ch != 0) {
2169 pvar->settings.KnownHostsFiles[i] = 0;
2170 SetDlgItemText(dlg, IDC_READWRITEFILENAME,
2171 pvar->settings.KnownHostsFiles);
2172 pvar->settings.KnownHostsFiles[i] = ch;
2173 SetDlgItemText(dlg, IDC_READONLYFILENAME,
2174 pvar->settings.KnownHostsFiles + i + 1);
2175 } else {
2176 SetDlgItemText(dlg, IDC_READWRITEFILENAME,
2177 pvar->settings.KnownHostsFiles);
2178 }
2179
2180 // SSH2 HeartBeat(keep-alive)������ (2005.2.22 yutaka)
2181 {
2182 char buf[10];
2183 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2184 "%d", pvar->settings.ssh_heartbeat_overtime);
2185 SetDlgItemText(dlg, IDC_HEARTBEAT_EDIT, buf);
2186 }
2187
2188 if (pvar->settings.ForwardAgent) {
2189 CheckDlgButton(dlg, IDC_FORWARDAGENT, TRUE);
2190 }
2191 }
2192
2193 void get_teraterm_dir_relative_name(char FAR * buf, int bufsize,
2194 char FAR * basename)
2195 {
2196 int filename_start = 0;
2197 int i;
2198 int ch;
2199
2200 if (basename[0] == '\\' || basename[0] == '/'
2201 || (basename[0] != 0 && basename[1] == ':')) {
2202 strncpy_s(buf, bufsize, basename, _TRUNCATE);
2203 return;
2204 }
2205
2206 GetModuleFileName(NULL, buf, bufsize);
2207 for (i = 0; (ch = buf[i]) != 0; i++) {
2208 if (ch == '\\' || ch == '/' || ch == ':') {
2209 filename_start = i + 1;
2210 }
2211 }
2212
2213 if (bufsize > filename_start) {
2214 strncpy_s(buf + filename_start, bufsize - filename_start, basename, _TRUNCATE);
2215 }
2216 }
2217
2218 int copy_teraterm_dir_relative_path(char FAR * dest, int destsize,
2219 char FAR * basename)
2220 {
2221 char buf[1024];
2222 int filename_start = 0;
2223 int i;
2224 int ch, ch2;
2225
2226 if (basename[0] != '\\' && basename[0] != '/'
2227 && (basename[0] == 0 || basename[1] != ':')) {
2228 strncpy_s(dest, destsize, basename, _TRUNCATE);
2229 return strlen(dest);
2230 }
2231
2232 GetModuleFileName(NULL, buf, sizeof(buf));
2233 for (i = 0; (ch = buf[i]) != 0; i++) {
2234 if (ch == '\\' || ch == '/' || ch == ':') {
2235 filename_start = i + 1;
2236 }
2237 }
2238
2239 for (i = 0; i < filename_start; i++) {
2240 ch = toupper(buf[i]);
2241 ch2 = toupper(basename[i]);
2242
2243 if (ch == ch2 ||
2244 ((ch == '\\' || ch == '/') && (ch2 == '\\' || ch2 == '/'))) {
2245 } else {
2246 break;
2247 }
2248 }
2249
2250 if (i == filename_start) {
2251 strncpy_s(dest, destsize, basename + i, _TRUNCATE);
2252 } else {
2253 strncpy_s(dest, destsize, basename, _TRUNCATE);
2254 }
2255 return strlen(dest);
2256 }
2257
2258 static void complete_setup_dlg(PTInstVar pvar, HWND dlg)
2259 {
2260 char buf[4096];
2261 char buf2[1024];
2262 HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
2263 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
2264 int i, j, buf2index, bufindex;
2265 int count = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0);
2266
2267 pvar->settings.CompressionLevel =
2268 (int) SendMessage(compressionControl, TBM_GETPOS, 0, 0);
2269
2270 buf2index = 0;
2271 for (i = 0; i < count; i++) {
2272 int len = SendMessage(cipherControl, LB_GETTEXTLEN, i, 0);
2273
2274 if (len > 0 && len < sizeof(buf)) { /* should always be true */
2275 buf[0] = 0;
2276 SendMessage(cipherControl, LB_GETTEXT, i, (LPARAM) buf);
2277 for (j = 0;
2278 j <= SSH_CIPHER_MAX
2279 && strcmp(buf, get_cipher_name(j)) != 0; j++) {
2280 }
2281 if (j <= SSH_CIPHER_MAX) {
2282 buf2[buf2index] = '0' + j;
2283 buf2index++;
2284 }
2285 }
2286 }
2287 buf2[buf2index] = 0;
2288 normalize_cipher_order(buf2);
2289 strncpy_s(pvar->settings.CipherOrder, sizeof(pvar->settings.CipherOrder), buf2, _TRUNCATE);
2290
2291 buf[0] = 0;
2292 GetDlgItemText(dlg, IDC_READWRITEFILENAME, buf, sizeof(buf));
2293 j = copy_teraterm_dir_relative_path(pvar->settings.KnownHostsFiles,
2294 sizeof(pvar->settings.KnownHostsFiles),
2295 buf);
2296 buf[0] = 0;
2297 bufindex = 0;
2298 GetDlgItemText(dlg, IDC_READONLYFILENAME, buf, sizeof(buf));
2299 for (i = 0; buf[i] != 0; i++) {
2300 if (buf[i] == ';') {
2301 buf[i] = 0;
2302 if (j < sizeof(pvar->settings.KnownHostsFiles) - 1) {
2303 pvar->settings.KnownHostsFiles[j] = ';';
2304 j++;
2305 j += copy_teraterm_dir_relative_path(pvar->settings.
2306 KnownHostsFiles + j,
2307 sizeof(pvar->settings.
2308 KnownHostsFiles)
2309 - j, buf + bufindex);
2310 }
2311 bufindex = i + 1;
2312 }
2313 }
2314 if (bufindex < i && j < sizeof(pvar->settings.KnownHostsFiles) - 1) {
2315 pvar->settings.KnownHostsFiles[j] = ';';
2316 j++;
2317 copy_teraterm_dir_relative_path(pvar->settings.KnownHostsFiles + j,
2318 sizeof(pvar->settings. KnownHostsFiles) - j,
2319 buf + bufindex);
2320 }
2321
2322 // get SSH HeartBeat(keep-alive)
2323 SendMessage(GetDlgItem(dlg, IDC_HEARTBEAT_EDIT), WM_GETTEXT, sizeof(buf), (LPARAM)buf);
2324 i = atoi(buf);
2325 if (i < 0)
2326 i = 60;
2327 pvar->settings.ssh_heartbeat_overtime = i;
2328
2329 pvar->settings.ForwardAgent = IsDlgButtonChecked(dlg, IDC_FORWARDAGENT);
2330 }
2331
2332 static void move_cur_sel_delta(HWND listbox, int delta)
2333 {
2334 int curPos = (int) SendMessage(listbox, LB_GETCURSEL, 0, 0);
2335 int maxPos = (int) SendMessage(listbox, LB_GETCOUNT, 0, 0) - 1;
2336 int newPos = curPos + delta;
2337 char buf[1024];
2338
2339 if (curPos >= 0 && newPos >= 0 && newPos <= maxPos) {
2340 int len = SendMessage(listbox, LB_GETTEXTLEN, curPos, 0);
2341
2342 if (len > 0 && len < sizeof(buf)) { /* should always be true */
2343 buf[0] = 0;
2344 SendMessage(listbox, LB_GETTEXT, curPos, (LPARAM) buf);
2345 SendMessage(listbox, LB_DELETESTRING, curPos, 0);
2346 SendMessage(listbox, LB_INSERTSTRING, newPos,
2347 (LPARAM) (char FAR *) buf);
2348 SendMessage(listbox, LB_SETCURSEL, newPos, 0);
2349 }
2350 }
2351 }
2352
2353 static int get_keys_file_name(HWND parent, char FAR * buf, int bufsize,
2354 int readonly)
2355 {
2356 OPENFILENAME params;
2357 char fullname_buf[2048] = "ssh_known_hosts";
2358
2359 params.lStructSize = sizeof(OPENFILENAME);
2360 params.hwndOwner = parent;
2361 params.lpstrFilter = NULL;
2362 params.lpstrCustomFilter = NULL;
2363 params.nFilterIndex = 0;
2364 buf[0] = 0;
2365 params.lpstrFile = fullname_buf;
2366 params.nMaxFile = sizeof(fullname_buf);
2367 params.lpstrFileTitle = NULL;
2368 params.lpstrInitialDir = NULL;
2369 if (readonly) {
2370 UTIL_get_lang_msg("MSG_OPEN_KNOWNHOSTS_RO_TITLE", pvar,
2371 "Choose a read-only known-hosts file to add");
2372 }
2373 else {
2374 UTIL_get_lang_msg("MSG_OPEN_KNOWNHOSTS_RW_TITLE", pvar,
2375 "Choose a read/write known-hosts file");
2376 }
2377 params.lpstrTitle = pvar->ts->UIMsg;
2378 params.Flags = (readonly ? OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST : 0)
2379 | OFN_HIDEREADONLY | (!readonly ? OFN_NOREADONLYRETURN : 0);
2380 params.lpstrDefExt = NULL;
2381
2382 if (GetOpenFileName(&params) != 0) {
2383 copy_teraterm_dir_relative_path(buf, bufsize, fullname_buf);
2384 return 1;
2385 } else {
2386 int err = CommDlgExtendedError();
2387
2388 if (err != 0) {
2389 char buf[1024];
2390 UTIL_get_lang_msg("MSG_OPEN_FILEDLG_KNOWNHOSTS_ERROR", pvar,
2391 "Unable to display file dialog box: error %d");
2392 _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, err);
2393 MessageBox(parent, buf, "TTSSH Error",
2394 MB_OK | MB_ICONEXCLAMATION);
2395 }
2396
2397 return 0;
2398 }
2399 }
2400
2401 static void choose_read_write_file(HWND dlg)
2402 {
2403 char buf[1024];
2404
2405 if (get_keys_file_name(dlg, buf, sizeof(buf), 0)) {
2406 SetDlgItemText(dlg, IDC_READWRITEFILENAME, buf);
2407 }
2408 }
2409
2410 static void choose_read_only_file(HWND dlg)
2411 {
2412 char buf[1024];
2413 char buf2[4096];
2414
2415 if (get_keys_file_name(dlg, buf, sizeof(buf), 1)) {
2416 buf2[0] = 0;
2417 GetDlgItemText(dlg, IDC_READONLYFILENAME, buf2, sizeof(buf2));
2418 if (buf2[0] != 0 && buf2[strlen(buf2) - 1] != ';') {
2419 strncat_s(buf2, sizeof(buf2), ";", _TRUNCATE);
2420 }
2421 strncat_s(buf2, sizeof(buf2), buf, _TRUNCATE);
2422 SetDlgItemText(dlg, IDC_READONLYFILENAME, buf2);
2423 }
2424 }
2425
2426 static BOOL CALLBACK TTXSetupDlg(HWND dlg, UINT msg, WPARAM wParam,
2427 LPARAM lParam)
2428 {
2429 LOGFONT logfont;
2430 HFONT font;
2431
2432 switch (msg) {
2433 case WM_INITDIALOG:
2434 SetWindowLong(dlg, DWL_USER, lParam);
2435 init_setup_dlg((PTInstVar) lParam, dlg);
2436
2437 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2438 GetObject(font, sizeof(LOGFONT), &logfont);
2439 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgSetupFont, pvar)) {
2440 SendDlgItemMessage(dlg, IDC_COMPRESSLABEL, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2441 SendDlgItemMessage(dlg, IDC_CIPHERORDER, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2442 SendDlgItemMessage(dlg, IDC_SSHCIPHERPREFS, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2443 SendDlgItemMessage(dlg, IDC_SSHMOVECIPHERUP, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2444 SendDlgItemMessage(dlg, IDC_SSHMOVECIPHERDOWN, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2445 SendDlgItemMessage(dlg, IDC_CHOOSEREADWRITEFILE, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2446 SendDlgItemMessage(dlg, IDC_READWRITEFILENAME, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2447 SendDlgItemMessage(dlg, IDC_CHOOSEREADONLYFILE, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2448 SendDlgItemMessage(dlg, IDC_READONLYFILENAME, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2449 SendDlgItemMessage(dlg, IDC_COMPRESSNONE, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2450 SendDlgItemMessage(dlg, IDC_COMPRESSHIGH, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2451 SendDlgItemMessage(dlg, IDC_NOTICEBANNER, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2452 SendDlgItemMessage(dlg, IDC_KNOWNHOSTS, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2453 SendDlgItemMessage(dlg, IDC_HEARTBEATLABEL, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2454 SendDlgItemMessage(dlg, IDC_HEARTBEAT_EDIT, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2455 SendDlgItemMessage(dlg, IDC_HEARTBEATLABEL2, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2456 SendDlgItemMessage(dlg, IDC_FORWARDAGENT, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2457 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2458 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgSetupFont, MAKELPARAM(TRUE,0));
2459 }
2460 else {
2461 DlgSetupFont = NULL;
2462 }
2463
2464 return TRUE;
2465 case WM_COMMAND:
2466 switch (LOWORD(wParam)) {
2467 case IDOK:
2468 complete_setup_dlg((PTInstVar) GetWindowLong(dlg, DWL_USER), dlg);
2469 EndDialog(dlg, 1);
2470 if (DlgSetupFont != NULL) {
2471 DeleteObject(DlgSetupFont);
2472 }
2473 return TRUE;
2474 case IDCANCEL: /* there isn't a cancel button, but other Windows
2475 UI things can send this message */
2476 EndDialog(dlg, 0);
2477 if (DlgSetupFont != NULL) {
2478 DeleteObject(DlgSetupFont);
2479 }
2480 return TRUE;
2481 case IDC_SSHMOVECIPHERUP:
2482 move_cur_sel_delta(GetDlgItem(dlg, IDC_SSHCIPHERPREFS), -1);
2483 set_move_button_status(dlg);
2484 SetFocus(GetDlgItem(dlg, IDC_SSHCIPHERPREFS));
2485 return TRUE;
2486 case IDC_SSHMOVECIPHERDOWN:
2487 move_cur_sel_delta(GetDlgItem(dlg, IDC_SSHCIPHERPREFS), 1);
2488 set_move_button_status(dlg);
2489 SetFocus(GetDlgItem(dlg, IDC_SSHCIPHERPREFS));
2490 return TRUE;
2491 case IDC_SSHCIPHERPREFS:
2492 set_move_button_status(dlg);
2493 return TRUE;
2494 case IDC_CHOOSEREADWRITEFILE:
2495 choose_read_write_file(dlg);
2496 return TRUE;
2497 case IDC_CHOOSEREADONLYFILE:
2498 choose_read_only_file(dlg);
2499 return TRUE;
2500 }
2501 break;
2502 }
2503
2504 return FALSE;
2505 }
2506
2507
2508 //
2509 // SSH key generator dialog (2005.4.10 yutaka)
2510 //
2511
2512 typedef struct {
2513 RSA *rsa;
2514 DSA *dsa;
2515 } ssh_private_key_t;
2516
2517 static ssh_private_key_t private_key = {NULL, NULL};
2518
2519 typedef struct {
2520 RSA *rsa;
2521 DSA *dsa;
2522 } ssh_public_key_t;
2523
2524 static ssh_public_key_t public_key = {NULL, NULL};;
2525
2526 static void free_ssh_key(void)
2527 {
2528 // DSA_free(), RSA_free()��NULL���n�����������������B
2529 DSA_free(private_key.dsa);
2530 private_key.dsa = NULL;
2531 DSA_free(public_key.dsa);
2532 public_key.dsa = NULL;
2533
2534 RSA_free(private_key.rsa);
2535 private_key.rsa = NULL;
2536 RSA_free(public_key.rsa);
2537 public_key.rsa = NULL;
2538 }
2539
2540
2541 static BOOL generate_ssh_key(enum hostkey_type type)
2542 {
2543 int bits = 1024;
2544
2545 // if SSH key already is generated, should free the resource.
2546 free_ssh_key();
2547
2548 if (type == KEY_RSA1 || type == KEY_RSA) {
2549 RSA *priv = NULL;
2550 RSA *pub = NULL;
2551
2552 // private key
2553 priv = RSA_generate_key(bits, 35, NULL, NULL);
2554 if (priv == NULL)
2555 goto error;
2556 private_key.rsa = priv;
2557
2558 // public key
2559 pub = RSA_new();
2560 pub->n = BN_new();
2561 pub->e = BN_new();
2562 if (pub->n == NULL || pub->e == NULL) {
2563 RSA_free(pub);
2564 goto error;
2565 }
2566
2567 BN_copy(pub->n, priv->n);
2568 BN_copy(pub->e, priv->e);
2569 public_key.rsa = pub;
2570
2571 } else if (type == KEY_DSA) {
2572 DSA *priv = NULL;
2573 DSA *pub = NULL;
2574
2575 // private key
2576 priv = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
2577 if (priv == NULL)
2578 goto error;
2579 if (!DSA_generate_key(priv)) {
2580 // TODO: free 'priv'?
2581 goto error;
2582 }
2583 private_key.dsa = priv;
2584
2585 // public key
2586 pub = DSA_new();
2587 if (pub == NULL)
2588 goto error;
2589 pub->p = BN_new();
2590 pub->q = BN_new();
2591 pub->g = BN_new();
2592 pub->pub_key = BN_new();
2593 if (pub->p == NULL || pub->q == NULL || pub->g == NULL || pub->pub_key == NULL) {
2594 DSA_free(pub);
2595 goto error;
2596 }
2597
2598 BN_copy(pub->p, priv->p);
2599 BN_copy(pub->q, priv->q);
2600 BN_copy(pub->g, priv->g);
2601 BN_copy(pub->pub_key, priv->pub_key);
2602 public_key.dsa = pub;
2603
2604 } else {
2605 goto error;
2606 }
2607
2608 return TRUE;
2609
2610 error:
2611 free_ssh_key();
2612 return FALSE;
2613 }
2614
2615
2616 //
2617 // RC4
2618 //
2619
2620 /* Size of key to use */
2621 #define SEED_SIZE 20
2622
2623 /* Number of bytes to reseed after */
2624 #define REKEY_BYTES (1 << 24)
2625
2626 static int rc4_ready = 0;
2627 static RC4_KEY rc4;
2628
2629 static void seed_rng(void)
2630 {
2631 if (RAND_status() != 1)
2632 return;
2633 }
2634
2635 static void arc4random_stir(void)
2636 {
2637 unsigned char rand_buf[SEED_SIZE];
2638 int i;
2639
2640 memset(&rc4, 0, sizeof(rc4));
2641 if (RAND_bytes(rand_buf, sizeof(rand_buf)) <= 0) {
2642 //fatal("Couldn't obtain random bytes (error %ld)",
2643 // ERR_get_error());
2644 }
2645 RC4_set_key(&rc4, sizeof(rand_buf), rand_buf);
2646
2647 /*
2648 * Discard early keystream, as per recommendations in:
2649 * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
2650 */
2651 for(i = 0; i <= 256; i += sizeof(rand_buf))
2652 RC4(&rc4, sizeof(rand_buf), rand_buf, rand_buf);
2653
2654 memset(rand_buf, 0, sizeof(rand_buf));
2655
2656 rc4_ready = REKEY_BYTES;
2657 }
2658
2659 static unsigned int arc4random(void)
2660 {
2661 unsigned int r = 0;
2662 static int first_time = 1;
2663
2664 if (rc4_ready <= 0) {
2665 if (first_time) {
2666 seed_rng();
2667 }
2668 first_time = 0;
2669 arc4random_stir();
2670 }
2671
2672 RC4(&rc4, sizeof(r), (unsigned char *)&r, (unsigned char *)&r);
2673
2674 rc4_ready -= sizeof(r);
2675
2676 return(r);
2677 }
2678
2679 //
2680 // SSH1 3DES
2681 //
2682 /*
2683 * This is used by SSH1:
2684 *
2685 * What kind of triple DES are these 2 routines?
2686 *
2687 * Why is there a redundant initialization vector?
2688 *
2689 * If only iv3 was used, then, this would till effect have been
2690 * outer-cbc. However, there is also a private iv1 == iv2 which
2691 * perhaps makes differential analysis easier. On the other hand, the
2692 * private iv1 probably makes the CRC-32 attack ineffective. This is a
2693 * result of that there is no longer any known iv1 to use when
2694 * choosing the X block.
2695 */
2696 struct ssh1_3des_ctx
2697 {
2698 EVP_CIPHER_CTX k1, k2, k3;
2699 };
2700
2701 static int ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, int enc)
2702 {
2703 struct ssh1_3des_ctx *c;
2704 u_char *k1, *k2, *k3;
2705
2706 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
2707 c = malloc(sizeof(*c));
2708 EVP_CIPHER_CTX_set_app_data(ctx, c);
2709 }
2710 if (key == NULL)
2711 return (1);
2712 if (enc == -1)
2713 enc = ctx->encrypt;
2714 k1 = k2 = k3 = (u_char *) key;
2715 k2 += 8;
2716 if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
2717 if (enc)
2718 k3 += 16;
2719 else
2720 k1 += 16;
2721 }
2722 EVP_CIPHER_CTX_init(&c->k1);
2723 EVP_CIPHER_CTX_init(&c->k2);
2724 EVP_CIPHER_CTX_init(&c->k3);
2725 if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
2726 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
2727 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
2728 memset(c, 0, sizeof(*c));
2729 free(c);
2730 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
2731 return (0);
2732 }
2733 return (1);
2734 }
2735
2736 static int ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
2737 {
2738 struct ssh1_3des_ctx *c;
2739
2740 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
2741 //error("ssh1_3des_cbc: no context");
2742 return (0);
2743 }
2744 if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
2745 EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
2746 EVP_Cipher(&c->k3, dest, dest, len) == 0)
2747 return (0);
2748 return (1);
2749 }
2750
2751 static int ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
2752 {
2753 struct ssh1_3des_ctx *c;
2754
2755 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
2756 EVP_CIPHER_CTX_cleanup(&c->k1);
2757 EVP_CIPHER_CTX_cleanup(&c->k2);
2758 EVP_CIPHER_CTX_cleanup(&c->k3);
2759 memset(c, 0, sizeof(*c));
2760 free(c);
2761 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
2762 }
2763 return (1);
2764 }
2765
2766 void ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len)
2767 {
2768 struct ssh1_3des_ctx *c;
2769
2770 if (len != 24)
2771 //fatal("%s: bad 3des iv length: %d", __func__, len);
2772 ;
2773
2774 if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
2775 //fatal("%s: no 3des context", __func__);
2776 ;
2777
2778 if (doset) {
2779 //debug3("%s: Installed 3DES IV", __func__);
2780 memcpy(c->k1.iv, iv, 8);
2781 memcpy(c->k2.iv, iv + 8, 8);
2782 memcpy(c->k3.iv, iv + 16, 8);
2783 } else {
2784 //debug3("%s: Copying 3DES IV", __func__);
2785 memcpy(iv, c->k1.iv, 8);
2786 memcpy(iv + 8, c->k2.iv, 8);
2787 memcpy(iv + 16, c->k3.iv, 8);
2788 }
2789 }
2790
2791 const EVP_CIPHER *evp_ssh1_3des(void)
2792 {
2793 static EVP_CIPHER ssh1_3des;
2794
2795 memset(&ssh1_3des, 0, sizeof(EVP_CIPHER));
2796 ssh1_3des.nid = NID_undef;
2797 ssh1_3des.block_size = 8;
2798 ssh1_3des.iv_len = 0;
2799 ssh1_3des.key_len = 16;
2800 ssh1_3des.init = ssh1_3des_init;
2801 ssh1_3des.cleanup = ssh1_3des_cleanup;
2802 ssh1_3des.do_cipher = ssh1_3des_cbc;
2803 ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
2804 return (&ssh1_3des);
2805 }
2806
2807 static void ssh_make_comment(char *comment, int maxlen)
2808 {
2809 char user[UNLEN + 1], host[128];
2810 DWORD dwSize;
2811 WSADATA wsaData;
2812 int ret;
2813
2814 // get Windows logon user name
2815 dwSize = sizeof(user);
2816 if (GetUserName(user, &dwSize) == 0) {
2817 strncpy_s(user, sizeof(user), "yutaka", _TRUNCATE);
2818 }
2819
2820 // get local hostname (by WinSock)
2821 ret = WSAStartup(MAKEWORD(2,2), &wsaData);
2822 if (ret == 0) {
2823 if (gethostname(host, sizeof(host)) != 0) {
2824 ret = WSAGetLastError();
2825 }
2826 WSACleanup();
2827 }
2828 if (ret != 0) {
2829 strncpy_s(host, sizeof(host), "sai", _TRUNCATE);
2830 }
2831
2832 _snprintf_s(comment, maxlen, _TRUNCATE, "%s@%s", user, host);
2833 }
2834
2835 // uuencode (rfc1521)
2836 int uuencode(unsigned char *src, int srclen, unsigned char *target, int targsize)
2837 {
2838 char base64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2839 char pad = '=';
2840 int datalength = 0;
2841 unsigned char input[3];
2842 unsigned char output[4];
2843 int i;
2844
2845 while (srclen > 2) {
2846 input[0] = *src++;
2847 input[1] = *src++;
2848 input[2] = *src++;
2849 srclen -= 3;
2850
2851 output[0] = input[0] >> 2;
2852 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
2853 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
2854