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 4422 - (hide annotations) (download) (as text)
Fri Apr 8 07:13:27 2011 UTC (13 years ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 147492 byte(s)
hmac-sha1-96, hmac-md5-96 をサポート。

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