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 2758 - (show annotations) (download) (as text)
Fri Dec 17 14:28:36 2004 UTC (19 years, 3 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 55348 byte(s)
メッセージ認証アルゴリズムに HMAC-MD5 を追加。
TTSSHバージョンダイアログにHMACアルゴリズム表示を追加。

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 // add HMAC algorithm (2004.12.17 yutaka)
1375 buf[0] = '\0';
1376 if (pvar->ctos_hmac == HMAC_SHA1) {
1377 strcat(buf, "hmac-sha1");
1378 } else if (pvar->ctos_hmac == HMAC_MD5) {
1379 strcat(buf, "hmac-md5");
1380 }
1381 strcat(buf, " to server, ");
1382 if (pvar->stoc_hmac == HMAC_SHA1) {
1383 strcat(buf, "hmac-sha1");
1384 } else if (pvar->stoc_hmac == HMAC_MD5) {
1385 strcat(buf, "hmac-md5");
1386 }
1387 strcat(buf, " from server");
1388 append_about_text(dlg, "HMAC: ", buf);
1389
1390 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
1391 append_about_text(dlg, "Encryption: ", buf);
1392 CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
1393 append_about_text(dlg, "Server keys: ", buf);
1394 AUTH_get_auth_info(pvar, buf, sizeof(buf));
1395 append_about_text(dlg, "Authentication: ", buf);
1396 SSH_get_compression_info(pvar, buf, sizeof(buf));
1397 append_about_text(dlg, "Compression: ", buf);
1398
1399 }
1400 }
1401 }
1402
1403 static BOOL CALLBACK TTXAboutDlg(HWND dlg, UINT msg, WPARAM wParam,
1404 LPARAM lParam)
1405 {
1406 switch (msg) {
1407 case WM_INITDIALOG:
1408 init_about_dlg((PTInstVar) lParam, dlg);
1409 return TRUE;
1410 case WM_COMMAND:
1411 switch (LOWORD(wParam)) {
1412 case IDOK:
1413 EndDialog(dlg, 1);
1414 return TRUE;
1415 case IDCANCEL: /* there isn't a cancel button, but other Windows
1416 UI things can send this message */
1417 EndDialog(dlg, 0);
1418 return TRUE;
1419 }
1420 break;
1421 }
1422
1423 return FALSE;
1424 }
1425
1426 static char FAR *get_cipher_name(int cipher)
1427 {
1428 switch (cipher) {
1429 case SSH_CIPHER_NONE:
1430 return "<ciphers below this line are disabled>";
1431 case SSH_CIPHER_RC4:
1432 return "RC4";
1433 case SSH_CIPHER_3DES:
1434 return "3DES";
1435 case SSH_CIPHER_DES:
1436 return "DES";
1437 case SSH_CIPHER_IDEA:
1438 return "IDEA";
1439 case SSH_CIPHER_TSS:
1440 return "TSS";
1441 case SSH_CIPHER_BLOWFISH:
1442 return "Blowfish";
1443
1444 // for SSH2(yutaka)
1445 case SSH_CIPHER_AES128:
1446 return "AES128(SSH2)";
1447 case SSH_CIPHER_3DES_CBC:
1448 return "3DES-CBC(SSH2)";
1449
1450 default:
1451 return NULL;
1452 }
1453 }
1454
1455 static void set_move_button_status(HWND dlg)
1456 {
1457 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
1458 int curPos = (int) SendMessage(cipherControl, LB_GETCURSEL, 0, 0);
1459 int maxPos = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0) - 1;
1460
1461 EnableWindow(GetDlgItem(dlg, IDC_SSHMOVECIPHERUP), curPos > 0
1462 && curPos <= maxPos);
1463 EnableWindow(GetDlgItem(dlg, IDC_SSHMOVECIPHERDOWN), curPos >= 0
1464 && curPos < maxPos);
1465 }
1466
1467 static void init_setup_dlg(PTInstVar pvar, HWND dlg)
1468 {
1469 HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
1470 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
1471 int i;
1472 int ch;
1473
1474 SendMessage(compressionControl, TBM_SETRANGE, TRUE, MAKELONG(0, 9));
1475 SendMessage(compressionControl, TBM_SETPOS, TRUE,
1476 pvar->settings.CompressionLevel);
1477
1478 normalize_cipher_order(pvar->settings.CipherOrder);
1479 SSH2_update_cipher_myproposal(pvar); // yutaka
1480
1481 for (i = 0; pvar->settings.CipherOrder[i] != 0; i++) {
1482 int cipher = pvar->settings.CipherOrder[i] - '0';
1483 char FAR *name = get_cipher_name(cipher);
1484
1485 if (name != NULL) {
1486 SendMessage(cipherControl, LB_ADDSTRING, 0, (LPARAM) name);
1487 }
1488 }
1489
1490 SendMessage(cipherControl, LB_SETCURSEL, 0, 0);
1491 set_move_button_status(dlg);
1492
1493 for (i = 0; (ch = pvar->settings.KnownHostsFiles[i]) != 0 && ch != ';';
1494 i++) {
1495 }
1496 if (ch != 0) {
1497 pvar->settings.KnownHostsFiles[i] = 0;
1498 SetDlgItemText(dlg, IDC_READWRITEFILENAME,
1499 pvar->settings.KnownHostsFiles);
1500 pvar->settings.KnownHostsFiles[i] = ch;
1501 SetDlgItemText(dlg, IDC_READONLYFILENAME,
1502 pvar->settings.KnownHostsFiles + i + 1);
1503 } else {
1504 SetDlgItemText(dlg, IDC_READWRITEFILENAME,
1505 pvar->settings.KnownHostsFiles);
1506 }
1507 }
1508
1509 void get_teraterm_dir_relative_name(char FAR * buf, int bufsize,
1510 char FAR * basename)
1511 {
1512 int filename_start = 0;
1513 int i;
1514 int ch;
1515
1516 if (basename[0] == '\\' || basename[0] == '/'
1517 || (basename[0] != 0 && basename[1] == ':')) {
1518 strncpy(buf, basename, bufsize);
1519 buf[bufsize - 1] = 0;
1520 return;
1521 }
1522
1523 GetModuleFileName(NULL, buf, bufsize);
1524 for (i = 0; (ch = buf[i]) != 0; i++) {
1525 if (ch == '\\' || ch == '/' || ch == ':') {
1526 filename_start = i + 1;
1527 }
1528 }
1529
1530 if (bufsize > filename_start) {
1531 strncpy(buf + filename_start, basename, bufsize - filename_start);
1532 }
1533 buf[bufsize - 1] = 0;
1534 }
1535
1536 int copy_teraterm_dir_relative_path(char FAR * dest, int destsize,
1537 char FAR * basename)
1538 {
1539 char buf[1024];
1540 int filename_start = 0;
1541 int i;
1542 int ch, ch2;
1543
1544 if (basename[0] != '\\' && basename[0] != '/'
1545 && (basename[0] == 0 || basename[1] != ':')) {
1546 strncpy(dest, basename, destsize);
1547 dest[destsize - 1] = 0;
1548 return strlen(dest);
1549 }
1550
1551 GetModuleFileName(NULL, buf, sizeof(buf));
1552 for (i = 0; (ch = buf[i]) != 0; i++) {
1553 if (ch == '\\' || ch == '/' || ch == ':') {
1554 filename_start = i + 1;
1555 }
1556 }
1557
1558 for (i = 0; i < filename_start; i++) {
1559 ch = toupper(buf[i]);
1560 ch2 = toupper(basename[i]);
1561
1562 if (ch == ch2
1563 || ((ch == '\\' || ch == '/')
1564 && (ch2 == '\\' || ch2 == '/'))) {
1565 } else {
1566 break;
1567 }
1568 }
1569
1570 if (i == filename_start) {
1571 strncpy(dest, basename + i, destsize);
1572 } else {
1573 strncpy(dest, basename, destsize);
1574 }
1575 dest[destsize - 1] = 0;
1576 return strlen(dest);
1577 }
1578
1579 static void complete_setup_dlg(PTInstVar pvar, HWND dlg)
1580 {
1581 char buf[4096];
1582 char buf2[1024];
1583 HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
1584 HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
1585 int i, j, buf2index, bufindex;
1586 int count = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0);
1587
1588 pvar->settings.CompressionLevel =
1589 (int) SendMessage(compressionControl, TBM_GETPOS, 0, 0);
1590
1591 buf2index = 0;
1592 for (i = 0; i < count; i++) {
1593 int len = SendMessage(cipherControl, LB_GETTEXTLEN, i, 0);
1594
1595 if (len > 0 && len < sizeof(buf)) { /* should always be true */
1596 buf[0] = 0;
1597 SendMessage(cipherControl, LB_GETTEXT, i, (LPARAM) buf);
1598 for (j = 0;
1599 j <= SSH_CIPHER_MAX
1600 && strcmp(buf, get_cipher_name(j)) != 0; j++) {
1601 }
1602 if (j <= SSH_CIPHER_MAX) {
1603 buf2[buf2index] = '0' + j;
1604 buf2index++;
1605 }
1606 }
1607 }
1608 buf2[buf2index] = 0;
1609 normalize_cipher_order(buf2);
1610 strcpy(pvar->settings.CipherOrder, buf2);
1611 SSH2_update_cipher_myproposal(pvar); // yutaka
1612
1613 buf[0] = 0;
1614 GetDlgItemText(dlg, IDC_READWRITEFILENAME, buf, sizeof(buf));
1615 j = copy_teraterm_dir_relative_path(pvar->settings.KnownHostsFiles,
1616 sizeof(pvar->settings.
1617 KnownHostsFiles), buf);
1618 buf[0] = 0;
1619 bufindex = 0;
1620 GetDlgItemText(dlg, IDC_READONLYFILENAME, buf, sizeof(buf));
1621 for (i = 0; buf[i] != 0; i++) {
1622 if (buf[i] == ';') {
1623 buf[i] = 0;
1624 if (j < sizeof(pvar->settings.KnownHostsFiles) - 1) {
1625 pvar->settings.KnownHostsFiles[j] = ';';
1626 j++;
1627 j += copy_teraterm_dir_relative_path(pvar->settings.
1628 KnownHostsFiles + j,
1629 sizeof(pvar->settings.
1630 KnownHostsFiles)
1631 - j, buf + bufindex);
1632 }
1633 bufindex = i + 1;
1634 }
1635 }
1636 if (bufindex < i && j < sizeof(pvar->settings.KnownHostsFiles) - 1) {
1637 pvar->settings.KnownHostsFiles[j] = ';';
1638 j++;
1639 copy_teraterm_dir_relative_path(pvar->settings.KnownHostsFiles + j,
1640 sizeof(pvar->settings.
1641 KnownHostsFiles) - j,
1642 buf + bufindex);
1643 }
1644 }
1645
1646 static void move_cur_sel_delta(HWND listbox, int delta)
1647 {
1648 int curPos = (int) SendMessage(listbox, LB_GETCURSEL, 0, 0);
1649 int maxPos = (int) SendMessage(listbox, LB_GETCOUNT, 0, 0) - 1;
1650 int newPos = curPos + delta;
1651 char buf[1024];
1652
1653 if (curPos >= 0 && newPos >= 0 && newPos <= maxPos) {
1654 int len = SendMessage(listbox, LB_GETTEXTLEN, curPos, 0);
1655
1656 if (len > 0 && len < sizeof(buf)) { /* should always be true */
1657 buf[0] = 0;
1658 SendMessage(listbox, LB_GETTEXT, curPos, (LPARAM) buf);
1659 SendMessage(listbox, LB_DELETESTRING, curPos, 0);
1660 SendMessage(listbox, LB_INSERTSTRING, newPos,
1661 (LPARAM) (char FAR *) buf);
1662 SendMessage(listbox, LB_SETCURSEL, newPos, 0);
1663 }
1664 }
1665 }
1666
1667 static int get_keys_file_name(HWND parent, char FAR * buf, int bufsize,
1668 int readonly)
1669 {
1670 #ifdef TERATERM32
1671 OPENFILENAME params;
1672 char fullname_buf[2048] = "ssh_known_hosts";
1673
1674 params.lStructSize = sizeof(OPENFILENAME);
1675 params.hwndOwner = parent;
1676 params.lpstrFilter = NULL;
1677 params.lpstrCustomFilter = NULL;
1678 params.nFilterIndex = 0;
1679 buf[0] = 0;
1680 params.lpstrFile = fullname_buf;
1681 params.nMaxFile = sizeof(fullname_buf);
1682 params.lpstrFileTitle = NULL;
1683 params.lpstrInitialDir = NULL;
1684 params.lpstrTitle =
1685 readonly ? "Choose a read-only known-hosts file to add" :
1686 "Choose a read/write known-hosts file";
1687 params.Flags = (readonly ? OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST : 0)
1688 | OFN_HIDEREADONLY | (!readonly ? OFN_NOREADONLYRETURN : 0);
1689 params.lpstrDefExt = NULL;
1690
1691 if (GetOpenFileName(&params) != 0) {
1692 copy_teraterm_dir_relative_path(buf, bufsize, fullname_buf);
1693 return 1;
1694 } else {
1695 int err = CommDlgExtendedError();
1696
1697 if (err != 0) {
1698 char buf[1024];
1699
1700 _snprintf(buf, sizeof(buf),
1701 "Cannot show file dialog box: error %d", err);
1702 buf[sizeof(buf) - 1] = 0;
1703 MessageBox(parent, buf, "TTSSH Error",
1704 MB_OK | MB_ICONEXCLAMATION);
1705 }
1706
1707 return 0;
1708 }
1709 #else
1710 return 0;
1711 #endif
1712 }
1713
1714 static void choose_read_write_file(HWND dlg)
1715 {
1716 char buf[1024];
1717
1718 if (get_keys_file_name(dlg, buf, sizeof(buf), 0)) {
1719 SetDlgItemText(dlg, IDC_READWRITEFILENAME, buf);
1720 }
1721 }
1722
1723 static void choose_read_only_file(HWND dlg)
1724 {
1725 char buf[1024];
1726 char buf2[4096];
1727
1728 if (get_keys_file_name(dlg, buf, sizeof(buf), 1)) {
1729 buf2[0] = 0;
1730 GetDlgItemText(dlg, IDC_READONLYFILENAME, buf2, sizeof(buf2));
1731 if (buf2[0] != 0 && buf2[strlen(buf2) - 1] != ';') {
1732 strncat(buf2, ";", sizeof(buf2));
1733 }
1734 strncat(buf2, buf, sizeof(buf2));
1735 SetDlgItemText(dlg, IDC_READONLYFILENAME, buf2);
1736 }
1737 }
1738
1739 static BOOL CALLBACK TTXSetupDlg(HWND dlg, UINT msg, WPARAM wParam,
1740 LPARAM lParam)
1741 {
1742 switch (msg) {
1743 case WM_INITDIALOG:
1744 SetWindowLong(dlg, DWL_USER, lParam);
1745 init_setup_dlg((PTInstVar) lParam, dlg);
1746 return TRUE;
1747 case WM_COMMAND:
1748 switch (LOWORD(wParam)) {
1749 case IDOK:
1750 complete_setup_dlg((PTInstVar) GetWindowLong(dlg, DWL_USER),
1751 dlg);
1752 EndDialog(dlg, 1);
1753 return TRUE;
1754 case IDCANCEL: /* there isn't a cancel button, but other Windows
1755 UI things can send this message */
1756 EndDialog(dlg, 0);
1757 return TRUE;
1758 case IDC_SSHMOVECIPHERUP:
1759 move_cur_sel_delta(GetDlgItem(dlg, IDC_SSHCIPHERPREFS), -1);
1760 set_move_button_status(dlg);
1761 SetFocus(GetDlgItem(dlg, IDC_SSHCIPHERPREFS));
1762 return TRUE;
1763 case IDC_SSHMOVECIPHERDOWN:
1764 move_cur_sel_delta(GetDlgItem(dlg, IDC_SSHCIPHERPREFS), 1);
1765 set_move_button_status(dlg);
1766 SetFocus(GetDlgItem(dlg, IDC_SSHCIPHERPREFS));
1767 return TRUE;
1768 case IDC_SSHCIPHERPREFS:
1769 set_move_button_status(dlg);
1770 return TRUE;
1771 case IDC_CHOOSEREADWRITEFILE:
1772 choose_read_write_file(dlg);
1773 return TRUE;
1774 case IDC_CHOOSEREADONLYFILE:
1775 choose_read_only_file(dlg);
1776 return TRUE;
1777 }
1778 break;
1779 }
1780
1781 return FALSE;
1782 }
1783
1784 static int PASCAL FAR TTXProcessCommand(HWND hWin, WORD cmd)
1785 {
1786 GET_VAR();
1787
1788 if (pvar->fatal_error) {
1789 return 0;
1790 }
1791
1792 switch (cmd) {
1793 case ID_ABOUTMENU:
1794 if (DialogBoxParam
1795 (hInst, MAKEINTRESOURCE(IDD_ABOUTDIALOG), hWin, TTXAboutDlg,
1796 (LPARAM) pvar)
1797 == -1) {
1798 MessageBox(hWin, "Cannot create About box window.",
1799 "TTSSH Error", MB_OK | MB_ICONEXCLAMATION);
1800 }
1801 return 1;
1802 case ID_SSHAUTH:
1803 AUTH_do_cred_dialog(pvar);
1804 return 1;
1805 case ID_SSHSETUPMENU:
1806 if (DialogBoxParam
1807 (hInst, MAKEINTRESOURCE(IDD_SSHSETUP), hWin, TTXSetupDlg,
1808 (LPARAM) pvar)
1809 == -1) {
1810 MessageBox(hWin, "Cannot create TTSSH Setup window.",
1811 "TTSSH Error", MB_OK | MB_ICONEXCLAMATION);
1812 }
1813 return 1;
1814 case ID_SSHAUTHSETUPMENU:
1815 AUTH_do_default_cred_dialog(pvar);
1816 return 1;
1817 case ID_SSHFWDSETUPMENU:
1818 FWDUI_do_forwarding_dialog(pvar);
1819 return 1;
1820 case ID_SSHUNKNOWNHOST:
1821 HOSTS_do_unknown_host_dialog(hWin, pvar);
1822 return 1;
1823 case ID_SSHDIFFERENTHOST:
1824 HOSTS_do_different_host_dialog(hWin, pvar);
1825 return 1;
1826 case ID_SSHASYNCMESSAGEBOX:
1827 if (pvar->err_msg != NULL) {
1828 char FAR *msg = pvar->err_msg;
1829
1830 /* Could there be a buffer overrun bug anywhere in Win32
1831 MessageBox? Who knows? I'm paranoid. */
1832 if (strlen(msg) > 2048) {
1833 msg[2048] = 0;
1834 }
1835
1836 pvar->showing_err = TRUE;
1837 pvar->err_msg = NULL;
1838 #if 1
1839 // XXX: "SECURITY WARINIG" dialog�� ESC �L�[�������������A
1840 // �������A�v���P�[�V�����G���[�����������A���LAPI�������B(2004.12.16 yutaka)
1841 if (!SSHv1(pvar)) {
1842 MessageBox(NULL, msg, "TTSSH",
1843 MB_TASKMODAL | MB_ICONEXCLAMATION);
1844 }
1845 #else
1846 MessageBox(NULL, msg, "TTSSH",
1847 MB_TASKMODAL | MB_ICONEXCLAMATION);
1848 #endif
1849 free(msg);
1850 pvar->showing_err = FALSE;
1851
1852 if (pvar->err_msg != NULL) {
1853 PostMessage(hWin, WM_COMMAND, ID_SSHASYNCMESSAGEBOX, 0);
1854 } else {
1855 AUTH_notify_end_error(pvar);
1856 }
1857 }
1858 return 1;
1859 default:
1860 return 0;
1861 }
1862 }
1863
1864 static void PASCAL FAR TTXSetCommandLine(PCHAR cmd, int cmdlen,
1865 PGetHNRec rec)
1866 {
1867 char tmpFile[MAX_PATH];
1868 char tmpPath[1024];
1869 char buf[1024];
1870 int i;
1871 GET_VAR();
1872
1873 GetTempPath(sizeof(tmpPath), tmpPath);
1874 GetTempFileName(tmpPath, "TTX", 0, tmpFile);
1875
1876 for (i = 0; cmd[i] != ' ' && cmd[i] != 0; i++) {
1877 }
1878
1879 if (i < cmdlen) {
1880 strncpy(buf, cmd + i, sizeof(buf));
1881 cmd[i] = 0;
1882
1883 write_ssh_options(pvar, tmpFile, &pvar->settings);
1884
1885 strncat(cmd, " /ssh-consume=", cmdlen);
1886 strncat(cmd, tmpFile, cmdlen);
1887
1888 strncat(cmd, buf, cmdlen);
1889
1890 if (pvar->hostdlg_Enabled) {
1891 strncat(cmd, " /ssh", cmdlen);
1892
1893 // add option of SSH protcol version (2004.10.11 yutaka)
1894 if (pvar->settings.ssh_protocol_version == 2) {
1895 strncat(cmd, " /2", cmdlen);
1896 } else {
1897 strncat(cmd, " /1", cmdlen);
1898 }
1899
1900 }
1901 }
1902 }
1903
1904 /* This function is called when Teraterm is quitting. You can use it to clean
1905 up.
1906
1907 This function is called for each extension, in reverse load order (see
1908 below).
1909 */
1910 static void PASCAL FAR TTXEnd(void)
1911 {
1912 GET_VAR();
1913
1914 uninit_TTSSH(pvar);
1915
1916 if (pvar->err_msg != NULL) {
1917 /* Could there be a buffer overrun bug anywhere in Win32
1918 MessageBox? Who knows? I'm paranoid. */
1919 if (strlen(pvar->err_msg) > 2048) {
1920 pvar->err_msg[2048] = 0;
1921 }
1922
1923 MessageBox(NULL, pvar->err_msg, "TTSSH",
1924 MB_TASKMODAL | MB_ICONEXCLAMATION);
1925
1926 free(pvar->err_msg);
1927 pvar->err_msg = NULL;
1928 }
1929 #ifndef TERATERM32
1930 DelVar();
1931 #endif
1932 }
1933
1934 /* This record contains all the information that the extension forwards to the
1935 main Teraterm code. It mostly consists of pointers to the above functions.
1936 Any of the function pointers can be replaced with NULL, in which case
1937 Teraterm will just ignore that function and assume default behaviour, which
1938 means "do nothing".
1939 */
1940 static TTXExports Exports = {
1941 /* This must contain the size of the structure. See below for its usage. */
1942 sizeof(TTXExports),
1943 ORDER,
1944
1945 /* Now we just list the functions that we've implemented. */
1946 TTXInit,
1947 TTXGetUIHooks,
1948 TTXGetSetupHooks,
1949 TTXOpenTCP,
1950 TTXCloseTCP,
1951 TTXSetWinSize,
1952 TTXModifyMenu,
1953 NULL,
1954 TTXProcessCommand,
1955 TTXEnd,
1956 TTXSetCommandLine
1957 };
1958
1959 #ifdef TERATERM32
1960 BOOL __declspec(dllexport)
1961 PASCAL FAR TTXBind(WORD Version, TTXExports FAR * exports)
1962 {
1963 #else
1964 BOOL __export PASCAL FAR TTXBind(WORD Version, TTXExports FAR * exports)
1965 {
1966 #endif
1967 int size = sizeof(Exports) - sizeof(exports->size);
1968 /* do version checking if necessary */
1969 /* if (Version!=TTVERSION) return FALSE; */
1970
1971 if (size > exports->size) {
1972 size = exports->size;
1973 }
1974 memcpy((char FAR *) exports + sizeof(exports->size),
1975 (char FAR *) &Exports + sizeof(exports->size), size);
1976 return TRUE;
1977 }
1978
1979 #ifdef TERATERM32
1980 static HANDLE __mem_mapping = NULL;
1981
1982 BOOL WINAPI DllMain(HANDLE hInstance,
1983 ULONG ul_reason_for_call, LPVOID lpReserved)
1984 {
1985 switch (ul_reason_for_call) {
1986 case DLL_THREAD_ATTACH:
1987 /* do thread initialization */
1988 break;
1989 case DLL_THREAD_DETACH:
1990 /* do thread cleanup */
1991 break;
1992 case DLL_PROCESS_ATTACH:
1993 /* do process initialization */
1994 DisableThreadLibraryCalls(hInstance);
1995 hInst = hInstance;
1996 pvar = &InstVar;
1997 __mem_mapping =
1998 CreateFileMapping((HANDLE) 0xFFFFFFFF, NULL, PAGE_READWRITE, 0,
1999 sizeof(TS_SSH), "TTSSH_1-4_TS_data");
2000 if (__mem_mapping == NULL) {
2001 /* fake it. The settings won't be shared, but what the heck. */
2002 pvar->ts_SSH = NULL;
2003 } else {
2004 pvar->ts_SSH =
2005 (TS_SSH *) MapViewOfFile(__mem_mapping, FILE_MAP_WRITE, 0,
2006 0, 0);
2007 }
2008 if (pvar->ts_SSH == NULL) {
2009 /* fake it. The settings won't be shared, but what the heck. */
2010 pvar->ts_SSH = (TS_SSH *) malloc(sizeof(TS_SSH));
2011 if (__mem_mapping != NULL) {
2012 CloseHandle(__mem_mapping);
2013 }
2014 }
2015 break;
2016 case DLL_PROCESS_DETACH:
2017 /* do process cleanup */
2018 if (__mem_mapping == NULL) {
2019 free(pvar->ts_SSH);
2020 } else {
2021 CloseHandle(__mem_mapping);
2022 UnmapViewOfFile(pvar->ts_SSH);
2023 }
2024 break;
2025 }
2026 return TRUE;
2027 }
2028 #else
2029 #ifdef WATCOM
2030 #pragma off (unreferenced);
2031 #endif
2032 int CALLBACK LibMain(HANDLE hInstance, WORD wDataSegment,
2033 WORD wHeapSize, LPSTR lpszCmdLine)
2034 #ifdef WATCOM
2035 #pragma on (unreferenced);
2036 #endif
2037 {
2038 int i;
2039 for (i = 0; i < MAXNUMINST; i++)
2040 TaskList[i] = NULL;
2041 hInst = hInstance;
2042 return (1);
2043 }
2044 #endif
2045
2046
2047 /*
2048 * $Log: not supported by cvs2svn $
2049 * Revision 1.6 2004/12/16 13:57:43 yutakakn
2050 * "SECURITY WARINIG" dialog�� ESC �L�[�������������A
2051 * �A�v���P�[�V�����G���[���������������b�������B
2052 *
2053 * Revision 1.5 2004/12/11 07:31:00 yutakakn
2054 * SSH heartbeat�X���b�h�����������B�����������AIP�}�X�J���[�h�������������A���[�^��
2055 * NAT�e�[�u���N���A�������ASSH�R�l�N�V���������f�����������������������B
2056 * ���������������Ateraterm.ini��TTSSH�Z�N�V�������AHeartBeat �G���g���������B
2057 *
2058 * Revision 1.4 2004/12/01 15:37:49 yutakakn
2059 * SSH2�������O�C���@�\�������B
2060 * �����A�p�X���[�h�F�������������B
2061 * �E�R�}���h���C��
2062 * /ssh /auth=�F�����\�b�h /user=���[�U�� /passwd=�p�X���[�h
2063 *
2064 * Revision 1.3 2004/11/29 15:52:37 yutakakn
2065 * SSH��default protocol��SSH2�������B
2066 *
2067 * Revision 1.2 2004/11/23 14:32:26 yutakakn
2068 * �����_�C�A���O���N�������ATCP/IP���u�z�X�g���v���t�H�[�J�X�������������������B
2069 *
2070 *
2071 */

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