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 9350 - (hide annotations) (download) (as text)
Tue Aug 10 14:42:28 2021 UTC (2 years, 8 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 68547 byte(s)
UILanguageFile を unicode版(UILanguageFileW)へ切り替え

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