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 3541 - (hide annotations) (download) (as text)
Sat Jun 27 07:50:29 2009 UTC (14 years, 9 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 138019 byte(s)
raw接続で Telnet が off にならないのを修正。

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     pvar->ts->DisableTCPEchoCR = TRUE;
791    
792     pvar->session_settings = pvar->settings;
793    
794     notify_verbose_message(pvar, "---------------------------------------------------------------------", LOG_LEVEL_VERBOSE);
795     notify_verbose_message(pvar, "Initiating SSH session", LOG_LEVEL_VERBOSE);
796    
797     FWDUI_load_settings(pvar);
798    
799     pvar->cv->TelAutoDetect = FALSE;
800     /* This next line should not be needed because Tera Term's
801     CommLib should find ts->Telnet == 0 ... but we'll do this
802     just to be on the safe side. */
803     pvar->cv->TelFlag = FALSE;
804 doda 3495 pvar->cv->TelLineMode = FALSE;
805 maya 3227
806     pvar->Precv = *hooks->Precv;
807     pvar->Psend = *hooks->Psend;
808     pvar->PWSAAsyncSelect = *hooks->PWSAAsyncSelect;
809     pvar->Pconnect = *hooks->Pconnect;
810     pvar->PWSAGetLastError = *hooks->PWSAGetLastError;
811    
812     *hooks->Precv = TTXrecv;
813     *hooks->Psend = TTXsend;
814     *hooks->PWSAAsyncSelect = TTXWSAAsyncSelect;
815     *hooks->Pconnect = TTXconnect;
816    
817     SSH_open(pvar);
818     HOSTS_open(pvar);
819     FWDUI_open(pvar);
820    
821     // ������ myproposal �����f���������A�������O�����������B (2006.6.26 maya)
822     SSH2_update_cipher_myproposal(pvar);
823     SSH2_update_compression_myproposal(pvar);
824     }
825     }
826    
827     static void PASCAL FAR TTXCloseTCP(TTXSockHooks FAR * hooks)
828     {
829     if (pvar->session_settings.Enabled) {
830     pvar->socket = INVALID_SOCKET;
831    
832     notify_verbose_message(pvar, "Terminating SSH session...",
833     LOG_LEVEL_VERBOSE);
834    
835     *hooks->Precv = pvar->Precv;
836     *hooks->Psend = pvar->Psend;
837     *hooks->PWSAAsyncSelect = pvar->PWSAAsyncSelect;
838     *hooks->Pconnect = pvar->Pconnect;
839     }
840    
841     uninit_TTSSH(pvar);
842     init_TTSSH(pvar);
843     }
844    
845     static void enable_dlg_items(HWND dlg, int from, int to, BOOL enabled)
846     {
847     for (; from <= to; from++) {
848     EnableWindow(GetDlgItem(dlg, from), enabled);
849     }
850     }
851    
852     // C-p/C-n/C-b/C-f/C-a/C-e ���T�|�[�g (2007.9.5 maya)
853     // C-d/C-k ���T�|�[�g (2007.10.3 yutaka)
854     // �h���b�v�_�E���������G�f�B�b�g�R���g���[����
855     // �T�u�N���X�������������E�C���h�E�v���V�[�W��
856     WNDPROC OrigHostnameEditProc; // Original window procedure
857     LRESULT CALLBACK HostnameEditProc(HWND dlg, UINT msg,
858     WPARAM wParam, LPARAM lParam)
859     {
860     HWND parent;
861     int max, select, len;
862     char *str, *orgstr;
863    
864     switch (msg) {
865     // �L�[�����������������m����
866     case WM_KEYDOWN:
867     if (GetKeyState(VK_CONTROL) < 0) {
868     switch (wParam) {
869     case 0x50: // Ctrl+p ... up
870     parent = GetParent(dlg);
871     select = SendMessage(parent, CB_GETCURSEL, 0, 0);
872     if (select > 0) {
873     PostMessage(parent, CB_SETCURSEL, select - 1, 0);
874     }
875     return 0;
876     case 0x4e: // Ctrl+n ... down
877     parent = GetParent(dlg);
878     max = SendMessage(parent, CB_GETCOUNT, 0, 0);
879     select = SendMessage(parent, CB_GETCURSEL, 0, 0);
880     if (select < max - 1) {
881     PostMessage(parent, CB_SETCURSEL, select + 1, 0);
882     }
883     return 0;
884     case 0x42: // Ctrl+b ... left
885     SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
886     PostMessage(dlg, EM_SETSEL, select-1, select-1);
887     return 0;
888     case 0x46: // Ctrl+f ... right
889     SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
890     max = GetWindowTextLength(dlg) ;
891     PostMessage(dlg, EM_SETSEL, select+1, select+1);
892     return 0;
893     case 0x41: // Ctrl+a ... home
894     PostMessage(dlg, EM_SETSEL, 0, 0);
895     return 0;
896     case 0x45: // Ctrl+e ... end
897     max = GetWindowTextLength(dlg) ;
898     PostMessage(dlg, EM_SETSEL, max, max);
899     return 0;
900    
901     case 0x44: // Ctrl+d
902     case 0x4b: // Ctrl+k
903     case 0x55: // Ctrl+u
904     SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
905     max = GetWindowTextLength(dlg);
906     max++; // '\0'
907     orgstr = str = malloc(max);
908     if (str != NULL) {
909     len = GetWindowText(dlg, str, max);
910     if (select >= 0 && select < len) {
911     if (wParam == 0x44) { // �J�[�\���z����������������������
912     memmove(&str[select], &str[select + 1], len - select - 1);
913     str[len - 1] = '\0';
914    
915     } else if (wParam == 0x4b) { // �J�[�\�������s��������������
916     str[select] = '\0';
917    
918     }
919     }
920    
921     if (wParam == 0x55) { // �J�[�\����������������������
922     if (select >= len) {
923     str[0] = '\0';
924     } else {
925     str = &str[select];
926     }
927     select = 0;
928     }
929    
930     SetWindowText(dlg, str);
931     SendMessage(dlg, EM_SETSEL, select, select);
932     free(orgstr);
933     return 0;
934     }
935     break;
936     }
937     }
938     break;
939    
940     // �����L�[��������������������������������������������
941     case WM_CHAR:
942     switch (wParam) {
943     case 0x01:
944     case 0x02:
945     case 0x04:
946     case 0x05:
947     case 0x06:
948     case 0x0b:
949     case 0x0e:
950     case 0x10:
951     case 0x15:
952     return 0;
953     }
954     }
955    
956     return CallWindowProc(OrigHostnameEditProc, dlg, msg, wParam, lParam);
957     }
958    
959     static BOOL CALLBACK TTXHostDlg(HWND dlg, UINT msg, WPARAM wParam,
960     LPARAM lParam)
961     {
962     static char *ssh_version[] = {"SSH1", "SSH2", NULL};
963     PGetHNRec GetHNRec;
964     char EntName[128];
965     char TempHost[HostNameMaxLength + 1];
966     WORD i, j, w;
967     WORD ComPortTable[MAXCOMPORT];
968     static char *ComPortDesc[MAXCOMPORT];
969     int comports;
970     BOOL Ok;
971     LOGFONT logfont;
972     HFONT font;
973     char uimsg[MAX_UIMSG];
974     static HWND hwndHostname = NULL; // HOSTNAME dropdown
975     static HWND hwndHostnameEdit = NULL; // Edit control on HOSTNAME dropdown
976    
977     switch (msg) {
978     case WM_INITDIALOG:
979     GetHNRec = (PGetHNRec) lParam;
980     SetWindowLong(dlg, DWL_USER, lParam);
981    
982     GetWindowText(dlg, uimsg, sizeof(uimsg));
983     UTIL_get_lang_msg("DLG_HOST_TITLE", pvar, uimsg);
984     SetWindowText(dlg, pvar->ts->UIMsg);
985     GetDlgItemText(dlg, IDC_HOSTNAMELABEL, uimsg, sizeof(uimsg));
986     UTIL_get_lang_msg("DLG_HOST_TCPIPHOST", pvar, uimsg);
987     SetDlgItemText(dlg, IDC_HOSTNAMELABEL, pvar->ts->UIMsg);
988     GetDlgItemText(dlg, IDC_HISTORY, uimsg, sizeof(uimsg));
989     UTIL_get_lang_msg("DLG_HOST_TCPIPHISTORY", pvar, uimsg);
990     SetDlgItemText(dlg, IDC_HISTORY, pvar->ts->UIMsg);
991     GetDlgItemText(dlg, IDC_SERVICELABEL, uimsg, sizeof(uimsg));
992     UTIL_get_lang_msg("DLG_HOST_TCPIPSERVICE", pvar, uimsg);
993     SetDlgItemText(dlg, IDC_SERVICELABEL, pvar->ts->UIMsg);
994     GetDlgItemText(dlg, IDC_HOSTOTHER, uimsg, sizeof(uimsg));
995     UTIL_get_lang_msg("DLG_HOST_TCPIPOTHER", pvar, uimsg);
996     SetDlgItemText(dlg, IDC_HOSTOTHER, pvar->ts->UIMsg);
997     GetDlgItemText(dlg, IDC_HOSTTCPPORTLABEL, uimsg, sizeof(uimsg));
998     UTIL_get_lang_msg("DLG_HOST_TCPIPPORT", pvar, uimsg);
999     SetDlgItemText(dlg, IDC_HOSTTCPPORTLABEL, pvar->ts->UIMsg);
1000     GetDlgItemText(dlg, IDC_SSH_VERSION_LABEL, uimsg, sizeof(uimsg));
1001     UTIL_get_lang_msg("DLG_HOST_TCPIPSSHVERSION", pvar, uimsg);
1002     SetDlgItemText(dlg, IDC_SSH_VERSION_LABEL, pvar->ts->UIMsg);
1003     GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOLLABEL, uimsg, sizeof(uimsg));
1004     UTIL_get_lang_msg("DLG_HOST_TCPIPPROTOCOL", pvar, uimsg);
1005     SetDlgItemText(dlg, IDC_HOSTTCPPROTOCOLLABEL, pvar->ts->UIMsg);
1006     GetDlgItemText(dlg, IDC_HOSTSERIAL, uimsg, sizeof(uimsg));
1007     UTIL_get_lang_msg("DLG_HOST_SERIAL", pvar, uimsg);
1008     SetDlgItemText(dlg, IDC_HOSTSERIAL, pvar->ts->UIMsg);
1009     GetDlgItemText(dlg, IDC_HOSTCOMLABEL, uimsg, sizeof(uimsg));
1010     UTIL_get_lang_msg("DLG_HOST_SERIALPORT", pvar, uimsg);
1011     SetDlgItemText(dlg, IDC_HOSTCOMLABEL, pvar->ts->UIMsg);
1012     GetDlgItemText(dlg, IDC_HOSTHELP, uimsg, sizeof(uimsg));
1013     UTIL_get_lang_msg("DLG_HOST_HELP", pvar, uimsg);
1014     SetDlgItemText(dlg, IDC_HOSTHELP, pvar->ts->UIMsg);
1015     GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
1016     UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
1017     SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
1018     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1019     UTIL_get_lang_msg("BTN_CANCEL", pvar, uimsg);
1020     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1021    
1022     // �z�X�g�q�X�g�����`�F�b�N�{�b�N�X������ (2005.10.21 yutaka)
1023     if (pvar->ts->HistoryList > 0) {
1024     SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_SETCHECK, BST_CHECKED, 0);
1025     } else {
1026     SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_SETCHECK, BST_UNCHECKED, 0);
1027     }
1028    
1029     if (GetHNRec->PortType == IdFile)
1030     GetHNRec->PortType = IdTCPIP;
1031    
1032     strncpy_s(EntName, sizeof(EntName), "Host", _TRUNCATE);
1033    
1034     i = 1;
1035     do {
1036     _snprintf_s(&EntName[4], sizeof(EntName)-4, _TRUNCATE, "%d", i);
1037     GetPrivateProfileString("Hosts", EntName, "",
1038     TempHost, sizeof(TempHost),
1039     GetHNRec->SetupFN);
1040     if (strlen(TempHost) > 0)
1041     SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_ADDSTRING,
1042     0, (LPARAM) TempHost);
1043     i++;
1044     } while ((i <= MAXHOSTLIST) && (strlen(TempHost) > 0));
1045    
1046     SendDlgItemMessage(dlg, IDC_HOSTNAME, EM_LIMITTEXT,
1047     HostNameMaxLength - 1, 0);
1048    
1049     SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_SETCURSEL, 0, 0);
1050    
1051     // C-n/C-p ���������T�u�N���X�� (2007.9.4 maya)
1052     hwndHostname = GetDlgItem(dlg, IDC_HOSTNAME);
1053     hwndHostnameEdit = GetWindow(hwndHostname, GW_CHILD);
1054     OrigHostnameEditProc = (WNDPROC)GetWindowLong(hwndHostnameEdit, GWL_WNDPROC);
1055     SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)HostnameEditProc);
1056    
1057     CheckRadioButton(dlg, IDC_HOSTTELNET, IDC_HOSTOTHER,
1058     pvar->settings.Enabled ? IDC_HOSTSSH : GetHNRec->
1059     Telnet ? IDC_HOSTTELNET : IDC_HOSTOTHER);
1060     SendDlgItemMessage(dlg, IDC_HOSTTCPPORT, EM_LIMITTEXT, 5, 0);
1061     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TCPPort, FALSE);
1062     #ifndef NO_INET6
1063     for (i = 0; ProtocolFamilyList[i]; ++i) {
1064     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_ADDSTRING,
1065     0, (LPARAM) ProtocolFamilyList[i]);
1066     }
1067     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, EM_LIMITTEXT,
1068     ProtocolFamilyMaxLength - 1, 0);
1069     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_SETCURSEL, 0, 0);
1070     #endif /* NO_INET6 */
1071    
1072     /////// SSH version
1073     for (i = 0; ssh_version[i]; ++i) {
1074     SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_ADDSTRING,
1075     0, (LPARAM) ssh_version[i]);
1076     }
1077     SendDlgItemMessage(dlg, IDC_SSH_VERSION, EM_LIMITTEXT,
1078     NUM_ELEM(ssh_version) - 1, 0);
1079    
1080     if (pvar->settings.ssh_protocol_version == 1) {
1081     SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 0, 0); // SSH1
1082     } else {
1083     SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 1, 0); // SSH2
1084     }
1085    
1086     if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1087     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE); // enabled
1088     } else {
1089     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1090     }
1091     /////// SSH version
1092    
1093    
1094     j = 0;
1095     w = 1;
1096     if ((comports=DetectComPorts(ComPortTable, GetHNRec->MaxComPort, ComPortDesc)) >= 0) {
1097     for (i=0; i<comports; i++) {
1098     // MaxComPort ���z�����|�[�g���\��������
1099     if (ComPortTable[i] > GetHNRec->MaxComPort) {
1100     continue;
1101     }
1102    
1103     // �g�p�����|�[�g���\��������
1104     if (CheckCOMFlag(ComPortTable[i]) == 1) {
1105     continue;
1106     }
1107    
1108     _snprintf_s(EntName, sizeof(EntName), _TRUNCATE, "COM%d", ComPortTable[i]);
1109     if (ComPortDesc[i] != NULL) {
1110     strncat_s(EntName, sizeof(EntName), ": ", _TRUNCATE);
1111     strncat_s(EntName, sizeof(EntName), ComPortDesc[i], _TRUNCATE);
1112     }
1113     SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_ADDSTRING,
1114     0, (LPARAM)EntName);
1115     j++;
1116     if (GetHNRec->ComPort == ComPortTable[i])
1117     w = j;
1118     }
1119    
1120     } else {
1121     for (i = 1; i <= GetHNRec->MaxComPort; i++) {
1122     // �g�p�����|�[�g���\��������
1123     if (CheckCOMFlag(i) == 1) {
1124     continue;
1125     }
1126    
1127     _snprintf_s(EntName, sizeof(EntName), _TRUNCATE, "COM%d", i);
1128     SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_ADDSTRING,
1129     0, (LPARAM) EntName);
1130     j++;
1131     if (GetHNRec->ComPort == i)
1132     w = j;
1133     }
1134     }
1135    
1136     if (j > 0)
1137     SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_SETCURSEL, w - 1, 0);
1138     else { /* All com ports are already used */
1139     GetHNRec->PortType = IdTCPIP;
1140     enable_dlg_items(dlg, IDC_HOSTSERIAL, IDC_HOSTSERIAL, FALSE);
1141     }
1142    
1143     CheckRadioButton(dlg, IDC_HOSTTCPIP, IDC_HOSTSERIAL,
1144     IDC_HOSTTCPIP + GetHNRec->PortType - 1);
1145    
1146     if (GetHNRec->PortType == IdTCPIP) {
1147     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
1148    
1149     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE);
1150     enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE);
1151    
1152     enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, TRUE); // enabled
1153     }
1154     #ifndef NO_INET6
1155     else {
1156     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1157     FALSE);
1158     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1159     IDC_HOSTTCPPROTOCOL, FALSE);
1160    
1161     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1162     enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1163    
1164     enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, FALSE); // disabled
1165     }
1166     #else
1167     else
1168     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1169     FALSE);
1170     #endif /* NO_INET6 */
1171    
1172     // Host dialog���t�H�[�J�X�������� (2004.10.2 yutaka)
1173     if (GetHNRec->PortType == IdTCPIP) {
1174     HWND hwnd = GetDlgItem(dlg, IDC_HOSTNAME);
1175     SetFocus(hwnd);
1176     } else {
1177     HWND hwnd = GetDlgItem(dlg, IDC_HOSTCOM);
1178     SetFocus(hwnd);
1179     }
1180    
1181     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1182     GetObject(font, sizeof(LOGFONT), &logfont);
1183     if (UTIL_get_lang_font("DLG_SYSTEM_FONT", dlg, &logfont, &DlgHostFont, pvar)) {
1184     SendDlgItemMessage(dlg, IDC_HOSTTCPIP, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1185     SendDlgItemMessage(dlg, IDC_HOSTNAMELABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1186     SendDlgItemMessage(dlg, IDC_HOSTNAME, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1187     SendDlgItemMessage(dlg, IDC_HISTORY, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1188     SendDlgItemMessage(dlg, IDC_SERVICELABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1189     SendDlgItemMessage(dlg, IDC_HOSTTELNET, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1190     SendDlgItemMessage(dlg, IDC_HOSTSSH, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1191     SendDlgItemMessage(dlg, IDC_HOSTOTHER, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1192     SendDlgItemMessage(dlg, IDC_HOSTTCPPORTLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1193     SendDlgItemMessage(dlg, IDC_HOSTTCPPORT, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1194     SendDlgItemMessage(dlg, IDC_SSH_VERSION_LABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1195     SendDlgItemMessage(dlg, IDC_SSH_VERSION, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1196     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOLLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1197     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1198     SendDlgItemMessage(dlg, IDC_HOSTSERIAL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1199     SendDlgItemMessage(dlg, IDC_HOSTCOMLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1200     SendDlgItemMessage(dlg, IDC_HOSTCOM, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1201     SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1202     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1203     SendDlgItemMessage(dlg, IDC_HOSTHELP, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1204     }
1205     else {
1206     DlgHostFont = NULL;
1207     }
1208    
1209     // SetFocus()���t�H�[�J�X���������������AFALSE�������K�v�������B
1210     // TRUE���������ATABSTOP�������������������R���g���[�����I�������B
1211     // (2004.11.23 yutaka)
1212     return FALSE;
1213     //return TRUE;
1214    
1215     case WM_COMMAND:
1216     switch (LOWORD(wParam)) {
1217     case IDOK:
1218     GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1219     if (GetHNRec != NULL) {
1220     if (IsDlgButtonChecked(dlg, IDC_HOSTTCPIP)) {
1221     #ifndef NO_INET6
1222     char afstr[BUFSIZ];
1223     #endif /* NO_INET6 */
1224     i = GetDlgItemInt(dlg, IDC_HOSTTCPPORT, &Ok, FALSE);
1225     if (Ok) {
1226     GetHNRec->TCPPort = i;
1227     } else {
1228     UTIL_get_lang_msg("MSG_TCPPORT_NAN_ERROR", pvar,
1229     "The TCP port must be a number.");
1230     MessageBox(dlg, pvar->ts->UIMsg,
1231     "Tera Term", MB_OK | MB_ICONEXCLAMATION);
1232     return TRUE;
1233     }
1234     #ifndef NO_INET6
1235     #define getaf(str) \
1236     ((strcmp((str), "IPv6") == 0) ? AF_INET6 : \
1237     ((strcmp((str), "IPv4") == 0) ? AF_INET : AF_UNSPEC))
1238     memset(afstr, 0, sizeof(afstr));
1239     GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOL, afstr,
1240     sizeof(afstr));
1241     GetHNRec->ProtocolFamily = getaf(afstr);
1242     #endif /* NO_INET6 */
1243     GetHNRec->PortType = IdTCPIP;
1244     GetDlgItemText(dlg, IDC_HOSTNAME, GetHNRec->HostName,
1245     HostNameMaxLength);
1246     pvar->hostdlg_activated = TRUE;
1247     pvar->hostdlg_Enabled = FALSE;
1248     if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1249     GetHNRec->Telnet = TRUE;
1250     } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1251     pvar->hostdlg_Enabled = TRUE;
1252    
1253     // check SSH protocol version
1254     memset(afstr, 0, sizeof(afstr));
1255     GetDlgItemText(dlg, IDC_SSH_VERSION, afstr, sizeof(afstr));
1256     if (_stricmp(afstr, "SSH1") == 0) {
1257     pvar->settings.ssh_protocol_version = 1;
1258     } else {
1259     pvar->settings.ssh_protocol_version = 2;
1260     }
1261     }
1262 doda 3541 else { // IDC_HOSTOTHER
1263     GetHNRec->Telnet = FALSE;
1264     }
1265 maya 3227
1266     // host history check button
1267     if (SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_GETCHECK, 0, 0) == BST_CHECKED) {
1268     pvar->ts->HistoryList = 1;
1269     } else {
1270     pvar->ts->HistoryList = 0;
1271     }
1272    
1273     } else {
1274     GetHNRec->PortType = IdSerial;
1275     GetHNRec->HostName[0] = 0;
1276     memset(EntName, 0, sizeof(EntName));
1277     GetDlgItemText(dlg, IDC_HOSTCOM, EntName,
1278     sizeof(EntName) - 1);
1279     if (strncmp(EntName, "COM", 3) == 0 && EntName[3] != '\0') {
1280     #if 0
1281     GetHNRec->ComPort = (BYTE) (EntName[3]) - 0x30;
1282     if (strlen(EntName) > 4)
1283     GetHNRec->ComPort =
1284     GetHNRec->ComPort * 10 + (BYTE) (EntName[4]) -
1285     0x30;
1286     #else
1287     GetHNRec->ComPort = atoi(&EntName[3]);
1288     #endif
1289     if (GetHNRec->ComPort > GetHNRec->MaxComPort)
1290     GetHNRec->ComPort = 1;
1291     } else {
1292     GetHNRec->ComPort = 1;
1293     }
1294     }
1295     }
1296     SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)OrigHostnameEditProc);
1297     EndDialog(dlg, 1);
1298    
1299     if (DlgHostFont != NULL) {
1300     DeleteObject(DlgHostFont);
1301     }
1302    
1303     return TRUE;
1304    
1305     case IDCANCEL:
1306     SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)OrigHostnameEditProc);
1307     EndDialog(dlg, 0);
1308    
1309     if (DlgHostFont != NULL) {
1310     DeleteObject(DlgHostFont);
1311     }
1312    
1313     return TRUE;
1314    
1315     case IDC_HOSTTCPIP:
1316     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1317     TRUE);
1318     #ifndef NO_INET6
1319     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1320     IDC_HOSTTCPPROTOCOL, TRUE);
1321     #endif /* NO_INET6 */
1322     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
1323    
1324     enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE); // disabled (2004.11.23 yutaka)
1325     if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1326     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE);
1327     } else {
1328     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1329     }
1330    
1331     enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, TRUE); // disabled
1332    
1333     return TRUE;
1334    
1335     case IDC_HOSTSERIAL:
1336     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, TRUE);
1337     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1338     FALSE);
1339     #ifndef NO_INET6
1340     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1341     IDC_HOSTTCPPROTOCOL, FALSE);
1342     #endif /* NO_INET6 */
1343     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1344     enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1345    
1346     enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, FALSE); // disabled
1347    
1348     return TRUE;
1349    
1350     case IDC_HOSTSSH:
1351     enable_dlg_items(dlg, IDC_SSH_VERSION,
1352     IDC_SSH_VERSION, TRUE);
1353     goto hostssh_enabled;
1354    
1355     case IDC_HOSTTELNET:
1356     case IDC_HOSTOTHER:
1357     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1358     hostssh_enabled:
1359    
1360     GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1361    
1362     if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1363     if (GetHNRec != NULL)
1364     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TelPort,
1365     FALSE);
1366     } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1367     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, 22, FALSE);
1368     }
1369     return TRUE;
1370    
1371     case IDC_HOSTCOM:
1372     if(HIWORD(wParam) == CBN_DROPDOWN) {
1373     HWND hostcom = GetDlgItem(dlg, IDC_HOSTCOM);
1374     int count = SendMessage(hostcom, CB_GETCOUNT, 0, 0);
1375     int i, len, max_len = 0;
1376     char *lbl;
1377     HDC TmpDC = GetDC(hostcom);
1378     SIZE s;
1379     for (i=0; i<count; i++) {
1380     len = SendMessage(hostcom, CB_GETLBTEXTLEN, i, 0);
1381     lbl = (char *)calloc(len+1, sizeof(char));
1382     SendMessage(hostcom, CB_GETLBTEXT, i, (LPARAM)lbl);
1383     GetTextExtentPoint32(TmpDC, lbl, len, &s);
1384     if (s.cx > max_len)
1385     max_len = s.cx;
1386     free(lbl);
1387     }
1388     SendMessage(hostcom, CB_SETDROPPEDWIDTH,
1389     max_len + GetSystemMetrics(SM_CXVSCROLL), 0);
1390     }
1391     break;
1392    
1393     case IDC_HOSTHELP:
1394     PostMessage(GetParent(dlg), WM_USER_DLGHELP2, 0, 0);
1395     }
1396     }
1397     return FALSE;
1398     }
1399    
1400     static BOOL FAR PASCAL TTXGetHostName(HWND parent, PGetHNRec rec)
1401     {
1402     return (BOOL) DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HOSTDLG),
1403     parent, TTXHostDlg, (LONG) rec);
1404     }
1405    
1406     static void PASCAL FAR TTXGetUIHooks(TTXUIHooks FAR * hooks)
1407     {
1408     *hooks->GetHostName = TTXGetHostName;
1409     }
1410    
1411     static void FAR PASCAL TTXReadINIFile(PCHAR fileName, PTTSet ts)
1412     {
1413     (pvar->ReadIniFile) (fileName, ts);
1414     read_ssh_options(pvar, fileName);
1415     pvar->settings = *pvar->ts_SSH;
1416     notify_verbose_message(pvar, "Reading INI file", LOG_LEVEL_VERBOSE);
1417     FWDUI_load_settings(pvar);
1418     }
1419    
1420     static void FAR PASCAL TTXWriteINIFile(PCHAR fileName, PTTSet ts)
1421     {
1422     (pvar->WriteIniFile) (fileName, ts);
1423     *pvar->ts_SSH = pvar->settings;
1424     clear_local_settings(pvar);
1425     notify_verbose_message(pvar, "Writing INI file", LOG_LEVEL_VERBOSE);
1426     write_ssh_options(pvar, fileName, pvar->ts_SSH, TRUE);
1427     }
1428    
1429     static void read_ssh_options_from_user_file(PTInstVar pvar,
1430     char FAR * user_file_name)
1431     {
1432     if (user_file_name[0] == '.') {
1433     read_ssh_options(pvar, user_file_name);
1434     } else {
1435     char buf[1024];
1436    
1437     get_teraterm_dir_relative_name(buf, sizeof(buf), user_file_name);
1438     read_ssh_options(pvar, buf);
1439     }
1440    
1441     pvar->settings = *pvar->ts_SSH;
1442     FWDUI_load_settings(pvar);
1443     }
1444    
1445 maya 3433 #ifdef USE_ATCMDLINE
1446 maya 3227 // @���u�����N���u�������B (2005.1.26 yutaka)
1447     static void replace_to_blank(char *src, char *dst, int dst_len)
1448     {
1449     int len, i;
1450    
1451     len = strlen(src);
1452     if (dst_len < len) // buffer overflow check
1453     return;
1454    
1455     for (i = 0 ; i < len ; i++) {
1456     if (src[i] == '@') { // @ ���o��������
1457     if (i < len - 1 && src[i + 1] == '@') { // �������� @ �����A�b�g�}�[�N���F������
1458     *dst++ = '@';
1459     i++;
1460     } else {
1461     *dst++ = ' '; // �������u��������
1462     }
1463     } else {
1464     *dst++ = src[i];
1465     }
1466     }
1467     *dst = '\0';
1468     }
1469 maya 3433 #endif
1470 maya 3227
1471     // Percent-encode������������src���f�R�[�h����dst���R�s�[�����B
1472     // dstlen��dst���T�C�Y�B�����������������������A�����������������������B
1473     static void percent_decode(char *dst, int dstlen, char *src) {
1474     if (src == NULL || dst == NULL || dstlen < 1) {
1475     return;
1476     }
1477    
1478     while (*src != 0 && dstlen > 1) {
1479     if (*src == '%' && isxdigit(*(src+1)) && isxdigit(*(src+2))) {
1480     src++; *dst = (isalpha(*src) ? (*src|0x20) - 'a' + 10 : *src - '0') << 4;
1481     src++; *dst |= (isalpha(*src) ? (*src|0x20) - 'a' + 10 : *src - '0');
1482     src++; dst++;
1483     }
1484     else {
1485     *dst++ = *src++;
1486     }
1487     dstlen--;
1488     }
1489     *dst = 0;
1490     return;
1491     }
1492    
1493     /* returns 1 if the option text must be deleted */
1494     static int parse_option(PTInstVar pvar, char FAR * option)
1495     {
1496     if ((option[0] == '-' || option[0] == '/')) {
1497     if (MATCH_STR(option + 1, "ssh") == 0) {
1498     if (option[4] == 0) {
1499     pvar->settings.Enabled = 1;
1500     } else if (MATCH_STR(option + 4, "-L") == 0 ||
1501     MATCH_STR(option + 4, "-R") == 0 ||
1502     _stricmp(option + 4, "-X") == 0) {
1503     if (pvar->settings.DefaultForwarding[0] == 0) {
1504     strncpy_s(pvar->settings.DefaultForwarding,
1505     sizeof(pvar->settings.DefaultForwarding),
1506     option + 5, _TRUNCATE);
1507     } else {
1508     strncat_s(pvar->settings.DefaultForwarding,
1509     sizeof(pvar->settings.DefaultForwarding),
1510     ";", _TRUNCATE);
1511     strncat_s(pvar->settings.DefaultForwarding,
1512     sizeof(pvar->settings.DefaultForwarding),
1513     option + 5, _TRUNCATE);
1514     }
1515     } else if (MATCH_STR(option + 4, "-f=") == 0) {
1516     read_ssh_options_from_user_file(pvar, option + 7);
1517     } else if (MATCH_STR(option + 4, "-v") == 0) {
1518     pvar->settings.LogLevel = LOG_LEVEL_VERBOSE;
1519     } else if (_stricmp(option + 4, "-autologin") == 0 ||
1520     _stricmp(option + 4, "-autologon") == 0) {
1521     pvar->settings.TryDefaultAuth = TRUE;
1522    
1523     } else if (_stricmp(option + 4, "-acceptall") == 0) {
1524     pvar->settings.LocalForwardingIdentityCheck = FALSE;
1525    
1526     // -axx������������������
1527     } else if (MATCH_STR(option + 4, "-a") == 0) {
1528     pvar->settings.ForwardAgent = FALSE;
1529     } else if (MATCH_STR(option + 4, "-A") == 0) {
1530     pvar->settings.ForwardAgent = TRUE;
1531    
1532     } else if (MATCH_STR(option + 4, "-consume=") == 0) {
1533     read_ssh_options_from_user_file(pvar, option + 13);
1534     DeleteFile(option + 13);
1535    
1536     // /ssh1 �� /ssh2 �I�v�V�������V�K���� (2006.9.16 maya)
1537     } else if (MATCH_STR(option + 4, "1") == 0) {
1538     pvar->settings.Enabled = 1;
1539     pvar->settings.ssh_protocol_version = 1;
1540     } else if (MATCH_STR(option + 4, "2") == 0) {
1541     pvar->settings.Enabled = 1;
1542     pvar->settings.ssh_protocol_version = 2;
1543    
1544     } else {
1545     char buf[1024];
1546    
1547     UTIL_get_lang_msg("MSG_UNKNOWN_OPTION_ERROR", pvar,
1548     "Unrecognized command-line option: %s");
1549     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, option);
1550    
1551     MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
1552     }
1553    
1554     // ttermpro.exe �� /T= �w�������p�������A������������ (2006.10.19 maya)
1555     } else if (MATCH_STR_I(option + 1, "t=") == 0) {
1556     if (strcmp(option + 3, "2") == 0) {
1557     pvar->settings.Enabled = 1;
1558 doda 3307 return OPTION_CLEAR; // /t=2��ttssh�������g������������
1559 maya 3227 } else {
1560     pvar->settings.Enabled = 0;
1561 doda 3307 return OPTION_NONE; // Tera Term������������������������
1562 maya 3227 }
1563    
1564     // ttermpro.exe �� /F= �w������ TTSSH ������������ (2006.10.11 maya)
1565     } else if (MATCH_STR_I(option + 1, "f=") == 0) {
1566     read_ssh_options_from_user_file(pvar, option + 3);
1567 doda 3307 return OPTION_NONE; // Tera Term���������������K�v������������������
1568 maya 3227
1569     // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
1570     } else if (MATCH_STR(option + 1, "1") == 0) {
1571     // command line: /ssh /1 is SSH1 only
1572     pvar->settings.ssh_protocol_version = 1;
1573    
1574     } else if (MATCH_STR(option + 1, "2") == 0) {
1575     // command line: /ssh /2 is SSH2 & SSH1
1576     pvar->settings.ssh_protocol_version = 2;
1577    
1578     } else if (MATCH_STR(option + 1, "nossh") == 0) {
1579     // '/nossh' �I�v�V�����������B
1580     // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
1581     // �����������������B(2004.10.11 yutaka)
1582     pvar->settings.Enabled = 0;
1583    
1584     } else if (MATCH_STR(option + 1, "telnet") == 0) {
1585     // '/telnet' ���w�������������������� '/nossh' ��������
1586     // SSH������������ (2006.9.16 maya)
1587     pvar->settings.Enabled = 0;
1588 maya 3533 // Tera Term �� Telnet �t���O���t����
1589     pvar->ts->Telnet = 1;
1590 maya 3227
1591     } else if (MATCH_STR(option + 1, "auth") == 0) {
1592     // SSH2�������O�C���I�v�V����������
1593     //
1594     // SYNOPSIS: /ssh /auth=passowrd /user=���[�U�� /passwd=�p�X���[�h
1595     // /ssh /auth=publickey /user=���[�U�� /passwd=�p�X���[�h /keyfile=�p�X
1596     // EXAMPLE: /ssh /auth=password /user=nike /passwd=a@bc
1597     // /ssh /auth=publickey /user=foo /passwd=bar /keyfile=d:\tmp\id_rsa
1598     // NOTICE: �p�X���[�h���p�X�������������������A�u�����N���������� @ ���g�������B
1599     //
1600     // (2004.11.30 yutaka)
1601     // (2005.1.26 yutaka) ���������B���J���F���T�|�[�g�B
1602     //
1603     pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
1604    
1605     if (MATCH_STR(option + 5, "=password") == 0) { // �p�X���[�h
1606     //pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
1607     pvar->ssh2_authmethod = SSH_AUTH_PASSWORD;
1608    
1609     // /auth=challenge ������ (2007.10.5 maya)
1610     } else if (MATCH_STR(option + 5, "=challenge") == 0) { // keyboard-interactive�F��
1611     //pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
1612     pvar->ssh2_authmethod = SSH_AUTH_TIS;
1613    
1614     } else if (MATCH_STR(option + 5, "=publickey") == 0) { // ���J���F��
1615     //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1616     pvar->ssh2_authmethod = SSH_AUTH_RSA;
1617    
1618     } else if (MATCH_STR(option + 5, "=pageant") == 0) { // ���J���F�� by Pageant
1619     //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1620     pvar->ssh2_authmethod = SSH_AUTH_PAGEANT;
1621    
1622     } else {
1623     // TODO:
1624    
1625     }
1626    
1627     } else if (MATCH_STR(option + 1, "user=") == 0) {
1628 maya 3433 #ifdef USE_ATCMDLINE
1629 maya 3227 replace_to_blank(option + 6, pvar->ssh2_username, sizeof(pvar->ssh2_username));
1630     //_snprintf(pvar->ssh2_username, sizeof(pvar->ssh2_username), "%s", option + 6);
1631    
1632 maya 3433 #else
1633     _snprintf_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), _TRUNCATE, "%s", option + 6);
1634     #endif
1635    
1636 maya 3227 } else if (MATCH_STR(option + 1, "passwd=") == 0) {
1637 maya 3433 #ifdef USE_ATCMDLINE
1638 maya 3227 replace_to_blank(option + 8, pvar->ssh2_password, sizeof(pvar->ssh2_password));
1639     //_snprintf(pvar->ssh2_password, sizeof(pvar->ssh2_password), "%s", option + 8);
1640 maya 3433 #else
1641     _snprintf_s(pvar->ssh2_password, sizeof(pvar->ssh2_password), _TRUNCATE, "%s", option + 8);
1642     #endif
1643 maya 3227
1644     } else if (MATCH_STR(option + 1, "keyfile=") == 0) {
1645 maya 3433 #ifdef USE_ATCMDLINE
1646 maya 3227 replace_to_blank(option + 9, pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile));
1647 maya 3433 #else
1648     _snprintf_s(pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile), _TRUNCATE, "%s", option + 9);
1649     #endif
1650 maya 3227
1651     } else if (MATCH_STR(option + 1, "ask4passwd") == 0) {
1652     // �p�X���[�h������ (2006.9.18 maya)
1653     pvar->ask4passwd = 1;
1654    
1655     }
1656 doda 3307 else { // Other (not ttssh) option
1657     return OPTION_NONE; // ttssh���I�v�V������������������������
1658     }
1659 maya 3227
1660     // �p�X���[�h�������������������O�C��������������
1661     // /auth ���F�����\�b�h���w�������������p������ (2006.9.18 maya)
1662     if (pvar->ask4passwd == 1) {
1663     pvar->ssh2_autologin = 0;
1664     }
1665 doda 3307 return OPTION_CLEAR;
1666 maya 3227
1667     }
1668     else if ((MATCH_STR_I(option, "ssh://") == 0) ||
1669     (MATCH_STR_I(option, "ssh1://") == 0) ||
1670     (MATCH_STR_I(option, "ssh2://") == 0) ||
1671     (MATCH_STR_I(option, "slogin://") == 0) ||
1672     (MATCH_STR_I(option, "slogin1://") == 0) ||
1673     (MATCH_STR_I(option, "slogin2://") == 0)) {
1674     //
1675     // ssh://user@host/ ����URL�`�����T�|�[�g
1676     // ���{�I�������� telnet:// URL��������
1677     //
1678     // �Q�l:
1679     // RFC3986: Uniform Resource Identifier (URI): Generic Syntax
1680     // RFC4248: The telnet URI Scheme
1681     //
1682     char *p, *p2, *p3;
1683     int optlen, hostlen;
1684    
1685     optlen = strlen(option);
1686    
1687     // ������':'���O�����������������������A������ssh�v���g�R���o�[�W������������
1688 doda 3232 p = _mbschr(option, ':');
1689 maya 3227 switch (*(p-1)) {
1690     case '1':
1691     pvar->settings.ssh_protocol_version = 1;
1692     break;
1693     case '2':
1694     pvar->settings.ssh_protocol_version = 2;
1695     break;
1696     }
1697    
1698     // authority part �����|�C���^������
1699     p += 3;
1700    
1701     // path part ������������
1702 doda 3232 if ((p2 = _mbschr(p, '/')) != NULL) {
1703 maya 3227 *p2 = 0;
1704     }
1705    
1706     // '@'�������������A���������O�����[�U����
1707 doda 3232 if ((p2 = _mbschr(p, '@')) != NULL) {
1708 maya 3227 *p2 = 0;
1709     // ':'���~���p�X���[�h
1710 doda 3232 if ((p3 = _mbschr(p, ':')) != NULL) {
1711 maya 3227 *p3 = 0;
1712     percent_decode(pvar->ssh2_password, sizeof(pvar->ssh2_password), p3 + 1);
1713     }
1714     percent_decode(pvar->ssh2_username, sizeof(pvar->ssh2_username), p);
1715     // p �� host part ������('@'����������)����������������
1716     p = p2 + 1;
1717     }
1718    
1719     // host part �� option �����������������Ascheme part ������
1720     // port�w����������������port���������������������m��������������
1721     hostlen = strlen(p);
1722     memmove_s(option, optlen, p, hostlen);
1723     option[hostlen] = 0;
1724    
1725     // �|�[�g�w������������":22"������
1726     #ifndef NO_INET6
1727     if (option[0] == '[' && option[hostlen-1] == ']' || // IPv6 raw address without port
1728 doda 3232 option[0] != '[' && _mbschr(option, ':') == NULL) { // hostname or IPv4 raw address without port
1729 maya 3227 #else
1730 doda 3232 if (_mbschr(option, ':') == NULL) {
1731 maya 3227 #endif /* NO_INET6 */
1732     memcpy_s(option+hostlen, optlen-hostlen, ":22", 3);
1733     hostlen += 3;
1734     }
1735    
1736     // �|�[�g�w�����������������X�y�[�X������
1737     memset(option+hostlen, ' ', optlen-hostlen);
1738    
1739     pvar->settings.Enabled = 1;
1740    
1741     return OPTION_REPLACE;
1742     }
1743 doda 3232 else if (_mbschr(option, '@') != NULL) {
1744 maya 3227 //
1745     // user@host �`�����T�|�[�g
1746     // ����������ssh�������T�|�[�g�����A���[�U����ttssh���������B
1747     // (ssh�������O -- ttssh�������W������������)
1748     // �����I��telnet authentication option���T�|�[�g��������
1749     // Tera Term�{�����������������������\���B
1750     //
1751     char *p;
1752 doda 3232 p = _mbschr(option, '@');
1753 maya 3227 *p = 0;
1754    
1755     strncpy_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), option, _TRUNCATE);
1756    
1757     // ���[�U���������X�y�[�X�������B
1758     // ������TTX��Tera Term�{�������������������X�y�[�X�����������������A
1759     // �z�X�g�����������l�����K�v�������B
1760     memset(option, ' ', p-option+1);
1761    
1762     return OPTION_REPLACE;
1763     }
1764    
1765     return OPTION_NONE;
1766     }
1767    
1768     static void FAR PASCAL TTXParseParam(PCHAR param, PTTSet ts,
1769     PCHAR DDETopic)
1770     {
1771 maya 3433 #ifndef USE_ATCMDLINE
1772 maya 3427 int i;
1773     BOOL inParam = FALSE;
1774     BOOL inQuotes = FALSE;
1775     BOOL inEqual = FALSE;
1776     int param_len=strlen(param);
1777     PCHAR start = NULL;
1778     char *buf = (char *)calloc(param_len+1, sizeof(char));
1779     int buflen = 0;
1780    
1781     if (pvar->hostdlg_activated) {
1782     pvar->settings.Enabled = pvar->hostdlg_Enabled;
1783     }
1784    
1785     for (i = 0; i < param_len; i++) {
1786     if (inQuotes) {
1787     // �������u��"����
1788     if (param[i] == '"') {
1789     if (param[i+1] == '"') {
1790 maya 3433 buf[buflen] = param[i];
1791     buflen++;
1792 maya 3427 i++;
1793     }
1794     else {
1795     // �N�H�[�g���������������������I����
1796     // "��buf�����������������n��
1797     switch (parse_option(pvar, buf)) {
1798     case OPTION_CLEAR:
1799     memset(start, ' ', (param + i) - start + 1);
1800     break;
1801     case OPTION_REPLACE:
1802     memset(start, ' ', (param + i) - start + 1);
1803     buflen = strlen(buf);
1804     memcpy(start, buf, buflen);
1805     break;
1806     }
1807     inParam = FALSE;
1808     inEqual = FALSE;
1809     start = NULL;
1810     memset(buf, 0, param_len);
1811     buflen = 0;
1812     inQuotes = FALSE;
1813     }
1814     }
1815     else {
1816     buf[buflen] = param[i];
1817     buflen++;
1818     }
1819     }
1820     else {
1821     if (!inParam) {
1822     // �����p�����[�^������������
1823     if (param[i] == '"') {
1824     // " ���n����
1825     start = param + i;
1826     inParam = TRUE;
1827     inQuotes = TRUE;
1828     }
1829     else if (param[i] != ' ' && param[i] != '\t') {
1830     // �������n����
1831     buf[buflen] = param[i];
1832     buflen++;
1833     start = param + i;
1834     inParam = TRUE;
1835     }
1836     }
1837     else {
1838     // �������u���p�����[�^����
1839     if (param[i] == ' ' || param[i] == '\t') {
1840     // �N�H�[�g�����������������������I����
1841     switch (parse_option(pvar, buf)) {
1842     case OPTION_CLEAR:
1843     memset(start, ' ', (param + i) - start + 1);
1844     break;
1845     case OPTION_REPLACE:
1846     memset(start, ' ', (param + i) - start + 1);
1847     buflen = strlen(buf);
1848     memcpy(start, buf, buflen);
1849     break;
1850     }
1851     inParam = FALSE;
1852     inEqual = FALSE;
1853     start = NULL;
1854     memset(buf, 0, param_len);
1855     buflen = 0;
1856     }
1857     else {
1858     buf[buflen] = param[i];
1859     buflen++;
1860     if (!inEqual && param[i] == '=') {
1861     inEqual = TRUE;
1862     if (param[i+1] == '"') {
1863     inQuotes = TRUE;
1864     i++;
1865     }
1866     }
1867     }
1868     }
1869     }
1870     }
1871    
1872     // buf ���c�����������������n��
1873 maya 3435 // +1������������'\0'�������������������A��������������������
1874 maya 3427 if (strlen(buf) > 0) {
1875     switch (parse_option(pvar, buf)) {
1876     case OPTION_CLEAR:
1877 maya 3435 memset(start, ' ', (param + i) - start);
1878 maya 3427 break;
1879     case OPTION_REPLACE:
1880 maya 3435 memset(start, ' ', (param + i) - start);
1881 maya 3427 buflen = strlen(buf);
1882     memcpy(start, buf, buflen);
1883     break;
1884     }
1885     }
1886     free(buf);
1887     #else
1888 maya 3227 // �X�y�[�X�������t�@�C�������F�������������C�� (2006.10.7 maya)
1889     int i, buflen;
1890     BOOL inParam = FALSE;
1891     BOOL inQuotes = FALSE;
1892     BOOL inFileParam = FALSE;
1893     PCHAR option = NULL;
1894    
1895     if (pvar->hostdlg_activated) {
1896     pvar->settings.Enabled = pvar->hostdlg_Enabled;
1897     }
1898    
1899     for (i = 0; param[i] != 0; i++) {
1900     if (inQuotes ? param[i] == '"'
1901     : (param[i] == ' ' || param[i] == '\t')) {
1902     if (option != NULL) {
1903     char ch = param[i];
1904     PCHAR Equal;
1905    
1906     param[i] = 0;
1907     Equal = strchr(option, '=');
1908     if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
1909     int buf_len = strlen(option) * sizeof(char);
1910     char *buf = (char *)calloc(strlen(option), sizeof(char));
1911     char c = option[Equal - option + 1];
1912     option[Equal - option + 1] = 0;
1913     strncat_s(buf, buf_len, option, _TRUNCATE);
1914     option[Equal - option + 1] = c;
1915     strncat_s(buf, buf_len, Equal + 2, _TRUNCATE);
1916     switch (parse_option(pvar, *buf == '"' ? buf + 1 : buf)) {
1917     case OPTION_CLEAR:
1918     memset(option, ' ', i + 1 - (option - param));
1919     break;
1920     case OPTION_REPLACE:
1921     buflen = strlen(buf);
1922     memcpy(option, buf, buflen);
1923     memset(option + buflen, ' ', i + 1 - buflen - (option - param));
1924     break;
1925     default:
1926     param[i] = ch;
1927     }
1928     free(buf);
1929     }
1930     else {
1931     switch (parse_option(pvar, *option == '"' ? option + 1 : option)) {
1932     case OPTION_CLEAR:
1933     memset(option, ' ', i + 1 - (option - param));
1934     break;
1935     default:
1936     param[i] = ch;
1937     }
1938     }
1939     option = NULL;
1940     }
1941     inParam = FALSE;
1942     inQuotes = FALSE;
1943     inFileParam = FALSE;
1944     } else if (!inParam) {
1945     if (param[i] == '"') {
1946     inQuotes = TRUE;
1947     inParam = TRUE;
1948     option = param + i;
1949     } else if (param[i] != ' ' && param[i] != '\t') {
1950     inParam = TRUE;
1951     option = param + i;
1952     }
1953     } else {
1954     if (option == NULL) {
1955     continue;
1956     }
1957     if ((option[0] == '-' || option[0] == '/') &&
1958 doda 3288 (MATCH_STR(option + 1, "ssh-f=") == 0 || // ttssh option
1959     MATCH_STR(option + 1, "ssh-consume=") == 0 || // ttssh option
1960     MATCH_STR_I(option + 1, "f=") == 0 || // Tera Term option
1961     MATCH_STR_I(option + 1, "fd=") == 0 || // Tera Term option
1962     MATCH_STR_I(option + 1, "k=") == 0 || // Tera Term option
1963     MATCH_STR_I(option + 1, "l=") == 0 || // Tera Term option
1964     MATCH_STR_I(option + 1, "m=") == 0 || // Tera Term option
1965     MATCH_STR_I(option + 1, "r=") == 0 || // Tera Term option
1966     MATCH_STR_I(option + 1, "w=") == 0 || // Tera Term option
1967     MATCH_STR(option + 1, "keyfile=") == 0)) { // ttssh option
1968 maya 3227 if (param[i] == '"') {
1969     inQuotes = TRUE;
1970     }
1971     inFileParam = TRUE;
1972     }
1973     }
1974     }
1975    
1976     if (option != NULL) {
1977     PCHAR Equal = strchr(option, '=');
1978     if (inFileParam && Equal != NULL && *(Equal + 1) == '"') {
1979     int buf_len = strlen(option) * sizeof(char);
1980     char *buf = (char *)calloc(strlen(option), sizeof(char));
1981     char c = option[Equal - option + 1];
1982     option[Equal - option + 1] = 0;
1983     strncat_s(buf, buf_len, option, _TRUNCATE);
1984     option[Equal - option + 1] = c;
1985     strncat_s(buf, buf_len, Equal + 2, _TRUNCATE);
1986     switch (parse_option(pvar, *buf == '"' ? buf + 1 : buf)) {
1987     case OPTION_CLEAR:
1988     memset(option, ' ', i + 1 - (option - param));
1989     break;
1990     case OPTION_REPLACE:
1991     strcpy_s(option, i - (param - option), buf);
1992     break;
1993     }
1994     free(buf);
1995     }
1996     else {
1997     switch (parse_option(pvar, option)) {
1998     case OPTION_CLEAR:
1999     memset(option, ' ', i - (option - param));
2000     break;
2001     }
2002     }
2003     }
2004 maya 3427 #endif
2005 maya 3227
2006     FWDUI_load_settings(pvar);
2007    
2008     (pvar->ParseParam) (param, ts, DDETopic);
2009    
2010     }
2011    
2012     static void PASCAL FAR TTXGetSetupHooks(TTXSetupHooks FAR * hooks)
2013     {
2014     pvar->ReadIniFile = *hooks->ReadIniFile;
2015     pvar->WriteIniFile = *hooks->WriteIniFile;
2016     pvar->ParseParam = *hooks->ParseParam;
2017    
2018     *hooks->ReadIniFile = TTXReadINIFile;
2019     *hooks->WriteIniFile = TTXWriteINIFile;
2020     *hooks->ParseParam = TTXParseParam;
2021     }
2022    
2023     static void PASCAL FAR TTXSetWinSize(int rows, int cols)
2024     {
2025     SSH_notify_win_size(pvar, cols, rows);
2026     }
2027    
2028     static void insertMenuBeforeItem(HMENU menu, WORD beforeItemID, WORD flags,
2029     WORD newItemID, char FAR * text)
2030     {
2031     int i, j;
2032    
2033     for (i = GetMenuItemCount(menu) - 1; i >= 0; i--) {
2034     HMENU submenu = GetSubMenu(menu, i);
2035    
2036     for (j = GetMenuItemCount(submenu) - 1; j >= 0; j--) {
2037     if (GetMenuItemID(submenu, j) == beforeItemID) {
2038     InsertMenu(submenu, j, MF_BYPOSITION | flags, newItemID, text);
2039     return;
2040     }
2041     }
2042     }
2043     }
2044    
2045     static void PASCAL FAR TTXModifyMenu(HMENU menu)
2046     {
2047     /* inserts before ID_HELP_ABOUT */
2048     UTIL_get_lang_msg("MENU_ABOUT", pvar, "About &TTSSH...");
2049     insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU, pvar->ts->UIMsg);
2050    
2051     /* inserts before ID_SETUP_TCPIP */
2052     UTIL_get_lang_msg("MENU_SSH", pvar, "SS&H...");
2053     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU, pvar->ts->UIMsg);
2054     /* inserts before ID_SETUP_TCPIP */
2055     UTIL_get_lang_msg("MENU_SSH_AUTH", pvar, "SSH &Authentication...");
2056     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU, pvar->ts->UIMsg);
2057     /* inserts before ID_SETUP_TCPIP */
2058     UTIL_get_lang_msg("MENU_SSH_FORWARD", pvar, "SSH F&orwarding...");
2059     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU, pvar->ts->UIMsg);
2060     UTIL_get_lang_msg("MENU_SSH_KEYGEN", pvar, "SSH KeyGe&nerator...");
2061     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHKEYGENMENU, pvar->ts->UIMsg);
2062    
2063     /* inserts before ID_FILE_CHANGEDIR */
2064     UTIL_get_lang_msg("MENU_SSH_SCP", pvar, "SS&H SCP...");
2065     insertMenuBeforeItem(menu, 50170, MF_ENABLED, ID_SSHSCPMENU, pvar->ts->UIMsg);
2066     }
2067    
2068     static void append_about_text(HWND dlg, char FAR * prefix, char FAR * msg)
2069     {
2070     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
2071     (LPARAM) prefix);
2072     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0, (LPARAM) msg);
2073     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, EM_REPLACESEL, 0,
2074     (LPARAM) (char FAR *) "\r\n");
2075     }
2076    
2077     // ���s�t�@�C�������o�[�W�������������� (2005.2.28 yutaka)
2078     void get_file_version(char *exefile, int *major, int *minor, int *release, int *build)
2079     {
2080     typedef struct {
2081     WORD wLanguage;
2082     WORD wCodePage;
2083     } LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
2084     LPLANGANDCODEPAGE lplgcode;
2085     UINT unLen;
2086     DWORD size;
2087     char *buf = NULL;
2088     BOOL ret;
2089     int i;
2090     char fmt[80];
2091     char *pbuf;
2092    
2093     size = GetFileVersionInfoSize(exefile, NULL);
2094     if (size == 0) {
2095     goto error;
2096     }
2097     buf = malloc(size);
2098     ZeroMemory(buf, size);
2099    
2100     if (GetFileVersionInfo(exefile, 0, size, buf) == FALSE) {
2101     goto error;
2102     }
2103    
2104     ret = VerQueryValue(buf,
2105     "\\VarFileInfo\\Translation",
2106     (LPVOID *)&lplgcode, &unLen);
2107     if (ret == FALSE)
2108     goto error;
2109    
2110     for (i = 0 ; i < (int)(unLen / sizeof(LANGANDCODEPAGE)) ; i++) {
2111     _snprintf_s(fmt, sizeof(fmt), _TRUNCATE,
2112     "\\StringFileInfo\\%04x%04x\\FileVersion",
2113     lplgcode[i].wLanguage, lplgcode[i].wCodePage);
2114     VerQueryValue(buf, fmt, &pbuf, &unLen);
2115     if (unLen > 0) { // get success
2116     int n, a, b, c, d;
2117    
2118     n = sscanf(pbuf, "%d, %d, %d, %d", &a, &b, &c, &d);
2119     if (n == 4) { // convert success
2120     *major = a;
2121     *minor = b;
2122     *release = c;
2123     *build = d;
2124     break;
2125     }
2126     }
2127     }
2128    
2129     free(buf);
2130     return;
2131    
2132     error:
2133     free(buf);
2134     *major = *minor = *release = *build = 0;
2135     }
2136    
2137     static void init_about_dlg(PTInstVar pvar, HWND dlg)
2138     {
2139     char buf[1024];
2140     int a, b, c, d;
2141     char uimsg[MAX_UIMSG];
2142    
2143     GetWindowText(dlg, uimsg, sizeof(uimsg));
2144     UTIL_get_lang_msg("DLG_ABOUT_TITLE", pvar, uimsg);
2145     SetWindowText(dlg, pvar->ts->UIMsg);
2146     GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
2147     UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
2148     SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
2149    
2150     // TTSSH���o�[�W�������������� (2005.2.28 yutaka)
2151     get_file_version("ttxssh.dll", &a, &b, &c, &d);
2152     _snprintf_s(buf, sizeof(buf), _TRUNCATE,
2153     "TTSSH\r\nTera Term Secure Shell extension, %d.%d", a, b);
2154     SendMessage(GetDlgItem(dlg, IDC_TTSSH_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2155    
2156     // OpenSSL���o�[�W�������������� (2005.1.24 yutaka)
2157     // ���������� (2005.5.11 yutaka)
2158     #ifdef OPENSSL_VERSION_TEXT
2159     SendMessage(GetDlgItem(dlg, IDC_OPENSSL_VERSION), WM_SETTEXT, 0, (LPARAM)OPENSSL_VERSION_TEXT);
2160     #else
2161     SendMessage(GetDlgItem(dlg, IDC_OPENSSL_VERSION), WM_SETTEXT, 0, (LPARAM)"Unknown");
2162     #endif
2163    
2164     // zlib���o�[�W�������������� (2005.5.11 yutaka)
2165     #ifdef ZLIB_VERSION
2166     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "ZLib %s", ZLIB_VERSION);
2167     #else
2168     _snprintf(buf, sizeof(buf), "ZLib Unknown");
2169     #endif
2170     SendMessage(GetDlgItem(dlg, IDC_ZLIB_VERSION), WM_SETTEXT, 0, (LPARAM)buf);
2171    
2172    
2173     // TTSSH�_�C�A���O���\������SSH������������ (2004.10.30 yutaka)
2174     if (pvar->socket != INVALID_SOCKET) {
2175     if (SSHv1(pvar)) {
2176     SSH_get_server_ID_info(pvar, buf, sizeof(buf));
2177     UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID:");
2178     append_about_text(dlg, pvar->ts->UIMsg, buf);
2179     SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
2180     UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol:");
2181     append_about_text(dlg, pvar->ts->UIMsg, buf);
2182     CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
2183     UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:");
2184     append_about_text(dlg, pvar->ts->UIMsg, buf);
2185     CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
2186     UTIL_get_lang_msg("DLG_ABOUT_SERVERKEY", pvar, "Server keys:");
2187     append_about_text(dlg, pvar->ts->UIMsg, buf);
2188     AUTH_get_auth_info(pvar, buf, sizeof(buf));
2189     UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication:");
2190     append_about_text(dlg, pvar->ts->UIMsg, buf);
2191     SSH_get_compression_info(pvar, buf, sizeof(buf));
2192     UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression:");
2193     append_about_text(dlg, pvar->ts->UIMsg, buf);
2194    
2195     } else { // SSH2
2196     SSH_get_server_ID_info(pvar, buf, sizeof(buf));
2197     UTIL_get_lang_msg("DLG_ABOUT_SERVERID", pvar, "Server ID:");
2198     append_about_text(dlg, pvar->ts->UIMsg, buf);
2199     UTIL_get_lang_msg("DLG_ABOUT_CLIENTID", pvar, "Client ID:");
2200     append_about_text(dlg, pvar->ts->UIMsg, pvar->client_version_string);
2201    
2202     SSH_get_protocol_version_info(pvar, buf, sizeof(buf));
2203     UTIL_get_lang_msg("DLG_ABOUT_PROTOCOL", pvar, "Using protocol:");
2204     append_about_text(dlg, pvar->ts->UIMsg, buf);
2205    
2206     if (pvar->kex_type == KEX_DH_GRP1_SHA1) {
2207     strncpy_s(buf, sizeof(buf), KEX_DH1, _TRUNCATE);
2208     } else if (pvar->kex_type == KEX_DH_GRP14_SHA1) {
2209     strncpy_s(buf, sizeof(buf), KEX_DH14, _TRUNCATE);
2210     } else {
2211     strncpy_s(buf, sizeof(buf), KEX_DHGEX, _TRUNCATE);
2212     }
2213     append_about_text(dlg, "KEX:", buf);
2214    
2215     if (pvar->hostkey_type == KEY_DSA) {
2216     strncpy_s(buf, sizeof(buf), "ssh-dss", _TRUNCATE);
2217     } else {
2218     strncpy_s(buf, sizeof(buf), "ssh-rsa", _TRUNCATE);
2219     }
2220     UTIL_get_lang_msg("DLG_ABOUT_HOSTKEY", pvar, "Host Key:");
2221     append_about_text(dlg, pvar->ts->UIMsg, buf);
2222    
2223     // add HMAC algorithm (2004.12.17 yutaka)
2224     buf[0] = '\0';
2225     if (pvar->ctos_hmac == HMAC_SHA1) {
2226     strncat_s(buf, sizeof(buf), "hmac-sha1", _TRUNCATE);
2227     } else if (pvar->ctos_hmac == HMAC_MD5) {
2228     strncat_s(buf, sizeof(buf), "hmac-md5", _TRUNCATE);
2229     }
2230     UTIL_get_lang_msg("DLG_ABOUT_TOSERVER", pvar, " to server,");
2231     strncat_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2232     if (pvar->stoc_hmac == HMAC_SHA1) {
2233     strncat_s(buf, sizeof(buf), "hmac-sha1", _TRUNCATE);
2234     } else if (pvar->stoc_hmac == HMAC_MD5) {
2235     strncat_s(buf, sizeof(buf), "hmac-md5", _TRUNCATE);
2236     }
2237     UTIL_get_lang_msg("DLG_ABOUT_FROMSERVER", pvar, " from server");
2238     strncat_s(buf, sizeof(buf), pvar->ts->UIMsg, _TRUNCATE);
2239     append_about_text(dlg, "HMAC:", buf);
2240    
2241     CRYPT_get_cipher_info(pvar, buf, sizeof(buf));
2242     UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:");
2243     append_about_text(dlg, pvar->ts->UIMsg, buf);
2244     CRYPT_get_server_key_info(pvar, buf, sizeof(buf));
2245     UTIL_get_lang_msg("DLG_ABOUT_SERVERKEY", pvar, "Server keys:");
2246     append_about_text(dlg, pvar->ts->UIMsg, buf);
2247    
2248     AUTH_get_auth_info(pvar, buf, sizeof(buf));
2249     UTIL_get_lang_msg("DLG_ABOUT_AUTH", pvar, "Authentication:");
2250     append_about_text(dlg, pvar->ts->UIMsg, buf);
2251    
2252     SSH_get_compression_info(pvar, buf, sizeof(buf));
2253     if (pvar->ctos_compression == COMP_DELAYED) { // �x���p�P�b�g���k������ (2006.6.23 yutaka)
2254     UTIL_get_lang_msg("DLG_ABOUT_COMPDELAY", pvar, "Delayed Compression:");
2255     append_about_text(dlg, pvar->ts->UIMsg, buf);
2256     } else {
2257     UTIL_get_lang_msg("DLG_ABOUT_COMP", pvar, "Compression:");
2258     append_about_text(dlg, pvar->ts->UIMsg, buf);
2259     }
2260     }
2261     }
2262     }
2263    
2264     static BOOL CALLBACK TTXAboutDlg(HWND dlg, UINT msg, WPARAM wParam,
2265     LPARAM lParam)
2266     {
2267     LOGFONT logfont;
2268     HFONT font;
2269    
2270     switch (msg) {
2271     case WM_INITDIALOG:
2272     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2273     GetObject(font, sizeof(LOGFONT), &logfont);
2274     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgAboutFont, pvar)) {
2275     SendDlgItemMessage(dlg, IDC_TTSSH_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2276     SendDlgItemMessage(dlg, IDC_SSHVERSIONS, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2277     SendDlgItemMessage(dlg, IDC_INCLUDES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2278     SendDlgItemMessage(dlg, IDC_OPENSSL_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2279     SendDlgItemMessage(dlg, IDC_ZLIB_VERSION, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2280     SendDlgItemMessage(dlg, IDC_WEBSITES, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2281     SendDlgItemMessage(dlg, IDC_CRYPTOGRAPHY, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2282     SendDlgItemMessage(dlg, IDC_CREDIT, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2283     SendDlgItemMessage(dlg, IDC_ABOUTTEXT, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2284     SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgAboutFont, MAKELPARAM(TRUE,0));
2285     }
2286     else {
2287     DlgAboutFont = NULL;
2288     }
2289    
2290     // �A�C�R�������I���Z�b�g
2291     {
2292     int fuLoad = LR_DEFAULTCOLOR;