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 4423 - (hide annotations) (download) (as text)
Fri Apr 8 07:34:37 2011 UTC (13 years ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 147511 byte(s)
hmac-ripemd160@openssh.com をサポート。hmac-ripemd160 は IANA に登録されていないのでサポートしない。

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