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