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 5575 - (hide annotations) (download) (as text)
Thu May 1 14:09:18 2014 UTC (9 years, 11 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 177597 byte(s)
#33743: ホスト鍵のfingerprint

TTSSHのバージョン情報に、ホストの公開鍵の指紋(fingerprint)およびランダムアートを表示する。

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