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 4392 - (hide annotations) (download) (as text)
Tue Mar 22 00:05:50 2011 UTC (13 years ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 147459 byte(s)
最後の二つの暗号方式 (Blowfish-CTR, CAST128-CTR) が常に無効化されるのを修正。
# 暗号方式で 1, 4, 5 が欠番なので、デフォルトのリストに三つ分のダミーエントリーを追加

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