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

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