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 5578 - (hide annotations) (download) (as text)
Sun May 4 15:49:47 2014 UTC (9 years, 11 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 178028 byte(s)
バージョン情報のEdit Controlに、等幅フォントを指定できるようにした。
また、横スクロールバーを追加した。

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