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 4151 - (hide annotations) (download) (as text)
Wed Nov 10 06:20:21 2010 UTC (13 years, 5 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 138993 byte(s)
圧縮を有効/無効にするオプション、/ssh-C, /ssh-c を追加。

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