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