| 2232 |
{ |
{ |
| 2233 |
size_t i; |
size_t i; |
| 2234 |
int dlgresult; |
int dlgresult; |
|
char msg[1024]; |
|
| 2235 |
char *host; |
char *host; |
| 2236 |
|
|
| 2237 |
host = pvar->ssh_state.hostname; |
host = pvar->ssh_state.hostname; |
| 2238 |
|
|
| 2239 |
// "/nosecuritywarning"が指定されている場合、更新は一切行わない。 |
// "/nosecuritywarning"が指定されている場合、更新は一切行わない。 |
| 2240 |
if (pvar->nocheck_known_hosts) { |
if (pvar->nocheck_known_hosts) { |
| 2241 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because `/nosecuritywarning' option was specified."); |
logputs(LOG_LEVEL_VERBOSE, "Hostkey was not updated because `/nosecuritywarning' option was specified."); |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE); |
|
| 2242 |
goto error; |
goto error; |
| 2243 |
} |
} |
| 2244 |
|
|
| 2251 |
cur_active != NULL ? cur_active : pvar->NotificationWindow, |
cur_active != NULL ? cur_active : pvar->NotificationWindow, |
| 2252 |
hosts_updatekey_dlg_proc, (LPARAM)pvar); |
hosts_updatekey_dlg_proc, (LPARAM)pvar); |
| 2253 |
if (dlgresult != 1) { |
if (dlgresult != 1) { |
| 2254 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because a user cancelled."); |
logputs(LOG_LEVEL_VERBOSE, "Hostkey was not updated because a user cancelled."); |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE); |
|
| 2255 |
goto error; |
goto error; |
| 2256 |
} |
} |
| 2257 |
} |
} |
| 2263 |
for (i = 0; i < ctx->nkeys; i++) { |
for (i = 0; i < ctx->nkeys; i++) { |
| 2264 |
HOSTS_add_host_key(pvar, ctx->keys[i]); |
HOSTS_add_host_key(pvar, ctx->keys[i]); |
| 2265 |
} |
} |
| 2266 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was successfully updated to known_hosts file."); |
logputs(LOG_LEVEL_VERBOSE, "Hostkey was successfully updated to known_hosts file."); |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE); |
|
| 2267 |
|
|
| 2268 |
error: |
error: |
| 2269 |
return; |
return; |
| 2272 |
static void client_global_hostkeys_private_confirm(PTInstVar pvar, int type, u_int32_t seq, void *_ctx) |
static void client_global_hostkeys_private_confirm(PTInstVar pvar, int type, u_int32_t seq, void *_ctx) |
| 2273 |
{ |
{ |
| 2274 |
struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; |
struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; |
|
char msg[128]; |
|
| 2275 |
char *data; |
char *data; |
| 2276 |
int len; |
int len; |
| 2277 |
unsigned char *blob = NULL; |
unsigned char *blob = NULL; |
| 2302 |
memcpy(cp, data, len); |
memcpy(cp, data, len); |
| 2303 |
|
|
| 2304 |
if (ctx->nnew == 0) { |
if (ctx->nnew == 0) { |
| 2305 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey can not be updated because ctx->nnew %d(program bug).", ctx->nnew); |
logprintf(LOG_LEVEL_FATAL, |
| 2306 |
notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL); |
"Hostkey can not be updated because ctx->nnew %d(program bug).", ctx->nnew); |
| 2307 |
goto error; |
goto error; |
| 2308 |
} |
} |
| 2309 |
if (type != SSH2_MSG_REQUEST_SUCCESS) { |
if (type != SSH2_MSG_REQUEST_SUCCESS) { |
| 2310 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Server failed to confirm ownership of private host keys(type %d)", type); |
logprintf(LOG_LEVEL_ERROR, |
| 2311 |
notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR); |
"Server failed to confirm ownership of private host keys(type %d)", type); |
| 2312 |
goto error; |
goto error; |
| 2313 |
} |
} |
| 2314 |
if (pvar->session_id_len == 0) { |
if (pvar->session_id_len == 0) { |
| 2315 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey can not be updated because pvar->session_id_len %d(program bug).", pvar->session_id_len); |
logprintf(LOG_LEVEL_FATAL, |
| 2316 |
notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL); |
"Hostkey can not be updated because pvar->session_id_len %d(program bug).", |
| 2317 |
|
pvar->session_id_len); |
| 2318 |
goto error; |
goto error; |
| 2319 |
} |
} |
| 2320 |
|
|
| 2341 |
free(sig); |
free(sig); |
| 2342 |
sig = NULL; |
sig = NULL; |
| 2343 |
if (ret != 1) { |
if (ret != 1) { |
| 2344 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "server gave bad signature for %s key %u", |
logprintf(LOG_LEVEL_ERROR, |
| 2345 |
|
"server gave bad signature for %s key %u", |
| 2346 |
get_sshname_from_key(ctx->keys[i]), i); |
get_sshname_from_key(ctx->keys[i]), i); |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR); |
|
| 2347 |
goto error; |
goto error; |
| 2348 |
} |
} |
| 2349 |
ndone++; |
ndone++; |
| 2350 |
} |
} |
| 2351 |
|
|
| 2352 |
if (ndone != ctx->nnew) { |
if (ndone != ctx->nnew) { |
| 2353 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey can not be updated because ndone != ctx->nnew (%u / %u)(program bug).", |
logprintf(LOG_LEVEL_FATAL, |
| 2354 |
|
"Hostkey can not be updated because ndone != ctx->nnew (%u / %u)(program bug).", |
| 2355 |
ndone, ctx->nnew); |
ndone, ctx->nnew); |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL); |
|
| 2356 |
goto error; |
goto error; |
| 2357 |
} |
} |
| 2358 |
|
|
| 2377 |
int len; |
int len; |
| 2378 |
size_t i; |
size_t i; |
| 2379 |
char *cp, *fp; |
char *cp, *fp; |
|
char msg[128]; |
|
| 2380 |
unsigned char *blob = NULL; |
unsigned char *blob = NULL; |
| 2381 |
buffer_t *b = NULL; |
buffer_t *b = NULL; |
| 2382 |
struct hostkeys_update_ctx *ctx = NULL; |
struct hostkeys_update_ctx *ctx = NULL; |
| 2385 |
|
|
| 2386 |
// Tera Termの設定で、当該機能のオンオフを制御できるようにする。 |
// Tera Termの設定で、当該機能のオンオフを制御できるようにする。 |
| 2387 |
if (pvar->settings.UpdateHostkeys == SSH_UPDATE_HOSTKEYS_NO) { |
if (pvar->settings.UpdateHostkeys == SSH_UPDATE_HOSTKEYS_NO) { |
| 2388 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Hostkey was not updated because ts.UpdateHostkeys is disabled."); |
logputs(LOG_LEVEL_VERBOSE, "Hostkey was not updated because ts.UpdateHostkeys is disabled."); |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE); |
|
| 2389 |
return 1; |
return 1; |
| 2390 |
} |
} |
| 2391 |
|
|
| 2407 |
blob = buffer_get_string_msg(b, &len); |
blob = buffer_get_string_msg(b, &len); |
| 2408 |
key = key_from_blob(blob, len); |
key = key_from_blob(blob, len); |
| 2409 |
if (key == NULL) { |
if (key == NULL) { |
| 2410 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not found host key into blob %p (%d)", blob, len); |
logprintf(LOG_LEVEL_ERROR, "Not found host key into blob %p (%d)", blob, len); |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR); |
|
| 2411 |
goto error; |
goto error; |
| 2412 |
} |
} |
| 2413 |
free(blob); |
free(blob); |
| 2414 |
blob = NULL; |
blob = NULL; |
| 2415 |
|
|
| 2416 |
fp = key_fingerprint(key, SSH_FP_HEX, SSH_DIGEST_MD5); |
fp = key_fingerprint(key, SSH_FP_HEX, SSH_DIGEST_MD5); |
| 2417 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Received %s host key %s", |
logprintf(LOG_LEVEL_VERBOSE, "Received %s host key %s", get_sshname_from_key(key), fp); |
|
get_sshname_from_key(key), fp); |
|
|
notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE); |
|
| 2418 |
free(fp); |
free(fp); |
| 2419 |
|
|
| 2420 |
// 許可されたホストキーアルゴリズムかをチェックする。 |
// 許可されたホストキーアルゴリズムかをチェックする。 |
| 2421 |
if (check_hostkey_algorithm(pvar, key) == 0) { |
if (check_hostkey_algorithm(pvar, key) == 0) { |
| 2422 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "%s host key is not permitted by ts.HostKeyOrder", |
logprintf(LOG_LEVEL_VERBOSE, "%s host key is not permitted by ts.HostKeyOrder", |
| 2423 |
get_sshname_from_key(key)); |
get_sshname_from_key(key)); |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE); |
|
| 2424 |
continue; |
continue; |
| 2425 |
} |
} |
| 2426 |
|
|
| 2429 |
// 重複したキーを受信したらエラーとする。 |
// 重複したキーを受信したらエラーとする。 |
| 2430 |
for (i = 0; i < ctx->nkeys; i++) { |
for (i = 0; i < ctx->nkeys; i++) { |
| 2431 |
if (HOSTS_compare_public_key(key, ctx->keys[i]) == 1) { |
if (HOSTS_compare_public_key(key, ctx->keys[i]) == 1) { |
| 2432 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Received duplicated %s host key", |
logprintf(LOG_LEVEL_ERROR, "Received duplicated %s host key", |
| 2433 |
get_sshname_from_key(key)); |
get_sshname_from_key(key)); |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_ERROR); |
|
| 2434 |
goto error; |
goto error; |
| 2435 |
} |
} |
| 2436 |
} |
} |
| 2438 |
// キーを登録する。 |
// キーを登録する。 |
| 2439 |
tmp = realloc(ctx->keys, (ctx->nkeys + 1)*sizeof(*ctx->keys)); |
tmp = realloc(ctx->keys, (ctx->nkeys + 1)*sizeof(*ctx->keys)); |
| 2440 |
if (tmp == NULL) { |
if (tmp == NULL) { |
| 2441 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not memory: realloc ctx->keys %d", |
logprintf(LOG_LEVEL_FATAL, "Not memory: realloc ctx->keys %d", |
| 2442 |
ctx->nkeys); |
ctx->nkeys); |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL); |
|
| 2443 |
goto error; |
goto error; |
| 2444 |
} |
} |
| 2445 |
ctx->keys = tmp; |
ctx->keys = tmp; |
| 2448 |
} |
} |
| 2449 |
|
|
| 2450 |
if (ctx->nkeys == 0) { |
if (ctx->nkeys == 0) { |
| 2451 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "No host rotation key"); |
logputs(LOG_LEVEL_VERBOSE, "No host rotation key"); |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE); |
|
| 2452 |
goto error; |
goto error; |
| 2453 |
} |
} |
| 2454 |
|
|
| 2455 |
if ((ctx->keys_seen = calloc(ctx->nkeys, sizeof(*ctx->keys_seen))) == NULL) { |
if ((ctx->keys_seen = calloc(ctx->nkeys, sizeof(*ctx->keys_seen))) == NULL) { |
| 2456 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not memory: calloc ctx->keys %d", |
logprintf(LOG_LEVEL_FATAL, "Not memory: calloc ctx->keys %d", |
| 2457 |
ctx->nkeys); |
ctx->nkeys); |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_FATAL); |
|
| 2458 |
goto error; |
goto error; |
| 2459 |
} |
} |
| 2460 |
|
|
| 2466 |
if (!ctx->keys_seen[i]) |
if (!ctx->keys_seen[i]) |
| 2467 |
ctx->nnew++; |
ctx->nnew++; |
| 2468 |
} |
} |
| 2469 |
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "%u keys from server: %u new, %u retained. %u to remove", |
logprintf(LOG_LEVEL_VERBOSE, "%u keys from server: %u new, %u retained. %u to remove", |
| 2470 |
ctx->nkeys, ctx->nnew, ctx->nkeys - ctx->nnew, ctx->nold); |
ctx->nkeys, ctx->nnew, ctx->nkeys - ctx->nnew, ctx->nold); |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE); |
|
| 2471 |
|
|
| 2472 |
// 新規追加する鍵はゼロだが、deprecatedな鍵が存在する。 |
// 新規追加する鍵はゼロだが、deprecatedな鍵が存在する。 |
| 2473 |
if (ctx->nnew == 0 && ctx->nold != 0) { |
if (ctx->nnew == 0 && ctx->nold != 0) { |