Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2753 - (hide 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 yutakakn 2728 /*
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 yutakakn 2748 #include "ssh.h"
39 yutakakn 2728
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 yutakakn 2748
176     ssh_heartbeat_lock_initialize();
177 yutakakn 2728 }
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 yutakakn 2738 // default is SSH2 (2004.11.30 yutaka)
369     settings->ssh_protocol_version = GetPrivateProfileInt("TTSSH", "ProtocolVersion", 2, fileName);
370 yutakakn 2728
371 yutakakn 2748 // SSH heartbeat time(second) (2004.12.11 yutaka)
372     settings->ssh_heartbeat_overtime = GetPrivateProfileInt("TTSSH", "HeartBeat", 60, fileName);
373    
374 yutakakn 2728 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 yutakakn 2748 // 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 yutakakn 2728 }
436    
437 yutakakn 2748
438 yutakakn 2728 /* 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 yutakakn 2748 int ret;
617    
618     ssh_heartbeat_lock();
619     ret = PKT_recv(pvar, buf, len);
620     ssh_heartbeat_unlock();
621     return (ret);
622    
623 yutakakn 2728 } 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 yutakakn 2748 ssh_heartbeat_lock();
635 yutakakn 2728 SSH_send(pvar, buf, len);
636 yutakakn 2748 ssh_heartbeat_unlock();
637 yutakakn 2728 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 yutakakn 2734 if (pvar->settings.ssh_protocol_version == 1) {
878     SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 0, 0); // SSH1
879     } else {
880 yutakakn 2728 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 yutakakn 2734
926 yutakakn 2728 SetFocus(hwnd);
927 yutakakn 2734 //SendMessage(hwnd, BM_SETCHECK, BST_CHECKED, 0);
928     //style = GetClassLongPtr(hwnd, GCL_STYLE);
929     //SetClassLongPtr(hwnd, GCL_STYLE, style | WS_TABSTOP);
930 yutakakn 2728 }
931    
932 yutakakn 2734 // 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 yutakakn 2728
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 yutakakn 2734 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE); // disabled (2004.11.23 yutaka)
1015 yutakakn 2728 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 yutakakn 2734 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1033 yutakakn 2728
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 yutakakn 2739
1139 yutakakn 2728 } 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 yutakakn 2739 } 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 yutakakn 2728 }
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 yutakakn 2753 #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 yutakakn 2728 MessageBox(NULL, msg, "TTSSH",
1831     MB_TASKMODAL | MB_ICONEXCLAMATION);
1832 yutakakn 2753 #endif
1833 yutakakn 2728 free(msg);
1834     pvar->showing_err = FALSE;
1835 yutakakn 2753
1836 yutakakn 2728 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 yutakakn 2734
2030    
2031     /*
2032     * $Log: not supported by cvs2svn $
2033 yutakakn 2753 * 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 yutakakn 2748 * 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 yutakakn 2739 * Revision 1.3 2004/11/29 15:52:37 yutakakn
2045     * SSH��default protocol��SSH2�������B
2046     *
2047 yutakakn 2738 * 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 yutakakn 2734 *
2050 yutakakn 2738 *
2051 yutakakn 2734 */

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