Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/ttssh2/ttxssh/hosts.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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