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