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 2782 - (hide annotations) (download) (as text)
Mon Jan 24 14:07:07 2005 UTC (19 years, 2 months ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 56288 byte(s)
・keyboard-interactive認証をサポートした。
 それに伴い、teraterm.iniに "KeyboardInteractive" エントリを追加した。
・バージョンダイアログに OpenSSLバージョン を追加

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

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