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