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 7560 - (hide annotations) (download) (as text)
Mon Apr 8 17:12:02 2019 UTC (5 years ago) by zmatsuo
File MIME type: text/x-csrc
File size: 68429 byte(s)
ttssh 高DPI対応
1 maya 3227 /*
2 doda 6841 * Copyright (c) 1998-2001, Robert O'Callahan
3     * (C) 2004-2017 TeraTerm Project
4     * All rights reserved.
5     *
6     * Redistribution and use in source and binary forms, with or without
7     * modification, are permitted provided that the following conditions
8     * are met:
9     *
10     * 1. Redistributions of source code must retain the above copyright
11     * notice, this list of conditions and the following disclaimer.
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the distribution.
15     * 3. The name of the author may not be used to endorse or promote products
16     * derived from this software without specific prior written permission.
17     *
18     * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21     * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28     */
29 maya 3227
30     /*
31     This code is copyright (C) 1998-1999 Robert O'Callahan.
32     See LICENSE.TXT for the license.
33     */
34     #include "ttxssh.h"
35     #include "util.h"
36     #include "resource.h"
37     #include "matcher.h"
38     #include "ssh.h"
39 maya 4304 #include "key.h"
40 maya 3227 #include "hosts.h"
41 doda 4569 #include "dns.h"
42 zmatsuo 7560 #include "dlglib.h"
43 maya 3227
44     #include <openssl/bn.h>
45     #include <openssl/evp.h>
46     #include <openssl/rsa.h>
47     #include <openssl/dsa.h>
48    
49     #include <fcntl.h>
50     #include <io.h>
51     #include <errno.h>
52     #include <sys/stat.h>
53     #include <direct.h>
54 doda 4531 #include <memory.h>
55 maya 3227
56 doda 4531
57 zmatsuo 7560 #undef DialogBoxParam
58     #define DialogBoxParam(p1,p2,p3,p4,p5) \
59     TTDialogBoxParam(p1,p2,p3,p4,p5)
60     #undef EndDialog
61     #define EndDialog(p1,p2) \
62     TTEndDialog(p1, p2)
63 maya 3227
64 zmatsuo 7560 //static HFONT DlgHostsAddFont;
65     //static HFONT DlgHostsReplaceFont;
66    
67 maya 3227 // BASE64�\���������i��������'='�����������������j
68     static char base64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
69    
70    
71 doda 6801 static char **parse_multi_path(char *buf)
72 maya 3227 {
73     int i;
74     int ch;
75     int num_paths = 1;
76 doda 6801 char ** result;
77 maya 3227 int last_path_index;
78    
79     for (i = 0; (ch = buf[i]) != 0; i++) {
80     if (ch == ';') {
81     num_paths++;
82     }
83     }
84    
85     result =
86 doda 6801 (char **) malloc(sizeof(char *) * (num_paths + 1));
87 maya 3227
88     last_path_index = 0;
89     num_paths = 0;
90     for (i = 0; (ch = buf[i]) != 0; i++) {
91     if (ch == ';') {
92     buf[i] = 0;
93     result[num_paths] = _strdup(buf + last_path_index);
94     num_paths++;
95     buf[i] = ch;
96     last_path_index = i + 1;
97     }
98     }
99     if (i > last_path_index) {
100     result[num_paths] = _strdup(buf + last_path_index);
101     num_paths++;
102     }
103     result[num_paths] = NULL;
104     return result;
105     }
106    
107     void HOSTS_init(PTInstVar pvar)
108     {
109     pvar->hosts_state.prefetched_hostname = NULL;
110 maya 6147 key_init(&pvar->hosts_state.hostkey);
111 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
112     pvar->hosts_state.file_names = NULL;
113     }
114    
115     void HOSTS_open(PTInstVar pvar)
116     {
117     pvar->hosts_state.file_names =
118     parse_multi_path(pvar->session_settings.KnownHostsFiles);
119     }
120    
121     //
122     // known_hosts�t�@�C�������e�������� pvar->hosts_state.file_data ����������
123     //
124 doda 6801 static int begin_read_file(PTInstVar pvar, char *name,
125 maya 3227 int suppress_errors)
126     {
127     int fd;
128     int length;
129     int amount_read;
130     char buf[2048];
131    
132     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
133     fd = _open(buf, _O_RDONLY | _O_SEQUENTIAL | _O_BINARY);
134     if (fd == -1) {
135     if (!suppress_errors) {
136     if (errno == ENOENT) {
137     UTIL_get_lang_msg("MSG_HOSTS_READ_ENOENT_ERROR", pvar,
138     "An error occurred while trying to read a known_hosts file.\n"
139     "The specified filename does not exist.");
140     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
141     } else {
142     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
143     "An error occurred while trying to read a known_hosts file.");
144     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
145     }
146     }
147     return 0;
148     }
149    
150     length = (int) _lseek(fd, 0, SEEK_END);
151     _lseek(fd, 0, SEEK_SET);
152    
153     if (length >= 0 && length < 0x7FFFFFFF) {
154     pvar->hosts_state.file_data = malloc(length + 1);
155     if (pvar->hosts_state.file_data == NULL) {
156     if (!suppress_errors) {
157     UTIL_get_lang_msg("MSG_HOSTS_ALLOC_ERROR", pvar,
158     "Memory ran out while trying to allocate space to read a known_hosts file.");
159     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
160     }
161     _close(fd);
162     return 0;
163     }
164     } else {
165     if (!suppress_errors) {
166     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
167     "An error occurred while trying to read a known_hosts file.");
168     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
169     }
170     _close(fd);
171     return 0;
172     }
173    
174     amount_read = _read(fd, pvar->hosts_state.file_data, length);
175     pvar->hosts_state.file_data[length] = 0;
176    
177     _close(fd);
178    
179     if (amount_read != length) {
180     if (!suppress_errors) {
181     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
182     "An error occurred while trying to read a known_hosts file.");
183     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
184     }
185     free(pvar->hosts_state.file_data);
186     pvar->hosts_state.file_data = NULL;
187     return 0;
188     } else {
189     return 1;
190     }
191     }
192    
193     static int end_read_file(PTInstVar pvar, int suppress_errors)
194     {
195     free(pvar->hosts_state.file_data);
196     pvar->hosts_state.file_data = NULL;
197     return 1;
198     }
199    
200     static int begin_read_host_files(PTInstVar pvar, int suppress_errors)
201     {
202     pvar->hosts_state.file_num = 0;
203     pvar->hosts_state.file_data = NULL;
204     return 1;
205     }
206    
207     // MIME64�����������X�L�b�v����
208 doda 6801 static int eat_base64(char *data)
209 maya 3227 {
210     int index = 0;
211     int ch;
212    
213     for (;;) {
214     ch = data[index];
215     if (ch == '=' || strchr(base64, ch)) {
216     // BASE64���\�������������������� index ���i����
217     index++;
218     } else {
219     break;
220     }
221     }
222    
223     return index;
224     }
225    
226 doda 6801 static int eat_spaces(char *data)
227 maya 3227 {
228     int index = 0;
229     int ch;
230    
231     while ((ch = data[index]) == ' ' || ch == '\t') {
232     index++;
233     }
234     return index;
235     }
236    
237 doda 6801 static int eat_digits(char *data)
238 maya 3227 {
239     int index = 0;
240     int ch;
241    
242     while ((ch = data[index]) >= '0' && ch <= '9') {
243     index++;
244     }
245     return index;
246     }
247    
248 doda 6801 static int eat_to_end_of_line(char *data)
249 maya 3227 {
250     int index = 0;
251     int ch;
252    
253     while ((ch = data[index]) != '\n' && ch != '\r' && ch != 0) {
254     index++;
255     }
256    
257     while ((ch = data[index]) == '\n' || ch == '\r') {
258     index++;
259     }
260    
261     return index;
262     }
263    
264 doda 6801 static int eat_to_end_of_pattern(char *data)
265 maya 3227 {
266     int index = 0;
267     int ch;
268    
269     while (ch = data[index], is_pattern_char(ch)) {
270     index++;
271     }
272    
273     return index;
274     }
275    
276     // SSH2���� BASE64 �`�����i�[����������
277 doda 6621 static Key *parse_base64data(char *data)
278 maya 3227 {
279     int count;
280     unsigned char *blob = NULL;
281     int len, n;
282     Key *key = NULL;
283     char ch;
284    
285     // BASE64���������T�C�Y������
286     count = eat_base64(data);
287     len = 2 * count;
288     blob = malloc(len);
289     if (blob == NULL)
290     goto error;
291    
292     // BASE64�f�R�[�h
293     ch = data[count];
294     data[count] = '\0'; // ���������s�R�[�h������������������������������������
295 doda 6621 n = b64decode(blob, len, data);
296 maya 3227 data[count] = ch;
297     if (n < 0) {
298     goto error;
299     }
300    
301     key = key_from_blob(blob, n);
302     if (key == NULL)
303     goto error;
304    
305     error:
306     if (blob != NULL)
307     free(blob);
308    
309     return (key);
310     }
311    
312    
313 doda 6801 static char *parse_bignum(char *data)
314 maya 3227 {
315     uint32 digits = 0;
316     BIGNUM *num = BN_new();
317     BIGNUM *billion = BN_new();
318     BIGNUM *digits_num = BN_new();
319     BN_CTX *ctx = BN_CTX_new();
320 doda 6801 char *result;
321 maya 3227 int ch;
322     int leftover_digits = 1;
323    
324     BN_CTX_init(ctx);
325     BN_set_word(num, 0);
326     BN_set_word(billion, 1000000000L);
327    
328     while ((ch = *data) >= '0' && ch <= '9') {
329     if (leftover_digits == 1000000000L) {
330     BN_set_word(digits_num, digits);
331     BN_mul(num, num, billion, ctx);
332     BN_add(num, num, digits_num);
333     leftover_digits = 1;
334     digits = 0;
335     }
336    
337     digits = digits * 10 + ch - '0';
338     leftover_digits *= 10;
339     data++;
340     }
341    
342     BN_set_word(digits_num, digits);
343     BN_set_word(billion, leftover_digits);
344     BN_mul(num, num, billion, ctx);
345     BN_add(num, num, digits_num);
346    
347 doda 6801 result = (char *) malloc(2 + BN_num_bytes(num));
348 maya 3227 set_ushort16_MSBfirst(result, BN_num_bits(num));
349     BN_bn2bin(num, result + 2);
350    
351     BN_CTX_free(ctx);
352     BN_free(digits_num);
353     BN_free(num);
354     BN_free(billion);
355    
356     return result;
357     }
358    
359     //
360     // known_hosts�t�@�C�������e���������A�w�������z�X�g�����J�����T���B
361     //
362 doda 6801 static int check_host_key(PTInstVar pvar, char *hostname,
363     unsigned short tcpport, char *data,
364 maya 6152 Key *key)
365 maya 3227 {
366     int index = eat_spaces(data);
367     int matched = 0;
368     int keybits = 0;
369    
370     if (data[index] == '#') {
371     return index + eat_to_end_of_line(data + index);
372     }
373    
374     /* if we find an empty line, then it won't have any patterns matching the hostname
375     and so we skip it */
376     index--;
377     do {
378     int negated;
379     int bracketed;
380     char *end_bracket;
381     int host_matched = 0;
382     unsigned short keyfile_port = 22;
383    
384     index++;
385     negated = data[index] == '!';
386    
387     if (negated) {
388     index++;
389     bracketed = data[index] == '[';
390     if (bracketed) {
391     end_bracket = strstr(data + index + 1, "]:");
392     if (end_bracket != NULL) {
393     *end_bracket = ' ';
394     index++;
395     }
396     }
397     host_matched = match_pattern(data + index, hostname);
398     if (bracketed && end_bracket != NULL) {
399     *end_bracket = ']';
400     keyfile_port = atoi(end_bracket + 2);
401     }
402     if (host_matched && keyfile_port == tcpport) {
403     return index + eat_to_end_of_line(data + index);
404     }
405     } else {
406     bracketed = data[index] == '[';
407     if (bracketed) {
408     end_bracket = strstr(data + index + 1, "]:");
409     if (end_bracket != NULL) {
410     *end_bracket = ' ';
411     index++;
412     }
413     }
414     host_matched = match_pattern(data + index, hostname);
415     if (bracketed && end_bracket != NULL) {
416     *end_bracket = ']';
417     keyfile_port = atoi(end_bracket + 2);
418     }
419     if (host_matched && keyfile_port == tcpport) {
420     matched = 1;
421     }
422     }
423    
424     index += eat_to_end_of_pattern(data + index);
425     } while (data[index] == ',');
426    
427     if (!matched) {
428     return index + eat_to_end_of_line(data + index);
429     } else {
430     // ���������������t�H�[�}�b�g��������
431     // �����A���������v�����G���g�����������������������B
432     /*
433     [SSH1]
434     192.168.1.2 1024 35 13032....
435    
436     [SSH2]
437     192.168.1.2 ssh-rsa AAAAB3NzaC1....
438     192.168.1.2 ssh-dss AAAAB3NzaC1....
439     192.168.1.2 rsa AAAAB3NzaC1....
440     192.168.1.2 dsa AAAAB3NzaC1....
441     192.168.1.2 rsa1 AAAAB3NzaC1....
442     */
443     int rsa1_key_bits;
444    
445     index += eat_spaces(data + index);
446    
447     rsa1_key_bits = atoi(data + index);
448     if (rsa1_key_bits > 0) { // RSA1������
449     if (!SSHv1(pvar)) { // SSH2��������������������
450     return index + eat_to_end_of_line(data + index);
451     }
452    
453 maya 6152 key->type = KEY_RSA1;
454 maya 3227
455 maya 6152 key->bits = rsa1_key_bits;
456 maya 3227 index += eat_digits(data + index);
457     index += eat_spaces(data + index);
458    
459 maya 6152 key->exp = parse_bignum(data + index);
460 maya 3227 index += eat_digits(data + index);
461     index += eat_spaces(data + index);
462    
463 maya 6152 key->mod = parse_bignum(data + index);
464 maya 3227 } else {
465     char *cp, *p;
466 maya 6152 Key *key2;
467     ssh_keytype key_type;
468 maya 3227
469     if (!SSHv2(pvar)) { // SSH1��������������������
470     return index + eat_to_end_of_line(data + index);
471     }
472    
473     cp = data + index;
474     p = strchr(cp, ' ');
475     if (p == NULL) {
476     return index + eat_to_end_of_line(data + index);
477     }
478     index += (p - cp); // setup index
479     *p = '\0';
480 maya 6152 key_type = get_keytype_from_name(cp);
481 maya 3227 *p = ' ';
482    
483     index += eat_spaces(data + index); // update index
484    
485 doda 6621 // base64 decode
486     key2 = parse_base64data(data + index);
487 maya 6152 if (key2 == NULL) {
488 maya 3227 return index + eat_to_end_of_line(data + index);
489     }
490    
491     // setup
492 maya 6152 key->type = key2->type;
493     key->dsa = key2->dsa;
494     key->rsa = key2->rsa;
495     key->ecdsa = key2->ecdsa;
496     key->ed25519_pk = key2->ed25519_pk;
497 maya 3227
498     index += eat_base64(data + index);
499     index += eat_spaces(data + index);
500    
501     // Key�\�������g���������� (2008.3.2 yutaka)
502 maya 6152 free(key2);
503 maya 3227 }
504    
505     return index + eat_to_end_of_line(data + index);
506     }
507     }
508    
509     //
510     // known_hosts�t�@�C�������z�X�g�������v�����s������
511 maya 6152 // return_always
512     // 0: �������������T��
513     // 1: 1�s�����T��������
514 maya 3227 //
515     static int read_host_key(PTInstVar pvar,
516 doda 6801 char *hostname, unsigned short tcpport,
517 maya 6152 int suppress_errors, int return_always,
518     Key *key)
519 maya 3227 {
520     int i;
521     int while_flg;
522    
523     for (i = 0; hostname[i] != 0; i++) {
524     int ch = hostname[i];
525    
526     if (!is_pattern_char(ch) || ch == '*' || ch == '?') {
527     if (!suppress_errors) {
528     UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_INVALID_ERROR", pvar,
529     "The host name contains an invalid character.\n"
530     "This session will be terminated.");
531 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
532 maya 3227 }
533     return 0;
534     }
535     }
536    
537     if (i == 0) {
538     if (!suppress_errors) {
539     UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_EMPTY_ERROR", pvar,
540     "The host name should not be empty.\n"
541     "This session will be terminated.");
542 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
543 maya 3227 }
544     return 0;
545     }
546    
547     // hostkey type is KEY_UNSPEC.
548 maya 6152 key_init(key);
549 maya 3227
550     do {
551     if (pvar->hosts_state.file_data == NULL
552     || pvar->hosts_state.file_data[pvar->hosts_state.file_data_index] == 0) {
553 doda 6801 char *filename;
554 maya 3227 int keep_going = 1;
555    
556     if (pvar->hosts_state.file_data != NULL) {
557     end_read_file(pvar, suppress_errors);
558     }
559    
560     do {
561     filename =
562     pvar->hosts_state.file_names[pvar->hosts_state.file_num];
563    
564     if (filename == NULL) {
565     return 1;
566     } else {
567     pvar->hosts_state.file_num++;
568    
569     if (filename[0] != 0) {
570     if (begin_read_file(pvar, filename, suppress_errors)) {
571     pvar->hosts_state.file_data_index = 0;
572     keep_going = 0;
573     }
574     }
575     }
576     } while (keep_going);
577     }
578    
579     pvar->hosts_state.file_data_index +=
580     check_host_key(pvar, hostname, tcpport,
581     pvar->hosts_state.file_data +
582 maya 6152 pvar->hosts_state.file_data_index,
583     key);
584 maya 3227
585     if (!return_always) {
586     // �L�����L�[��������������
587 maya 6152 while_flg = (key->type == KEY_UNSPEC);
588 maya 3227 }
589     else {
590     while_flg = 0;
591     }
592     } while (while_flg);
593    
594     return 1;
595     }
596    
597     static void finish_read_host_files(PTInstVar pvar, int suppress_errors)
598     {
599     if (pvar->hosts_state.file_data != NULL) {
600     end_read_file(pvar, suppress_errors);
601     }
602     }
603    
604     // �T�[�o�����������O���Aknown_hosts�t�@�C�������z�X�g���J�������������������B
605 doda 6801 void HOSTS_prefetch_host_key(PTInstVar pvar, char *hostname, unsigned short tcpport)
606 maya 3227 {
607 maya 6152 Key key; // known_hosts���o�^������������
608    
609 maya 3227 if (!begin_read_host_files(pvar, 1)) {
610     return;
611     }
612    
613 maya 6152 memset(&key, 0, sizeof(key));
614     if (!read_host_key(pvar, hostname, tcpport, 1, 0, &key)) {
615 maya 3227 return;
616     }
617    
618 maya 6152 key_copy(&pvar->hosts_state.hostkey, &key);
619     key_init(&key);
620    
621 maya 3227 free(pvar->hosts_state.prefetched_hostname);
622     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
623    
624     finish_read_host_files(pvar, 1);
625     }
626    
627 yutakapon 5846
628     // known_hosts�t�@�C�������Y�������L�[���������������B
629     //
630     // return:
631     // *keyptr != NULL ��������
632     //
633 doda 6801 static int parse_hostkey_file(PTInstVar pvar, char *hostname,
634     unsigned short tcpport, char *data, Key **keyptr)
635 yutakapon 5846 {
636     int index = eat_spaces(data);
637     int matched = 0;
638     int keybits = 0;
639     ssh_keytype ktype;
640 yutakapon 5847 Key *key;
641 yutakapon 5846
642     *keyptr = NULL;
643    
644     if (data[index] == '#') {
645     return index + eat_to_end_of_line(data + index);
646     }
647    
648     /* if we find an empty line, then it won't have any patterns matching the hostname
649     and so we skip it */
650     index--;
651     do {
652     int negated;
653     int bracketed;
654     char *end_bracket;
655     int host_matched = 0;
656     unsigned short keyfile_port = 22;
657    
658     index++;
659     negated = data[index] == '!';
660    
661     if (negated) {
662     index++;
663     bracketed = data[index] == '[';
664     if (bracketed) {
665     end_bracket = strstr(data + index + 1, "]:");
666     if (end_bracket != NULL) {
667     *end_bracket = ' ';
668     index++;
669     }
670     }
671     host_matched = match_pattern(data + index, hostname);
672     if (bracketed && end_bracket != NULL) {
673     *end_bracket = ']';
674     keyfile_port = atoi(end_bracket + 2);
675     }
676     if (host_matched && keyfile_port == tcpport) {
677     return index + eat_to_end_of_line(data + index);
678     }
679     }
680     else {
681     bracketed = data[index] == '[';
682     if (bracketed) {
683     end_bracket = strstr(data + index + 1, "]:");
684     if (end_bracket != NULL) {
685     *end_bracket = ' ';
686     index++;
687     }
688     }
689     host_matched = match_pattern(data + index, hostname);
690     if (bracketed && end_bracket != NULL) {
691     *end_bracket = ']';
692     keyfile_port = atoi(end_bracket + 2);
693     }
694     if (host_matched && keyfile_port == tcpport) {
695     matched = 1;
696     }
697     }
698    
699     index += eat_to_end_of_pattern(data + index);
700     } while (data[index] == ',');
701    
702     if (!matched) {
703     return index + eat_to_end_of_line(data + index);
704     }
705     else {
706     // ���������������t�H�[�}�b�g��������
707     // �����A���������v�����G���g�����������������������B
708     /*
709     [SSH1]
710     192.168.1.2 1024 35 13032....
711    
712     [SSH2]
713     192.168.1.2 ssh-rsa AAAAB3NzaC1....
714     192.168.1.2 ssh-dss AAAAB3NzaC1....
715     192.168.1.2 rsa AAAAB3NzaC1....
716     192.168.1.2 dsa AAAAB3NzaC1....
717     192.168.1.2 rsa1 AAAAB3NzaC1....
718     */
719     int rsa1_key_bits;
720    
721     index += eat_spaces(data + index);
722    
723     rsa1_key_bits = atoi(data + index);
724     if (rsa1_key_bits > 0) { // RSA1������
725     if (!SSHv1(pvar)) { // SSH2��������������������
726     return index + eat_to_end_of_line(data + index);
727     }
728 yutakapon 5847
729     key = key_new(KEY_RSA1);
730     key->bits = rsa1_key_bits;
731    
732 yutakapon 5846 index += eat_digits(data + index);
733     index += eat_spaces(data + index);
734 yutakapon 5847 key->exp = parse_bignum(data + index);
735 yutakapon 5846
736     index += eat_digits(data + index);
737     index += eat_spaces(data + index);
738 yutakapon 5847 key->mod = parse_bignum(data + index);
739 yutakapon 5846
740 yutakapon 5847 // setup
741     *keyptr = key;
742    
743 yutakapon 5846 }
744     else {
745     char *cp, *p;
746    
747     if (!SSHv2(pvar)) { // SSH1��������������������
748     return index + eat_to_end_of_line(data + index);
749     }
750    
751     cp = data + index;
752     p = strchr(cp, ' ');
753     if (p == NULL) {
754     return index + eat_to_end_of_line(data + index);
755     }
756     index += (p - cp); // setup index
757     *p = '\0';
758     ktype = get_keytype_from_name(cp);
759     *p = ' ';
760    
761     index += eat_spaces(data + index); // update index
762    
763 doda 6621 // base64 decode
764     key = parse_base64data(data + index);
765 yutakapon 5846 if (key == NULL) {
766     return index + eat_to_end_of_line(data + index);
767     }
768    
769     // setup
770     *keyptr = key;
771    
772     index += eat_base64(data + index);
773     index += eat_spaces(data + index);
774     }
775    
776     return index + eat_to_end_of_line(data + index);
777     }
778     }
779    
780     // known_hosts�t�@�C�������z�X�g���J�������������B
781     // �������������������������������AHost key rotation�p���V�K���p�������B
782     //
783     // return 1: success
784     // 0: fail
785     int HOSTS_hostkey_foreach(PTInstVar pvar, hostkeys_foreach_fn *callback, void *ctx)
786     {
787     int success = 0;
788     int suppress_errors = 1;
789     unsigned short tcpport;
790 doda 6801 char *filename;
791 yutakapon 5846 char *hostname;
792     Key *key;
793    
794     if (!begin_read_host_files(pvar, 1)) {
795     goto error;
796     }
797    
798     // Host key rotation�����Aknown_hosts �t�@�C�������������������A
799     // ������������1�������t�@�C�������������i2�������t�@�C����ReadOnly�������j�B
800     filename = pvar->hosts_state.file_names[pvar->hosts_state.file_num];
801     pvar->hosts_state.file_num++;
802    
803     pvar->hosts_state.file_data_index = -1;
804     if (filename[0] != 0) {
805     if (begin_read_file(pvar, filename, suppress_errors)) {
806     pvar->hosts_state.file_data_index = 0;
807     }
808     }
809     if (pvar->hosts_state.file_data_index == -1)
810     goto error;
811    
812     // ���������������z�X�g�����|�[�g�����B
813     hostname = pvar->ssh_state.hostname;
814     tcpport = pvar->ssh_state.tcpport;
815    
816     // known_hosts�t�@�C�������e�������� pvar->hosts_state.file_data �������������������B
817     // ������ \0 �B
818     while (pvar->hosts_state.file_data[pvar->hosts_state.file_data_index] != 0) {
819     key = NULL;
820    
821     pvar->hosts_state.file_data_index +=
822     parse_hostkey_file(pvar, hostname, tcpport,
823     pvar->hosts_state.file_data +
824     pvar->hosts_state.file_data_index,
825     &key);
826    
827 yutakapon 5847 // �Y�����������������������A�R�[���o�b�N�����������o���B
828 yutakapon 5846 if (key != NULL) {
829 yutakapon 5847 if (callback(key, ctx) == 0)
830     key_free(key);
831 yutakapon 5846 }
832     }
833    
834     success = 1;
835    
836     error:
837     finish_read_host_files(pvar, 1);
838    
839     return (success);
840     }
841    
842    
843 doda 6801 static BOOL equal_mp_ints(unsigned char *num1,
844     unsigned char *num2)
845 maya 3227 {
846     if (num1 == NULL || num2 == NULL) {
847     return FALSE;
848     } else {
849     uint32 bytes = (get_ushort16_MSBfirst(num1) + 7) / 8;
850    
851     if (bytes != (get_ushort16_MSBfirst(num2) + 7) / 8) {
852     return FALSE; /* different byte lengths */
853     } else {
854     return memcmp(num1 + 2, num2 + 2, bytes) == 0;
855     }
856     }
857     }
858    
859 yutakapon 5843
860     // ���J�������r���s���B
861     //
862     // return
863 maya 4332 // -1 ... �����^������
864     // 0 ... ����������
865     // 1 ... ������
866 yutakapon 5843 int HOSTS_compare_public_key(Key *src, Key *key)
867 maya 3227 {
868     int bits;
869 doda 6801 unsigned char *exp;
870     unsigned char *mod;
871 maya 4321 const EC_GROUP *group;
872     const EC_POINT *pa, *pb;
873 yutakapon 5545 Key *a, *b;
874 maya 3227
875 yutakapon 5843 if (src->type != key->type) {
876 maya 4332 return -1;
877     }
878    
879 maya 4321 switch (key->type) {
880     case KEY_RSA1: // SSH1 host public key
881 maya 3227 bits = key->bits;
882     exp = key->exp;
883     mod = key->mod;
884    
885     /* just check for equal exponent and modulus */
886 yutakapon 5843 return equal_mp_ints(exp, src->exp)
887     && equal_mp_ints(mod, src->mod);
888 maya 3227 /*
889     return equal_mp_ints(exp, pvar->hosts_state.key_exp)
890 yutakapon 5843 && equal_mp_ints(mod, pvar->hosts_state.key_mod);
891     */
892 maya 3227
893 maya 4321 case KEY_RSA: // SSH2 RSA host public key
894 yutakapon 5843 return key->rsa != NULL && src->rsa != NULL &&
895     BN_cmp(key->rsa->e, src->rsa->e) == 0 &&
896     BN_cmp(key->rsa->n, src->rsa->n) == 0;
897 maya 3227
898 maya 4321 case KEY_DSA: // SSH2 DSA host public key
899 yutakapon 5843 return key->dsa != NULL && src->dsa &&
900     BN_cmp(key->dsa->p, src->dsa->p) == 0 &&
901     BN_cmp(key->dsa->q, src->dsa->q) == 0 &&
902     BN_cmp(key->dsa->g, src->dsa->g) == 0 &&
903     BN_cmp(key->dsa->pub_key, src->dsa->pub_key) == 0;
904 maya 3227
905 maya 4321 case KEY_ECDSA256:
906     case KEY_ECDSA384:
907     case KEY_ECDSA521:
908 yutakapon 5843 if (key->ecdsa == NULL || src->ecdsa == NULL) {
909 maya 4321 return FALSE;
910     }
911     group = EC_KEY_get0_group(key->ecdsa);
912     pa = EC_KEY_get0_public_key(key->ecdsa),
913 yutakapon 5843 pb = EC_KEY_get0_public_key(src->ecdsa);
914 maya 4321 return EC_POINT_cmp(group, pa, pb, NULL) == 0;
915    
916 yutakapon 5545 case KEY_ED25519:
917     a = key;
918 yutakapon 5843 b = src;
919 yutakapon 5545 return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
920 yutakapon 5843 memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;
921 yutakapon 5545
922 maya 4321 default:
923 maya 4307 return FALSE;
924     }
925 yutakapon 5843 }
926 maya 3227
927 maya 6152 #if 0
928     // pvar->hosts_state.hostkey ���n���������J����������������������
929 yutakapon 5843 // -1 ... �����^������
930     // 0 ... ����������
931     // 1 ... ������
932     static int match_key(PTInstVar pvar, Key *key)
933     {
934     return HOSTS_compare_public_key(&pvar->hosts_state.hostkey, key);
935 maya 3227 }
936 maya 6152 #endif
937 maya 3227
938 maya 6132 static void hosts_dlg_set_fingerprint(PTInstVar pvar, HWND dlg, digest_algorithm dgst_alg)
939     {
940     char *fp = NULL;
941    
942     // fingerprint����������
943     switch (dgst_alg) {
944     case SSH_DIGEST_MD5:
945     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX, dgst_alg);
946 maya 6158 if (fp != NULL) {
947     SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
948     free(fp);
949     }
950 maya 6132 break;
951     case SSH_DIGEST_SHA256:
952 maya 6158 default:
953     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_BASE64, SSH_DIGEST_SHA256);
954     if (fp != NULL) {
955     SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
956     free(fp);
957     }
958 maya 6132 break;
959     }
960    
961     // �r�W���A����fingerprint���\������
962     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART, dgst_alg);
963 maya 6158 if (fp != NULL) {
964     SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETTEXT, 0, (LPARAM)fp);
965     free(fp);
966     }
967 maya 6132 }
968    
969 maya 3227 static void init_hosts_dlg(PTInstVar pvar, HWND dlg)
970     {
971     char buf[1024];
972     char buf2[2048];
973     int i, j;
974     int ch;
975    
976     // static text�� # �������z�X�g�����u������
977     GetDlgItemText(dlg, IDC_HOSTWARNING, buf, sizeof(buf));
978     for (i = 0; (ch = buf[i]) != 0 && ch != '#'; i++) {
979     buf2[i] = ch;
980     }
981     strncpy_s(buf2 + i, sizeof(buf2) - i,
982     pvar->hosts_state.prefetched_hostname, _TRUNCATE);
983     j = i + strlen(buf2 + i);
984     for (; buf[i] == '#'; i++) {
985     }
986     strncpy_s(buf2 + j, sizeof(buf2) - j, buf + i, _TRUNCATE);
987    
988     SetDlgItemText(dlg, IDC_HOSTWARNING, buf2);
989    
990 maya 6132 SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), TRUE);
991 maya 3227
992 maya 6145 CheckDlgButton(dlg, IDC_FP_HASH_ALG_SHA256, TRUE);
993     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
994 maya 3227 }
995    
996 doda 6801 static int print_mp_int(char *buf, unsigned char *mp)
997 maya 3227 {
998     int i = 0, j, k;
999     BIGNUM *num = BN_new();
1000     int ch;
1001    
1002     BN_bin2bn(mp + 2, (get_ushort16_MSBfirst(mp) + 7) / 8, num);
1003    
1004     do {
1005     buf[i] = (char) ((BN_div_word(num, 10)) + '0');
1006     i++;
1007     } while (!BN_is_zero(num));
1008    
1009     /* we need to reverse the digits */
1010     for (j = 0, k = i - 1; j < k; j++, k--) {
1011     ch = buf[j];
1012     buf[j] = buf[k];
1013     buf[k] = ch;
1014     }
1015    
1016     buf[i] = 0;
1017     return i;
1018     }
1019    
1020     //
1021     // known_hosts �t�@�C�������������G���g�������������B
1022     //
1023 doda 6801 static char *format_host_key(PTInstVar pvar)
1024 maya 3227 {
1025     int host_len = strlen(pvar->hosts_state.prefetched_hostname);
1026     char *result = NULL;
1027     int index;
1028 maya 4378 ssh_keytype type = pvar->hosts_state.hostkey.type;
1029 maya 3227
1030 maya 4321 switch (type) {
1031     case KEY_RSA1:
1032     {
1033 maya 3227 int result_len = host_len + 50 + 8 +
1034     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.exp) / 3 +
1035     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.mod) / 3;
1036 doda 6801 result = (char *) malloc(result_len);
1037 maya 3227
1038     if (pvar->ssh_state.tcpport == 22) {
1039     strncpy_s(result, result_len, pvar->hosts_state.prefetched_hostname, _TRUNCATE);
1040     index = host_len;
1041     }
1042     else {
1043     _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
1044     pvar->hosts_state.prefetched_hostname,
1045     pvar->ssh_state.tcpport);
1046     index = strlen(result);
1047     }
1048    
1049     _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
1050     " %d ", pvar->hosts_state.hostkey.bits);
1051     index += strlen(result + index);
1052     index += print_mp_int(result + index, pvar->hosts_state.hostkey.exp);
1053     result[index] = ' ';
1054     index++;
1055     index += print_mp_int(result + index, pvar->hosts_state.hostkey.mod);
1056     strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
1057    
1058 maya 4321 break;
1059     }
1060    
1061     case KEY_RSA:
1062     case KEY_DSA:
1063     case KEY_ECDSA256:
1064     case KEY_ECDSA384:
1065     case KEY_ECDSA521:
1066 yutakapon 5545 case KEY_ED25519:
1067 maya 4321 {
1068 maya 3227 Key *key = &pvar->hosts_state.hostkey;
1069     char *blob = NULL;
1070     int blen, uulen, msize;
1071     char *uu = NULL;
1072     int n;
1073    
1074     key_to_blob(key, &blob, &blen);
1075     uulen = 2 * blen;
1076     uu = malloc(uulen);
1077     if (uu == NULL) {
1078     goto error;
1079     }
1080     n = uuencode(blob, blen, uu, uulen);
1081     if (n > 0) {
1082     msize = host_len + 50 + uulen;
1083     result = malloc(msize);
1084     if (result == NULL) {
1085     goto error;
1086     }
1087    
1088     // setup
1089     if (pvar->ssh_state.tcpport == 22) {
1090     _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
1091     pvar->hosts_state.prefetched_hostname,
1092     get_sshname_from_key(key),
1093     uu);
1094     } else {
1095     _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
1096     pvar->hosts_state.prefetched_hostname,
1097     pvar->ssh_state.tcpport,
1098     get_sshname_from_key(key),
1099     uu);
1100     }
1101     }
1102     error:
1103     if (blob != NULL)
1104     free(blob);
1105     if (uu != NULL)
1106     free(uu);
1107    
1108 maya 4321 break;
1109     }
1110    
1111     default:
1112 maya 3227 return NULL;
1113    
1114     }
1115    
1116     return result;
1117     }
1118    
1119 doda 6801 static char *format_specified_host_key(Key *key, char *hostname, unsigned short tcpport)
1120 yutakapon 5849 {
1121     int host_len = strlen(hostname);
1122     char *result = NULL;
1123     int index;
1124     ssh_keytype type = key->type;
1125    
1126     switch (type) {
1127     case KEY_RSA1:
1128     {
1129     int result_len = host_len + 50 + 8 +
1130     get_ushort16_MSBfirst(key->exp) / 3 +
1131     get_ushort16_MSBfirst(key->mod) / 3;
1132 doda 6801 result = (char *) malloc(result_len);
1133 yutakapon 5849
1134     if (tcpport == 22) {
1135     strncpy_s(result, result_len, hostname, _TRUNCATE);
1136     index = host_len;
1137     }
1138     else {
1139     _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
1140     hostname,
1141     tcpport);
1142     index = strlen(result);
1143     }
1144    
1145     _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
1146     " %d ", key->bits);
1147     index += strlen(result + index);
1148     index += print_mp_int(result + index, key->exp);
1149     result[index] = ' ';
1150     index++;
1151     index += print_mp_int(result + index, key->mod);
1152     strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
1153    
1154     break;
1155     }
1156    
1157     case KEY_RSA:
1158     case KEY_DSA:
1159     case KEY_ECDSA256:
1160     case KEY_ECDSA384:
1161     case KEY_ECDSA521:
1162     case KEY_ED25519:
1163     {
1164     //Key *key = &pvar->hosts_state.hostkey;
1165     char *blob = NULL;
1166     int blen, uulen, msize;
1167     char *uu = NULL;
1168     int n;
1169    
1170     key_to_blob(key, &blob, &blen);
1171     uulen = 2 * blen;
1172     uu = malloc(uulen);
1173     if (uu == NULL) {
1174     goto error;
1175     }
1176     n = uuencode(blob, blen, uu, uulen);
1177     if (n > 0) {
1178     msize = host_len + 50 + uulen;
1179     result = malloc(msize);
1180     if (result == NULL) {
1181     goto error;
1182     }
1183    
1184     // setup
1185     if (tcpport == 22) {
1186     _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
1187     hostname,
1188     get_sshname_from_key(key),
1189     uu);
1190     }
1191     else {
1192     _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
1193     hostname,
1194     tcpport,
1195     get_sshname_from_key(key),
1196     uu);
1197     }
1198     }
1199     error:
1200     if (blob != NULL)
1201     free(blob);
1202     if (uu != NULL)
1203     free(uu);
1204    
1205     break;
1206     }
1207    
1208     default:
1209     return NULL;
1210    
1211     }
1212    
1213     return result;
1214     }
1215    
1216 maya 3227 static void add_host_key(PTInstVar pvar)
1217     {
1218 doda 6801 char *name = NULL;
1219 maya 3227
1220     if ( pvar->hosts_state.file_names != NULL)
1221     name = pvar->hosts_state.file_names[0];
1222    
1223     if (name == NULL || name[0] == 0) {
1224     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1225     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1226     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1227     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1228     } else {
1229 doda 6801 char *keydata = format_host_key(pvar);
1230 maya 3227 int length = strlen(keydata);
1231     int fd;
1232     int amount_written;
1233     int close_result;
1234     char buf[FILENAME_MAX];
1235    
1236     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1237     fd = _open(buf,
1238     _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1239     _S_IREAD | _S_IWRITE);
1240     if (fd == -1) {
1241     if (errno == EACCES) {
1242     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1243     "An error occurred while trying to write the host key.\n"
1244     "You do not have permission to write to the known-hosts file.");
1245     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1246     } else {
1247     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1248     "An error occurred while trying to write the host key.\n"
1249     "The host key could not be written.");
1250     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1251     }
1252     return;
1253     }
1254    
1255     amount_written = _write(fd, keydata, length);
1256     free(keydata);
1257     close_result = _close(fd);
1258    
1259     if (amount_written != length || close_result == -1) {
1260     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1261     "An error occurred while trying to write the host key.\n"
1262     "The host key could not be written.");
1263     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1264     }
1265     }
1266     }
1267    
1268 yutakapon 5849 // �w�������L�[�� known_hosts �����������B
1269     void HOSTS_add_host_key(PTInstVar pvar, Key *key)
1270     {
1271 doda 6801 char *name = NULL;
1272 yutakapon 5849 char *hostname;
1273     unsigned short tcpport;
1274    
1275     hostname = pvar->ssh_state.hostname;
1276     tcpport = pvar->ssh_state.tcpport;
1277    
1278     if (pvar->hosts_state.file_names != NULL)
1279     name = pvar->hosts_state.file_names[0];
1280    
1281     if (name == NULL || name[0] == 0) {
1282     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1283     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1284     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1285     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1286     }
1287     else {
1288 doda 6801 char *keydata = format_specified_host_key(key, hostname, tcpport);
1289 yutakapon 5849 int length = strlen(keydata);
1290     int fd;
1291     int amount_written;
1292     int close_result;
1293     char buf[FILENAME_MAX];
1294    
1295     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1296     fd = _open(buf,
1297     _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1298     _S_IREAD | _S_IWRITE);
1299     if (fd == -1) {
1300     if (errno == EACCES) {
1301     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1302     "An error occurred while trying to write the host key.\n"
1303     "You do not have permission to write to the known-hosts file.");
1304     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1305     }
1306     else {
1307     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1308     "An error occurred while trying to write the host key.\n"
1309     "The host key could not be written.");
1310     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1311     }
1312     return;
1313     }
1314    
1315     amount_written = _write(fd, keydata, length);
1316     free(keydata);
1317     close_result = _close(fd);
1318    
1319     if (amount_written != length || close_result == -1) {
1320     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1321     "An error occurred while trying to write the host key.\n"
1322     "The host key could not be written.");
1323     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1324     }
1325     }
1326     }
1327    
1328 maya 3227 //
1329     // �����z�X�g�����e���������L�[����������
1330     // add_host_key ����������������
1331     //
1332     static void delete_different_key(PTInstVar pvar)
1333     {
1334 doda 6801 char *name = pvar->hosts_state.file_names[0];
1335 maya 3227
1336     if (name == NULL || name[0] == 0) {
1337     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1338     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1339     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1340     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1341     }
1342     else {
1343 maya 6152 Key key; // known_hosts���o�^������������
1344 maya 3227 int length;
1345     char filename[MAX_PATH];
1346     char tmp[L_tmpnam];
1347     int fd;
1348     int amount_written = 0;
1349     int close_result;
1350     int data_index = 0;
1351     char buf[FILENAME_MAX];
1352    
1353     // �������������t�@�C�����J��
1354     _getcwd(filename, sizeof(filename));
1355     tmpnam_s(tmp,sizeof(tmp));
1356     strcat_s(filename, sizeof(filename), tmp);
1357     fd = _open(filename,
1358     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1359     _S_IREAD | _S_IWRITE);
1360    
1361     if (fd == -1) {
1362     if (errno == EACCES) {
1363     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1364     "An error occurred while trying to write the host key.\n"
1365     "You do not have permission to write to the known-hosts file.");
1366     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1367     } else {
1368     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1369     "An error occurred while trying to write the host key.\n"
1370     "The host key could not be written.");
1371     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1372     }
1373     return;
1374     }
1375    
1376 maya 6152 // �t�@�C��������������
1377 maya 6147 memset(&key, 0, sizeof(key));
1378 maya 3227 begin_read_host_files(pvar, 0);
1379     do {
1380     int host_index = 0;
1381     int matched = 0;
1382     int keybits = 0;
1383 doda 6801 char *data;
1384 maya 3227 int do_write = 0;
1385     length = amount_written = 0;
1386    
1387 maya 6152 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1, &key)) {
1388 maya 3227 break;
1389     }
1390    
1391     if (data_index == pvar->hosts_state.file_data_index) {
1392     // index ���i������ == ��������������
1393     break;
1394     }
1395    
1396     data = pvar->hosts_state.file_data + data_index;
1397     host_index = eat_spaces(data);
1398    
1399     if (data[host_index] == '#') {
1400     do_write = 1;
1401     }
1402     else {
1403     // �z�X�g������
1404     host_index--;
1405     do {
1406     int negated;
1407     int bracketed;
1408     char *end_bracket;
1409     int host_matched = 0;
1410     unsigned short keyfile_port = 22;
1411    
1412     host_index++;
1413     negated = data[host_index] == '!';
1414    
1415     if (negated) {
1416     host_index++;
1417     bracketed = data[host_index] == '[';
1418     if (bracketed) {
1419     end_bracket = strstr(data + host_index + 1, "]:");
1420     if (end_bracket != NULL) {
1421     *end_bracket = ' ';
1422     host_index++;
1423     }
1424     }
1425     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1426     if (bracketed && end_bracket != NULL) {
1427     *end_bracket = ']';
1428     keyfile_port = atoi(end_bracket + 2);
1429     }
1430     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1431     matched = 0;
1432     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1433     host_index--;
1434     do {
1435     host_index++;
1436     host_index += eat_to_end_of_pattern(data + host_index);
1437     } while (data[host_index] == ',');
1438     break;
1439     }
1440     }
1441     else {
1442     bracketed = data[host_index] == '[';
1443     if (bracketed) {
1444     end_bracket = strstr(data + host_index + 1, "]:");
1445     if (end_bracket != NULL) {
1446     *end_bracket = ' ';
1447     host_index++;
1448     }
1449     }
1450     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1451     if (bracketed && end_bracket != NULL) {
1452     *end_bracket = ']';
1453     keyfile_port = atoi(end_bracket + 2);
1454     }
1455     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1456     matched = 1;
1457     }
1458     }
1459     host_index += eat_to_end_of_pattern(data + host_index);
1460     } while (data[host_index] == ',');
1461    
1462     // �z�X�g������������
1463 maya 4332 if (!matched) {
1464 maya 3227 do_write = 1;
1465     }
1466 maya 4332 // �z�X�g��������
1467 maya 3227 else {
1468 maya 4332 // �����`�������� or ���v�����L�[
1469 maya 6152 if (HOSTS_compare_public_key(&pvar->hosts_state.hostkey, &key) != 0) {
1470 maya 4332 do_write = 1;
1471 maya 3227 }
1472 maya 4332 // �����`�������������v�������L�[���X�L�b�v������
1473 maya 3227 }
1474     }
1475    
1476     // ������������
1477     if (do_write) {
1478     length = pvar->hosts_state.file_data_index - data_index;
1479     amount_written =
1480     _write(fd, pvar->hosts_state.file_data + data_index,
1481     length);
1482    
1483     if (amount_written != length) {
1484     goto error1;
1485     }
1486     }
1487     data_index = pvar->hosts_state.file_data_index;
1488     } while (1); // ������������
1489    
1490     error1:
1491     close_result = _close(fd);
1492     if (amount_written != length || close_result == -1) {
1493     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1494     "An error occurred while trying to write the host key.\n"
1495     "The host key could not be written.");
1496     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1497     goto error2;
1498     }
1499    
1500     // �������������t�@�C���������l�[��
1501     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1502     _unlink(buf);
1503     rename(filename, buf);
1504    
1505     error2:
1506     _unlink(filename);
1507    
1508     finish_read_host_files(pvar, 0);
1509 yutakapon 5545
1510     // ���������������������������B
1511 maya 6147 key_init(&key);
1512 maya 3227 }
1513     }
1514    
1515 yutakapon 5849
1516     void HOSTS_delete_all_hostkeys(PTInstVar pvar)
1517     {
1518 doda 6801 char *name = pvar->hosts_state.file_names[0];
1519 yutakapon 5849 char *hostname;
1520     unsigned short tcpport;
1521    
1522     hostname = pvar->ssh_state.hostname;
1523     tcpport = pvar->ssh_state.tcpport;
1524    
1525     if (name == NULL || name[0] == 0) {
1526     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1527     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1528     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1529     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1530     }
1531     else {
1532 maya 6152 Key key; // known_hosts���o�^������������
1533 yutakapon 5849 int length;
1534     char filename[MAX_PATH];
1535     char tmp[L_tmpnam];
1536     int fd;
1537     int amount_written = 0;
1538     int close_result;
1539     int data_index = 0;
1540     char buf[FILENAME_MAX];
1541    
1542     // �������������t�@�C�����J��
1543     _getcwd(filename, sizeof(filename));
1544     tmpnam_s(tmp, sizeof(tmp));
1545     strcat_s(filename, sizeof(filename), tmp);
1546     fd = _open(filename,
1547     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1548     _S_IREAD | _S_IWRITE);
1549    
1550     if (fd == -1) {
1551     if (errno == EACCES) {
1552     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1553     "An error occurred while trying to write the host key.\n"
1554     "You do not have permission to write to the known-hosts file.");
1555     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1556     }
1557     else {
1558     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1559     "An error occurred while trying to write the host key.\n"
1560     "The host key could not be written.");
1561     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1562     }
1563     return;
1564     }
1565    
1566 maya 6152 // �t�@�C��������������
1567 maya 6147 memset(&key, 0, sizeof(key));
1568 yutakapon 5849 begin_read_host_files(pvar, 0);
1569     do {
1570     int host_index = 0;
1571     int matched = 0;
1572     int keybits = 0;
1573 doda 6801 char *data;
1574 yutakapon 5849 int do_write = 0;
1575     length = amount_written = 0;
1576    
1577 maya 6152 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1, &key)) {
1578 yutakapon 5849 break;
1579     }
1580    
1581     if (data_index == pvar->hosts_state.file_data_index) {
1582     // index ���i������ == ��������������
1583     break;
1584     }
1585    
1586     data = pvar->hosts_state.file_data + data_index;
1587     host_index = eat_spaces(data);
1588    
1589     if (data[host_index] == '#') {
1590     do_write = 1;
1591     }
1592     else {
1593     // �z�X�g������
1594     host_index--;
1595     do {
1596     int negated;
1597     int bracketed;
1598     char *end_bracket;
1599     int host_matched = 0;
1600     unsigned short keyfile_port = 22;
1601    
1602     host_index++;
1603     negated = data[host_index] == '!';
1604    
1605     if (negated) {
1606     host_index++;
1607     bracketed = data[host_index] == '[';
1608     if (bracketed) {
1609     end_bracket = strstr(data + host_index + 1, "]:");
1610     if (end_bracket != NULL) {
1611     *end_bracket = ' ';
1612     host_index++;
1613     }
1614     }
1615     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1616     if (bracketed && end_bracket != NULL) {
1617     *end_bracket = ']';
1618     keyfile_port = atoi(end_bracket + 2);
1619     }
1620     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1621     matched = 0;
1622     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1623     host_index--;
1624     do {
1625     host_index++;
1626     host_index += eat_to_end_of_pattern(data + host_index);
1627     } while (data[host_index] == ',');
1628     break;
1629     }
1630     }
1631     else {
1632     bracketed = data[host_index] == '[';
1633     if (bracketed) {
1634     end_bracket = strstr(data + host_index + 1, "]:");
1635     if (end_bracket != NULL) {
1636     *end_bracket = ' ';
1637     host_index++;
1638     }
1639     }
1640     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1641     if (bracketed && end_bracket != NULL) {
1642     *end_bracket = ']';
1643     keyfile_port = atoi(end_bracket + 2);
1644     }
1645     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1646     matched = 1;
1647     }
1648     }
1649     host_index += eat_to_end_of_pattern(data + host_index);
1650     } while (data[host_index] == ',');
1651    
1652     // �z�X�g������������
1653     if (!matched) {
1654     do_write = 1;
1655     }
1656     // �z�X�g��������
1657     else {
1658     // ���������������������B
1659    
1660     }
1661     }
1662    
1663     // ������������
1664     if (do_write) {
1665     length = pvar->hosts_state.file_data_index - data_index;
1666     amount_written =
1667     _write(fd, pvar->hosts_state.file_data + data_index,
1668     length);
1669    
1670     if (amount_written != length) {
1671     goto error1;
1672     }
1673     }
1674     data_index = pvar->hosts_state.file_data_index;
1675     } while (1); // ������������
1676    
1677     error1:
1678     close_result = _close(fd);
1679     if (amount_written != length || close_result == -1) {
1680     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1681     "An error occurred while trying to write the host key.\n"
1682     "The host key could not be written.");
1683     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1684     goto error2;
1685     }
1686    
1687     // �������������t�@�C���������l�[��
1688     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1689     _unlink(buf);
1690     rename(filename, buf);
1691    
1692     error2:
1693     _unlink(filename);
1694    
1695     finish_read_host_files(pvar, 0);
1696    
1697     // ���������������������������B
1698 maya 6147 key_init(&key);
1699 yutakapon 5849 }
1700     }
1701    
1702    
1703 maya 3227 //
1704     // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1705     // ���[�U���m�F�������B
1706     // TODO: finger print���\�����s���B
1707     // (2006.3.25 yutaka)
1708     //
1709     static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1710     LPARAM lParam)
1711     {
1712     PTInstVar pvar;
1713 zmatsuo 7560 // LOGFONT logfont;
1714     // HFONT font;
1715 maya 3227 char uimsg[MAX_UIMSG];
1716    
1717     switch (msg) {
1718     case WM_INITDIALOG:
1719     pvar = (PTInstVar) lParam;
1720     pvar->hosts_state.hosts_dialog = dlg;
1721     SetWindowLong(dlg, DWL_USER, lParam);
1722    
1723     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1724     GetWindowText(dlg, uimsg, sizeof(uimsg));
1725 doda 6688 UTIL_get_lang_msg("DLG_UNKNOWNHOST_TITLE", pvar, uimsg);
1726 maya 3227 SetWindowText(dlg, pvar->ts->UIMsg);
1727     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1728 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING", pvar, uimsg);
1729 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1730     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1731 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING2", pvar, uimsg);
1732 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1733     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1734     UTIL_get_lang_msg("DLG_UNKNOWNHOST_FINGERPRINT", pvar, uimsg);
1735     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1736 maya 6132 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
1737     UTIL_get_lang_msg("DLG_UNKNOWNHOST_FP_HASH_ALGORITHM", pvar, uimsg);
1738     SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
1739 maya 3227 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1740     UTIL_get_lang_msg("DLG_UNKNOWNHOST_ADD", pvar, uimsg);
1741     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1742     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1743     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1744     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1745     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1746     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1747     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1748    
1749 doda 4559 switch (pvar->dns_key_check) {
1750     case DNS_VERIFY_NOTFOUND:
1751 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1752 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1753     break;
1754     case DNS_VERIFY_MATCH:
1755     case DNS_VERIFY_AUTH_MATCH:
1756 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1757 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1758     break;
1759     case DNS_VERIFY_MISMATCH:
1760     case DNS_VERIFY_AUTH_MISMATCH:
1761 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1762 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1763     break;
1764     case DNS_VERIFY_DIFFERENTTYPE:
1765     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1766 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1767 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1768     break;
1769     }
1770    
1771     switch (pvar->dns_key_check) {
1772     case DNS_VERIFY_MATCH:
1773     case DNS_VERIFY_MISMATCH:
1774     case DNS_VERIFY_DIFFERENTTYPE:
1775 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1776 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1777     break;
1778     case DNS_VERIFY_AUTH_MATCH:
1779     case DNS_VERIFY_AUTH_MISMATCH:
1780     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1781 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1782 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1783     break;
1784     }
1785    
1786 maya 3227 init_hosts_dlg(pvar, dlg);
1787 zmatsuo 7560 #if 0
1788 maya 3227 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1789     GetObject(font, sizeof(LOGFONT), &logfont);
1790     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1791     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1792     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1793 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1794     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1795 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1796 maya 6132 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1797     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1798     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1799     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
1800 maya 3227 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1801     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1802     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1803     }
1804     else {
1805     DlgHostsAddFont = NULL;
1806     }
1807 zmatsuo 7560 #endif
1808 maya 3227 // add host check box���`�F�b�N���f�t�H���g������������
1809     SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1810    
1811     return TRUE; /* because we do not set the focus */
1812    
1813     case WM_COMMAND:
1814     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1815    
1816     switch (LOWORD(wParam)) {
1817     case IDC_CONTINUE:
1818 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1819     if (!pvar->cv->Ready) {
1820     goto canceled;
1821     }
1822    
1823 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1824     add_host_key(pvar);
1825     }
1826    
1827     if (SSHv1(pvar)) {
1828     SSH_notify_host_OK(pvar);
1829     } else { // SSH2
1830     // SSH2���������� SSH_notify_host_OK() �������B
1831     }
1832    
1833     pvar->hosts_state.hosts_dialog = NULL;
1834    
1835     EndDialog(dlg, 1);
1836 zmatsuo 7560 #if 0
1837 maya 3227 if (DlgHostsAddFont != NULL) {
1838     DeleteObject(DlgHostsAddFont);
1839     }
1840 zmatsuo 7560 #endif
1841 maya 3227 return TRUE;
1842    
1843     case IDCANCEL: /* kill the connection */
1844 yutakapon 5562 canceled:
1845 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
1846 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
1847 maya 3227 EndDialog(dlg, 0);
1848 zmatsuo 7560 #if 0
1849 maya 3227 if (DlgHostsAddFont != NULL) {
1850     DeleteObject(DlgHostsAddFont);
1851     }
1852 zmatsuo 7560 #endif
1853 maya 3227 return TRUE;
1854    
1855 maya 6132 case IDC_FP_HASH_ALG_MD5:
1856     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
1857     return TRUE;
1858    
1859     case IDC_FP_HASH_ALG_SHA256:
1860     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
1861     return TRUE;
1862    
1863 maya 3227 default:
1864     return FALSE;
1865     }
1866    
1867     default:
1868     return FALSE;
1869     }
1870     }
1871    
1872     //
1873     // �u�����������m�F�_�C�A���O������
1874     //
1875     static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1876     LPARAM lParam)
1877     {
1878     PTInstVar pvar;
1879 zmatsuo 7560 // LOGFONT logfont;
1880     // HFONT font;
1881 maya 3227 char uimsg[MAX_UIMSG];
1882    
1883     switch (msg) {
1884     case WM_INITDIALOG:
1885     pvar = (PTInstVar) lParam;
1886     pvar->hosts_state.hosts_dialog = dlg;
1887     SetWindowLong(dlg, DWL_USER, lParam);
1888    
1889     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1890     GetWindowText(dlg, uimsg, sizeof(uimsg));
1891 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
1892 maya 3227 SetWindowText(dlg, pvar->ts->UIMsg);
1893     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1894 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
1895 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1896     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1897 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
1898 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1899     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1900 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
1901 maya 3227 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1902 maya 6132 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
1903     UTIL_get_lang_msg("DLG_DIFFERENTKEY_FP_HASH_ALGORITHM", pvar, uimsg);
1904     SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
1905 maya 3227 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1906 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
1907 maya 3227 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1908     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1909     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1910     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1911     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1912     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1913     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1914    
1915 doda 4559 switch (pvar->dns_key_check) {
1916     case DNS_VERIFY_NOTFOUND:
1917 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1918 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1919     break;
1920     case DNS_VERIFY_MATCH:
1921     case DNS_VERIFY_AUTH_MATCH:
1922 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1923 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1924     break;
1925     case DNS_VERIFY_MISMATCH:
1926     case DNS_VERIFY_AUTH_MISMATCH:
1927 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1928 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1929     break;
1930     case DNS_VERIFY_DIFFERENTTYPE:
1931     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1932 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1933 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1934     break;
1935     }
1936    
1937     switch (pvar->dns_key_check) {
1938     case DNS_VERIFY_MATCH:
1939     case DNS_VERIFY_MISMATCH:
1940     case DNS_VERIFY_DIFFERENTTYPE:
1941 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1942 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1943     break;
1944     case DNS_VERIFY_AUTH_MATCH:
1945     case DNS_VERIFY_AUTH_MISMATCH:
1946     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1947 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1948 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1949     break;
1950     }
1951    
1952 maya 3227 init_hosts_dlg(pvar, dlg);
1953 zmatsuo 7560 #if 0
1954 maya 3227 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1955     GetObject(font, sizeof(LOGFONT), &logfont);
1956     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
1957     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1958     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1959 maya 6132 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1960     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1961 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1962 maya 6132 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
1963     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
1964     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
1965     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE, 0));
1966 maya 3227 SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1967     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1968     }
1969     else {
1970     DlgHostsReplaceFont = NULL;
1971     }
1972 zmatsuo 7560 #endif
1973 maya 3227 // �f�t�H���g���`�F�b�N����������
1974     return TRUE; /* because we do not set the focus */
1975    
1976     case WM_COMMAND:
1977     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1978    
1979     switch (LOWORD(wParam)) {
1980     case IDC_CONTINUE:
1981 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1982     if (!pvar->cv->Ready) {
1983     goto canceled;
1984     }
1985    
1986 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1987     add_host_key(pvar);
1988     delete_different_key(pvar);
1989     }
1990    
1991     if (SSHv1(pvar)) {
1992     SSH_notify_host_OK(pvar);
1993     } else { // SSH2
1994     // SSH2���������� SSH_notify_host_OK() �������B
1995     }
1996    
1997     pvar->hosts_state.hosts_dialog = NULL;
1998    
1999     EndDialog(dlg, 1);
2000 zmatsuo 7560 #if 0
2001 maya 3227 if (DlgHostsReplaceFont != NULL) {
2002     DeleteObject(DlgHostsReplaceFont);
2003     }
2004 zmatsuo 7560 #endif
2005 maya 3227 return TRUE;
2006    
2007     case IDCANCEL: /* kill the connection */
2008 yutakapon 5562 canceled:
2009 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
2010 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
2011 maya 3227 EndDialog(dlg, 0);
2012 zmatsuo 7560 #if 0
2013 maya 3227 if (DlgHostsReplaceFont != NULL) {
2014     DeleteObject(DlgHostsReplaceFont);
2015     }
2016 zmatsuo 7560 #endif
2017 maya 3227 return TRUE;
2018    
2019 maya 6132 case IDC_FP_HASH_ALG_MD5:
2020     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2021     return TRUE;
2022    
2023     case IDC_FP_HASH_ALG_SHA256:
2024     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2025     return TRUE;
2026    
2027 maya 3227 default:
2028     return FALSE;
2029     }
2030    
2031     default:
2032     return FALSE;
2033     }
2034     }
2035    
2036 maya 4332 //
2037     // �����z�X�g�����`�����������������m�F�_�C�A���O������
2038     //
2039     static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
2040     LPARAM lParam)
2041     {
2042     PTInstVar pvar;
2043 zmatsuo 7560 // LOGFONT logfont;
2044     // HFONT font;
2045 maya 4332 char uimsg[MAX_UIMSG];
2046    
2047     switch (msg) {
2048     case WM_INITDIALOG:
2049     pvar = (PTInstVar) lParam;
2050     pvar->hosts_state.hosts_dialog = dlg;
2051     SetWindowLong(dlg, DWL_USER, lParam);
2052    
2053     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
2054     GetWindowText(dlg, uimsg, sizeof(uimsg));
2055     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
2056     SetWindowText(dlg, pvar->ts->UIMsg);
2057     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
2058 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
2059 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
2060     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
2061 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
2062 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
2063     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
2064     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
2065     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
2066 maya 6132 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2067     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FP_HASH_ALGORITHM", pvar, uimsg);
2068     SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2069 maya 4332 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
2070     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
2071     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
2072     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
2073     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
2074     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
2075     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2076     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
2077     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2078    
2079 doda 4559 switch (pvar->dns_key_check) {
2080     case DNS_VERIFY_NOTFOUND:
2081 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
2082 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2083     break;
2084     case DNS_VERIFY_MATCH:
2085     case DNS_VERIFY_AUTH_MATCH:
2086 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
2087 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2088     break;
2089     case DNS_VERIFY_MISMATCH:
2090     case DNS_VERIFY_AUTH_MISMATCH:
2091 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
2092 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2093     break;
2094     case DNS_VERIFY_DIFFERENTTYPE:
2095     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2096 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
2097 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2098     break;
2099     }
2100    
2101     switch (pvar->dns_key_check) {
2102     case DNS_VERIFY_MATCH:
2103     case DNS_VERIFY_MISMATCH:
2104     case DNS_VERIFY_DIFFERENTTYPE:
2105 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
2106 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2107     break;
2108     case DNS_VERIFY_AUTH_MATCH:
2109     case DNS_VERIFY_AUTH_MISMATCH:
2110     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2111 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
2112 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2113     break;
2114     }
2115    
2116 maya 4332 init_hosts_dlg(pvar, dlg);
2117 zmatsuo 7560 #if 0
2118 maya 4332 font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
2119     GetObject(font, sizeof(LOGFONT), &logfont);
2120     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
2121     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2122     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2123 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2124     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2125 maya 4332 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2126 maya 6132 SendDlgItemMessage(dlg, IDC_FP_HASH_ALG, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2127     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_MD5, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2128     SendDlgItemMessage(dlg, IDC_FP_HASH_ALG_SHA256, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2129     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE, 0));
2130 maya 4332 SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2131     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2132     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
2133     }
2134     else {
2135     DlgHostsAddFont = NULL;
2136     }
2137 zmatsuo 7560 #endif
2138 maya 4332 // add host check box ���f�t�H���g�� off ������
2139     // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
2140    
2141     return TRUE; /* because we do not set the focus */
2142    
2143     case WM_COMMAND:
2144     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
2145    
2146     switch (LOWORD(wParam)) {
2147     case IDC_CONTINUE:
2148 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
2149     if (!pvar->cv->Ready) {
2150     goto canceled;
2151     }
2152    
2153 maya 4332 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
2154     add_host_key(pvar);
2155     }
2156    
2157     if (SSHv1(pvar)) {
2158     SSH_notify_host_OK(pvar);
2159     } else { // SSH2
2160     // SSH2���������� SSH_notify_host_OK() �������B
2161     }
2162    
2163     pvar->hosts_state.hosts_dialog = NULL;
2164    
2165     EndDialog(dlg, 1);
2166 zmatsuo 7560 #if 0
2167 maya 4332 if (DlgHostsAddFont != NULL) {
2168     DeleteObject(DlgHostsAddFont);
2169     }
2170 zmatsuo 7560 #endif
2171 maya 4332 return TRUE;
2172    
2173     case IDCANCEL: /* kill the connection */
2174 yutakapon 5562 canceled:
2175 maya 4332 pvar->hosts_state.hosts_dialog = NULL;
2176 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
2177 maya 4332 EndDialog(dlg, 0);
2178 zmatsuo 7560 #if 0
2179 maya 4332 if (DlgHostsAddFont != NULL) {
2180     DeleteObject(DlgHostsAddFont);
2181     }
2182 zmatsuo 7560 #endif
2183 maya 4332 return TRUE;
2184    
2185 maya 6132 case IDC_FP_HASH_ALG_MD5:
2186     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2187     return TRUE;
2188    
2189     case IDC_FP_HASH_ALG_SHA256:
2190     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2191     return TRUE;
2192    
2193 maya 4332 default:
2194     return FALSE;
2195     }
2196    
2197     default:
2198     return FALSE;
2199     }
2200     }
2201    
2202 maya 3227 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
2203     {
2204     if (pvar->hosts_state.hosts_dialog == NULL) {
2205     HWND cur_active = GetActiveWindow();
2206    
2207     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
2208     cur_active != NULL ? cur_active : wnd,
2209     hosts_add_dlg_proc, (LPARAM) pvar);
2210     }
2211     }
2212    
2213 maya 4330 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
2214 maya 3227 {
2215     if (pvar->hosts_state.hosts_dialog == NULL) {
2216     HWND cur_active = GetActiveWindow();
2217    
2218 maya 4330 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
2219 maya 3227 cur_active != NULL ? cur_active : wnd,
2220     hosts_replace_dlg_proc, (LPARAM) pvar);
2221     }
2222     }
2223    
2224 maya 4332 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
2225     {
2226     if (pvar->hosts_state.hosts_dialog == NULL) {
2227     HWND cur_active = GetActiveWindow();
2228    
2229     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
2230     cur_active != NULL ? cur_active : wnd,
2231     hosts_add2_dlg_proc, (LPARAM) pvar);
2232     }
2233     }
2234    
2235 maya 3227 //
2236     // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
2237 maya 6152 // key: �T�[�o���������J��
2238 maya 3227 //
2239     // SSH2���������� (2006.3.24 yutaka)
2240     //
2241 doda 6801 BOOL HOSTS_check_host_key(PTInstVar pvar, char *hostname, unsigned short tcpport, Key *key)
2242 maya 3227 {
2243 doda 4559 int found_different_key = 0, found_different_type_key = 0;
2244 maya 6152 Key key2; // known_hosts���o�^������������
2245 maya 3227
2246 doda 4559 pvar->dns_key_check = DNS_VERIFY_NONE;
2247    
2248 maya 3227 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
2249     if (pvar->hosts_state.prefetched_hostname != NULL
2250     && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
2251 maya 6152 && HOSTS_compare_public_key(&pvar->hosts_state.hostkey, key) == 1) {
2252 maya 3227
2253     if (SSHv1(pvar)) {
2254     SSH_notify_host_OK(pvar);
2255     } else {
2256     // SSH2���������� SSH_notify_host_OK() �������B
2257     }
2258     return TRUE;
2259     }
2260    
2261     // �������������������������A�������_���t�@�C��������������
2262 maya 6152 memset(&key2, 0, sizeof(key2));
2263 maya 3227 if (begin_read_host_files(pvar, 0)) {
2264     do {
2265 maya 6152 if (!read_host_key(pvar, hostname, tcpport, 0, 0, &key2)) {
2266 maya 3227 break;
2267     }
2268    
2269 maya 6152 if (key2.type != KEY_UNSPEC) {
2270     int match = HOSTS_compare_public_key(&key2, key);
2271 maya 4332 if (match == 1) {
2272 maya 3227 finish_read_host_files(pvar, 0);
2273     // ���������G���g�����Q�������A���v�����L�[�������������������B
2274     // SSH2���������������������������B(2006.3.29 yutaka)
2275     if (SSHv1(pvar)) {
2276     SSH_notify_host_OK(pvar);
2277     } else {
2278     // SSH2���������� SSH_notify_host_OK() �������B
2279     }
2280 maya 6998
2281     // About TTSSH �_�C�A���O�����\�����������A�������������������B
2282     key_copy(&pvar->hosts_state.hostkey, key);
2283    
2284 maya 3227 return TRUE;
2285 maya 4332 }
2286     else if (match == 0) {
2287 maya 3227 // �L�[�� known_hosts ���������������A�L�[�����e���������B
2288     found_different_key = 1;
2289     }
2290 maya 4332 else {
2291     // �L�[���`������������
2292     found_different_type_key = 1;
2293     }
2294 maya 3227 }
2295 maya 6152 } while (key2.type != KEY_UNSPEC); // �L�[�����������������������[�v����
2296 maya 3227
2297 maya 6152 key_init(&key2);
2298 maya 3227 finish_read_host_files(pvar, 0);
2299     }
2300    
2301     // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
2302 maya 6147 key_copy(&pvar->hosts_state.hostkey, key);
2303 maya 6145
2304 maya 3227 free(pvar->hosts_state.prefetched_hostname);
2305     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
2306    
2307 yutakapon 3631 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
2308     if (pvar->nocheck_known_hosts == TRUE) {
2309     return TRUE;
2310     }
2311    
2312 doda 4542 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
2313 maya 6063 pvar->dns_key_check = verify_hostkey_dns(pvar, hostname, key);
2314 doda 4542 }
2315    
2316 maya 3227 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
2317     // �������K�v�����������A�����R�[�������X�����B
2318     // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
2319     // (2007.10.1 yutaka)
2320     if (found_different_key) {
2321 maya 4330 HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar);
2322 maya 4332 }
2323     else if (found_different_type_key) {
2324     HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar);
2325     }
2326     else {
2327 maya 3227 HOSTS_do_unknown_host_dialog(pvar->NotificationWindow, pvar);
2328     }
2329    
2330     return TRUE;
2331     }
2332    
2333     void HOSTS_notify_disconnecting(PTInstVar pvar)
2334     {
2335     if (pvar->hosts_state.hosts_dialog != NULL) {
2336 doda 4531 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
2337 maya 3227 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
2338     EnableWindow(pvar->NotificationWindow, TRUE);
2339     }
2340     }
2341    
2342     void HOSTS_end(PTInstVar pvar)
2343     {
2344     int i;
2345    
2346     free(pvar->hosts_state.prefetched_hostname);
2347 maya 6147 key_init(&pvar->hosts_state.hostkey);
2348 maya 3227
2349     if (pvar->hosts_state.file_names != NULL) {
2350     for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
2351     free(pvar->hosts_state.file_names[i]);
2352     }
2353     free(pvar->hosts_state.file_names);
2354     }
2355     }

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