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 10073 - (hide annotations) (download) (as text)
Sun Jul 17 15:40:49 2022 UTC (20 months, 3 weeks ago) by doda
File MIME type: text/x-csrc
File size: 67478 byte(s)
ホスト鍵確認ダイアログ表示中にSSH_MSG_EXT_INFOが扱え無い問題を修正した。

問題:
  ホスト鍵がssh_known_hostsに登録されていないサーバへの接続時、サーバ側が
  ユーザ認証でrsa-sha2-256/512に対応していると、ホスト鍵の確認ダイアログ
  表示中に「現在のステージでは想定外のSSH2 メッセージです」というエラーを
  表示して接続を切断してしまう。

原因:
  ホスト鍵確認ダイアログ表示中に送られて来た SSH_MSG_EXT_INFO が扱え無い為。

  ホスト鍵確認ダイアログを表示した時は、KEXの処理を中断するようになっていた。
  その状態で SSH_MSG_NEWKEYS を受信した場合は、SSH_MSG_NEWKEYS の処理も
  保留していた。
  それにより、KEXの処理が中断する事で通信暗号用の鍵/IVが設定されず、また
  SSH_MSG_NEWKEYS の処理も保留している為、受信方向の暗号化(復号)が開始
  されない状態となっていた。
  そこに暗号化された SSH_MSG_EXT_INFO を受信した為、復号せずにそのまま読み
  不明なパケットとして扱っていた。

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