diff --git a/ssh/login1-server.c b/ssh/login1-server.c index 040342da..14f5edd6 100644 --- a/ssh/login1-server.c +++ b/ssh/login1-server.c @@ -39,7 +39,6 @@ struct ssh1_login_server_state { unsigned ap_methods, current_method; unsigned char auth_rsa_expected_response[16]; RSAKey *authkey; - bool auth_successful; PacketProtocolLayer ppl; }; @@ -267,7 +266,9 @@ static void ssh1_login_server_process_queue(PacketProtocolLayer *ppl) s->username.ptr = s->username_str = mkstr(s->username); ppl_logevent("Received username '%.*s'", PTRLEN_PRINTF(s->username)); - s->auth_successful = auth_none(s->authpolicy, s->username); + if (auth_none(s->authpolicy, s->username)) + goto auth_success; + while (1) { /* Signal failed authentication */ pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_SMSG_FAILURE); diff --git a/ssh/server.h b/ssh/server.h index 5cc393df..7a4f9e78 100644 --- a/ssh/server.h +++ b/ssh/server.h @@ -21,6 +21,9 @@ struct SshServerConfig { bool stunt_pretend_to_accept_any_pubkey; bool stunt_open_unconditional_agent_socket; + bool stunt_allow_none_auth; + bool stunt_allow_trivial_ki_auth; + bool stunt_return_success_to_pubkey_offer; }; Plug *ssh_server_plug( diff --git a/ssh/userauth2-server.c b/ssh/userauth2-server.c index da1e79c6..bfe258ce 100644 --- a/ssh/userauth2-server.c +++ b/ssh/userauth2-server.c @@ -209,7 +209,8 @@ static void ssh2_userauth_server_process_queue(PacketProtocolLayer *ppl) if (!(s->methods & s->this_method)) goto failure; - has_signature = get_bool(pktin); + has_signature = get_bool(pktin) || + s->ssc->stunt_return_success_to_pubkey_offer; algorithm = get_string(pktin); blob = get_string(pktin); @@ -251,7 +252,8 @@ static void ssh2_userauth_server_process_queue(PacketProtocolLayer *ppl) signature = get_string(pktin); success = ssh_key_verify(key, signature, - ptrlen_from_strbuf(sigdata)); + ptrlen_from_strbuf(sigdata)) || + s->ssc->stunt_return_success_to_pubkey_offer; ssh_key_free(key); strbuf_free(sigdata); diff --git a/unix/uppity.c b/unix/uppity.c index 1a35451b..4189c7e0 100644 --- a/unix/uppity.c +++ b/unix/uppity.c @@ -110,6 +110,8 @@ void make_unix_sftp_filehandle_key(void *data, size_t size) static bool verbose; +struct server_config; + struct AuthPolicyShared { struct AuthPolicy_ssh1_pubkey *ssh1keys; struct AuthPolicy_ssh2_pubkey *ssh2keys; @@ -124,6 +126,24 @@ struct server_instance { unsigned id; AuthPolicy ap; LogPolicy logpolicy; + struct server_config *cfg; +}; + +struct server_config { + Conf *conf; + const SshServerConfig *ssc; + + ssh_key **hostkeys; + int nhostkeys; + + RSAKey *hostkey1; + + struct AuthPolicyShared *ap_shared; + + unsigned next_id; + + Socket *listening_socket; + Plug listening_plug; }; static void log_to_stderr(unsigned id, const char *msg) @@ -175,11 +195,21 @@ struct AuthPolicy_ssh2_pubkey { unsigned auth_methods(AuthPolicy *ap) { - return (AUTHMETHOD_PUBLICKEY | AUTHMETHOD_PASSWORD | AUTHMETHOD_KBDINT | - AUTHMETHOD_TIS | AUTHMETHOD_CRYPTOCARD); + struct server_instance *inst = container_of( + ap, struct server_instance, ap); + unsigned methods = (AUTHMETHOD_PUBLICKEY | AUTHMETHOD_PASSWORD | + AUTHMETHOD_KBDINT | AUTHMETHOD_TIS | + AUTHMETHOD_CRYPTOCARD); + if (inst->cfg->ssc->stunt_allow_none_auth) + methods |= AUTHMETHOD_NONE; + return methods; } bool auth_none(AuthPolicy *ap, ptrlen username) { + struct server_instance *inst = container_of( + ap, struct server_instance, ap); + if (inst->cfg->ssc->stunt_allow_none_auth) + return true; return false; } int auth_password(AuthPolicy *ap, ptrlen username, ptrlen password, @@ -249,13 +279,21 @@ AuthKbdInt *auth_kbdint_prompts(AuthPolicy *ap, ptrlen username) aki->prompts[1].prompt = dupstr("Silent prompt: "); aki->prompts[1].echo = false; return aki; - case 1: + case 1: { + struct server_instance *inst = container_of( + ap, struct server_instance, ap); aki = snew(AuthKbdInt); - aki->title = dupstr("Zero-prompt step"); - aki->instruction = dupstr("Shouldn't see any prompts this time"); + if (inst->cfg->ssc->stunt_allow_trivial_ki_auth) { + aki->title = dupstr(""); + aki->instruction = dupstr(""); + } else { + aki->title = dupstr("Zero-prompt step"); + aki->instruction = dupstr("Shouldn't see any prompts this time"); + } aki->nprompts = 0; aki->prompts = NULL; return aki; + } default: ap->kbdint_state = 0; return NULL; @@ -416,23 +454,6 @@ static bool longoptnoarg(const char *arg, const char *expected) return false; } -struct server_config { - Conf *conf; - const SshServerConfig *ssc; - - ssh_key **hostkeys; - int nhostkeys; - - RSAKey *hostkey1; - - struct AuthPolicyShared *ap_shared; - - unsigned next_id; - - Socket *listening_socket; - Plug listening_plug; -}; - static Plug *server_conn_plug( struct server_config *cfg, struct server_instance **inst_out) { @@ -442,7 +463,10 @@ static Plug *server_conn_plug( inst->id = cfg->next_id++; inst->ap.shared = cfg->ap_shared; + if (cfg->ssc->stunt_allow_trivial_ki_auth) + inst->ap.kbdint_state = 1; inst->logpolicy.vt = &server_logpolicy_vt; + inst->cfg = cfg; if (inst_out) *inst_out = inst; @@ -785,6 +809,12 @@ int main(int argc, char **argv) ssc.stunt_pretend_to_accept_any_pubkey = true; } else if (!strcmp(arg, "--open-unconditional-agent-socket")) { ssc.stunt_open_unconditional_agent_socket = true; + } else if (!strcmp(arg, "--allow-none-auth")) { + ssc.stunt_allow_none_auth = true; + } else if (!strcmp(arg, "--allow-trivial-ki-auth")) { + ssc.stunt_allow_trivial_ki_auth = true; + } else if (!strcmp(arg, "--return-success-to-pubkey-offer")) { + ssc.stunt_return_success_to_pubkey_offer = true; } else { fprintf(stderr, "%s: unrecognised option '%s'\n", appname, arg); exit(1);