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 2940 - (hide annotations) (download) (as text)
Thu Nov 30 09:56:43 2006 UTC (17 years, 4 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/hosts.c
File MIME type: text/x-csrc
File size: 37219 byte(s)
表示メッセージの読み込み対応

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

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