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 4533 - (hide annotations) (download) (as text)
Tue Jul 26 15:07:33 2011 UTC (12 years, 8 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 164228 byte(s)
TTSSHのバージョンダイアログに、PuTTYバージョンを表記するようにした。

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