Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/ttssh2/ttxssh/hosts.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8542 - (hide annotations) (download) (as text)
Sun Feb 16 14:55:30 2020 UTC (4 years, 1 month ago) by zmatsuo
File MIME type: text/x-csrc
File size: 68385 byte(s)
ttxsshの鍵確認ダイアログの文字化けしないようにした

- ttxsshのNew connectionダイアログのデザインを修正
  - ホスト名のドロップダウンを大きくした
  - sshバージョンのドロップダウンを大きくした
- tcharを使用しない (ttxssh/auth.c)
- const static を static const に置き換え
  - warning: 'static' is not at beginning of declaration [-Wold-style-declaration]
1 maya 3227 /*
2 doda 6841 * Copyright (c) 1998-2001, Robert O'Callahan
3 doda 8485 * (C) 2004-2020 TeraTerm Project
4 doda 6841 * All rights reserved.
5     *
6     * Redistribution and use in source and binary forms, with or without
7     * modification, are permitted provided that the following conditions
8     * are met:
9     *
10     * 1. Redistributions of source code must retain the above copyright
11     * notice, this list of conditions and the following disclaimer.
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the distribution.
15     * 3. The name of the author may not be used to endorse or promote products
16     * derived from this software without specific prior written permission.
17     *
18     * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21     * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28     */
29 maya 3227
30     /*
31     This code is copyright (C) 1998-1999 Robert O'Callahan.
32     See LICENSE.TXT for the license.
33     */
34     #include "ttxssh.h"
35     #include "util.h"
36     #include "resource.h"
37     #include "matcher.h"
38     #include "ssh.h"
39 maya 4304 #include "key.h"
40 maya 3227 #include "hosts.h"
41 doda 4569 #include "dns.h"
42 zmatsuo 7560 #include "dlglib.h"
43 zmatsuo 7714 #include "compat_win.h"
44 maya 3227
45     #include <openssl/bn.h>
46     #include <openssl/evp.h>
47     #include <openssl/rsa.h>
48     #include <openssl/dsa.h>
49    
50     #include <fcntl.h>
51     #include <io.h>
52     #include <errno.h>
53     #include <sys/stat.h>
54     #include <direct.h>
55 doda 4531 #include <memory.h>
56 maya 3227
57 zmatsuo 8542 #include "codeconv.h"
58     #include "layer_for_unicode.h"
59 doda 4531
60 zmatsuo 7560 #undef DialogBoxParam
61     #define DialogBoxParam(p1,p2,p3,p4,p5) \
62     TTDialogBoxParam(p1,p2,p3,p4,p5)
63     #undef EndDialog
64     #define EndDialog(p1,p2) \
65     TTEndDialog(p1, p2)
66 maya 3227
67     // BASE64�\���������i��������'='�����������������j
68     static char base64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
69    
70    
71 yutakapon 8093 BOOL HOSTS_resume_session_after_known_hosts(PTInstVar pvar);
72     void HOSTS_cancel_session_after_known_hosts(PTInstVar pvar);
73    
74    
75 doda 6801 static char **parse_multi_path(char *buf)
76 maya 3227 {
77     int i;
78     int ch;
79     int num_paths = 1;
80 doda 6801 char ** result;
81 maya 3227 int last_path_index;
82    
83     for (i = 0; (ch = buf[i]) != 0; i++) {
84     if (ch == ';') {
85     num_paths++;
86     }
87     }
88    
89     result =
90 doda 6801 (char **) malloc(sizeof(char *) * (num_paths + 1));
91 maya 3227
92     last_path_index = 0;
93     num_paths = 0;
94     for (i = 0; (ch = buf[i]) != 0; i++) {
95     if (ch == ';') {
96     buf[i] = 0;
97     result[num_paths] = _strdup(buf + last_path_index);
98     num_paths++;
99     buf[i] = ch;
100     last_path_index = i + 1;
101     }
102     }
103     if (i > last_path_index) {
104     result[num_paths] = _strdup(buf + last_path_index);
105     num_paths++;
106     }
107     result[num_paths] = NULL;
108     return result;
109     }
110    
111     void HOSTS_init(PTInstVar pvar)
112     {
113     pvar->hosts_state.prefetched_hostname = NULL;
114 maya 6147 key_init(&pvar->hosts_state.hostkey);
115 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
116     pvar->hosts_state.file_names = NULL;
117 yutakapon 8093
118     /*
119     * �O�����I�v�V�����w��(/nosecuritywarning)���c���������������������������B
120     */
121     pvar->nocheck_known_hosts = FALSE;
122 maya 3227 }
123    
124     void HOSTS_open(PTInstVar pvar)
125     {
126     pvar->hosts_state.file_names =
127     parse_multi_path(pvar->session_settings.KnownHostsFiles);
128     }
129    
130     //
131     // known_hosts�t�@�C�������e�������� pvar->hosts_state.file_data ����������
132     //
133 doda 6801 static int begin_read_file(PTInstVar pvar, char *name,
134 maya 3227 int suppress_errors)
135     {
136     int fd;
137     int length;
138     int amount_read;
139     char buf[2048];
140    
141     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
142     fd = _open(buf, _O_RDONLY | _O_SEQUENTIAL | _O_BINARY);
143     if (fd == -1) {
144     if (!suppress_errors) {
145     if (errno == ENOENT) {
146     UTIL_get_lang_msg("MSG_HOSTS_READ_ENOENT_ERROR", pvar,
147     "An error occurred while trying to read a known_hosts file.\n"
148     "The specified filename does not exist.");
149     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
150     } else {
151     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
152     "An error occurred while trying to read a known_hosts file.");
153     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
154     }
155     }
156     return 0;
157     }
158    
159     length = (int) _lseek(fd, 0, SEEK_END);
160     _lseek(fd, 0, SEEK_SET);
161    
162     if (length >= 0 && length < 0x7FFFFFFF) {
163     pvar->hosts_state.file_data = malloc(length + 1);
164     if (pvar->hosts_state.file_data == NULL) {
165     if (!suppress_errors) {
166     UTIL_get_lang_msg("MSG_HOSTS_ALLOC_ERROR", pvar,
167     "Memory ran out while trying to allocate space to read a known_hosts file.");
168     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
169     }
170     _close(fd);
171     return 0;
172     }
173     } else {
174     if (!suppress_errors) {
175     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
176     "An error occurred while trying to read a known_hosts file.");
177     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
178     }
179     _close(fd);
180     return 0;
181     }
182    
183     amount_read = _read(fd, pvar->hosts_state.file_data, length);
184     pvar->hosts_state.file_data[length] = 0;
185    
186     _close(fd);
187    
188     if (amount_read != length) {
189     if (!suppress_errors) {
190     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
191     "An error occurred while trying to read a known_hosts file.");
192     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
193     }
194     free(pvar->hosts_state.file_data);
195     pvar->hosts_state.file_data = NULL;
196     return 0;
197     } else {
198     return 1;
199     }
200     }
201    
202     static int end_read_file(PTInstVar pvar, int suppress_errors)
203     {
204     free(pvar->hosts_state.file_data);
205     pvar->hosts_state.file_data = NULL;
206     return 1;
207     }
208    
209     static int begin_read_host_files(PTInstVar pvar, int suppress_errors)
210     {
211     pvar->hosts_state.file_num = 0;
212     pvar->hosts_state.file_data = NULL;
213     return 1;
214     }
215    
216     // MIME64�����������X�L�b�v����
217 doda 6801 static int eat_base64(char *data)
218 maya 3227 {
219     int index = 0;
220     int ch;
221    
222     for (;;) {
223     ch = data[index];
224     if (ch == '=' || strchr(base64, ch)) {
225     // BASE64���\�������������������� index ���i����
226     index++;
227     } else {
228     break;
229     }
230     }
231    
232     return index;
233     }
234    
235 doda 6801 static int eat_spaces(char *data)
236 maya 3227 {
237     int index = 0;
238     int ch;
239    
240     while ((ch = data[index]) == ' ' || ch == '\t') {
241     index++;
242     }
243     return index;
244     }
245    
246 doda 6801 static int eat_digits(char *data)
247 maya 3227 {
248     int index = 0;
249     int ch;
250    
251     while ((ch = data[index]) >= '0' && ch <= '9') {
252     index++;
253     }
254     return index;
255     }
256    
257 doda 6801 static int eat_to_end_of_line(char *data)
258 maya 3227 {
259     int index = 0;
260     int ch;
261    
262     while ((ch = data[index]) != '\n' && ch != '\r' && ch != 0) {
263     index++;
264     }
265    
266     while ((ch = data[index]) == '\n' || ch == '\r') {
267     index++;
268     }
269    
270     return index;
271     }
272    
273 doda 6801 static int eat_to_end_of_pattern(char *data)
274 maya 3227 {
275     int index = 0;
276     int ch;
277    
278     while (ch = data[index], is_pattern_char(ch)) {
279     index++;
280     }
281    
282     return index;
283     }
284    
285     // SSH2���� BASE64 �`�����i�[����������
286 doda 6621 static Key *parse_base64data(char *data)
287 maya 3227 {
288     int count;
289     unsigned char *blob = NULL;
290     int len, n;
291     Key *key = NULL;
292     char ch;
293    
294     // BASE64���������T�C�Y������
295     count = eat_base64(data);
296     len = 2 * count;
297     blob = malloc(len);
298     if (blob == NULL)
299     goto error;
300    
301     // BASE64�f�R�[�h
302     ch = data[count];
303     data[count] = '\0'; // ���������s�R�[�h������������������������������������
304 doda 6621 n = b64decode(blob, len, data);
305 maya 3227 data[count] = ch;
306     if (n < 0) {
307     goto error;
308     }
309    
310     key = key_from_blob(blob, n);
311     if (key == NULL)
312     goto error;
313    
314     error:
315     if (blob != NULL)
316     free(blob);
317    
318     return (key);
319     }
320    
321    
322 doda 6801 static char *parse_bignum(char *data)
323 maya 3227 {
324     uint32 digits = 0;
325     BIGNUM *num = BN_new();
326     BIGNUM *billion = BN_new();
327     BIGNUM *digits_num = BN_new();
328     BN_CTX *ctx = BN_CTX_new();
329 doda 6801 char *result;
330 maya 3227 int ch;
331     int leftover_digits = 1;
332    
333 yutakapon 8316 // BN_CTX_init������ OpenSSL 1.1.0 �������������B
334     // OpenSSL 1.0.2�����_�������� deprecated �����������B
335 maya 3227 BN_set_word(num, 0);
336     BN_set_word(billion, 1000000000L);
337    
338     while ((ch = *data) >= '0' && ch <= '9') {
339     if (leftover_digits == 1000000000L) {
340     BN_set_word(digits_num, digits);
341     BN_mul(num, num, billion, ctx);
342     BN_add(num, num, digits_num);
343     leftover_digits = 1;
344     digits = 0;
345     }
346    
347     digits = digits * 10 + ch - '0';
348     leftover_digits *= 10;
349     data++;
350     }
351    
352     BN_set_word(digits_num, digits);
353     BN_set_word(billion, leftover_digits);
354     BN_mul(num, num, billion, ctx);
355     BN_add(num, num, digits_num);
356    
357 doda 6801 result = (char *) malloc(2 + BN_num_bytes(num));
358 maya 3227 set_ushort16_MSBfirst(result, BN_num_bits(num));
359     BN_bn2bin(num, result + 2);
360    
361     BN_CTX_free(ctx);
362     BN_free(digits_num);
363     BN_free(num);
364     BN_free(billion);
365    
366     return result;
367     }
368    
369     //
370     // known_hosts�t�@�C�������e���������A�w�������z�X�g�����J�����T���B
371     //
372 doda 6801 static int check_host_key(PTInstVar pvar, char *hostname,
373     unsigned short tcpport, char *data,
374 maya 6152 Key *key)
375 maya 3227 {
376     int index = eat_spaces(data);
377     int matched = 0;
378     int keybits = 0;
379    
380     if (data[index] == '#') {
381     return index + eat_to_end_of_line(data + index);
382     }
383    
384     /* if we find an empty line, then it won't have any patterns matching the hostname
385     and so we skip it */
386     index--;
387     do {
388     int negated;
389     int bracketed;
390     char *end_bracket;
391     int host_matched = 0;
392     unsigned short keyfile_port = 22;
393    
394     index++;
395     negated = data[index] == '!';
396    
397     if (negated) {
398     index++;
399     bracketed = data[index] == '[';
400     if (bracketed) {
401     end_bracket = strstr(data + index + 1, "]:");
402     if (end_bracket != NULL) {
403     *end_bracket = ' ';
404     index++;
405     }
406     }
407     host_matched = match_pattern(data + index, hostname);
408     if (bracketed && end_bracket != NULL) {
409     *end_bracket = ']';
410     keyfile_port = atoi(end_bracket + 2);
411     }
412     if (host_matched && keyfile_port == tcpport) {
413     return index + eat_to_end_of_line(data + index);
414     }
415     } else {
416     bracketed = data[index] == '[';
417     if (bracketed) {
418     end_bracket = strstr(data + index + 1, "]:");
419     if (end_bracket != NULL) {
420     *end_bracket = ' ';
421     index++;
422     }
423     }
424     host_matched = match_pattern(data + index, hostname);
425     if (bracketed && end_bracket != NULL) {
426     *end_bracket = ']';
427     keyfile_port = atoi(end_bracket + 2);
428     }
429     if (host_matched && keyfile_port == tcpport) {
430     matched = 1;
431     }
432     }
433    
434     index += eat_to_end_of_pattern(data + index);
435     } while (data[index] == ',');
436    
437     if (!matched) {
438     return index + eat_to_end_of_line(data + index);
439     } else {
440     // ���������������t�H�[�}�b�g��������
441     // �����A���������v�����G���g�����������������������B
442     /*
443     [SSH1]
444     192.168.1.2 1024 35 13032....
445    
446     [SSH2]
447     192.168.1.2 ssh-rsa AAAAB3NzaC1....
448     192.168.1.2 ssh-dss AAAAB3NzaC1....
449     192.168.1.2 rsa AAAAB3NzaC1....
450     192.168.1.2 dsa AAAAB3NzaC1....
451     192.168.1.2 rsa1 AAAAB3NzaC1....
452     */
453     int rsa1_key_bits;
454    
455     index += eat_spaces(data + index);
456    
457     rsa1_key_bits = atoi(data + index);
458     if (rsa1_key_bits > 0) { // RSA1������
459     if (!SSHv1(pvar)) { // SSH2��������������������
460     return index + eat_to_end_of_line(data + index);
461     }
462    
463 maya 6152 key->type = KEY_RSA1;
464 maya 3227
465 maya 6152 key->bits = rsa1_key_bits;
466 maya 3227 index += eat_digits(data + index);
467     index += eat_spaces(data + index);
468    
469 maya 6152 key->exp = parse_bignum(data + index);
470 maya 3227 index += eat_digits(data + index);
471     index += eat_spaces(data + index);
472    
473 maya 6152 key->mod = parse_bignum(data + index);
474 maya 3227 } else {
475     char *cp, *p;
476 maya 6152 Key *key2;
477     ssh_keytype key_type;
478 maya 3227
479     if (!SSHv2(pvar)) { // SSH1��������������������
480     return index + eat_to_end_of_line(data + index);
481     }
482    
483     cp = data + index;
484     p = strchr(cp, ' ');
485     if (p == NULL) {
486     return index + eat_to_end_of_line(data + index);
487     }
488     index += (p - cp); // setup index
489     *p = '\0';
490 maya 6152 key_type = get_keytype_from_name(cp);
491 maya 3227 *p = ' ';
492    
493     index += eat_spaces(data + index); // update index
494    
495 doda 6621 // base64 decode
496     key2 = parse_base64data(data + index);
497 maya 6152 if (key2 == NULL) {
498 maya 3227 return index + eat_to_end_of_line(data + index);
499     }
500    
501     // setup
502 maya 6152 key->type = key2->type;
503     key->dsa = key2->dsa;
504     key->rsa = key2->rsa;
505     key->ecdsa = key2->ecdsa;
506     key->ed25519_pk = key2->ed25519_pk;
507 maya 3227
508     index += eat_base64(data + index);
509     index += eat_spaces(data + index);
510    
511     // Key�\�������g���������� (2008.3.2 yutaka)
512 maya 6152 free(key2);
513 maya 3227 }
514    
515     return index + eat_to_end_of_line(data + index);
516     }
517     }
518    
519     //
520     // known_hosts�t�@�C�������z�X�g�������v�����s������
521 maya 6152 // return_always
522     // 0: �������������T��
523     // 1: 1�s�����T��������
524 maya 3227 //
525     static int read_host_key(PTInstVar pvar,
526 doda 6801 char *hostname, unsigned short tcpport,
527 maya 6152 int suppress_errors, int return_always,
528     Key *key)
529 maya 3227 {
530     int i;
531     int while_flg;
532    
533     for (i = 0; hostname[i] != 0; i++) {
534     int ch = hostname[i];
535    
536     if (!is_pattern_char(ch) || ch == '*' || ch == '?') {
537     if (!suppress_errors) {
538     UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_INVALID_ERROR", pvar,
539     "The host name contains an invalid character.\n"
540     "This session will be terminated.");
541 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
542 maya 3227 }
543     return 0;
544     }
545     }
546    
547     if (i == 0) {
548     if (!suppress_errors) {
549     UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_EMPTY_ERROR", pvar,
550     "The host name should not be empty.\n"
551     "This session will be terminated.");
552 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
553 maya 3227 }
554     return 0;
555     }
556    
557     // hostkey type is KEY_UNSPEC.
558 maya 6152 key_init(key);
559 maya 3227
560     do {
561     if (pvar->hosts_state.file_data == NULL
562     || pvar->hosts_state.file_data[pvar->hosts_state.file_data_index] == 0) {
563 doda 6801 char *filename;
564 maya 3227 int keep_going = 1;
565    
566     if (pvar->hosts_state.file_data != NULL) {
567     end_read_file(pvar, suppress_errors);
568     }
569    
570     do {
571     filename =
572     pvar->hosts_state.file_names[pvar->hosts_state.file_num];
573    
574     if (filename == NULL) {
575     return 1;
576     } else {
577     pvar->hosts_state.file_num++;
578    
579     if (filename[0] != 0) {
580     if (begin_read_file(pvar, filename, suppress_errors)) {
581     pvar->hosts_state.file_data_index = 0;
582     keep_going = 0;
583     }
584     }
585     }
586     } while (keep_going);
587     }
588    
589     pvar->hosts_state.file_data_index +=
590     check_host_key(pvar, hostname, tcpport,
591     pvar->hosts_state.file_data +
592 maya 6152 pvar->hosts_state.file_data_index,
593     key);
594 maya 3227
595     if (!return_always) {
596     // �L�����L�[��������������
597 maya 6152 while_flg = (key->type == KEY_UNSPEC);
598 maya 3227 }
599     else {
600     while_flg = 0;
601     }
602     } while (while_flg);
603    
604     return 1;
605     }
606    
607     static void finish_read_host_files(PTInstVar pvar, int suppress_errors)
608     {
609     if (pvar->hosts_state.file_data != NULL) {
610     end_read_file(pvar, suppress_errors);
611     }
612     }
613    
614     // �T�[�o�����������O���Aknown_hosts�t�@�C�������z�X�g���J�������������������B
615 doda 6801 void HOSTS_prefetch_host_key(PTInstVar pvar, char *hostname, unsigned short tcpport)
616 maya 3227 {
617 maya 6152 Key key; // known_hosts���o�^������������
618    
619 maya 3227 if (!begin_read_host_files(pvar, 1)) {
620     return;
621     }
622    
623 maya 6152 memset(&key, 0, sizeof(key));
624     if (!read_host_key(pvar, hostname, tcpport, 1, 0, &key)) {
625 maya 3227 return;
626     }
627    
628 maya 6152 key_copy(&pvar->hosts_state.hostkey, &key);
629     key_init(&key);
630    
631 maya 3227 free(pvar->hosts_state.prefetched_hostname);
632     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
633    
634     finish_read_host_files(pvar, 1);
635     }
636    
637 yutakapon 5846
638     // known_hosts�t�@�C�������Y�������L�[���������������B
639     //
640     // return:
641     // *keyptr != NULL ��������
642     //
643 doda 6801 static int parse_hostkey_file(PTInstVar pvar, char *hostname,
644     unsigned short tcpport, char *data, Key **keyptr)
645 yutakapon 5846 {
646     int index = eat_spaces(data);
647     int matched = 0;
648     int keybits = 0;
649     ssh_keytype ktype;
650 yutakapon 5847 Key *key;
651 yutakapon 5846
652     *keyptr = NULL;
653    
654     if (data[index] == '#') {
655     return index + eat_to_end_of_line(data + index);
656     }
657    
658     /* if we find an empty line, then it won't have any patterns matching the hostname
659     and so we skip it */
660     index--;
661     do {
662     int negated;
663     int bracketed;
664     char *end_bracket;
665     int host_matched = 0;
666     unsigned short keyfile_port = 22;
667    
668     index++;
669     negated = data[index] == '!';
670    
671     if (negated) {
672     index++;
673     bracketed = data[index] == '[';
674     if (bracketed) {
675     end_bracket = strstr(data + index + 1, "]:");
676     if (end_bracket != NULL) {
677     *end_bracket = ' ';
678     index++;
679     }
680     }
681     host_matched = match_pattern(data + index, hostname);
682     if (bracketed && end_bracket != NULL) {
683     *end_bracket = ']';
684     keyfile_port = atoi(end_bracket + 2);
685     }
686     if (host_matched && keyfile_port == tcpport) {
687     return index + eat_to_end_of_line(data + index);
688     }
689     }
690     else {
691     bracketed = data[index] == '[';
692     if (bracketed) {
693     end_bracket = strstr(data + index + 1, "]:");
694     if (end_bracket != NULL) {
695     *end_bracket = ' ';
696     index++;
697     }
698     }
699     host_matched = match_pattern(data + index, hostname);
700     if (bracketed && end_bracket != NULL) {
701     *end_bracket = ']';
702     keyfile_port = atoi(end_bracket + 2);
703     }
704     if (host_matched && keyfile_port == tcpport) {
705     matched = 1;
706     }
707     }
708    
709     index += eat_to_end_of_pattern(data + index);
710     } while (data[index] == ',');
711    
712     if (!matched) {
713     return index + eat_to_end_of_line(data + index);
714     }
715     else {
716     // ���������������t�H�[�}�b�g��������
717     // �����A���������v�����G���g�����������������������B
718     /*
719     [SSH1]
720     192.168.1.2 1024 35 13032....
721    
722     [SSH2]
723     192.168.1.2 ssh-rsa AAAAB3NzaC1....
724     192.168.1.2 ssh-dss AAAAB3NzaC1....
725     192.168.1.2 rsa AAAAB3NzaC1....
726     192.168.1.2 dsa AAAAB3NzaC1....
727     192.168.1.2 rsa1 AAAAB3NzaC1....
728     */
729     int rsa1_key_bits;
730    
731     index += eat_spaces(data + index);
732    
733     rsa1_key_bits = atoi(data + index);
734     if (rsa1_key_bits > 0) { // RSA1������
735     if (!SSHv1(pvar)) { // SSH2��������������������
736     return index + eat_to_end_of_line(data + index);
737     }
738 yutakapon 5847
739     key = key_new(KEY_RSA1);
740     key->bits = rsa1_key_bits;
741    
742 yutakapon 5846 index += eat_digits(data + index);
743     index += eat_spaces(data + index);
744 yutakapon 5847 key->exp = parse_bignum(data + index);
745 yutakapon 5846
746     index += eat_digits(data + index);
747     index += eat_spaces(data + index);
748 yutakapon 5847 key->mod = parse_bignum(data + index);
749 yutakapon 5846
750 yutakapon 5847 // setup
751     *keyptr = key;
752    
753 yutakapon 5846 }
754     else {
755     char *cp, *p;
756    
757     if (!SSHv2(pvar)) { // SSH1��������������������
758     return index + eat_to_end_of_line(data + index);
759     }
760    
761     cp = data + index;
762     p = strchr(cp, ' ');
763     if (p == NULL) {
764     return index + eat_to_end_of_line(data + index);
765     }
766     index += (p - cp); // setup index
767     *p = '\0';
768     ktype = get_keytype_from_name(cp);
769     *p = ' ';
770    
771     index += eat_spaces(data + index); // update index
772    
773 doda 6621 // base64 decode
774     key = parse_base64data(data + index);
775 yutakapon 5846 if (key == NULL) {
776     return index + eat_to_end_of_line(data + index);
777     }
778    
779     // setup
780     *keyptr = key;
781    
782     index += eat_base64(data + index);
783     index += eat_spaces(data + index);
784     }
785    
786     return index + eat_to_end_of_line(data + index);
787     }
788     }
789    
790     // known_hosts�t�@�C�������z�X�g���J�������������B
791     // �������������������������������AHost key rotation�p���V�K���p�������B
792     //
793     // return 1: success
794     // 0: fail
795     int HOSTS_hostkey_foreach(PTInstVar pvar, hostkeys_foreach_fn *callback, void *ctx)
796     {
797     int success = 0;
798     int suppress_errors = 1;
799     unsigned short tcpport;
800 doda 6801 char *filename;
801 yutakapon 5846 char *hostname;
802     Key *key;
803    
804     if (!begin_read_host_files(pvar, 1)) {
805     goto error;
806     }
807    
808     // Host key rotation�����Aknown_hosts �t�@�C�������������������A
809     // ������������1�������t�@�C�������������i2�������t�@�C����ReadOnly�������j�B
810     filename = pvar->hosts_state.file_names[pvar->hosts_state.file_num];
811     pvar->hosts_state.file_num++;
812    
813     pvar->hosts_state.file_data_index = -1;
814     if (filename[0] != 0) {
815     if (begin_read_file(pvar, filename, suppress_errors)) {
816     pvar->hosts_state.file_data_index = 0;
817     }
818     }
819     if (pvar->hosts_state.file_data_index == -1)
820     goto error;
821    
822     // ���������������z�X�g�����|�[�g�����B
823     hostname = pvar->ssh_state.hostname;
824     tcpport = pvar->ssh_state.tcpport;
825    
826     // known_hosts�t�@�C�������e�������� pvar->hosts_state.file_data �������������������B
827     // ������ \0 �B
828     while (pvar->hosts_state.file_data[pvar->hosts_state.file_data_index] != 0) {
829     key = NULL;
830    
831     pvar->hosts_state.file_data_index +=
832     parse_hostkey_file(pvar, hostname, tcpport,
833     pvar->hosts_state.file_data +
834     pvar->hosts_state.file_data_index,
835     &key);
836    
837 yutakapon 5847 // �Y�����������������������A�R�[���o�b�N�����������o���B
838 yutakapon 5846 if (key != NULL) {
839 yutakapon 5847 if (callback(key, ctx) == 0)
840     key_free(key);
841 yutakapon 5846 }
842     }
843    
844     success = 1;
845    
846     error:
847     finish_read_host_files(pvar, 1);
848    
849     return (success);
850     }
851    
852    
853 doda 6801 static BOOL equal_mp_ints(unsigned char *num1,
854     unsigned char *num2)
855 maya 3227 {
856     if (num1 == NULL || num2 == NULL) {
857     return FALSE;
858     } else {
859     uint32 bytes = (get_ushort16_MSBfirst(num1) + 7) / 8;
860    
861     if (bytes != (get_ushort16_MSBfirst(num2) + 7) / 8) {
862     return FALSE; /* different byte lengths */
863     } else {
864     return memcmp(num1 + 2, num2 + 2, bytes) == 0;
865     }
866     }
867     }
868    
869 yutakapon 5843
870     // ���J�������r���s���B
871     //
872     // return
873 maya 4332 // -1 ... �����^������
874     // 0 ... ����������
875     // 1 ... ������
876 yutakapon 5843 int HOSTS_compare_public_key(Key *src, Key *key)
877 maya 3227 {
878     int bits;
879 doda 6801 unsigned char *exp;
880     unsigned char *mod;
881 maya 4321 const EC_GROUP *group;
882     const EC_POINT *pa, *pb;
883 yutakapon 5545 Key *a, *b;
884 yutakapon 8316 BIGNUM *e = NULL, *n = NULL;
885     BIGNUM *se = NULL, *sn = NULL;
886     BIGNUM *p, *q, *g, *pub_key;
887     BIGNUM *sp, *sq, *sg, *spub_key;
888 maya 3227
889 yutakapon 5843 if (src->type != key->type) {
890 maya 4332 return -1;
891     }
892    
893 maya 4321 switch (key->type) {
894     case KEY_RSA1: // SSH1 host public key
895 maya 3227 bits = key->bits;
896     exp = key->exp;
897     mod = key->mod;
898    
899     /* just check for equal exponent and modulus */
900 yutakapon 5843 return equal_mp_ints(exp, src->exp)
901     && equal_mp_ints(mod, src->mod);
902 maya 3227 /*
903     return equal_mp_ints(exp, pvar->hosts_state.key_exp)
904 yutakapon 5843 && equal_mp_ints(mod, pvar->hosts_state.key_mod);
905     */
906 maya 3227
907 maya 4321 case KEY_RSA: // SSH2 RSA host public key
908 yutakapon 8316 RSA_get0_key(key->rsa, &n, &e, NULL);
909     RSA_get0_key(src->rsa, &sn, &se, NULL);
910 yutakapon 5843 return key->rsa != NULL && src->rsa != NULL &&
911 yutakapon 8316 BN_cmp(e, se) == 0 &&
912     BN_cmp(n, sn) == 0;
913 maya 3227
914 maya 4321 case KEY_DSA: // SSH2 DSA host public key
915 yutakapon 8316 DSA_get0_pqg(key->dsa, &p, &q, &g);
916     DSA_get0_pqg(src->dsa, &sp, &sq, &sg);
917     DSA_get0_key(key->dsa, &pub_key, NULL);
918     DSA_get0_key(src->dsa, &spub_key, NULL);
919 yutakapon 5843 return key->dsa != NULL && src->dsa &&
920 yutakapon 8316 BN_cmp(p, sp) == 0 &&
921     BN_cmp(q, sq) == 0 &&
922     BN_cmp(g, sg) == 0 &&
923     BN_cmp(pub_key, spub_key) == 0;
924 maya 3227
925 maya 4321 case KEY_ECDSA256:
926     case KEY_ECDSA384:
927     case KEY_ECDSA521:
928 yutakapon 5843 if (key->ecdsa == NULL || src->ecdsa == NULL) {
929 maya 4321 return FALSE;
930     }
931     group = EC_KEY_get0_group(key->ecdsa);
932     pa = EC_KEY_get0_public_key(key->ecdsa),
933 yutakapon 5843 pb = EC_KEY_get0_public_key(src->ecdsa);
934 maya 4321 return EC_POINT_cmp(group, pa, pb, NULL) == 0;
935    
936 yutakapon 5545 case KEY_ED25519:
937     a = key;
938 yutakapon 5843 b = src;
939 yutakapon 5545 return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
940 yutakapon 5843 memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;
941 yutakapon 5545
942 maya 4321 default:
943 maya 4307 return FALSE;
944     }
945 yutakapon 5843 }
946 maya 3227
947 maya 6152 #if 0
948     // pvar->hosts_state.hostkey ���n���������J����������������������
949 yutakapon 5843 // -1 ... �����^������
950     // 0 ... ����������
951     // 1 ... ������
952     static int match_key(PTInstVar pvar, Key *key)
953     {
954     return HOSTS_compare_public_key(&pvar->hosts_state.hostkey, key);
955 maya 3227 }
956 maya 6152 #endif
957 maya 3227
958 maya 6132 static void hosts_dlg_set_fingerprint(PTInstVar pvar, HWND dlg, digest_algorithm dgst_alg)
959     {
960     char *fp = NULL;
961    
962     // fingerprint����������
963     switch (dgst_alg) {
964     case SSH_DIGEST_MD5:
965     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX, dgst_alg);
966 maya 6158 if (fp != NULL) {
967     SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
968     free(fp);
969     }
970 maya 6132 break;
971     case SSH_DIGEST_SHA256:
972 maya 6158 default:
973     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_BASE64, SSH_DIGEST_SHA256);
974     if (fp != NULL) {
975     SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
976     free(fp);
977     }
978 maya 6132 break;
979     }
980    
981     // �r�W���A����fingerprint���\������
982     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART, dgst_alg);
983 maya 6158 if (fp != NULL) {
984     SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETTEXT, 0, (LPARAM)fp);
985     free(fp);
986     }
987 maya 6132 }
988    
989 maya 3227 static void init_hosts_dlg(PTInstVar pvar, HWND dlg)
990     {
991 zmatsuo 8542 wchar_t buf[MAX_UIMSG];
992     wchar_t buf2[2048];
993     size_t i, j;
994     wchar_t ch;
995     wchar_t *hostW;
996 maya 3227
997     // static text�� # �������z�X�g�����u������
998 zmatsuo 8542 _GetDlgItemTextW(dlg, IDC_HOSTWARNING, buf, sizeof(buf));
999     for (i = 0; (ch = buf[i]) != 0 && ch != L'#'; i++) {
1000 maya 3227 buf2[i] = ch;
1001     }
1002 zmatsuo 8542 hostW = ToWcharA(pvar->hosts_state.prefetched_hostname);
1003     wcsncpy_s(buf2 + i, _countof(buf2) - i, hostW, _TRUNCATE);
1004     free(hostW);
1005     j = i + wcslen(buf2 + i);
1006     for (; buf[i] == L'#'; i++) {
1007 maya 3227 }
1008 zmatsuo 8542 wcsncpy_s(buf2 + j, _countof(buf2) - j, buf + i, _TRUNCATE);
1009 maya 3227
1010 zmatsuo 8542 _SetDlgItemTextW(dlg, IDC_HOSTWARNING, buf2);
1011 maya 3227
1012 zmatsuo 7714 pvar->hFontFixed = UTIL_get_lang_fixedfont(dlg, pvar->ts->UILanguageFile);
1013     if (pvar->hFontFixed != NULL) {
1014     SendDlgItemMessage(dlg, IDC_FP_RANDOMART, WM_SETFONT,
1015     (WPARAM)pvar->hFontFixed, MAKELPARAM(TRUE,0));
1016     }
1017 maya 3227
1018 maya 6145 CheckDlgButton(dlg, IDC_FP_HASH_ALG_SHA256, TRUE);
1019     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
1020 maya 3227 }
1021    
1022 doda 6801 static int print_mp_int(char *buf, unsigned char *mp)
1023 maya 3227 {
1024     int i = 0, j, k;
1025     BIGNUM *num = BN_new();
1026     int ch;
1027    
1028     BN_bin2bn(mp + 2, (get_ushort16_MSBfirst(mp) + 7) / 8, num);
1029    
1030     do {
1031     buf[i] = (char) ((BN_div_word(num, 10)) + '0');
1032     i++;
1033     } while (!BN_is_zero(num));
1034    
1035     /* we need to reverse the digits */
1036     for (j = 0, k = i - 1; j < k; j++, k--) {
1037     ch = buf[j];
1038     buf[j] = buf[k];
1039     buf[k] = ch;
1040     }
1041    
1042     buf[i] = 0;
1043     return i;
1044     }
1045    
1046     //
1047     // known_hosts �t�@�C�������������G���g�������������B
1048     //
1049 doda 6801 static char *format_host_key(PTInstVar pvar)
1050 maya 3227 {
1051     int host_len = strlen(pvar->hosts_state.prefetched_hostname);
1052     char *result = NULL;
1053     int index;
1054 maya 4378 ssh_keytype type = pvar->hosts_state.hostkey.type;
1055 maya 3227
1056 maya 4321 switch (type) {
1057     case KEY_RSA1:
1058     {
1059 maya 3227 int result_len = host_len + 50 + 8 +
1060     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.exp) / 3 +
1061     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.mod) / 3;
1062 doda 6801 result = (char *) malloc(result_len);
1063 maya 3227
1064     if (pvar->ssh_state.tcpport == 22) {
1065     strncpy_s(result, result_len, pvar->hosts_state.prefetched_hostname, _TRUNCATE);
1066     index = host_len;
1067     }
1068     else {
1069     _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
1070     pvar->hosts_state.prefetched_hostname,
1071     pvar->ssh_state.tcpport);
1072     index = strlen(result);
1073     }
1074    
1075 yutakapon 7889 // ��2����(sizeOfBuffer)���w�������������A�������o�b�t�@�T�C�Y����
1076     // �����������������������C�������B
1077     // �|�[�g������22���O�������AVS2005��debug build�����Aadd_host_key()��
1078     // free(keydata)���A���������u�u���[�N�|�C���g���������������B�q�[�v������������������
1079     // �����������l�����������B�v���������O�����������B
1080     // release build�����������������B
1081     _snprintf_s(result + index, result_len - index, _TRUNCATE,
1082 maya 3227 " %d ", pvar->hosts_state.hostkey.bits);
1083     index += strlen(result + index);
1084     index += print_mp_int(result + index, pvar->hosts_state.hostkey.exp);
1085     result[index] = ' ';
1086     index++;
1087     index += print_mp_int(result + index, pvar->hosts_state.hostkey.mod);
1088     strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
1089    
1090 maya 4321 break;
1091     }
1092    
1093     case KEY_RSA:
1094     case KEY_DSA:
1095     case KEY_ECDSA256:
1096     case KEY_ECDSA384:
1097     case KEY_ECDSA521:
1098 yutakapon 5545 case KEY_ED25519:
1099 maya 4321 {
1100 maya 3227 Key *key = &pvar->hosts_state.hostkey;
1101     char *blob = NULL;
1102     int blen, uulen, msize;
1103     char *uu = NULL;
1104     int n;
1105    
1106     key_to_blob(key, &blob, &blen);
1107     uulen = 2 * blen;
1108     uu = malloc(uulen);
1109     if (uu == NULL) {
1110     goto error;
1111     }
1112     n = uuencode(blob, blen, uu, uulen);
1113     if (n > 0) {
1114     msize = host_len + 50 + uulen;
1115     result = malloc(msize);
1116     if (result == NULL) {
1117     goto error;
1118     }
1119    
1120     // setup
1121     if (pvar->ssh_state.tcpport == 22) {
1122     _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
1123     pvar->hosts_state.prefetched_hostname,
1124     get_sshname_from_key(key),
1125     uu);
1126     } else {
1127     _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
1128     pvar->hosts_state.prefetched_hostname,
1129     pvar->ssh_state.tcpport,
1130     get_sshname_from_key(key),
1131     uu);
1132     }
1133     }
1134     error:
1135     if (blob != NULL)
1136     free(blob);
1137     if (uu != NULL)
1138     free(uu);
1139    
1140 maya 4321 break;
1141     }
1142    
1143     default:
1144 maya 3227 return NULL;
1145    
1146     }
1147    
1148     return result;
1149     }
1150    
1151 doda 6801 static char *format_specified_host_key(Key *key, char *hostname, unsigned short tcpport)
1152 yutakapon 5849 {
1153     int host_len = strlen(hostname);
1154     char *result = NULL;
1155     int index;
1156     ssh_keytype type = key->type;
1157    
1158     switch (type) {
1159     case KEY_RSA1:
1160     {
1161     int result_len = host_len + 50 + 8 +
1162     get_ushort16_MSBfirst(key->exp) / 3 +
1163     get_ushort16_MSBfirst(key->mod) / 3;
1164 doda 6801 result = (char *) malloc(result_len);
1165 yutakapon 5849
1166     if (tcpport == 22) {
1167     strncpy_s(result, result_len, hostname, _TRUNCATE);
1168     index = host_len;
1169     }
1170     else {
1171     _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
1172     hostname,
1173     tcpport);
1174     index = strlen(result);
1175     }
1176    
1177     _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
1178     " %d ", key->bits);
1179     index += strlen(result + index);
1180     index += print_mp_int(result + index, key->exp);
1181     result[index] = ' ';
1182     index++;
1183     index += print_mp_int(result + index, key->mod);
1184     strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
1185    
1186     break;
1187     }
1188    
1189     case KEY_RSA:
1190     case KEY_DSA:
1191     case KEY_ECDSA256:
1192     case KEY_ECDSA384:
1193     case KEY_ECDSA521:
1194     case KEY_ED25519:
1195     {
1196     //Key *key = &pvar->hosts_state.hostkey;
1197     char *blob = NULL;
1198     int blen, uulen, msize;
1199     char *uu = NULL;
1200     int n;
1201    
1202     key_to_blob(key, &blob, &blen);
1203     uulen = 2 * blen;
1204     uu = malloc(uulen);
1205     if (uu == NULL) {
1206     goto error;
1207     }
1208     n = uuencode(blob, blen, uu, uulen);
1209     if (n > 0) {
1210     msize = host_len + 50 + uulen;
1211     result = malloc(msize);
1212     if (result == NULL) {
1213     goto error;
1214     }
1215    
1216     // setup
1217     if (tcpport == 22) {
1218     _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
1219     hostname,
1220     get_sshname_from_key(key),
1221     uu);
1222     }
1223     else {
1224     _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
1225     hostname,
1226     tcpport,
1227     get_sshname_from_key(key),
1228     uu);
1229     }
1230     }
1231     error:
1232     if (blob != NULL)
1233     free(blob);
1234     if (uu != NULL)
1235     free(uu);
1236    
1237     break;
1238     }
1239    
1240     default:
1241     return NULL;
1242    
1243     }
1244    
1245     return result;
1246     }
1247    
1248 maya 3227 static void add_host_key(PTInstVar pvar)
1249     {
1250 doda 6801 char *name = NULL;
1251 maya 3227
1252     if ( pvar->hosts_state.file_names != NULL)
1253     name = pvar->hosts_state.file_names[0];
1254    
1255     if (name == NULL || name[0] == 0) {
1256     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1257     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1258     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1259     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1260     } else {
1261 doda 6801 char *keydata = format_host_key(pvar);
1262 maya 3227 int length = strlen(keydata);
1263     int fd;
1264     int amount_written;
1265     int close_result;
1266     char buf[FILENAME_MAX];
1267    
1268     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1269     fd = _open(buf,
1270     _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1271     _S_IREAD | _S_IWRITE);
1272     if (fd == -1) {
1273     if (errno == EACCES) {
1274     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1275     "An error occurred while trying to write the host key.\n"
1276     "You do not have permission to write to the known-hosts file.");
1277     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1278     } else {
1279     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1280     "An error occurred while trying to write the host key.\n"
1281     "The host key could not be written.");
1282     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1283     }
1284     return;
1285     }
1286    
1287     amount_written = _write(fd, keydata, length);
1288     free(keydata);
1289     close_result = _close(fd);
1290    
1291     if (amount_written != length || close_result == -1) {
1292     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1293     "An error occurred while trying to write the host key.\n"
1294     "The host key could not be written.");
1295     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1296     }
1297     }
1298     }
1299    
1300 yutakapon 5849 // �w�������L�[�� known_hosts �����������B
1301     void HOSTS_add_host_key(PTInstVar pvar, Key *key)
1302     {
1303 doda 6801 char *name = NULL;
1304 yutakapon 5849 char *hostname;
1305     unsigned short tcpport;
1306    
1307     hostname = pvar->ssh_state.hostname;
1308     tcpport = pvar->ssh_state.tcpport;
1309    
1310     if (pvar->hosts_state.file_names != NULL)
1311     name = pvar->hosts_state.file_names[0];
1312    
1313     if (name == NULL || name[0] == 0) {
1314     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1315     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1316     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1317     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1318     }
1319     else {
1320 doda 6801 char *keydata = format_specified_host_key(key, hostname, tcpport);
1321 yutakapon 5849 int length = strlen(keydata);
1322     int fd;
1323     int amount_written;
1324     int close_result;
1325     char buf[FILENAME_MAX];
1326    
1327     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1328     fd = _open(buf,
1329     _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1330     _S_IREAD | _S_IWRITE);
1331     if (fd == -1) {
1332     if (errno == EACCES) {
1333     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1334     "An error occurred while trying to write the host key.\n"
1335     "You do not have permission to write to the known-hosts file.");
1336     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1337     }
1338     else {
1339     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1340     "An error occurred while trying to write the host key.\n"
1341     "The host key could not be written.");
1342     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1343     }
1344     return;
1345     }
1346    
1347     amount_written = _write(fd, keydata, length);
1348     free(keydata);
1349     close_result = _close(fd);
1350    
1351     if (amount_written != length || close_result == -1) {
1352     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1353     "An error occurred while trying to write the host key.\n"
1354     "The host key could not be written.");
1355     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1356     }
1357     }
1358     }
1359    
1360 maya 3227 //
1361     // �����z�X�g�����e���������L�[����������
1362     // add_host_key ����������������
1363     //
1364     static void delete_different_key(PTInstVar pvar)
1365     {
1366 doda 6801 char *name = pvar->hosts_state.file_names[0];
1367 maya 3227
1368     if (name == NULL || name[0] == 0) {
1369     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1370     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1371     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1372     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1373     }
1374     else {
1375 maya 6152 Key key; // known_hosts���o�^������������
1376 maya 3227 int length;
1377     char filename[MAX_PATH];
1378     char tmp[L_tmpnam];
1379     int fd;
1380     int amount_written = 0;
1381     int close_result;
1382     int data_index = 0;
1383     char buf[FILENAME_MAX];
1384    
1385     // �������������t�@�C�����J��
1386     _getcwd(filename, sizeof(filename));
1387     tmpnam_s(tmp,sizeof(tmp));
1388     strcat_s(filename, sizeof(filename), tmp);
1389     fd = _open(filename,
1390     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1391     _S_IREAD | _S_IWRITE);
1392    
1393     if (fd == -1) {
1394     if (errno == EACCES) {
1395     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1396     "An error occurred while trying to write the host key.\n"
1397     "You do not have permission to write to the known-hosts file.");
1398     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1399     } else {
1400     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1401     "An error occurred while trying to write the host key.\n"
1402     "The host key could not be written.");
1403     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1404     }
1405     return;
1406     }
1407    
1408 maya 6152 // �t�@�C��������������
1409 maya 6147 memset(&key, 0, sizeof(key));
1410 maya 3227 begin_read_host_files(pvar, 0);
1411     do {
1412     int host_index = 0;
1413     int matched = 0;
1414     int keybits = 0;
1415 doda 6801 char *data;
1416 maya 3227 int do_write = 0;
1417     length = amount_written = 0;
1418    
1419 maya 6152 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1, &key)) {
1420 maya 3227 break;
1421     }
1422    
1423     if (data_index == pvar->hosts_state.file_data_index) {
1424     // index ���i������ == ��������������
1425     break;
1426     }
1427    
1428     data = pvar->hosts_state.file_data + data_index;
1429     host_index = eat_spaces(data);
1430    
1431     if (data[host_index] == '#') {
1432     do_write = 1;
1433     }
1434     else {
1435     // �z�X�g������
1436     host_index--;
1437     do {
1438     int negated;
1439     int bracketed;
1440     char *end_bracket;
1441     int host_matched = 0;
1442     unsigned short keyfile_port = 22;
1443    
1444     host_index++;
1445     negated = data[host_index] == '!';
1446    
1447     if (negated) {
1448     host_index++;
1449     bracketed = data[host_index] == '[';
1450     if (bracketed) {
1451     end_bracket = strstr(data + host_index + 1, "]:");
1452     if (end_bracket != NULL) {
1453     *end_bracket = ' ';
1454     host_index++;
1455     }
1456     }
1457     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1458     if (bracketed && end_bracket != NULL) {
1459     *end_bracket = ']';
1460     keyfile_port = atoi(end_bracket + 2);
1461     }
1462     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1463     matched = 0;
1464     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1465     host_index--;
1466     do {
1467     host_index++;
1468     host_index += eat_to_end_of_pattern(data + host_index);
1469     } while (data[host_index] == ',');
1470     break;
1471     }
1472     }
1473     else {
1474     bracketed = data[host_index] == '[';
1475     if (bracketed) {
1476     end_bracket = strstr(data + host_index + 1, "]:");
1477     if (end_bracket != NULL) {
1478     *end_bracket = ' ';
1479     host_index++;
1480     }
1481     }
1482     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1483     if (bracketed && end_bracket != NULL) {
1484     *end_bracket = ']';
1485     keyfile_port = atoi(end_bracket + 2);
1486     }
1487     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1488     matched = 1;
1489     }
1490     }
1491     host_index += eat_to_end_of_pattern(data + host_index);
1492     } while (data[host_index] == ',');
1493    
1494     // �z�X�g������������
1495 maya 4332 if (!matched) {
1496 maya 3227 do_write = 1;
1497     }
1498 maya 4332 // �z�X�g��������
1499 maya 3227 else {
1500 maya 4332 // �����`�������� or ���v�����L�[
1501 maya 6152 if (HOSTS_compare_public_key(&pvar->hosts_state.hostkey, &key) != 0) {
1502 maya 4332 do_write = 1;
1503 maya 3227 }
1504 maya 4332 // �����`�������������v�������L�[���X�L�b�v������
1505 maya 3227 }
1506     }
1507    
1508     // ������������
1509     if (do_write) {
1510     length = pvar->hosts_state.file_data_index - data_index;
1511     amount_written =
1512     _write(fd, pvar->hosts_state.file_data + data_index,
1513     length);
1514    
1515     if (amount_written != length) {
1516     goto error1;
1517     }
1518     }
1519     data_index = pvar->hosts_state.file_data_index;
1520     } while (1); // ������������
1521    
1522     error1:
1523     close_result = _close(fd);
1524     if (amount_written != length || close_result == -1) {
1525     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1526     "An error occurred while trying to write the host key.\n"
1527     "The host key could not be written.");
1528     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1529     goto error2;
1530     }
1531    
1532     // �������������t�@�C���������l�[��
1533     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1534     _unlink(buf);
1535     rename(filename, buf);
1536    
1537     error2:
1538     _unlink(filename);
1539    
1540     finish_read_host_files(pvar, 0);
1541 yutakapon 5545
1542     // ���������������������������B
1543 maya 6147 key_init(&key);
1544 maya 3227 }
1545     }
1546    
1547 yutakapon 5849
1548     void HOSTS_delete_all_hostkeys(PTInstVar pvar)
1549     {
1550 doda 6801 char *name = pvar->hosts_state.file_names[0];
1551 yutakapon 5849 char *hostname;
1552     unsigned short tcpport;
1553    
1554     hostname = pvar->ssh_state.hostname;
1555     tcpport = pvar->ssh_state.tcpport;
1556    
1557     if (name == NULL || name[0] == 0) {
1558     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1559     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1560     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1561     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1562     }
1563     else {
1564 maya 6152 Key key; // known_hosts���o�^������������
1565 yutakapon 5849 int length;
1566     char filename[MAX_PATH];
1567     char tmp[L_tmpnam];
1568     int fd;
1569     int amount_written = 0;
1570     int close_result;
1571     int data_index = 0;
1572     char buf[FILENAME_MAX];
1573    
1574     // �������������t�@�C�����J��
1575     _getcwd(filename, sizeof(filename));
1576     tmpnam_s(tmp, sizeof(tmp));
1577     strcat_s(filename, sizeof(filename), tmp);
1578     fd = _open(filename,
1579     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1580     _S_IREAD | _S_IWRITE);
1581    
1582     if (fd == -1) {
1583     if (errno == EACCES) {
1584     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1585     "An error occurred while trying to write the host key.\n"
1586     "You do not have permission to write to the known-hosts file.");
1587     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1588     }
1589     else {
1590     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1591     "An error occurred while trying to write the host key.\n"
1592     "The host key could not be written.");
1593     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1594     }
1595     return;
1596     }
1597    
1598 maya 6152 // �t�@�C��������������
1599 maya 6147 memset(&key, 0, sizeof(key));
1600 yutakapon 5849 begin_read_host_files(pvar, 0);
1601     do {
1602     int host_index = 0;
1603     int matched = 0;
1604     int keybits = 0;
1605 doda 6801 char *data;
1606 yutakapon 5849 int do_write = 0;
1607     length = amount_written = 0;
1608    
1609 maya 6152 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1, &key)) {
1610 yutakapon 5849 break;
1611     }
1612    
1613     if (data_index == pvar->hosts_state.file_data_index) {
1614     // index ���i������ == ��������������
1615     break;
1616     }
1617    
1618     data = pvar->hosts_state.file_data + data_index;
1619     host_index = eat_spaces(data);
1620    
1621     if (data[host_index] == '#') {
1622     do_write = 1;
1623     }
1624     else {
1625     // �z�X�g������
1626     host_index--;
1627     do {
1628     int negated;
1629     int bracketed;
1630     char *end_bracket;
1631     int host_matched = 0;
1632     unsigned short keyfile_port = 22;
1633    
1634     host_index++;
1635     negated = data[host_index] == '!';
1636    
1637     if (negated) {
1638     host_index++;
1639     bracketed = data[host_index] == '[';
1640     if (bracketed) {
1641     end_bracket = strstr(data + host_index + 1, "]:");
1642     if (end_bracket != NULL) {
1643     *end_bracket = ' ';
1644     host_index++;
1645     }
1646     }
1647     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1648     if (bracketed && end_bracket != NULL) {
1649     *end_bracket = ']';
1650     keyfile_port = atoi(end_bracket + 2);
1651     }
1652     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1653     matched = 0;
1654     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1655     host_index--;
1656     do {
1657     host_index++;
1658     host_index += eat_to_end_of_pattern(data + host_index);
1659     } while (data[host_index] == ',');
1660     break;
1661     }
1662     }
1663     else {
1664     bracketed = data[host_index] == '[';
1665     if (bracketed) {
1666     end_bracket = strstr(data + host_index + 1, "]:");
1667     if (end_bracket != NULL) {
1668     *end_bracket = ' ';
1669     host_index++;
1670     }
1671     }
1672     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1673     if (bracketed && end_bracket != NULL) {
1674     *end_bracket = ']';
1675     keyfile_port = atoi(end_bracket + 2);
1676     }
1677     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1678     matched = 1;
1679     }
1680     }
1681     host_index += eat_to_end_of_pattern(data + host_index);
1682     } while (data[host_index] == ',');
1683    
1684     // �z�X�g������������
1685     if (!matched) {
1686     do_write = 1;
1687     }
1688     // �z�X�g��������
1689     else {
1690     // ���������������������B
1691    
1692     }
1693     }
1694    
1695     // ������������
1696     if (do_write) {
1697     length = pvar->hosts_state.file_data_index - data_index;
1698     amount_written =
1699     _write(fd, pvar->hosts_state.file_data + data_index,
1700     length);
1701    
1702     if (amount_written != length) {
1703     goto error1;
1704     }
1705     }
1706     data_index = pvar->hosts_state.file_data_index;
1707     } while (1); // ������������
1708    
1709     error1:
1710     close_result = _close(fd);
1711     if (amount_written != length || close_result == -1) {
1712     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1713     "An error occurred while trying to write the host key.\n"
1714     "The host key could not be written.");
1715     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1716     goto error2;
1717     }
1718    
1719     // �������������t�@�C���������l�[��
1720     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1721     _unlink(buf);
1722     rename(filename, buf);
1723    
1724     error2:
1725     _unlink(filename);
1726    
1727     finish_read_host_files(pvar, 0);
1728    
1729     // ���������������������������B
1730 maya 6147 key_init(&key);
1731 yutakapon 5849 }
1732     }
1733    
1734    
1735 maya 3227 //
1736     // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1737     // ���[�U���m�F�������B
1738     // TODO: finger print���\�����s���B
1739     // (2006.3.25 yutaka)
1740     //
1741 zmatsuo 7896 static INT_PTR CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1742     LPARAM lParam)
1743 maya 3227 {
1744 zmatsuo 8542 static const DlgTextInfo text_info[] = {
1745 zmatsuo 8240 { 0, "DLG_UNKNOWNHOST_TITLE" },
1746     { IDC_HOSTWARNING, "DLG_UNKNOWNHOST_WARNING" },
1747     { IDC_HOSTWARNING2, "DLG_UNKNOWNHOST_WARNING2" },
1748     { IDC_HOSTFINGERPRINT, "DLG_UNKNOWNHOST_FINGERPRINT" },
1749     { IDC_FP_HASH_ALG, "DLG_UNKNOWNHOST_FP_HASH_ALGORITHM" },
1750     { IDC_ADDTOKNOWNHOSTS, "DLG_UNKNOWNHOST_ADD" },
1751     { IDC_CONTINUE, "BTN_CONTINUE" },
1752     { IDCANCEL, "BTN_DISCONNECT" },
1753     };
1754 maya 3227 PTInstVar pvar;
1755    
1756     switch (msg) {
1757     case WM_INITDIALOG:
1758     pvar = (PTInstVar) lParam;
1759     pvar->hosts_state.hosts_dialog = dlg;
1760 zmatsuo 7896 SetWindowLongPtr(dlg, DWLP_USER, lParam);
1761 maya 3227
1762     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1763 doda 8485 SetI18nDlgStrs("TTSSH", dlg, text_info, _countof(text_info), pvar->ts->UILanguageFile);
1764 maya 3227
1765 doda 4559 switch (pvar->dns_key_check) {
1766     case DNS_VERIFY_NOTFOUND:
1767 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1768 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1769     break;
1770     case DNS_VERIFY_MATCH:
1771     case DNS_VERIFY_AUTH_MATCH:
1772 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1773 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1774     break;
1775     case DNS_VERIFY_MISMATCH:
1776     case DNS_VERIFY_AUTH_MISMATCH:
1777 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1778 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1779     break;
1780     case DNS_VERIFY_DIFFERENTTYPE:
1781     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1782 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1783 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1784     break;
1785     }
1786    
1787     switch (pvar->dns_key_check) {
1788     case DNS_VERIFY_MATCH:
1789     case DNS_VERIFY_MISMATCH:
1790     case DNS_VERIFY_DIFFERENTTYPE:
1791 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1792 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1793     break;
1794     case DNS_VERIFY_AUTH_MATCH:
1795     case DNS_VERIFY_AUTH_MISMATCH:
1796     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1797 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1798 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1799     break;
1800     }
1801    
1802 maya 3227 init_hosts_dlg(pvar, dlg);
1803     // add host check box���`�F�b�N���f�t�H���g������������
1804     SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1805    
1806 zmatsuo 7592 CenterWindow(dlg, GetParent(dlg));
1807    
1808 maya 3227 return TRUE; /* because we do not set the focus */
1809    
1810     case WM_COMMAND:
1811 zmatsuo 7896 pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
1812 maya 3227
1813     switch (LOWORD(wParam)) {
1814     case IDC_CONTINUE:
1815 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1816     if (!pvar->cv->Ready) {
1817     goto canceled;
1818     }
1819    
1820 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1821     add_host_key(pvar);
1822     }
1823    
1824 yutakapon 8093 /*
1825     * known_hosts�_�C�A���O���������������~��������
1826     * SSH�T�[�o�����l�S�V�G�[�V���������J�������B
1827     */
1828     HOSTS_resume_session_after_known_hosts(pvar);
1829 maya 3227
1830     pvar->hosts_state.hosts_dialog = NULL;
1831    
1832     EndDialog(dlg, 1);
1833     return TRUE;
1834    
1835     case IDCANCEL: /* kill the connection */
1836 yutakapon 5562 canceled:
1837 yutakapon 8093 /*
1838     * known_hosts���L�����Z�����������A���J�p�����\�[�X���j�����������B
1839     */
1840     HOSTS_cancel_session_after_known_hosts(pvar);
1841    
1842 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
1843 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
1844 maya 3227 EndDialog(dlg, 0);
1845     return TRUE;
1846    
1847 yutakapon 8093 case IDCLOSE:
1848     /*
1849     * known_hosts�����T�[�o�������l�b�g���[�N���f�����������A
1850     * �_�C�A���O�������������B
1851     */
1852     HOSTS_cancel_session_after_known_hosts(pvar);
1853    
1854     pvar->hosts_state.hosts_dialog = NULL;
1855     EndDialog(dlg, 0);
1856     return TRUE;
1857    
1858 maya 6132 case IDC_FP_HASH_ALG_MD5:
1859     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
1860     return TRUE;
1861    
1862     case IDC_FP_HASH_ALG_SHA256:
1863     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
1864     return TRUE;
1865    
1866 maya 3227 default:
1867     return FALSE;
1868     }
1869    
1870 zmatsuo 7714 case WM_DPICHANGED:
1871     pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
1872     if (pvar->hFontFixed != NULL) {
1873     DeleteObject(pvar->hFontFixed);
1874     }
1875     pvar->hFontFixed = UTIL_get_lang_fixedfont(dlg, pvar->ts->UILanguageFile);
1876     if (pvar->hFontFixed != NULL) {
1877     SendDlgItemMessage(dlg, IDC_FP_RANDOMART, WM_SETFONT,
1878     (WPARAM)pvar->hFontFixed, MAKELPARAM(TRUE,0));
1879     }
1880     return FALSE;
1881    
1882     case WM_DESTROY:
1883     pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
1884     if (pvar->hFontFixed != NULL) {
1885     DeleteObject(pvar->hFontFixed);
1886     pvar->hFontFixed = NULL;
1887     }
1888     return FALSE;
1889    
1890 maya 3227 default:
1891     return FALSE;
1892     }
1893     }
1894    
1895     //
1896     // �u�����������m�F�_�C�A���O������
1897     //
1898 zmatsuo 7896 static INT_PTR CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1899     LPARAM lParam)
1900 maya 3227 {
1901 zmatsuo 8542 static const DlgTextInfo text_info[] = {
1902 zmatsuo 8240 { 0, "DLG_UNKNOWNHOST_TITLE" },
1903     { IDC_HOSTWARNING, "DLG_DIFFERENTKEY_WARNING" },
1904     { IDC_HOSTWARNING2, "DLG_DIFFERENTKEY_WARNING2" },
1905     { IDC_HOSTFINGERPRINT, "DLG_DIFFERENTKEY_FINGERPRINT" },
1906     { IDC_FP_HASH_ALG, "DLG_DIFFERENTKEY_FP_HASH_ALGORITHM" },
1907     { IDC_ADDTOKNOWNHOSTS, "DLG_DIFFERENTKEY_REPLACE" },
1908     { IDC_CONTINUE, "BTN_CONTINUE" },
1909     { IDCANCEL, "BTN_DISCONNECT" },
1910     };
1911 maya 3227 PTInstVar pvar;
1912    
1913     switch (msg) {
1914     case WM_INITDIALOG:
1915     pvar = (PTInstVar) lParam;
1916     pvar->hosts_state.hosts_dialog = dlg;
1917 zmatsuo 7896 SetWindowLongPtr(dlg, DWLP_USER, lParam);
1918 maya 3227
1919     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1920 doda 8485 SetI18nDlgStrs("TTSSH", dlg, text_info, _countof(text_info), pvar->ts->UILanguageFile);
1921 maya 3227
1922 doda 4559 switch (pvar->dns_key_check) {
1923     case DNS_VERIFY_NOTFOUND:
1924 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1925 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1926     break;
1927     case DNS_VERIFY_MATCH:
1928     case DNS_VERIFY_AUTH_MATCH:
1929 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1930 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1931     break;
1932     case DNS_VERIFY_MISMATCH:
1933     case DNS_VERIFY_AUTH_MISMATCH:
1934 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1935 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1936     break;
1937     case DNS_VERIFY_DIFFERENTTYPE:
1938     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1939 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1940 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1941     break;
1942     }
1943    
1944     switch (pvar->dns_key_check) {
1945     case DNS_VERIFY_MATCH:
1946     case DNS_VERIFY_MISMATCH:
1947     case DNS_VERIFY_DIFFERENTTYPE:
1948 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1949 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1950     break;
1951     case DNS_VERIFY_AUTH_MATCH:
1952     case DNS_VERIFY_AUTH_MISMATCH:
1953     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1954 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1955 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1956     break;
1957     }
1958    
1959 maya 3227 init_hosts_dlg(pvar, dlg);
1960 zmatsuo 7592 CenterWindow(dlg, GetParent(dlg));
1961 maya 3227 // �f�t�H���g���`�F�b�N����������
1962     return TRUE; /* because we do not set the focus */
1963    
1964     case WM_COMMAND:
1965 zmatsuo 7896 pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
1966 maya 3227
1967     switch (LOWORD(wParam)) {
1968     case IDC_CONTINUE:
1969 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1970     if (!pvar->cv->Ready) {
1971     goto canceled;
1972     }
1973    
1974 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1975     add_host_key(pvar);
1976     delete_different_key(pvar);
1977     }
1978    
1979 yutakapon 8093 /*
1980     * known_hosts�_�C�A���O���������������~��������
1981     * SSH�T�[�o�����l�S�V�G�[�V���������J�������B
1982     */
1983     HOSTS_resume_session_after_known_hosts(pvar);
1984 maya 3227
1985     pvar->hosts_state.hosts_dialog = NULL;
1986    
1987     EndDialog(dlg, 1);
1988     return TRUE;
1989    
1990     case IDCANCEL: /* kill the connection */
1991 yutakapon 5562 canceled:
1992 yutakapon 8093 /*
1993     * known_hosts���L�����Z�����������A���J�p�����\�[�X���j�����������B
1994     */
1995     HOSTS_cancel_session_after_known_hosts(pvar);
1996    
1997 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
1998 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
1999 maya 3227 EndDialog(dlg, 0);
2000     return TRUE;
2001    
2002 yutakapon 8093 case IDCLOSE:
2003     /*
2004     * known_hosts�����T�[�o�������l�b�g���[�N���f�����������A
2005     * �_�C�A���O�������������B
2006     */
2007     HOSTS_cancel_session_after_known_hosts(pvar);
2008    
2009     pvar->hosts_state.hosts_dialog = NULL;
2010     EndDialog(dlg, 0);
2011     return TRUE;
2012    
2013 maya 6132 case IDC_FP_HASH_ALG_MD5:
2014     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2015     return TRUE;
2016    
2017     case IDC_FP_HASH_ALG_SHA256:
2018     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2019     return TRUE;
2020    
2021 maya 3227 default:
2022     return FALSE;
2023     }
2024    
2025 zmatsuo 7714 case WM_DPICHANGED:
2026     pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
2027     if (pvar->hFontFixed != NULL) {
2028     DeleteObject(pvar->hFontFixed);
2029     }
2030     pvar->hFontFixed = UTIL_get_lang_fixedfont(dlg, pvar->ts->UILanguageFile);
2031     if (pvar->hFontFixed != NULL) {
2032     SendDlgItemMessage(dlg, IDC_FP_RANDOMART, WM_SETFONT,
2033     (WPARAM)pvar->hFontFixed, MAKELPARAM(TRUE,0));
2034     }
2035     return FALSE;
2036    
2037     case WM_DESTROY:
2038     pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
2039     if (pvar->hFontFixed != NULL) {
2040     DeleteObject(pvar->hFontFixed);
2041     pvar->hFontFixed = NULL;
2042     }
2043     return FALSE;
2044    
2045 maya 3227 default:
2046     return FALSE;
2047     }
2048     }
2049    
2050 maya 4332 //
2051     // �����z�X�g�����`�����������������m�F�_�C�A���O������
2052     //
2053 zmatsuo 7896 static INT_PTR CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
2054     LPARAM lParam)
2055 maya 4332 {
2056 zmatsuo 8542 static const DlgTextInfo text_info[] = {
2057 zmatsuo 8240 { 0, "DLG_DIFFERENTTYPEKEY_TITLE" },
2058     { IDC_HOSTWARNING, "DLG_DIFFERENTTYPEKEY_WARNING" },
2059     { IDC_HOSTWARNING2, "DLG_DIFFERENTTYPEKEY_WARNING2" },
2060     { IDC_HOSTFINGERPRINT, "DLG_DIFFERENTTYPEKEY_FINGERPRINT" },
2061     { IDC_FP_HASH_ALG, "DLG_DIFFERENTTYPEKEY_FP_HASH_ALGORITHM" },
2062     { IDC_ADDTOKNOWNHOSTS, "DLG_DIFFERENTTYPEKEY_ADD" },
2063     { IDC_CONTINUE, "BTN_CONTINUE" },
2064     { IDCANCEL, "BTN_DISCONNECT" },
2065     };
2066 maya 4332 PTInstVar pvar;
2067    
2068     switch (msg) {
2069     case WM_INITDIALOG:
2070     pvar = (PTInstVar) lParam;
2071     pvar->hosts_state.hosts_dialog = dlg;
2072 zmatsuo 7896 SetWindowLongPtr(dlg, DWLP_USER, lParam);
2073 maya 4332
2074     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
2075 doda 8485 SetI18nDlgStrs("TTSSH", dlg, text_info, _countof(text_info), pvar->ts->UILanguageFile);
2076 maya 4332
2077 doda 4559 switch (pvar->dns_key_check) {
2078     case DNS_VERIFY_NOTFOUND:
2079 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
2080 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2081     break;
2082     case DNS_VERIFY_MATCH:
2083     case DNS_VERIFY_AUTH_MATCH:
2084 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
2085 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2086     break;
2087     case DNS_VERIFY_MISMATCH:
2088     case DNS_VERIFY_AUTH_MISMATCH:
2089 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
2090 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2091     break;
2092     case DNS_VERIFY_DIFFERENTTYPE:
2093     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2094 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
2095 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2096     break;
2097     }
2098    
2099     switch (pvar->dns_key_check) {
2100     case DNS_VERIFY_MATCH:
2101     case DNS_VERIFY_MISMATCH:
2102     case DNS_VERIFY_DIFFERENTTYPE:
2103 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
2104 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2105     break;
2106     case DNS_VERIFY_AUTH_MATCH:
2107     case DNS_VERIFY_AUTH_MISMATCH:
2108     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2109 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
2110 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2111     break;
2112     }
2113    
2114 maya 4332 init_hosts_dlg(pvar, dlg);
2115 zmatsuo 7592 CenterWindow(dlg, GetParent(dlg));
2116 maya 4332 // add host check box ���f�t�H���g�� off ������
2117     // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
2118    
2119     return TRUE; /* because we do not set the focus */
2120    
2121     case WM_COMMAND:
2122 zmatsuo 7896 pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
2123 maya 4332
2124     switch (LOWORD(wParam)) {
2125     case IDC_CONTINUE:
2126 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
2127     if (!pvar->cv->Ready) {
2128     goto canceled;
2129     }
2130    
2131 maya 4332 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
2132     add_host_key(pvar);
2133     }
2134    
2135 yutakapon 8093 /*
2136     * known_hosts�_�C�A���O���������������~��������
2137     * SSH�T�[�o�����l�S�V�G�[�V���������J�������B
2138     */
2139     HOSTS_resume_session_after_known_hosts(pvar);
2140 maya 4332
2141     pvar->hosts_state.hosts_dialog = NULL;
2142    
2143     EndDialog(dlg, 1);
2144     return TRUE;
2145    
2146     case IDCANCEL: /* kill the connection */
2147 yutakapon 5562 canceled:
2148 yutakapon 8093 /*
2149     * known_hosts���L�����Z�����������A���J�p�����\�[�X���j�����������B
2150     */
2151     HOSTS_cancel_session_after_known_hosts(pvar);
2152    
2153 maya 4332 pvar->hosts_state.hosts_dialog = NULL;
2154 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
2155 maya 4332 EndDialog(dlg, 0);
2156     return TRUE;
2157    
2158 yutakapon 8093 case IDCLOSE:
2159     /*
2160     * known_hosts�����T�[�o�������l�b�g���[�N���f�����������A
2161     * �_�C�A���O�������������B
2162     */
2163     HOSTS_cancel_session_after_known_hosts(pvar);
2164    
2165     pvar->hosts_state.hosts_dialog = NULL;
2166     EndDialog(dlg, 0);
2167     return TRUE;
2168    
2169 maya 6132 case IDC_FP_HASH_ALG_MD5:
2170     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2171     return TRUE;
2172    
2173     case IDC_FP_HASH_ALG_SHA256:
2174     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2175     return TRUE;
2176    
2177 maya 4332 default:
2178     return FALSE;
2179     }
2180    
2181 zmatsuo 7714 case WM_DPICHANGED:
2182     pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
2183     if (pvar->hFontFixed != NULL) {
2184     DeleteObject(pvar->hFontFixed);
2185     }
2186     pvar->hFontFixed = UTIL_get_lang_fixedfont(dlg, pvar->ts->UILanguageFile);
2187     if (pvar->hFontFixed != NULL) {
2188     SendDlgItemMessage(dlg, IDC_FP_RANDOMART, WM_SETFONT,
2189     (WPARAM)pvar->hFontFixed, MAKELPARAM(TRUE,0));
2190     }
2191     return FALSE;
2192    
2193     case WM_DESTROY:
2194     pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
2195     if (pvar->hFontFixed != NULL) {
2196     DeleteObject(pvar->hFontFixed);
2197     pvar->hFontFixed = NULL;
2198     }
2199     return FALSE;
2200    
2201 maya 4332 default:
2202     return FALSE;
2203     }
2204     }
2205    
2206 maya 3227 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
2207     {
2208     if (pvar->hosts_state.hosts_dialog == NULL) {
2209 yutakapon 8093 /* known_hosts�������������AID_SSHASYNCMESSAGEBOX ���g����
2210     * MessageBox ���\�������������A�I�[�i�[����(no owner)�����������A
2211     * MessageBox ��Tera Term�������B���������������B
2212     * ���������� GetActiveWindow() �������o�����Aknown_hosts�_�C�A���O��
2213     * �I�[�i�[�� MessageBox ���������ATera Term�������B�����������B
2214     * �������Aknown_hosts�_�C�A���O���I�[�i�[������ Tera Term ���w������
2215     * �����������B
2216     */
2217     HWND cur_active = NULL;
2218 maya 3227
2219     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
2220     cur_active != NULL ? cur_active : wnd,
2221     hosts_add_dlg_proc, (LPARAM) pvar);
2222     }
2223     }
2224    
2225 maya 4330 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
2226 maya 3227 {
2227     if (pvar->hosts_state.hosts_dialog == NULL) {
2228 yutakapon 8093 /* known_hosts�������������AID_SSHASYNCMESSAGEBOX ���g����
2229     * MessageBox ���\�������������A�I�[�i�[����(no owner)�����������A
2230     * MessageBox ��Tera Term�������B���������������B
2231     * ���������� GetActiveWindow() �������o�����Aknown_hosts�_�C�A���O��
2232     * �I�[�i�[�� MessageBox ���������ATera Term�������B�����������B
2233     * �������Aknown_hosts�_�C�A���O���I�[�i�[������ Tera Term ���w������
2234     * �����������B
2235     */
2236     HWND cur_active = NULL;
2237 maya 3227
2238 maya 4330 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
2239 maya 3227 cur_active != NULL ? cur_active : wnd,
2240     hosts_replace_dlg_proc, (LPARAM) pvar);
2241     }
2242     }
2243    
2244 maya 4332 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
2245     {
2246     if (pvar->hosts_state.hosts_dialog == NULL) {
2247 yutakapon 8093 /* known_hosts�������������AID_SSHASYNCMESSAGEBOX ���g����
2248     * MessageBox ���\�������������A�I�[�i�[����(no owner)�����������A
2249     * MessageBox ��Tera Term�������B���������������B
2250     * ���������� GetActiveWindow() �������o�����Aknown_hosts�_�C�A���O��
2251     * �I�[�i�[�� MessageBox ���������ATera Term�������B�����������B
2252     * �������Aknown_hosts�_�C�A���O���I�[�i�[������ Tera Term ���w������
2253     * �����������B
2254     */
2255     HWND cur_active = NULL;
2256 maya 4332
2257     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
2258     cur_active != NULL ? cur_active : wnd,
2259     hosts_add2_dlg_proc, (LPARAM) pvar);
2260     }
2261     }
2262    
2263 yutakapon 8093 /*
2264     * �T�[�o�����������������z�X�g���J�������������`�F�b�N���A
2265     * �K�v�������� known_hosts �_�C�A���O�������o���B
2266     *
2267     * hostname: ���������z�X�g��
2268     * tcpport: �������|�[�g����
2269     * key: �T�[�o���������J��
2270     *
2271     * return:
2272     * TRUE: known_hosts�_�C�A���O�������o�����s�v
2273     * FALSE: known_hosts�_�C�A���O�������o����
2274     *
2275     */
2276 doda 6801 BOOL HOSTS_check_host_key(PTInstVar pvar, char *hostname, unsigned short tcpport, Key *key)
2277 maya 3227 {
2278 doda 4559 int found_different_key = 0, found_different_type_key = 0;
2279 maya 6152 Key key2; // known_hosts���o�^������������
2280 yutakapon 8093 DWORD id;
2281 maya 3227
2282 doda 4559 pvar->dns_key_check = DNS_VERIFY_NONE;
2283    
2284 maya 3227 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
2285     if (pvar->hosts_state.prefetched_hostname != NULL
2286     && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
2287 maya 6152 && HOSTS_compare_public_key(&pvar->hosts_state.hostkey, key) == 1) {
2288 maya 3227
2289 yutakapon 8093 // ���������������B
2290     return TRUE;
2291 maya 3227 }
2292    
2293     // �������������������������A�������_���t�@�C��������������
2294 maya 6152 memset(&key2, 0, sizeof(key2));
2295 maya 3227 if (begin_read_host_files(pvar, 0)) {
2296     do {
2297 maya 6152 if (!read_host_key(pvar, hostname, tcpport, 0, 0, &key2)) {
2298 maya 3227 break;
2299     }
2300    
2301 maya 6152 if (key2.type != KEY_UNSPEC) {
2302     int match = HOSTS_compare_public_key(&key2, key);
2303 maya 4332 if (match == 1) {
2304 maya 3227 finish_read_host_files(pvar, 0);
2305     // ���������G���g�����Q�������A���v�����L�[�������������������B
2306 maya 6998 // About TTSSH �_�C�A���O�����\�����������A�������������������B
2307     key_copy(&pvar->hosts_state.hostkey, key);
2308    
2309 maya 3227 return TRUE;
2310 maya 4332 }
2311     else if (match == 0) {
2312 maya 3227 // �L�[�� known_hosts ���������������A�L�[�����e���������B
2313     found_different_key = 1;
2314     }
2315 maya 4332 else {
2316     // �L�[���`������������
2317     found_different_type_key = 1;
2318     }
2319 maya 3227 }
2320 maya 6152 } while (key2.type != KEY_UNSPEC); // �L�[�����������������������[�v����
2321 maya 3227
2322 maya 6152 key_init(&key2);
2323 maya 3227 finish_read_host_files(pvar, 0);
2324     }
2325    
2326     // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
2327 maya 6147 key_copy(&pvar->hosts_state.hostkey, key);
2328 maya 6145
2329 maya 3227 free(pvar->hosts_state.prefetched_hostname);
2330     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
2331    
2332 yutakapon 3631 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
2333     if (pvar->nocheck_known_hosts == TRUE) {
2334 yutakapon 8093 // ���������������B
2335 yutakapon 3631 return TRUE;
2336     }
2337    
2338 doda 4542 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
2339 maya 6063 pvar->dns_key_check = verify_hostkey_dns(pvar, hostname, key);
2340 doda 4542 }
2341    
2342 maya 3227 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
2343     // �������K�v�����������A�����R�[�������X�����B
2344     // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
2345     // (2007.10.1 yutaka)
2346 yutakapon 8093 /*
2347     * known_hosts�_�C�A���O�����������\�����������������������B
2348     * known_hosts�_�C�A���O���\�������������������A�T�[�o�������f���s�����A
2349     * TTXCloseTCP�������o�����ATTSSH�����\�[�X�������������������B
2350     * SSH�n���h����������known_hosts�_�C�A���O���o�����~���������������A
2351     * �������J�����s���A�N�Z�X���������B
2352     * (2019.9.3 yutaka)
2353     */
2354 maya 3227 if (found_different_key) {
2355 yutakapon 8093 // TTXProcessCommand ���� HOSTS_do_different_key_dialog() �������o���B
2356     id = ID_SSHDIFFERENTKEY;
2357 maya 4332 }
2358     else if (found_different_type_key) {
2359 yutakapon 8093 // TTXProcessCommand ���� HOSTS_do_different_type_key_dialog() �������o���B
2360     id = ID_SSHDIFFERENT_TYPE_KEY;
2361 maya 4332 }
2362     else {
2363 yutakapon 8093 // TTXProcessCommand ���� HOSTS_do_unknown_host_dialog() �������o���B
2364     id = ID_SSHUNKNOWNHOST;
2365 maya 3227 }
2366    
2367 yutakapon 8093 PostMessage(pvar->NotificationWindow, WM_COMMAND, id, 0);
2368    
2369     logprintf(LOG_LEVEL_INFO, "Calling known_hosts dialog...(%s)",
2370     id == ID_SSHDIFFERENTKEY ? "SSHDIFFERENTKEY" :
2371     id == ID_SSHDIFFERENT_TYPE_KEY ? "SSHDIFFERENT_TYPE_KEY" : "SSHUNKNOWNHOST"
2372     );
2373    
2374     return FALSE;
2375 maya 3227 }
2376    
2377 yutakapon 8093 /*
2378     * known_hosts�_�C�A���O�����[�U���F���ASSH�T�[�o�����l�S�V�G�[�V���������J�����B
2379     */
2380     BOOL HOSTS_resume_session_after_known_hosts(PTInstVar pvar)
2381     {
2382     enum ssh_kex_known_hosts type;
2383     int ret = FALSE;
2384    
2385     type = pvar->contents_after_known_hosts.kex_type;
2386     if (type == SSH1_PUBLIC_KEY_KNOWN_HOSTS) {
2387     ret = handle_server_public_key_after_known_hosts(pvar);
2388    
2389     } else if (type == SSH2_DH_KEX_REPLY_KNOWN_HOSTS) {
2390     ret = handle_SSH2_dh_kex_reply_after_known_hosts(pvar);
2391    
2392     } else if (type == SSH2_DH_GEX_REPLY_KNOWN_HOSTS) {
2393     ret = handle_SSH2_dh_gex_reply_after_known_hosts(pvar);
2394    
2395     } else if (type == SSH2_ECDH_KEX_REPLY_KNOWN_HOSTS) {
2396     ret = handle_SSH2_ecdh_kex_reply_after_known_hosts(pvar);
2397    
2398     }
2399    
2400     return (ret);
2401     }
2402    
2403     /*
2404     * known_hosts�_�C�A���O��SSH�������L�����Z������
2405     */
2406     void HOSTS_cancel_session_after_known_hosts(PTInstVar pvar)
2407     {
2408     enum ssh_kex_known_hosts type;
2409    
2410     type = pvar->contents_after_known_hosts.kex_type;
2411     if (type != NONE_KNOWN_HOSTS) {
2412     handle_SSH2_canel_reply_after_known_hosts(pvar);
2413     }
2414    
2415     return;
2416     }
2417    
2418    
2419 maya 3227 void HOSTS_notify_disconnecting(PTInstVar pvar)
2420     {
2421     if (pvar->hosts_state.hosts_dialog != NULL) {
2422 doda 4531 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
2423 maya 3227 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
2424     EnableWindow(pvar->NotificationWindow, TRUE);
2425     }
2426     }
2427    
2428 yutakapon 8093 // TCP�Z�b�V�������N���[�Y�����������Aknown_hosts�_�C�A���O���������������w�����o���B
2429     // HOSTS_notify_disconnecting()�����������A�_�C�A���O���������������A
2430     // SSH�T�[�o�����m���o�������B
2431