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 5562 - (hide annotations) (download) (as text)
Mon Mar 31 06:28:16 2014 UTC (10 years ago) by yutakapon
File MIME type: text/x-csrc
File size: 55862 byte(s)
チケット #33579
認証ダイアログの表示中に、サーバ側から切断された場合、アプリケーションフォルトで落ちる
問題を修正した。

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     notify_fatal_error(pvar, pvar->ts->UIMsg);
680     }
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     notify_fatal_error(pvar, pvar->ts->UIMsg);
691     }
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     // ���J����������������������
785 maya 4332 // -1 ... �����^������
786     // 0 ... ����������
787     // 1 ... ������
788     static int match_key(PTInstVar pvar, Key *key)
789 maya 3227 {
790     int bits;
791     unsigned char FAR * exp;
792     unsigned char FAR * mod;
793 maya 4321 const EC_GROUP *group;
794     const EC_POINT *pa, *pb;
795 yutakapon 5545 Key *a, *b;
796 maya 3227
797 maya 4332 if (pvar->hosts_state.hostkey.type != key->type) {
798     return -1;
799     }
800    
801 maya 4321 switch (key->type) {
802     case KEY_RSA1: // SSH1 host public key
803 maya 3227 bits = key->bits;
804     exp = key->exp;
805     mod = key->mod;
806    
807     /* just check for equal exponent and modulus */
808     return equal_mp_ints(exp, pvar->hosts_state.hostkey.exp)
809     && equal_mp_ints(mod, pvar->hosts_state.hostkey.mod);
810     /*
811     return equal_mp_ints(exp, pvar->hosts_state.key_exp)
812     && equal_mp_ints(mod, pvar->hosts_state.key_mod);
813     */
814    
815 maya 4321 case KEY_RSA: // SSH2 RSA host public key
816 maya 3227 return key->rsa != NULL && pvar->hosts_state.hostkey.rsa != NULL &&
817     BN_cmp(key->rsa->e, pvar->hosts_state.hostkey.rsa->e) == 0 &&
818     BN_cmp(key->rsa->n, pvar->hosts_state.hostkey.rsa->n) == 0;
819    
820 maya 4321 case KEY_DSA: // SSH2 DSA host public key
821 maya 3227 return key->dsa != NULL && pvar->hosts_state.hostkey.dsa &&
822     BN_cmp(key->dsa->p, pvar->hosts_state.hostkey.dsa->p) == 0 &&
823     BN_cmp(key->dsa->q, pvar->hosts_state.hostkey.dsa->q) == 0 &&
824     BN_cmp(key->dsa->g, pvar->hosts_state.hostkey.dsa->g) == 0 &&
825     BN_cmp(key->dsa->pub_key, pvar->hosts_state.hostkey.dsa->pub_key) == 0;
826    
827 maya 4321 case KEY_ECDSA256:
828     case KEY_ECDSA384:
829     case KEY_ECDSA521:
830     if (key->ecdsa == NULL || pvar->hosts_state.hostkey.ecdsa == NULL) {
831     return FALSE;
832     }
833     group = EC_KEY_get0_group(key->ecdsa);
834     pa = EC_KEY_get0_public_key(key->ecdsa),
835     pb = EC_KEY_get0_public_key(pvar->hosts_state.hostkey.ecdsa);
836     return EC_POINT_cmp(group, pa, pb, NULL) == 0;
837    
838 yutakapon 5545 case KEY_ED25519:
839     a = key;
840     b = &pvar->hosts_state.hostkey;
841     return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
842     memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;
843    
844 maya 4321 default:
845 maya 4307 return FALSE;
846     }
847 maya 3227
848     }
849    
850     static void init_hosts_dlg(PTInstVar pvar, HWND dlg)
851     {
852     char buf[1024];
853     char buf2[2048];
854     int i, j;
855     int ch;
856     char *fp = NULL;
857    
858     // static text�� # �������z�X�g�����u������
859     GetDlgItemText(dlg, IDC_HOSTWARNING, buf, sizeof(buf));
860     for (i = 0; (ch = buf[i]) != 0 && ch != '#'; i++) {
861     buf2[i] = ch;
862     }
863     strncpy_s(buf2 + i, sizeof(buf2) - i,
864     pvar->hosts_state.prefetched_hostname, _TRUNCATE);
865     j = i + strlen(buf2 + i);
866     for (; buf[i] == '#'; i++) {
867     }
868     strncpy_s(buf2 + j, sizeof(buf2) - j, buf + i, _TRUNCATE);
869    
870     SetDlgItemText(dlg, IDC_HOSTWARNING, buf2);
871    
872     // fingerprint����������
873     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX);
874     SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp);
875     free(fp);
876    
877     // �r�W���A����fingerprint���\������
878     fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART);
879     SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETTEXT, 0, (LPARAM)fp);
880     SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), TRUE);
881     free(fp);
882     }
883    
884     static int print_mp_int(char FAR * buf, unsigned char FAR * mp)
885     {
886     int i = 0, j, k;
887     BIGNUM *num = BN_new();
888     int ch;
889    
890     BN_bin2bn(mp + 2, (get_ushort16_MSBfirst(mp) + 7) / 8, num);
891    
892     do {
893     buf[i] = (char) ((BN_div_word(num, 10)) + '0');
894     i++;
895     } while (!BN_is_zero(num));
896    
897     /* we need to reverse the digits */
898     for (j = 0, k = i - 1; j < k; j++, k--) {
899     ch = buf[j];
900     buf[j] = buf[k];
901     buf[k] = ch;
902     }
903    
904     buf[i] = 0;
905     return i;
906     }
907    
908     //
909     // known_hosts �t�@�C�������������G���g�������������B
910     //
911     static char FAR *format_host_key(PTInstVar pvar)
912     {
913     int host_len = strlen(pvar->hosts_state.prefetched_hostname);
914     char *result = NULL;
915     int index;
916 maya 4378 ssh_keytype type = pvar->hosts_state.hostkey.type;
917 maya 3227
918 maya 4321 switch (type) {
919     case KEY_RSA1:
920     {
921 maya 3227 int result_len = host_len + 50 + 8 +
922     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.exp) / 3 +
923     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.mod) / 3;
924     result = (char FAR *) malloc(result_len);
925    
926     if (pvar->ssh_state.tcpport == 22) {
927     strncpy_s(result, result_len, pvar->hosts_state.prefetched_hostname, _TRUNCATE);
928     index = host_len;
929     }
930     else {
931     _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
932     pvar->hosts_state.prefetched_hostname,
933     pvar->ssh_state.tcpport);
934     index = strlen(result);
935     }
936    
937     _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
938     " %d ", pvar->hosts_state.hostkey.bits);
939     index += strlen(result + index);
940     index += print_mp_int(result + index, pvar->hosts_state.hostkey.exp);
941     result[index] = ' ';
942     index++;
943     index += print_mp_int(result + index, pvar->hosts_state.hostkey.mod);
944     strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
945    
946 maya 4321 break;
947     }
948    
949     case KEY_RSA:
950     case KEY_DSA:
951     case KEY_ECDSA256:
952     case KEY_ECDSA384:
953     case KEY_ECDSA521:
954 yutakapon 5545 case KEY_ED25519:
955 maya 4321 {
956 maya 3227 Key *key = &pvar->hosts_state.hostkey;
957     char *blob = NULL;
958     int blen, uulen, msize;
959     char *uu = NULL;
960     int n;
961    
962     key_to_blob(key, &blob, &blen);
963     uulen = 2 * blen;
964     uu = malloc(uulen);
965     if (uu == NULL) {
966     goto error;
967     }
968     n = uuencode(blob, blen, uu, uulen);
969     if (n > 0) {
970     msize = host_len + 50 + uulen;
971     result = malloc(msize);
972     if (result == NULL) {
973     goto error;
974     }
975    
976     // setup
977     if (pvar->ssh_state.tcpport == 22) {
978     _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
979     pvar->hosts_state.prefetched_hostname,
980     get_sshname_from_key(key),
981     uu);
982     } else {
983     _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
984     pvar->hosts_state.prefetched_hostname,
985     pvar->ssh_state.tcpport,
986     get_sshname_from_key(key),
987     uu);
988     }
989     }
990     error:
991     if (blob != NULL)
992     free(blob);
993     if (uu != NULL)
994     free(uu);
995    
996 maya 4321 break;
997     }
998    
999     default:
1000 maya 3227 return NULL;
1001    
1002     }
1003    
1004     return result;
1005     }
1006    
1007     static void add_host_key(PTInstVar pvar)
1008     {
1009     char FAR *name = NULL;
1010    
1011     if ( pvar->hosts_state.file_names != NULL)
1012     name = pvar->hosts_state.file_names[0];
1013    
1014     if (name == NULL || name[0] == 0) {
1015     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1016     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1017     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1018     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1019     } else {
1020     char FAR *keydata = format_host_key(pvar);
1021     int length = strlen(keydata);
1022     int fd;
1023     int amount_written;
1024     int close_result;
1025     char buf[FILENAME_MAX];
1026    
1027     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1028     fd = _open(buf,
1029     _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1030     _S_IREAD | _S_IWRITE);
1031     if (fd == -1) {
1032     if (errno == EACCES) {
1033     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1034     "An error occurred while trying to write the host key.\n"
1035     "You do not have permission to write to the known-hosts file.");
1036     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1037     } else {
1038     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1039     "An error occurred while trying to write the host key.\n"
1040     "The host key could not be written.");
1041     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1042     }
1043     return;
1044     }
1045    
1046     amount_written = _write(fd, keydata, length);
1047     free(keydata);
1048     close_result = _close(fd);
1049    
1050     if (amount_written != length || close_result == -1) {
1051     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1052     "An error occurred while trying to write the host key.\n"
1053     "The host key could not be written.");
1054     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1055     }
1056     }
1057     }
1058    
1059     static char FAR *copy_mp_int(char FAR * num)
1060     {
1061     int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;
1062     char FAR *result = (char FAR *) malloc(len);
1063    
1064     if (result != NULL) {
1065     memcpy(result, num, len);
1066     }
1067    
1068     return result;
1069     }
1070    
1071     //
1072     // �����z�X�g�����e���������L�[����������
1073     // add_host_key ����������������
1074     //
1075     static void delete_different_key(PTInstVar pvar)
1076     {
1077     char FAR *name = pvar->hosts_state.file_names[0];
1078    
1079     if (name == NULL || name[0] == 0) {
1080     UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1081     "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1082     "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1083     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1084     }
1085     else {
1086     Key key; // ���������z�X�g���L�[
1087     int length;
1088     char filename[MAX_PATH];
1089     char tmp[L_tmpnam];
1090     int fd;
1091     int amount_written = 0;
1092     int close_result;
1093     int data_index = 0;
1094     char buf[FILENAME_MAX];
1095    
1096     // �������������t�@�C�����J��
1097     _getcwd(filename, sizeof(filename));
1098     tmpnam_s(tmp,sizeof(tmp));
1099     strcat_s(filename, sizeof(filename), tmp);
1100     fd = _open(filename,
1101     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1102     _S_IREAD | _S_IWRITE);
1103    
1104     if (fd == -1) {
1105     if (errno == EACCES) {
1106     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1107     "An error occurred while trying to write the host key.\n"
1108     "You do not have permission to write to the known-hosts file.");
1109     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1110     } else {
1111     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1112     "An error occurred while trying to write the host key.\n"
1113     "The host key could not be written.");
1114     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1115     }
1116     return;
1117     }
1118    
1119     // ���������T�[�o���L�[����������
1120 yutakapon 5545 memset(&key, 0, sizeof(key));
1121 maya 4321 switch (pvar->hosts_state.hostkey.type) {
1122     case KEY_RSA1: // SSH1
1123 maya 3227 key.type = KEY_RSA1;
1124     key.bits = pvar->hosts_state.hostkey.bits;
1125     key.exp = copy_mp_int(pvar->hosts_state.hostkey.exp);
1126     key.mod = copy_mp_int(pvar->hosts_state.hostkey.mod);
1127 maya 4321 break;
1128     case KEY_RSA: // SSH2 RSA
1129 maya 3227 key.type = KEY_RSA;
1130     key.rsa = duplicate_RSA(pvar->hosts_state.hostkey.rsa);
1131 maya 4321 break;
1132     case KEY_DSA: // SSH2 DSA
1133 maya 3227 key.type = KEY_DSA;
1134     key.dsa = duplicate_DSA(pvar->hosts_state.hostkey.dsa);
1135 maya 4321 break;
1136     case KEY_ECDSA256:
1137     case KEY_ECDSA384:
1138     case KEY_ECDSA521:
1139     key.type = pvar->hosts_state.hostkey.type;
1140     key.ecdsa = EC_KEY_dup(pvar->hosts_state.hostkey.ecdsa);
1141     break;
1142 yutakapon 5545 case KEY_ED25519:
1143     key.type = pvar->hosts_state.hostkey.type;
1144     key.ed25519_pk = duplicate_ED25519_PK(pvar->hosts_state.hostkey.ed25519_pk);
1145     break;
1146 maya 3227 }
1147    
1148     // �t�@�C��������������
1149     begin_read_host_files(pvar, 0);
1150     do {
1151     int host_index = 0;
1152     int matched = 0;
1153     int keybits = 0;
1154     char FAR *data;
1155     int do_write = 0;
1156     length = amount_written = 0;
1157    
1158     if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1)) {
1159     break;
1160     }
1161    
1162     if (data_index == pvar->hosts_state.file_data_index) {
1163     // index ���i������ == ��������������
1164     break;
1165     }
1166    
1167     data = pvar->hosts_state.file_data + data_index;
1168     host_index = eat_spaces(data);
1169    
1170     if (data[host_index] == '#') {
1171     do_write = 1;
1172     }
1173     else {
1174     // �z�X�g������
1175     host_index--;
1176     do {
1177     int negated;
1178     int bracketed;
1179     char *end_bracket;
1180     int host_matched = 0;
1181     unsigned short keyfile_port = 22;
1182    
1183     host_index++;
1184     negated = data[host_index] == '!';
1185    
1186     if (negated) {
1187     host_index++;
1188     bracketed = data[host_index] == '[';
1189     if (bracketed) {
1190     end_bracket = strstr(data + host_index + 1, "]:");
1191     if (end_bracket != NULL) {
1192     *end_bracket = ' ';
1193     host_index++;
1194     }
1195     }
1196     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1197     if (bracketed && end_bracket != NULL) {
1198     *end_bracket = ']';
1199     keyfile_port = atoi(end_bracket + 2);
1200     }
1201     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1202     matched = 0;
1203     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1204     host_index--;
1205     do {
1206     host_index++;
1207     host_index += eat_to_end_of_pattern(data + host_index);
1208     } while (data[host_index] == ',');
1209     break;
1210     }
1211     }
1212     else {
1213     bracketed = data[host_index] == '[';
1214     if (bracketed) {
1215     end_bracket = strstr(data + host_index + 1, "]:");
1216     if (end_bracket != NULL) {
1217     *end_bracket = ' ';
1218     host_index++;
1219     }
1220     }
1221     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1222     if (bracketed && end_bracket != NULL) {
1223     *end_bracket = ']';
1224     keyfile_port = atoi(end_bracket + 2);
1225     }
1226     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1227     matched = 1;
1228     }
1229     }
1230     host_index += eat_to_end_of_pattern(data + host_index);
1231     } while (data[host_index] == ',');
1232    
1233     // �z�X�g������������
1234 maya 4332 if (!matched) {
1235 maya 3227 do_write = 1;
1236     }
1237 maya 4332 // �z�X�g��������
1238 maya 3227 else {
1239 maya 4332 // �����`�������� or ���v�����L�[
1240     if (match_key(pvar, &key) != 0) {
1241     do_write = 1;
1242 maya 3227 }
1243 maya 4332 // �����`�������������v�������L�[���X�L�b�v������
1244 maya 3227 }
1245     }
1246    
1247     // ������������
1248     if (do_write) {
1249     length = pvar->hosts_state.file_data_index - data_index;
1250     amount_written =
1251     _write(fd, pvar->hosts_state.file_data + data_index,
1252     length);
1253    
1254     if (amount_written != length) {
1255     goto error1;
1256     }
1257     }
1258     data_index = pvar->hosts_state.file_data_index;
1259     } while (1); // ������������
1260    
1261     error1:
1262     close_result = _close(fd);
1263     if (amount_written != length || close_result == -1) {
1264     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1265     "An error occurred while trying to write the host key.\n"
1266     "The host key could not be written.");
1267     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1268     goto error2;
1269     }
1270    
1271     // �������������t�@�C���������l�[��
1272     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1273     _unlink(buf);
1274     rename(filename, buf);
1275    
1276     error2:
1277     _unlink(filename);
1278    
1279     finish_read_host_files(pvar, 0);
1280 yutakapon 5545
1281     // ���������������������������B
1282     key_free(&key);
1283 maya 3227 }
1284     }
1285    
1286     //
1287     // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1288     // ���[�U���m�F�������B
1289     // TODO: finger print���\�����s���B
1290     // (2006.3.25 yutaka)
1291     //
1292     static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1293     LPARAM lParam)
1294     {
1295     PTInstVar pvar;
1296     LOGFONT logfont;
1297     HFONT font;
1298     char uimsg[MAX_UIMSG];
1299    
1300     switch (msg) {
1301     case WM_INITDIALOG:
1302     pvar = (PTInstVar) lParam;
1303     pvar->hosts_state.hosts_dialog = dlg;
1304     SetWindowLong(dlg, DWL_USER, lParam);
1305    
1306     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1307     GetWindowText(dlg, uimsg, sizeof(uimsg));
1308     UTIL_get_lang_msg("DLG_UNKNONWHOST_TITLE", pvar, uimsg);
1309     SetWindowText(dlg, pvar->ts->UIMsg);
1310     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1311 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING", pvar, uimsg);
1312 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1313     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1314 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING2", pvar, uimsg);
1315 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1316     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1317     UTIL_get_lang_msg("DLG_UNKNOWNHOST_FINGERPRINT", pvar, uimsg);
1318     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1319     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1320     UTIL_get_lang_msg("DLG_UNKNOWNHOST_ADD", pvar, uimsg);
1321     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1322     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1323     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1324     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1325     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1326     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1327     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1328    
1329 doda 4559 switch (pvar->dns_key_check) {
1330     case DNS_VERIFY_NOTFOUND:
1331 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1332 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1333     break;
1334     case DNS_VERIFY_MATCH:
1335     case DNS_VERIFY_AUTH_MATCH:
1336 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1337 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1338     break;
1339     case DNS_VERIFY_MISMATCH:
1340     case DNS_VERIFY_AUTH_MISMATCH:
1341 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1342 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1343     break;
1344     case DNS_VERIFY_DIFFERENTTYPE:
1345     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1346 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1347 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1348     break;
1349     }
1350    
1351     switch (pvar->dns_key_check) {
1352     case DNS_VERIFY_MATCH:
1353     case DNS_VERIFY_MISMATCH:
1354     case DNS_VERIFY_DIFFERENTTYPE:
1355 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1356 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1357     break;
1358     case DNS_VERIFY_AUTH_MATCH:
1359     case DNS_VERIFY_AUTH_MISMATCH:
1360     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1361 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1362 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1363     break;
1364     }
1365    
1366 maya 3227 init_hosts_dlg(pvar, dlg);
1367    
1368     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1369     GetObject(font, sizeof(LOGFONT), &logfont);
1370     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1371     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1372     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1373 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1374     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1375 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1376     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1377     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1378     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1379     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1380     }
1381     else {
1382     DlgHostsAddFont = NULL;
1383     }
1384    
1385     // add host check box���`�F�b�N���f�t�H���g������������
1386     SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1387    
1388     return TRUE; /* because we do not set the focus */
1389    
1390     case WM_COMMAND:
1391     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1392    
1393     switch (LOWORD(wParam)) {
1394     case IDC_CONTINUE:
1395 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1396     if (!pvar->cv->Ready) {
1397     goto canceled;
1398     }
1399    
1400 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1401     add_host_key(pvar);
1402     }
1403    
1404     if (SSHv1(pvar)) {
1405     SSH_notify_host_OK(pvar);
1406     } else { // SSH2
1407     // SSH2���������� SSH_notify_host_OK() �������B
1408     }
1409    
1410     pvar->hosts_state.hosts_dialog = NULL;
1411    
1412     EndDialog(dlg, 1);
1413    
1414     if (DlgHostsAddFont != NULL) {
1415     DeleteObject(DlgHostsAddFont);
1416     }
1417    
1418     return TRUE;
1419    
1420     case IDCANCEL: /* kill the connection */
1421 yutakapon 5562 canceled:
1422 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
1423     notify_closed_connection(pvar);
1424     EndDialog(dlg, 0);
1425    
1426     if (DlgHostsAddFont != NULL) {
1427     DeleteObject(DlgHostsAddFont);
1428     }
1429    
1430     return TRUE;
1431    
1432     default:
1433     return FALSE;
1434     }
1435    
1436     default:
1437     return FALSE;
1438     }
1439     }
1440    
1441     //
1442     // �u�����������m�F�_�C�A���O������
1443     //
1444     static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1445     LPARAM lParam)
1446     {
1447     PTInstVar pvar;
1448     LOGFONT logfont;
1449     HFONT font;
1450     char uimsg[MAX_UIMSG];
1451    
1452     switch (msg) {
1453     case WM_INITDIALOG:
1454     pvar = (PTInstVar) lParam;
1455     pvar->hosts_state.hosts_dialog = dlg;
1456     SetWindowLong(dlg, DWL_USER, lParam);
1457    
1458     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1459     GetWindowText(dlg, uimsg, sizeof(uimsg));
1460 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
1461 maya 3227 SetWindowText(dlg, pvar->ts->UIMsg);
1462     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1463 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
1464 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1465     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1466 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
1467 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1468     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1469 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
1470 maya 3227 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1471     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1472 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
1473 maya 3227 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1474     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1475     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1476     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1477     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1478     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1479     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1480    
1481 doda 4559 switch (pvar->dns_key_check) {
1482     case DNS_VERIFY_NOTFOUND:
1483 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1484 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1485     break;
1486     case DNS_VERIFY_MATCH:
1487     case DNS_VERIFY_AUTH_MATCH:
1488 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1489 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1490     break;
1491     case DNS_VERIFY_MISMATCH:
1492     case DNS_VERIFY_AUTH_MISMATCH:
1493 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1494 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1495     break;
1496     case DNS_VERIFY_DIFFERENTTYPE:
1497     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1498 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1499 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1500     break;
1501     }
1502    
1503     switch (pvar->dns_key_check) {
1504     case DNS_VERIFY_MATCH:
1505     case DNS_VERIFY_MISMATCH:
1506     case DNS_VERIFY_DIFFERENTTYPE:
1507 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1508 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1509     break;
1510     case DNS_VERIFY_AUTH_MATCH:
1511     case DNS_VERIFY_AUTH_MISMATCH:
1512     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1513 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1514 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1515     break;
1516     }
1517    
1518 maya 3227 init_hosts_dlg(pvar, dlg);
1519    
1520     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1521     GetObject(font, sizeof(LOGFONT), &logfont);
1522     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
1523     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1524     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1525 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1526     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1527 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1528     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1529     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1530     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1531     }
1532     else {
1533     DlgHostsReplaceFont = NULL;
1534     }
1535    
1536     // �f�t�H���g���`�F�b�N����������
1537     return TRUE; /* because we do not set the focus */
1538    
1539     case WM_COMMAND:
1540     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1541    
1542     switch (LOWORD(wParam)) {
1543     case IDC_CONTINUE:
1544 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1545     if (!pvar->cv->Ready) {
1546     goto canceled;
1547     }
1548    
1549 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1550     add_host_key(pvar);
1551     delete_different_key(pvar);
1552     }
1553    
1554     if (SSHv1(pvar)) {
1555     SSH_notify_host_OK(pvar);
1556     } else { // SSH2
1557     // SSH2���������� SSH_notify_host_OK() �������B
1558     }
1559    
1560     pvar->hosts_state.hosts_dialog = NULL;
1561    
1562     EndDialog(dlg, 1);
1563    
1564     if (DlgHostsReplaceFont != NULL) {
1565     DeleteObject(DlgHostsReplaceFont);
1566     }
1567    
1568     return TRUE;
1569    
1570     case IDCANCEL: /* kill the connection */
1571 yutakapon 5562 canceled:
1572 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
1573     notify_closed_connection(pvar);
1574     EndDialog(dlg, 0);
1575    
1576     if (DlgHostsReplaceFont != NULL) {
1577     DeleteObject(DlgHostsReplaceFont);
1578     }
1579    
1580     return TRUE;
1581    
1582     default:
1583     return FALSE;
1584     }
1585    
1586     default:
1587     return FALSE;
1588     }
1589     }
1590    
1591 maya 4332 //
1592     // �����z�X�g�����`�����������������m�F�_�C�A���O������
1593     //
1594     static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1595     LPARAM lParam)
1596     {
1597     PTInstVar pvar;
1598     LOGFONT logfont;
1599     HFONT font;
1600     char uimsg[MAX_UIMSG];
1601    
1602     switch (msg) {
1603     case WM_INITDIALOG:
1604     pvar = (PTInstVar) lParam;
1605     pvar->hosts_state.hosts_dialog = dlg;
1606     SetWindowLong(dlg, DWL_USER, lParam);
1607    
1608     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1609     GetWindowText(dlg, uimsg, sizeof(uimsg));
1610     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
1611     SetWindowText(dlg, pvar->ts->UIMsg);
1612     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1613 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
1614 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1615     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1616 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
1617 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1618     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1619     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
1620     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1621     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1622     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
1623     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1624     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1625     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1626     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1627     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1628     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1629     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1630    
1631 doda 4559 switch (pvar->dns_key_check) {
1632     case DNS_VERIFY_NOTFOUND:
1633 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1634 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1635     break;
1636     case DNS_VERIFY_MATCH:
1637     case DNS_VERIFY_AUTH_MATCH:
1638 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1639 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1640     break;
1641     case DNS_VERIFY_MISMATCH:
1642     case DNS_VERIFY_AUTH_MISMATCH:
1643 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1644 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1645     break;
1646     case DNS_VERIFY_DIFFERENTTYPE:
1647     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1648 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1649 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1650     break;
1651     }
1652    
1653     switch (pvar->dns_key_check) {
1654     case DNS_VERIFY_MATCH:
1655     case DNS_VERIFY_MISMATCH:
1656     case DNS_VERIFY_DIFFERENTTYPE:
1657 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1658 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1659     break;
1660     case DNS_VERIFY_AUTH_MATCH:
1661     case DNS_VERIFY_AUTH_MISMATCH:
1662     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1663 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1664 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1665     break;
1666     }
1667    
1668 maya 4332 init_hosts_dlg(pvar, dlg);
1669    
1670     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1671     GetObject(font, sizeof(LOGFONT), &logfont);
1672     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1673     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1674     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1675 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1676     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1677 maya 4332 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1678     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1679     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1680     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1681     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1682     }
1683     else {
1684     DlgHostsAddFont = NULL;
1685     }
1686    
1687     // add host check box ���f�t�H���g�� off ������
1688     // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1689    
1690     return TRUE; /* because we do not set the focus */
1691    
1692     case WM_COMMAND:
1693     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1694    
1695     switch (LOWORD(wParam)) {
1696     case IDC_CONTINUE:
1697 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1698     if (!pvar->cv->Ready) {
1699     goto canceled;
1700     }
1701    
1702 maya 4332 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1703     add_host_key(pvar);
1704     }
1705    
1706     if (SSHv1(pvar)) {
1707     SSH_notify_host_OK(pvar);
1708     } else { // SSH2
1709     // SSH2���������� SSH_notify_host_OK() �������B
1710     }
1711    
1712     pvar->hosts_state.hosts_dialog = NULL;
1713    
1714     EndDialog(dlg, 1);
1715    
1716     if (DlgHostsAddFont != NULL) {
1717     DeleteObject(DlgHostsAddFont);
1718     }
1719    
1720     return TRUE;
1721    
1722     case IDCANCEL: /* kill the connection */
1723 yutakapon 5562 canceled:
1724 maya 4332 pvar->hosts_state.hosts_dialog = NULL;
1725     notify_closed_connection(pvar);
1726     EndDialog(dlg, 0);
1727    
1728     if (DlgHostsAddFont != NULL) {
1729     DeleteObject(DlgHostsAddFont);
1730     }
1731    
1732     return TRUE;
1733    
1734     default:
1735     return FALSE;
1736     }
1737    
1738     default:
1739     return FALSE;
1740     }
1741     }
1742    
1743 maya 3227 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
1744     {
1745     if (pvar->hosts_state.hosts_dialog == NULL) {
1746     HWND cur_active = GetActiveWindow();
1747    
1748     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
1749     cur_active != NULL ? cur_active : wnd,
1750     hosts_add_dlg_proc, (LPARAM) pvar);
1751     }
1752     }
1753    
1754 maya 4330 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
1755 maya 3227 {
1756     if (pvar->hosts_state.hosts_dialog == NULL) {
1757     HWND cur_active = GetActiveWindow();
1758    
1759 maya 4330 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
1760 maya 3227 cur_active != NULL ? cur_active : wnd,
1761     hosts_replace_dlg_proc, (LPARAM) pvar);
1762     }
1763     }
1764    
1765 maya 4332 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
1766     {
1767     if (pvar->hosts_state.hosts_dialog == NULL) {
1768     HWND cur_active = GetActiveWindow();
1769    
1770     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
1771     cur_active != NULL ? cur_active : wnd,
1772     hosts_add2_dlg_proc, (LPARAM) pvar);
1773     }
1774     }
1775    
1776 maya 3227 //
1777     // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
1778     //
1779     // SSH2���������� (2006.3.24 yutaka)
1780     //
1781     BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key)
1782     {
1783 doda 4559 int found_different_key = 0, found_different_type_key = 0;
1784 maya 3227
1785 doda 4559 pvar->dns_key_check = DNS_VERIFY_NONE;
1786    
1787 maya 3227 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
1788     if (pvar->hosts_state.prefetched_hostname != NULL
1789     && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
1790 maya 4332 && match_key(pvar, key) == 1) {
1791 maya 3227
1792     if (SSHv1(pvar)) {
1793     SSH_notify_host_OK(pvar);
1794     } else {
1795     // SSH2���������� SSH_notify_host_OK() �������B
1796     }
1797     return TRUE;
1798     }
1799    
1800     // �������������������������A�������_���t�@�C��������������
1801     if (begin_read_host_files(pvar, 0)) {
1802     do {
1803     if (!read_host_key(pvar, hostname, tcpport, 0, 0)) {
1804     break;
1805     }
1806    
1807     if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
1808 maya 4332 int match = match_key(pvar, key);
1809     if (match == 1) {
1810 maya 3227 finish_read_host_files(pvar, 0);
1811     // ���������G���g�����Q�������A���v�����L�[�������������������B
1812     // SSH2���������������������������B(2006.3.29 yutaka)
1813     if (SSHv1(pvar)) {
1814     SSH_notify_host_OK(pvar);
1815     } else {
1816     // SSH2���������� SSH_notify_host_OK() �������B
1817     }
1818     return TRUE;
1819 maya 4332 }
1820     else if (match == 0) {
1821 maya 3227 // �L�[�� known_hosts ���������������A�L�[�����e���������B
1822     found_different_key = 1;
1823     }
1824 maya 4332 else {
1825     // �L�[���`������������
1826     found_different_type_key = 1;
1827     }
1828 maya 3227 }
1829     } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // �L�[�����������������������[�v����
1830    
1831     finish_read_host_files(pvar, 0);
1832     }
1833    
1834     // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
1835     pvar->hosts_state.hostkey.type = key->type;
1836 maya 4321 switch (key->type) {
1837     case KEY_RSA1: // SSH1
1838 maya 3227 pvar->hosts_state.hostkey.bits = key->bits;
1839     pvar->hosts_state.hostkey.exp = copy_mp_int(key->exp);
1840     pvar->hosts_state.hostkey.mod = copy_mp_int(key->mod);
1841 maya 4321 break;
1842     case KEY_RSA: // SSH2 RSA
1843 maya 3227 pvar->hosts_state.hostkey.rsa = duplicate_RSA(key->rsa);
1844 maya 4321 break;
1845     case KEY_DSA: // SSH2 DSA
1846 maya 3227 pvar->hosts_state.hostkey.dsa = duplicate_DSA(key->dsa);
1847 maya 4321 break;
1848     case KEY_ECDSA256: // SSH2 ECDSA
1849     case KEY_ECDSA384:
1850     case KEY_ECDSA521:
1851     pvar->hosts_state.hostkey.ecdsa = EC_KEY_dup(key->ecdsa);
1852     break;
1853 yutakapon 5545 case KEY_ED25519:
1854     pvar->hosts_state.hostkey.ed25519_pk = duplicate_ED25519_PK(key->ed25519_pk);
1855     break;
1856 maya 3227 }
1857     free(pvar->hosts_state.prefetched_hostname);
1858     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
1859    
1860 yutakapon 3631 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
1861     if (pvar->nocheck_known_hosts == TRUE) {
1862     return TRUE;
1863     }
1864    
1865 doda 4542 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
1866 doda 4559 pvar->dns_key_check = verify_hostkey_dns(hostname, key);
1867 doda 4542 }
1868    
1869 maya 3227 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
1870     // �������K�v�����������A�����R�[�������X�����B
1871     // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
1872     // (2007.10.1 yutaka)
1873     if (found_different_key) {
1874 maya 4330 HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar);
1875 maya 4332 }
1876     else if (found_different_type_key) {
1877     HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar);
1878     }
1879     else {
1880 maya 3227 HOSTS_do_unknown_host_dialog(pvar->NotificationWindow, pvar);
1881     }
1882    
1883     return TRUE;
1884     }
1885    
1886     void HOSTS_notify_disconnecting(PTInstVar pvar)
1887     {
1888     if (pvar->hosts_state.hosts_dialog != NULL) {
1889 doda 4531 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
1890 maya 3227 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
1891     EnableWindow(pvar->NotificationWindow, TRUE);
1892     }
1893     }
1894    
1895     void HOSTS_end(PTInstVar pvar)
1896     {
1897     int i;
1898    
1899     free(pvar->hosts_state.prefetched_hostname);
1900     init_hostkey(&pvar->hosts_state.hostkey);
1901    
1902     if (pvar->hosts_state.file_names != NULL) {
1903     for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
1904     free(pvar->hosts_state.file_names[i]);
1905     }
1906     free(pvar->hosts_state.file_names);
1907     }
1908     }

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