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 7714 - (hide annotations) (download) (as text)
Mon May 27 13:23:19 2019 UTC (4 years, 10 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 65285 byte(s)
ttssh2、ビジュアル化fingerprintの表示に等幅フォントを設定する

- 従来のフォント関連の設定が不要になったのでUTIL_get_lang_font()を削除
- モニタのDPIに合わせて等幅フォントを取得する UTIL_get_lang_fixedfont()を追加
- DPIが変化したとき、OSがフォントを再設定するので、DPIに合わせたサイズのフォントを再設定するようにした
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     _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
1052     " %d ", pvar->hosts_state.hostkey.bits);
1053     index += strlen(result + index);
1054     index += print_mp_int(result + index, pvar->hosts_state.hostkey.exp);
1055     result[index] = ' ';
1056     index++;
1057     index += print_mp_int(result + index, pvar->hosts_state.hostkey.mod);
1058     strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
1059    
1060 maya 4321 break;
1061     }
1062    
1063     case KEY_RSA:
1064     case KEY_DSA:
1065     case KEY_ECDSA256:
1066     case KEY_ECDSA384:
1067     case KEY_ECDSA521:
1068 yutakapon 5545 case KEY_ED25519:
1069 maya 4321 {
1070 maya 3227 Key *key = &pvar->hosts_state.hostkey;
1071     char *blob = NULL;
1072     int blen, uulen, msize;
1073     char *uu = NULL;
1074     int n;
1075    
1076     key_to_blob(key, &blob, &blen);
1077     uulen = 2 * blen;
1078     uu = malloc(uulen);
1079     if (uu == NULL) {
1080     goto error;
1081     }
1082     n = uuencode(blob, blen, uu, uulen);
1083     if (n > 0) {
1084     msize = host_len + 50 + uulen;
1085     result = malloc(msize);
1086     if (result == NULL) {
1087     goto error;
1088     }
1089    
1090     // setup
1091     if (pvar->ssh_state.tcpport == 22) {
1092     _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
1093     pvar->hosts_state.prefetched_hostname,
1094     get_sshname_from_key(key),
1095     uu);
1096     } else {
1097     _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
1098     pvar->hosts_state.prefetched_hostname,
1099     pvar->ssh_state.tcpport,
1100     get_sshname_from_key(key),
1101     uu);
1102     }
1103     }
1104     error:
1105     if (blob != NULL)
1106     free(blob);
1107     if (uu != NULL)
1108     free(uu);
1109    
1110 maya 4321 break;
1111     }
1112    
1113     default:
1114 maya 3227 return NULL;
1115    
1116     }
1117    
1118     return result;
1119     }
1120    
1121 doda 6801 static char *format_specified_host_key(Key *key, char *hostname, unsigned short tcpport)
1122 yutakapon 5849 {
1123     int host_len = strlen(hostname);
1124     char *result = NULL;
1125     int index;
1126     ssh_keytype type = key->type;
1127    
1128     switch (type) {
1129     case KEY_RSA1:
1130     {
1131     int result_len = host_len + 50 + 8 +
1132     get_ushort16_MSBfirst(key->exp) / 3 +
1133     get_ushort16_MSBfirst(key->mod) / 3;
1134 doda 6801 result = (char *) malloc(result_len);
1135 yutakapon 5849
1136     if (tcpport == 22) {
1137     strncpy_s(result, result_len, hostname, _TRUNCATE);
1138     index = host_len;
1139     }
1140     else {
1141     _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
1142     hostname,
1143     tcpport);
1144     index = strlen(result);
1145     }
1146    
1147     _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
1148     " %d ", key->bits);
1149     index += strlen(result + index);
1150     index += print_mp_int(result + index, key->exp);
1151     result[index] = ' ';
1152     index++;
1153     index += print_mp_int(result + index, key->mod);
1154     strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
1155    
1156     break;
1157     }
1158    
1159     case KEY_RSA:
1160     case KEY_DSA:
1161     case KEY_ECDSA256:
1162     case KEY_ECDSA384:
1163     case KEY_ECDSA521:
1164     case KEY_ED25519:
1165     {
1166     //Key *key = &pvar->hosts_state.hostkey;
1167     char *blob = NULL;
1168     int blen, uulen, msize;
1169     char *uu = NULL;
1170     int n;
1171    
1172     key_to_blob(key, &blob, &blen);
1173     uulen = 2 * blen;
1174     uu = malloc(uulen);
1175     if (uu == NULL) {
1176     goto error;
1177     }
1178     n = uuencode(blob, blen, uu, uulen);
1179     if (n > 0) {
1180     msize = host_len + 50 + uulen;
1181     result = malloc(msize);
1182     if (result == NULL) {
1183     goto error;
1184     }
1185    
1186     // setup
1187     if (tcpport == 22) {
1188     _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
1189     hostname,
1190     get_sshname_from_key(key),
1191     uu);
1192     }
1193     else {
1194     _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
1195     hostname,
1196     tcpport,
1197     get_sshname_from_key(key),
1198     uu);
1199     }
1200     }
1201     error:
1202     if (blob != NULL)
1203     free(blob);
1204     if (uu != NULL)
1205     free(uu);
1206    
1207     break;
1208     }
1209    
1210     default:
1211     return NULL;
1212    
1213     }
1214    
1215     return result;
1216     }
1217    
1218 maya 3227 static void add_host_key(PTInstVar pvar)
1219     {
1220 doda 6801 char *name = NULL;
1221 maya 3227
1222     if ( pvar->hosts_state.file_names != NULL)
1223     name = pvar->hosts_state.file_names[0];
1224    
1225     if (name == NULL || name[0] == 0) {
1226     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1227     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1228     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1229     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1230     } else {
1231 doda 6801 char *keydata = format_host_key(pvar);
1232 maya 3227 int length = strlen(keydata);
1233     int fd;
1234     int amount_written;
1235     int close_result;
1236     char buf[FILENAME_MAX];
1237    
1238     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1239     fd = _open(buf,
1240     _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1241     _S_IREAD | _S_IWRITE);
1242     if (fd == -1) {
1243     if (errno == EACCES) {
1244     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1245     "An error occurred while trying to write the host key.\n"
1246     "You do not have permission to write to the known-hosts file.");
1247     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1248     } else {
1249     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1250     "An error occurred while trying to write the host key.\n"
1251     "The host key could not be written.");
1252     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1253     }
1254     return;
1255     }
1256    
1257     amount_written = _write(fd, keydata, length);
1258     free(keydata);
1259     close_result = _close(fd);
1260    
1261     if (amount_written != length || close_result == -1) {
1262     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1263     "An error occurred while trying to write the host key.\n"
1264     "The host key could not be written.");
1265     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1266     }
1267     }
1268     }
1269    
1270 yutakapon 5849 // �w�������L�[�� known_hosts �����������B
1271     void HOSTS_add_host_key(PTInstVar pvar, Key *key)
1272     {
1273 doda 6801 char *name = NULL;
1274 yutakapon 5849 char *hostname;
1275     unsigned short tcpport;
1276    
1277     hostname = pvar->ssh_state.hostname;
1278     tcpport = pvar->ssh_state.tcpport;
1279    
1280     if (pvar->hosts_state.file_names != NULL)
1281     name = pvar->hosts_state.file_names[0];
1282    
1283     if (name == NULL || name[0] == 0) {
1284     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1285     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1286     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1287     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1288     }
1289     else {
1290 doda 6801 char *keydata = format_specified_host_key(key, hostname, tcpport);
1291 yutakapon 5849 int length = strlen(keydata);
1292     int fd;
1293     int amount_written;
1294     int close_result;
1295     char buf[FILENAME_MAX];
1296    
1297     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1298     fd = _open(buf,
1299     _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1300     _S_IREAD | _S_IWRITE);
1301     if (fd == -1) {
1302     if (errno == EACCES) {
1303     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1304     "An error occurred while trying to write the host key.\n"
1305     "You do not have permission to write to the known-hosts file.");
1306     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1307     }
1308     else {
1309     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1310     "An error occurred while trying to write the host key.\n"
1311     "The host key could not be written.");
1312     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1313     }
1314     return;
1315     }
1316    
1317     amount_written = _write(fd, keydata, length);
1318     free(keydata);
1319     close_result = _close(fd);
1320    
1321     if (amount_written != length || close_result == -1) {
1322     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1323     "An error occurred while trying to write the host key.\n"
1324     "The host key could not be written.");
1325     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1326     }
1327     }
1328     }
1329    
1330 maya 3227 //
1331     // �����z�X�g�����e���������L�[����������
1332     // add_host_key ����������������
1333     //
1334     static void delete_different_key(PTInstVar pvar)
1335     {
1336 doda 6801 char *name = pvar->hosts_state.file_names[0];
1337 maya 3227
1338     if (name == NULL || name[0] == 0) {
1339     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1340     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1341     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1342     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1343     }
1344     else {
1345 maya 6152 Key key; // known_hosts���o�^������������
1346 maya 3227 int length;
1347     char filename[MAX_PATH];
1348     char tmp[L_tmpnam];
1349     int fd;
1350     int amount_written = 0;
1351     int close_result;
1352     int data_index = 0;
1353     char buf[FILENAME_MAX];
1354    
1355     // �������������t�@�C�����J��
1356     _getcwd(filename, sizeof(filename));
1357     tmpnam_s(tmp,sizeof(tmp));
1358     strcat_s(filename, sizeof(filename), tmp);
1359     fd = _open(filename,
1360     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1361     _S_IREAD | _S_IWRITE);
1362    
1363     if (fd == -1) {
1364     if (errno == EACCES) {
1365     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1366     "An error occurred while trying to write the host key.\n"
1367     "You do not have permission to write to the known-hosts file.");
1368     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1369     } else {
1370     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1371     "An error occurred while trying to write the host key.\n"
1372     "The host key could not be written.");
1373     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1374     }
1375     return;
1376     }
1377    
1378 maya 6152 // �t�@�C��������������
1379 maya 6147 memset(&key, 0, sizeof(key));
1380 maya 3227 begin_read_host_files(pvar, 0);
1381     do {
1382     int host_index = 0;
1383     int matched = 0;
1384     int keybits = 0;
1385 doda 6801 char *data;
1386 maya 3227 int do_write = 0;
1387     length = amount_written = 0;
1388    
1389 maya 6152 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1, &key)) {
1390 maya 3227 break;
1391     }
1392    
1393     if (data_index == pvar->hosts_state.file_data_index) {
1394     // index ���i������ == ��������������
1395     break;
1396     }
1397    
1398     data = pvar->hosts_state.file_data + data_index;
1399     host_index = eat_spaces(data);
1400    
1401     if (data[host_index] == '#') {
1402     do_write = 1;
1403     }
1404     else {
1405     // �z�X�g������
1406     host_index--;
1407     do {
1408     int negated;
1409     int bracketed;
1410     char *end_bracket;
1411     int host_matched = 0;
1412     unsigned short keyfile_port = 22;
1413    
1414     host_index++;
1415     negated = data[host_index] == '!';
1416    
1417     if (negated) {
1418     host_index++;
1419     bracketed = data[host_index] == '[';
1420     if (bracketed) {
1421     end_bracket = strstr(data + host_index + 1, "]:");
1422     if (end_bracket != NULL) {
1423     *end_bracket = ' ';
1424     host_index++;
1425     }
1426     }
1427     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1428     if (bracketed && end_bracket != NULL) {
1429     *end_bracket = ']';
1430     keyfile_port = atoi(end_bracket + 2);
1431     }
1432     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1433     matched = 0;
1434     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1435     host_index--;
1436     do {
1437     host_index++;
1438     host_index += eat_to_end_of_pattern(data + host_index);
1439     } while (data[host_index] == ',');
1440     break;
1441     }
1442     }
1443     else {
1444     bracketed = data[host_index] == '[';
1445     if (bracketed) {
1446     end_bracket = strstr(data + host_index + 1, "]:");
1447     if (end_bracket != NULL) {
1448     *end_bracket = ' ';
1449     host_index++;
1450     }
1451     }
1452     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1453     if (bracketed && end_bracket != NULL) {
1454     *end_bracket = ']';
1455     keyfile_port = atoi(end_bracket + 2);
1456     }
1457     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1458     matched = 1;
1459     }
1460     }
1461     host_index += eat_to_end_of_pattern(data + host_index);
1462     } while (data[host_index] == ',');
1463    
1464     // �z�X�g������������
1465 maya 4332 if (!matched) {
1466 maya 3227 do_write = 1;
1467     }
1468 maya 4332 // �z�X�g��������
1469 maya 3227 else {
1470 maya 4332 // �����`�������� or ���v�����L�[
1471 maya 6152 if (HOSTS_compare_public_key(&pvar->hosts_state.hostkey, &key) != 0) {
1472 maya 4332 do_write = 1;
1473 maya 3227 }
1474 maya 4332 // �����`�������������v�������L�[���X�L�b�v������
1475 maya 3227 }
1476     }
1477    
1478     // ������������
1479     if (do_write) {
1480     length = pvar->hosts_state.file_data_index - data_index;
1481     amount_written =
1482     _write(fd, pvar->hosts_state.file_data + data_index,
1483     length);
1484    
1485     if (amount_written != length) {
1486     goto error1;
1487     }
1488     }
1489     data_index = pvar->hosts_state.file_data_index;
1490     } while (1); // ������������
1491    
1492     error1:
1493     close_result = _close(fd);
1494     if (amount_written != length || close_result == -1) {
1495     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1496     "An error occurred while trying to write the host key.\n"
1497     "The host key could not be written.");
1498     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1499     goto error2;
1500     }
1501    
1502     // �������������t�@�C���������l�[��
1503     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1504     _unlink(buf);
1505     rename(filename, buf);
1506    
1507     error2:
1508     _unlink(filename);
1509    
1510     finish_read_host_files(pvar, 0);
1511 yutakapon 5545
1512     // ���������������������������B
1513 maya 6147 key_init(&key);
1514 maya 3227 }
1515     }
1516    
1517 yutakapon 5849
1518     void HOSTS_delete_all_hostkeys(PTInstVar pvar)
1519     {
1520 doda 6801 char *name = pvar->hosts_state.file_names[0];
1521 yutakapon 5849 char *hostname;
1522     unsigned short tcpport;
1523    
1524     hostname = pvar->ssh_state.hostname;
1525     tcpport = pvar->ssh_state.tcpport;
1526    
1527     if (name == NULL || name[0] == 0) {
1528     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1529     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1530     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1531     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1532     }
1533     else {
1534 maya 6152 Key key; // known_hosts���o�^������������
1535 yutakapon 5849 int length;
1536     char filename[MAX_PATH];
1537     char tmp[L_tmpnam];
1538     int fd;
1539     int amount_written = 0;
1540     int close_result;
1541     int data_index = 0;
1542     char buf[FILENAME_MAX];
1543    
1544     // �������������t�@�C�����J��
1545     _getcwd(filename, sizeof(filename));
1546     tmpnam_s(tmp, sizeof(tmp));
1547     strcat_s(filename, sizeof(filename), tmp);
1548     fd = _open(filename,
1549     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1550     _S_IREAD | _S_IWRITE);
1551    
1552     if (fd == -1) {
1553     if (errno == EACCES) {
1554     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1555     "An error occurred while trying to write the host key.\n"
1556     "You do not have permission to write to the known-hosts file.");
1557     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1558     }
1559     else {
1560     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1561     "An error occurred while trying to write the host key.\n"
1562     "The host key could not be written.");
1563     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1564     }
1565     return;
1566     }
1567    
1568 maya 6152 // �t�@�C��������������
1569 maya 6147 memset(&key, 0, sizeof(key));
1570 yutakapon 5849 begin_read_host_files(pvar, 0);
1571     do {
1572     int host_index = 0;
1573     int matched = 0;
1574     int keybits = 0;
1575 doda 6801 char *data;
1576 yutakapon 5849 int do_write = 0;
1577     length = amount_written = 0;
1578    
1579 maya 6152 if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1, &key)) {
1580 yutakapon 5849 break;
1581     }
1582    
1583     if (data_index == pvar->hosts_state.file_data_index) {
1584     // index ���i������ == ��������������
1585     break;
1586     }
1587    
1588     data = pvar->hosts_state.file_data + data_index;
1589     host_index = eat_spaces(data);
1590    
1591     if (data[host_index] == '#') {
1592     do_write = 1;
1593     }
1594     else {
1595     // �z�X�g������
1596     host_index--;
1597     do {
1598     int negated;
1599     int bracketed;
1600     char *end_bracket;
1601     int host_matched = 0;
1602     unsigned short keyfile_port = 22;
1603    
1604     host_index++;
1605     negated = data[host_index] == '!';
1606    
1607     if (negated) {
1608     host_index++;
1609     bracketed = data[host_index] == '[';
1610     if (bracketed) {
1611     end_bracket = strstr(data + host_index + 1, "]:");
1612     if (end_bracket != NULL) {
1613     *end_bracket = ' ';
1614     host_index++;
1615     }
1616     }
1617     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1618     if (bracketed && end_bracket != NULL) {
1619     *end_bracket = ']';
1620     keyfile_port = atoi(end_bracket + 2);
1621     }
1622     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1623     matched = 0;
1624     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1625     host_index--;
1626     do {
1627     host_index++;
1628     host_index += eat_to_end_of_pattern(data + host_index);
1629     } while (data[host_index] == ',');
1630     break;
1631     }
1632     }
1633     else {
1634     bracketed = data[host_index] == '[';
1635     if (bracketed) {
1636     end_bracket = strstr(data + host_index + 1, "]:");
1637     if (end_bracket != NULL) {
1638     *end_bracket = ' ';
1639     host_index++;
1640     }
1641     }
1642     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1643     if (bracketed && end_bracket != NULL) {
1644     *end_bracket = ']';
1645     keyfile_port = atoi(end_bracket + 2);
1646     }
1647     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1648     matched = 1;
1649     }
1650     }
1651     host_index += eat_to_end_of_pattern(data + host_index);
1652     } while (data[host_index] == ',');
1653    
1654     // �z�X�g������������
1655     if (!matched) {
1656     do_write = 1;
1657     }
1658     // �z�X�g��������
1659     else {
1660     // ���������������������B
1661    
1662     }
1663     }
1664    
1665     // ������������
1666     if (do_write) {
1667     length = pvar->hosts_state.file_data_index - data_index;
1668     amount_written =
1669     _write(fd, pvar->hosts_state.file_data + data_index,
1670     length);
1671    
1672     if (amount_written != length) {
1673     goto error1;
1674     }
1675     }
1676     data_index = pvar->hosts_state.file_data_index;
1677     } while (1); // ������������
1678    
1679     error1:
1680     close_result = _close(fd);
1681     if (amount_written != length || close_result == -1) {
1682     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1683     "An error occurred while trying to write the host key.\n"
1684     "The host key could not be written.");
1685     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1686     goto error2;
1687     }
1688    
1689     // �������������t�@�C���������l�[��
1690     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1691     _unlink(buf);
1692     rename(filename, buf);
1693    
1694     error2:
1695     _unlink(filename);
1696    
1697     finish_read_host_files(pvar, 0);
1698    
1699     // ���������������������������B
1700 maya 6147 key_init(&key);
1701 yutakapon 5849 }
1702     }
1703    
1704    
1705 maya 3227 //
1706     // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1707     // ���[�U���m�F�������B
1708     // TODO: finger print���\�����s���B
1709     // (2006.3.25 yutaka)
1710     //
1711     static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1712     LPARAM lParam)
1713     {
1714     PTInstVar pvar;
1715     char uimsg[MAX_UIMSG];
1716    
1717     switch (msg) {
1718     case WM_INITDIALOG:
1719     pvar = (PTInstVar) lParam;
1720     pvar->hosts_state.hosts_dialog = dlg;
1721     SetWindowLong(dlg, DWL_USER, lParam);
1722    
1723     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1724     GetWindowText(dlg, uimsg, sizeof(uimsg));
1725 doda 6688 UTIL_get_lang_msg("DLG_UNKNOWNHOST_TITLE", pvar, uimsg);
1726 maya 3227 SetWindowText(dlg, pvar->ts->UIMsg);
1727     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1728 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING", pvar, uimsg);
1729 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1730     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1731 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING2", pvar, uimsg);
1732 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1733     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1734     UTIL_get_lang_msg("DLG_UNKNOWNHOST_FINGERPRINT", pvar, uimsg);
1735     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1736 maya 6132 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
1737     UTIL_get_lang_msg("DLG_UNKNOWNHOST_FP_HASH_ALGORITHM", pvar, uimsg);
1738     SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
1739 maya 3227 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1740     UTIL_get_lang_msg("DLG_UNKNOWNHOST_ADD", pvar, uimsg);
1741     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1742     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1743     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1744     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1745     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1746     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1747     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1748    
1749 doda 4559 switch (pvar->dns_key_check) {
1750     case DNS_VERIFY_NOTFOUND:
1751 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1752 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1753     break;
1754     case DNS_VERIFY_MATCH:
1755     case DNS_VERIFY_AUTH_MATCH:
1756 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1757 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1758     break;
1759     case DNS_VERIFY_MISMATCH:
1760     case DNS_VERIFY_AUTH_MISMATCH:
1761 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1762 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1763     break;
1764     case DNS_VERIFY_DIFFERENTTYPE:
1765     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1766 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1767 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1768     break;
1769     }
1770    
1771     switch (pvar->dns_key_check) {
1772     case DNS_VERIFY_MATCH:
1773     case DNS_VERIFY_MISMATCH:
1774     case DNS_VERIFY_DIFFERENTTYPE:
1775 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1776 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1777     break;
1778     case DNS_VERIFY_AUTH_MATCH:
1779     case DNS_VERIFY_AUTH_MISMATCH:
1780     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1781 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1782 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1783     break;
1784     }
1785    
1786 maya 3227 init_hosts_dlg(pvar, dlg);
1787     // add host check box���`�F�b�N���f�t�H���g������������
1788     SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1789    
1790 zmatsuo 7592 CenterWindow(dlg, GetParent(dlg));
1791    
1792 maya 3227 return TRUE; /* because we do not set the focus */
1793    
1794     case WM_COMMAND:
1795     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1796    
1797     switch (LOWORD(wParam)) {
1798     case IDC_CONTINUE:
1799 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1800     if (!pvar->cv->Ready) {
1801     goto canceled;
1802     }
1803    
1804 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1805     add_host_key(pvar);
1806     }
1807    
1808     if (SSHv1(pvar)) {
1809     SSH_notify_host_OK(pvar);
1810     } else { // SSH2
1811     // SSH2���������� SSH_notify_host_OK() �������B
1812     }
1813    
1814     pvar->hosts_state.hosts_dialog = NULL;
1815    
1816     EndDialog(dlg, 1);
1817     return TRUE;
1818    
1819     case IDCANCEL: /* kill the connection */
1820 yutakapon 5562 canceled:
1821 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
1822 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
1823 maya 3227 EndDialog(dlg, 0);
1824     return TRUE;
1825    
1826 maya 6132 case IDC_FP_HASH_ALG_MD5:
1827     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
1828     return TRUE;
1829    
1830     case IDC_FP_HASH_ALG_SHA256:
1831     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
1832     return TRUE;
1833    
1834 maya 3227 default:
1835     return FALSE;
1836     }
1837    
1838 zmatsuo 7714 case WM_DPICHANGED:
1839     pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
1840     if (pvar->hFontFixed != NULL) {
1841     DeleteObject(pvar->hFontFixed);
1842     }
1843     pvar->hFontFixed = UTIL_get_lang_fixedfont(dlg, pvar->ts->UILanguageFile);
1844     if (pvar->hFontFixed != NULL) {
1845     SendDlgItemMessage(dlg, IDC_FP_RANDOMART, WM_SETFONT,
1846     (WPARAM)pvar->hFontFixed, MAKELPARAM(TRUE,0));
1847     }
1848     return FALSE;
1849    
1850     case WM_DESTROY:
1851     pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
1852     if (pvar->hFontFixed != NULL) {
1853     DeleteObject(pvar->hFontFixed);
1854     pvar->hFontFixed = NULL;
1855     }
1856     return FALSE;
1857    
1858 maya 3227 default:
1859     return FALSE;
1860     }
1861     }
1862    
1863     //
1864     // �u�����������m�F�_�C�A���O������
1865     //
1866     static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1867     LPARAM lParam)
1868     {
1869     PTInstVar pvar;
1870     char uimsg[MAX_UIMSG];
1871    
1872     switch (msg) {
1873     case WM_INITDIALOG:
1874     pvar = (PTInstVar) lParam;
1875     pvar->hosts_state.hosts_dialog = dlg;
1876     SetWindowLong(dlg, DWL_USER, lParam);
1877    
1878     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1879     GetWindowText(dlg, uimsg, sizeof(uimsg));
1880 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
1881 maya 3227 SetWindowText(dlg, pvar->ts->UIMsg);
1882     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1883 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
1884 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1885     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1886 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
1887 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1888     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1889 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
1890 maya 3227 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1891 maya 6132 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
1892     UTIL_get_lang_msg("DLG_DIFFERENTKEY_FP_HASH_ALGORITHM", pvar, uimsg);
1893     SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
1894 maya 3227 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1895 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
1896 maya 3227 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1897     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1898     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1899     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1900     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1901     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1902     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1903    
1904 doda 4559 switch (pvar->dns_key_check) {
1905     case DNS_VERIFY_NOTFOUND:
1906 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1907 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1908     break;
1909     case DNS_VERIFY_MATCH:
1910     case DNS_VERIFY_AUTH_MATCH:
1911 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1912 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1913     break;
1914     case DNS_VERIFY_MISMATCH:
1915     case DNS_VERIFY_AUTH_MISMATCH:
1916 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1917 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1918     break;
1919     case DNS_VERIFY_DIFFERENTTYPE:
1920     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1921 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1922 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1923     break;
1924     }
1925    
1926     switch (pvar->dns_key_check) {
1927     case DNS_VERIFY_MATCH:
1928     case DNS_VERIFY_MISMATCH:
1929     case DNS_VERIFY_DIFFERENTTYPE:
1930 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1931 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1932     break;
1933     case DNS_VERIFY_AUTH_MATCH:
1934     case DNS_VERIFY_AUTH_MISMATCH:
1935     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1936 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1937 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1938     break;
1939     }
1940    
1941 maya 3227 init_hosts_dlg(pvar, dlg);
1942 zmatsuo 7592 CenterWindow(dlg, GetParent(dlg));
1943 maya 3227 // �f�t�H���g���`�F�b�N����������
1944     return TRUE; /* because we do not set the focus */
1945    
1946     case WM_COMMAND:
1947     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1948    
1949     switch (LOWORD(wParam)) {
1950     case IDC_CONTINUE:
1951 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1952     if (!pvar->cv->Ready) {
1953     goto canceled;
1954     }
1955    
1956 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1957     add_host_key(pvar);
1958     delete_different_key(pvar);
1959     }
1960    
1961     if (SSHv1(pvar)) {
1962     SSH_notify_host_OK(pvar);
1963     } else { // SSH2
1964     // SSH2���������� SSH_notify_host_OK() �������B
1965     }
1966    
1967     pvar->hosts_state.hosts_dialog = NULL;
1968    
1969     EndDialog(dlg, 1);
1970     return TRUE;
1971    
1972     case IDCANCEL: /* kill the connection */
1973 yutakapon 5562 canceled:
1974 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
1975 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
1976 maya 3227 EndDialog(dlg, 0);
1977     return TRUE;
1978    
1979 maya 6132 case IDC_FP_HASH_ALG_MD5:
1980     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
1981     return TRUE;
1982    
1983     case IDC_FP_HASH_ALG_SHA256:
1984     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
1985     return TRUE;
1986    
1987 maya 3227 default:
1988     return FALSE;
1989     }
1990    
1991 zmatsuo 7714 case WM_DPICHANGED:
1992     pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
1993     if (pvar->hFontFixed != NULL) {
1994     DeleteObject(pvar->hFontFixed);
1995     }
1996     pvar->hFontFixed = UTIL_get_lang_fixedfont(dlg, pvar->ts->UILanguageFile);
1997     if (pvar->hFontFixed != NULL) {
1998     SendDlgItemMessage(dlg, IDC_FP_RANDOMART, WM_SETFONT,
1999     (WPARAM)pvar->hFontFixed, MAKELPARAM(TRUE,0));
2000     }
2001     return FALSE;
2002    
2003     case WM_DESTROY:
2004     pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
2005     if (pvar->hFontFixed != NULL) {
2006     DeleteObject(pvar->hFontFixed);
2007     pvar->hFontFixed = NULL;
2008     }
2009     return FALSE;
2010    
2011 maya 3227 default:
2012     return FALSE;
2013     }
2014     }
2015    
2016 maya 4332 //
2017     // �����z�X�g�����`�����������������m�F�_�C�A���O������
2018     //
2019     static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
2020     LPARAM lParam)
2021     {
2022     PTInstVar pvar;
2023     char uimsg[MAX_UIMSG];
2024    
2025     switch (msg) {
2026     case WM_INITDIALOG:
2027     pvar = (PTInstVar) lParam;
2028     pvar->hosts_state.hosts_dialog = dlg;
2029     SetWindowLong(dlg, DWL_USER, lParam);
2030    
2031     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
2032     GetWindowText(dlg, uimsg, sizeof(uimsg));
2033     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
2034     SetWindowText(dlg, pvar->ts->UIMsg);
2035     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
2036 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
2037 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
2038     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
2039 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
2040 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
2041     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
2042     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
2043     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
2044 maya 6132 GetDlgItemText(dlg, IDC_FP_HASH_ALG, uimsg, sizeof(uimsg));
2045     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FP_HASH_ALGORITHM", pvar, uimsg);
2046     SetDlgItemText(dlg, IDC_FP_HASH_ALG, pvar->ts->UIMsg);
2047 maya 4332 GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
2048     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
2049     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
2050     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
2051     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
2052     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
2053     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
2054     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
2055     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
2056    
2057 doda 4559 switch (pvar->dns_key_check) {
2058     case DNS_VERIFY_NOTFOUND:
2059 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
2060 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2061     break;
2062     case DNS_VERIFY_MATCH:
2063     case DNS_VERIFY_AUTH_MATCH:
2064 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
2065 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2066     break;
2067     case DNS_VERIFY_MISMATCH:
2068     case DNS_VERIFY_AUTH_MISMATCH:
2069 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
2070 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2071     break;
2072     case DNS_VERIFY_DIFFERENTTYPE:
2073     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2074 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
2075 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
2076     break;
2077     }
2078    
2079     switch (pvar->dns_key_check) {
2080     case DNS_VERIFY_MATCH:
2081     case DNS_VERIFY_MISMATCH:
2082     case DNS_VERIFY_DIFFERENTTYPE:
2083 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
2084 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2085     break;
2086     case DNS_VERIFY_AUTH_MATCH:
2087     case DNS_VERIFY_AUTH_MISMATCH:
2088     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
2089 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
2090 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
2091     break;
2092     }
2093    
2094 maya 4332 init_hosts_dlg(pvar, dlg);
2095 zmatsuo 7592 CenterWindow(dlg, GetParent(dlg));
2096 maya 4332 // add host check box ���f�t�H���g�� off ������
2097     // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
2098    
2099     return TRUE; /* because we do not set the focus */
2100    
2101     case WM_COMMAND:
2102     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
2103    
2104     switch (LOWORD(wParam)) {
2105     case IDC_CONTINUE:
2106 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
2107     if (!pvar->cv->Ready) {
2108     goto canceled;
2109     }
2110    
2111 maya 4332 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
2112     add_host_key(pvar);
2113     }
2114    
2115     if (SSHv1(pvar)) {
2116     SSH_notify_host_OK(pvar);
2117     } else { // SSH2
2118     // SSH2���������� SSH_notify_host_OK() �������B
2119     }
2120    
2121     pvar->hosts_state.hosts_dialog = NULL;
2122    
2123     EndDialog(dlg, 1);
2124     return TRUE;
2125    
2126     case IDCANCEL: /* kill the connection */
2127 yutakapon 5562 canceled:
2128 maya 4332 pvar->hosts_state.hosts_dialog = NULL;
2129 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
2130 maya 4332 EndDialog(dlg, 0);
2131     return TRUE;
2132    
2133 maya 6132 case IDC_FP_HASH_ALG_MD5:
2134     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_MD5);
2135     return TRUE;
2136    
2137     case IDC_FP_HASH_ALG_SHA256:
2138     hosts_dlg_set_fingerprint(pvar, dlg, SSH_DIGEST_SHA256);
2139     return TRUE;
2140    
2141 maya 4332 default:
2142     return FALSE;
2143     }
2144    
2145 zmatsuo 7714 case WM_DPICHANGED:
2146     pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
2147     if (pvar->hFontFixed != NULL) {
2148     DeleteObject(pvar->hFontFixed);
2149     }
2150     pvar->hFontFixed = UTIL_get_lang_fixedfont(dlg, pvar->ts->UILanguageFile);
2151     if (pvar->hFontFixed != NULL) {
2152     SendDlgItemMessage(dlg, IDC_FP_RANDOMART, WM_SETFONT,
2153     (WPARAM)pvar->hFontFixed, MAKELPARAM(TRUE,0));
2154     }
2155     return FALSE;
2156    
2157     case WM_DESTROY:
2158     pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
2159     if (pvar->hFontFixed != NULL) {
2160     DeleteObject(pvar->hFontFixed);
2161     pvar->hFontFixed = NULL;
2162     }
2163     return FALSE;
2164    
2165 maya 4332 default:
2166     return FALSE;
2167     }
2168     }
2169    
2170 maya 3227 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
2171     {
2172     if (pvar->hosts_state.hosts_dialog == NULL) {
2173     HWND cur_active = GetActiveWindow();
2174    
2175     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
2176     cur_active != NULL ? cur_active : wnd,
2177     hosts_add_dlg_proc, (LPARAM) pvar);
2178     }
2179     }
2180    
2181 maya 4330 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
2182 maya 3227 {
2183     if (pvar->hosts_state.hosts_dialog == NULL) {
2184     HWND cur_active = GetActiveWindow();
2185    
2186 maya 4330 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
2187 maya 3227 cur_active != NULL ? cur_active : wnd,
2188     hosts_replace_dlg_proc, (LPARAM) pvar);
2189     }
2190     }
2191    
2192 maya 4332 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
2193     {
2194     if (pvar->hosts_state.hosts_dialog == NULL) {
2195     HWND cur_active = GetActiveWindow();
2196    
2197     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
2198     cur_active != NULL ? cur_active : wnd,
2199     hosts_add2_dlg_proc, (LPARAM) pvar);
2200     }
2201     }
2202    
2203 maya 3227 //
2204     // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
2205 maya 6152 // key: �T�[�o���������J��
2206 maya 3227 //
2207     // SSH2���������� (2006.3.24 yutaka)
2208     //
2209 doda 6801 BOOL HOSTS_check_host_key(PTInstVar pvar, char *hostname, unsigned short tcpport, Key *key)
2210 maya 3227 {
2211 doda 4559 int found_different_key = 0, found_different_type_key = 0;
2212 maya 6152 Key key2; // known_hosts���o�^������������
2213 maya 3227
2214 doda 4559 pvar->dns_key_check = DNS_VERIFY_NONE;
2215    
2216 maya 3227 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
2217     if (pvar->hosts_state.prefetched_hostname != NULL
2218     && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
2219 maya 6152 && HOSTS_compare_public_key(&pvar->hosts_state.hostkey, key) == 1) {
2220 maya 3227
2221     if (SSHv1(pvar)) {
2222     SSH_notify_host_OK(pvar);
2223     } else {
2224     // SSH2���������� SSH_notify_host_OK() �������B
2225     }
2226     return TRUE;
2227     }
2228    
2229     // �������������������������A�������_���t�@�C��������������
2230 maya 6152 memset(&key2, 0, sizeof(key2));
2231 maya 3227 if (begin_read_host_files(pvar, 0)) {
2232     do {
2233 maya 6152 if (!read_host_key(pvar, hostname, tcpport, 0, 0, &key2)) {
2234 maya 3227 break;
2235     }
2236    
2237 maya 6152 if (key2.type != KEY_UNSPEC) {
2238     int match = HOSTS_compare_public_key(&key2, key);
2239 maya 4332 if (match == 1) {
2240 maya 3227 finish_read_host_files(pvar, 0);
2241     // ���������G���g�����Q�������A���v�����L�[�������������������B
2242     // SSH2���������������������������B(2006.3.29 yutaka)
2243     if (SSHv1(pvar)) {
2244     SSH_notify_host_OK(pvar);
2245     } else {
2246     // SSH2���������� SSH_notify_host_OK() �������B
2247     }
2248 maya 6998
2249     // About TTSSH �_�C�A���O�����\�����������A�������������������B
2250     key_copy(&pvar->hosts_state.hostkey, key);
2251    
2252 maya 3227 return TRUE;
2253 maya 4332 }
2254     else if (match == 0) {
2255 maya 3227 // �L�[�� known_hosts ���������������A�L�[�����e���������B
2256     found_different_key = 1;
2257     }
2258 maya 4332 else {
2259     // �L�[���`������������
2260     found_different_type_key = 1;
2261     }
2262 maya 3227 }
2263 maya 6152 } while (key2.type != KEY_UNSPEC); // �L�[�����������������������[�v����
2264 maya 3227
2265 maya 6152 key_init(&key2);
2266 maya 3227 finish_read_host_files(pvar, 0);
2267     }
2268    
2269     // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
2270 maya 6147 key_copy(&pvar->hosts_state.hostkey, key);
2271 maya 6145
2272 maya 3227 free(pvar->hosts_state.prefetched_hostname);
2273     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
2274    
2275 yutakapon 3631 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
2276     if (pvar->nocheck_known_hosts == TRUE) {
2277     return TRUE;
2278     }
2279    
2280 doda 4542 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
2281 maya 6063 pvar->dns_key_check = verify_hostkey_dns(pvar, hostname, key);
2282 doda 4542 }
2283    
2284 maya 3227 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
2285     // �������K�v�����������A�����R�[�������X�����B
2286     // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
2287     // (2007.10.1 yutaka)
2288     if (found_different_key) {
2289 maya 4330 HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar);
2290 maya 4332 }
2291     else if (found_different_type_key) {
2292     HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar);
2293     }
2294     else {
2295 maya 3227 HOSTS_do_unknown_host_dialog(pvar->NotificationWindow, pvar);
2296     }
2297    
2298     return TRUE;
2299     }
2300    
2301     void HOSTS_notify_disconnecting(PTInstVar pvar)
2302     {
2303     if (pvar->hosts_state.hosts_dialog != NULL) {
2304 doda 4531 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
2305 maya 3227 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
2306     EnableWindow(pvar->NotificationWindow, TRUE);
2307     }
2308     }
2309    
2310     void HOSTS_end(PTInstVar pvar)
2311     {
2312     int i;
2313    
2314     free(pvar->hosts_state.prefetched_hostname);
2315 maya 6147 key_init(&pvar->hosts_state.hostkey);
2316 maya 3227
2317     if (pvar->hosts_state.file_names != NULL) {
2318     for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
2319     free(pvar->hosts_state.file_names[i]);
2320     }
2321     free(pvar->hosts_state.file_names);
2322     }
2323     }

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