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 3579 - (hide annotations) (download) (as text)
Mon Jul 6 02:56:52 2009 UTC (14 years, 9 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 138141 byte(s)
ssh接続後の接続で、TCPLocalEcho,TCPCRSendの設定が使われないのを修正した。
https://sourceforge.jp/ticket/browse.php?group_id=1412&tid=17592

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