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

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