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 2799 - (hide annotations) (download) (as text)
Sat Mar 12 12:08:05 2005 UTC (19 years, 1 month ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 60555 byte(s)
パスワード認証の前に行うkeyboard-interactiveメソッドで、デフォルト設定値を無効(0)にした。
また、認証ダイアログのラベル名を設定の有無により変更するようにした。

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

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