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 8086 - (hide annotations) (download) (as text)
Sat Sep 7 12:18:28 2019 UTC (4 years, 7 months ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 174874 byte(s)
チケット38959
ユーザ認証ダイアログの表示タイミングをknown_hostsダイアログの後に変更した。

branches/ttssh_improvedからリビジョン8027をマージ:
ProxyやNAT経由でサーバに接続できない場合、すでに切断状態にも関わらず、
認証ダイアログが表示されたままとなる問題を修正した。



........

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