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 2766 - (hide annotations) (download) (as text)
Mon Dec 27 14:05:08 2004 UTC (19 years, 3 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 55576 byte(s)
'Auto window close'が有効の場合、切断後の接続ができない問題を修正した。
 ・スレッドの終了待ち合わせ処理の追加
 ・確保済みSSHリソースの解放

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

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