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 2803 - (hide annotations) (download) (as text)
Wed Mar 23 12:39:20 2005 UTC (19 years ago) by yutakakn
Original Path: ttssh2/trunk/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 61257 byte(s)
シリアルポートを開いた状態からAlt-Nで新規接続を開こうとしたとき、フォーカスを当てるようにした。

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

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