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 2947 - (hide annotations) (download) (as text)
Thu Jan 4 11:59:03 2007 UTC (17 years, 3 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 114376 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 2946 if (UTIL_get_lang_font("DLG_SYSTEM_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 maya 2946 SendDlgItemMessage(dlg, IDC_HOSTNAME, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1091 maya 2943 SendDlgItemMessage(dlg, IDC_HISTORY, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1092     SendDlgItemMessage(dlg, IDC_SERVICELABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1093     SendDlgItemMessage(dlg, IDC_HOSTTELNET, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1094     SendDlgItemMessage(dlg, IDC_HOSTSSH, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1095     SendDlgItemMessage(dlg, IDC_HOSTOTHER, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1096     SendDlgItemMessage(dlg, IDC_HOSTTCPPORTLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1097 maya 2946 SendDlgItemMessage(dlg, IDC_HOSTTCPPORT, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1098 maya 2943 SendDlgItemMessage(dlg, IDC_SSH_VERSION_LABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1099 maya 2946 SendDlgItemMessage(dlg, IDC_SSH_VERSION, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1100 maya 2943 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOLLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1101 maya 2946 SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1102 maya 2943 SendDlgItemMessage(dlg, IDC_HOSTSERIAL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1103     SendDlgItemMessage(dlg, IDC_HOSTCOMLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1104 maya 2946 SendDlgItemMessage(dlg, IDC_HOSTCOM, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1105 maya 2943 SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1106     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1107     SendDlgItemMessage(dlg, IDC_HOSTHELP, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1108     }
1109     else {
1110     DlgHostFont = NULL;
1111     }
1112     #endif
1113    
1114 yutakakn 2734 // SetFocus()���t�H�[�J�X���������������AFALSE�������K�v�������B
1115     // TRUE���������ATABSTOP�������������������R���g���[�����I�������B
1116     // (2004.11.23 yutaka)
1117     return FALSE;
1118     //return TRUE;
1119 yutakakn 2728
1120     case WM_COMMAND:
1121     switch (LOWORD(wParam)) {
1122     case IDOK:
1123     GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1124     if (GetHNRec != NULL) {
1125     if (IsDlgButtonChecked(dlg, IDC_HOSTTCPIP)) {
1126     #ifdef INET6
1127     char afstr[BUFSIZ];
1128     #endif /* INET6 */
1129     i = GetDlgItemInt(dlg, IDC_HOSTTCPPORT, &Ok, FALSE);
1130     if (Ok) {
1131     GetHNRec->TCPPort = i;
1132     } else {
1133 maya 2937 #ifdef I18N
1134     strcpy(pvar->ts->UIMsg, "The TCP port must be a number.");
1135     UTIL_get_lang_msg("MSG_TCPPORT_NAN_ERROR", pvar);
1136     MessageBox(dlg, pvar->ts->UIMsg,
1137     "Teraterm", MB_OK | MB_ICONEXCLAMATION);
1138     #else
1139 maya 2930 MessageBox(dlg, "The TCP port must be a number.",
1140     "Teraterm", MB_OK | MB_ICONEXCLAMATION);
1141 maya 2937 #endif
1142 yutakakn 2728 return TRUE;
1143     }
1144     #ifdef INET6
1145     #define getaf(str) \
1146     ((strcmp((str), "IPv6") == 0) ? AF_INET6 : \
1147     ((strcmp((str), "IPv4") == 0) ? AF_INET : AF_UNSPEC))
1148     memset(afstr, 0, sizeof(afstr));
1149     GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOL, afstr,
1150     sizeof(afstr));
1151     GetHNRec->ProtocolFamily = getaf(afstr);
1152     #endif /* INET6 */
1153     GetHNRec->PortType = IdTCPIP;
1154     GetDlgItemText(dlg, IDC_HOSTNAME, GetHNRec->HostName,
1155     HostNameMaxLength);
1156     GetHNRec->Telnet = FALSE;
1157     pvar->hostdlg_activated = TRUE;
1158     pvar->hostdlg_Enabled = FALSE;
1159     if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1160     GetHNRec->Telnet = TRUE;
1161     } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1162     pvar->hostdlg_Enabled = TRUE;
1163    
1164     // check SSH protocol version
1165     memset(afstr, 0, sizeof(afstr));
1166     GetDlgItemText(dlg, IDC_SSH_VERSION, afstr, sizeof(afstr));
1167 yutakakn 2850 if (_stricmp(afstr, "SSH1") == 0) {
1168 yutakakn 2728 pvar->settings.ssh_protocol_version = 1;
1169     } else {
1170     pvar->settings.ssh_protocol_version = 2;
1171     }
1172     }
1173 yutakakn 2846
1174     // host history check button
1175     if (SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_GETCHECK, 0, 0) == BST_CHECKED) {
1176     pvar->ts->HistoryList = 1;
1177     } else {
1178     pvar->ts->HistoryList = 0;
1179     }
1180    
1181 yutakakn 2728 } else {
1182     GetHNRec->PortType = IdSerial;
1183     GetHNRec->HostName[0] = 0;
1184     memset(EntName, 0, sizeof(EntName));
1185     GetDlgItemText(dlg, IDC_HOSTCOM, EntName,
1186     sizeof(EntName) - 1);
1187     GetHNRec->ComPort = (BYTE) (EntName[3]) - 0x30;
1188     if (strlen(EntName) > 4)
1189     GetHNRec->ComPort =
1190     GetHNRec->ComPort * 10 + (BYTE) (EntName[4]) -
1191     0x30;
1192     }
1193     }
1194     EndDialog(dlg, 1);
1195 maya 2943
1196     #ifdef I18N
1197 maya 2947 if (DlgHostFont != NULL) {
1198     DeleteObject(DlgHostFont);
1199 maya 2943 }
1200     #endif
1201    
1202 yutakakn 2728 return TRUE;
1203    
1204     case IDCANCEL:
1205     EndDialog(dlg, 0);
1206 maya 2943
1207     #ifdef I18N
1208 maya 2947 if (DlgHostFont != NULL) {
1209     DeleteObject(DlgHostFont);
1210 maya 2943 }
1211     #endif
1212    
1213 yutakakn 2728 return TRUE;
1214    
1215     case IDC_HOSTTCPIP:
1216     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1217     TRUE);
1218     #ifdef INET6
1219     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1220     IDC_HOSTTCPPROTOCOL, TRUE);
1221     #endif /* INET6 */
1222     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
1223    
1224 yutakakn 2734 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE); // disabled (2004.11.23 yutaka)
1225 yutakakn 2728 if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1226     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE);
1227     } else {
1228     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1229     }
1230    
1231 yutakakn 2847 enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, TRUE); // disabled
1232    
1233 yutakakn 2728 return TRUE;
1234    
1235     case IDC_HOSTSERIAL:
1236     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, TRUE);
1237     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1238     FALSE);
1239     #ifdef INET6
1240     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1241     IDC_HOSTTCPPROTOCOL, FALSE);
1242     #endif /* INET6 */
1243     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1244 yutakakn 2734 enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1245 yutakakn 2728
1246 yutakakn 2847 enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, FALSE); // disabled
1247    
1248 yutakakn 2728 return TRUE;
1249    
1250     case IDC_HOSTSSH:
1251     enable_dlg_items(dlg, IDC_SSH_VERSION,
1252     IDC_SSH_VERSION, TRUE);
1253     goto hostssh_enabled;
1254    
1255     case IDC_HOSTTELNET:
1256     case IDC_HOSTOTHER:
1257     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1258     hostssh_enabled:
1259    
1260     GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1261    
1262     if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1263     if (GetHNRec != NULL)
1264     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TelPort,
1265     FALSE);
1266     } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1267     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, 22, FALSE);
1268     }
1269     return TRUE;
1270    
1271     case IDC_HOSTHELP:
1272     PostMessage(GetParent(dlg), WM_USER_DLGHELP2, 0, 0);
1273     }
1274     }
1275     return FALSE;
1276     }
1277    
1278     static BOOL FAR PASCAL TTXGetHostName(HWND parent, PGetHNRec rec)
1279     {
1280     return (BOOL) DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HOSTDLG),
1281     parent, TTXHostDlg, (LONG) rec);
1282     }
1283    
1284     static void PASCAL FAR TTXGetUIHooks(TTXUIHooks FAR * hooks)
1285     {
1286     GET_VAR();
1287    
1288     *hooks->GetHostName = TTXGetHostName;
1289     }
1290    
1291     static void FAR PASCAL TTXReadINIFile(PCHAR fileName, PTTSet ts)
1292     {
1293     GET_VAR();
1294    
1295     (pvar->ReadIniFile) (fileName, ts);
1296     read_ssh_options(pvar, fileName);
1297     pvar->settings = *pvar->ts_SSH;
1298     notify_verbose_message(pvar, "Reading INI file", LOG_LEVEL_VERBOSE);
1299     FWDUI_load_settings(pvar);
1300     }
1301    
1302     static void FAR PASCAL TTXWriteINIFile(PCHAR fileName, PTTSet ts)
1303     {
1304     GET_VAR();
1305    
1306     (pvar->WriteIniFile) (fileName, ts);
1307     *pvar->ts_SSH = pvar->settings;
1308     clear_local_settings(pvar);
1309     notify_verbose_message(pvar, "Writing INI file", LOG_LEVEL_VERBOSE);
1310 maya 2909 write_ssh_options(pvar, fileName, pvar->ts_SSH, TRUE);
1311 yutakakn 2728 }
1312    
1313     static void read_ssh_options_from_user_file(PTInstVar pvar,
1314     char FAR * user_file_name)
1315     {
1316     if (user_file_name[0] == '.') {
1317     read_ssh_options(pvar, user_file_name);
1318     } else {
1319     char buf[1024];
1320    
1321     get_teraterm_dir_relative_name(buf, sizeof(buf), user_file_name);
1322     read_ssh_options(pvar, buf);
1323     }
1324    
1325     pvar->settings = *pvar->ts_SSH;
1326     FWDUI_load_settings(pvar);
1327     }
1328    
1329 yutakakn 2784
1330     // @���u�����N���u�������B (2005.1.26 yutaka)
1331     static void replace_to_blank(char *src, char *dst, int dst_len)
1332     {
1333     int len, i;
1334    
1335     len = strlen(src);
1336     if (dst_len < len) // buffer overflow check
1337     return;
1338    
1339     for (i = 0 ; i < len ; i++) {
1340     if (src[i] == '@') { // @ ���o��������
1341     if (i < len - 1 && src[i + 1] == '@') { // �������� @ �����A�b�g�}�[�N���F������
1342     *dst++ = '@';
1343     i++;
1344     } else {
1345     *dst++ = ' '; // �������u��������
1346     }
1347     } else {
1348     *dst++ = src[i];
1349     }
1350     }
1351     *dst = '\0';
1352     }
1353    
1354 yutakakn 2728 /* returns 1 if the option text must be deleted */
1355     static int parse_option(PTInstVar pvar, char FAR * option)
1356     {
1357     if ((option[0] == '-' || option[0] == '/')) {
1358     if (MATCH_STR(option + 1, "ssh") == 0) {
1359     if (option[4] == 0) {
1360     pvar->settings.Enabled = 1;
1361     } else if (MATCH_STR(option + 4, "-L") == 0
1362     || MATCH_STR(option + 4, "-R") == 0
1363 yutakakn 2850 || _stricmp(option + 4, "-X") == 0) {
1364 yutakakn 2728 if (pvar->settings.DefaultForwarding[0] == 0) {
1365     strcpy(pvar->settings.DefaultForwarding, option + 5);
1366     } else {
1367     strcat(pvar->settings.DefaultForwarding, ";");
1368     strcat(pvar->settings.DefaultForwarding, option + 5);
1369     }
1370     } else if (MATCH_STR(option + 4, "-f=") == 0) {
1371 maya 2911 read_ssh_options_from_user_file(pvar, option + 7);
1372 yutakakn 2728 } else if (MATCH_STR(option + 4, "-v") == 0) {
1373     pvar->settings.LogLevel = LOG_LEVEL_VERBOSE;
1374 yutakakn 2850 } else if (_stricmp(option + 4, "-autologin") == 0
1375     || _stricmp(option + 4, "-autologon") == 0) {
1376 yutakakn 2728 pvar->settings.TryDefaultAuth = TRUE;
1377 yutakakn 2739
1378 yutakakn 2728 } else if (MATCH_STR(option + 4, "-consume=") == 0) {
1379 maya 2911 read_ssh_options_from_user_file(pvar, option + 13);
1380 yutakakn 2728 DeleteFile(option + 13);
1381 maya 2907
1382     // /ssh1 �� /ssh2 �I�v�V�������V�K���� (2006.9.16 maya)
1383     } else if (MATCH_STR(option + 4, "1") == 0) {
1384     pvar->settings.ssh_protocol_version = 1;
1385     } else if (MATCH_STR(option + 4, "2") == 0) {
1386     pvar->settings.ssh_protocol_version = 2;
1387    
1388 yutakakn 2728 } else {
1389     char buf[1024];
1390    
1391 maya 2937 #ifdef I18N
1392     strcpy(pvar->ts->UIMsg, "Unrecognized command-line option: %s");
1393     UTIL_get_lang_msg("MSG_UNKNOWN_OPTION_ERROR", pvar);
1394     _snprintf(buf, sizeof(buf), pvar->ts->UIMsg, option);
1395     #else
1396 yutakakn 2728 _snprintf(buf, sizeof(buf),
1397     "Unrecognized command-line option: %s", option);
1398 maya 2937 #endif
1399 yutakakn 2728 buf[sizeof(buf) - 1] = 0;
1400    
1401     MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
1402     }
1403    
1404     return 1;
1405 maya 2915
1406     // ttermpro.exe �� /T= �w�������p�������A������������ (2006.10.19 maya)
1407     } else if (MATCH_STR_I(option + 1, "t=") == 0) {
1408 yutakakn 2728 if (strcmp(option + 3, "2") == 0) {
1409     pvar->settings.Enabled = 1;
1410     return 1;
1411     } else {
1412     pvar->settings.Enabled = 0;
1413     }
1414    
1415 maya 2915 // ttermpro.exe �� /F= �w������ TTSSH ������������ (2006.10.11 maya)
1416     } else if (MATCH_STR_I(option + 1, "f=") == 0) {
1417 maya 2913 read_ssh_options_from_user_file(pvar, option + 3);
1418    
1419 yutakakn 2728 // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
1420     } else if (MATCH_STR(option + 1, "1") == 0) {
1421     // command line: /ssh /1 is SSH1 only
1422     pvar->settings.ssh_protocol_version = 1;
1423    
1424     } else if (MATCH_STR(option + 1, "2") == 0) {
1425     // command line: /ssh /2 is SSH2 & SSH1
1426     pvar->settings.ssh_protocol_version = 2;
1427    
1428     } else if (MATCH_STR(option + 1, "nossh") == 0) {
1429     // '/nossh' �I�v�V�����������B
1430     // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
1431     // �����������������B(2004.10.11 yutaka)
1432     pvar->settings.Enabled = 0;
1433    
1434 maya 2907 } else if (MATCH_STR(option + 1, "telnet") == 0) {
1435     // '/telnet' ���w�������������������� '/nossh' ��������
1436     // SSH������������ (2006.9.16 maya)
1437     pvar->settings.Enabled = 0;
1438    
1439 yutakakn 2739 } else if (MATCH_STR(option + 1, "auth") == 0) {
1440 yutakakn 2784 // SSH2�������O�C���I�v�V����������
1441 yutakakn 2739 //
1442 yutakakn 2784 // SYNOPSIS: /ssh /auth=passowrd /user=���[�U�� /passwd=�p�X���[�h
1443     // /ssh /auth=publickey /user=���[�U�� /passwd=�p�X���[�h /keyfile=�p�X
1444     // EXAMPLE: /ssh /auth=password /user=nike /passwd=a@bc
1445     // /ssh /auth=publickey /user=foo /passwd=bar /keyfile=d:\tmp\id_rsa
1446     // NOTICE: �p�X���[�h���p�X�������������������A�u�����N���������� @ ���g�������B
1447 yutakakn 2739 //
1448 yutakakn 2784 // (2004.11.30 yutaka)
1449     // (2005.1.26 yutaka) ���������B���J���F���T�|�[�g�B
1450     //
1451 yutakakn 2739 pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
1452    
1453 yutakakn 2784 if (MATCH_STR(option + 5, "=password") == 0) { // �p�X���[�h/keyboard-interactive�F��
1454     //pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
1455     pvar->ssh2_authmethod = SSH_AUTH_PASSWORD;
1456 yutakakn 2739
1457 yutakakn 2784 } else if (MATCH_STR(option + 5, "=publickey") == 0) { // ���J���F��
1458     //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1459     pvar->ssh2_authmethod = SSH_AUTH_RSA;
1460    
1461 yutakakn 2739 } else {
1462     // TODO:
1463    
1464     }
1465    
1466     } else if (MATCH_STR(option + 1, "user=") == 0) {
1467 yutakakn 2784 replace_to_blank(option + 6, pvar->ssh2_username, sizeof(pvar->ssh2_username));
1468     //_snprintf(pvar->ssh2_username, sizeof(pvar->ssh2_username), "%s", option + 6);
1469 yutakakn 2739
1470     } else if (MATCH_STR(option + 1, "passwd=") == 0) {
1471 yutakakn 2784 replace_to_blank(option + 8, pvar->ssh2_password, sizeof(pvar->ssh2_password));
1472     //_snprintf(pvar->ssh2_password, sizeof(pvar->ssh2_password), "%s", option + 8);
1473 yutakakn 2739
1474 yutakakn 2784 } else if (MATCH_STR(option + 1, "keyfile=") == 0) {
1475     replace_to_blank(option + 9, pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile));
1476    
1477 maya 2908 } else if (MATCH_STR(option + 1, "ask4passwd") == 0) {
1478     // �p�X���[�h������ (2006.9.18 maya)
1479     pvar->ask4passwd = 1;
1480    
1481 yutakakn 2728 }
1482    
1483 maya 2908 // �p�X���[�h�������������������O�C��������������
1484     // /auth ���F�����\�b�h���w�������������p������ (2006.9.18 maya)
1485     if (pvar->ask4passwd == 1) {
1486     pvar->ssh2_autologin = 0;
1487     }
1488    
1489 yutakakn 2728 }
1490    
1491     return 0;
1492     }
1493    
1494     static void FAR PASCAL TTXParseParam(PCHAR param, PTTSet ts,
1495     PCHAR DDETopic)
1496     {
1497 maya 2911 // �X�y�[�X�������t�@�C�������F�������������C�� (2006.10.7 maya)
1498 yutakakn 2728 int i;
1499     BOOL inParam = FALSE;
1500     BOOL inQuotes = FALSE;
1501 maya 2911 BOOL inFileParam = FALSE;
1502 yutakakn 2728 PCHAR option = NULL;
1503     GET_VAR();
1504    
1505     if (pvar->hostdlg_activated) {
1506     pvar->settings.Enabled = pvar->hostdlg_Enabled;
1507     }
1508    
1509     for (i = 0; param[i] != 0; i++) {
1510 maya 2911 if (inQuotes ? param[i] == '"'
1511     : (param[i] == ' ' || param[i] == '\t')) {
1512 yutakakn 2728 if (option != NULL) {
1513     char ch = param[i];
1514 maya 2911 PCHAR Equal;
1515 yutakakn 2728
1516     param[i] = 0;
1517 maya 2911 Equal = strchr(option, '=');
1518     if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
1519     char *buf = (char *)calloc(strlen(option), sizeof(char));
1520     strncat(buf, option, Equal - option + 1);
1521     strcat(buf, Equal + 2);
1522     if (parse_option
1523     (pvar, *buf == '"' ? buf + 1 : buf)) {
1524     memset(option, ' ', i + 1 - (option - param));
1525     } else {
1526     param[i] = ch;
1527     }
1528     free(buf);
1529 yutakakn 2728 }
1530 maya 2911 else {
1531     if (parse_option
1532     (pvar, *option == '"' ? option + 1 : option)) {
1533     memset(option, ' ', i + 1 - (option - param));
1534     } else {
1535     param[i] = ch;
1536     }
1537     }
1538 yutakakn 2728 option = NULL;
1539     }
1540     inParam = FALSE;
1541     inQuotes = FALSE;
1542 maya 2911 inFileParam = FALSE;
1543 yutakakn 2728 } else if (!inParam) {
1544     if (param[i] == '"') {
1545     inQuotes = TRUE;
1546     inParam = TRUE;
1547     option = param + i;
1548     } else if (param[i] != ' ' && param[i] != '\t') {
1549     inParam = TRUE;
1550     option = param + i;
1551     }
1552 maya 2911 } else {
1553     if (option == NULL) {
1554     continue;
1555     }
1556     if ((option[0] == '-' || option[0] == '/') &&
1557     (MATCH_STR(option + 1, "ssh-f=") == 0 ||
1558     MATCH_STR(option + 1, "ssh-consume=") == 0 ||
1559 maya 2915 MATCH_STR_I(option + 1, "f=") == 0)) {
1560 maya 2911 if (param[i] == '"') {
1561     inQuotes = TRUE;
1562     }
1563     inFileParam = TRUE;
1564     }
1565 yutakakn 2728 }
1566     }
1567    
1568     if (option != NULL) {
1569 maya 2911 PCHAR Equal = strchr(option, '=');
1570     if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
1571     char *buf = (char *)calloc(strlen(option), sizeof(char));
1572     strncat(buf, option, Equal - option + 1);
1573     strcat(buf, Equal + 2);
1574     if (parse_option
1575     (pvar, *buf == '"' ? buf + 1 : buf)) {
1576     memset(option, ' ', i + 1 - (option - param));
1577     }
1578     free(buf);
1579 yutakakn 2728 }
1580 maya 2911 else {
1581     if (parse_option(pvar, option)) {
1582     memset(option, ' ', i - (option - param));
1583     }
1584     }
1585 yutakakn 2728 }
1586    
1587     FWDUI_load_settings(pvar);
1588    
1589     (pvar->ParseParam) (param, ts, DDETopic);
1590    
1591     }
1592    
1593     static void PASCAL FAR TTXGetSetupHooks(TTXSetupHooks FAR * hooks)
1594     {
1595     GET_VAR();
1596    
1597     pvar->ReadIniFile = *hooks->ReadIniFile;
1598     pvar->WriteIniFile = *hooks->WriteIniFile;
1599     pvar->ParseParam = *hooks->ParseParam;
1600    
1601     *hooks->ReadIniFile = TTXReadINIFile;
1602     *hooks->WriteIniFile = TTXWriteINIFile;
1603     *hooks->ParseParam = TTXParseParam;
1604     }
1605    
1606     static void PASCAL FAR TTXSetWinSize(int rows, int cols)
1607     {
1608     GET_VAR();
1609    
1610     SSH_notify_win_size(pvar, cols, rows);
1611     }
1612    
1613     static void insertMenuBeforeItem(HMENU menu, WORD beforeItemID, WORD flags,
1614     WORD newItemID, char FAR * text)
1615     {
1616     int i, j;
1617    
1618     for (i = GetMenuItemCount(menu) - 1; i >= 0; i--) {
1619     HMENU submenu = GetSubMenu(menu, i);
1620    
1621     for (j = GetMenuItemCount(submenu) - 1; j >= 0; j--) {
1622     if (GetMenuItemID(submenu, j) == beforeItemID) {
1623     InsertMenu(submenu, j, MF_BYPOSITION | flags, newItemID,
1624     text);
1625     return;
1626     }
1627     }
1628     }
1629     }
1630    
1631     static void PASCAL FAR TTXModifyMenu(HMENU menu)
1632     {
1633     GET_VAR();
1634    
1635     /* inserts before ID_HELP_ABOUT */
1636 maya 2937 #ifdef I18N
1637     strcpy(pvar->ts->UIMsg, "About &TTSSH...");
1638     UTIL_get_lang_msg("MENU_ABOUT", pvar);
1639     insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU, pvar->ts->UIMsg);
1640     #else
1641 yutakakn 2728 insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU,
1642     "About &TTSSH...");
1643 maya 2937 #endif
1644 yutakakn 2728
1645     /* inserts before ID_SETUP_TCPIP */
1646 maya 2937 #ifdef I18N
1647     strcpy(pvar->ts->UIMsg, "SS&H...");
1648     UTIL_get_lang_msg("MENU_SSH", pvar);
1649     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU, pvar->ts->UIMsg);
1650     #else
1651 yutakakn 2728 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU,
1652     "SS&H...");
1653 maya 2937 #endif
1654 yutakakn 2728 /* inserts before ID_SETUP_TCPIP */
1655 maya 2937 #ifdef I18N
1656     strcpy(pvar->ts->UIMsg, "SSH &Authentication...");
1657     UTIL_get_lang_msg("MENU_SSH_AUTH", pvar);
1658     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU, pvar->ts->UIMsg);
1659     #else
1660 yutakakn 2728 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU,
1661     "SSH &Authentication...");
1662 maya 2937 #endif
1663 yutakakn 2728 /* inserts before ID_SETUP_TCPIP */
1664 maya 2937 #ifdef I18N
1665     strcpy(pvar->ts->UIMsg, "SSH F&orwarding...");
1666     UTIL_get_lang_msg("MENU_SSH_FORWARD", pvar);
1667     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU, pvar->ts->UIMsg);
1668     #else
1669 yutakakn 2728 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU,
1670     "SSH F&orwarding...");
1671 maya 2937 #endif
1672 yutakakn 2816
1673 maya 2937 #ifdef I18N
1674     strcpy(pvar->ts->UIMsg, "SSH KeyGenerator...");
1675     UTIL_get_lang_msg("MENU_SSH_KEYGEN", pvar);
1676     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHKEYGENMENU, pvar->ts->UIMsg);
1677     #else
1678 yutakakn 2816 insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHKEYGENMENU,
1679     "SSH KeyGenerator...");
1680 maya 2937 #endif
1681 yutakakn 2728 }
1682    
1683     static void append_about_text(HWND dlg, char FAR * prefix, char FAR * msg)
1684     {
1685     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
1686     (LPARAM) prefix);
1687     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0, (LPARAM) msg);
1688     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
1689     (LPARAM) (char FAR *) "\r\n");
1690     }
1691    
1692 yutakakn 2792 // ���s�t�@�C�������o�[�W�������������� (2005.2.28 yutaka)
1693 yutakakn 2793 void get_file_version(char *exefile, int *major, int *minor, int *release, int *build)
1694 yutakakn 2792 {
1695     typedef struct {
1696     WORD wLanguage;
1697     WORD wCodePage;
1698     } LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
1699     LPLANGANDCODEPAGE lplgcode;
1700     UINT unLen;
1701     DWORD size;
1702     char *buf = NULL;
1703     BOOL ret;
1704     int i;
1705     char fmt[80];
1706     char *pbuf;
1707    
1708     size = GetFileVersionInfoSize(exefile, NULL);
1709     if (size == 0) {
1710     goto error;
1711     }
1712     buf = malloc(size);
1713     ZeroMemory(buf, size);
1714    
1715     if (GetFileVersionInfo(exefile, 0, size, buf) == FALSE) {
1716     goto error;
1717     }
1718    
1719     ret = VerQueryValue(buf,
1720     "\\VarFileInfo\\Translation",
1721     (LPVOID *)&lplgcode, &unLen);
1722     if (ret == FALSE)
1723     goto error;
1724    
1725     for (i = 0 ; i < (int)(unLen / sizeof(LANGANDCODEPAGE)) ; i++) {
1726     _snprintf(fmt, sizeof(fmt), "\\StringFileInfo\\%04x%04x\\FileVersion",
1727     lplgcode[i].wLanguage, lplgcode[i].wCodePage);
1728     VerQueryValue(buf, fmt, &pbuf, &unLen);
1729     if (unLen > 0) { // get success
1730     int n, a, b, c, d;
1731    
1732     n = sscanf(pbuf, "%d, %d, %d, %d", &a, &b, &c, &d);
1733     if (n == 4) { // convert success
1734     *major = a;
1735     *minor = b;
1736     *release = c;
1737     *build = d;
1738     break;
1739     }
1740     }
1741     }
1742    
1743     free(buf);
1744     return;
1745    
1746     error:
1747     free(buf);
1748     *major = *minor = *release = *build = 0;
1749     }
1750    
1751 yutakakn 2728 static void init_about_dlg(PTInstVar pvar, HWND dlg)
1752     {
1753     char buf[1024];
1754 yutakakn 2792 int a, b, c, d;
1755 maya 2937
1756     #ifdef I18N
1757     GetWindowText(dlg, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1758     UTIL_get_lang_msg("DLG_ABOUT_TITLE", pvar);
1759     SetWindowText(dlg, pvar->ts->UIMsg);
1760 yutakakn 2728
1761 maya 2937 GetDlgItemText(dlg, IDOK, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1762     UTIL_get_lang_msg("BTN_OK", pvar);
1763     SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
1764     #endif
1765    
1766 yutakakn 2792 // TTSSH���o�[�W�������������� (2005.2.28 yutaka)
1767     get_file_version("ttxssh.dll", &a, &b, &c, &d);
1768     _snprintf(buf, sizeof(buf), "TTSSH\r\nTeraterm Secure Shell extension, %d.%d", a, b);
1769     SendMessage(GetDlgItem(dlg, IDC_TTSSH_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
1770    
1771 yutakakn 2782 // OpenSSL���o�[�W�������������� (2005.1.24 yutaka)
1772 yutakakn 2820 // ���������� (2005.5.11 yutaka)
1773     #ifdef OPENSSL_VERSION_TEXT
1774 yutakakn 2782 SendMessage(GetDlgItem(dlg, IDC_OPENSSL_VERSION), WM_SETTEXT, 0, (LPARAM)OPENSSL_VERSION_TEXT);
1775 yutakakn 2820 #else
1776     SendMessage(GetDlgItem(dlg, IDC_OPENSSL_VERSION), WM_SETTEXT, 0, (LPARAM)"Unknown");
1777     #endif
1778 yutakakn 2782
1779 yutakakn 2820 // zlib���o�[�W�������������� (2005.5.11 yutaka)
1780     #ifdef ZLIB_VERSION
1781 yutakakn 2823 _snprintf(buf, sizeof(buf), "ZLib %s", ZLIB_VERSION);
1782 yutakakn 2820 #else
1783 yutakakn 2823 _snprintf(buf, sizeof(buf), "ZLib Unknown");
1784 yutakakn 2820 #endif
1785     SendMessage(GetDlgItem(dlg, IDC_ZLIB_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
1786    
1787    
1788 yutakakn 2728 // TTSSH�_�C�A���O���\������SSH������������ (2004.10.30 yutaka)
1789     if (pvar->socket != INVALID_SOCKET) {
1790     if (SSHv1(pvar)) {
1791     SSH_get_server_ID_info(pvar, buf, sizeof(buf));
1792     append_about_text(dlg, "Server ID: ", buf);
1793     SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
1794     append_about_text(dlg, "Using protocol: ", buf);
1795     CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
1796     append_about_text(dlg, "Encryption: ", buf);
1797     CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
1798     append_about_text(dlg, "Server keys: ", buf);
1799     AUTH_get_auth_info(pvar, buf, sizeof(buf));
1800     append_about_text(dlg, "Authentication: ", buf);
1801     SSH_get_compression_info(pvar, buf, sizeof(buf));
1802     append_about_text(dlg, "Compression: ", buf);
1803    
1804     } else { // SSH2
1805     SSH_get_server_ID_info(pvar, buf, sizeof(buf));
1806     append_about_text(dlg, "Server ID: ", buf);
1807    
1808     append_about_text(dlg, "Client ID: ", pvar->client_version_string);
1809    
1810     SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
1811     append_about_text(dlg, "Using protocol: ", buf);
1812    
1813     if (pvar->kex_type == KEX_DH_GRP1_SHA1) {
1814     strcpy(buf, KEX_DH1);
1815     } else if (pvar->kex_type == KEX_DH_GRP14_SHA1) {
1816     strcpy(buf, KEX_DH14);
1817     } else {
1818     strcpy(buf, KEX_DHGEX);
1819     }
1820     append_about_text(dlg, "KEX: ", buf);
1821    
1822     if (pvar->hostkey_type == KEY_DSA) {
1823     strcpy(buf, "ssh-dss");
1824     } else {
1825     strcpy(buf, "ssh-rsa");
1826     }
1827     append_about_text(dlg, "Host Key: ", buf);
1828    
1829 yutakakn 2758 // add HMAC algorithm (2004.12.17 yutaka)
1830     buf[0] = '\0';
1831     if (pvar->ctos_hmac == HMAC_SHA1) {
1832     strcat(buf, "hmac-sha1");
1833     } else if (pvar->ctos_hmac == HMAC_MD5) {
1834     strcat(buf, "hmac-md5");
1835     }
1836     strcat(buf, " to server, ");
1837     if (pvar->stoc_hmac == HMAC_SHA1) {
1838     strcat(buf, "hmac-sha1");
1839     } else if (pvar->stoc_hmac == HMAC_MD5) {
1840     strcat(buf, "hmac-md5");
1841     }
1842     strcat(buf, " from server");
1843     append_about_text(dlg, "HMAC: ", buf);
1844    
1845 yutakakn 2728 CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
1846     append_about_text(dlg, "Encryption: ", buf);
1847     CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
1848     append_about_text(dlg, "Server keys: ", buf);
1849     AUTH_get_auth_info(pvar, buf, sizeof(buf));
1850     append_about_text(dlg, "Authentication: ", buf);
1851 yutakakn 2873
1852 yutakakn 2728 SSH_get_compression_info(pvar, buf, sizeof(buf));
1853 yutakakn 2873 if (pvar->ctos_compression == COMP_DELAYED) { // �x���p�P�b�g���k������ (2006.6.23 yutaka)
1854     append_about_text(dlg, "Delayed Compression: ", buf);
1855     } else {
1856     append_about_text(dlg, "Compression: ", buf);
1857     }
1858 yutakakn 2728
1859     }
1860     }
1861     }
1862    
1863     static BOOL CALLBACK TTXAboutDlg(HWND dlg, UINT msg, WPARAM wParam,
1864     LPARAM lParam)
1865     {
1866 maya 2937 #ifdef I18N
1867     LOGFONT logfont;
1868     HFONT font;
1869     #endif
1870 yutakakn 2728 switch (msg) {
1871     case WM_INITDIALOG:
1872 maya 2937 #ifdef I18N
1873     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1874     GetObject(font, sizeof(LOGFONT), &logfont);
1875 maya 2946 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgAboutFont, pvar)) {
1876 maya 2937 SendDlgItemMessage(dlg, IDC_TTSSH_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1877     SendDlgItemMessage(dlg, IDC_SSHVERSIONS, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1878     SendDlgItemMessage(dlg, IDC_INCLUDES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1879     SendDlgItemMessage(dlg, IDC_OPENSSL_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1880     SendDlgItemMessage(dlg, IDC_ZLIB_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1881     SendDlgItemMessage(dlg, IDC_WEBSITES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1882     SendDlgItemMessage(dlg, IDC_CRYPTOGRAPHY, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1883     SendDlgItemMessage(dlg, IDC_CREDIT, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1884     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1885     SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
1886     }
1887     else {
1888     DlgAboutFont = NULL;
1889     }
1890     #endif
1891 yutakakn 2728 init_about_dlg((PTInstVar) lParam, dlg);
1892     return TRUE;
1893     case WM_COMMAND:
1894     switch (LOWORD(wParam)) {
1895     case IDOK:
1896     EndDialog(dlg, 1);
1897 maya 2937 #ifdef I18N
1898     if (DlgAboutFont != NULL) {
1899     DeleteObject(DlgAboutFont);
1900     }
1901     #endif
1902 yutakakn 2728 return TRUE;
1903     case IDCANCEL: /* there isn't a cancel button, but other Windows
1904     UI things can send this message */
1905     EndDialog(dlg, 0);
1906 maya 2937 #ifdef I18N
1907     if (DlgAboutFont != NULL) {
1908     DeleteObject(DlgAboutFont);
1909     }
1910     #endif
1911 yutakakn 2728 return TRUE;
1912     }
1913     break;
1914     }
1915    
1916     return FALSE;
1917     }
1918    
1919     static char FAR *get_cipher_name(int cipher)
1920     {
1921     switch (cipher) {
1922     case SSH_CIPHER_NONE:
1923 maya 2937 #ifdef I18N
1924     strcpy(pvar->ts->UIMsg, "<ciphers below this line are disabled>");
1925     UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_BORDER", pvar);
1926     return pvar->ts->UIMsg;
1927     #else
1928 yutakakn 2728 return "<ciphers below this line are disabled>";
1929 maya 2937 #endif
1930 yutakakn 2728 case SSH_CIPHER_RC4:
1931     return "RC4";
1932     case SSH_CIPHER_3DES:
1933     return "3DES";
1934     case SSH_CIPHER_DES:
1935     return "DES";
1936     case SSH_CIPHER_IDEA:
1937     return "IDEA";
1938     case SSH_CIPHER_TSS:
1939     return "TSS";
1940     case SSH_CIPHER_BLOWFISH:
1941     return "Blowfish";
1942    
1943     // for SSH2(yutaka)
1944     case SSH_CIPHER_AES128:
1945     return "AES128(SSH2)";
1946     case SSH_CIPHER_3DES_CBC:
1947     return "3DES-CBC(SSH2)";
1948    
1949     default:
1950     return NULL;
1951     }
1952     }
1953    
1954     static void set_move_button_status(HWND dlg)
1955     {
1956     HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
1957     int curPos = (int) SendMessage(cipherControl, LB_GETCURSEL, 0, 0);
1958     int maxPos = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0) - 1;
1959    
1960     EnableWindow(GetDlgItem(dlg, IDC_SSHMOVECIPHERUP), curPos > 0
1961     && curPos <= maxPos);
1962     EnableWindow(GetDlgItem(dlg, IDC_SSHMOVECIPHERDOWN), curPos >= 0
1963     && curPos < maxPos);
1964     }
1965    
1966     static void init_setup_dlg(PTInstVar pvar, HWND dlg)
1967     {
1968     HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
1969     HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
1970     int i;
1971     int ch;
1972 maya 2937
1973     #ifdef I18N
1974     GetWindowText(dlg, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1975     UTIL_get_lang_msg("DLG_SSHSETUP_TITLE", pvar);
1976     SetWindowText(dlg, pvar->ts->UIMsg);
1977 yutakakn 2728
1978 maya 2937 GetDlgItemText(dlg, IDC_COMPRESSLABEL, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1979     UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS", pvar);
1980     SetDlgItemText(dlg, IDC_COMPRESSLABEL, pvar->ts->UIMsg);
1981    
1982     GetDlgItemText(dlg, IDC_COMPRESSNONE, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1983     UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_NONE", pvar);
1984     SetDlgItemText(dlg, IDC_COMPRESSNONE, pvar->ts->UIMsg);
1985    
1986     GetDlgItemText(dlg, IDC_COMPRESSHIGH, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1987     UTIL_get_lang_msg("DLG_SSHSETUP_COMPRESS_HIGHEST", pvar);
1988     SetDlgItemText(dlg, IDC_COMPRESSHIGH, pvar->ts->UIMsg);
1989    
1990     GetDlgItemText(dlg, IDC_CIPHERORDER, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1991     UTIL_get_lang_msg("DLG_SSHSETUP_CHIPER", pvar);
1992     SetDlgItemText(dlg, IDC_CIPHERORDER, pvar->ts->UIMsg);
1993    
1994     GetDlgItemText(dlg, IDC_SSHMOVECIPHERUP, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1995     UTIL_get_lang_msg("DLG_SSHSETUP_CHIPER_UP", pvar);
1996     SetDlgItemText(dlg, IDC_SSHMOVECIPHERUP, pvar->ts->UIMsg);
1997    
1998     GetDlgItemText(dlg, IDC_SSHMOVECIPHERDOWN, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1999     UTIL_get_lang_msg("DLG_SSHSETUP_CHIPER_DOWN", pvar);
2000     SetDlgItemText(dlg, IDC_SSHMOVECIPHERDOWN, pvar->ts->UIMsg);
2001    
2002     GetDlgItemText(dlg, IDC_KNOWNHOSTS, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
2003     UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST", pvar);
2004     SetDlgItemText(dlg, IDC_KNOWNHOSTS, pvar->ts->UIMsg);
2005    
2006     GetDlgItemText(dlg, IDC_CHOOSEREADWRITEFILE, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
2007     UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST_RW", pvar);
2008     SetDlgItemText(dlg, IDC_CHOOSEREADWRITEFILE, pvar->ts->UIMsg);
2009    
2010     GetDlgItemText(dlg, IDC_CHOOSEREADONLYFILE, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
2011     UTIL_get_lang_msg("DLG_SSHSETUP_KNOWNHOST_RO", pvar);
2012     SetDlgItemText(dlg, IDC_CHOOSEREADONLYFILE, pvar->ts->UIMsg);
2013    
2014     GetDlgItemText(dlg, IDC_HEARTBEATLABEL, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
2015     UTIL_get_lang_msg("DLG_SSHSETUP_HEARTBEAT", pvar);
2016     SetDlgItemText(dlg, IDC_HEARTBEATLABEL, pvar->ts->UIMsg);
2017    
2018     GetDlgItemText(dlg, IDC_HEARTBEATLABEL2, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
2019     UTIL_get_lang_msg("DLG_SSHSETUP_HEARTBEAT_UNIT", pvar);
2020     SetDlgItemText(dlg, IDC_HEARTBEATLABEL2, pvar->ts->UIMsg);
2021    
2022     GetDlgItemText(dlg, IDC_NOTICEBANNER, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
2023     UTIL_get_lang_msg("DLG_SSHSETUP_NOTICE", pvar);
2024     SetDlgItemText(dlg, IDC_NOTICEBANNER, pvar->ts->UIMsg);
2025    
2026     strcpy(pvar->ts->UIMsg, "OK");
2027     UTIL_get_lang_msg("BTN_OK", pvar);
2028     SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2029    
2030     strcpy(pvar->ts->UIMsg, "Cancel");
2031     UTIL_get_lang_msg("BTN_CANCEL", pvar);
2032     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2033     #endif
2034    
2035 yutakakn 2728 SendMessage(compressionControl, TBM_SETRANGE, TRUE, MAKELONG(0, 9));
2036     SendMessage(compressionControl, TBM_SETPOS, TRUE,
2037     pvar->settings.CompressionLevel);
2038    
2039     normalize_cipher_order(pvar->settings.CipherOrder);
2040    
2041     for (i = 0; pvar->settings.CipherOrder[i] != 0; i++) {
2042     int cipher = pvar->settings.CipherOrder[i] - '0';
2043     char FAR *name = get_cipher_name(cipher);
2044    
2045     if (name != NULL) {
2046     SendMessage(cipherControl, LB_ADDSTRING, 0, (LPARAM) name);
2047     }
2048     }
2049    
2050     SendMessage(cipherControl, LB_SETCURSEL, 0, 0);
2051     set_move_button_status(dlg);
2052    
2053     for (i = 0; (ch = pvar->settings.KnownHostsFiles[i]) != 0 && ch != ';';
2054     i++) {
2055     }
2056     if (ch != 0) {
2057     pvar->settings.KnownHostsFiles[i] = 0;
2058     SetDlgItemText(dlg, IDC_READWRITEFILENAME,
2059     pvar->settings.KnownHostsFiles);
2060     pvar->settings.KnownHostsFiles[i] = ch;
2061     SetDlgItemText(dlg, IDC_READONLYFILENAME,
2062     pvar->settings.KnownHostsFiles + i + 1);
2063     } else {
2064     SetDlgItemText(dlg, IDC_READWRITEFILENAME,
2065     pvar->settings.KnownHostsFiles);
2066     }
2067 yutakakn 2789
2068     // SSH2 HeartBeat(keep-alive)������ (2005.2.22 yutaka)
2069     {
2070     char buf[10];
2071     _snprintf(buf, sizeof(buf), "%d", pvar->settings.ssh_heartbeat_overtime);
2072     SetDlgItemText(dlg, IDC_HEARTBEAT_EDIT, buf);
2073     }
2074    
2075 yutakakn 2728 }
2076    
2077     void get_teraterm_dir_relative_name(char FAR * buf, int bufsize,
2078     char FAR * basename)
2079     {
2080     int filename_start = 0;
2081     int i;
2082     int ch;
2083    
2084     if (basename[0] == '\\' || basename[0] == '/'
2085     || (basename[0] != 0 && basename[1] == ':')) {
2086     strncpy(buf, basename, bufsize);
2087     buf[bufsize - 1] = 0;
2088     return;
2089     }
2090    
2091     GetModuleFileName(NULL, buf, bufsize);
2092     for (i = 0; (ch = buf[i]) != 0; i++) {
2093     if (ch == '\\' || ch == '/' || ch == ':') {
2094     filename_start = i + 1;
2095     }
2096     }
2097    
2098     if (bufsize > filename_start) {
2099     strncpy(buf + filename_start, basename, bufsize - filename_start);
2100     }
2101     buf[bufsize - 1] = 0;
2102     }
2103    
2104     int copy_teraterm_dir_relative_path(char FAR * dest, int destsize,
2105     char FAR * basename)
2106     {
2107     char buf[1024];
2108     int filename_start = 0;
2109     int i;
2110     int ch, ch2;
2111    
2112     if (basename[0] != '\\' && basename[0] != '/'
2113     && (basename[0] == 0 || basename[1] != ':')) {
2114     strncpy(dest, basename, destsize);
2115     dest[destsize - 1] = 0;
2116     return strlen(dest);
2117     }
2118    
2119     GetModuleFileName(NULL, buf, sizeof(buf));
2120     for (i = 0; (ch = buf[i]) != 0; i++) {
2121     if (ch == '\\' || ch == '/' || ch == ':') {
2122     filename_start = i + 1;
2123     }
2124     }
2125    
2126     for (i = 0; i < filename_start; i++) {
2127     ch = toupper(buf[i]);
2128     ch2 = toupper(basename[i]);
2129    
2130     if (ch == ch2
2131     || ((ch == '\\' || ch == '/')
2132     && (ch2 == '\\' || ch2 == '/'))) {
2133     } else {
2134     break;
2135     }
2136     }
2137    
2138     if (i == filename_start) {
2139     strncpy(dest, basename + i, destsize);
2140     } else {
2141     strncpy(dest, basename, destsize);
2142     }
2143     dest[destsize - 1] = 0;
2144     return strlen(dest);
2145     }
2146    
2147     static void complete_setup_dlg(PTInstVar pvar, HWND dlg)
2148     {
2149     char buf[4096];
2150     char buf2[1024];
2151     HWND compressionControl = GetDlgItem(dlg, IDC_SSHCOMPRESSIONLEVEL);
2152     HWND cipherControl = GetDlgItem(dlg, IDC_SSHCIPHERPREFS);
2153     int i, j, buf2index, bufindex;
2154     int count = (int) SendMessage(cipherControl, LB_GETCOUNT, 0, 0);
2155    
2156     pvar->settings.CompressionLevel =
2157     (int) SendMessage(compressionControl, TBM_GETPOS, 0, 0);
2158    
2159     buf2index = 0;
2160     for (i = 0; i < count; i++) {
2161     int len = SendMessage(cipherControl, LB_GETTEXTLEN, i, 0);
2162    
2163     if (len > 0 && len < sizeof(buf)) { /* should always be true */
2164     buf[0] = 0;
2165     SendMessage(cipherControl, LB_GETTEXT, i, (LPARAM) buf);
2166     for (j = 0;
2167     j <= SSH_CIPHER_MAX
2168     && strcmp(buf, get_cipher_name(j)) != 0; j++) {
2169     }
2170     if (j <= SSH_CIPHER_MAX) {
2171     buf2[buf2index] = '0' + j;
2172     buf2index++;
2173     }
2174     }
2175     }
2176     buf2[buf2index] = 0;
2177     normalize_cipher_order(buf2);
2178     strcpy(pvar->settings.CipherOrder, buf2);
2179    
2180     buf[0] = 0;
2181     GetDlgItemText(dlg, IDC_READWRITEFILENAME, buf, sizeof(buf));
2182     j = copy_teraterm_dir_relative_path(pvar->settings.KnownHostsFiles,
2183     sizeof(pvar->settings.
2184     KnownHostsFiles), buf);
2185     buf[0] = 0;
2186     bufindex = 0;
2187     GetDlgItemText(dlg, IDC_READONLYFILENAME, buf, sizeof(buf));
2188     for (i = 0; buf[i] != 0; i++) {
2189     if (buf[i] == ';') {
2190     buf[i] = 0;
2191     if (j < sizeof(pvar->settings.KnownHostsFiles) - 1) {
2192     pvar->settings.KnownHostsFiles[j] = ';';
2193     j++;
2194     j += copy_teraterm_dir_relative_path(pvar->settings.
2195     KnownHostsFiles + j,
2196     sizeof(pvar->settings.
2197     KnownHostsFiles)
2198     - j, buf + bufindex);
2199     }
2200     bufindex = i + 1;
2201     }
2202     }
2203     if (bufindex < i && j < sizeof(pvar->settings.KnownHostsFiles) - 1) {
2204     pvar->settings.KnownHostsFiles[j] = ';';
2205     j++;
2206     copy_teraterm_dir_relative_path(pvar->settings.KnownHostsFiles + j,
2207     sizeof(pvar->settings.
2208     KnownHostsFiles) - j,
2209     buf + bufindex);
2210     }
2211 yutakakn 2789
2212     // get SSH HeartBeat(keep-alive)
2213     SendMessage(GetDlgItem(dlg, IDC_HEARTBEAT_EDIT), WM_GETTEXT, sizeof(buf), (LPARAM)buf);
2214     i = atoi(buf);
2215     if (i < 0)
2216     i = 60;
2217     pvar->settings.ssh_heartbeat_overtime = i;
2218    
2219 yutakakn 2728 }
2220    
2221     static void move_cur_sel_delta(HWND listbox, int delta)
2222     {
2223     int curPos = (int) SendMessage(listbox, LB_GETCURSEL, 0, 0);
2224     int maxPos = (int) SendMessage(listbox, LB_GETCOUNT, 0, 0) - 1;
2225     int newPos = curPos + delta;
2226     char buf[1024];
2227    
2228     if (curPos >= 0 && newPos >= 0 && newPos <= maxPos) {
2229     int len = SendMessage(listbox, LB_GETTEXTLEN, curPos, 0);
2230    
2231     if (len > 0 && len < sizeof(buf)) { /* should always be true */
2232     buf[0] = 0;
2233     SendMessage(listbox, LB_GETTEXT, curPos, (LPARAM) buf);
2234     SendMessage(listbox, LB_DELETESTRING, curPos, 0);
2235     SendMessage(listbox, LB_INSERTSTRING, newPos,
2236     (LPARAM) (char FAR *) buf);
2237     SendMessage(listbox, LB_SETCURSEL, newPos, 0);
2238     }
2239     }
2240     }
2241    
2242     static int get_keys_file_name(HWND parent, char FAR * buf, int bufsize,
2243     int readonly)
2244     {
2245     #ifdef TERATERM32
2246     OPENFILENAME params;
2247     char fullname_buf[2048] = "ssh_known_hosts";
2248    
2249     params.lStructSize = sizeof(OPENFILENAME);
2250     params.hwndOwner = parent;
2251     params.lpstrFilter = NULL;
2252     params.lpstrCustomFilter = NULL;
2253     params.nFilterIndex = 0;
2254     buf[0] = 0;
2255     params.lpstrFile = fullname_buf;
2256     params.nMaxFile = sizeof(fullname_buf);
2257     params.lpstrFileTitle = NULL;
2258     params.lpstrInitialDir = NULL;
2259 maya 2937 #ifdef I18N
2260     if (readonly) {
2261     strcpy(pvar->ts->UIMsg, "Choose a read-only known-hosts file to add");
2262     UTIL_get_lang_msg("MSG_OPEN_KNOWNHOSTS_RO_TITLE", pvar);
2263     }
2264     else {
2265     strcpy(pvar->ts->UIMsg, "Choose a read/write known-hosts file");
2266     UTIL_get_lang_msg("MSG_OPEN_KNOWNHOSTS_RW_TITLE", pvar);
2267     }
2268     params.lpstrTitle = pvar->ts->UIMsg;
2269     #else
2270 yutakakn 2728 params.lpstrTitle =
2271     readonly ? "Choose a read-only known-hosts file to add" :
2272     "Choose a read/write known-hosts file";
2273 maya 2937 #endif
2274 yutakakn 2728 params.Flags = (readonly ? OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST : 0)
2275     | OFN_HIDEREADONLY | (!readonly ? OFN_NOREADONLYRETURN : 0);
2276     params.lpstrDefExt = NULL;
2277    
2278     if (GetOpenFileName(&params) != 0) {
2279     copy_teraterm_dir_relative_path(buf, bufsize, fullname_buf);
2280     return 1;
2281     } else {
2282     int err = CommDlgExtendedError();
2283    
2284     if (err != 0) {
2285     char buf[1024];
2286 maya 2937 #ifdef I18N
2287     strcpy(pvar->ts->UIMsg, "Cannot show file dialog box: error %d");
2288     UTIL_get_lang_msg("MSG_OPEN_FILEDLG_KNOWNHOSTS_ERROR", pvar);
2289     _snprintf(buf, sizeof(buf), pvar->ts->UIMsg, err);
2290     #else
2291 yutakakn 2728 _snprintf(buf, sizeof(buf),
2292