| 791 |
} |
} |
| 792 |
|
|
| 793 |
// 公開鍵が等しいかを検証する |
// 公開鍵が等しいかを検証する |
| 794 |
static BOOL match_key(PTInstVar pvar, Key *key) |
// -1 ... 鍵の型が違う |
| 795 |
|
// 0 ... 等しくない |
| 796 |
|
// 1 ... 等しい |
| 797 |
|
static int match_key(PTInstVar pvar, Key *key) |
| 798 |
{ |
{ |
| 799 |
int bits; |
int bits; |
| 800 |
unsigned char FAR * exp; |
unsigned char FAR * exp; |
| 802 |
const EC_GROUP *group; |
const EC_GROUP *group; |
| 803 |
const EC_POINT *pa, *pb; |
const EC_POINT *pa, *pb; |
| 804 |
|
|
| 805 |
|
if (pvar->hosts_state.hostkey.type != key->type) { |
| 806 |
|
return -1; |
| 807 |
|
} |
| 808 |
|
|
| 809 |
switch (key->type) { |
switch (key->type) { |
| 810 |
case KEY_RSA1: // SSH1 host public key |
case KEY_RSA1: // SSH1 host public key |
| 811 |
bits = key->bits; |
bits = key->bits; |
| 1226 |
host_index += eat_to_end_of_pattern(data + host_index); |
host_index += eat_to_end_of_pattern(data + host_index); |
| 1227 |
} while (data[host_index] == ','); |
} while (data[host_index] == ','); |
| 1228 |
|
|
|
// ホストが等しくて合致するキーが見つかる |
|
|
if (match_key(pvar, &key)) { |
|
|
do_write = 1; |
|
|
} |
|
| 1229 |
// ホストが等しくない |
// ホストが等しくない |
| 1230 |
else if (!matched) { |
if (!matched) { |
| 1231 |
do_write = 1; |
do_write = 1; |
| 1232 |
} |
} |
| 1233 |
// ホストが等しい and 接続のバージョンが違う |
// ホストが等しい |
| 1234 |
else { |
else { |
| 1235 |
int rsa1_key_bits=0; |
// 鍵の形式が違う or 合致するキー |
| 1236 |
rsa1_key_bits = atoi(data + host_index + eat_spaces(data + host_index)); |
if (match_key(pvar, &key) != 0) { |
| 1237 |
|
do_write = 1; |
|
if (rsa1_key_bits > 0) { // ファイルのキーは ssh1 |
|
|
if (!SSHv1(pvar)) { |
|
|
do_write = 1; |
|
|
} |
|
|
} |
|
|
else { // ファイルのキーは ssh2 |
|
|
if (!SSHv2(pvar)) { |
|
|
do_write = 1; |
|
|
} |
|
| 1238 |
} |
} |
| 1239 |
|
// 鍵の形式が同じで合致しないキーはスキップされる |
| 1240 |
} |
} |
| 1241 |
} |
} |
| 1242 |
|
|
| 1491 |
} |
} |
| 1492 |
} |
} |
| 1493 |
|
|
| 1494 |
|
// |
| 1495 |
|
// 同じホストで鍵形式が違う時の追加確認ダイアログを分離 |
| 1496 |
|
// |
| 1497 |
|
static BOOL CALLBACK hosts_add2_dlg_proc(HWND dlg, UINT msg, WPARAM wParam, |
| 1498 |
|
LPARAM lParam) |
| 1499 |
|
{ |
| 1500 |
|
PTInstVar pvar; |
| 1501 |
|
LOGFONT logfont; |
| 1502 |
|
HFONT font; |
| 1503 |
|
char uimsg[MAX_UIMSG]; |
| 1504 |
|
|
| 1505 |
|
switch (msg) { |
| 1506 |
|
case WM_INITDIALOG: |
| 1507 |
|
pvar = (PTInstVar) lParam; |
| 1508 |
|
pvar->hosts_state.hosts_dialog = dlg; |
| 1509 |
|
SetWindowLong(dlg, DWL_USER, lParam); |
| 1510 |
|
|
| 1511 |
|
// 追加・置き換えとも init_hosts_dlg を呼んでいるので、その前にセットする必要がある |
| 1512 |
|
GetWindowText(dlg, uimsg, sizeof(uimsg)); |
| 1513 |
|
UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_TITLE", pvar, uimsg); |
| 1514 |
|
SetWindowText(dlg, pvar->ts->UIMsg); |
| 1515 |
|
GetDlgItemText(dlg, IDC_HOSTWARNING, uimsg, sizeof(uimsg)); |
| 1516 |
|
UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNINIG", pvar, uimsg); |
| 1517 |
|
SetDlgItemText(dlg, IDC_HOSTWARNING, pvar->ts->UIMsg); |
| 1518 |
|
GetDlgItemText(dlg, IDC_HOSTWARNING2, uimsg, sizeof(uimsg)); |
| 1519 |
|
UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_WARNINIG2", pvar, uimsg); |
| 1520 |
|
SetDlgItemText(dlg, IDC_HOSTWARNING2, pvar->ts->UIMsg); |
| 1521 |
|
GetDlgItemText(dlg, IDC_HOSTFINGERPRINT, uimsg, sizeof(uimsg)); |
| 1522 |
|
UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_FINGERPRINT", pvar, uimsg); |
| 1523 |
|
SetDlgItemText(dlg, IDC_HOSTFINGERPRINT, pvar->ts->UIMsg); |
| 1524 |
|
GetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, uimsg, sizeof(uimsg)); |
| 1525 |
|
UTIL_get_lang_msg("DLG_DIFFERENTTYPEKEY_ADD", pvar, uimsg); |
| 1526 |
|
SetDlgItemText(dlg, IDC_ADDTOKNOWNHOSTS, pvar->ts->UIMsg); |
| 1527 |
|
GetDlgItemText(dlg, IDC_CONTINUE, uimsg, sizeof(uimsg)); |
| 1528 |
|
UTIL_get_lang_msg("BTN_CONTINUE", pvar, uimsg); |
| 1529 |
|
SetDlgItemText(dlg, IDC_CONTINUE, pvar->ts->UIMsg); |
| 1530 |
|
GetDlgItemText(dlg, IDCANCEL, uimsg, sizeof(uimsg)); |
| 1531 |
|
UTIL_get_lang_msg("BTN_DISCONNECT", pvar, uimsg); |
| 1532 |
|
SetDlgItemText(dlg, IDCANCEL, pvar->ts->UIMsg); |
| 1533 |
|
|
| 1534 |
|
init_hosts_dlg(pvar, dlg); |
| 1535 |
|
|
| 1536 |
|
font = (HFONT)SendMessage(dlg, WM_GETFONT, 0, 0); |
| 1537 |
|
GetObject(font, sizeof(LOGFONT), &logfont); |
| 1538 |
|
if (UTIL_get_lang_font("DLG_TAHOMA_FONT", dlg, &logfont, &DlgHostsAddFont, pvar)) { |
| 1539 |
|
SendDlgItemMessage(dlg, IDC_HOSTWARNING, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0)); |
| 1540 |
|
SendDlgItemMessage(dlg, IDC_HOSTWARNING2, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0)); |
| 1541 |
|
SendDlgItemMessage(dlg, IDC_HOSTFINGERPRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0)); |
| 1542 |
|
SendDlgItemMessage(dlg, IDC_FINGER_PRINT, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0)); |
| 1543 |
|
SendDlgItemMessage(dlg, IDC_ADDTOKNOWNHOSTS, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0)); |
| 1544 |
|
SendDlgItemMessage(dlg, IDC_CONTINUE, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0)); |
| 1545 |
|
SendDlgItemMessage(dlg, IDCANCEL, WM_SETFONT, (WPARAM)DlgHostsAddFont, MAKELPARAM(TRUE,0)); |
| 1546 |
|
} |
| 1547 |
|
else { |
| 1548 |
|
DlgHostsAddFont = NULL; |
| 1549 |
|
} |
| 1550 |
|
|
| 1551 |
|
// add host check box のデフォルトは off にする |
| 1552 |
|
// SendMessage(GetDlgItem(dlg, IDC_ADDTOKNOWNHOSTS), BM_SETCHECK, BST_CHECKED, 0); |
| 1553 |
|
|
| 1554 |
|
return TRUE; /* because we do not set the focus */ |
| 1555 |
|
|
| 1556 |
|
case WM_COMMAND: |
| 1557 |
|
pvar = (PTInstVar) GetWindowLong(dlg, DWL_USER); |
| 1558 |
|
|
| 1559 |
|
switch (LOWORD(wParam)) { |
| 1560 |
|
case IDC_CONTINUE: |
| 1561 |
|
if (IsDlgButtonChecked(dlg, IDC_ADDTOKNOWNHOSTS)) { |
| 1562 |
|
add_host_key(pvar); |
| 1563 |
|
} |
| 1564 |
|
|
| 1565 |
|
if (SSHv1(pvar)) { |
| 1566 |
|
SSH_notify_host_OK(pvar); |
| 1567 |
|
} else { // SSH2 |
| 1568 |
|
// SSH2ではあとで SSH_notify_host_OK() を呼ぶ。 |
| 1569 |
|
} |
| 1570 |
|
|
| 1571 |
|
pvar->hosts_state.hosts_dialog = NULL; |
| 1572 |
|
|
| 1573 |
|
EndDialog(dlg, 1); |
| 1574 |
|
|
| 1575 |
|
if (DlgHostsAddFont != NULL) { |
| 1576 |
|
DeleteObject(DlgHostsAddFont); |
| 1577 |
|
} |
| 1578 |
|
|
| 1579 |
|
return TRUE; |
| 1580 |
|
|
| 1581 |
|
case IDCANCEL: /* kill the connection */ |
| 1582 |
|
pvar->hosts_state.hosts_dialog = NULL; |
| 1583 |
|
notify_closed_connection(pvar); |
| 1584 |
|
EndDialog(dlg, 0); |
| 1585 |
|
|
| 1586 |
|
if (DlgHostsAddFont != NULL) { |
| 1587 |
|
DeleteObject(DlgHostsAddFont); |
| 1588 |
|
} |
| 1589 |
|
|
| 1590 |
|
return TRUE; |
| 1591 |
|
|
| 1592 |
|
default: |
| 1593 |
|
return FALSE; |
| 1594 |
|
} |
| 1595 |
|
|
| 1596 |
|
default: |
| 1597 |
|
return FALSE; |
| 1598 |
|
} |
| 1599 |
|
} |
| 1600 |
|
|
| 1601 |
void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar) |
void HOSTS_do_unknown_host_dialog(HWND wnd, PTInstVar pvar) |
| 1602 |
{ |
{ |
| 1603 |
if (pvar->hosts_state.hosts_dialog == NULL) { |
if (pvar->hosts_state.hosts_dialog == NULL) { |
| 1620 |
} |
} |
| 1621 |
} |
} |
| 1622 |
|
|
| 1623 |
|
void HOSTS_do_different_type_key_dialog(HWND wnd, PTInstVar pvar) |
| 1624 |
|
{ |
| 1625 |
|
if (pvar->hosts_state.hosts_dialog == NULL) { |
| 1626 |
|
HWND cur_active = GetActiveWindow(); |
| 1627 |
|
|
| 1628 |
|
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHDIFFERENTTYPEKEY), |
| 1629 |
|
cur_active != NULL ? cur_active : wnd, |
| 1630 |
|
hosts_add2_dlg_proc, (LPARAM) pvar); |
| 1631 |
|
} |
| 1632 |
|
} |
| 1633 |
|
|
| 1634 |
// |
// |
| 1635 |
// サーバから送られてきたホスト公開鍵の妥当性をチェックする |
// サーバから送られてきたホスト公開鍵の妥当性をチェックする |
| 1636 |
// |
// |
| 1638 |
// |
// |
| 1639 |
BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key) |
BOOL HOSTS_check_host_key(PTInstVar pvar, char FAR * hostname, unsigned short tcpport, Key *key) |
| 1640 |
{ |
{ |
| 1641 |
int found_different_key = 0; |
int found_different_key = 0, found_different_type_key = 0; |
| 1642 |
|
|
| 1643 |
// すでに known_hosts ファイルからホスト公開鍵を読み込んでいるなら、それと比較する。 |
// すでに known_hosts ファイルからホスト公開鍵を読み込んでいるなら、それと比較する。 |
| 1644 |
if (pvar->hosts_state.prefetched_hostname != NULL |
if (pvar->hosts_state.prefetched_hostname != NULL |
| 1645 |
&& _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0 |
&& _stricmp(pvar->hosts_state.prefetched_hostname, hostname) == 0 |
| 1646 |
&& match_key(pvar, key)) { |
&& match_key(pvar, key) == 1) { |
| 1647 |
|
|
| 1648 |
if (SSHv1(pvar)) { |
if (SSHv1(pvar)) { |
| 1649 |
SSH_notify_host_OK(pvar); |
SSH_notify_host_OK(pvar); |
| 1661 |
} |
} |
| 1662 |
|
|
| 1663 |
if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) { |
if (pvar->hosts_state.hostkey.type != KEY_UNSPEC) { |
| 1664 |
if (match_key(pvar, key)) { |
int match = match_key(pvar, key); |
| 1665 |
|
if (match == 1) { |
| 1666 |
finish_read_host_files(pvar, 0); |
finish_read_host_files(pvar, 0); |
| 1667 |
// すべてのエントリを参照して、合致するキーが見つかったら戻る。 |
// すべてのエントリを参照して、合致するキーが見つかったら戻る。 |
| 1668 |
// SSH2の場合はここでは何もしない。(2006.3.29 yutaka) |
// SSH2の場合はここでは何もしない。(2006.3.29 yutaka) |
| 1672 |
// SSH2ではあとで SSH_notify_host_OK() を呼ぶ。 |
// SSH2ではあとで SSH_notify_host_OK() を呼ぶ。 |
| 1673 |
} |
} |
| 1674 |
return TRUE; |
return TRUE; |
| 1675 |
} else { |
} |
| 1676 |
|
else if (match == 0) { |
| 1677 |
// キーは known_hosts に見つかったが、キーの内容が異なる。 |
// キーは known_hosts に見つかったが、キーの内容が異なる。 |
| 1678 |
found_different_key = 1; |
found_different_key = 1; |
| 1679 |
} |
} |
| 1680 |
|
else { |
| 1681 |
|
// キーの形式が違う場合 |
| 1682 |
|
found_different_type_key = 1; |
| 1683 |
|
} |
| 1684 |
} |
} |
| 1685 |
} while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // キーが見つかっている間はループする |
} while (pvar->hosts_state.hostkey.type != KEY_UNSPEC); // キーが見つかっている間はループする |
| 1686 |
|
|
| 1727 |
#else |
#else |
| 1728 |
HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar); |
HOSTS_do_different_key_dialog(pvar->NotificationWindow, pvar); |
| 1729 |
#endif |
#endif |
| 1730 |
} else { |
} |
| 1731 |
|
else if (found_different_type_key) { |
| 1732 |
|
HOSTS_do_different_type_key_dialog(pvar->NotificationWindow, pvar); |
| 1733 |
|
} |
| 1734 |
|
else { |
| 1735 |
#if 0 |
#if 0 |
| 1736 |
PostMessage(pvar->NotificationWindow, WM_COMMAND, |
PostMessage(pvar->NotificationWindow, WM_COMMAND, |
| 1737 |
ID_SSHUNKNOWNHOST, 0); |
ID_SSHUNKNOWNHOST, 0); |