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 5562 - (show annotations) (download) (as text)
Mon Mar 31 06:28:16 2014 UTC (10 years ago) by yutakapon
File MIME type: text/x-csrc
File size: 55862 byte(s)
チケット #33579
認証ダイアログの表示中に、サーバ側から切断された場合、アプリケーションフォルトで落ちる
問題を修正した。

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 int length;
1088 char filename[MAX_PATH];
1089 char tmp[L_tmpnam];
1090 int fd;
1091 int amount_written = 0;
1092 int close_result;
1093 int data_index = 0;
1094 char buf[FILENAME_MAX];
1095
1096 // �������������t�@�C�����J��
1097 _getcwd(filename, sizeof(filename));
1098 tmpnam_s(tmp,sizeof(tmp));
1099 strcat_s(filename, sizeof(filename), tmp);
1100 fd = _open(filename,
1101 _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1102 _S_IREAD | _S_IWRITE);
1103
1104 if (fd == -1) {
1105 if (errno == EACCES) {
1106 UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1107 "An error occurred while trying to write the host key.\n"
1108 "You do not have permission to write to the known-hosts file.");
1109 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1110 } else {
1111 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1112 "An error occurred while trying to write the host key.\n"
1113 "The host key could not be written.");
1114 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1115 }
1116 return;
1117 }
1118
1119 // ���������T�[�o���L�[����������
1120 memset(&key, 0, sizeof(key));
1121 switch (pvar->hosts_state.hostkey.type) {
1122 case KEY_RSA1: // SSH1
1123 key.type = KEY_RSA1;
1124 key.bits = pvar->hosts_state.hostkey.bits;
1125 key.exp = copy_mp_int(pvar->hosts_state.hostkey.exp);
1126 key.mod = copy_mp_int(pvar->hosts_state.hostkey.mod);
1127 break;
1128 case KEY_RSA: // SSH2 RSA
1129 key.type = KEY_RSA;
1130 key.rsa = duplicate_RSA(pvar->hosts_state.hostkey.rsa);
1131 break;
1132 case KEY_DSA: // SSH2 DSA
1133 key.type = KEY_DSA;
1134 key.dsa = duplicate_DSA(pvar->hosts_state.hostkey.dsa);
1135 break;
1136 case KEY_ECDSA256:
1137 case KEY_ECDSA384:
1138 case KEY_ECDSA521:
1139 key.type = pvar->hosts_state.hostkey.type;
1140 key.ecdsa = EC_KEY_dup(pvar->hosts_state.hostkey.ecdsa);
1141 break;
1142 case KEY_ED25519:
1143 key.type = pvar->hosts_state.hostkey.type;
1144 key.ed25519_pk = duplicate_ED25519_PK(pvar->hosts_state.hostkey.ed25519_pk);
1145 break;
1146 }
1147
1148 // �t�@�C��������������
1149 begin_read_host_files(pvar, 0);
1150 do {
1151 int host_index = 0;
1152 int matched = 0;
1153 int keybits = 0;
1154 char FAR *data;
1155 int do_write = 0;
1156 length = amount_written = 0;
1157
1158 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1)) {
1159 break;
1160 }
1161
1162 if (data_index == pvar->hosts_state.file_data_index) {
1163 // index ���i������ == ��������������
1164 break;
1165 }
1166
1167 data = pvar->hosts_state.file_data + data_index;
1168 host_index = eat_spaces(data);
1169
1170 if (data[host_index] == '#') {
1171 do_write = 1;
1172 }
1173 else {
1174 // �z�X�g������
1175 host_index--;
1176 do {
1177 int negated;
1178 int bracketed;
1179 char *end_bracket;
1180 int host_matched = 0;
1181 unsigned short keyfile_port = 22;
1182
1183 host_index++;
1184 negated = data[host_index] == '!';
1185
1186 if (negated) {
1187 host_index++;
1188 bracketed = data[host_index] == '[';
1189 if (bracketed) {
1190 end_bracket = strstr(data + host_index + 1, "]:");
1191 if (end_bracket != NULL) {
1192 *end_bracket = ' ';
1193 host_index++;
1194 }
1195 }
1196 host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1197 if (bracketed && end_bracket != NULL) {
1198 *end_bracket = ']';
1199 keyfile_port = atoi(end_bracket + 2);
1200 }
1201 if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1202 matched = 0;
1203 // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1204 host_index--;
1205 do {
1206 host_index++;
1207 host_index += eat_to_end_of_pattern(data + host_index);
1208 } while (data[host_index] == ',');
1209 break;
1210 }
1211 }
1212 else {
1213 bracketed = data[host_index] == '[';
1214 if (bracketed) {
1215 end_bracket = strstr(data + host_index + 1, "]:");
1216 if (end_bracket != NULL) {
1217 *end_bracket = ' ';
1218 host_index++;
1219 }
1220 }
1221 host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1222 if (bracketed && end_bracket != NULL) {
1223 *end_bracket = ']';
1224 keyfile_port = atoi(end_bracket + 2);
1225 }
1226 if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1227 matched = 1;
1228 }
1229 }
1230 host_index += eat_to_end_of_pattern(data + host_index);
1231 } while (data[host_index] == ',');
1232
1233 // �z�X�g������������
1234 if (!matched) {
1235 do_write = 1;
1236 }
1237 // �z�X�g��������
1238 else {
1239 // �����`�������� or ���v�����L�[
1240 if (match_key(pvar, &key) != 0) {
1241 do_write = 1;
1242 }
1243 // �����`�������������v�������L�[���X�L�b�v������
1244 }
1245 }
1246
1247 // ������������
1248 if (do_write) {
1249 length = pvar->hosts_state.file_data_index - data_index;
1250 amount_written =
1251 _write(fd, pvar->hosts_state.file_data + data_index,
1252 length);
1253
1254 if (amount_written != length) {
1255 goto error1;
1256 }
1257 }
1258 data_index = pvar->hosts_state.file_data_index;
1259 } while (1); // ������������
1260
1261 error1:
1262 close_result = _close(fd);
1263 if (amount_written != length || close_result == -1) {
1264 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1265 "An error occurred while trying to write the host key.\n"
1266 "The host key could not be written.");
1267 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1268 goto error2;
1269 }
1270
1271 // �������������t�@�C���������l�[��
1272 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1273 _unlink(buf);
1274 rename(filename, buf);
1275
1276 error2:
1277 _unlink(filename);
1278
1279 finish_read_host_files(pvar, 0);
1280
1281 // ���������������������������B
1282 key_free(&key);
1283 }
1284 }
1285
1286 //
1287 // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1288 // ���[�U���m�F�������B
1289 // TODO: finger print���\�����s���B
1290 // (2006.3.25 yutaka)
1291 //
1292 static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1293 LPARAM lParam)
1294 {
1295 PTInstVar pvar;
1296 LOGFONT logfont;
1297 HFONT font;
1298 char uimsg[MAX_UIMSG];
1299
1300 switch (msg) {
1301 case WM_INITDIALOG:
1302 pvar = (PTInstVar) lParam;
1303 pvar->hosts_state.hosts_dialog = dlg;
1304 SetWindowLong(dlg, DWL_USER, lParam);
1305
1306 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1307 GetWindowText(dlg, uimsg, sizeof(uimsg));
1308 UTIL_get_lang_msg("DLG_UNKNONWHOST_TITLE", pvar, uimsg);
1309 SetWindowText(dlg, pvar->ts->UIMsg);
1310 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1311 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING", pvar, uimsg);
1312 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1313 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1314 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING2", pvar, uimsg);
1315 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1316 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1317 UTIL_get_lang_msg("DLG_UNKNOWNHOST_FINGERPRINT", pvar, uimsg);
1318 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1319 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1320 UTIL_get_lang_msg("DLG_UNKNOWNHOST_ADD", pvar, uimsg);
1321 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1322 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1323 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1324 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1325 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1326 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1327 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1328
1329 switch (pvar->dns_key_check) {
1330 case DNS_VERIFY_NOTFOUND:
1331 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1332 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1333 break;
1334 case DNS_VERIFY_MATCH:
1335 case DNS_VERIFY_AUTH_MATCH:
1336 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1337 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1338 break;
1339 case DNS_VERIFY_MISMATCH:
1340 case DNS_VERIFY_AUTH_MISMATCH:
1341 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1342 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1343 break;
1344 case DNS_VERIFY_DIFFERENTTYPE:
1345 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1346 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1347 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1348 break;
1349 }
1350
1351 switch (pvar->dns_key_check) {
1352 case DNS_VERIFY_MATCH:
1353 case DNS_VERIFY_MISMATCH:
1354 case DNS_VERIFY_DIFFERENTTYPE:
1355 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1356 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1357 break;
1358 case DNS_VERIFY_AUTH_MATCH:
1359 case DNS_VERIFY_AUTH_MISMATCH:
1360 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1361 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1362 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1363 break;
1364 }
1365
1366 init_hosts_dlg(pvar, dlg);
1367
1368 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1369 GetObject(font, sizeof(LOGFONT), &logfont);
1370 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1371 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1372 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1373 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1374 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1375 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1376 SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1377 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1378 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1379 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1380 }
1381 else {
1382 DlgHostsAddFont = NULL;
1383 }
1384
1385 // add host check box���`�F�b�N���f�t�H���g������������
1386 SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1387
1388 return TRUE; /* because we do not set the focus */
1389
1390 case WM_COMMAND:
1391 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1392
1393 switch (LOWORD(wParam)) {
1394 case IDC_CONTINUE:
1395 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1396 if (!pvar->cv->Ready) {
1397 goto canceled;
1398 }
1399
1400 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1401 add_host_key(pvar);
1402 }
1403
1404 if (SSHv1(pvar)) {
1405 SSH_notify_host_OK(pvar);
1406 } else { // SSH2
1407 // SSH2���������� SSH_notify_host_OK() �������B
1408 }
1409
1410 pvar->hosts_state.hosts_dialog = NULL;
1411
1412 EndDialog(dlg, 1);
1413
1414 if (DlgHostsAddFont != NULL) {
1415 DeleteObject(DlgHostsAddFont);
1416 }
1417
1418 return TRUE;
1419
1420 case IDCANCEL: /* kill the connection */
1421 canceled:
1422 pvar->hosts_state.hosts_dialog = NULL;
1423 notify_closed_connection(pvar);
1424 EndDialog(dlg, 0);
1425
1426 if (DlgHostsAddFont != NULL) {
1427 DeleteObject(DlgHostsAddFont);
1428 }
1429
1430 return TRUE;
1431
1432 default:
1433 return FALSE;
1434 }
1435
1436 default:
1437 return FALSE;
1438 }
1439 }
1440
1441 //
1442 // �u�����������m�F�_�C�A���O������
1443 //
1444 static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1445 LPARAM lParam)
1446 {
1447 PTInstVar pvar;
1448 LOGFONT logfont;
1449 HFONT font;
1450 char uimsg[MAX_UIMSG];
1451
1452 switch (msg) {
1453 case WM_INITDIALOG:
1454 pvar = (PTInstVar) lParam;
1455 pvar->hosts_state.hosts_dialog = dlg;
1456 SetWindowLong(dlg, DWL_USER, lParam);
1457
1458 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1459 GetWindowText(dlg, uimsg, sizeof(uimsg));
1460 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
1461 SetWindowText(dlg, pvar->ts->UIMsg);
1462 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1463 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
1464 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1465 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1466 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
1467 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1468 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1469 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
1470 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1471 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1472 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
1473 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1474 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1475 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1476 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1477 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1478 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1479 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1480
1481 switch (pvar->dns_key_check) {
1482 case DNS_VERIFY_NOTFOUND:
1483 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1484 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1485 break;
1486 case DNS_VERIFY_MATCH:
1487 case DNS_VERIFY_AUTH_MATCH:
1488 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1489 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1490 break;
1491 case DNS_VERIFY_MISMATCH:
1492 case DNS_VERIFY_AUTH_MISMATCH:
1493 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1494 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1495 break;
1496 case DNS_VERIFY_DIFFERENTTYPE:
1497 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1498 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1499 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1500 break;
1501 }
1502
1503 switch (pvar->dns_key_check) {
1504 case DNS_VERIFY_MATCH:
1505 case DNS_VERIFY_MISMATCH:
1506 case DNS_VERIFY_DIFFERENTTYPE:
1507 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1508 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1509 break;
1510 case DNS_VERIFY_AUTH_MATCH:
1511 case DNS_VERIFY_AUTH_MISMATCH:
1512 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1513 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1514 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1515 break;
1516 }
1517
1518 init_hosts_dlg(pvar, dlg);
1519
1520 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1521 GetObject(font, sizeof(LOGFONT), &logfont);
1522 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
1523 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1524 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1525 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1526 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1527 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1528 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1529 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1530 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1531 }
1532 else {
1533 DlgHostsReplaceFont = NULL;
1534 }
1535
1536 // �f�t�H���g���`�F�b�N����������
1537 return TRUE; /* because we do not set the focus */
1538
1539 case WM_COMMAND:
1540 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1541
1542 switch (LOWORD(wParam)) {
1543 case IDC_CONTINUE:
1544 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1545 if (!pvar->cv->Ready) {
1546 goto canceled;
1547 }
1548
1549 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1550 add_host_key(pvar);
1551 delete_different_key(pvar);
1552 }
1553
1554 if (SSHv1(pvar)) {
1555 SSH_notify_host_OK(pvar);
1556 } else { // SSH2
1557 // SSH2���������� SSH_notify_host_OK() �������B
1558 }
1559
1560 pvar->hosts_state.hosts_dialog = NULL;
1561
1562 EndDialog(dlg, 1);
1563
1564 if (DlgHostsReplaceFont != NULL) {
1565 DeleteObject(DlgHostsReplaceFont);
1566 }
1567
1568 return TRUE;
1569
1570 case IDCANCEL: /* kill the connection */
1571 canceled:
1572 pvar->hosts_state.hosts_dialog = NULL;
1573 notify_closed_connection(pvar);
1574 EndDialog(dlg, 0);
1575
1576 if (DlgHostsReplaceFont != NULL) {
1577 DeleteObject(DlgHostsReplaceFont);
1578 }
1579
1580 return TRUE;
1581
1582 default:
1583 return FALSE;
1584 }
1585
1586 default:
1587 return FALSE;
1588 }
1589 }
1590
1591 //
1592 // �����z�X�g�����`�����������������m�F�_�C�A���O������
1593 //
1594 static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1595 LPARAM lParam)
1596 {
1597 PTInstVar pvar;
1598 LOGFONT logfont;
1599 HFONT font;
1600 char uimsg[MAX_UIMSG];
1601
1602 switch (msg) {
1603 case WM_INITDIALOG:
1604 pvar = (PTInstVar) lParam;
1605 pvar->hosts_state.hosts_dialog = dlg;
1606 SetWindowLong(dlg, DWL_USER, lParam);
1607
1608 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1609 GetWindowText(dlg, uimsg, sizeof(uimsg));
1610 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
1611 SetWindowText(dlg, pvar->ts->UIMsg);
1612 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1613 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
1614 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1615 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1616 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
1617 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1618 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1619 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
1620 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1621 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1622 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
1623 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1624 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1625 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1626 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1627 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1628 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1629 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1630
1631 switch (pvar->dns_key_check) {
1632 case DNS_VERIFY_NOTFOUND:
1633 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1634 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1635 break;
1636 case DNS_VERIFY_MATCH:
1637 case DNS_VERIFY_AUTH_MATCH:
1638 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1639 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1640 break;
1641 case DNS_VERIFY_MISMATCH:
1642 case DNS_VERIFY_AUTH_MISMATCH:
1643 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1644 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1645 break;
1646 case DNS_VERIFY_DIFFERENTTYPE:
1647 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1648 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1649 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1650 break;
1651 }
1652
1653 switch (pvar->dns_key_check) {
1654 case DNS_VERIFY_MATCH:
1655 case DNS_VERIFY_MISMATCH:
1656 case DNS_VERIFY_DIFFERENTTYPE:
1657 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1658 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1659 break;
1660 case DNS_VERIFY_AUTH_MATCH:
1661 case DNS_VERIFY_AUTH_MISMATCH:
1662 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1663 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1664 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1665 break;
1666 }
1667
1668 init_hosts_dlg(pvar, dlg);
1669
1670 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1671 GetObject(font, sizeof(LOGFONT), &logfont);
1672 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1673 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1674 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1675 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1676 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1677 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1678 SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1679 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1680 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1681 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1682 }
1683 else {
1684 DlgHostsAddFont = NULL;
1685 }
1686
1687 // add host check box ���f�t�H���g�� off ������
1688 // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1689
1690 return TRUE; /* because we do not set the focus */
1691
1692 case WM_COMMAND:
1693 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1694
1695 switch (LOWORD(wParam)) {
1696 case IDC_CONTINUE:
1697 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1698 if (!pvar->cv->Ready) {
1699 goto canceled;
1700 }
1701
1702 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1703 add_host_key(pvar);
1704 }
1705
1706 if (SSHv1(pvar)) {
1707 SSH_notify_host_OK(pvar);
1708 } else { // SSH2
1709 // SSH2���������� SSH_notify_host_OK() �������B
1710 }
1711
1712 pvar->hosts_state.hosts_dialog = NULL;
1713
1714 EndDialog(dlg, 1);
1715
1716 if (DlgHostsAddFont != NULL) {
1717 DeleteObject(DlgHostsAddFont);
1718 }
1719
1720 return TRUE;
1721
1722 case IDCANCEL: /* kill the connection */
1723 canceled:
1724 pvar->hosts_state.hosts_dialog = NULL;
1725 notify_closed_connection(pvar);
1726 EndDialog(dlg, 0);
1727
1728 if (DlgHostsAddFont != NULL) {
1729 DeleteObject(DlgHostsAddFont);
1730 }
1731
1732 return TRUE;
1733
1734 default:
1735 return FALSE;
1736 }
1737
1738 default:
1739 return FALSE;
1740 }
1741 }
1742
1743 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
1744 {
1745 if (pvar->hosts_state.hosts_dialog == NULL) {
1746 HWND cur_active = GetActiveWindow();
1747
1748 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
1749 cur_active != NULL ? cur_active : wnd,
1750 hosts_add_dlg_proc, (LPARAM) pvar);
1751 }
1752 }
1753
1754 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
1755 {
1756 if (pvar->hosts_state.hosts_dialog == NULL) {
1757 HWND cur_active = GetActiveWindow();
1758
1759 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
1760 cur_active != NULL ? cur_active : wnd,
1761 hosts_replace_dlg_proc, (LPARAM) pvar);
1762 }
1763 }
1764
1765 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
1766 {
1767 if (pvar->hosts_state.hosts_dialog == NULL) {
1768 HWND cur_active = GetActiveWindow();
1769
1770 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
1771 cur_active != NULL ? cur_active : wnd,
1772 hosts_add2_dlg_proc, (LPARAM) pvar);
1773 }
1774 }
1775
1776 //
1777 // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
1778 //
1779 // SSH2���������� (2006.3.24 yutaka)
1780 //
1781 BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key)
1782 {
1783 int found_different_key = 0, found_different_type_key = 0;
1784
1785 pvar->dns_key_check = DNS_VERIFY_NONE;
1786
1787 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
1788 if (pvar->hosts_state.prefetched_hostname != NULL
1789 && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
1790 && match_key(pvar, key) == 1) {
1791
1792 if (SSHv1(pvar)) {
1793 SSH_notify_host_OK(pvar);
1794 } else {
1795 // SSH2���������� SSH_notify_host_OK() �������B
1796 }
1797 return TRUE;
1798 }
1799
1800 // �������������������������A�������_���t�@�C��������������
1801 if (begin_read_host_files(pvar, 0)) {
1802 do {
1803 if (!read_host_key(pvar, hostname, tcpport, 0, 0)) {
1804 break;
1805 }
1806
1807 if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
1808 int match = match_key(pvar, key);
1809 if (match == 1) {
1810 finish_read_host_files(pvar, 0);
1811 // ���������G���g�����Q�������A���v�����L�[�������������������B
1812 // SSH2���������������������������B(2006.3.29 yutaka)
1813 if (SSHv1(pvar)) {
1814 SSH_notify_host_OK(pvar);
1815 } else {
1816 // SSH2���������� SSH_notify_host_OK() �������B
1817 }
1818 return TRUE;
1819 }
1820 else if (match == 0) {
1821 // �L�[�� known_hosts ���������������A�L�[�����e���������B
1822 found_different_key = 1;
1823 }
1824 else {
1825 // �L�[���`������������
1826 found_different_type_key = 1;
1827 }
1828 }
1829 } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // �L�[�����������������������[�v����
1830
1831 finish_read_host_files(pvar, 0);
1832 }
1833
1834 // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
1835 pvar->hosts_state.hostkey.type = key->type;
1836 switch (key->type) {
1837 case KEY_RSA1: // SSH1
1838 pvar->hosts_state.hostkey.bits = key->bits;
1839 pvar->hosts_state.hostkey.exp = copy_mp_int(key->exp);
1840 pvar->hosts_state.hostkey.mod = copy_mp_int(key->mod);
1841 break;
1842 case KEY_RSA: // SSH2 RSA
1843 pvar->hosts_state.hostkey.rsa = duplicate_RSA(key->rsa);
1844 break;
1845 case KEY_DSA: // SSH2 DSA
1846 pvar->hosts_state.hostkey.dsa = duplicate_DSA(key->dsa);
1847 break;
1848 case KEY_ECDSA256: // SSH2 ECDSA
1849 case KEY_ECDSA384:
1850 case KEY_ECDSA521:
1851 pvar->hosts_state.hostkey.ecdsa = EC_KEY_dup(key->ecdsa);
1852 break;
1853 case KEY_ED25519:
1854 pvar->hosts_state.hostkey.ed25519_pk = duplicate_ED25519_PK(key->ed25519_pk);
1855 break;
1856 }
1857 free(pvar->hosts_state.prefetched_hostname);
1858 pvar->hosts_state.prefetched_hostname = _strdup(hostname);
1859
1860 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
1861 if (pvar->nocheck_known_hosts == TRUE) {
1862 return TRUE;
1863 }
1864
1865 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
1866 pvar->dns_key_check = verify_hostkey_dns(hostname, key);
1867 }
1868
1869 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
1870 // �������K�v�����������A�����R�[�������X�����B
1871 // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
1872 // (2007.10.1 yutaka)
1873 if (found_different_key) {
1874 HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar);
1875 }
1876 else if (found_different_type_key) {
1877 HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar);
1878 }
1879 else {
1880 HOSTS_do_unknown_host_dialog(pvar->NotificationWindow, pvar);
1881 }
1882
1883 return TRUE;
1884 }
1885
1886 void HOSTS_notify_disconnecting(PTInstVar pvar)
1887 {
1888 if (pvar->hosts_state.hosts_dialog != NULL) {
1889 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
1890 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
1891 EnableWindow(pvar->NotificationWindow, TRUE);
1892 }
1893 }
1894
1895 void HOSTS_end(PTInstVar pvar)
1896 {
1897 int i;
1898
1899 free(pvar->hosts_state.prefetched_hostname);
1900 init_hostkey(&pvar->hosts_state.hostkey);
1901
1902 if (pvar->hosts_state.file_names != NULL) {
1903 for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
1904 free(pvar->hosts_state.file_names[i]);
1905 }
1906 free(pvar->hosts_state.file_names);
1907 }
1908 }

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