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 6145 - (hide annotations) (download) (as text)
Tue Nov 17 04:37:00 2015 UTC (8 years, 4 months ago) by maya
File MIME type: text/x-csrc
File size: 71742 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 static char FAR *copy_mp_int(char FAR * num)
1461     {
1462     int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;
1463     char FAR *result = (char FAR *) malloc(len);
1464    
1465     if (result != NULL) {
1466     memcpy(result, num, len);
1467     }
1468    
1469     return result;
1470     }
1471    
1472     //
1473     // �����z�X�g�����e���������L�[����������
1474     // add_host_key ����������������
1475     //
1476     static void delete_different_key(PTInstVar pvar)
1477     {
1478     char FAR *name = pvar->hosts_state.file_names[0];
1479    
1480     if (name == NULL || name[0] == 0) {
1481     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1482     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1483     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1484     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1485     }
1486     else {
1487     Key key; // ���������z�X�g���L�[
1488 yutakapon 5663 Key *key_freed;
1489 maya 3227 int length;
1490     char filename[MAX_PATH];
1491     char tmp[L_tmpnam];
1492     int fd;
1493     int amount_written = 0;
1494     int close_result;
1495     int data_index = 0;
1496     char buf[FILENAME_MAX];
1497    
1498     // �������������t�@�C�����J��
1499     _getcwd(filename, sizeof(filename));
1500     tmpnam_s(tmp,sizeof(tmp));
1501     strcat_s(filename, sizeof(filename), tmp);
1502     fd = _open(filename,
1503     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1504     _S_IREAD | _S_IWRITE);
1505    
1506     if (fd == -1) {
1507     if (errno == EACCES) {
1508     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1509     "An error occurred while trying to write the host key.\n"
1510     "You do not have permission to write to the known-hosts file.");
1511     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1512     } else {
1513     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1514     "An error occurred while trying to write the host key.\n"
1515     "The host key could not be written.");
1516     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1517     }
1518     return;
1519     }
1520    
1521     // ���������T�[�o���L�[����������
1522 maya 6145 key_copy(&key, &(pvar->hosts_state.hostkey));
1523 maya 3227
1524     // �t�@�C��������������
1525     begin_read_host_files(pvar, 0);
1526     do {
1527     int host_index = 0;
1528     int matched = 0;
1529     int keybits = 0;
1530     char FAR *data;
1531     int do_write = 0;
1532     length = amount_written = 0;
1533    
1534     if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1)) {
1535     break;
1536     }
1537    
1538     if (data_index == pvar->hosts_state.file_data_index) {
1539     // index ���i������ == ��������������
1540     break;
1541     }
1542    
1543     data = pvar->hosts_state.file_data + data_index;
1544     host_index = eat_spaces(data);
1545    
1546     if (data[host_index] == '#') {
1547     do_write = 1;
1548     }
1549     else {
1550     // �z�X�g������
1551     host_index--;
1552     do {
1553     int negated;
1554     int bracketed;
1555     char *end_bracket;
1556     int host_matched = 0;
1557     unsigned short keyfile_port = 22;
1558    
1559     host_index++;
1560     negated = data[host_index] == '!';
1561    
1562     if (negated) {
1563     host_index++;
1564     bracketed = data[host_index] == '[';
1565     if (bracketed) {
1566     end_bracket = strstr(data + host_index + 1, "]:");
1567     if (end_bracket != NULL) {
1568     *end_bracket = ' ';
1569     host_index++;
1570     }
1571     }
1572     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1573     if (bracketed && end_bracket != NULL) {
1574     *end_bracket = ']';
1575     keyfile_port = atoi(end_bracket + 2);
1576     }
1577     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1578     matched = 0;
1579     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1580     host_index--;
1581     do {
1582     host_index++;
1583     host_index += eat_to_end_of_pattern(data + host_index);
1584     } while (data[host_index] == ',');
1585     break;
1586     }
1587     }
1588     else {
1589     bracketed = data[host_index] == '[';
1590     if (bracketed) {
1591     end_bracket = strstr(data + host_index + 1, "]:");
1592     if (end_bracket != NULL) {
1593     *end_bracket = ' ';
1594     host_index++;
1595     }
1596     }
1597     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1598     if (bracketed && end_bracket != NULL) {
1599     *end_bracket = ']';
1600     keyfile_port = atoi(end_bracket + 2);
1601     }
1602     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1603     matched = 1;
1604     }
1605     }
1606     host_index += eat_to_end_of_pattern(data + host_index);
1607     } while (data[host_index] == ',');
1608    
1609     // �z�X�g������������
1610 maya 4332 if (!matched) {
1611 maya 3227 do_write = 1;
1612     }
1613 maya 4332 // �z�X�g��������
1614 maya 3227 else {
1615 maya 4332 // �����`�������� or ���v�����L�[
1616     if (match_key(pvar, &key) != 0) {
1617     do_write = 1;
1618 maya 3227 }
1619 maya 4332 // �����`�������������v�������L�[���X�L�b�v������
1620 maya 3227 }
1621     }
1622    
1623     // ������������
1624     if (do_write) {
1625     length = pvar->hosts_state.file_data_index - data_index;
1626     amount_written =
1627     _write(fd, pvar->hosts_state.file_data + data_index,
1628     length);
1629    
1630     if (amount_written != length) {
1631     goto error1;
1632     }
1633     }
1634     data_index = pvar->hosts_state.file_data_index;
1635     } while (1); // ������������
1636    
1637     error1:
1638     close_result = _close(fd);
1639     if (amount_written != length || close_result == -1) {
1640     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1641     "An error occurred while trying to write the host key.\n"
1642     "The host key could not be written.");
1643     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1644     goto error2;
1645     }
1646    
1647     // �������������t�@�C���������l�[��
1648     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1649     _unlink(buf);
1650     rename(filename, buf);
1651    
1652     error2:
1653     _unlink(filename);
1654    
1655     finish_read_host_files(pvar, 0);
1656 yutakapon 5545
1657     // ���������������������������B
1658 yutakapon 5663 key_freed = key_new(KEY_UNSPEC);
1659     memcpy(key_freed, &key, sizeof(Key));
1660     key_free(key_freed);
1661 maya 3227 }
1662     }
1663    
1664 yutakapon 5849
1665     void HOSTS_delete_all_hostkeys(PTInstVar pvar)
1666     {
1667     char FAR *name = pvar->hosts_state.file_names[0];
1668     char *hostname;
1669     unsigned short tcpport;
1670    
1671     hostname = pvar->ssh_state.hostname;
1672     tcpport = pvar->ssh_state.tcpport;
1673    
1674     if (name == NULL || name[0] == 0) {
1675     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1676     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1677     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1678     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1679     }
1680     else {
1681     Key key; // ���������z�X�g���L�[
1682     Key *key_freed;
1683     int length;
1684     char filename[MAX_PATH];
1685     char tmp[L_tmpnam];
1686     int fd;
1687     int amount_written = 0;
1688     int close_result;
1689     int data_index = 0;
1690     char buf[FILENAME_MAX];
1691    
1692     // �������������t�@�C�����J��
1693     _getcwd(filename, sizeof(filename));
1694     tmpnam_s(tmp, sizeof(tmp));
1695     strcat_s(filename, sizeof(filename), tmp);
1696     fd = _open(filename,
1697     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1698     _S_IREAD | _S_IWRITE);
1699    
1700     if (fd == -1) {
1701     if (errno == EACCES) {
1702     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1703     "An error occurred while trying to write the host key.\n"
1704     "You do not have permission to write to the known-hosts file.");
1705     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1706     }
1707     else {
1708     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1709     "An error occurred while trying to write the host key.\n"
1710     "The host key could not be written.");
1711     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1712     }
1713     return;
1714     }
1715    
1716     // ���������T�[�o���L�[����������
1717 maya 6145 key_copy(&key, &(pvar->hosts_state.hostkey));
1718 yutakapon 5849
1719     // �t�@�C��������������
1720     begin_read_host_files(pvar, 0);
1721     do {
1722     int host_index = 0;
1723     int matched = 0;
1724     int keybits = 0;
1725     char FAR *data;
1726     int do_write = 0;
1727     length = amount_written = 0;
1728    
1729     if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1)) {
1730     break;
1731     }
1732    
1733     if (data_index == pvar->hosts_state.file_data_index) {
1734     // index ���i������ == ��������������
1735     break;
1736     }
1737    
1738     data = pvar->hosts_state.file_data + data_index;
1739     host_index = eat_spaces(data);
1740    
1741     if (data[host_index] == '#') {
1742     do_write = 1;
1743     }
1744     else {
1745     // �z�X�g������
1746     host_index--;
1747     do {
1748     int negated;
1749     int bracketed;
1750     char *end_bracket;
1751     int host_matched = 0;
1752     unsigned short keyfile_port = 22;
1753    
1754     host_index++;
1755     negated = data[host_index] == '!';
1756    
1757     if (negated) {
1758     host_index++;
1759     bracketed = data[host_index] == '[';
1760     if (bracketed) {
1761     end_bracket = strstr(data + host_index + 1, "]:");
1762     if (end_bracket != NULL) {
1763     *end_bracket = ' ';
1764     host_index++;
1765     }
1766     }
1767     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1768     if (bracketed && end_bracket != NULL) {
1769     *end_bracket = ']';
1770     keyfile_port = atoi(end_bracket + 2);
1771     }
1772     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1773     matched = 0;
1774     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1775     host_index--;
1776     do {
1777     host_index++;
1778     host_index += eat_to_end_of_pattern(data + host_index);
1779     } while (data[host_index] == ',');
1780     break;
1781     }
1782     }
1783     else {
1784     bracketed = data[host_index] == '[';
1785     if (bracketed) {
1786     end_bracket = strstr(data + host_index + 1, "]:");
1787     if (end_bracket != NULL) {
1788     *end_bracket = ' ';
1789     host_index++;
1790     }
1791     }
1792     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1793     if (bracketed && end_bracket != NULL) {
1794     *end_bracket = ']';
1795     keyfile_port = atoi(end_bracket + 2);
1796     }
1797     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1798     matched = 1;
1799     }
1800     }
1801     host_index += eat_to_end_of_pattern(data + host_index);
1802     } while (data[host_index] == ',');
1803    
1804     // �z�X�g������������
1805     if (!matched) {
1806     do_write = 1;
1807     }
1808     // �z�X�g��������
1809     else {
1810     // ���������������������B
1811    
1812     }
1813     }
1814    
1815     // ������������
1816     if (do_write) {
1817     length = pvar->hosts_state.file_data_index - data_index;
1818     amount_written =
1819     _write(fd, pvar->hosts_state.file_data + data_index,
1820     length);
1821    
1822     if (amount_written != length) {
1823     goto error1;
1824     }
1825     }
1826     data_index = pvar->hosts_state.file_data_index;
1827     } while (1); // ������������
1828    
1829     error1:
1830     close_result = _close(fd);
1831     if (amount_written != length || close_result == -1) {
1832     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1833     "An error occurred while trying to write the host key.\n"
1834     "The host key could not be written.");
1835     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1836     goto error2;
1837     }
1838    
1839     // �������������t�@�C���������l�[��
1840     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1841     _unlink(buf);
1842     rename(filename, buf);
1843    
1844     error2:
1845     _unlink(filename);
1846    
1847     finish_read_host_files(pvar, 0);
1848    
1849     // ���������������������������B
1850     key_freed = key_new(KEY_UNSPEC);
1851     memcpy(key_freed, &key, sizeof(Key));
1852     key_free(key_freed);
1853     }
1854     }
1855    
1856    
1857 maya 3227 //
1858     // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1859     // ���[�U���m�F�������B
1860     // TODO: finger print���\�����s���B
1861     // (2006.3.25 yutaka)
1862     //
1863     static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1864     LPARAM lParam)
1865     {
1866     PTInstVar pvar;
1867     LOGFONT logfont;
1868     HFONT font;
1869     char uimsg[MAX_UIMSG];
1870    
1871     switch (msg) {
1872     case WM_INITDIALOG:
1873     pvar = (PTInstVar) lParam;
1874     pvar->hosts_state.hosts_dialog = dlg;
1875     SetWindowLong(dlg, DWL_USER, lParam);
1876    
1877     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1878     GetWindowText(dlg, uimsg, sizeof(uimsg));
1879     UTIL_get_lang_msg("DLG_UNKNONWHOST_TITLE", pvar, uimsg);
1880     SetWindowText(dlg, pvar->ts->UIMsg);
1881     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1882 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING", pvar, uimsg);
1883 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1884     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1885 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING2", pvar, uimsg);
1886 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1887     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1888     UTIL_get_lang_msg("DLG_UNKNOWNHOST_FINGERPRINT", pvar, uimsg);
1889     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1890 maya 6132 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
1891     UTIL_get_lang_msg("DLG_UNKNOWNHOST_FP_HASH_ALGORITHM", pvar, uimsg);
1892     SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
1893 maya 3227 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1894     UTIL_get_lang_msg("DLG_UNKNOWNHOST_ADD", pvar, uimsg);
1895     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1896     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1897     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1898     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1899     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1900     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1901     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1902    
1903 doda 4559 switch (pvar->dns_key_check) {
1904     case DNS_VERIFY_NOTFOUND:
1905 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1906 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1907     break;
1908     case DNS_VERIFY_MATCH:
1909     case DNS_VERIFY_AUTH_MATCH:
1910 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1911 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1912     break;
1913     case DNS_VERIFY_MISMATCH:
1914     case DNS_VERIFY_AUTH_MISMATCH:
1915 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1916 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1917     break;
1918     case DNS_VERIFY_DIFFERENTTYPE:
1919     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1920 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1921 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1922     break;
1923     }
1924    
1925     switch (pvar->dns_key_check) {
1926     case DNS_VERIFY_MATCH:
1927     case DNS_VERIFY_MISMATCH:
1928     case DNS_VERIFY_DIFFERENTTYPE:
1929 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1930 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1931     break;
1932     case DNS_VERIFY_AUTH_MATCH:
1933     case DNS_VERIFY_AUTH_MISMATCH:
1934     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1935 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1936 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1937     break;
1938     }
1939    
1940 maya 3227 init_hosts_dlg(pvar, dlg);
1941    
1942     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1943     GetObject(font, sizeof(LOGFONT), &logfont);
1944     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1945     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1946     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1947 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1948     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1949 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1950 maya 6132 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1951     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1952     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1953     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1954 maya 3227 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1955     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1956     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1957     }
1958     else {
1959     DlgHostsAddFont = NULL;
1960     }
1961    
1962     // add host check box���`�F�b�N���f�t�H���g������������
1963     SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1964    
1965     return TRUE; /* because we do not set the focus */
1966    
1967     case WM_COMMAND:
1968     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1969    
1970     switch (LOWORD(wParam)) {
1971     case IDC_CONTINUE:
1972 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1973     if (!pvar->cv->Ready) {
1974     goto canceled;
1975     }
1976    
1977 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1978     add_host_key(pvar);
1979     }
1980    
1981     if (SSHv1(pvar)) {
1982     SSH_notify_host_OK(pvar);
1983     } else { // SSH2
1984     // SSH2���������� SSH_notify_host_OK() �������B
1985     }
1986    
1987     pvar->hosts_state.hosts_dialog = NULL;
1988    
1989     EndDialog(dlg, 1);
1990    
1991     if (DlgHostsAddFont != NULL) {
1992     DeleteObject(DlgHostsAddFont);
1993     }
1994    
1995     return TRUE;
1996    
1997     case IDCANCEL: /* kill the connection */
1998 yutakapon 5562 canceled:
1999 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
2000 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
2001 maya 3227 EndDialog(dlg, 0);
2002    
2003     if (DlgHostsAddFont != NULL) {
2004     DeleteObject(DlgHostsAddFont);
2005     }
2006    
2007     return TRUE;
2008    
2009 maya 6132 case IDC_FP_HASH_ALG_MD5:
2010     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2011     return TRUE;
2012    
2013     case IDC_FP_HASH_ALG_SHA256:
2014     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2015     return TRUE;
2016    
2017 maya 3227 default:
2018     return FALSE;
2019     }
2020    
2021     default:
2022     return FALSE;
2023     }
2024     }
2025    
2026     //
2027     // �u�����������m�F�_�C�A���O������
2028     //
2029     static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
2030     LPARAM lParam)
2031     {
2032     PTInstVar pvar;
2033     LOGFONT logfont;
2034     HFONT font;
2035     char uimsg[MAX_UIMSG];
2036    
2037     switch (msg) {
2038     case WM_INITDIALOG:
2039     pvar = (PTInstVar) lParam;
2040     pvar->hosts_state.hosts_dialog = dlg;
2041     SetWindowLong(dlg, DWL_USER, lParam);
2042    
2043     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
2044     GetWindowText(dlg, uimsg, sizeof(uimsg));
2045 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
2046 maya 3227 SetWindowText(dlg, pvar->ts->UIMsg);
2047     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
2048 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
2049 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
2050     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
2051 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
2052 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
2053     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
2054 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
2055 maya 3227 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
2056 maya 6132 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2057     UTIL_get_lang_msg("DLG_DIFFERENTKEY_FP_HASH_ALGORITHM", pvar, uimsg);
2058     SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2059 maya 3227 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
2060 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
2061 maya 3227 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
2062     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
2063     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
2064     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
2065     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2066     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
2067     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2068    
2069 doda 4559 switch (pvar->dns_key_check) {
2070     case DNS_VERIFY_NOTFOUND:
2071 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
2072 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2073     break;
2074     case DNS_VERIFY_MATCH:
2075     case DNS_VERIFY_AUTH_MATCH:
2076 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
2077 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2078     break;
2079     case DNS_VERIFY_MISMATCH:
2080     case DNS_VERIFY_AUTH_MISMATCH:
2081 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
2082 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2083     break;
2084     case DNS_VERIFY_DIFFERENTTYPE:
2085     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2086 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
2087 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2088     break;
2089     }
2090    
2091     switch (pvar->dns_key_check) {
2092     case DNS_VERIFY_MATCH:
2093     case DNS_VERIFY_MISMATCH:
2094     case DNS_VERIFY_DIFFERENTTYPE:
2095 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
2096 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2097     break;
2098     case DNS_VERIFY_AUTH_MATCH:
2099     case DNS_VERIFY_AUTH_MISMATCH:
2100     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2101 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
2102 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2103     break;
2104     }
2105    
2106 maya 3227 init_hosts_dlg(pvar, dlg);
2107    
2108     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2109     GetObject(font, sizeof(LOGFONT), &logfont);
2110     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
2111     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2112     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2113 maya 6132 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2114     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2115 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2116 maya 6132 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2117     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2118     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2119     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2120 maya 3227 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2121     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2122     }
2123     else {
2124     DlgHostsReplaceFont = NULL;
2125     }
2126    
2127     // �f�t�H���g���`�F�b�N����������
2128     return TRUE; /* because we do not set the focus */
2129    
2130     case WM_COMMAND:
2131     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
2132    
2133     switch (LOWORD(wParam)) {
2134     case IDC_CONTINUE:
2135 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
2136     if (!pvar->cv->Ready) {
2137     goto canceled;
2138     }
2139    
2140 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
2141     add_host_key(pvar);
2142     delete_different_key(pvar);
2143     }
2144    
2145     if (SSHv1(pvar)) {
2146     SSH_notify_host_OK(pvar);
2147     } else { // SSH2
2148     // SSH2���������� SSH_notify_host_OK() �������B
2149     }
2150    
2151     pvar->hosts_state.hosts_dialog = NULL;
2152    
2153     EndDialog(dlg, 1);
2154    
2155     if (DlgHostsReplaceFont != NULL) {
2156     DeleteObject(DlgHostsReplaceFont);
2157     }
2158    
2159     return TRUE;
2160    
2161     case IDCANCEL: /* kill the connection */
2162 yutakapon 5562 canceled:
2163 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
2164 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
2165 maya 3227 EndDialog(dlg, 0);
2166    
2167     if (DlgHostsReplaceFont != NULL) {
2168     DeleteObject(DlgHostsReplaceFont);
2169     }
2170    
2171     return TRUE;
2172    
2173 maya 6132 case IDC_FP_HASH_ALG_MD5:
2174     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2175     return TRUE;
2176    
2177     case IDC_FP_HASH_ALG_SHA256:
2178     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2179     return TRUE;
2180    
2181 maya 3227 default:
2182     return FALSE;
2183     }
2184    
2185     default:
2186     return FALSE;
2187     }
2188     }
2189    
2190 maya 4332 //
2191     // �����z�X�g�����`�����������������m�F�_�C�A���O������
2192     //
2193     static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
2194     LPARAM lParam)
2195     {
2196     PTInstVar pvar;
2197     LOGFONT logfont;
2198     HFONT font;
2199     char uimsg[MAX_UIMSG];
2200    
2201     switch (msg) {
2202     case WM_INITDIALOG:
2203     pvar = (PTInstVar) lParam;
2204     pvar->hosts_state.hosts_dialog = dlg;
2205     SetWindowLong(dlg, DWL_USER, lParam);
2206    
2207     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
2208     GetWindowText(dlg, uimsg, sizeof(uimsg));
2209     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
2210     SetWindowText(dlg, pvar->ts->UIMsg);
2211     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
2212 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
2213 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
2214     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
2215 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
2216 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
2217     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
2218     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
2219     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
2220 maya 6132 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2221     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FP_HASH_ALGORITHM", pvar, uimsg);
2222     SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2223 maya 4332 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
2224     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
2225     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
2226     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
2227     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
2228     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
2229     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2230     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
2231     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2232    
2233 doda 4559 switch (pvar->dns_key_check) {
2234     case DNS_VERIFY_NOTFOUND:
2235 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
2236 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2237     break;
2238     case DNS_VERIFY_MATCH:
2239     case DNS_VERIFY_AUTH_MATCH:
2240 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
2241 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2242     break;
2243     case DNS_VERIFY_MISMATCH:
2244     case DNS_VERIFY_AUTH_MISMATCH:
2245 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
2246 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2247     break;
2248     case DNS_VERIFY_DIFFERENTTYPE:
2249     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2250 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
2251 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2252     break;
2253     }
2254    
2255     switch (pvar->dns_key_check) {
2256     case DNS_VERIFY_MATCH:
2257     case DNS_VERIFY_MISMATCH:
2258     case DNS_VERIFY_DIFFERENTTYPE:
2259 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
2260 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2261     break;
2262     case DNS_VERIFY_AUTH_MATCH:
2263     case DNS_VERIFY_AUTH_MISMATCH:
2264     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2265 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
2266 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2267     break;
2268     }
2269    
2270 maya 4332 init_hosts_dlg(pvar, dlg);
2271    
2272     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2273     GetObject(font, sizeof(LOGFONT), &logfont);
2274     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
2275     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2276     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2277 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2278     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2279 maya 4332 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2280 maya 6132 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2281     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2282     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2283     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2284 maya 4332 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2285     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2286     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2287     }
2288     else {
2289     DlgHostsAddFont = NULL;
2290     }
2291    
2292     // add host check box ���f�t�H���g�� off ������
2293     // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
2294    
2295     return TRUE; /* because we do not set the focus */
2296    
2297     case WM_COMMAND:
2298     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
2299    
2300     switch (LOWORD(wParam)) {
2301     case IDC_CONTINUE:
2302 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
2303     if (!pvar->cv->Ready) {
2304     goto canceled;
2305     }
2306    
2307 maya 4332 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
2308     add_host_key(pvar);
2309     }
2310    
2311     if (SSHv1(pvar)) {
2312     SSH_notify_host_OK(pvar);
2313     } else { // SSH2
2314     // SSH2���������� SSH_notify_host_OK() �������B
2315     }
2316    
2317     pvar->hosts_state.hosts_dialog = NULL;
2318    
2319     EndDialog(dlg, 1);
2320    
2321     if (DlgHostsAddFont != NULL) {
2322     DeleteObject(DlgHostsAddFont);
2323     }
2324    
2325     return TRUE;
2326    
2327     case IDCANCEL: /* kill the connection */
2328 yutakapon 5562 canceled:
2329 maya 4332 pvar->hosts_state.hosts_dialog = NULL;
2330 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
2331 maya 4332 EndDialog(dlg, 0);
2332    
2333     if (DlgHostsAddFont != NULL) {
2334     DeleteObject(DlgHostsAddFont);
2335     }
2336    
2337     return TRUE;
2338    
2339 maya 6132 case IDC_FP_HASH_ALG_MD5:
2340     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2341     return TRUE;
2342    
2343     case IDC_FP_HASH_ALG_SHA256:
2344     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2345     return TRUE;
2346    
2347 maya 4332 default:
2348     return FALSE;
2349     }
2350    
2351     default:
2352     return FALSE;
2353     }
2354     }
2355    
2356 maya 3227 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
2357     {
2358     if (pvar->hosts_state.hosts_dialog == NULL) {
2359     HWND cur_active = GetActiveWindow();
2360    
2361     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
2362     cur_active != NULL ? cur_active : wnd,
2363     hosts_add_dlg_proc, (LPARAM) pvar);
2364     }
2365     }
2366    
2367 maya 4330 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
2368 maya 3227 {
2369     if (pvar->hosts_state.hosts_dialog == NULL) {
2370     HWND cur_active = GetActiveWindow();
2371    
2372 maya 4330 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
2373 maya 3227 cur_active != NULL ? cur_active : wnd,
2374     hosts_replace_dlg_proc, (LPARAM) pvar);
2375     }
2376     }
2377    
2378 maya 4332 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
2379     {
2380     if (pvar->hosts_state.hosts_dialog == NULL) {
2381     HWND cur_active = GetActiveWindow();
2382    
2383     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
2384     cur_active != NULL ? cur_active : wnd,
2385     hosts_add2_dlg_proc, (LPARAM) pvar);
2386     }
2387     }
2388    
2389 maya 3227 //
2390     // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
2391     //
2392     // SSH2���������� (2006.3.24 yutaka)
2393     //
2394     BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key)
2395     {
2396 doda 4559 int found_different_key = 0, found_different_type_key = 0;
2397 maya 3227
2398 doda 4559 pvar->dns_key_check = DNS_VERIFY_NONE;
2399    
2400 maya 3227 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
2401     if (pvar->hosts_state.prefetched_hostname != NULL
2402     && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
2403 maya 4332 && match_key(pvar, key) == 1) {
2404 maya 3227
2405     if (SSHv1(pvar)) {
2406     SSH_notify_host_OK(pvar);
2407     } else {
2408