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 9506 - (hide annotations) (download) (as text)
Fri Oct 29 15:19:22 2021 UTC (2 years, 5 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 68843 byte(s)
ユーザーの設定ファイルフォルダの ssh_known_host を使用するよう変更

- 従来は ttermpro.exe(ttssh.dll) のあるフォルダの ssh_known_host だった
- get_teraterm_dir_relative_nameW() を get_home_dir_relative_nameW() へ切り替え

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