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 2859 by yutakakn, Wed Mar 29 14:56:52 2006 UTC revision 2861 by yutakakn, Tue Apr 4 13:52:52 2006 UTC
# Line 614  static int check_host_key(PTInstVar pvar Line 614  static int check_host_key(PTInstVar pvar
614  // known_hostsファイルからホスト名に合致する行を読む  // 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, int return_always)
618  {  {
619          int i;          int i;
620            int while_flg;
621    
622          for (i = 0; hostname[i] != 0; i++) {          for (i = 0; hostname[i] != 0; i++) {
623                  int ch = hostname[i];                  int ch = hostname[i];
# Line 686  static int read_host_key(PTInstVar pvar, Line 687  static int read_host_key(PTInstVar pvar,
687                          check_host_key(pvar, hostname,                          check_host_key(pvar, hostname,
688                                                     pvar->hosts_state.file_data +                                                     pvar->hosts_state.file_data +
689                                                     pvar->hosts_state.file_data_index);                                                     pvar->hosts_state.file_data_index);
690          } while (pvar->hosts_state.hostkey.type == KEY_UNSPEC);  // 有効なキーが見つかるまで  
691                    if (!return_always) {
692                            // 有効なキーが見つかるまで
693                            while_flg = (pvar->hosts_state.hostkey.type == KEY_UNSPEC);
694                    }
695                    else {
696                            while_flg = 0;
697                    }
698            } while (while_flg);
699    
700          return 1;          return 1;
701  }  }
# Line 705  void HOSTS_prefetch_host_key(PTInstVar p Line 714  void HOSTS_prefetch_host_key(PTInstVar p
714                  return;                  return;
715          }          }
716    
717          if (!read_host_key(pvar, hostname, 1)) {          if (!read_host_key(pvar, hostname, 1, 0)) {
718                  return;                  return;
719          }          }
720    
# Line 939  static void add_host_key(PTInstVar pvar) Line 948  static void add_host_key(PTInstVar pvar)
948          }          }
949  }  }
950    
951    static char FAR *copy_mp_int(char FAR * num)
952    {
953            int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;
954            char FAR *result = (char FAR *) malloc(len);
955    
956            if (result != NULL) {
957                    memcpy(result, num, len);
958            }
959    
960            return result;
961    }
962    
963    //
964    // 同じホストで内容の異なるキーを削除する
965    // add_host_key のあとに呼ぶこと
966    //
967    static void delete_different_key(PTInstVar pvar)
968    {
969            char FAR *name = pvar->hosts_state.file_names[0];
970    
971            if (name == NULL || name[0] == 0) {
972                    notify_nonfatal_error(pvar,
973                                                              "The host and its key cannot be added, because no known-hosts file has been specified.\n"
974                                                              "Restart Teraterm and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
975            }
976            else {
977                    Key key; // 接続中のホストのキー
978                    int length = strlen(name);
979                    char filename[L_tmpnam];
980                    int fd;
981                    int amount_written = 0;
982                    int close_result;
983                    int data_index = 0;
984    
985                    // 書き込み一時ファイルを開く
986                    tmpnam(filename);
987                    fd =
988                            _open(filename,
989                                      _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY |
990                                      _O_TRUNC,
991                                      _S_IREAD | _S_IWRITE);
992    
993                    if (fd == -1) {
994                            if (errno == EACCES) {
995                                    notify_nonfatal_error(pvar,
996                                                                              "An error occurred while trying to write the host key.\n"
997                                                                              "You do not have permission to write to the known-hosts file.");
998                            } else {
999                                    notify_nonfatal_error(pvar,
1000                                                                              "An error occurred while trying to write the host key.\n"
1001                                                                              "The host key could not be written.");
1002                            }
1003                            free(filename);
1004                            return;
1005                    }
1006    
1007                    // 接続中のサーバのキーを読み込む
1008                    if (pvar->hosts_state.hostkey.type == KEY_RSA1) { // SSH1
1009                            key.type = KEY_RSA1;
1010                            key.bits = pvar->hosts_state.hostkey.bits;
1011                            key.exp = copy_mp_int(pvar->hosts_state.hostkey.exp);
1012                            key.mod = copy_mp_int(pvar->hosts_state.hostkey.mod);
1013                    } else if (pvar->hosts_state.hostkey.type == KEY_RSA) { // SSH2 RSA
1014                            key.type = KEY_RSA;
1015                            key.rsa = duplicate_RSA(pvar->hosts_state.hostkey.rsa);
1016                    } else { // SSH2 DSA
1017                            key.type = KEY_DSA;
1018                            key.dsa = duplicate_DSA(pvar->hosts_state.hostkey.dsa);
1019                    }
1020    
1021                    // ファイルから読み込む
1022                    begin_read_host_files(pvar, 0);
1023                    do {
1024                            int host_index = 0;
1025                            int matched = 0;
1026                            int keybits = 0;
1027                            char FAR *data;
1028                            int do_write = 0;
1029                            length = amount_written = 0;
1030    
1031                            if (!read_host_key(pvar, pvar->ssh_state.hostname, 0, 1)) {
1032                                    break;
1033                            }
1034    
1035                            if (data_index == pvar->hosts_state.file_data_index) {
1036                                    // index が進まない == 最後まで読んだ
1037                                    break;
1038                            }
1039    
1040                            data = pvar->hosts_state.file_data + data_index;
1041                            host_index = eat_spaces(data);
1042    
1043                            if (data[host_index] == '#') {
1044                                    do_write = 1;
1045                            }
1046                            else {
1047                                    // ホストの照合
1048                                    host_index--;
1049                                    do {
1050                                            int negated;
1051    
1052                                            host_index++;
1053                                            negated = data[host_index] == '!';
1054    
1055                                            if (negated) {
1056                                                    host_index++;
1057                                                    if (match_pattern(data + host_index,
1058                                                                                      pvar->ssh_state.hostname)) {
1059                                                            matched = 0;
1060                                                            // 接続バージョンチェックのために host_index を進めてから抜ける
1061                                                            host_index--;
1062                                                            do {
1063                                                                    host_index++;
1064                                                                    host_index += eat_to_end_of_pattern(data + host_index);
1065                                                            } while (data[host_index] == ',');
1066                                                            break;
1067                                                    }
1068                                            }
1069                                            else if (match_pattern(data + host_index,
1070                                                                              pvar->ssh_state.hostname)) {
1071                                                    matched = 1;
1072                                            }
1073                                            host_index += eat_to_end_of_pattern(data + host_index);
1074                                    } while (data[host_index] == ',');
1075    
1076                                    // ホストが等しくて合致するキーが見つかる
1077                                    if (match_key(pvar, &key)) {
1078                                            do_write = 1;
1079                                    }
1080                                    // ホストが等しくない
1081                                    else if (!matched) {
1082                                            do_write = 1;
1083                                    }
1084                                    // ホストが等しい and 接続のバージョンが違う
1085                                    else {
1086                                            int rsa1_key_bits=0;
1087                                            rsa1_key_bits = atoi(data + host_index + eat_spaces(data + host_index));
1088                                            
1089                                            if (rsa1_key_bits > 0) { // ファイルのキーは ssh1
1090                                                    if (!SSHv1(pvar)) {
1091                                                            do_write = 1;
1092                                                    }
1093                                            }
1094                                            else { // ファイルのキーは ssh2
1095                                                    if (!SSHv2(pvar)) {
1096                                                            do_write = 1;
1097                                                    }
1098                                            }
1099                                    }
1100                            }
1101    
1102                            // 書き込み処理
1103                            if (do_write) {
1104                                    length = pvar->hosts_state.file_data_index - data_index;
1105                                    amount_written =
1106                                            _write(fd, pvar->hosts_state.file_data + data_index,
1107                                                       length);
1108    
1109                                    if (amount_written != length) {
1110                                            goto error1;
1111                                    }
1112                            }
1113                            data_index = pvar->hosts_state.file_data_index;
1114                    } while (1); // 最後まで読む
1115    
1116    error1:
1117                    close_result = _close(fd);
1118                    if (amount_written != length || close_result == -1) {
1119                            notify_nonfatal_error(pvar,
1120                                                                      "An error occurred while trying to write the host key.\n"
1121                                                                      "The host key could not be written.");
1122                            goto error2;
1123                    }
1124    
1125                    // 書き込み一時ファイルからリネーム
1126                    _unlink(pvar->hosts_state.file_names[0]);
1127                    rename(filename, pvar->hosts_state.file_names[0]);
1128    
1129    error2:
1130                    _unlink(filename);
1131    
1132                    finish_read_host_files(pvar, 0);
1133            }
1134    }
1135    
1136  //  //
1137  // Unknown hostのホスト公開鍵を known_hosts ファイルへ保存するかどうかを  // Unknown hostのホスト公開鍵を known_hosts ファイルへ保存するかどうかを
1138  // ユーザに確認させる。  // ユーザに確認させる。
1139  // TODO: finger printの表示も行う。  // TODO: finger printの表示も行う。
1140  // (2006.3.25 yutaka)  // (2006.3.25 yutaka)
1141  //  //
1142  static BOOL CALLBACK hosts_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,  static BOOL CALLBACK hosts_add_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1143                                                                          LPARAM lParam)                                                                                  LPARAM lParam)
1144  {  {
1145          PTInstVar pvar;          PTInstVar pvar;
1146    
# Line 998  static BOOL CALLBACK hosts_dlg_proc(HWND Line 1192  static BOOL CALLBACK hosts_dlg_proc(HWND
1192          }          }
1193  }  }
1194    
1195  static char FAR *copy_mp_int(char FAR * num)  //
1196    // 置き換え時の確認ダイアログを分離
1197    //
1198    static BOOL CALLBACK hosts_replace_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
1199                                                                                            LPARAM lParam)
1200  {  {
1201          int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;          PTInstVar pvar;
         char FAR *result = (char FAR *) malloc(len);  
1202    
1203          if (result != NULL) {          switch (msg) {
1204                  memcpy(result, num, len);          case WM_INITDIALOG:
1205          }                  pvar = (PTInstVar) lParam;
1206                    pvar->hosts_state.hosts_dialog = dlg;
1207                    SetWindowLong(dlg, DWL_USER, lParam);
1208    
1209          return result;                  init_hosts_dlg(pvar, dlg);
1210    
1211                    // デフォルトでチェックは入れない
1212                    return TRUE;                    /* because we do not set the focus */
1213    
1214            case WM_COMMAND:
1215                    pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER);
1216    
1217                    switch (LOWORD(wParam)) {
1218                    case IDC_CONTINUE:
1219                            if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) {
1220                                    add_host_key(pvar);
1221                                    delete_different_key(pvar);
1222                            }
1223    
1224                            if (SSHv1(pvar)) {
1225                                    SSH_notify_host_OK(pvar);
1226                            } else { // SSH2
1227                                    // SSH2ではあとで SSH_notify_host_OK() を呼ぶ。
1228                            }
1229    
1230                            pvar->hosts_state.hosts_dialog = NULL;
1231    
1232                            EndDialog(dlg, 1);
1233                            return TRUE;
1234    
1235                    case IDCANCEL:                  /* kill the connection */
1236                            pvar->hosts_state.hosts_dialog = NULL;
1237                            notify_closed_connection(pvar);
1238                            EndDialog(dlg, 0);
1239                            return TRUE;
1240    
1241                    default:
1242                            return FALSE;
1243                    }
1244    
1245            default:
1246                    return FALSE;
1247            }
1248  }  }
1249    
1250  void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)  void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar)
# Line 1017  void HOSTS_do_unknown_host_dialog(HWND w Line 1254  void HOSTS_do_unknown_host_dialog(HWND w
1254    
1255                  DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),                  DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHUNKNOWNHOST),
1256                                             cur_active != NULL ? cur_active : wnd,                                             cur_active != NULL ? cur_active : wnd,
1257                                             hosts_dlg_proc, (LPARAM) pvar);                                             hosts_add_dlg_proc, (LPARAM) pvar);
1258          }          }
1259  }  }
1260    
# Line 1028  void HOSTS_do_different_host_dialog(HWND Line 1265  void HOSTS_do_different_host_dialog(HWND
1265    
1266                  DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTHOST),                  DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTHOST),
1267                                             cur_active != NULL ? cur_active : wnd,                                             cur_active != NULL ? cur_active : wnd,
1268                                             hosts_dlg_proc, (LPARAM) pvar);                                             hosts_replace_dlg_proc, (LPARAM) pvar);
1269          }          }
1270  }  }
1271    
# Line 1057  BOOL HOSTS_check_host_key(PTInstVar pvar Line 1294  BOOL HOSTS_check_host_key(PTInstVar pvar
1294          // 先読みされていない場合は、この時点でファイルから読み込む          // 先読みされていない場合は、この時点でファイルから読み込む
1295          if (begin_read_host_files(pvar, 0)) {          if (begin_read_host_files(pvar, 0)) {
1296                  do {                  do {
1297                          if (!read_host_key(pvar, hostname, 0)) {                          if (!read_host_key(pvar, hostname, 0, 0)) {
1298                                  break;                                  break;
1299                          }                          }
1300    
# Line 1143  void HOSTS_end(PTInstVar pvar) Line 1380  void HOSTS_end(PTInstVar pvar)
1380    
1381  /*  /*
1382   * $Log: not supported by cvs2svn $   * $Log: not supported by cvs2svn $
1383     * Revision 1.6  2006/03/29 14:56:52  yutakakn
1384     * known_hostsファイルにキー種別の異なる同一ホストのエントリがあると、アプリケーションエラーとなるバグを修正した。
1385     *
1386   * Revision 1.5  2006/03/26 17:07:17  yutakakn   * Revision 1.5  2006/03/26 17:07:17  yutakakn
1387   * fingerprint表示を追加   * fingerprint表示を追加
1388   *   *

Legend:
Removed from v.2859  
changed lines
  Added in v.2861

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