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 7889 - (hide annotations) (download) (as text)
Thu Jul 25 10:36:55 2019 UTC (4 years, 8 months ago) by yutakapon
File MIME type: text/x-csrc
File size: 65648 byte(s)
SSH1: 接続先のポート番号が22以外で、新規にknown_hostsファイルへホスト鍵を
書き込む時、アプリが落ちることがある問題を修正した。

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

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