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 2944 - (hide annotations) (download) (as text)
Wed Dec 6 14:31:13 2006 UTC (17 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 109918 byte(s)
表示メッセージの読み込み対応

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