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