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 6146 - (show annotations) (download) (as text)
Tue Nov 17 04:38:16 2015 UTC (8 years, 4 months ago) by maya
File MIME type: text/x-csrc
File size: 71509 byte(s)
移動して使わなくなった関数を削除
1 /*
2 Copyright (c) 1998-2001, Robert O'Callahan
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8 Redistributions of source code must retain the above copyright notice, this list of
9 conditions and the following disclaimer.
10
11 Redistributions in binary form must reproduce the above copyright notice, this list
12 of conditions and the following disclaimer in the documentation and/or other materials
13 provided with the distribution.
14
15 The name of Robert O'Callahan may not be used to endorse or promote products derived from
16 this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 This code is copyright (C) 1998-1999 Robert O'Callahan.
31 See LICENSE.TXT for the license.
32 */
33 #include "ttxssh.h"
34 #include "util.h"
35 #include "resource.h"
36 #include "matcher.h"
37 #include "ssh.h"
38 #include "key.h"
39 #include "hosts.h"
40 #include "dns.h"
41
42 #include <openssl/bn.h>
43 #include <openssl/evp.h>
44 #include <openssl/rsa.h>
45 #include <openssl/dsa.h>
46
47 #include <fcntl.h>
48 #include <io.h>
49 #include <errno.h>
50 #include <sys/stat.h>
51 #include <direct.h>
52 #include <memory.h>
53
54
55 static HFONT DlgHostsAddFont;
56 static HFONT DlgHostsReplaceFont;
57
58 // BASE64�\���������i��������'='�����������������j
59 static char base64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
60
61
62 // �z�X�g�L�[�������� (2006.3.21 yutaka)
63 static void init_hostkey(Key *key)
64 {
65 key->type = KEY_UNSPEC;
66
67 // SSH1
68 key->bits = 0;
69 if (key->exp != NULL) {
70 free(key->exp);
71 key->exp = NULL;
72 }
73 if (key->mod != NULL) {
74 free(key->mod);
75 key->mod = NULL;
76 }
77
78 // SSH2
79 if (key->dsa != NULL) {
80 DSA_free(key->dsa);
81 key->dsa = NULL;
82 }
83 if (key->rsa != NULL) {
84 RSA_free(key->rsa);
85 key->rsa = NULL;
86 }
87 if (key->ecdsa != NULL) {
88 EC_KEY_free(key->ecdsa);
89 key->ecdsa = NULL;
90 }
91 }
92
93
94 static char FAR *FAR * parse_multi_path(char FAR * buf)
95 {
96 int i;
97 int ch;
98 int num_paths = 1;
99 char FAR *FAR * result;
100 int last_path_index;
101
102 for (i = 0; (ch = buf[i]) != 0; i++) {
103 if (ch == ';') {
104 num_paths++;
105 }
106 }
107
108 result =
109 (char FAR * FAR *) malloc(sizeof(char FAR *) * (num_paths + 1));
110
111 last_path_index = 0;
112 num_paths = 0;
113 for (i = 0; (ch = buf[i]) != 0; i++) {
114 if (ch == ';') {
115 buf[i] = 0;
116 result[num_paths] = _strdup(buf + last_path_index);
117 num_paths++;
118 buf[i] = ch;
119 last_path_index = i + 1;
120 }
121 }
122 if (i > last_path_index) {
123 result[num_paths] = _strdup(buf + last_path_index);
124 num_paths++;
125 }
126 result[num_paths] = NULL;
127 return result;
128 }
129
130 void HOSTS_init(PTInstVar pvar)
131 {
132 pvar->hosts_state.prefetched_hostname = NULL;
133 init_hostkey(&pvar->hosts_state.hostkey);
134 pvar->hosts_state.hosts_dialog = NULL;
135 pvar->hosts_state.file_names = NULL;
136 }
137
138 void HOSTS_open(PTInstVar pvar)
139 {
140 pvar->hosts_state.file_names =
141 parse_multi_path(pvar->session_settings.KnownHostsFiles);
142 }
143
144 //
145 // known_hosts�t�@�C�������e�������� pvar->hosts_state.file_data ����������
146 //
147 static int begin_read_file(PTInstVar pvar, char FAR * name,
148 int suppress_errors)
149 {
150 int fd;
151 int length;
152 int amount_read;
153 char buf[2048];
154
155 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
156 fd = _open(buf, _O_RDONLY | _O_SEQUENTIAL | _O_BINARY);
157 if (fd == -1) {
158 if (!suppress_errors) {
159 if (errno == ENOENT) {
160 UTIL_get_lang_msg("MSG_HOSTS_READ_ENOENT_ERROR", pvar,
161 "An error occurred while trying to read a known_hosts file.\n"
162 "The specified filename does not exist.");
163 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
164 } else {
165 UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
166 "An error occurred while trying to read a known_hosts file.");
167 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
168 }
169 }
170 return 0;
171 }
172
173 length = (int) _lseek(fd, 0, SEEK_END);
174 _lseek(fd, 0, SEEK_SET);
175
176 if (length >= 0 && length < 0x7FFFFFFF) {
177 pvar->hosts_state.file_data = malloc(length + 1);
178 if (pvar->hosts_state.file_data == NULL) {
179 if (!suppress_errors) {
180 UTIL_get_lang_msg("MSG_HOSTS_ALLOC_ERROR", pvar,
181 "Memory ran out while trying to allocate space to read a known_hosts file.");
182 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
183 }
184 _close(fd);
185 return 0;
186 }
187 } else {
188 if (!suppress_errors) {
189 UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
190 "An error occurred while trying to read a known_hosts file.");
191 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
192 }
193 _close(fd);
194 return 0;
195 }
196
197 amount_read = _read(fd, pvar->hosts_state.file_data, length);
198 pvar->hosts_state.file_data[length] = 0;
199
200 _close(fd);
201
202 if (amount_read != length) {
203 if (!suppress_errors) {
204 UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
205 "An error occurred while trying to read a known_hosts file.");
206 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
207 }
208 free(pvar->hosts_state.file_data);
209 pvar->hosts_state.file_data = NULL;
210 return 0;
211 } else {
212 return 1;
213 }
214 }
215
216 static int end_read_file(PTInstVar pvar, int suppress_errors)
217 {
218 free(pvar->hosts_state.file_data);
219 pvar->hosts_state.file_data = NULL;
220 return 1;
221 }
222
223 static int begin_read_host_files(PTInstVar pvar, int suppress_errors)
224 {
225 pvar->hosts_state.file_num = 0;
226 pvar->hosts_state.file_data = NULL;
227 return 1;
228 }
229
230 // MIME64�����������X�L�b�v����
231 static int eat_base64(char FAR * data)
232 {
233 int index = 0;
234 int ch;
235
236 for (;;) {
237 ch = data[index];
238 if (ch == '=' || strchr(base64, ch)) {
239 // BASE64���\�������������������� index ���i����
240 index++;
241 } else {
242 break;
243 }
244 }
245
246 return index;
247 }
248
249 static int eat_spaces(char FAR * data)
250 {
251 int index = 0;
252 int ch;
253
254 while ((ch = data[index]) == ' ' || ch == '\t') {
255 index++;
256 }
257 return index;
258 }
259
260 static int eat_digits(char FAR * data)
261 {
262 int index = 0;
263 int ch;
264
265 while ((ch = data[index]) >= '0' && ch <= '9') {
266 index++;
267 }
268 return index;
269 }
270
271 static int eat_to_end_of_line(char FAR * data)
272 {
273 int index = 0;
274 int ch;
275
276 while ((ch = data[index]) != '\n' && ch != '\r' && ch != 0) {
277 index++;
278 }
279
280 while ((ch = data[index]) == '\n' || ch == '\r') {
281 index++;
282 }
283
284 return index;
285 }
286
287 static int eat_to_end_of_pattern(char FAR * data)
288 {
289 int index = 0;
290 int ch;
291
292 while (ch = data[index], is_pattern_char(ch)) {
293 index++;
294 }
295
296 return index;
297 }
298
299 //
300 // BASE64�f�R�[�h�������s���B(rfc1521)
301 // src�o�b�t�@�� null-terminate ���������K�v�����B
302 //
303 int uudecode(unsigned char *src, int srclen, unsigned char *target, int targsize)
304 {
305 char pad = '=';
306 int tarindex, state, ch;
307 char *pos;
308
309 state = 0;
310 tarindex = 0;
311
312 while ((ch = *src++) != '\0') {
313 if (isspace(ch)) /* Skip whitespace anywhere. */
314 continue;
315
316 if (ch == pad)
317 break;
318
319 pos = strchr(base64, ch);
320 if (pos == 0) /* A non-base64 character. */
321 return (-1);
322
323 switch (state) {
324 case 0:
325 if (target) {
326 if (tarindex >= targsize)
327 return (-1);
328 target[tarindex] = (pos - base64) << 2;
329 }
330 state = 1;
331 break;
332 case 1:
333 if (target) {
334 if (tarindex + 1 >= targsize)
335 return (-1);
336 target[tarindex] |= (pos - base64) >> 4;
337 target[tarindex+1] = ((pos - base64) & 0x0f) << 4 ;
338 }
339 tarindex++;
340 state = 2;
341 break;
342 case 2:
343 if (target) {
344 if (tarindex + 1 >= targsize)
345 return (-1);
346 target[tarindex] |= (pos - base64) >> 2;
347 target[tarindex+1] = ((pos - base64) & 0x03) << 6;
348 }
349 tarindex++;
350 state = 3;
351 break;
352 case 3:
353 if (target) {
354 if (tarindex >= targsize)
355 return (-1);
356 target[tarindex] |= (pos - base64);
357 }
358 tarindex++;
359 state = 0;
360 break;
361 }
362 }
363
364 /*
365 * We are done decoding Base-64 chars. Let's see if we ended
366 * on a byte boundary, and/or with erroneous trailing characters.
367 */
368
369 if (ch == pad) { /* We got a pad char. */
370 ch = *src++; /* Skip it, get next. */
371 switch (state) {
372 case 0: /* Invalid = in first position */
373 case 1: /* Invalid = in second position */
374 return (-1);
375
376 case 2: /* Valid, means one byte of info */
377 /* Skip any number of spaces. */
378 for (; ch != '\0'; ch = *src++)
379 if (!isspace(ch))
380 break;
381 /* Make sure there is another trailing = sign. */
382 if (ch != pad)
383 return (-1);
384 ch = *src++; /* Skip the = */
385 /* Fall through to "single trailing =" case. */
386 /* FALLTHROUGH */
387
388 case 3: /* Valid, means two bytes of info */
389 /*
390 * We know this char is an =. Is there anything but
391 * whitespace after it?
392 */
393 for (; ch != '\0'; ch = *src++)
394 if (!isspace(ch))
395 return (-1);
396
397 /*
398 * Now make sure for cases 2 and 3 that the "extra"
399 * bits that slopped past the last full byte were
400 * zeros. If we don't check them, they become a
401 * subliminal channel.
402 */
403 if (target && target[tarindex] != 0)
404 return (-1);
405 }
406 } else {
407 /*
408 * We ended by seeing the end of the string. Make sure we
409 * have no partial bytes lying around.
410 */
411 if (state != 0)
412 return (-1);
413 }
414
415 return (tarindex);
416 }
417
418
419 // SSH2���� BASE64 �`�����i�[����������
420 static Key *parse_uudecode(char *data)
421 {
422 int count;
423 unsigned char *blob = NULL;
424 int len, n;
425 Key *key = NULL;
426 char ch;
427
428 // BASE64���������T�C�Y������
429 count = eat_base64(data);
430 len = 2 * count;
431 blob = malloc(len);
432 if (blob == NULL)
433 goto error;
434
435 // BASE64�f�R�[�h
436 ch = data[count];
437 data[count] = '\0'; // ���������s�R�[�h������������������������������������
438 n = uudecode(data, count, blob, len);
439 data[count] = ch;
440 if (n < 0) {
441 goto error;
442 }
443
444 key = key_from_blob(blob, n);
445 if (key == NULL)
446 goto error;
447
448 error:
449 if (blob != NULL)
450 free(blob);
451
452 return (key);
453 }
454
455
456 static char FAR *parse_bignum(char FAR * data)
457 {
458 uint32 digits = 0;
459 BIGNUM *num = BN_new();
460 BIGNUM *billion = BN_new();
461 BIGNUM *digits_num = BN_new();
462 BN_CTX *ctx = BN_CTX_new();
463 char FAR *result;
464 int ch;
465 int leftover_digits = 1;
466
467 BN_CTX_init(ctx);
468 BN_set_word(num, 0);
469 BN_set_word(billion, 1000000000L);
470
471 while ((ch = *data) >= '0' && ch <= '9') {
472 if (leftover_digits == 1000000000L) {
473 BN_set_word(digits_num, digits);
474 BN_mul(num, num, billion, ctx);
475 BN_add(num, num, digits_num);
476 leftover_digits = 1;
477 digits = 0;
478 }
479
480 digits = digits * 10 + ch - '0';
481 leftover_digits *= 10;
482 data++;
483 }
484
485 BN_set_word(digits_num, digits);
486 BN_set_word(billion, leftover_digits);
487 BN_mul(num, num, billion, ctx);
488 BN_add(num, num, digits_num);
489
490 result = (char FAR *) malloc(2 + BN_num_bytes(num));
491 set_ushort16_MSBfirst(result, BN_num_bits(num));
492 BN_bn2bin(num, result + 2);
493
494 BN_CTX_free(ctx);
495 BN_free(digits_num);
496 BN_free(num);
497 BN_free(billion);
498
499 return result;
500 }
501
502 //
503 // known_hosts�t�@�C�������e���������A�w�������z�X�g�����J�����T���B
504 //
505 static int check_host_key(PTInstVar pvar, char FAR * hostname,
506 unsigned short tcpport, char FAR * data)
507 {
508 int index = eat_spaces(data);
509 int matched = 0;
510 int keybits = 0;
511
512 if (data[index] == '#') {
513 return index + eat_to_end_of_line(data + index);
514 }
515
516 /* if we find an empty line, then it won't have any patterns matching the hostname
517 and so we skip it */
518 index--;
519 do {
520 int negated;
521 int bracketed;
522 char *end_bracket;
523 int host_matched = 0;
524 unsigned short keyfile_port = 22;
525
526 index++;
527 negated = data[index] == '!';
528
529 if (negated) {
530 index++;
531 bracketed = data[index] == '[';
532 if (bracketed) {
533 end_bracket = strstr(data + index + 1, "]:");
534 if (end_bracket != NULL) {
535 *end_bracket = ' ';
536 index++;
537 }
538 }
539 host_matched = match_pattern(data + index, hostname);
540 if (bracketed && end_bracket != NULL) {
541 *end_bracket = ']';
542 keyfile_port = atoi(end_bracket + 2);
543 }
544 if (host_matched && keyfile_port == tcpport) {
545 return index + eat_to_end_of_line(data + index);
546 }
547 } else {
548 bracketed = data[index] == '[';
549 if (bracketed) {
550 end_bracket = strstr(data + index + 1, "]:");
551 if (end_bracket != NULL) {
552 *end_bracket = ' ';
553 index++;
554 }
555 }
556 host_matched = match_pattern(data + index, hostname);
557 if (bracketed && end_bracket != NULL) {
558 *end_bracket = ']';
559 keyfile_port = atoi(end_bracket + 2);
560 }
561 if (host_matched && keyfile_port == tcpport) {
562 matched = 1;
563 }
564 }
565
566 index += eat_to_end_of_pattern(data + index);
567 } while (data[index] == ',');
568
569 if (!matched) {
570 return index + eat_to_end_of_line(data + index);
571 } else {
572 // ���������������t�H�[�}�b�g��������
573 // �����A���������v�����G���g�����������������������B
574 /*
575 [SSH1]
576 192.168.1.2 1024 35 13032....
577
578 [SSH2]
579 192.168.1.2 ssh-rsa AAAAB3NzaC1....
580 192.168.1.2 ssh-dss AAAAB3NzaC1....
581 192.168.1.2 rsa AAAAB3NzaC1....
582 192.168.1.2 dsa AAAAB3NzaC1....
583 192.168.1.2 rsa1 AAAAB3NzaC1....
584 */
585 int rsa1_key_bits;
586
587 index += eat_spaces(data + index);
588
589 rsa1_key_bits = atoi(data + index);
590 if (rsa1_key_bits > 0) { // RSA1������
591 if (!SSHv1(pvar)) { // SSH2��������������������
592 return index + eat_to_end_of_line(data + index);
593 }
594
595 pvar->hosts_state.hostkey.type = KEY_RSA1;
596
597 pvar->hosts_state.hostkey.bits = rsa1_key_bits;
598 index += eat_digits(data + index);
599 index += eat_spaces(data + index);
600
601 pvar->hosts_state.hostkey.exp = parse_bignum(data + index);
602 index += eat_digits(data + index);
603 index += eat_spaces(data + index);
604
605 pvar->hosts_state.hostkey.mod = parse_bignum(data + index);
606
607 /*
608 if (pvar->hosts_state.key_bits < 0
609 || pvar->hosts_state.key_exp == NULL
610 || pvar->hosts_state.key_mod == NULL) {
611 pvar->hosts_state.key_bits = 0;
612 free(pvar->hosts_state.key_exp);
613 free(pvar->hosts_state.key_mod);
614 }*/
615
616 } else {
617 char *cp, *p;
618 Key *key;
619
620 if (!SSHv2(pvar)) { // SSH1��������������������
621 return index + eat_to_end_of_line(data + index);
622 }
623
624 cp = data + index;
625 p = strchr(cp, ' ');
626 if (p == NULL) {
627 return index + eat_to_end_of_line(data + index);
628 }
629 index += (p - cp); // setup index
630 *p = '\0';
631 pvar->hosts_state.hostkey.type = get_keytype_from_name(cp);
632 *p = ' ';
633
634 index += eat_spaces(data + index); // update index
635
636 // uudecode
637 key = parse_uudecode(data + index);
638 if (key == NULL) {
639 return index + eat_to_end_of_line(data + index);
640 }
641
642 // setup
643 pvar->hosts_state.hostkey.type = key->type;
644 pvar->hosts_state.hostkey.dsa = key->dsa;
645 pvar->hosts_state.hostkey.rsa = key->rsa;
646 pvar->hosts_state.hostkey.ecdsa = key->ecdsa;
647 pvar->hosts_state.hostkey.ed25519_pk = key->ed25519_pk;
648
649 index += eat_base64(data + index);
650 index += eat_spaces(data + index);
651
652 // Key�\�������g���������� (2008.3.2 yutaka)
653 free(key);
654 }
655
656 return index + eat_to_end_of_line(data + index);
657 }
658 }
659
660 //
661 // known_hosts�t�@�C�������z�X�g�������v�����s������
662 //
663 static int read_host_key(PTInstVar pvar,
664 char FAR * hostname, unsigned short tcpport,
665 int suppress_errors, int return_always)
666 {
667 int i;
668 int while_flg;
669
670 for (i = 0; hostname[i] != 0; i++) {
671 int ch = hostname[i];
672
673 if (!is_pattern_char(ch) || ch == '*' || ch == '?') {
674 if (!suppress_errors) {
675 UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_INVALID_ERROR", pvar,
676 "The host name contains an invalid character.\n"
677 "This session will be terminated.");
678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
679 }
680 return 0;
681 }
682 }
683
684 if (i == 0) {
685 if (!suppress_errors) {
686 UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_EMPTY_ERROR", pvar,
687 "The host name should not be empty.\n"
688 "This session will be terminated.");
689 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
690 }
691 return 0;
692 }
693
694 // hostkey type is KEY_UNSPEC.
695 init_hostkey(&pvar->hosts_state.hostkey);
696
697 do {
698 if (pvar->hosts_state.file_data == NULL
699 || pvar->hosts_state.file_data[pvar->hosts_state.file_data_index] == 0) {
700 char FAR *filename;
701 int keep_going = 1;
702
703 if (pvar->hosts_state.file_data != NULL) {
704 end_read_file(pvar, suppress_errors);
705 }
706
707 do {
708 filename =
709 pvar->hosts_state.file_names[pvar->hosts_state.file_num];
710
711 if (filename == NULL) {
712 return 1;
713 } else {
714 pvar->hosts_state.file_num++;
715
716 if (filename[0] != 0) {
717 if (begin_read_file(pvar, filename, suppress_errors)) {
718 pvar->hosts_state.file_data_index = 0;
719 keep_going = 0;
720 }
721 }
722 }
723 } while (keep_going);
724 }
725
726 pvar->hosts_state.file_data_index +=
727 check_host_key(pvar, hostname, tcpport,
728 pvar->hosts_state.file_data +
729 pvar->hosts_state.file_data_index);
730
731 if (!return_always) {
732 // �L�����L�[��������������
733 while_flg = (pvar->hosts_state.hostkey.type == KEY_UNSPEC);
734 }
735 else {
736 while_flg = 0;
737 }
738 } while (while_flg);
739
740 return 1;
741 }
742
743 static void finish_read_host_files(PTInstVar pvar, int suppress_errors)
744 {
745 if (pvar->hosts_state.file_data != NULL) {
746 end_read_file(pvar, suppress_errors);
747 }
748 }
749
750 // �T�[�o�����������O���Aknown_hosts�t�@�C�������z�X�g���J�������������������B
751 void HOSTS_prefetch_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport)
752 {
753 if (!begin_read_host_files(pvar, 1)) {
754 return;
755 }
756
757 if (!read_host_key(pvar, hostname, tcpport, 1, 0)) {
758 return;
759 }
760
761 free(pvar->hosts_state.prefetched_hostname);
762 pvar->hosts_state.prefetched_hostname = _strdup(hostname);
763
764 finish_read_host_files(pvar, 1);
765 }
766
767
768 // known_hosts�t�@�C�������Y�������L�[���������������B
769 //
770 // return:
771 // *keyptr != NULL ��������
772 //
773 static int parse_hostkey_file(PTInstVar pvar, char FAR * hostname,
774 unsigned short tcpport, char FAR * data, Key **keyptr)
775 {
776 int index = eat_spaces(data);
777 int matched = 0;
778 int keybits = 0;
779 ssh_keytype ktype;
780 Key *key;
781
782 *keyptr = NULL;
783
784 if (data[index] == '#') {
785 return index + eat_to_end_of_line(data + index);
786 }
787
788 /* if we find an empty line, then it won't have any patterns matching the hostname
789 and so we skip it */
790 index--;
791 do {
792 int negated;
793 int bracketed;
794 char *end_bracket;
795 int host_matched = 0;
796 unsigned short keyfile_port = 22;
797
798 index++;
799 negated = data[index] == '!';
800
801 if (negated) {
802 index++;
803 bracketed = data[index] == '[';
804 if (bracketed) {
805 end_bracket = strstr(data + index + 1, "]:");
806 if (end_bracket != NULL) {
807 *end_bracket = ' ';
808 index++;
809 }
810 }
811 host_matched = match_pattern(data + index, hostname);
812 if (bracketed && end_bracket != NULL) {
813 *end_bracket = ']';
814 keyfile_port = atoi(end_bracket + 2);
815 }
816 if (host_matched && keyfile_port == tcpport) {
817 return index + eat_to_end_of_line(data + index);
818 }
819 }
820 else {
821 bracketed = data[index] == '[';
822 if (bracketed) {
823 end_bracket = strstr(data + index + 1, "]:");
824 if (end_bracket != NULL) {
825 *end_bracket = ' ';
826 index++;
827 }
828 }
829 host_matched = match_pattern(data + index, hostname);
830 if (bracketed && end_bracket != NULL) {
831 *end_bracket = ']';
832 keyfile_port = atoi(end_bracket + 2);
833 }
834 if (host_matched && keyfile_port == tcpport) {
835 matched = 1;
836 }
837 }
838
839 index += eat_to_end_of_pattern(data + index);
840 } while (data[index] == ',');
841
842 if (!matched) {
843 return index + eat_to_end_of_line(data + index);
844 }
845 else {
846 // ���������������t�H�[�}�b�g��������
847 // �����A���������v�����G���g�����������������������B
848 /*
849 [SSH1]
850 192.168.1.2 1024 35 13032....
851
852 [SSH2]
853 192.168.1.2 ssh-rsa AAAAB3NzaC1....
854 192.168.1.2 ssh-dss AAAAB3NzaC1....
855 192.168.1.2 rsa AAAAB3NzaC1....
856 192.168.1.2 dsa AAAAB3NzaC1....
857 192.168.1.2 rsa1 AAAAB3NzaC1....
858 */
859 int rsa1_key_bits;
860
861 index += eat_spaces(data + index);
862
863 rsa1_key_bits = atoi(data + index);
864 if (rsa1_key_bits > 0) { // RSA1������
865 if (!SSHv1(pvar)) { // SSH2��������������������
866 return index + eat_to_end_of_line(data + index);
867 }
868
869 key = key_new(KEY_RSA1);
870 key->bits = rsa1_key_bits;
871
872 index += eat_digits(data + index);
873 index += eat_spaces(data + index);
874 key->exp = parse_bignum(data + index);
875
876 index += eat_digits(data + index);
877 index += eat_spaces(data + index);
878 key->mod = parse_bignum(data + index);
879
880 // setup
881 *keyptr = key;
882
883 }
884 else {
885 char *cp, *p;
886
887 if (!SSHv2(pvar)) { // SSH1��������������������
888 return index + eat_to_end_of_line(data + index);
889 }
890
891 cp = data + index;
892 p = strchr(cp, ' ');
893 if (p == NULL) {
894 return index + eat_to_end_of_line(data + index);
895 }
896 index += (p - cp); // setup index
897 *p = '\0';
898 ktype = get_keytype_from_name(cp);
899 *p = ' ';
900
901 index += eat_spaces(data + index); // update index
902
903 // uudecode
904 key = parse_uudecode(data + index);
905 if (key == NULL) {
906 return index + eat_to_end_of_line(data + index);
907 }
908
909 // setup
910 *keyptr = key;
911
912 index += eat_base64(data + index);
913 index += eat_spaces(data + index);
914 }
915
916 return index + eat_to_end_of_line(data + index);
917 }
918 }
919
920 // known_hosts�t�@�C�������z�X�g���J�������������B
921 // �������������������������������AHost key rotation�p���V�K���p�������B
922 //
923 // return 1: success
924 // 0: fail
925 int HOSTS_hostkey_foreach(PTInstVar pvar, hostkeys_foreach_fn *callback, void *ctx)
926 {
927 int success = 0;
928 int suppress_errors = 1;
929 unsigned short tcpport;
930 char FAR *filename;
931 char *hostname;
932 Key *key;
933
934 if (!begin_read_host_files(pvar, 1)) {
935 goto error;
936 }
937
938 // Host key rotation�����Aknown_hosts �t�@�C�������������������A
939 // ������������1�������t�@�C�������������i2�������t�@�C����ReadOnly�������j�B
940 filename = pvar->hosts_state.file_names[pvar->hosts_state.file_num];
941 pvar->hosts_state.file_num++;
942
943 pvar->hosts_state.file_data_index = -1;
944 if (filename[0] != 0) {
945 if (begin_read_file(pvar, filename, suppress_errors)) {
946 pvar->hosts_state.file_data_index = 0;
947 }
948 }
949 if (pvar->hosts_state.file_data_index == -1)
950 goto error;
951
952 // ���������������z�X�g�����|�[�g�����B
953 hostname = pvar->ssh_state.hostname;
954 tcpport = pvar->ssh_state.tcpport;
955
956 // known_hosts�t�@�C�������e�������� pvar->hosts_state.file_data �������������������B
957 // ������ \0 �B
958 while (pvar->hosts_state.file_data[pvar->hosts_state.file_data_index] != 0) {
959 key = NULL;
960
961 pvar->hosts_state.file_data_index +=
962 parse_hostkey_file(pvar, hostname, tcpport,
963 pvar->hosts_state.file_data +
964 pvar->hosts_state.file_data_index,
965 &key);
966
967 // �Y�����������������������A�R�[���o�b�N�����������o���B
968 if (key != NULL) {
969 if (callback(key, ctx) == 0)
970 key_free(key);
971 }
972 }
973
974 success = 1;
975
976 error:
977 finish_read_host_files(pvar, 1);
978
979 return (success);
980 }
981
982
983 static BOOL equal_mp_ints(unsigned char FAR * num1,
984 unsigned char FAR * num2)
985 {
986 if (num1 == NULL || num2 == NULL) {
987 return FALSE;
988 } else {
989 uint32 bytes = (get_ushort16_MSBfirst(num1) + 7) / 8;
990
991 if (bytes != (get_ushort16_MSBfirst(num2) + 7) / 8) {
992 return FALSE; /* different byte lengths */
993 } else {
994 return memcmp(num1 + 2, num2 + 2, bytes) == 0;
995 }
996 }
997 }
998
999
1000 // ���J�������r���s���B
1001 //
1002 // return
1003 // -1 ... �����^������
1004 // 0 ... ����������
1005 // 1 ... ������
1006 int HOSTS_compare_public_key(Key *src, Key *key)
1007 {
1008 int bits;
1009 unsigned char FAR * exp;
1010 unsigned char FAR * mod;
1011 const EC_GROUP *group;
1012 const EC_POINT *pa, *pb;
1013 Key *a, *b;
1014
1015 if (src->type != key->type) {
1016 return -1;
1017 }
1018
1019 switch (key->type) {
1020 case KEY_RSA1: // SSH1 host public key
1021 bits = key->bits;
1022 exp = key->exp;
1023 mod = key->mod;
1024
1025 /* just check for equal exponent and modulus */
1026 return equal_mp_ints(exp, src->exp)
1027 && equal_mp_ints(mod, src->mod);
1028 /*
1029 return equal_mp_ints(exp, pvar->hosts_state.key_exp)
1030 && equal_mp_ints(mod, pvar->hosts_state.key_mod);
1031 */
1032
1033 case KEY_RSA: // SSH2 RSA host public key
1034 return key->rsa != NULL && src->rsa != NULL &&
1035 BN_cmp(key->rsa->e, src->rsa->e) == 0 &&
1036 BN_cmp(key->rsa->n, src->rsa->n) == 0;
1037
1038 case KEY_DSA: // SSH2 DSA host public key
1039 return key->dsa != NULL && src->dsa &&
1040 BN_cmp(key->dsa->p, src->dsa->p) == 0 &&
1041 BN_cmp(key->dsa->q, src->dsa->q) == 0 &&
1042 BN_cmp(key->dsa->g, src->dsa->g) == 0 &&
1043 BN_cmp(key->dsa->pub_key, src->dsa->pub_key) == 0;
1044
1045 case KEY_ECDSA256:
1046 case KEY_ECDSA384:
1047 case KEY_ECDSA521:
1048 if (key->ecdsa == NULL || src->ecdsa == NULL) {
1049 return FALSE;
1050 }
1051 group = EC_KEY_get0_group(key->ecdsa);
1052 pa = EC_KEY_get0_public_key(key->ecdsa),
1053 pb = EC_KEY_get0_public_key(src->ecdsa);
1054 return EC_POINT_cmp(group, pa, pb, NULL) == 0;
1055
1056 case KEY_ED25519:
1057 a = key;
1058 b = src;
1059 return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
1060 memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;
1061
1062 default:
1063 return FALSE;
1064 }
1065 }
1066
1067
1068 // ���J����������������������
1069 // -1 ... �����^������
1070 // 0 ... ����������
1071 // 1 ... ������
1072 static int match_key(PTInstVar pvar, Key *key)
1073 {
1074 return HOSTS_compare_public_key(&pvar->hosts_state.hostkey, key);
1075 }
1076
1077 static void hosts_dlg_set_fingerprint(PTInstVar pvar, HWND dlg, digest_algorithm dgst_alg)
1078 {
1079 char *fp = NULL;
1080
1081 // fingerprint����������
1082 switch (dgst_alg) {
1083 case SSH_DIGEST_MD5:
1084 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX, dgst_alg);
1085 SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
1086 free(fp);
1087 break;
1088 case SSH_DIGEST_SHA256:
1089 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_BASE64, dgst_alg);
1090 SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
1091 free(fp);
1092 break;
1093 }
1094
1095 // �r�W���A����fingerprint���\������
1096 fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART, dgst_alg);
1097 SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETTEXT, 0, (LPARAM)fp);
1098 free(fp);
1099 }
1100
1101 static void init_hosts_dlg(PTInstVar pvar, HWND dlg)
1102 {
1103 char buf[1024];
1104 char buf2[2048];
1105 int i, j;
1106 int ch;
1107
1108 // static text�� # �������z�X�g�����u������
1109 GetDlgItemText(dlg, IDC_HOSTWARNING, buf, sizeof(buf));
1110 for (i = 0; (ch = buf[i]) != 0 && ch != '#'; i++) {
1111 buf2[i] = ch;
1112 }
1113 strncpy_s(buf2 + i, sizeof(buf2) - i,
1114 pvar->hosts_state.prefetched_hostname, _TRUNCATE);
1115 j = i + strlen(buf2 + i);
1116 for (; buf[i] == '#'; i++) {
1117 }
1118 strncpy_s(buf2 + j, sizeof(buf2) - j, buf + i, _TRUNCATE);
1119
1120 SetDlgItemText(dlg, IDC_HOSTWARNING, buf2);
1121
1122 SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), TRUE);
1123
1124 CheckDlgButton(dlg, IDC_FP_HASH_ALG_SHA256, TRUE);
1125 hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
1126 }
1127
1128 static int print_mp_int(char FAR * buf, unsigned char FAR * mp)
1129 {
1130 int i = 0, j, k;
1131 BIGNUM *num = BN_new();
1132 int ch;
1133
1134 BN_bin2bn(mp + 2, (get_ushort16_MSBfirst(mp) + 7) / 8, num);
1135
1136 do {
1137 buf[i] = (char) ((BN_div_word(num, 10)) + '0');
1138 i++;
1139 } while (!BN_is_zero(num));
1140
1141 /* we need to reverse the digits */
1142 for (j = 0, k = i - 1; j < k; j++, k--) {
1143 ch = buf[j];
1144 buf[j] = buf[k];
1145 buf[k] = ch;
1146 }
1147
1148 buf[i] = 0;
1149 return i;
1150 }
1151
1152 //
1153 // known_hosts �t�@�C�������������G���g�������������B
1154 //
1155 static char FAR *format_host_key(PTInstVar pvar)
1156 {
1157 int host_len = strlen(pvar->hosts_state.prefetched_hostname);
1158 char *result = NULL;
1159 int index;
1160 ssh_keytype type = pvar->hosts_state.hostkey.type;
1161
1162 switch (type) {
1163 case KEY_RSA1:
1164 {
1165 int result_len = host_len + 50 + 8 +
1166 get_ushort16_MSBfirst(pvar->hosts_state.hostkey.exp) / 3 +
1167 get_ushort16_MSBfirst(pvar->hosts_state.hostkey.mod) / 3;
1168 result = (char FAR *) malloc(result_len);
1169
1170 if (pvar->ssh_state.tcpport == 22) {
1171 strncpy_s(result, result_len, pvar->hosts_state.prefetched_hostname, _TRUNCATE);
1172 index = host_len;
1173 }
1174 else {
1175 _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
1176 pvar->hosts_state.prefetched_hostname,
1177 pvar->ssh_state.tcpport);
1178 index = strlen(result);
1179 }
1180
1181 _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
1182 " %d ", pvar->hosts_state.hostkey.bits);
1183 index += strlen(result + index);
1184 index += print_mp_int(result + index, pvar->hosts_state.hostkey.exp);
1185 result[index] = ' ';
1186 index++;
1187 index += print_mp_int(result + index, pvar->hosts_state.hostkey.mod);
1188 strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
1189
1190 break;
1191 }
1192
1193 case KEY_RSA:
1194 case KEY_DSA:
1195 case KEY_ECDSA256:
1196 case KEY_ECDSA384:
1197 case KEY_ECDSA521:
1198 case KEY_ED25519:
1199 {
1200 Key *key = &pvar->hosts_state.hostkey;
1201 char *blob = NULL;
1202 int blen, uulen, msize;
1203 char *uu = NULL;
1204 int n;
1205
1206 key_to_blob(key, &blob, &blen);
1207 uulen = 2 * blen;
1208 uu = malloc(uulen);
1209 if (uu == NULL) {
1210 goto error;
1211 }
1212 n = uuencode(blob, blen, uu, uulen);
1213 if (n > 0) {
1214 msize = host_len + 50 + uulen;
1215 result = malloc(msize);
1216 if (result == NULL) {
1217 goto error;
1218 }
1219
1220 // setup
1221 if (pvar->ssh_state.tcpport == 22) {
1222 _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
1223 pvar->hosts_state.prefetched_hostname,
1224 get_sshname_from_key(key),
1225 uu);
1226 } else {
1227 _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
1228 pvar->hosts_state.prefetched_hostname,
1229 pvar->ssh_state.tcpport,
1230 get_sshname_from_key(key),
1231 uu);
1232 }
1233 }
1234 error:
1235 if (blob != NULL)
1236 free(blob);
1237 if (uu != NULL)
1238 free(uu);
1239
1240 break;
1241 }
1242
1243 default:
1244 return NULL;
1245
1246 }
1247
1248 return result;
1249 }
1250
1251 static char FAR *format_specified_host_key(Key *key, char *hostname, unsigned short tcpport)
1252 {
1253 int host_len = strlen(hostname);
1254 char *result = NULL;
1255 int index;
1256 ssh_keytype type = key->type;
1257
1258 switch (type) {
1259 case KEY_RSA1:
1260 {
1261 int result_len = host_len + 50 + 8 +
1262 get_ushort16_MSBfirst(key->exp) / 3 +
1263 get_ushort16_MSBfirst(key->mod) / 3;
1264 result = (char FAR *) malloc(result_len);
1265
1266 if (tcpport == 22) {
1267 strncpy_s(result, result_len, hostname, _TRUNCATE);
1268 index = host_len;
1269 }
1270 else {
1271 _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
1272 hostname,
1273 tcpport);
1274 index = strlen(result);
1275 }
1276
1277 _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
1278 " %d ", key->bits);
1279 index += strlen(result + index);
1280 index += print_mp_int(result + index, key->exp);
1281 result[index] = ' ';
1282 index++;
1283 index += print_mp_int(result + index, key->mod);
1284 strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
1285
1286 break;
1287 }
1288
1289 case KEY_RSA:
1290 case KEY_DSA:
1291 case KEY_ECDSA256:
1292 case KEY_ECDSA384:
1293 case KEY_ECDSA521:
1294 case KEY_ED25519:
1295 {
1296 //Key *key = &pvar->hosts_state.hostkey;
1297 char *blob = NULL;
1298 int blen, uulen, msize;
1299 char *uu = NULL;
1300 int n;
1301
1302 key_to_blob(key, &blob, &blen);
1303 uulen = 2 * blen;
1304 uu = malloc(uulen);
1305 if (uu == NULL) {
1306 goto error;
1307 }
1308 n = uuencode(blob, blen, uu, uulen);
1309 if (n > 0) {
1310 msize = host_len + 50 + uulen;
1311 result = malloc(msize);
1312 if (result == NULL) {
1313 goto error;
1314 }
1315
1316 // setup
1317 if (tcpport == 22) {
1318 _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
1319 hostname,
1320 get_sshname_from_key(key),
1321 uu);
1322 }
1323 else {
1324 _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
1325 hostname,
1326 tcpport,
1327 get_sshname_from_key(key),
1328 uu);
1329 }
1330 }
1331 error:
1332 if (blob != NULL)
1333 free(blob);
1334 if (uu != NULL)
1335 free(uu);
1336
1337 break;
1338 }
1339
1340 default:
1341 return NULL;
1342
1343 }
1344
1345 return result;
1346 }
1347
1348 static void add_host_key(PTInstVar pvar)
1349 {
1350 char FAR *name = NULL;
1351
1352 if ( pvar->hosts_state.file_names != NULL)
1353 name = pvar->hosts_state.file_names[0];
1354
1355 if (name == NULL || name[0] == 0) {
1356 UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1357 "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1358 "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1359 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1360 } else {
1361 char FAR *keydata = format_host_key(pvar);
1362 int length = strlen(keydata);
1363 int fd;
1364 int amount_written;
1365 int close_result;
1366 char buf[FILENAME_MAX];
1367
1368 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1369 fd = _open(buf,
1370 _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1371 _S_IREAD | _S_IWRITE);
1372 if (fd == -1) {
1373 if (errno == EACCES) {
1374 UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1375 "An error occurred while trying to write the host key.\n"
1376 "You do not have permission to write to the known-hosts file.");
1377 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1378 } else {
1379 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1380 "An error occurred while trying to write the host key.\n"
1381 "The host key could not be written.");
1382 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1383 }
1384 return;
1385 }
1386
1387 amount_written = _write(fd, keydata, length);
1388 free(keydata);
1389 close_result = _close(fd);
1390
1391 if (amount_written != length || close_result == -1) {
1392 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1393 "An error occurred while trying to write the host key.\n"
1394 "The host key could not be written.");
1395 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1396 }
1397 }
1398 }
1399
1400 // �w�������L�[�� known_hosts �����������B
1401 void HOSTS_add_host_key(PTInstVar pvar, Key *key)
1402 {
1403 char FAR *name = NULL;
1404 char *hostname;
1405 unsigned short tcpport;
1406
1407 hostname = pvar->ssh_state.hostname;
1408 tcpport = pvar->ssh_state.tcpport;
1409
1410 if (pvar->hosts_state.file_names != NULL)
1411 name = pvar->hosts_state.file_names[0];
1412
1413 if (name == NULL || name[0] == 0) {
1414 UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1415 "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1416 "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1417 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1418 }
1419 else {
1420 char FAR *keydata = format_specified_host_key(key, hostname, tcpport);
1421 int length = strlen(keydata);
1422 int fd;
1423 int amount_written;
1424 int close_result;
1425 char buf[FILENAME_MAX];
1426
1427 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1428 fd = _open(buf,
1429 _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1430 _S_IREAD | _S_IWRITE);
1431 if (fd == -1) {
1432 if (errno == EACCES) {
1433 UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1434 "An error occurred while trying to write the host key.\n"
1435 "You do not have permission to write to the known-hosts file.");
1436 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1437 }
1438 else {
1439 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1440 "An error occurred while trying to write the host key.\n"
1441 "The host key could not be written.");
1442 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1443 }
1444 return;
1445 }
1446
1447 amount_written = _write(fd, keydata, length);
1448 free(keydata);
1449 close_result = _close(fd);
1450
1451 if (amount_written != length || close_result == -1) {
1452 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1453 "An error occurred while trying to write the host key.\n"
1454 "The host key could not be written.");
1455 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1456 }
1457 }
1458 }
1459
1460 //
1461 // �����z�X�g�����e���������L�[����������
1462 // add_host_key ����������������
1463 //
1464 static void delete_different_key(PTInstVar pvar)
1465 {
1466 char FAR *name = pvar->hosts_state.file_names[0];
1467
1468 if (name == NULL || name[0] == 0) {
1469 UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1470 "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1471 "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1472 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1473 }
1474 else {
1475 Key key; // ���������z�X�g���L�[
1476 Key *key_freed;
1477 int length;
1478 char filename[MAX_PATH];
1479 char tmp[L_tmpnam];
1480 int fd;
1481 int amount_written = 0;
1482 int close_result;
1483 int data_index = 0;
1484 char buf[FILENAME_MAX];
1485
1486 // �������������t�@�C�����J��
1487 _getcwd(filename, sizeof(filename));
1488 tmpnam_s(tmp,sizeof(tmp));
1489 strcat_s(filename, sizeof(filename), tmp);
1490 fd = _open(filename,
1491 _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1492 _S_IREAD | _S_IWRITE);
1493
1494 if (fd == -1) {
1495 if (errno == EACCES) {
1496 UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1497 "An error occurred while trying to write the host key.\n"
1498 "You do not have permission to write to the known-hosts file.");
1499 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1500 } else {
1501 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1502 "An error occurred while trying to write the host key.\n"
1503 "The host key could not be written.");
1504 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1505 }
1506 return;
1507 }
1508
1509 // ���������T�[�o���L�[����������
1510 key_copy(&key, &(pvar->hosts_state.hostkey));
1511
1512 // �t�@�C��������������
1513 begin_read_host_files(pvar, 0);
1514 do {
1515 int host_index = 0;
1516 int matched = 0;
1517 int keybits = 0;
1518 char FAR *data;
1519 int do_write = 0;
1520 length = amount_written = 0;
1521
1522 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1)) {
1523 break;
1524 }
1525
1526 if (data_index == pvar->hosts_state.file_data_index) {
1527 // index ���i������ == ��������������
1528 break;
1529 }
1530
1531 data = pvar->hosts_state.file_data + data_index;
1532 host_index = eat_spaces(data);
1533
1534 if (data[host_index] == '#') {
1535 do_write = 1;
1536 }
1537 else {
1538 // �z�X�g������
1539 host_index--;
1540 do {
1541 int negated;
1542 int bracketed;
1543 char *end_bracket;
1544 int host_matched = 0;
1545 unsigned short keyfile_port = 22;
1546
1547 host_index++;
1548 negated = data[host_index] == '!';
1549
1550 if (negated) {
1551 host_index++;
1552 bracketed = data[host_index] == '[';
1553 if (bracketed) {
1554 end_bracket = strstr(data + host_index + 1, "]:");
1555 if (end_bracket != NULL) {
1556 *end_bracket = ' ';
1557 host_index++;
1558 }
1559 }
1560 host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1561 if (bracketed && end_bracket != NULL) {
1562 *end_bracket = ']';
1563 keyfile_port = atoi(end_bracket + 2);
1564 }
1565 if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1566 matched = 0;
1567 // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1568 host_index--;
1569 do {
1570 host_index++;
1571 host_index += eat_to_end_of_pattern(data + host_index);
1572 } while (data[host_index] == ',');
1573 break;
1574 }
1575 }
1576 else {
1577 bracketed = data[host_index] == '[';
1578 if (bracketed) {
1579 end_bracket = strstr(data + host_index + 1, "]:");
1580 if (end_bracket != NULL) {
1581 *end_bracket = ' ';
1582 host_index++;
1583 }
1584 }
1585 host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1586 if (bracketed && end_bracket != NULL) {
1587 *end_bracket = ']';
1588 keyfile_port = atoi(end_bracket + 2);
1589 }
1590 if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1591 matched = 1;
1592 }
1593 }
1594 host_index += eat_to_end_of_pattern(data + host_index);
1595 } while (data[host_index] == ',');
1596
1597 // �z�X�g������������
1598 if (!matched) {
1599 do_write = 1;
1600 }
1601 // �z�X�g��������
1602 else {
1603 // �����`�������� or ���v�����L�[
1604 if (match_key(pvar, &key) != 0) {
1605 do_write = 1;
1606 }
1607 // �����`�������������v�������L�[���X�L�b�v������
1608 }
1609 }
1610
1611 // ������������
1612 if (do_write) {
1613 length = pvar->hosts_state.file_data_index - data_index;
1614 amount_written =
1615 _write(fd, pvar->hosts_state.file_data + data_index,
1616 length);
1617
1618 if (amount_written != length) {
1619 goto error1;
1620 }
1621 }
1622 data_index = pvar->hosts_state.file_data_index;
1623 } while (1); // ������������
1624
1625 error1:
1626 close_result = _close(fd);
1627 if (amount_written != length || close_result == -1) {
1628 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1629 "An error occurred while trying to write the host key.\n"
1630 "The host key could not be written.");
1631 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1632 goto error2;
1633 }
1634
1635 // �������������t�@�C���������l�[��
1636 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1637 _unlink(buf);
1638 rename(filename, buf);
1639
1640 error2:
1641 _unlink(filename);
1642
1643 finish_read_host_files(pvar, 0);
1644
1645 // ���������������������������B
1646 key_freed = key_new(KEY_UNSPEC);
1647 memcpy(key_freed, &key, sizeof(Key));
1648 key_free(key_freed);
1649 }
1650 }
1651
1652
1653 void HOSTS_delete_all_hostkeys(PTInstVar pvar)
1654 {
1655 char FAR *name = pvar->hosts_state.file_names[0];
1656 char *hostname;
1657 unsigned short tcpport;
1658
1659 hostname = pvar->ssh_state.hostname;
1660 tcpport = pvar->ssh_state.tcpport;
1661
1662 if (name == NULL || name[0] == 0) {
1663 UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1664 "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1665 "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1666 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1667 }
1668 else {
1669 Key key; // ���������z�X�g���L�[
1670 Key *key_freed;
1671 int length;
1672 char filename[MAX_PATH];
1673 char tmp[L_tmpnam];
1674 int fd;
1675 int amount_written = 0;
1676 int close_result;
1677 int data_index = 0;
1678 char buf[FILENAME_MAX];
1679
1680 // �������������t�@�C�����J��
1681 _getcwd(filename, sizeof(filename));
1682 tmpnam_s(tmp, sizeof(tmp));
1683 strcat_s(filename, sizeof(filename), tmp);
1684 fd = _open(filename,
1685 _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1686 _S_IREAD | _S_IWRITE);
1687
1688 if (fd == -1) {
1689 if (errno == EACCES) {
1690 UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1691 "An error occurred while trying to write the host key.\n"
1692 "You do not have permission to write to the known-hosts file.");
1693 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1694 }
1695 else {
1696 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1697 "An error occurred while trying to write the host key.\n"
1698 "The host key could not be written.");
1699 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1700 }
1701 return;
1702 }
1703
1704 // ���������T�[�o���L�[����������
1705 key_copy(&key, &(pvar->hosts_state.hostkey));
1706
1707 // �t�@�C��������������
1708 begin_read_host_files(pvar, 0);
1709 do {
1710 int host_index = 0;
1711 int matched = 0;
1712 int keybits = 0;
1713 char FAR *data;
1714 int do_write = 0;
1715 length = amount_written = 0;
1716
1717 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1)) {
1718 break;
1719 }
1720
1721 if (data_index == pvar->hosts_state.file_data_index) {
1722 // index ���i������ == ��������������
1723 break;
1724 }
1725
1726 data = pvar->hosts_state.file_data + data_index;
1727 host_index = eat_spaces(data);
1728
1729 if (data[host_index] == '#') {
1730 do_write = 1;
1731 }
1732 else {
1733 // �z�X�g������
1734 host_index--;
1735 do {
1736 int negated;
1737 int bracketed;
1738 char *end_bracket;
1739 int host_matched = 0;
1740 unsigned short keyfile_port = 22;
1741
1742 host_index++;
1743 negated = data[host_index] == '!';
1744
1745 if (negated) {
1746 host_index++;
1747 bracketed = data[host_index] == '[';
1748 if (bracketed) {
1749 end_bracket = strstr(data + host_index + 1, "]:");
1750 if (end_bracket != NULL) {
1751 *end_bracket = ' ';
1752 host_index++;
1753 }
1754 }
1755 host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1756 if (bracketed && end_bracket != NULL) {
1757 *end_bracket = ']';
1758 keyfile_port = atoi(end_bracket + 2);
1759 }
1760 if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1761 matched = 0;
1762 // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1763 host_index--;
1764 do {
1765 host_index++;
1766 host_index += eat_to_end_of_pattern(data + host_index);
1767 } while (data[host_index] == ',');
1768 break;
1769 }
1770 }
1771 else {
1772 bracketed = data[host_index] == '[';
1773 if (bracketed) {
1774 end_bracket = strstr(data + host_index + 1, "]:");
1775 if (end_bracket != NULL) {
1776 *end_bracket = ' ';
1777 host_index++;
1778 }
1779 }
1780 host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1781 if (bracketed && end_bracket != NULL) {
1782 *end_bracket = ']';
1783 keyfile_port = atoi(end_bracket + 2);
1784 }
1785 if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1786 matched = 1;
1787 }
1788 }
1789 host_index += eat_to_end_of_pattern(data + host_index);
1790 } while (data[host_index] == ',');
1791
1792 // �z�X�g������������
1793 if (!matched) {
1794 do_write = 1;
1795 }
1796 // �z�X�g��������
1797 else {
1798 // ���������������������B
1799
1800 }
1801 }
1802
1803 // ������������
1804 if (do_write) {
1805 length = pvar->hosts_state.file_data_index - data_index;
1806 amount_written =
1807 _write(fd, pvar->hosts_state.file_data + data_index,
1808 length);
1809
1810 if (amount_written != length) {
1811 goto error1;
1812 }
1813 }
1814 data_index = pvar->hosts_state.file_data_index;
1815 } while (1); // ������������
1816
1817 error1:
1818 close_result = _close(fd);
1819 if (amount_written != length || close_result == -1) {
1820 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1821 "An error occurred while trying to write the host key.\n"
1822 "The host key could not be written.");
1823 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1824 goto error2;
1825 }
1826
1827 // �������������t�@�C���������l�[��
1828 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1829 _unlink(buf);
1830 rename(filename, buf);
1831
1832 error2:
1833 _unlink(filename);
1834
1835 finish_read_host_files(pvar, 0);
1836
1837 // ���������������������������B
1838 key_freed = key_new(KEY_UNSPEC);
1839 memcpy(key_freed, &key, sizeof(Key));
1840 key_free(key_freed);
1841 }
1842 }
1843
1844
1845 //
1846 // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1847 // ���[�U���m�F�������B
1848 // TODO: finger print���\�����s���B
1849 // (2006.3.25 yutaka)
1850 //
1851 static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1852 LPARAM lParam)
1853 {
1854 PTInstVar pvar;
1855 LOGFONT logfont;
1856 HFONT font;
1857 char uimsg[MAX_UIMSG];
1858
1859 switch (msg) {
1860 case WM_INITDIALOG:
1861 pvar = (PTInstVar) lParam;
1862 pvar->hosts_state.hosts_dialog = dlg;
1863 SetWindowLong(dlg, DWL_USER, lParam);
1864
1865 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1866 GetWindowText(dlg, uimsg, sizeof(uimsg));
1867 UTIL_get_lang_msg("DLG_UNKNONWHOST_TITLE", pvar, uimsg);
1868 SetWindowText(dlg, pvar->ts->UIMsg);
1869 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1870 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING", pvar, uimsg);
1871 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1872 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1873 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING2", pvar, uimsg);
1874 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1875 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1876 UTIL_get_lang_msg("DLG_UNKNOWNHOST_FINGERPRINT", pvar, uimsg);
1877 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1878 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
1879 UTIL_get_lang_msg("DLG_UNKNOWNHOST_FP_HASH_ALGORITHM", pvar, uimsg);
1880 SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
1881 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1882 UTIL_get_lang_msg("DLG_UNKNOWNHOST_ADD", pvar, uimsg);
1883 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1884 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1885 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1886 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1887 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1888 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1889 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1890
1891 switch (pvar->dns_key_check) {
1892 case DNS_VERIFY_NOTFOUND:
1893 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1894 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1895 break;
1896 case DNS_VERIFY_MATCH:
1897 case DNS_VERIFY_AUTH_MATCH:
1898 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1899 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1900 break;
1901 case DNS_VERIFY_MISMATCH:
1902 case DNS_VERIFY_AUTH_MISMATCH:
1903 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1904 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1905 break;
1906 case DNS_VERIFY_DIFFERENTTYPE:
1907 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1908 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1909 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1910 break;
1911 }
1912
1913 switch (pvar->dns_key_check) {
1914 case DNS_VERIFY_MATCH:
1915 case DNS_VERIFY_MISMATCH:
1916 case DNS_VERIFY_DIFFERENTTYPE:
1917 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1918 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1919 break;
1920 case DNS_VERIFY_AUTH_MATCH:
1921 case DNS_VERIFY_AUTH_MISMATCH:
1922 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1923 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1924 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1925 break;
1926 }
1927
1928 init_hosts_dlg(pvar, dlg);
1929
1930 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1931 GetObject(font, sizeof(LOGFONT), &logfont);
1932 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1933 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1934 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1935 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1936 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1937 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1938 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1939 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1940 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1941 SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1942 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1943 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1944 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1945 }
1946 else {
1947 DlgHostsAddFont = NULL;
1948 }
1949
1950 // add host check box���`�F�b�N���f�t�H���g������������
1951 SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1952
1953 return TRUE; /* because we do not set the focus */
1954
1955 case WM_COMMAND:
1956 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1957
1958 switch (LOWORD(wParam)) {
1959 case IDC_CONTINUE:
1960 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1961 if (!pvar->cv->Ready) {
1962 goto canceled;
1963 }
1964
1965 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1966 add_host_key(pvar);
1967 }
1968
1969 if (SSHv1(pvar)) {
1970 SSH_notify_host_OK(pvar);
1971 } else { // SSH2
1972 // SSH2���������� SSH_notify_host_OK() �������B
1973 }
1974
1975 pvar->hosts_state.hosts_dialog = NULL;
1976
1977 EndDialog(dlg, 1);
1978
1979 if (DlgHostsAddFont != NULL) {
1980 DeleteObject(DlgHostsAddFont);
1981 }
1982
1983 return TRUE;
1984
1985 case IDCANCEL: /* kill the connection */
1986 canceled:
1987 pvar->hosts_state.hosts_dialog = NULL;
1988 notify_closed_connection(pvar, "authentication cancelled");
1989 EndDialog(dlg, 0);
1990
1991 if (DlgHostsAddFont != NULL) {
1992 DeleteObject(DlgHostsAddFont);
1993 }
1994
1995 return TRUE;
1996
1997 case IDC_FP_HASH_ALG_MD5:
1998 hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
1999 return TRUE;
2000
2001 case IDC_FP_HASH_ALG_SHA256:
2002 hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2003 return TRUE;
2004
2005 default:
2006 return FALSE;
2007 }
2008
2009 default:
2010 return FALSE;
2011 }
2012 }
2013
2014 //
2015 // �u�����������m�F�_�C�A���O������
2016 //
2017 static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
2018 LPARAM lParam)
2019 {
2020 PTInstVar pvar;
2021 LOGFONT logfont;
2022 HFONT font;
2023 char uimsg[MAX_UIMSG];
2024
2025 switch (msg) {
2026 case WM_INITDIALOG:
2027 pvar = (PTInstVar) lParam;
2028 pvar->hosts_state.hosts_dialog = dlg;
2029 SetWindowLong(dlg, DWL_USER, lParam);
2030
2031 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
2032 GetWindowText(dlg, uimsg, sizeof(uimsg));
2033 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
2034 SetWindowText(dlg, pvar->ts->UIMsg);
2035 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
2036 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
2037 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
2038 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
2039 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
2040 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
2041 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
2042 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
2043 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
2044 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2045 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FP_HASH_ALGORITHM", pvar, uimsg);
2046 SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2047 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
2048 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
2049 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
2050 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
2051 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
2052 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
2053 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2054 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
2055 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2056
2057 switch (pvar->dns_key_check) {
2058 case DNS_VERIFY_NOTFOUND:
2059 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
2060 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2061 break;
2062 case DNS_VERIFY_MATCH:
2063 case DNS_VERIFY_AUTH_MATCH:
2064 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
2065 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2066 break;
2067 case DNS_VERIFY_MISMATCH:
2068 case DNS_VERIFY_AUTH_MISMATCH:
2069 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
2070 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2071 break;
2072 case DNS_VERIFY_DIFFERENTTYPE:
2073 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2074 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
2075 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2076 break;
2077 }
2078
2079 switch (pvar->dns_key_check) {
2080 case DNS_VERIFY_MATCH:
2081 case DNS_VERIFY_MISMATCH:
2082 case DNS_VERIFY_DIFFERENTTYPE:
2083 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
2084 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2085 break;
2086 case DNS_VERIFY_AUTH_MATCH:
2087 case DNS_VERIFY_AUTH_MISMATCH:
2088 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2089 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
2090 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2091 break;
2092 }
2093
2094 init_hosts_dlg(pvar, dlg);
2095
2096 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2097 GetObject(font, sizeof(LOGFONT), &logfont);
2098 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
2099 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2100 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2101 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2102 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2103 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2104 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2105 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2106 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2107 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2108 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2109 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2110 }
2111 else {
2112 DlgHostsReplaceFont = NULL;
2113 }
2114
2115 // �f�t�H���g���`�F�b�N����������
2116 return TRUE; /* because we do not set the focus */
2117
2118 case WM_COMMAND:
2119 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
2120
2121 switch (LOWORD(wParam)) {
2122 case IDC_CONTINUE:
2123 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
2124 if (!pvar->cv->Ready) {
2125 goto canceled;
2126 }
2127
2128 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
2129 add_host_key(pvar);
2130 delete_different_key(pvar);
2131 }
2132
2133 if (SSHv1(pvar)) {
2134 SSH_notify_host_OK(pvar);
2135 } else { // SSH2
2136 // SSH2���������� SSH_notify_host_OK() �������B
2137 }
2138
2139 pvar->hosts_state.hosts_dialog = NULL;
2140
2141 EndDialog(dlg, 1);
2142
2143 if (DlgHostsReplaceFont != NULL) {
2144 DeleteObject(DlgHostsReplaceFont);
2145 }
2146
2147 return TRUE;
2148
2149 case IDCANCEL: /* kill the connection */
2150 canceled:
2151 pvar->hosts_state.hosts_dialog = NULL;
2152 notify_closed_connection(pvar, "authentication cancelled");
2153 EndDialog(dlg, 0);
2154
2155 if (DlgHostsReplaceFont != NULL) {
2156 DeleteObject(DlgHostsReplaceFont);
2157 }
2158
2159 return TRUE;
2160
2161 case IDC_FP_HASH_ALG_MD5:
2162 hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2163 return TRUE;
2164
2165 case IDC_FP_HASH_ALG_SHA256:
2166 hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2167 return TRUE;
2168
2169 default:
2170 return FALSE;
2171 }
2172
2173 default:
2174 return FALSE;
2175 }
2176 }
2177
2178 //
2179 // �����z�X�g�����`�����������������m�F�_�C�A���O������
2180 //
2181 static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
2182 LPARAM lParam)
2183 {
2184 PTInstVar pvar;
2185 LOGFONT logfont;
2186 HFONT font;
2187 char uimsg[MAX_UIMSG];
2188
2189 switch (msg) {
2190 case WM_INITDIALOG:
2191 pvar = (PTInstVar) lParam;
2192 pvar->hosts_state.hosts_dialog = dlg;
2193 SetWindowLong(dlg, DWL_USER, lParam);
2194
2195 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
2196 GetWindowText(dlg, uimsg, sizeof(uimsg));
2197 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
2198 SetWindowText(dlg, pvar->ts->UIMsg);
2199 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
2200 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
2201 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
2202 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
2203 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
2204 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
2205 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
2206 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
2207 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
2208 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2209 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FP_HASH_ALGORITHM", pvar, uimsg);
2210 SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2211 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
2212 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
2213 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
2214 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
2215 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
2216 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
2217 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2218 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
2219 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2220
2221 switch (pvar->dns_key_check) {
2222 case DNS_VERIFY_NOTFOUND:
2223 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
2224 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2225 break;
2226 case DNS_VERIFY_MATCH:
2227 case DNS_VERIFY_AUTH_MATCH:
2228 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
2229 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2230 break;
2231 case DNS_VERIFY_MISMATCH:
2232 case DNS_VERIFY_AUTH_MISMATCH:
2233 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
2234 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2235 break;
2236 case DNS_VERIFY_DIFFERENTTYPE:
2237 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2238 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
2239 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2240 break;
2241 }
2242
2243 switch (pvar->dns_key_check) {
2244 case DNS_VERIFY_MATCH:
2245 case DNS_VERIFY_MISMATCH:
2246 case DNS_VERIFY_DIFFERENTTYPE:
2247 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
2248 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2249 break;
2250 case DNS_VERIFY_AUTH_MATCH:
2251 case DNS_VERIFY_AUTH_MISMATCH:
2252 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2253 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
2254 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2255 break;
2256 }
2257
2258 init_hosts_dlg(pvar, dlg);
2259
2260 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2261 GetObject(font, sizeof(LOGFONT), &logfont);
2262 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
2263 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2264 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2265 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2266 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2267 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2268 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2269 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2270 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2271 SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2272 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2273 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2274 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2275 }
2276 else {
2277 DlgHostsAddFont = NULL;
2278 }
2279
2280 // add host check box ���f�t�H���g�� off ������
2281 // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
2282
2283 return TRUE; /* because we do not set the focus */
2284
2285 case WM_COMMAND:
2286 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
2287
2288 switch (LOWORD(wParam)) {
2289 case IDC_CONTINUE:
2290 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
2291 if (!pvar->cv->Ready) {
2292 goto canceled;
2293 }
2294
2295 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
2296 add_host_key(pvar);
2297 }
2298
2299 if (SSHv1(pvar)) {
2300 SSH_notify_host_OK(pvar);
2301 } else { // SSH2
2302 // SSH2���������� SSH_notify_host_OK() �������B
2303 }
2304
2305 pvar->hosts_state.hosts_dialog = NULL;
2306
2307 EndDialog(dlg, 1);
2308
2309 if (DlgHostsAddFont != NULL) {
2310 DeleteObject(DlgHostsAddFont);
2311 }
2312
2313 return TRUE;
2314
2315 case IDCANCEL: /* kill the connection */
2316 canceled:
2317 pvar->hosts_state.hosts_dialog = NULL;
2318 notify_closed_connection(pvar, "authentication cancelled");
2319 EndDialog(dlg, 0);
2320
2321 if (DlgHostsAddFont != NULL) {
2322 DeleteObject(DlgHostsAddFont);
2323 }
2324
2325 return TRUE;
2326
2327 case IDC_FP_HASH_ALG_MD5:
2328 hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2329 return TRUE;
2330
2331 case IDC_FP_HASH_ALG_SHA256:
2332 hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2333 return TRUE;
2334
2335 default:
2336 return FALSE;
2337 }
2338
2339 default:
2340 return FALSE;
2341 }
2342 }
2343
2344 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
2345 {
2346 if (pvar->hosts_state.hosts_dialog == NULL) {
2347 HWND cur_active = GetActiveWindow();
2348
2349 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
2350 cur_active != NULL ? cur_active : wnd,
2351 hosts_add_dlg_proc, (LPARAM) pvar);
2352 }
2353 }
2354
2355 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
2356 {
2357 if (pvar->hosts_state.hosts_dialog == NULL) {
2358 HWND cur_active = GetActiveWindow();
2359
2360 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
2361 cur_active != NULL ? cur_active : wnd,
2362 hosts_replace_dlg_proc, (LPARAM) pvar);
2363 }
2364 }
2365
2366 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
2367 {
2368 if (pvar->hosts_state.hosts_dialog == NULL) {
2369 HWND cur_active = GetActiveWindow();
2370
2371 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
2372 cur_active != NULL ? cur_active : wnd,
2373 hosts_add2_dlg_proc, (LPARAM) pvar);
2374 }
2375 }
2376
2377 //
2378 // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
2379 //
2380 // SSH2���������� (2006.3.24 yutaka)
2381 //
2382 BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key)
2383 {
2384 int found_different_key = 0, found_different_type_key = 0;
2385
2386 pvar->dns_key_check = DNS_VERIFY_NONE;
2387
2388 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
2389 if (pvar->hosts_state.prefetched_hostname != NULL
2390 && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
2391 && match_key(pvar, key) == 1) {
2392
2393 if (SSHv1(pvar)) {
2394 SSH_notify_host_OK(pvar);
2395 } else {
2396 // SSH2���������� SSH_notify_host_OK() �������B
2397 }
2398 return TRUE;
2399 }
2400
2401 // �������������������������A�������_���t�@�C��������������
2402 if (begin_read_host_files(pvar, 0)) {
2403 do {
2404 if (!read_host_key(pvar, hostname, tcpport, 0, 0)) {
2405 break;
2406 }
2407
2408 if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
2409 int match = match_key(pvar, key);
2410 if (match == 1) {
2411 finish_read_host_files(pvar, 0);
2412 // ���������G���g�����Q�������A���v�����L�[�������������������B
2413 // SSH2���������������������������B(2006.3.29 yutaka)
2414 if (SSHv1(pvar)) {
2415 SSH_notify_host_OK(pvar);
2416 } else {
2417 // SSH2���������� SSH_notify_host_OK() �������B
2418 }
2419 return TRUE;
2420 }
2421 else if (match == 0) {
2422 // �L�[�� known_hosts ���������������A�L�[�����e���������B
2423 found_different_key = 1;
2424 }
2425 else {
2426 // �L�[���`������������
2427 found_different_type_key = 1;
2428 }
2429 }
2430 } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // �L�[�����������������������[�v����
2431
2432 finish_read_host_files(pvar, 0);
2433 }
2434
2435 // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
2436 key_copy(&(pvar->hosts_state.hostkey), key);
2437
2438 free(pvar->hosts_state.prefetched_hostname);
2439 pvar->hosts_state.prefetched_hostname = _strdup(hostname);
2440
2441 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
2442 if (pvar->nocheck_known_hosts == TRUE) {
2443 return TRUE;
2444 }
2445
2446 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
2447 pvar->dns_key_check = verify_hostkey_dns(pvar, hostname, key);
2448 }
2449
2450 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
2451 // �������K�v�����������A�����R�[�������X�����B
2452 // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
2453 // (2007.10.1 yutaka)
2454 if (found_different_key) {
2455 HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar);
2456 }
2457 else if (found_different_type_key) {
2458 HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar);
2459 }
2460 else {
2461 HOSTS_do_unknown_host_dialog(pvar->NotificationWindow, pvar);
2462 }
2463
2464 return TRUE;
2465 }
2466
2467 void HOSTS_notify_disconnecting(PTInstVar pvar)
2468 {
2469 if (pvar->hosts_state.hosts_dialog != NULL) {
2470 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
2471 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
2472 EnableWindow(pvar->NotificationWindow, TRUE);
2473 }
2474 }
2475
2476 void HOSTS_end(PTInstVar pvar)
2477 {
2478 int i;
2479
2480 free(pvar->hosts_state.prefetched_hostname);
2481 init_hostkey(&pvar->hosts_state.hostkey);
2482
2483 if (pvar->hosts_state.file_names != NULL) {
2484 for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
2485 free(pvar->hosts_state.file_names[i]);
2486 }
2487 free(pvar->hosts_state.file_names);
2488 }
2489 }

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