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

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