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 5678 - (hide annotations) (download) (as text)
Sat Oct 4 03:39:24 2014 UTC (9 years, 6 months ago) by maya
File MIME type: text/x-csrc
File size: 56059 byte(s)
SSH2 切断シーケンスの調整
・shell のチャネルが MSG_CHANNEL_CLOSE を受け取ったとき
  MSG_DISCONNECT を送り、MSG_CHANNEL_CLOSE を送り、socket を切断する
  ↓
  MSG_CHANNEL_CLOSE を送り、MSG_DISCONNECT を送り、socket を切断する
・認証中にユーザがキャンセルしたとき
  MSG_CHANNEL_CLOSE を送り、socket を切断する
  ↓
  MSG_DISCONNECT を送り、socket を切断する
・MSG_DISCONNECT を受け取ったとき
  MSG_CHANNEL_CLOSE を送り、socket を切断する
    ↓
  socket を切断する
1 maya 3227 /*
2     Copyright (c) 1998-2001, Robert O'Callahan
3     All rights reserved.
4    
5     Redistribution and use in source and binary forms, with or without modification,
6     are permitted provided that the following conditions are met:
7    
8     Redistributions of source code must retain the above copyright notice, this list of
9     conditions and the following disclaimer.
10    
11     Redistributions in binary form must reproduce the above copyright notice, this list
12     of conditions and the following disclaimer in the documentation and/or other materials
13     provided with the distribution.
14    
15     The name of Robert O'Callahan may not be used to endorse or promote products derived from
16     this software without specific prior written permission.
17    
18     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21     THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27     */
28    
29     /*
30     This code is copyright (C) 1998-1999 Robert O'Callahan.
31     See LICENSE.TXT for the license.
32     */
33    
34     #include "ttxssh.h"
35     #include "util.h"
36     #include "resource.h"
37     #include "matcher.h"
38     #include "ssh.h"
39 maya 4304 #include "key.h"
40 maya 3227 #include "hosts.h"
41 doda 4569 #include "dns.h"
42 maya 3227
43     #include <openssl/bn.h>
44     #include <openssl/evp.h>
45     #include <openssl/rsa.h>
46     #include <openssl/dsa.h>
47    
48     #include <fcntl.h>
49     #include <io.h>
50     #include <errno.h>
51     #include <sys/stat.h>
52     #include <direct.h>
53 doda 4531 #include <memory.h>
54 maya 3227
55 doda 4531
56 maya 3227 static HFONT DlgHostsAddFont;
57     static HFONT DlgHostsReplaceFont;
58    
59     // BASE64�\���������i��������'='�����������������j
60     static char base64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
61    
62    
63     // �z�X�g�L�[�������� (2006.3.21 yutaka)
64     static void init_hostkey(Key *key)
65     {
66     key->type = KEY_UNSPEC;
67    
68     // SSH1
69     key->bits = 0;
70     if (key->exp != NULL) {
71     free(key->exp);
72     key->exp = NULL;
73     }
74     if (key->mod != NULL) {
75     free(key->mod);
76     key->mod = NULL;
77     }
78    
79     // SSH2
80     if (key->dsa != NULL) {
81     DSA_free(key->dsa);
82     key->dsa = NULL;
83     }
84     if (key->rsa != NULL) {
85     RSA_free(key->rsa);
86     key->rsa = NULL;
87     }
88 maya 4323 if (key->ecdsa != NULL) {
89     EC_KEY_free(key->ecdsa);
90     key->ecdsa = NULL;
91     }
92 maya 3227 }
93    
94    
95     static char FAR *FAR * parse_multi_path(char FAR * buf)
96     {
97     int i;
98     int ch;
99     int num_paths = 1;
100     char FAR *FAR * result;
101     int last_path_index;
102    
103     for (i = 0; (ch = buf[i]) != 0; i++) {
104     if (ch == ';') {
105     num_paths++;
106     }
107     }
108    
109     result =
110     (char FAR * FAR *) malloc(sizeof(char FAR *) * (num_paths + 1));
111    
112     last_path_index = 0;
113     num_paths = 0;
114     for (i = 0; (ch = buf[i]) != 0; i++) {
115     if (ch == ';') {
116     buf[i] = 0;
117     result[num_paths] = _strdup(buf + last_path_index);
118     num_paths++;
119     buf[i] = ch;
120     last_path_index = i + 1;
121     }
122     }
123     if (i > last_path_index) {
124     result[num_paths] = _strdup(buf + last_path_index);
125     num_paths++;
126     }
127     result[num_paths] = NULL;
128     return result;
129     }
130    
131     void HOSTS_init(PTInstVar pvar)
132     {
133     pvar->hosts_state.prefetched_hostname = NULL;
134     init_hostkey(&pvar->hosts_state.hostkey);
135     pvar->hosts_state.hosts_dialog = NULL;
136     pvar->hosts_state.file_names = NULL;
137     }
138    
139     void HOSTS_open(PTInstVar pvar)
140     {
141     pvar->hosts_state.file_names =
142     parse_multi_path(pvar->session_settings.KnownHostsFiles);
143     }
144    
145     //
146     // known_hosts�t�@�C�������e�������� pvar->hosts_state.file_data ����������
147     //
148     static int begin_read_file(PTInstVar pvar, char FAR * name,
149     int suppress_errors)
150     {
151     int fd;
152     int length;
153     int amount_read;
154     char buf[2048];
155    
156     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
157     fd = _open(buf, _O_RDONLY | _O_SEQUENTIAL | _O_BINARY);
158     if (fd == -1) {
159     if (!suppress_errors) {
160     if (errno == ENOENT) {
161     UTIL_get_lang_msg("MSG_HOSTS_READ_ENOENT_ERROR", pvar,
162     "An error occurred while trying to read a known_hosts file.\n"
163     "The specified filename does not exist.");
164     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
165     } else {
166     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
167     "An error occurred while trying to read a known_hosts file.");
168     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
169     }
170     }
171     return 0;
172     }
173    
174     length = (int) _lseek(fd, 0, SEEK_END);
175     _lseek(fd, 0, SEEK_SET);
176    
177     if (length >= 0 && length < 0x7FFFFFFF) {
178     pvar->hosts_state.file_data = malloc(length + 1);
179     if (pvar->hosts_state.file_data == NULL) {
180     if (!suppress_errors) {
181     UTIL_get_lang_msg("MSG_HOSTS_ALLOC_ERROR", pvar,
182     "Memory ran out while trying to allocate space to read a known_hosts file.");
183     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
184     }
185     _close(fd);
186     return 0;
187     }
188     } else {
189     if (!suppress_errors) {
190     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
191     "An error occurred while trying to read a known_hosts file.");
192     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
193     }
194     _close(fd);
195     return 0;
196     }
197    
198     amount_read = _read(fd, pvar->hosts_state.file_data, length);
199     pvar->hosts_state.file_data[length] = 0;
200    
201     _close(fd);
202    
203     if (amount_read != length) {
204     if (!suppress_errors) {
205     UTIL_get_lang_msg("MSG_HOSTS_READ_ERROR", pvar,
206     "An error occurred while trying to read a known_hosts file.");
207     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
208     }
209     free(pvar->hosts_state.file_data);
210     pvar->hosts_state.file_data = NULL;
211     return 0;
212     } else {
213     return 1;
214     }
215     }
216    
217     static int end_read_file(PTInstVar pvar, int suppress_errors)
218     {
219     free(pvar->hosts_state.file_data);
220     pvar->hosts_state.file_data = NULL;
221     return 1;
222     }
223    
224     static int begin_read_host_files(PTInstVar pvar, int suppress_errors)
225     {
226     pvar->hosts_state.file_num = 0;
227     pvar->hosts_state.file_data = NULL;
228     return 1;
229     }
230    
231     // MIME64�����������X�L�b�v����
232     static int eat_base64(char FAR * data)
233     {
234     int index = 0;
235     int ch;
236    
237     for (;;) {
238     ch = data[index];
239     if (ch == '=' || strchr(base64, ch)) {
240     // BASE64���\�������������������� index ���i����
241     index++;
242     } else {
243     break;
244     }
245     }
246    
247     return index;
248     }
249    
250     static int eat_spaces(char FAR * data)
251     {
252     int index = 0;
253     int ch;
254    
255     while ((ch = data[index]) == ' ' || ch == '\t') {
256     index++;
257     }
258     return index;
259     }
260    
261     static int eat_digits(char FAR * data)
262     {
263     int index = 0;
264     int ch;
265    
266     while ((ch = data[index]) >= '0' && ch <= '9') {
267     index++;
268     }
269     return index;
270     }
271    
272     static int eat_to_end_of_line(char FAR * data)
273     {
274     int index = 0;
275     int ch;
276    
277     while ((ch = data[index]) != '\n' && ch != '\r' && ch != 0) {
278     index++;
279     }
280    
281     while ((ch = data[index]) == '\n' || ch == '\r') {
282     index++;
283     }
284    
285     return index;
286     }
287    
288     static int eat_to_end_of_pattern(char FAR * data)
289     {
290     int index = 0;
291     int ch;
292    
293     while (ch = data[index], is_pattern_char(ch)) {
294     index++;
295     }
296    
297     return index;
298     }
299    
300     //
301     // BASE64�f�R�[�h�������s���B(rfc1521)
302     // src�o�b�t�@�� null-terminate ���������K�v�����B
303     //
304 yutakapon 5545 int uudecode(unsigned char *src, int srclen, unsigned char *target, int targsize)
305 maya 3227 {
306     char pad = '=';
307     int tarindex, state, ch;
308     char *pos;
309    
310     state = 0;
311     tarindex = 0;
312    
313     while ((ch = *src++) != '\0') {
314     if (isspace(ch)) /* Skip whitespace anywhere. */
315     continue;
316    
317     if (ch == pad)
318     break;
319    
320     pos = strchr(base64, ch);
321     if (pos == 0) /* A non-base64 character. */
322     return (-1);
323    
324     switch (state) {
325     case 0:
326     if (target) {
327     if (tarindex >= targsize)
328     return (-1);
329     target[tarindex] = (pos - base64) << 2;
330     }
331     state = 1;
332     break;
333     case 1:
334     if (target) {
335     if (tarindex + 1 >= targsize)
336     return (-1);
337     target[tarindex] |= (pos - base64) >> 4;
338     target[tarindex+1] = ((pos - base64) & 0x0f) << 4 ;
339     }
340     tarindex++;
341     state = 2;
342     break;
343     case 2:
344     if (target) {
345     if (tarindex + 1 >= targsize)
346     return (-1);
347     target[tarindex] |= (pos - base64) >> 2;
348     target[tarindex+1] = ((pos - base64) & 0x03) << 6;
349     }
350     tarindex++;
351     state = 3;
352     break;
353     case 3:
354     if (target) {
355     if (tarindex >= targsize)
356     return (-1);
357     target[tarindex] |= (pos - base64);
358     }
359     tarindex++;
360     state = 0;
361     break;
362     }
363     }
364    
365     /*
366     * We are done decoding Base-64 chars. Let's see if we ended
367     * on a byte boundary, and/or with erroneous trailing characters.
368     */
369    
370     if (ch == pad) { /* We got a pad char. */
371     ch = *src++; /* Skip it, get next. */
372     switch (state) {
373     case 0: /* Invalid = in first position */
374     case 1: /* Invalid = in second position */
375     return (-1);
376    
377     case 2: /* Valid, means one byte of info */
378     /* Skip any number of spaces. */
379     for (; ch != '\0'; ch = *src++)
380     if (!isspace(ch))
381     break;
382     /* Make sure there is another trailing = sign. */
383     if (ch != pad)
384     return (-1);
385     ch = *src++; /* Skip the = */
386     /* Fall through to "single trailing =" case. */
387     /* FALLTHROUGH */
388    
389     case 3: /* Valid, means two bytes of info */
390     /*
391     * We know this char is an =. Is there anything but
392     * whitespace after it?
393     */
394     for (; ch != '\0'; ch = *src++)
395     if (!isspace(ch))
396     return (-1);
397    
398     /*
399     * Now make sure for cases 2 and 3 that the "extra"
400     * bits that slopped past the last full byte were
401     * zeros. If we don't check them, they become a
402     * subliminal channel.
403     */
404     if (target && target[tarindex] != 0)
405     return (-1);
406     }
407     } else {
408     /*
409     * We ended by seeing the end of the string. Make sure we
410     * have no partial bytes lying around.
411     */
412     if (state != 0)
413     return (-1);
414     }
415    
416     return (tarindex);
417     }
418    
419    
420     // SSH2���� BASE64 �`�����i�[����������
421     static Key *parse_uudecode(char *data)
422     {
423     int count;
424     unsigned char *blob = NULL;
425     int len, n;
426     Key *key = NULL;
427     char ch;
428    
429     // BASE64���������T�C�Y������
430     count = eat_base64(data);
431     len = 2 * count;
432     blob = malloc(len);
433     if (blob == NULL)
434     goto error;
435    
436     // BASE64�f�R�[�h
437     ch = data[count];
438     data[count] = '\0'; // ���������s�R�[�h������������������������������������
439     n = uudecode(data, count, blob, len);
440     data[count] = ch;
441     if (n < 0) {
442     goto error;
443     }
444    
445     key = key_from_blob(blob, n);
446     if (key == NULL)
447     goto error;
448    
449     error:
450     if (blob != NULL)
451     free(blob);
452    
453     return (key);
454     }
455    
456    
457     static char FAR *parse_bignum(char FAR * data)
458     {
459     uint32 digits = 0;
460     BIGNUM *num = BN_new();
461     BIGNUM *billion = BN_new();
462     BIGNUM *digits_num = BN_new();
463     BN_CTX *ctx = BN_CTX_new();
464     char FAR *result;
465     int ch;
466     int leftover_digits = 1;
467    
468     BN_CTX_init(ctx);
469     BN_set_word(num, 0);
470     BN_set_word(billion, 1000000000L);
471    
472     while ((ch = *data) >= '0' && ch <= '9') {
473     if (leftover_digits == 1000000000L) {
474     BN_set_word(digits_num, digits);
475     BN_mul(num, num, billion, ctx);
476     BN_add(num, num, digits_num);
477     leftover_digits = 1;
478     digits = 0;
479     }
480    
481     digits = digits * 10 + ch - '0';
482     leftover_digits *= 10;
483     data++;
484     }
485    
486     BN_set_word(digits_num, digits);
487     BN_set_word(billion, leftover_digits);
488     BN_mul(num, num, billion, ctx);
489     BN_add(num, num, digits_num);
490    
491     result = (char FAR *) malloc(2 + BN_num_bytes(num));
492     set_ushort16_MSBfirst(result, BN_num_bits(num));
493     BN_bn2bin(num, result + 2);
494    
495     BN_CTX_free(ctx);
496     BN_free(digits_num);
497     BN_free(num);
498     BN_free(billion);
499    
500     return result;
501     }
502    
503     //
504     // known_hosts�t�@�C�������e���������A�w�������z�X�g�����J�����T���B
505     //
506     static int check_host_key(PTInstVar pvar, char FAR * hostname,
507     unsigned short tcpport, char FAR * data)
508     {
509     int index = eat_spaces(data);
510     int matched = 0;
511     int keybits = 0;
512    
513     if (data[index] == '#') {
514     return index + eat_to_end_of_line(data + index);
515     }
516    
517     /* if we find an empty line, then it won't have any patterns matching the hostname
518     and so we skip it */
519     index--;
520     do {
521     int negated;
522     int bracketed;
523     char *end_bracket;
524     int host_matched = 0;
525     unsigned short keyfile_port = 22;
526    
527     index++;
528     negated = data[index] == '!';
529    
530     if (negated) {
531     index++;
532     bracketed = data[index] == '[';
533     if (bracketed) {
534     end_bracket = strstr(data + index + 1, "]:");
535     if (end_bracket != NULL) {
536     *end_bracket = ' ';
537     index++;
538     }
539     }
540     host_matched = match_pattern(data + index, hostname);
541     if (bracketed && end_bracket != NULL) {
542     *end_bracket = ']';
543     keyfile_port = atoi(end_bracket + 2);
544     }
545     if (host_matched && keyfile_port == tcpport) {
546     return index + eat_to_end_of_line(data + index);
547     }
548     } else {
549     bracketed = data[index] == '[';
550     if (bracketed) {
551     end_bracket = strstr(data + index + 1, "]:");
552     if (end_bracket != NULL) {
553     *end_bracket = ' ';
554     index++;
555     }
556     }
557     host_matched = match_pattern(data + index, hostname);
558     if (bracketed && end_bracket != NULL) {
559     *end_bracket = ']';
560     keyfile_port = atoi(end_bracket + 2);
561     }
562     if (host_matched && keyfile_port == tcpport) {
563     matched = 1;
564     }
565     }
566    
567     index += eat_to_end_of_pattern(data + index);
568     } while (data[index] == ',');
569    
570     if (!matched) {
571     return index + eat_to_end_of_line(data + index);
572     } else {
573     // ���������������t�H�[�}�b�g��������
574     // �����A���������v�����G���g�����������������������B
575     /*
576     [SSH1]
577     192.168.1.2 1024 35 13032....
578    
579     [SSH2]
580     192.168.1.2 ssh-rsa AAAAB3NzaC1....
581     192.168.1.2 ssh-dss AAAAB3NzaC1....
582     192.168.1.2 rsa AAAAB3NzaC1....
583     192.168.1.2 dsa AAAAB3NzaC1....
584     192.168.1.2 rsa1 AAAAB3NzaC1....
585     */
586     int rsa1_key_bits;
587    
588     index += eat_spaces(data + index);
589    
590     rsa1_key_bits = atoi(data + index);
591     if (rsa1_key_bits > 0) { // RSA1������
592     if (!SSHv1(pvar)) { // SSH2��������������������
593     return index + eat_to_end_of_line(data + index);
594     }
595    
596     pvar->hosts_state.hostkey.type = KEY_RSA1;
597    
598     pvar->hosts_state.hostkey.bits = rsa1_key_bits;
599     index += eat_digits(data + index);
600     index += eat_spaces(data + index);
601    
602     pvar->hosts_state.hostkey.exp = parse_bignum(data + index);
603     index += eat_digits(data + index);
604     index += eat_spaces(data + index);
605    
606     pvar->hosts_state.hostkey.mod = parse_bignum(data + index);
607    
608     /*
609     if (pvar->hosts_state.key_bits < 0
610     || pvar->hosts_state.key_exp == NULL
611     || pvar->hosts_state.key_mod == NULL) {
612     pvar->hosts_state.key_bits = 0;
613     free(pvar->hosts_state.key_exp);
614     free(pvar->hosts_state.key_mod);
615     }*/
616    
617     } else {
618     char *cp, *p;
619     Key *key;
620    
621     if (!SSHv2(pvar)) { // SSH1��������������������
622     return index + eat_to_end_of_line(data + index);
623     }
624    
625     cp = data + index;
626     p = strchr(cp, ' ');
627     if (p == NULL) {
628     return index + eat_to_end_of_line(data + index);
629     }
630     index += (p - cp); // setup index
631     *p = '\0';
632     pvar->hosts_state.hostkey.type = get_keytype_from_name(cp);
633     *p = ' ';
634    
635     index += eat_spaces(data + index); // update index
636    
637     // uudecode
638     key = parse_uudecode(data + index);
639     if (key == NULL) {
640     return index + eat_to_end_of_line(data + index);
641     }
642    
643     // setup
644     pvar->hosts_state.hostkey.type = key->type;
645     pvar->hosts_state.hostkey.dsa = key->dsa;
646     pvar->hosts_state.hostkey.rsa = key->rsa;
647 maya 4321 pvar->hosts_state.hostkey.ecdsa = key->ecdsa;
648 yutakapon 5545 pvar->hosts_state.hostkey.ed25519_pk = key->ed25519_pk;
649 maya 3227
650     index += eat_base64(data + index);
651     index += eat_spaces(data + index);
652    
653     // Key�\�������g���������� (2008.3.2 yutaka)
654     free(key);
655     }
656    
657     return index + eat_to_end_of_line(data + index);
658     }
659     }
660    
661     //
662     // known_hosts�t�@�C�������z�X�g�������v�����s������
663     //
664     static int read_host_key(PTInstVar pvar,
665     char FAR * hostname, unsigned short tcpport,
666     int suppress_errors, int return_always)
667     {
668     int i;
669     int while_flg;
670    
671     for (i = 0; hostname[i] != 0; i++) {
672     int ch = hostname[i];
673    
674     if (!is_pattern_char(ch) || ch == '*' || ch == '?') {
675     if (!suppress_errors) {
676     UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_INVALID_ERROR", pvar,
677     "The host name contains an invalid character.\n"
678     "This session will be terminated.");
679 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
680 maya 3227 }
681     return 0;
682     }
683     }
684    
685     if (i == 0) {
686     if (!suppress_errors) {
687     UTIL_get_lang_msg("MSG_HOSTS_HOSTNAME_EMPTY_ERROR", pvar,
688     "The host name should not be empty.\n"
689     "This session will be terminated.");
690 maya 5678 notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
691 maya 3227 }
692     return 0;
693     }
694    
695     // hostkey type is KEY_UNSPEC.
696     init_hostkey(&pvar->hosts_state.hostkey);
697    
698     do {
699     if (pvar->hosts_state.file_data == NULL
700     || pvar->hosts_state.file_data[pvar->hosts_state.file_data_index] == 0) {
701     char FAR *filename;
702     int keep_going = 1;
703    
704     if (pvar->hosts_state.file_data != NULL) {
705     end_read_file(pvar, suppress_errors);
706     }
707    
708     do {
709     filename =
710     pvar->hosts_state.file_names[pvar->hosts_state.file_num];
711    
712     if (filename == NULL) {
713     return 1;
714     } else {
715     pvar->hosts_state.file_num++;
716    
717     if (filename[0] != 0) {
718     if (begin_read_file(pvar, filename, suppress_errors)) {
719     pvar->hosts_state.file_data_index = 0;
720     keep_going = 0;
721     }
722     }
723     }
724     } while (keep_going);
725     }
726    
727     pvar->hosts_state.file_data_index +=
728     check_host_key(pvar, hostname, tcpport,
729     pvar->hosts_state.file_data +
730     pvar->hosts_state.file_data_index);
731    
732     if (!return_always) {
733     // �L�����L�[��������������
734     while_flg = (pvar->hosts_state.hostkey.type == KEY_UNSPEC);
735     }
736     else {
737     while_flg = 0;
738     }
739     } while (while_flg);
740    
741     return 1;
742     }
743    
744     static void finish_read_host_files(PTInstVar pvar, int suppress_errors)
745     {
746     if (pvar->hosts_state.file_data != NULL) {
747     end_read_file(pvar, suppress_errors);
748     }
749     }
750    
751     // �T�[�o�����������O���Aknown_hosts�t�@�C�������z�X�g���J�������������������B
752     void HOSTS_prefetch_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport)
753     {
754     if (!begin_read_host_files(pvar, 1)) {
755     return;
756     }
757    
758     if (!read_host_key(pvar, hostname, tcpport, 1, 0)) {
759     return;
760     }
761    
762     free(pvar->hosts_state.prefetched_hostname);
763     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
764    
765     finish_read_host_files(pvar, 1);
766     }
767    
768     static BOOL equal_mp_ints(unsigned char FAR * num1,
769     unsigned char FAR * num2)
770     {
771     if (num1 == NULL || num2 == NULL) {
772     return FALSE;
773     } else {
774     uint32 bytes = (get_ushort16_MSBfirst(num1) + 7) / 8;
775    
776     if (bytes != (get_ushort16_MSBfirst(num2) + 7) / 8) {
777     return FALSE; /* different byte lengths */
778     } else {
779     return memcmp(num1 + 2, num2 + 2, bytes) == 0;
780     }
781     }
782     }
783    
784     // ���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 yutakapon 5663 Key *key_freed;
1088 maya 3227 int length;
1089     char filename[MAX_PATH];
1090     char tmp[L_tmpnam];
1091     int fd;
1092     int amount_written = 0;
1093     int close_result;
1094     int data_index = 0;
1095     char buf[FILENAME_MAX];
1096    
1097     // �������������t�@�C�����J��
1098     _getcwd(filename, sizeof(filename));
1099     tmpnam_s(tmp,sizeof(tmp));
1100     strcat_s(filename, sizeof(filename), tmp);
1101     fd = _open(filename,
1102     _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1103     _S_IREAD | _S_IWRITE);
1104    
1105     if (fd == -1) {
1106     if (errno == EACCES) {
1107     UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1108     "An error occurred while trying to write the host key.\n"
1109     "You do not have permission to write to the known-hosts file.");
1110     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1111     } else {
1112     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1113     "An error occurred while trying to write the host key.\n"
1114     "The host key could not be written.");
1115     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1116     }
1117     return;
1118     }
1119    
1120     // ���������T�[�o���L�[����������
1121 yutakapon 5545 memset(&key, 0, sizeof(key));
1122 maya 4321 switch (pvar->hosts_state.hostkey.type) {
1123     case KEY_RSA1: // SSH1
1124 maya 3227 key.type = KEY_RSA1;
1125     key.bits = pvar->hosts_state.hostkey.bits;
1126     key.exp = copy_mp_int(pvar->hosts_state.hostkey.exp);
1127     key.mod = copy_mp_int(pvar->hosts_state.hostkey.mod);
1128 maya 4321 break;
1129     case KEY_RSA: // SSH2 RSA
1130 maya 3227 key.type = KEY_RSA;
1131     key.rsa = duplicate_RSA(pvar->hosts_state.hostkey.rsa);
1132 maya 4321 break;
1133     case KEY_DSA: // SSH2 DSA
1134 maya 3227 key.type = KEY_DSA;
1135     key.dsa = duplicate_DSA(pvar->hosts_state.hostkey.dsa);
1136 maya 4321 break;
1137     case KEY_ECDSA256:
1138     case KEY_ECDSA384:
1139     case KEY_ECDSA521:
1140     key.type = pvar->hosts_state.hostkey.type;
1141     key.ecdsa = EC_KEY_dup(pvar->hosts_state.hostkey.ecdsa);
1142     break;
1143 yutakapon 5545 case KEY_ED25519:
1144     key.type = pvar->hosts_state.hostkey.type;
1145     key.ed25519_pk = duplicate_ED25519_PK(pvar->hosts_state.hostkey.ed25519_pk);
1146     break;
1147 maya 3227 }
1148    
1149     // �t�@�C��������������
1150     begin_read_host_files(pvar, 0);
1151     do {
1152     int host_index = 0;
1153     int matched = 0;
1154     int keybits = 0;
1155     char FAR *data;
1156     int do_write = 0;
1157     length = amount_written = 0;
1158    
1159     if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1)) {
1160     break;
1161     }
1162    
1163     if (data_index == pvar->hosts_state.file_data_index) {
1164     // index ���i������ == ��������������
1165     break;
1166     }
1167    
1168     data = pvar->hosts_state.file_data + data_index;
1169     host_index = eat_spaces(data);
1170    
1171     if (data[host_index] == '#') {
1172     do_write = 1;
1173     }
1174     else {
1175     // �z�X�g������
1176     host_index--;
1177     do {
1178     int negated;
1179     int bracketed;
1180     char *end_bracket;
1181     int host_matched = 0;
1182     unsigned short keyfile_port = 22;
1183    
1184     host_index++;
1185     negated = data[host_index] == '!';
1186    
1187     if (negated) {
1188     host_index++;
1189     bracketed = data[host_index] == '[';
1190     if (bracketed) {
1191     end_bracket = strstr(data + host_index + 1, "]:");
1192     if (end_bracket != NULL) {
1193     *end_bracket = ' ';
1194     host_index++;
1195     }
1196     }
1197     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1198     if (bracketed && end_bracket != NULL) {
1199     *end_bracket = ']';
1200     keyfile_port = atoi(end_bracket + 2);
1201     }
1202     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1203     matched = 0;
1204     // �����o�[�W�����`�F�b�N�������� host_index ���i��������������
1205     host_index--;
1206     do {
1207     host_index++;
1208     host_index += eat_to_end_of_pattern(data + host_index);
1209     } while (data[host_index] == ',');
1210     break;
1211     }
1212     }
1213     else {
1214     bracketed = data[host_index] == '[';
1215     if (bracketed) {
1216     end_bracket = strstr(data + host_index + 1, "]:");
1217     if (end_bracket != NULL) {
1218     *end_bracket = ' ';
1219     host_index++;
1220     }
1221     }
1222     host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1223     if (bracketed && end_bracket != NULL) {
1224     *end_bracket = ']';
1225     keyfile_port = atoi(end_bracket + 2);
1226     }
1227     if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1228     matched = 1;
1229     }
1230     }
1231     host_index += eat_to_end_of_pattern(data + host_index);
1232     } while (data[host_index] == ',');
1233    
1234     // �z�X�g������������
1235 maya 4332 if (!matched) {
1236 maya 3227 do_write = 1;
1237     }
1238 maya 4332 // �z�X�g��������
1239 maya 3227 else {
1240 maya 4332 // �����`�������� or ���v�����L�[
1241     if (match_key(pvar, &key) != 0) {
1242     do_write = 1;
1243 maya 3227 }
1244 maya 4332 // �����`�������������v�������L�[���X�L�b�v������
1245 maya 3227 }
1246     }
1247    
1248     // ������������
1249     if (do_write) {
1250     length = pvar->hosts_state.file_data_index - data_index;
1251     amount_written =
1252     _write(fd, pvar->hosts_state.file_data + data_index,
1253     length);
1254    
1255     if (amount_written != length) {
1256     goto error1;
1257     }
1258     }
1259     data_index = pvar->hosts_state.file_data_index;
1260     } while (1); // ������������
1261    
1262     error1:
1263     close_result = _close(fd);
1264     if (amount_written != length || close_result == -1) {
1265     UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1266     "An error occurred while trying to write the host key.\n"
1267     "The host key could not be written.");
1268     notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1269     goto error2;
1270     }
1271    
1272     // �������������t�@�C���������l�[��
1273     get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1274     _unlink(buf);
1275     rename(filename, buf);
1276    
1277     error2:
1278     _unlink(filename);
1279    
1280     finish_read_host_files(pvar, 0);
1281 yutakapon 5545
1282     // ���������������������������B
1283 yutakapon 5663 key_freed = key_new(KEY_UNSPEC);
1284     memcpy(key_freed, &key, sizeof(Key));
1285     key_free(key_freed);
1286 maya 3227 }
1287     }
1288    
1289     //
1290     // Unknown host���z�X�g���J���� known_hosts �t�@�C����������������������
1291     // ���[�U���m�F�������B
1292     // TODO: finger print���\�����s���B
1293     // (2006.3.25 yutaka)
1294     //
1295     static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1296     LPARAM lParam)
1297     {
1298     PTInstVar pvar;
1299     LOGFONT logfont;
1300     HFONT font;
1301     char uimsg[MAX_UIMSG];
1302    
1303     switch (msg) {
1304     case WM_INITDIALOG:
1305     pvar = (PTInstVar) lParam;
1306     pvar->hosts_state.hosts_dialog = dlg;
1307     SetWindowLong(dlg, DWL_USER, lParam);
1308    
1309     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1310     GetWindowText(dlg, uimsg, sizeof(uimsg));
1311     UTIL_get_lang_msg("DLG_UNKNONWHOST_TITLE", pvar, uimsg);
1312     SetWindowText(dlg, pvar->ts->UIMsg);
1313     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1314 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING", pvar, uimsg);
1315 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1316     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1317 maya 4333 UTIL_get_lang_msg("DLG_UNKNOWNHOST_WARNING2", pvar, uimsg);
1318 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1319     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1320     UTIL_get_lang_msg("DLG_UNKNOWNHOST_FINGERPRINT", pvar, uimsg);
1321     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1322     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1323     UTIL_get_lang_msg("DLG_UNKNOWNHOST_ADD", pvar, uimsg);
1324     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1325     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1326     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1327     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1328     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1329     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1330     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1331    
1332 doda 4559 switch (pvar->dns_key_check) {
1333     case DNS_VERIFY_NOTFOUND:
1334 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1335 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1336     break;
1337     case DNS_VERIFY_MATCH:
1338     case DNS_VERIFY_AUTH_MATCH:
1339 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1340 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1341     break;
1342     case DNS_VERIFY_MISMATCH:
1343     case DNS_VERIFY_AUTH_MISMATCH:
1344 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1345 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1346     break;
1347     case DNS_VERIFY_DIFFERENTTYPE:
1348     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1349 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1350 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1351     break;
1352     }
1353    
1354     switch (pvar->dns_key_check) {
1355     case DNS_VERIFY_MATCH:
1356     case DNS_VERIFY_MISMATCH:
1357     case DNS_VERIFY_DIFFERENTTYPE:
1358 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1359 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1360     break;
1361     case DNS_VERIFY_AUTH_MATCH:
1362     case DNS_VERIFY_AUTH_MISMATCH:
1363     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1364 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1365 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1366     break;
1367     }
1368    
1369 maya 3227 init_hosts_dlg(pvar, dlg);
1370    
1371     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1372     GetObject(font, sizeof(LOGFONT), &logfont);
1373     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1374     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1375     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1376 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1377     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1378 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1379     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1380     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1381     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1382     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1383     }
1384     else {
1385     DlgHostsAddFont = NULL;
1386     }
1387    
1388     // add host check box���`�F�b�N���f�t�H���g������������
1389     SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1390    
1391     return TRUE; /* because we do not set the focus */
1392    
1393     case WM_COMMAND:
1394     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1395    
1396     switch (LOWORD(wParam)) {
1397     case IDC_CONTINUE:
1398 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1399     if (!pvar->cv->Ready) {
1400     goto canceled;
1401     }
1402    
1403 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1404     add_host_key(pvar);
1405     }
1406    
1407     if (SSHv1(pvar)) {
1408     SSH_notify_host_OK(pvar);
1409     } else { // SSH2
1410     // SSH2���������� SSH_notify_host_OK() �������B
1411     }
1412    
1413     pvar->hosts_state.hosts_dialog = NULL;
1414    
1415     EndDialog(dlg, 1);
1416    
1417     if (DlgHostsAddFont != NULL) {
1418     DeleteObject(DlgHostsAddFont);
1419     }
1420    
1421     return TRUE;
1422    
1423     case IDCANCEL: /* kill the connection */
1424 yutakapon 5562 canceled:
1425 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
1426 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
1427 maya 3227 EndDialog(dlg, 0);
1428    
1429     if (DlgHostsAddFont != NULL) {
1430     DeleteObject(DlgHostsAddFont);
1431     }
1432    
1433     return TRUE;
1434    
1435     default:
1436     return FALSE;
1437     }
1438    
1439     default:
1440     return FALSE;
1441     }
1442     }
1443    
1444     //
1445     // �u�����������m�F�_�C�A���O������
1446     //
1447     static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1448     LPARAM lParam)
1449     {
1450     PTInstVar pvar;
1451     LOGFONT logfont;
1452     HFONT font;
1453     char uimsg[MAX_UIMSG];
1454    
1455     switch (msg) {
1456     case WM_INITDIALOG:
1457     pvar = (PTInstVar) lParam;
1458     pvar->hosts_state.hosts_dialog = dlg;
1459     SetWindowLong(dlg, DWL_USER, lParam);
1460    
1461     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1462     GetWindowText(dlg, uimsg, sizeof(uimsg));
1463 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_TITLE", pvar, uimsg);
1464 maya 3227 SetWindowText(dlg, pvar->ts->UIMsg);
1465     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1466 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING", pvar, uimsg);
1467 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1468     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1469 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_WARNING2", pvar, uimsg);
1470 maya 3227 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1471     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1472 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_FINGERPRINT", pvar, uimsg);
1473 maya 3227 SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1474     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1475 maya 4330 UTIL_get_lang_msg("DLG_DIFFERENTKEY_REPLACE", pvar, uimsg);
1476 maya 3227 SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1477     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1478     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1479     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1480     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1481     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1482     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1483    
1484 doda 4559 switch (pvar->dns_key_check) {
1485     case DNS_VERIFY_NOTFOUND:
1486 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1487 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1488     break;
1489     case DNS_VERIFY_MATCH:
1490     case DNS_VERIFY_AUTH_MATCH:
1491 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1492 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1493     break;
1494     case DNS_VERIFY_MISMATCH:
1495     case DNS_VERIFY_AUTH_MISMATCH:
1496 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1497 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1498     break;
1499     case DNS_VERIFY_DIFFERENTTYPE:
1500     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1501 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1502 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1503     break;
1504     }
1505    
1506     switch (pvar->dns_key_check) {
1507     case DNS_VERIFY_MATCH:
1508     case DNS_VERIFY_MISMATCH:
1509     case DNS_VERIFY_DIFFERENTTYPE:
1510 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1511 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1512     break;
1513     case DNS_VERIFY_AUTH_MATCH:
1514     case DNS_VERIFY_AUTH_MISMATCH:
1515     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1516 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1517 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1518     break;
1519     }
1520    
1521 maya 3227 init_hosts_dlg(pvar, dlg);
1522    
1523     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1524     GetObject(font, sizeof(LOGFONT), &logfont);
1525     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsReplaceFont, pvar)) {
1526     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1527     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1528 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1529     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1530 maya 3227 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1531     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1532     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1533     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsReplaceFont, MAKELPARAM(TRUE,0));
1534     }
1535     else {
1536     DlgHostsReplaceFont = NULL;
1537     }
1538    
1539     // �f�t�H���g���`�F�b�N����������
1540     return TRUE; /* because we do not set the focus */
1541    
1542     case WM_COMMAND:
1543     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1544    
1545     switch (LOWORD(wParam)) {
1546     case IDC_CONTINUE:
1547 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1548     if (!pvar->cv->Ready) {
1549     goto canceled;
1550     }
1551    
1552 maya 3227 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1553     add_host_key(pvar);
1554     delete_different_key(pvar);
1555     }
1556    
1557     if (SSHv1(pvar)) {
1558     SSH_notify_host_OK(pvar);
1559     } else { // SSH2
1560     // SSH2���������� SSH_notify_host_OK() �������B
1561     }
1562    
1563     pvar->hosts_state.hosts_dialog = NULL;
1564    
1565     EndDialog(dlg, 1);
1566    
1567     if (DlgHostsReplaceFont != NULL) {
1568     DeleteObject(DlgHostsReplaceFont);
1569     }
1570    
1571     return TRUE;
1572    
1573     case IDCANCEL: /* kill the connection */
1574 yutakapon 5562 canceled:
1575 maya 3227 pvar->hosts_state.hosts_dialog = NULL;
1576 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
1577 maya 3227 EndDialog(dlg, 0);
1578    
1579     if (DlgHostsReplaceFont != NULL) {
1580     DeleteObject(DlgHostsReplaceFont);
1581     }
1582    
1583     return TRUE;
1584    
1585     default:
1586     return FALSE;
1587     }
1588    
1589     default:
1590     return FALSE;
1591     }
1592     }
1593    
1594 maya 4332 //
1595     // �����z�X�g�����`�����������������m�F�_�C�A���O������
1596     //
1597     static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1598     LPARAM lParam)
1599     {
1600     PTInstVar pvar;
1601     LOGFONT logfont;
1602     HFONT font;
1603     char uimsg[MAX_UIMSG];
1604    
1605     switch (msg) {
1606     case WM_INITDIALOG:
1607     pvar = (PTInstVar) lParam;
1608     pvar->hosts_state.hosts_dialog = dlg;
1609     SetWindowLong(dlg, DWL_USER, lParam);
1610    
1611     // �����E�u���������� init_hosts_dlg �����������������A�����O���Z�b�g�����K�v������
1612     GetWindowText(dlg, uimsg, sizeof(uimsg));
1613     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg);
1614     SetWindowText(dlg, pvar->ts->UIMsg);
1615     GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg));
1616 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING", pvar, uimsg);
1617 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg);
1618     GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg));
1619 maya 4333 UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNING2", pvar, uimsg);
1620 maya 4332 SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg);
1621     GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg));
1622     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg);
1623     SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg);
1624     GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg));
1625     UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg);
1626     SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg);
1627     GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg));
1628     UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg);
1629     SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg);
1630     GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg));
1631     UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg);
1632     SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg);
1633    
1634 doda 4559 switch (pvar->dns_key_check) {
1635     case DNS_VERIFY_NOTFOUND:
1636 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_NOTFOUND", pvar, "No host key fingerprint found in DNS.");
1637 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1638     break;
1639     case DNS_VERIFY_MATCH:
1640     case DNS_VERIFY_AUTH_MATCH:
1641 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MATCH", pvar, "Matching host key fingerprint found in DNS.");
1642 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1643     break;
1644     case DNS_VERIFY_MISMATCH:
1645     case DNS_VERIFY_AUTH_MISMATCH:
1646 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_MISMATCH", pvar, "Mismatching host key fingerprint found in DNS.");
1647 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1648     break;
1649     case DNS_VERIFY_DIFFERENTTYPE:
1650     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1651 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_SSHFP_DIFFTYPE", pvar, "Mismatching host key type found in DNS.");
1652 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPCHECK, pvar->ts->UIMsg);
1653     break;
1654     }
1655    
1656     switch (pvar->dns_key_check) {
1657     case DNS_VERIFY_MATCH:
1658     case DNS_VERIFY_MISMATCH:
1659     case DNS_VERIFY_DIFFERENTTYPE:
1660 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_NG", pvar, "Found insecure fingerprint in DNS.");
1661 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1662     break;
1663     case DNS_VERIFY_AUTH_MATCH:
1664     case DNS_VERIFY_AUTH_MISMATCH:
1665     case DNS_VERIFY_AUTH_DIFFERENTTYPE:
1666 maya 4602 UTIL_get_lang_msg("DLG_HOSTKEY_DNSSEC_OK", pvar, "Found secure fingerprint in DNS.");
1667 doda 4559 SetDlgItemText(dlg, IDC_HOSTSSHFPDNSSEC, pvar->ts->UIMsg);
1668     break;
1669     }
1670    
1671 maya 4332 init_hosts_dlg(pvar, dlg);
1672    
1673     font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0);
1674     GetObject(font, sizeof(LOGFONT), &logfont);
1675     if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) {
1676     SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1677     SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1678 maya 4565 SendDlgItemMessage(dlg, IDC_HOSTSSHFPCHECK, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1679     SendDlgItemMessage(dlg, IDC_HOSTSSHFPDNSSEC, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1680 maya 4332 SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1681     SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1682     SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1683     SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1684     SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0));
1685     }
1686     else {
1687     DlgHostsAddFont = NULL;
1688     }
1689    
1690     // add host check box ���f�t�H���g�� off ������
1691     // SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
1692    
1693     return TRUE; /* because we do not set the focus */
1694    
1695     case WM_COMMAND:
1696     pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1697    
1698     switch (LOWORD(wParam)) {
1699     case IDC_CONTINUE:
1700 yutakapon 5562 // �F�������T�[�o�������f�������������A�L�����Z�������������B(2014.3.31 yutaka)
1701     if (!pvar->cv->Ready) {
1702     goto canceled;
1703     }
1704    
1705 maya 4332 if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1706     add_host_key(pvar);
1707     }
1708    
1709     if (SSHv1(pvar)) {
1710     SSH_notify_host_OK(pvar);
1711     } else { // SSH2
1712     // SSH2���������� SSH_notify_host_OK() �������B
1713     }
1714    
1715     pvar->hosts_state.hosts_dialog = NULL;
1716    
1717     EndDialog(dlg, 1);
1718    
1719     if (DlgHostsAddFont != NULL) {
1720     DeleteObject(DlgHostsAddFont);
1721     }
1722    
1723     return TRUE;
1724    
1725     case IDCANCEL: /* kill the connection */
1726 yutakapon 5562 canceled:
1727 maya 4332 pvar->hosts_state.hosts_dialog = NULL;
1728 maya 5678 notify_closed_connection(pvar, "authentication cancelled");
1729 maya 4332 EndDialog(dlg, 0);
1730    
1731     if (DlgHostsAddFont != NULL) {
1732     DeleteObject(DlgHostsAddFont);
1733     }
1734    
1735     return TRUE;
1736    
1737     default:
1738     return FALSE;
1739     }
1740    
1741     default:
1742     return FALSE;
1743     }
1744     }
1745    
1746 maya 3227 void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
1747     {
1748     if (pvar->hosts_state.hosts_dialog == NULL) {
1749     HWND cur_active = GetActiveWindow();
1750    
1751     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
1752     cur_active != NULL ? cur_active : wnd,
1753     hosts_add_dlg_proc, (LPARAM) pvar);
1754     }
1755     }
1756    
1757 maya 4330 void HOSTS_do_different_key_dialog(HWND wnd, PTInstVar pvar)
1758 maya 3227 {
1759     if (pvar->hosts_state.hosts_dialog == NULL) {
1760     HWND cur_active = GetActiveWindow();
1761    
1762 maya 4330 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTKEY),
1763 maya 3227 cur_active != NULL ? cur_active : wnd,
1764     hosts_replace_dlg_proc, (LPARAM) pvar);
1765     }
1766     }
1767    
1768 maya 4332 void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar)
1769     {
1770     if (pvar->hosts_state.hosts_dialog == NULL) {
1771     HWND cur_active = GetActiveWindow();
1772    
1773     DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY),
1774     cur_active != NULL ? cur_active : wnd,
1775     hosts_add2_dlg_proc, (LPARAM) pvar);
1776     }
1777     }
1778    
1779 maya 3227 //
1780     // �T�[�o�����������������z�X�g���J�������������`�F�b�N����
1781     //
1782     // SSH2���������� (2006.3.24 yutaka)
1783     //
1784     BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key)
1785     {
1786 doda 4559 int found_different_key = 0, found_different_type_key = 0;
1787 maya 3227
1788 doda 4559 pvar->dns_key_check = DNS_VERIFY_NONE;
1789    
1790 maya 3227 // ������ known_hosts �t�@�C�������z�X�g���J�����������������������A���������r�����B
1791     if (pvar->hosts_state.prefetched_hostname != NULL
1792     && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
1793 maya 4332 && match_key(pvar, key) == 1) {
1794 maya 3227
1795     if (SSHv1(pvar)) {
1796     SSH_notify_host_OK(pvar);
1797     } else {
1798     // SSH2���������� SSH_notify_host_OK() �������B
1799     }
1800     return TRUE;
1801     }
1802    
1803     // �������������������������A�������_���t�@�C��������������
1804     if (begin_read_host_files(pvar, 0)) {
1805     do {
1806     if (!read_host_key(pvar, hostname, tcpport, 0, 0)) {
1807     break;
1808     }
1809    
1810     if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
1811 maya 4332 int match = match_key(pvar, key);
1812     if (match == 1) {
1813 maya 3227 finish_read_host_files(pvar, 0);
1814     // ���������G���g�����Q�������A���v�����L�[�������������������B
1815     // SSH2���������������������������B(2006.3.29 yutaka)
1816     if (SSHv1(pvar)) {
1817     SSH_notify_host_OK(pvar);
1818     } else {
1819     // SSH2���������� SSH_notify_host_OK() �������B
1820     }
1821     return TRUE;
1822 maya 4332 }
1823     else if (match == 0) {
1824 maya 3227 // �L�[�� known_hosts ���������������A�L�[�����e���������B
1825     found_different_key = 1;
1826     }
1827 maya 4332 else {
1828     // �L�[���`������������
1829     found_different_type_key = 1;
1830     }
1831 maya 3227 }
1832     } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // �L�[�����������������������[�v����
1833    
1834     finish_read_host_files(pvar, 0);
1835     }
1836    
1837     // known_hosts �������������L�[���������t�@�C�������������������A�������������������B
1838     pvar->hosts_state.hostkey.type = key->type;
1839 maya 4321 switch (key->type) {
1840     case KEY_RSA1: // SSH1
1841 maya 3227 pvar->hosts_state.hostkey.bits = key->bits;
1842     pvar->hosts_state.hostkey.exp = copy_mp_int(key->exp);
1843     pvar->hosts_state.hostkey.mod = copy_mp_int(key->mod);
1844 maya 4321 break;
1845     case KEY_RSA: // SSH2 RSA
1846 maya 3227 pvar->hosts_state.hostkey.rsa = duplicate_RSA(key->rsa);
1847 maya 4321 break;
1848     case KEY_DSA: // SSH2 DSA
1849 maya 3227 pvar->hosts_state.hostkey.dsa = duplicate_DSA(key->dsa);
1850 maya 4321 break;
1851     case KEY_ECDSA256: // SSH2 ECDSA
1852     case KEY_ECDSA384:
1853     case KEY_ECDSA521:
1854     pvar->hosts_state.hostkey.ecdsa = EC_KEY_dup(key->ecdsa);
1855     break;
1856 yutakapon 5545 case KEY_ED25519:
1857     pvar->hosts_state.hostkey.ed25519_pk = duplicate_ED25519_PK(key->ed25519_pk);
1858     break;
1859 maya 3227 }
1860     free(pvar->hosts_state.prefetched_hostname);
1861     pvar->hosts_state.prefetched_hostname = _strdup(hostname);
1862    
1863 yutakapon 3631 // "/nosecuritywarning"���w�����������������A�_�C�A���O���\���������� return success �����B
1864     if (pvar->nocheck_known_hosts == TRUE) {
1865     return TRUE;
1866     }
1867    
1868 doda 4542 if (pvar->settings.VerifyHostKeyDNS && !is_numeric_hostname(hostname)) {
1869 doda 4559 pvar->dns_key_check = verify_hostkey_dns(hostname, key);
1870 doda 4542 }
1871    
1872 maya 3227 // known_hosts�_�C�A���O�������I���\�������A�������_�����������[�U���m�F
1873     // �������K�v�����������A�����R�[�������X�����B
1874     // ����������known_hosts���m�F�����������A�T�[�o�����[�U���������������������������������B
1875     // (2007.10.1 yutaka)
1876     if (found_different_key) {
1877 maya 4330 HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar);
1878 maya 4332 }
1879     else if (found_different_type_key) {
1880     HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar);
1881     }
1882     else {
1883 maya 3227 HOSTS_do_unknown_host_dialog(pvar->NotificationWindow, pvar);
1884     }
1885    
1886     return TRUE;
1887     }
1888    
1889     void HOSTS_notify_disconnecting(PTInstVar pvar)
1890     {
1891     if (pvar->hosts_state.hosts_dialog != NULL) {
1892 doda 4531 PostMessage(pvar->hosts_state.hosts_dialog, WM_COMMAND, IDCANCEL, 0);
1893 maya 3227 /* the main window might not go away if it's not enabled. (see vtwin.cpp) */
1894     EnableWindow(pvar->NotificationWindow, TRUE);
1895     }
1896     }
1897    
1898     void HOSTS_end(PTInstVar pvar)
1899     {
1900     int i;
1901    
1902     free(pvar->hosts_state.prefetched_hostname);
1903     init_hostkey(&pvar->hosts_state.hostkey);
1904    
1905     if (pvar->hosts_state.file_names != NULL) {
1906     for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
1907     free(pvar->hosts_state.file_names[i]);
1908     }
1909     free(pvar->hosts_state.file_names);
1910     }
1911     }

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