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