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