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