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