Develop and Download Open Source Software

Browse Subversion Repository

Diff of /trunk/ttssh2/ttxssh/hosts.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2850 by yutakakn, Sat Feb 18 07:37:02 2006 UTC revision 2856 by yutakakn, Sun Mar 26 15:43:58 2006 UTC
# Line 35  See LICENSE.TXT for the license. Line 35  See LICENSE.TXT for the license.
35  #include "util.h"  #include "util.h"
36  #include "resource.h"  #include "resource.h"
37  #include "matcher.h"  #include "matcher.h"
38    #include "ssh.h"
39    #include "hosts.h"
40    
41  #include <openssl/bn.h>  #include <openssl/bn.h>
42    #include <openssl/evp.h>
43    #include <openssl/rsa.h>
44    #include <openssl/dsa.h>
45    
46  #include <fcntl.h>  #include <fcntl.h>
47  #include <io.h>  #include <io.h>
48  #include <errno.h>  #include <errno.h>
49  #include <sys/stat.h>  #include <sys/stat.h>
50    
51    
52    // BASE64構成文字列(ここでは'='は含まれていない)
53    static char base64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
54    
55    
56    // ホストキーの初期化 (2006.3.21 yutaka)
57    static void init_hostkey(Key *key)
58    {
59            key->type = KEY_UNSPEC;
60    
61            // SSH1
62            key->bits = 0;
63            if (key->exp != NULL) {
64                    free(key->exp);
65                    key->exp = NULL;
66            }
67            if (key->mod != NULL) {
68                    free(key->mod);
69                    key->mod = NULL;
70            }
71    
72            // SSH2
73            if (key->dsa != NULL) {
74                    DSA_free(key->dsa);
75                    key->dsa = NULL;
76            }
77            if (key->rsa != NULL) {
78                    RSA_free(key->rsa);
79                    key->rsa = NULL;
80            }
81    }
82    
83    
84  static char FAR *FAR * parse_multi_path(char FAR * buf)  static char FAR *FAR * parse_multi_path(char FAR * buf)
85  {  {
86          int i;          int i;
# Line 82  static char FAR *FAR * parse_multi_path( Line 120  static char FAR *FAR * parse_multi_path(
120  void HOSTS_init(PTInstVar pvar)  void HOSTS_init(PTInstVar pvar)
121  {  {
122          pvar->hosts_state.prefetched_hostname = NULL;          pvar->hosts_state.prefetched_hostname = NULL;
123    #if 0
124          pvar->hosts_state.key_exp = NULL;          pvar->hosts_state.key_exp = NULL;
125          pvar->hosts_state.key_mod = NULL;          pvar->hosts_state.key_mod = NULL;
126    #else
127            init_hostkey(&pvar->hosts_state.hostkey);
128    #endif
129          pvar->hosts_state.hosts_dialog = NULL;          pvar->hosts_state.hosts_dialog = NULL;
130          pvar->hosts_state.file_names = NULL;          pvar->hosts_state.file_names = NULL;
131  }  }
# Line 94  void HOSTS_open(PTInstVar pvar) Line 136  void HOSTS_open(PTInstVar pvar)
136                  parse_multi_path(pvar->session_settings.KnownHostsFiles);                  parse_multi_path(pvar->session_settings.KnownHostsFiles);
137  }  }
138    
139    //
140    // known_hostsファイルの内容をすべて pvar->hosts_state.file_data へ読み込む
141    //
142  static int begin_read_file(PTInstVar pvar, char FAR * name,  static int begin_read_file(PTInstVar pvar, char FAR * name,
143                                                     int suppress_errors)                                                     int suppress_errors)
144  {  {
# Line 172  static int begin_read_host_files(PTInstV Line 217  static int begin_read_host_files(PTInstV
217          return 1;          return 1;
218  }  }
219    
220    // MIME64の文字列をスキップする
221    static int eat_base64(char FAR * data)
222    {
223            int index = 0;
224            int ch;
225    
226            for (;;) {
227                    ch = data[index];
228                    if (ch == '=' || strchr(base64, ch)) {
229                            // BASE64の構成文字が見つかったら index を進める
230                            index++;
231                    } else {
232                            break;
233                    }
234            }
235    
236            return index;
237    }
238    
239  static int eat_spaces(char FAR * data)  static int eat_spaces(char FAR * data)
240  {  {
241          int index = 0;          int index = 0;
# Line 222  static int eat_to_end_of_pattern(char FA Line 286  static int eat_to_end_of_pattern(char FA
286          return index;          return index;
287  }  }
288    
289    //
290    // BASE64デコード処理を行う。(rfc1521)
291    // srcバッファは null-terminate している必要あり。
292    //
293    static int uudecode(unsigned char *src, int srclen, unsigned char *target, int targsize)
294    {
295            char pad = '=';
296            int tarindex, state, ch;
297            char *pos;
298    
299            state = 0;
300            tarindex = 0;
301    
302            while ((ch = *src++) != '\0') {
303                    if (isspace(ch))        /* Skip whitespace anywhere. */
304                            continue;
305    
306                    if (ch == pad)
307                            break;
308    
309                    pos = strchr(base64, ch);
310                    if (pos == 0)           /* A non-base64 character. */
311                            return (-1);
312    
313                    switch (state) {
314                    case 0:
315                            if (target) {
316                                    if (tarindex >= targsize)
317                                            return (-1);
318                                    target[tarindex] = (pos - base64) << 2;
319                            }
320                            state = 1;
321                            break;
322                    case 1:
323                            if (target) {
324                                    if (tarindex + 1 >= targsize)
325                                            return (-1);
326                                    target[tarindex]   |=  (pos - base64) >> 4;
327                                    target[tarindex+1]  = ((pos - base64) & 0x0f) << 4 ;
328                            }
329                            tarindex++;
330                            state = 2;
331                            break;
332                    case 2:
333                            if (target) {
334                                    if (tarindex + 1 >= targsize)
335                                            return (-1);
336                                    target[tarindex]   |=  (pos - base64) >> 2;
337                                    target[tarindex+1]  = ((pos - base64) & 0x03) << 6;
338                            }
339                            tarindex++;
340                            state = 3;
341                            break;
342                    case 3:
343                            if (target) {
344                                    if (tarindex >= targsize)
345                                            return (-1);
346                                    target[tarindex] |= (pos - base64);
347                            }
348                            tarindex++;
349                            state = 0;
350                            break;
351                    }
352            }
353    
354            /*
355             * We are done decoding Base-64 chars.  Let's see if we ended
356             * on a byte boundary, and/or with erroneous trailing characters.
357             */
358    
359            if (ch == pad) {                /* We got a pad char. */
360                    ch = *src++;            /* Skip it, get next. */
361                    switch (state) {
362                    case 0:         /* Invalid = in first position */
363                    case 1:         /* Invalid = in second position */
364                            return (-1);
365    
366                    case 2:         /* Valid, means one byte of info */
367                            /* Skip any number of spaces. */
368                            for (; ch != '\0'; ch = *src++)
369                                    if (!isspace(ch))
370                                            break;
371                            /* Make sure there is another trailing = sign. */
372                            if (ch != pad)
373                                    return (-1);
374                            ch = *src++;            /* Skip the = */
375                            /* Fall through to "single trailing =" case. */
376                            /* FALLTHROUGH */
377    
378                    case 3:         /* Valid, means two bytes of info */
379                            /*
380                             * We know this char is an =.  Is there anything but
381                             * whitespace after it?
382                             */
383                            for (; ch != '\0'; ch = *src++)
384                                    if (!isspace(ch))
385                                            return (-1);
386    
387                            /*
388                             * Now make sure for cases 2 and 3 that the "extra"
389                             * bits that slopped past the last full byte were
390                             * zeros.  If we don't check them, they become a
391                             * subliminal channel.
392                             */
393                            if (target && target[tarindex] != 0)
394                                    return (-1);
395                    }
396            } else {
397                    /*
398                     * We ended by seeing the end of the string.  Make sure we
399                     * have no partial bytes lying around.
400                     */
401                    if (state != 0)
402                            return (-1);
403            }
404    
405            return (tarindex);
406    }
407    
408    
409    // SSH2鍵は BASE64 形式で格納されている
410    static Key *parse_uudecode(char *data)
411    {
412            int count;
413            unsigned char *blob = NULL;
414            int len, n;
415            Key *key = NULL;
416            char ch;
417    
418            // BASE64文字列のサイズを得る
419            count = eat_base64(data);
420            len = 2 * count;
421            blob = malloc(len);
422            if (blob == NULL)
423                    goto error;
424    
425            // BASE64デコード
426            ch = data[count];
427            data[count] = '\0';  // ここは改行コードのはずなので書き潰しても問題ないはず
428            n = uudecode(data, count, blob, len);
429            data[count] = ch;
430            if (n < 0) {
431                    goto error;
432            }
433    
434            key = key_from_blob(blob, n);
435            if (key == NULL)
436                    goto error;
437    
438    error:
439            if (blob != NULL)
440                    free(blob);
441    
442            return (key);
443    }
444    
445    
446  static char FAR *parse_bignum(char FAR * data)  static char FAR *parse_bignum(char FAR * data)
447  {  {
448          uint32 digits = 0;          uint32 digits = 0;
# Line 268  static char FAR *parse_bignum(char FAR * Line 489  static char FAR *parse_bignum(char FAR *
489          return result;          return result;
490  }  }
491    
492    //
493    // known_hostsファイルの内容を解析し、指定したホストの公開鍵を探す。
494    //
495  static int check_host_key(PTInstVar pvar, char FAR * hostname,  static int check_host_key(PTInstVar pvar, char FAR * hostname,
496                                                    char FAR * data)                                                    char FAR * data)
497  {  {
# Line 303  static int check_host_key(PTInstVar pvar Line 527  static int check_host_key(PTInstVar pvar
527          if (!matched) {          if (!matched) {
528                  return index + eat_to_end_of_line(data + index);                  return index + eat_to_end_of_line(data + index);
529          } else {          } else {
530                  index += eat_spaces(data + index);                  // 鍵の種類によりフォーマットが異なる
531                    // また、最初に一致したエントリを取得することになる。
532                    /*
533                    [SSH1]
534                    192.168.1.2 1024 35 13032....
535    
536                    [SSH2]
537                    192.168.1.2 ssh-rsa AAAAB3NzaC1....
538                    192.168.1.2 ssh-dss AAAAB3NzaC1....
539                    192.168.1.2 rsa AAAAB3NzaC1....
540                    192.168.1.2 dsa AAAAB3NzaC1....
541                    192.168.1.2 rsa1 AAAAB3NzaC1....
542                     */
543                    int rsa1_key_bits;
544    
                 pvar->hosts_state.key_bits = atoi(data + index);  
                 index += eat_digits(data + index);  
545                  index += eat_spaces(data + index);                  index += eat_spaces(data + index);
546    
547                  pvar->hosts_state.key_exp = parse_bignum(data + index);                  rsa1_key_bits = atoi(data + index);
548                  index += eat_digits(data + index);                  if (rsa1_key_bits > 0) { // RSA1である
549                  index += eat_spaces(data + index);                          if (!SSHv1(pvar)) { // SSH2接続であれば無視する
550                                    return index + eat_to_end_of_line(data + index);
551                            }
552    
553                            pvar->hosts_state.hostkey.type = KEY_RSA1;
554    
555                            pvar->hosts_state.hostkey.bits = rsa1_key_bits;
556                            index += eat_digits(data + index);
557                            index += eat_spaces(data + index);
558    
559                            pvar->hosts_state.hostkey.exp = parse_bignum(data + index);
560                            index += eat_digits(data + index);
561                            index += eat_spaces(data + index);
562    
563                            pvar->hosts_state.hostkey.mod = parse_bignum(data + index);
564    
565                            /*
566                            if (pvar->hosts_state.key_bits < 0
567                                    || pvar->hosts_state.key_exp == NULL
568                                    || pvar->hosts_state.key_mod == NULL) {
569                                    pvar->hosts_state.key_bits = 0;
570                                    free(pvar->hosts_state.key_exp);
571                                    free(pvar->hosts_state.key_mod);
572                            }*/
573    
574                    } else {
575                            char *cp, *p;
576                            Key *key;
577    
578                            if (!SSHv2(pvar)) { // SSH1接続であれば無視する
579                                    return index + eat_to_end_of_line(data + index);
580                            }
581    
582                            cp = data + index;
583                            p = strchr(cp, ' ');
584                            if (p == NULL) {
585                                    return index + eat_to_end_of_line(data + index);
586                            }
587                            index += (p - cp);  // setup index
588                            *p = '\0';
589                            pvar->hosts_state.hostkey.type = get_keytype_from_name(cp);
590                            *p = ' ';
591    
592                            index += eat_spaces(data + index);  // update index
593    
594                            // uudecode
595                            key = parse_uudecode(data + index);
596                            if (key == NULL) {
597                                    return index + eat_to_end_of_line(data + index);
598                            }
599    
600                  pvar->hosts_state.key_mod = parse_bignum(data + index);                          // setup
601                            pvar->hosts_state.hostkey.type = key->type;
602                            pvar->hosts_state.hostkey.dsa = key->dsa;
603                            pvar->hosts_state.hostkey.rsa = key->rsa;
604    
605                  if (pvar->hosts_state.key_bits < 0                          index += eat_base64(data + index);
606                          || pvar->hosts_state.key_exp == NULL                          index += eat_spaces(data + index);
                         || pvar->hosts_state.key_mod == NULL) {  
                         pvar->hosts_state.key_bits = 0;  
                         free(pvar->hosts_state.key_exp);  
                         free(pvar->hosts_state.key_mod);  
607                  }                  }
608    
609                  return index + eat_to_end_of_line(data + index);                  return index + eat_to_end_of_line(data + index);
610          }          }
611  }  }
612    
613    //
614    // known_hostsファイルからホスト名に合致する行を読む
615    //
616  static int read_host_key(PTInstVar pvar, char FAR * hostname,  static int read_host_key(PTInstVar pvar, char FAR * hostname,
617                                                   int suppress_errors)                                                   int suppress_errors)
618  {  {
# Line 353  static int read_host_key(PTInstVar pvar, Line 639  static int read_host_key(PTInstVar pvar,
639                  return 0;                  return 0;
640          }          }
641    
642    #if 0
643          pvar->hosts_state.key_bits = 0;          pvar->hosts_state.key_bits = 0;
644          free(pvar->hosts_state.key_exp);          free(pvar->hosts_state.key_exp);
645          pvar->hosts_state.key_exp = NULL;          pvar->hosts_state.key_exp = NULL;
646          free(pvar->hosts_state.key_mod);          free(pvar->hosts_state.key_mod);
647          pvar->hosts_state.key_mod = NULL;          pvar->hosts_state.key_mod = NULL;
648    #else
649            // hostkey type is KEY_UNSPEC.
650            init_hostkey(&pvar->hosts_state.hostkey);
651    #endif
652    
653          do {          do {
654                  if (pvar->hosts_state.file_data == NULL                  if (pvar->hosts_state.file_data == NULL
# Line 395  static int read_host_key(PTInstVar pvar, Line 686  static int read_host_key(PTInstVar pvar,
686                          check_host_key(pvar, hostname,                          check_host_key(pvar, hostname,
687                                                     pvar->hosts_state.file_data +                                                     pvar->hosts_state.file_data +
688                                                     pvar->hosts_state.file_data_index);                                                     pvar->hosts_state.file_data_index);
689          } while (pvar->hosts_state.key_bits == 0);          } while (pvar->hosts_state.hostkey.type == KEY_UNSPEC);  // 有効なキーが見つかるまで
690    
691          return 1;          return 1;
692  }  }
# Line 407  static void finish_read_host_files(PTIns Line 698  static void finish_read_host_files(PTIns
698          }          }
699  }  }
700    
701    // サーバへ接続する前に、known_hostsファイルからホスト公開鍵を先読みしておく。
702  void HOSTS_prefetch_host_key(PTInstVar pvar, char FAR * hostname)  void HOSTS_prefetch_host_key(PTInstVar pvar, char FAR * hostname)
703  {  {
704          if (!begin_read_host_files(pvar, 1)) {          if (!begin_read_host_files(pvar, 1)) {
# Line 439  static BOOL equal_mp_ints(unsigned char Line 731  static BOOL equal_mp_ints(unsigned char
731          }          }
732  }  }
733    
734  static BOOL match_key(PTInstVar pvar,  // 公開鍵が等しいかを検証する
735                                            int bits, unsigned char FAR * exp,  static BOOL match_key(PTInstVar pvar, Key *key)
736                                            unsigned char FAR * mod)  {
737  {          int bits;
738          /* just check for equal exponent and modulus */          unsigned char FAR * exp;
739          return equal_mp_ints(exp, pvar->hosts_state.key_exp)          unsigned char FAR * mod;
740                  && equal_mp_ints(mod, pvar->hosts_state.key_mod);  
741            if (key->type == KEY_RSA1) {  // SSH1 host public key
742                    bits = key->bits;
743                    exp = key->exp;
744                    mod = key->mod;
745    
746                    /* just check for equal exponent and modulus */
747                    return equal_mp_ints(exp, pvar->hosts_state.hostkey.exp)
748                            && equal_mp_ints(mod, pvar->hosts_state.hostkey.mod);
749                    /*
750                    return equal_mp_ints(exp, pvar->hosts_state.key_exp)
751                            && equal_mp_ints(mod, pvar->hosts_state.key_mod);
752                            */
753    
754            } else if (key->type == KEY_RSA) {  // SSH2 RSA host public key
755    
756                    return key->rsa != NULL && pvar->hosts_state.hostkey.rsa != NULL &&
757                               BN_cmp(key->rsa->e, pvar->hosts_state.hostkey.rsa->e) == 0 &&
758                               BN_cmp(key->rsa->n, pvar->hosts_state.hostkey.rsa->n) == 0;
759    
760            } else { // // SSH2 DSA host public key
761    
762                    return key->dsa != NULL && pvar->hosts_state.hostkey.dsa &&
763                               BN_cmp(key->dsa->p, pvar->hosts_state.hostkey.dsa->p) == 0 &&
764                               BN_cmp(key->dsa->q, pvar->hosts_state.hostkey.dsa->q) == 0 &&
765                               BN_cmp(key->dsa->g, pvar->hosts_state.hostkey.dsa->g) == 0 &&
766                               BN_cmp(key->dsa->pub_key, pvar->hosts_state.hostkey.dsa->pub_key) == 0;
767    
768            }
769    
770  }  }
771    
772  static void init_hosts_dlg(PTInstVar pvar, HWND dlg)  static void init_hosts_dlg(PTInstVar pvar, HWND dlg)
# Line 498  static int print_mp_int(char FAR * buf, Line 819  static int print_mp_int(char FAR * buf,
819          return i;          return i;
820  }  }
821    
822    //
823    // known_hosts ファイルへ保存するエントリを作成する。
824    //
825  static char FAR *format_host_key(PTInstVar pvar)  static char FAR *format_host_key(PTInstVar pvar)
826  {  {
827          int host_len = strlen(pvar->hosts_state.prefetched_hostname);          int host_len = strlen(pvar->hosts_state.prefetched_hostname);
828          char FAR *result = (char FAR *) malloc(host_len          char *result = NULL;
829            int index;
830            enum hostkey_type type = pvar->hosts_state.hostkey.type;
831    
832            if (type == KEY_RSA1) {
833                    result = (char FAR *) malloc(host_len
834                                                                                     + 50 +                                                                                     + 50 +
835                                                                                     get_ushort16_MSBfirst(pvar->                                                                                     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.exp) /
                                                                                                                                  hosts_state.  
                                                                                                                                  key_exp) /  
836                                                                                     3 +                                                                                     3 +
837                                                                                     get_ushort16_MSBfirst(pvar->                                                                                     get_ushort16_MSBfirst(pvar->hosts_state.hostkey.mod) /
                                                                                                                                  hosts_state.  
                                                                                                                                  key_mod) /  
838                                                                                     3);                                                                                     3);
         int index;  
839    
840          strcpy(result, pvar->hosts_state.prefetched_hostname);                  strcpy(result, pvar->hosts_state.prefetched_hostname);
841          index = host_len;                  index = host_len;
842    
843                    sprintf(result + index, " %d ", pvar->hosts_state.hostkey.bits);
844                    index += strlen(result + index);
845                    index += print_mp_int(result + index, pvar->hosts_state.hostkey.exp);
846                    result[index] = ' ';
847                    index++;
848                    index += print_mp_int(result + index, pvar->hosts_state.hostkey.mod);
849                    strcpy(result + index, " \r\n");
850    
851            } else if (type == KEY_RSA || type == KEY_DSA) {
852                    Key *key = &pvar->hosts_state.hostkey;
853                    char *blob = NULL;
854                    int blen, uulen, msize;
855                    char *uu = NULL;
856                    int n;
857    
858                    key_to_blob(key, &blob, &blen);
859                    uulen = 2 * blen;
860                    uu = malloc(uulen);
861                    if (uu == NULL) {
862                            goto error;
863                    }
864                    n = uuencode(blob, blen, uu, uulen);
865                    if (n > 0) {
866                            msize = host_len + 50 + uulen;
867                            result = malloc(msize);
868                            if (result == NULL) {
869                                    goto error;
870                            }
871    
872                            // setup
873                            _snprintf(result, msize, "%s %s %s\r\n",
874                                    pvar->hosts_state.prefetched_hostname,
875                                    get_sshname_from_key(key),
876                                    uu);
877                    }
878    error:
879                    if (blob != NULL)
880                            free(blob);
881                    if (uu != NULL)
882                            free(uu);
883    
884          sprintf(result + index, " %d ", pvar->hosts_state.key_bits);          } else {
885          index += strlen(result + index);                  return NULL;
886          index += print_mp_int(result + index, pvar->hosts_state.key_exp);  
887          result[index] = ' ';          }
         index++;  
         index += print_mp_int(result + index, pvar->hosts_state.key_mod);  
         strcpy(result + index, " \r\n");  
888    
889          return result;          return result;
890  }  }
# Line 571  static void add_host_key(PTInstVar pvar) Line 933  static void add_host_key(PTInstVar pvar)
933          }          }
934  }  }
935    
936    //
937    // Unknown hostのホスト公開鍵を known_hosts ファイルへ保存するかどうかを
938    // ユーザに確認させる。
939    // TODO: finger printの表示も行う。
940    // (2006.3.25 yutaka)
941    //
942  static BOOL CALLBACK hosts_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,  static BOOL CALLBACK hosts_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
943                                                                          LPARAM lParam)                                                                          LPARAM lParam)
944  {  {
# Line 583  static BOOL CALLBACK hosts_dlg_proc(HWND Line 951  static BOOL CALLBACK hosts_dlg_proc(HWND
951                  SetWindowLong(dlg, DWL_USER, lParam);                  SetWindowLong(dlg, DWL_USER, lParam);
952    
953                  init_hosts_dlg(pvar, dlg);                  init_hosts_dlg(pvar, dlg);
954    
955                    // add host check boxにチェックをデフォルトで入れておく
956                    SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0);
957    
958                  return TRUE;                    /* because we do not set the focus */                  return TRUE;                    /* because we do not set the focus */
959    
960          case WM_COMMAND:          case WM_COMMAND:
# Line 593  static BOOL CALLBACK hosts_dlg_proc(HWND Line 965  static BOOL CALLBACK hosts_dlg_proc(HWND
965                          if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {                          if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
966                                  add_host_key(pvar);                                  add_host_key(pvar);
967                          }                          }
968                          SSH_notify_host_OK(pvar);  
969                            if (SSHv1(pvar)) {
970                                    SSH_notify_host_OK(pvar);
971                            } else { // SSH2
972                                    // SSH2ではあとで SSH_notify_host_OK() を呼ぶ。
973                            }
974    
975                          pvar->hosts_state.hosts_dialog = NULL;                          pvar->hosts_state.hosts_dialog = NULL;
976    
# Line 649  void HOSTS_do_different_host_dialog(HWND Line 1026  void HOSTS_do_different_host_dialog(HWND
1026          }          }
1027  }  }
1028    
1029  BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname,  //
1030                                                    int bits, unsigned char FAR * exp,  // サーバから送られてきたホスト公開鍵の妥当性をチェックする
1031                                                    unsigned char FAR * mod)  //
1032    // SSH2対応を追加 (2006.3.24 yutaka)
1033    //
1034    BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, Key *key)
1035  {  {
1036          int found_different_key = 0;          int found_different_key = 0;
1037    
1038            // すでに known_hosts ファイルからホスト公開鍵を読み込んでいるなら、それと比較する。
1039          if (pvar->hosts_state.prefetched_hostname != NULL          if (pvar->hosts_state.prefetched_hostname != NULL
1040                  && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0                  && _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0
1041                  && match_key(pvar, bits, exp, mod)) {                  && match_key(pvar, key)) {
1042                  SSH_notify_host_OK(pvar);  
1043                    if (SSHv1(pvar)) {
1044                            SSH_notify_host_OK(pvar);
1045                    } else {
1046                            // SSH2ではあとで SSH_notify_host_OK() を呼ぶ。
1047                    }
1048                  return TRUE;                  return TRUE;
1049          }          }
1050    
1051            // 先読みされていない場合は、この時点でファイルから読み込む
1052          if (begin_read_host_files(pvar, 0)) {          if (begin_read_host_files(pvar, 0)) {
1053                  do {                  do {
1054                          if (!read_host_key(pvar, hostname, 0)) {                          if (!read_host_key(pvar, hostname, 0)) {
1055                                  break;                                  break;
1056                          }                          }
1057    
1058                          if (pvar->hosts_state.key_bits > 0) {                          if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) {
1059                                  if (match_key(pvar, bits, exp, mod)) {                                  if (match_key(pvar, key)) {
1060                                          finish_read_host_files(pvar, 0);                                          finish_read_host_files(pvar, 0);
1061                                          SSH_notify_host_OK(pvar);                                          SSH_notify_host_OK(pvar);
1062                                          return TRUE;                                          return TRUE;
1063                                  } else {                                  } else {
1064                                            // キーは known_hosts に見つかったが、キーの内容が異なる。
1065                                          found_different_key = 1;                                          found_different_key = 1;
1066                                  }                                  }
1067                          }                          }
1068                  } while (pvar->hosts_state.key_bits > 0);                  } while (pvar->hosts_state.hostkey.type != KEY_UNSPEC);  // キーが見つかっている間はループする
1069    
1070                  finish_read_host_files(pvar, 0);                  finish_read_host_files(pvar, 0);
1071          }          }
1072    
1073          pvar->hosts_state.key_bits = bits;  
1074          pvar->hosts_state.key_exp = copy_mp_int(exp);          // known_hosts に存在しないキーはあとでファイルへ書き込むために、ここで保存しておく。
1075          pvar->hosts_state.key_mod = copy_mp_int(mod);          pvar->hosts_state.hostkey.type = key->type;
1076            if (key->type == KEY_RSA1) { // SSH1
1077                    pvar->hosts_state.hostkey.bits = key->bits;
1078                    pvar->hosts_state.hostkey.exp = copy_mp_int(key->exp);
1079                    pvar->hosts_state.hostkey.mod = copy_mp_int(key->mod);
1080    
1081            } else if (key->type == KEY_RSA) { // SSH2 RSA
1082                    pvar->hosts_state.hostkey.rsa = duplicate_RSA(key->rsa);
1083    
1084            } else { // SSH2 DSA
1085                    pvar->hosts_state.hostkey.dsa = duplicate_DSA(key->dsa);
1086    
1087            }
1088          free(pvar->hosts_state.prefetched_hostname);          free(pvar->hosts_state.prefetched_hostname);
1089          pvar->hosts_state.prefetched_hostname = _strdup(hostname);          pvar->hosts_state.prefetched_hostname = _strdup(hostname);
1090    
# Line 714  void HOSTS_end(PTInstVar pvar) Line 1114  void HOSTS_end(PTInstVar pvar)
1114          int i;          int i;
1115    
1116          free(pvar->hosts_state.prefetched_hostname);          free(pvar->hosts_state.prefetched_hostname);
1117    #if 0
1118          free(pvar->hosts_state.key_exp);          free(pvar->hosts_state.key_exp);
1119          free(pvar->hosts_state.key_mod);          free(pvar->hosts_state.key_mod);
1120    #else
1121            init_hostkey(&pvar->hosts_state.hostkey);
1122    #endif
1123    
1124          if (pvar->hosts_state.file_names != NULL) {          if (pvar->hosts_state.file_names != NULL) {
1125                  for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {                  for (i = 0; pvar->hosts_state.file_names[i] != NULL; i++) {
# Line 727  void HOSTS_end(PTInstVar pvar) Line 1131  void HOSTS_end(PTInstVar pvar)
1131    
1132  /*  /*
1133   * $Log: not supported by cvs2svn $   * $Log: not supported by cvs2svn $
1134     * Revision 1.3  2006/02/18 07:37:02  yutakakn
1135     *   ・コンパイラを Visual Studio 2005 Standard Edition に切り替えた。
1136     *   ・stricmp()を_stricmp()へ置換した
1137     *   ・strdup()を_strdup()へ置換した
1138     *
1139   * Revision 1.2  2004/12/19 15:39:42  yutakakn   * Revision 1.2  2004/12/19 15:39:42  yutakakn
1140   * CVS LogIDの追加   * CVS LogIDの追加
1141   *   *

Legend:
Removed from v.2850  
changed lines
  Added in v.2856

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