Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/ttssh2/ttxssh/hosts.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2937 - (hide 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 yutakakn 2728 /*
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 yutakakn 2856 #include "ssh.h"
39     #include "hosts.h"
40 yutakakn 2728
41     #include <openssl/bn.h>
42 yutakakn 2856 #include <openssl/evp.h>
43     #include <openssl/rsa.h>
44     #include <openssl/dsa.h>
45 yutakakn 2728
46     #include <fcntl.h>
47     #include <io.h>
48     #include <errno.h>
49     #include <sys/stat.h>
50    
51 yutakakn 2856
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 yutakakn 2728 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 yutakakn 2856 #if 0
124 yutakakn 2728 pvar->hosts_state.key_exp = NULL;
125     pvar->hosts_state.key_mod = NULL;
126 yutakakn 2856 #else
127     init_hostkey(&pvar->hosts_state.hostkey);
128     #endif
129 yutakakn 2728 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 yutakakn 2856 //
140     // known_hosts�t�@�C�������e�������� pvar->hosts_state.file_data ����������
141     //
142 yutakakn 2728 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 yutakakn 2856 // 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 yutakakn 2728 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 yutakakn 2856 //
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 yutakakn 2728 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 yutakakn 2856 //
493     // known_hosts�t�@�C�������e���������A�w�������z�X�g�����J�����T���B
494     //
495 yutakakn 2728 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 yutakakn 2856 // ���������������t�H�[�}�b�g��������
531     // �����A���������v�����G���g�����������������������B
532     /*
533     [SSH1]
534     192.168.1.2 1024 35 13032....
535 yutakakn 2728
536 yutakakn 2856 [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 yutakakn 2728
545     index += eat_spaces(data + index);
546    
547 yutakakn 2856 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 yutakakn 2728
553 yutakakn 2856 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 yutakakn 2728 }
608    
609     return index + eat_to_end_of_line(data + index);
610     }
611     }
612    
613 yutakakn 2856 //
614     // known_hosts�t�@�C�������z�X�g�������v�����s������
615     //
616 yutakakn 2728 static int read_host_key(PTInstVar pvar, char FAR * hostname,
617 yutakakn 2861 int suppress_errors, int return_always)
618 yutakakn 2728 {
619     int i;
620 yutakakn 2861 int while_flg;
621 yutakakn 2728
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 yutakakn 2856 #if 0
644 yutakakn 2728 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 yutakakn 2856 #else
650     // hostkey type is KEY_UNSPEC.
651     init_hostkey(&pvar->hosts_state.hostkey);
652     #endif
653 yutakakn 2728
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 yutakakn 2861 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 yutakakn 2728 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 yutakakn 2856 // �T�[�o�����������O���Aknown_hosts�t�@�C�������z�X�g���J�������������������B
711 yutakakn 2728 void HOSTS_prefetch_host_key(PTInstVar pvar, char FAR * hostname)
712     {
713     if (!begin_read_host_files(pvar, 1)) {
714     return;
715     }
716    
717 yutakakn 2861 if (!read_host_key(pvar, hostname, 1, 0)) {
718 yutakakn 2728 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 yutakakn 2856 // ���J����������������������
744     static BOOL match_key(PTInstVar pvar, Key *key)
745 yutakakn 2728 {
746 yutakakn 2856 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 yutakakn 2728 }
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 yutakakn 2857 char *fp;
788 yutakakn 2728
789 yutakakn 2857 // static text�� # �������z�X�g�����u������
790 yutakakn 2728 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 yutakakn 2857
808     // fingerprint����������
809     fp = key_fingerprint(&pvar->hosts_state.hostkey);
810     SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
811 yutakakn 2728 }
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 yutakakn 2856 //
838     // known_hosts �t�@�C�������������G���g�������������B
839     //
840 yutakakn 2728 static char FAR *format_host_key(PTInstVar pvar)
841     {
842     int host_len = strlen(pvar->hosts_state.prefetched_hostname);
843 yutakakn 2856 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 yutakakn 2728 + 50 +
850 yutakakn 2856 get_ushort16_MSBfirst(pvar->hosts_state.hostkey.exp) /
851 yutakakn 2728 3 +
852 yutakakn 2856 get_ushort16_MSBfirst(pvar->hosts_state.hostkey.mod) /
853 yutakakn 2728 3);
854    
855 yutakakn 2856 strcpy(result, pvar->hosts_state.prefetched_hostname);
856     index = host_len;
857 yutakakn 2728
858 yutakakn 2856 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 yutakakn 2728
866 yutakakn 2856 } 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 yutakakn 2728 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 maya 2879 if (name == NULL || name[0] == 0) {
912 yutakakn 2728 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 maya 2879 int fd;
919 yutakakn 2728 int amount_written;
920     int close_result;
921 maya 2879 char buf[FILENAME_MAX];
922 yutakakn 2728
923 maya 2879 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 yutakakn 2728 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 yutakakn 2861 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 yutakakn 2856 //
966 yutakakn 2861 // �����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 maya 2879 if (name == NULL || name[0] == 0) {
974 yutakakn 2861 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 yutakakn 2876 int length;
981 yutakakn 2861 char filename[L_tmpnam];
982     int fd;
983     int amount_written = 0;
984     int close_result;
985     int data_index = 0;
986 maya 2879 char buf[FILENAME_MAX];
987 yutakakn 2861
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 maya 2879 get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1130 yutakakn 2876 _unlink(buf);
1131     rename(filename, buf);
1132 yutakakn 2861
1133     error2:
1134     _unlink(filename);
1135    
1136     finish_read_host_files(pvar, 0);
1137     }
1138     }
1139    
1140     //
1141 yutakakn 2856 // 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 yutakakn 2861 static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1147     LPARAM lParam)
1148 yutakakn 2728 {
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 maya 2937 #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 yutakakn 2728 init_hosts_dlg(pvar, dlg);
1189 yutakakn 2856
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 yutakakn 2728 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 yutakakn 2856 if (SSHv1(pvar)) {
1205     SSH_notify_host_OK(pvar);
1206     } else { // SSH2
1207     // SSH2���������� SSH_notify_host_OK() �������B
1208     }
1209    
1210 yutakakn 2728 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 yutakakn 2861 //
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 yutakakn 2728 {
1236 yutakakn 2861 PTInstVar pvar;
1237 yutakakn 2728
1238 yutakakn 2861 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 maya 2937 #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 yutakakn 2861 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 yutakakn 2728 }
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 yutakakn 2861 hosts_add_dlg_proc, (LPARAM) pvar);
1324 yutakakn 2728 }
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 yutakakn 2861 hosts_replace_dlg_proc, (LPARAM) pvar);
1335 yutakakn 2728 }
1336     }
1337    
1338 yutakakn 2856 //
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 yutakakn 2728 {
1345     int found_different_key = 0;
1346    
1347 yutakakn 2856 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
1348 yutakakn 2728 if (pvar->hosts_state.prefetched_hostname != NULL
1349 yutakakn 2850 && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
1350 yutakakn 2856 && 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 yutakakn 2728 return TRUE;
1358     }
1359    
1360 yutakakn 2856 // �������������������������A�������_���t�@�C��������������
1361 yutakakn 2728 if (begin_read_host_files(pvar, 0)) {
1362     do {
1363 yutakakn 2861 if (!read_host_key(pvar, hostname, 0, 0)) {
1364 yutakakn 2728 break;
1365     }
1366    
1367 yutakakn 2856 if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
1368     if (match_key(pvar, key)) {
1369 yutakakn 2728 finish_read_host_files(pvar, 0);
1370 yutakakn 2859 // ���������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 yutakakn 2728 return TRUE;
1378     } else {
1379 yutakakn 2856 // �L�[�� known_hosts ���������������A�L�[�����e���������B
1380 yutakakn 2728 found_different_key = 1;
1381     }
1382     }
1383 yutakakn 2856 } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // �L�[�����������������������[�v����
1384 yutakakn 2728
1385     finish_read_host_files(pvar, 0);
1386     }
1387    
1388 yutakakn 2856
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 yutakakn 2728 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 yutakakn 2856 #if 0
1433 yutakakn 2728 free(pvar->hosts_state.key_exp);
1434     free(pvar->hosts_state.key_mod);
1435 yutakakn 2856 #else
1436     init_hostkey(&pvar->hosts_state.hostkey);
1437     #endif
1438 yutakakn 2728
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 yutakakn 2761
1447     /*
1448     * $Log: not supported by cvs2svn $
1449 maya 2937 * Revision 1.9 2006/07/01 00:41:02 maya
1450     * ���������p ssh_known_hosts ���w���������������������������s�������C�������B
1451     *
1452 maya 2879 * 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 yutakakn 2876 * 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 yutakakn 2861 * 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 yutakakn 2859 * Revision 1.5 2006/03/26 17:07:17 yutakakn
1462     * fingerprint�\��������
1463     *
1464 yutakakn 2857 * Revision 1.4 2006/03/26 15:43:58 yutakakn
1465     * SSH2��known_hosts���������������B
1466     *
1467 yutakakn 2856 * 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 yutakakn 2850 * Revision 1.2 2004/12/19 15:39:42 yutakakn
1473     * CVS LogID������
1474     *
1475 yutakakn 2761 */

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