/* * Tries to authenticate the user using the .rhosts file and the host using * its host key. Returns true if authentication succeeds. */ int auth_rhosts_rsa(Authctxt *authctxt, char *cuser, Key *client_host_key) { char *chost; struct passwd *pw = authctxt->pw; debug("Trying rhosts with RSA host authentication for client user %.100s", cuser); if (!authctxt->valid || client_host_key == NULL || client_host_key->rsa == NULL) return 0; chost = (char *)get_canonical_hostname(options.use_dns); debug("Rhosts RSA authentication: canonical host %.900s", chost); if (!PRIVSEP(auth_rhosts_rsa_key_allowed(pw, cuser, chost, client_host_key))) { debug("Rhosts with RSA host authentication denied: unknown or invalid host key"); packet_send_debug("Your host key cannot be verified: unknown or invalid host key."); return 0; } /* A matching host key was found and is known. */ /* Perform the challenge-response dialog with the client for the host key. */ if (!auth_rsa_challenge_dialog(client_host_key)) { logit("Client on %.800s failed to respond correctly to host authentication.", chost); return 0; } /* * We have authenticated the user using .rhosts or /etc/hosts.equiv, * and the host using RSA. We accept the authentication. */ verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.", pw->pw_name, cuser, chost); packet_send_debug("Rhosts with RSA host authentication accepted."); return 1; }
int mm_answer_keyallowed(int sock, Buffer *m) { Key *key; char *cuser, *chost; u_char *blob; u_int bloblen; enum mm_keytype type = 0; int allowed = 0; debug3("%s entering", __func__); type = buffer_get_int(m); cuser = buffer_get_string(m, NULL); chost = buffer_get_string(m, NULL); blob = buffer_get_string(m, &bloblen); key = key_from_blob(blob, bloblen); if ((compat20 && type == MM_RSAHOSTKEY) || (!compat20 && type != MM_RSAHOSTKEY)) fatal("%s: key type and protocol mismatch", __func__); debug3("%s: key_from_blob: %p", __func__, key); if (key != NULL && authctxt->valid) { switch (type) { case MM_USERKEY: allowed = options.pubkey_authentication && user_key_allowed(authctxt->pw, key); break; case MM_HOSTKEY: allowed = options.hostbased_authentication && hostbased_key_allowed(authctxt->pw, cuser, chost, key); break; case MM_RSAHOSTKEY: key->type = KEY_RSA1; /* XXX */ allowed = options.rhosts_rsa_authentication && auth_rhosts_rsa_key_allowed(authctxt->pw, cuser, chost, key); break; default: fatal("%s: unknown key type %d", __func__, type); break; } } if (key != NULL) key_free(key); /* clear temporarily storage (used by verify) */ monitor_reset_key_state(); if (allowed) { /* Save temporarily for comparison in verify */ key_blob = blob; key_bloblen = bloblen; key_blobtype = type; hostbased_cuser = cuser; hostbased_chost = chost; } debug3("%s: key %p is %s", __func__, key, allowed ? "allowed" : "disallowed"); buffer_clear(m); buffer_put_int(m, allowed); buffer_put_int(m, forced_command != NULL); mm_append_debug(m); mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); if (type == MM_RSAHOSTKEY) monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); return (0); }
int mm_answer_keyallowed(int sock, struct sshbuf *m) { struct ssh *ssh = active_state; /* XXX */ struct sshkey *key; char *cuser, *chost; u_char *blob; size_t bloblen; enum mm_keytype type = 0; int r, allowed = 0; debug3("%s entering", __func__); if ((r = sshbuf_get_u32(m, &type)) != 0 || (r = sshbuf_get_cstring(m, &cuser, NULL)) != 0 || (r = sshbuf_get_cstring(m, &chost, NULL)) != 0 || (r = sshbuf_get_string(m, &blob, &bloblen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if ((r = sshkey_from_blob(blob, bloblen, &key)) != 0) fatal("%s: cannot parse key: %s", __func__, ssh_err(r)); if ((compat20 && type == MM_RSAHOSTKEY) || (!compat20 && type != MM_RSAHOSTKEY)) fatal("%s: key type and protocol mismatch", __func__); if (key != NULL && authctxt->valid) { /* These should not make it past the privsep child */ if (sshkey_type_plain(key->type) == KEY_RSA && (ssh->compat & SSH_BUG_RSASIGMD5) != 0) fatal("%s: passed a SSH_BUG_RSASIGMD5 key", __func__); switch (type) { case MM_USERKEY: allowed = options.pubkey_authentication && !auth2_userkey_already_used(authctxt, key) && match_pattern_list(sshkey_ssh_name(key), options.pubkey_key_types, strlen(options.pubkey_key_types), 0) == 1 && user_key_allowed(authctxt->pw, key); pubkey_auth_info(authctxt, key, NULL); auth_method = "publickey"; if (options.pubkey_authentication && allowed != 1) auth_clear_options(); break; case MM_HOSTKEY: allowed = options.hostbased_authentication && match_pattern_list(sshkey_ssh_name(key), options.hostbased_key_types, strlen(options.hostbased_key_types), 0) == 1 && hostbased_key_allowed(authctxt->pw, cuser, chost, key); pubkey_auth_info(authctxt, key, "client user \"%.100s\", client host \"%.100s\"", cuser, chost); auth_method = "hostbased"; break; #ifdef WITH_SSH1 case MM_RSAHOSTKEY: key->type = KEY_RSA1; /* XXX */ allowed = options.rhosts_rsa_authentication && auth_rhosts_rsa_key_allowed(authctxt->pw, cuser, chost, key); if (options.rhosts_rsa_authentication && allowed != 1) auth_clear_options(); auth_method = "rsa"; break; #endif default: fatal("%s: unknown key type %d", __func__, type); break; } } if (key != NULL) sshkey_free(key); /* clear temporarily storage (used by verify) */ monitor_reset_key_state(); if (allowed) { /* Save temporarily for comparison in verify */ key_blob = blob; key_bloblen = bloblen; key_blobtype = type; hostbased_cuser = cuser; hostbased_chost = chost; } else { /* Log failed attempt */ auth_log(authctxt, 0, 0, auth_method, NULL); free(blob); free(cuser); free(chost); } debug3("%s: key %p is %s", __func__, key, allowed ? "allowed" : "not allowed"); sshbuf_reset(m); if ((r = sshbuf_put_u32(m, allowed)) != 0 || (r = sshbuf_put_u32(m, forced_command != NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); if (type == MM_RSAHOSTKEY) monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); return (0); }