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 4531 - (hide annotations) (download) (as text)
Tue Jul 26 08:50:11 2011 UTC (12 years, 8 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 163914 byte(s)
RFC 4255 "Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints" 対応の準備
http://tools.ietf.org/html/rfc4255

VerifyHostKeyDNS = 1 にすると、ホスト鍵の検証を行う。
検証するだけで検証結果は使ってないけれど。

DNSSEC 未対応の問題が有るので、その部分について検討中。
解決する目途が立っていないので、もしかするとお蔵入りするかも。

Windows95/98/Me/NT4 では動かないかも。

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