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 6830 - (hide annotations) (download) (as text)
Tue Jul 4 15:01:24 2017 UTC (6 years, 9 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/ttxssh.c
File MIME type: text/x-csrc
File size: 184963 byte(s)
複数バージョンの同時起動の為、共有メモリの名前を変更
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 doda 6821 // HMAC order
442 yutakapon 4367 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 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Entering secure mode");
850 maya 3227 }
851    
852 doda 6801 void notify_closed_connection(PTInstVar pvar, char *send_msg)
853 maya 3227 {
854 maya 5678 SSH_notify_disconnecting(pvar, send_msg);
855 maya 3227 AUTH_notify_disconnecting(pvar);
856     HOSTS_notify_disconnecting(pvar);
857    
858     PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,
859     pvar->socket, MAKELPARAM(FD_CLOSE, 0));
860     }
861    
862 doda 6801 static void add_err_msg(PTInstVar pvar, char *msg)
863 maya 3227 {
864     if (pvar->err_msg != NULL) {
865     int buf_len = strlen(pvar->err_msg) + 3 + strlen(msg);
866 doda 6801 char *buf = (char *) malloc(buf_len);
867 maya 3227
868     strncpy_s(buf, buf_len, pvar->err_msg, _TRUNCATE);
869     strncat_s(buf, buf_len, "\n\n", _TRUNCATE);
870     strncat_s(buf, buf_len, msg, _TRUNCATE);
871     free(pvar->err_msg);
872     pvar->err_msg = buf;
873     } else {
874     pvar->err_msg = _strdup(msg);
875     }
876     }
877    
878 doda 6801 void notify_nonfatal_error(PTInstVar pvar, char *msg)
879 maya 3227 {
880     if (!pvar->showing_err) {
881     // �������������������m���E�B���h�E�����������A�f�X�N�g�b�v���I�[�i�[������
882     // ���b�Z�[�W�{�b�N�X���o���������B(2006.6.11 yutaka)
883     if (pvar->NotificationWindow == NULL) {
884 doda 6688 UTIL_get_lang_msg("MSG_NONFATAL_ERROR", pvar,
885 maya 3227 "Tera Term: not fatal error");
886     MessageBox(NULL, msg, pvar->ts->UIMsg, MB_OK|MB_ICONINFORMATION);
887     msg[0] = '\0';
888    
889     } else {
890     PostMessage(pvar->NotificationWindow, WM_COMMAND,
891     ID_SSHASYNCMESSAGEBOX, 0);
892     }
893     }
894     if (msg[0] != 0) {
895 doda 6809 logputs(LOG_LEVEL_ERROR, msg);
896 maya 3227 add_err_msg(pvar, msg);
897     }
898     }
899    
900 doda 6801 void notify_fatal_error(PTInstVar pvar, char *msg, BOOL send_disconnect)
901 maya 3227 {
902     if (msg[0] != 0) {
903 doda 6809 logputs(LOG_LEVEL_FATAL, msg);
904 maya 3227 add_err_msg(pvar, msg);
905     }
906    
907     if (!pvar->fatal_error) {
908     pvar->fatal_error = TRUE;
909    
910 maya 5678 if (send_disconnect) {
911     SSH_notify_disconnecting(pvar, msg);
912     }
913 maya 3227 AUTH_notify_disconnecting(pvar);
914     HOSTS_notify_disconnecting(pvar);
915    
916     PostMessage(pvar->NotificationWindow, WM_USER_COMMNOTIFY,
917     pvar->socket, MAKELPARAM(FD_CLOSE,
918     (pvar->PWSAGetLastError) ()));
919     }
920     }
921    
922 doda 6809 void logputs(int level, char *msg)
923 maya 3227 {
924 doda 6823 if (level <= pvar->settings.LogLevel) {
925 maya 3227 char buf[1024];
926     int file;
927    
928     get_teraterm_dir_relative_name(buf, NUM_ELEM(buf), "TTSSH.LOG");
929     file = _open(buf, _O_RDWR | _O_APPEND | _O_CREAT | _O_TEXT,
930     _S_IREAD | _S_IWRITE);
931    
932     if (file >= 0) {
933 doda 6778 char *strtime = mctimelocal("%Y-%m-%d %H:%M:%S.%NZ", TRUE);
934 maya 4546 DWORD processid;
935 maya 3227 char tmp[26];
936 maya 4546
937     _write(file, strtime, strlen(strtime));
938 maya 3227 GetWindowThreadProcessId(pvar->cv->HWin, &processid);
939     _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, " [%lu] ",processid);
940     _write(file, tmp, strlen(tmp));
941     _write(file, msg, strlen(msg));
942     _write(file, "\n", 1);
943     _close(file);
944     }
945     }
946     }
947    
948 doda 6808 void logprintf(int level, char *fmt, ...)
949 doda 6051 {
950     char buff[4096];
951     va_list params;
952    
953 doda 6823 if (level <= pvar->settings.LogLevel) {
954 doda 6051 va_start(params, fmt);
955     vsnprintf_s(buff, sizeof(buff), _TRUNCATE, fmt, params);
956     va_end(params);
957    
958 doda 6809 logputs(level, buff);
959 doda 6051 }
960     }
961    
962 yutakapon 6302 static void format_line_hexdump(char *buf, int buflen, int addr, int *bytes, int byte_cnt)
963     {
964     int i, c;
965     char tmp[128];
966    
967     buf[0] = 0;
968    
969     /* �������A�h���X�\�� */
970     _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, "%08X : ", addr);
971     strncat_s(buf, buflen, tmp, _TRUNCATE);
972    
973     /* �o�C�i���\���i4�o�C�g�������������}���j*/
974     for (i = 0; i < byte_cnt; i++) {
975     if (i > 0 && i % 4 == 0) {
976     strncat_s(buf, buflen, " ", _TRUNCATE);
977     }
978    
979     _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, "%02X", bytes[i]);
980     strncat_s(buf, buflen, tmp, _TRUNCATE);
981     }
982    
983     /* ASCII�\���������������������� */
984     _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, " %*s%*s", (16 - byte_cnt) * 2 + 1, " ", (16 - byte_cnt + 3) / 4, " ");
985     strncat_s(buf, buflen, tmp, _TRUNCATE);
986    
987     /* ASCII�\�� */
988     for (i = 0; i < byte_cnt; i++) {
989     c = bytes[i];
990     if (isprint(c)) {
991     _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, "%c", c);
992     strncat_s(buf, buflen, tmp, _TRUNCATE);
993     }
994     else {
995     strncat_s(buf, buflen, ".", _TRUNCATE);
996     }
997     }
998    
999     //strncat_s(buf, buflen, "\n", _TRUNCATE);
1000     }
1001    
1002 doda 6808 void logprintf_hexdump(int level, char *data, int len, char *fmt, ...)
1003 yutakapon 6302 {
1004     char buff[4096];
1005     va_list params;
1006     int c, addr;
1007     int bytes[16], *ptr;
1008     int byte_cnt;
1009     int i;
1010    
1011 doda 6823 if (level <= pvar->settings.LogLevel) {
1012 yutakapon 6302 va_start(params, fmt);
1013     vsnprintf_s(buff, sizeof(buff), _TRUNCATE, fmt, params);
1014     va_end(params);
1015    
1016 doda 6809 logputs(level, buff);
1017 yutakapon 6302
1018     addr = 0;
1019     byte_cnt = 0;
1020     ptr = bytes;
1021     for (i = 0; i < len; i++) {
1022     c = data[i];
1023     *ptr++ = c & 0xff;
1024     byte_cnt++;
1025    
1026     if (byte_cnt == 16) {
1027     format_line_hexdump(buff, sizeof(buff), addr, bytes, byte_cnt);
1028 doda 6809 logputs(level, buff);
1029 yutakapon 6302
1030     addr += 16;
1031     byte_cnt = 0;
1032     ptr = bytes;
1033     }
1034     }
1035    
1036     if (byte_cnt > 0) {
1037     format_line_hexdump(buff, sizeof(buff), addr, bytes, byte_cnt);
1038 doda 6809 logputs(level, buff);
1039 yutakapon 6302 }
1040     }
1041     }
1042    
1043 doda 6801 static void PASCAL TTXOpenTCP(TTXSockHooks *hooks)
1044 maya 3227 {
1045     if (pvar->settings.Enabled) {
1046     // TCPLocalEcho/TCPCRSend ������������ (maya 2007.4.25)
1047 doda 3579 pvar->origDisableTCPEchoCR = pvar->ts->DisableTCPEchoCR;
1048 maya 3227 pvar->ts->DisableTCPEchoCR = TRUE;
1049    
1050     pvar->session_settings = pvar->settings;
1051    
1052 doda 6809 logputs(LOG_LEVEL_VERBOSE, "---------------------------------------------------------------------");
1053     logputs(LOG_LEVEL_VERBOSE, "Initiating SSH session");
1054 maya 3227
1055     FWDUI_load_settings(pvar);
1056    
1057     pvar->cv->TelAutoDetect = FALSE;
1058     /* This next line should not be needed because Tera Term's
1059     CommLib should find ts->Telnet == 0 ... but we'll do this
1060     just to be on the safe side. */
1061     pvar->cv->TelFlag = FALSE;
1062 doda 3495 pvar->cv->TelLineMode = FALSE;
1063 maya 3227
1064     pvar->Precv = *hooks->Precv;
1065     pvar->Psend = *hooks->Psend;
1066     pvar->PWSAAsyncSelect = *hooks->PWSAAsyncSelect;
1067     pvar->Pconnect = *hooks->Pconnect;
1068     pvar->PWSAGetLastError = *hooks->PWSAGetLastError;
1069    
1070     *hooks->Precv = TTXrecv;
1071     *hooks->Psend = TTXsend;
1072     *hooks->PWSAAsyncSelect = TTXWSAAsyncSelect;
1073     *hooks->Pconnect = TTXconnect;
1074    
1075     SSH_open(pvar);
1076     HOSTS_open(pvar);
1077     FWDUI_open(pvar);
1078    
1079     // ������ myproposal �����f���������A�������O�����������B (2006.6.26 maya)
1080     SSH2_update_cipher_myproposal(pvar);
1081 yutakapon 4367 SSH2_update_kex_myproposal(pvar);
1082     SSH2_update_host_key_myproposal(pvar);
1083     SSH2_update_hmac_myproposal(pvar);
1084 maya 3227 SSH2_update_compression_myproposal(pvar);
1085     }
1086     }
1087    
1088 doda 6801 static void PASCAL TTXCloseTCP(TTXSockHooks *hooks)
1089 maya 3227 {
1090     if (pvar->session_settings.Enabled) {
1091     pvar->socket = INVALID_SOCKET;
1092    
1093 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Terminating SSH session...");
1094 maya 3227
1095     *hooks->Precv = pvar->Precv;
1096     *hooks->Psend = pvar->Psend;
1097     *hooks->PWSAAsyncSelect = pvar->PWSAAsyncSelect;
1098     *hooks->Pconnect = pvar->Pconnect;
1099 doda 3579
1100     pvar->ts->DisableTCPEchoCR = pvar->origDisableTCPEchoCR;
1101 maya 3227 }
1102    
1103     uninit_TTSSH(pvar);
1104     init_TTSSH(pvar);
1105     }
1106    
1107     static void enable_dlg_items(HWND dlg, int from, int to, BOOL enabled)
1108     {
1109     for (; from <= to; from++) {
1110     EnableWindow(GetDlgItem(dlg, from), enabled);
1111     }
1112     }
1113    
1114     // C-p/C-n/C-b/C-f/C-a/C-e ���T�|�[�g (2007.9.5 maya)
1115     // C-d/C-k ���T�|�[�g (2007.10.3 yutaka)
1116     // �h���b�v�_�E���������G�f�B�b�g�R���g���[����
1117     // �T�u�N���X�������������E�C���h�E�v���V�[�W��
1118     WNDPROC OrigHostnameEditProc; // Original window procedure
1119     LRESULT CALLBACK HostnameEditProc(HWND dlg, UINT msg,
1120 maya 5868 WPARAM wParam, LPARAM lParam)
1121 maya 3227 {
1122     HWND parent;
1123     int max, select, len;
1124     char *str, *orgstr;
1125    
1126     switch (msg) {
1127     // �L�[�����������������m����
1128     case WM_KEYDOWN:
1129     if (GetKeyState(VK_CONTROL) < 0) {
1130     switch (wParam) {
1131     case 0x50: // Ctrl+p ... up
1132     parent = GetParent(dlg);
1133     select = SendMessage(parent, CB_GETCURSEL, 0, 0);
1134     if (select > 0) {
1135     PostMessage(parent, CB_SETCURSEL, select - 1, 0);
1136     }
1137     return 0;
1138     case 0x4e: // Ctrl+n ... down
1139     parent = GetParent(dlg);
1140     max = SendMessage(parent, CB_GETCOUNT, 0, 0);
1141     select = SendMessage(parent, CB_GETCURSEL, 0, 0);
1142     if (select < max - 1) {
1143     PostMessage(parent, CB_SETCURSEL, select + 1, 0);
1144     }
1145     return 0;
1146     case 0x42: // Ctrl+b ... left
1147     SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1148     PostMessage(dlg, EM_SETSEL, select-1, select-1);
1149     return 0;
1150     case 0x46: // Ctrl+f ... right
1151     SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1152     max = GetWindowTextLength(dlg) ;
1153     PostMessage(dlg, EM_SETSEL, select+1, select+1);
1154     return 0;
1155     case 0x41: // Ctrl+a ... home
1156     PostMessage(dlg, EM_SETSEL, 0, 0);
1157     return 0;
1158     case 0x45: // Ctrl+e ... end
1159     max = GetWindowTextLength(dlg) ;
1160     PostMessage(dlg, EM_SETSEL, max, max);
1161     return 0;
1162    
1163     case 0x44: // Ctrl+d
1164     case 0x4b: // Ctrl+k
1165     case 0x55: // Ctrl+u
1166     SendMessage(dlg, EM_GETSEL, 0, (LPARAM)&select);
1167     max = GetWindowTextLength(dlg);
1168     max++; // '\0'
1169     orgstr = str = malloc(max);
1170     if (str != NULL) {
1171     len = GetWindowText(dlg, str, max);
1172     if (select >= 0 && select < len) {
1173     if (wParam == 0x44) { // �J�[�\���z����������������������
1174     memmove(&str[select], &str[select + 1], len - select - 1);
1175     str[len - 1] = '\0';
1176    
1177     } else if (wParam == 0x4b) { // �J�[�\�������s��������������
1178     str[select] = '\0';
1179    
1180     }
1181     }
1182    
1183     if (wParam == 0x55) { // �J�[�\����������������������
1184     if (select >= len) {
1185     str[0] = '\0';
1186     } else {
1187     str = &str[select];
1188     }
1189     select = 0;
1190     }
1191    
1192     SetWindowText(dlg, str);
1193     SendMessage(dlg, EM_SETSEL, select, select);
1194     free(orgstr);
1195     return 0;
1196     }
1197     break;
1198     }
1199     }
1200     break;
1201    
1202     // �����L�[��������������������������������������������
1203     case WM_CHAR:
1204     switch (wParam) {
1205     case 0x01:
1206     case 0x02:
1207     case 0x04:
1208     case 0x05:
1209     case 0x06:
1210     case 0x0b:
1211     case 0x0e:
1212     case 0x10:
1213     case 0x15:
1214     return 0;
1215     }
1216     }
1217    
1218     return CallWindowProc(OrigHostnameEditProc, dlg, msg, wParam, lParam);
1219     }
1220    
1221     static BOOL CALLBACK TTXHostDlg(HWND dlg, UINT msg, WPARAM wParam,
1222     LPARAM lParam)
1223     {
1224     static char *ssh_version[] = {"SSH1", "SSH2", NULL};
1225     PGetHNRec GetHNRec;
1226     char EntName[128];
1227     char TempHost[HostNameMaxLength + 1];
1228     WORD i, j, w;
1229     WORD ComPortTable[MAXCOMPORT];
1230     static char *ComPortDesc[MAXCOMPORT];
1231     int comports;
1232     BOOL Ok;
1233     LOGFONT logfont;
1234     HFONT font;
1235     char uimsg[MAX_UIMSG];
1236     static HWND hwndHostname = NULL; // HOSTNAME dropdown
1237     static HWND hwndHostnameEdit = NULL; // Edit control on HOSTNAME dropdown
1238    
1239     switch (msg) {
1240     case WM_INITDIALOG:
1241     GetHNRec = (PGetHNRec) lParam;
1242     SetWindowLong(dlg, DWL_USER, lParam);
1243    
1244     GetWindowText(dlg, uimsg, sizeof(uimsg));
1245     UTIL_get_lang_msg("DLG_HOST_TITLE", pvar, uimsg);
1246     SetWindowText(dlg, pvar->ts->UIMsg);
1247     GetDlgItemText(dlg, IDC_HOSTNAMELABEL, uimsg, sizeof(uimsg));
1248     UTIL_get_lang_msg("DLG_HOST_TCPIPHOST", pvar, uimsg);
1249     SetDlgItemText(dlg, IDC_HOSTNAMELABEL, pvar->ts->UIMsg);
1250     GetDlgItemText(dlg, IDC_HISTORY, uimsg, sizeof(uimsg));
1251     UTIL_get_lang_msg("DLG_HOST_TCPIPHISTORY", pvar, uimsg);
1252     SetDlgItemText(dlg, IDC_HISTORY, pvar->ts->UIMsg);
1253     GetDlgItemText(dlg, IDC_SERVICELABEL, uimsg, sizeof(uimsg));
1254     UTIL_get_lang_msg("DLG_HOST_TCPIPSERVICE", pvar, uimsg);
1255     SetDlgItemText(dlg, IDC_SERVICELABEL, pvar->ts->UIMsg);
1256     GetDlgItemText(dlg, IDC_HOSTOTHER, uimsg, sizeof(uimsg));
1257     UTIL_get_lang_msg("DLG_HOST_TCPIPOTHER", pvar, uimsg);
1258     SetDlgItemText(dlg, IDC_HOSTOTHER, pvar->ts->UIMsg);
1259     GetDlgItemText(dlg, IDC_HOSTTCPPORTLABEL, uimsg, sizeof(uimsg));
1260     UTIL_get_lang_msg("DLG_HOST_TCPIPPORT", pvar, uimsg);
1261     SetDlgItemText(dlg, IDC_HOSTTCPPORTLABEL, pvar->ts->UIMsg);
1262     GetDlgItemText(dlg, IDC_SSH_VERSION_LABEL, uimsg, sizeof(uimsg));
1263     UTIL_get_lang_msg("DLG_HOST_TCPIPSSHVERSION", pvar, uimsg);
1264     SetDlgItemText(dlg, IDC_SSH_VERSION_LABEL, pvar->ts->UIMsg);
1265     GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOLLABEL, uimsg, sizeof(uimsg));
1266     UTIL_get_lang_msg("DLG_HOST_TCPIPPROTOCOL", pvar, uimsg);
1267     SetDlgItemText(dlg, IDC_HOSTTCPPROTOCOLLABEL, pvar->ts->UIMsg);
1268     GetDlgItemText(dlg, IDC_HOSTSERIAL, uimsg, sizeof(uimsg));
1269     UTIL_get_lang_msg("DLG_HOST_SERIAL", pvar, uimsg);
1270     SetDlgItemText(dlg, IDC_HOSTSERIAL, pvar->ts->UIMsg);
1271     GetDlgItemText(dlg, IDC_HOSTCOMLABEL, uimsg, sizeof(uimsg));
1272     UTIL_get_lang_msg("DLG_HOST_SERIALPORT", pvar, uimsg);
1273     SetDlgItemText(dlg, IDC_HOSTCOMLABEL, pvar->ts->UIMsg);
1274     GetDlgItemText(dlg, IDC_HOSTHELP, uimsg, sizeof(uimsg));
1275     UTIL_get_lang_msg("DLG_HOST_HELP", pvar, uimsg);
1276     SetDlgItemText(dlg, IDC_HOSTHELP, pvar->ts->UIMsg);
1277     GetDlgItemText(dlg, IDOK, uimsg, sizeof(uimsg));
1278     UTIL_get_lang_msg("BTN_OK", pvar, uimsg);
1279     SetDlgItemText(dlg, IDOK, pvar->ts->UIMsg);
1280     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1281     UTIL_get_lang_msg("BTN_CANCEL", pvar, uimsg);
1282     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1283    
1284     // �z�X�g�q�X�g�����`�F�b�N�{�b�N�X������ (2005.10.21 yutaka)
1285     if (pvar->ts->HistoryList > 0) {
1286     SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_SETCHECK, BST_CHECKED, 0);
1287     } else {
1288     SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_SETCHECK, BST_UNCHECKED, 0);
1289     }
1290    
1291 yutakapon 4860 // �t�@�C�����������O�t���p�C�v�������ATCP/IP�����������B
1292     if (GetHNRec->PortType == IdFile ||
1293     GetHNRec->PortType == IdNamedPipe
1294     )
1295 maya 3227 GetHNRec->PortType = IdTCPIP;
1296    
1297     strncpy_s(EntName, sizeof(EntName), "Host", _TRUNCATE);
1298    
1299     i = 1;
1300     do {
1301     _snprintf_s(&EntName[4], sizeof(EntName)-4, _TRUNCATE, "%d", i);
1302     GetPrivateProfileString("Hosts", EntName, "",
1303     TempHost, sizeof(TempHost),
1304     GetHNRec->SetupFN);
1305     if (strlen(TempHost) > 0)
1306     SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_ADDSTRING,
1307     0, (LPARAM) TempHost);
1308     i++;
1309 maya 4963 } while (i <= MAXHOSTLIST);
1310 maya 3227
1311     SendDlgItemMessage(dlg, IDC_HOSTNAME, EM_LIMITTEXT,
1312     HostNameMaxLength - 1, 0);
1313    
1314     SendDlgItemMessage(dlg, IDC_HOSTNAME, CB_SETCURSEL, 0, 0);
1315    
1316     // C-n/C-p ���������T�u�N���X�� (2007.9.4 maya)
1317     hwndHostname = GetDlgItem(dlg, IDC_HOSTNAME);
1318     hwndHostnameEdit = GetWindow(hwndHostname, GW_CHILD);
1319     OrigHostnameEditProc = (WNDPROC)GetWindowLong(hwndHostnameEdit, GWL_WNDPROC);
1320     SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)HostnameEditProc);
1321    
1322     CheckRadioButton(dlg, IDC_HOSTTELNET, IDC_HOSTOTHER,
1323     pvar->settings.Enabled ? IDC_HOSTSSH : GetHNRec->
1324     Telnet ? IDC_HOSTTELNET : IDC_HOSTOTHER);
1325     SendDlgItemMessage(dlg, IDC_HOSTTCPPORT, EM_LIMITTEXT, 5, 0);
1326     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TCPPort, FALSE);
1327     for (i = 0; ProtocolFamilyList[i]; ++i) {
1328     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_ADDSTRING,
1329     0, (LPARAM) ProtocolFamilyList[i]);
1330     }
1331     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, EM_LIMITTEXT,
1332     ProtocolFamilyMaxLength - 1, 0);
1333     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, CB_SETCURSEL, 0, 0);
1334    
1335     /////// SSH version
1336     for (i = 0; ssh_version[i]; ++i) {
1337     SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_ADDSTRING,
1338     0, (LPARAM) ssh_version[i]);
1339     }
1340     SendDlgItemMessage(dlg, IDC_SSH_VERSION, EM_LIMITTEXT,
1341     NUM_ELEM(ssh_version) - 1, 0);
1342    
1343     if (pvar->settings.ssh_protocol_version == 1) {
1344     SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 0, 0); // SSH1
1345     } else {
1346     SendDlgItemMessage(dlg, IDC_SSH_VERSION, CB_SETCURSEL, 1, 0); // SSH2
1347     }
1348    
1349     if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1350     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE); // enabled
1351     } else {
1352     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1353     }
1354     /////// SSH version
1355    
1356    
1357     j = 0;
1358     w = 1;
1359     if ((comports=DetectComPorts(ComPortTable, GetHNRec->MaxComPort, ComPortDesc)) >= 0) {
1360     for (i=0; i<comports; i++) {
1361     // MaxComPort ���z�����|�[�g���\��������
1362     if (ComPortTable[i] > GetHNRec->MaxComPort) {
1363     continue;
1364     }
1365    
1366     // �g�p�����|�[�g���\��������
1367     if (CheckCOMFlag(ComPortTable[i]) == 1) {
1368     continue;
1369     }
1370    
1371     _snprintf_s(EntName, sizeof(EntName), _TRUNCATE, "COM%d", ComPortTable[i]);
1372     if (ComPortDesc[i] != NULL) {
1373     strncat_s(EntName, sizeof(EntName), ": ", _TRUNCATE);
1374     strncat_s(EntName, sizeof(EntName), ComPortDesc[i], _TRUNCATE);
1375     }
1376     SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_ADDSTRING,
1377     0, (LPARAM)EntName);
1378     j++;
1379     if (GetHNRec->ComPort == ComPortTable[i])
1380     w = j;
1381     }
1382    
1383     } else {
1384     for (i = 1; i <= GetHNRec->MaxComPort; i++) {
1385     // �g�p�����|�[�g���\��������
1386     if (CheckCOMFlag(i) == 1) {
1387     continue;
1388     }
1389    
1390     _snprintf_s(EntName, sizeof(EntName), _TRUNCATE, "COM%d", i);
1391     SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_ADDSTRING,
1392     0, (LPARAM) EntName);
1393     j++;
1394     if (GetHNRec->ComPort == i)
1395     w = j;
1396     }
1397     }
1398    
1399     if (j > 0)
1400     SendDlgItemMessage(dlg, IDC_HOSTCOM, CB_SETCURSEL, w - 1, 0);
1401     else { /* All com ports are already used */
1402     GetHNRec->PortType = IdTCPIP;
1403     enable_dlg_items(dlg, IDC_HOSTSERIAL, IDC_HOSTSERIAL, FALSE);
1404     }
1405    
1406     CheckRadioButton(dlg, IDC_HOSTTCPIP, IDC_HOSTSERIAL,
1407     IDC_HOSTTCPIP + GetHNRec->PortType - 1);
1408    
1409     if (GetHNRec->PortType == IdTCPIP) {
1410     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
1411    
1412     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE);
1413     enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE);
1414    
1415     enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, TRUE); // enabled
1416     }
1417     else {
1418     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1419     FALSE);
1420     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1421     IDC_HOSTTCPPROTOCOL, FALSE);
1422    
1423     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1424     enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1425    
1426     enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, FALSE); // disabled
1427     }
1428    
1429     // Host dialog���t�H�[�J�X�������� (2004.10.2 yutaka)
1430     if (GetHNRec->PortType == IdTCPIP) {
1431     HWND hwnd = GetDlgItem(dlg, IDC_HOSTNAME);
1432     SetFocus(hwnd);
1433     } else {
1434     HWND hwnd = GetDlgItem(dlg, IDC_HOSTCOM);
1435     SetFocus(hwnd);
1436     }
1437    
1438     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1439     GetObject(font, sizeof(LOGFONT), &logfont);
1440     if (UTIL_get_lang_font("DLG_SYSTEM_FONT", dlg, &logfont, &DlgHostFont, pvar)) {
1441     SendDlgItemMessage(dlg, IDC_HOSTTCPIP, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1442     SendDlgItemMessage(dlg, IDC_HOSTNAMELABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1443     SendDlgItemMessage(dlg, IDC_HOSTNAME, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1444     SendDlgItemMessage(dlg, IDC_HISTORY, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1445     SendDlgItemMessage(dlg, IDC_SERVICELABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1446     SendDlgItemMessage(dlg, IDC_HOSTTELNET, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1447     SendDlgItemMessage(dlg, IDC_HOSTSSH, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1448     SendDlgItemMessage(dlg, IDC_HOSTOTHER, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1449     SendDlgItemMessage(dlg, IDC_HOSTTCPPORTLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1450     SendDlgItemMessage(dlg, IDC_HOSTTCPPORT, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1451     SendDlgItemMessage(dlg, IDC_SSH_VERSION_LABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1452     SendDlgItemMessage(dlg, IDC_SSH_VERSION, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1453     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOLLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1454     SendDlgItemMessage(dlg, IDC_HOSTTCPPROTOCOL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1455     SendDlgItemMessage(dlg, IDC_HOSTSERIAL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1456     SendDlgItemMessage(dlg, IDC_HOSTCOMLABEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1457     SendDlgItemMessage(dlg, IDC_HOSTCOM, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1458     SendDlgItemMessage(dlg, IDOK, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1459     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1460     SendDlgItemMessage(dlg, IDC_HOSTHELP, WM_SETFONT, (WPARAM)DlgHostFont, MAKELPARAM(TRUE,0));
1461     }
1462     else {
1463     DlgHostFont = NULL;
1464     }
1465    
1466     // SetFocus()���t�H�[�J�X���������������AFALSE�������K�v�������B
1467     // TRUE���������ATABSTOP�������������������R���g���[�����I�������B
1468     // (2004.11.23 yutaka)
1469     return FALSE;
1470     //return TRUE;
1471    
1472     case WM_COMMAND:
1473     switch (LOWORD(wParam)) {
1474     case IDOK:
1475     GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1476     if (GetHNRec != NULL) {
1477     if (IsDlgButtonChecked(dlg, IDC_HOSTTCPIP)) {
1478     char afstr[BUFSIZ];
1479     i = GetDlgItemInt(dlg, IDC_HOSTTCPPORT, &Ok, FALSE);
1480     if (Ok) {
1481     GetHNRec->TCPPort = i;
1482     } else {
1483     UTIL_get_lang_msg("MSG_TCPPORT_NAN_ERROR", pvar,
1484     "The TCP port must be a number.");
1485     MessageBox(dlg, pvar->ts->UIMsg,
1486     "Tera Term", MB_OK | MB_ICONEXCLAMATION);
1487     return TRUE;
1488     }
1489     #define getaf(str) \
1490     ((strcmp((str), "IPv6") == 0) ? AF_INET6 : \
1491     ((strcmp((str), "IPv4") == 0) ? AF_INET : AF_UNSPEC))
1492     memset(afstr, 0, sizeof(afstr));
1493     GetDlgItemText(dlg, IDC_HOSTTCPPROTOCOL, afstr,
1494     sizeof(afstr));
1495     GetHNRec->ProtocolFamily = getaf(afstr);
1496     GetHNRec->PortType = IdTCPIP;
1497     GetDlgItemText(dlg, IDC_HOSTNAME, GetHNRec->HostName,
1498     HostNameMaxLength);
1499     pvar->hostdlg_activated = TRUE;
1500     pvar->hostdlg_Enabled = FALSE;
1501     if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1502     GetHNRec->Telnet = TRUE;
1503     } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1504     pvar->hostdlg_Enabled = TRUE;
1505    
1506     // check SSH protocol version
1507     memset(afstr, 0, sizeof(afstr));
1508     GetDlgItemText(dlg, IDC_SSH_VERSION, afstr, sizeof(afstr));
1509     if (_stricmp(afstr, "SSH1") == 0) {
1510     pvar->settings.ssh_protocol_version = 1;
1511     } else {
1512     pvar->settings.ssh_protocol_version = 2;
1513     }
1514     }
1515 doda 3541 else { // IDC_HOSTOTHER
1516     GetHNRec->Telnet = FALSE;
1517     }
1518 maya 3227
1519     // host history check button
1520     if (SendMessage(GetDlgItem(dlg, IDC_HISTORY), BM_GETCHECK, 0, 0) == BST_CHECKED) {
1521     pvar->ts->HistoryList = 1;
1522     } else {
1523     pvar->ts->HistoryList = 0;
1524     }
1525    
1526     } else {
1527     GetHNRec->PortType = IdSerial;
1528     GetHNRec->HostName[0] = 0;
1529     memset(EntName, 0, sizeof(EntName));
1530     GetDlgItemText(dlg, IDC_HOSTCOM, EntName,
1531     sizeof(EntName) - 1);
1532     if (strncmp(EntName, "COM", 3) == 0 && EntName[3] != '\0') {
1533     GetHNRec->ComPort = atoi(&EntName[3]);
1534     if (GetHNRec->ComPort > GetHNRec->MaxComPort)
1535     GetHNRec->ComPort = 1;
1536     } else {
1537     GetHNRec->ComPort = 1;
1538     }
1539     }
1540     }
1541     SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)OrigHostnameEditProc);
1542     EndDialog(dlg, 1);
1543    
1544     if (DlgHostFont != NULL) {
1545     DeleteObject(DlgHostFont);
1546     }
1547    
1548     return TRUE;
1549    
1550     case IDCANCEL:
1551     SetWindowLong(hwndHostnameEdit, GWL_WNDPROC, (LONG)OrigHostnameEditProc);
1552     EndDialog(dlg, 0);
1553    
1554     if (DlgHostFont != NULL) {
1555     DeleteObject(DlgHostFont);
1556     }
1557    
1558     return TRUE;
1559    
1560     case IDC_HOSTTCPIP:
1561     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1562     TRUE);
1563     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1564     IDC_HOSTTCPPROTOCOL, TRUE);
1565     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, FALSE);
1566    
1567     enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, TRUE); // disabled (2004.11.23 yutaka)
1568     if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1569     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, TRUE);
1570     } else {
1571     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1572     }
1573    
1574     enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, TRUE); // disabled
1575    
1576     return TRUE;
1577    
1578     case IDC_HOSTSERIAL:
1579     enable_dlg_items(dlg, IDC_HOSTCOMLABEL, IDC_HOSTCOM, TRUE);
1580     enable_dlg_items(dlg, IDC_HOSTNAMELABEL, IDC_HOSTTCPPORT,
1581     FALSE);
1582     enable_dlg_items(dlg, IDC_HOSTTCPPROTOCOLLABEL,
1583     IDC_HOSTTCPPROTOCOL, FALSE);
1584     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1585     enable_dlg_items(dlg, IDC_SSH_VERSION_LABEL, IDC_SSH_VERSION_LABEL, FALSE); // disabled (2004.11.23 yutaka)
1586    
1587     enable_dlg_items(dlg, IDC_HISTORY, IDC_HISTORY, FALSE); // disabled
1588    
1589     return TRUE;
1590    
1591     case IDC_HOSTSSH:
1592     enable_dlg_items(dlg, IDC_SSH_VERSION,
1593     IDC_SSH_VERSION, TRUE);
1594     goto hostssh_enabled;
1595    
1596     case IDC_HOSTTELNET:
1597     case IDC_HOSTOTHER:
1598     enable_dlg_items(dlg, IDC_SSH_VERSION, IDC_SSH_VERSION, FALSE); // disabled
1599     hostssh_enabled:
1600    
1601     GetHNRec = (PGetHNRec) GetWindowLong(dlg, DWL_USER);
1602    
1603     if (IsDlgButtonChecked(dlg, IDC_HOSTTELNET)) {
1604     if (GetHNRec != NULL)
1605     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, GetHNRec->TelPort,
1606     FALSE);
1607     } else if (IsDlgButtonChecked(dlg, IDC_HOSTSSH)) {
1608     SetDlgItemInt(dlg, IDC_HOSTTCPPORT, 22, FALSE);
1609     }
1610     return TRUE;
1611    
1612     case IDC_HOSTCOM:
1613     if(HIWORD(wParam) == CBN_DROPDOWN) {
1614     HWND hostcom = GetDlgItem(dlg, IDC_HOSTCOM);
1615     int count = SendMessage(hostcom, CB_GETCOUNT, 0, 0);
1616     int i, len, max_len = 0;
1617     char *lbl;
1618     HDC TmpDC = GetDC(hostcom);
1619     SIZE s;
1620     for (i=0; i<count; i++) {
1621     len = SendMessage(hostcom, CB_GETLBTEXTLEN, i, 0);
1622     lbl = (char *)calloc(len+1, sizeof(char));
1623     SendMessage(hostcom, CB_GETLBTEXT, i, (LPARAM)lbl);
1624     GetTextExtentPoint32(TmpDC, lbl, len, &s);
1625     if (s.cx > max_len)
1626     max_len = s.cx;
1627     free(lbl);
1628     }
1629     SendMessage(hostcom, CB_SETDROPPEDWIDTH,
1630     max_len + GetSystemMetrics(SM_CXVSCROLL), 0);
1631     }
1632     break;
1633    
1634     case IDC_HOSTHELP:
1635     PostMessage(GetParent(dlg), WM_USER_DLGHELP2, 0, 0);
1636     }
1637     }
1638     return FALSE;
1639     }
1640    
1641 doda 6801 static BOOL PASCAL TTXGetHostName(HWND parent, PGetHNRec rec)
1642 maya 3227 {
1643     return (BOOL) DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HOSTDLG),
1644     parent, TTXHostDlg, (LONG) rec);
1645     }
1646    
1647 doda 6801 static void PASCAL TTXGetUIHooks(TTXUIHooks *hooks)
1648 maya 3227 {
1649     *hooks->GetHostName = TTXGetHostName;
1650     }
1651    
1652 doda 6801 static void PASCAL TTXReadINIFile(PCHAR fileName, PTTSet ts)
1653 maya 3227 {
1654     (pvar->ReadIniFile) (fileName, ts);
1655     read_ssh_options(pvar, fileName);
1656     pvar->settings = *pvar->ts_SSH;
1657 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Reading INI file");
1658 maya 3227 FWDUI_load_settings(pvar);
1659     }
1660    
1661 doda 6801 static void PASCAL TTXWriteINIFile(PCHAR fileName, PTTSet ts)
1662 maya 3227 {
1663     (pvar->WriteIniFile) (fileName, ts);
1664     *pvar->ts_SSH = pvar->settings;
1665     clear_local_settings(pvar);
1666 doda 6809 logputs(LOG_LEVEL_VERBOSE, "Writing INI file");
1667 maya 3227 write_ssh_options(pvar, fileName, pvar->ts_SSH, TRUE);
1668     }
1669    
1670     static void read_ssh_options_from_user_file(PTInstVar pvar,
1671 doda 6801 char *user_file_name)
1672 maya 3227 {
1673     if (user_file_name[0] == '.') {
1674     read_ssh_options(pvar, user_file_name);
1675     } else {
1676     char buf[1024];
1677    
1678     get_teraterm_dir_relative_name(buf, sizeof(buf), user_file_name);
1679     read_ssh_options(pvar, buf);
1680     }
1681    
1682     pvar->settings = *pvar->ts_SSH;
1683     FWDUI_load_settings(pvar);
1684     }
1685    
1686     // Percent-encode������������src���f�R�[�h����dst���R�s�[�����B
1687     // dstlen��dst���T�C�Y�B�����������������������A�����������������������B
1688     static void percent_decode(char *dst, int dstlen, char *src) {
1689     if (src == NULL || dst == NULL || dstlen < 1) {
1690     return;
1691     }
1692    
1693     while (*src != 0 && dstlen > 1) {
1694     if (*src == '%' && isxdigit(*(src+1)) && isxdigit(*(src+2))) {
1695     src++; *dst = (isalpha(*src) ? (*src|0x20) - 'a' + 10 : *src - '0') << 4;
1696     src++; *dst |= (isalpha(*src) ? (*src|0x20) - 'a' + 10 : *src - '0');
1697     src++; dst++;
1698     }
1699     else {
1700     *dst++ = *src++;
1701     }
1702     dstlen--;
1703     }
1704     *dst = 0;
1705     return;
1706     }
1707    
1708 doda 5799 void add_forward_param(PTInstVar pvar, char *param)
1709     {
1710     if (pvar->settings.DefaultForwarding[0] == 0) {
1711     strncpy_s(pvar->settings.DefaultForwarding,
1712     sizeof(pvar->settings.DefaultForwarding),
1713     param, _TRUNCATE);
1714     } else {
1715     strncat_s(pvar->settings.DefaultForwarding,
1716     sizeof(pvar->settings.DefaultForwarding),
1717     ";", _TRUNCATE);
1718     strncat_s(pvar->settings.DefaultForwarding,
1719     sizeof(pvar->settings.DefaultForwarding),
1720     param, _TRUNCATE);
1721     }
1722     }
1723    
1724 doda 6801 static void PASCAL TTXParseParam(PCHAR param, PTTSet ts, PCHAR DDETopic) {
1725 maya 5869 int param_len=strlen(param);
1726     int opt_len = param_len+1;
1727     char *option = (char *)calloc(opt_len, sizeof(char));
1728 maya 5882 char *option2 = (char *)calloc(opt_len, sizeof(char));
1729 maya 5869 int action;
1730 maya 5874 PCHAR start, cur, next;
1731 maya 5908 size_t i;
1732 maya 5869
1733     if (pvar->hostdlg_activated) {
1734     pvar->settings.Enabled = pvar->hostdlg_Enabled;
1735     }
1736    
1737 maya 5874 /* the first term shuld be executable filename of Tera Term */
1738     start = GetParam(option, opt_len, param);
1739    
1740     cur = start;
1741 maya 5869 while (next = GetParam(option, opt_len, cur)) {
1742 doda 6140 DequoteParam(option, opt_len, option);
1743 maya 5869 action = OPTION_NONE;
1744    
1745     if ((option[0] == '-' || option[0] == '/')) {
1746     if (MATCH_STR(option + 1, "ssh") == 0) {
1747     if (MATCH_STR(option + 4, "-f=") == 0) {
1748 doda 6140 strncpy_s(option2, opt_len, option + 7, _TRUNCATE);
1749 maya 5882 read_ssh_options_from_user_file(pvar, option2);
1750 maya 5869 action = OPTION_CLEAR;
1751     } else if (MATCH_STR(option + 4, "-consume=") == 0) {
1752 doda 6140 strncpy_s(option2, opt_len, option + 13, _TRUNCATE);
1753 maya 5882 read_ssh_options_from_user_file(pvar, option2);
1754     DeleteFile(option2);
1755 maya 5869 action = OPTION_CLEAR;
1756     }
1757    
1758     // ttermpro.exe �� /F= �w������ TTSSH ������������ (2006.10.11 maya)
1759     } else if (MATCH_STR_I(option + 1, "f=") == 0) {
1760 doda 6140 strncpy_s(option2, opt_len, option + 3, _TRUNCATE);
1761 maya 5882 read_ssh_options_from_user_file(pvar, option2);
1762 maya 5869 // Tera Term���������������K�v������������������
1763     }
1764     }
1765    
1766     switch (action) {
1767     case OPTION_CLEAR:
1768     memset(cur, ' ', next-cur);
1769     break;
1770     case OPTION_REPLACE:
1771     memset(cur, ' ', next-cur);
1772     memcpy(cur+1, option, strlen(option));
1773     break;
1774     }
1775    
1776     cur = next;
1777     }
1778    
1779 maya 5874 cur = start;
1780 maya 5869 while (next = GetParam(option, opt_len, cur)) {
1781 doda 6140 DequoteParam(option, opt_len, option);
1782 maya 5869 action = OPTION_NONE;
1783    
1784     if ((option[0] == '-' || option[0] == '/')) {
1785     action = OPTION_CLEAR;
1786     if (MATCH_STR(option + 1, "ssh") == 0) {
1787     if (option[4] == 0) {
1788     pvar->settings.Enabled = 1;
1789     } else if (MATCH_STR(option + 4, "-L") == 0 ||
1790 doda 5959 MATCH_STR(option + 4, "-R") == 0) {
1791     char *p = option + 5;
1792     option2[0] = *p;
1793     i = 1;
1794     while (*++p) {
1795     if (*p == ';' || *p == ',') {
1796     option2[i] = 0;
1797     add_forward_param(pvar, option2);
1798     i = 1;
1799 maya 5908 }
1800 doda 5959 else {
1801     option2[i++] = *p;
1802     }
1803 maya 5908 }
1804 doda 5959 if (i > 1) {
1805     option2[i] = 0;
1806     add_forward_param(pvar, option2);
1807     }
1808 maya 5869 } else if (MATCH_STR(option + 4, "-X") == 0) {
1809     add_forward_param(pvar, "X");
1810 doda 5959 if (option+6 != 0) {
1811     strncpy_s(pvar->settings.X11Display,
1812     sizeof(pvar->settings.X11Display),
1813     option + 6, _TRUNCATE);
1814     }
1815 doda 6473 } else if (strcmp(option + 4, "-v") == 0) {
1816 maya 5869 pvar->settings.LogLevel = LOG_LEVEL_VERBOSE;
1817     } else if (_stricmp(option + 4, "-autologin") == 0 ||
1818     _stricmp(option + 4, "-autologon") == 0) {
1819     pvar->settings.TryDefaultAuth = TRUE;
1820     } else if (MATCH_STR_I(option + 4, "-agentconfirm=") == 0) {
1821     if ((_stricmp(option+18, "off") == 0) ||
1822     (_stricmp(option+18, "no") == 0) ||
1823     (_stricmp(option+18, "false") == 0) ||
1824     (_stricmp(option+18, "0") == 0) ||
1825     (_stricmp(option+18, "n") == 0)) {
1826     pvar->settings.ForwardAgentConfirm = 0;
1827     }
1828     else {
1829     pvar->settings.ForwardAgentConfirm = 1;
1830     }
1831 doda 6473 } else if (strcmp(option + 4, "-a") == 0) {
1832 maya 5869 pvar->settings.ForwardAgent = FALSE;
1833 doda 6473 } else if (strcmp(option + 4, "-A") == 0) {
1834 maya 5869 pvar->settings.ForwardAgent = TRUE;
1835    
1836     } else if (MATCH_STR(option + 4, "-C=") == 0) {
1837     pvar->settings.CompressionLevel = atoi(option+7);
1838     if (pvar->settings.CompressionLevel < 0) {
1839     pvar->settings.CompressionLevel = 0;
1840     }
1841     else if (pvar->settings.CompressionLevel > 9) {
1842     pvar->settings.CompressionLevel = 9;
1843     }
1844 doda 6473 } else if (strcmp(option + 4, "-C") == 0) {
1845 maya 5869 pvar->settings.CompressionLevel = 6;
1846 doda 6473 } else if (strcmp(option + 4, "-c") == 0) {
1847 maya 5869 pvar->settings.CompressionLevel = 0;
1848     } else if (MATCH_STR_I(option + 4, "-icon=") == 0) {
1849     if ((_stricmp(option+10, "old") == 0) ||
1850     (_stricmp(option+10, "yellow") == 0) ||
1851     (_stricmp(option+10, "securett_yellow") == 0)) {
1852     pvar->settings.IconID = IDI_SECURETT_YELLOW;
1853     }
1854 maya 6386 else if ((_stricmp(option+10, "green") == 0) ||
1855     (_stricmp(option+10, "securett_green") == 0)) {
1856     pvar->settings.IconID = IDI_SECURETT_GREEN;
1857     }
1858 maya 5869 else {
1859     pvar->settings.IconID = IDI_SECURETT;
1860     }
1861 doda 6717 } else if (MATCH_STR(option + 4, "-subsystem=") == 0) {
1862     pvar->use_subsystem = TRUE;
1863     strncpy_s(pvar->subsystem_name,
1864     sizeof(pvar->subsystem_name),
1865     option + 15, _TRUNCATE);
1866 maya 5869
1867     // /ssh1 �� /ssh2 �I�v�V�������V�K���� (2006.9.16 maya)
1868 doda 6473 } else if (strcmp(option + 4, "1") == 0) {
1869 maya 5869 pvar->settings.Enabled = 1;
1870     pvar->settings.ssh_protocol_version = 1;
1871 doda 6473 } else if (strcmp(option + 4, "2") == 0) {
1872 maya 5869 pvar->settings.Enabled = 1;
1873     pvar->settings.ssh_protocol_version = 2;
1874    
1875     } else {
1876     char buf[1024];
1877    
1878     UTIL_get_lang_msg("MSG_UNKNOWN_OPTION_ERROR", pvar,
1879     "Unrecognized command-line option: %s");
1880     _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, option);
1881    
1882     MessageBox(NULL, buf, "TTSSH", MB_OK | MB_ICONEXCLAMATION);
1883     }
1884    
1885     // ttermpro.exe �� /T= �w�������p�������A������������ (2006.10.19 maya)
1886     } else if (MATCH_STR_I(option + 1, "t=") == 0) {
1887     if (strcmp(option + 3, "2") == 0) {
1888     pvar->settings.Enabled = 1;
1889     // /t=2��ttssh�������g������������
1890     } else {
1891     pvar->settings.Enabled = 0;
1892     action = OPTION_NONE; // Tera Term������������������������
1893     }
1894    
1895     // /1 ������ /2 �I�v�V�������V�K���� (2004.10.3 yutaka)
1896 doda 6473 } else if (strcmp(option + 1, "1") == 0) {
1897 maya 5869 // command line: /ssh /1 is SSH1 only
1898     pvar->settings.ssh_protocol_version = 1;
1899    
1900 doda 6473 } else if (strcmp(option + 1, "2") == 0) {
1901 maya 5869 // command line: /ssh /2 is SSH2 & SSH1
1902     pvar->settings.ssh_protocol_version = 2;
1903    
1904 doda 6473 } else if (strcmp(option + 1, "nossh") == 0) {
1905 maya 5869 // '/nossh' �I�v�V�����������B
1906     // TERATERM.INI ��SSH���L�������������������A������Cygterm���N��������������
1907     // �����������������B(2004.10.11 yutaka)
1908     pvar->settings.Enabled = 0;
1909    
1910 doda 6473 } else if (strcmp(option + 1, "telnet") == 0) {
1911 maya 5869 // '/telnet' ���w�������������������� '/nossh' ��������
1912     // SSH������������ (2006.9.16 maya)
1913     pvar->settings.Enabled = 0;
1914     // Tera Term �� Telnet �t���O���t����
1915     pvar->ts->Telnet = 1;
1916    
1917 doda 6473 } else if (MATCH_STR(option + 1, "auth=") == 0) {
1918 maya 5869 // SSH2�������O�C���I�v�V����������
1919     //
1920     // SYNOPSIS: /ssh /auth=passowrd /user=���[�U�� /passwd=�p�X���[�h
1921     // /ssh /auth=publickey /user=���[�U�� /passwd=�p�X���[�h /keyfile=�p�X
1922 doda 6472 // EXAMPLE: /ssh /auth=password /user=nike /passwd="a b""c" ; �p�X���[�h: �ua b"c�v
1923 maya 5869 // /ssh /auth=publickey /user=foo /passwd=bar /keyfile=d:\tmp\id_rsa
1924 doda 6472 // NOTICE: �p�X���[�h���p�X���������Z�~�R���������������������_�u���N�H�[�g " ������
1925     // �p�X���[�h���_�u���N�H�[�g�����������������A�������_�u���N�H�[�g "" ���u��������
1926 maya 5869 //
1927     pvar->ssh2_autologin = 1; // for SSH2 (2004.11.30 yutaka)
1928    
1929 doda 6473 if (_stricmp(option + 6, "password") == 0) { // �p�X���[�h
1930 maya 5869 //pvar->auth_state.cur_cred.method = SSH_AUTH_PASSWORD;
1931     pvar->ssh2_authmethod = SSH_AUTH_PASSWORD;
1932    
1933     // /auth=challenge ������ (2007.10.5 maya)
1934 doda 6473 } else if (_stricmp(option + 6, "challenge") == 0) { // keyboard-interactive�F��
1935 maya 5869 //pvar->auth_state.cur_cred.method = SSH_AUTH_TIS;
1936     pvar->ssh2_authmethod = SSH_AUTH_TIS;
1937    
1938 doda 6473 } else if (_stricmp(option + 6, "publickey") == 0) { // ���J���F��
1939 maya 5869 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1940     pvar->ssh2_authmethod = SSH_AUTH_RSA;
1941    
1942 doda 6473 } else if (_stricmp(option + 6, "pageant") == 0) { // ���J���F�� by Pageant
1943 maya 5869 //pvar->auth_state.cur_cred.method = SSH_AUTH_RSA;
1944     pvar->ssh2_authmethod = SSH_AUTH_PAGEANT;
1945    
1946     } else {
1947     // TODO:
1948     }
1949    
1950     } else if (MATCH_STR(option + 1, "user=") == 0) {
1951 doda 6140 _snprintf_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), _TRUNCATE, "%s", option+6);
1952 maya 5869
1953     } else if (MATCH_STR(option + 1, "passwd=") == 0) {
1954 doda 6140 _snprintf_s(pvar->ssh2_password, sizeof(pvar->ssh2_password), _TRUNCATE, "%s", option+8);
1955 maya 5869
1956     } else if (MATCH_STR(option + 1, "keyfile=") == 0) {
1957 doda 6140 _snprintf_s(pvar->ssh2_keyfile, sizeof(pvar->ssh2_keyfile), _TRUNCATE, "%s", option+9);
1958 maya 5869
1959 doda 6473 } else if (strcmp(option + 1, "ask4passwd") == 0) {
1960 maya 5869 // �p�X���[�h������ (2006.9.18 maya)
1961     pvar->ask4passwd = 1;
1962    
1963 doda 6473 } else if (strcmp(option + 1, "nosecuritywarning") == 0) {
1964 maya 5869 // known_hosts�`�F�b�N���������B���Y�I�v�V�������g�����A�Z�L�����e�B������������
1965     // �����A�B���I�v�V���������������B
1966     // (2009.10.4 yutaka)
1967     pvar->nocheck_known_hosts = TRUE;
1968    
1969     }
1970     else { // Other (not ttssh) option
1971     action = OPTION_NONE; // ttssh���I�v�V������������������������
1972     }
1973    
1974     // �p�X���[�h�������������������O�C��������������
1975     // /auth ���F�����\�b�h���w�������������p������ (2006.9.18 maya)
1976     if (pvar->ask4passwd == 1) {
1977     pvar->ssh2_autologin = 0;
1978     }
1979    
1980     }
1981     else if ((MATCH_STR_I(option, "ssh://") == 0) ||
1982     (MATCH_STR_I(option, "ssh1://") == 0) ||
1983     (MATCH_STR_I(option, "ssh2://") == 0) ||
1984     (MATCH_STR_I(option, "slogin://") == 0) ||
1985     (MATCH_STR_I(option, "slogin1://") == 0) ||
1986     (MATCH_STR_I(option, "slogin2://") == 0)) {
1987     //
1988     // ssh://user@host/ ����URL�`�����T�|�[�g
1989     // ���{�I�������� telnet:// URL��������
1990     //
1991     // �Q�l:
1992     // RFC3986: Uniform Resource Identifier (URI): Generic Syntax
1993     // RFC4248: The telnet URI Scheme
1994     //
1995     char *p, *p2, *p3;
1996     int optlen, hostlen;
1997    
1998     optlen = strlen(option);
1999    
2000     // ������':'���O�����������������������A������ssh�v���g�R���o�[�W������������
2001     p = _mbschr(option, ':');
2002     switch (*(p-1)) {
2003     case '1':
2004     pvar->settings.ssh_protocol_version = 1;
2005     break;
2006     case '2':
2007     pvar->settings.ssh_protocol_version = 2;
2008     break;
2009     }
2010    
2011     // authority part �����|�C���^������
2012     p += 3;
2013    
2014     // path part ������������
2015     if ((p2 = _mbschr(p, '/')) != NULL) {
2016     *p2 = 0;
2017     }
2018    
2019     // '@'�������������A���������O�����[�U����
2020     if ((p2 = _mbschr(p, '@')) != NULL) {
2021     *p2 = 0;
2022     // ':'���~���p�X���[�h
2023     if ((p3 = _mbschr(p, ':')) != NULL) {
2024     *p3 = 0;
2025     percent_decode(pvar->ssh2_password, sizeof(pvar->ssh2_password), p3 + 1);
2026     }
2027     percent_decode(pvar->ssh2_username, sizeof(pvar->ssh2_username), p);
2028     // p �� host part ������('@'����������)����������������
2029     p = p2 + 1;
2030     }
2031    
2032     // host part �� option �����������������Ascheme part ������
2033     // port�w����������������port���������������������m��������������
2034     hostlen = strlen(p);
2035     memmove_s(option, optlen, p, hostlen);
2036     option[hostlen] = 0;
2037    
2038     // �|�[�g�w������������":22"������
2039     if (option[0] == '[' && option[hostlen-1] == ']' || // IPv6 raw address without port
2040     option[0] != '[' && _mbschr(option, ':') == NULL) { // hostname or IPv4 raw address without port
2041     memcpy_s(option+hostlen, optlen-hostlen, ":22", 3);
2042     hostlen += 3;
2043     }
2044    
2045     // �|�[�g�w�����������������X�y�[�X������
2046     memset(option+hostlen, ' ', optlen-hostlen);
2047    
2048     pvar->settings.Enabled = 1;
2049    
2050     action = OPTION_REPLACE;
2051     }
2052     else if (_mbschr(option, '@') != NULL) {
2053     //
2054     // user@host �`�����T�|�[�g
2055     // ����������ssh�������T�|�[�g�����A���[�U����ttssh���������B
2056     // (ssh�������O -- ttssh�������W������������)
2057     // �����I��telnet authentication option���T�|�[�g��������
2058     // Tera Term�{�����������������������\���B
2059     //
2060     char *p;
2061     p = _mbschr(option, '@');
2062     *p = 0;
2063    
2064     strncpy_s(pvar->ssh2_username, sizeof(pvar->ssh2_username), option, _TRUNCATE);
2065    
2066     // ���[�U���������X�y�[�X�������B
2067     // ������TTX��Tera Term�{�������������������X�y�[�X�����������������A
2068     // �z�X�g�����������l�����K�v�������B
2069     memset(option, ' ', p-option+1);
2070    
2071     action = OPTION_REPLACE;
2072     }
2073    
2074    
2075     switch (action) {
2076     case OPTION_CLEAR:
2077     memset(cur, ' ', next-cur);
2078     break;
2079     case OPTION_REPLACE:
2080     memset(cur, ' ', next-cur);
2081     memcpy(cur+1, option, strlen(option));
2082     break;
2083     }
2084    
2085     cur = next;
2086     }
2087    
2088     free(option);
2089    
2090     FWDUI_load_settings(pvar);
2091    
2092     (pvar->ParseParam) (param, ts, DDETopic);
2093     }
2094 maya 3227
2095 doda 6801 static void PASCAL TTXGetSetupHooks(TTXSetupHooks *hooks)
2096 maya 3227 {
2097     pvar->ReadIniFile = *hooks->ReadIniFile;
2098     pvar->WriteIniFile = *hooks->WriteIniFile;
2099     pvar->ParseParam = *hooks->ParseParam;
2100    
2101     *hooks->ReadIniFile = TTXReadINIFile;
2102     *hooks->WriteIniFile = TTXWriteINIFile;
2103     *hooks->ParseParam = TTXParseParam;
2104     }
2105    
2106 doda 6801 static void PASCAL TTXSetWinSize(int rows, int cols)
2107 maya 3227 {
2108     SSH_notify_win_size(pvar, cols, rows);
2109     }
2110    
2111     static void insertMenuBeforeItem(HMENU menu, WORD beforeItemID, WORD flags,
2112 doda 6801 WORD newItemID, char *text)
2113 maya 3227 {
2114     int i, j;
2115    
2116     for (i = GetMenuItemCount(menu) - 1; i >= 0; i--) {
2117     HMENU submenu = GetSubMenu(menu, i);
2118    
2119     for (j = GetMenuItemCount(submenu) - 1; j >= 0; j--) {
2120     if (GetMenuItemID(submenu, j) == beforeItemID) {
2121     InsertMenu(submenu, j, MF_BYPOSITION | flags, newItemID, text);
2122     return;
2123     }
2124     }
2125     }
2126     }
2127    
2128 doda 4463 #define GetFileMenu(menu) GetSubMenuByChildID(menu, 50110) // ID_FILE_NEWCONNECTION
2129     #define GetEditMenu(menu) GetSubMenuByChildID(menu, 50210) // ID_EDIT_COPY2
2130     #define GetSetupMenu(menu) GetSubMenuByChildID(menu, 50310) // ID_SETUP_TERMINAL
2131     #define GetControlMenu(menu) GetSubMenuByChildID(menu, 50410) // ID_CONTROL_RESETTERMINAL
2132     #define GetHelpMenu(menu) GetSubMenuByChildID(menu, 50990) // ID_HELP_ABOUT
2133    
2134     HMENU GetSubMenuByChildID(HMENU menu, UINT id) {
2135     int i, j, items, subitems, cur_id;
2136     HMENU m;
2137    
2138     items = GetMenuItemCount(menu);
2139    
2140     for (i=0; i<items; i++) {
2141     if (m = GetSubMenu(menu, i)) {
2142     subitems = GetMenuItemCount(m);
2143     for (j=0; j<subitems; j++) {
2144     cur_id = GetMenuItemID(m, j);
2145     if (cur_id == id) {
2146     return m;
2147     }
2148     }
2149     }
2150     }
2151     return NULL;
2152     }
2153    
2154 doda 6801 static void PASCAL TTXModifyMenu(HMENU menu)
2155 maya 3227 {
2156 doda 4463 pvar->FileMenu = GetFileMenu(menu);
2157    
2158 maya 3227 /* inserts before ID_HELP_ABOUT */
2159     UTIL_get_lang_msg("MENU_ABOUT", pvar, "About &TTSSH...");
2160     insertMenuBeforeItem(menu, 50990, MF_ENABLED, ID_ABOUTMENU, pvar->ts->UIMsg);
2161    
2162     /* inserts before ID_SETUP_TCPIP */
2163     UTIL_get_lang_msg("MENU_SSH", pvar, "SS&H...");
2164     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHSETUPMENU, pvar->ts->UIMsg);
2165     /* inserts before ID_SETUP_TCPIP */
2166     UTIL_get_lang_msg("MENU_SSH_AUTH", pvar, "SSH &Authentication...");
2167     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHAUTHSETUPMENU, pvar->ts->UIMsg);
2168     /* inserts before ID_SETUP_TCPIP */
2169     UTIL_get_lang_msg("MENU_SSH_FORWARD", pvar, "SSH F&orwarding...");
2170     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHFWDSETUPMENU, pvar->ts->UIMsg);
2171     UTIL_get_lang_msg("MENU_SSH_KEYGEN", pvar, "SSH KeyGe&nerator...");
2172     insertMenuBeforeItem(menu, 50360, MF_ENABLED, ID_SSHKEYGENMENU, pvar->ts->UIMsg);
2173    
2174     /* inserts before ID_FILE_CHANGEDIR */
2175     UTIL_get_lang_msg("MENU_SSH_SCP", pvar, "SS&H SCP...");
2176 doda 4463 insertMenuBeforeItem(menu, 50170, MF_GRAYED, ID_SSHSCPMENU, pvar->ts->UIMsg);
2177 maya 3227 }
2178    
2179 doda 6801 static void PASCAL TTXModifyPopupMenu(HMENU menu) {
2180 doda 4463 if (menu == pvar->FileMenu) {
2181     if (pvar->cv->Ready && pvar->settings.Enabled)
2182     EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_ENABLED);
2183     else
2184     EnableMenuItem(menu, ID_SSHSCPMENU, MF_BYCOMMAND | MF_GRAYED);
2185     }
2186     }
2187    
2188 maya 3227 // ���s�t�@�C�������o�[�W�������������� (2005.2.28 yutaka)
2189     void get_file_version(char *exefile, int *major, int *minor, int *release, int *build)
2190     {
2191     typedef struct {
2192     WORD wLanguage;
2193     WORD wCodePage;
2194     } LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
2195     LPLANGANDCODEPAGE lplgcode;
2196     UINT unLen;
2197     DWORD size;
2198     char *buf = NULL;
2199     BOOL ret;
2200     int i;
2201     char fmt[80];
2202     char *pbuf;
2203    
2204     size = GetFileVersionInfoSize(exefile, NULL);
2205     if (size == 0) {
2206     goto error;
2207     }
2208     buf = malloc(size);
2209     ZeroMemory(buf, size);
2210    
2211     if (GetFileVersionInfo(exefile, 0, size, buf) == FALSE) {
2212     goto error;
2213     }
2214    
2215     ret = VerQueryValue(buf,
2216     "\\VarFileInfo\\Translation",
2217     (LPVOID *)&lplgcode, &unLen);
2218     if (ret == FALSE)
2219     goto error;
2220    
2221     for (i = 0 ; i < (int)(unLen / sizeof(LANGANDCODEPAGE)) ; i++) {
2222     _snprintf_s(fmt, sizeof(fmt), _TRUNCATE,
2223     "\\StringFileInfo\\%04x%04x\\FileVersion",
2224     lplgcode[i].wLanguage, lplgcode[i].wCodePage);
2225     VerQueryValue(buf, fmt, &pbuf, &unLen);
2226     if (unLen > 0) { // get success
2227     int n, a, b, c, d;
2228    
2229     n = sscanf(pbuf, "%d, %d, %d, %d", &a, &b, &c, &d);
2230     if (n == 4) { // convert success
2231     *major = a;
2232     *minor = b;
2233     *release = c;
2234     *build = d;
2235     break;
2236     }
2237     }
2238     }
2239    
2240     free(buf);
2241     return;
2242    
2243     error:
2244     free(buf