version 1.158, 2020/03/06 18:16:21 |
version 1.159, 2020/10/18 11:32:01 |
|
|
(r = sshpkt_put_cstring(ssh, banner)) != 0 || |
(r = sshpkt_put_cstring(ssh, banner)) != 0 || |
(r = sshpkt_put_cstring(ssh, "")) != 0 || /* language, unused */ |
(r = sshpkt_put_cstring(ssh, "")) != 0 || /* language, unused */ |
(r = sshpkt_send(ssh)) != 0) |
(r = sshpkt_send(ssh)) != 0) |
fatal("%s: %s", __func__, ssh_err(r)); |
fatal_fr(r, "send packet"); |
debug("userauth_banner: sent"); |
debug("userauth_banner: sent"); |
done: |
done: |
free(banner); |
free(banner); |
|
|
(void)snprintf(b, sizeof b, "%llu%s", |
(void)snprintf(b, sizeof b, "%llu%s", |
(unsigned long long)options.timing_secret, user); |
(unsigned long long)options.timing_secret, user); |
if (ssh_digest_memory(SSH_DIGEST_SHA512, b, strlen(b), hash, len) != 0) |
if (ssh_digest_memory(SSH_DIGEST_SHA512, b, strlen(b), hash, len) != 0) |
fatal("%s: ssh_digest_memory", __func__); |
fatal_f("ssh_digest_memory"); |
/* 0-4.2 ms of delay */ |
/* 0-4.2 ms of delay */ |
delay = (double)PEEK_U32(hash) / 1000 / 1000 / 1000 / 1000; |
delay = (double)PEEK_U32(hash) / 1000 / 1000 / 1000 / 1000; |
freezero(hash, len); |
freezero(hash, len); |
debug3("%s: user specific delay %0.3lfms", __func__, delay/1000); |
debug3_f("user specific delay %0.3lfms", delay/1000); |
return MIN_FAIL_DELAY_SECONDS + delay; |
return MIN_FAIL_DELAY_SECONDS + delay; |
} |
} |
|
|
|
|
|
|
ts.tv_sec = remain; |
ts.tv_sec = remain; |
ts.tv_nsec = (remain - ts.tv_sec) * 1000000000; |
ts.tv_nsec = (remain - ts.tv_sec) * 1000000000; |
debug3("%s: elapsed %0.3lfms, delaying %0.3lfms (requested %0.3lfms)", |
debug3_f("elapsed %0.3lfms, delaying %0.3lfms (requested %0.3lfms)", |
__func__, elapsed*1000, remain*1000, req*1000); |
elapsed*1000, remain*1000, req*1000); |
nanosleep(&ts, NULL); |
nanosleep(&ts, NULL); |
} |
} |
|
|
|
|
authctxt->pw = PRIVSEP(getpwnamallow(ssh, user)); |
authctxt->pw = PRIVSEP(getpwnamallow(ssh, user)); |
if (authctxt->pw && strcmp(service, "ssh-connection")==0) { |
if (authctxt->pw && strcmp(service, "ssh-connection")==0) { |
authctxt->valid = 1; |
authctxt->valid = 1; |
debug2("%s: setting up authctxt for %s", |
debug2_f("setting up authctxt for %s", user); |
__func__, user); |
|
} else { |
} else { |
/* Invalid user, fake password information */ |
/* Invalid user, fake password information */ |
authctxt->pw = fakepw(); |
authctxt->pw = fakepw(); |
|
|
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_SUCCESS)) != 0 || |
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_SUCCESS)) != 0 || |
(r = sshpkt_send(ssh)) != 0 || |
(r = sshpkt_send(ssh)) != 0 || |
(r = ssh_packet_write_wait(ssh)) != 0) |
(r = ssh_packet_write_wait(ssh)) != 0) |
fatal("%s: %s", __func__, ssh_err(r)); |
fatal_fr(r, "send success packet"); |
/* now we can break out */ |
/* now we can break out */ |
authctxt->success = 1; |
authctxt->success = 1; |
ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); |
ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); |
|
|
if (authctxt->failures >= options.max_authtries) |
if (authctxt->failures >= options.max_authtries) |
auth_maxtries_exceeded(ssh); |
auth_maxtries_exceeded(ssh); |
methods = authmethods_get(authctxt); |
methods = authmethods_get(authctxt); |
debug3("%s: failure partial=%d next methods=\"%s\"", __func__, |
debug3_f("failure partial=%d next methods=\"%s\"", |
partial, methods); |
partial, methods); |
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_FAILURE)) != 0 || |
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_FAILURE)) != 0 || |
(r = sshpkt_put_cstring(ssh, methods)) != 0 || |
(r = sshpkt_put_cstring(ssh, methods)) != 0 || |
(r = sshpkt_put_u8(ssh, partial)) != 0 || |
(r = sshpkt_put_u8(ssh, partial)) != 0 || |
(r = sshpkt_send(ssh)) != 0 || |
(r = sshpkt_send(ssh)) != 0 || |
(r = ssh_packet_write_wait(ssh)) != 0) |
(r = ssh_packet_write_wait(ssh)) != 0) |
fatal("%s: %s", __func__, ssh_err(r)); |
fatal_fr(r, "send failure packet"); |
free(methods); |
free(methods); |
} |
} |
} |
} |
|
|
int i, r; |
int i, r; |
|
|
if ((b = sshbuf_new()) == NULL) |
if ((b = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
for (i = 0; authmethods[i] != NULL; i++) { |
for (i = 0; authmethods[i] != NULL; i++) { |
if (strcmp(authmethods[i]->name, "none") == 0) |
if (strcmp(authmethods[i]->name, "none") == 0) |
continue; |
continue; |
|
|
continue; |
continue; |
if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) ? "," : "", |
if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) ? "," : "", |
authmethods[i]->name)) != 0) |
authmethods[i]->name)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "buffer error"); |
} |
} |
if ((list = sshbuf_dup_string(b)) == NULL) |
if ((list = sshbuf_dup_string(b)) == NULL) |
fatal("%s: sshbuf_dup_string failed", __func__); |
fatal_f("sshbuf_dup_string failed"); |
sshbuf_free(b); |
sshbuf_free(b); |
return list; |
return list; |
} |
} |
|
|
|
|
if (options.num_auth_methods == 0) |
if (options.num_auth_methods == 0) |
return 0; |
return 0; |
debug3("%s: checking methods", __func__); |
debug3_f("checking methods"); |
authctxt->auth_methods = xcalloc(options.num_auth_methods, |
authctxt->auth_methods = xcalloc(options.num_auth_methods, |
sizeof(*authctxt->auth_methods)); |
sizeof(*authctxt->auth_methods)); |
authctxt->num_auth_methods = 0; |
authctxt->num_auth_methods = 0; |
|
|
{ |
{ |
u_int i, found = 0; |
u_int i, found = 0; |
|
|
debug3("%s: updating methods list after \"%s\"", __func__, method); |
debug3_f("updating methods list after \"%s\"", method); |
for (i = 0; i < authctxt->num_auth_methods; i++) { |
for (i = 0; i < authctxt->num_auth_methods; i++) { |
if (!remove_method(&(authctxt->auth_methods[i]), method, |
if (!remove_method(&(authctxt->auth_methods[i]), method, |
submethod)) |
submethod)) |
|
|
} |
} |
/* This should not happen, but would be bad if it did */ |
/* This should not happen, but would be bad if it did */ |
if (!found) |
if (!found) |
fatal("%s: method not in AuthenticationMethods", __func__); |
fatal_f("method not in AuthenticationMethods"); |
return 0; |
return 0; |
} |
} |
|
|
|
|
va_end(ap); |
va_end(ap); |
|
|
if (i == -1) |
if (i == -1) |
fatal("%s: vasprintf failed", __func__); |
fatal_f("vasprintf failed"); |
} |
} |
|
|
/* |
/* |
|
|
int r; |
int r; |
|
|
if ((r = sshkey_from_private(key, &dup)) != 0) |
if ((r = sshkey_from_private(key, &dup)) != 0) |
fatal("%s: copy key: %s", __func__, ssh_err(r)); |
fatal_fr(r, "copy key"); |
sshkey_free(authctxt->auth_method_key); |
sshkey_free(authctxt->auth_method_key); |
authctxt->auth_method_key = dup; |
authctxt->auth_method_key = dup; |
|
|
|
|
|
|
/* If authenticated, make sure we don't accept this key again */ |
/* If authenticated, make sure we don't accept this key again */ |
if ((r = sshkey_from_private(key, &dup)) != 0) |
if ((r = sshkey_from_private(key, &dup)) != 0) |
fatal("%s: copy key: %s", __func__, ssh_err(r)); |
fatal_fr(r, "copy key"); |
if (authctxt->nprev_keys >= INT_MAX || |
if (authctxt->nprev_keys >= INT_MAX || |
(tmp = recallocarray(authctxt->prev_keys, authctxt->nprev_keys, |
(tmp = recallocarray(authctxt->prev_keys, authctxt->nprev_keys, |
authctxt->nprev_keys + 1, sizeof(*authctxt->prev_keys))) == NULL) |
authctxt->nprev_keys + 1, sizeof(*authctxt->prev_keys))) == NULL) |
fatal("%s: reallocarray failed", __func__); |
fatal_f("reallocarray failed"); |
authctxt->prev_keys = tmp; |
authctxt->prev_keys = tmp; |
authctxt->prev_keys[authctxt->nprev_keys] = dup; |
authctxt->prev_keys[authctxt->nprev_keys] = dup; |
authctxt->nprev_keys++; |
authctxt->nprev_keys++; |
|
|
if (sshkey_equal_public(key, authctxt->prev_keys[i])) { |
if (sshkey_equal_public(key, authctxt->prev_keys[i])) { |
fp = sshkey_fingerprint(authctxt->prev_keys[i], |
fp = sshkey_fingerprint(authctxt->prev_keys[i], |
options.fingerprint_hash, SSH_FP_DEFAULT); |
options.fingerprint_hash, SSH_FP_DEFAULT); |
debug3("%s: key already used: %s %s", __func__, |
debug3_f("key already used: %s %s", |
sshkey_type(authctxt->prev_keys[i]), |
sshkey_type(authctxt->prev_keys[i]), |
fp == NULL ? "UNKNOWN" : fp); |
fp == NULL ? "UNKNOWN" : fp); |
free(fp); |
free(fp); |
|
|
|
|
if (authctxt->session_info == NULL) { |
if (authctxt->session_info == NULL) { |
if ((authctxt->session_info = sshbuf_new()) == NULL) |
if ((authctxt->session_info = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new", __func__); |
fatal_f("sshbuf_new"); |
} |
} |
|
|
/* Append method[/submethod] */ |
/* Append method[/submethod] */ |
if ((r = sshbuf_putf(authctxt->session_info, "%s%s%s", |
if ((r = sshbuf_putf(authctxt->session_info, "%s%s%s", |
method, submethod == NULL ? "" : "/", |
method, submethod == NULL ? "" : "/", |
submethod == NULL ? "" : submethod)) != 0) |
submethod == NULL ? "" : submethod)) != 0) |
fatal("%s: append method: %s", __func__, ssh_err(r)); |
fatal_fr(r, "append method"); |
|
|
/* Append key if present */ |
/* Append key if present */ |
if (authctxt->auth_method_key != NULL) { |
if (authctxt->auth_method_key != NULL) { |
if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 || |
if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 || |
(r = sshkey_format_text(authctxt->auth_method_key, |
(r = sshkey_format_text(authctxt->auth_method_key, |
authctxt->session_info)) != 0) |
authctxt->session_info)) != 0) |
fatal("%s: append key: %s", __func__, ssh_err(r)); |
fatal_fr(r, "append key"); |
} |
} |
|
|
if (authctxt->auth_method_info != NULL) { |
if (authctxt->auth_method_info != NULL) { |
/* Ensure no ambiguity here */ |
/* Ensure no ambiguity here */ |
if (strchr(authctxt->auth_method_info, '\n') != NULL) |
if (strchr(authctxt->auth_method_info, '\n') != NULL) |
fatal("%s: auth_method_info contains \\n", __func__); |
fatal_f("auth_method_info contains \\n"); |
if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 || |
if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 || |
(r = sshbuf_putf(authctxt->session_info, "%s", |
(r = sshbuf_putf(authctxt->session_info, "%s", |
authctxt->auth_method_info)) != 0) { |
authctxt->auth_method_info)) != 0) { |
fatal("%s: append method info: %s", |
fatal_fr(r, "append method info"); |
__func__, ssh_err(r)); |
|
} |
} |
} |
} |
if ((r = sshbuf_put_u8(authctxt->session_info, '\n')) != 0) |
if ((r = sshbuf_put_u8(authctxt->session_info, '\n')) != 0) |
fatal("%s: append: %s", __func__, ssh_err(r)); |
fatal_fr(r, "append"); |
} |
} |
|
|