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