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