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 3173 - (show annotations) (download) (as text)
Sun Nov 23 12:34:33 2008 UTC (15 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 118967 byte(s)
KEX_DEFAULT_ENCRYPT を空にした。
  normalize_cipher_order() で、設定値とデフォルト値(default_ciphers)をマージしているため、なくてもいいと判断。

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