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 2753 - (show annotations) (download) (as text)
Thu Dec 16 13:57:43 2004 UTC (19 years, 3 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 54728 byte(s)
"SECURITY WARINIG" dialogで ESC キーを押下すると、
アプリケーションエラーとなる現象への暫定対処。

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 /* Teraterm extension mechanism
30 Robert O'Callahan (roc+tt@cs.cmu.edu)
31
32 Teraterm 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
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <io.h>
44 #include <fcntl.h>
45 #include <sys/stat.h>
46 #include <time.h>
47
48 #include "resource.h"
49 #include <commctrl.h>
50 #include <commdlg.h>
51 #ifdef INET6
52 #include <winsock2.h>
53 static char FAR *ProtocolFamilyList[] = { "UNSPEC", "IPv6", "IPv4", NULL };
54 #else
55 #include <winsock.h>
56 #endif /* INET6 */
57
58 #define MATCH_STR(s, o) _strnicmp((s), (o), NUM_ELEM(o) - 1)
59
60 /* This extension implements SSH, so we choose a load order in the
61 "protocols" range. */
62 #define ORDER 2500
63
64 #ifdef TERATERM32
65 static HICON SecureIcon = NULL;
66 #endif
67
68 static TInstVar FAR *pvar;
69
70 #ifdef TERATERM32
71 /* WIN32 allows multiple instances of a DLL */
72 static TInstVar InstVar;
73 #define GET_VAR()
74 #else
75 /* WIN16 does not allow multiple instances of a DLL */
76
77 /* maximum number of Tera Term instances */
78 #define MAXNUMINST 32
79 /* list of task handles for Tera Term instances */
80 static HANDLE FAR TaskList[MAXNUMINST];
81 /* variable sets for instances */
82 static TInstVar FAR *FAR InstVar[MAXNUMINST];
83
84 /* Here's how the TS settings work.
85 Whenever the TS settings are read or written to the INI file, then
86 the shared memory containing those settings is updated.
87 When Teraterm starts, the shared memory is read to initialize the TS
88 settings. */
89
90 /* TS settings shared across instances */
91 static TS_SSH ts_SSH_settings;
92
93
94 extern void SSH2_update_cipher_myproposal(PTInstVar pvar);
95
96
97 static BOOL NewVar()
98 {
99 int i = 0;
100 HANDLE Task = GetCurrentTask();
101
102 if (TaskList[0] == NULL)
103
104 if (Task == NULL)
105 return FALSE;
106 while ((i < MAXNUMINST) && (TaskList[i] != NULL))
107 i++;
108 if (i >= MAXNUMINST)
109 return FALSE;
110 pvar = (TInstVar FAR *) malloc(sizeof(TInstVar));
111 InstVar[i] = pvar;
112 TaskList[i] = Task;
113 return TRUE;
114 }
115
116 void DelVar()
117 {
118 int i = 0;
119 HANDLE Task = GetCurrentTask();
120
121 if (Task == NULL)
122 return;
123 while ((i < MAXNUMINST) && (TaskList[i] != Task))
124 i++;
125 if (i >= MAXNUMINST)
126 return;
127 free(TaskList[i]);
128 TaskList[i] = NULL;
129 }
130
131 BOOL GetVar()
132 {
133 int i = 0;
134 HANDLE Task = GetCurrentTask();
135
136 if (Task == NULL)
137 return FALSE;
138 while ((i < MAXNUMINST) && (TaskList[i] != Task))
139 i++;
140 if (i >= MAXNUMINST)
141 return FALSE;
142 pvar = InstVar[i];
143 return TRUE;
144 }
145
146 #define GET_VAR() if (!GetVar()) return
147 #endif
148
149 /*
150 This code makes lots of assumptions about the order in which Teraterm
151 does things, and how. A key assumption is that the Notification window
152 passed into WSAAsyncSelect is the main terminal window. We also assume
153 that the socket used in the first WSAconnect is the main session socket.
154 */
155
156 static void init_TTSSH(PTInstVar pvar)
157 {
158 pvar->socket = INVALID_SOCKET;
159 pvar->OldLargeIcon = NULL;
160 pvar->OldSmallIcon = NULL;
161 pvar->NotificationWindow = NULL;
162 pvar->hostdlg_activated = FALSE;
163 pvar->socket = INVALID_SOCKET;
164 pvar->NotificationWindow = NULL;
165 pvar->protocol_major = 0;
166 pvar->protocol_minor = 0;
167
168 PKT_init(pvar);
169 SSH_init(pvar);
170 CRYPT_init(pvar);
171 AUTH_init(pvar);
172 HOSTS_init(pvar);
173 FWD_init(pvar);
174 FWDUI_init(pvar);
175
176 ssh_heartbeat_lock_initialize();
177 }
178
179 static void uninit_TTSSH(PTInstVar pvar)
180 {
181 SSH_end(pvar);
182 PKT_end(pvar);
183 AUTH_end(pvar);
184 CRYPT_end(pvar);
185 HOSTS_end(pvar);
186 FWD_end(pvar);
187 FWDUI_end(pvar);
188
189 if (pvar->OldLargeIcon != NULL) {
190 PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_BIG,
191 (LPARAM) pvar->OldLargeIcon);
192 pvar->OldLargeIcon = NULL;
193 }
194 if (pvar->OldSmallIcon != NULL) {
195 PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_SMALL,
196 (LPARAM) pvar->OldSmallIcon);
197 pvar->OldSmallIcon = NULL;
198 }
199 }
200
201 static void PASCAL FAR TTXInit(PTTSet ts, PComVar cv)
202 {
203 #ifndef TERATERM32
204 if (!NewVar())
205 return; /* should be called first */
206 pvar->ts_SSH = &ts_SSH_settings;
207 #endif
208 pvar->settings = *pvar->ts_SSH;
209 pvar->ts = ts;
210 pvar->cv = cv;
211 pvar->fatal_error = FALSE;
212 pvar->showing_err = FALSE;
213 pvar->err_msg = NULL;
214
215 init_TTSSH(pvar);
216 }
217
218 static void normalize_cipher_order(char FAR * buf)
219 {
220 char ciphers_listed[SSH_CIPHER_MAX + 1];
221 char ciphers_allowed[SSH_CIPHER_MAX + 1];
222 int i, j;
223
224 /* SSH_CIPHER_NONE means that all ciphers below that one are disabled.
225 We *never* allow no encryption. */
226 #if 0
227 static char default_ciphers[] = {
228 SSH_CIPHER_3DES,
229 SSH_CIPHER_NONE,
230 SSH_CIPHER_DES, SSH_CIPHER_BLOWFISH
231 };
232 #else
233 // for SSH2(yutaka)
234 static char default_ciphers[] = {
235 SSH_CIPHER_AES128,
236 SSH_CIPHER_3DES_CBC,
237 SSH_CIPHER_3DES,
238 SSH_CIPHER_NONE,
239 SSH_CIPHER_DES, SSH_CIPHER_BLOWFISH
240 };
241 #endif
242
243 memset(ciphers_listed, 0, sizeof(ciphers_listed));
244
245 memset(ciphers_allowed, 0, sizeof(ciphers_allowed));
246 for (i = 0; i < NUM_ELEM(default_ciphers); i++) {
247 ciphers_allowed[default_ciphers[i]] = 1;
248 }
249
250 for (i = 0; buf[i] != 0; i++) {
251 int cipher_num = buf[i] - '0';
252
253 if (cipher_num < 0 || cipher_num > SSH_CIPHER_MAX
254 || !ciphers_allowed[cipher_num]
255 || ciphers_listed[cipher_num]) {
256 memmove(buf + i, buf + i + 1, strlen(buf + i + 1) + 1);
257 i--;
258 } else {
259 ciphers_listed[cipher_num] = 1;
260 }
261 }
262
263 for (j = 0; j < NUM_ELEM(default_ciphers); j++) {
264 int cipher_num = default_ciphers[j];
265
266 if (!ciphers_listed[cipher_num]) {
267 buf[i] = cipher_num + '0';
268 i++;
269 }
270 }
271
272 buf[i] = 0;
273 }
274
275 /* Remove local settings from the shared memory block. */
276 static void clear_local_settings(PTInstVar pvar)
277 {
278 pvar->ts_SSH->TryDefaultAuth = FALSE;
279 }
280
281 static BOOL read_BOOL_option(PCHAR fileName, char FAR * keyName, BOOL def)
282 {
283 char buf[1024];
284
285 buf[0] = 0;
286 GetPrivateProfileString("TTSSH", keyName, "", buf, sizeof(buf),
287 fileName);
288 if (buf[0] == 0) {
289 return def;
290 } else {
291 return atoi(buf) != 0 ||
292 stricmp(buf, "yes") == 0 || stricmp(buf, "y") == 0;
293 }
294 }
295
296 static void read_string_option(PCHAR fileName, char FAR * keyName,
297 char FAR * def, char FAR * buf, int bufSize)
298 {
299
300 buf[0] = 0;
301 GetPrivateProfileString("TTSSH", keyName, def, buf, bufSize, fileName);
302 }
303
304 static void read_ssh_options(PTInstVar pvar, PCHAR fileName)
305 {
306 extern void SSH2_update_cipher_myproposal(PTInstVar pvar);
307 char buf[1024];
308 TS_SSH FAR *settings = pvar->ts_SSH;
309
310 #define READ_STD_STRING_OPTION(name) \
311 read_string_option(fileName, #name, "", settings->name, sizeof(settings->name))
312
313 settings->Enabled = read_BOOL_option(fileName, "Enabled", FALSE);
314
315 buf[0] = 0;
316 GetPrivateProfileString("TTSSH", "Compression", "", buf, sizeof(buf),
317 fileName);
318 settings->CompressionLevel = atoi(buf);
319 if (settings->CompressionLevel < 0 || settings->CompressionLevel > 9) {
320 settings->CompressionLevel = 0;
321 }
322
323 READ_STD_STRING_OPTION(DefaultUserName);
324 READ_STD_STRING_OPTION(DefaultForwarding);
325 READ_STD_STRING_OPTION(DefaultRhostsLocalUserName);
326 READ_STD_STRING_OPTION(DefaultRhostsHostPrivateKeyFile);
327 READ_STD_STRING_OPTION(DefaultRSAPrivateKeyFile);
328
329 READ_STD_STRING_OPTION(CipherOrder);
330 normalize_cipher_order(settings->CipherOrder);
331 SSH2_update_cipher_myproposal(pvar); // yutaka
332
333 read_string_option(fileName, "KnownHostsFiles", "ssh_known_hosts",
334 settings->KnownHostsFiles,
335 sizeof(settings->KnownHostsFiles));
336
337 buf[0] = 0;
338 GetPrivateProfileString("TTSSH", "DefaultAuthMethod", "", buf,
339 sizeof(buf), fileName);
340 settings->DefaultAuthMethod = atoi(buf);
341 if (settings->DefaultAuthMethod != SSH_AUTH_PASSWORD
342 && settings->DefaultAuthMethod != SSH_AUTH_RSA
343 && settings->DefaultAuthMethod != SSH_AUTH_RHOSTS) {
344 /* this default can never be SSH_AUTH_RHOSTS_RSA because that is not a
345 selection in the dialog box; SSH_AUTH_RHOSTS_RSA is automatically chosen
346 when the dialog box has rhosts selected and an host private key file
347 is supplied. */
348 settings->DefaultAuthMethod = SSH_AUTH_PASSWORD;
349 }
350
351 buf[0] = 0;
352 GetPrivateProfileString("TTSSH", "LogLevel", "", buf, sizeof(buf),
353 fileName);
354 settings->LogLevel = atoi(buf);
355
356 buf[0] = 0;
357 GetPrivateProfileString("TTSSH", "WriteBufferSize", "", buf,
358 sizeof(buf), fileName);
359 settings->WriteBufferSize = atoi(buf);
360 if (settings->WriteBufferSize <= 0) {
361 settings->WriteBufferSize = 2 * 1024 * 1024;
362 }
363
364 settings->LocalForwardingIdentityCheck =
365 read_BOOL_option(fileName, "LocalForwardingIdentityCheck", TRUE);
366
367 // SSH protocol version (2004.10.11 yutaka)
368 // default is SSH2 (2004.11.30 yutaka)
369 settings->ssh_protocol_version = GetPrivateProfileInt("TTSSH", "ProtocolVersion", 2, fileName);
370
371 // SSH heartbeat time(second) (2004.12.11 yutaka)
372 settings->ssh_heartbeat_overtime = GetPrivateProfileInt("TTSSH", "HeartBeat", 60, fileName);
373
374 clear_local_settings(pvar);
375 }
376
377 static void write_ssh_options(PTInstVar pvar, PCHAR fileName,
378 TS_SSH FAR * settings)
379 {
380 char buf[1024];
381
382 WritePrivateProfileString("TTSSH", "Enabled",
383 settings->Enabled ? "1" : "0", fileName);
384
385 _itoa(settings->CompressionLevel, buf, 10);
386 WritePrivateProfileString("TTSSH", "Compression", buf, fileName);
387
388 WritePrivateProfileString("TTSSH", "DefaultUserName",
389 settings->DefaultUserName, fileName);
390
391 WritePrivateProfileString("TTSSH", "DefaultForwarding",
392 settings->DefaultForwarding, fileName);
393
394 WritePrivateProfileString("TTSSH", "CipherOrder",
395 settings->CipherOrder, fileName);
396
397 WritePrivateProfileString("TTSSH", "KnownHostsFiles",
398 settings->KnownHostsFiles, fileName);
399
400 WritePrivateProfileString("TTSSH", "DefaultRhostsLocalUserName",
401 settings->DefaultRhostsLocalUserName,
402 fileName);
403
404 WritePrivateProfileString("TTSSH", "DefaultRhostsHostPrivateKeyFile",
405 settings->DefaultRhostsHostPrivateKeyFile,
406 fileName);
407
408 WritePrivateProfileString("TTSSH", "DefaultRSAPrivateKeyFile",
409 settings->DefaultRSAPrivateKeyFile,
410 fileName);
411
412 _itoa(settings->DefaultAuthMethod, buf, 10);
413 WritePrivateProfileString("TTSSH", "DefaultAuthMethod", buf, fileName);
414
415 _itoa(settings->LogLevel, buf, 10);
416 WritePrivateProfileString("TTSSH", "LogLevel", buf, fileName);
417
418 _itoa(settings->WriteBufferSize, buf, 10);
419 WritePrivateProfileString("TTSSH", "WriteBufferSize", buf, fileName);
420
421 WritePrivateProfileString("TTSSH", "LocalForwardingIdentityCheck",
422 settings->
423 LocalForwardingIdentityCheck ? "1" : "0",
424 fileName);
425
426 // SSH protocol version (2004.10.11 yutaka)
427 WritePrivateProfileString("TTSSH", "ProtocolVersion",
428 settings->ssh_protocol_version==2 ? "2" : "1",
429 fileName);
430
431 // SSH heartbeat time(second) (2004.12.11 yutaka)
432 _snprintf(buf, sizeof(buf), "%d", settings->ssh_heartbeat_overtime);
433 WritePrivateProfileString("TTSSH", "HeartBeat", buf, fileName);
434
435 }
436
437
438 /* find free port in all protocol family */
439 static unsigned short find_local_port(PTInstVar pvar)
440 {
441 int tries;
442 #ifdef INET6
443 SOCKET connecter;
444 struct addrinfo hints;
445 struct addrinfo FAR *res;
446 struct addrinfo FAR *res0;
447 unsigned short port;
448 char pname[NI_MAXHOST];
449 #endif /* INET6 */
450
451 if (pvar->session_settings.DefaultAuthMethod != SSH_AUTH_RHOSTS) {
452 return 0;
453 }
454
455 /* The random numbers here are only used to try to get fresh
456 ports across runs (dangling ports can cause bind errors
457 if we're unlucky). They do not need to be (and are not)
458 cryptographically strong.
459 */
460 srand((unsigned) GetTickCount());
461
462 #ifdef INET6
463 for (tries = 20; tries > 0; tries--) {
464 memset(&hints, 0, sizeof(hints));
465 hints.ai_family = pvar->ts->ProtocolFamily;
466 hints.ai_flags = AI_PASSIVE;
467 hints.ai_socktype = SOCK_STREAM;
468 port = (unsigned) rand() % 512 + 512;
469 _snprintf(pname, sizeof(pname), "%d", (int) port);
470 if (getaddrinfo(NULL, pname, &hints, &res0)) {
471 return 0;
472 /* NOT REACHED */
473 }
474
475 for (res = res0; res; res = res->ai_next) {
476 if (res->ai_family == AF_INET || res->ai_family == AF_INET6)
477 continue;
478
479 connecter =
480 socket(res->ai_family, res->ai_socktype, res->ai_protocol);
481 if (connecter == INVALID_SOCKET) {
482 freeaddrinfo(res0);
483 return 0;
484 }
485
486 if (bind(connecter, res->ai_addr, res->ai_addrlen) !=
487 SOCKET_ERROR) {
488 return port;
489 freeaddrinfo(res0);
490 closesocket(connecter);
491 } else if (WSAGetLastError() != WSAEADDRINUSE) {
492 closesocket(connecter);
493 freeaddrinfo(res0);
494 return 0;
495 }
496
497 closesocket(connecter);
498 }
499 freeaddrinfo(res0);
500 }
501
502 return 0;
503 #else
504 for (tries = 20; tries > 0; tries--) {
505 SOCKET connecter = socket(AF_INET, SOCK_STREAM, 0);
506 struct sockaddr_in connecter_addr;
507
508 connecter_addr.sin_family = AF_INET;
509 connecter_addr.sin_port = (unsigned) rand() % 512 + 512;
510 connecter_addr.sin_addr.s_addr = htonl(INADDR_ANY);
511
512 if (connecter == INVALID_SOCKET) {
513 return 0;
514 }
515
516 if (bind
517 (connecter, (struct sockaddr FAR *) &connecter_addr,
518 sizeof(connecter_addr)) != SOCKET_ERROR) {
519 closesocket(connecter);
520 return connecter_addr.sin_port;
521 } else if (WSAGetLastError() != WSAEADDRINUSE) {
522 closesocket(connecter);
523 return 0;
524 }
525
526 closesocket(connecter);
527 }
528
529 return 0;
530 #endif /* INET6 */
531 }
532
533 static int PASCAL FAR TTXconnect(SOCKET s,
534 const struct sockaddr FAR * name,
535 int namelen)
536 {
537 GET_VAR();
538
539 #ifdef INET6
540 if (pvar->socket == INVALID_SOCKET) {
541 struct sockaddr_storage ss;
542 int len;
543
544 pvar->socket = s;
545
546 memset(&ss, 0, sizeof(ss));
547 switch (pvar->ts->ProtocolFamily) {
548 case AF_INET:
549 len = sizeof(struct sockaddr_in);
550 ((struct sockaddr_in FAR *) &ss)->sin_family = AF_INET;
551 ((struct sockaddr_in FAR *) &ss)->sin_addr.s_addr = INADDR_ANY;
552 ((struct sockaddr_in FAR *) &ss)->sin_port =
553 htons(find_local_port(pvar));
554 break;
555 case AF_INET6:
556 len = sizeof(struct sockaddr_in6);
557 ((struct sockaddr_in6 FAR *) &ss)->sin6_family = AF_INET6;
558 #if 0 /* symbol "in6addr_any" is not included in wsock32.lib */
559 /* if wsock32.lib will be linked, we can't refer "in6addr_any" */
560 ((struct sockaddr_in6 FAR *) &ss)->sin6_addr = in6addr_any;
561 #eles
562 memset(&((struct sockaddr_in6 FAR *) &ss)->sin6_addr, 0,
563 sizeof(struct in_addr6));
564 #endif /* 0 */
565 ((struct sockaddr_in6 FAR *) &ss)->sin6_port =
566 htons(find_local_port(pvar));
567 break;
568 default:
569 /* NOT REACHED */
570 break;
571 }
572
573 bind(s, (struct sockaddr FAR *) &ss, len);
574 }
575 #else
576 if (pvar->socket == INVALID_SOCKET) {
577 struct sockaddr_in addr;
578
579 pvar->socket = s;
580
581 addr.sin_family = AF_INET;
582 addr.sin_port = htons(find_local_port(pvar));
583 addr.sin_addr.s_addr = INADDR_ANY;
584 memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
585
586 bind(s, (struct sockaddr FAR *) &addr, sizeof(addr));
587 }
588 #endif /* INET6 */
589
590 return (pvar->Pconnect) (s, name, namelen);
591 }
592
593 static int PASCAL FAR TTXWSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,
594 long lEvent)
595 {
596 GET_VAR();
597
598 if (s == pvar->socket) {
599 pvar->notification_events = lEvent;
600 pvar->notification_msg = wMsg;
601
602 if (pvar->NotificationWindow == NULL) {
603 pvar->NotificationWindow = hWnd;
604 AUTH_advance_to_next_cred(pvar);
605 }
606 }
607
608 return (pvar->PWSAAsyncSelect) (s, hWnd, wMsg, lEvent);
609 }
610
611 static int PASCAL FAR TTXrecv(SOCKET s, char FAR * buf, int len, int flags)
612 {
613 GET_VAR();
614
615 if (s == pvar->socket) {
616 int ret;
617
618 ssh_heartbeat_lock();
619 ret = PKT_recv(pvar, buf, len);
620 ssh_heartbeat_unlock();
621 return (ret);
622
623 } else {
624 return (pvar->Precv) (s, buf, len, flags);
625 }
626 }
627
628 static int PASCAL FAR TTXsend(SOCKET s, char const FAR * buf, int len,
629 int flags)
630 {
631 GET_VAR();
632
633 if (s == pvar->socket) {
634 ssh_heartbeat_lock();
635 SSH_send(pvar, buf, len);
636 ssh_heartbeat_unlock();
637 return len;
638 } else {
639 return (pvar->Psend) (s, buf, len, flags);
640 }
641 }
642
643 void notify_established_secure_connection(PTInstVar pvar)
644 {
645 #ifdef TERATERM32
646 if (SecureIcon == NULL) {
647 SecureIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_SECURETT));
648 }
649
650 if (SecureIcon != NULL) {
651 pvar->OldSmallIcon =
652 (HICON) SendMessage(pvar->NotificationWindow, WM_GETICON,
653 ICON_SMALL, 0);
654 pvar->OldLargeIcon =
655 (HICON) SendMessage(pvar->NotificationWindow, WM_GETICON,
656 ICON_BIG, 0);
657 PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_BIG,
658 (LPARAM) SecureIcon);
659 PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_SMALL,
660 (LPARAM) SecureIcon);
661 }
662 #endif
663
664 notify_verbose_message(pvar, "Entering secure mode",
665 LOG_LEVEL_VERBOSE);
666 }
667
668 void notify_closed_connection(PTInstVar pvar)
669 {
670 PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,
671 pvar->socket, MAKELPARAM(FD_CLOSE, 0));
672
673 SSH_notify_disconnecting(pvar, NULL);
674 AUTH_notify_disconnecting(pvar);
675 HOSTS_notify_disconnecting(pvar);
676 }
677
678 static void add_err_msg(PTInstVar pvar, char FAR * msg)
679 {
680 if (pvar->err_msg != NULL) {
681 char FAR *buf =
682 (char FAR *) malloc(strlen(pvar->err_msg) + 3 + strlen(msg));
683
684 strcpy(buf, pvar->err_msg);
685 strcat(buf, "\n\n");
686 strcat(buf, msg);
687 free(pvar->err_msg);
688 pvar->err_msg = buf;
689 } else {
690 pvar->err_msg = _strdup(msg);
691 }
692 }
693
694 void notify_nonfatal_error(PTInstVar pvar, char FAR * msg)
695 {
696 if (!pvar->showing_err) {
697 PostMessage(pvar->NotificationWindow, WM_COMMAND,
698 ID_SSHASYNCMESSAGEBOX, 0);
699 }
700 if (msg[0] != 0) {
701 notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
702 add_err_msg(pvar, msg);
703 }
704 }
705
706 void notify_fatal_error(PTInstVar pvar, char FAR * msg)
707 {
708 if (msg[0] != 0) {
709 notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
710 add_err_msg(pvar, msg);
711 }
712
713 if (!pvar->fatal_error) {
714 pvar->fatal_error = TRUE;
715
716 SSH_notify_disconnecting(pvar, msg);
717 AUTH_notify_disconnecting(pvar);
718 HOSTS_notify_disconnecting(pvar);
719
720 PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,
721 pvar->socket, MAKELPARAM(FD_CLOSE,
722 (pvar->PWSAGetLastError) ()));
723 }
724 }
725
726 void notify_verbose_message(PTInstVar pvar, char FAR * msg, int level)
727 {
728 if (level <= pvar->session_settings.LogLevel) {
729 char buf[1024];
730 int file;
731
732 get_teraterm_dir_relative_name(buf, NUM_ELEM(buf), "TTSSH.LOG");
733 file = _open(buf, _O_RDWR | _O_APPEND | _O_CREAT | _O_TEXT,
734 _S_IREAD | _S_IWRITE);
735
736 if (file >= 0) {
737 _write(file, msg, strlen(msg));
738 _write(file, "\n", 1);
739 _close(file);
740 }
741 }
742 }
743
744 static void PASCAL FAR TTXOpenTCP(TTXSockHooks FAR * hooks)
745 {
746 GET_VAR();
747
748 if (pvar->settings.Enabled) {
749 char buf[1024] = "\nInitiating SSH session at ";
750 struct tm FAR *newtime;
751 time_t long_time;
752
753 pvar->session_settings = pvar->settings;
754
755 time(&long_time);
756 newtime = localtime(&long_time);
757 strcat(buf, asctime(newtime));
758 buf[strlen(buf) - 1] = 0;
759 notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE);
760
761 FWDUI_load_settings(pvar);
762
763 pvar->cv->TelAutoDetect = FALSE;
764 /* This next line should not be needed because Teraterm's
765 CommLib should find ts->Telnet == 0 ... but we'll do this
766 just to be on the safe side. */
767 pvar->cv->TelFlag = FALSE;
768
769 pvar->Precv = *hooks->Precv;
770 pvar->Psend = *hooks->Psend;
771 pvar->PWSAAsyncSelect = *hooks->PWSAAsyncSelect;
772 pvar->Pconnect = *hooks->Pconnect;
773 pvar->PWSAGetLastError = *hooks->PWSAGetLastError;
774
775 *hooks->Precv = TTXrecv;
776 *hooks->Psend = TTXsend;
777 *hooks->PWSAAsyncSelect = TTXWSAAsyncSelect;
778 *hooks->Pconnect = TTXconnect;
779
780 SSH_open(pvar);
781 HOSTS_open(pvar);
782 FWDUI_open(pvar);
783 }
784 }
785
786 static void PASCAL FAR TTXCloseTCP(TTXSockHooks FAR * hooks)
787 {
788 GET_VAR();
789
790 if (pvar->session_settings.Enabled) {
791 pvar->socket = INVALID_SOCKET;
792
793 notify_verbose_message(pvar, "Terminating SSH session...",
794 LOG_LEVEL_VERBOSE);
795
796 *hooks->Precv = pvar->Precv;
797 *hooks->Psend = pvar->Psend;
798 *hooks->PWSAAsyncSelect = pvar->PWSAAsyncSelect;
799 *hooks->Pconnect = pvar->Pconnect;
800 }
801
802 uninit_TTSSH(pvar);
803 init_TTSSH(pvar);
804 }
805
806 static void enable_dlg_items(HWND dlg, int from, int to, BOOL enabled)
807 {
808 for (; from <= to; from++) {
809 EnableWindow(GetDlgItem(dlg, from), enabled);
810 }
811 }
812
813 static BOOL CALLBACK TTXHostDlg(HWND dlg, UINT msg, WPARAM wParam,
814 LPARAM lParam)
815 {
816 static char *ssh_version[] = {"SSH1", "SSH2", NULL};
817 PGetHNRec GetHNRec;
818 char EntName[7];
819 char TempHost[HostNameMaxLength + 1];
820 WORD i, j, w;
821 BOOL Ok;
822
823 GET_VAR();
824
825 switch (msg) {
826 case WM_INITDIALOG:
827 GetHNRec = (PGetHNRec) lParam;
828 SetWindowLong(dlg, DWL_USER, lParam);
829
830 if (GetHNRec->PortType == IdFile)
831 GetHNRec->PortType = IdTCPIP;
832 CheckRadioButton(dlg, IDC_HOSTTCPIP, IDC_HOSTSERIAL,
833 IDC_HOSTTCPIP + GetHNRec->PortType - 1);
834
835 strcpy(EntName, "Host");
836
837 i = 1;
838 do {
839 sprintf(&EntName[4], "%d", i);
840 GetPrivateProfileString("Hosts", EntName, "",
841 TempHost, sizeof(TempHost),
842 GetHNRec->SetupFN);
843 if (strlen(TempHost) > 0)
844 SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_ADDSTRING,
845 0, (LPARAM) TempHost);
846 i++;
847 } while ((i <= 99) && (strlen(TempHost) > 0));
848
849 SendDlgItemMessage(dlg, IDC_HOSTNAME, EM_LIMITTEXT,
850 HostNameMaxLength - 1, 0);
851
852 SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_SETCURSEL, 0, 0);
853
854 CheckRadioButton(dlg, IDC_HOSTTELNET, IDC_HOSTOTHER,
855 pvar->settings.Enabled ? IDC_HOSTSSH : GetHNRec->
856 Telnet ? IDC_HOSTTELNET : IDC_HOSTOTHER);
857 SendDlgItemMessage(dlg, IDC_HOSTTCPPORT, EM_LIMITTEXT, 5, 0);
858 SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TCPPort, FALSE);
859 #ifdef INET6
860 for (i = 0; ProtocolFamilyList[i]; ++i) {
861 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_ADDSTRING,
862 0, (LPARAM) ProtocolFamilyList[i]);
863 }
864 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, EM_LIMITTEXT,
865 ProtocolFamilyMaxLength - 1, 0);
866 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_SETCURSEL, 0, 0);
867 #endif /* INET6 */
868
869 /////// SSH version
870 for (i = 0; ssh_version[i]; ++i) {
871 SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_ADDSTRING,
872 0, (LPARAM) ssh_version[i]);
873 }
874 SendDlgItemMessage(dlg, IDC_SSH_VERSION, EM_LIMITTEXT,
875 NUM_ELEM(ssh_version) - 1, 0);
876
877 if (pvar->settings.ssh_protocol_version == 1) {
878 SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 0, 0); // SSH1
879 } else {
880 SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 1, 0); // SSH2
881 }
882
883 if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
884 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE); // enabled
885 } else {
886 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
887 }
888 /////// SSH version
889
890
891 j = 0;
892 w = 1;
893 strcpy(EntName, "COM");
894 for (i = 1; i <= GetHNRec->MaxComPort; i++) {
895 sprintf(&EntName[3], "%d", i);
896 SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_ADDSTRING,
897 0, (LPARAM) EntName);
898 j++;
899 if (GetHNRec->ComPort == i)
900 w = j;
901 }
902 if (j > 0)
903 SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_SETCURSEL, w - 1, 0);
904 else /* All com ports are already used */
905 GetHNRec->PortType = IdTCPIP;
906
907 if (GetHNRec->PortType == IdTCPIP)
908 enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
909 #ifdef INET6
910 else {
911 enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
912 FALSE);
913 enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
914 IDC_HOSTTCPPROTOCOL, FALSE);
915 }
916 #else
917 else
918 enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
919 FALSE);
920 #endif /* INET6 */
921
922 // Host dialog���t�H�[�J�X�������� (2004.10.2 yutaka)
923 {
924 HWND hwnd = GetDlgItem(dlg, IDC_HOSTNAME);
925
926 SetFocus(hwnd);
927 //SendMessage(hwnd, BM_SETCHECK, BST_CHECKED, 0);
928 //style = GetClassLongPtr(hwnd, GCL_STYLE);
929 //SetClassLongPtr(hwnd, GCL_STYLE, style | WS_TABSTOP);
930 }
931
932 // SetFocus()���t�H�[�J�X���������������AFALSE�������K�v�������B
933 // TRUE���������ATABSTOP�������������������R���g���[�����I�������B
934 // (2004.11.23 yutaka)
935 return FALSE;
936 //return TRUE;
937
938 case WM_COMMAND:
939 switch (LOWORD(wParam)) {
940 case IDOK:
941 GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
942 if (GetHNRec != NULL) {
943 if (IsDlgButtonChecked(dlg, IDC_HOSTTCPIP)) {
944 #ifdef INET6
945 char afstr[BUFSIZ];
946 #endif /* INET6 */
947 i = GetDlgItemInt(dlg, IDC_HOSTTCPPORT, &Ok, FALSE);
948 if (Ok) {
949 GetHNRec->TCPPort = i;
950 } else {
951 MessageBox(dlg, "Teraterm",
952 "The TCP port must be a number.",
953 MB_OK | MB_ICONEXCLAMATION);
954 return TRUE;
955 }
956 #ifdef INET6
957 #define getaf(str) \
958 ((strcmp((str), "IPv6") == 0) ? AF_INET6 : \
959 ((strcmp((str), "IPv4") == 0) ? AF_INET : AF_UNSPEC))
960 memset(afstr, 0, sizeof(afstr));
961 GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOL, afstr,
962 sizeof(afstr));
963 GetHNRec->ProtocolFamily = getaf(afstr);
964 #endif /* INET6 */
965 GetHNRec->PortType = IdTCPIP;
966 GetDlgItemText(dlg, IDC_HOSTNAME, GetHNRec->HostName,
967 HostNameMaxLength);
968 GetHNRec->Telnet = FALSE;
969 pvar->hostdlg_activated = TRUE;
970 pvar->hostdlg_Enabled = FALSE;
971 if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
972 GetHNRec->Telnet = TRUE;
973 } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
974 pvar->hostdlg_Enabled = TRUE;
975
976 // check SSH protocol version
977 memset(afstr, 0, sizeof(afstr));
978 GetDlgItemText(dlg, IDC_SSH_VERSION, afstr, sizeof(afstr));
979 if (stricmp(afstr, "SSH1") == 0) {
980 pvar->settings.ssh_protocol_version = 1;
981 } else {
982 pvar->settings.ssh_protocol_version = 2;
983 }
984 }
985 } else {
986 GetHNRec->PortType = IdSerial;
987 GetHNRec->HostName[0] = 0;
988 memset(EntName, 0, sizeof(EntName));
989 GetDlgItemText(dlg, IDC_HOSTCOM, EntName,
990 sizeof(EntName) - 1);
991 GetHNRec->ComPort = (BYTE) (EntName[3]) - 0x30;
992 if (strlen(EntName) > 4)
993 GetHNRec->ComPort =
994 GetHNRec->ComPort * 10 + (BYTE) (EntName[4]) -
995 0x30;
996 }
997 }
998 EndDialog(dlg, 1);
999 return TRUE;
1000
1001 case IDCANCEL:
1002 EndDialog(dlg, 0);
1003 return TRUE;
1004
1005 case IDC_HOSTTCPIP:
1006 enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1007 TRUE);
1008 #ifdef INET6
1009 enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1010 IDC_HOSTTCPPROTOCOL, TRUE);
1011 #endif /* INET6 */
1012 enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
1013
1014 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE); // disabled (2004.11.23 yutaka)
1015 if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1016 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE);
1017 } else {
1018 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1019 }
1020
1021 return TRUE;
1022
1023 case IDC_HOSTSERIAL:
1024 enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, TRUE);
1025 enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1026 FALSE);
1027 #ifdef INET6
1028 enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1029 IDC_HOSTTCPPROTOCOL, FALSE);
1030 #endif /* INET6 */
1031 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1032 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1033
1034 return TRUE;
1035
1036 case IDC_HOSTSSH:
1037 enable_dlg_items(dlg, IDC_SSH_VERSION,
1038 IDC_SSH_VERSION, TRUE);
1039 goto hostssh_enabled;
1040
1041 case IDC_HOSTTELNET:
1042 case IDC_HOSTOTHER:
1043 enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1044 hostssh_enabled:
1045
1046 GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1047
1048 if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1049 if (GetHNRec != NULL)
1050 SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TelPort,
1051 FALSE);
1052 } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1053 SetDlgItemInt(dlg, IDC_HOSTTCPPORT, 22, FALSE);
1054 }
1055 return TRUE;
1056
1057 case IDC_HOSTHELP:
1058 PostMessage(GetParent(dlg), WM_USER_DLGHELP2, 0, 0);
1059 }
1060 }
1061 return FALSE;
1062 }
1063
1064 static BOOL FAR PASCAL TTXGetHostName(HWND parent, PGetHNRec rec)
1065 {
1066 return (BOOL) DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HOSTDLG),
1067 parent, TTXHostDlg, (LONG) rec);
1068 }
1069
1070 static void PASCAL FAR TTXGetUIHooks(TTXUIHooks FAR * hooks)
1071 {
1072 GET_VAR();
1073
1074 *hooks->GetHostName = TTXGetHostName;
1075 }
1076
1077 static void FAR PASCAL TTXReadINIFile(PCHAR fileName, PTTSet ts)
1078 {
1079 GET_VAR();
1080
1081 (pvar->ReadIniFile) (fileName, ts);
1082 read_ssh_options(pvar, fileName);
1083 pvar->settings = *pvar->ts_SSH;
1084 notify_verbose_message(pvar, "Reading INI file", LOG_LEVEL_VERBOSE);
1085 FWDUI_load_settings(pvar);
1086 }
1087
1088 static void FAR PASCAL TTXWriteINIFile(PCHAR fileName, PTTSet ts)
1089 {
1090 GET_VAR();
1091
1092 (pvar->WriteIniFile) (fileName, ts);
1093 *pvar->ts_SSH = pvar->settings;
1094 clear_local_settings(pvar);
1095 notify_verbose_message(pvar, "Writing INI file", LOG_LEVEL_VERBOSE);
1096 write_ssh_options(pvar, fileName, pvar->ts_SSH);
1097 }
1098
1099 static void read_ssh_options_from_user_file(PTInstVar pvar,
1100 char FAR * user_file_name)
1101 {
1102 if (user_file_name[0] == '.') {
1103 read_ssh_options(pvar, user_file_name);
1104 } else {
1105 char buf[1024];
1106
1107 get_teraterm_dir_relative_name(buf, sizeof(buf), user_file_name);
1108 read_ssh_options(pvar, buf);
1109 }
1110
1111 pvar->settings = *pvar->ts_SSH;
1112 FWDUI_load_settings(pvar);
1113 }
1114
1115 /* returns 1 if the option text must be deleted */
1116 static int parse_option(PTInstVar pvar, char FAR * option)
1117 {
1118 if ((option[0] == '-' || option[0] == '/')) {
1119 if (MATCH_STR(option + 1, "ssh") == 0) {
1120 if (option[4] == 0) {
1121 pvar->settings.Enabled = 1;
1122 } else if (MATCH_STR(option + 4, "-L") == 0
1123 || MATCH_STR(option + 4, "-R") == 0
1124 || stricmp(option + 4, "-X") == 0) {
1125 if (pvar->settings.DefaultForwarding[0] == 0) {
1126 strcpy(pvar->settings.DefaultForwarding, option + 5);
1127 } else {
1128 strcat(pvar->settings.DefaultForwarding, ";");
1129 strcat(pvar->settings.DefaultForwarding, option + 5);
1130 }
1131 } else if (MATCH_STR(option + 4, "-f=") == 0) {
1132 read_ssh_options_from_user_file(pvar, option + 7);
1133 } else if (MATCH_STR(option + 4, "-v") == 0) {
1134 pvar->settings.LogLevel = LOG_LEVEL_VERBOSE;
1135 } else if (stricmp(option + 4, "-autologin") == 0
1136 || stricmp(option + 4, "-autologon") == 0) {
1137 pvar->settings.TryDefaultAuth = TRUE;
1138
1139 } else if (MATCH_STR(option + 4, "-consume=") == 0) {
1140 read_ssh_options_from_user_file(pvar, option + 13);
1141 DeleteFile(option + 13);
1142 } else {
1143 char buf[1024];
1144
1145 _snprintf(buf, sizeof(buf),
1146 "Unrecognized command-line option: %s", option);
1147 buf[sizeof(buf) - 1] = 0;
1148
1149 MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
1150 }
1151
1152 return 1;
1153 } else if (MATCH_STR(option + 1, "t=") == 0) {
1154 if (strcmp(option + 3, "2") == 0) {
1155 pvar->settings.Enabled = 1;
1156 return 1;
1157 } else {
1158 pvar->settings.Enabled = 0;
1159 }
1160 } else if (MATCH_STR(option + 1, "f=") == 0) {
1161 read_ssh_options_from_user_file(pvar, option + 3);
1162
1163 // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
1164 } else if (MATCH_STR(option + 1, "1") == 0) {
1165 // command line: /ssh /1 is SSH1 only
1166 pvar->settings.ssh_protocol_version = 1;
1167
1168 } else if (MATCH_STR(option + 1, "2") == 0) {
1169 // command line: /ssh /2 is SSH2 & SSH1
1170 pvar->settings.ssh_protocol_version = 2;
1171
1172 } else if (MATCH_STR(option + 1, "nossh") == 0) {
1173 // '/nossh' �I�v�V�����������B
1174 // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
1175 // �����������������B(2004.10.11 yutaka)
1176 pvar->settings.Enabled = 0;
1177
1178 } else if (MATCH_STR(option + 1, "auth") == 0) {
1179 // SSH2�������O�C���I�v�V���������� (2004.11.30 yutaka)
1180 //
1181 // SYNOPSIS: /ssh /auth=�F�����\�b�h /user=���[�U�� /passwd=�p�X���[�h
1182 // EXAMPLE: /ssh /auth=password /user=nike "/passwd=a b c"
1183 // NOTICE: �p�X���[�h�����������������������A�I�v�V�����S�������p�������������B
1184 //
1185 pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
1186
1187 if (MATCH_STR(option + 5, "=password") == 0) { // �p�X���[�h�F��
1188 pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
1189
1190 } else {
1191 // TODO:
1192
1193 }
1194
1195 } else if (MATCH_STR(option + 1, "user=") == 0) {
1196 _snprintf(pvar->ssh2_username, sizeof(pvar->ssh2_username), "%s", option + 6);
1197
1198 } else if (MATCH_STR(option + 1, "passwd=") == 0) {
1199 _snprintf(pvar->ssh2_password, sizeof(pvar->ssh2_password), "%s", option + 8);
1200
1201 }
1202
1203 }
1204
1205 return 0;
1206 }
1207
1208 static void FAR PASCAL TTXParseParam(PCHAR param, PTTSet ts,
1209 PCHAR DDETopic)
1210 {
1211 int i;
1212 BOOL inParam = FALSE;
1213 BOOL inQuotes = FALSE;
1214 PCHAR option = NULL;
1215 GET_VAR();
1216
1217 if (pvar->hostdlg_activated) {
1218 pvar->settings.Enabled = pvar->hostdlg_Enabled;
1219 }
1220
1221 for (i = 0; param[i] != 0; i++) {
1222 if (inQuotes ? param[i] ==
1223 '"' : (param[i] == ' ' || param[i] == '\t')) {
1224 if (option != NULL) {
1225 char ch = param[i];
1226
1227 param[i] = 0;
1228 if (parse_option
1229 (pvar, *option == '"' ? option + 1 : option)) {
1230 memset(option, ' ', i + 1 - (option - param));
1231 } else {
1232 param[i] = ch;
1233 }
1234 option = NULL;
1235 }
1236 inParam = FALSE;
1237 inQuotes = FALSE;
1238 } else if (!inParam) {
1239 if (param[i] == '"') {
1240 inQuotes = TRUE;
1241 inParam = TRUE;
1242 option = param + i;
1243 } else if (param[i] != ' ' && param[i] != '\t') {
1244 inParam = TRUE;
1245 option = param + i;
1246 }
1247 }
1248 }
1249
1250 if (option != NULL) {
1251 if (parse_option(pvar, option)) {
1252 memset(option, ' ', i - (option - param));
1253 }
1254 }
1255
1256 FWDUI_load_settings(pvar);
1257
1258 (pvar->ParseParam) (param, ts, DDETopic);
1259
1260 }
1261
1262 static void PASCAL FAR TTXGetSetupHooks(TTXSetupHooks FAR * hooks)
1263 {
1264 GET_VAR();
1265
1266 pvar->ReadIniFile = *hooks->ReadIniFile;
1267 pvar->WriteIniFile = *hooks->WriteIniFile;
1268 pvar->ParseParam = *hooks->ParseParam;
1269
1270 *hooks->ReadIniFile = TTXReadINIFile;
1271 *hooks->WriteIniFile = TTXWriteINIFile;
1272 *hooks->ParseParam = TTXParseParam;
1273 }
1274
1275 static void PASCAL FAR TTXSetWinSize(int rows, int cols)
1276 {
1277 GET_VAR();
1278
1279 SSH_notify_win_size(pvar, cols, rows);
1280 }
1281
1282 static void insertMenuBeforeItem(HMENU menu, WORD beforeItemID, WORD flags,
1283 WORD newItemID, char FAR * text)
1284 {
1285 int i, j;
1286
1287 for (i = GetMenuItemCount(menu) - 1; i >= 0; i--) {
1288 HMENU submenu = GetSubMenu(menu, i);
1289
1290 for (j = GetMenuItemCount(submenu) - 1; j >= 0; j--) {
1291 if (GetMenuItemID(submenu, j) == beforeItemID) {
1292 InsertMenu(submenu, j, MF_BYPOSITION | flags, newItemID,
1293 text);
1294 return;
1295 }
1296 }
1297 }
1298 }
1299
1300 static void PASCAL FAR TTXModifyMenu(HMENU menu)
1301 {
1302 GET_VAR();
1303
1304 /* inserts before ID_HELP_ABOUT */
1305 insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU,
1306 "About &TTSSH...");
1307
1308 /* inserts before ID_SETUP_TCPIP */
1309 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU,
1310 "SS&H...");
1311 /* inserts before ID_SETUP_TCPIP */
1312 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU,
1313 "SSH &Authentication...");
1314 /* inserts before ID_SETUP_TCPIP */
1315 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU,
1316 "SSH F&orwarding...");
1317 }
1318
1319 static void append_about_text(HWND dlg, char FAR * prefix, char FAR * msg)
1320 {
1321 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
1322 (LPARAM) prefix);
1323 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0, (LPARAM) msg);
1324 SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
1325 (LPARAM) (char FAR *) "\r\n");
1326 }
1327
1328 static void init_about_dlg(PTInstVar pvar, HWND dlg)
1329 {
1330 char buf[1024];
1331
1332 // TTSSH�_�C�A���O���\������SSH������������ (2004.10.30 yutaka)
1333
1334 if (pvar->socket != INVALID_SOCKET) {
1335 if (SSHv1(pvar)) {
1336 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
1337 append_about_text(dlg, "Server ID: ", buf);
1338 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
1339 append_about_text(dlg, "Using protocol: ", buf);
1340 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
1341 append_about_text(dlg, "Encryption: ", buf);
1342 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
1343 append_about_text(dlg, "Server keys: ", buf);
1344 AUTH_get_auth_info(pvar, buf, sizeof(buf));
1345 append_about_text(dlg, "Authentication: ", buf);
1346 SSH_get_compression_info(pvar, buf, sizeof(buf));
1347 append_about_text(dlg, "Compression: ", buf);
1348
1349 } else { // SSH2
1350 SSH_get_server_ID_info(pvar, buf, sizeof(buf));
1351 append_about_text(dlg, "Server ID: ", buf);
1352
1353 append_about_text(dlg, "Client ID: ", pvar->client_version_string);
1354
1355 SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
1356 append_about_text(dlg, "Using protocol: ", buf);
1357
1358 if (pvar->kex_type == KEX_DH_GRP1_SHA1) {
1359 strcpy(buf, KEX_DH1);
1360 } else if (pvar->kex_type == KEX_DH_GRP14_SHA1) {
1361 strcpy(buf, KEX_DH14);
1362 } else {
1363 strcpy(buf, KEX_DHGEX);
1364 }
1365 append_about_text(dlg, "KEX: ", buf);
1366
1367 if (pvar->hostkey_type == KEY_DSA) {
1368 strcpy(buf, "ssh-dss");
1369 } else {
1370 strcpy(buf, "ssh-rsa");
1371 }
1372 append_about_text(dlg, "Host Key: ", buf);
1373
1374 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
1375 append_about_text(dlg, "Encryption: ", buf);
1376 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
1377 append_about_text(dlg, "Server keys: ", buf);
1378 AUTH_get_auth_info(pvar, buf, sizeof(buf));
1379 append_about_text(dlg, "Authentication: ", buf);
1380 SSH_get_compression_info(pvar, buf, sizeof(buf));
1381 append_about_text(dlg, "Compression: ", buf);
1382
1383 }
1384 }
1385 }
1386
1387 static BOOL CALLBACK TTXAboutDlg(HWND dlg, UINT msg, WPARAM wParam,
1388 LPARAM lParam)
1389 {
1390 switch (msg) {
1391 case WM_INITDIALOG:
1392 init_about_dlg((PTInstVar) lParam, dlg);
1393 return TRUE;
1394 case WM_COMMAND:
1395 switch (LOWORD(wParam)) {
1396 case IDOK:
1397 EndDialog(dlg, 1);
1398 return TRUE;
1399 case IDCANCEL: /* there isn't a cancel button, but other Windows
1400 UI things can send this message */
1401 EndDialog(dlg, 0);
1402 return TRUE;
1403 }
1404 break;
1405 }
1406
1407 return FALSE;
1408 }
1409
1410 static char FAR *get_cipher_name(int cipher)
1411 {
1412 switch (cipher) {
1413 case SSH_CIPHER_NONE:
1414 return "<ciphers below this line are disabled>";
1415 case SSH_CIPHER_RC4:
1416 return "RC4";
1417 case SSH_CIPHER_3DES:
1418 return "3DES";
1419 case SSH_CIPHER_DES:
1420 return "DES";
1421 case SSH_CIPHER_IDEA:
1422 return "IDEA";
1423 case SSH_CIPHER_TSS:
1424 return "TSS";
1425 case SSH_CIPHER_BLOWFISH:
1426 return "Blowfish";
1427
1428 // for SSH2(yutaka)
1429 case SSH_CIPHER_AES128:
1430 return "AES128(SSH2)";
1431 case SSH_CIPHER_3DES_CBC:
1432 return "3DES-CBC(SSH2)";
1433
1434 default:
1435 return NULL;
1436 }
1437 }
1438
1439 static void set_move_button_status(HWND dlg)
1440 {
1441 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
1442 int curPos = (int) SendMessage(cipherControl, LB_GETCURSEL, 0, 0);
1443 int maxPos = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0) - 1;
1444
1445 EnableWindow(GetDlgItem(dlg, IDC_SSHMOVECIPHERUP), curPos > 0
1446 && curPos <= maxPos);
1447 EnableWindow(GetDlgItem(dlg, IDC_SSHMOVECIPHERDOWN), curPos >= 0
1448 && curPos < maxPos);
1449 }
1450
1451 static void init_setup_dlg(PTInstVar pvar, HWND dlg)
1452 {
1453 HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
1454 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
1455 int i;
1456 int ch;
1457
1458 SendMessage(compressionControl, TBM_SETRANGE, TRUE, MAKELONG(0, 9));
1459 SendMessage(compressionControl, TBM_SETPOS, TRUE,
1460 pvar->settings.CompressionLevel);
1461
1462 normalize_cipher_order(pvar->settings.CipherOrder);
1463 SSH2_update_cipher_myproposal(pvar); // yutaka
1464
1465 for (i = 0; pvar->settings.CipherOrder[i] != 0; i++) {
1466 int cipher = pvar->settings.CipherOrder[i] - '0';
1467 char FAR *name = get_cipher_name(cipher);
1468
1469 if (name != NULL) {
1470 SendMessage(cipherControl, LB_ADDSTRING, 0, (LPARAM) name);
1471 }
1472 }
1473
1474 SendMessage(cipherControl, LB_SETCURSEL, 0, 0);
1475 set_move_button_status(dlg);
1476
1477 for (i = 0; (ch = pvar->settings.KnownHostsFiles[i]) != 0 && ch != ';';
1478 i++) {
1479 }
1480 if (ch != 0) {
1481 pvar->settings.KnownHostsFiles[i] = 0;
1482 SetDlgItemText(dlg, IDC_READWRITEFILENAME,
1483 pvar->settings.KnownHostsFiles);
1484 pvar->settings.KnownHostsFiles[i] = ch;
1485 SetDlgItemText(dlg, IDC_READONLYFILENAME,
1486 pvar->settings.KnownHostsFiles + i + 1);
1487 } else {
1488 SetDlgItemText(dlg, IDC_READWRITEFILENAME,
1489 pvar->settings.KnownHostsFiles);
1490 }
1491 }
1492
1493 void get_teraterm_dir_relative_name(char FAR * buf, int bufsize,
1494 char FAR * basename)
1495 {
1496 int filename_start = 0;
1497 int i;
1498 int ch;
1499
1500 if (basename[0] == '\\' || basename[0] == '/'
1501 || (basename[0] != 0 && basename[1] == ':')) {
1502 strncpy(buf, basename, bufsize);
1503 buf[bufsize - 1] = 0;
1504 return;
1505 }
1506
1507 GetModuleFileName(NULL, buf, bufsize);
1508 for (i = 0; (ch = buf[i]) != 0; i++) {
1509 if (ch == '\\' || ch == '/' || ch == ':') {
1510 filename_start = i + 1;
1511 }
1512 }
1513
1514 if (bufsize > filename_start) {
1515 strncpy(buf + filename_start, basename, bufsize - filename_start);
1516 }
1517 buf[bufsize - 1] = 0;
1518 }
1519
1520 int copy_teraterm_dir_relative_path(char FAR * dest, int destsize,
1521 char FAR * basename)
1522 {
1523 char buf[1024];
1524 int filename_start = 0;
1525 int i;
1526 int ch, ch2;
1527
1528 if (basename[0] != '\\' && basename[0] != '/'
1529 && (basename[0] == 0 || basename[1] != ':')) {
1530 strncpy(dest, basename, destsize);
1531 dest[destsize - 1] = 0;
1532 return strlen(dest);
1533 }
1534
1535 GetModuleFileName(NULL, buf, sizeof(buf));
1536 for (i = 0; (ch = buf[i]) != 0; i++) {
1537 if (ch == '\\' || ch == '/' || ch == ':') {
1538 filename_start = i + 1;
1539 }
1540 }
1541
1542 for (i = 0; i < filename_start; i++) {
1543 ch = toupper(buf[i]);
1544 ch2 = toupper(basename[i]);
1545
1546 if (ch == ch2
1547 || ((ch == '\\' || ch == '/')
1548 && (ch2 == '\\' || ch2 == '/'))) {
1549 } else {
1550 break;
1551 }
1552 }
1553
1554 if (i == filename_start) {
1555 strncpy(dest, basename + i, destsize);
1556 } else {
1557 strncpy(dest, basename, destsize);
1558 }
1559 dest[destsize - 1] = 0;
1560 return strlen(dest);
1561 }
1562
1563 static void complete_setup_dlg(PTInstVar pvar, HWND dlg)
1564 {
1565 char buf[4096];
1566 char buf2[1024];
1567 HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
1568 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
1569 int i, j, buf2index, bufindex;
1570 int count = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0);
1571
1572 pvar->settings.CompressionLevel =
1573 (int) SendMessage(compressionControl, TBM_GETPOS, 0, 0);
1574
1575 buf2index = 0;
1576 for (i = 0; i < count; i++) {
1577 int len = SendMessage(cipherControl, LB_GETTEXTLEN, i, 0);
1578
1579 if (len > 0 && len < sizeof(buf)) { /* should always be true */
1580 buf[0] = 0;
1581 SendMessage(cipherControl, LB_GETTEXT, i, (LPARAM) buf);
1582 for (j = 0;
1583 j <= SSH_CIPHER_MAX
1584 && strcmp(buf, get_cipher_name(j)) != 0; j++) {
1585 }
1586 if (j <= SSH_CIPHER_MAX) {
1587 buf2[buf2index] = '0' + j;
1588 buf2index++;
1589 }
1590 }
1591 }
1592 buf2[buf2index] = 0;
1593 normalize_cipher_order(buf2);
1594 strcpy(pvar->settings.CipherOrder, buf2);
1595 SSH2_update_cipher_myproposal(pvar); // yutaka
1596
1597 buf[0] = 0;
1598 GetDlgItemText(dlg, IDC_READWRITEFILENAME, buf, sizeof(buf));
1599 j = copy_teraterm_dir_relative_path(pvar->settings.KnownHostsFiles,
1600 sizeof(pvar->settings.
1601 KnownHostsFiles), buf);
1602 buf[0] = 0;
1603 bufindex = 0;
1604 GetDlgItemText(dlg, IDC_READONLYFILENAME, buf, sizeof(buf));
1605 for (i = 0; buf[i] != 0; i++) {
1606 if (buf[i] == ';') {
1607 buf[i] = 0;
1608 if (j < sizeof(pvar->settings.KnownHostsFiles) - 1) {
1609 pvar->settings.KnownHostsFiles[j] = ';';
1610 j++;
1611 j += copy_teraterm_dir_relative_path(pvar->settings.
1612 KnownHostsFiles + j,
1613 sizeof(pvar->settings.
1614 KnownHostsFiles)
1615 - j, buf + bufindex);
1616 }
1617 bufindex = i + 1;
1618 }
1619 }
1620 if (bufindex < i && j < sizeof(pvar->settings.KnownHostsFiles) - 1) {
1621 pvar->settings.KnownHostsFiles[j] = ';';
1622 j++;
1623 copy_teraterm_dir_relative_path(pvar->settings.KnownHostsFiles + j,
1624 sizeof(pvar->settings.
1625 KnownHostsFiles) - j,
1626 buf + bufindex);
1627 }
1628 }
1629
1630 static void move_cur_sel_delta(HWND listbox, int delta)
1631 {
1632 int curPos = (int) SendMessage(listbox, LB_GETCURSEL, 0, 0);
1633 int maxPos = (int) SendMessage(listbox, LB_GETCOUNT, 0, 0) - 1;
1634 int newPos = curPos + delta;
1635 char buf[1024];
1636
1637 if (curPos >= 0 && newPos >= 0 && newPos <= maxPos) {
1638 int len = SendMessage(listbox, LB_GETTEXTLEN, curPos, 0);
1639
1640 if (len > 0 && len < sizeof(buf)) { /* should always be true */
1641 buf[0] = 0;
1642 SendMessage(listbox, LB_GETTEXT, curPos, (LPARAM) buf);
1643 SendMessage(listbox, LB_DELETESTRING, curPos, 0);
1644 SendMessage(listbox, LB_INSERTSTRING, newPos,
1645 (LPARAM) (char FAR *) buf);
1646 SendMessage(listbox, LB_SETCURSEL, newPos, 0);
1647 }
1648 }
1649 }
1650
1651 static int get_keys_file_name(HWND parent, char FAR * buf, int bufsize,
1652 int readonly)
1653 {
1654 #ifdef TERATERM32
1655 OPENFILENAME params;
1656 char fullname_buf[2048] = "ssh_known_hosts";
1657
1658 params.lStructSize = sizeof(OPENFILENAME);
1659 params.hwndOwner = parent;
1660 params.lpstrFilter = NULL;
1661 params.lpstrCustomFilter = NULL;
1662 params.nFilterIndex = 0;
1663 buf[0] = 0;
1664 params.lpstrFile = fullname_buf;
1665 params.nMaxFile = sizeof(fullname_buf);
1666 params.lpstrFileTitle = NULL;
1667 params.lpstrInitialDir = NULL;
1668 params.lpstrTitle =
1669 readonly ? "Choose a read-only known-hosts file to add" :
1670 "Choose a read/write known-hosts file";
1671 params.Flags = (readonly ? OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST : 0)
1672 | OFN_HIDEREADONLY | (!readonly ? OFN_NOREADONLYRETURN : 0);
1673 params.lpstrDefExt = NULL;
1674
1675 if (GetOpenFileName(&params) != 0) {
1676 copy_teraterm_dir_relative_path(buf, bufsize, fullname_buf);
1677 return 1;
1678 } else {
1679 int err = CommDlgExtendedError();
1680
1681 if (err != 0) {
1682 char buf[1024];
1683
1684 _snprintf(buf, sizeof(buf),
1685 "Cannot show file dialog box: error %d", err);
1686 buf[sizeof(buf) - 1] = 0;
1687 MessageBox(parent, buf, "TTSSH Error",
1688 MB_OK | MB_ICONEXCLAMATION);
1689 }
1690
1691 return 0;
1692 }
1693 #else
1694 return 0;
1695 #endif
1696 }
1697
1698 static void choose_read_write_file(HWND dlg)
1699 {
1700 char buf[1024];
1701
1702 if (get_keys_file_name(dlg, buf, sizeof(buf), 0)) {
1703 SetDlgItemText(dlg, IDC_READWRITEFILENAME, buf);
1704 }
1705 }
1706
1707 static void choose_read_only_file(HWND dlg)
1708 {
1709 char buf[1024];
1710 char buf2[4096];
1711
1712 if (get_keys_file_name(dlg, buf, sizeof(buf), 1)) {
1713 buf2[0] = 0;
1714 GetDlgItemText(dlg, IDC_READONLYFILENAME, buf2, sizeof(buf2));
1715 if (buf2[0] != 0 && buf2[strlen(buf2) - 1] != ';') {
1716 strncat(buf2, ";", sizeof(buf2));
1717 }
1718 strncat(buf2, buf, sizeof(buf2));
1719 SetDlgItemText(dlg, IDC_READONLYFILENAME, buf2);
1720 }
1721 }
1722
1723 static BOOL CALLBACK TTXSetupDlg(HWND dlg, UINT msg, WPARAM wParam,
1724 LPARAM lParam)
1725 {
1726 switch (msg) {
1727 case WM_INITDIALOG:
1728 SetWindowLong(dlg, DWL_USER, lParam);
1729 init_setup_dlg((PTInstVar) lParam, dlg);
1730 return TRUE;
1731 case WM_COMMAND:
1732 switch (LOWORD(wParam)) {
1733 case IDOK:
1734 complete_setup_dlg((PTInstVar) GetWindowLong(dlg, DWL_USER),
1735 dlg);
1736 EndDialog(dlg, 1);
1737 return TRUE;
1738 case IDCANCEL: /* there isn't a cancel button, but other Windows
1739 UI things can send this message */
1740 EndDialog(dlg, 0);
1741 return TRUE;
1742 case IDC_SSHMOVECIPHERUP:
1743 move_cur_sel_delta(GetDlgItem(dlg, IDC_SSHCIPHERPREFS), -1);
1744 set_move_button_status(dlg);
1745 SetFocus(GetDlgItem(dlg, IDC_SSHCIPHERPREFS));
1746 return TRUE;
1747 case IDC_SSHMOVECIPHERDOWN:
1748 move_cur_sel_delta(GetDlgItem(dlg, IDC_SSHCIPHERPREFS), 1);
1749 set_move_button_status(dlg);
1750 SetFocus(GetDlgItem(dlg, IDC_SSHCIPHERPREFS));
1751 return TRUE;
1752 case IDC_SSHCIPHERPREFS:
1753 set_move_button_status(dlg);
1754 return TRUE;
1755 case IDC_CHOOSEREADWRITEFILE:
1756 choose_read_write_file(dlg);
1757 return TRUE;
1758 case IDC_CHOOSEREADONLYFILE:
1759 choose_read_only_file(dlg);
1760 return TRUE;
1761 }
1762 break;
1763 }
1764
1765 return FALSE;
1766 }
1767
1768 static int PASCAL FAR TTXProcessCommand(HWND hWin, WORD cmd)
1769 {
1770 GET_VAR();
1771
1772 if (pvar->fatal_error) {
1773 return 0;
1774 }
1775
1776 switch (cmd) {
1777 case ID_ABOUTMENU:
1778 if (DialogBoxParam
1779 (hInst, MAKEINTRESOURCE(IDD_ABOUTDIALOG), hWin, TTXAboutDlg,
1780 (LPARAM) pvar)
1781 == -1) {
1782 MessageBox(hWin, "Cannot create About box window.",
1783 "TTSSH Error", MB_OK | MB_ICONEXCLAMATION);
1784 }
1785 return 1;
1786 case ID_SSHAUTH:
1787 AUTH_do_cred_dialog(pvar);
1788 return 1;
1789 case ID_SSHSETUPMENU:
1790 if (DialogBoxParam
1791 (hInst, MAKEINTRESOURCE(IDD_SSHSETUP), hWin, TTXSetupDlg,
1792 (LPARAM) pvar)
1793 == -1) {
1794 MessageBox(hWin, "Cannot create TTSSH Setup window.",
1795 "TTSSH Error", MB_OK | MB_ICONEXCLAMATION);
1796 }
1797 return 1;
1798 case ID_SSHAUTHSETUPMENU:
1799 AUTH_do_default_cred_dialog(pvar);
1800 return 1;
1801 case ID_SSHFWDSETUPMENU:
1802 FWDUI_do_forwarding_dialog(pvar);
1803 return 1;
1804 case ID_SSHUNKNOWNHOST:
1805 HOSTS_do_unknown_host_dialog(hWin, pvar);
1806 return 1;
1807 case ID_SSHDIFFERENTHOST:
1808 HOSTS_do_different_host_dialog(hWin, pvar);
1809 return 1;
1810 case ID_SSHASYNCMESSAGEBOX:
1811 if (pvar->err_msg != NULL) {
1812 char FAR *msg = pvar->err_msg;
1813
1814 /* Could there be a buffer overrun bug anywhere in Win32
1815 MessageBox? Who knows? I'm paranoid. */
1816 if (strlen(msg) > 2048) {
1817 msg[2048] = 0;
1818 }
1819
1820 pvar->showing_err = TRUE;
1821 pvar->err_msg = NULL;
1822 #if 1
1823 // XXX: "SECURITY WARINIG" dialog�� ESC �L�[�������������A
1824 // �������A�v���P�[�V�����G���[�����������A���LAPI�������B(2004.12.16 yutaka)
1825 if (!SSHv1(pvar)) {
1826 MessageBox(NULL, msg, "TTSSH",
1827 MB_TASKMODAL | MB_ICONEXCLAMATION);
1828 }
1829 #else
1830 MessageBox(NULL, msg, "TTSSH",
1831 MB_TASKMODAL | MB_ICONEXCLAMATION);
1832 #endif
1833 free(msg);
1834 pvar->showing_err = FALSE;
1835
1836 if (pvar->err_msg != NULL) {
1837 PostMessage(hWin, WM_COMMAND, ID_SSHASYNCMESSAGEBOX, 0);
1838 } else {
1839 AUTH_notify_end_error(pvar);
1840 }
1841 }
1842 return 1;
1843 default:
1844 return 0;
1845 }
1846 }
1847
1848 static void PASCAL FAR TTXSetCommandLine(PCHAR cmd, int cmdlen,
1849 PGetHNRec rec)
1850 {
1851 char tmpFile[MAX_PATH];
1852 char tmpPath[1024];
1853 char buf[1024];
1854 int i;
1855 GET_VAR();
1856
1857 GetTempPath(sizeof(tmpPath), tmpPath);
1858 GetTempFileName(tmpPath, "TTX", 0, tmpFile);
1859
1860 for (i = 0; cmd[i] != ' ' && cmd[i] != 0; i++) {
1861 }
1862
1863 if (i < cmdlen) {
1864 strncpy(buf, cmd + i, sizeof(buf));
1865 cmd[i] = 0;
1866
1867 write_ssh_options(pvar, tmpFile, &pvar->settings);
1868
1869 strncat(cmd, " /ssh-consume=", cmdlen);
1870 strncat(cmd, tmpFile, cmdlen);
1871
1872 strncat(cmd, buf, cmdlen);
1873
1874 if (pvar->hostdlg_Enabled) {
1875 strncat(cmd, " /ssh", cmdlen);
1876
1877 // add option of SSH protcol version (2004.10.11 yutaka)
1878 if (pvar->settings.ssh_protocol_version == 2) {
1879 strncat(cmd, " /2", cmdlen);
1880 } else {
1881 strncat(cmd, " /1", cmdlen);
1882 }
1883
1884 }
1885 }
1886 }
1887
1888 /* This function is called when Teraterm is quitting. You can use it to clean
1889 up.
1890
1891 This function is called for each extension, in reverse load order (see
1892 below).
1893 */
1894 static void PASCAL FAR TTXEnd(void)
1895 {
1896 GET_VAR();
1897
1898 uninit_TTSSH(pvar);
1899
1900 if (pvar->err_msg != NULL) {
1901 /* Could there be a buffer overrun bug anywhere in Win32
1902 MessageBox? Who knows? I'm paranoid. */
1903 if (strlen(pvar->err_msg) > 2048) {
1904 pvar->err_msg[2048] = 0;
1905 }
1906
1907 MessageBox(NULL, pvar->err_msg, "TTSSH",
1908 MB_TASKMODAL | MB_ICONEXCLAMATION);
1909
1910 free(pvar->err_msg);
1911 pvar->err_msg = NULL;
1912 }
1913 #ifndef TERATERM32
1914 DelVar();
1915 #endif
1916 }
1917
1918 /* This record contains all the information that the extension forwards to the
1919 main Teraterm code. It mostly consists of pointers to the above functions.
1920 Any of the function pointers can be replaced with NULL, in which case
1921 Teraterm will just ignore that function and assume default behaviour, which
1922 means "do nothing".
1923 */
1924 static TTXExports Exports = {
1925 /* This must contain the size of the structure. See below for its usage. */
1926 sizeof(TTXExports),
1927 ORDER,
1928
1929 /* Now we just list the functions that we've implemented. */
1930 TTXInit,
1931 TTXGetUIHooks,
1932 TTXGetSetupHooks,
1933 TTXOpenTCP,
1934 TTXCloseTCP,
1935 TTXSetWinSize,
1936 TTXModifyMenu,
1937 NULL,
1938 TTXProcessCommand,
1939 TTXEnd,
1940 TTXSetCommandLine
1941 };
1942
1943 #ifdef TERATERM32
1944 BOOL __declspec(dllexport)
1945 PASCAL FAR TTXBind(WORD Version, TTXExports FAR * exports)
1946 {
1947 #else
1948 BOOL __export PASCAL FAR TTXBind(WORD Version, TTXExports FAR * exports)
1949 {
1950 #endif
1951 int size = sizeof(Exports) - sizeof(exports->size);
1952 /* do version checking if necessary */
1953 /* if (Version!=TTVERSION) return FALSE; */
1954
1955 if (size > exports->size) {
1956 size = exports->size;
1957 }
1958 memcpy((char FAR *) exports + sizeof(exports->size),
1959 (char FAR *) &Exports + sizeof(exports->size), size);
1960 return TRUE;
1961 }
1962
1963 #ifdef TERATERM32
1964 static HANDLE __mem_mapping = NULL;
1965
1966 BOOL WINAPI DllMain(HANDLE hInstance,
1967 ULONG ul_reason_for_call, LPVOID lpReserved)
1968 {
1969 switch (ul_reason_for_call) {
1970 case DLL_THREAD_ATTACH:
1971 /* do thread initialization */
1972 break;
1973 case DLL_THREAD_DETACH:
1974 /* do thread cleanup */
1975 break;
1976 case DLL_PROCESS_ATTACH:
1977 /* do process initialization */
1978 DisableThreadLibraryCalls(hInstance);
1979 hInst = hInstance;
1980 pvar = &InstVar;
1981 __mem_mapping =
1982 CreateFileMapping((HANDLE) 0xFFFFFFFF, NULL, PAGE_READWRITE, 0,
1983 sizeof(TS_SSH), "TTSSH_1-4_TS_data");
1984 if (__mem_mapping == NULL) {
1985 /* fake it. The settings won't be shared, but what the heck. */
1986 pvar->ts_SSH = NULL;
1987 } else {
1988 pvar->ts_SSH =
1989 (TS_SSH *) MapViewOfFile(__mem_mapping, FILE_MAP_WRITE, 0,
1990 0, 0);
1991 }
1992 if (pvar->ts_SSH == NULL) {
1993 /* fake it. The settings won't be shared, but what the heck. */
1994 pvar->ts_SSH = (TS_SSH *) malloc(sizeof(TS_SSH));
1995 if (__mem_mapping != NULL) {
1996 CloseHandle(__mem_mapping);
1997 }
1998 }
1999 break;
2000 case DLL_PROCESS_DETACH:
2001 /* do process cleanup */
2002 if (__mem_mapping == NULL) {
2003 free(pvar->ts_SSH);
2004 } else {
2005 CloseHandle(__mem_mapping);
2006 UnmapViewOfFile(pvar->ts_SSH);
2007 }
2008 break;
2009 }
2010 return TRUE;
2011 }
2012 #else
2013 #ifdef WATCOM
2014 #pragma off (unreferenced);
2015 #endif
2016 int CALLBACK LibMain(HANDLE hInstance, WORD wDataSegment,
2017 WORD wHeapSize, LPSTR lpszCmdLine)
2018 #ifdef WATCOM
2019 #pragma on (unreferenced);
2020 #endif
2021 {
2022 int i;
2023 for (i = 0; i < MAXNUMINST; i++)
2024 TaskList[i] = NULL;
2025 hInst = hInstance;
2026 return (1);
2027 }
2028 #endif
2029
2030
2031 /*
2032 * $Log: not supported by cvs2svn $
2033 * Revision 1.5 2004/12/11 07:31:00 yutakakn
2034 * SSH heartbeat�X���b�h�����������B�����������AIP�}�X�J���[�h�������������A���[�^��
2035 * NAT�e�[�u���N���A�������ASSH�R�l�N�V���������f�����������������������B
2036 * ���������������Ateraterm.ini��TTSSH�Z�N�V�������AHeartBeat �G���g���������B
2037 *
2038 * Revision 1.4 2004/12/01 15:37:49 yutakakn
2039 * SSH2�������O�C���@�\�������B
2040 * �����A�p�X���[�h�F�������������B
2041 * �E�R�}���h���C��
2042 * /ssh /auth=�F�����\�b�h /user=���[�U�� /passwd=�p�X���[�h
2043 *
2044 * Revision 1.3 2004/11/29 15:52:37 yutakakn
2045 * SSH��default protocol��SSH2�������B
2046 *
2047 * Revision 1.2 2004/11/23 14:32:26 yutakakn
2048 * �����_�C�A���O���N�������ATCP/IP���u�z�X�g���v���t�H�[�J�X�������������������B
2049 *
2050 *
2051 */

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26