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 2940 - (show annotations) (download) (as text)
Thu Nov 30 09:56:43 2006 UTC (17 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/hosts.c
File MIME type: text/x-csrc
File size: 37219 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
34 #include "ttxssh.h"
35 #include "util.h"
36 #include "resource.h"
37 #include "matcher.h"
38 #include "ssh.h"
39 #include "hosts.h"
40
41 #include <openssl/bn.h>
42 #include <openssl/evp.h>
43 #include <openssl/rsa.h>
44 #include <openssl/dsa.h>
45
46 #include <fcntl.h>
47 #include <io.h>
48 #include <errno.h>
49 #include <sys/stat.h>
50
51
52 // BASE64�\���������i��������'='�����������������j
53 static char base64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
54
55
56 // �z�X�g�L�[�������� (2006.3.21 yutaka)
57 static void init_hostkey(Key *key)
58 {
59 key->type = KEY_UNSPEC;
60
61 // SSH1
62 key->bits = 0;
63 if (key->exp != NULL) {
64 free(key->exp);
65 key->exp = NULL;
66 }
67 if (key->mod != NULL) {
68 free(key->mod);
69 key->mod = NULL;
70 }
71
72 // SSH2
73 if (key->dsa != NULL) {
74 DSA_free(key->dsa);
75 key->dsa = NULL;
76 }
77 if (key->rsa != NULL) {
78 RSA_free(key->rsa);
79 key->rsa = NULL;
80 }
81 }
82
83
84 static char FAR *FAR * parse_multi_path(char FAR * buf)
85 {
86 int i;
87 int ch;
88 int num_paths = 1;
89 char FAR *FAR * result;
90 int last_path_index;
91
92 for (i = 0; (ch = buf[i]) != 0; i++) {
93 if (ch == ';') {
94 num_paths++;
95 }
96 }
97
98 result =
99 (char FAR * FAR *) malloc(sizeof(char FAR *) * (num_paths + 1));
100
101 last_path_index = 0;
102 num_paths = 0;
103 for (i = 0; (ch = buf[i]) != 0; i++) {
104 if (ch == ';') {
105 buf[i] = 0;
106 result[num_paths] = _strdup(buf + last_path_index);
107 num_paths++;
108 buf[i] = ch;
109 last_path_index = i + 1;
110 }
111 }
112 if (i > last_path_index) {
113 result[num_paths] = _strdup(buf + last_path_index);
114 num_paths++;
115 }
116 result[num_paths] = NULL;
117 return result;
118 }
119
120 void HOSTS_init(PTInstVar pvar)
121 {
122 pvar->hosts_state.prefetched_hostname = NULL;
123 #if 0
124 pvar->hosts_state.key_exp = NULL;
125 pvar->hosts_state.key_mod = NULL;
126 #else
127 init_hostkey(&pvar->hosts_state.hostkey);
128 #endif
129 pvar->hosts_state.hosts_dialog = NULL;
130 pvar->hosts_state.file_names = NULL;
131 }
132
133 void HOSTS_open(PTInstVar pvar)
134 {
135 pvar->hosts_state.file_names =
136 parse_multi_path(pvar->session_settings.KnownHostsFiles);
137 }
138
139 //
140 // known_hosts�t�@�C�������e�������� pvar->hosts_state.file_data ����������
141 //
142 static int begin_read_file(PTInstVar pvar, char FAR * name,
143 int suppress_errors)
144 {
145 int fd;
146 int length;
147 int amount_read;
148 char buf[2048];
149
150 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
151 fd = _open(buf, _O_RDONLY | _O_SEQUENTIAL | _O_BINARY);
152 if (fd == -1) {
153 if (!suppress_errors) {
154 if (errno == ENOENT) {
155 #ifdef I18N
156 #else
157 notify_nonfatal_error(pvar,
158 "An error occurred while trying to read a known_hosts file.\n"
159 "The specified filename does not exist.");
160 #endif
161 } else {
162 #ifdef I18N
163 #else
164 notify_nonfatal_error(pvar,
165 "An error occurred while trying to read a known_hosts file.");
166 #endif
167 }
168 }
169 return 0;
170 }
171
172 length = (int) _lseek(fd, 0, SEEK_END);
173 _lseek(fd, 0, SEEK_SET);
174
175 if (length >= 0 && length < 0x7FFFFFFF) {
176 pvar->hosts_state.file_data = malloc(length + 1);
177 if (pvar->hosts_state.file_data == NULL) {
178 if (!suppress_errors) {
179 #ifdef I18N
180 #else
181 notify_nonfatal_error(pvar,
182 "Memory ran out while trying to allocate space to read a known_hosts file.");
183 #endif
184 }
185 _close(fd);
186 return 0;
187 }
188 } else {
189 if (!suppress_errors) {
190 #ifdef I18N
191 #else
192 notify_nonfatal_error(pvar,
193 "An error occurred while trying to read a known_hosts file.");
194 #endif
195 }
196 _close(fd);
197 return 0;
198 }
199
200 amount_read = _read(fd, pvar->hosts_state.file_data, length);
201 pvar->hosts_state.file_data[length] = 0;
202
203 _close(fd);
204
205 if (amount_read != length) {
206 if (!suppress_errors) {
207 #ifdef I18N
208 #else
209 notify_nonfatal_error(pvar,
210 "An error occurred while trying to read a known_hosts file.");
211 #endif
212 }
213 free(pvar->hosts_state.file_data);
214 pvar->hosts_state.file_data = NULL;
215 return 0;
216 } else {
217 return 1;
218 }
219 }
220
221 static int end_read_file(PTInstVar pvar, int suppress_errors)
222 {
223 free(pvar->hosts_state.file_data);
224 pvar->hosts_state.file_data = NULL;
225 return 1;
226 }
227
228 static int begin_read_host_files(PTInstVar pvar, int suppress_errors)
229 {
230 pvar->hosts_state.file_num = 0;
231 pvar->hosts_state.file_data = NULL;
232 return 1;
233 }
234
235 // MIME64�����������X�L�b�v����
236 static int eat_base64(char FAR * data)
237 {
238 int index = 0;
239 int ch;
240
241 for (;;) {
242 ch = data[index];
243 if (ch == '=' || strchr(base64, ch)) {
244 // BASE64���\�������������������� index ���i����
245 index++;
246 } else {
247 break;
248 }
249 }
250
251 return index;
252 }
253
254 static int eat_spaces(char FAR * data)
255 {
256 int index = 0;
257 int ch;
258
259 while ((ch = data[index]) == ' ' || ch == '\t') {
260 index++;
261 }
262 return index;
263 }
264
265 static int eat_digits(char FAR * data)
266 {
267 int index = 0;
268 int ch;
269
270 while ((ch = data[index]) >= '0' && ch <= '9') {
271 index++;
272 }
273 return index;
274 }
275
276 static int eat_to_end_of_line(char FAR * data)
277 {
278 int index = 0;
279 int ch;
280
281 while ((ch = data[index]) != '\n' && ch != '\r' && ch != 0) {
282 index++;
283 }
284
285 while ((ch = data[index]) == '\n' || ch == '\r') {
286 index++;
287 }
288
289 return index;
290 }
291
292 static int eat_to_end_of_pattern(char FAR * data)
293 {
294 int index = 0;
295 int ch;
296
297 while (ch = data[index], is_pattern_char(ch)) {
298 index++;
299 }
300
301 return index;
302 }
303
304 //
305 // BASE64�f�R�[�h�������s���B(rfc1521)
306 // src�o�b�t�@�� null-terminate ���������K�v�����B
307 //
308 static int uudecode(unsigned char *src, int srclen, unsigned char *target, int targsize)
309 {
310 char pad = '=';
311 int tarindex, state, ch;
312 char *pos;
313
314 state = 0;
315 tarindex = 0;
316
317 while ((ch = *src++) != '\0') {
318 if (isspace(ch)) /* Skip whitespace anywhere. */
319 continue;
320
321 if (ch == pad)
322 break;
323
324 pos = strchr(base64, ch);
325 if (pos == 0) /* A non-base64 character. */
326 return (-1);
327
328 switch (state) {
329 case 0:
330 if (target) {
331 if (tarindex >= targsize)
332 return (-1);
333 target[tarindex] = (pos - base64) << 2;
334 }
335 state = 1;
336 break;
337 case 1:
338 if (target) {
339 if (tarindex + 1 >= targsize)
340 return (-1);
341 target[tarindex] |= (pos - base64) >> 4;
342 target[tarindex+1] = ((pos - base64) & 0x0f) << 4 ;
343 }
344 tarindex++;
345 state = 2;
346 break;
347 case 2:
348 if (target) {
349 if (tarindex + 1 >= targsize)
350 return (-1);
351 target[tarindex] |= (pos - base64) >> 2;
352 target[tarindex+1] = ((pos - base64) & 0x03) << 6;
353 }
354 tarindex++;
355 state = 3;
356 break;
357 case 3:
358 if (target) {
359 if (tarindex >= targsize)
360 return (-1);
361 target[tarindex] |= (pos - base64);
362 }
363 tarindex++;
364 state = 0;
365 break;
366 }
367 }
368
369 /*
370 * We are done decoding Base-64 chars. Let's see if we ended
371 * on a byte boundary, and/or with erroneous trailing characters.
372 */
373
374 if (ch == pad) { /* We got a pad char. */
375 ch = *src++; /* Skip it, get next. */
376 switch (state) {
377 case 0: /* Invalid = in first position */
378 case 1: /* Invalid = in second position */
379 return (-1);
380
381 case 2: /* Valid, means one byte of info */
382 /* Skip any number of spaces. */
383 for (; ch != '\0'; ch = *src++)
384 if (!isspace(ch))
385 break;
386 /* Make sure there is another trailing = sign. */
387 if (ch != pad)
388 return (-1);
389 ch = *src++; /* Skip the = */
390 /* Fall through to "single trailing =" case. */
391 /* FALLTHROUGH */
392
393 case 3: /* Valid, means two bytes of info */
394 /*
395 * We know this char is an =. Is there anything but
396 * whitespace after it?
397 */
398 for (; ch != '\0'; ch = *src++)
399 if (!isspace(ch))
400 return (-1);
401
402 /*
403 * Now make sure for cases 2 and 3 that the "extra"
404 * bits that slopped past the last full byte were
405 * zeros. If we don't check them, they become a
406 * subliminal channel.
407 */
408 if (target && target[tarindex] != 0)
409 return (-1);
410 }
411 } else {
412 /*
413 * We ended by seeing the end of the string. Make sure we
414 * have no partial bytes lying around.
415 */
416 if (state != 0)
417 return (-1);
418 }
419
420 return (tarindex);
421 }
422
423
424 // SSH2���� BASE64 �`�����i�[����������
425 static Key *parse_uudecode(char *data)
426 {
427 int count;
428 unsigned char *blob = NULL;
429 int len, n;
430 Key *key = NULL;
431 char ch;
432
433 // BASE64���������T�C�Y������
434 count = eat_base64(data);
435 len = 2 * count;
436 blob = malloc(len);
437 if (blob == NULL)
438 goto error;
439
440 // BASE64�f�R�[�h
441 ch = data[count];
442 data[count] = '\0'; // ���������s�R�[�h������������������������������������
443 n = uudecode(data, count, blob, len);
444 data[count] = ch;
445 if (n < 0) {
446 goto error;
447 }
448
449 key = key_from_blob(blob, n);
450 if (key == NULL)
451 goto error;
452
453 error:
454 if (blob != NULL)
455 free(blob);
456
457 return (key);
458 }
459
460
461 static char FAR *parse_bignum(char FAR * data)
462 {
463 uint32 digits = 0;
464 BIGNUM *num = BN_new();
465 BIGNUM *billion = BN_new();
466 BIGNUM *digits_num = BN_new();
467 BN_CTX *ctx = BN_CTX_new();
468 char FAR *result;
469 int ch;
470 int leftover_digits = 1;
471
472 BN_CTX_init(ctx);
473 BN_set_word(num, 0);
474 BN_set_word(billion, 1000000000L);
475
476 while ((ch = *data) >= '0' && ch <= '9') {
477 if (leftover_digits == 1000000000L) {
478 BN_set_word(digits_num, digits);
479 BN_mul(num, num, billion, ctx);
480 BN_add(num, num, digits_num);
481 leftover_digits = 1;
482 digits = 0;
483 }
484
485 digits = digits * 10 + ch - '0';
486 leftover_digits *= 10;
487 data++;
488 }
489
490 BN_set_word(digits_num, digits);
491 BN_set_word(billion, leftover_digits);
492 BN_mul(num, num, billion, ctx);
493 BN_add(num, num, digits_num);
494
495 result = (char FAR *) malloc(2 + BN_num_bytes(num));
496 set_ushort16_MSBfirst(result, BN_num_bits(num));
497 BN_bn2bin(num, result + 2);
498
499 BN_CTX_free(ctx);
500 BN_free(digits_num);
501 BN_free(num);
502 BN_free(billion);
503
504 return result;
505 }
506
507 //
508 // known_hosts�t�@�C�������e���������A�w�������z�X�g�����J�����T���B
509 //
510 static int check_host_key(PTInstVar pvar, char FAR * hostname,
511 char FAR * data)
512 {
513 int index = eat_spaces(data);
514 int matched = 0;
515 int keybits = 0;
516
517 if (data[index] == '#') {
518 return index + eat_to_end_of_line(data + index);
519 }
520
521 /* if we find an empty line, then it won't have any patterns matching the hostname
522 and so we skip it */
523 index--;
524 do {
525 int negated;
526
527 index++;
528 negated = data[index] == '!';
529
530 if (negated) {
531 index++;
532 if (match_pattern(data + index, hostname)) {
533 return index + eat_to_end_of_line(data + index);
534 }
535 } else if (match_pattern(data + index, hostname)) {
536 matched = 1;
537 }
538
539 index += eat_to_end_of_pattern(data + index);
540 } while (data[index] == ',');
541
542 if (!matched) {
543 return index + eat_to_end_of_line(data + index);
544 } else {
545 // ���������������t�H�[�}�b�g��������
546 // �����A���������v�����G���g�����������������������B
547 /*
548 [SSH1]
549 192.168.1.2 1024 35 13032....
550
551 [SSH2]
552 192.168.1.2 ssh-rsa AAAAB3NzaC1....
553 192.168.1.2 ssh-dss AAAAB3NzaC1....
554 192.168.1.2 rsa AAAAB3NzaC1....
555 192.168.1.2 dsa AAAAB3NzaC1....
556 192.168.1.2 rsa1 AAAAB3NzaC1....
557 */
558 int rsa1_key_bits;
559
560 index += eat_spaces(data + index);
561
562 rsa1_key_bits = atoi(data + index);
563 if (rsa1_key_bits > 0) { // RSA1������
564 if (!SSHv1(pvar)) { // SSH2��������������������
565 return index + eat_to_end_of_line(data + index);
566 }
567
568 pvar->hosts_state.hostkey.type = KEY_RSA1;
569
570 pvar->hosts_state.hostkey.bits = rsa1_key_bits;
571 index += eat_digits(data + index);
572 index += eat_spaces(data + index);
573
574 pvar->hosts_state.hostkey.exp = parse_bignum(data + index);
575 index += eat_digits(data + index);
576 index += eat_spaces(data + index);
577
578 pvar->hosts_state.hostkey.mod = parse_bignum(data + index);
579
580 /*
581 if (pvar->hosts_state.key_bits < 0
582 || pvar->hosts_state.key_exp == NULL
583 || pvar->hosts_state.key_mod == NULL) {
584 pvar->hosts_state.key_bits = 0;
585 free(pvar->hosts_state.key_exp);
586 free(pvar->hosts_state.key_mod);
587 }*/
588
589 } else {
590 char *cp, *p;
591 Key *key;
592
593 if (!SSHv2(pvar)) { // SSH1��������������������
594 return index + eat_to_end_of_line(data + index);
595 }
596
597 cp = data + index;
598 p = strchr(cp, ' ');
599 if (p == NULL) {
600 return index + eat_to_end_of_line(data + index);
601 }
602 index += (p - cp); // setup index
603 *p = '\0';
604 pvar->hosts_state.hostkey.type = get_keytype_from_name(cp);
605 *p = ' ';
606
607 index += eat_spaces(data + index); // update index
608
609 // uudecode
610 key = parse_uudecode(data + index);
611 if (key == NULL) {
612 return index + eat_to_end_of_line(data + index);
613 }
614
615 // setup
616 pvar->hosts_state.hostkey.type = key->type;
617 pvar->hosts_state.hostkey.dsa = key->dsa;
618 pvar->hosts_state.hostkey.rsa = key->rsa;
619
620 index += eat_base64(data + index);
621 index += eat_spaces(data + index);
622 }
623
624 return index + eat_to_end_of_line(data + index);
625 }
626 }
627
628 //
629 // known_hosts�t�@�C�������z�X�g�������v�����s������
630 //
631 static int read_host_key(PTInstVar pvar, char FAR * hostname,
632 int suppress_errors, int return_always)
633 {
634 int i;
635 int while_flg;
636
637 for (i = 0; hostname[i] != 0; i++) {
638 int ch = hostname[i];
639
640 if (!is_pattern_char(ch) || ch == '*' || ch == '?') {
641 if (!suppress_errors) {
642 #ifdef I18N
643 #else
644 notify_fatal_error(pvar,
645 "The host name contains an invalid character.\n"
646 "This session will be terminated.");
647 #endif
648 }
649 return 0;
650 }
651 }
652
653 if (i == 0) {
654 if (!suppress_errors) {
655 #ifdef I18N
656 #else
657 notify_fatal_error(pvar, "The host name should not be empty.\n"
658 "This session will be terminated.");
659 #endif
660 }
661 return 0;
662 }
663
664 #if 0
665 pvar->hosts_state.key_bits = 0;
666 free(pvar->hosts_state.key_exp);
667 pvar->hosts_state.key_exp = NULL;
668 free(pvar->hosts_state.key_mod);
669 pvar->hosts_state.key_mod = NULL;
670 #else
671 // hostkey type is KEY_UNSPEC.
672 init_hostkey(&pvar->hosts_state.hostkey);
673 #endif
674
675 do {
676 if (pvar->hosts_state.file_data == NULL
677 || pvar->hosts_state.file_data[pvar->hosts_state.
678 file_data_index] == 0) {
679 char FAR *filename;
680 int keep_going = 1;
681
682 if (pvar->hosts_state.file_data != NULL) {
683 end_read_file(pvar, suppress_errors);
684 }
685
686 do {
687 filename =
688 pvar->hosts_state.file_names[pvar->hosts_state.
689 file_num];
690
691 if (filename == NULL) {
692 return 1;
693 } else {
694 pvar->hosts_state.file_num++;
695
696 if (filename[0] != 0) {
697 if (begin_read_file
698 (pvar, filename, suppress_errors)) {
699 pvar->hosts_state.file_data_index = 0;
700 keep_going = 0;
701 }
702 }
703 }
704 } while (keep_going);
705 }
706
707 pvar->hosts_state.file_data_index +=
708 check_host_key(pvar, hostname,
709 pvar->hosts_state.file_data +
710 pvar->hosts_state.file_data_index);
711
712 if (!return_always) {
713 // �L�����L�[��������������
714 while_flg = (pvar->hosts_state.hostkey.type == KEY_UNSPEC);
715 }
716 else {
717 while_flg = 0;
718 }
719 } while (while_flg);
720
721 return 1;
722 }
723
724 static void finish_read_host_files(PTInstVar pvar, int suppress_errors)
725 {
726 if (pvar->hosts_state.file_data != NULL) {
727 end_read_file(pvar, suppress_errors);
728 }
729 }
730
731 // �T�[�o�����������O���Aknown_hosts�t�@�C�������z�X�g���J�������������������B
732 void HOSTS_prefetch_host_key(PTInstVar pvar, char FAR * hostname)
733 {
734 if (!begin_read_host_files(pvar, 1)) {
735 return;
736 }
737
738 if (!read_host_key(pvar, hostname, 1, 0)) {
739 return;
740 }
741
742 free(pvar->hosts_state.prefetched_hostname);
743 pvar->hosts_state.prefetched_hostname = _strdup(hostname);
744
745 finish_read_host_files(pvar, 1);
746 }
747
748 static BOOL equal_mp_ints(unsigned char FAR * num1,
749 unsigned char FAR * num2)
750 {
751 if (num1 == NULL || num2 == NULL) {
752 return FALSE;
753 } else {
754 uint32 bytes = (get_ushort16_MSBfirst(num1) + 7) / 8;
755
756 if (bytes != (get_ushort16_MSBfirst(num2) + 7) / 8) {
757 return FALSE; /* different byte lengths */
758 } else {
759 return memcmp(num1 + 2, num2 + 2, bytes) == 0;
760 }
761 }
762 }
763
764 // ���J����������������������
765 static BOOL match_key(PTInstVar pvar, Key *key)
766 {
767 int bits;
768 unsigned char FAR * exp;
769 unsigned char FAR * mod;
770
771 if (key->type == KEY_RSA1) { // SSH1 host public key
772 bits = key->bits;
773 exp = key->exp;
774 mod = key->mod;
775
776 /* just check for equal exponent and modulus */
777 return equal_mp_ints(exp, pvar->hosts_state.hostkey.exp)
778 && equal_mp_ints(mod, pvar->hosts_state.hostkey.mod);
779 /*
780 return equal_mp_ints(exp, pvar->hosts_state.key_exp)
781 && equal_mp_ints(mod, pvar->hosts_state.key_mod);
782 */
783
784 } else if (key->type == KEY_RSA) { // SSH2 RSA host public key
785
786 return key->rsa != NULL && pvar->hosts_state.hostkey.rsa != NULL &&
787 BN_cmp(key->rsa->e, pvar->hosts_state.hostkey.rsa->e) == 0 &&
788 BN_cmp(key->rsa->n, pvar->hosts_state.hostkey.rsa->n) == 0;
789
790 } else { // // SSH2 DSA host public key
791
792 return key->dsa != NULL && pvar->hosts_state.hostkey.dsa &&
793 BN_cmp(key->dsa->p, pvar->hosts_state.hostkey.dsa->p) == 0 &&
794 BN_cmp(key->dsa->q, pvar->hosts_state.hostkey.dsa->q) == 0 &&
795 BN_cmp(key->dsa->g, pvar->hosts_state.hostkey.dsa->g) == 0 &&
796 BN_cmp(key->dsa->pub_key, pvar->hosts_state.hostkey.dsa->pub_key) == 0;
797
798 }
799
800 }
801
802 static void init_hosts_dlg(PTInstVar pvar, HWND dlg)
803 {
804 char buf[1024];
805 char buf2[2048];
806 int i, j;
807 int ch;
808 char *fp;
809
810 // static text�� # �������z�X�g�����u������
811 GetDlgItemText(dlg, IDC_HOSTWARNING, buf, sizeof(buf));
812 for (i = 0; (ch = buf[i]) != 0 && ch != '#'; i++) {
813 buf2[i] = ch;
814 }
815 if (sizeof(buf2) - i - 1 > 0) {
816 strncpy(buf2 + i, pvar->hosts_state.prefetched_hostname,
817 sizeof(buf2) - i - 1);
818 }
819 j = i + strlen(buf2 + i);
820 for (; buf[i] == '#'; i++) {
821 }
822 if (sizeof(buf2) - j - 1 > 0) {
823 strncpy(buf2 + j, buf + i, sizeof(buf2) - j - 1);
824 }
825 buf2[sizeof(buf2) - 1] = 0;
826
827 SetDlgItemText(dlg, IDC_HOSTWARNING, buf2);
828
829 // fingerprint����������
830 fp = key_fingerprint(&pvar->hosts_state.hostkey);
831 SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
832 }
833
834 static int print_mp_int(char FAR * buf, unsigned char FAR * mp)
835 {
836 int i = 0, j, k;
837 BIGNUM *num = BN_new();
838 int ch;
839
840 BN_bin2bn(mp + 2, (get_ushort16_MSBfirst(mp) + 7) / 8, num);
841
842 do {
843 buf[i] = (char) ((BN_div_word(num, 10)) + '0');
844 i++;
845 } while (!BN_is_zero(num));
846
847 /* we need to reverse the digits */
848 for (j = 0, k = i - 1; j < k; j++, k--) {
849 ch = buf[j];
850 buf[j] = buf[k];
851 buf[k] = ch;
852 }
853
854 buf[i] = 0;
855 return i;
856 }
857
858 //
859 // known_hosts �t�@�C�������������G���g�������������B
860 //
861 static char FAR *format_host_key(PTInstVar pvar)
862 {
863 int host_len = strlen(pvar->hosts_state.prefetched_hostname);
864 char *result = NULL;
865 int index;
866 enum hostkey_type type = pvar->hosts_state.hostkey.type;
867
868 if (type == KEY_RSA1) {
869 result = (char FAR *) malloc(host_len
870 + 50 +
871 get_ushort16_MSBfirst(pvar->hosts_state.hostkey.exp) /
872 3 +
873 get_ushort16_MSBfirst(pvar->hosts_state.hostkey.mod) /
874 3);
875
876 strcpy(result, pvar->hosts_state.prefetched_hostname);
877 index = host_len;
878
879 sprintf(result + index, " %d ", pvar->hosts_state.hostkey.bits);
880 index += strlen(result + index);
881 index += print_mp_int(result + index, pvar->hosts_state.hostkey.exp);
882 result[index] = ' ';
883 index++;
884 index += print_mp_int(result + index, pvar->hosts_state.hostkey.mod);
885 strcpy(result + index, " \r\n");
886
887 } else if (type == KEY_RSA || type == KEY_DSA) {
888 Key *key = &pvar->hosts_state.hostkey;
889 char *blob = NULL;
890 int blen, uulen, msize;
891 char *uu = NULL;
892 int n;
893
894 key_to_blob(key, &blob, &blen);
895 uulen = 2 * blen;
896 uu = malloc(uulen);
897 if (uu == NULL) {
898 goto error;
899 }
900 n = uuencode(blob, blen, uu, uulen);
901 if (n > 0) {
902 msize = host_len + 50 + uulen;
903 result = malloc(msize);
904 if (result == NULL) {
905 goto error;
906 }
907
908 // setup
909 _snprintf(result, msize, "%s %s %s\r\n",
910 pvar->hosts_state.prefetched_hostname,
911 get_sshname_from_key(key),
912 uu);
913 }
914 error:
915 if (blob != NULL)
916 free(blob);
917 if (uu != NULL)
918 free(uu);
919
920 } else {
921 return NULL;
922
923 }
924
925 return result;
926 }
927
928 static void add_host_key(PTInstVar pvar)
929 {
930 char FAR *name = pvar->hosts_state.file_names[0];
931
932 if (name == NULL || name[0] == 0) {
933 #ifdef I18N
934 #else
935 notify_nonfatal_error(pvar,
936 "The host and its key cannot be added, because no known-hosts file has been specified.\n"
937 "Restart Teraterm and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
938 #endif
939 } else {
940 char FAR *keydata = format_host_key(pvar);
941 int length = strlen(keydata);
942 int fd;
943 int amount_written;
944 int close_result;
945 char buf[FILENAME_MAX];
946
947 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
948 fd = _open(buf,
949 _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL |
950 _O_BINARY,
951 _S_IREAD | _S_IWRITE);
952 if (fd == -1) {
953 if (errno == EACCES) {
954 #ifdef I18N
955 #else
956 notify_nonfatal_error(pvar,
957 "An error occurred while trying to write the host key.\n"
958 "You do not have permission to write to the known-hosts file.");
959 #endif
960 } else {
961 #ifdef I18N
962 #else
963 notify_nonfatal_error(pvar,
964 "An error occurred while trying to write the host key.\n"
965 "The host key could not be written.");
966 #endif
967 }
968 return;
969 }
970
971 amount_written = _write(fd, keydata, length);
972 free(keydata);
973 close_result = _close(fd);
974
975 if (amount_written != length || close_result == -1) {
976 #ifdef I18N
977 #else
978 notify_nonfatal_error(pvar,
979 "An error occurred while trying to write the host key.\n"
980 "The host key could not be written.");
981 #endif
982 }
983 }
984 }
985
986 static char FAR *copy_mp_int(char FAR * num)
987 {
988 int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;
989 char FAR *result = (char FAR *) malloc(len);
990
991 if (result != NULL) {
992 memcpy(result, num, len);
993 }
994
995 return result;
996 }
997
998 //
999 // �����z�X�g�����e���������L�[����������
1000 // add_host_key ����������������
1001 //
1002 static void delete_different_key(PTInstVar pvar)
1003 {
1004 char FAR *name = pvar->hosts_state.file_names[0];
1005
1006 if (name == NULL || name[0] == 0) {
1007 #ifdef I18N
1008 #else
1009 notify_nonfatal_error(pvar,
1010 "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1011 "Restart Teraterm and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1012 #endif
1013 }
1014 else {
1015 Key key; // ���������z�X�g���L�[
1016 int length;
1017 char filename[L_tmpnam];
1018 int fd;
1019 int amount_written = 0;
1020 int close_result;
1021 int data_index = 0;
1022 char buf[FILENAME_MAX];
1023
1024 // �������������t�@�C�����J��
1025 tmpnam(filename);
1026 fd =
1027 _open(filename,
1028 _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY |
1029 _O_TRUNC,
1030 _S_IREAD | _S_IWRITE);
1031
1032 if (fd == -1) {
1033 if (errno == EACCES) {
1034 #ifdef I18N
1035 #else
1036 notify_nonfatal_error(pvar,
1037 "An error occurred while trying to write the host key.\n"
1038 "You do not have permission to write to the known-hosts file.");
1039 #endif
1040 } else {
1041 #ifdef I18N
1042 #else
1043 notify_nonfatal_error(pvar,
1044 "An error occurred while trying to write the host key.\n"
1045 "The host key could not be written.");
1046 #endif
1047 }
1048 free(filename);
1049 return;
1050 }
1051
1052 // ���������T�[�o���L�[����������
1053 if (pvar->hosts_state.hostkey.type == KEY_RSA1) { // SSH1
1054 key.type = KEY_RSA1;
1055 key.bits = pvar->hosts_state.hostkey.bits;
1056 key.exp = copy_mp_int(pvar->hosts_state.hostkey.exp);
1057 key.mod = copy_mp_int(pvar->hosts_state.hostkey.mod);
1058 } else if (pvar->hosts_state.hostkey.type == KEY_RSA) { // SSH2 RSA
1059 key.type = KEY_RSA;
1060 key.rsa = duplicate_RSA(pvar->hosts_state.hostkey.rsa);
1061 } else { // SSH2 DSA
1062 key.type = KEY_DSA;
1063 key.dsa = duplicate_DSA(pvar->hosts_state.hostkey.dsa);
1064 }
1065
1066 // �t�@�C��������������
1067 begin_read_host_files(pvar, 0);
1068 do {
1069 int host_index = 0;
1070 int matched = 0;
1071 int keybits = 0;
1072 char FAR *data;
1073 int do_write = 0;
1074 length = amount_written = 0;
1075
1076 if (!read_host_key(pvar, pvar->ssh_state.hostname, 0, 1)) {
1077 break;
1078 }
1079
1080 if (data_index == pvar->hosts_state.file_data_index) {
1081 // index ���i������ == ��������������
1082 break;
1083 }
1084
1085 data = pvar->hosts_state.file_data + data_index;
1086 host_index = eat_spaces(data);
1087
1088 if (data[host_index] == '#') {
1089 do_write = 1;
1090 }
1091 else {
1092 // �z�X�g������
1093 host_index--;
1094 do {
1095 int negated;
1096
1097 host_index++;
1098 negated = data[host_index] == '!';
1099
1100 if (negated) {
1101 host_index++;
1102 if (match_pattern(data + host_index,
1103 pvar->ssh_state.hostname)) {
1104 matched = 0;
1105 // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1106 host_index--;
1107 do {
1108 host_index++;
1109 host_index += eat_to_end_of_pattern(data + host_index);
1110 } while (data[host_index] == ',');
1111 break;
1112 }
1113 }
1114 else if (match_pattern(data + host_index,
1115 pvar->ssh_state.hostname)) {
1116 matched = 1;
1117 }
1118 host_index += eat_to_end_of_pattern(data + host_index);
1119 } while (data[host_index] == ',');
1120
1121 // �z�X�g�������������v�����L�[����������
1122 if (match_key(pvar, &key)) {
1123 do_write = 1;
1124 }
1125 // �z�X�g������������
1126 else if (!matched) {
1127 do_write = 1;
1128 }
1129 // �z�X�g�������� and �������o�[�W����������
1130 else {
1131 int rsa1_key_bits=0;
1132 rsa1_key_bits = atoi(data + host_index + eat_spaces(data + host_index));
1133
1134 if (rsa1_key_bits > 0) { // �t�@�C�����L�[�� ssh1
1135 if (!SSHv1(pvar)) {
1136 do_write = 1;
1137 }
1138 }
1139 else { // �t�@�C�����L�[�� ssh2
1140 if (!SSHv2(pvar)) {
1141 do_write = 1;
1142 }
1143 }
1144 }
1145 }
1146
1147 // ������������
1148 if (do_write) {
1149 length = pvar->hosts_state.file_data_index - data_index;
1150 amount_written =
1151 _write(fd, pvar->hosts_state.file_data + data_index,
1152 length);
1153
1154 if (amount_written != length) {
1155 goto error1;
1156 }
1157 }
1158 data_index = pvar->hosts_state.file_data_index;
1159 } while (1); // ������������
1160
1161 error1:
1162 close_result = _close(fd);
1163 if (amount_written != length || close_result == -1) {
1164 #ifdef I18N
1165 #else
1166 notify_nonfatal_error(pvar,
1167 "An error occurred while trying to write the host key.\n"
1168 "The host key could not be written.");
1169 #endif
1170 goto error2;
1171 }
1172
1173 // �������������t�@�C���������l�[��
1174 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1175 _unlink(buf);
1176 rename(filename, buf);
1177
1178 error2:
1179 _unlink(filename);
1180
1181 finish_read_host_files(pvar, 0);
1182 }
1183 }
1184
1185 //
1186 // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1187 // ���[�U���m�F�������B
1188 // TODO: finger print���\�����s���B
1189 // (2006.3.25 yutaka)
1190 //
1191 static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1192 LPARAM lParam)
1193 {
1194 PTInstVar pvar;
1195
1196 switch (msg) {
1197 case WM_INITDIALOG:
1198 pvar = (PTInstVar) lParam;
1199 pvar->hosts_state.hosts_dialog = dlg;
1200 SetWindowLong(dlg, DWL_USER, lParam);
1201
1202 #ifdef I18N
1203 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1204 GetWindowText(dlg, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1205 UTIL_get_lang_msg("DLG_UNKNONWHOST_TITLE", pvar);
1206 SetWindowText(dlg, pvar->ts->UIMsg);
1207
1208 GetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1209 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNINIG", pvar);
1210 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1211
1212 GetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1213 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNINIG2", pvar);
1214 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1215
1216 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1217 UTIL_get_lang_msg("DLG_UNKNOWNHOST_FINGERPRINT", pvar);
1218 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1219
1220 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1221 UTIL_get_lang_msg("DLG_UNKNOWNHOST_ADD", pvar);
1222 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1223
1224 GetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1225 UTIL_get_lang_msg("BTN_CONTINUE", pvar);
1226 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1227
1228 GetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1229 UTIL_get_lang_msg("BTN_DISCONNECT", pvar);
1230 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1231 #endif
1232
1233 init_hosts_dlg(pvar, dlg);
1234
1235 // add host check box���`�F�b�N���f�t�H���g������������
1236 SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1237
1238 return TRUE; /* because we do not set the focus */
1239
1240 case WM_COMMAND:
1241 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1242
1243 switch (LOWORD(wParam)) {
1244 case IDC_CONTINUE:
1245 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1246 add_host_key(pvar);
1247 }
1248
1249 if (SSHv1(pvar)) {
1250 SSH_notify_host_OK(pvar);
1251 } else { // SSH2
1252 // SSH2���������� SSH_notify_host_OK() �������B
1253 }
1254
1255 pvar->hosts_state.hosts_dialog = NULL;
1256
1257 EndDialog(dlg, 1);
1258 return TRUE;
1259
1260 case IDCANCEL: /* kill the connection */
1261 pvar->hosts_state.hosts_dialog = NULL;
1262 notify_closed_connection(pvar);
1263 EndDialog(dlg, 0);
1264 return TRUE;
1265
1266 default:
1267 return FALSE;
1268 }
1269
1270 default:
1271 return FALSE;
1272 }
1273 }
1274
1275 //
1276 // �u�����������m�F�_�C�A���O������
1277 //
1278 static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1279 LPARAM lParam)
1280 {
1281 PTInstVar pvar;
1282
1283 switch (msg) {
1284 case WM_INITDIALOG:
1285 pvar = (PTInstVar) lParam;
1286 pvar->hosts_state.hosts_dialog = dlg;
1287 SetWindowLong(dlg, DWL_USER, lParam);
1288
1289 #ifdef I18N
1290 // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1291 GetWindowText(dlg, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1292 UTIL_get_lang_msg("DLG_DIFFERENTHOST_TITLE", pvar);
1293 SetWindowText(dlg, pvar->ts->UIMsg);
1294
1295 GetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1296 UTIL_get_lang_msg("DLG_DIFFERENTHOST_WARNING", pvar);
1297 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1298
1299 GetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1300 UTIL_get_lang_msg("DLG_DIFFERENTHOST_WARNING2", pvar);
1301 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1302
1303 GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1304 UTIL_get_lang_msg("DLG_DIFFERENTHOST_FINGERPRINT", pvar);
1305 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1306
1307 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1308 UTIL_get_lang_msg("DLG_DIFFERENTHOST_REPLACE", pvar);
1309 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1310
1311 GetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1312 UTIL_get_lang_msg("BTN_CONTINUE", pvar);
1313 SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1314
1315 GetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg, sizeof(pvar->ts->UIMsg));
1316 UTIL_get_lang_msg("BTN_DISCONNECT", pvar);
1317 SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1318 #endif
1319
1320 init_hosts_dlg(pvar, dlg);
1321
1322 // �f�t�H���g���`�F�b�N����������
1323 return TRUE; /* because we do not set the focus */
1324
1325 case WM_COMMAND:
1326 pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1327
1328 switch (LOWORD(wParam)) {
1329 case IDC_CONTINUE:
1330 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1331 add_host_key(pvar);
1332 delete_different_key(pvar);
1333 }
1334
1335 if (SSHv1(pvar)) {
1336 SSH_notify_host_OK(pvar);
1337 } else { // SSH2
1338 // SSH2���������� SSH_notify_host_OK() �������B
1339 }
1340
1341 pvar->hosts_state.hosts_dialog = NULL;
1342
1343 EndDialog(dlg, 1);
1344 return TRUE;
1345
1346 case IDCANCEL: /* kill the connection */
1347 pvar->hosts_state.hosts_dialog = NULL;
1348 notify_closed_connection(pvar);
1349 EndDialog(dlg, 0);
1350 return TRUE;
1351
1352 default:
1353 return FALSE;
1354 }
1355
1356 default:
1357 return FALSE;
1358 }
1359 }
1360
1361 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
1362 {
1363 if (pvar->hosts_state.hosts_dialog == NULL) {
1364 HWND cur_active = GetActiveWindow();
1365
1366 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
1367 cur_active != NULL ? cur_active : wnd,
1368 hosts_add_dlg_proc, (LPARAM) pvar);
1369 }
1370 }
1371
1372 void HOSTS_do_different_host_dialog(HWND wnd, PTInstVar pvar)
1373 {
1374 if (pvar->hosts_state.hosts_dialog == NULL) {
1375 HWND cur_active = GetActiveWindow();
1376
1377 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTHOST),
1378 cur_active != NULL ? cur_active : wnd,
1379 hosts_replace_dlg_proc, (LPARAM) pvar);
1380 }
1381 }
1382
1383 //
1384 // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
1385 //
1386 // SSH2���������� (2006.3.24 yutaka)
1387 //
1388 BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, Key *key)
1389 {
1390 int found_different_key = 0;
1391
1392 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
1393 if (pvar->hosts_state.prefetched_hostname != NULL
1394 && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
1395 && match_key(pvar, key)) {
1396
1397 if (SSHv1(pvar)) {
1398 SSH_notify_host_OK(pvar);
1399 } else {
1400 // SSH2���������� SSH_notify_host_OK() �������B
1401 }
1402 return TRUE;
1403 }
1404
1405 // �������������������������A�������_���t�@�C��������������
1406 if (begin_read_host_files(pvar, 0)) {
1407 do {
1408 if (!read_host_key(pvar, hostname, 0, 0)) {
1409 break;
1410 }
1411
1412 if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
1413 if (match_key(pvar, key)) {
1414 finish_read_host_files(pvar, 0);
1415 // ���������G���g�����Q�������A���v�����L�[�������������������B
1416 // SSH2���������������������������B(2006.3.29 yutaka)
1417 if (SSHv1(pvar)) {
1418 SSH_notify_host_OK(pvar);
1419 } else {
1420 // SSH2���������� SSH_notify_host_OK() �������B
1421 }
1422 return TRUE;
1423 } else {
1424 // �L�[�� known_hosts ���������������A�L�[�����e���������B
1425 found_different_key = 1;
1426 }
1427 }
1428 } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // �L�[�����������������������[�v����
1429
1430 finish_read_host_files(pvar, 0);
1431 }
1432
1433
1434 // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
1435 pvar->hosts_state.hostkey.type = key->type;
1436 if (key->type == KEY_RSA1) { // SSH1
1437 pvar->hosts_state.hostkey.bits = key->bits;
1438 pvar->hosts_state.hostkey.exp = copy_mp_int(key->exp);
1439 pvar->hosts_state.hostkey.mod = copy_mp_int(key->mod);
1440
1441 } else if (key->type == KEY_RSA) { // SSH2 RSA
1442 pvar->hosts_state.hostkey.rsa = duplicate_RSA(key->rsa);
1443
1444 } else { // SSH2 DSA
1445 pvar->hosts_state.hostkey.dsa = duplicate_DSA(key->dsa);
1446
1447 }
1448 free(pvar->hosts_state.prefetched_hostname);
1449 pvar->hosts_state.prefetched_hostname = _strdup(hostname);
1450
1451 if (found_different_key) {
1452 PostMessage(pvar->NotificationWindow, WM_COMMAND,
1453 ID_SSHDIFFERENTHOST, 0);
1454 } else {
1455 PostMessage(pvar->NotificationWindow, WM_COMMAND,
1456 ID_SSHUNKNOWNHOST, 0);
1457 }
1458
1459 return TRUE;
1460 }
1461
1462 void HOSTS_notify_disconnecting(PTInstVar pvar)
1463 {
1464 if (pvar->hosts_state.hosts_dialog != NULL) {
1465 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL,
1466 0);
1467 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
1468 EnableWindow(pvar->NotificationWindow, TRUE);
1469 }
1470 }
1471
1472 void HOSTS_end(PTInstVar pvar)
1473 {
1474 int i;
1475
1476 free(pvar->hosts_state.prefetched_hostname);
1477 #if 0
1478 free(pvar->hosts_state.key_exp);
1479 free(pvar->hosts_state.key_mod);
1480 #else
1481 init_hostkey(&pvar->hosts_state.hostkey);
1482 #endif
1483
1484 if (pvar->hosts_state.file_names != NULL) {
1485 for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
1486 free(pvar->hosts_state.file_names[i]);
1487 }
1488 free(pvar->hosts_state.file_names);
1489 }
1490 }
1491
1492 /*
1493 * $Log: not supported by cvs2svn $
1494 * Revision 1.10 2006/11/23 02:19:30 maya
1495 * �\�����b�Z�[�W�������t�@�C�����������������R�[�h���������J�n�����B
1496 *
1497 * Revision 1.9 2006/07/01 00:41:02 maya
1498 * ���������p ssh_known_hosts ���w���������������������������s�������C�������B
1499 *
1500 * Revision 1.8 2006/06/29 15:27:00 yutakakn
1501 * ssh_known_files�t�@�C��������TeraTerm�C���X�g�[���f�B���N�g�����������������������B
1502 *
1503 * Revision 1.7 2006/04/04 13:52:52 yutakakn
1504 * known_hosts�t�@�C�����������L�[�����������������z�X�g���G���g���������������A�����L�[�����������@�\�����������B
1505 *
1506 * Revision 1.6 2006/03/29 14:56:52 yutakakn
1507 * known_hosts�t�@�C�����L�[�����������������z�X�g���G���g�����������A�A�v���P�[�V�����G���[�������o�O���C�������B
1508 *
1509 * Revision 1.5 2006/03/26 17:07:17 yutakakn
1510 * fingerprint�\��������
1511 *
1512 * Revision 1.4 2006/03/26 15:43:58 yutakakn
1513 * SSH2��known_hosts���������������B
1514 *
1515 * Revision 1.3 2006/02/18 07:37:02 yutakakn
1516 * �E�R���p�C���� Visual Studio 2005 Standard Edition �������������B
1517 * �Estricmp()��_stricmp()���u������
1518 * �Estrdup()��_strdup()���u������
1519 *
1520 * Revision 1.2 2004/12/19 15:39:42 yutakakn
1521 * CVS LogID������
1522 *
1523 */

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