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 4546 - (hide annotations) (download) (as text)
Thu Jul 28 08:58:28 2011 UTC (12 years, 8 months ago) by maya
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 164808 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 4546 SYSTEMTIME LocalTime;
896     char strtime[29];
897     char week[][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
898     char month[][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
899     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
900     DWORD processid;
901 maya 3227 char tmp[26];
902 maya 4546
903     GetLocalTime(&LocalTime);
904     _snprintf_s(strtime, sizeof(strtime), _TRUNCATE,
905     "%s %s %02d %02d:%02d:%02d.%03d %04d",
906     week[LocalTime.wDayOfWeek],
907     month[LocalTime.wMonth-1],
908     LocalTime.wDay,
909     LocalTime.wHour,
910     LocalTime.wMinute,
911     LocalTime.wSecond,
912     LocalTime.wMilliseconds,
913     LocalTime.wYear);
914     _write(file, strtime, strlen(strtime));
915 maya 3227 GetWindowThreadProcessId(pvar->cv->HWin, &processid);
916     _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, " [%lu] ",processid);
917     _write(file, tmp, strlen(tmp));
918     _write(file, msg, strlen(msg));
919     _write(file, "\n", 1);
920     _close(file);
921     }
922     }
923     }
924    
925     static void PASCAL FAR TTXOpenTCP(TTXSockHooks FAR * hooks)
926     {
927     if (pvar->settings.Enabled) {
928     // TCPLocalEcho/TCPCRSend ������������ (maya 2007.4.25)
929 doda 3579 pvar->origDisableTCPEchoCR = pvar->ts->DisableTCPEchoCR;
930 maya 3227 pvar->ts->DisableTCPEchoCR = TRUE;
931    
932     pvar->session_settings = pvar->settings;
933    
934     notify_verbose_message(pvar, "---------------------------------------------------------------------", LOG_LEVEL_VERBOSE);
935     notify_verbose_message(pvar, "Initiating SSH session", LOG_LEVEL_VERBOSE);
936    
937     FWDUI_load_settings(pvar);
938    
939     pvar->cv->TelAutoDetect = FALSE;
940     /* This next line should not be needed because Tera Term's
941     CommLib should find ts->Telnet == 0 ... but we'll do this
942     just to be on the safe side. */
943     pvar->cv->TelFlag = FALSE;
944 doda 3495 pvar->cv->TelLineMode = FALSE;
945 maya 3227
946     pvar->Precv = *hooks->Precv;
947     pvar->Psend = *hooks->Psend;
948     pvar->PWSAAsyncSelect = *hooks->PWSAAsyncSelect;
949     pvar->Pconnect = *hooks->Pconnect;
950     pvar->PWSAGetLastError = *hooks->PWSAGetLastError;
951    
952     *hooks->Precv = TTXrecv;
953     *hooks->Psend = TTXsend;
954     *hooks->PWSAAsyncSelect = TTXWSAAsyncSelect;
955     *hooks->Pconnect = TTXconnect;
956    
957     SSH_open(pvar);
958     HOSTS_open(pvar);
959     FWDUI_open(pvar);
960    
961     // ������ myproposal �����f���������A�������O�����������B (2006.6.26 maya)
962     SSH2_update_cipher_myproposal(pvar);
963 yutakapon 4367 SSH2_update_kex_myproposal(pvar);
964     SSH2_update_host_key_myproposal(pvar);
965     SSH2_update_hmac_myproposal(pvar);
966 maya 3227 SSH2_update_compression_myproposal(pvar);
967     }
968     }
969    
970     static void PASCAL FAR TTXCloseTCP(TTXSockHooks FAR * hooks)
971     {
972     if (pvar->session_settings.Enabled) {
973     pvar->socket = INVALID_SOCKET;
974    
975     notify_verbose_message(pvar, "Terminating SSH session...",
976     LOG_LEVEL_VERBOSE);
977    
978     *hooks->Precv = pvar->Precv;
979     *hooks->Psend = pvar->Psend;
980     *hooks->PWSAAsyncSelect = pvar->PWSAAsyncSelect;
981     *hooks->Pconnect = pvar->Pconnect;
982 doda 3579
983     pvar->ts->DisableTCPEchoCR = pvar->origDisableTCPEchoCR;
984 maya 3227 }
985    
986     uninit_TTSSH(pvar);
987     init_TTSSH(pvar);
988     }
989    
990     static void enable_dlg_items(HWND dlg, int from, int to, BOOL enabled)
991     {
992     for (; from <= to; from++) {
993     EnableWindow(GetDlgItem(dlg, from), enabled);
994     }
995     }
996    
997     // C-p/C-n/C-b/C-f/C-a/C-e ���T�|�[�g (2007.9.5 maya)
998     // C-d/C-k ���T�|�[�g (2007.10.3 yutaka)
999     // �h���b�v�_�E���������G�f�B�b�g�R���g���[����
1000     // �T�u�N���X�������������E�C���h�E�v���V�[�W��
1001     WNDPROC OrigHostnameEditProc; // Original window procedure
1002     LRESULT CALLBACK HostnameEditProc(HWND dlg, UINT msg,
1003     WPARAM wParam, LPARAM lParam)
1004     {
1005     HWND parent;
1006     int max, select, len;
1007     char *str, *orgstr;
1008    
1009     switch (msg) {
1010     // �L�[�����������������m����
1011     case WM_KEYDOWN:
1012     if (GetKeyState(VK_CONTROL) < 0) {
1013     switch (wParam) {
1014     case 0x50: // Ctrl+p ... up
1015     parent = GetParent(dlg);
1016     select = SendMessage(parent, CB_GETCURSEL, 0, 0);
1017     if (select > 0) {
1018     PostMessage(parent, CB_SETCURSEL, select - 1, 0);
1019     }
1020     return 0;
1021     case 0x4e: // Ctrl+n ... down
1022     parent = GetParent(dlg);
1023     max = SendMessage(parent, CB_GETCOUNT, 0, 0);
1024     select = SendMessage(parent, CB_GETCURSEL, 0, 0);
1025     if (select < max - 1) {
1026     PostMessage(parent, CB_SETCURSEL, select + 1, 0);
1027     }
1028     return 0;
1029     case 0x42: // Ctrl+b ... left
1030     SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1031     PostMessage(dlg, EM_SETSEL, select-1, select-1);
1032     return 0;
1033     case 0x46: // Ctrl+f ... right
1034     SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1035     max = GetWindowTextLength(dlg) ;
1036     PostMessage(dlg, EM_SETSEL, select+1, select+1);
1037     return 0;
1038     case 0x41: // Ctrl+a ... home
1039     PostMessage(dlg, EM_SETSEL, 0, 0);
1040     return 0;
1041     case 0x45: // Ctrl+e ... end
1042     max = GetWindowTextLength(dlg) ;
1043     PostMessage(dlg, EM_SETSEL, max, max);
1044     return 0;
1045    
1046     case 0x44: // Ctrl+d
1047     case 0x4b: // Ctrl+k
1048     case 0x55: // Ctrl+u
1049     SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1050     max = GetWindowTextLength(dlg);
1051     max++; // '\0'
1052     orgstr = str = malloc(max);
1053     if (str != NULL) {
1054     len = GetWindowText(dlg, str, max);
1055     if (select >= 0 && select < len) {
1056     if (wParam == 0x44) { // �J�[�\���z����������������������
1057     memmove(&str[select], &str[select + 1], len - select - 1);
1058     str[len - 1] = '\0';
1059    
1060     } else if (wParam == 0x4b) { // �J�[�\�������s��������������
1061     str[select] = '\0';
1062    
1063     }
1064     }
1065    
1066     if (wParam == 0x55) { // �J�[�\����������������������
1067     if (select >= len) {
1068     str[0] = '\0';
1069     } else {
1070     str = &str[select];
1071     }
1072     select = 0;
1073     }
1074    
1075     SetWindowText(dlg, str);
1076     SendMessage(dlg, EM_SETSEL, select, select);
1077     free(orgstr);
1078     return 0;
1079     }
1080     break;
1081     }
1082     }
1083     break;
1084    
1085     // �����L�[��������������������������������������������
1086     case WM_CHAR:
1087     switch (wParam) {
1088     case 0x01:
1089     case 0x02:
1090     case 0x04:
1091     case 0x05:
1092     case 0x06:
1093     case 0x0b:
1094     case 0x0e:
1095     case 0x10:
1096     case 0x15:
1097     return 0;
1098     }
1099     }
1100    
1101     return CallWindowProc(OrigHostnameEditProc, dlg, msg, wParam, lParam);
1102     }
1103    
1104     static BOOL CALLBACK TTXHostDlg(HWND dlg, UINT msg, WPARAM wParam,
1105     LPARAM lParam)
1106     {
1107     static char *ssh_version[] = {"SSH1", "SSH2", NULL};
1108     PGetHNRec GetHNRec;
1109     char EntName[128];
1110     char TempHost[HostNameMaxLength + 1];
1111     WORD i, j, w;
1112     WORD ComPortTable[MAXCOMPORT];
1113     static char *ComPortDesc[MAXCOMPORT];
1114     int comports;
1115     BOOL Ok;
1116     LOGFONT logfont;
1117     HFONT font;
1118     char uimsg[MAX_UIMSG];
1119     static HWND hwndHostname = NULL; // HOSTNAME dropdown
1120     static HWND hwndHostnameEdit = NULL; // Edit control on HOSTNAME dropdown
1121    
1122     switch (msg) {
1123     case WM_INITDIALOG:
1124     GetHNRec = (PGetHNRec) lParam;
1125     SetWindowLong(dlg, DWL_USER, lParam);
1126    
1127     GetWindowText(dlg, uimsg, sizeof(uimsg));
1128     UTIL_get_lang_msg("DLG_HOST_TITLE", pvar, uimsg);
1129     SetWindowText(dlg, pvar->ts->UIMsg);
1130     GetDlgItemText(dlg, IDC_HOSTNAMELABEL, uimsg, sizeof(uimsg));
1131     UTIL_get_lang_msg("DLG_HOST_TCPIPHOST", pvar, uimsg);
1132     SetDlgItemText(dlg, IDC_HOSTNAMELABEL, pvar->ts->UIMsg);
1133     GetDlgItemText(dlg, IDC_HISTORY, uimsg, sizeof(uimsg));
1134     UTIL_get_lang_msg("DLG_HOST_TCPIPHISTORY", pvar, uimsg);
1135     SetDlgItemText(dlg, IDC_HISTORY, pvar->ts->UIMsg);
1136     GetDlgItemText(dlg, IDC_SERVICELABEL, uimsg, sizeof(uimsg));
1137     UTIL_get_lang_msg("DLG_HOST_TCPIPSERVICE", pvar, uimsg);
1138     SetDlgItemText(dlg, IDC_SERVICELABEL, pvar->ts->UIMsg);
1139     GetDlgItemText(dlg, IDC_HOSTOTHER, uimsg, sizeof(uimsg));
1140     UTIL_get_lang_msg("DLG_HOST_TCPIPOTHER", pvar, uimsg);
1141     SetDlgItemText(dlg, IDC_HOSTOTHER, pvar->ts->UIMsg);
1142     GetDlgItemText(dlg, IDC_HOSTTCPPORTLABEL, uimsg, sizeof(uimsg));
1143     UTIL_get_lang_msg("DLG_HOST_TCPIPPORT", pvar, uimsg);
1144     SetDlgItemText(dlg, IDC_HOSTTCPPORTLABEL, pvar->ts->UIMsg);
1145     GetDlgItemText(dlg, IDC_SSH_VERSION_LABEL, uimsg, sizeof(uimsg));
1146     UTIL_get_lang_msg("DLG_HOST_TCPIPSSHVERSION", pvar, uimsg);
1147     SetDlgItemText(dlg, IDC_SSH_VERSION_LABEL, pvar->ts->UIMsg);
1148     GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOLLABEL, uimsg, sizeof(uimsg));
1149     UTIL_get_lang_msg("DLG_HOST_TCPIPPROTOCOL", pvar, uimsg);
1150     SetDlgItemText(dlg, IDC_HOSTTCPPROTOCOLLABEL, pvar->ts->UIMsg);
1151     GetDlgItemText(dlg, IDC_HOSTSERIAL, uimsg, sizeof(uimsg));
1152     UTIL_get_lang_msg("DLG_HOST_SERIAL", pvar, uimsg);
1153     SetDlgItemText(dlg, IDC_HOSTSERIAL, pvar->ts->UIMsg);
1154     GetDlgItemText(dlg, IDC_HOSTCOMLABEL, uimsg, sizeof(uimsg));
1155     UTIL_get_lang_msg("DLG_HOST_SERIALPORT", pvar, uimsg);
1156     SetDlgItemText(dlg, IDC_HOSTCOMLABEL, pvar->ts->UIMsg);
1157     GetDlgItemText(dlg, IDC_HOSTHELP, uimsg, sizeof(uimsg));
1158     UTIL_get_lang_msg("DLG_HOST_HELP", pvar, uimsg);
1159     SetDlgItemText(dlg, IDC_HOSTHELP, pvar->ts->UIMsg);
1160     GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
1161     UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
1162     SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
1163     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1164     UTIL_get_lang_msg("BTN_CANCEL", pvar, uimsg);
1165     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1166    
1167     // �z�X�g�q�X�g�����`�F�b�N�{�b�N�X������ (2005.10.21 yutaka)
1168     if (pvar->ts->HistoryList > 0) {
1169     SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_SETCHECK, BST_CHECKED, 0);
1170     } else {
1171     SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_SETCHECK, BST_UNCHECKED, 0);
1172     }
1173    
1174     if (GetHNRec->PortType == IdFile)
1175     GetHNRec->PortType = IdTCPIP;
1176    
1177     strncpy_s(EntName, sizeof(EntName), "Host", _TRUNCATE);
1178    
1179     i = 1;
1180     do {
1181     _snprintf_s(&EntName[4], sizeof(EntName)-4, _TRUNCATE, "%d", i);
1182     GetPrivateProfileString("Hosts", EntName, "",
1183     TempHost, sizeof(TempHost),
1184     GetHNRec->SetupFN);
1185     if (strlen(TempHost) > 0)
1186     SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_ADDSTRING,
1187     0, (LPARAM) TempHost);
1188     i++;
1189     } while ((i <= MAXHOSTLIST) && (strlen(TempHost) > 0));
1190    
1191     SendDlgItemMessage(dlg, IDC_HOSTNAME, EM_LIMITTEXT,
1192     HostNameMaxLength - 1, 0);
1193    
1194     SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_SETCURSEL, 0, 0);
1195    
1196     // C-n/C-p ���������T�u�N���X�� (2007.9.4 maya)
1197     hwndHostname = GetDlgItem(dlg, IDC_HOSTNAME);
1198     hwndHostnameEdit = GetWindow(hwndHostname, GW_CHILD);
1199     OrigHostnameEditProc = (WNDPROC)GetWindowLong(hwndHostnameEdit, GWL_WNDPROC);
1200     SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)HostnameEditProc);
1201    
1202     CheckRadioButton(dlg, IDC_HOSTTELNET, IDC_HOSTOTHER,
1203     pvar->settings.Enabled ? IDC_HOSTSSH : GetHNRec->
1204     Telnet ? IDC_HOSTTELNET : IDC_HOSTOTHER);
1205     SendDlgItemMessage(dlg, IDC_HOSTTCPPORT, EM_LIMITTEXT, 5, 0);
1206     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TCPPort, FALSE);
1207     #ifndef NO_INET6
1208     for (i = 0; ProtocolFamilyList[i]; ++i) {
1209     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_ADDSTRING,
1210     0, (LPARAM) ProtocolFamilyList[i]);
1211     }
1212     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, EM_LIMITTEXT,
1213     ProtocolFamilyMaxLength - 1, 0);
1214     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_SETCURSEL, 0, 0);
1215     #endif /* NO_INET6 */
1216    
1217     /////// SSH version
1218     for (i = 0; ssh_version[i]; ++i) {
1219     SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_ADDSTRING,
1220     0, (LPARAM) ssh_version[i]);
1221     }
1222     SendDlgItemMessage(dlg, IDC_SSH_VERSION, EM_LIMITTEXT,
1223     NUM_ELEM(ssh_version) - 1, 0);
1224    
1225     if (pvar->settings.ssh_protocol_version == 1) {
1226     SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 0, 0); // SSH1
1227     } else {
1228     SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 1, 0); // SSH2
1229     }
1230    
1231     if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1232     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE); // enabled
1233     } else {
1234     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1235     }
1236     /////// SSH version
1237    
1238    
1239     j = 0;
1240     w = 1;
1241     if ((comports=DetectComPorts(ComPortTable, GetHNRec->MaxComPort, ComPortDesc)) >= 0) {
1242     for (i=0; i<comports; i++) {
1243     // MaxComPort ���z�����|�[�g���\��������
1244     if (ComPortTable[i] > GetHNRec->MaxComPort) {
1245     continue;
1246     }
1247    
1248     // �g�p�����|�[�g���\��������
1249     if (CheckCOMFlag(ComPortTable[i]) == 1) {
1250     continue;
1251     }
1252    
1253     _snprintf_s(EntName, sizeof(EntName), _TRUNCATE, "COM%d", ComPortTable[i]);
1254     if (ComPortDesc[i] != NULL) {
1255     strncat_s(EntName, sizeof(EntName), ": ", _TRUNCATE);
1256     strncat_s(EntName, sizeof(EntName), ComPortDesc[i], _TRUNCATE);
1257     }
1258     SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_ADDSTRING,
1259     0, (LPARAM)EntName);
1260     j++;
1261     if (GetHNRec->ComPort == ComPortTable[i])
1262     w = j;
1263     }
1264    
1265     } else {
1266     for (i = 1; i <= GetHNRec->MaxComPort; i++) {
1267     // �g�p�����|�[�g���\��������
1268     if (CheckCOMFlag(i) == 1) {
1269     continue;
1270     }
1271    
1272     _snprintf_s(EntName, sizeof(EntName), _TRUNCATE, "COM%d", i);
1273     SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_ADDSTRING,
1274     0, (LPARAM) EntName);
1275     j++;
1276     if (GetHNRec->ComPort == i)
1277     w = j;
1278     }
1279     }
1280    
1281     if (j > 0)
1282     SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_SETCURSEL, w - 1, 0);
1283     else { /* All com ports are already used */
1284     GetHNRec->PortType = IdTCPIP;
1285     enable_dlg_items(dlg, IDC_HOSTSERIAL, IDC_HOSTSERIAL, FALSE);
1286     }
1287    
1288     CheckRadioButton(dlg, IDC_HOSTTCPIP, IDC_HOSTSERIAL,
1289     IDC_HOSTTCPIP + GetHNRec->PortType - 1);
1290    
1291     if (GetHNRec->PortType == IdTCPIP) {
1292     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
1293    
1294     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE);
1295     enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE);
1296    
1297     enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, TRUE); // enabled
1298     }
1299     #ifndef NO_INET6
1300     else {
1301     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1302     FALSE);
1303     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1304     IDC_HOSTTCPPROTOCOL, FALSE);
1305    
1306     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1307     enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1308    
1309     enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, FALSE); // disabled
1310     }
1311     #else
1312     else
1313     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1314     FALSE);
1315     #endif /* NO_INET6 */
1316    
1317     // Host dialog���t�H�[�J�X�������� (2004.10.2 yutaka)
1318     if (GetHNRec->PortType == IdTCPIP) {
1319     HWND hwnd = GetDlgItem(dlg, IDC_HOSTNAME);
1320     SetFocus(hwnd);
1321     } else {
1322     HWND hwnd = GetDlgItem(dlg, IDC_HOSTCOM);
1323     SetFocus(hwnd);
1324     }
1325    
1326     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1327     GetObject(font, sizeof(LOGFONT), &logfont);
1328     if (UTIL_get_lang_font("DLG_SYSTEM_FONT", dlg, &logfont, &DlgHostFont, pvar)) {
1329     SendDlgItemMessage(dlg, IDC_HOSTTCPIP, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1330     SendDlgItemMessage(dlg, IDC_HOSTNAMELABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1331     SendDlgItemMessage(dlg, IDC_HOSTNAME, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1332     SendDlgItemMessage(dlg, IDC_HISTORY, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1333     SendDlgItemMessage(dlg, IDC_SERVICELABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1334     SendDlgItemMessage(dlg, IDC_HOSTTELNET, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1335     SendDlgItemMessage(dlg, IDC_HOSTSSH, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1336     SendDlgItemMessage(dlg, IDC_HOSTOTHER, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1337     SendDlgItemMessage(dlg, IDC_HOSTTCPPORTLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1338     SendDlgItemMessage(dlg, IDC_HOSTTCPPORT, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1339     SendDlgItemMessage(dlg, IDC_SSH_VERSION_LABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1340     SendDlgItemMessage(dlg, IDC_SSH_VERSION, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1341     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOLLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1342     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1343     SendDlgItemMessage(dlg, IDC_HOSTSERIAL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1344     SendDlgItemMessage(dlg, IDC_HOSTCOMLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1345     SendDlgItemMessage(dlg, IDC_HOSTCOM, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1346     SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1347     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1348     SendDlgItemMessage(dlg, IDC_HOSTHELP, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1349     }
1350     else {
1351     DlgHostFont = NULL;
1352     }
1353    
1354     // SetFocus()���t�H�[�J�X���������������AFALSE�������K�v�������B
1355     // TRUE���������ATABSTOP�������������������R���g���[�����I�������B
1356     // (2004.11.23 yutaka)
1357     return FALSE;
1358     //return TRUE;
1359    
1360     case WM_COMMAND:
1361     switch (LOWORD(wParam)) {
1362     case IDOK:
1363     GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1364     if (GetHNRec != NULL) {
1365     if (IsDlgButtonChecked(dlg, IDC_HOSTTCPIP)) {
1366     #ifndef NO_INET6
1367     char afstr[BUFSIZ];
1368     #endif /* NO_INET6 */
1369     i = GetDlgItemInt(dlg, IDC_HOSTTCPPORT, &Ok, FALSE);
1370     if (Ok) {
1371     GetHNRec->TCPPort = i;
1372     } else {
1373     UTIL_get_lang_msg("MSG_TCPPORT_NAN_ERROR", pvar,
1374     "The TCP port must be a number.");
1375     MessageBox(dlg, pvar->ts->UIMsg,
1376     "Tera Term", MB_OK | MB_ICONEXCLAMATION);
1377     return TRUE;
1378     }
1379     #ifndef NO_INET6
1380     #define getaf(str) \
1381     ((strcmp((str), "IPv6") == 0) ? AF_INET6 : \
1382     ((strcmp((str), "IPv4") == 0) ? AF_INET : AF_UNSPEC))
1383     memset(afstr, 0, sizeof(afstr));
1384     GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOL, afstr,
1385     sizeof(afstr));
1386     GetHNRec->ProtocolFamily = getaf(afstr);
1387     #endif /* NO_INET6 */
1388     GetHNRec->PortType = IdTCPIP;
1389     GetDlgItemText(dlg, IDC_HOSTNAME, GetHNRec->HostName,
1390     HostNameMaxLength);
1391     pvar->hostdlg_activated = TRUE;
1392     pvar->hostdlg_Enabled = FALSE;
1393     if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1394     GetHNRec->Telnet = TRUE;
1395     } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1396     pvar->hostdlg_Enabled = TRUE;
1397    
1398     // check SSH protocol version
1399     memset(afstr, 0, sizeof(afstr));
1400     GetDlgItemText(dlg, IDC_SSH_VERSION, afstr, sizeof(afstr));
1401     if (_stricmp(afstr, "SSH1") == 0) {
1402     pvar->settings.ssh_protocol_version = 1;
1403     } else {
1404     pvar->settings.ssh_protocol_version = 2;
1405     }
1406     }
1407 doda 3541 else { // IDC_HOSTOTHER
1408     GetHNRec->Telnet = FALSE;
1409     }
1410 maya 3227
1411     // host history check button
1412     if (SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_GETCHECK, 0, 0) == BST_CHECKED) {
1413     pvar->ts->HistoryList = 1;
1414     } else {
1415     pvar->ts->HistoryList = 0;
1416     }
1417    
1418     } else {
1419     GetHNRec->PortType = IdSerial;
1420     GetHNRec->HostName[0] = 0;
1421     memset(EntName, 0, sizeof(EntName));
1422     GetDlgItemText(dlg, IDC_HOSTCOM, EntName,
1423     sizeof(EntName) - 1);
1424     if (strncmp(EntName, "COM", 3) == 0 && EntName[3] != '\0') {
1425     #if 0
1426     GetHNRec->ComPort = (BYTE) (EntName[3]) - 0x30;
1427     if (strlen(EntName) > 4)
1428     GetHNRec->ComPort =
1429     GetHNRec->ComPort * 10 + (BYTE) (EntName[4]) -
1430     0x30;
1431     #else
1432     GetHNRec->ComPort = atoi(&EntName[3]);
1433     #endif
1434     if (GetHNRec->ComPort > GetHNRec->MaxComPort)
1435     GetHNRec->ComPort = 1;
1436     } else {
1437     GetHNRec->ComPort = 1;
1438     }
1439     }
1440     }
1441     SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)OrigHostnameEditProc);
1442     EndDialog(dlg, 1);
1443    
1444     if (DlgHostFont != NULL) {
1445     DeleteObject(DlgHostFont);
1446     }
1447    
1448     return TRUE;
1449    
1450     case IDCANCEL:
1451     SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)OrigHostnameEditProc);
1452     EndDialog(dlg, 0);
1453    
1454     if (DlgHostFont != NULL) {
1455     DeleteObject(DlgHostFont);
1456     }
1457    
1458     return TRUE;
1459    
1460     case IDC_HOSTTCPIP:
1461     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1462     TRUE);
1463     #ifndef NO_INET6
1464     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1465     IDC_HOSTTCPPROTOCOL, TRUE);
1466     #endif /* NO_INET6 */
1467     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
1468    
1469     enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE); // disabled (2004.11.23 yutaka)
1470     if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1471     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE);
1472     } else {
1473     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1474     }
1475    
1476     enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, TRUE); // disabled
1477    
1478     return TRUE;
1479    
1480     case IDC_HOSTSERIAL:
1481     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, TRUE);
1482     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1483     FALSE);
1484     #ifndef NO_INET6
1485     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1486     IDC_HOSTTCPPROTOCOL, FALSE);
1487     #endif /* NO_INET6 */
1488     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1489     enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1490    
1491     enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, FALSE); // disabled
1492    
1493     return TRUE;
1494    
1495     case IDC_HOSTSSH:
1496     enable_dlg_items(dlg, IDC_SSH_VERSION,
1497     IDC_SSH_VERSION, TRUE);
1498     goto hostssh_enabled;
1499    
1500     case IDC_HOSTTELNET:
1501     case IDC_HOSTOTHER:
1502     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1503     hostssh_enabled:
1504    
1505     GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1506    
1507     if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1508     if (GetHNRec != NULL)
1509     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TelPort,
1510     FALSE);
1511     } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1512     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, 22, FALSE);
1513     }
1514     return TRUE;
1515    
1516     case IDC_HOSTCOM:
1517     if(HIWORD(wParam) == CBN_DROPDOWN) {
1518     HWND hostcom = GetDlgItem(dlg, IDC_HOSTCOM);
1519     int count = SendMessage(hostcom, CB_GETCOUNT, 0, 0);
1520     int i, len, max_len = 0;
1521     char *lbl;
1522     HDC TmpDC = GetDC(hostcom);
1523     SIZE s;
1524     for (i=0; i<count; i++) {
1525     len = SendMessage(hostcom, CB_GETLBTEXTLEN, i, 0);
1526     lbl = (char *)calloc(len+1, sizeof(char));
1527     SendMessage(hostcom, CB_GETLBTEXT, i, (LPARAM)lbl);
1528     GetTextExtentPoint32(TmpDC, lbl, len, &s);
1529     if (s.cx > max_len)
1530     max_len = s.cx;
1531     free(lbl);
1532     }
1533     SendMessage(hostcom, CB_SETDROPPEDWIDTH,
1534     max_len + GetSystemMetrics(SM_CXVSCROLL), 0);
1535     }
1536     break;
1537    
1538     case IDC_HOSTHELP:
1539     PostMessage(GetParent(dlg), WM_USER_DLGHELP2, 0, 0);
1540     }
1541     }
1542     return FALSE;
1543     }
1544    
1545     static BOOL FAR PASCAL TTXGetHostName(HWND parent, PGetHNRec rec)
1546     {
1547     return (BOOL) DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HOSTDLG),
1548     parent, TTXHostDlg, (LONG) rec);
1549     }
1550    
1551     static void PASCAL FAR TTXGetUIHooks(TTXUIHooks FAR * hooks)
1552     {
1553     *hooks->GetHostName = TTXGetHostName;
1554     }
1555    
1556     static void FAR PASCAL TTXReadINIFile(PCHAR fileName, PTTSet ts)
1557     {
1558     (pvar->ReadIniFile) (fileName, ts);
1559     read_ssh_options(pvar, fileName);
1560     pvar->settings = *pvar->ts_SSH;
1561     notify_verbose_message(pvar, "Reading INI file", LOG_LEVEL_VERBOSE);
1562     FWDUI_load_settings(pvar);
1563     }
1564    
1565     static void FAR PASCAL TTXWriteINIFile(PCHAR fileName, PTTSet ts)
1566     {
1567     (pvar->WriteIniFile) (fileName, ts);
1568     *pvar->ts_SSH = pvar->settings;
1569     clear_local_settings(pvar);
1570     notify_verbose_message(pvar, "Writing INI file", LOG_LEVEL_VERBOSE);
1571     write_ssh_options(pvar, fileName, pvar->ts_SSH, TRUE);
1572     }
1573    
1574     static void read_ssh_options_from_user_file(PTInstVar pvar,
1575     char FAR * user_file_name)
1576     {
1577     if (user_file_name[0] == '.') {
1578     read_ssh_options(pvar, user_file_name);
1579     } else {
1580     char buf[1024];
1581    
1582     get_teraterm_dir_relative_name(buf, sizeof(buf), user_file_name);
1583     read_ssh_options(pvar, buf);
1584     }
1585    
1586     pvar->settings = *pvar->ts_SSH;
1587     FWDUI_load_settings(pvar);
1588     }
1589    
1590 maya 3433 #ifdef USE_ATCMDLINE
1591 maya 3227 // @���u�����N���u�������B (2005.1.26 yutaka)
1592     static void replace_to_blank(char *src, char *dst, int dst_len)
1593     {
1594     int len, i;
1595    
1596     len = strlen(src);
1597     if (dst_len < len) // buffer overflow check
1598     return;
1599    
1600     for (i = 0 ; i < len ; i++) {
1601     if (src[i] == '@') { // @ ���o��������
1602     if (i < len - 1 && src[i + 1] == '@') { // �������� @ �����A�b�g�}�[�N���F������
1603     *dst++ = '@';
1604     i++;
1605     } else {
1606     *dst++ = ' '; // �������u��������
1607     }
1608     } else {
1609     *dst++ = src[i];
1610     }
1611     }
1612     *dst = '\0';
1613     }
1614 maya 3433 #endif
1615 maya 3227
1616     // Percent-encode������������src���f�R�[�h����dst���R�s�[�����B
1617     // dstlen��dst���T�C�Y�B�����������������������A�����������������������B
1618     static void percent_decode(char *dst, int dstlen, char *src) {
1619     if (src == NULL || dst == NULL || dstlen < 1) {
1620     return;
1621     }
1622    
1623     while (*src != 0 && dstlen > 1) {
1624     if (*src == '%' && isxdigit(*(src+1)) && isxdigit(*(src+2))) {
1625     src++; *dst = (isalpha(*src) ? (*src|0x20) - 'a' + 10 : *src - '0') << 4;
1626     src++; *dst |= (isalpha(*src) ? (*src|0x20) - 'a' + 10 : *src - '0');
1627     src++; dst++;
1628     }
1629     else {
1630     *dst++ = *src++;
1631     }
1632     dstlen--;
1633     }
1634     *dst = 0;
1635     return;
1636     }
1637    
1638     /* returns 1 if the option text must be deleted */
1639     static int parse_option(PTInstVar pvar, char FAR * option)
1640     {
1641     if ((option[0] == '-' || option[0] == '/')) {
1642     if (MATCH_STR(option + 1, "ssh") == 0) {
1643     if (option[4] == 0) {
1644     pvar->settings.Enabled = 1;
1645     } else if (MATCH_STR(option + 4, "-L") == 0 ||
1646     MATCH_STR(option + 4, "-R") == 0 ||
1647     _stricmp(option + 4, "-X") == 0) {
1648     if (pvar->settings.DefaultForwarding[0] == 0) {
1649     strncpy_s(pvar->settings.DefaultForwarding,
1650     sizeof(pvar->settings.DefaultForwarding),
1651     option + 5, _TRUNCATE);
1652     } else {
1653     strncat_s(pvar->settings.DefaultForwarding,
1654     sizeof(pvar->settings.DefaultForwarding),
1655     ";", _TRUNCATE);
1656     strncat_s(pvar->settings.DefaultForwarding,
1657     sizeof(pvar->settings.DefaultForwarding),
1658     option + 5, _TRUNCATE);
1659     }
1660     } else if (MATCH_STR(option + 4, "-f=") == 0) {
1661     read_ssh_options_from_user_file(pvar, option + 7);
1662     } else if (MATCH_STR(option + 4, "-v") == 0) {
1663     pvar->settings.LogLevel = LOG_LEVEL_VERBOSE;
1664     } else if (_stricmp(option + 4, "-autologin") == 0 ||
1665     _stricmp(option + 4, "-autologon") == 0) {
1666     pvar->settings.TryDefaultAuth = TRUE;
1667 doda 4235 } else if (MATCH_STR_I(option + 4, "-agentconfirm=") == 0) {
1668     if ((_stricmp(option+18, "off") == 0) ||
1669     (_stricmp(option+18, "no") == 0) ||
1670     (_stricmp(option+18, "false") == 0) ||
1671     (_stricmp(option+18, "0") == 0) ||
1672     (_stricmp(option+18, "n") == 0)) {
1673     pvar->settings.ForwardAgentConfirm = 0;
1674     }
1675     else {
1676     pvar->settings.ForwardAgentConfirm = 1;
1677     }
1678 maya 3227
1679     // -axx������������������
1680     } else if (MATCH_STR(option + 4, "-a") == 0) {
1681     pvar->settings.ForwardAgent = FALSE;
1682     } else if (MATCH_STR(option + 4, "-A") == 0) {
1683     pvar->settings.ForwardAgent = TRUE;
1684    
1685     } else if (MATCH_STR(option + 4, "-consume=") == 0) {
1686     read_ssh_options_from_user_file(pvar, option + 13);
1687     DeleteFile(option + 13);
1688    
1689 doda 4151 } else if (MATCH_STR(option + 4, "-C=") == 0) {
1690     pvar->settings.CompressionLevel = atoi(option+7);
1691     if (pvar->settings.CompressionLevel < 0) {
1692     pvar->settings.CompressionLevel = 0;
1693     }
1694     else if (pvar->settings.CompressionLevel > 9) {
1695     pvar->settings.CompressionLevel = 9;
1696     }
1697     } else if (MATCH_STR(option + 4, "-C") == 0) {
1698     pvar->settings.CompressionLevel = 6;
1699     } else if (MATCH_STR(option + 4, "-c") == 0) {
1700     pvar->settings.CompressionLevel = 0;
1701    
1702 maya 3227 // /ssh1 �� /ssh2 �I�v�V�������V�K���� (2006.9.16 maya)
1703     } else if (MATCH_STR(option + 4, "1") == 0) {
1704     pvar->settings.Enabled = 1;
1705     pvar->settings.ssh_protocol_version = 1;
1706     } else if (MATCH_STR(option + 4, "2") == 0) {
1707     pvar->settings.Enabled = 1;
1708     pvar->settings.ssh_protocol_version = 2;
1709    
1710     } else {
1711     char buf[1024];
1712    
1713     UTIL_get_lang_msg("MSG_UNKNOWN_OPTION_ERROR", pvar,
1714     "Unrecognized command-line option: %s");
1715     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, option);
1716    
1717     MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
1718     }
1719    
1720     // ttermpro.exe �� /T= �w�������p�������A������������ (2006.10.19 maya)
1721     } else if (MATCH_STR_I(option + 1, "t=") == 0) {
1722     if (strcmp(option + 3, "2") == 0) {
1723     pvar->settings.Enabled = 1;
1724 doda 3307 return OPTION_CLEAR; // /t=2��ttssh�������g������������
1725 maya 3227 } else {
1726     pvar->settings.Enabled = 0;
1727 doda 3307 return OPTION_NONE; // Tera Term������������������������
1728 maya 3227 }
1729    
1730     // ttermpro.exe �� /F= �w������ TTSSH ������������ (2006.10.11 maya)
1731     } else if (MATCH_STR_I(option + 1, "f=") == 0) {
1732     read_ssh_options_from_user_file(pvar, option + 3);
1733 doda 3307 return OPTION_NONE; // Tera Term���������������K�v������������������
1734 maya 3227
1735     // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
1736     } else if (MATCH_STR(option + 1, "1") == 0) {
1737     // command line: /ssh /1 is SSH1 only
1738     pvar->settings.ssh_protocol_version = 1;
1739    
1740     } else if (MATCH_STR(option + 1, "2") == 0) {
1741     // command line: /ssh /2 is SSH2 & SSH1
1742     pvar->settings.ssh_protocol_version = 2;
1743    
1744     } else if (MATCH_STR(option + 1, "nossh") == 0) {
1745     // '/nossh' �I�v�V�����������B
1746     // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
1747     // �����������������B(2004.10.11 yutaka)
1748     pvar->settings.Enabled = 0;
1749    
1750     } else if (MATCH_STR(option + 1, "telnet") == 0) {
1751     // '/telnet' ���w�������������������� '/nossh' ��������
1752     // SSH������������ (2006.9.16 maya)
1753     pvar->settings.Enabled = 0;
1754 maya 3533 // Tera Term �� Telnet �t���O���t����
1755     pvar->ts->Telnet = 1;
1756 maya 3227
1757     } else if (MATCH_STR(option + 1, "auth") == 0) {
1758     // SSH2�������O�C���I�v�V����������
1759     //
1760     // SYNOPSIS: /ssh /auth=passowrd /user=���[�U�� /passwd=�p�X���[�h
1761     // /ssh /auth=publickey /user=���[�U�� /passwd=�p�X���[�h /keyfile=�p�X
1762     // EXAMPLE: /ssh /auth=password /user=nike /passwd=a@bc
1763     // /ssh /auth=publickey /user=foo /passwd=bar /keyfile=d:\tmp\id_rsa
1764     // NOTICE: �p�X���[�h���p�X�������������������A�u�����N���������� @ ���g�������B
1765     //
1766     // (2004.11.30 yutaka)
1767     // (2005.1.26 yutaka) ���������B���J���F���T�|�[�g�B
1768     //
1769     pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
1770    
1771     if (MATCH_STR(option + 5, "=password") == 0) { // �p�X���[�h
1772     //pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
1773     pvar->ssh2_authmethod = SSH_AUTH_PASSWORD;
1774    
1775     // /auth=challenge ������ (2007.10.5 maya)
1776     } else if (MATCH_STR(option + 5, "=challenge") == 0) { // keyboard-interactive�F��
1777     //pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
1778     pvar->ssh2_authmethod = SSH_AUTH_TIS;
1779    
1780     } else if (MATCH_STR(option + 5, "=publickey") == 0) { // ���J���F��
1781     //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1782     pvar->ssh2_authmethod = SSH_AUTH_RSA;
1783    
1784     } else if (MATCH_STR(option + 5, "=pageant") == 0) { // ���J���F�� by Pageant
1785     //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1786     pvar->ssh2_authmethod = SSH_AUTH_PAGEANT;
1787    
1788     } else {
1789     // TODO:
1790    
1791     }
1792    
1793     } else if (MATCH_STR(option + 1, "user=") == 0) {
1794 maya 3433 #ifdef USE_ATCMDLINE
1795 maya 3227 replace_to_blank(option + 6, pvar->ssh2_username, sizeof(pvar->ssh2_username));
1796     //_snprintf(pvar->ssh2_username, sizeof(pvar->ssh2_username), "%s", option + 6);
1797    
1798 maya 3433 #else
1799     _snprintf_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), _TRUNCATE, "%s", option + 6);
1800     #endif
1801    
1802 maya 3227 } else if (MATCH_STR(option + 1, "passwd=") == 0) {
1803 maya 3433 #ifdef USE_ATCMDLINE
1804 maya 3227 replace_to_blank(option + 8, pvar->ssh2_password, sizeof(pvar->ssh2_password));
1805     //_snprintf(pvar->ssh2_password, sizeof(pvar->ssh2_password), "%s", option + 8);
1806 maya 3433 #else
1807     _snprintf_s(pvar->ssh2_password, sizeof(pvar->ssh2_password), _TRUNCATE, "%s", option + 8);
1808     #endif
1809 maya 3227
1810     } else if (MATCH_STR(option + 1, "keyfile=") == 0) {
1811 maya 3433 #ifdef USE_ATCMDLINE
1812 maya 3227 replace_to_blank(option + 9, pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile));
1813 maya 3433 #else
1814     _snprintf_s(pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile), _TRUNCATE, "%s", option + 9);
1815     #endif
1816 maya 3227
1817     } else if (MATCH_STR(option + 1, "ask4passwd") == 0) {
1818     // �p�X���[�h������ (2006.9.18 maya)
1819     pvar->ask4passwd = 1;
1820    
1821 yutakapon 3631 } else if (MATCH_STR(option + 1, "nosecuritywarning") == 0) {
1822     // known_hosts�`�F�b�N���������B���Y�I�v�V�������g�����A�Z�L�����e�B������������
1823     // �����A�B���I�v�V���������������B
1824     // (2009.10.4 yutaka)
1825     pvar->nocheck_known_hosts = TRUE;
1826    
1827 maya 3227 }
1828 doda 3307 else { // Other (not ttssh) option
1829     return OPTION_NONE; // ttssh���I�v�V������������������������
1830     }
1831 maya 3227
1832     // �p�X���[�h�������������������O�C��������������
1833     // /auth ���F�����\�b�h���w�������������p������ (2006.9.18 maya)
1834     if (pvar->ask4passwd == 1) {
1835     pvar->ssh2_autologin = 0;
1836     }
1837 doda 3307 return OPTION_CLEAR;
1838 maya 3227
1839     }
1840     else if ((MATCH_STR_I(option, "ssh://") == 0) ||
1841     (MATCH_STR_I(option, "ssh1://") == 0) ||
1842     (MATCH_STR_I(option, "ssh2://") == 0) ||
1843     (MATCH_STR_I(option, "slogin://") == 0) ||
1844     (MATCH_STR_I(option, "slogin1://") == 0) ||
1845     (MATCH_STR_I(option, "slogin2://") == 0)) {
1846     //
1847     // ssh://user@host/ ����URL�`�����T�|�[�g
1848     // ���{�I�������� telnet:// URL��������
1849     //
1850     // �Q�l:
1851     // RFC3986: Uniform Resource Identifier (URI): Generic Syntax
1852     // RFC4248: The telnet URI Scheme
1853     //
1854     char *p, *p2, *p3;
1855     int optlen, hostlen;
1856    
1857     optlen = strlen(option);
1858    
1859     // ������':'���O�����������������������A������ssh�v���g�R���o�[�W������������
1860 doda 3232 p = _mbschr(option, ':');
1861 maya 3227 switch (*(p-1)) {
1862     case '1':
1863     pvar->settings.ssh_protocol_version = 1;
1864     break;
1865     case '2':
1866     pvar->settings.ssh_protocol_version = 2;
1867     break;
1868     }
1869    
1870     // authority part �����|�C���^������
1871     p += 3;
1872    
1873     // path part ������������
1874 doda 3232 if ((p2 = _mbschr(p, '/')) != NULL) {
1875 maya 3227 *p2 = 0;
1876     }
1877    
1878     // '@'�������������A���������O�����[�U����
1879 doda 3232 if ((p2 = _mbschr(p, '@')) != NULL) {
1880 maya 3227 *p2 = 0;
1881     // ':'���~���p�X���[�h
1882 doda 3232 if ((p3 = _mbschr(p, ':')) != NULL) {
1883 maya 3227 *p3 = 0;
1884     percent_decode(pvar->ssh2_password, sizeof(pvar->ssh2_password), p3 + 1);
1885     }
1886     percent_decode(pvar->ssh2_username, sizeof(pvar->ssh2_username), p);
1887     // p �� host part ������('@'����������)����������������
1888     p = p2 + 1;
1889     }
1890    
1891     // host part �� option �����������������Ascheme part ������
1892     // port�w����������������port���������������������m��������������
1893     hostlen = strlen(p);
1894     memmove_s(option, optlen, p, hostlen);
1895     option[hostlen] = 0;
1896    
1897     // �|�[�g�w������������":22"������
1898     #ifndef NO_INET6
1899     if (option[0] == '[' && option[hostlen-1] == ']' || // IPv6 raw address without port
1900 doda 3232 option[0] != '[' && _mbschr(option, ':') == NULL) { // hostname or IPv4 raw address without port
1901 maya 3227 #else
1902 doda 3232 if (_mbschr(option, ':') == NULL) {
1903 maya 3227 #endif /* NO_INET6 */
1904     memcpy_s(option+hostlen, optlen-hostlen, ":22", 3);
1905     hostlen += 3;
1906     }
1907    
1908     // �|�[�g�w�����������������X�y�[�X������
1909     memset(option+hostlen, ' ', optlen-hostlen);
1910    
1911     pvar->settings.Enabled = 1;
1912    
1913     return OPTION_REPLACE;
1914     }
1915 doda 3232 else if (_mbschr(option, '@') != NULL) {
1916 maya 3227 //
1917     // user@host �`�����T�|�[�g
1918     // ����������ssh�������T�|�[�g�����A���[�U����ttssh���������B
1919     // (ssh�������O -- ttssh�������W������������)
1920     // �����I��telnet authentication option���T�|�[�g��������
1921     // Tera Term�{�����������������������\���B
1922     //
1923     char *p;
1924 doda 3232 p = _mbschr(option, '@');
1925 maya 3227 *p = 0;
1926    
1927     strncpy_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), option, _TRUNCATE);
1928    
1929     // ���[�U���������X�y�[�X�������B
1930     // ������TTX��Tera Term�{�������������������X�y�[�X�����������������A
1931     // �z�X�g�����������l�����K�v�������B
1932     memset(option, ' ', p-option+1);
1933    
1934     return OPTION_REPLACE;
1935     }
1936    
1937     return OPTION_NONE;
1938     }
1939    
1940     static void FAR PASCAL TTXParseParam(PCHAR param, PTTSet ts,
1941     PCHAR DDETopic)
1942     {
1943 maya 3433 #ifndef USE_ATCMDLINE
1944 maya 3427 int i;
1945     BOOL inParam = FALSE;
1946     BOOL inQuotes = FALSE;
1947     BOOL inEqual = FALSE;
1948     int param_len=strlen(param);
1949     PCHAR start = NULL;
1950     char *buf = (char *)calloc(param_len+1, sizeof(char));
1951     int buflen = 0;
1952    
1953     if (pvar->hostdlg_activated) {
1954     pvar->settings.Enabled = pvar->hostdlg_Enabled;
1955     }
1956    
1957     for (i = 0; i < param_len; i++) {
1958     if (inQuotes) {
1959     // �������u��"����
1960     if (param[i] == '"') {
1961     if (param[i+1] == '"') {
1962 maya 3433 buf[buflen] = param[i];
1963     buflen++;
1964 maya 3427 i++;
1965     }
1966     else {
1967     // �N�H�[�g���������������������I����
1968     // "��buf�����������������n��
1969     switch (parse_option(pvar, buf)) {
1970     case OPTION_CLEAR:
1971     memset(start, ' ', (param + i) - start + 1);
1972     break;
1973     case OPTION_REPLACE:
1974     memset(start, ' ', (param + i) - start + 1);
1975     buflen = strlen(buf);
1976     memcpy(start, buf, buflen);
1977     break;
1978     }
1979     inParam = FALSE;
1980     inEqual = FALSE;
1981     start = NULL;
1982     memset(buf, 0, param_len);
1983     buflen = 0;
1984     inQuotes = FALSE;
1985     }
1986     }
1987     else {
1988     buf[buflen] = param[i];
1989     buflen++;
1990     }
1991     }
1992     else {
1993     if (!inParam) {
1994     // �����p�����[�^������������
1995     if (param[i] == '"') {
1996     // " ���n����
1997     start = param + i;
1998     inParam = TRUE;
1999     inQuotes = TRUE;
2000     }
2001     else if (param[i] != ' ' && param[i] != '\t') {
2002     // �������n����
2003     buf[buflen] = param[i];
2004     buflen++;
2005     start = param + i;
2006     inParam = TRUE;
2007     }
2008     }
2009     else {
2010     // �������u���p�����[�^����
2011     if (param[i] == ' ' || param[i] == '\t') {
2012     // �N�H�[�g�����������������������I����
2013     switch (parse_option(pvar, buf)) {
2014     case OPTION_CLEAR:
2015     memset(start, ' ', (param + i) - start + 1);
2016     break;
2017     case OPTION_REPLACE:
2018     memset(start, ' ', (param + i) - start + 1);
2019     buflen = strlen(buf);
2020     memcpy(start, buf, buflen);
2021     break;
2022     }
2023     inParam = FALSE;
2024     inEqual = FALSE;
2025     start = NULL;
2026     memset(buf, 0, param_len);
2027     buflen = 0;
2028     }
2029     else {
2030     buf[buflen] = param[i];
2031     buflen++;
2032     if (!inEqual && param[i] == '=') {
2033     inEqual = TRUE;
2034     if (param[i+1] == '"') {
2035     inQuotes = TRUE;
2036     i++;
2037     }
2038     }
2039     }
2040     }
2041     }
2042     }
2043    
2044     // buf ���c�����������������n��
2045 maya 3435 // +1������������'\0'�������������������A��������������������
2046 maya 3427 if (strlen(buf) > 0) {
2047     switch (parse_option(pvar, buf)) {
2048     case OPTION_CLEAR:
2049 maya 3435 memset(start, ' ', (param + i) - start);
2050 maya 3427 break;
2051     case OPTION_REPLACE:
2052 maya 3435 memset(start, ' ', (param + i) - start);
2053 maya 3427 buflen = strlen(buf);
2054     memcpy(start, buf, buflen);
2055     break;
2056     }
2057     }
2058     free(buf);
2059     #else
2060 maya 3227 // �X�y�[�X�������t�@�C�������F�������������C�� (2006.10.7 maya)
2061     int i, buflen;
2062     BOOL inParam = FALSE;
2063     BOOL inQuotes = FALSE;
2064     BOOL inFileParam = FALSE;
2065     PCHAR option = NULL;
2066    
2067     if (pvar->hostdlg_activated) {
2068     pvar->settings.Enabled = pvar->hostdlg_Enabled;
2069     }
2070    
2071     for (i = 0; param[i] != 0; i++) {
2072     if (inQuotes ? param[i] == '"'
2073     : (param[i] == ' ' || param[i] == '\t')) {
2074     if (option != NULL) {
2075     char ch = param[i];
2076     PCHAR Equal;
2077    
2078     param[i] = 0;
2079     Equal = strchr(option, '=');
2080     if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
2081     int buf_len = strlen(option) * sizeof(char);
2082     char *buf = (char *)calloc(strlen(option), sizeof(char));
2083     char c = option[Equal - option + 1];
2084     option[Equal - option + 1] = 0;
2085     strncat_s(buf, buf_len, option, _TRUNCATE);
2086     option[Equal - option + 1] = c;
2087     strncat_s(buf, buf_len, Equal + 2, _TRUNCATE);
2088     switch (parse_option(pvar, *buf == '"' ? buf + 1 : buf)) {
2089     case OPTION_CLEAR:
2090     memset(option, ' ', i + 1 - (option - param));
2091     break;
2092     case OPTION_REPLACE:
2093     buflen = strlen(buf);
2094     memcpy(option, buf, buflen);
2095     memset(option + buflen, ' ', i + 1 - buflen - (option - param));
2096     break;
2097     default:
2098     param[i] = ch;
2099     }
2100     free(buf);
2101     }
2102     else {
2103     switch (parse_option(pvar, *option == '"' ? option + 1 : option)) {
2104     case OPTION_CLEAR:
2105     memset(option, ' ', i + 1 - (option - param));
2106     break;
2107     default:
2108     param[i] = ch;
2109     }
2110     }
2111     option = NULL;
2112     }
2113     inParam = FALSE;
2114     inQuotes = FALSE;
2115     inFileParam = FALSE;
2116     } else if (!inParam) {
2117     if (param[i] == '"') {
2118     inQuotes = TRUE;
2119     inParam = TRUE;
2120     option = param + i;
2121     } else if (param[i] != ' ' && param[i] != '\t') {
2122     inParam = TRUE;
2123     option = param + i;
2124     }
2125     } else {
2126     if (option == NULL) {
2127     continue;
2128     }
2129     if ((option[0] == '-' || option[0] == '/') &&
2130 doda 3288 (MATCH_STR(option + 1, "ssh-f=") == 0 || // ttssh option
2131     MATCH_STR(option + 1, "ssh-consume=") == 0 || // ttssh option
2132     MATCH_STR_I(option + 1, "f=") == 0 || // Tera Term option
2133     MATCH_STR_I(option + 1, "fd=") == 0 || // Tera Term option
2134     MATCH_STR_I(option + 1, "k=") == 0 || // Tera Term option
2135     MATCH_STR_I(option + 1, "l=") == 0 || // Tera Term option
2136     MATCH_STR_I(option + 1, "m=") == 0 || // Tera Term option
2137     MATCH_STR_I(option + 1, "r=") == 0 || // Tera Term option
2138     MATCH_STR_I(option + 1, "w=") == 0 || // Tera Term option
2139     MATCH_STR(option + 1, "keyfile=") == 0)) { // ttssh option
2140 maya 3227 if (param[i] == '"') {
2141     inQuotes = TRUE;
2142     }
2143     inFileParam = TRUE;
2144     }
2145     }
2146     }
2147    
2148     if (option != NULL) {
2149     PCHAR Equal = strchr(option, '=');
2150     if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
2151     int buf_len = strlen(option) * sizeof(char);
2152     char *buf = (char *)calloc(strlen(option), sizeof(char));
2153     char c = option[Equal - option + 1];
2154     option[Equal - option + 1] = 0;
2155     strncat_s(buf, buf_len, option, _TRUNCATE);
2156     option[Equal - option + 1] = c;
2157     strncat_s(buf, buf_len, Equal + 2, _TRUNCATE);
2158     switch (parse_option(pvar, *buf == '"' ? buf + 1 : buf)) {
2159     case OPTION_CLEAR:
2160     memset(option, ' ', i + 1 - (option - param));
2161     break;
2162     case OPTION_REPLACE:
2163     strcpy_s(option, i - (param - option), buf);
2164     break;
2165     }
2166     free(buf);
2167     }
2168     else {
2169     switch (parse_option(pvar, option)) {
2170     case OPTION_CLEAR:
2171     memset(option, ' ', i - (option - param));
2172     break;
2173     }
2174     }
2175     }
2176 maya 3427 #endif
2177 maya 3227
2178     FWDUI_load_settings(pvar);
2179    
2180     (pvar->ParseParam) (param, ts, DDETopic);
2181    
2182     }
2183    
2184     static void PASCAL FAR TTXGetSetupHooks(TTXSetupHooks FAR * hooks)
2185     {
2186     pvar->ReadIniFile = *hooks->ReadIniFile;
2187     pvar->WriteIniFile = *hooks->WriteIniFile;
2188     pvar->ParseParam = *hooks->ParseParam;
2189    
2190     *hooks->ReadIniFile = TTXReadINIFile;
2191     *hooks->WriteIniFile = TTXWriteINIFile;
2192     *hooks->ParseParam = TTXParseParam;
2193     }
2194    
2195     static void PASCAL FAR TTXSetWinSize(int rows, int cols)
2196     {
2197     SSH_notify_win_size(pvar, cols, rows);
2198     }
2199    
2200     static void insertMenuBeforeItem(HMENU menu, WORD beforeItemID, WORD flags,
2201     WORD newItemID, char FAR * text)
2202     {
2203     int i, j;
2204    
2205     for (i = GetMenuItemCount(menu) - 1; i >= 0; i--) {
2206     HMENU submenu = GetSubMenu(menu, i);
2207    
2208     for (j = GetMenuItemCount(submenu) - 1; j >= 0; j--) {
2209     if (GetMenuItemID(submenu, j) == beforeItemID) {
2210     InsertMenu(submenu, j, MF_BYPOSITION | flags, newItemID, text);
2211     return;
2212     }
2213     }
2214     }
2215     }
2216    
2217 doda 4463 #define GetFileMenu(menu) GetSubMenuByChildID(menu, 50110) // ID_FILE_NEWCONNECTION
2218     #define GetEditMenu(menu) GetSubMenuByChildID(menu, 50210) // ID_EDIT_COPY2
2219     #define GetSetupMenu(menu) GetSubMenuByChildID(menu, 50310) // ID_SETUP_TERMINAL
2220     #define GetControlMenu(menu) GetSubMenuByChildID(menu, 50410) // ID_CONTROL_RESETTERMINAL
2221     #define GetHelpMenu(menu) GetSubMenuByChildID(menu, 50990) // ID_HELP_ABOUT
2222    
2223     HMENU GetSubMenuByChildID(HMENU menu, UINT id) {
2224     int i, j, items, subitems, cur_id;
2225     HMENU m;
2226    
2227     items = GetMenuItemCount(menu);
2228    
2229     for (i=0; i<items; i++) {
2230     if (m = GetSubMenu(menu, i)) {
2231     subitems = GetMenuItemCount(m);
2232     for (j=0; j<subitems; j++) {
2233     cur_id = GetMenuItemID(m, j);
2234     if (cur_id == id) {
2235     return m;
2236     }
2237     }
2238     }
2239     }
2240     return NULL;
2241     }
2242    
2243 maya 3227 static void PASCAL FAR TTXModifyMenu(HMENU menu)
2244     {
2245 doda 4463 pvar->FileMenu = GetFileMenu(menu);
2246    
2247 maya 3227 /* inserts before ID_HELP_ABOUT */
2248     UTIL_get_lang_msg("MENU_ABOUT", pvar, "About &TTSSH...");
2249     insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU, pvar->ts->UIMsg);
2250    
2251     /* inserts before ID_SETUP_TCPIP */
2252     UTIL_get_lang_msg("MENU_SSH", pvar, "SS&H...");
2253     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU, pvar->ts->UIMsg);
2254     /* inserts before ID_SETUP_TCPIP */
2255     UTIL_get_lang_msg("MENU_SSH_AUTH", pvar, "SSH &Authentication...");
2256     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU, pvar->ts->UIMsg);
2257     /* inserts before ID_SETUP_TCPIP */
2258     UTIL_get_lang_msg("MENU_SSH_FORWARD", pvar, "SSH F&orwarding...");
2259     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU, pvar->ts->UIMsg);
2260     UTIL_get_lang_msg("MENU_SSH_KEYGEN", pvar, "SSH KeyGe&nerator...");
2261     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHKEYGENMENU, pvar->ts->UIMsg);
2262    
2263     /* inserts before ID_FILE_CHANGEDIR */
2264     UTIL_get_lang_msg("MENU_SSH_SCP", pvar, "SS&H SCP...");
2265 doda 4463 insertMenuBeforeItem(menu, 50170, MF_GRAYED, ID_SSHSCPMENU, pvar->ts->UIMsg);
2266 maya 3227 }
2267    
2268 doda 4463 static void PASCAL FAR TTXModifyPopupMenu(HMENU menu) {
2269     if (menu == pvar->FileMenu) {
2270     if (pvar->cv->Ready && pvar->settings.Enabled)
2271     EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_ENABLED);
2272     else
2273     EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_GRAYED);
2274     }
2275     }
2276    
2277 maya 3227 static void append_about_text(HWND dlg, char FAR * prefix, char FAR * msg)
2278     {
2279     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
2280     (LPARAM) prefix);
2281     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0, (LPARAM) msg);
2282     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
2283     (LPARAM) (char FAR *) "\r\n");
2284     }
2285    
2286     // ���s�t�@�C�������o�[�W�������������� (2005.2.28 yutaka)
2287     void get_file_version(char *exefile, int *major, int *minor, int *release, int *build)
2288     {
2289     typedef struct {
2290     WORD wLanguage;
2291     WORD wCodePage;
2292     } LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
2293     LPLANGANDCODEPAGE lplgcode;
2294     UINT unLen;
2295     DWORD size;
2296     char *buf = NULL;
2297     BOOL ret;
2298     int i;
2299     char fmt[80];
2300     char *pbuf;
2301    
2302     size = GetFileVersionInfoSize(exefile, NULL);
2303     if (size == 0) {
2304     goto error;
2305     }
2306     buf = malloc(size);
2307     ZeroMemory(buf, size);
2308