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 5843 - (hide annotations) (download) (as text)
Fri May 1 07:44:21 2015 UTC (8 years, 11 months ago) by yutakapon
File MIME type: text/x-csrc
File size: 55955 byte(s)
チケット #35047 SSH サーバホスト公開鍵の自動更新

公開鍵の重複チェックを行う関数を HOSTS_compare_public_key() として切り出した。

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    
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 maya 3227
43     #include <openssl/bn.h>
44     #include <openssl/evp.h>
45     #include <openssl/rsa.h>
46     #include <openssl/dsa.h>
47    
48     #include <fcntl.h>
49     #include <io.h>
50     #include <errno.h>
51     #include <sys/stat.h>
52     #include <direct.h>
53 doda 4531 #include <memory.h>
54 maya 3227
55 doda 4531
56 maya 3227 static HFONT DlgHostsAddFont;
57     static HFONT DlgHostsReplaceFont;
58    
59     // BASE64�\���������i��������'='�����������������j
60     static char base64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
61    
62    
63     // �z�X�g�L�[�������� (2006.3.21 yutaka)
64     static void init_hostkey(Key *key)
65     {
66     key->type = KEY_UNSPEC;
67    
68     // SSH1
69     key->bits = 0;
70     if (key->exp != NULL) {
71     free(key->exp);
72     key->exp = NULL;
73     }
74     if (key->mod != NULL) {
75     free(key->mod);
76     key->mod = NULL;
77     }
78    
79     // SSH2
80     if (key->dsa != NULL) {
81     DSA_free(key->dsa);
82     key->dsa = NULL;
83     }
84     if (key->rsa != NULL) {
85     RSA_free(key->rsa);
86     key->rsa = NULL;
87     }
88 maya 4323 if (key->ecdsa != NULL) {
89     EC_KEY_free(key->ecdsa);
90     key->ecdsa = NULL;
91     }
92 maya 3227 }
93    
94    
95     static char FAR *FAR * parse_multi_path(char FAR * buf)
96     {
97     int i;
98     int ch;
99     int num_paths = 1;
100     char FAR *FAR * result;
101     int last_path_index;
102    
103     for (i = 0; (ch = buf[i]) != 0; i++) {
104     if (ch == ';') {
105     num_paths++;
106     }
107     }
108    
109     result =
110     (char FAR * FAR *) malloc(sizeof(char FAR *) * (num_paths + 1));
111    
112     last_path_index = 0;
113     num_paths = 0;
114     for (i = 0; (ch = buf[i]) != 0; i++) {
115     if (ch == ';') {
116     buf[i] = 0;
117     result[num_paths] = _strdup(buf + last_path_index);
118     num_paths++;
119     buf[i] = ch;
120     last_path_index = i + 1;
121     }
122     }
123     if (i > last_path_index) {
124     result[num_paths] = _strdup(buf + last_path_index);
125     num_paths++;
126     }
127     result[num_paths] = NULL;
128     return result;
129     }
130    
131     void HOSTS_init(PTInstVar pvar)
132     {
133     pvar->hosts_state.prefetched_hostname = NULL;
134     init_hostkey(&pvar->hosts_state.hostkey);
135     pvar->hosts_state.hosts_dialog = NULL;
136     pvar->hosts_state.file_names = NULL;
137     }
138    
139     void HOSTS_open(PTInstVar pvar)
140     {
141     pvar->hosts_state.file_names =
142     parse_multi_path(pvar->session_settings.KnownHostsFiles);
143     }
144    
145     //
146     // known_hosts�t�@�C�������e�������� pvar->hosts_state.file_data ����������
147     //
148     static int begin_read_file(PTInstVar pvar, char FAR * name,
149     int suppress_errors)
150     {
151     int fd;
152     int length;
153     int amount_read;
154     char buf[2048];
155    
156     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
157     fd = _open(buf, _O_RDONLY | _O_SEQUENTIAL | _O_BINARY);
158     if (fd == -1) {
159     if (!suppress_errors) {
160     if (errno == ENOENT) {
161     UTIL_get_lang_msg("MSG_HOSTS_READ_ENOENT_ERROR", pvar,
162     "An error occurred while trying to read a known_hosts file.\n"
163     "The specified filename does not exist.");
164     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
165     } else {
166     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
167     "An error occurred while trying to read a known_hosts file.");
168     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
169     }
170     }
171     return 0;
172     }
173    
174     length = (int) _lseek(fd, 0, SEEK_END);
175     _lseek(fd, 0, SEEK_SET);
176    
177     if (length >= 0 && length < 0x7FFFFFFF) {
178     pvar->hosts_state.file_data = malloc(length + 1);
179     if (pvar->hosts_state.file_data == NULL) {
180     if (!suppress_errors) {
181     UTIL_get_lang_msg("MSG_HOSTS_ALLOC_ERROR", pvar,
182     "Memory ran out while trying to allocate space to read a known_hosts file.");
183     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
184     }
185     _close(fd);
186     return 0;
187     }
188     } else {
189     if (!suppress_errors) {
190     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
191     "An error occurred while trying to read a known_hosts file.");
192     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
193     }
194     _close(fd);
195     return 0;
196     }
197    
198     amount_read = _read(fd, pvar->hosts_state.file_data, length);
199     pvar->hosts_state.file_data[length] = 0;
200    
201     _close(fd);
202    
203     if (amount_read != length) {
204     if (!suppress_errors) {
205     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
206     "An error occurred while trying to read a known_hosts file.");
207     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
208     }
209     free(pvar->hosts_state.file_data);
210     pvar->hosts_state.file_data = NULL;
211     return 0;
212     } else {
213     return 1;
214     }
215     }
216    
217     static int end_read_file(PTInstVar pvar, int suppress_errors)
218     {
219     free(pvar->hosts_state.file_data);
220     pvar->hosts_state.file_data = NULL;
221     return 1;
222     }
223    
224     static int begin_read_host_files(PTInstVar pvar, int suppress_errors)
225     {
226     pvar->hosts_state.file_num = 0;
227     pvar->hosts_state.file_data = NULL;
228     return 1;
229     }
230    
231     // MIME64�����������X�L�b�v����
232     static int eat_base64(char FAR * data)
233     {
234     int index = 0;
235     int ch;
236    
237     for (;;) {
238     ch = data[index];
239     if (ch == '=' || strchr(base64, ch)) {
240     // BASE64���\�������������������� index ���i����
241     index++;
242     } else {
243     break;
244     }
245     }
246    
247     return index;
248     }
249    
250     static int eat_spaces(char FAR * data)
251     {
252     int index = 0;
253     int ch;
254    
255     while ((ch = data[index]) == ' ' || ch == '\t') {
256     index++;
257     }
258     return index;
259     }
260    
261     static int eat_digits(char FAR * data)
262     {
263     int index = 0;
264     int ch;
265    
266     while ((ch = data[index]) >= '0' && ch <= '9') {
267     index++;
268     }
269     return index;
270     }
271    
272     static int eat_to_end_of_line(char FAR * data)
273     {
274     int index = 0;
275     int ch;
276    
277     while ((ch = data[index]) != '\n' && ch != '\r' && ch != 0) {
278     index++;
279     }
280    
281     while ((ch = data[index]) == '\n' || ch == '\r') {
282     index++;
283     }
284    
285     return index;
286     }
287    
288     static int eat_to_end_of_pattern(char FAR * data)
289     {
290     int index = 0;
291     int ch;
292    
293     while (ch = data[index], is_pattern_char(ch)) {
294     index++;
295     }
296    
297     return index;
298     }
299    
300     //
301     // BASE64�f�R�[�h�������s���B(rfc1521)
302     // src�o�b�t�@�� null-terminate ���������K�v�����B
303     //
304 yutakapon 5545 int uudecode(unsigned char *src, int srclen, unsigned char *target, int targsize)
305 maya 3227 {
306     char pad = '=';
307     int tarindex, state, ch;
308     char *pos;
309    
310     state = 0;
311     tarindex = 0;
312    
313     while ((ch = *src++) != '\0') {
314     if (isspace(ch)) /* Skip whitespace anywhere. */
315     continue;
316    
317     if (ch == pad)
318     break;
319    
320     pos = strchr(base64, ch);
321     if (pos == 0) /* A non-base64 character. */
322     return (-1);
323    
324     switch (state) {
325     case 0:
326     if (target) {
327     if (tarindex >= targsize)
328     return (-1);
329     target[tarindex] = (pos - base64) << 2;
330     }
331     state = 1;
332     break;
333     case 1:
334     if (target) {
335     if (tarindex + 1 >= targsize)
336     return (-1);
337     target[tarindex] |= (pos - base64) >> 4;
338     target[tarindex+1] = ((pos - base64) & 0x0f) << 4 ;
339     }
340     tarindex++;
341     state = 2;
342     break;
343     case 2:
344     if (target) {
345     if (tarindex + 1 >= targsize)
346     return (-1);
347     target[tarindex] |= (pos - base64) >> 2;
348     target[tarindex+1] = ((pos - base64) & 0x03) << 6;
349     }
350     tarindex++;
351     state = 3;
352     break;
353     case 3:
354     if (target) {
355     if (tarindex >= targsize)
356     return (-1);
357     target[tarindex] |= (pos - base64);
358     }
359     tarindex++;
360     state = 0;
361     break;
362     }
363     }
364    
365     /*
366     * We are done decoding Base-64 chars. Let's see if we ended
367     * on a byte boundary, and/or with erroneous trailing characters.
368     */
369    
370     if (ch == pad) { /* We got a pad char. */
371     ch = *src++; /* Skip it, get next. */
372     switch (state) {
373     case 0: /* Invalid = in first position */
374     case 1: /* Invalid = in second position */
375     return (-1);
376    
377     case 2: /* Valid, means one byte of info */
378     /* Skip any number of spaces. */
379     for (; ch != '\0'; ch = *src++)
380     if (!isspace(ch))
381     break;
382     /* Make sure there is another trailing = sign. */
383     if (ch != pad)
384     return (-1);
385     ch = *src++; /* Skip the = */
386     /* Fall through to "single trailing =" case. */
387     /* FALLTHROUGH */
388    
389     case 3: /* Valid, means two bytes of info */
390     /*
391     * We know this char is an =. Is there anything but
392     * whitespace after it?
393     */
394     for (; ch != '\0'; ch = *src++)
395     if (!isspace(ch))
396     return (-1);
397    
398     /*
399     * Now make sure for cases 2 and 3 that the "extra"
400     * bits that slopped past the last full byte were
401     * zeros. If we don't check them, they become a
402     * subliminal channel.
403     */
404     if (target && target[tarindex] != 0)
405     return (-1);
406     }
407     } else {
408     /*
409     * We ended by seeing the end of the string. Make sure we
410     * have no partial bytes lying around.
411     */
412     if (state != 0)
413     return (-1);
414     }
415    
416     return (tarindex);
417     }
418    
419    
420     // SSH2���� BASE64 �`�����i�[����������
421     static Key *parse_uudecode(char *data)
422     {
423     int count;
424     unsigned char *blob = NULL;
425     int len, n;
426     Key *key = NULL;
427     char ch;
428    
429     // BASE64���������T�C�Y������
430     count = eat_base64(data);
431     len = 2 * count;
432     blob = malloc(len);
433     if (blob == NULL)
434     goto error;
435    
436     // BASE64�f�R�[�h
437     ch = data[count];
438     data[count] = '\0'; // ���������s�R�[�h������������������������������������
439     n = uudecode(data, count, blob, len);
440     data[count] = ch;
441     if (n < 0) {
442     goto error;
443     }
444    
445     key = key_from_blob(blob, n);
446     if (key == NULL)
447     goto error;
448    
449     error:
450     if (blob != NULL)
451     free(blob);
452    
453     return (key);
454     }
455    
456    
457     static char FAR *parse_bignum(char FAR * data)
458     {
459     uint32 digits = 0;
460     BIGNUM *num = BN_new();
461     BIGNUM *billion = BN_new();
462     BIGNUM *digits_num = BN_new();
463     BN_CTX *ctx = BN_CTX_new();
464     char FAR *result;
465     int ch;
466     int leftover_digits = 1;
467    
468     BN_CTX_init(ctx);
469     BN_set_word(num, 0);
470     BN_set_word(billion, 1000000000L);
471    
472     while ((ch = *data) >= '0' && ch <= '9') {
473     if (leftover_digits == 1000000000L) {
474     BN_set_word(digits_num, digits);
475     BN_mul(num, num, billion, ctx);
476     BN_add(num, num, digits_num);
477     leftover_digits = 1;
478     digits = 0;
479     }
480    
481     digits = digits * 10 + ch - '0';
482     leftover_digits *= 10;
483     data++;
484     }
485    
486     BN_set_word(digits_num, digits);
487     BN_set_word(billion, leftover_digits);
488     BN_mul(num, num, billion, ctx);
489     BN_add(num, num, digits_num);
490    
491     result = (char FAR *) malloc(2 + BN_num_bytes(num));
492     set_ushort16_MSBfirst(result, BN_num_bits(num));
493     BN_bn2bin(num, result + 2);
494    
495     BN_CTX_free(ctx);
496     BN_free(digits_num);
497     BN_free(num);
498     BN_free(billion);
499    
500     return result;
501     }
502    
503     //
504     // known_hosts�t�@�C�������e���������A�w�������z�X�g�����J�����T���B
505     //
506     static int check_host_key(PTInstVar pvar, char FAR * hostname,
507     unsigned short tcpport, char FAR * data)
508     {
509     int index = eat_spaces(data);
510     int matched = 0;
511     int keybits = 0;
512    
513     if (data[index] == '#') {
514     return index + eat_to_end_of_line(data + index);
515     }
516    
517     /* if we find an empty line, then it won't have any patterns matching the hostname
518     and so we skip it */
519     index--;
520     do {
521     int negated;
522     int bracketed;
523     char *end_bracket;
524     int host_matched = 0;
525     unsigned short keyfile_port = 22;
526    
527     index++;
528     negated = data[index] == '!';
529    
530     if (negated) {
531     index++;
532     bracketed = data[index] == '[';
533     if (bracketed) {
534     end_bracket = strstr(data + index + 1, "]:");
535     if (end_bracket != NULL) {
536     *end_bracket = ' ';
537     index++;
538     }
539     }
540     host_matched = match_pattern(data + index, hostname);
541     if (bracketed && end_bracket != NULL) {
542     *end_bracket = ']';
543     keyfile_port = atoi(end_bracket + 2);
544     }
545     if (host_matched && keyfile_port == tcpport) {
546     return index + eat_to_end_of_line(data + index);
547     }
548     } else {
549     bracketed = data[index] == '[';
550     if (bracketed) {
551     end_bracket = strstr(data + index + 1, "]:");
552     if (end_bracket != NULL) {
553     *end_bracket = ' ';
554     index++;
555     }
556     }
557     host_matched = match_pattern(data + index, hostname);
558     if (bracketed && end_bracket != NULL) {
559     *end_bracket = ']';
560     keyfile_port = atoi(end_bracket + 2);
561     }
562     if (host_matched && keyfile_port == tcpport) {
563     matched = 1;
564     }
565     }
566    
567     index += eat_to_end_of_pattern(data + index);
568     } while (data[index] == ',');
569    
570     if (!matched) {
571     return index + eat_to_end_of_line(data + index);
572     } else {
573     // ���������������t�H�[�}�b�g��������
574     // �����A���������v�����G���g�����������������������B
575     /*
576     [SSH1]
577     192.168.1.2 1024 35 13032....
578    
579     [SSH2]
580     192.168.1.2 ssh-rsa AAAAB3NzaC1....
581     192.168.1.2 ssh-dss AAAAB3NzaC1....
582     192.168.1.2 rsa AAAAB3NzaC1....
583     192.168.1.2 dsa AAAAB3NzaC1....
584     192.168.1.2 rsa1 AAAAB3NzaC1....
585     */
586     int rsa1_key_bits;
587    
588     index += eat_spaces(data + index);
589    
590     rsa1_key_bits = atoi(data + index);
591     if (rsa1_key_bits > 0) { // RSA1������
592     if (!SSHv1(pvar)) { // SSH2��������������������
593     return index + eat_to_end_of_line(data + index);
594     }
595    
596     pvar->hosts_state.hostkey.type = KEY_RSA1;
597    
598     pvar->hosts_state.hostkey.bits = rsa1_key_bits;
599     index += eat_digits(data + index);
600     index += eat_spaces(data + index);
601    
602     pvar->hosts_state.hostkey.exp = parse_bignum(data + index);
603     index += eat_digits(data + index);
604     index += eat_spaces(data + index);
605    
606     pvar->hosts_state.hostkey.mod = parse_bignum(data + index);
607    
608     /*
609     if (pvar->hosts_state.key_bits < 0
610     || pvar->hosts_state.key_exp == NULL
611     || pvar->hosts_state.key_mod == NULL) {
612     pvar->hosts_state.key_bits = 0;
613     free(pvar->hosts_state.key_exp);
614     free(pvar->hosts_state.key_mod);
615     }*/
616    
617     } else {
618     char *cp, *p;
619     Key *key;
620    
621     if (!SSHv2(pvar)) { // SSH1��������������������
622     return index + eat_to_end_of_line(data + index);
623     }
624    
625     cp = data + index;
626     p = strchr(cp, ' ');
627     if (p == NULL) {
628     return index + eat_to_end_of_line(data + index);
629     }
630     index += (p - cp); // setup index
631     *p = '\0';
632     pvar->hosts_state.hostkey.type = get_keytype_from_name(cp);
633     *p = ' ';
634    
635     index += eat_spaces(data + index); // update index
636    
637     // uudecode
638     key = parse_uudecode(data + index);
639     if (key == NULL) {
640     return index + eat_to_end_of_line(data + index);
641     }
642    
643     // setup
644     pvar->hosts_state.hostkey.type = key->type;
645     pvar->hosts_state.hostkey.dsa = key->dsa;
646     pvar->hosts_state.hostkey.rsa = key->rsa;
647 maya 4321 pvar->hosts_state.hostkey.ecdsa = key->ecdsa;
648 yutakapon 5545 pvar->hosts_state.hostkey.ed25519_pk = key->ed25519_pk;
649 maya 3227
650     index += eat_base64(data + index);
651     index += eat_spaces(data + index);
652    
653     // Key�\�������g���������� (2008.3.2 yutaka)
654     free(key);
655     }
656    
657     return index + eat_to_end_of_line(data + index);
658     }
659     }
660    
661     //
662     // known_hosts�t�@�C�������z�X�g�������v�����s������
663     //
664     static int read_host_key(PTInstVar pvar,
665     char FAR * hostname, unsigned short tcpport,
666     int suppress_errors, int return_always)
667     {
668     int i;
669     int while_flg;
670    
671     for (i = 0; hostname[i] != 0; i++) {
672     int ch = hostname[i];
673    
674     if (!is_pattern_char(ch) || ch == '*' || ch == '?') {
675     if (!suppress_errors) {
676     UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_INVALID_ERROR", pvar,
677     "The host name contains an invalid character.\n"
678     "This session will be terminated.");
679 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
680 maya 3227 }
681     return 0;
682     }
683     }
684    
685     if (i == 0) {
686     if (!suppress_errors) {
687     UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_EMPTY_ERROR", pvar,
688     "The host name should not be empty.\n"
689     "This session will be terminated.");
690 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
691 maya 3227 }
692     return 0;
693     }
694    
695     // hostkey type is KEY_UNSPEC.
696     init_hostkey(&pvar->hosts_state.hostkey);
697    
698     do {
699     if (pvar->hosts_state.file_data == NULL
700     || pvar->hosts_state.file_data[pvar->hosts_state.file_data_index] == 0) {
701     char FAR *filename;
702     int keep_going = 1;
703    
704     if (pvar->hosts_state.file_data != NULL) {
705     end_read_file(pvar, suppress_errors);
706     }
707    
708     do {
709     filename =
710     pvar->hosts_state.file_names[pvar->hosts_state.file_num];
711    
712     if (filename == NULL) {
713     return 1;
714     } else {
715     pvar->hosts_state.file_num++;
716    
717     if (filename[0] != 0) {
718     if (begin_read_file(pvar, filename, suppress_errors)) {
719     pvar->hosts_state.file_data_index = 0;
720     keep_going = 0;
721     }
722     }
723     }
724     } while (keep_going);
725     }
726    
727     pvar->hosts_state.file_data_index +=
728     check_host_key(pvar, hostname, tcpport,
729     pvar->hosts_state.file_data +
730     pvar->hosts_state.file_data_index);
731    
732     if (!return_always) {
733     // �L�����L�[��������������
734     while_flg = (pvar->hosts_state.hostkey.type == KEY_UNSPEC);
735     }
736     else {
737     while_flg = 0;
738     }
739     } while (while_flg);
740    
741     return 1;
742     }
743    
744     static void finish_read_host_files(PTInstVar pvar, int suppress_errors)
745     {
746     if (pvar->hosts_state.file_data != NULL) {
747     end_read_file(pvar, suppress_errors);
748     }
749     }
750    
751     // �T�[�o�����������O���Aknown_hosts�t�@�C�������z�X�g���J�������������������B
752     void HOSTS_prefetch_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport)
753     {
754     if (!begin_read_host_files(pvar, 1)) {
755     return;
756     }
757    
758     if (!read_host_key(pvar, hostname, tcpport, 1, 0)) {
759     return;
760     }
761    
762     free(pvar->hosts_state.prefetched_hostname);
763     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
764    
765     finish_read_host_files(pvar, 1);
766     }
767    
768     static BOOL equal_mp_ints(unsigned char FAR * num1,
769     unsigned char FAR * num2)
770     {
771     if (num1 == NULL || num2 == NULL) {
772     return FALSE;
773     } else {
774     uint32 bytes = (get_ushort16_MSBfirst(num1) + 7) / 8;
775    
776     if (bytes != (get_ushort16_MSBfirst(num2) + 7) / 8) {
777     return FALSE; /* different byte lengths */
778     } else {
779     return memcmp(num1 + 2, num2 + 2, bytes) == 0;
780     }
781     }
782     }
783    
784 yutakapon 5843
785     // ���J�������r���s���B
786     //
787     // return
788 maya 4332 // -1 ... �����^������
789     // 0 ... ����������
790     // 1 ... ������
791 yutakapon 5843 int HOSTS_compare_public_key(Key *src, Key *key)
792 maya 3227 {
793     int bits;
794     unsigned char FAR * exp;
795     unsigned char FAR * mod;
796 maya 4321 const EC_GROUP *group;
797     const EC_POINT *pa, *pb;
798 yutakapon 5545 Key *a, *b;
799 maya 3227
800 yutakapon 5843 if (src->type != key->type) {
801 maya 4332 return -1;
802     }
803    
804 maya 4321 switch (key->type) {
805     case KEY_RSA1: // SSH1 host public key
806 maya 3227 bits = key->bits;
807     exp = key->exp;
808     mod = key->mod;
809    
810     /* just check for equal exponent and modulus */
811 yutakapon 5843 return equal_mp_ints(exp, src->exp)
812     && equal_mp_ints(mod, src->mod);
813 maya 3227 /*
814     return equal_mp_ints(exp, pvar->hosts_state.key_exp)
815 yutakapon 5843 && equal_mp_ints(mod, pvar->hosts_state.key_mod);
816     */
817 maya 3227
818 maya 4321 case KEY_RSA: // SSH2 RSA host public key
819 yutakapon 5843 return key->rsa != NULL && src->rsa != NULL &&
820     BN_cmp(key->rsa->e, src->rsa->e) == 0 &&
821     BN_cmp(key->rsa->n, src->rsa->n) == 0;
822 maya 3227
823 maya 4321 case KEY_DSA: // SSH2 DSA host public key
824 yutakapon 5843 return key->dsa != NULL && src->dsa &&
825     BN_cmp(key->dsa->p, src->dsa->p) == 0 &&
826     BN_cmp(key->dsa->q, src->dsa->q) == 0 &&
827     BN_cmp(key->dsa->g, src->dsa->g) == 0 &&
828     BN_cmp(key->dsa->pub_key, src->dsa->pub_key) == 0;
829 maya 3227
830 maya 4321 case KEY_ECDSA256:
831     case KEY_ECDSA384:
832     case KEY_ECDSA521:
833 yutakapon 5843 if (key->ecdsa == NULL || src->ecdsa == NULL) {
834 maya 4321 return FALSE;
835     }
836     group = EC_KEY_get0_group(key->ecdsa);
837     pa = EC_KEY_get0_public_key(key->ecdsa),
838 yutakapon 5843 pb = EC_KEY_get0_public_key(src->ecdsa);
839 maya 4321 return EC_POINT_cmp(group, pa, pb, NULL) == 0;
840    
841 yutakapon 5545 case KEY_ED25519:
842     a = key;
843 yutakapon 5843 b = src;
844 yutakapon 5545 return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
845 yutakapon 5843 memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;
846 yutakapon 5545
847 maya 4321 default:
848 maya 4307 return FALSE;
849     }
850 yutakapon 5843 }
851 maya 3227
852 yutakapon 5843
853     // ���J����������������������
854     // -1 ... �����^������
855     // 0 ... ����������
856     // 1 ... ������
857     static int match_key(PTInstVar pvar, Key *key)
858     {
859     return HOSTS_compare_public_key(&pvar->hosts_state.hostkey, key);
860 maya 3227 }
861    
862     static void init_hosts_dlg(PTInstVar pvar, HWND dlg)
863     {
864     char buf[1024];
865     char buf2[2048];
866     int i, j;
867     int ch;
868     char *fp = NULL;
869    
870     // static text�� # �������z�X�g�����u������
871     GetDlgItemText(dlg, IDC_HOSTWARNING, buf, sizeof(buf));
872     for (i = 0; (ch = buf[i]) != 0 && ch != '#'; i++) {
873     buf2[i] = ch;
874     }
875     strncpy_s(buf2 + i, sizeof(buf2) - i,
876     pvar->hosts_state.prefetched_hostname, _TRUNCATE);
877     j = i + strlen(buf2 + i);
878     for (; buf[i] == '#'; i++) {
879     }
880     strncpy_s(buf2 + j, sizeof(buf2) - j, buf + i, _TRUNCATE);
881    
882     SetDlgItemText(dlg, IDC_HOSTWARNING, buf2);
883    
884     // fingerprint����������
885     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX);
886     SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
887     free(fp);
888    
889     // �r�W���A����fingerprint���\������
890     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART);
891     SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETTEXT, 0, (LPARAM)fp);
892     SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), TRUE);
893     free(fp);
894     }
895    
896     static int print_mp_int(char FAR * buf, unsigned char FAR * mp)
897     {
898     int i = 0, j, k;
899     BIGNUM *num = BN_new();
900     int ch;
901    
902     BN_bin2bn(mp + 2, (get_ushort16_MSBfirst(mp) + 7) / 8, num);
903    
904     do {
905     buf[i] = (char) ((BN_div_word(num, 10)) + '0');
906     i++;
907     } while (!BN_is_zero(num));
908    
909     /* we need to reverse the digits */
910     for (j = 0, k = i - 1; j < k; j++, k--) {
911     ch = buf[j];
912     buf[j] = buf[k];
913     buf[k] = ch;
914     }
915    
916     buf[i] = 0;
917     return i;
918     }
919    
920     //
921     // known_hosts �t�@�C�������������G���g�������������B
922     //
923     static char FAR *format_host_key(PTInstVar pvar)
924     {
925     int host_len = strlen(pvar->hosts_state.prefetched_hostname);
926     char *result = NULL;
927     int index;
928 maya 4378 ssh_keytype type = pvar->hosts_state.hostkey.type;
929 maya 3227
930 maya 4321 switch (type) {
931     case KEY_RSA1:
932     {
933 maya 3227 int result_len = host_len + 50 + 8 +
934     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.exp) / 3 +
935     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.mod) / 3;
936     result = (char FAR *) malloc(result_len);
937    
938     if (pvar->ssh_state.tcpport == 22) {
939     strncpy_s(result, result_len, pvar->hosts_state.prefetched_hostname, _TRUNCATE);
940     index = host_len;
941     }
942     else {
943     _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
944     pvar->hosts_state.prefetched_hostname,
945     pvar->ssh_state.tcpport);
946     index = strlen(result);
947     }
948    
949     _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
950     " %d ", pvar->hosts_state.hostkey.bits);
951     index += strlen(result + index);
952     index += print_mp_int(result + index, pvar->hosts_state.hostkey.exp);
953     result[index] = ' ';
954     index++;
955     index += print_mp_int(result + index, pvar->hosts_state.hostkey.mod);
956     strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
957    
958 maya 4321 break;
959     }
960    
961     case KEY_RSA:
962     case KEY_DSA:
963     case KEY_ECDSA256:
964     case KEY_ECDSA384:
965     case KEY_ECDSA521:
966 yutakapon 5545 case KEY_ED25519:
967 maya 4321 {
968 maya 3227 Key *key = &pvar->hosts_state.hostkey;
969     char *blob = NULL;
970     int blen, uulen, msize;
971     char *uu = NULL;
972     int n;
973    
974     key_to_blob(key, &blob, &blen);
975     uulen = 2 * blen;
976     uu = malloc(uulen);
977     if (uu == NULL) {
978     goto error;
979     }
980     n = uuencode(blob, blen, uu, uulen);
981     if (n > 0) {
982     msize = host_len + 50 + uulen;
983     result = malloc(msize);
984     if (result == NULL) {
985     goto error;
986     }
987    
988     // setup
989     if (pvar->ssh_state.tcpport == 22) {
990     _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
991     pvar->hosts_state.prefetched_hostname,
992     get_sshname_from_key(key),
993     uu);
994     } else {
995     _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
996     pvar->hosts_state.prefetched_hostname,
997     pvar->ssh_state.tcpport,
998     get_sshname_from_key(key),
999     uu);
1000     }
1001     }
1002     error:
1003     if (blob != NULL)
1004     free(blob);
1005     if (uu != NULL)
1006     free(uu);
1007    
1008 maya 4321 break;
1009     }
1010    
1011     default:
1012 maya 3227 return NULL;
1013    
1014     }
1015    
1016     return result;
1017     }
1018    
1019     static void add_host_key(PTInstVar pvar)
1020     {
1021     char FAR *name = NULL;
1022    
1023     if ( pvar->hosts_state.file_names != NULL)
1024     name = pvar->hosts_state.file_names[0];
1025    
1026     if (name == NULL || name[0] == 0) {
1027     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1028     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1029     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1030     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1031     } else {
1032     char FAR *keydata = format_host_key(pvar);
1033     int length = strlen(keydata);
1034     int fd;
1035     int amount_written;
1036     int close_result;
1037     char buf[FILENAME_MAX];
1038    
1039     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1040     fd = _open(buf,
1041     _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1042     _S_IREAD | _S_IWRITE);
1043     if (fd == -1) {
1044     if (errno == EACCES) {
1045     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1046     "An error occurred while trying to write the host key.\n"
1047     "You do not have permission to write to the known-hosts file.");
1048     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1049     } else {
1050     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1051     "An error occurred while trying to write the host key.\n"
1052     "The host key could not be written.");
1053     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1054     }
1055     return;
1056     }
1057    
1058     amount_written = _write(fd, keydata, length);
1059     free(keydata);
1060     close_result = _close(fd);
1061    
1062     if (amount_written != length || close_result == -1) {
1063     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1064     "An error occurred while trying to write the host key.\n"
1065     "The host key could not be written.");
1066     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1067     }
1068     }
1069     }
1070    
1071     static char FAR *copy_mp_int(char FAR * num)
1072     {
1073     int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;
1074     char FAR *result = (char FAR *) malloc(len);
1075    
1076     if (result != NULL) {
1077     memcpy(result, num, len);
1078     }
1079    
1080     return result;
1081     }
1082    
1083     //
1084     // �����z�X�g�����e���������L�[����������
1085     // add_host_key ����������������
1086     //
1087     static void delete_different_key(PTInstVar pvar)
1088     {
1089     char FAR *name = pvar->hosts_state.file_names[0];
1090    
1091     if (name == NULL || name[0] == 0) {
1092     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1093     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1094     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1095     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1096     }
1097     else {
1098     Key key; // ���������z�X�g���L�[
1099 yutakapon 5663 Key *key_freed;
1100 maya 3227 int length;
1101     char filename[MAX_PATH];
1102     char tmp[L_tmpnam];
1103     int fd;
1104     int amount_written = 0;
1105     int close_result;
1106     int data_index = 0;
1107     char buf[FILENAME_MAX];
1108    
1109     // �������������t�@�C�����J��
1110     _getcwd(filename, sizeof(filename));
1111     tmpnam_s(tmp,sizeof(tmp));
1112     strcat_s(filename, sizeof(filename), tmp);
1113     fd = _open(filename,
1114     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1115     _S_IREAD | _S_IWRITE);
1116    
1117     if (fd == -1) {
1118     if (errno == EACCES) {
1119     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1120     "An error occurred while trying to write the host key.\n"
1121     "You do not have permission to write to the known-hosts file.");
1122     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1123     } else {
1124     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1125     "An error occurred while trying to write the host key.\n"
1126     "The host key could not be written.");
1127     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1128     }
1129     return;
1130     }
1131    
1132     // ���������T�[�o���L�[����������
1133 yutakapon 5545 memset(&key, 0, sizeof(key));
1134 maya 4321 switch (pvar->hosts_state.hostkey.type) {
1135     case KEY_RSA1: // SSH1
1136 maya 3227 key.type = KEY_RSA1;
1137     key.bits = pvar->hosts_state.hostkey.bits;
1138     key.exp = copy_mp_int(pvar->hosts_state.hostkey.exp);
1139     key.mod = copy_mp_int(pvar->hosts_state.hostkey.mod);
1140 maya 4321 break;
1141     case KEY_RSA: // SSH2 RSA
1142 maya 3227 key.type = KEY_RSA;
1143     key.rsa = duplicate_RSA(pvar->hosts_state.hostkey.rsa);
1144 maya 4321 break;
1145     case KEY_DSA: // SSH2 DSA
1146 maya 3227 key.type = KEY_DSA;
1147     key.dsa = duplicate_DSA(pvar->hosts_state.hostkey.dsa);
1148 maya 4321 break;
1149     case KEY_ECDSA256:
1150     case KEY_ECDSA384:
1151     case KEY_ECDSA521:
1152     key.type = pvar->hosts_state.hostkey.type;
1153     key.ecdsa = EC_KEY_dup(pvar->hosts_state.hostkey.ecdsa);
1154     break;
1155 yutakapon 5545 case KEY_ED25519:
1156     key.type = pvar->hosts_state.hostkey.type;
1157     key.ed25519_pk = duplicate_ED25519_PK(pvar->hosts_state.hostkey.ed25519_pk);
1158     break;
1159 maya 3227 }
1160    
1161     // �t�@�C��������������
1162     begin_read_host_files(pvar, 0);
1163     do {
1164     int host_index = 0;
1165     int matched = 0;
1166     int keybits = 0;
1167     char FAR *data;
1168     int do_write = 0;
1169     length = amount_written = 0;
1170    
1171     if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1)) {
1172     break;
1173     }
1174    
1175     if (data_index == pvar->hosts_state.file_data_index) {
1176     // index ���i������ == ��������������
1177     break;
1178     }
1179    
1180     data = pvar->hosts_state.file_data + data_index;
1181     host_index = eat_spaces(data);
1182    
1183     if (data[host_index] == '#') {
1184     do_write = 1;
1185     }
1186     else {
1187     // �z�X�g������
1188     host_index--;
1189     do {
1190     int negated;
1191     int bracketed;
1192     char *end_bracket;
1193     int host_matched = 0;
1194     unsigned short keyfile_port = 22;
1195    
1196     host_index++;
1197     negated = data[host_index] == '!';
1198    
1199     if (negated) {
1200     host_index++;
1201     bracketed = data[host_index] == '[';
1202     if (bracketed) {
1203     end_bracket = strstr(data + host_index + 1, "]:");
1204     if (end_bracket != NULL) {
1205     *end_bracket = ' ';
1206     host_index++;
1207     }
1208     }
1209     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1210     if (bracketed && end_bracket != NULL) {
1211     *end_bracket = ']';
1212     keyfile_port = atoi(end_bracket + 2);
1213     }
1214     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1215     matched = 0;
1216     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1217     host_index--;
1218     do {
1219     host_index++;
1220     host_index += eat_to_end_of_pattern(data + host_index);
1221     } while (data[host_index] == ',');
1222     break;
1223     }
1224     }
1225     else {
1226     bracketed = data[host_index] == '[';
1227     if (bracketed) {
1228     end_bracket = strstr(data + host_index + 1, "]:");
1229     if (end_bracket != NULL) {
1230     *end_bracket = ' ';
1231     host_index++;
1232     }
1233     }
1234     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1235     if (bracketed && end_bracket != NULL) {
1236     *end_bracket = ']';
1237     keyfile_port = atoi(end_bracket + 2);
1238     }
1239     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1240     matched = 1;
1241     }
1242     }
1243     host_index += eat_to_end_of_pattern(data + host_index);
1244     } while (data[host_index] == ',');
1245    
1246     // �z�X�g������������
1247 maya 4332 if (!matched) {
1248 maya 3227 do_write = 1;
1249     }
1250 maya 4332 // �z�X�g��������
1251 maya 3227 else {
1252 maya 4332 // �����`�������� or ���v�����L�[
1253     if (match_key(pvar, &key) != 0) {
1254     do_write = 1;
1255 maya 3227 }
1256 maya 4332 // �����`�������������v�������L�[���X�L�b�v������
1257 maya 3227 }
1258     }
1259    
1260     // ������������
1261     if (do_write) {
1262     length = pvar->hosts_state.file_data_index - data_index;
1263     amount_written =
1264     _write(fd, pvar->hosts_state.file_data + data_index,
1265     length);
1266    
1267     if (amount_written != length) {
1268     goto error1;
1269     }
1270     }
1271     data_index = pvar->hosts_state.file_data_index;
1272     } while (1); // ������������
1273    
1274     error1:
1275     close_result = _close(fd);
1276     if (amount_written != length || close_result == -1) {
1277     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1278     "An error occurred while trying to write the host key.\n"
1279     "The host key could not be written.");
1280     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1281     goto error2;
1282     }
1283    
1284     // �������������t�@�C���������l�[��
1285     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1286     _unlink(buf);
1287     rename(filename, buf);
1288    
1289     error2:
1290     _unlink(filename);
1291    
1292     finish_read_host_files(pvar, 0);
1293 yutakapon 5545
1294     // ���������������������������B
1295 yutakapon 5663 key_freed = key_new(KEY_UNSPEC);
1296     memcpy(key_freed, &key, sizeof(Key));
1297     key_free(key_freed);
1298 maya 3227 }
1299     }
1300    
1301     //
1302     // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1303     // ���[�U���m�F�������B
1304     // TODO: finger print���\�����s���B
1305     // (2006.3.25 yutaka)
1306     //
1307     static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1308     LPARAM lParam)
1309     {
1310     PTInstVar pvar;
1311     LOGFONT logfont;
1312     HFONT font;
1313     char uimsg[MAX_UIMSG];
1314    
1315     switch (msg) {
1316     case WM_INITDIALOG:
1317     pvar = (PTInstVar) lParam;
1318     pvar->hosts_state.hosts_dialog = dlg;
1319     SetWindowLong(dlg, DWL_USER, lParam);
1320    
1321     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1322     GetWindowText(dlg, uimsg, sizeof(uimsg));
1323     UTIL_get_lang_msg("DLG_UNKNONWHOST_TITLE", pvar, uimsg);
1324     SetWindowText(dlg, pvar->ts->UIMsg);
1325     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1326 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING", pvar, uimsg);
1327 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1328     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1329 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING2", pvar, uimsg);
1330 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1331     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1332     UTIL_get_lang_msg("DLG_UNKNOWNHOST_FINGERPRINT", pvar, uimsg);
1333     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1334     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1335     UTIL_get_lang_msg("DLG_UNKNOWNHOST_ADD", pvar, uimsg);
1336     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1337     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1338     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1339     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1340     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1341     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1342     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1343    
1344 doda 4559 switch (pvar->dns_key_check) {
1345     case DNS_VERIFY_NOTFOUND:
1346 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1347 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1348     break;
1349     case DNS_VERIFY_MATCH:
1350     case DNS_VERIFY_AUTH_MATCH:
1351 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1352 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1353     break;
1354     case DNS_VERIFY_MISMATCH:
1355     case DNS_VERIFY_AUTH_MISMATCH:
1356 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1357 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1358     break;
1359     case DNS_VERIFY_DIFFERENTTYPE:
1360     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1361 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1362 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1363     break;
1364     }
1365    
1366     switch (pvar->dns_key_check) {
1367     case DNS_VERIFY_MATCH:
1368     case DNS_VERIFY_MISMATCH:
1369     case DNS_VERIFY_DIFFERENTTYPE:
1370 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1371 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1372     break;
1373     case DNS_VERIFY_AUTH_MATCH:
1374     case DNS_VERIFY_AUTH_MISMATCH:
1375     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1376 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1377 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1378     break;
1379     }
1380    
1381 maya 3227 init_hosts_dlg(pvar, dlg);
1382    
1383     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1384     GetObject(font, sizeof(LOGFONT), &logfont);
1385     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1386     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1387     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1388 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1389     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1390 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1391     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1392     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1393     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1394     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1395     }
1396     else {
1397     DlgHostsAddFont = NULL;
1398     }
1399    
1400     // add host check box���`�F�b�N���f�t�H���g������������
1401     SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1402    
1403     return TRUE; /* because we do not set the focus */
1404    
1405     case WM_COMMAND:
1406     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1407    
1408     switch (LOWORD(wParam)) {
1409     case IDC_CONTINUE:
1410 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1411     if (!pvar->cv->Ready) {
1412     goto canceled;
1413     }
1414    
1415 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1416     add_host_key(pvar);
1417     }
1418    
1419     if (SSHv1(pvar)) {
1420     SSH_notify_host_OK(pvar);
1421     } else { // SSH2
1422     // SSH2���������� SSH_notify_host_OK() �������B
1423     }
1424    
1425     pvar->hosts_state.hosts_dialog = NULL;
1426    
1427     EndDialog(dlg, 1);
1428    
1429     if (DlgHostsAddFont != NULL) {
1430     DeleteObject(DlgHostsAddFont);
1431     }
1432    
1433     return TRUE;
1434    
1435     case IDCANCEL: /* kill the connection */
1436 yutakapon 5562 canceled:
1437 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
1438 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
1439 maya 3227 EndDialog(dlg, 0);
1440    
1441     if (DlgHostsAddFont != NULL) {
1442     DeleteObject(DlgHostsAddFont);
1443     }
1444    
1445     return TRUE;
1446    
1447     default:
1448     return FALSE;
1449     }
1450    
1451     default:
1452     return FALSE;
1453     }
1454     }
1455    
1456     //
1457     // �u�����������m�F�_�C�A���O������
1458     //
1459     static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1460     LPARAM lParam)
1461     {
1462     PTInstVar pvar;
1463     LOGFONT logfont;
1464     HFONT font;
1465     char uimsg[MAX_UIMSG];
1466    
1467     switch (msg) {
1468     case WM_INITDIALOG:
1469     pvar = (PTInstVar) lParam;
1470     pvar->hosts_state.hosts_dialog = dlg;
1471     SetWindowLong(dlg, DWL_USER, lParam);
1472    
1473     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1474     GetWindowText(dlg, uimsg, sizeof(uimsg));
1475 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
1476 maya 3227 SetWindowText(dlg, pvar->ts->UIMsg);
1477     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1478 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
1479 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1480     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1481 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
1482 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1483     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1484 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
1485 maya 3227 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1486     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1487 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
1488 maya 3227 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1489     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1490     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1491     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1492     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1493     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1494     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1495    
1496 doda 4559 switch (pvar->dns_key_check) {
1497     case DNS_VERIFY_NOTFOUND:
1498 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1499 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1500     break;
1501     case DNS_VERIFY_MATCH:
1502     case DNS_VERIFY_AUTH_MATCH:
1503 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1504 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1505     break;
1506     case DNS_VERIFY_MISMATCH:
1507     case DNS_VERIFY_AUTH_MISMATCH:
1508 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1509 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1510     break;
1511     case DNS_VERIFY_DIFFERENTTYPE:
1512     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1513 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1514 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1515     break;
1516     }
1517    
1518     switch (pvar->dns_key_check) {
1519     case DNS_VERIFY_MATCH:
1520     case DNS_VERIFY_MISMATCH:
1521     case DNS_VERIFY_DIFFERENTTYPE:
1522 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1523 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1524     break;
1525     case DNS_VERIFY_AUTH_MATCH:
1526     case DNS_VERIFY_AUTH_MISMATCH:
1527     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1528 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1529 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1530     break;
1531     }
1532    
1533 maya 3227 init_hosts_dlg(pvar, dlg);
1534    
1535     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1536     GetObject(font, sizeof(LOGFONT), &logfont);
1537     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
1538     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1539     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1540 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1541     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1542 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1543     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1544     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1545     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1546     }
1547     else {
1548     DlgHostsReplaceFont = NULL;
1549     }
1550    
1551     // �f�t�H���g���`�F�b�N����������
1552     return TRUE; /* because we do not set the focus */
1553    
1554     case WM_COMMAND:
1555     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1556    
1557     switch (LOWORD(wParam)) {
1558     case IDC_CONTINUE:
1559 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1560     if (!pvar->cv->Ready) {
1561     goto canceled;
1562     }
1563    
1564 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1565     add_host_key(pvar);
1566     delete_different_key(pvar);
1567     }
1568    
1569     if (SSHv1(pvar)) {
1570     SSH_notify_host_OK(pvar);
1571     } else { // SSH2
1572     // SSH2���������� SSH_notify_host_OK() �������B
1573     }
1574    
1575     pvar->hosts_state.hosts_dialog = NULL;
1576    
1577     EndDialog(dlg, 1);
1578    
1579     if (DlgHostsReplaceFont != NULL) {
1580     DeleteObject(DlgHostsReplaceFont);
1581     }
1582    
1583     return TRUE;
1584    
1585     case IDCANCEL: /* kill the connection */
1586 yutakapon 5562 canceled:
1587 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
1588 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
1589 maya 3227 EndDialog(dlg, 0);
1590    
1591     if (DlgHostsReplaceFont != NULL) {
1592     DeleteObject(DlgHostsReplaceFont);
1593     }
1594    
1595     return TRUE;
1596    
1597     default:
1598     return FALSE;
1599     }
1600    
1601     default:
1602     return FALSE;
1603     }
1604     }
1605    
1606 maya 4332 //
1607     // �����z�X�g�����`�����������������m�F�_�C�A���O������
1608     //
1609     static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1610     LPARAM lParam)
1611     {
1612     PTInstVar pvar;
1613     LOGFONT logfont;
1614     HFONT font;
1615     char uimsg[MAX_UIMSG];
1616    
1617     switch (msg) {
1618     case WM_INITDIALOG:
1619     pvar = (PTInstVar) lParam;
1620     pvar->hosts_state.hosts_dialog = dlg;
1621     SetWindowLong(dlg, DWL_USER, lParam);
1622    
1623     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1624     GetWindowText(dlg, uimsg, sizeof(uimsg));
1625     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
1626     SetWindowText(dlg, pvar->ts->UIMsg);
1627     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1628 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
1629 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1630     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1631 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
1632 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1633     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1634     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
1635     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1636     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1637     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
1638     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1639     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1640     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1641     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1642     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1643     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1644     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1645    
1646 doda 4559 switch (pvar->dns_key_check) {
1647     case DNS_VERIFY_NOTFOUND:
1648 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1649 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1650     break;
1651     case DNS_VERIFY_MATCH:
1652     case DNS_VERIFY_AUTH_MATCH:
1653 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1654 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1655     break;
1656     case DNS_VERIFY_MISMATCH:
1657     case DNS_VERIFY_AUTH_MISMATCH:
1658 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1659 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1660     break;
1661     case DNS_VERIFY_DIFFERENTTYPE:
1662     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1663 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1664 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1665     break;
1666     }
1667    
1668     switch (pvar->dns_key_check) {
1669     case DNS_VERIFY_MATCH:
1670     case DNS_VERIFY_MISMATCH:
1671     case DNS_VERIFY_DIFFERENTTYPE:
1672 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1673 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1674     break;
1675     case DNS_VERIFY_AUTH_MATCH:
1676     case DNS_VERIFY_AUTH_MISMATCH:
1677     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1678 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1679 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1680     break;
1681     }
1682    
1683 maya 4332 init_hosts_dlg(pvar, dlg);
1684    
1685     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1686     GetObject(font, sizeof(LOGFONT), &logfont);
1687     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1688     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1689     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1690 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1691     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1692 maya 4332 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1693     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1694     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1695     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1696     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1697     }
1698     else {
1699     DlgHostsAddFont = NULL;
1700     }
1701    
1702     // add host check box ���f�t�H���g�� off ������
1703     // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1704    
1705     return TRUE; /* because we do not set the focus */
1706    
1707     case WM_COMMAND:
1708     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1709    
1710     switch (LOWORD(wParam)) {
1711     case IDC_CONTINUE:
1712 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1713     if (!pvar->cv->Ready) {
1714     goto canceled;
1715     }
1716    
1717 maya 4332 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1718     add_host_key(pvar);
1719     }
1720    
1721     if (SSHv1(pvar)) {
1722     SSH_notify_host_OK(pvar);
1723     } else { // SSH2
1724     // SSH2���������� SSH_notify_host_OK() �������B
1725     }
1726    
1727     pvar->hosts_state.hosts_dialog = NULL;
1728    
1729     EndDialog(dlg, 1);
1730    
1731     if (DlgHostsAddFont != NULL) {
1732     DeleteObject(DlgHostsAddFont);
1733     }
1734    
1735     return TRUE;
1736    
1737     case IDCANCEL: /* kill the connection */
1738 yutakapon 5562 canceled:
1739 maya 4332 pvar->hosts_state.hosts_dialog = NULL;
1740 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
1741 maya 4332 EndDialog(dlg, 0);
1742    
1743     if (DlgHostsAddFont != NULL) {
1744     DeleteObject(DlgHostsAddFont);
1745     }
1746    
1747     return TRUE;
1748    
1749     default:
1750     return FALSE;
1751     }
1752    
1753     default:
1754     return FALSE;
1755     }
1756     }
1757    
1758 maya 3227 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
1759     {
1760     if (pvar->hosts_state.hosts_dialog == NULL) {
1761     HWND cur_active = GetActiveWindow();
1762    
1763     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
1764     cur_active != NULL ? cur_active : wnd,
1765     hosts_add_dlg_proc, (LPARAM) pvar);
1766     }
1767     }
1768    
1769 maya 4330 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
1770 maya 3227 {
1771     if (pvar->hosts_state.hosts_dialog == NULL) {
1772     HWND cur_active = GetActiveWindow();
1773    
1774 maya 4330 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
1775 maya 3227 cur_active != NULL ? cur_active : wnd,
1776     hosts_replace_dlg_proc, (LPARAM) pvar);
1777     }
1778     }
1779    
1780 maya 4332 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
1781     {
1782     if (pvar->hosts_state.hosts_dialog == NULL) {
1783     HWND cur_active = GetActiveWindow();
1784    
1785     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
1786     cur_active != NULL ? cur_active : wnd,
1787     hosts_add2_dlg_proc, (LPARAM) pvar);
1788     }
1789     }
1790    
1791 maya 3227 //
1792     // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
1793     //
1794     // SSH2���������� (2006.3.24 yutaka)
1795     //
1796     BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key)
1797     {
1798 doda 4559 int found_different_key = 0, found_different_type_key = 0;
1799 maya 3227
1800 doda 4559 pvar->dns_key_check = DNS_VERIFY_NONE;
1801    
1802 maya 3227 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
1803     if (pvar->hosts_state.prefetched_hostname != NULL
1804     && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
1805 maya 4332 && match_key(pvar, key) == 1) {
1806 maya 3227
1807     if (SSHv1(pvar)) {
1808     SSH_notify_host_OK(pvar);
1809     } else {
1810     // SSH2���������� SSH_notify_host_OK() �������B
1811     }
1812     return TRUE;
1813     }
1814    
1815     // �������������������������A�������_���t�@�C��������������
1816     if (begin_read_host_files(pvar, 0)) {
1817     do {
1818     if (!read_host_key(pvar, hostname, tcpport, 0, 0)) {
1819     break;
1820     }
1821    
1822     if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
1823 maya 4332 int match = match_key(pvar, key);
1824     if (match == 1) {
1825 maya 3227 finish_read_host_files(pvar, 0);
1826     // ���������G���g�����Q�������A���v�����L�[�������������������B
1827     // SSH2���������������������������B(2006.3.29 yutaka)
1828     if (SSHv1(pvar)) {
1829     SSH_notify_host_OK(pvar);
1830     } else {
1831     // SSH2���������� SSH_notify_host_OK() �������B
1832     }
1833     return TRUE;
1834 maya 4332 }
1835     else if (match == 0) {
1836 maya 3227 // �L�[�� known_hosts ���������������A�L�[�����e���������B
1837     found_different_key = 1;
1838     }
1839 maya 4332 else {
1840     // �L�[���`������������
1841     found_different_type_key = 1;
1842     }
1843 maya 3227 }
1844     } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // �L�[�����������������������[�v����
1845    
1846     finish_read_host_files(pvar, 0);
1847     }
1848    
1849     // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
1850     pvar->hosts_state.hostkey.type = key->type;
1851 maya 4321 switch (key->type) {
1852     case KEY_RSA1: // SSH1
1853 maya 3227 pvar->hosts_state.hostkey.bits = key->bits;
1854     pvar->hosts_state.hostkey.exp = copy_mp_int(key->exp);
1855     pvar->hosts_state.hostkey.mod = copy_mp_int(key->mod);
1856 maya 4321 break;
1857     case KEY_RSA: // SSH2 RSA
1858 maya 3227 pvar->hosts_state.hostkey.rsa = duplicate_RSA(key->rsa);
1859 maya 4321 break;
1860     case KEY_DSA: // SSH2 DSA
1861 maya 3227 pvar->hosts_state.hostkey.dsa = duplicate_DSA(key->dsa);
1862 maya 4321 break;
1863     case KEY_ECDSA256: // SSH2 ECDSA
1864     case KEY_ECDSA384:
1865     case KEY_ECDSA521:
1866     pvar->hosts_state.hostkey.ecdsa = EC_KEY_dup(key->ecdsa);
1867     break;
1868 yutakapon 5545 case KEY_ED25519:
1869     pvar->hosts_state.hostkey.ed25519_pk = duplicate_ED25519_PK(key->ed25519_pk);
1870     break;
1871 maya 3227 }
1872     free(pvar->hosts_state.prefetched_hostname);
1873     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
1874    
1875 yutakapon 3631 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
1876     if (pvar->nocheck_known_hosts == TRUE) {
1877     return TRUE;
1878     }
1879    
1880 doda 4542 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
1881 doda 4559 pvar->dns_key_check = verify_hostkey_dns(hostname, key);
1882 doda 4542 }
1883    
1884 maya 3227 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
1885     // �������K�v�����������A�����R�[�������X�����B
1886     // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
1887     // (2007.10.1 yutaka)
1888     if (found_different_key) {
1889 maya 4330 HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar);
1890 maya 4332 }
1891     else if (found_different_type_key) {
1892     HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar);
1893     }
1894     else {
1895 maya 3227 HOSTS_do_unknown_host_dialog(pvar->NotificationWindow, pvar);
1896     }
1897    
1898     return TRUE;
1899     }
1900    
1901     void HOSTS_notify_disconnecting(PTInstVar pvar)
1902     {
1903     if (pvar->hosts_state.hosts_dialog != NULL) {
1904 doda 4531 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
1905 maya 3227 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
1906     EnableWindow(pvar->NotificationWindow, TRUE);
1907     }
1908     }
1909    
1910     void HOSTS_end(PTInstVar pvar)
1911     {
1912     int i;
1913    
1914     free(pvar->hosts_state.prefetched_hostname);
1915     init_hostkey(&pvar->hosts_state.hostkey);
1916    
1917     if (pvar->hosts_state.file_names != NULL) {
1918     for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
1919     free(pvar->hosts_state.file_names[i]);
1920     }
1921     free(pvar->hosts_state.file_names);
1922     }
1923     }

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