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 5847 by yutakapon, Mon May 4 17:18:56 2015 UTC revision 5849 by yutakapon, Tue May 5 18:08:23 2015 UTC
# Line 1231  error: Line 1231  error:
1231          return result;          return result;
1232  }  }
1233    
1234    static char FAR *format_specified_host_key(Key *key, char *hostname, unsigned short tcpport)
1235    {
1236            int host_len = strlen(hostname);
1237            char *result = NULL;
1238            int index;
1239            ssh_keytype type = key->type;
1240    
1241            switch (type) {
1242            case KEY_RSA1:
1243            {
1244                    int result_len = host_len + 50 + 8 +
1245                            get_ushort16_MSBfirst(key->exp) / 3 +
1246                            get_ushort16_MSBfirst(key->mod) / 3;
1247                    result = (char FAR *) malloc(result_len);
1248    
1249                    if (tcpport == 22) {
1250                            strncpy_s(result, result_len, hostname, _TRUNCATE);
1251                            index = host_len;
1252                    }
1253                    else {
1254                            _snprintf_s(result, result_len, _TRUNCATE, "[%s]:%d",
1255                                    hostname,
1256                                    tcpport);
1257                            index = strlen(result);
1258                    }
1259    
1260                    _snprintf_s(result + index, result_len - host_len, _TRUNCATE,
1261                            " %d ", key->bits);
1262                    index += strlen(result + index);
1263                    index += print_mp_int(result + index, key->exp);
1264                    result[index] = ' ';
1265                    index++;
1266                    index += print_mp_int(result + index, key->mod);
1267                    strncpy_s(result + index, result_len - index, " \r\n", _TRUNCATE);
1268    
1269                    break;
1270            }
1271    
1272            case KEY_RSA:
1273            case KEY_DSA:
1274            case KEY_ECDSA256:
1275            case KEY_ECDSA384:
1276            case KEY_ECDSA521:
1277            case KEY_ED25519:
1278            {
1279                    //Key *key = &pvar->hosts_state.hostkey;
1280                    char *blob = NULL;
1281                    int blen, uulen, msize;
1282                    char *uu = NULL;
1283                    int n;
1284    
1285                    key_to_blob(key, &blob, &blen);
1286                    uulen = 2 * blen;
1287                    uu = malloc(uulen);
1288                    if (uu == NULL) {
1289                            goto error;
1290                    }
1291                    n = uuencode(blob, blen, uu, uulen);
1292                    if (n > 0) {
1293                            msize = host_len + 50 + uulen;
1294                            result = malloc(msize);
1295                            if (result == NULL) {
1296                                    goto error;
1297                            }
1298    
1299                            // setup
1300                            if (tcpport == 22) {
1301                                    _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
1302                                            hostname,
1303                                            get_sshname_from_key(key),
1304                                            uu);
1305                            }
1306                            else {
1307                                    _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
1308                                            hostname,
1309                                            tcpport,
1310                                            get_sshname_from_key(key),
1311                                            uu);
1312                            }
1313                    }
1314            error:
1315                    if (blob != NULL)
1316                            free(blob);
1317                    if (uu != NULL)
1318                            free(uu);
1319    
1320                    break;
1321            }
1322    
1323            default:
1324                    return NULL;
1325    
1326            }
1327    
1328            return result;
1329    }
1330    
1331  static void add_host_key(PTInstVar pvar)  static void add_host_key(PTInstVar pvar)
1332  {  {
1333          char FAR *name = NULL;          char FAR *name = NULL;
# Line 1283  static void add_host_key(PTInstVar pvar) Line 1380  static void add_host_key(PTInstVar pvar)
1380          }          }
1381  }  }
1382    
1383    // 指定したキーを known_hosts に追加する。
1384    void HOSTS_add_host_key(PTInstVar pvar, Key *key)
1385    {
1386            char FAR *name = NULL;
1387            char *hostname;
1388            unsigned short tcpport;
1389    
1390            hostname = pvar->ssh_state.hostname;
1391            tcpport = pvar->ssh_state.tcpport;
1392    
1393            if (pvar->hosts_state.file_names != NULL)
1394                    name = pvar->hosts_state.file_names[0];
1395    
1396            if (name == NULL || name[0] == 0) {
1397                    UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1398                            "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1399                            "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1400                    notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1401            }
1402            else {
1403                    char FAR *keydata = format_specified_host_key(key, hostname, tcpport);
1404                    int length = strlen(keydata);
1405                    int fd;
1406                    int amount_written;
1407                    int close_result;
1408                    char buf[FILENAME_MAX];
1409    
1410                    get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1411                    fd = _open(buf,
1412                            _O_APPEND | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY,
1413                            _S_IREAD | _S_IWRITE);
1414                    if (fd == -1) {
1415                            if (errno == EACCES) {
1416                                    UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1417                                            "An error occurred while trying to write the host key.\n"
1418                                            "You do not have permission to write to the known-hosts file.");
1419                                    notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1420                            }
1421                            else {
1422                                    UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1423                                            "An error occurred while trying to write the host key.\n"
1424                                            "The host key could not be written.");
1425                                    notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1426                            }
1427                            return;
1428                    }
1429    
1430                    amount_written = _write(fd, keydata, length);
1431                    free(keydata);
1432                    close_result = _close(fd);
1433    
1434                    if (amount_written != length || close_result == -1) {
1435                            UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1436                                    "An error occurred while trying to write the host key.\n"
1437                                    "The host key could not be written.");
1438                            notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1439                    }
1440            }
1441    }
1442    
1443  static char FAR *copy_mp_int(char FAR * num)  static char FAR *copy_mp_int(char FAR * num)
1444  {  {
1445          int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;          int len = (get_ushort16_MSBfirst(num) + 7) / 8 + 2;
# Line 1513  error2: Line 1670  error2:
1670          }          }
1671  }  }
1672    
1673    
1674    void HOSTS_delete_all_hostkeys(PTInstVar pvar)
1675    {
1676            char FAR *name = pvar->hosts_state.file_names[0];
1677            char *hostname;
1678            unsigned short tcpport;
1679    
1680            hostname = pvar->ssh_state.hostname;
1681            tcpport = pvar->ssh_state.tcpport;
1682    
1683            if (name == NULL || name[0] == 0) {
1684                    UTIL_get_lang_msg("MSG_HOSTS_FILE_UNSPECIFY_ERROR", pvar,
1685                            "The host and its key cannot be added, because no known-hosts file has been specified.\n"
1686                            "Restart Tera Term and specify a read/write known-hosts file in the TTSSH Setup dialog box.");
1687                    notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1688            }
1689            else {
1690                    Key key; // 接続中のホストのキー
1691                    Key *key_freed;
1692                    int length;
1693                    char filename[MAX_PATH];
1694                    char tmp[L_tmpnam];
1695                    int fd;
1696                    int amount_written = 0;
1697                    int close_result;
1698                    int data_index = 0;
1699                    char buf[FILENAME_MAX];
1700    
1701                    // 書き込み一時ファイルを開く
1702                    _getcwd(filename, sizeof(filename));
1703                    tmpnam_s(tmp, sizeof(tmp));
1704                    strcat_s(filename, sizeof(filename), tmp);
1705                    fd = _open(filename,
1706                            _O_CREAT | _O_WRONLY | _O_SEQUENTIAL | _O_BINARY | _O_TRUNC,
1707                            _S_IREAD | _S_IWRITE);
1708    
1709                    if (fd == -1) {
1710                            if (errno == EACCES) {
1711                                    UTIL_get_lang_msg("MSG_HOSTS_WRITE_EACCES_ERROR", pvar,
1712                                            "An error occurred while trying to write the host key.\n"
1713                                            "You do not have permission to write to the known-hosts file.");
1714                                    notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1715                            }
1716                            else {
1717                                    UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1718                                            "An error occurred while trying to write the host key.\n"
1719                                            "The host key could not be written.");
1720                                    notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1721                            }
1722                            return;
1723                    }
1724    
1725                    // 接続中のサーバのキーを読み込む
1726                    memset(&key, 0, sizeof(key));
1727                    switch (pvar->hosts_state.hostkey.type) {
1728                    case KEY_RSA1: // SSH1
1729                            key.type = KEY_RSA1;
1730                            key.bits = pvar->hosts_state.hostkey.bits;
1731                            key.exp = copy_mp_int(pvar->hosts_state.hostkey.exp);
1732                            key.mod = copy_mp_int(pvar->hosts_state.hostkey.mod);
1733                            break;
1734                    case KEY_RSA: // SSH2 RSA
1735                            key.type = KEY_RSA;
1736                            key.rsa = duplicate_RSA(pvar->hosts_state.hostkey.rsa);
1737                            break;
1738                    case KEY_DSA: // SSH2 DSA
1739                            key.type = KEY_DSA;
1740                            key.dsa = duplicate_DSA(pvar->hosts_state.hostkey.dsa);
1741                            break;
1742                    case KEY_ECDSA256:
1743                    case KEY_ECDSA384:
1744                    case KEY_ECDSA521:
1745                            key.type = pvar->hosts_state.hostkey.type;
1746                            key.ecdsa = EC_KEY_dup(pvar->hosts_state.hostkey.ecdsa);
1747                            break;
1748                    case KEY_ED25519:
1749                            key.type = pvar->hosts_state.hostkey.type;
1750                            key.ed25519_pk = duplicate_ED25519_PK(pvar->hosts_state.hostkey.ed25519_pk);
1751                            break;
1752                    }
1753    
1754                    // ファイルから読み込む
1755                    begin_read_host_files(pvar, 0);
1756                    do {
1757                            int host_index = 0;
1758                            int matched = 0;
1759                            int keybits = 0;
1760                            char FAR *data;
1761                            int do_write = 0;
1762                            length = amount_written = 0;
1763    
1764                            if (!read_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, 0, 1)) {
1765                                    break;
1766                            }
1767    
1768                            if (data_index == pvar->hosts_state.file_data_index) {
1769                                    // index が進まない == 最後まで読んだ
1770                                    break;
1771                            }
1772    
1773                            data = pvar->hosts_state.file_data + data_index;
1774                            host_index = eat_spaces(data);
1775    
1776                            if (data[host_index] == '#') {
1777                                    do_write = 1;
1778                            }
1779                            else {
1780                                    // ホストの照合
1781                                    host_index--;
1782                                    do {
1783                                            int negated;
1784                                            int bracketed;
1785                                            char *end_bracket;
1786                                            int host_matched = 0;
1787                                            unsigned short keyfile_port = 22;
1788    
1789                                            host_index++;
1790                                            negated = data[host_index] == '!';
1791    
1792                                            if (negated) {
1793                                                    host_index++;
1794                                                    bracketed = data[host_index] == '[';
1795                                                    if (bracketed) {
1796                                                            end_bracket = strstr(data + host_index + 1, "]:");
1797                                                            if (end_bracket != NULL) {
1798                                                                    *end_bracket = ' ';
1799                                                                    host_index++;
1800                                                            }
1801                                                    }
1802                                                    host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1803                                                    if (bracketed && end_bracket != NULL) {
1804                                                            *end_bracket = ']';
1805                                                            keyfile_port = atoi(end_bracket + 2);
1806                                                    }
1807                                                    if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1808                                                            matched = 0;
1809                                                            // 接続バージョンチェックのために host_index を進めてから抜ける
1810                                                            host_index--;
1811                                                            do {
1812                                                                    host_index++;
1813                                                                    host_index += eat_to_end_of_pattern(data + host_index);
1814                                                            } while (data[host_index] == ',');
1815                                                            break;
1816                                                    }
1817                                            }
1818                                            else {
1819                                                    bracketed = data[host_index] == '[';
1820                                                    if (bracketed) {
1821                                                            end_bracket = strstr(data + host_index + 1, "]:");
1822                                                            if (end_bracket != NULL) {
1823                                                                    *end_bracket = ' ';
1824                                                                    host_index++;
1825                                                            }
1826                                                    }
1827                                                    host_matched = match_pattern(data + host_index, pvar->ssh_state.hostname);
1828                                                    if (bracketed && end_bracket != NULL) {
1829                                                            *end_bracket = ']';
1830                                                            keyfile_port = atoi(end_bracket + 2);
1831                                                    }
1832                                                    if (host_matched && keyfile_port == pvar->ssh_state.tcpport) {
1833                                                            matched = 1;
1834                                                    }
1835                                            }
1836                                            host_index += eat_to_end_of_pattern(data + host_index);
1837                                    } while (data[host_index] == ',');
1838    
1839                                    // ホストが等しくない
1840                                    if (!matched) {
1841                                            do_write = 1;
1842                                    }
1843                                    // ホストが等しい
1844                                    else {
1845                                            // 一切書き込みをしない。
1846    
1847                                    }
1848                            }
1849    
1850                            // 書き込み処理
1851                            if (do_write) {
1852                                    length = pvar->hosts_state.file_data_index - data_index;
1853                                    amount_written =
1854                                            _write(fd, pvar->hosts_state.file_data + data_index,
1855                                            length);
1856    
1857                                    if (amount_written != length) {
1858                                            goto error1;
1859                                    }
1860                            }
1861                            data_index = pvar->hosts_state.file_data_index;
1862                    } while (1); // 最後まで読む
1863    
1864            error1:
1865                    close_result = _close(fd);
1866                    if (amount_written != length || close_result == -1) {
1867                            UTIL_get_lang_msg("MSG_HOSTS_WRITE_ERROR", pvar,
1868                                    "An error occurred while trying to write the host key.\n"
1869                                    "The host key could not be written.");
1870                            notify_nonfatal_error(pvar, pvar->ts->UIMsg);
1871                            goto error2;
1872                    }
1873    
1874                    // 書き込み一時ファイルからリネーム
1875                    get_teraterm_dir_relative_name(buf, sizeof(buf), name);
1876                    _unlink(buf);
1877                    rename(filename, buf);
1878    
1879            error2:
1880                    _unlink(filename);
1881    
1882                    finish_read_host_files(pvar, 0);
1883    
1884                    // 最後にメモリを解放しておく。
1885                    key_freed = key_new(KEY_UNSPEC);
1886                    memcpy(key_freed, &key, sizeof(Key));
1887                    key_free(key_freed);
1888            }
1889    }
1890    
1891    
1892  //  //
1893  // Unknown hostのホスト公開鍵を known_hosts ファイルへ保存するかどうかを  // Unknown hostのホスト公開鍵を known_hosts ファイルへ保存するかどうかを
1894  // ユーザに確認させる。  // ユーザに確認させる。

Legend:
Removed from v.5847  
changed lines
  Added in v.5849

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