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 5261 - (hide annotations) (download) (as text)
Mon May 13 05:37:00 2013 UTC (10 years, 11 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 167868 byte(s)
SSH接続時のアイコンを指定出来るようにした。

1 maya 3227 /*
2     Copyright (c) 1998-2001, Robert O'Callahan
3     All rights reserved.
4    
5     Redistribution and use in source and binary forms, with or without modification,
6     are permitted provided that the following conditions are met:
7    
8     Redistributions of source code must retain the above copyright notice, this list of
9     conditions and the following disclaimer.
10    
11     Redistributions in binary form must reproduce the above copyright notice, this list
12     of conditions and the following disclaimer in the documentation and/or other materials
13     provided with the distribution.
14    
15     The name of Robert O'Callahan may not be used to endorse or promote products derived from
16     this software without specific prior written permission.
17    
18     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21     THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27     */
28    
29     /* Tera Term extension mechanism
30     Robert O'Callahan (roc+tt@cs.cmu.edu)
31    
32     Tera Term by Takashi Teranishi (teranishi@rikaxp.riken.go.jp)
33     */
34    
35     #include "ttxssh.h"
36     #include "fwdui.h"
37     #include "util.h"
38     #include "ssh.h"
39     #include "ttcommon.h"
40 r850 3298 #include "ttlib.h"
41 maya 3227
42     #include <stdlib.h>
43     #include <stdio.h>
44     #include <string.h>
45     #include <io.h>
46     #include <fcntl.h>
47     #include <sys/stat.h>
48     #include <time.h>
49 doda 3232 #include <mbstring.h>
50 maya 3227
51     #include "resource.h"
52     #include <commctrl.h>
53     #include <commdlg.h>
54     #ifndef NO_INET6
55     #include <winsock2.h>
56     static char FAR *ProtocolFamilyList[] = { "UNSPEC", "IPv6", "IPv4", NULL };
57     #else
58     #include <winsock.h>
59     #endif /* NO_INET6 */
60    
61     #include <Lmcons.h>
62    
63     // include OpenSSL header file
64     #include <openssl/opensslv.h>
65     #include <openssl/evp.h>
66     #include <openssl/rsa.h>
67     #include <openssl/dsa.h>
68     #include <openssl/bn.h>
69     #include <openssl/pem.h>
70     #include <openssl/rand.h>
71     #include <openssl/rc4.h>
72     #include <openssl/md5.h>
73    
74     // include ZLib header file
75     #include <zlib.h>
76    
77     #include "buffer.h"
78     #include "cipher.h"
79 maya 4321 #include "key.h"
80 maya 3227
81     #include "sftp.h"
82    
83     #include "compat_w95.h"
84    
85 yutakapon 4533 #include "puttyversion.h"
86    
87 maya 3227 #define MATCH_STR(s, o) strncmp((s), (o), NUM_ELEM(o) - 1)
88     #define MATCH_STR_I(s, o) _strnicmp((s), (o), NUM_ELEM(o) - 1)
89    
90     /* This extension implements SSH, so we choose a load order in the
91     "protocols" range. */
92     #define ORDER 2500
93    
94     static HICON SecureLargeIcon = NULL;
95     static HICON SecureSmallIcon = NULL;
96    
97     static HFONT DlgHostFont;
98     static HFONT DlgAboutFont;
99     static HFONT DlgSetupFont;
100     static HFONT DlgKeygenFont;
101    
102     static TInstVar FAR *pvar;
103    
104     typedef struct {
105 maya 4307 int cnt;
106     HWND dlg;
107 maya 4378 ssh_keytype type;
108 maya 3227 } cbarg_t;
109    
110     /* WIN32 allows multiple instances of a DLL */
111     static TInstVar InstVar;
112    
113     /*
114     This code makes lots of assumptions about the order in which Tera Term
115     does things, and how. A key assumption is that the Notification window
116     passed into WSAAsyncSelect is the main terminal window. We also assume
117     that the socket used in the first WSAconnect is the main session socket.
118     */
119    
120     static void init_TTSSH(PTInstVar pvar)
121     {
122     pvar->socket = INVALID_SOCKET;
123     pvar->OldLargeIcon = NULL;
124     pvar->OldSmallIcon = NULL;
125     pvar->NotificationWindow = NULL;
126     pvar->hostdlg_activated = FALSE;
127     pvar->socket = INVALID_SOCKET;
128     pvar->NotificationWindow = NULL;
129     pvar->protocol_major = 0;
130     pvar->protocol_minor = 0;
131    
132     PKT_init(pvar);
133     SSH_init(pvar);
134     CRYPT_init(pvar);
135     AUTH_init(pvar);
136     HOSTS_init(pvar);
137     FWD_init(pvar);
138     FWDUI_init(pvar);
139    
140     ssh_heartbeat_lock_initialize();
141     }
142    
143     static void uninit_TTSSH(PTInstVar pvar)
144     {
145     halt_ssh_heartbeat_thread(pvar);
146    
147     ssh2_channel_free();
148    
149     SSH_end(pvar);
150     PKT_end(pvar);
151     AUTH_end(pvar);
152     CRYPT_end(pvar);
153     HOSTS_end(pvar);
154     FWD_end(pvar);
155     FWDUI_end(pvar);
156    
157     if (pvar->OldLargeIcon != NULL) {
158     PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_BIG,
159     (LPARAM) pvar->OldLargeIcon);
160     pvar->OldLargeIcon = NULL;
161     }
162     if (pvar->OldSmallIcon != NULL) {
163     PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_SMALL,
164     (LPARAM) pvar->OldSmallIcon);
165     pvar->OldSmallIcon = NULL;
166     }
167    
168     ssh_heartbeat_lock_finalize();
169     }
170    
171     static void PASCAL FAR TTXInit(PTTSet ts, PComVar cv)
172     {
173     pvar->settings = *pvar->ts_SSH;
174     pvar->ts = ts;
175     pvar->cv = cv;
176     pvar->fatal_error = FALSE;
177     pvar->showing_err = FALSE;
178     pvar->err_msg = NULL;
179    
180     init_TTSSH(pvar);
181     }
182    
183 maya 4378 static void normalize_generic_order(char *buf, char default_strings[], int default_strings_len)
184     {
185     char listed[max(KEX_DH_MAX,max(SSH_CIPHER_MAX,max(KEY_MAX,max(HMAC_MAX,COMP_MAX)))) + 1];
186     char allowed[max(KEX_DH_MAX,max(SSH_CIPHER_MAX,max(KEY_MAX,max(HMAC_MAX,COMP_MAX)))) + 1];
187     int i, j;
188    
189     memset(listed, 0, sizeof(listed));
190     memset(allowed, 0, sizeof(allowed));
191     for (i = 0; i < default_strings_len ; i++) {
192     allowed[default_strings[i]] = 1;
193     }
194    
195     for (i = 0; buf[i] != 0; i++) {
196     int num = buf[i] - '0';
197    
198     if (num < 0 || num > default_strings_len
199     || !allowed[num]
200     || listed[num]) {
201     memmove(buf + i, buf + i + 1, strlen(buf + i + 1) + 1);
202     i--;
203     } else {
204     listed[num] = 1;
205     }
206     }
207    
208     for (j = 0; j < default_strings_len ; j++) {
209     int num = default_strings[j];
210    
211     if (!listed[num]) {
212     buf[i] = num + '0';
213     i++;
214     }
215     }
216    
217     buf[i] = 0;
218     }
219    
220 maya 3227 /*
221     * Remove unsupported cipher or duplicated cipher.
222     * Add unspecified ciphers at the end of list.
223     */
224     static void normalize_cipher_order(char FAR * buf)
225     {
226     /* SSH_CIPHER_NONE means that all ciphers below that one are disabled.
227     We *never* allow no encryption. */
228     #if 0
229 maya 4378 static char default_strings[] = {
230 maya 3227 SSH_CIPHER_3DES,
231     SSH_CIPHER_NONE,
232     SSH_CIPHER_DES, SSH_CIPHER_BLOWFISH
233     };
234     #else
235     // for SSH2(yutaka)
236 maya 4378 static char default_strings[] = {
237 doda 4433 SSH2_CIPHER_CAMELLIA256_CTR,
238 maya 3227 SSH2_CIPHER_AES256_CTR,
239 doda 4433 SSH2_CIPHER_CAMELLIA256_CBC,
240 maya 3227 SSH2_CIPHER_AES256_CBC,
241 doda 4433 SSH2_CIPHER_CAMELLIA192_CTR,
242 maya 3227 SSH2_CIPHER_AES192_CTR,
243 doda 4433 SSH2_CIPHER_CAMELLIA192_CBC,
244 maya 3227 SSH2_CIPHER_AES192_CBC,
245 doda 4433 SSH2_CIPHER_CAMELLIA128_CTR,
246 maya 3227 SSH2_CIPHER_AES128_CTR,
247 doda 4433 SSH2_CIPHER_CAMELLIA128_CBC,
248 maya 3227 SSH2_CIPHER_AES128_CBC,
249 doda 3850 SSH2_CIPHER_3DES_CTR,
250 maya 3227 SSH2_CIPHER_3DES_CBC,
251 doda 3850 SSH2_CIPHER_BLOWFISH_CTR,
252 maya 3227 SSH2_CIPHER_BLOWFISH_CBC,
253     SSH2_CIPHER_ARCFOUR256,
254     SSH2_CIPHER_ARCFOUR128,
255     SSH2_CIPHER_ARCFOUR,
256 doda 3850 SSH2_CIPHER_CAST128_CTR,
257 maya 3227 SSH2_CIPHER_CAST128_CBC,
258     SSH_CIPHER_3DES,
259     SSH_CIPHER_NONE,
260     SSH_CIPHER_DES,
261 doda 4392 SSH_CIPHER_BLOWFISH,
262 maya 4432 0, 0, 0 // Dummy for SSH_CIPHER_IDEA, SSH_CIPHER_TSS, SSH_CIPHER_RC4
263 maya 3227 };
264     #endif
265    
266 maya 4378 normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
267 maya 3227 }
268    
269 yutakapon 4367 static void normalize_kex_order(char FAR * buf)
270     {
271     static char default_strings[] = {
272     KEX_ECDH_SHA2_256,
273     KEX_ECDH_SHA2_384,
274     KEX_ECDH_SHA2_521,
275     KEX_DH_GEX_SHA256,
276     KEX_DH_GEX_SHA1,
277     KEX_DH_GRP14_SHA1,
278     KEX_DH_GRP1_SHA1,
279     KEX_DH_NONE,
280     };
281    
282     normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
283     }
284    
285     static void normalize_host_key_order(char FAR * buf)
286     {
287     static char default_strings[] = {
288     KEY_ECDSA256,
289     KEY_ECDSA384,
290     KEY_ECDSA521,
291     KEY_RSA,
292     KEY_DSA,
293     KEY_NONE,
294     };
295    
296     normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
297     }
298    
299     static void normalize_mac_order(char FAR * buf)
300     {
301     static char default_strings[] = {
302 doda 4434 HMAC_SHA2_512,
303     HMAC_SHA2_256,
304 yutakapon 4367 HMAC_SHA1,
305 doda 4423 HMAC_RIPEMD160,
306 yutakapon 4367 HMAC_MD5,
307 doda 4426 HMAC_NONE,
308 doda 4434 HMAC_SHA1_96,
309     HMAC_MD5_96,
310 doda 5016 0, // Dummy for HMAC_SHA2_512_96,
311     0, // Dummy for HMAC_SHA2_256_96,
312 yutakapon 4367 };
313    
314     normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
315     }
316    
317     static void normalize_comp_order(char FAR * buf)
318     {
319     static char default_strings[] = {
320 doda 4371 COMP_DELAYED,
321     COMP_ZLIB,
322 maya 4378 COMP_NOCOMP,
323 yutakapon 4367 COMP_NONE,
324     };
325    
326     normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
327     }
328    
329    
330 maya 3227 /* Remove local settings from the shared memory block. */
331     static void clear_local_settings(PTInstVar pvar)
332     {
333     pvar->ts_SSH->TryDefaultAuth = FALSE;
334     }
335    
336     static BOOL read_BOOL_option(PCHAR fileName, char FAR * keyName, BOOL def)
337     {
338     char buf[1024];
339    
340     buf[0] = 0;
341     GetPrivateProfileString("TTSSH", keyName, "", buf, sizeof(buf),
342     fileName);
343     if (buf[0] == 0) {
344     return def;
345     } else {
346     return atoi(buf) != 0 ||
347     _stricmp(buf, "yes") == 0 ||
348     _stricmp(buf, "y") == 0;
349     }
350     }
351    
352     static void read_string_option(PCHAR fileName, char FAR * keyName,
353     char FAR * def, char FAR * buf, int bufSize)
354     {
355    
356     buf[0] = 0;
357     GetPrivateProfileString("TTSSH", keyName, def, buf, bufSize, fileName);
358     }
359    
360     static void read_ssh_options(PTInstVar pvar, PCHAR fileName)
361     {
362     char buf[1024];
363     TS_SSH FAR *settings = pvar->ts_SSH;
364    
365     #define READ_STD_STRING_OPTION(name) \
366     read_string_option(fileName, #name, "", settings->name, sizeof(settings->name))
367    
368     settings->Enabled = read_BOOL_option(fileName, "Enabled", FALSE);
369    
370     buf[0] = 0;
371     GetPrivateProfileString("TTSSH", "Compression", "", buf, sizeof(buf),
372     fileName);
373     settings->CompressionLevel = atoi(buf);
374     if (settings->CompressionLevel < 0 || settings->CompressionLevel > 9) {
375     settings->CompressionLevel = 0;
376     }
377    
378     READ_STD_STRING_OPTION(DefaultUserName);
379     READ_STD_STRING_OPTION(DefaultForwarding);
380     READ_STD_STRING_OPTION(DefaultRhostsLocalUserName);
381     READ_STD_STRING_OPTION(DefaultRhostsHostPrivateKeyFile);
382     READ_STD_STRING_OPTION(DefaultRSAPrivateKeyFile);
383    
384     READ_STD_STRING_OPTION(CipherOrder);
385     normalize_cipher_order(settings->CipherOrder);
386    
387 yutakapon 4367 // KEX order
388     READ_STD_STRING_OPTION(KexOrder);
389     normalize_kex_order(settings->KexOrder);
390     // Host Key algorithm order
391     READ_STD_STRING_OPTION(HostKeyOrder);
392     normalize_host_key_order(settings->HostKeyOrder);
393     // H-MAC order
394     READ_STD_STRING_OPTION(MacOrder);
395     normalize_mac_order(settings->MacOrder);
396     // Compression algorithm order
397     READ_STD_STRING_OPTION(CompOrder);
398     normalize_comp_order(settings->CompOrder);
399    
400 maya 3227 read_string_option(fileName, "KnownHostsFiles", "ssh_known_hosts",
401     settings->KnownHostsFiles,
402     sizeof(settings->KnownHostsFiles));
403    
404     buf[0] = 0;
405     GetPrivateProfileString("TTSSH", "DefaultAuthMethod", "", buf,
406     sizeof(buf), fileName);
407     settings->DefaultAuthMethod = atoi(buf);
408     if (settings->DefaultAuthMethod != SSH_AUTH_PASSWORD
409     && settings->DefaultAuthMethod != SSH_AUTH_RSA
410     && settings->DefaultAuthMethod != SSH_AUTH_TIS // add (2005.3.12 yutaka)
411     && settings->DefaultAuthMethod != SSH_AUTH_RHOSTS
412     && settings->DefaultAuthMethod != SSH_AUTH_PAGEANT) {
413     /* this default can never be SSH_AUTH_RHOSTS_RSA because that is not a
414     selection in the dialog box; SSH_AUTH_RHOSTS_RSA is automatically chosen
415     when the dialog box has rhosts selected and an host private key file
416     is supplied. */
417     settings->DefaultAuthMethod = SSH_AUTH_PASSWORD;
418     }
419    
420     buf[0] = 0;
421     GetPrivateProfileString("TTSSH", "LogLevel", "", buf, sizeof(buf),
422     fileName);
423     settings->LogLevel = atoi(buf);
424    
425     buf[0] = 0;
426     GetPrivateProfileString("TTSSH", "WriteBufferSize", "", buf,
427     sizeof(buf), fileName);
428     settings->WriteBufferSize = atoi(buf);
429     if (settings->WriteBufferSize <= 0) {
430     settings->WriteBufferSize = (PACKET_MAX_SIZE / 2); // 2MB
431     }
432    
433     // SSH protocol version (2004.10.11 yutaka)
434     // default is SSH2 (2004.11.30 yutaka)
435     settings->ssh_protocol_version = GetPrivateProfileInt("TTSSH", "ProtocolVersion", 2, fileName);
436    
437     // SSH heartbeat time(second) (2004.12.11 yutaka)
438     settings->ssh_heartbeat_overtime = GetPrivateProfileInt("TTSSH", "HeartBeat", 60, fileName);
439    
440     // �p�X���[�h�F�����������J���F�����g���p�X���[�h����������������������������������
441     // �\���B(2006.8.5 yutaka)
442     settings->remember_password = GetPrivateProfileInt("TTSSH", "RememberPassword", 1, fileName);
443    
444     // �������F���_�C�A���O���T�|�[�g�������������\�b�h���`�F�b�N���A
445     // ���������\�b�h���O���C�A�E�g���� (2007.9.24 maya)
446     settings->CheckAuthListFirst = read_BOOL_option(fileName, "CheckAuthListFirst", FALSE);
447    
448     // 768bit ������ RSA ���������T�[�o�����������L�������� (2008.9.11 maya)
449     settings->EnableRsaShortKeyServer = read_BOOL_option(fileName, "EnableRsaShortKeyServer", FALSE);
450    
451     // agent forward ���L�������� (2008.11.25 maya)
452     settings->ForwardAgent = read_BOOL_option(fileName, "ForwardAgent", FALSE);
453    
454 maya 4229 // agent forward �m�F���L��������
455     settings->ForwardAgentConfirm = read_BOOL_option(fileName, "ForwardAgentConfirm", TRUE);
456    
457 doda 4531 // �z�X�g���� DNS �����`�F�b�N (RFC 4255)
458 doda 4619 settings->VerifyHostKeyDNS = read_BOOL_option(fileName, "VerifyHostKeyDNS", TRUE);
459 doda 4531
460 doda 5261 // icon
461     GetPrivateProfileString("TTSSH", "SSHIcon", "", buf, sizeof(buf), fileName);
462     if ((_stricmp(buf, "old") == 0) ||
463     (_stricmp(buf, "yellow") == 0) ||
464     (_stricmp(buf, "securett_yellow") == 0)) {
465     settings->IconID = IDI_SECURETT_YELLOW;
466     }
467     else {
468     settings->IconID = IDI_SECURETT;
469     }
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     // �z�X�g���� DNS �����`�F�b�N (RFC 4255)
565     WritePrivateProfileString("TTSSH", "VerifyHostKeyDNS",
566     settings->VerifyHostKeyDNS ? "1" : "0", fileName);
567 maya 3227 }
568    
569    
570     /* find free port in all protocol family */
571     static unsigned short find_local_port(PTInstVar pvar)
572     {
573     int tries;
574     #ifndef NO_INET6
575     SOCKET connecter;
576     struct addrinfo hints;
577     struct addrinfo FAR *res;
578     struct addrinfo FAR *res0;
579     unsigned short port;
580     char pname[NI_MAXHOST];
581     #endif /* NO_INET6 */
582    
583     if (pvar->session_settings.DefaultAuthMethod != SSH_AUTH_RHOSTS) {
584     return 0;
585     }
586    
587     /* The random numbers here are only used to try to get fresh
588     ports across runs (dangling ports can cause bind errors
589     if we're unlucky). They do not need to be (and are not)
590     cryptographically strong.
591     */
592     srand((unsigned) GetTickCount());
593    
594     #ifndef NO_INET6
595     for (tries = 20; tries > 0; tries--) {
596     memset(&hints, 0, sizeof(hints));
597     hints.ai_family = pvar->ts->ProtocolFamily;
598     hints.ai_flags = AI_PASSIVE;
599     hints.ai_socktype = SOCK_STREAM;
600     port = (unsigned) rand() % 512 + 512;
601     _snprintf_s(pname, sizeof(pname), _TRUNCATE, "%d", (int) port);
602     if (getaddrinfo(NULL, pname, &hints, &res0)) {
603     return 0;
604     /* NOT REACHED */
605     }
606    
607     for (res = res0; res; res = res->ai_next) {
608     if (res->ai_family == AF_INET || res->ai_family == AF_INET6)
609     continue;
610    
611     connecter =
612     socket(res->ai_family, res->ai_socktype, res->ai_protocol);
613     if (connecter == INVALID_SOCKET) {
614     freeaddrinfo(res0);
615     return 0;
616     }
617    
618     if (bind(connecter, res->ai_addr, res->ai_addrlen) !=
619     SOCKET_ERROR) {
620     return port;
621     freeaddrinfo(res0);
622     closesocket(connecter);
623     } else if (WSAGetLastError() != WSAEADDRINUSE) {
624     closesocket(connecter);
625     freeaddrinfo(res0);
626     return 0;
627     }
628    
629     closesocket(connecter);
630     }
631     freeaddrinfo(res0);
632     }
633    
634     return 0;
635     #else
636     for (tries = 20; tries > 0; tries--) {
637     SOCKET connecter = socket(AF_INET, SOCK_STREAM, 0);
638     struct sockaddr_in connecter_addr;
639    
640     connecter_addr.sin_family = AF_INET;
641     connecter_addr.sin_port = (unsigned) rand() % 512 + 512;
642     connecter_addr.sin_addr.s_addr = htonl(INADDR_ANY);
643    
644     if (connecter == INVALID_SOCKET) {
645     return 0;
646     }
647    
648     if (bind
649     (connecter, (struct sockaddr FAR *) &connecter_addr,
650     sizeof(connecter_addr)) != SOCKET_ERROR) {
651     closesocket(connecter);
652     return connecter_addr.sin_port;
653     } else if (WSAGetLastError() != WSAEADDRINUSE) {
654     closesocket(connecter);
655     return 0;
656     }
657    
658     closesocket(connecter);
659     }
660    
661     return 0;
662     #endif /* NO_INET6 */
663     }
664    
665     static int PASCAL FAR TTXconnect(SOCKET s,
666     const struct sockaddr FAR * name,
667     int namelen)
668     {
669     #ifndef NO_INET6
670 maya 4584 if (pvar->socket == INVALID_SOCKET || pvar->socket != s) {
671 maya 3227 struct sockaddr_storage ss;
672     int len;
673    
674     pvar->socket = s;
675    
676     memset(&ss, 0, sizeof(ss));
677     switch (pvar->ts->ProtocolFamily) {
678     case AF_INET:
679     len = sizeof(struct sockaddr_in);
680     ((struct sockaddr_in FAR *) &ss)->sin_family = AF_INET;
681     ((struct sockaddr_in FAR *) &ss)->sin_addr.s_addr = INADDR_ANY;
682     ((struct sockaddr_in FAR *) &ss)->sin_port =
683     htons(find_local_port(pvar));
684     break;
685     case AF_INET6:
686     len = sizeof(struct sockaddr_in6);
687     ((struct sockaddr_in6 FAR *) &ss)->sin6_family = AF_INET6;
688     #if 0 /* symbol "in6addr_any" is not included in wsock32.lib */
689     /* if wsock32.lib will be linked, we can't refer "in6addr_any" */
690     ((struct sockaddr_in6 FAR *) &ss)->sin6_addr = in6addr_any;
691     #else
692     memset(&((struct sockaddr_in6 FAR *) &ss)->sin6_addr, 0,
693     sizeof(struct in_addr6));
694     #endif /* 0 */
695     ((struct sockaddr_in6 FAR *) &ss)->sin6_port =
696     htons(find_local_port(pvar));
697     break;
698     default:
699 maya 4586 /* UNSPEC */
700 maya 3227 break;
701     }
702    
703     bind(s, (struct sockaddr FAR *) &ss, len);
704     }
705     #else
706     if (pvar->socket == INVALID_SOCKET) {
707     struct sockaddr_in addr;
708    
709     pvar->socket = s;
710    
711     addr.sin_family = AF_INET;
712     addr.sin_port = htons(find_local_port(pvar));
713     addr.sin_addr.s_addr = INADDR_ANY;
714     memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
715    
716     bind(s, (struct sockaddr FAR *) &addr, sizeof(addr));
717     }
718     #endif /* NO_INET6 */
719    
720     return (pvar->Pconnect) (s, name, namelen);
721     }
722    
723     static int PASCAL FAR TTXWSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,
724     long lEvent)
725     {
726     if (s == pvar->socket) {
727     pvar->notification_events = lEvent;
728     pvar->notification_msg = wMsg;
729    
730     if (pvar->NotificationWindow == NULL) {
731     pvar->NotificationWindow = hWnd;
732     AUTH_advance_to_next_cred(pvar);
733     }
734     }
735    
736     return (pvar->PWSAAsyncSelect) (s, hWnd, wMsg, lEvent);
737     }
738    
739     static int PASCAL FAR TTXrecv(SOCKET s, char FAR * buf, int len, int flags)
740     {
741     if (s == pvar->socket) {
742     int ret;
743    
744     ssh_heartbeat_lock();
745     ret = PKT_recv(pvar, buf, len);
746     ssh_heartbeat_unlock();
747     return (ret);
748    
749     } else {
750     return (pvar->Precv) (s, buf, len, flags);
751     }
752     }
753    
754     static int PASCAL FAR TTXsend(SOCKET s, char const FAR * buf, int len,
755     int flags)
756     {
757     if (s == pvar->socket) {
758     ssh_heartbeat_lock();
759     SSH_send(pvar, buf, len);
760     ssh_heartbeat_unlock();
761     return len;
762     } else {
763     return (pvar->Psend) (s, buf, len, flags);
764     }
765     }
766    
767     void notify_established_secure_connection(PTInstVar pvar)
768     {
769     int fuLoad = LR_DEFAULTCOLOR;
770    
771     if (is_NT4()) {
772     fuLoad = LR_VGACOLOR;
773     }
774    
775     // LoadIcon �������� LoadImage ���g�����������A
776     // 16x16 ���A�C�R���������I�������������������� (2006.8.9 maya)
777     if (SecureLargeIcon == NULL) {
778 doda 5261 SecureLargeIcon = LoadImage(hInst, MAKEINTRESOURCE(pvar->settings.IconID),
779 maya 3227 IMAGE_ICON, 0, 0, fuLoad);
780     }
781     if (SecureSmallIcon == NULL) {
782 doda 5261 SecureSmallIcon = LoadImage(hInst, MAKEINTRESOURCE(pvar->settings.IconID),
783 maya 3227 IMAGE_ICON, 16, 16, fuLoad);
784     }
785    
786     if (SecureLargeIcon != NULL && SecureSmallIcon != NULL) {
787 maya 3454 #if 0
788 maya 3227 // �������A�C�R���� WNDCLASS ���Z�b�g�����������������o���������� (2006.8.10 maya)
789     pvar->OldLargeIcon =
790     (HICON) GetClassLong(pvar->NotificationWindow, GCL_HICON);
791 maya 3454 #else
792     // Tera Term ���� WM_SETICON �������������������������������o�� (2009.6.9 maya)
793     pvar->OldLargeIcon =
794     (HICON) SendMessage(pvar->NotificationWindow, WM_GETICON,
795     ICON_BIG, 0);
796     #endif
797 maya 3227 pvar->OldSmallIcon =
798     (HICON) SendMessage(pvar->NotificationWindow, WM_GETICON,
799     ICON_SMALL, 0);
800    
801     PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_BIG,
802     (LPARAM) SecureLargeIcon);
803     PostMessage(pvar->NotificationWindow, WM_SETICON, ICON_SMALL,
804     (LPARAM) SecureSmallIcon);
805     }
806    
807     notify_verbose_message(pvar, "Entering secure mode",
808     LOG_LEVEL_VERBOSE);
809     }
810    
811     void notify_closed_connection(PTInstVar pvar)
812     {
813     SSH_notify_disconnecting(pvar, NULL);
814     AUTH_notify_disconnecting(pvar);
815     HOSTS_notify_disconnecting(pvar);
816    
817     PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,
818     pvar->socket, MAKELPARAM(FD_CLOSE, 0));
819    
820     }
821    
822     static void add_err_msg(PTInstVar pvar, char FAR * msg)
823     {
824     if (pvar->err_msg != NULL) {
825     int buf_len = strlen(pvar->err_msg) + 3 + strlen(msg);
826     char FAR *buf = (char FAR *) malloc(buf_len);
827    
828     strncpy_s(buf, buf_len, pvar->err_msg, _TRUNCATE);
829     strncat_s(buf, buf_len, "\n\n", _TRUNCATE);
830     strncat_s(buf, buf_len, msg, _TRUNCATE);
831     free(pvar->err_msg);
832     pvar->err_msg = buf;
833     } else {
834     pvar->err_msg = _strdup(msg);
835     }
836     }
837    
838     void notify_nonfatal_error(PTInstVar pvar, char FAR * msg)
839     {
840     if (!pvar->showing_err) {
841     // �������������������m���E�B���h�E�����������A�f�X�N�g�b�v���I�[�i�[������
842     // ���b�Z�[�W�{�b�N�X���o���������B(2006.6.11 yutaka)
843     if (pvar->NotificationWindow == NULL) {
844     UTIL_get_lang_msg("MSG_ERROR_NONFAITAL", pvar,
845     "Tera Term: not fatal error");
846     MessageBox(NULL, msg, pvar->ts->UIMsg, MB_OK|MB_ICONINFORMATION);
847     msg[0] = '\0';
848    
849     } else {
850     PostMessage(pvar->NotificationWindow, WM_COMMAND,
851     ID_SSHASYNCMESSAGEBOX, 0);
852     }
853     }
854     if (msg[0] != 0) {
855     notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR);
856     add_err_msg(pvar, msg);
857     }
858     }
859    
860     void notify_fatal_error(PTInstVar pvar, char FAR * msg)
861     {
862     if (msg[0] != 0) {
863     notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL);
864     add_err_msg(pvar, msg);
865     }
866    
867     if (!pvar->fatal_error) {
868     pvar->fatal_error = TRUE;
869    
870     SSH_notify_disconnecting(pvar, msg);
871     AUTH_notify_disconnecting(pvar);
872     HOSTS_notify_disconnecting(pvar);
873    
874     PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,
875     pvar->socket, MAKELPARAM(FD_CLOSE,
876     (pvar->PWSAGetLastError) ()));
877     }
878     }
879    
880     void notify_verbose_message(PTInstVar pvar, char FAR * msg, int level)
881     {
882     if (level <= pvar->session_settings.LogLevel) {
883     char buf[1024];
884     int file;
885    
886     get_teraterm_dir_relative_name(buf, NUM_ELEM(buf), "TTSSH.LOG");
887     file = _open(buf, _O_RDWR | _O_APPEND | _O_CREAT | _O_TEXT,
888     _S_IREAD | _S_IWRITE);
889    
890     if (file >= 0) {
891 maya 4551 char *strtime = mctimelocal();
892 maya 4546 DWORD processid;
893 maya 3227 char tmp[26];
894 maya 4546
895     _write(file, strtime, strlen(strtime));
896 maya 3227 GetWindowThreadProcessId(pvar->cv->HWin, &processid);
897     _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, " [%lu] ",processid);
898     _write(file, tmp, strlen(tmp));
899     _write(file, msg, strlen(msg));
900     _write(file, "\n", 1);
901     _close(file);
902     }
903     }
904     }
905    
906     static void PASCAL FAR TTXOpenTCP(TTXSockHooks FAR * hooks)
907     {
908     if (pvar->settings.Enabled) {
909     // TCPLocalEcho/TCPCRSend ������������ (maya 2007.4.25)
910 doda 3579 pvar->origDisableTCPEchoCR = pvar->ts->DisableTCPEchoCR;
911 maya 3227 pvar->ts->DisableTCPEchoCR = TRUE;
912    
913     pvar->session_settings = pvar->settings;
914    
915     notify_verbose_message(pvar, "---------------------------------------------------------------------", LOG_LEVEL_VERBOSE);
916     notify_verbose_message(pvar, "Initiating SSH session", LOG_LEVEL_VERBOSE);
917    
918     FWDUI_load_settings(pvar);
919    
920     pvar->cv->TelAutoDetect = FALSE;
921     /* This next line should not be needed because Tera Term's
922     CommLib should find ts->Telnet == 0 ... but we'll do this
923     just to be on the safe side. */
924     pvar->cv->TelFlag = FALSE;
925 doda 3495 pvar->cv->TelLineMode = FALSE;
926 maya 3227
927     pvar->Precv = *hooks->Precv;
928     pvar->Psend = *hooks->Psend;
929     pvar->PWSAAsyncSelect = *hooks->PWSAAsyncSelect;
930     pvar->Pconnect = *hooks->Pconnect;
931     pvar->PWSAGetLastError = *hooks->PWSAGetLastError;
932    
933     *hooks->Precv = TTXrecv;
934     *hooks->Psend = TTXsend;
935     *hooks->PWSAAsyncSelect = TTXWSAAsyncSelect;
936     *hooks->Pconnect = TTXconnect;
937    
938     SSH_open(pvar);
939     HOSTS_open(pvar);
940     FWDUI_open(pvar);
941    
942     // ������ myproposal �����f���������A�������O�����������B (2006.6.26 maya)
943     SSH2_update_cipher_myproposal(pvar);
944 yutakapon 4367 SSH2_update_kex_myproposal(pvar);
945     SSH2_update_host_key_myproposal(pvar);
946     SSH2_update_hmac_myproposal(pvar);
947 maya 3227 SSH2_update_compression_myproposal(pvar);
948     }
949     }
950    
951     static void PASCAL FAR TTXCloseTCP(TTXSockHooks FAR * hooks)
952     {
953     if (pvar->session_settings.Enabled) {
954     pvar->socket = INVALID_SOCKET;
955    
956     notify_verbose_message(pvar, "Terminating SSH session...",
957     LOG_LEVEL_VERBOSE);
958    
959     *hooks->Precv = pvar->Precv;
960     *hooks->Psend = pvar->Psend;
961     *hooks->PWSAAsyncSelect = pvar->PWSAAsyncSelect;
962     *hooks->Pconnect = pvar->Pconnect;
963 doda 3579
964     pvar->ts->DisableTCPEchoCR = pvar->origDisableTCPEchoCR;
965 maya 3227 }
966    
967     uninit_TTSSH(pvar);
968     init_TTSSH(pvar);
969     }
970    
971     static void enable_dlg_items(HWND dlg, int from, int to, BOOL enabled)
972     {
973     for (; from <= to; from++) {
974     EnableWindow(GetDlgItem(dlg, from), enabled);
975     }
976     }
977    
978     // C-p/C-n/C-b/C-f/C-a/C-e ���T�|�[�g (2007.9.5 maya)
979     // C-d/C-k ���T�|�[�g (2007.10.3 yutaka)
980     // �h���b�v�_�E���������G�f�B�b�g�R���g���[����
981     // �T�u�N���X�������������E�C���h�E�v���V�[�W��
982     WNDPROC OrigHostnameEditProc; // Original window procedure
983     LRESULT CALLBACK HostnameEditProc(HWND dlg, UINT msg,
984     WPARAM wParam, LPARAM lParam)
985     {
986     HWND parent;
987     int max, select, len;
988     char *str, *orgstr;
989    
990     switch (msg) {
991     // �L�[�����������������m����
992     case WM_KEYDOWN:
993     if (GetKeyState(VK_CONTROL) < 0) {
994     switch (wParam) {
995     case 0x50: // Ctrl+p ... up
996     parent = GetParent(dlg);
997     select = SendMessage(parent, CB_GETCURSEL, 0, 0);
998     if (select > 0) {
999     PostMessage(parent, CB_SETCURSEL, select - 1, 0);
1000     }
1001     return 0;
1002     case 0x4e: // Ctrl+n ... down
1003     parent = GetParent(dlg);
1004     max = SendMessage(parent, CB_GETCOUNT, 0, 0);
1005     select = SendMessage(parent, CB_GETCURSEL, 0, 0);
1006     if (select < max - 1) {
1007     PostMessage(parent, CB_SETCURSEL, select + 1, 0);
1008     }
1009     return 0;
1010     case 0x42: // Ctrl+b ... left
1011     SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1012     PostMessage(dlg, EM_SETSEL, select-1, select-1);
1013     return 0;
1014     case 0x46: // Ctrl+f ... right
1015     SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1016     max = GetWindowTextLength(dlg) ;
1017     PostMessage(dlg, EM_SETSEL, select+1, select+1);
1018     return 0;
1019     case 0x41: // Ctrl+a ... home
1020     PostMessage(dlg, EM_SETSEL, 0, 0);
1021     return 0;
1022     case 0x45: // Ctrl+e ... end
1023     max = GetWindowTextLength(dlg) ;
1024     PostMessage(dlg, EM_SETSEL, max, max);
1025     return 0;
1026    
1027     case 0x44: // Ctrl+d
1028     case 0x4b: // Ctrl+k
1029     case 0x55: // Ctrl+u
1030     SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1031     max = GetWindowTextLength(dlg);
1032     max++; // '\0'
1033     orgstr = str = malloc(max);
1034     if (str != NULL) {
1035     len = GetWindowText(dlg, str, max);
1036     if (select >= 0 && select < len) {
1037     if (wParam == 0x44) { // �J�[�\���z����������������������
1038     memmove(&str[select], &str[select + 1], len - select - 1);
1039     str[len - 1] = '\0';
1040    
1041     } else if (wParam == 0x4b) { // �J�[�\�������s��������������
1042     str[select] = '\0';
1043    
1044     }
1045     }
1046    
1047     if (wParam == 0x55) { // �J�[�\����������������������
1048     if (select >= len) {
1049     str[0] = '\0';
1050     } else {
1051     str = &str[select];
1052     }
1053     select = 0;
1054     }
1055    
1056     SetWindowText(dlg, str);
1057     SendMessage(dlg, EM_SETSEL, select, select);
1058     free(orgstr);
1059     return 0;
1060     }
1061     break;
1062     }
1063     }
1064     break;
1065    
1066     // �����L�[��������������������������������������������
1067     case WM_CHAR:
1068     switch (wParam) {
1069     case 0x01:
1070     case 0x02:
1071     case 0x04:
1072     case 0x05:
1073     case 0x06:
1074     case 0x0b:
1075     case 0x0e:
1076     case 0x10:
1077     case 0x15:
1078     return 0;
1079     }
1080     }
1081    
1082     return CallWindowProc(OrigHostnameEditProc, dlg, msg, wParam, lParam);
1083     }
1084    
1085     static BOOL CALLBACK TTXHostDlg(HWND dlg, UINT msg, WPARAM wParam,
1086     LPARAM lParam)
1087     {
1088     static char *ssh_version[] = {"SSH1", "SSH2", NULL};
1089     PGetHNRec GetHNRec;
1090     char EntName[128];
1091     char TempHost[HostNameMaxLength + 1];
1092     WORD i, j, w;
1093     WORD ComPortTable[MAXCOMPORT];
1094     static char *ComPortDesc[MAXCOMPORT];
1095     int comports;
1096     BOOL Ok;
1097     LOGFONT logfont;
1098     HFONT font;
1099     char uimsg[MAX_UIMSG];
1100     static HWND hwndHostname = NULL; // HOSTNAME dropdown
1101     static HWND hwndHostnameEdit = NULL; // Edit control on HOSTNAME dropdown
1102    
1103     switch (msg) {
1104     case WM_INITDIALOG:
1105     GetHNRec = (PGetHNRec) lParam;
1106     SetWindowLong(dlg, DWL_USER, lParam);
1107    
1108     GetWindowText(dlg, uimsg, sizeof(uimsg));
1109     UTIL_get_lang_msg("DLG_HOST_TITLE", pvar, uimsg);
1110     SetWindowText(dlg, pvar->ts->UIMsg);
1111     GetDlgItemText(dlg, IDC_HOSTNAMELABEL, uimsg, sizeof(uimsg));
1112     UTIL_get_lang_msg("DLG_HOST_TCPIPHOST", pvar, uimsg);
1113     SetDlgItemText(dlg, IDC_HOSTNAMELABEL, pvar->ts->UIMsg);
1114     GetDlgItemText(dlg, IDC_HISTORY, uimsg, sizeof(uimsg));
1115     UTIL_get_lang_msg("DLG_HOST_TCPIPHISTORY", pvar, uimsg);
1116     SetDlgItemText(dlg, IDC_HISTORY, pvar->ts->UIMsg);
1117     GetDlgItemText(dlg, IDC_SERVICELABEL, uimsg, sizeof(uimsg));
1118     UTIL_get_lang_msg("DLG_HOST_TCPIPSERVICE", pvar, uimsg);
1119     SetDlgItemText(dlg, IDC_SERVICELABEL, pvar->ts->UIMsg);
1120     GetDlgItemText(dlg, IDC_HOSTOTHER, uimsg, sizeof(uimsg));
1121     UTIL_get_lang_msg("DLG_HOST_TCPIPOTHER", pvar, uimsg);
1122     SetDlgItemText(dlg, IDC_HOSTOTHER, pvar->ts->UIMsg);
1123     GetDlgItemText(dlg, IDC_HOSTTCPPORTLABEL, uimsg, sizeof(uimsg));
1124     UTIL_get_lang_msg("DLG_HOST_TCPIPPORT", pvar, uimsg);
1125     SetDlgItemText(dlg, IDC_HOSTTCPPORTLABEL, pvar->ts->UIMsg);
1126     GetDlgItemText(dlg, IDC_SSH_VERSION_LABEL, uimsg, sizeof(uimsg));
1127     UTIL_get_lang_msg("DLG_HOST_TCPIPSSHVERSION", pvar, uimsg);
1128     SetDlgItemText(dlg, IDC_SSH_VERSION_LABEL, pvar->ts->UIMsg);
1129     GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOLLABEL, uimsg, sizeof(uimsg));
1130     UTIL_get_lang_msg("DLG_HOST_TCPIPPROTOCOL", pvar, uimsg);
1131     SetDlgItemText(dlg, IDC_HOSTTCPPROTOCOLLABEL, pvar->ts->UIMsg);
1132     GetDlgItemText(dlg, IDC_HOSTSERIAL, uimsg, sizeof(uimsg));
1133     UTIL_get_lang_msg("DLG_HOST_SERIAL", pvar, uimsg);
1134     SetDlgItemText(dlg, IDC_HOSTSERIAL, pvar->ts->UIMsg);
1135     GetDlgItemText(dlg, IDC_HOSTCOMLABEL, uimsg, sizeof(uimsg));
1136     UTIL_get_lang_msg("DLG_HOST_SERIALPORT", pvar, uimsg);
1137     SetDlgItemText(dlg, IDC_HOSTCOMLABEL, pvar->ts->UIMsg);
1138     GetDlgItemText(dlg, IDC_HOSTHELP, uimsg, sizeof(uimsg));
1139     UTIL_get_lang_msg("DLG_HOST_HELP", pvar, uimsg);
1140     SetDlgItemText(dlg, IDC_HOSTHELP, pvar->ts->UIMsg);
1141     GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
1142     UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
1143     SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
1144     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1145     UTIL_get_lang_msg("BTN_CANCEL", pvar, uimsg);
1146     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1147    
1148     // �z�X�g�q�X�g�����`�F�b�N�{�b�N�X������ (2005.10.21 yutaka)
1149     if (pvar->ts->HistoryList > 0) {
1150     SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_SETCHECK, BST_CHECKED, 0);
1151     } else {
1152     SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_SETCHECK, BST_UNCHECKED, 0);
1153     }
1154    
1155 yutakapon 4860 // �t�@�C�����������O�t���p�C�v�������ATCP/IP�����������B
1156     if (GetHNRec->PortType == IdFile ||
1157     GetHNRec->PortType == IdNamedPipe
1158     )
1159 maya 3227 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 maya 4963 } while (i <= MAXHOSTLIST);
1174 maya 3227
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 doda 5261 } else if (MATCH_STR_I(option + 4, "-icon=") == 0) {
1686     if ((_stricmp(option+10, "old") == 0) ||
1687     (_stricmp(option+10, "yellow") == 0) ||
1688     (_stricmp(option+10, "securett_yellow") == 0)) {
1689     pvar->settings.IconID = IDI_SECURETT_YELLOW;
1690     }
1691     else {
1692     pvar->settings.IconID = IDI_SECURETT;
1693     }
1694 doda 4151
1695 maya 3227 // /ssh1 �� /ssh2 �I�v�V�������V�K���� (2006.9.16 maya)
1696     } else if (MATCH_STR(option + 4, "1") == 0) {
1697     pvar->settings.Enabled = 1;
1698     pvar->settings.ssh_protocol_version = 1;
1699     } else if (MATCH_STR(option + 4, "2") == 0) {
1700     pvar->settings.Enabled = 1;
1701     pvar->settings.ssh_protocol_version = 2;
1702    
1703     } else {
1704     char buf[1024];
1705    
1706     UTIL_get_lang_msg("MSG_UNKNOWN_OPTION_ERROR", pvar,
1707     "Unrecognized command-line option: %s");
1708     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, option);
1709    
1710     MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
1711     }
1712    
1713     // ttermpro.exe �� /T= �w�������p�������A������������ (2006.10.19 maya)
1714     } else if (MATCH_STR_I(option + 1, "t=") == 0) {
1715     if (strcmp(option + 3, "2") == 0) {
1716     pvar->settings.Enabled = 1;
1717 doda 3307 return OPTION_CLEAR; // /t=2��ttssh�������g������������
1718 maya 3227 } else {
1719     pvar->settings.Enabled = 0;
1720 doda 3307 return OPTION_NONE; // Tera Term������������������������
1721 maya 3227 }
1722    
1723     // ttermpro.exe �� /F= �w������ TTSSH ������������ (2006.10.11 maya)
1724     } else if (MATCH_STR_I(option + 1, "f=") == 0) {
1725     read_ssh_options_from_user_file(pvar, option + 3);
1726 doda 3307 return OPTION_NONE; // Tera Term���������������K�v������������������
1727 maya 3227
1728     // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
1729     } else if (MATCH_STR(option + 1, "1") == 0) {
1730     // command line: /ssh /1 is SSH1 only
1731     pvar->settings.ssh_protocol_version = 1;
1732    
1733     } else if (MATCH_STR(option + 1, "2") == 0) {
1734     // command line: /ssh /2 is SSH2 & SSH1
1735     pvar->settings.ssh_protocol_version = 2;
1736    
1737     } else if (MATCH_STR(option + 1, "nossh") == 0) {
1738     // '/nossh' �I�v�V�����������B
1739     // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
1740     // �����������������B(2004.10.11 yutaka)
1741     pvar->settings.Enabled = 0;
1742    
1743     } else if (MATCH_STR(option + 1, "telnet") == 0) {
1744     // '/telnet' ���w�������������������� '/nossh' ��������
1745     // SSH������������ (2006.9.16 maya)
1746     pvar->settings.Enabled = 0;
1747 maya 3533 // Tera Term �� Telnet �t���O���t����
1748     pvar->ts->Telnet = 1;
1749 maya 3227
1750     } else if (MATCH_STR(option + 1, "auth") == 0) {
1751     // SSH2�������O�C���I�v�V����������
1752     //
1753     // SYNOPSIS: /ssh /auth=passowrd /user=���[�U�� /passwd=�p�X���[�h
1754     // /ssh /auth=publickey /user=���[�U�� /passwd=�p�X���[�h /keyfile=�p�X
1755     // EXAMPLE: /ssh /auth=password /user=nike /passwd=a@bc
1756     // /ssh /auth=publickey /user=foo /passwd=bar /keyfile=d:\tmp\id_rsa
1757     // NOTICE: �p�X���[�h���p�X�������������������A�u�����N���������� @ ���g�������B
1758     //
1759     // (2004.11.30 yutaka)
1760     // (2005.1.26 yutaka) ���������B���J���F���T�|�[�g�B
1761     //
1762     pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
1763    
1764     if (MATCH_STR(option + 5, "=password") == 0) { // �p�X���[�h
1765     //pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
1766     pvar->ssh2_authmethod = SSH_AUTH_PASSWORD;
1767    
1768     // /auth=challenge ������ (2007.10.5 maya)
1769     } else if (MATCH_STR(option + 5, "=challenge") == 0) { // keyboard-interactive�F��
1770     //pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
1771     pvar->ssh2_authmethod = SSH_AUTH_TIS;
1772    
1773     } else if (MATCH_STR(option + 5, "=publickey") == 0) { // ���J���F��
1774     //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1775     pvar->ssh2_authmethod = SSH_AUTH_RSA;
1776    
1777     } else if (MATCH_STR(option + 5, "=pageant") == 0) { // ���J���F�� by Pageant
1778     //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1779     pvar->ssh2_authmethod = SSH_AUTH_PAGEANT;
1780    
1781     } else {
1782     // TODO:
1783    
1784     }
1785    
1786     } else if (MATCH_STR(option + 1, "user=") == 0) {
1787 maya 3433 #ifdef USE_ATCMDLINE
1788 maya 3227 replace_to_blank(option + 6, pvar->ssh2_username, sizeof(pvar->ssh2_username));
1789     //_snprintf(pvar->ssh2_username, sizeof(pvar->ssh2_username), "%s", option + 6);
1790    
1791 maya 3433 #else
1792     _snprintf_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), _TRUNCATE, "%s", option + 6);
1793     #endif
1794    
1795 maya 3227 } else if (MATCH_STR(option + 1, "passwd=") == 0) {
1796 maya 3433 #ifdef USE_ATCMDLINE
1797 maya 3227 replace_to_blank(option + 8, pvar->ssh2_password, sizeof(pvar->ssh2_password));
1798     //_snprintf(pvar->ssh2_password, sizeof(pvar->ssh2_password), "%s", option + 8);
1799 maya 3433 #else
1800     _snprintf_s(pvar->ssh2_password, sizeof(pvar->ssh2_password), _TRUNCATE, "%s", option + 8);
1801     #endif
1802 maya 3227
1803     } else if (MATCH_STR(option + 1, "keyfile=") == 0) {
1804 maya 3433 #ifdef USE_ATCMDLINE
1805 maya 3227 replace_to_blank(option + 9, pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile));
1806 maya 3433 #else
1807     _snprintf_s(pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile), _TRUNCATE, "%s", option + 9);
1808     #endif
1809 maya 3227
1810     } else if (MATCH_STR(option + 1, "ask4passwd") == 0) {
1811     // �p�X���[�h������ (2006.9.18 maya)
1812     pvar->ask4passwd = 1;
1813    
1814 yutakapon 3631 } else if (MATCH_STR(option + 1, "nosecuritywarning") == 0) {
1815     // known_hosts�`�F�b�N���������B���Y�I�v�V�������g�����A�Z�L�����e�B������������
1816     // �����A�B���I�v�V���������������B
1817     // (2009.10.4 yutaka)
1818     pvar->nocheck_known_hosts = TRUE;
1819    
1820 maya 3227 }
1821 doda 3307 else { // Other (not ttssh) option
1822     return OPTION_NONE; // ttssh���I�v�V������������������������
1823     }
1824 maya 3227
1825     // �p�X���[�h�������������������O�C��������������
1826     // /auth ���F�����\�b�h���w�������������p������ (2006.9.18 maya)
1827     if (pvar->ask4passwd == 1) {
1828     pvar->ssh2_autologin = 0;
1829     }
1830 doda 3307 return OPTION_CLEAR;
1831 maya 3227
1832     }
1833     else if ((MATCH_STR_I(option, "ssh://") == 0) ||
1834     (MATCH_STR_I(option, "ssh1://") == 0) ||
1835     (MATCH_STR_I(option, "ssh2://") == 0) ||
1836     (MATCH_STR_I(option, "slogin://") == 0) ||
1837     (MATCH_STR_I(option, "slogin1://") == 0) ||
1838     (MATCH_STR_I(option, "slogin2://") == 0)) {
1839     //
1840     // ssh://user@host/ ����URL�`�����T�|�[�g
1841     // ���{�I�������� telnet:// URL��������
1842     //
1843     // �Q�l:
1844     // RFC3986: Uniform Resource Identifier (URI): Generic Syntax
1845     // RFC4248: The telnet URI Scheme
1846     //
1847     char *p, *p2, *p3;
1848     int optlen, hostlen;
1849    
1850     optlen = strlen(option);
1851    
1852     // ������':'���O�����������������������A������ssh�v���g�R���o�[�W������������
1853 doda 3232 p = _mbschr(option, ':');
1854 maya 3227 switch (*(p-1)) {
1855     case '1':
1856     pvar->settings.ssh_protocol_version = 1;
1857     break;
1858     case '2':
1859     pvar->settings.ssh_protocol_version = 2;
1860     break;
1861     }
1862    
1863     // authority part �����|�C���^������
1864     p += 3;
1865    
1866     // path part ������������
1867 doda 3232 if ((p2 = _mbschr(p, '/')) != NULL) {
1868 maya 3227 *p2 = 0;
1869     }
1870    
1871     // '@'�������������A���������O�����[�U����
1872 doda 3232 if ((p2 = _mbschr(p, '@')) != NULL) {
1873 maya 3227 *p2 = 0;
1874     // ':'���~���p�X���[�h
1875 doda 3232 if ((p3 = _mbschr(p, ':')) != NULL) {
1876 maya 3227 *p3 = 0;
1877     percent_decode(pvar->ssh2_password, sizeof(pvar->ssh2_password), p3 + 1);
1878     }
1879     percent_decode(pvar->ssh2_username, sizeof(pvar->ssh2_username), p);
1880     // p �� host part ������('@'����������)����������������
1881     p = p2 + 1;
1882     }
1883    
1884     // host part �� option �����������������Ascheme part ������
1885     // port�w����������������port���������������������m��������������
1886     hostlen = strlen(p);
1887     memmove_s(option, optlen, p, hostlen);
1888     option[hostlen] = 0;
1889    
1890     // �|�[�g�w������������":22"������
1891     #ifndef NO_INET6
1892     if (option[0] == '[' && option[hostlen-1] == ']' || // IPv6 raw address without port
1893 doda 3232 option[0] != '[' && _mbschr(option, ':') == NULL) { // hostname or IPv4 raw address without port
1894 maya 3227 #else
1895 doda 3232 if (_mbschr(option, ':') == NULL) {
1896 maya 3227 #endif /* NO_INET6 */
1897     memcpy_s(option+hostlen, optlen-hostlen, ":22", 3);
1898     hostlen += 3;
1899     }
1900    
1901     // �|�[�g�w�����������������X�y�[�X������
1902     memset(option+hostlen, ' ', optlen-hostlen);
1903    
1904     pvar->settings.Enabled = 1;
1905    
1906     return OPTION_REPLACE;
1907     }
1908 doda 3232 else if (_mbschr(option, '@') != NULL) {
1909 maya 3227 //
1910     // user@host �`�����T�|�[�g
1911     // ����������ssh�������T�|�[�g�����A���[�U����ttssh���������B
1912     // (ssh�������O -- ttssh�������W������������)
1913     // �����I��telnet authentication option���T�|�[�g��������
1914     // Tera Term�{�����������������������\���B
1915     //
1916     char *p;
1917 doda 3232 p = _mbschr(option, '@');
1918 maya 3227 *p = 0;
1919    
1920     strncpy_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), option, _TRUNCATE);
1921    
1922     // ���[�U���������X�y�[�X�������B
1923     // ������TTX��Tera Term�{�������������������X�y�[�X�����������������A
1924     // �z�X�g�����������l�����K�v�������B
1925     memset(option, ' ', p-option+1);
1926    
1927     return OPTION_REPLACE;
1928     }
1929    
1930     return OPTION_NONE;
1931     }
1932    
1933     static void FAR PASCAL TTXParseParam(PCHAR param, PTTSet ts,
1934     PCHAR DDETopic)
1935     {
1936 maya 3433 #ifndef USE_ATCMDLINE
1937 maya 3427 int i;
1938     BOOL inParam = FALSE;
1939     BOOL inQuotes = FALSE;
1940     BOOL inEqual = FALSE;
1941     int param_len=strlen(param);
1942     PCHAR start = NULL;
1943     char *buf = (char *)calloc(param_len+1, sizeof(char));
1944     int buflen = 0;
1945    
1946     if (pvar->hostdlg_activated) {
1947     pvar->settings.Enabled = pvar->hostdlg_Enabled;
1948     }
1949    
1950     for (i = 0; i < param_len; i++) {
1951     if (inQuotes) {
1952     // �������u��"����
1953     if (param[i] == '"') {
1954     if (param[i+1] == '"') {
1955 maya 3433 buf[buflen] = param[i];
1956     buflen++;
1957 maya 3427 i++;
1958     }
1959     else {
1960     // �N�H�[�g���������������������I����
1961     // "��buf�����������������n��
1962     switch (parse_option(pvar, buf)) {
1963     case OPTION_CLEAR:
1964     memset(start, ' ', (param + i) - start + 1);
1965     break;
1966     case OPTION_REPLACE:
1967     memset(start, ' ', (param + i) - start + 1);
1968     buflen = strlen(buf);
1969     memcpy(start, buf, buflen);
1970     break;
1971     }
1972     inParam = FALSE;
1973     inEqual = FALSE;
1974     start = NULL;
1975     memset(buf, 0, param_len);
1976     buflen = 0;
1977     inQuotes = FALSE;
1978     }
1979     }
1980     else {
1981     buf[buflen] = param[i];
1982     buflen++;
1983     }
1984     }
1985     else {
1986     if (!inParam) {
1987     // �����p�����[�^������������
1988     if (param[i] == '"') {
1989     // " ���n����
1990     start = param + i;
1991     inParam = TRUE;
1992     inQuotes = TRUE;
1993     }
1994     else if (param[i] != ' ' && param[i] != '\t') {
1995     // �������n����
1996     buf[buflen] = param[i];
1997     buflen++;
1998     start = param + i;
1999     inParam = TRUE;
2000     }
2001     }
2002     else {
2003     // �������u���p�����[�^����
2004     if (param[i] == ' ' || param[i] == '\t') {
2005     // �N�H�[�g�����������������������I����
2006     switch (parse_option(pvar, buf)) {
2007     case OPTION_CLEAR:
2008     memset(start, ' ', (param + i) - start + 1);
2009     break;
2010     case OPTION_REPLACE:
2011     memset(start, ' ', (param + i) - start + 1);
2012     buflen = strlen(buf);
2013     memcpy(start, buf, buflen);
2014     break;
2015     }
2016     inParam = FALSE;
2017     inEqual = FALSE;
2018     start = NULL;
2019     memset(buf, 0, param_len);
2020     buflen = 0;
2021     }
2022     else {
2023     buf[buflen] = param[i];
2024     buflen++;
2025     if (!inEqual && param[i] == '=') {
2026     inEqual = TRUE;
2027     if (param[i+1] == '"') {
2028     inQuotes = TRUE;
2029     i++;
2030     }
2031     }
2032     }
2033     }
2034     }
2035     }
2036    
2037     // buf ���c�����������������n��
2038 maya 3435 // +1������������'\0'�������������������A��������������������
2039 maya 3427 if (strlen(buf) > 0) {
2040     switch (parse_option(pvar, buf)) {
2041     case OPTION_CLEAR:
2042 maya 3435 memset(start, ' ', (param + i) - start);
2043 maya 3427 break;
2044     case OPTION_REPLACE:
2045 maya 3435 memset(start, ' ', (param + i) - start);
2046 maya 3427 buflen = strlen(buf);
2047     memcpy(start, buf, buflen);
2048     break;
2049     }
2050     }
2051     free(buf);
2052     #else
2053 maya 3227 // �X�y�[�X�������t�@�C�������F�������������C�� (2006.10.7 maya)
2054     int i, buflen;
2055     BOOL inParam = FALSE;
2056     BOOL inQuotes = FALSE;
2057     BOOL inFileParam = FALSE;
2058     PCHAR option = NULL;
2059    
2060     if (pvar->hostdlg_activated) {
2061     pvar->settings.Enabled = pvar->hostdlg_Enabled;
2062     }
2063    
2064     for (i = 0; param[i] != 0; i++) {
2065     if (inQuotes ? param[i] == '"'
2066     : (param[i] == ' ' || param[i] == '\t')) {
2067     if (option != NULL) {
2068     char ch = param[i];
2069     PCHAR Equal;
2070    
2071     param[i] = 0;
2072     Equal = strchr(option, '=');
2073     if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
2074     int buf_len = strlen(option) * sizeof(char);
2075     char *buf = (char *)calloc(strlen(option), sizeof(char));
2076     char c = option[Equal - option + 1];
2077     option[Equal - option + 1] = 0;
2078     strncat_s(buf, buf_len, option, _TRUNCATE);
2079     option[Equal - option + 1] = c;
2080     strncat_s(buf, buf_len, Equal + 2, _TRUNCATE);
2081     switch (parse_option(pvar, *buf == '"' ? buf + 1 : buf)) {
2082     case OPTION_CLEAR:
2083     memset(option, ' ', i + 1 - (option - param));
2084     break;
2085     case OPTION_REPLACE:
2086     buflen = strlen(buf);
2087     memcpy(option, buf, buflen);
2088     memset(option + buflen, ' ', i + 1 - buflen - (option - param));
2089     break;
2090     default:
2091     param[i] = ch;
2092     }
2093     free(buf);
2094     }
2095     else {
2096     switch (parse_option(pvar, *option == '"' ? option + 1 : option)) {
2097     case OPTION_CLEAR:
2098     memset(option, ' ', i + 1 - (option - param));
2099     break;
2100     default:
2101     param[i] = ch;
2102     }
2103     }
2104     option = NULL;
2105     }
2106     inParam = FALSE;
2107     inQuotes = FALSE;
2108     inFileParam = FALSE;
2109     } else if (!inParam) {
2110     if (param[i] == '"') {
2111     inQuotes = TRUE;
2112     inParam = TRUE;
2113     option = param + i;
2114     } else if (param[i] != ' ' && param[i] != '\t') {
2115     inParam = TRUE;
2116     option = param + i;
2117     }
2118     } else {
2119     if (option == NULL) {
2120     continue;
2121     }
2122     if ((option[0] == '-' || option[0] == '/') &&
2123 doda 3288 (MATCH_STR(option + 1, "ssh-f=") == 0 || // ttssh option
2124     MATCH_STR(option + 1, "ssh-consume=") == 0 || // ttssh option
2125     MATCH_STR_I(option + 1, "f=") == 0 || // Tera Term option
2126     MATCH_STR_I(option + 1, "fd=") == 0 || // Tera Term option
2127     MATCH_STR_I(option + 1, "k=") == 0 || // Tera Term option
2128     MATCH_STR_I(option + 1, "l=") == 0 || // Tera Term option
2129     MATCH_STR_I(option + 1, "m=") == 0 || // Tera Term option
2130     MATCH_STR_I(option + 1, "r=") == 0 || // Tera Term option
2131     MATCH_STR_I(option + 1, "w=") == 0 || // Tera Term option
2132     MATCH_STR(option + 1, "keyfile=") == 0)) { // ttssh option
2133 maya 3227 if (param[i] == '"') {
2134     inQuotes = TRUE;
2135     }
2136     inFileParam = TRUE;
2137     }
2138     }
2139     }
2140    
2141     if (option != NULL) {
2142     PCHAR Equal = strchr(option, '=');
2143     if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
2144     int buf_len = strlen(option) * sizeof(char);
2145     char *buf = (char *)calloc(strlen(option), sizeof(char));
2146     char c = option[Equal - option + 1];
2147     option[Equal - option + 1] = 0;
2148     strncat_s(buf, buf_len, option, _TRUNCATE);
2149     option[Equal - option + 1] = c;
2150     strncat_s(buf, buf_len, Equal + 2, _TRUNCATE);
2151     switch (parse_option(pvar, *buf == '"' ? buf + 1 : buf)) {
2152     case OPTION_CLEAR:
2153     memset(option, ' ', i + 1 - (option - param));
2154     break;
2155     case OPTION_REPLACE:
2156     strcpy_s(option, i - (param - option), buf);
2157     break;
2158     }
2159     free(buf);
2160     }
2161     else {
2162     switch (parse_option(pvar, option)) {
2163     case OPTION_CLEAR:
2164     memset(option, ' ', i - (option - param));
2165     break;
2166     }
2167     }
2168     }
2169 maya 3427 #endif
2170 maya 3227
2171     FWDUI_load_settings(pvar);
2172    
2173     (pvar->ParseParam) (param, ts, DDETopic);
2174    
2175     }
2176    
2177     static void PASCAL FAR TTXGetSetupHooks(TTXSetupHooks FAR * hooks)
2178     {
2179     pvar->ReadIniFile = *hooks->ReadIniFile;
2180     pvar->WriteIniFile = *hooks->WriteIniFile;
2181     pvar->ParseParam = *hooks->ParseParam;
2182    
2183     *hooks->ReadIniFile = TTXReadINIFile;
2184     *hooks->WriteIniFile = TTXWriteINIFile;
2185     *hooks->ParseParam = TTXParseParam;
2186     }
2187    
2188     static void PASCAL FAR TTXSetWinSize(int rows, int cols)
2189     {
2190     SSH_notify_win_size(pvar, cols, rows);
2191     }
2192    
2193     static void insertMenuBeforeItem(HMENU menu, WORD beforeItemID, WORD flags,
2194     WORD newItemID, char FAR * text)
2195     {
2196     int i, j;
2197    
2198     for (i = GetMenuItemCount(menu) - 1; i >= 0; i--) {
2199     HMENU submenu = GetSubMenu(menu, i);
2200    
2201     for (j = GetMenuItemCount(submenu) - 1; j >= 0; j--) {
2202     if (GetMenuItemID(submenu, j) == beforeItemID) {
2203     InsertMenu(submenu, j, MF_BYPOSITION | flags, newItemID, text);
2204     return;
2205     }
2206     }
2207     }
2208     }
2209    
2210 doda 4463 #define GetFileMenu(menu) GetSubMenuByChildID(menu, 50110) // ID_FILE_NEWCONNECTION
2211     #define GetEditMenu(menu) GetSubMenuByChildID(menu, 50210) // ID_EDIT_COPY2
2212     #define GetSetupMenu(menu) GetSubMenuByChildID(menu, 50310) // ID_SETUP_TERMINAL
2213     #define GetControlMenu(menu) GetSubMenuByChildID(menu, 50410) // ID_CONTROL_RESETTERMINAL
2214     #define GetHelpMenu(menu) GetSubMenuByChildID(menu, 50990) // ID_HELP_ABOUT
2215    
2216     HMENU GetSubMenuByChildID(HMENU menu, UINT id) {
2217     int i, j, items, subitems, cur_id;
2218     HMENU m;
2219    
2220     items = GetMenuItemCount(menu);
2221    
2222     for (i=0; i<items; i++) {
2223     if (m = GetSubMenu(menu, i)) {
2224     subitems = GetMenuItemCount(m);
2225     for (j=0; j<subitems; j++) {
2226     cur_id = GetMenuItemID(m, j);
2227     if (cur_id == id) {
2228     return m;
2229     }
2230     }
2231     }
2232     }
2233     return NULL;
2234     }
2235    
2236 maya 3227 static void PASCAL FAR TTXModifyMenu(HMENU menu)
2237     {
2238 doda 4463 pvar->FileMenu = GetFileMenu(menu);
2239    
2240 maya 3227 /* inserts before ID_HELP_ABOUT */
2241     UTIL_get_lang_msg("MENU_ABOUT", pvar, "About &TTSSH...");
2242     insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU, pvar->ts->UIMsg);
2243    
2244     /* inserts before ID_SETUP_TCPIP */
2245     UTIL_get_lang_msg("MENU_SSH", pvar, "SS&H...");
2246     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU, pvar->ts->UIMsg);
2247     /* inserts before ID_SETUP_TCPIP */
2248     UTIL_get_lang_msg("MENU_SSH_AUTH", pvar, "SSH &Authentication...");
2249     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU, pvar->ts->UIMsg);
2250     /* inserts before ID_SETUP_TCPIP */
2251     UTIL_get_lang_msg("MENU_SSH_FORWARD", pvar, "SSH F&orwarding...");
2252     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU, pvar->ts->UIMsg);
2253     UTIL_get_lang_msg("MENU_SSH_KEYGEN", pvar, "SSH KeyGe&nerator...");
2254     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHKEYGENMENU, pvar->ts->UIMsg);
2255    
2256     /* inserts before ID_FILE_CHANGEDIR */
2257     UTIL_get_lang_msg("MENU_SSH_SCP", pvar, "SS&H SCP...");
2258 doda 4463 insertMenuBeforeItem(menu, 50170, MF_GRAYED, ID_SSHSCPMENU, pvar->ts->UIMsg);
2259 maya 3227 }
2260    
2261 doda 4463 static void PASCAL FAR TTXModifyPopupMenu(HMENU menu) {
2262     if (menu == pvar->FileMenu) {
2263     if (pvar->cv->Ready && pvar->settings.Enabled)
2264     EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_ENABLED);
2265     else
2266     EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_GRAYED);
2267     }
2268     }
2269    
2270 maya 3227 static void append_about_text(HWND dlg, char FAR * prefix, char FAR * msg)
2271     {
2272     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
2273     (LPARAM) prefix);
2274     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0, (LPARAM) msg);
2275     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
2276     (LPARAM) (char FAR *) "\r\n");
2277     }
2278    
2279     // ���s�t�@�C�������o�[�W�������������� (2005.2.28 yutaka)
2280     void get_file_version(char *exefile, int *major, int *minor, int *release, int *build)
2281     {
2282     typedef struct {
2283     WORD wLanguage;
2284     WORD wCodePage;
2285     } LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
2286     LPLANGANDCODEPAGE lplgcode;
2287     UINT unLen;
2288     DWORD size;
2289     char *buf = NULL;
2290     BOOL ret;
2291     int i;
2292     char fmt[80];
2293     char *pbuf;
2294    
2295     size = GetFileVersionInfoSize(exefile, NULL);
2296     if (size == 0) {
2297     goto error;
2298     }
2299     buf = malloc(size);
2300     ZeroMemory(buf, size);
2301    
2302     if (GetFileVersionInfo(exefile, 0, size, buf) == FALSE) {
2303