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 5663 - (show annotations) (download) (as text)
Thu Sep 18 14:44:53 2014 UTC (9 years, 6 months ago) by yutakapon
File MIME type: text/x-csrc
File size: 55963 byte(s)
SSHホスト鍵の交換で、アプリケーションが落ちる問題を修正した。
ED25519 対応時のデグレード。

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 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 pvar->hosts_state.hostkey.ed25519_pk = key->ed25519_pk;
649
650 index += eat_base64(data + index);
651 index += eat_spaces(data + index);
652
653 // Key�\�������g���������� (2008.3.2 yutaka)
654 free(key);
655 }
656
657 return index + eat_to_end_of_line(data + index);
658 }
659 }
660
661 //
662 // known_hosts�t�@�C�������z�X�g�������v�����s������
663 //
664 static int read_host_key(PTInstVar pvar,
665 char FAR * hostname, unsigned short tcpport,
666 int suppress_errors, int return_always)
667 {
668 int i;
669 int while_flg;
670
671 for (i = 0; hostname[i] != 0; i++) {
672 int ch = hostname[i];
673
674 if (!is_pattern_char(ch) || ch == '*' || ch == '?') {
675 if (!suppress_errors) {
676 UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_INVALID_ERROR", pvar,
677 "The host name contains an invalid character.\n"
678 "This session will be terminated.");
679 notify_fatal_error(pvar, pvar->ts->UIMsg);
680 }
681 return 0;
682 }
683 }
684
685 if (i == 0) {
686 if (!suppress_errors) {
687 UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_EMPTY_ERROR", pvar,
688 "The host name should not be empty.\n"
689 "This session will be terminated.");
690 notify_fatal_error(pvar, pvar->ts->UIMsg);
691 }
692 return 0;
693 }
694
695 // hostkey type is KEY_UNSPEC.
696 init_hostkey(&pvar->hosts_state.hostkey);
697
698 do {
699 if (pvar->hosts_state.file_data == NULL
700 || pvar->hosts_state.file_data[pvar->hosts_state.file_data_index] == 0) {
701 char FAR *filename;
702 int keep_going = 1;
703
704 if (pvar->hosts_state.file_data != NULL) {
705 end_read_file(pvar, suppress_errors);
706 }
707
708 do {
709 filename =
710 pvar->hosts_state.file_names[pvar->hosts_state.file_num];
711
712 if (filename == NULL) {
713 return 1;
714 } else {
715 pvar->hosts_state.file_num++;
716
717 if (filename[0] != 0) {
718 if (begin_read_file(pvar, filename, suppress_errors)) {
719 pvar->hosts_state.file_data_index = 0;
720 keep_going = 0;
721 }
722 }
723 }
724 } while (keep_going);
725 }
726
727 pvar->hosts_state.file_data_index +=
728 check_host_key(pvar, hostname, tcpport,
729 pvar->hosts_state.file_data +
730 pvar->hosts_state.file_data_index);
731
732 if (!return_always) {
733 // �L�����L�[��������������
734 while_flg = (pvar->hosts_state.hostkey.type == KEY_UNSPEC);
735 }
736 else {
737 while_flg = 0;
738 }
739 } while (while_flg);
740
741 return 1;
742 }
743
744 static void finish_read_host_files(PTInstVar pvar, int suppress_errors)
745 {
746 if (pvar->hosts_state.file_data != NULL) {
747 end_read_file(pvar, suppress_errors);
748 }
749 }
750
751 // �T�[�o�����������O���Aknown_hosts�t�@�C�������z�X�g���J�������������������B
752 void HOSTS_prefetch_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport)
753 {
754 if (!begin_read_host_files(pvar, 1)) {
755 return;
756 }
757
758 if (!read_host_key(pvar, hostname, tcpport, 1, 0)) {
759 return;
760 }
761
762 free(pvar->hosts_state.prefetched_hostname);
763 pvar->hosts_state.prefetched_hostname = _strdup(hostname);
764
765 finish_read_host_files(pvar, 1);
766 }
767
768 static BOOL equal_mp_ints(unsigned char FAR * num1,
769 unsigned char FAR * num2)
770 {
771 if (num1 == NULL || num2 == NULL) {
772 return FALSE;
773 } else {
774 uint32 bytes = (get_ushort16_MSBfirst(num1) + 7) / 8;
775
776 if (bytes != (get_ushort16_MSBfirst(num2) + 7) / 8) {
777 return FALSE; /* different byte lengths */
778 } else {
779 return memcmp(num1 + 2, num2 + 2, bytes) == 0;
780 }
781 }
782 }
783
784 // ���J����������������������
785 // -1 ... �����^������
786 // 0 ... ����������
787 // 1 ... ������
788 static int match_key(PTInstVar pvar, Key *key)
789 {
790 int bits;
791 unsigned char FAR * exp;
792 unsigned char FAR * mod;
793 const EC_GROUP *group;
794 const EC_POINT *pa, *pb;
795 Key *a, *b;
796
797 if (pvar->hosts_state.hostkey.type != key->type) {
798 return -1;
799 }
800
801 switch (key->type) {
802 case KEY_RSA1: // SSH1 host public key
803 bits = key->bits;
804 exp = key->exp;
805 mod = key->mod;
806
807 /* just check for equal exponent and modulus */
808 return equal_mp_ints(exp, pvar->hosts_state.hostkey.exp)
809 && equal_mp_ints(mod, pvar->hosts_state.hostkey.mod);
810 /*
811 return equal_mp_ints(exp, pvar->hosts_state.key_exp)
812 && equal_mp_ints(mod, pvar->hosts_state.key_mod);
813 */
814
815 case KEY_RSA: // SSH2 RSA host public key
816 return key->rsa != NULL && pvar->hosts_state.hostkey.rsa != NULL &&
817 BN_cmp(key->rsa->e, pvar->hosts_state.hostkey.rsa->e) == 0 &&
818 BN_cmp(key->rsa->n, pvar->hosts_state.hostkey.rsa->n) == 0;
819
820 case KEY_DSA: // SSH2 DSA host public key
821 return key->dsa != NULL && pvar->hosts_state.hostkey.dsa &&
822 BN_cmp(key->dsa->p, pvar->hosts_state.hostkey.dsa->p) == 0 &&
823 BN_cmp(key->dsa->q, pvar->hosts_state.hostkey.dsa->q) == 0 &&
824 BN_cmp(key->dsa->g, pvar->hosts_state.hostkey.dsa->g) == 0 &&
825 BN_cmp(key->dsa->pub_key, pvar->hosts_state.hostkey.dsa->pub_key) == 0;
826
827 case KEY_ECDSA256:
828 case KEY_ECDSA384:
829 case KEY_ECDSA521:
830 if (key->ecdsa == NULL || pvar->hosts_state.hostkey.ecdsa == NULL) {
831 return FALSE;
832 }
833 group = EC_KEY_get0_group(key->ecdsa);
834 pa = EC_KEY_get0_public_key(key->ecdsa),
835 pb = EC_KEY_get0_public_key(pvar->hosts_state.hostkey.ecdsa);
836 return EC_POINT_cmp(group, pa, pb, NULL) == 0;
837
838 case KEY_ED25519:
839 a = key;
840 b = &pvar->hosts_state.hostkey;
841 return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
842 memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;
843
844 default:
845 return FALSE;
846 }
847
848 }
849
850 static void init_hosts_dlg(PTInstVar pvar, HWND dlg)
851 {
852 char buf[1024];
853 char buf2[2048];
854 int i, j;
855 int ch;
856 char *fp = NULL;
857
858 // static text�� # �������z�X�g�����u������
859 GetDlgItemText(dlg, IDC_HOSTWARNING, buf, sizeof(buf));
860 for (i = 0; (ch = buf[i]) != 0 && ch != '#'; i++) {
861 buf2[i] = ch;
862 }
863 strncpy_s(buf2 + i, sizeof(buf2) - i,
864 pvar->hosts_state.prefetched_hostname, _TRUNCATE);
865 j = i + strlen(buf2 + i);
866 for (; buf[i] == '#'; i++) {
867 }
868 strncpy_s(buf2 + j, sizeof(buf2) - j, buf + i, _TRUNCATE);
869
870 SetDlgItemText(dlg, IDC_HOSTWARNING, buf2);
871
872 // fingerprint����������
873 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX);
874 SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
875 free(fp);
876
877 // �r�W���A����fingerprint���\������
878 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART);
879 SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETTEXT, 0, (LPARAM)fp);
880 SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), TRUE);
881 free(fp);
882 }
883
884 static int print_mp_int(char FAR * buf, unsigned char FAR * mp)
885 {
886 int i = 0, j, k;
887 BIGNUM *num = BN_new();
888 int ch;
889
890 BN_bin2bn(mp + 2, (get_ushort16_MSBfirst(mp) + 7) / 8, num);
891
892 do {
893 buf[i] = (char) ((BN_div_word(num, 10)) + '0');
894 i++;
895 } while (!BN_is_zero(num));
896
897 /* we need to reverse the digits */
898 for (j = 0, k = i - 1; j < k; j++, k--) {
899 ch = buf[j];
900 buf[j] = buf[k];
901 buf[k] = ch;
902 }
903
904 buf[i] = 0;
905 return i;
906 }
907
908 //
909 // known_hosts �t�@�C�������������G���g�������������B
910 //
911 static char FAR *format_host_key(PTInstVar pvar)
912 {
913 int host_len = strlen(pvar->hosts_state.prefetched_hostname);
914 char *result = NULL;
915 int index;
916 ssh_keytype type = pvar->hosts_state.hostkey.type;
917
918 switch (type) {
919 case KEY_RSA1:
920 {
921 int result_len = host_len + 50 + 8 +
922 get_ushort16_MSBfirst(pvar->hosts_state.hostkey.exp) / 3 +
923 get_ushort16_MSBfirst(pvar->hosts_state.hostkey.mod) / 3;
924 result = (char FAR *) malloc(result_len);
925
926 if (pvar->ssh_state.tcpport == 22) {
927 strncpy_s(result, result_len, pvar->hosts_state.prefetched_hostname, _TRUNCATE);
928 index = host_len;
929 }
930 else {
931 _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
932 pvar->hosts_state.prefetched_hostname,
933 pvar->ssh_state.tcpport);
934 index = strlen(result);
935 }
936
937 _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
938 " %d ", pvar->hosts_state.hostkey.bits);
939 index += strlen(result + index);
940 index += print_mp_int(result + index, pvar->hosts_state.hostkey.exp);
941 result[index] = ' ';
942 index++;
943 index += print_mp_int(result + index, pvar->hosts_state.hostkey.mod);
944 strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
945
946 break;
947 }
948
949 case KEY_RSA:
950 case KEY_DSA:
951 case KEY_ECDSA256:
952 case KEY_ECDSA384:
953 case KEY_ECDSA521:
954 case KEY_ED25519:
955 {
956 Key *key = &pvar->hosts_state.hostkey;
957 char *blob = NULL;
958 int blen, uulen, msize;
959 char *uu = NULL;
960 int n;
961
962 key_to_blob(key, &blob, &blen);
963 uulen = 2 * blen;
964 uu = malloc(uulen);
965 if (uu == NULL) {
966 goto error;
967 }
968 n = uuencode(blob, blen, uu, uulen);
969 if (n > 0) {
970 msize = host_len + 50 + uulen;
971 result = malloc(msize);
972 if (result == NULL) {
973 goto error;
974 }
975
976 // setup
977 if (pvar->ssh_state.tcpport == 22) {
978 _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
979 pvar->hosts_state.prefetched_hostname,
980 get_sshname_from_key(key),
981 uu);
982 } else {
983 _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
984 pvar->hosts_state.prefetched_hostname,
985 pvar->ssh_state.tcpport,
986 get_sshname_from_key(key),
987 uu);
988 }
989 }
990 error:
991 if (blob != NULL)
992 free(blob);
993 if (uu != NULL)
994 free(uu);
995
996 break;
997 }
998
999 default:
1000 return NULL;
1001
1002 }
1003
1004 return result;
1005 }
1006
1007 static void add_host_key(PTInstVar pvar)
1008 {
1009 char FAR *name = NULL;
1010
1011 if ( pvar->hosts_state.file_names != NULL)
1012 name = pvar->hosts_state.file_names[0];
1013
1014 if (name == NULL || name[0] == 0) {
1015 UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1016 "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1017 "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1018 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1019 } else {
1020 char FAR *keydata = format_host_key(pvar);
1021 int length = strlen(keydata);
1022 int fd;
1023 int amount_written;
1024 int close_result;
1025 char buf[FILENAME_MAX];
1026
1027 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1028 fd = _open(buf,
1029 _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1030 _S_IREAD | _S_IWRITE);
1031 if (fd == -1) {
1032 if (errno == EACCES) {
1033 UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1034 "An error occurred while trying to write the host key.\n"
1035 "You do not have permission to write to the known-hosts file.");
1036 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1037 } else {
1038 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1039 "An error occurred while trying to write the host key.\n"
1040 "The host key could not be written.");
1041 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1042 }
1043 return;
1044 }
1045
1046 amount_written = _write(fd, keydata, length);
1047 free(keydata);
1048 close_result = _close(fd);
1049
1050 if (amount_written != length || close_result == -1) {
1051 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1052 "An error occurred while trying to write the host key.\n"
1053 "The host key could not be written.");
1054 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1055 }
1056 }
1057 }
1058
1059 static char FAR *copy_mp_int(char FAR * num)
1060 {
1061 int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;
1062 char FAR *result = (char FAR *) malloc(len);
1063
1064 if (result != NULL) {
1065 memcpy(result, num, len);
1066 }
1067
1068 return result;
1069 }
1070
1071 //
1072 // �����z�X�g�����e���������L�[����������
1073 // add_host_key ����������������
1074 //
1075 static void delete_different_key(PTInstVar pvar)
1076 {
1077 char FAR *name = pvar->hosts_state.file_names[0];
1078
1079 if (name == NULL || name[0] == 0) {
1080 UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1081 "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1082 "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1083 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1084 }
1085 else {
1086 Key key; // ���������z�X�g���L�[
1087 Key *key_freed;
1088 int length;
1089 char filename[MAX_PATH];
1090 char tmp[L_tmpnam];
1091 int fd;
1092 int amount_written = 0;
1093 int close_result;
1094 int data_index = 0;
1095 char buf[FILENAME_MAX];
1096
1097 // �������������t�@�C�����J��
1098 _getcwd(filename, sizeof(filename));
1099 tmpnam_s(tmp,sizeof(tmp));
1100 strcat_s(filename, sizeof(filename), tmp);
1101 fd = _open(filename,
1102 _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1103 _S_IREAD | _S_IWRITE);
1104
1105 if (fd == -1) {
1106 if (errno == EACCES) {
1107 UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1108 "An error occurred while trying to write the host key.\n"
1109 "You do not have permission to write to the known-hosts file.");
1110 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1111 } else {
1112 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1113 "An error occurred while trying to write the host key.\n"
1114 "The host key could not be written.");
1115 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1116 }
1117 return;
1118 }
1119
1120 // ���������T�[�o���L�[����������
1121 memset(&key, 0, sizeof(key));
1122 switch (pvar->hosts_state.hostkey.type) {
1123 case KEY_RSA1: // SSH1
1124 key.type = KEY_RSA1;
1125 key.bits = pvar->hosts_state.hostkey.bits;
1126 key.exp = copy_mp_int(pvar->hosts_state.hostkey.exp);
1127 key.mod = copy_mp_int(pvar->hosts_state.hostkey.mod);
1128 break;
1129 case KEY_RSA: // SSH2 RSA
1130 key.type = KEY_RSA;
1131 key.rsa = duplicate_RSA(pvar->hosts_state.hostkey.rsa);
1132 break;
1133 case KEY_DSA: // SSH2 DSA
1134 key.type = KEY_DSA;
1135 key.dsa = duplicate_DSA(pvar->hosts_state.hostkey.dsa);
1136 break;
1137 case KEY_ECDSA256:
1138 case KEY_ECDSA384:
1139 case KEY_ECDSA521:
1140 key.type = pvar->hosts_state.hostkey.type;
1141 key.ecdsa = EC_KEY_dup(pvar->hosts_state.hostkey.ecdsa);
1142 break;
1143 case KEY_ED25519:
1144 key.type = pvar->hosts_state.hostkey.type;
1145 key.ed25519_pk = duplicate_ED25519_PK(pvar->hosts_state.hostkey.ed25519_pk);
1146 break;
1147 }
1148
1149 // �t�@�C��������������
1150 begin_read_host_files(pvar, 0);
1151 do {
1152 int host_index = 0;
1153 int matched = 0;
1154 int keybits = 0;
1155 char FAR *data;
1156 int do_write = 0;
1157 length = amount_written = 0;
1158
1159 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1)) {
1160 break;
1161 }
1162
1163 if (data_index == pvar->hosts_state.file_data_index) {
1164 // index ���i������ == ��������������
1165 break;
1166 }
1167
1168 data = pvar->hosts_state.file_data + data_index;
1169 host_index = eat_spaces(data);
1170
1171 if (data[host_index] == '#') {
1172 do_write = 1;
1173 }
1174 else {
1175 // �z�X�g������
1176 host_index--;
1177 do {
1178 int negated;
1179 int bracketed;
1180 char *end_bracket;
1181 int host_matched = 0;
1182 unsigned short keyfile_port = 22;
1183
1184 host_index++;
1185 negated = data[host_index] == '!';
1186
1187 if (negated) {
1188 host_index++;
1189 bracketed = data[host_index] == '[';
1190 if (bracketed) {
1191 end_bracket = strstr(data + host_index + 1, "]:");
1192 if (end_bracket != NULL) {
1193 *end_bracket = ' ';
1194 host_index++;
1195 }
1196 }
1197 host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1198 if (bracketed && end_bracket != NULL) {
1199 *end_bracket = ']';
1200 keyfile_port = atoi(end_bracket + 2);
1201 }
1202 if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1203 matched = 0;
1204 // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1205 host_index--;
1206 do {
1207 host_index++;
1208 host_index += eat_to_end_of_pattern(data + host_index);
1209 } while (data[host_index] == ',');
1210 break;
1211 }
1212 }
1213 else {
1214 bracketed = data[host_index] == '[';
1215 if (bracketed) {
1216 end_bracket = strstr(data + host_index + 1, "]:");
1217 if (end_bracket != NULL) {
1218 *end_bracket = ' ';
1219 host_index++;
1220 }
1221 }
1222 host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1223 if (bracketed && end_bracket != NULL) {
1224 *end_bracket = ']';
1225 keyfile_port = atoi(end_bracket + 2);
1226 }
1227 if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1228 matched = 1;
1229 }
1230 }
1231 host_index += eat_to_end_of_pattern(data + host_index);
1232 } while (data[host_index] == ',');
1233
1234 // �z�X�g������������
1235 if (!matched) {
1236 do_write = 1;
1237 }
1238 // �z�X�g��������
1239 else {
1240 // �����`�������� or ���v�����L�[
1241 if (match_key(pvar, &key) != 0) {
1242 do_write = 1;
1243 }
1244 // �����`�������������v�������L�[���X�L�b�v������
1245 }
1246 }
1247
1248 // ������������
1249 if (do_write) {
1250 length = pvar->hosts_state.file_data_index - data_index;
1251 amount_written =
1252 _write(fd, pvar->hosts_state.file_data + data_index,
1253 length);
1254
1255 if (amount_written != length) {
1256 goto error1;
1257 }
1258 }
1259 data_index = pvar->hosts_state.file_data_index;
1260 } while (1); // ������������
1261
1262 error1:
1263 close_result = _close(fd);
1264 if (amount_written != length || close_result == -1) {
1265 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1266 "An error occurred while trying to write the host key.\n"
1267 "The host key could not be written.");
1268 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1269 goto error2;
1270 }
1271
1272 // �������������t�@�C���������l�[��
1273 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1274 _unlink(buf);
1275 rename(filename, buf);
1276
1277 error2:
1278 _unlink(filename);
1279
1280 finish_read_host_files(pvar, 0);
1281
1282 // ���������������������������B
1283 key_freed = key_new(KEY_UNSPEC);
1284 memcpy(key_freed, &key, sizeof(Key));
1285 key_free(key_freed);
1286 }
1287 }
1288
1289 //
1290 // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1291 // ���[�U���m�F�������B
1292 // TODO: finger print���\�����s���B
1293 // (2006.3.25 yutaka)
1294 //
1295 static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1296 LPARAM lParam)
1297 {
1298 PTInstVar pvar;
1299 LOGFONT logfont;
1300 HFONT font;
1301 char uimsg[MAX_UIMSG];
1302
1303 switch (msg) {
1304 case WM_INITDIALOG:
1305 pvar = (PTInstVar) lParam;
1306 pvar->hosts_state.hosts_dialog = dlg;
1307 SetWindowLong(dlg, DWL_USER, lParam);
1308
1309 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1310 GetWindowText(dlg, uimsg, sizeof(uimsg));
1311 UTIL_get_lang_msg("DLG_UNKNONWHOST_TITLE", pvar, uimsg);
1312 SetWindowText(dlg, pvar->ts->UIMsg);
1313 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1314 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING", pvar, uimsg);
1315 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1316 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1317 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING2", pvar, uimsg);
1318 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1319 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1320 UTIL_get_lang_msg("DLG_UNKNOWNHOST_FINGERPRINT", pvar, uimsg);
1321 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1322 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1323 UTIL_get_lang_msg("DLG_UNKNOWNHOST_ADD", pvar, uimsg);
1324 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1325 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1326 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1327 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1328 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1329 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1330 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1331
1332 switch (pvar->dns_key_check) {
1333 case DNS_VERIFY_NOTFOUND:
1334 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1335 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1336 break;
1337 case DNS_VERIFY_MATCH:
1338 case DNS_VERIFY_AUTH_MATCH:
1339 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1340 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1341 break;
1342 case DNS_VERIFY_MISMATCH:
1343 case DNS_VERIFY_AUTH_MISMATCH:
1344 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1345 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1346 break;
1347 case DNS_VERIFY_DIFFERENTTYPE:
1348 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1349 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1350 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1351 break;
1352 }
1353
1354 switch (pvar->dns_key_check) {
1355 case DNS_VERIFY_MATCH:
1356 case DNS_VERIFY_MISMATCH:
1357 case DNS_VERIFY_DIFFERENTTYPE:
1358 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1359 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1360 break;
1361 case DNS_VERIFY_AUTH_MATCH:
1362 case DNS_VERIFY_AUTH_MISMATCH:
1363 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1364 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1365 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1366 break;
1367 }
1368
1369 init_hosts_dlg(pvar, dlg);
1370
1371 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1372 GetObject(font, sizeof(LOGFONT), &logfont);
1373 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1374 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1375 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1376 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1377 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1378 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1379 SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1380 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1381 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1382 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1383 }
1384 else {
1385 DlgHostsAddFont = NULL;
1386 }
1387
1388 // add host check box���`�F�b�N���f�t�H���g������������
1389 SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1390
1391 return TRUE; /* because we do not set the focus */
1392
1393 case WM_COMMAND:
1394 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1395
1396 switch (LOWORD(wParam)) {
1397 case IDC_CONTINUE:
1398 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1399 if (!pvar->cv->Ready) {
1400 goto canceled;
1401 }
1402
1403 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1404 add_host_key(pvar);
1405 }
1406
1407 if (SSHv1(pvar)) {
1408 SSH_notify_host_OK(pvar);
1409 } else { // SSH2
1410 // SSH2���������� SSH_notify_host_OK() �������B
1411 }
1412
1413 pvar->hosts_state.hosts_dialog = NULL;
1414
1415 EndDialog(dlg, 1);
1416
1417 if (DlgHostsAddFont != NULL) {
1418 DeleteObject(DlgHostsAddFont);
1419 }
1420
1421 return TRUE;
1422
1423 case IDCANCEL: /* kill the connection */
1424 canceled:
1425 pvar->hosts_state.hosts_dialog = NULL;
1426 notify_closed_connection(pvar);
1427 EndDialog(dlg, 0);
1428
1429 if (DlgHostsAddFont != NULL) {
1430 DeleteObject(DlgHostsAddFont);
1431 }
1432
1433 return TRUE;
1434
1435 default:
1436 return FALSE;
1437 }
1438
1439 default:
1440 return FALSE;
1441 }
1442 }
1443
1444 //
1445 // �u�����������m�F�_�C�A���O������
1446 //
1447 static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1448 LPARAM lParam)
1449 {
1450 PTInstVar pvar;
1451 LOGFONT logfont;
1452 HFONT font;
1453 char uimsg[MAX_UIMSG];
1454
1455 switch (msg) {
1456 case WM_INITDIALOG:
1457 pvar = (PTInstVar) lParam;
1458 pvar->hosts_state.hosts_dialog = dlg;
1459 SetWindowLong(dlg, DWL_USER, lParam);
1460
1461 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1462 GetWindowText(dlg, uimsg, sizeof(uimsg));
1463 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
1464 SetWindowText(dlg, pvar->ts->UIMsg);
1465 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1466 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
1467 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1468 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1469 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
1470 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1471 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1472 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
1473 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1474 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1475 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
1476 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1477 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1478 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1479 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1480 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1481 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1482 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1483
1484 switch (pvar->dns_key_check) {
1485 case DNS_VERIFY_NOTFOUND:
1486 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1487 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1488 break;
1489 case DNS_VERIFY_MATCH:
1490 case DNS_VERIFY_AUTH_MATCH:
1491 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1492 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1493 break;
1494 case DNS_VERIFY_MISMATCH:
1495 case DNS_VERIFY_AUTH_MISMATCH:
1496 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1497 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1498 break;
1499 case DNS_VERIFY_DIFFERENTTYPE:
1500 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1501 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1502 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1503 break;
1504 }
1505
1506 switch (pvar->dns_key_check) {
1507 case DNS_VERIFY_MATCH:
1508 case DNS_VERIFY_MISMATCH:
1509 case DNS_VERIFY_DIFFERENTTYPE:
1510 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1511 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1512 break;
1513 case DNS_VERIFY_AUTH_MATCH:
1514 case DNS_VERIFY_AUTH_MISMATCH:
1515 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1516 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1517 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1518 break;
1519 }
1520
1521 init_hosts_dlg(pvar, dlg);
1522
1523 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1524 GetObject(font, sizeof(LOGFONT), &logfont);
1525 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
1526 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1527 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1528 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1529 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1530 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1531 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1532 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1533 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1534 }
1535 else {
1536 DlgHostsReplaceFont = NULL;
1537 }
1538
1539 // �f�t�H���g���`�F�b�N����������
1540 return TRUE; /* because we do not set the focus */
1541
1542 case WM_COMMAND:
1543 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1544
1545 switch (LOWORD(wParam)) {
1546 case IDC_CONTINUE:
1547 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1548 if (!pvar->cv->Ready) {
1549 goto canceled;
1550 }
1551
1552 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1553 add_host_key(pvar);
1554 delete_different_key(pvar);
1555 }
1556
1557 if (SSHv1(pvar)) {
1558 SSH_notify_host_OK(pvar);
1559 } else { // SSH2
1560 // SSH2���������� SSH_notify_host_OK() �������B
1561 }
1562
1563 pvar->hosts_state.hosts_dialog = NULL;
1564
1565 EndDialog(dlg, 1);
1566
1567 if (DlgHostsReplaceFont != NULL) {
1568 DeleteObject(DlgHostsReplaceFont);
1569 }
1570
1571 return TRUE;
1572
1573 case IDCANCEL: /* kill the connection */
1574 canceled:
1575 pvar->hosts_state.hosts_dialog = NULL;
1576 notify_closed_connection(pvar);
1577 EndDialog(dlg, 0);
1578
1579 if (DlgHostsReplaceFont != NULL) {
1580 DeleteObject(DlgHostsReplaceFont);
1581 }
1582
1583 return TRUE;
1584
1585 default:
1586 return FALSE;
1587 }
1588
1589 default:
1590 return FALSE;
1591 }
1592 }
1593
1594 //
1595 // �����z�X�g�����`�����������������m�F�_�C�A���O������
1596 //
1597 static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1598 LPARAM lParam)
1599 {
1600 PTInstVar pvar;
1601 LOGFONT logfont;
1602 HFONT font;
1603 char uimsg[MAX_UIMSG];
1604
1605 switch (msg) {
1606 case WM_INITDIALOG:
1607 pvar = (PTInstVar) lParam;
1608 pvar->hosts_state.hosts_dialog = dlg;
1609 SetWindowLong(dlg, DWL_USER, lParam);
1610
1611 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1612 GetWindowText(dlg, uimsg, sizeof(uimsg));
1613 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
1614 SetWindowText(dlg, pvar->ts->UIMsg);
1615 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1616 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
1617 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1618 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1619 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
1620 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1621 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1622 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
1623 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1624 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1625 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
1626 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1627 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1628 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1629 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1630 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1631 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1632 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1633
1634 switch (pvar->dns_key_check) {
1635 case DNS_VERIFY_NOTFOUND:
1636 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1637 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1638 break;
1639 case DNS_VERIFY_MATCH:
1640 case DNS_VERIFY_AUTH_MATCH:
1641 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1642 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1643 break;
1644 case DNS_VERIFY_MISMATCH:
1645 case DNS_VERIFY_AUTH_MISMATCH:
1646 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1647 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1648 break;
1649 case DNS_VERIFY_DIFFERENTTYPE:
1650 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1651 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1652 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1653 break;
1654 }
1655
1656 switch (pvar->dns_key_check) {
1657 case DNS_VERIFY_MATCH:
1658 case DNS_VERIFY_MISMATCH:
1659 case DNS_VERIFY_DIFFERENTTYPE:
1660 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1661 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1662 break;
1663 case DNS_VERIFY_AUTH_MATCH:
1664 case DNS_VERIFY_AUTH_MISMATCH:
1665 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1666 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1667 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1668 break;
1669 }
1670
1671 init_hosts_dlg(pvar, dlg);
1672
1673 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1674 GetObject(font, sizeof(LOGFONT), &logfont);
1675 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1676 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1677 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1678 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1679 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1680 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1681 SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1682 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1683 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1684 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1685 }
1686 else {
1687 DlgHostsAddFont = NULL;
1688 }
1689
1690 // add host check box ���f�t�H���g�� off ������
1691 // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1692
1693 return TRUE; /* because we do not set the focus */
1694
1695 case WM_COMMAND:
1696 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1697
1698 switch (LOWORD(wParam)) {
1699 case IDC_CONTINUE:
1700 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1701 if (!pvar->cv->Ready) {
1702 goto canceled;
1703 }
1704
1705 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1706 add_host_key(pvar);
1707 }
1708
1709 if (SSHv1(pvar)) {
1710 SSH_notify_host_OK(pvar);
1711 } else { // SSH2
1712 // SSH2���������� SSH_notify_host_OK() �������B
1713 }
1714
1715 pvar->hosts_state.hosts_dialog = NULL;
1716
1717 EndDialog(dlg, 1);
1718
1719 if (DlgHostsAddFont != NULL) {
1720 DeleteObject(DlgHostsAddFont);
1721 }
1722
1723 return TRUE;
1724
1725 case IDCANCEL: /* kill the connection */
1726 canceled:
1727 pvar->hosts_state.hosts_dialog = NULL;
1728 notify_closed_connection(pvar);
1729 EndDialog(dlg, 0);
1730
1731 if (DlgHostsAddFont != NULL) {
1732 DeleteObject(DlgHostsAddFont);
1733 }
1734
1735 return TRUE;
1736
1737 default:
1738 return FALSE;
1739 }
1740
1741 default:
1742 return FALSE;
1743 }
1744 }
1745
1746 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
1747 {
1748 if (pvar->hosts_state.hosts_dialog == NULL) {
1749 HWND cur_active = GetActiveWindow();
1750
1751 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
1752 cur_active != NULL ? cur_active : wnd,
1753 hosts_add_dlg_proc, (LPARAM) pvar);
1754 }
1755 }
1756
1757 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
1758 {
1759 if (pvar->hosts_state.hosts_dialog == NULL) {
1760 HWND cur_active = GetActiveWindow();
1761
1762 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
1763 cur_active != NULL ? cur_active : wnd,
1764 hosts_replace_dlg_proc, (LPARAM) pvar);
1765 }
1766 }
1767
1768 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
1769 {
1770 if (pvar->hosts_state.hosts_dialog == NULL) {
1771 HWND cur_active = GetActiveWindow();
1772
1773 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
1774 cur_active != NULL ? cur_active : wnd,
1775 hosts_add2_dlg_proc, (LPARAM) pvar);
1776 }
1777 }
1778
1779 //
1780 // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
1781 //
1782 // SSH2���������� (2006.3.24 yutaka)
1783 //
1784 BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key)
1785 {
1786 int found_different_key = 0, found_different_type_key = 0;
1787
1788 pvar->dns_key_check = DNS_VERIFY_NONE;
1789
1790 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
1791 if (pvar->hosts_state.prefetched_hostname != NULL
1792 && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
1793 && match_key(pvar, key) == 1) {
1794
1795 if (SSHv1(pvar)) {
1796 SSH_notify_host_OK(pvar);
1797 } else {
1798 // SSH2���������� SSH_notify_host_OK() �������B
1799 }
1800 return TRUE;
1801 }
1802
1803 // �������������������������A�������_���t�@�C��������������
1804 if (begin_read_host_files(pvar, 0)) {
1805 do {
1806 if (!read_host_key(pvar, hostname, tcpport, 0, 0)) {
1807 break;
1808 }
1809
1810 if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
1811 int match = match_key(pvar, key);
1812 if (match == 1) {
1813 finish_read_host_files(pvar, 0);
1814 // ���������G���g�����Q�������A���v�����L�[�������������������B
1815 // SSH2���������������������������B(2006.3.29 yutaka)
1816 if (SSHv1(pvar)) {
1817 SSH_notify_host_OK(pvar);
1818 } else {
1819 // SSH2���������� SSH_notify_host_OK() �������B
1820 }
1821 return TRUE;
1822 }
1823 else if (match == 0) {
1824 // �L�[�� known_hosts ���������������A�L�[�����e���������B
1825 found_different_key = 1;
1826 }
1827 else {
1828 // �L�[���`������������
1829 found_different_type_key = 1;
1830 }
1831 }
1832 } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // �L�[�����������������������[�v����
1833
1834 finish_read_host_files(pvar, 0);
1835 }
1836
1837 // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
1838 pvar->hosts_state.hostkey.type = key->type;
1839 switch (key->type) {
1840 case KEY_RSA1: // SSH1
1841 pvar->hosts_state.hostkey.bits = key->bits;
1842 pvar->hosts_state.hostkey.exp = copy_mp_int(key->exp);
1843 pvar->hosts_state.hostkey.mod = copy_mp_int(key->mod);
1844 break;
1845 case KEY_RSA: // SSH2 RSA
1846 pvar->hosts_state.hostkey.rsa = duplicate_RSA(key->rsa);
1847 break;
1848 case KEY_DSA: // SSH2 DSA
1849 pvar->hosts_state.hostkey.dsa = duplicate_DSA(key->dsa);
1850 break;
1851 case KEY_ECDSA256: // SSH2 ECDSA
1852 case KEY_ECDSA384:
1853 case KEY_ECDSA521:
1854 pvar->hosts_state.hostkey.ecdsa = EC_KEY_dup(key->ecdsa);
1855 break;
1856 case KEY_ED25519:
1857 pvar->hosts_state.hostkey.ed25519_pk = duplicate_ED25519_PK(key->ed25519_pk);
1858 break;
1859 }
1860 free(pvar->hosts_state.prefetched_hostname);
1861 pvar->hosts_state.prefetched_hostname = _strdup(hostname);
1862
1863 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
1864 if (pvar->nocheck_known_hosts == TRUE) {
1865 return TRUE;
1866 }
1867
1868 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
1869 pvar->dns_key_check = verify_hostkey_dns(hostname, key);
1870 }
1871
1872 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
1873 // �������K�v�����������A�����R�[�������X�����B
1874 // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
1875 // (2007.10.1 yutaka)
1876 if (found_different_key) {
1877 HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar);
1878 }
1879 else if (found_different_type_key) {
1880 HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar);
1881 }
1882 else {
1883 HOSTS_do_unknown_host_dialog(pvar->NotificationWindow, pvar);
1884 }
1885
1886 return TRUE;
1887 }
1888
1889 void HOSTS_notify_disconnecting(PTInstVar pvar)
1890 {
1891 if (pvar->hosts_state.hosts_dialog != NULL) {
1892 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
1893 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
1894 EnableWindow(pvar->NotificationWindow, TRUE);
1895 }
1896 }
1897
1898 void HOSTS_end(PTInstVar pvar)
1899 {
1900 int i;
1901
1902 free(pvar->hosts_state.prefetched_hostname);
1903 init_hostkey(&pvar->hosts_state.hostkey);
1904
1905 if (pvar->hosts_state.file_names != NULL) {
1906 for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
1907 free(pvar->hosts_state.file_names[i]);
1908 }
1909 free(pvar->hosts_state.file_names);
1910 }
1911 }

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