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 5545 - (hide annotations) (download) (as text)
Mon Mar 17 16:06:58 2014 UTC (10 years ago) by yutakapon
File MIME type: text/x-csrc
File size: 55409 byte(s)
チケット #33263
Curve25519楕円曲線DH(Diffe Hellman)アルゴリズムを使った鍵交換をサポートした。

svn+ssh://svn.sourceforge.jp/svnroot/ttssh2/branches/ssh_ed25519
ブランチからマージ。

現時点でサポートしている機能は下記の通り。

 ・Key Generatorで ED25519 鍵の作成
 ・Key Generatorで RSA/DSA/ECDSA 秘密鍵ファイルに bcrypt KDF を選択可能。
 ・ED25519 による公開鍵認証ログイン
 ・RSA(bcrypt KDF) による公開鍵認証ログイン
 ・DSA(bcrypt KDF) による公開鍵認証ログイン
 ・ECDSA(bcrypt KDF) による公開鍵認証ログイン
 ・Host Keyに ssh-ed25519 のサポート

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     if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1396     add_host_key(pvar);
1397     }
1398    
1399     if (SSHv1(pvar)) {
1400     SSH_notify_host_OK(pvar);
1401     } else { // SSH2
1402     // SSH2���������� SSH_notify_host_OK() �������B
1403     }
1404    
1405     pvar->hosts_state.hosts_dialog = NULL;
1406    
1407     EndDialog(dlg, 1);
1408    
1409     if (DlgHostsAddFont != NULL) {
1410     DeleteObject(DlgHostsAddFont);
1411     }
1412    
1413     return TRUE;
1414    
1415     case IDCANCEL: /* kill the connection */
1416     pvar->hosts_state.hosts_dialog = NULL;
1417     notify_closed_connection(pvar);
1418     EndDialog(dlg, 0);
1419    
1420     if (DlgHostsAddFont != NULL) {
1421     DeleteObject(DlgHostsAddFont);
1422     }
1423    
1424     return TRUE;
1425    
1426     default:
1427     return FALSE;
1428     }
1429    
1430     default:
1431     return FALSE;
1432     }
1433     }
1434    
1435     //
1436     // �u�����������m�F�_�C�A���O������
1437     //
1438     static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1439     LPARAM lParam)
1440     {
1441     PTInstVar pvar;
1442     LOGFONT logfont;
1443     HFONT font;
1444     char uimsg[MAX_UIMSG];
1445    
1446     switch (msg) {
1447     case WM_INITDIALOG:
1448     pvar = (PTInstVar) lParam;
1449     pvar->hosts_state.hosts_dialog = dlg;
1450     SetWindowLong(dlg, DWL_USER, lParam);
1451    
1452     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1453     GetWindowText(dlg, uimsg, sizeof(uimsg));
1454 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
1455 maya 3227 SetWindowText(dlg, pvar->ts->UIMsg);
1456     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1457 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
1458 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1459     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1460 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
1461 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1462     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1463 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
1464 maya 3227 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1465     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1466 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
1467 maya 3227 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1468     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1469     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1470     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1471     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1472     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1473     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1474    
1475 doda 4559 switch (pvar->dns_key_check) {
1476     case DNS_VERIFY_NOTFOUND:
1477 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1478 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1479     break;
1480     case DNS_VERIFY_MATCH:
1481     case DNS_VERIFY_AUTH_MATCH:
1482 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1483 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1484     break;
1485     case DNS_VERIFY_MISMATCH:
1486     case DNS_VERIFY_AUTH_MISMATCH:
1487 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1488 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1489     break;
1490     case DNS_VERIFY_DIFFERENTTYPE:
1491     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1492 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1493 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1494     break;
1495     }
1496    
1497     switch (pvar->dns_key_check) {
1498     case DNS_VERIFY_MATCH:
1499     case DNS_VERIFY_MISMATCH:
1500     case DNS_VERIFY_DIFFERENTTYPE:
1501 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1502 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1503     break;
1504     case DNS_VERIFY_AUTH_MATCH:
1505     case DNS_VERIFY_AUTH_MISMATCH:
1506     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1507 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1508 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1509     break;
1510     }
1511    
1512 maya 3227 init_hosts_dlg(pvar, dlg);
1513    
1514     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1515     GetObject(font, sizeof(LOGFONT), &logfont);
1516     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
1517     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1518     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1519 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1520     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1521 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1522     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1523     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1524     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1525     }
1526     else {
1527     DlgHostsReplaceFont = NULL;
1528     }
1529    
1530     // �f�t�H���g���`�F�b�N����������
1531     return TRUE; /* because we do not set the focus */
1532    
1533     case WM_COMMAND:
1534     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1535    
1536     switch (LOWORD(wParam)) {
1537     case IDC_CONTINUE:
1538     if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1539     add_host_key(pvar);
1540     delete_different_key(pvar);
1541     }
1542    
1543     if (SSHv1(pvar)) {
1544     SSH_notify_host_OK(pvar);
1545     } else { // SSH2
1546     // SSH2���������� SSH_notify_host_OK() �������B
1547     }
1548    
1549     pvar->hosts_state.hosts_dialog = NULL;
1550    
1551     EndDialog(dlg, 1);
1552    
1553     if (DlgHostsReplaceFont != NULL) {
1554     DeleteObject(DlgHostsReplaceFont);
1555     }
1556    
1557     return TRUE;
1558    
1559     case IDCANCEL: /* kill the connection */
1560     pvar->hosts_state.hosts_dialog = NULL;
1561     notify_closed_connection(pvar);
1562     EndDialog(dlg, 0);
1563    
1564     if (DlgHostsReplaceFont != NULL) {
1565     DeleteObject(DlgHostsReplaceFont);
1566     }
1567    
1568     return TRUE;
1569    
1570     default:
1571     return FALSE;
1572     }
1573    
1574     default:
1575     return FALSE;
1576     }
1577     }
1578    
1579 maya 4332 //
1580     // �����z�X�g�����`�����������������m�F�_�C�A���O������
1581     //
1582     static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1583     LPARAM lParam)
1584     {
1585     PTInstVar pvar;
1586     LOGFONT logfont;
1587     HFONT font;
1588     char uimsg[MAX_UIMSG];
1589    
1590     switch (msg) {
1591     case WM_INITDIALOG:
1592     pvar = (PTInstVar) lParam;
1593     pvar->hosts_state.hosts_dialog = dlg;
1594     SetWindowLong(dlg, DWL_USER, lParam);
1595    
1596     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1597     GetWindowText(dlg, uimsg, sizeof(uimsg));
1598     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
1599     SetWindowText(dlg, pvar->ts->UIMsg);
1600     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1601 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
1602 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1603     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1604 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
1605 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1606     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1607     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
1608     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1609     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1610     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
1611     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1612     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1613     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1614     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1615     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1616     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1617     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1618    
1619 doda 4559 switch (pvar->dns_key_check) {
1620     case DNS_VERIFY_NOTFOUND:
1621 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1622 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1623     break;
1624     case DNS_VERIFY_MATCH:
1625     case DNS_VERIFY_AUTH_MATCH:
1626 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1627 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1628     break;
1629     case DNS_VERIFY_MISMATCH:
1630     case DNS_VERIFY_AUTH_MISMATCH:
1631 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1632 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1633     break;
1634     case DNS_VERIFY_DIFFERENTTYPE:
1635     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1636 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1637 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1638     break;
1639     }
1640    
1641     switch (pvar->dns_key_check) {
1642     case DNS_VERIFY_MATCH:
1643     case DNS_VERIFY_MISMATCH:
1644     case DNS_VERIFY_DIFFERENTTYPE:
1645 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1646 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1647     break;
1648     case DNS_VERIFY_AUTH_MATCH:
1649     case DNS_VERIFY_AUTH_MISMATCH:
1650     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1651 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1652 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1653     break;
1654     }
1655    
1656 maya 4332 init_hosts_dlg(pvar, dlg);
1657    
1658     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1659     GetObject(font, sizeof(LOGFONT), &logfont);
1660     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1661     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1662     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1663 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1664     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1665 maya 4332 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1666     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1667     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1668     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1669     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1670     }
1671     else {
1672     DlgHostsAddFont = NULL;
1673     }
1674    
1675     // add host check box ���f�t�H���g�� off ������
1676     // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1677    
1678     return TRUE; /* because we do not set the focus */
1679    
1680     case WM_COMMAND:
1681     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1682    
1683     switch (LOWORD(wParam)) {
1684     case IDC_CONTINUE:
1685     if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1686     add_host_key(pvar);
1687     }
1688    
1689     if (SSHv1(pvar)) {
1690     SSH_notify_host_OK(pvar);
1691     } else { // SSH2
1692     // SSH2���������� SSH_notify_host_OK() �������B
1693     }
1694    
1695     pvar->hosts_state.hosts_dialog = NULL;
1696    
1697     EndDialog(dlg, 1);
1698    
1699     if (DlgHostsAddFont != NULL) {
1700     DeleteObject(DlgHostsAddFont);
1701     }
1702    
1703     return TRUE;
1704    
1705     case IDCANCEL: /* kill the connection */
1706     pvar->hosts_state.hosts_dialog = NULL;
1707     notify_closed_connection(pvar);
1708     EndDialog(dlg, 0);
1709    
1710     if (DlgHostsAddFont != NULL) {
1711     DeleteObject(DlgHostsAddFont);
1712     }
1713    
1714     return TRUE;
1715    
1716     default:
1717     return FALSE;
1718     }
1719    
1720     default:
1721     return FALSE;
1722     }
1723     }
1724    
1725 maya 3227 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
1726     {
1727     if (pvar->hosts_state.hosts_dialog == NULL) {
1728     HWND cur_active = GetActiveWindow();
1729    
1730     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
1731     cur_active != NULL ? cur_active : wnd,
1732     hosts_add_dlg_proc, (LPARAM) pvar);
1733     }
1734     }
1735    
1736 maya 4330 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
1737 maya 3227 {
1738     if (pvar->hosts_state.hosts_dialog == NULL) {
1739     HWND cur_active = GetActiveWindow();
1740    
1741 maya 4330 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
1742 maya 3227 cur_active != NULL ? cur_active : wnd,
1743     hosts_replace_dlg_proc, (LPARAM) pvar);
1744     }
1745     }
1746    
1747 maya 4332 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
1748     {
1749     if (pvar->hosts_state.hosts_dialog == NULL) {
1750     HWND cur_active = GetActiveWindow();
1751    
1752     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
1753     cur_active != NULL ? cur_active : wnd,
1754     hosts_add2_dlg_proc, (LPARAM) pvar);
1755     }
1756     }
1757    
1758 maya 3227 //
1759     // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
1760     //
1761     // SSH2���������� (2006.3.24 yutaka)
1762     //
1763     BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key)
1764     {
1765 doda 4559 int found_different_key = 0, found_different_type_key = 0;
1766 maya 3227
1767 doda 4559 pvar->dns_key_check = DNS_VERIFY_NONE;
1768    
1769 maya 3227 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
1770     if (pvar->hosts_state.prefetched_hostname != NULL
1771     && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
1772 maya 4332 && match_key(pvar, key) == 1) {
1773 maya 3227
1774     if (SSHv1(pvar)) {
1775     SSH_notify_host_OK(pvar);
1776     } else {
1777     // SSH2���������� SSH_notify_host_OK() �������B
1778     }
1779     return TRUE;
1780     }
1781    
1782     // �������������������������A�������_���t�@�C��������������
1783     if (begin_read_host_files(pvar, 0)) {
1784     do {
1785     if (!read_host_key(pvar, hostname, tcpport, 0, 0)) {
1786     break;
1787     }
1788    
1789     if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
1790 maya 4332 int match = match_key(pvar, key);
1791     if (match == 1) {
1792 maya 3227 finish_read_host_files(pvar, 0);
1793     // ���������G���g�����Q�������A���v�����L�[�������������������B
1794     // SSH2���������������������������B(2006.3.29 yutaka)
1795     if (SSHv1(pvar)) {
1796     SSH_notify_host_OK(pvar);
1797     } else {
1798     // SSH2���������� SSH_notify_host_OK() �������B
1799     }
1800     return TRUE;
1801 maya 4332 }
1802     else if (match == 0) {
1803 maya 3227 // �L�[�� known_hosts ���������������A�L�[�����e���������B
1804     found_different_key = 1;
1805     }
1806 maya 4332 else {
1807     // �L�[���`������������
1808     found_different_type_key = 1;
1809     }
1810 maya 3227 }
1811     } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // �L�[�����������������������[�v����
1812    
1813     finish_read_host_files(pvar, 0);
1814     }
1815    
1816     // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
1817     pvar->hosts_state.hostkey.type = key->type;
1818 maya 4321 switch (key->type) {
1819     case KEY_RSA1: // SSH1
1820 maya 3227 pvar->hosts_state.hostkey.bits = key->bits;
1821     pvar->hosts_state.hostkey.exp = copy_mp_int(key->exp);
1822     pvar->hosts_state.hostkey.mod = copy_mp_int(key->mod);
1823 maya 4321 break;
1824     case KEY_RSA: // SSH2 RSA
1825 maya 3227 pvar->hosts_state.hostkey.rsa = duplicate_RSA(key->rsa);
1826 maya 4321 break;
1827     case KEY_DSA: // SSH2 DSA
1828 maya 3227 pvar->hosts_state.hostkey.dsa = duplicate_DSA(key->dsa);
1829 maya 4321 break;
1830     case KEY_ECDSA256: // SSH2 ECDSA
1831     case KEY_ECDSA384:
1832     case KEY_ECDSA521:
1833     pvar->hosts_state.hostkey.ecdsa = EC_KEY_dup(key->ecdsa);
1834     break;
1835 yutakapon 5545 case KEY_ED25519:
1836     pvar->hosts_state.hostkey.ed25519_pk = duplicate_ED25519_PK(key->ed25519_pk);
1837     break;
1838 maya 3227 }
1839     free(pvar->hosts_state.prefetched_hostname);
1840     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
1841    
1842 yutakapon 3631 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
1843     if (pvar->nocheck_known_hosts == TRUE) {
1844     return TRUE;
1845     }
1846    
1847 doda 4542 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
1848 doda 4559 pvar->dns_key_check = verify_hostkey_dns(hostname, key);
1849 doda 4542 }
1850    
1851 maya 3227 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
1852     // �������K�v�����������A�����R�[�������X�����B
1853     // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
1854     // (2007.10.1 yutaka)
1855     if (found_different_key) {
1856 maya 4330 HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar);
1857 maya 4332 }
1858     else if (found_different_type_key) {
1859     HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar);
1860     }
1861     else {
1862 maya 3227 HOSTS_do_unknown_host_dialog(pvar->NotificationWindow, pvar);
1863     }
1864    
1865     return TRUE;
1866     }
1867    
1868     void HOSTS_notify_disconnecting(PTInstVar pvar)
1869     {
1870     if (pvar->hosts_state.hosts_dialog != NULL) {
1871 doda 4531 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
1872 maya 3227 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
1873     EnableWindow(pvar->NotificationWindow, TRUE);
1874     }
1875     }
1876    
1877     void HOSTS_end(PTInstVar pvar)
1878     {
1879     int i;
1880    
1881     free(pvar->hosts_state.prefetched_hostname);
1882     init_hostkey(&pvar->hosts_state.hostkey);
1883    
1884     if (pvar->hosts_state.file_names != NULL) {
1885     for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
1886     free(pvar->hosts_state.file_names[i]);
1887     }
1888     free(pvar->hosts_state.file_names);
1889     }
1890     }

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