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 2994 - (hide annotations) (download) (as text)
Mon Aug 13 22:30:03 2007 UTC (16 years, 8 months ago) by maya
Original Path: ttssh2/trunk/ttxssh/hosts.c
File MIME type: text/x-csrc
File size: 40651 byte(s)
国際化関数を修正した。
NO_I18N マクロを削除した。

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

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