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