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 5430 - (hide annotations) (download) (as text)
Sat Nov 23 16:29:16 2013 UTC (10 years, 4 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 168238 byte(s)
OpenSSL バージョンの取得方法を変更した。

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