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

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