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 6152 - (hide annotations) (download) (as text)
Wed Nov 18 13:11:56 2015 UTC (8 years, 4 months ago) by maya
File MIME type: text/x-csrc
File size: 70771 byte(s)
鍵の置き換え・Hostkey Rotationの更新後に About TTSSH ダイアログを表示すると落ちる問題を修正
  hosts_state.hostkey を known_hosts の読み込みテンポラリに使っているのをやめた
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     SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
1058     free(fp);
1059     break;
1060     case SSH_DIGEST_SHA256:
1061     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_BASE64, dgst_alg);
1062     SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
1063     free(fp);
1064     break;
1065     }
1066    
1067     // �r�W���A����fingerprint���\������
1068     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART, dgst_alg);
1069     SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETTEXT, 0, (LPARAM)fp);
1070     free(fp);
1071     }
1072    
1073 maya 3227 static void init_hosts_dlg(PTInstVar pvar, HWND dlg)
1074     {
1075     char buf[1024];
1076     char buf2[2048];
1077     int i, j;
1078     int ch;
1079    
1080     // static text�� # �������z�X�g�����u������
1081     GetDlgItemText(dlg, IDC_HOSTWARNING, buf, sizeof(buf));
1082     for (i = 0; (ch = buf[i]) != 0 && ch != '#'; i++) {
1083     buf2[i] = ch;
1084     }
1085     strncpy_s(buf2 + i, sizeof(buf2) - i,
1086     pvar->hosts_state.prefetched_hostname, _TRUNCATE);
1087     j = i + strlen(buf2 + i);
1088     for (; buf[i] == '#'; i++) {
1089     }
1090     strncpy_s(buf2 + j, sizeof(buf2) - j, buf + i, _TRUNCATE);
1091    
1092     SetDlgItemText(dlg, IDC_HOSTWARNING, buf2);
1093    
1094 maya 6132 SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), TRUE);
1095 maya 3227
1096 maya 6145 CheckDlgButton(dlg, IDC_FP_HASH_ALG_SHA256, TRUE);
1097     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
1098 maya 3227 }
1099    
1100     static int print_mp_int(char FAR * buf, unsigned char FAR * mp)
1101     {
1102     int i = 0, j, k;
1103     BIGNUM *num = BN_new();
1104     int ch;
1105    
1106     BN_bin2bn(mp + 2, (get_ushort16_MSBfirst(mp) + 7) / 8, num);
1107    
1108     do {
1109     buf[i] = (char) ((BN_div_word(num, 10)) + '0');
1110     i++;
1111     } while (!BN_is_zero(num));
1112    
1113     /* we need to reverse the digits */
1114     for (j = 0, k = i - 1; j < k; j++, k--) {
1115     ch = buf[j];
1116     buf[j] = buf[k];
1117     buf[k] = ch;
1118     }
1119    
1120     buf[i] = 0;
1121     return i;
1122     }
1123    
1124     //
1125     // known_hosts �t�@�C�������������G���g�������������B
1126     //
1127     static char FAR *format_host_key(PTInstVar pvar)
1128     {
1129     int host_len = strlen(pvar->hosts_state.prefetched_hostname);
1130     char *result = NULL;
1131     int index;
1132 maya 4378 ssh_keytype type = pvar->hosts_state.hostkey.type;
1133 maya 3227
1134 maya 4321 switch (type) {
1135     case KEY_RSA1:
1136     {
1137 maya 3227 int result_len = host_len + 50 + 8 +
1138     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.exp) / 3 +
1139     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.mod) / 3;
1140     result = (char FAR *) malloc(result_len);
1141    
1142     if (pvar->ssh_state.tcpport == 22) {
1143     strncpy_s(result, result_len, pvar->hosts_state.prefetched_hostname, _TRUNCATE);
1144     index = host_len;
1145     }
1146     else {
1147     _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
1148     pvar->hosts_state.prefetched_hostname,
1149     pvar->ssh_state.tcpport);
1150     index = strlen(result);
1151     }
1152    
1153     _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
1154     " %d ", pvar->hosts_state.hostkey.bits);
1155     index += strlen(result + index);
1156     index += print_mp_int(result + index, pvar->hosts_state.hostkey.exp);
1157     result[index] = ' ';
1158     index++;
1159     index += print_mp_int(result + index, pvar->hosts_state.hostkey.mod);
1160     strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
1161    
1162 maya 4321 break;
1163     }
1164    
1165     case KEY_RSA:
1166     case KEY_DSA:
1167     case KEY_ECDSA256:
1168     case KEY_ECDSA384:
1169     case KEY_ECDSA521:
1170 yutakapon 5545 case KEY_ED25519:
1171 maya 4321 {
1172 maya 3227 Key *key = &pvar->hosts_state.hostkey;
1173     char *blob = NULL;
1174     int blen, uulen, msize;
1175     char *uu = NULL;
1176     int n;
1177    
1178     key_to_blob(key, &blob, &blen);
1179     uulen = 2 * blen;
1180     uu = malloc(uulen);
1181     if (uu == NULL) {
1182     goto error;
1183     }
1184     n = uuencode(blob, blen, uu, uulen);
1185     if (n > 0) {
1186     msize = host_len + 50 + uulen;
1187     result = malloc(msize);
1188     if (result == NULL) {
1189     goto error;
1190     }
1191    
1192     // setup
1193     if (pvar->ssh_state.tcpport == 22) {
1194     _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
1195     pvar->hosts_state.prefetched_hostname,
1196     get_sshname_from_key(key),
1197     uu);
1198     } else {
1199     _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
1200     pvar->hosts_state.prefetched_hostname,
1201     pvar->ssh_state.tcpport,
1202     get_sshname_from_key(key),
1203     uu);
1204     }
1205     }
1206     error:
1207     if (blob != NULL)
1208     free(blob);
1209     if (uu != NULL)
1210     free(uu);
1211    
1212 maya 4321 break;
1213     }
1214    
1215     default:
1216 maya 3227 return NULL;
1217    
1218     }
1219    
1220     return result;
1221     }
1222    
1223 yutakapon 5849 static char FAR *format_specified_host_key(Key *key, char *hostname, unsigned short tcpport)
1224     {
1225     int host_len = strlen(hostname);
1226     char *result = NULL;
1227     int index;
1228     ssh_keytype type = key->type;
1229    
1230     switch (type) {
1231     case KEY_RSA1:
1232     {
1233     int result_len = host_len + 50 + 8 +
1234     get_ushort16_MSBfirst(key->exp) / 3 +
1235     get_ushort16_MSBfirst(key->mod) / 3;
1236     result = (char FAR *) malloc(result_len);
1237    
1238     if (tcpport == 22) {
1239     strncpy_s(result, result_len, hostname, _TRUNCATE);
1240     index = host_len;
1241     }
1242     else {
1243     _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
1244     hostname,
1245     tcpport);
1246     index = strlen(result);
1247     }
1248    
1249     _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
1250     " %d ", key->bits);
1251     index += strlen(result + index);
1252     index += print_mp_int(result + index, key->exp);
1253     result[index] = ' ';
1254     index++;
1255     index += print_mp_int(result + index, key->mod);
1256     strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
1257    
1258     break;
1259     }
1260    
1261     case KEY_RSA:
1262     case KEY_DSA:
1263     case KEY_ECDSA256:
1264     case KEY_ECDSA384:
1265     case KEY_ECDSA521:
1266     case KEY_ED25519:
1267     {
1268     //Key *key = &pvar->hosts_state.hostkey;
1269     char *blob = NULL;
1270     int blen, uulen, msize;
1271     char *uu = NULL;
1272     int n;
1273    
1274     key_to_blob(key, &blob, &blen);
1275     uulen = 2 * blen;
1276     uu = malloc(uulen);
1277     if (uu == NULL) {
1278     goto error;
1279     }
1280     n = uuencode(blob, blen, uu, uulen);
1281     if (n > 0) {
1282     msize = host_len + 50 + uulen;
1283     result = malloc(msize);
1284     if (result == NULL) {
1285     goto error;
1286     }
1287    
1288     // setup
1289     if (tcpport == 22) {
1290     _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
1291     hostname,
1292     get_sshname_from_key(key),
1293     uu);
1294     }
1295     else {
1296     _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
1297     hostname,
1298     tcpport,
1299     get_sshname_from_key(key),
1300     uu);
1301     }
1302     }
1303     error:
1304     if (blob != NULL)
1305     free(blob);
1306     if (uu != NULL)
1307     free(uu);
1308    
1309     break;
1310     }
1311    
1312     default:
1313     return NULL;
1314    
1315     }
1316    
1317     return result;
1318     }
1319    
1320 maya 3227 static void add_host_key(PTInstVar pvar)
1321     {
1322     char FAR *name = NULL;
1323    
1324     if ( pvar->hosts_state.file_names != NULL)
1325     name = pvar->hosts_state.file_names[0];
1326    
1327     if (name == NULL || name[0] == 0) {
1328     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1329     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1330     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1331     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1332     } else {
1333     char FAR *keydata = format_host_key(pvar);
1334     int length = strlen(keydata);
1335     int fd;
1336     int amount_written;
1337     int close_result;
1338     char buf[FILENAME_MAX];
1339    
1340     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1341     fd = _open(buf,
1342     _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1343     _S_IREAD | _S_IWRITE);
1344     if (fd == -1) {
1345     if (errno == EACCES) {
1346     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1347     "An error occurred while trying to write the host key.\n"
1348     "You do not have permission to write to the known-hosts file.");
1349     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1350     } else {
1351     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1352     "An error occurred while trying to write the host key.\n"
1353     "The host key could not be written.");
1354     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1355     }
1356     return;
1357     }
1358    
1359     amount_written = _write(fd, keydata, length);
1360     free(keydata);
1361     close_result = _close(fd);
1362    
1363     if (amount_written != length || close_result == -1) {
1364     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1365     "An error occurred while trying to write the host key.\n"
1366     "The host key could not be written.");
1367     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1368     }
1369     }
1370     }
1371    
1372 yutakapon 5849 // �w�������L�[�� known_hosts �����������B
1373     void HOSTS_add_host_key(PTInstVar pvar, Key *key)
1374     {
1375     char FAR *name = NULL;
1376     char *hostname;
1377     unsigned short tcpport;
1378    
1379     hostname = pvar->ssh_state.hostname;
1380     tcpport = pvar->ssh_state.tcpport;
1381    
1382     if (pvar->hosts_state.file_names != NULL)
1383     name = pvar->hosts_state.file_names[0];
1384    
1385     if (name == NULL || name[0] == 0) {
1386     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1387     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1388     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1389     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1390     }
1391     else {
1392     char FAR *keydata = format_specified_host_key(key, hostname, tcpport);
1393     int length = strlen(keydata);
1394     int fd;
1395     int amount_written;
1396     int close_result;
1397     char buf[FILENAME_MAX];
1398    
1399     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1400     fd = _open(buf,
1401     _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1402     _S_IREAD | _S_IWRITE);
1403     if (fd == -1) {
1404     if (errno == EACCES) {
1405     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1406     "An error occurred while trying to write the host key.\n"
1407     "You do not have permission to write to the known-hosts file.");
1408     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1409     }
1410     else {
1411     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1412     "An error occurred while trying to write the host key.\n"
1413     "The host key could not be written.");
1414     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1415     }
1416     return;
1417     }
1418    
1419     amount_written = _write(fd, keydata, length);
1420     free(keydata);
1421     close_result = _close(fd);
1422    
1423     if (amount_written != length || close_result == -1) {
1424     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1425     "An error occurred while trying to write the host key.\n"
1426     "The host key could not be written.");
1427     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1428     }
1429     }
1430     }
1431    
1432 maya 3227 //
1433     // �����z�X�g�����e���������L�[����������
1434     // add_host_key ����������������
1435     //
1436     static void delete_different_key(PTInstVar pvar)
1437     {
1438     char FAR *name = pvar->hosts_state.file_names[0];
1439    
1440     if (name == NULL || name[0] == 0) {
1441     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1442     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1443     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1444     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1445     }
1446     else {
1447 maya 6152 Key key; // known_hosts���o�^������������
1448 maya 3227 int length;
1449     char filename[MAX_PATH];
1450     char tmp[L_tmpnam];
1451     int fd;
1452     int amount_written = 0;
1453     int close_result;
1454     int data_index = 0;
1455     char buf[FILENAME_MAX];
1456    
1457     // �������������t�@�C�����J��
1458     _getcwd(filename, sizeof(filename));
1459     tmpnam_s(tmp,sizeof(tmp));
1460     strcat_s(filename, sizeof(filename), tmp);
1461     fd = _open(filename,
1462     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1463     _S_IREAD | _S_IWRITE);
1464    
1465     if (fd == -1) {
1466     if (errno == EACCES) {
1467     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1468     "An error occurred while trying to write the host key.\n"
1469     "You do not have permission to write to the known-hosts file.");
1470     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1471     } else {
1472     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1473     "An error occurred while trying to write the host key.\n"
1474     "The host key could not be written.");
1475     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1476     }
1477     return;
1478     }
1479    
1480 maya 6152 // �t�@�C��������������
1481 maya 6147 memset(&key, 0, sizeof(key));
1482 maya 3227 begin_read_host_files(pvar, 0);
1483     do {
1484     int host_index = 0;
1485     int matched = 0;
1486     int keybits = 0;
1487     char FAR *data;
1488     int do_write = 0;
1489     length = amount_written = 0;
1490    
1491 maya 6152 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1, &key)) {
1492 maya 3227 break;
1493     }
1494    
1495     if (data_index == pvar->hosts_state.file_data_index) {
1496     // index ���i������ == ��������������
1497     break;
1498     }
1499    
1500     data = pvar->hosts_state.file_data + data_index;
1501     host_index = eat_spaces(data);
1502    
1503     if (data[host_index] == '#') {
1504     do_write = 1;
1505     }
1506     else {
1507     // �z�X�g������
1508     host_index--;
1509     do {
1510     int negated;
1511     int bracketed;
1512     char *end_bracket;
1513     int host_matched = 0;
1514     unsigned short keyfile_port = 22;
1515    
1516     host_index++;
1517     negated = data[host_index] == '!';
1518    
1519     if (negated) {
1520     host_index++;
1521     bracketed = data[host_index] == '[';
1522     if (bracketed) {
1523     end_bracket = strstr(data + host_index + 1, "]:");
1524     if (end_bracket != NULL) {
1525     *end_bracket = ' ';
1526     host_index++;
1527     }
1528     }
1529     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1530     if (bracketed && end_bracket != NULL) {
1531     *end_bracket = ']';
1532     keyfile_port = atoi(end_bracket + 2);
1533     }
1534     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1535     matched = 0;
1536     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1537     host_index--;
1538     do {
1539     host_index++;
1540     host_index += eat_to_end_of_pattern(data + host_index);
1541     } while (data[host_index] == ',');
1542     break;
1543     }
1544     }
1545     else {
1546     bracketed = data[host_index] == '[';
1547     if (bracketed) {
1548     end_bracket = strstr(data + host_index + 1, "]:");
1549     if (end_bracket != NULL) {
1550     *end_bracket = ' ';
1551     host_index++;
1552     }
1553     }
1554     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1555     if (bracketed && end_bracket != NULL) {
1556     *end_bracket = ']';
1557     keyfile_port = atoi(end_bracket + 2);
1558     }
1559     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1560     matched = 1;
1561     }
1562     }
1563     host_index += eat_to_end_of_pattern(data + host_index);
1564     } while (data[host_index] == ',');
1565    
1566     // �z�X�g������������
1567 maya 4332 if (!matched) {
1568 maya 3227 do_write = 1;
1569     }
1570 maya 4332 // �z�X�g��������
1571 maya 3227 else {
1572 maya 4332 // �����`�������� or ���v�����L�[
1573 maya 6152 if (HOSTS_compare_public_key(&pvar->hosts_state.hostkey, &key) != 0) {
1574 maya 4332 do_write = 1;
1575 maya 3227 }
1576 maya 4332 // �����`�������������v�������L�[���X�L�b�v������
1577 maya 3227 }
1578     }
1579    
1580     // ������������
1581     if (do_write) {
1582     length = pvar->hosts_state.file_data_index - data_index;
1583     amount_written =
1584     _write(fd, pvar->hosts_state.file_data + data_index,
1585     length);
1586    
1587     if (amount_written != length) {
1588     goto error1;
1589     }
1590     }
1591     data_index = pvar->hosts_state.file_data_index;
1592     } while (1); // ������������
1593    
1594     error1:
1595     close_result = _close(fd);
1596     if (amount_written != length || close_result == -1) {
1597     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1598     "An error occurred while trying to write the host key.\n"
1599     "The host key could not be written.");
1600     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1601     goto error2;
1602     }
1603    
1604     // �������������t�@�C���������l�[��
1605     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1606     _unlink(buf);
1607     rename(filename, buf);
1608    
1609     error2:
1610     _unlink(filename);
1611    
1612     finish_read_host_files(pvar, 0);
1613 yutakapon 5545
1614     // ���������������������������B
1615 maya 6147 key_init(&key);
1616 maya 3227 }
1617     }
1618    
1619 yutakapon 5849
1620     void HOSTS_delete_all_hostkeys(PTInstVar pvar)
1621     {
1622     char FAR *name = pvar->hosts_state.file_names[0];
1623     char *hostname;
1624     unsigned short tcpport;
1625    
1626     hostname = pvar->ssh_state.hostname;
1627     tcpport = pvar->ssh_state.tcpport;
1628    
1629     if (name == NULL || name[0] == 0) {
1630     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1631     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1632     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1633     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1634     }
1635     else {
1636 maya 6152 Key key; // known_hosts���o�^������������
1637 yutakapon 5849 int length;
1638     char filename[MAX_PATH];
1639     char tmp[L_tmpnam];
1640     int fd;
1641     int amount_written = 0;
1642     int close_result;
1643     int data_index = 0;
1644     char buf[FILENAME_MAX];
1645    
1646     // �������������t�@�C�����J��
1647     _getcwd(filename, sizeof(filename));
1648     tmpnam_s(tmp, sizeof(tmp));
1649     strcat_s(filename, sizeof(filename), tmp);
1650     fd = _open(filename,
1651     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1652     _S_IREAD | _S_IWRITE);
1653    
1654     if (fd == -1) {
1655     if (errno == EACCES) {
1656     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1657     "An error occurred while trying to write the host key.\n"
1658     "You do not have permission to write to the known-hosts file.");
1659     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1660     }
1661     else {
1662     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1663     "An error occurred while trying to write the host key.\n"
1664     "The host key could not be written.");
1665     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1666     }
1667     return;
1668     }
1669    
1670 maya 6152 // �t�@�C��������������
1671 maya 6147 memset(&key, 0, sizeof(key));
1672 yutakapon 5849 begin_read_host_files(pvar, 0);
1673     do {
1674     int host_index = 0;
1675     int matched = 0;
1676     int keybits = 0;
1677     char FAR *data;
1678     int do_write = 0;
1679     length = amount_written = 0;
1680    
1681 maya 6152 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1, &key)) {
1682 yutakapon 5849 break;
1683     }
1684    
1685     if (data_index == pvar->hosts_state.file_data_index) {
1686     // index ���i������ == ��������������
1687     break;
1688     }
1689    
1690     data = pvar->hosts_state.file_data + data_index;
1691     host_index = eat_spaces(data);
1692    
1693     if (data[host_index] == '#') {
1694     do_write = 1;
1695     }
1696     else {
1697     // �z�X�g������
1698     host_index--;
1699     do {
1700     int negated;
1701     int bracketed;
1702     char *end_bracket;
1703     int host_matched = 0;
1704     unsigned short keyfile_port = 22;
1705    
1706     host_index++;
1707     negated = data[host_index] == '!';
1708    
1709     if (negated) {
1710     host_index++;
1711     bracketed = data[host_index] == '[';
1712     if (bracketed) {
1713     end_bracket = strstr(data + host_index + 1, "]:");
1714     if (end_bracket != NULL) {
1715     *end_bracket = ' ';
1716     host_index++;
1717     }
1718     }
1719     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1720     if (bracketed && end_bracket != NULL) {
1721     *end_bracket = ']';
1722     keyfile_port = atoi(end_bracket + 2);
1723     }
1724     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1725     matched = 0;
1726     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1727     host_index--;
1728     do {
1729     host_index++;
1730     host_index += eat_to_end_of_pattern(data + host_index);
1731     } while (data[host_index] == ',');
1732     break;
1733     }
1734     }
1735     else {
1736     bracketed = data[host_index] == '[';
1737     if (bracketed) {
1738     end_bracket = strstr(data + host_index + 1, "]:");
1739     if (end_bracket != NULL) {
1740     *end_bracket = ' ';
1741     host_index++;
1742     }
1743     }
1744     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1745     if (bracketed && end_bracket != NULL) {
1746     *end_bracket = ']';
1747     keyfile_port = atoi(end_bracket + 2);
1748     }
1749     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1750     matched = 1;
1751     }
1752     }
1753     host_index += eat_to_end_of_pattern(data + host_index);
1754     } while (data[host_index] == ',');
1755    
1756     // �z�X�g������������
1757     if (!matched) {
1758     do_write = 1;
1759     }
1760     // �z�X�g��������
1761     else {
1762     // ���������������������B
1763    
1764     }
1765     }
1766    
1767     // ������������
1768     if (do_write) {
1769     length = pvar->hosts_state.file_data_index - data_index;
1770     amount_written =
1771     _write(fd, pvar->hosts_state.file_data + data_index,
1772     length);
1773    
1774     if (amount_written != length) {
1775     goto error1;
1776     }
1777     }
1778     data_index = pvar->hosts_state.file_data_index;
1779     } while (1); // ������������
1780    
1781     error1:
1782     close_result = _close(fd);
1783     if (amount_written != length || close_result == -1) {
1784     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1785     "An error occurred while trying to write the host key.\n"
1786     "The host key could not be written.");
1787     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1788     goto error2;
1789     }
1790    
1791     // �������������t�@�C���������l�[��
1792     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1793     _unlink(buf);
1794     rename(filename, buf);
1795    
1796     error2:
1797     _unlink(filename);
1798    
1799     finish_read_host_files(pvar, 0);
1800    
1801     // ���������������������������B
1802 maya 6147 key_init(&key);
1803 yutakapon 5849 }
1804     }
1805    
1806    
1807 maya 3227 //
1808     // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1809     // ���[�U���m�F�������B
1810     // TODO: finger print���\�����s���B
1811     // (2006.3.25 yutaka)
1812     //
1813     static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1814     LPARAM lParam)
1815     {
1816     PTInstVar pvar;
1817     LOGFONT logfont;
1818     HFONT font;
1819     char uimsg[MAX_UIMSG];
1820    
1821     switch (msg) {
1822     case WM_INITDIALOG:
1823     pvar = (PTInstVar) lParam;
1824     pvar->hosts_state.hosts_dialog = dlg;
1825     SetWindowLong(dlg, DWL_USER, lParam);
1826    
1827     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1828     GetWindowText(dlg, uimsg, sizeof(uimsg));
1829     UTIL_get_lang_msg("DLG_UNKNONWHOST_TITLE", pvar, uimsg);
1830     SetWindowText(dlg, pvar->ts->UIMsg);
1831     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1832 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING", pvar, uimsg);
1833 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1834     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1835 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING2", pvar, uimsg);
1836 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1837     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1838     UTIL_get_lang_msg("DLG_UNKNOWNHOST_FINGERPRINT", pvar, uimsg);
1839     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1840 maya 6132 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
1841     UTIL_get_lang_msg("DLG_UNKNOWNHOST_FP_HASH_ALGORITHM", pvar, uimsg);
1842     SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
1843 maya 3227 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1844     UTIL_get_lang_msg("DLG_UNKNOWNHOST_ADD", pvar, uimsg);
1845     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1846     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1847     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1848     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1849     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1850     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1851     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1852    
1853 doda 4559 switch (pvar->dns_key_check) {
1854     case DNS_VERIFY_NOTFOUND:
1855 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1856 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1857     break;
1858     case DNS_VERIFY_MATCH:
1859     case DNS_VERIFY_AUTH_MATCH:
1860 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1861 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1862     break;
1863     case DNS_VERIFY_MISMATCH:
1864     case DNS_VERIFY_AUTH_MISMATCH:
1865 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1866 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1867     break;
1868     case DNS_VERIFY_DIFFERENTTYPE:
1869     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1870 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1871 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1872     break;
1873     }
1874    
1875     switch (pvar->dns_key_check) {
1876     case DNS_VERIFY_MATCH:
1877     case DNS_VERIFY_MISMATCH:
1878     case DNS_VERIFY_DIFFERENTTYPE:
1879 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1880 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1881     break;
1882     case DNS_VERIFY_AUTH_MATCH:
1883     case DNS_VERIFY_AUTH_MISMATCH:
1884     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1885 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1886 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1887     break;
1888     }
1889    
1890 maya 3227 init_hosts_dlg(pvar, dlg);
1891    
1892     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1893     GetObject(font, sizeof(LOGFONT), &logfont);
1894     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1895     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1896     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1897 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1898     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1899 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1900 maya 6132 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1901     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1902     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1903     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1904 maya 3227 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1905     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1906     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1907     }
1908     else {
1909     DlgHostsAddFont = NULL;
1910     }
1911    
1912     // add host check box���`�F�b�N���f�t�H���g������������
1913     SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1914    
1915     return TRUE; /* because we do not set the focus */
1916    
1917     case WM_COMMAND:
1918     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1919    
1920     switch (LOWORD(wParam)) {
1921     case IDC_CONTINUE:
1922 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1923     if (!pvar->cv->Ready) {
1924     goto canceled;
1925     }
1926    
1927 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1928     add_host_key(pvar);
1929     }
1930    
1931     if (SSHv1(pvar)) {
1932     SSH_notify_host_OK(pvar);
1933     } else { // SSH2
1934     // SSH2���������� SSH_notify_host_OK() �������B
1935     }
1936    
1937     pvar->hosts_state.hosts_dialog = NULL;
1938    
1939     EndDialog(dlg, 1);
1940    
1941     if (DlgHostsAddFont != NULL) {
1942     DeleteObject(DlgHostsAddFont);
1943     }
1944    
1945     return TRUE;
1946    
1947     case IDCANCEL: /* kill the connection */
1948 yutakapon 5562 canceled:
1949 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
1950 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
1951 maya 3227 EndDialog(dlg, 0);
1952    
1953     if (DlgHostsAddFont != NULL) {
1954     DeleteObject(DlgHostsAddFont);
1955     }
1956    
1957     return TRUE;
1958    
1959 maya 6132 case IDC_FP_HASH_ALG_MD5:
1960     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
1961     return TRUE;
1962    
1963     case IDC_FP_HASH_ALG_SHA256:
1964     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
1965     return TRUE;
1966    
1967 maya 3227 default:
1968     return FALSE;
1969     }
1970    
1971     default:
1972     return FALSE;
1973     }
1974     }
1975    
1976     //
1977     // �u�����������m�F�_�C�A���O������
1978     //
1979     static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1980     LPARAM lParam)
1981     {
1982     PTInstVar pvar;
1983     LOGFONT logfont;
1984     HFONT font;
1985     char uimsg[MAX_UIMSG];
1986    
1987     switch (msg) {
1988     case WM_INITDIALOG:
1989     pvar = (PTInstVar) lParam;
1990     pvar->hosts_state.hosts_dialog = dlg;
1991     SetWindowLong(dlg, DWL_USER, lParam);
1992    
1993     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1994     GetWindowText(dlg, uimsg, sizeof(uimsg));
1995 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
1996 maya 3227 SetWindowText(dlg, pvar->ts->UIMsg);
1997     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1998 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
1999 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
2000     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
2001 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
2002 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
2003     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
2004 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
2005 maya 3227 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
2006 maya 6132 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2007     UTIL_get_lang_msg("DLG_DIFFERENTKEY_FP_HASH_ALGORITHM", pvar, uimsg);
2008     SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2009 maya 3227 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
2010 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
2011 maya 3227 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
2012     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
2013     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
2014     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
2015     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2016     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
2017     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2018    
2019 doda 4559 switch (pvar->dns_key_check) {
2020     case DNS_VERIFY_NOTFOUND:
2021 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
2022 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2023     break;
2024     case DNS_VERIFY_MATCH:
2025     case DNS_VERIFY_AUTH_MATCH:
2026 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
2027 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2028     break;
2029     case DNS_VERIFY_MISMATCH:
2030     case DNS_VERIFY_AUTH_MISMATCH:
2031 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
2032 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2033     break;
2034     case DNS_VERIFY_DIFFERENTTYPE:
2035     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2036 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
2037 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2038     break;
2039     }
2040    
2041     switch (pvar->dns_key_check) {
2042     case DNS_VERIFY_MATCH:
2043     case DNS_VERIFY_MISMATCH:
2044     case DNS_VERIFY_DIFFERENTTYPE:
2045 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
2046 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2047     break;
2048     case DNS_VERIFY_AUTH_MATCH:
2049     case DNS_VERIFY_AUTH_MISMATCH:
2050     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2051 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
2052 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2053     break;
2054     }
2055    
2056 maya 3227 init_hosts_dlg(pvar, dlg);
2057    
2058     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2059     GetObject(font, sizeof(LOGFONT), &logfont);
2060     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
2061     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2062     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2063 maya 6132 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2064     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2065 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2066 maya 6132 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2067     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2068     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2069     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2070 maya 3227 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2071     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2072     }
2073     else {
2074     DlgHostsReplaceFont = NULL;
2075     }
2076    
2077     // �f�t�H���g���`�F�b�N����������
2078     return TRUE; /* because we do not set the focus */
2079    
2080     case WM_COMMAND:
2081     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
2082    
2083     switch (LOWORD(wParam)) {
2084     case IDC_CONTINUE:
2085 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
2086     if (!pvar->cv->Ready) {
2087     goto canceled;
2088     }
2089    
2090 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
2091     add_host_key(pvar);
2092     delete_different_key(pvar);
2093     }
2094    
2095     if (SSHv1(pvar)) {
2096     SSH_notify_host_OK(pvar);
2097     } else { // SSH2
2098     // SSH2���������� SSH_notify_host_OK() �������B
2099     }
2100    
2101     pvar->hosts_state.hosts_dialog = NULL;
2102    
2103     EndDialog(dlg, 1);
2104    
2105     if (DlgHostsReplaceFont != NULL) {
2106     DeleteObject(DlgHostsReplaceFont);
2107     }
2108    
2109     return TRUE;
2110    
2111     case IDCANCEL: /* kill the connection */
2112 yutakapon 5562 canceled:
2113 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
2114 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
2115 maya 3227 EndDialog(dlg, 0);
2116    
2117     if (DlgHostsReplaceFont != NULL) {
2118     DeleteObject(DlgHostsReplaceFont);
2119     }
2120    
2121     return TRUE;
2122    
2123 maya 6132 case IDC_FP_HASH_ALG_MD5:
2124     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2125     return TRUE;
2126    
2127     case IDC_FP_HASH_ALG_SHA256:
2128     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2129     return TRUE;
2130    
2131 maya 3227 default:
2132     return FALSE;
2133     }
2134    
2135     default:
2136     return FALSE;
2137     }
2138     }
2139    
2140 maya 4332 //
2141     // �����z�X�g�����`�����������������m�F�_�C�A���O������
2142     //
2143     static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
2144     LPARAM lParam)
2145     {
2146     PTInstVar pvar;
2147     LOGFONT logfont;
2148     HFONT font;
2149     char uimsg[MAX_UIMSG];
2150    
2151     switch (msg) {
2152     case WM_INITDIALOG:
2153     pvar = (PTInstVar) lParam;
2154     pvar->hosts_state.hosts_dialog = dlg;
2155     SetWindowLong(dlg, DWL_USER, lParam);
2156    
2157     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
2158     GetWindowText(dlg, uimsg, sizeof(uimsg));
2159     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
2160     SetWindowText(dlg, pvar->ts->UIMsg);
2161     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
2162 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
2163 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
2164     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
2165 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
2166 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
2167     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
2168     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
2169     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
2170 maya 6132 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2171     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FP_HASH_ALGORITHM", pvar, uimsg);
2172     SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2173 maya 4332 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
2174     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
2175     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
2176     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
2177     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
2178     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
2179     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2180     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
2181     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2182    
2183 doda 4559 switch (pvar->dns_key_check) {
2184     case DNS_VERIFY_NOTFOUND:
2185 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
2186 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2187     break;
2188     case DNS_VERIFY_MATCH:
2189     case DNS_VERIFY_AUTH_MATCH:
2190 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
2191 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2192     break;
2193     case DNS_VERIFY_MISMATCH:
2194     case DNS_VERIFY_AUTH_MISMATCH:
2195 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
2196 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2197     break;
2198     case DNS_VERIFY_DIFFERENTTYPE:
2199     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2200 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
2201 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2202     break;
2203     }
2204    
2205     switch (pvar->dns_key_check) {
2206     case DNS_VERIFY_MATCH:
2207     case DNS_VERIFY_MISMATCH:
2208     case DNS_VERIFY_DIFFERENTTYPE:
2209 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
2210 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2211     break;
2212     case DNS_VERIFY_AUTH_MATCH:
2213     case DNS_VERIFY_AUTH_MISMATCH:
2214     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2215 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
2216 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2217     break;
2218     }
2219    
2220 maya 4332 init_hosts_dlg(pvar, dlg);
2221    
2222     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2223     GetObject(font, sizeof(LOGFONT), &logfont);
2224     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
2225     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2226     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2227 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2228     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2229 maya 4332 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2230 maya 6132 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2231     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2232     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2233     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2234 maya 4332 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2235     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2236     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2237     }
2238     else {
2239     DlgHostsAddFont = NULL;
2240     }
2241    
2242     // add host check box ���f�t�H���g�� off ������
2243     // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
2244    
2245     return TRUE; /* because we do not set the focus */
2246    
2247     case WM_COMMAND:
2248     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
2249    
2250     switch (LOWORD(wParam)) {
2251     case IDC_CONTINUE:
2252 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
2253     if (!pvar->cv->Ready) {
2254     goto canceled;
2255     }
2256    
2257 maya 4332 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
2258     add_host_key(pvar);
2259     }
2260    
2261     if (SSHv1(pvar)) {
2262     SSH_notify_host_OK(pvar);
2263     } else { // SSH2
2264     // SSH2���������� SSH_notify_host_OK() �������B
2265     }
2266    
2267     pvar->hosts_state.hosts_dialog = NULL;
2268    
2269     EndDialog(dlg, 1);
2270    
2271     if (DlgHostsAddFont != NULL) {
2272     DeleteObject(DlgHostsAddFont);
2273     }
2274    
2275     return TRUE;
2276    
2277     case IDCANCEL: /* kill the connection */
2278 yutakapon 5562 canceled:
2279 maya 4332 pvar->hosts_state.hosts_dialog = NULL;
2280 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
2281 maya 4332 EndDialog(dlg, 0);
2282    
2283     if (DlgHostsAddFont != NULL) {
2284     DeleteObject(DlgHostsAddFont);
2285     }
2286    
2287     return TRUE;
2288    
2289 maya 6132 case IDC_FP_HASH_ALG_MD5:
2290     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2291     return TRUE;
2292    
2293     case IDC_FP_HASH_ALG_SHA256:
2294     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2295     return TRUE;
2296    
2297 maya 4332 default:
2298     return FALSE;
2299     }
2300    
2301     default:
2302     return FALSE;
2303     }
2304     }
2305    
2306 maya 3227 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
2307     {
2308     if (pvar->hosts_state.hosts_dialog == NULL) {
2309     HWND cur_active = GetActiveWindow();
2310    
2311     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
2312     cur_active != NULL ? cur_active : wnd,
2313     hosts_add_dlg_proc, (LPARAM) pvar);
2314     }
2315     }
2316    
2317 maya 4330 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
2318 maya 3227 {
2319     if (pvar->hosts_state.hosts_dialog == NULL) {
2320     HWND cur_active = GetActiveWindow();
2321    
2322 maya 4330 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
2323 maya 3227 cur_active != NULL ? cur_active : wnd,
2324     hosts_replace_dlg_proc, (LPARAM) pvar);
2325     }
2326     }
2327    
2328 maya 4332 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
2329     {
2330     if (pvar->hosts_state.hosts_dialog == NULL) {
2331     HWND cur_active = GetActiveWindow();
2332    
2333     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
2334     cur_active != NULL ? cur_active : wnd,
2335     hosts_add2_dlg_proc, (LPARAM) pvar);
2336     }
2337     }
2338    
2339 maya 3227 //
2340     // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
2341 maya 6152 // key: �T�[�o���������J��
2342 maya 3227 //
2343     // SSH2���������� (2006.3.24 yutaka)
2344     //
2345     BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key)
2346     {
2347 doda 4559 int found_different_key = 0, found_different_type_key = 0;
2348 maya 6152 Key key2; // known_hosts���o�^������������
2349 maya 3227
2350 doda 4559 pvar->dns_key_check = DNS_VERIFY_NONE;
2351    
2352 maya 3227 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
2353     if (pvar->hosts_state.prefetched_hostname != NULL
2354     && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
2355 maya 6152 && HOSTS_compare_public_key(&pvar->hosts_state.hostkey, key) == 1) {
2356 maya 3227
2357     if (SSHv1(pvar)) {
2358     SSH_notify_host_OK(pvar);
2359     } else {
2360     // SSH2���������� SSH_notify_host_OK() �������B
2361     }
2362     return TRUE;
2363     }
2364    
2365     // �������������������������A�������_���t�@�C��������������
2366 maya 6152 memset(&key2, 0, sizeof(key2));
2367 maya 3227 if (begin_read_host_files(pvar, 0)) {
2368     do {
2369 maya 6152 if (!read_host_key(pvar, hostname, tcpport, 0, 0, &key2)) {
2370 maya 3227 break;
2371     }
2372    
2373 maya 6152 if (key2.type != KEY_UNSPEC) {
2374     int match = HOSTS_compare_public_key(&key2, key);
2375 maya 4332 if (match == 1) {
2376 maya 3227 finish_read_host_files(pvar, 0);
2377     // ���������G���g�����Q�������A���v�����L�[�������������������B
2378     // SSH2���������������������������B(2006.3.29 yutaka)
2379     if (SSHv1(pvar)) {
2380     SSH_notify_host_OK(pvar);
2381     } else {
2382     // SSH2���������� SSH_notify_host_OK() �������B
2383     }
2384     return TRUE;
2385 maya 4332 }
2386     else if (match == 0) {
2387 maya 3227 // �L�[�� known_hosts ���������������A�L�[�����e���������B
2388     found_different_key = 1;
2389     }
2390 maya 4332