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 5545 - (show annotations) (download) (as text)
Mon Mar 17 16:06:58 2014 UTC (10 years ago) by yutakapon
File MIME type: text/x-csrc
File size: 55409 byte(s)
チケット #33263
Curve25519楕円曲線DH(Diffe Hellman)アルゴリズムを使った鍵交換をサポートした。

svn+ssh://svn.sourceforge.jp/svnroot/ttssh2/branches/ssh_ed25519
ブランチからマージ。

現時点でサポートしている機能は下記の通り。

 ・Key Generatorで ED25519 鍵の作成
 ・Key Generatorで RSA/DSA/ECDSA 秘密鍵ファイルに bcrypt KDF を選択可能。
 ・ED25519 による公開鍵認証ログイン
 ・RSA(bcrypt KDF) による公開鍵認証ログイン
 ・DSA(bcrypt KDF) による公開鍵認証ログイン
 ・ECDSA(bcrypt KDF) による公開鍵認証ログイン
 ・Host Keyに 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 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 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1396 add_host_key(pvar);
1397 }
1398
1399 if (SSHv1(pvar)) {
1400 SSH_notify_host_OK(pvar);
1401 } else { // SSH2
1402 // SSH2���������� SSH_notify_host_OK() �������B
1403 }
1404
1405 pvar->hosts_state.hosts_dialog = NULL;
1406
1407 EndDialog(dlg, 1);
1408
1409 if (DlgHostsAddFont != NULL) {
1410 DeleteObject(DlgHostsAddFont);
1411 }
1412
1413 return TRUE;
1414
1415 case IDCANCEL: /* kill the connection */
1416 pvar->hosts_state.hosts_dialog = NULL;
1417 notify_closed_connection(pvar);
1418 EndDialog(dlg, 0);
1419
1420 if (DlgHostsAddFont != NULL) {
1421 DeleteObject(DlgHostsAddFont);
1422 }
1423
1424 return TRUE;
1425
1426 default:
1427 return FALSE;
1428 }
1429
1430 default:
1431 return FALSE;
1432 }
1433 }
1434
1435 //
1436 // �u�����������m�F�_�C�A���O������
1437 //
1438 static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1439 LPARAM lParam)
1440 {
1441 PTInstVar pvar;
1442 LOGFONT logfont;
1443 HFONT font;
1444 char uimsg[MAX_UIMSG];
1445
1446 switch (msg) {
1447 case WM_INITDIALOG:
1448 pvar = (PTInstVar) lParam;
1449 pvar->hosts_state.hosts_dialog = dlg;
1450 SetWindowLong(dlg, DWL_USER, lParam);
1451
1452 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1453 GetWindowText(dlg, uimsg, sizeof(uimsg));
1454 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
1455 SetWindowText(dlg, pvar->ts->UIMsg);
1456 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1457 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
1458 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1459 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1460 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
1461 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1462 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1463 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
1464 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1465 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1466 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
1467 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1468 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1469 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1470 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1471 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1472 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1473 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1474
1475 switch (pvar->dns_key_check) {
1476 case DNS_VERIFY_NOTFOUND:
1477 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1478 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1479 break;
1480 case DNS_VERIFY_MATCH:
1481 case DNS_VERIFY_AUTH_MATCH:
1482 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1483 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1484 break;
1485 case DNS_VERIFY_MISMATCH:
1486 case DNS_VERIFY_AUTH_MISMATCH:
1487 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1488 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1489 break;
1490 case DNS_VERIFY_DIFFERENTTYPE:
1491 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1492 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1493 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1494 break;
1495 }
1496
1497 switch (pvar->dns_key_check) {
1498 case DNS_VERIFY_MATCH:
1499 case DNS_VERIFY_MISMATCH:
1500 case DNS_VERIFY_DIFFERENTTYPE:
1501 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1502 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1503 break;
1504 case DNS_VERIFY_AUTH_MATCH:
1505 case DNS_VERIFY_AUTH_MISMATCH:
1506 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1507 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1508 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1509 break;
1510 }
1511
1512 init_hosts_dlg(pvar, dlg);
1513
1514 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1515 GetObject(font, sizeof(LOGFONT), &logfont);
1516 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
1517 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1518 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1519 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1520 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1521 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1522 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1523 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1524 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1525 }
1526 else {
1527 DlgHostsReplaceFont = NULL;
1528 }
1529
1530 // �f�t�H���g���`�F�b�N����������
1531 return TRUE; /* because we do not set the focus */
1532
1533 case WM_COMMAND:
1534 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1535
1536 switch (LOWORD(wParam)) {
1537 case IDC_CONTINUE:
1538 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1539 add_host_key(pvar);
1540 delete_different_key(pvar);
1541 }
1542
1543 if (SSHv1(pvar)) {
1544 SSH_notify_host_OK(pvar);
1545 } else { // SSH2
1546 // SSH2���������� SSH_notify_host_OK() �������B
1547 }
1548
1549 pvar->hosts_state.hosts_dialog = NULL;
1550
1551 EndDialog(dlg, 1);
1552
1553 if (DlgHostsReplaceFont != NULL) {
1554 DeleteObject(DlgHostsReplaceFont);
1555 }
1556
1557 return TRUE;
1558
1559 case IDCANCEL: /* kill the connection */
1560 pvar->hosts_state.hosts_dialog = NULL;
1561 notify_closed_connection(pvar);
1562 EndDialog(dlg, 0);
1563
1564 if (DlgHostsReplaceFont != NULL) {
1565 DeleteObject(DlgHostsReplaceFont);
1566 }
1567
1568 return TRUE;
1569
1570 default:
1571 return FALSE;
1572 }
1573
1574 default:
1575 return FALSE;
1576 }
1577 }
1578
1579 //
1580 // �����z�X�g�����`�����������������m�F�_�C�A���O������
1581 //
1582 static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1583 LPARAM lParam)
1584 {
1585 PTInstVar pvar;
1586 LOGFONT logfont;
1587 HFONT font;
1588 char uimsg[MAX_UIMSG];
1589
1590 switch (msg) {
1591 case WM_INITDIALOG:
1592 pvar = (PTInstVar) lParam;
1593 pvar->hosts_state.hosts_dialog = dlg;
1594 SetWindowLong(dlg, DWL_USER, lParam);
1595
1596 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1597 GetWindowText(dlg, uimsg, sizeof(uimsg));
1598 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
1599 SetWindowText(dlg, pvar->ts->UIMsg);
1600 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1601 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
1602 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1603 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1604 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
1605 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1606 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1607 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
1608 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1609 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1610 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
1611 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1612 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1613 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1614 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1615 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1616 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1617 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1618
1619 switch (pvar->dns_key_check) {
1620 case DNS_VERIFY_NOTFOUND:
1621 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1622 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1623 break;
1624 case DNS_VERIFY_MATCH:
1625 case DNS_VERIFY_AUTH_MATCH:
1626 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1627 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1628 break;
1629 case DNS_VERIFY_MISMATCH:
1630 case DNS_VERIFY_AUTH_MISMATCH:
1631 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1632 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1633 break;
1634 case DNS_VERIFY_DIFFERENTTYPE:
1635 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1636 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1637 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1638 break;
1639 }
1640
1641 switch (pvar->dns_key_check) {
1642 case DNS_VERIFY_MATCH:
1643 case DNS_VERIFY_MISMATCH:
1644 case DNS_VERIFY_DIFFERENTTYPE:
1645 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1646 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1647 break;
1648 case DNS_VERIFY_AUTH_MATCH:
1649 case DNS_VERIFY_AUTH_MISMATCH:
1650 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1651 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1652 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1653 break;
1654 }
1655
1656 init_hosts_dlg(pvar, dlg);
1657
1658 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1659 GetObject(font, sizeof(LOGFONT), &logfont);
1660 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1661 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1662 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1663 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1664 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1665 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1666 SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1667 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1668 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1669 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1670 }
1671 else {
1672 DlgHostsAddFont = NULL;
1673 }
1674
1675 // add host check box ���f�t�H���g�� off ������
1676 // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1677
1678 return TRUE; /* because we do not set the focus */
1679
1680 case WM_COMMAND:
1681 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1682
1683 switch (LOWORD(wParam)) {
1684 case IDC_CONTINUE:
1685 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1686 add_host_key(pvar);
1687 }
1688
1689 if (SSHv1(pvar)) {
1690 SSH_notify_host_OK(pvar);
1691 } else { // SSH2
1692 // SSH2���������� SSH_notify_host_OK() �������B
1693 }
1694
1695 pvar->hosts_state.hosts_dialog = NULL;
1696
1697 EndDialog(dlg, 1);
1698
1699 if (DlgHostsAddFont != NULL) {
1700 DeleteObject(DlgHostsAddFont);
1701 }
1702
1703 return TRUE;
1704
1705 case IDCANCEL: /* kill the connection */
1706 pvar->hosts_state.hosts_dialog = NULL;
1707 notify_closed_connection(pvar);
1708 EndDialog(dlg, 0);
1709
1710 if (DlgHostsAddFont != NULL) {
1711 DeleteObject(DlgHostsAddFont);
1712 }
1713
1714 return TRUE;
1715
1716 default:
1717 return FALSE;
1718 }
1719
1720 default:
1721 return FALSE;
1722 }
1723 }
1724
1725 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
1726 {
1727 if (pvar->hosts_state.hosts_dialog == NULL) {
1728 HWND cur_active = GetActiveWindow();
1729
1730 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
1731 cur_active != NULL ? cur_active : wnd,
1732 hosts_add_dlg_proc, (LPARAM) pvar);
1733 }
1734 }
1735
1736 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
1737 {
1738 if (pvar->hosts_state.hosts_dialog == NULL) {
1739 HWND cur_active = GetActiveWindow();
1740
1741 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
1742 cur_active != NULL ? cur_active : wnd,
1743 hosts_replace_dlg_proc, (LPARAM) pvar);
1744 }
1745 }
1746
1747 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
1748 {
1749 if (pvar->hosts_state.hosts_dialog == NULL) {
1750 HWND cur_active = GetActiveWindow();
1751
1752 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
1753 cur_active != NULL ? cur_active : wnd,
1754 hosts_add2_dlg_proc, (LPARAM) pvar);
1755 }
1756 }
1757
1758 //
1759 // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
1760 //
1761 // SSH2���������� (2006.3.24 yutaka)
1762 //
1763 BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key)
1764 {
1765 int found_different_key = 0, found_different_type_key = 0;
1766
1767 pvar->dns_key_check = DNS_VERIFY_NONE;
1768
1769 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
1770 if (pvar->hosts_state.prefetched_hostname != NULL
1771 && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
1772 && match_key(pvar, key) == 1) {
1773
1774 if (SSHv1(pvar)) {
1775 SSH_notify_host_OK(pvar);
1776 } else {
1777 // SSH2���������� SSH_notify_host_OK() �������B
1778 }
1779 return TRUE;
1780 }
1781
1782 // �������������������������A�������_���t�@�C��������������
1783 if (begin_read_host_files(pvar, 0)) {
1784 do {
1785 if (!read_host_key(pvar, hostname, tcpport, 0, 0)) {
1786 break;
1787 }
1788
1789 if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
1790 int match = match_key(pvar, key);
1791 if (match == 1) {
1792 finish_read_host_files(pvar, 0);
1793 // ���������G���g�����Q�������A���v�����L�[�������������������B
1794 // SSH2���������������������������B(2006.3.29 yutaka)
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 else if (match == 0) {
1803 // �L�[�� known_hosts ���������������A�L�[�����e���������B
1804 found_different_key = 1;
1805 }
1806 else {
1807 // �L�[���`������������
1808 found_different_type_key = 1;
1809 }
1810 }
1811 } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // �L�[�����������������������[�v����
1812
1813 finish_read_host_files(pvar, 0);
1814 }
1815
1816 // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
1817 pvar->hosts_state.hostkey.type = key->type;
1818 switch (key->type) {
1819 case KEY_RSA1: // SSH1
1820 pvar->hosts_state.hostkey.bits = key->bits;
1821 pvar->hosts_state.hostkey.exp = copy_mp_int(key->exp);
1822 pvar->hosts_state.hostkey.mod = copy_mp_int(key->mod);
1823 break;
1824 case KEY_RSA: // SSH2 RSA
1825 pvar->hosts_state.hostkey.rsa = duplicate_RSA(key->rsa);
1826 break;
1827 case KEY_DSA: // SSH2 DSA
1828 pvar->hosts_state.hostkey.dsa = duplicate_DSA(key->dsa);
1829 break;
1830 case KEY_ECDSA256: // SSH2 ECDSA
1831 case KEY_ECDSA384:
1832 case KEY_ECDSA521:
1833 pvar->hosts_state.hostkey.ecdsa = EC_KEY_dup(key->ecdsa);
1834 break;
1835 case KEY_ED25519:
1836 pvar->hosts_state.hostkey.ed25519_pk = duplicate_ED25519_PK(key->ed25519_pk);
1837 break;
1838 }
1839 free(pvar->hosts_state.prefetched_hostname);
1840 pvar->hosts_state.prefetched_hostname = _strdup(hostname);
1841
1842 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
1843 if (pvar->nocheck_known_hosts == TRUE) {
1844 return TRUE;
1845 }
1846
1847 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
1848 pvar->dns_key_check = verify_hostkey_dns(hostname, key);
1849 }
1850
1851 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
1852 // �������K�v�����������A�����R�[�������X�����B
1853 // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
1854 // (2007.10.1 yutaka)
1855 if (found_different_key) {
1856 HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar);
1857 }
1858 else if (found_different_type_key) {
1859 HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar);
1860 }
1861 else {
1862 HOSTS_do_unknown_host_dialog(pvar->NotificationWindow, pvar);
1863 }
1864
1865 return TRUE;
1866 }
1867
1868 void HOSTS_notify_disconnecting(PTInstVar pvar)
1869 {
1870 if (pvar->hosts_state.hosts_dialog != NULL) {
1871 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
1872 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
1873 EnableWindow(pvar->NotificationWindow, TRUE);
1874 }
1875 }
1876
1877 void HOSTS_end(PTInstVar pvar)
1878 {
1879 int i;
1880
1881 free(pvar->hosts_state.prefetched_hostname);
1882 init_hostkey(&pvar->hosts_state.hostkey);
1883
1884 if (pvar->hosts_state.file_names != NULL) {
1885 for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
1886 free(pvar->hosts_state.file_names[i]);
1887 }
1888 free(pvar->hosts_state.file_names);
1889 }
1890 }

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