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 4374 - (hide annotations) (download) (as text)
Tue Mar 8 01:00:58 2011 UTC (13 years, 1 month ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 148087 byte(s)
鍵生成ダイアログの挙動を変更
・ECDSA 鍵を選んだ時はビット数の入力ボックスを無効化するようにした
・ECDSA 鍵を選んだ後に RSA/DSA 鍵を選んだ時はビット数の値を元に戻すようにした

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