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