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 4565 - (hide annotations) (download) (as text)
Tue Aug 2 11:50:35 2011 UTC (12 years, 8 months ago) by maya
File MIME type: text/x-csrc
File size: 56896 byte(s)
新しいラベルにフォントを適用
1 maya 3227 /*
2     Copyright (c) 1998-2001, Robert O'Callahan
3     All rights reserved.
4    
5     Redistribution and use in source and binary forms, with or without modification,
6     are permitted provided that the following conditions are met:
7    
8     Redistributions of source code must retain the above copyright notice, this list of
9     conditions and the following disclaimer.
10    
11     Redistributions in binary form must reproduce the above copyright notice, this list
12     of conditions and the following disclaimer in the documentation and/or other materials
13     provided with the distribution.
14    
15     The name of Robert O'Callahan may not be used to endorse or promote products derived from
16     this software without specific prior written permission.
17    
18     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21     THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27     */
28    
29     /*
30     This code is copyright (C) 1998-1999 Robert O'Callahan.
31     See LICENSE.TXT for the license.
32     */
33    
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 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1374     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1375 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1376     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1377     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1378     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1379     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1380     }
1381     else {
1382     DlgHostsAddFont = NULL;
1383     }
1384    
1385     // add host check box���`�F�b�N���f�t�H���g������������
1386     SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1387    
1388     return TRUE; /* because we do not set the focus */
1389    
1390     case WM_COMMAND:
1391     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1392    
1393     switch (LOWORD(wParam)) {
1394     case IDC_CONTINUE:
1395     if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1396     add_host_key(pvar);
1397     }
1398    
1399     if (SSHv1(pvar)) {
1400     SSH_notify_host_OK(pvar);
1401     } else { // SSH2
1402     // SSH2���������� SSH_notify_host_OK() �������B
1403     }
1404    
1405     pvar->hosts_state.hosts_dialog = NULL;
1406    
1407     EndDialog(dlg, 1);
1408    
1409     if (DlgHostsAddFont != NULL) {
1410     DeleteObject(DlgHostsAddFont);
1411     }
1412    
1413     return TRUE;
1414    
1415     case IDCANCEL: /* kill the connection */
1416     pvar->hosts_state.hosts_dialog = NULL;
1417     notify_closed_connection(pvar);
1418     EndDialog(dlg, 0);
1419    
1420     if (DlgHostsAddFont != NULL) {
1421     DeleteObject(DlgHostsAddFont);
1422     }
1423    
1424     return TRUE;
1425    
1426     default:
1427     return FALSE;
1428     }
1429    
1430     default:
1431     return FALSE;
1432     }
1433     }
1434    
1435     //
1436     // �u�����������m�F�_�C�A���O������
1437     //
1438     static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1439     LPARAM lParam)
1440     {
1441     PTInstVar pvar;
1442     LOGFONT logfont;
1443     HFONT font;
1444     char uimsg[MAX_UIMSG];
1445    
1446     switch (msg) {
1447     case WM_INITDIALOG:
1448     pvar = (PTInstVar) lParam;
1449     pvar->hosts_state.hosts_dialog = dlg;
1450     SetWindowLong(dlg, DWL_USER, lParam);
1451    
1452     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1453     GetWindowText(dlg, uimsg, sizeof(uimsg));
1454 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
1455 maya 3227 SetWindowText(dlg, pvar->ts->UIMsg);
1456     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1457 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
1458 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1459     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1460 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
1461 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1462     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1463 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
1464 maya 3227 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1465     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1466 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
1467 maya 3227 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1468     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1469     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1470     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1471     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1472     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1473     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1474    
1475 doda 4559 switch (pvar->dns_key_check) {
1476     case DNS_VERIFY_NOTFOUND:
1477     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "SSHFP RR not found.");
1478     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1479     break;
1480     case DNS_VERIFY_MATCH:
1481     case DNS_VERIFY_AUTH_MATCH:
1482     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "SSHFP RR found and match.");
1483     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1484     break;
1485     case DNS_VERIFY_MISMATCH:
1486     case DNS_VERIFY_AUTH_MISMATCH:
1487     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "SSHFP RR found but not match.");
1488     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1489     break;
1490     case DNS_VERIFY_DIFFERENTTYPE:
1491     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1492     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "SSHFP RR found but different type.");
1493     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1494     break;
1495     }
1496    
1497     switch (pvar->dns_key_check) {
1498     case DNS_VERIFY_MATCH:
1499     case DNS_VERIFY_MISMATCH:
1500     case DNS_VERIFY_DIFFERENTTYPE:
1501     UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "SSHFP RR is *not* authenticated by DNSSEC.");
1502     SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1503     break;
1504     case DNS_VERIFY_AUTH_MATCH:
1505     case DNS_VERIFY_AUTH_MISMATCH:
1506     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1507     UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "SSHFP RR is authenticated by DNSSEC.");
1508     SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1509     break;
1510     }
1511    
1512 maya 3227 init_hosts_dlg(pvar, dlg);
1513    
1514     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1515     GetObject(font, sizeof(LOGFONT), &logfont);
1516     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
1517     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1518     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1519 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1520     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1521 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1522     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1523     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1524     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1525     }
1526     else {
1527     DlgHostsReplaceFont = NULL;
1528     }
1529    
1530     // �f�t�H���g���`�F�b�N����������
1531     return TRUE; /* because we do not set the focus */
1532    
1533     case WM_COMMAND:
1534     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1535    
1536     switch (LOWORD(wParam)) {
1537     case IDC_CONTINUE:
1538     if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1539     add_host_key(pvar);
1540     delete_different_key(pvar);
1541     }
1542    
1543     if (SSHv1(pvar)) {
1544     SSH_notify_host_OK(pvar);
1545     } else { // SSH2
1546     // SSH2���������� SSH_notify_host_OK() �������B
1547     }
1548    
1549     pvar->hosts_state.hosts_dialog = NULL;
1550    
1551     EndDialog(dlg, 1);
1552    
1553     if (DlgHostsReplaceFont != NULL) {
1554     DeleteObject(DlgHostsReplaceFont);
1555     }
1556    
1557     return TRUE;
1558    
1559     case IDCANCEL: /* kill the connection */
1560     pvar->hosts_state.hosts_dialog = NULL;
1561     notify_closed_connection(pvar);
1562     EndDialog(dlg, 0);
1563    
1564     if (DlgHostsReplaceFont != NULL) {
1565     DeleteObject(DlgHostsReplaceFont);
1566     }
1567    
1568     return TRUE;
1569    
1570     default:
1571     return FALSE;
1572     }
1573    
1574     default:
1575     return FALSE;
1576     }
1577     }
1578    
1579 maya 4332 //
1580     // �����z�X�g�����`�����������������m�F�_�C�A���O������
1581     //
1582     static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1583     LPARAM lParam)
1584     {
1585     PTInstVar pvar;
1586     LOGFONT logfont;
1587     HFONT font;
1588     char uimsg[MAX_UIMSG];
1589    
1590     switch (msg) {
1591     case WM_INITDIALOG:
1592     pvar = (PTInstVar) lParam;
1593     pvar->hosts_state.hosts_dialog = dlg;
1594     SetWindowLong(dlg, DWL_USER, lParam);
1595    
1596     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1597     GetWindowText(dlg, uimsg, sizeof(uimsg));
1598     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
1599     SetWindowText(dlg, pvar->ts->UIMsg);
1600     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1601 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
1602 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1603     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1604 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
1605 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1606     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1607     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
1608     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1609     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1610     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
1611     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1612     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1613     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1614     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1615     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1616     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1617     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1618    
1619 doda 4559 switch (pvar->dns_key_check) {
1620     case DNS_VERIFY_NOTFOUND:
1621     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "SSHFP RR not found.");
1622     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1623     break;
1624     case DNS_VERIFY_MATCH:
1625     case DNS_VERIFY_AUTH_MATCH:
1626     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "SSHFP RR found and match.");
1627     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1628     break;
1629     case DNS_VERIFY_MISMATCH:
1630     case DNS_VERIFY_AUTH_MISMATCH:
1631     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "SSHFP RR found but not match.");
1632     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1633     break;
1634     case DNS_VERIFY_DIFFERENTTYPE:
1635     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1636     UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "SSHFP RR found but different type.");
1637     SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1638     break;
1639     }
1640    
1641     switch (pvar->dns_key_check) {
1642     case DNS_VERIFY_MATCH:
1643     case DNS_VERIFY_MISMATCH:
1644     case DNS_VERIFY_DIFFERENTTYPE:
1645     UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "SSHFP RR is *not* authenticated by DNSSEC.");
1646     SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1647     break;
1648     case DNS_VERIFY_AUTH_MATCH:
1649     case DNS_VERIFY_AUTH_MISMATCH:
1650     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1651     UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "SSHFP RR is authenticated by DNSSEC.");
1652     SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1653     break;
1654     }
1655    
1656 maya 4332 init_hosts_dlg(pvar, dlg);
1657    
1658     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1659     GetObject(font, sizeof(LOGFONT), &logfont);
1660     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1661     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1662     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1663 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1664     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1665 maya 4332 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1666     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1667     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1668     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1669     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1670     }
1671     else {
1672     DlgHostsAddFont = NULL;
1673     }
1674    
1675     // add host check box ���f�t�H���g�� off ������
1676     // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1677    
1678     return TRUE; /* because we do not set the focus */
1679    
1680     case WM_COMMAND:
1681     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1682    
1683     switch (LOWORD(wParam)) {
1684     case IDC_CONTINUE:
1685     if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1686     add_host_key(pvar);
1687     }
1688    
1689     if (SSHv1(pvar)) {
1690     SSH_notify_host_OK(pvar);
1691     } else { // SSH2
1692     // SSH2���������� SSH_notify_host_OK() �������B
1693     }
1694    
1695     pvar->hosts_state.hosts_dialog = NULL;
1696    
1697     EndDialog(dlg, 1);
1698    
1699     if (DlgHostsAddFont != NULL) {
1700     DeleteObject(DlgHostsAddFont);
1701     }
1702    
1703     return TRUE;
1704    
1705     case IDCANCEL: /* kill the connection */
1706     pvar->hosts_state.hosts_dialog = NULL;
1707     notify_closed_connection(pvar);
1708     EndDialog(dlg, 0);
1709    
1710     if (DlgHostsAddFont != NULL) {
1711     DeleteObject(DlgHostsAddFont);
1712     }
1713    
1714     return TRUE;
1715    
1716     default:
1717     return FALSE;
1718     }
1719    
1720     default:
1721     return FALSE;
1722     }
1723     }
1724    
1725 maya 3227 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
1726     {
1727     if (pvar->hosts_state.hosts_dialog == NULL) {
1728     HWND cur_active = GetActiveWindow();
1729    
1730     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
1731     cur_active != NULL ? cur_active : wnd,
1732     hosts_add_dlg_proc, (LPARAM) pvar);
1733     }
1734     }
1735    
1736 maya 4330 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
1737 maya 3227 {
1738     if (pvar->hosts_state.hosts_dialog == NULL) {
1739     HWND cur_active = GetActiveWindow();
1740    
1741 maya 4330 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
1742 maya 3227 cur_active != NULL ? cur_active : wnd,
1743     hosts_replace_dlg_proc, (LPARAM) pvar);
1744     }
1745     }
1746    
1747 maya 4332 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
1748     {
1749     if (pvar->hosts_state.hosts_dialog == NULL) {
1750     HWND cur_active = GetActiveWindow();
1751    
1752     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
1753     cur_active != NULL ? cur_active : wnd,
1754     hosts_add2_dlg_proc, (LPARAM) pvar);
1755     }
1756     }
1757    
1758 doda 4531 int is_numeric_hostname(const char *hostname)
1759     {
1760     struct addrinfo hints, *ai;
1761    
1762     if (hostname == NULL) {
1763     return -1;
1764     }
1765    
1766     memset(&hints, 0, sizeof(hints));
1767     hints.ai_socktype = SOCK_DGRAM;
1768     hints.ai_flags = AI_NUMERICHOST;
1769    
1770     if (getaddrinfo(hostname, NULL, &hints, &ai) == 0) {
1771     freeaddrinfo(ai);
1772     return 1;
1773     }
1774    
1775     return 0;
1776     }
1777    
1778     int verify_hostkey_dns(char FAR *hostname, Key *key)
1779     {
1780     DNS_STATUS status;
1781     PDNS_RECORD rec, p;
1782     PDNS_SSHFP_DATA t;
1783     int hostkey_alg, hostkey_dtype, hostkey_dlen;
1784     BYTE *hostkey_digest;
1785 doda 4559 int found = DNS_VERIFY_NOTFOUND;
1786 doda 4531
1787     switch (key->type) {
1788     case KEY_RSA:
1789     hostkey_alg = SSHFP_KEY_RSA;
1790 doda 4539 hostkey_dtype = SSHFP_HASH_SHA1;
1791 doda 4531 break;
1792     case KEY_DSA:
1793     hostkey_alg = SSHFP_KEY_DSA;
1794 doda 4539 hostkey_dtype = SSHFP_HASH_SHA1;
1795 doda 4531 break;
1796 doda 4539 case KEY_ECDSA256:
1797     case KEY_ECDSA384:
1798     case KEY_ECDSA521:
1799     hostkey_alg = SSHFP_KEY_ECDSA;
1800     hostkey_dtype = SSHFP_HASH_SHA256;
1801     break;
1802 doda 4540 default: // Un-supported algorithm
1803 doda 4531 hostkey_alg = SSHFP_KEY_RESERVED;
1804 doda 4539 hostkey_dtype = SSHFP_HASH_RESERVED;
1805 doda 4531 }
1806    
1807     if (hostkey_alg) {
1808 doda 4539 hostkey_digest = key_fingerprint_raw(key, hostkey_dtype, &hostkey_dlen);
1809 doda 4531 }
1810     else {
1811     hostkey_digest = NULL;
1812     }
1813    
1814     status = DnsQuery(hostname, DNS_TYPE_SSHFP, DNS_QUERY_STANDARD, NULL, &rec, NULL);
1815    
1816     if (status == 0) {
1817     for (p=rec; p!=NULL; p=p->pNext) {
1818     if (p->wType == DNS_TYPE_SSHFP) {
1819     t = (PDNS_SSHFP_DATA)&(p->Data.Null);
1820     if (t->Algorithm == hostkey_alg && t->DigestType == hostkey_dtype) {
1821     if (hostkey_dlen == p->wDataLength-2 && memcmp(hostkey_digest, t->Digest, hostkey_dlen) == 0) {
1822     found = DNS_VERIFY_MATCH;
1823     break;
1824     }
1825     else {
1826     found = DNS_VERIFY_MISMATCH;
1827     break;
1828     }
1829     }
1830     else {
1831     found = DNS_VERIFY_DIFFERENTTYPE;
1832     }
1833     }
1834     }
1835     }
1836    
1837     free(hostkey_digest);
1838     DnsRecordListFree(rec, DnsFreeRecordList);
1839     return found;
1840     }
1841    
1842 maya 3227 //
1843     // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
1844     //
1845     // SSH2���������� (2006.3.24 yutaka)
1846     //
1847     BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key)
1848     {
1849 doda 4559 int found_different_key = 0, found_different_type_key = 0;
1850 maya 3227
1851 doda 4559 pvar->dns_key_check = DNS_VERIFY_NONE;
1852    
1853 maya 3227 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
1854     if (pvar->hosts_state.prefetched_hostname != NULL
1855     && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
1856 maya 4332 && match_key(pvar, key) == 1) {
1857 maya 3227
1858     if (SSHv1(pvar)) {
1859     SSH_notify_host_OK(pvar);
1860     } else {
1861     // SSH2���������� SSH_notify_host_OK() �������B
1862     }
1863     return TRUE;
1864     }
1865    
1866     // �������������������������A�������_���t�@�C��������������
1867     if (begin_read_host_files(pvar, 0)) {
1868     do {
1869     if (!read_host_key(pvar, hostname, tcpport, 0, 0)) {
1870     break;
1871     }
1872    
1873     if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
1874 maya 4332 int match = match_key(pvar, key);
1875     if (match == 1) {
1876 maya 3227 finish_read_host_files(pvar, 0);
1877     // ���������G���g�����Q�������A���v�����L�[�������������������B
1878     // SSH2���������������������������B(2006.3.29 yutaka)
1879     if (SSHv1(pvar)) {
1880     SSH_notify_host_OK(pvar);
1881     } else {
1882     // SSH2���������� SSH_notify_host_OK() �������B
1883     }
1884     return TRUE;
1885 maya 4332 }
1886     else if (match == 0) {
1887 maya 3227 // �L�[�� known_hosts ���������������A�L�[�����e���������B
1888     found_different_key = 1;
1889     }
1890 maya 4332 else {
1891     // �L�[���`������������
1892     found_different_type_key = 1;
1893     }
1894 maya 3227 }
1895     } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // �L�[�����������������������[�v����
1896    
1897     finish_read_host_files(pvar, 0);
1898     }
1899    
1900     // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
1901     pvar->hosts_state.hostkey.type = key->type;
1902 maya 4321 switch (key->type) {
1903     case KEY_RSA1: // SSH1
1904 maya 3227 pvar->hosts_state.hostkey.bits = key->bits;
1905     pvar->hosts_state.hostkey.exp = copy_mp_int(key->exp);
1906     pvar->hosts_state.hostkey.mod = copy_mp_int(key->mod);
1907 maya 4321 break;
1908     case KEY_RSA: // SSH2 RSA
1909 maya 3227 pvar->hosts_state.hostkey.rsa = duplicate_RSA(key->rsa);
1910 maya 4321 break;
1911     case KEY_DSA: // SSH2 DSA
1912 maya 3227 pvar->hosts_state.hostkey.dsa = duplicate_DSA(key->dsa);
1913 maya 4321 break;
1914     case KEY_ECDSA256: // SSH2 ECDSA
1915     case KEY_ECDSA384:
1916     case KEY_ECDSA521:
1917     pvar->hosts_state.hostkey.ecdsa = EC_KEY_dup(key->ecdsa);
1918     break;
1919 maya 3227 }
1920     free(pvar->hosts_state.prefetched_hostname);
1921     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
1922    
1923 yutakapon 3631 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
1924     if (pvar->nocheck_known_hosts == TRUE) {
1925     return TRUE;
1926     }
1927    
1928 doda 4542 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
1929 doda 4559 pvar->dns_key_check = verify_hostkey_dns(hostname, key);
1930 doda 4542 }
1931    
1932 maya 3227 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
1933     // �������K�v�����������A�����R�[�������X�����B
1934     // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
1935     // (2007.10.1 yutaka)
1936     if (found_different_key) {
1937 maya 4330 HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar);
1938 maya 4332 }
1939     else if (found_different_type_key) {
1940     HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar);
1941     }
1942     else {
1943 maya 3227 HOSTS_do_unknown_host_dialog(pvar->NotificationWindow, pvar);
1944     }
1945    
1946     return TRUE;
1947     }
1948    
1949     void HOSTS_notify_disconnecting(PTInstVar pvar)
1950     {
1951     if (pvar->hosts_state.hosts_dialog != NULL) {
1952 doda 4531 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
1953 maya 3227 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
1954     EnableWindow(pvar->NotificationWindow, TRUE);
1955     }
1956     }
1957    
1958     void HOSTS_end(PTInstVar pvar)
1959     {
1960     int i;
1961    
1962     free(pvar->hosts_state.prefetched_hostname);
1963     init_hostkey(&pvar->hosts_state.hostkey);
1964    
1965     if (pvar->hosts_state.file_names != NULL) {
1966     for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
1967     free(pvar->hosts_state.file_names[i]);
1968     }
1969     free(pvar->hosts_state.file_names);
1970     }
1971     }

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