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 9208 - (hide annotations) (download) (as text)
Sat Apr 17 06:15:51 2021 UTC (2 years, 11 months ago) by nmaya
File MIME type: text/x-csrc
File size: 171116 byte(s)
create a branch for chacha20-poly1305

from 4-stable
planned to merge to 4-stable and trunk

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