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 4871 - (hide annotations) (download) (as text)
Mon Apr 2 17:00:40 2012 UTC (12 years ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 166233 byte(s)
SSH鍵生成ダイアログで、公開鍵のコメントを指定出来るようにした。
https://twitter.com/#!/akabekobeko/status/186806136379424768

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