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 6145 - (show annotations) (download) (as text)
Tue Nov 17 04:37:00 2015 UTC (8 years, 4 months ago) by maya
File MIME type: text/x-csrc
File size: 71742 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 static char FAR *copy_mp_int(char FAR * num)
1461 {
1462 int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;
1463 char FAR *result = (char FAR *) malloc(len);
1464
1465 if (result != NULL) {
1466 memcpy(result, num, len);
1467 }
1468
1469 return result;
1470 }
1471
1472 //
1473 // �����z�X�g�����e���������L�[����������
1474 // add_host_key ����������������
1475 //
1476 static void delete_different_key(PTInstVar pvar)
1477 {
1478 char FAR *name = pvar->hosts_state.file_names[0];
1479
1480 if (name == NULL || name[0] == 0) {
1481 UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1482 "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1483 "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1484 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1485 }
1486 else {
1487 Key key; // ���������z�X�g���L�[
1488 Key *key_freed;
1489 int length;
1490 char filename[MAX_PATH];
1491 char tmp[L_tmpnam];
1492 int fd;
1493 int amount_written = 0;
1494 int close_result;
1495 int data_index = 0;
1496 char buf[FILENAME_MAX];
1497
1498 // �������������t�@�C�����J��
1499 _getcwd(filename, sizeof(filename));
1500 tmpnam_s(tmp,sizeof(tmp));
1501 strcat_s(filename, sizeof(filename), tmp);
1502 fd = _open(filename,
1503 _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1504 _S_IREAD | _S_IWRITE);
1505
1506 if (fd == -1) {
1507 if (errno == EACCES) {
1508 UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1509 "An error occurred while trying to write the host key.\n"
1510 "You do not have permission to write to the known-hosts file.");
1511 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1512 } else {
1513 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1514 "An error occurred while trying to write the host key.\n"
1515 "The host key could not be written.");
1516 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1517 }
1518 return;
1519 }
1520
1521 // ���������T�[�o���L�[����������
1522 key_copy(&key, &(pvar->hosts_state.hostkey));
1523
1524 // �t�@�C��������������
1525 begin_read_host_files(pvar, 0);
1526 do {
1527 int host_index = 0;
1528 int matched = 0;
1529 int keybits = 0;
1530 char FAR *data;
1531 int do_write = 0;
1532 length = amount_written = 0;
1533
1534 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1)) {
1535 break;
1536 }
1537
1538 if (data_index == pvar->hosts_state.file_data_index) {
1539 // index ���i������ == ��������������
1540 break;
1541 }
1542
1543 data = pvar->hosts_state.file_data + data_index;
1544 host_index = eat_spaces(data);
1545
1546 if (data[host_index] == '#') {
1547 do_write = 1;
1548 }
1549 else {
1550 // �z�X�g������
1551 host_index--;
1552 do {
1553 int negated;
1554 int bracketed;
1555 char *end_bracket;
1556 int host_matched = 0;
1557 unsigned short keyfile_port = 22;
1558
1559 host_index++;
1560 negated = data[host_index] == '!';
1561
1562 if (negated) {
1563 host_index++;
1564 bracketed = data[host_index] == '[';
1565 if (bracketed) {
1566 end_bracket = strstr(data + host_index + 1, "]:");
1567 if (end_bracket != NULL) {
1568 *end_bracket = ' ';
1569 host_index++;
1570 }
1571 }
1572 host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1573 if (bracketed && end_bracket != NULL) {
1574 *end_bracket = ']';
1575 keyfile_port = atoi(end_bracket + 2);
1576 }
1577 if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1578 matched = 0;
1579 // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1580 host_index--;
1581 do {
1582 host_index++;
1583 host_index += eat_to_end_of_pattern(data + host_index);
1584 } while (data[host_index] == ',');
1585 break;
1586 }
1587 }
1588 else {
1589 bracketed = data[host_index] == '[';
1590 if (bracketed) {
1591 end_bracket = strstr(data + host_index + 1, "]:");
1592 if (end_bracket != NULL) {
1593 *end_bracket = ' ';
1594 host_index++;
1595 }
1596 }
1597 host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1598 if (bracketed && end_bracket != NULL) {
1599 *end_bracket = ']';
1600 keyfile_port = atoi(end_bracket + 2);
1601 }
1602 if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1603 matched = 1;
1604 }
1605 }
1606 host_index += eat_to_end_of_pattern(data + host_index);
1607 } while (data[host_index] == ',');
1608
1609 // �z�X�g������������
1610 if (!matched) {
1611 do_write = 1;
1612 }
1613 // �z�X�g��������
1614 else {
1615 // �����`�������� or ���v�����L�[
1616 if (match_key(pvar, &key) != 0) {
1617 do_write = 1;
1618 }
1619 // �����`�������������v�������L�[���X�L�b�v������
1620 }
1621 }
1622
1623 // ������������
1624 if (do_write) {
1625 length = pvar->hosts_state.file_data_index - data_index;
1626 amount_written =
1627 _write(fd, pvar->hosts_state.file_data + data_index,
1628 length);
1629
1630 if (amount_written != length) {
1631 goto error1;
1632 }
1633 }
1634 data_index = pvar->hosts_state.file_data_index;
1635 } while (1); // ������������
1636
1637 error1:
1638 close_result = _close(fd);
1639 if (amount_written != length || close_result == -1) {
1640 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1641 "An error occurred while trying to write the host key.\n"
1642 "The host key could not be written.");
1643 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1644 goto error2;
1645 }
1646
1647 // �������������t�@�C���������l�[��
1648 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1649 _unlink(buf);
1650 rename(filename, buf);
1651
1652 error2:
1653 _unlink(filename);
1654
1655 finish_read_host_files(pvar, 0);
1656
1657 // ���������������������������B
1658 key_freed = key_new(KEY_UNSPEC);
1659 memcpy(key_freed, &key, sizeof(Key));
1660 key_free(key_freed);
1661 }
1662 }
1663
1664
1665 void HOSTS_delete_all_hostkeys(PTInstVar pvar)
1666 {
1667 char FAR *name = pvar->hosts_state.file_names[0];
1668 char *hostname;
1669 unsigned short tcpport;
1670
1671 hostname = pvar->ssh_state.hostname;
1672 tcpport = pvar->ssh_state.tcpport;
1673
1674 if (name == NULL || name[0] == 0) {
1675 UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1676 "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1677 "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1678 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1679 }
1680 else {
1681 Key key; // ���������z�X�g���L�[
1682 Key *key_freed;
1683 int length;
1684 char filename[MAX_PATH];
1685 char tmp[L_tmpnam];
1686 int fd;
1687 int amount_written = 0;
1688 int close_result;
1689 int data_index = 0;
1690 char buf[FILENAME_MAX];
1691
1692 // �������������t�@�C�����J��
1693 _getcwd(filename, sizeof(filename));
1694 tmpnam_s(tmp, sizeof(tmp));
1695 strcat_s(filename, sizeof(filename), tmp);
1696 fd = _open(filename,
1697 _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1698 _S_IREAD | _S_IWRITE);
1699
1700 if (fd == -1) {
1701 if (errno == EACCES) {
1702 UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1703 "An error occurred while trying to write the host key.\n"
1704 "You do not have permission to write to the known-hosts file.");
1705 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1706 }
1707 else {
1708 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1709 "An error occurred while trying to write the host key.\n"
1710 "The host key could not be written.");
1711 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1712 }
1713 return;
1714 }
1715
1716 // ���������T�[�o���L�[����������
1717 key_copy(&key, &(pvar->hosts_state.hostkey));
1718
1719 // �t�@�C��������������
1720 begin_read_host_files(pvar, 0);
1721 do {
1722 int host_index = 0;
1723 int matched = 0;
1724 int keybits = 0;
1725 char FAR *data;
1726 int do_write = 0;
1727 length = amount_written = 0;
1728
1729 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1)) {
1730 break;
1731 }
1732
1733 if (data_index == pvar->hosts_state.file_data_index) {
1734 // index ���i������ == ��������������
1735 break;
1736 }
1737
1738 data = pvar->hosts_state.file_data + data_index;
1739 host_index = eat_spaces(data);
1740
1741 if (data[host_index] == '#') {
1742 do_write = 1;
1743 }
1744 else {
1745 // �z�X�g������
1746 host_index--;
1747 do {
1748 int negated;
1749 int bracketed;
1750 char *end_bracket;
1751 int host_matched = 0;
1752 unsigned short keyfile_port = 22;
1753
1754 host_index++;
1755 negated = data[host_index] == '!';
1756
1757 if (negated) {
1758 host_index++;
1759 bracketed = data[host_index] == '[';
1760 if (bracketed) {
1761 end_bracket = strstr(data + host_index + 1, "]:");
1762 if (end_bracket != NULL) {
1763 *end_bracket = ' ';
1764 host_index++;
1765 }
1766 }
1767 host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1768 if (bracketed && end_bracket != NULL) {
1769 *end_bracket = ']';
1770 keyfile_port = atoi(end_bracket + 2);
1771 }
1772 if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1773 matched = 0;
1774 // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1775 host_index--;
1776 do {
1777 host_index++;
1778 host_index += eat_to_end_of_pattern(data + host_index);
1779 } while (data[host_index] == ',');
1780 break;
1781 }
1782 }
1783 else {
1784 bracketed = data[host_index] == '[';
1785 if (bracketed) {
1786 end_bracket = strstr(data + host_index + 1, "]:");
1787 if (end_bracket != NULL) {
1788 *end_bracket = ' ';
1789 host_index++;
1790 }
1791 }
1792 host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1793 if (bracketed && end_bracket != NULL) {
1794 *end_bracket = ']';
1795 keyfile_port = atoi(end_bracket + 2);
1796 }
1797 if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1798 matched = 1;
1799 }
1800 }
1801 host_index += eat_to_end_of_pattern(data + host_index);
1802 } while (data[host_index] == ',');
1803
1804 // �z�X�g������������
1805 if (!matched) {
1806 do_write = 1;
1807 }
1808 // �z�X�g��������
1809 else {
1810 // ���������������������B
1811
1812 }
1813 }
1814
1815 // ������������
1816 if (do_write) {
1817 length = pvar->hosts_state.file_data_index - data_index;
1818 amount_written =
1819 _write(fd, pvar->hosts_state.file_data + data_index,
1820 length);
1821
1822 if (amount_written != length) {
1823 goto error1;
1824 }
1825 }
1826 data_index = pvar->hosts_state.file_data_index;
1827 } while (1); // ������������
1828
1829 error1:
1830 close_result = _close(fd);
1831 if (amount_written != length || close_result == -1) {
1832 UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1833 "An error occurred while trying to write the host key.\n"
1834 "The host key could not be written.");
1835 notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1836 goto error2;
1837 }
1838
1839 // �������������t�@�C���������l�[��
1840 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1841 _unlink(buf);
1842 rename(filename, buf);
1843
1844 error2:
1845 _unlink(filename);
1846
1847 finish_read_host_files(pvar, 0);
1848
1849 // ���������������������������B
1850 key_freed = key_new(KEY_UNSPEC);
1851 memcpy(key_freed, &key, sizeof(Key));
1852 key_free(key_freed);
1853 }
1854 }
1855
1856
1857 //
1858 // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1859 // ���[�U���m�F�������B
1860 // TODO: finger print���\�����s���B
1861 // (2006.3.25 yutaka)
1862 //
1863 static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1864 LPARAM lParam)
1865 {
1866 PTInstVar pvar;
1867 LOGFONT logfont;
1868 HFONT font;
1869 char uimsg[MAX_UIMSG];
1870
1871 switch (msg) {
1872 case WM_INITDIALOG:
1873 pvar = (PTInstVar) lParam;
1874 pvar->hosts_state.hosts_dialog = dlg;
1875 SetWindowLong(dlg, DWL_USER, lParam);
1876
1877 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1878 GetWindowText(dlg, uimsg, sizeof(uimsg));
1879 UTIL_get_lang_msg("DLG_UNKNONWHOST_TITLE", pvar, uimsg);
1880 SetWindowText(dlg, pvar->ts->UIMsg);
1881 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1882 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING", pvar, uimsg);
1883 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1884 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1885 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING2", pvar, uimsg);
1886 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1887 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1888 UTIL_get_lang_msg("DLG_UNKNOWNHOST_FINGERPRINT", pvar, uimsg);
1889 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1890 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
1891 UTIL_get_lang_msg("DLG_UNKNOWNHOST_FP_HASH_ALGORITHM", pvar, uimsg);
1892 SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
1893 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1894 UTIL_get_lang_msg("DLG_UNKNOWNHOST_ADD", pvar, uimsg);
1895 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1896 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1897 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1898 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1899 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1900 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1901 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1902
1903 switch (pvar->dns_key_check) {
1904 case DNS_VERIFY_NOTFOUND:
1905 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1906 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1907 break;
1908 case DNS_VERIFY_MATCH:
1909 case DNS_VERIFY_AUTH_MATCH:
1910 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1911 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1912 break;
1913 case DNS_VERIFY_MISMATCH:
1914 case DNS_VERIFY_AUTH_MISMATCH:
1915 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1916 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1917 break;
1918 case DNS_VERIFY_DIFFERENTTYPE:
1919 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1920 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1921 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1922 break;
1923 }
1924
1925 switch (pvar->dns_key_check) {
1926 case DNS_VERIFY_MATCH:
1927 case DNS_VERIFY_MISMATCH:
1928 case DNS_VERIFY_DIFFERENTTYPE:
1929 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1930 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1931 break;
1932 case DNS_VERIFY_AUTH_MATCH:
1933 case DNS_VERIFY_AUTH_MISMATCH:
1934 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1935 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1936 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1937 break;
1938 }
1939
1940 init_hosts_dlg(pvar, dlg);
1941
1942 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1943 GetObject(font, sizeof(LOGFONT), &logfont);
1944 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1945 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1946 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1947 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1948 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1949 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1950 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1951 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1952 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1953 SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1954 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1955 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1956 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1957 }
1958 else {
1959 DlgHostsAddFont = NULL;
1960 }
1961
1962 // add host check box���`�F�b�N���f�t�H���g������������
1963 SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1964
1965 return TRUE; /* because we do not set the focus */
1966
1967 case WM_COMMAND:
1968 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1969
1970 switch (LOWORD(wParam)) {
1971 case IDC_CONTINUE:
1972 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1973 if (!pvar->cv->Ready) {
1974 goto canceled;
1975 }
1976
1977 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1978 add_host_key(pvar);
1979 }
1980
1981 if (SSHv1(pvar)) {
1982 SSH_notify_host_OK(pvar);
1983 } else { // SSH2
1984 // SSH2���������� SSH_notify_host_OK() �������B
1985 }
1986
1987 pvar->hosts_state.hosts_dialog = NULL;
1988
1989 EndDialog(dlg, 1);
1990
1991 if (DlgHostsAddFont != NULL) {
1992 DeleteObject(DlgHostsAddFont);
1993 }
1994
1995 return TRUE;
1996
1997 case IDCANCEL: /* kill the connection */
1998 canceled:
1999 pvar->hosts_state.hosts_dialog = NULL;
2000 notify_closed_connection(pvar, "authentication cancelled");
2001 EndDialog(dlg, 0);
2002
2003 if (DlgHostsAddFont != NULL) {
2004 DeleteObject(DlgHostsAddFont);
2005 }
2006
2007 return TRUE;
2008
2009 case IDC_FP_HASH_ALG_MD5:
2010 hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2011 return TRUE;
2012
2013 case IDC_FP_HASH_ALG_SHA256:
2014 hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2015 return TRUE;
2016
2017 default:
2018 return FALSE;
2019 }
2020
2021 default:
2022 return FALSE;
2023 }
2024 }
2025
2026 //
2027 // �u�����������m�F�_�C�A���O������
2028 //
2029 static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
2030 LPARAM lParam)
2031 {
2032 PTInstVar pvar;
2033 LOGFONT logfont;
2034 HFONT font;
2035 char uimsg[MAX_UIMSG];
2036
2037 switch (msg) {
2038 case WM_INITDIALOG:
2039 pvar = (PTInstVar) lParam;
2040 pvar->hosts_state.hosts_dialog = dlg;
2041 SetWindowLong(dlg, DWL_USER, lParam);
2042
2043 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
2044 GetWindowText(dlg, uimsg, sizeof(uimsg));
2045 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
2046 SetWindowText(dlg, pvar->ts->UIMsg);
2047 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
2048 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
2049 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
2050 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
2051 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
2052 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
2053 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
2054 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
2055 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
2056 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2057 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FP_HASH_ALGORITHM", pvar, uimsg);
2058 SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2059 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
2060 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
2061 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
2062 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
2063 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
2064 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
2065 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2066 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
2067 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2068
2069 switch (pvar->dns_key_check) {
2070 case DNS_VERIFY_NOTFOUND:
2071 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
2072 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2073 break;
2074 case DNS_VERIFY_MATCH:
2075 case DNS_VERIFY_AUTH_MATCH:
2076 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
2077 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2078 break;
2079 case DNS_VERIFY_MISMATCH:
2080 case DNS_VERIFY_AUTH_MISMATCH:
2081 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
2082 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2083 break;
2084 case DNS_VERIFY_DIFFERENTTYPE:
2085 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2086 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
2087 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2088 break;
2089 }
2090
2091 switch (pvar->dns_key_check) {
2092 case DNS_VERIFY_MATCH:
2093 case DNS_VERIFY_MISMATCH:
2094 case DNS_VERIFY_DIFFERENTTYPE:
2095 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
2096 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2097 break;
2098 case DNS_VERIFY_AUTH_MATCH:
2099 case DNS_VERIFY_AUTH_MISMATCH:
2100 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2101 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
2102 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2103 break;
2104 }
2105
2106 init_hosts_dlg(pvar, dlg);
2107
2108 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2109 GetObject(font, sizeof(LOGFONT), &logfont);
2110 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
2111 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2112 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2113 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2114 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2115 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2116 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2117 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2118 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2119 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
2120 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2121 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
2122 }
2123 else {
2124 DlgHostsReplaceFont = NULL;
2125 }
2126
2127 // �f�t�H���g���`�F�b�N����������
2128 return TRUE; /* because we do not set the focus */
2129
2130 case WM_COMMAND:
2131 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
2132
2133 switch (LOWORD(wParam)) {
2134 case IDC_CONTINUE:
2135 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
2136 if (!pvar->cv->Ready) {
2137 goto canceled;
2138 }
2139
2140 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
2141 add_host_key(pvar);
2142 delete_different_key(pvar);
2143 }
2144
2145 if (SSHv1(pvar)) {
2146 SSH_notify_host_OK(pvar);
2147 } else { // SSH2
2148 // SSH2���������� SSH_notify_host_OK() �������B
2149 }
2150
2151 pvar->hosts_state.hosts_dialog = NULL;
2152
2153 EndDialog(dlg, 1);
2154
2155 if (DlgHostsReplaceFont != NULL) {
2156 DeleteObject(DlgHostsReplaceFont);
2157 }
2158
2159 return TRUE;
2160
2161 case IDCANCEL: /* kill the connection */
2162 canceled:
2163 pvar->hosts_state.hosts_dialog = NULL;
2164 notify_closed_connection(pvar, "authentication cancelled");
2165 EndDialog(dlg, 0);
2166
2167 if (DlgHostsReplaceFont != NULL) {
2168 DeleteObject(DlgHostsReplaceFont);
2169 }
2170
2171 return TRUE;
2172
2173 case IDC_FP_HASH_ALG_MD5:
2174 hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2175 return TRUE;
2176
2177 case IDC_FP_HASH_ALG_SHA256:
2178 hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2179 return TRUE;
2180
2181 default:
2182 return FALSE;
2183 }
2184
2185 default:
2186 return FALSE;
2187 }
2188 }
2189
2190 //
2191 // �����z�X�g�����`�����������������m�F�_�C�A���O������
2192 //
2193 static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
2194 LPARAM lParam)
2195 {
2196 PTInstVar pvar;
2197 LOGFONT logfont;
2198 HFONT font;
2199 char uimsg[MAX_UIMSG];
2200
2201 switch (msg) {
2202 case WM_INITDIALOG:
2203 pvar = (PTInstVar) lParam;
2204 pvar->hosts_state.hosts_dialog = dlg;
2205 SetWindowLong(dlg, DWL_USER, lParam);
2206
2207 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
2208 GetWindowText(dlg, uimsg, sizeof(uimsg));
2209 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
2210 SetWindowText(dlg, pvar->ts->UIMsg);
2211 GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
2212 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
2213 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
2214 GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
2215 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
2216 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
2217 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
2218 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
2219 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
2220 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2221 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FP_HASH_ALGORITHM", pvar, uimsg);
2222 SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2223 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
2224 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
2225 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
2226 GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
2227 UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
2228 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
2229 GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2230 UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
2231 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2232
2233 switch (pvar->dns_key_check) {
2234 case DNS_VERIFY_NOTFOUND:
2235 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
2236 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2237 break;
2238 case DNS_VERIFY_MATCH:
2239 case DNS_VERIFY_AUTH_MATCH:
2240 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
2241 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2242 break;
2243 case DNS_VERIFY_MISMATCH:
2244 case DNS_VERIFY_AUTH_MISMATCH:
2245 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
2246 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2247 break;
2248 case DNS_VERIFY_DIFFERENTTYPE:
2249 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2250 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
2251 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2252 break;
2253 }
2254
2255 switch (pvar->dns_key_check) {
2256 case DNS_VERIFY_MATCH:
2257 case DNS_VERIFY_MISMATCH:
2258 case DNS_VERIFY_DIFFERENTTYPE:
2259 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
2260 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2261 break;
2262 case DNS_VERIFY_AUTH_MATCH:
2263 case DNS_VERIFY_AUTH_MISMATCH:
2264 case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2265 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
2266 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2267 break;
2268 }
2269
2270 init_hosts_dlg(pvar, dlg);
2271
2272 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2273 GetObject(font, sizeof(LOGFONT), &logfont);
2274 if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
2275 SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2276 SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2277 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2278 SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2279 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2280 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2281 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2282 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2283 SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2284 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2285 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2286 SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2287 }
2288 else {
2289 DlgHostsAddFont = NULL;
2290 }
2291
2292 // add host check box ���f�t�H���g�� off ������
2293 // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
2294
2295 return TRUE; /* because we do not set the focus */
2296
2297 case WM_COMMAND:
2298 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
2299
2300 switch (LOWORD(wParam)) {
2301 case IDC_CONTINUE:
2302 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
2303 if (!pvar->cv->Ready) {
2304 goto canceled;
2305 }
2306
2307 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
2308 add_host_key(pvar);
2309 }
2310
2311 if (SSHv1(pvar)) {
2312 SSH_notify_host_OK(pvar);
2313 } else { // SSH2
2314 // SSH2���������� SSH_notify_host_OK() �������B
2315 }
2316
2317 pvar->hosts_state.hosts_dialog = NULL;
2318
2319 EndDialog(dlg, 1);
2320
2321 if (DlgHostsAddFont != NULL) {
2322 DeleteObject(DlgHostsAddFont);
2323 }
2324
2325 return TRUE;
2326
2327 case IDCANCEL: /* kill the connection */
2328 canceled:
2329 pvar->hosts_state.hosts_dialog = NULL;
2330 notify_closed_connection(pvar, "authentication cancelled");
2331 EndDialog(dlg, 0);
2332
2333 if (DlgHostsAddFont != NULL) {
2334 DeleteObject(DlgHostsAddFont);
2335 }
2336
2337 return TRUE;
2338
2339 case IDC_FP_HASH_ALG_MD5:
2340 hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2341 return TRUE;
2342
2343 case IDC_FP_HASH_ALG_SHA256:
2344 hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2345 return TRUE;
2346
2347 default:
2348 return FALSE;
2349 }
2350
2351 default:
2352 return FALSE;
2353 }
2354 }
2355
2356 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
2357 {
2358 if (pvar->hosts_state.hosts_dialog == NULL) {
2359 HWND cur_active = GetActiveWindow();
2360
2361 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
2362 cur_active != NULL ? cur_active : wnd,
2363 hosts_add_dlg_proc, (LPARAM) pvar);
2364 }
2365 }
2366
2367 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
2368 {
2369 if (pvar->hosts_state.hosts_dialog == NULL) {
2370 HWND cur_active = GetActiveWindow();
2371
2372 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
2373 cur_active != NULL ? cur_active : wnd,
2374 hosts_replace_dlg_proc, (LPARAM) pvar);
2375 }
2376 }
2377
2378 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
2379 {
2380 if (pvar->hosts_state.hosts_dialog == NULL) {
2381 HWND cur_active = GetActiveWindow();
2382
2383 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
2384 cur_active != NULL ? cur_active : wnd,
2385 hosts_add2_dlg_proc, (LPARAM) pvar);
2386 }
2387 }
2388
2389 //
2390 // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
2391 //
2392 // SSH2���������� (2006.3.24 yutaka)
2393 //
2394 BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key)
2395 {
2396 int found_different_key = 0, found_different_type_key = 0;
2397
2398 pvar->dns_key_check = DNS_VERIFY_NONE;
2399
2400 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
2401 if (pvar->hosts_state.prefetched_hostname != NULL
2402 && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
2403 && match_key(pvar, key) == 1) {
2404
2405 if (SSHv1(pvar)) {
2406 SSH_notify_host_OK(pvar);
2407 } else {
2408 // SSH2���������� SSH_notify_host_OK() �������B
2409 }
2410 return TRUE;
2411 }
2412
2413 // �������������������������A�������_���t�@�C��������������
2414 if (begin_read_host_files(pvar, 0)) {
2415 do {
2416 if (!read_host_key(pvar, hostname, tcpport, 0, 0)) {
2417 break;
2418 }
2419
2420 if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
2421 int match = match_key(pvar, key);
2422 if (match == 1) {
2423 finish_read_host_files(pvar, 0);
2424 // ���������G���g�����Q�������A���v�����L�[�������������������B
2425 // SSH2���������������������������B(2006.3.29 yutaka)
2426 if (SSHv1(pvar)) {
2427 SSH_notify_host_OK(pvar);
2428 } else {
2429 // SSH2���������� SSH_notify_host_OK() �������B
2430 }
2431 return TRUE;
2432 }
2433 else if (match == 0) {
2434 // �L�[�� known_hosts ���������������A�L�[�����e���������B
2435 found_different_key = 1;
2436 }
2437 else {
2438 // �L�[���`������������
2439 found_different_type_key = 1;
2440 }
2441 }
2442 } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // �L�[�����������������������[�v����
2443
2444 finish_read_host_files(pvar, 0);
2445 }
2446
2447 // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
2448 key_copy(&(pvar->hosts_state.hostkey), key);
2449
2450 free(pvar->hosts_state.prefetched_hostname);
2451 pvar->hosts_state.prefetched_hostname = _strdup(hostname);
2452
2453 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
2454 if (pvar->nocheck_known_hosts == TRUE) {
2455 return TRUE;
2456 }
2457
2458 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
2459 pvar->dns_key_check = verify_hostkey_dns(pvar, hostname, key);
2460 }
2461
2462 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
2463 // �������K�v�����������A�����R�[�������X�����B
2464 // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
2465 // (2007.10.1 yutaka)
2466 if (found_different_key) {
2467 HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar);
2468 }
2469 else if (found_different_type_key) {
2470 HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar);
2471 }
2472 else {
2473 HOSTS_do_unknown_host_dialog(pvar->NotificationWindow, pvar);
2474 }
2475
2476 return TRUE;
2477 }
2478
2479 void HOSTS_notify_disconnecting(PTInstVar pvar)
2480 {
2481 if (pvar->hosts_state.hosts_dialog != NULL) {
2482 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
2483 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
2484 EnableWindow(pvar->NotificationWindow, TRUE);
2485 }
2486 }
2487
2488 void HOSTS_end(PTInstVar pvar)
2489 {
2490 int i;
2491
2492 free(pvar->hosts_state.prefetched_hostname);
2493 init_hostkey(&pvar->hosts_state.hostkey);
2494
2495 if (pvar->hosts_state.file_names != NULL) {
2496 for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
2497 free(pvar->hosts_state.file_names[i]);
2498 }
2499 free(pvar->hosts_state.file_names);
2500 }
2501 }

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