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 2980 - (hide annotations) (download) (as text)
Wed Jun 6 14:10:12 2007 UTC (16 years, 10 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/hosts.c
File MIME type: text/x-csrc
File size: 43798 byte(s)
プリプロセッサにより構造体が変わってしまうので、INET6 と I18N の #define を逆転させた。

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

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