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 4559 - (hide annotations) (download) (as text)
Mon Aug 1 07:21:58 2011 UTC (12 years, 8 months ago) by doda
File MIME type: text/x-csrc
File size: 56257 byte(s)
SSHFP 検証の結果を Security Warning ダイアログに表示するようにした。メッセージは暫定。

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    
34     #include "ttxssh.h"
35     #include "util.h"
36     #include "resource.h"
37     #include "matcher.h"
38     #include "ssh.h"
39 maya 4304 #include "key.h"
40 maya 3227 #include "hosts.h"
41    
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 #include <windns.h>
55    
56 doda 4559 #define DNS_TYPE_SSHFP 44
57     typedef struct {
58     BYTE Algorithm;
59     BYTE DigestType;
60     BYTE Digest[1];
61     } DNS_SSHFP_DATA, *PDNS_SSHFP_DATA;
62     enum verifydns_result {
63     DNS_VERIFY_NONE,
64     DNS_VERIFY_NOTFOUND,
65     DNS_VERIFY_MATCH,
66     DNS_VERIFY_MISMATCH,
67     DNS_VERIFY_DIFFERENTTYPE,
68     DNS_VERIFY_AUTH_MATCH,
69     DNS_VERIFY_AUTH_MISMATCH,
70     DNS_VERIFY_AUTH_DIFFERENTTYPE
71     };
72    
73 maya 3227 static HFONT DlgHostsAddFont;
74     static HFONT DlgHostsReplaceFont;
75    
76     // BASE64�\���������i��������'='�����������������j
77     static char base64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
78    
79    
80     // �z�X�g�L�[�������� (2006.3.21 yutaka)
81     static void init_hostkey(Key *key)
82     {
83     key->type = KEY_UNSPEC;
84    
85     // SSH1
86     key->bits = 0;
87     if (key->exp != NULL) {
88     free(key->exp);
89     key->exp = NULL;
90     }
91     if (key->mod != NULL) {
92     free(key->mod);
93     key->mod = NULL;
94     }
95    
96     // SSH2
97     if (key->dsa != NULL) {
98     DSA_free(key->dsa);
99     key->dsa = NULL;
100     }
101     if (key->rsa != NULL) {
102     RSA_free(key->rsa);
103     key->rsa = NULL;
104     }
105 maya 4323 if (key->ecdsa != NULL) {
106     EC_KEY_free(key->ecdsa);
107     key->ecdsa = NULL;
108     }
109 maya 3227 }
110    
111    
112     static char FAR *FAR * parse_multi_path(char FAR * buf)
113     {
114     int i;
115     int ch;
116     int num_paths = 1;
117     char FAR *FAR * result;
118     int last_path_index;
119    
120     for (i = 0; (ch = buf[i]) != 0; i++) {
121     if (ch == ';') {
122     num_paths++;
123     }
124     }
125    
126     result =
127     (char FAR * FAR *) malloc(sizeof(char FAR *) * (num_paths + 1));
128    
129     last_path_index = 0;
130     num_paths = 0;
131     for (i = 0; (ch = buf[i]) != 0; i++) {
132     if (ch == ';') {
133     buf[i] = 0;
134     result[num_paths] = _strdup(buf + last_path_index);
135     num_paths++;
136     buf[i] = ch;
137     last_path_index = i + 1;
138     }
139     }
140     if (i > last_path_index) {
141     result[num_paths] = _strdup(buf + last_path_index);
142     num_paths++;
143     }
144     result[num_paths] = NULL;
145     return result;
146     }
147    
148     void HOSTS_init(PTInstVar pvar)
149     {
150     pvar->hosts_state.prefetched_hostname = NULL;
151     init_hostkey(&pvar->hosts_state.hostkey);
152     pvar->hosts_state.hosts_dialog = NULL;
153     pvar->hosts_state.file_names = NULL;
154     }
155    
156     void HOSTS_open(PTInstVar pvar)
157     {
158     pvar->hosts_state.file_names =
159     parse_multi_path(pvar->session_settings.KnownHostsFiles);
160     }
161    
162     //
163     // known_hosts�t�@�C�������e�������� pvar->hosts_state.file_data ����������
164     //
165     static int begin_read_file(PTInstVar pvar, char FAR * name,
166     int suppress_errors)
167     {
168     int fd;
169     int length;
170     int amount_read;
171     char buf[2048];
172    
173     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
174     fd = _open(buf, _O_RDONLY | _O_SEQUENTIAL | _O_BINARY);
175     if (fd == -1) {
176     if (!suppress_errors) {
177     if (errno == ENOENT) {
178     UTIL_get_lang_msg("MSG_HOSTS_READ_ENOENT_ERROR", pvar,
179     "An error occurred while trying to read a known_hosts file.\n"
180     "The specified filename does not exist.");
181     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
182     } else {
183     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
184     "An error occurred while trying to read a known_hosts file.");
185     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
186     }
187     }
188     return 0;
189     }
190    
191     length = (int) _lseek(fd, 0, SEEK_END);
192     _lseek(fd, 0, SEEK_SET);
193    
194     if (length >= 0 && length < 0x7FFFFFFF) {
195     pvar->hosts_state.file_data = malloc(length + 1);
196     if (pvar->hosts_state.file_data == NULL) {
197     if (!suppress_errors) {
198     UTIL_get_lang_msg("MSG_HOSTS_ALLOC_ERROR", pvar,
199     "Memory ran out while trying to allocate space to read a known_hosts file.");
200     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
201     }
202     _close(fd);
203     return 0;
204     }
205     } else {
206     if (!suppress_errors) {
207     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
208     "An error occurred while trying to read a known_hosts file.");
209     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
210     }
211     _close(fd);
212     return 0;
213     }
214    
215     amount_read = _read(fd, pvar->hosts_state.file_data, length);
216     pvar->hosts_state.file_data[length] = 0;
217    
218     _close(fd);
219    
220     if (amount_read != length) {
221     if (!suppress_errors) {
222     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
223     "An error occurred while trying to read a known_hosts file.");
224     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
225     }
226     free(pvar->hosts_state.file_data);
227     pvar->hosts_state.file_data = NULL;
228     return 0;
229     } else {
230     return 1;
231     }
232     }
233    
234     static int end_read_file(PTInstVar pvar, int suppress_errors)
235     {
236     free(pvar->hosts_state.file_data);
237     pvar->hosts_state.file_data = NULL;
238     return 1;
239     }
240    
241     static int begin_read_host_files(PTInstVar pvar, int suppress_errors)
242     {
243     pvar->hosts_state.file_num = 0;
244     pvar->hosts_state.file_data = NULL;
245     return 1;
246     }
247    
248     // MIME64�����������X�L�b�v����
249     static int eat_base64(char FAR * data)
250     {
251     int index = 0;
252     int ch;
253    
254     for (;;) {
255     ch = data[index];
256     if (ch == '=' || strchr(base64, ch)) {
257     // BASE64���\�������������������� index ���i����
258     index++;
259     } else {
260     break;
261     }
262     }
263    
264     return index;
265     }
266    
267     static int eat_spaces(char FAR * data)
268     {
269     int index = 0;
270     int ch;
271    
272     while ((ch = data[index]) == ' ' || ch == '\t') {
273     index++;
274     }
275     return index;
276     }
277    
278     static int eat_digits(char FAR * data)
279     {
280     int index = 0;
281     int ch;
282    
283     while ((ch = data[index]) >= '0' && ch <= '9') {
284     index++;
285     }
286     return index;
287     }
288    
289     static int eat_to_end_of_line(char FAR * data)
290     {
291     int index = 0;
292     int ch;
293    
294     while ((ch = data[index]) != '\n' && ch != '\r' && ch != 0) {
295     index++;
296     }
297    
298     while ((ch = data[index]) == '\n' || ch == '\r') {
299     index++;
300     }
301    
302     return index;
303     }
304    
305     static int eat_to_end_of_pattern(char FAR * data)
306     {
307     int index = 0;
308     int ch;
309    
310     while (ch = data[index], is_pattern_char(ch)) {
311     index++;
312     }
313    
314     return index;
315     }
316    
317     //
318     // BASE64�f�R�[�h�������s���B(rfc1521)
319     // src�o�b�t�@�� null-terminate ���������K�v�����B
320     //
321     static int uudecode(unsigned char *src, int srclen, unsigned char *target, int targsize)
322     {
323     char pad = '=';
324     int tarindex, state, ch;
325     char *pos;
326    
327     state = 0;
328     tarindex = 0;
329    
330     while ((ch = *src++) != '\0') {
331     if (isspace(ch)) /* Skip whitespace anywhere. */
332     continue;
333    
334     if (ch == pad)
335     break;
336    
337     pos = strchr(base64, ch);
338     if (pos == 0) /* A non-base64 character. */
339     return (-1);
340    
341     switch (state) {
342     case 0:
343     if (target) {
344     if (tarindex >= targsize)
345     return (-1);
346     target[tarindex] = (pos - base64) << 2;
347     }
348     state = 1;
349     break;
350     case 1:
351     if (target) {
352     if (tarindex + 1 >= targsize)
353     return (-1);
354     target[tarindex] |= (pos - base64) >> 4;
355     target[tarindex+1] = ((pos - base64) & 0x0f) << 4 ;
356     }
357     tarindex++;
358     state = 2;
359     break;
360     case 2:
361     if (target) {
362     if (tarindex + 1 >= targsize)
363     return (-1);
364     target[tarindex] |= (pos - base64) >> 2;
365     target[tarindex+1] = ((pos - base64) & 0x03) << 6;
366     }
367     tarindex++;
368     state = 3;
369     break;
370     case 3:
371     if (target) {
372     if (tarindex >= targsize)
373     return (-1);
374     target[tarindex] |= (pos - base64);
375     }
376     tarindex++;
377     state = 0;
378     break;
379     }
380     }
381    
382     /*
383     * We are done decoding Base-64 chars. Let's see if we ended
384     * on a byte boundary, and/or with erroneous trailing characters.
385     */
386    
387     if (ch == pad) { /* We got a pad char. */
388     ch = *src++; /* Skip it, get next. */
389     switch (state) {
390     case 0: /* Invalid = in first position */
391     case 1: /* Invalid = in second position */
392     return (-1);
393    
394     case 2: /* Valid, means one byte of info */
395     /* Skip any number of spaces. */
396     for (; ch != '\0'; ch = *src++)
397     if (!isspace(ch))
398     break;
399     /* Make sure there is another trailing = sign. */
400     if (ch != pad)
401     return (-1);
402     ch = *src++; /* Skip the = */
403     /* Fall through to "single trailing =" case. */
404     /* FALLTHROUGH */
405    
406     case 3: /* Valid, means two bytes of info */
407     /*
408     * We know this char is an =. Is there anything but
409     * whitespace after it?
410     */
411     for (; ch != '\0'; ch = *src++)
412     if (!isspace(ch))
413     return (-1);
414    
415     /*
416     * Now make sure for cases 2 and 3 that the "extra"
417     * bits that slopped past the last full byte were
418     * zeros. If we don't check them, they become a
419     * subliminal channel.
420     */
421     if (target && target[tarindex] != 0)
422     return (-1);
423     }
424     } else {
425     /*
426     * We ended by seeing the end of the string. Make sure we
427     * have no partial bytes lying around.
428     */
429     if (state != 0)
430     return (-1);
431     }
432    
433     return (tarindex);
434     }
435    
436    
437     // SSH2���� BASE64 �`�����i�[����������
438     static Key *parse_uudecode(char *data)
439     {
440     int count;
441     unsigned char *blob = NULL;
442     int len, n;
443     Key *key = NULL;
444     char ch;
445    
446     // BASE64���������T�C�Y������
447     count = eat_base64(data);
448     len = 2 * count;
449     blob = malloc(len);
450     if (blob == NULL)
451     goto error;
452    
453     // BASE64�f�R�[�h
454     ch = data[count];
455     data[count] = '\0'; // ���������s�R�[�h������������������������������������
456     n = uudecode(data, count, blob, len);
457     data[count] = ch;
458     if (n < 0) {
459     goto error;
460     }
461    
462     key = key_from_blob(blob, n);
463     if (key == NULL)
464     goto error;
465    
466     error:
467     if (blob != NULL)
468     free(blob);
469    
470     return (key);
471     }
472    
473    
474     static char FAR *parse_bignum(char FAR * data)
475     {
476     uint32 digits = 0;
477     BIGNUM *num = BN_new();
478     BIGNUM *billion = BN_new();
479     BIGNUM *digits_num = BN_new();
480     BN_CTX *ctx = BN_CTX_new();
481     char FAR *result;
482     int ch;
483     int leftover_digits = 1;
484    
485     BN_CTX_init(ctx);
486     BN_set_word(num, 0);
487     BN_set_word(billion, 1000000000L);
488    
489     while ((ch = *data) >= '0' && ch <= '9') {
490     if (leftover_digits == 1000000000L) {
491     BN_set_word(digits_num, digits);
492     BN_mul(num, num, billion, ctx);
493     BN_add(num, num, digits_num);
494     leftover_digits = 1;
495     digits = 0;
496     }
497    
498     digits = digits * 10 + ch - '0';
499     leftover_digits *= 10;
500     data++;
501     }
502    
503     BN_set_word(digits_num, digits);
504     BN_set_word(billion, leftover_digits);
505     BN_mul(num, num, billion, ctx);
506     BN_add(num, num, digits_num);
507    
508     result = (char FAR *) malloc(2 + BN_num_bytes(num));
509     set_ushort16_MSBfirst(result, BN_num_bits(num));
510     BN_bn2bin(num, result + 2);
511    
512     BN_CTX_free(ctx);
513     BN_free(digits_num);
514     BN_free(num);
515     BN_free(billion);
516    
517     return result;
518     }
519    
520     //
521     // known_hosts�t�@�C�������e���������A�w�������z�X�g�����J�����T���B
522     //
523     static int check_host_key(PTInstVar pvar, char FAR * hostname,
524     unsigned short tcpport, char FAR * data)
525     {
526     int index = eat_spaces(data);
527     int matched = 0;
528     int keybits = 0;
529    
530     if (data[index] == '#') {
531     return index + eat_to_end_of_line(data + index);
532     }
533    
534     /* if we find an empty line, then it won't have any patterns matching the hostname
535     and so we skip it */
536     index--;
537     do {
538     int negated;
539     int bracketed;
540     char *end_bracket;
541     int host_matched = 0;
542     unsigned short keyfile_port = 22;
543    
544     index++;
545     negated = data[index] == '!';
546    
547     if (negated) {
548     index++;
549     bracketed = data[index] == '[';
550     if (bracketed) {
551     end_bracket = strstr(data + index + 1, "]:");
552     if (end_bracket != NULL) {
553     *end_bracket = ' ';
554     index++;
555     }
556     }
557     host_matched = match_pattern(data + index, hostname);
558     if (bracketed && end_bracket != NULL) {
559     *end_bracket = ']';
560     keyfile_port = atoi(end_bracket + 2);
561     }
562     if (host_matched && keyfile_port == tcpport) {
563     return index + eat_to_end_of_line(data + index);
564     }
565     } else {
566     bracketed = data[index] == '[';
567     if (bracketed) {
568     end_bracket = strstr(data + index + 1, "]:");
569     if (end_bracket != NULL) {
570     *end_bracket = ' ';
571     index++;
572     }
573     }
574     host_matched = match_pattern(data + index, hostname);
575     if (bracketed && end_bracket != NULL) {
576     *end_bracket = ']';
577     keyfile_port = atoi(end_bracket + 2);
578     }
579     if (host_matched && keyfile_port == tcpport) {
580     matched = 1;
581     }
582     }
583    
584     index += eat_to_end_of_pattern(data + index);
585     } while (data[index] == ',');
586    
587     if (!matched) {
588     return index + eat_to_end_of_line(data + index);
589     } else {
590     // ���������������t�H�[�}�b�g��������
591     // �����A���������v�����G���g�����������������������B
592     /*
593     [SSH1]
594     192.168.1.2 1024 35 13032....
595    
596     [SSH2]
597     192.168.1.2 ssh-rsa AAAAB3NzaC1....
598     192.168.1.2 ssh-dss AAAAB3NzaC1....
599     192.168.1.2 rsa AAAAB3NzaC1....
600     192.168.1.2 dsa AAAAB3NzaC1....
601     192.168.1.2 rsa1 AAAAB3NzaC1....
602     */
603     int rsa1_key_bits;
604    
605     index += eat_spaces(data + index);
606    
607     rsa1_key_bits = atoi(data + index);
608     if (rsa1_key_bits > 0) { // RSA1������
609     if (!SSHv1(pvar)) { // SSH2��������������������
610     return index + eat_to_end_of_line(data + index);
611     }
612    
613     pvar->hosts_state.hostkey.type = KEY_RSA1;
614    
615     pvar->hosts_state.hostkey.bits = rsa1_key_bits;
616     index += eat_digits(data + index);
617     index += eat_spaces(data + index);
618    
619     pvar->hosts_state.hostkey.exp = parse_bignum(data + index);
620     index += eat_digits(data + index);
621     index += eat_spaces(data + index);
622    
623     pvar->hosts_state.hostkey.mod = parse_bignum(data + index);
624    
625     /*
626     if (pvar->hosts_state.key_bits < 0
627     || pvar->hosts_state.key_exp == NULL
628     || pvar->hosts_state.key_mod == NULL) {
629     pvar->hosts_state.key_bits = 0;
630     free(pvar->hosts_state.key_exp);
631     free(pvar->hosts_state.key_mod);
632     }*/
633    
634     } else {
635     char *cp, *p;
636     Key *key;
637    
638     if (!SSHv2(pvar)) { // SSH1��������������������
639     return index + eat_to_end_of_line(data + index);
640     }
641    
642     cp = data + index;
643     p = strchr(cp, ' ');
644     if (p == NULL) {
645     return index + eat_to_end_of_line(data + index);
646     }
647     index += (p - cp); // setup index
648     *p = '\0';
649     pvar->hosts_state.hostkey.type = get_keytype_from_name(cp);
650     *p = ' ';
651    
652     index += eat_spaces(data + index); // update index
653    
654     // uudecode
655     key = parse_uudecode(data + index);
656     if (key == NULL) {
657     return index + eat_to_end_of_line(data + index);
658     }
659    
660     // setup
661     pvar->hosts_state.hostkey.type = key->type;
662     pvar->hosts_state.hostkey.dsa = key->dsa;
663     pvar->hosts_state.hostkey.rsa = key->rsa;
664 maya 4321 pvar->hosts_state.hostkey.ecdsa = key->ecdsa;
665 maya 3227
666     index += eat_base64(data + index);
667     index += eat_spaces(data + index);
668    
669     // Key�\�������g���������� (2008.3.2 yutaka)
670     free(key);
671     }
672    
673     return index + eat_to_end_of_line(data + index);
674     }
675     }
676    
677     //
678     // known_hosts�t�@�C�������z�X�g�������v�����s������
679     //
680     static int read_host_key(PTInstVar pvar,
681     char FAR * hostname, unsigned short tcpport,
682     int suppress_errors, int return_always)
683     {
684     int i;
685     int while_flg;
686    
687     for (i = 0; hostname[i] != 0; i++) {
688     int ch = hostname[i];
689    
690     if (!is_pattern_char(ch) || ch == '*' || ch == '?') {
691     if (!suppress_errors) {
692     UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_INVALID_ERROR", pvar,
693     "The host name contains an invalid character.\n"
694     "This session will be terminated.");
695     notify_fatal_error(pvar, pvar->ts->UIMsg);
696     }
697     return 0;
698     }
699     }
700    
701     if (i == 0) {
702     if (!suppress_errors) {
703     UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_EMPTY_ERROR", pvar,
704     "The host name should not be empty.\n"
705     "This session will be terminated.");
706     notify_fatal_error(pvar, pvar->ts->UIMsg);
707     }
708     return 0;
709     }
710    
711     // hostkey type is KEY_UNSPEC.
712     init_hostkey(&pvar->hosts_state.hostkey);
713    
714     do {
715     if (pvar->hosts_state.file_data == NULL
716     || pvar->hosts_state.file_data[pvar->hosts_state.file_data_index] == 0) {
717     char FAR *filename;
718     int keep_going = 1;
719    
720     if (pvar->hosts_state.file_data != NULL) {
721     end_read_file(pvar, suppress_errors);
722     }
723    
724     do {
725     filename =
726     pvar->hosts_state.file_names[pvar->hosts_state.file_num];
727    
728     if (filename == NULL) {
729     return 1;
730     } else {
731     pvar->hosts_state.file_num++;
732    
733     if (filename[0] != 0) {
734     if (begin_read_file(pvar, filename, suppress_errors)) {
735     pvar->hosts_state.file_data_index = 0;
736     keep_going = 0;
737     }
738     }
739     }
740     } while (keep_going);
741     }
742    
743     pvar->hosts_state.file_data_index +=
744     check_host_key(pvar, hostname, tcpport,
745     pvar->hosts_state.file_data +
746     pvar->hosts_state.file_data_index);
747    
748     if (!return_always) {
749     // �L�����L�[��������������
750     while_flg = (pvar->hosts_state.hostkey.type == KEY_UNSPEC);
751     }
752     else {
753     while_flg = 0;
754     }
755     } while (while_flg);
756    
757     return 1;
758     }
759    
760     static void finish_read_host_files(PTInstVar pvar, int suppress_errors)
761     {
762     if (pvar->hosts_state.file_data != NULL) {
763     end_read_file(pvar, suppress_errors);
764     }
765     }
766    
767     // �T�[�o�����������O���Aknown_hosts�t�@�C�������z�X�g���J�������������������B
768     void HOSTS_prefetch_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport)
769     {
770     if (!begin_read_host_files(pvar, 1)) {
771     return;
772     }
773    
774     if (!read_host_key(pvar, hostname, tcpport, 1, 0)) {
775     return;
776     }
777    
778     free(pvar->hosts_state.prefetched_hostname);
779     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
780    
781     finish_read_host_files(pvar, 1);
782     }
783    
784     static BOOL equal_mp_ints(unsigned char FAR * num1,
785     unsigned char FAR * num2)
786     {
787     if (num1 == NULL || num2 == NULL) {
788     return FALSE;
789     } else {
790     uint32 bytes = (get_ushort16_MSBfirst(num1) + 7) / 8;
791    
792     if (bytes != (get_ushort16_MSBfirst(num2) + 7) / 8) {
793     return FALSE; /* different byte lengths */
794     } else {
795     return memcmp(num1 + 2, num2 + 2, bytes) == 0;
796     }
797     }
798     }
799    
800     // ���J����������������������
801 maya 4332 // -1 ... �����^������
802     // 0 ... ����������
803     // 1 ... ������
804     static int match_key(PTInstVar pvar, Key *key)
805 maya 3227 {
806     int bits;
807     unsigned char FAR * exp;
808     unsigned char FAR * mod;
809 maya 4321 const EC_GROUP *group;
810     const EC_POINT *pa, *pb;
811 maya 3227
812 maya 4332 if (pvar->hosts_state.hostkey.type != key->type) {
813     return -1;
814     }
815    
816 maya 4321 switch (key->type) {
817     case KEY_RSA1: // SSH1 host public key
818 maya 3227 bits = key->bits;
819     exp = key->exp;
820     mod = key->mod;
821    
822     /* just check for equal exponent and modulus */
823     return equal_mp_ints(exp, pvar->hosts_state.hostkey.exp)
824     && equal_mp_ints(mod, pvar->hosts_state.hostkey.mod);
825     /*
826     return equal_mp_ints(exp, pvar->hosts_state.key_exp)
827     && equal_mp_ints(mod, pvar->hosts_state.key_mod);
828     */
829    
830 maya 4321 case KEY_RSA: // SSH2 RSA host public key
831 maya 3227 return key->rsa != NULL && pvar->hosts_state.hostkey.rsa != NULL &&
832     BN_cmp(key->rsa->e, pvar->hosts_state.hostkey.rsa->e) == 0 &&
833     BN_cmp(key->rsa->n, pvar->hosts_state.hostkey.rsa->n) == 0;
834    
835 maya 4321 case KEY_DSA: // SSH2 DSA host public key
836 maya 3227 return key->dsa != NULL && pvar->hosts_state.hostkey.dsa &&
837     BN_cmp(key->dsa->p, pvar->hosts_state.hostkey.dsa->p) == 0 &&
838     BN_cmp(key->dsa->q, pvar->hosts_state.hostkey.dsa->q) == 0 &&
839     BN_cmp(key->dsa->g, pvar->hosts_state.hostkey.dsa->g) == 0 &&
840     BN_cmp(key->dsa->pub_key, pvar->hosts_state.hostkey.dsa->pub_key) == 0;
841    
842 maya 4321 case KEY_ECDSA256:
843     case KEY_ECDSA384:
844     case KEY_ECDSA521:
845     if (key->ecdsa == NULL || pvar->hosts_state.hostkey.ecdsa == NULL) {
846     return FALSE;
847     }
848     group = EC_KEY_get0_group(key->ecdsa);
849     pa = EC_KEY_get0_public_key(key->ecdsa),
850     pb = EC_KEY_get0_public_key(pvar->hosts_state.hostkey.ecdsa);
851     return EC_POINT_cmp(group, pa, pb, NULL) == 0;
852    
853     default:
854 maya 4307 return FALSE;
855     }
856 maya 3227
857     }
858    
859     static void init_hosts_dlg(PTInstVar pvar, HWND dlg)
860     {
861     char buf[1024];
862     char buf2[2048];
863     int i, j;
864     int ch;
865     char *fp = NULL;
866    
867     // static text�� # �������z�X�g�����u������
868     GetDlgItemText(dlg, IDC_HOSTWARNING, buf, sizeof(buf));
869     for (i = 0; (ch = buf[i]) != 0 && ch != '#'; i++) {
870     buf2[i] = ch;
871     }
872     strncpy_s(buf2 + i, sizeof(buf2) - i,
873     pvar->hosts_state.prefetched_hostname, _TRUNCATE);
874     j = i + strlen(buf2 + i);
875     for (; buf[i] == '#'; i++) {
876     }
877     strncpy_s(buf2 + j, sizeof(buf2) - j, buf + i, _TRUNCATE);
878    
879     SetDlgItemText(dlg, IDC_HOSTWARNING, buf2);
880    
881     // fingerprint����������
882     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX);
883     SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
884     free(fp);
885    
886     // �r�W���A����fingerprint���\������
887     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART);
888     SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETTEXT, 0, (LPARAM)fp);
889     SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), TRUE);
890     free(fp);
891     }
892    
893     static int print_mp_int(char FAR * buf, unsigned char FAR * mp)
894     {
895     int i = 0, j, k;
896     BIGNUM *num = BN_new();
897     int ch;
898    
899     BN_bin2bn(mp + 2, (get_ushort16_MSBfirst(mp) + 7) / 8, num);
900    
901     do {
902     buf[i] = (char) ((BN_div_word(num, 10)) + '0');
903     i++;
904     } while (!BN_is_zero(num));
905    
906     /* we need to reverse the digits */
907     for (j = 0, k = i - 1; j < k; j++, k--) {
908     ch = buf[j];
909     buf[j] = buf[k];
910     buf[k] = ch;
911     }
912    
913     buf[i] = 0;
914     return i;
915     }
916    
917     //
918     // known_hosts �t�@�C�������������G���g�������������B
919     //
920     static char FAR *format_host_key(PTInstVar pvar)
921     {
922     int host_len = strlen(pvar->hosts_state.prefetched_hostname);
923     char *result = NULL;
924     int index;
925 maya 4378 ssh_keytype type = pvar->hosts_state.hostkey.type;
926 maya 3227
927 maya 4321 switch (type) {
928     case KEY_RSA1:
929     {
930 maya 3227 int result_len = host_len + 50 + 8 +
931     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.exp) / 3 +
932     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.mod) / 3;
933     result = (char FAR *) malloc(result_len);
934    
935     if (pvar->ssh_state.tcpport == 22) {
936     strncpy_s(result, result_len, pvar->hosts_state.prefetched_hostname, _TRUNCATE);
937     index = host_len;
938     }
939     else {
940     _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
941     pvar->hosts_state.prefetched_hostname,
942     pvar->ssh_state.tcpport);
943     index = strlen(result);
944     }
945    
946     _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
947     " %d ", pvar->hosts_state.hostkey.bits);
948     index += strlen(result + index);
949     index += print_mp_int(result + index, pvar->hosts_state.hostkey.exp);
950     result[index] = ' ';
951     index++;
952     index += print_mp_int(result + index, pvar->hosts_state.hostkey.mod);
953     strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
954    
955 maya 4321 break;
956     }
957    
958     case KEY_RSA:
959     case KEY_DSA:
960     case KEY_ECDSA256:
961     case KEY_ECDSA384:
962     case KEY_ECDSA521:
963     {
964 maya 3227 Key *key = &pvar->hosts_state.hostkey;
965     char *blob = NULL;
966     int blen, uulen, msize;
967     char *uu = NULL;
968     int n;
969    
970     key_to_blob(key, &blob, &blen);
971     uulen = 2 * blen;
972     uu = malloc(uulen);
973     if (uu == NULL) {
974     goto error;
975     }
976     n = uuencode(blob, blen, uu, uulen);
977     if (n > 0) {
978     msize = host_len + 50 + uulen;
979     result = malloc(msize);
980     if (result == NULL) {
981     goto error;
982     }
983    
984     // setup
985     if (pvar->ssh_state.tcpport == 22) {
986     _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
987     pvar->hosts_state.prefetched_hostname,
988     get_sshname_from_key(key),
989     uu);
990     } else {
991     _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
992     pvar->hosts_state.prefetched_hostname,
993     pvar->ssh_state.tcpport,
994     get_sshname_from_key(key),
995     uu);
996     }
997     }
998     error:
999     if (blob != NULL)
1000     free(blob);
1001     if (uu != NULL)
1002     free(uu);
1003    
1004 maya 4321 break;
1005     }
1006    
1007     default:
1008 maya 3227 return NULL;
1009    
1010     }
1011    
1012     return result;
1013     }
1014    
1015     static void add_host_key(PTInstVar pvar)
1016     {
1017     char FAR *name = NULL;
1018    
1019     if ( pvar->hosts_state.file_names != NULL)
1020     name = pvar->hosts_state.file_names[0];
1021    
1022     if (name == NULL || name[0] == 0) {
1023     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1024     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1025     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1026     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1027     } else {
1028     char FAR *keydata = format_host_key(pvar);
1029     int length = strlen(keydata);
1030     int fd;
1031     int amount_written;
1032     int close_result;
1033     char buf[FILENAME_MAX];
1034    
1035     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1036     fd = _open(buf,
1037     _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1038     _S_IREAD | _S_IWRITE);
1039     if (fd == -1) {
1040     if (errno == EACCES) {
1041     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1042     "An error occurred while trying to write the host key.\n"
1043     "You do not have permission to write to the known-hosts file.");
1044     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1045     } else {
1046     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1047     "An error occurred while trying to write the host key.\n"
1048     "The host key could not be written.");
1049     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1050     }
1051     return;
1052     }
1053    
1054     amount_written = _write(fd, keydata, length);
1055     free(keydata);
1056     close_result = _close(fd);
1057    
1058     if (amount_written != length || close_result == -1) {
1059     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1060     "An error occurred while trying to write the host key.\n"
1061     "The host key could not be written.");
1062     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1063     }
1064     }
1065     }
1066    
1067     static char FAR *copy_mp_int(char FAR * num)
1068     {
1069     int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;
1070     char FAR *result = (char FAR *) malloc(len);
1071    
1072     if (result != NULL) {
1073     memcpy(result, num, len);
1074     }
1075    
1076     return result;
1077     }
1078    
1079     //
1080     // �����z�X�g�����e���������L�[����������
1081     // add_host_key ����������������
1082     //
1083     static void delete_different_key(PTInstVar pvar)
1084     {
1085     char FAR *name = pvar->hosts_state.file_names[0];
1086    
1087     if (name == NULL || name[0] == 0) {
1088     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1089     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1090     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1091     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1092     }
1093     else {
1094     Key key; // ���������z�X�g���L�[
1095     int length;
1096     char filename[MAX_PATH];
1097     char tmp[L_tmpnam];
1098     int fd;
1099     int amount_written = 0;
1100     int close_result;
1101     int data_index = 0;
1102     char buf[FILENAME_MAX];
1103    
1104     // �������������t�@�C�����J��
1105     _getcwd(filename, sizeof(filename));
1106     tmpnam_s(tmp,sizeof(tmp));
1107     strcat_s(filename, sizeof(filename), tmp);
1108     fd = _open(filename,
1109     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1110     _S_IREAD | _S_IWRITE);
1111    
1112     if (fd == -1) {
1113     if (errno == EACCES) {
1114     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1115     "An error occurred while trying to write the host key.\n"
1116     "You do not have permission to write to the known-hosts file.");
1117     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1118     } else {
1119     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1120     "An error occurred while trying to write the host key.\n"
1121     "The host key could not be written.");
1122     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1123     }
1124     return;
1125     }
1126    
1127     // ���������T�[�o���L�[����������
1128 maya 4321 switch (pvar->hosts_state.hostkey.type) {
1129     case KEY_RSA1: // SSH1
1130 maya 3227 key.type = KEY_RSA1;
1131     key.bits = pvar->hosts_state.hostkey.bits;
1132     key.exp = copy_mp_int(pvar->hosts_state.hostkey.exp);
1133     key.mod = copy_mp_int(pvar->hosts_state.hostkey.mod);
1134 maya 4321 break;
1135     case KEY_RSA: // SSH2 RSA
1136 maya 3227 key.type = KEY_RSA;
1137     key.rsa = duplicate_RSA(pvar->hosts_state.hostkey.rsa);
1138 maya 4321 break;
1139     case KEY_DSA: // SSH2 DSA
1140 maya 3227 key.type = KEY_DSA;
1141     key.dsa = duplicate_DSA(pvar->hosts_state.hostkey.dsa);
1142 maya 4321 break;
1143     case KEY_ECDSA256:
1144     case KEY_ECDSA384:
1145     case KEY_ECDSA521:
1146     key.type = pvar->hosts_state.hostkey.type;
1147     key.ecdsa = EC_KEY_dup(pvar->hosts_state.hostkey.ecdsa);
1148     break;
1149 maya 3227 }
1150    
1151     // �t�@�C��������������
1152     begin_read_host_files(pvar, 0);
1153     do {
1154     int host_index = 0;
1155     int matched = 0;
1156     int keybits = 0;
1157     char FAR *data;
1158     int do_write = 0;
1159     length = amount_written = 0;
1160    
1161     if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1)) {
1162     break;
1163     }
1164    
1165     if (data_index == pvar->hosts_state.file_data_index) {
1166     // index ���i������ == ��������������
1167     break;
1168     }
1169    
1170     data = pvar->hosts_state.file_data + data_index;
1171     host_index = eat_spaces(data);
1172    
1173     if (data[host_index] == '#') {
1174     do_write = 1;
1175     }
1176     else {
1177     // �z�X�g������
1178     host_index--;
1179     do {
1180     int negated;
1181     int bracketed;
1182     char *end_bracket;
1183     int host_matched = 0;
1184     unsigned short keyfile_port = 22;
1185    
1186     host_index++;
1187     negated = data[host_index] == '!';
1188    
1189     if (negated) {
1190     host_index++;
1191     bracketed = data[host_index] == '[';
1192     if (bracketed) {
1193     end_bracket = strstr(data + host_index + 1, "]:");
1194     if (end_bracket != NULL) {
1195     *end_bracket = ' ';
1196     host_index++;
1197     }
1198     }
1199     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1200     if (bracketed && end_bracket != NULL) {
1201     *end_bracket = ']';
1202     keyfile_port = atoi(end_bracket + 2);
1203     }
1204     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1205     matched = 0;
1206     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1207     host_index--;
1208     do {
1209     host_index++;
1210     host_index += eat_to_end_of_pattern(data + host_index);
1211     } while (data[host_index] == ',');
1212     break;
1213     }
1214     }
1215     else {
1216     bracketed = data[host_index] == '[';
1217     if (bracketed) {
1218     end_bracket = strstr(data + host_index + 1, "]:");
1219     if (end_bracket != NULL) {
1220     *end_bracket = ' ';
1221     host_index++;
1222     }
1223     }
1224     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1225     if (bracketed && end_bracket != NULL) {
1226     *end_bracket = ']';
1227     keyfile_port = atoi(end_bracket + 2);
1228     }
1229     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1230     matched = 1;
1231     }
1232     }
1233     host_index += eat_to_end_of_pattern(data + host_index);
1234     } while (data[host_index] == ',');
1235    
1236     // �z�X�g������������
1237 maya 4332 if (!matched) {
1238 maya 3227 do_write = 1;
1239     }
1240 maya 4332 // �z�X�g��������
1241 maya 3227 else {
1242 maya 4332 // �����`�������� or ���v�����L�[
1243     if (match_key(pvar, &key) != 0) {
1244     do_write = 1;
1245 maya 3227 }
1246 maya 4332 // �����`�������������v�������L�[���X�L�b�v������
1247 maya 3227 }
1248     }
1249    
1250     // ������������
1251     if (do_write) {
1252     length = pvar->hosts_state.file_data_index - data_index;
1253     amount_written =
1254     _write(fd, pvar->hosts_state.file_data + data_index,
1255     length);
1256    
1257     if (amount_written != length) {
1258     goto error1;
1259     }
1260     }
1261     data_index = pvar->hosts_state.file_data_index;
1262     } while (1); // ������������
1263    
1264     error1:
1265     close_result = _close(fd);
1266     if (amount_written != length || close_result == -1) {
1267     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1268     "An error occurred while trying to write the host key.\n"
1269     "The host key could not be written.");
1270     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1271     goto error2;
1272     }
1273    
1274     // �������������t�@�C���������l�[��
1275     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1276     _unlink(buf);
1277     rename(filename, buf);
1278    
1279     error2:
1280     _unlink(filename);
1281    
1282     finish_read_host_files(pvar, 0);
1283     }
1284     }
1285    
1286     //
1287     // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1288     // ���[�U���m�F�������B
1289     // TODO: finger print���\�����s���B
1290     // (2006.3.25 yutaka)
1291     //
1292     static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1293     LPARAM lParam)
1294     {
1295     PTInstVar pvar;
1296     LOGFONT logfont;
1297     HFONT font;
1298     char uimsg[MAX_UIMSG];
1299    
1300     switch (msg) {
1301     case WM_INITDIALOG:
1302     pvar = (PTInstVar) lParam;
1303     pvar->hosts_state.hosts_dialog = dlg;
1304     SetWindowLong(dlg, DWL_USER, lParam);
1305    
1306     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1307     GetWindowText(dlg, uimsg, sizeof(uimsg));
1308     UTIL_get_lang_msg("DLG_UNKNONWHOST_TITLE", pvar, uimsg);
1309     SetWindowText(dlg, pvar->ts->UIMsg);
1310     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1311 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING", pvar, uimsg);
1312 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1313     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1314 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING2", pvar, uimsg);
1315 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1316     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1317     UTIL_get_lang_msg("DLG_UNKNOWNHOST_FINGERPRINT", pvar, uimsg);
1318     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1319     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1320     UTIL_get_lang_msg("DLG_UNKNOWNHOST_ADD", pvar, uimsg);
1321     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1322     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1323     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1324     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1325     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1326     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1327     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1328    
1329 doda 4559 switch (pvar->dns_key_check) {
1330     case DNS_VERIFY_NOTFOUND:
1331     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "SSHFP RR not found.");
1332     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1333     break;
1334     case DNS_VERIFY_MATCH:
1335     case DNS_VERIFY_AUTH_MATCH:
1336     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "SSHFP RR found and match.");
1337     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1338     break;
1339     case DNS_VERIFY_MISMATCH:
1340     case DNS_VERIFY_AUTH_MISMATCH:
1341     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "SSHFP RR found but not match.");
1342     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1343     break;
1344     case DNS_VERIFY_DIFFERENTTYPE:
1345     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1346     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "SSHFP RR found but different type.");
1347     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1348     break;
1349     }
1350    
1351     switch (pvar->dns_key_check) {
1352     case DNS_VERIFY_MATCH:
1353     case DNS_VERIFY_MISMATCH:
1354     case DNS_VERIFY_DIFFERENTTYPE:
1355     UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "SSHFP RR is *not* authenticated by DNSSEC.");
1356     SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1357     break;
1358     case DNS_VERIFY_AUTH_MATCH:
1359     case DNS_VERIFY_AUTH_MISMATCH:
1360     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1361     UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "SSHFP RR is authenticated by DNSSEC.");
1362     SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1363     break;
1364     }
1365    
1366 maya 3227 init_hosts_dlg(pvar, dlg);
1367    
1368     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1369     GetObject(font, sizeof(LOGFONT), &logfont);
1370     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1371     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1372     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1373     SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1374     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1375     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1376     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1377     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1378     }
1379     else {
1380     DlgHostsAddFont = NULL;
1381     }
1382    
1383     // add host check box���`�F�b�N���f�t�H���g������������
1384     SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1385    
1386     return TRUE; /* because we do not set the focus */
1387    
1388     case WM_COMMAND:
1389     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1390    
1391     switch (LOWORD(wParam)) {
1392     case IDC_CONTINUE:
1393     if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1394     add_host_key(pvar);
1395     }
1396    
1397     if (SSHv1(pvar)) {
1398     SSH_notify_host_OK(pvar);
1399     } else { // SSH2
1400     // SSH2���������� SSH_notify_host_OK() �������B
1401     }
1402    
1403     pvar->hosts_state.hosts_dialog = NULL;
1404    
1405     EndDialog(dlg, 1);
1406    
1407     if (DlgHostsAddFont != NULL) {
1408     DeleteObject(DlgHostsAddFont);
1409     }
1410    
1411     return TRUE;
1412    
1413     case IDCANCEL: /* kill the connection */
1414     pvar->hosts_state.hosts_dialog = NULL;
1415     notify_closed_connection(pvar);
1416     EndDialog(dlg, 0);
1417    
1418     if (DlgHostsAddFont != NULL) {
1419     DeleteObject(DlgHostsAddFont);
1420     }
1421    
1422     return TRUE;
1423    
1424     default:
1425     return FALSE;
1426     }
1427    
1428     default:
1429     return FALSE;
1430     }
1431     }
1432    
1433     //
1434     // �u�����������m�F�_�C�A���O������
1435     //
1436     static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1437     LPARAM lParam)
1438     {
1439     PTInstVar pvar;
1440     LOGFONT logfont;
1441     HFONT font;
1442     char uimsg[MAX_UIMSG];
1443    
1444     switch (msg) {
1445     case WM_INITDIALOG:
1446     pvar = (PTInstVar) lParam;
1447     pvar->hosts_state.hosts_dialog = dlg;
1448     SetWindowLong(dlg, DWL_USER, lParam);
1449    
1450     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1451     GetWindowText(dlg, uimsg, sizeof(uimsg));
1452 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
1453 maya 3227 SetWindowText(dlg, pvar->ts->UIMsg);
1454     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1455 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
1456 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1457     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1458 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
1459 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1460     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1461 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
1462 maya 3227 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1463     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1464 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
1465 maya 3227 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1466     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1467     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1468     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1469     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1470     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1471     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1472    
1473 doda 4559 switch (pvar->dns_key_check) {
1474     case DNS_VERIFY_NOTFOUND:
1475     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "SSHFP RR not found.");
1476     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1477     break;
1478     case DNS_VERIFY_MATCH:
1479     case DNS_VERIFY_AUTH_MATCH:
1480     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "SSHFP RR found and match.");
1481     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1482     break;
1483     case DNS_VERIFY_MISMATCH:
1484     case DNS_VERIFY_AUTH_MISMATCH:
1485     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "SSHFP RR found but not match.");
1486     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1487     break;
1488     case DNS_VERIFY_DIFFERENTTYPE:
1489     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1490     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "SSHFP RR found but different type.");
1491     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1492     break;
1493     }
1494    
1495     switch (pvar->dns_key_check) {
1496     case DNS_VERIFY_MATCH:
1497     case DNS_VERIFY_MISMATCH:
1498     case DNS_VERIFY_DIFFERENTTYPE:
1499     UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "SSHFP RR is *not* authenticated by DNSSEC.");
1500     SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1501     break;
1502     case DNS_VERIFY_AUTH_MATCH:
1503     case DNS_VERIFY_AUTH_MISMATCH:
1504     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1505     UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "SSHFP RR is authenticated by DNSSEC.");
1506     SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1507     break;
1508     }
1509    
1510 maya 3227 init_hosts_dlg(pvar, dlg);
1511    
1512     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1513     GetObject(font, sizeof(LOGFONT), &logfont);
1514     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
1515     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1516     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1517     SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1518     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1519     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1520     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1521     }
1522     else {
1523     DlgHostsReplaceFont = NULL;
1524     }
1525    
1526     // �f�t�H���g���`�F�b�N����������
1527     return TRUE; /* because we do not set the focus */
1528    
1529     case WM_COMMAND:
1530     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1531    
1532     switch (LOWORD(wParam)) {
1533     case IDC_CONTINUE:
1534     if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1535     add_host_key(pvar);
1536     delete_different_key(pvar);
1537     }
1538    
1539     if (SSHv1(pvar)) {
1540     SSH_notify_host_OK(pvar);
1541     } else { // SSH2
1542     // SSH2���������� SSH_notify_host_OK() �������B
1543     }
1544    
1545     pvar->hosts_state.hosts_dialog = NULL;
1546    
1547     EndDialog(dlg, 1);
1548    
1549     if (DlgHostsReplaceFont != NULL) {
1550     DeleteObject(DlgHostsReplaceFont);
1551     }
1552    
1553     return TRUE;
1554    
1555     case IDCANCEL: /* kill the connection */
1556     pvar->hosts_state.hosts_dialog = NULL;
1557     notify_closed_connection(pvar);
1558     EndDialog(dlg, 0);
1559    
1560     if (DlgHostsReplaceFont != NULL) {
1561     DeleteObject(DlgHostsReplaceFont);
1562     }
1563    
1564     return TRUE;
1565    
1566     default:
1567     return FALSE;
1568     }
1569    
1570     default:
1571     return FALSE;
1572     }
1573     }
1574    
1575 maya 4332 //
1576     // �����z�X�g�����`�����������������m�F�_�C�A���O������
1577     //
1578     static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1579     LPARAM lParam)
1580     {
1581     PTInstVar pvar;
1582     LOGFONT logfont;
1583     HFONT font;
1584     char uimsg[MAX_UIMSG];
1585    
1586     switch (msg) {
1587     case WM_INITDIALOG:
1588     pvar = (PTInstVar) lParam;
1589     pvar->hosts_state.hosts_dialog = dlg;
1590     SetWindowLong(dlg, DWL_USER, lParam);
1591    
1592     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1593     GetWindowText(dlg, uimsg, sizeof(uimsg));
1594     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
1595     SetWindowText(dlg, pvar->ts->UIMsg);
1596     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1597 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
1598 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1599     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1600 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
1601 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1602     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1603     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
1604     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1605     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1606     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
1607     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1608     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1609     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1610     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1611     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1612     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1613     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1614    
1615 doda 4559 switch (pvar->dns_key_check) {
1616     case DNS_VERIFY_NOTFOUND:
1617     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "SSHFP RR not found.");
1618     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1619     break;
1620     case DNS_VERIFY_MATCH:
1621     case DNS_VERIFY_AUTH_MATCH:
1622     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "SSHFP RR found and match.");
1623     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1624     break;
1625     case DNS_VERIFY_MISMATCH:
1626     case DNS_VERIFY_AUTH_MISMATCH:
1627     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "SSHFP RR found but not match.");
1628     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1629     break;
1630     case DNS_VERIFY_DIFFERENTTYPE:
1631     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1632     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "SSHFP RR found but different type.");
1633     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1634     break;
1635     }
1636    
1637     switch (pvar->dns_key_check) {
1638     case DNS_VERIFY_MATCH:
1639     case DNS_VERIFY_MISMATCH:
1640     case DNS_VERIFY_DIFFERENTTYPE:
1641     UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "SSHFP RR is *not* authenticated by DNSSEC.");
1642     SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1643     break;
1644     case DNS_VERIFY_AUTH_MATCH:
1645     case DNS_VERIFY_AUTH_MISMATCH:
1646     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1647     UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "SSHFP RR is authenticated by DNSSEC.");
1648     SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1649     break;
1650     }
1651    
1652 maya 4332 init_hosts_dlg(pvar, dlg);
1653    
1654     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1655     GetObject(font, sizeof(LOGFONT), &logfont);
1656     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1657     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1658     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1659     SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1660     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1661     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1662     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1663     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1664     }
1665     else {
1666     DlgHostsAddFont = NULL;
1667     }
1668    
1669     // add host check box ���f�t�H���g�� off ������
1670     // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1671    
1672     return TRUE; /* because we do not set the focus */
1673    
1674     case WM_COMMAND:
1675     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1676    
1677     switch (LOWORD(wParam)) {
1678     case IDC_CONTINUE:
1679     if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1680     add_host_key(pvar);
1681     }
1682    
1683     if (SSHv1(pvar)) {
1684     SSH_notify_host_OK(pvar);
1685     } else { // SSH2
1686     // SSH2���������� SSH_notify_host_OK() �������B
1687     }
1688    
1689     pvar->hosts_state.hosts_dialog = NULL;
1690    
1691     EndDialog(dlg, 1);
1692    
1693     if (DlgHostsAddFont != NULL) {
1694     DeleteObject(DlgHostsAddFont);
1695     }
1696    
1697     return TRUE;
1698    
1699     case IDCANCEL: /* kill the connection */
1700     pvar->hosts_state.hosts_dialog = NULL;
1701     notify_closed_connection(pvar);
1702     EndDialog(dlg, 0);
1703    
1704     if (DlgHostsAddFont != NULL) {
1705     DeleteObject(DlgHostsAddFont);
1706     }
1707    
1708     return TRUE;
1709    
1710     default:
1711     return FALSE;
1712     }
1713    
1714     default:
1715     return FALSE;
1716     }
1717     }
1718    
1719 maya 3227 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
1720     {
1721     if (pvar->hosts_state.hosts_dialog == NULL) {
1722     HWND cur_active = GetActiveWindow();
1723    
1724     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
1725     cur_active != NULL ? cur_active : wnd,
1726     hosts_add_dlg_proc, (LPARAM) pvar);
1727     }
1728     }
1729    
1730 maya 4330 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
1731 maya 3227 {
1732     if (pvar->hosts_state.hosts_dialog == NULL) {
1733     HWND cur_active = GetActiveWindow();
1734    
1735 maya 4330 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
1736 maya 3227 cur_active != NULL ? cur_active : wnd,
1737     hosts_replace_dlg_proc, (LPARAM) pvar);
1738     }
1739     }
1740    
1741 maya 4332 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
1742     {
1743     if (pvar->hosts_state.hosts_dialog == NULL) {
1744     HWND cur_active = GetActiveWindow();
1745    
1746     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
1747     cur_active != NULL ? cur_active : wnd,
1748     hosts_add2_dlg_proc, (LPARAM) pvar);
1749     }
1750     }
1751    
1752 doda 4531 int is_numeric_hostname(const char *hostname)
1753     {
1754     struct addrinfo hints, *ai;
1755    
1756     if (hostname == NULL) {
1757     return -1;
1758     }
1759    
1760     memset(&hints, 0, sizeof(hints));
1761     hints.ai_socktype = SOCK_DGRAM;
1762     hints.ai_flags = AI_NUMERICHOST;
1763    
1764     if (getaddrinfo(hostname, NULL, &hints, &ai) == 0) {
1765     freeaddrinfo(ai);
1766     return 1;
1767     }
1768    
1769     return 0;
1770     }
1771    
1772     int verify_hostkey_dns(char FAR *hostname, Key *key)
1773     {
1774     DNS_STATUS status;
1775     PDNS_RECORD rec, p;
1776     PDNS_SSHFP_DATA t;
1777     int hostkey_alg, hostkey_dtype, hostkey_dlen;
1778     BYTE *hostkey_digest;
1779 doda 4559 int found = DNS_VERIFY_NOTFOUND;
1780 doda 4531
1781     switch (key->type) {
1782     case KEY_RSA:
1783     hostkey_alg = SSHFP_KEY_RSA;
1784 doda 4539 hostkey_dtype = SSHFP_HASH_SHA1;
1785 doda 4531 break;
1786     case KEY_DSA:
1787     hostkey_alg = SSHFP_KEY_DSA;
1788 doda 4539 hostkey_dtype = SSHFP_HASH_SHA1;
1789 doda 4531 break;
1790 doda 4539 case KEY_ECDSA256:
1791     case KEY_ECDSA384:
1792     case KEY_ECDSA521:
1793     hostkey_alg = SSHFP_KEY_ECDSA;
1794     hostkey_dtype = SSHFP_HASH_SHA256;
1795     break;
1796 doda 4540 default: // Un-supported algorithm
1797 doda 4531 hostkey_alg = SSHFP_KEY_RESERVED;
1798 doda 4539 hostkey_dtype = SSHFP_HASH_RESERVED;
1799 doda 4531 }
1800    
1801     if (hostkey_alg) {
1802 doda 4539 hostkey_digest = key_fingerprint_raw(key, hostkey_dtype, &hostkey_dlen);
1803 doda 4531 }
1804     else {
1805     hostkey_digest = NULL;
1806     }
1807    
1808     status = DnsQuery(hostname, DNS_TYPE_SSHFP, DNS_QUERY_STANDARD, NULL, &rec, NULL);
1809    
1810     if (status == 0) {
1811     for (p=rec; p!=NULL; p=p->pNext) {
1812     if (p->wType == DNS_TYPE_SSHFP) {
1813     t = (PDNS_SSHFP_DATA)&(p->Data.Null);
1814     if (t->Algorithm == hostkey_alg && t->DigestType == hostkey_dtype) {
1815     if (hostkey_dlen == p->wDataLength-2 && memcmp(hostkey_digest, t->Digest, hostkey_dlen) == 0) {
1816     found = DNS_VERIFY_MATCH;
1817     break;
1818     }
1819     else {
1820     found = DNS_VERIFY_MISMATCH;
1821     break;
1822     }
1823     }
1824     else {
1825     found = DNS_VERIFY_DIFFERENTTYPE;
1826     }
1827     }
1828     }
1829     }
1830    
1831     free(hostkey_digest);
1832     DnsRecordListFree(rec, DnsFreeRecordList);
1833     return found;
1834     }
1835    
1836 maya 3227 //
1837     // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
1838     //
1839     // SSH2���������� (2006.3.24 yutaka)
1840     //
1841     BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key)
1842     {
1843 doda 4559 int found_different_key = 0, found_different_type_key = 0;
1844 maya 3227
1845 doda 4559 pvar->dns_key_check = DNS_VERIFY_NONE;
1846    
1847 maya 3227 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
1848     if (pvar->hosts_state.prefetched_hostname != NULL
1849     && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
1850 maya 4332 && match_key(pvar, key) == 1) {
1851 maya 3227
1852     if (SSHv1(pvar)) {
1853     SSH_notify_host_OK(pvar);
1854     } else {
1855     // SSH2���������� SSH_notify_host_OK() �������B
1856     }
1857     return TRUE;
1858     }
1859    
1860     // �������������������������A�������_���t�@�C��������������
1861     if (begin_read_host_files(pvar, 0)) {
1862     do {
1863     if (!read_host_key(pvar, hostname, tcpport, 0, 0)) {
1864     break;
1865     }
1866    
1867     if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
1868 maya 4332 int match = match_key(pvar, key);
1869     if (match == 1) {
1870 maya 3227 finish_read_host_files(pvar, 0);
1871     // ���������G���g�����Q�������A���v�����L�[�������������������B
1872     // SSH2���������������������������B(2006.3.29 yutaka)
1873     if (SSHv1(pvar)) {
1874     SSH_notify_host_OK(pvar);
1875     } else {
1876     // SSH2���������� SSH_notify_host_OK() �������B
1877     }
1878     return TRUE;
1879 maya 4332 }
1880     else if (match == 0) {
1881 maya 3227 // �L�[�� known_hosts ���������������A�L�[�����e���������B
1882     found_different_key = 1;
1883     }
1884 maya 4332 else {
1885     // �L�[���`������������
1886     found_different_type_key = 1;
1887     }
1888 maya 3227 }
1889     } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // �L�[�����������������������[�v����
1890    
1891     finish_read_host_files(pvar, 0);
1892     }
1893    
1894     // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
1895     pvar->hosts_state.hostkey.type = key->type;
1896 maya 4321 switch (key->type) {
1897     case KEY_RSA1: // SSH1
1898 maya 3227 pvar->hosts_state.hostkey.bits = key->bits;
1899     pvar->hosts_state.hostkey.exp = copy_mp_int(key->exp);
1900     pvar->hosts_state.hostkey.mod = copy_mp_int(key->mod);
1901 maya 4321 break;
1902     case KEY_RSA: // SSH2 RSA
1903 maya 3227 pvar->hosts_state.hostkey.rsa = duplicate_RSA(key->rsa);
1904 maya 4321 break;
1905     case KEY_DSA: // SSH2 DSA
1906 maya 3227 pvar->hosts_state.hostkey.dsa = duplicate_DSA(key->dsa);
1907 maya 4321 break;
1908     case KEY_ECDSA256: // SSH2 ECDSA
1909     case KEY_ECDSA384:
1910     case KEY_ECDSA521:
1911     pvar->hosts_state.hostkey.ecdsa = EC_KEY_dup(key->ecdsa);
1912     break;
1913 maya 3227 }
1914     free(pvar->hosts_state.prefetched_hostname);
1915     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
1916    
1917 yutakapon 3631 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
1918     if (pvar->nocheck_known_hosts == TRUE) {
1919     return TRUE;
1920     }
1921    
1922 doda 4542 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
1923 doda 4559 pvar->dns_key_check = verify_hostkey_dns(hostname, key);
1924 doda 4542 }
1925    
1926 maya 3227 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
1927     // �������K�v�����������A�����R�[�������X�����B
1928     // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
1929     // (2007.10.1 yutaka)
1930     if (found_different_key) {
1931 maya 4330 HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar);
1932 maya 4332 }
1933     else if (found_different_type_key) {
1934     HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar);
1935     }
1936     else {
1937 maya 3227 HOSTS_do_unknown_host_dialog(pvar->NotificationWindow, pvar);
1938     }
1939    
1940     return TRUE;
1941     }
1942    
1943     void HOSTS_notify_disconnecting(PTInstVar pvar)
1944     {
1945     if (pvar->hosts_state.hosts_dialog != NULL) {
1946 doda 4531 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
1947 maya 3227 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
1948     EnableWindow(pvar->NotificationWindow, TRUE);
1949     }
1950     }
1951    
1952     void HOSTS_end(PTInstVar pvar)
1953     {
1954     int i;
1955    
1956     free(pvar->hosts_state.prefetched_hostname);
1957     init_hostkey(&pvar->hosts_state.hostkey);
1958    
1959     if (pvar->hosts_state.file_names != NULL) {
1960     for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
1961     free(pvar->hosts_state.file_names[i]);
1962     }
1963     free(pvar->hosts_state.file_names);
1964     }
1965     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26