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

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